2016-02-28
| 01:12 | joker_ | Newbie question: Do I have include/require any ns to use 'source' and 'find-doc' functions in a nREPL (counterclockwise eclipse IDE) ? |
| 04:53 | rinat | Hi. Sorry for noob question in advance. I'm trying to learn Clojure, building a small API with a bunch of components (using component lib). However, I can't figure out how to make Liberator work nicely with Component. Are they a good fit for each other? |
| 05:27 | john222222 | I’ve just started with emacs and cider. does cider use something differnt to provide expand-region functionallity? |
| 09:05 | justin_smith | the answer to joker_'s question above is clojure.repl, but seems joker_ is not around |
| 10:23 | renl | hi im having some trouble using leinigen, it says Failed to resolve version for play-clj:lein-template:jar:RELEASE: Could not find metadata play-clj:lein-template/maven-metadata.xml in local |
| 10:24 | renl | this is while using linux in my vmware |
| 10:24 | justin_smith | renl: that's while trying to do "lein new play-clj foo" right? |
| 10:26 | renl | yeah |
| 10:26 | justin_smith | interesting, what lein version? |
| 10:26 | renl | Leiningen 2.6.1 on Java 1.8.0_66-internal OpenJDK 64-Bit Server VM |
| 10:27 | justin_smith | interesting |
| 10:27 | justin_smith | brb |
| 10:27 | renl | thanks! :D |
| 10:31 | ridcully | your network is fine in your vm? e.g. a curl call into the world works? |
| 10:31 | renl | network is fine with vm, this irc client is currently connected from my vm |
| 10:33 | justin_smith | renl: could be clojars was down for a moment - I was just able to run that just fine |
| 10:33 | ridcully | dito |
| 10:34 | renl | i tried it yesterday and today both times didnt work, trying it now again |
| 10:35 | renl | nope still not working |
| 10:36 | renl | oh when i just add it as a dependency in the project.clj i get this |
| 10:36 | renl | Could not transfer artifact org.clojure:clojure:pom:1.8.0 from/to central (https://repo1.maven.org/maven2/): java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty |
| 10:36 | justin_smith | can you ping clojars.org? |
| 10:36 | justin_smith | renl: aha! |
| 10:36 | renl | ping works |
| 10:36 | justin_smith | this is the bullshit java on ubuntu trustdb bug |
| 10:36 | renl | oh? |
| 10:36 | renl | let me google that mmm |
| 10:36 | justin_smith | renl: http://askubuntu.com/a/635395 |
| 10:37 | justin_smith | it's a simple fix |
| 10:37 | justin_smith | stupid bug |
| 10:37 | justin_smith | (swap! ubuntu dec) |
| 10:37 | renl | cool thanks! :D |
| 10:38 | renl | woo works :D |
| 10:39 | gfredericks | justin_smith: yeah it definitely has some sort of size threshold, same for maps |
| 10:39 | gfredericks | even though it's the same underlying type |
| 10:40 | justin_smith | gfredericks: oh yeah, when I take the first of my two hash-sets and increase the size, then the problem kicks in, even on the first call |
| 10:41 | jgertm | is it normal that cljr-move-to-let only moves the current occurance of the form, not all of them? |
| 10:42 | justin_smith | gfredericks: the threshold, with a bit of trial and error, is at 8 |
| 10:42 | justin_smith | 8 or less is fine, adding the ninth item makes the bug happen |
| 10:42 | justin_smith | jgertm: what does "occurance of a form" mean? |
| 10:45 | jgertm | justin_smith: identical expressions |
| 10:45 | justin_smith | aha |
| 10:45 | justin_smith | yeah, I bet it doesn't do that because the tool doesn't know that it's safe - I mean what if the expression has a side effect? |
| 10:46 | justin_smith | I don't know that, just a guess |
| 10:46 | jgertm | i just watched this video (https://youtu.be/mOSUE3czp9w) and thats what happens there |
| 10:47 | jgertm | justin_smith: but maybe they realized that since. what youre saying makes sense |
| 10:47 | benjyz1 | what's the easiest way to store clojure data structures? key-value store? |
| 10:47 | benjyz1 | instead of just edn files |
| 10:48 | jgertm | though they should still leave it to the user. its not cljr-refactor's job to enforce saftety after all |
| 10:48 | justin_smith | benjyz1: datomic actually supports most of the clojure data types. But the translation to json is often good enough too (and a few different dbs support json) |
| 10:49 | LauJensen | Gents, fun hobby task. I have 7 guests who has to be seated at 2 tables. 3 guests @ each table (the spare goes wherever). The trick is, noone must be seated with guests they have previously been seated with, unless thats impossible to avoid. Can anyone think of a good algorithm for sorting out the seating arrangements? |
| 10:49 | benjyz1 | justin_smith: I'm considering datomic. I'm wondering whether I need to handle schemas at all |
| 10:49 | justin_smith | LauJensen: core.logic would handle that easily - once you figure out core.logic of course |
| 10:50 | LauJensen | justin_smith, i'll go have a look |
| 10:50 | justin_smith | benjyz1: depending on your correctness needs, the translation to/from monger is very simple also |
| 10:50 | benjyz1 | i.e. rather than key-value store or schema-less .. monger.. right |
| 10:50 | justin_smith | monger being a mongo lib |
| 10:50 | benjyz1 | I've never used key-value store like redis |
| 10:51 | justin_smith | that's not even a db |
| 10:51 | justin_smith | that's a cache |
| 10:51 | justin_smith | I mean mongo is arguably in a similar position (more durable, maybe less reliable) |
| 10:53 | benjyz1 | thx, I'll go with datomic. I want to avoid SQL for sure |
| 11:55 | kungi | Is (get-in m [:foo :bar]) or (-> m :foo :bar) more idiomatic? |
| 11:55 | TimMc | justin_smith: Redis styles itself as a DB. |
| 11:56 | TimMc | (You don't have to set an eviction policy, IIRC.) |
| 11:57 | justin_smith | TimMc: fascinating ... https://muut.com/blog/technology/redis-as-primary-datastore-wtf.html |
| 12:02 | justin_smith | TimMc: redis also has distsys data loss bugs, as exposed by our friend aphyr |
| 12:04 | TimMc | "You have to be able to fit all your data in memory, and If your server fails between disk syncs you lose anything that was sitting in memory." |
| 12:04 | TimMc | welp |
| 12:04 | justin_smith | haha, yeah |
| 12:05 | TimMc | forgot about that part |
| 12:05 | justin_smith | TimMc: it's like the anti-kafka |
| 12:05 | justin_smith | in that kafka is meant to be a message queue, but almost accidentally has very reliable persistence |
| 12:06 | justin_smith | (because the fastest queue turns out to be the disk, used in strict sequential sectors) |
| 12:13 | edmondo1984 | hello, is there anyone who can help a newbie to re-write assoc-in? |
| 12:16 | TimMc | edmondo1984: ...what needs rewriting about it? |
| 12:20 | edmondo1984 | TimMc I am learning clojure, one of the exercises of Clojure for the brave and the true is to rewrite that funciton |
| 12:21 | edmondo1984 | maybe to prove you understand recursion, in fact I didn't understand it because I can't rewrite it |
| 12:27 | justin_smith | edmondo1984: cool idea for that exercise is make it prefer to create a vector if they key is 0 and the parent is nil |
| 12:28 | TimMc | ,(assoc-in nil [0] :probe) |
| 12:28 | clojurebot | {0 :probe} |
| 12:28 | TimMc | interesting ambiguous case |
| 12:29 | justin_smith | I mean it makes the logic more complex for sure, but it would be a nifty behavior |
| 12:32 | edmondo1984 | justin_smith are you |
| 12:33 | justin_smith | edmondo1984: I'm glad to provide feedback or suggestions if you have questions, or you can show what you've tried |
| 12:34 | edmondo1984 | thanks |
| 12:34 | edmondo1984 | so |
| 12:34 | edmondo1984 | this is my first try |
| 12:34 | edmondo1984 | http://paste.ofcode.org/?edit=WdwLuA3cgBdaegQgzPzAg |
| 12:34 | luxbock | I'd like to wrap a long-running process that communicates in via stdin and stdout into a REPL that I can then embed in a Clojure program |
| 12:34 | edmondo1984 | I am missing the recursive branch |
| 12:35 | luxbock | does anyone here happen to have any resources on doing something like this? examples, blog posts, experiences etc. |
| 12:35 | justin_smith | edmondo1984: for starters, you have way too many parens |
| 12:35 | justin_smith | edmondo1984: in clojure, (f) is like f() in another language |
| 12:35 | justin_smith | what you are doing is effectively f()() (in a few places) which is almost always wrong |
| 12:35 | justin_smith | and in your case, recur doesn't even allow that |
| 12:37 | edmondo1984 | ok |
| 12:37 | edmondo1984 | so... |
| 12:37 | edmondo1984 | where is the exceeding parenthesis? |
| 12:38 | justin_smith | edmondo1984: pretty much everywhere you have (( |
| 12:38 | justin_smith | what you are doing is ((f)) instead of (f), and these are very different in clojure |
| 12:39 | edmondo1984 | I see, are you saying around the if? |
| 12:39 | justin_smith | no, if doesn't have (( |
| 12:39 | edmondo1984 | I thought because the if it's a special form I should do (if (f) (f1) (f2) ) |
| 12:39 | justin_smith | but your loop and recur are both broken because they are wrapped in (( |
| 12:39 | justin_smith | edmondo1984: no |
| 12:39 | justin_smith | the if has nothing to do with this |
| 12:39 | TimMc | justin_smith: "f()()", that's a good way of explaining that. |
| 12:40 | justin_smith | TimMc: thanks, but the correct form might be something terrible like (f())() but we can pretend it's a non-terrible algol family language I invented |
| 12:40 | justin_smith | (due to precedence of ()) |
| 12:40 | jonathanj | can one do the equivalent of passing `-Dsomething=x` to java from an application already running in the JVM? |
| 12:41 | justin_smith | jonathanj: (System/setProperty "something" "x") |
| 12:41 | jonathanj | fantastic, thank you |
| 12:41 | edmondo1984 | so justin, the first parenthesis is the one that wrap the body of the function |
| 12:41 | justin_smith | no! |
| 12:41 | edmondo1984 | I thought this was mandatory by syntax? |
| 12:41 | edmondo1984 | AH! |
| 12:41 | justin_smith | edmondo1984: that isn't even a thing! |
| 12:41 | justin_smith | there's no such thing |
| 12:42 | edmondo1984 | so the parenthesis before the loop |
| 12:42 | edmondo1984 | is not needed |
| 12:42 | justin_smith | ,((fn [])) |
| 12:42 | clojurebot | nil |
| 12:42 | justin_smith | edmondo1984: not only is it "not needed", it is an error |
| 12:42 | edmondo1984 | got it |
| 12:42 | justin_smith | edmondo1984: there is no such thing as free parens in clojure |
| 12:42 | edmondo1984 | because it would treat the loop block as a function |
| 12:42 | justin_smith | they always do something, unlike in math class |
| 12:42 | justin_smith | exactly |
| 12:43 | TimMc | edmondo1984: Take a look at these three evaluations: |
| 12:43 | edmondo1984 | which constructs are not function? loop, if, let? |
| 12:43 | TimMc | ,(let [f (fn [] 3)] (f)) |
| 12:43 | clojurebot | 3 |
| 12:43 | TimMc | ,(3) |
| 12:43 | clojurebot | #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval77 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval77 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval77 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6927]... |
| 12:43 | justin_smith | edmondo1984: it doesn't matter - those things are all callable, thus they all need to be wrapped in parens |
| 12:43 | TimMc | ,(let [f (fn [] 3)] ((f))) |
| 12:43 | clojurebot | #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval101 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval101 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval101 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 69... |
| 12:43 | edmondo1984 | ,(constant 3) |
| 12:43 | clojurebot | #error {\n :cause "Unable to resolve symbol: constant in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: constant in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: constan... |
| 12:43 | edmondo1984 | ,(constantly 3) |
| 12:43 | clojurebot | #object[clojure.core$constantly$fn__4614 0x4c760aaa "clojure.core$constantly$fn__4614@4c760aaa"] |
| 12:43 | justin_smith | edmondo1984: whether they are functions or not comes up later |
| 12:43 | edmondo1984 | ,((constantly 3)) |
| 12:44 | clojurebot | 3 |
| 12:44 | edmondo1984 | got it |
| 12:44 | edmondo1984 | the () resolve the function execution |
| 12:44 | edmondo1984 | cool |
| 12:44 | justin_smith | we use "resolve" to mean "look up a value in a namespace" but yes, (f) calls f (or attempts to), with very few exceptions |
| 12:44 | justin_smith | one of those exceptions being case |
| 12:44 | edmondo1984 | cool |
| 12:44 | justin_smith | I forget the other one right now |
| 12:45 | TimMc | (...) is a list, and evaluating a list in Clojure means calling the first item |
| 12:45 | justin_smith | ,(case 1 (1 2) :this (3 4) :that) |
| 12:45 | clojurebot | :this |
| 12:45 | edmondo1984 | but look in this example |
| 12:45 | edmondo1984 | https://clojuredocs.org/clojure.core/recur |
| 12:45 | edmondo1984 | the first loop is wrapped by () |
| 12:45 | justin_smith | edmondo1984: sure - loop is something you call |
| 12:46 | justin_smith | edmondo1984: but notice you don't wrap that in yet another pair of parens |
| 12:46 | justin_smith | edmondo1984: as I said before, we don't need to worry about what's a function vs. macro vs. special form yet, the rules are the same - wrap it in parens to invoke it |
| 12:47 | edmondo1984 | ok so why in my example is an error? |
| 12:48 | edmondo1984 | It's really difficult to understand clojure from a non lisp background :) |
| 12:49 | rhg135 | Cuz f() is easier than (f) |
| 12:49 | justin_smith | edmondo1984: ((loop)) in clojure is like loop()() in js |
| 12:49 | justin_smith | see what's wrong there? |
| 12:50 | justin_smith | similarly ((recur)) is recur()() |
| 12:51 | justin_smith | ((loop)) is usually an error - unless you expect your loop to return something you call |
| 12:51 | edmondo1984 | oh right there's an additional parenthesis around loop |
| 12:52 | justin_smith | ((recur)) is always an error, because recur must be in tail position, and the extra parens mean it is not in the tail position |
| 12:52 | edmondo1984 | http://paste.ofcode.org/JRWWTmfP9vcejmQe87zU3Y |
| 12:53 | justin_smith | much better |
| 12:53 | edmondo1984 | now the question is I don't know how to recurse |
| 12:53 | justin_smith | recur takes half as many args as you put in your loop binding block |
| 12:53 | justin_smith | so it sends a new value for each binding |
| 12:54 | edmondo1984 | that's what I don't know how to express in clojure |
| 12:54 | justin_smith | edmondo1984: two more problems - your recur is outside the loop body, and the if is a noop |
| 12:54 | edmondo1984 | so I think first of all that my bindings need to have the keys |
| 12:55 | justin_smith | edmondo1984: right now your second binding has the keys |
| 12:55 | edmondo1984 | oh yeah I corrected it already |
| 12:55 | edmondo1984 | I forgot that improvement |
| 12:56 | justin_smith | edmondo1984: this is much harder to do with loop/recur, and much easier to do with primitive recursion |
| 12:56 | justin_smith | (this particular assignment, that is) |
| 12:56 | edmondo1984 | right |
| 12:57 | edmondo1984 | what's the difference? |
| 12:57 | justin_smith | in order to do this with loop/recur you would need to pass an accumulator that represents each step of the work, and be able to move forward only using the data in the next call |
| 12:57 | justin_smith | with primitive recursion you can use the value of the recursive call after it returns |
| 12:57 | edmondo1984 | so I imagine loop recur result in a tail call optimization which prevents stackoverflow |
| 12:57 | justin_smith | right |
| 12:57 | justin_smith | that's exactly the point |
| 12:59 | edmondo1984 | so with primitive recursion |
| 13:00 | justin_smith | you'd end up with something like (assoc-in (get m k) (rest keys) v) |
| 13:00 | justin_smith | as your recursive call |
| 13:00 | justin_smith | and you'd be associng that back into m |
| 13:00 | edmondo1984 | yes |
| 13:00 | edmondo1984 | it's obvious |
| 13:00 | edmondo1984 | wait |
| 13:00 | justin_smith | but you can't do that with recur |
| 13:00 | clojurebot | Excuse me? |
| 13:00 | justin_smith | because of the assoc-back-in step |
| 13:02 | edmondo1984 | I didn't know the assoc-in has this syntax |
| 13:03 | justin_smith | what syntax? |
| 13:04 | justin_smith | it's a function, it has the same syntax all functions have |
| 13:08 | edmondo1984 | sorry that's fool of me |
| 13:08 | edmondo1984 | I was looking to the assoc-in in the documentation |
| 13:08 | edmondo1984 | can you explain me the first parameter? why get m k? |
| 13:09 | justin_smith | ,(get {:a {:b {}}} :a) |
| 13:09 | clojurebot | {:b {}} |
| 13:10 | justin_smith | edmondo1984: because if the keys had :a as their first item, the value under :a needs to be passed to the recursive call |
| 13:14 | edmondo1984 | sorry maybe my signature is wrong |
| 13:14 | justin_smith | no, it's fine |
| 13:14 | edmondo1984 | the first element in my signature is the map |
| 13:14 | edmondo1984 | so probably my call would be |
| 13:14 | justin_smith | maybe you are misunderstanding destructuring? |
| 13:14 | justin_smith | right, it should be! |
| 13:14 | edmondo1984 | (assoc-in v (rest keys) (get m k) ) |
| 13:15 | justin_smith | NO |
| 13:15 | justin_smith | err... |
| 13:15 | justin_smith | no |
| 13:15 | justin_smith | edmondo1984: why would the first arg be the value to assoc? |
| 13:16 | edmondo1984 | so v is the value to the assoc |
| 13:16 | justin_smith | right, v is the last arg |
| 13:16 | justin_smith | never the first |
| 13:16 | edmondo1984 | , (get {:a {: b {} } } :c) |
| 13:16 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: :> |
| 13:16 | edmondo1984 | , (get {:a {: b {} } :c) |
| 13:16 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: :> |
| 13:16 | justin_smith | : b is invalid |
| 13:16 | justin_smith | perhaps you mean :b |
| 13:16 | edmondo1984 | , (get {:a {:b {} } :c) |
| 13:16 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )> |
| 13:16 | edmondo1984 | , (get {:a {:b {} }} :c) |
| 13:16 | clojurebot | nil |
| 13:16 | edmondo1984 | right |
| 13:17 | edmondo1984 | I imagine assoc-in nil returns a map |
| 13:17 | justin_smith | ,(assoc nil :c :v) |
| 13:17 | clojurebot | {:c :v} |
| 13:17 | justin_smith | sure, it works |
| 13:17 | edmondo1984 | that's what I didn't know |
| 13:17 | justin_smith | the assoc fixes it up |
| 13:17 | justin_smith | edmondo1984: the other option: |
| 13:17 | edmondo1984 | what if returns a value? |
| 13:17 | justin_smith | ,(get {:b {}} :a {}) ; if assoc was not magic |
| 13:17 | clojurebot | {} |
| 13:17 | justin_smith | edmondo1984: then you pass the value of course |
| 13:18 | justin_smith | edmondo1984: because that value is the thing you are doing further associng into |
| 13:18 | justin_smith | if it is not associative, that's a bug and it's your caller's fault |
| 13:18 | edmondo1984 | , (assoc (get {:a 3} :a) "hello" "world") |
| 13:18 | clojurebot | #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.Associative"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.Associative"\n :at [clojure.lang.RT assoc "RT.java" 792]}]\n :trace\n [[clojure.lang.RT assoc "RT.java" 792]\n [clojure.core$assoc__4371 invokeStatic "core.clj" 191]\n [clojure.core$assoc__4371 invoke "core.clj" ... |
| 13:18 | justin_smith | edmondo1984: right, that's your caller's fault if they try that |
| 13:18 | edmondo1984 | got you |
| 13:20 | edmondo1984 | it works |
| 13:20 | edmondo1984 | brilliant |
| 13:21 | edmondo1984 | (if (empty ks) (assoc map k v)) (assoc-in (get map k) ks v) ) |
| 13:21 | justin_smith | that looks right, yeah |
| 13:22 | justin_smith | that's limited to ks being less than stack size, but that's probably reasonable and is likely a restriction in the original |
| 13:22 | justin_smith | edmondo1984: so as I was saying at the start, what about making it so that if the key is the integer 0 and the m is nil, making m a vector instead of map? |
| 13:22 | justin_smith | maybe a silly feature |
| 13:22 | justin_smith | ,(assoc [] 0 :a) |
| 13:22 | clojurebot | [:a] |
| 13:23 | edmondo1984 | how would I do that? no idea |
| 13:30 | edmondo1984 | justin can I ask you also a question about macros? |
| 13:30 | justin_smith | sure |
| 13:30 | william-s | join #haskell |
| 13:30 | edmondo1984 | I am trying to write a macro that when evaluated prints hello world, but the following doesn't work |
| 13:31 | edmondo1984 | , (read-string "'(clojure.string/join ["Hello ","World "])'") |
| 13:31 | clojurebot | #error {\n :cause "Unable to resolve symbol: Hello in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: Hello in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: Hello in this... |
| 13:31 | justin_smith | edmondo1984: what does ' do? |
| 13:31 | edmondo1984 | so this should ealuate to a list (clojure.string.join, ["Hello", "World"])) |
| 13:31 | justin_smith | edmondo1984: you are using ' wrong |
| 13:32 | edmondo1984 | , (clojure.string/join, ["Hello", "World"]) |
| 13:32 | clojurebot | "HelloWorld" |
| 13:32 | edmondo1984 | ahaha |
| 13:32 | edmondo1984 | actually the bot evaluates the list |
| 13:32 | justin_smith | right, function calls are just lists |
| 13:33 | edmondo1984 | so how do I use the ' |
| 13:33 | justin_smith | ,(read-string "(clojure.string/join ["hello" "world"])") |
| 13:33 | clojurebot | #error {\n :cause "Unable to resolve symbol: hello in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: hello in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: hello in this... |
| 13:33 | justin_smith | ergh! |
| 13:33 | justin_smith | ,(read-string "(clojure.string/join [\"hello\" \"world\"])") |
| 13:33 | clojurebot | (clojure.string/join ["hello" "world"]) |
| 13:33 | justin_smith | edmondo1984: in this case, you simply don't |
| 13:33 | edmondo1984 | well |
| 13:33 | justin_smith | ' is not a string operation |
| 13:33 | edmondo1984 | wait |
| 13:33 | justin_smith | ,'foo |
| 13:33 | clojurebot | foo |
| 13:33 | justin_smith | that's what ' does |
| 13:33 | edmondo1984 | I am reading in clojure from the impatient |
| 13:33 | edmondo1984 | sorry |
| 13:33 | edmondo1984 | clojure from the brave and the true |
| 13:34 | edmondo1984 | Use the list function, quoting, and read-string to create a list that, when evaluated, prints your first name and your favorite sci-fi movie. |
| 13:34 | justin_smith | clojure from the impatient and misleading |
| 13:34 | edmondo1984 | (Exercise number 1 |
| 13:34 | justin_smith | edmondo1984: OK, your version just uses read-string, so there's no place for quoting |
| 13:34 | justin_smith | and it also doesn't use the list function yet |
| 13:36 | edmondo1984 | so how would that be? |
| 13:37 | justin_smith | well, there are lots of ways to do macros. The key is that you need to end up with the right list of symbols, right? |
| 13:37 | edmondo1984 | yes |
| 13:38 | justin_smith | read-string easily turns "(list of symbols)" into one, ' can turn what would otherwise be a function call into a literal list, and list can be used to construct lists as well |
| 13:38 | justin_smith | ' can also be used to get a symbol instead of its value |
| 13:38 | justin_smith | ,(defmacro silly-double [x] (list '+ x x)) |
| 13:38 | clojurebot | #'sandbox/silly-double |
| 13:38 | justin_smith | ,(silly-double 4) |
| 13:38 | clojurebot | 8 |
| 13:39 | justin_smith | edmondo1984: the secret to all macros is that they return the list that you want to see compiled |
| 13:40 | justin_smith | after that it's all just tricks for constructing lists |
| 13:41 | edmondo1984 | , (read-string "'(clojure.string/join ["Hello ","World "])") |
| 13:41 | clojurebot | #error {\n :cause "Unable to resolve symbol: Hello in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: Hello in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: Hello in this... |
| 13:41 | edmondo1984 | , (read-string "'(clojure.string/join ['"Hello ",'"World "])") |
| 13:41 | clojurebot | #error {\n :cause "Unable to resolve symbol: Hello in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: Hello in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: Hello in this... |
| 13:42 | justin_smith | edmondo1984: you need to escape your " inside the string |
| 13:42 | edmondo1984 | , (read-string "'(clojure.string/join '["Hello ",'"World "])") |
| 13:42 | clojurebot | #error {\n :cause "Unable to resolve symbol: Hello in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: Hello in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: Hello in this... |
| 13:42 | justin_smith | ' does not help with that at all |
| 13:42 | justin_smith | edmondo1984: clojure uses the same string escaping rules as most languages. ' does not escape things in strings |
| 13:42 | justin_smith | ,"\"" |
| 13:42 | clojurebot | "\"" |
| 13:43 | justin_smith | ,(print "\"") |
| 13:43 | clojurebot | " |
| 13:43 | edmondo1984 | got it |
| 13:44 | edmondo1984 | , (read-string "'(clojure.string/join '[\"Hello \",'"World "])") |
| 13:44 | clojurebot | #error {\n :cause "Unable to resolve symbol: World in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: World in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: World in this... |
| 13:44 | edmondo1984 | , (read-string "'(clojure.string/join '[\"Hello \",\"World \"])") |
| 13:44 | clojurebot | (quote (clojure.string/join (quote ["Hello " "World "]))) |
| 13:44 | edmondo1984 | , (read-string "'(clojure.string/join [\"Hello \",\"World \"])") |
| 13:44 | clojurebot | (quote (clojure.string/join ["Hello " "World "])) |
| 13:44 | edmondo1984 | , (eval (read-string "'(clojure.string/join [\"Hello \",\"World \"])") ) |
| 13:44 | clojurebot | (clojure.string/join ["Hello " "World "]) |
| 13:44 | edmondo1984 | , (eval (eval (read-string "'(clojure.string/join [\"Hello \",\"World \"])") ) ) |
| 13:44 | clojurebot | "Hello World " |
| 13:44 | justin_smith | edmondo1984: read string already returns an unevaluated result |
| 13:44 | edmondo1984 | aha! |
| 13:45 | justin_smith | edmondo1984: since the result is already unevaluated, you don't need the quote or the second eval |
| 13:45 | edmondo1984 | , (eval (read-string "(clojure.string/join [\"Hello \",\"World \"])") ) |
| 13:45 | clojurebot | "Hello World " |
| 13:45 | edmondo1984 | excellent |
| 13:45 | justin_smith | also, in that case, you could replace clojure.string/join with apply str |
| 13:45 | edmondo1984 | what's apply str? |
| 13:45 | justin_smith | ,(apply str ["hello" "world"]) |
| 13:45 | clojurebot | "helloworld" |
| 13:46 | justin_smith | apply is a function, and str is a function |
| 13:46 | justin_smith | ,(apply + [1 2 3]) |
| 13:46 | clojurebot | 6 |
| 13:46 | justin_smith | ,(apply str [1 2 3]) |
| 13:46 | clojurebot | "123" |
| 13:46 | justin_smith | ,(str 1 2 3) |
| 13:46 | edmondo1984 | str makes a string of an array of element |
| 13:46 | clojurebot | "123" |
| 13:46 | edmondo1984 | why apply then? |
| 13:46 | edmondo1984 | ah it vectorize |
| 13:46 | edmondo1984 | the arguments |
| 13:46 | edmondo1984 | got it |
| 13:47 | justin_smith | edmondo1984: apply is for when arguments are in a collection |
| 13:47 | edmondo1984 | Create an infix function that takes a list like (1 + 3 * 4 - 5) and transforms it into the lists that Clojure needs in order to correctly evaluate the expression using operator precedence rules. |
| 13:49 | edmondo1984 | ok |
| 14:33 | benjyz1 | does anyone know about authentication in Ring? |
| 14:50 | Kamuela | do you find that Clojure is more like an enabler of domain specific languages than its own language properly |
| 14:51 | sineer | Hi, how do I (seq my-map) then drop all the keys and keep only the values ? |
| 14:52 | sineer | I want to count the # of keys in a nested map. |
| 14:54 | clintm | Is it that I'm doing something else wrong, or does the `(package/~@thing) not work by design in (defmacro x [thing & args] `(package/~@thing ...)) |
| 14:57 | TMA | ,(defn foo [] []) |
| 14:57 | clojurebot | #'sandbox/foo |
| 14:57 | TMA | ,'sandbox/~@bar |
| 14:57 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: sandbox/> |
| 14:57 | TMA | ,'`sandbox/~@bar |
| 14:57 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: sandbox/> |
| 14:58 | TMA | clintm: ~@thing splices the value of thing -- but it splices a form, not part of a token |
| 14:59 | TMA | ,'sandbox/quux |
| 14:59 | clojurebot | sandbox/quux |
| 15:00 | clintm | TMA - ok, that's probably for the best. Looking at what I was trying to do, I think I might have been trying to add too much magic from the beginning. |
| 15:01 | clintm | I was trying to turn (mypkg/make-request method ..) into (http.client/get or (http.client/post depending on the value of :param, but maybe that's not keeping with the clojure style to begin with. |
| 15:02 | TMA | clintm: it is certainly possible to achieve what would seem the logical meaning of package/~@thing, I just do not know how just now ;) |
| 15:02 | clintm | TMA - thanks for poking at it just the same :) |
| 15:03 | coventry | Anyone have trouble with spacemacs hanging when loading cljs files? |
| 15:04 | coventry | Oops, I'll ask in #clojurescript first. |
| 15:13 | max3 | why are names in closure always so long? spelled out all the way? |
| 15:17 | clintm | max3 - I assume so that their meaning isn't ambiguous. |
| 16:16 | kungi | max3: I find clojure names rather short which long ones do you mean? |
| 16:26 | notostraca | kungi: map is so much typing :) |
| 16:26 | notostraca | I guess sorted-map-by is one |
| 16:27 | notostraca | still wouldn't consider it an Apache Commons name |
| 16:33 | kungi | notostraca: I still prefer initWithTimeIntervalSinceReferenceDate from the Obejective C DateTime library |
| 16:34 | notostraca | aaaaagh |
| 16:34 | notostraca | PHP still wins worst naming conventions, since it doesn't have any |
| 16:35 | kungi | notostraca: And using \ as the namespace separator is ... meh |
| 16:35 | notostraca | agh |
| 16:35 | kungi | notostraca: And especially when you have to pass namespace names in strings it gets funny |
| 16:35 | notostraca | I can see why clojure uses \c for what Java calls 'c', since 'c is a different type than a char |
| 16:54 | justin_smith | yeah the lisps had a parallel evolution alongside the algol family, and clojure often goes for the lisp convention for the basic stuff |
| 19:46 | tolstoy | Hm. "lein repl -- arg" gives me "Unknown subcommand --'. Is there no setting CLI args for some tasks? |
| 19:47 | tolstoy | I guess only "run" supports it. Hm. |
| 20:02 | justin_smith | tolstoy: what args would you want to give the repl? |
| 20:02 | tolstoy | Pointer to a config file. ;) |
| 20:02 | justin_smith | what would a repl do with a config file? |
| 20:02 | tolstoy | CONFIG="secrets.edn" lein repl ;; is good enough. |
| 20:02 | justin_smith | ahh, OK |
| 20:02 | tolstoy | Yeah, the reloaded workflow thing. |
| 20:04 | tolstoy | In my user.clj, I have (app/make-system (app/load-config ...)) and sometimes I'm in a situation where there's no way "sensible defaults" can work. |
| 20:07 | tolstoy | Because lein run supports cli args, I overgeneralized. ;) |
| 20:22 | justin_smith | we're programmers, overgeneralizing is what we do |
| 20:26 | amalloy | you undergeneralized there, justin_smith. humans overgeneralize |
| 22:35 | tolstoy | Reminds me of how children, learning a language, make syntax mistakes that are the result of a too-regular application of the rules. |