2012-10-30
| 00:18 | jonasen | bbloom: about cljs-412, I think the issues I raised here https://groups.google.com/d/msg/clojure-dev/Ge5uEqlUcJk/_b9xEVrKha8J might be related? |
| 00:20 | bbloom | jonasen: yes. there are some interrelated issues |
| 00:20 | bbloom | jonasen: var resolution is a bit of a mess at the moment |
| 00:21 | bbloom | jonasen: there's a bunch of janky tricks like (resolve … (dissoc env :locals) …) |
| 00:21 | bbloom | jonasen: and then resolve-var vs resolve-existing-var |
| 00:22 | bbloom | jonasen: and then even more weirdness in that resolve-var can throw a warning, but is sometimes used to generate a different warning, so some odd cases do or don't warn |
| 00:22 | jonasen | bbloom: I fixed resolve-var/resolve-existing-var in my fork |
| 00:22 | jonasen | bbloom: at least I think I did :) |
| 00:23 | jonasen | bbloom: but that's several months ago... ClojureScript has moved on since then |
| 00:23 | bbloom | jonasen: heh, yeah and new complexity has crept in to the resolution code paths |
| 00:23 | jonasen | bbloom: yes |
| 00:24 | bbloom | jonasen: but it looks like there is some good ideas in your branches… could you try to break it up a bit? for example the js/ prefixes |
| 00:24 | bbloom | jonasen: that would be a great patch on it's own |
| 00:25 | jonasen | bbloom: If I remember correctly, the defprotocol (or was it deftype?) did some very strange things also.. duplicating the resolve-var |
| 00:25 | bbloom | jonasen: something is funky in there.... |
| 00:26 | jonasen | sorry, I mean the defprotocol macro dupicates the logic (badly) of resolve-var |
| 00:26 | bbloom | jonasen: a good goal would be to eliminate the *cljs-warn-on-undeclared* flag and to have it always be enabled |
| 00:26 | bbloom | jonasen: we should talk to dnolen and get his buy in on that |
| 00:27 | bbloom | jonasen: also, i'd like to see a more robust "warnings" system in general. as it is, warnings are a side effect. it would be nice to have them be represented in the AST or :env |
| 00:31 | bbloom | jonasen: regarding the "statics", i think that would be a small and welcome patch to replace them with declare/defs. I see no reason why cljs.core.List/Empty shouldn't just be empty-list |
| 00:31 | bbloom | and empty-vector |
| 00:31 | bbloom | same goes for the static methods |
| 00:31 | jonasen | bbloom: I totally agree with that |
| 00:32 | bbloom | jonasen: you're more likely to get your patches accepted if you distill them down to the essence & open separate patches for each. sadly that sometimes means one patch at a time & bugging dnolen :-) |
| 00:33 | jonasen | bbloom: The reason for cljs.core.PersistentVector/EMPTY is that it's a straight port from the java source |
| 00:33 | bbloom | jonasen: unsurprising :-) |
| 00:33 | jonasen | bbloom: but it's the wrong way to do it IMO |
| 00:33 | jonasen | bbloom: and it confuses the analyzer |
| 00:34 | bbloom | jonasen: yup. that seems like a reasonable starting place. could you work up a patch for just that? open a ticket |
| 00:35 | bbloom | jonasen: and if there is a way to get the analyzer to detect that situation: have it emit a deprecated warning! |
| 00:36 | jonasen | bbloom: I talked to dnolen about it (a few months ago) and he wasn't too keen on accepting such a patch |
| 00:36 | bbloom | jonasen: what did he say about it? |
| 00:36 | jonasen | bbloom: I |
| 00:36 | jonasen | bbloom: I'd have to search the IRC logs :) |
| 00:38 | bbloom | jonasen: http://clojure-log.n01se.net/date/2012-06-20.html |
| 00:39 | jonasen | bbloom: that's the one! |
| 00:39 | jonasen | bbloom: sorry, gotta run! |
| 00:40 | jonasen | bbloom: But I'd love to talk about this stuff more.. there is a lot of fun work with the analyzer still! |
| 00:40 | bbloom | jonasen: i don't really buy the "pollution" argument :-P there are LOTS of top levels that should be ^:private |
| 00:40 | bbloom | but aren't |
| 00:40 | bbloom | jonasen: but cljs doesn't really respect private yet… heh |
| 01:42 | tomoj | hmm https://www.refheap.com/paste/3e2aa9f9ae734ba5ac89aa71b clj->el would be nice |
| 03:38 | tomoj | why does pmap look at the number of available processors? |
| 03:39 | ivan | what else would it do? |
| 03:43 | tomoj | https://www.refheap.com/paste/bb37b0cf096f905d8ca995f9c |
| 03:43 | tomoj | er |
| 03:43 | tomoj | (+ 2 (.. Runtime getRuntime availableProcessors)) is 6, here |
| 03:44 | tomoj | yet it appears to use 32 threads at a time due to the chunkiness of range |
| 03:44 | tomoj | maybe that's just cus it's chunky.. |
| 03:44 | tomoj | ah yes |
| 03:44 | tomoj | with s/(range)/(iterate inc 0)/ the behavior is as expected |
| 03:56 | ebaxt | Hi, I'm trying to extract some information from an XML-file produced by SAP. I'm using clojure.data.zip.xml and trying to figure out how I can do something like the following xpath //ATNAM[text() = "Z_BRAND"]/../ATWRT. I've tried (xml-> l descendants :ATNAM "Z_BRAND" ancestors :ATWRT text) but I get nothing, could someone please point me in the right direction? |
| 04:19 | tomoj | datomic.api/touch is confusingly named |
| 04:20 | brainproxy | tomoj: how so? |
| 08:20 | clgv | ,(type {:a 1}) |
| 08:20 | clojurebot | clojure.lang.PersistentArrayMap |
| 08:20 | deg | Does metadata get passed along when, e.g. I create a new map by assoc'ing into an existing one? |
| 08:21 | clgv | deg: yes |
| 08:21 | deg | very cool! |
| 08:22 | clgv | &(let [m (with-meta {:a 1} {:type :some-map})] (type (assoc m :b 2))) |
| 08:22 | lazybot | ⇒ :some-map |
| 08:22 | chouser_log | one of the few ways lists differ from lazy seqs |
| 08:24 | clgv | chouser: you mean that lists keep metadata and lazy seqs do not, right? |
| 08:24 | chouser | well, each step of a lazy seq keeps its own metadata |
| 08:25 | clgv | yes. the implementation would have to pass on the metadata from the head if that was desired |
| 08:25 | chouser | &(let [L (with-meta '(a b) {:foo :bar})] (meta (next L))) |
| 08:25 | lazybot | ⇒ nil |
| 08:25 | chouser | ha! |
| 08:25 | chouser | &(let [L (with-meta '(a b) {:foo :bar})] (next L)) |
| 08:25 | lazybot | ⇒ (b) |
| 08:26 | chouser | oh, next. That returns a lazy seq |
| 08:26 | chouser | &(let [L (with-meta '(a b) {:foo :bar})] (pop L)) |
| 08:26 | lazybot | ⇒ (b) |
| 08:26 | chouser | &(let [L (with-meta '(a b) {:foo :bar})] (meta (pop L))) |
| 08:26 | lazybot | ⇒ nil |
| 08:26 | chouser | man, maybe I'm just plain wrong. |
| 08:26 | chouser | &(let [L (with-meta '(a b) {:foo :bar})] (type (pop L))) |
| 08:26 | lazybot | ⇒ clojure.lang.PersistentList |
| 08:27 | chouser | &(let [L (with-meta '(a b) {:foo :bar})] (meta (conj L 'c))) |
| 08:27 | lazybot | ⇒ {:foo :bar} |
| 08:27 | chouser | &(let [L (with-meta '(a b) {:foo :bar})] (meta (cons 'c L))) |
| 08:27 | lazybot | ⇒ nil |
| 08:27 | chouser | &(let [L (with-meta (seq '(a b)) {:foo :bar})] (meta (conj L 'c))) |
| 08:27 | lazybot | ⇒ {:foo :bar} |
| 08:28 | chouser | &(let [L (with-meta (map identity '(a b)) {:foo :bar})] (meta (conj L 'c))) |
| 08:28 | lazybot | ⇒ nil |
| 08:28 | chouser | ok, enough spam, sorry. |
| 08:29 | clgv | humm interesting though |
| 08:29 | deg | chouser: Ok, meta-question here... What is the lazybot that seems to be executing your code? Is that magic in some IRC client? |
| 08:30 | clgv | the question is if you really need to use metadata on lists in practice |
| 08:30 | clgv | deg: it's an irc bot |
| 08:30 | deg | Triggered by the "& in front of the expression?? |
| 08:30 | lazybot | deg: What are you, crazy? Of course not! |
| 08:30 | deg | &(+ 40 2) |
| 08:30 | lazybot | ⇒ 42 |
| 08:30 | deg | Aha |
| 08:31 | clgv | deg: but do try to not spam the channel much. it's good for examples to questions |
| 09:09 | brainproxy | tyring again to get slime-ritz / lein ritz working ... anyone successfully using it? |
| 09:26 | Cubic | Is there anything in core that would let me grab all fields from a class and expose them in my namespace? |
| 09:26 | Cubic | *all static final fields |
| 09:33 | clgv | Cubic: no, there is not. maybe there is some lib to do that |
| 09:33 | antares_ | Cubic: no |
| 09:34 | Cubic | Eh, well I guess it's too localized to belong there |
| 09:34 | clgv | &(loaded-libs) |
| 09:34 | lazybot | ⇒ #{bultitude.core cd-client.core cemerick.url cheshire.core cheshire.factory cheshire.generate cheshire.parse clj-config.core clj-http.client clj-http.cookies clj-http.core clj-http.util clj-time.core clj-time.format clojail.core clojail.jvm clojail.testers cloju... https://www.refheap.com/paste/6257 |
| 09:35 | Cubic | What's the difference between lazy bot and clojure bot? |
| 09:36 | clgv | Cubic: lazybot is more advanced ^^ |
| 09:36 | clgv | right lazybot??? |
| 09:36 | lazybot | clgv: How could that be wrong? |
| 09:37 | clgv | Cubic: the clojure.reflect namespace might help you to write a macro that imports those static final fields to local symbols. |
| 09:38 | Cubic | I already wrote that macro, I just wanted to know if there already was one out of pure interest. Though I did it with java.lang.reflect, I wonder if I could do it better with clojure? |
| 09:44 | Cubic | Just for reference, it's here: http://ideone.com/AHYm . It's my first nontrivial (for me) macro, so I probably did something wrong. It kinda does what I want it to, but you have to fully qualify the class names. Is there some way to avoid that? |
| 09:45 | clgv | "This page does not existPage not found." |
| 09:45 | Cubic | clgv: Sorry http://ideone.com/AHYmr8 |
| 09:47 | clgv | Cubic: you would need to import the class to avoid full qualified class name |
| 09:47 | clgv | but since the code is generated why bother? |
| 09:48 | clgv | or did you mean the class you give as param to the macro must be full qualified? |
| 09:48 | Cubic | No I mean, you have to use the maco like this: (export-static-final-fields java.lang.Integer) rather than (export-static-final-fields Integer) |
| 09:48 | clgv | ,(resolve 'Integer) |
| 09:48 | clojurebot | java.lang.Integer |
| 09:49 | Cubic | oh |
| 09:49 | clgv | there is the trick ^^ |
| 09:49 | Cubic | clgv: thanks I'll try that |
| 09:50 | clgv | but you could easily skip that. replace (get-static-final-fields (Class/forName (str class))) by (get-static-final-fields ~class) |
| 09:50 | clgv | then it should be resolved automatically |
| 09:52 | clgv | oh I overlooked your unquoting. well then it's not that easy^^ |
| 09:52 | clgv | s/overlooked/missed/ |
| 09:53 | clgv | (get-static-final-fields (resolve class)) should work |
| 10:12 | tolsen | maybe this is more of a java question, but why does (/ (Double. 4.0) (Double. 0.0)) give a divide-by-zero error while (/ 4.0 0.0) gives Infinity. I understand the latter is by IEEE standard, but why don't boxed Doubles do the same? |
| 10:14 | clgv | tolsen: my guess: the operation on the boxed doubles can check the operands whereas the native operation is just executed |
| 10:15 | tolsen | clgv: that makes sense |
| 10:26 | tolsen | hmm.. if I write the equivalent boxed double program in java, I get Infinity: http://pastebin.com/rTvhBBMf . Could this inconsistency be considered a bug in clojure? |
| 10:27 | nDuff | tolsen: Would you mind using a different pastebin (gist.github.com, refheap, ideone) in the future? pastebin.com is full of flashy, animated ads for anyone not running a blocker. |
| 10:27 | tolsen | nDuff: sure. sorry |
| 10:32 | TimMc | clgv: People who work in or with the advertising industry have to. |
| 10:32 | nDuff | clgv: My last several employers, present included, have made their money off of tasteful advertisements used to promote valuable services. Seeing someone using tasteless ads to promote subpar services still make it big by virtue of their domain name rubs me the wrong way. |
| 10:32 | clgv | TimMc: for real? I'd argue that my job performs suffers from it^^ |
| 10:33 | nDuff | clgv: Anyhow -- if I run adblock, and it prevents me from seeing a bug on a customer site, it's a problem. Been there, done that. |
| 10:33 | nDuff | s/to promote/to fund/ |
| 10:34 | mpan | &(type 4.0) |
| 10:34 | lazybot | ⇒ java.lang.Double |
| 10:34 | clgv | tolsen: you have to have a look at where the exception comes from: clojure.lang.Numbers.divide |
| 10:34 | mpan | (= 4.0 (Double. 4.0)) |
| 10:34 | clgv | tolsen: so it's definitely a clojure bug or feature ;) |
| 10:34 | goracio | hi there - suppose we have func with (let ) form let returns nil but if i need to return last expr in let how i can do that ? |
| 10:34 | mpan | &(= 4.0 (Double. 4.0)) |
| 10:34 | lazybot | ⇒ true |
| 10:35 | nDuff | goracio: let doesn't return nil |
| 10:35 | nDuff | goracio: it returns the last thing within it. |
| 10:35 | mpan | goracio: put what you want to return in the expr after all the bindings |
| 10:35 | goracio | hmm will check .. |
| 10:35 | mpan | like, you have let, then a bunch of pairs of names and bindings, and then the expr you want |
| 10:36 | mpan | and the overall let-expr will evaluate to the expr |
| 10:36 | mpan | for example, ##(let [a 1] 1.0) |
| 10:36 | lazybot | ⇒ 1.0 |
| 10:36 | _ulises | ##(let [a 1]) |
| 10:36 | lazybot | ⇒ nil |
| 10:36 | mpan | I mean, usually you use let because you want to use some of the newly-bound names in the expr, but that's a silly example that doesn't |
| 10:37 | _ulises | so let can result in nil |
| 10:37 | nDuff | _ulises: I don't think anyone said it _can't_ |
| 10:37 | nDuff | ...not with statements taken in context, anyhow. |
| 10:37 | _ulises | nDuff: 'course; I was just curious if it'd fail :) |
| 10:37 | _ulises | nDuff: *fail with an exception along the lines of "let needs a body" or something |
| 10:38 | _ulises | not being cheeky |
| 10:38 | mpan | _ulises: that is very interesting but I don't know what it would be used for |
| 10:39 | mpan | I recall someone mentioned that / is treated specially? |
| 10:40 | mpan | a while back I was wondering why / existed yet I wasn't allowed to define a / in the current ns |
| 10:43 | Bronsa | user=> (defn / []) |
| 10:43 | Bronsa | WARNING: / already refers to: #'clojure.core// in namespace: user, being replaced by: #'user// |
| 10:43 | Bronsa | #'user// |
| 10:43 | Bronsa | user=> (in-ns 'a) |
| 10:43 | Bronsa | #<Namespace a> |
| 10:43 | Bronsa | a=> user// |
| 10:43 | Bronsa | RuntimeException Invalid token: user// clojure.lang.Util.runtimeException (Util.java:170) |
| 10:44 | jkkramer | ,((fn [& ∕] (let [[/ ∕] ∕] (#'/ / ∕))) 12 3) |
| 10:44 | clojurebot | 4 |
| 10:46 | mpan | I'm not sure what to make of that |
| 10:46 | mpan | is this generally not advisable to do, then> |
| 10:46 | mpan | ? |
| 10:47 | Bronsa | fwiw it's just a one-line patch to LispReader.java to make that work |
| 10:47 | goracio | ##(let [a 1] 1.0) |
| 10:48 | lazybot | ⇒ 1.0 |
| 10:48 | goracio | is this form valid only here :) ? ##(let [a 1] 1.0) |
| 10:48 | lazybot | ⇒ 1.0 |
| 10:48 | mpan | the use of ## is a special instruction to the bot |
| 10:48 | goracio | ah i see now :) |
| 10:49 | mpan | it says, read-eval this, regardless of its position in the line |
| 10:49 | mpan | whereas # must be at the start |
| 10:49 | mpan | the rest of that is a standard s-expr |
| 10:50 | mpan | btw perhaps I picked bad example values |
| 10:50 | mpan | that could have just as easily been ##(let [a 1] "HELLO WORLD") |
| 10:50 | lazybot | ⇒ "HELLO WORLD" |
| 10:50 | mpan | or ##(let [a 1] (+ a 1)) |
| 10:50 | lazybot | ⇒ 2 |
| 10:50 | mpan | and usually, you'd want to do something with the bindings, as such ^ |
| 11:39 | sunkencityryleh | I'm wondering how I can do an inject in clojure. I'd like to pick out an element from an array of maps and create a new map with that element as the key and the map as value. |
| 11:40 | sunkencityryleh | In ruby i'd use each_with_object or inject if the other method is not available |
| 11:40 | sunkencityryleh | (sorry if this is too long) [{id:1,name:'foo'}, {id:2,name:'bar'}].each_with_object({}) { |a,o| o[a[:id]] = a } results in: {1=>{:id=>1, :name=>"foo"}, 2=>{:id=>2, :name=>"bar"}} |
| 11:41 | sunkencityryleh | now I do it like this in clojure (apply hash-map (flatten (map get-keypair acts)))) |
| 11:41 | augustl | sunkencityryleh: inject === reduce basically |
| 11:42 | sunkencityryleh | augustl: ok I'll take a look at reduce |
| 11:46 | augustl | sunkencityryleh: (reduce (fn [curr prev] (assoc curr (:id prev) prev) ) {} [{:id 1 :name "foo"}, {:id 2 :name "bar"}]) |
| 11:47 | augustl | err a bit weird naming but yeah |
| 11:48 | technomancy | is each_with_object new? |
| 11:48 | technomancy | looks kind of like a gross non-functional reduce |
| 11:49 | technomancy | if you're going to bash around something like that why not just close over it? |
| 11:49 | technomancy | oh ruby... |
| 11:51 | augustl | technomancy: haha |
| 11:51 | augustl | as I suspected, it is added by Rails |
| 11:51 | augustl | so it's not in Ruby |
| 11:52 | augustl | Rails brings out the best of Ruby, doesn't it |
| 11:53 | sunkencityryleh | it's from rails, it's inject but you don't have to do ;memo in the end :) |
| 11:54 | technomancy | yeah but what's the point of taking it as a block arg instead of using a closure? |
| 11:55 | sunkencityryleh | hm, it's a one-liner for fold-l ? |
| 12:00 | sunkencityryleh | I've been dabbling with compojure, one thing I don't get is how middleware is wrapped. doesn't (-> foo bar baz) expand to (bas (bar foo)), but it seems like the middleware is expanded run the other way. i.e. middleware that's last in the (-> expression is run first) |
| 12:01 | augustl | sunkencityryleh: correct |
| 12:04 | sunkencityryleh | augustl: it seems that there's something funky going on behind the scene there! |
| 12:10 | TimMc | foo is the request? |
| 12:12 | sunkencityryleh | TimMc: another example: (def app (-> (handler/api app-routes) debug-session1 wrap-session debug-session2) debug-session2 is the middleware that gets run first |
| 12:12 | TimMc | gets run first == outermost? |
| 12:12 | sunkencityryleh | yes, the last one |
| 12:12 | sunkencityryleh | wouldn't -> wrap the other way? |
| 12:13 | TimMc | No, this makes sense to me. |
| 12:14 | TimMc | If foo were the request, you'd be right. |
| 12:14 | sunkencityryleh | hm |
| 12:15 | sunkencityryleh | '(-> '(1 2 3 4) rest rest rest first) |
| 12:15 | hiredman | sunkencityryleh: if you wrap a box in red, then green, then white paper, when you go to open it what order do you encounter the papers in? |
| 12:15 | sunkencityryleh | 4 |
| 12:15 | sunkencityryleh | (first (clojure.core/-> (clojure.core/-> (clojure.core/-> (quote (1 2 3 4)) rest) rest) rest)) |
| 12:15 | TimMc | It's not about ->. |
| 12:15 | sunkencityryleh | ok so what am I missing? |
| 12:15 | sunkencityryleh | I |
| 12:15 | sunkencityryleh | m completely lost :) |
| 12:15 | TimMc | sunkencityryleh: If each of those middleware calls is returning a fn, then the last one in the chain is returning the "outermost" fn, which then gets the reqeust object first. |
| 12:16 | sunkencityryleh | TimMc: ah, thanks |
| 12:17 | TimMc | In hiredman's analogy, each of those fns is a piece of wrapping paper. |
| 12:17 | sunkencityryleh | I need to meditate on this |
| 12:19 | sunkencityryleh | hiredman: Ok, now I see it (almost) |
| 12:22 | sunkencityryleh | when I macroexpand an expression with -> why is there still clojure.core/-> left |
| 12:22 | sunkencityryleh | in the expression |
| 12:22 | hiredman | because macroexpand is not recursive |
| 12:23 | sunkencityryleh | hiredman: ok tnx |
| 12:26 | TimMc | sunkencityryleh: ##(let [incw (fn [f] #(f (inc %))), firstw (fn [f] #(f (first %))), stack (-> identity incw firstw)] (stack [0 2 4 6])) |
| 12:26 | lazybot | ⇒ 1 |
| 12:27 | TimMc | Here, identity stands in for the core of your app. |
| 12:29 | TimMc | Here's a version that does the wrapping in the opposite order: |
| 12:29 | sunkencityryleh | TimMc: tnx |
| 12:29 | TimMc | &(let [incw (fn [f] #(inc (f %))), firstw (fn [f] #(first (f %))), stack (-> identity firstw incw)] (stack [0 2 4 6])) |
| 12:29 | lazybot | ⇒ 1 |
| 12:30 | bhenry | how can i take everything but the last three items in a vector? |
| 12:31 | bhenry | reverse drop 3? |
| 12:31 | TimMc | butlast? |
| 12:31 | bhenry | butlast only takes the coll |
| 12:31 | hiredman | ,(doc drop-last) |
| 12:31 | clojurebot | "([s] [n s]); Return a lazy sequence of all but the last n (default 1) items in coll" |
| 12:31 | bhenry | boom. thanks hiredman |
| 12:31 | TimMc | Ah, right. |
| 12:31 | TimMc | ,(apropos 'last) |
| 12:31 | clojurebot | (last butlast drop-last take-last) |
| 12:31 | hiredman | checkout the impl of drop-last, it is pretty cute |
| 12:32 | hiredman | ~def drop-last |
| 12:32 | TimMc | Oh, is that the one that uses drop and ternary map? |
| 12:32 | hiredman | dunno if that works |
| 12:32 | hiredman | TimMc: yeah |
| 12:32 | TimMc | Very cute. |
| 12:33 | technomancy | oh that is clever |
| 12:41 | goracio | can we save 2 values in session ( memory store) ? something like this (session/put! :key val key2 val2) |
| 12:44 | thorbjornDX | haha, drop-last :P |
| 13:01 | jcromartie | sets are functions |
| 13:01 | jcromartie | but *functions are sets*! |
| 13:02 | jcromartie | or close enough |
| 13:02 | _ulises | yes! \o/ |
| 13:04 | bhenry | can things inside of a future start other futures? |
| 13:05 | ohpauleez | bhenry: Yes |
| 13:05 | ohpauleez | they pull from the same pool though |
| 13:19 | technomancy | lynaghk: mind if I pm? |
| 13:25 | dnolen | bbloom: ping |
| 13:25 | bbloom | dnolen: what's up? |
| 13:26 | dnolen | bbloom: any thoughts on CLJS-411, I keep coming up with more cases that are broken. Not feeling so hot about the CLJS-369 changes. |
| 13:26 | dnolen | bbloom: there are many more broken cases that have nothing to w/ the top level. |
| 13:27 | dnolen | bbloom: part of the issue is that CLJS-369 assumes that lexical scope exists in JS, it does not |
| 13:27 | dnolen | bbloom: even if not at the top level if you have multiple lets in the same fn scope and say you conj some fns into atom, it's going to be broken |
| 13:27 | technomancy | (require '[clojure.dev.jira :as jira]) (add-watch (jira/issue 369) (partial email bbloom)) |
| 13:28 | dnolen | bbloom: nested top level dos w/ lets are broken, very bad for macros |
| 13:28 | bbloom | dnolen: bah. sorry about this. |
| 13:28 | dnolen | bbloom: I'm kicking myself for not seeing this issue much earlier. |
| 13:29 | bbloom | dnolen: give me a few minutes to investigate/think |
| 13:29 | dnolen | bbloom: k |
| 13:31 | dnolen | bbloom: an ideal fix would be perhaps somehow always gem-syming let bindings only in compiler.clj - thus punting the issue to backends - some languages will have sane scoping, some won't. |
| 13:31 | bbloom | dnolen: yup. my primary motivation was to allow analysis to happen BEFORE introducing insane semantics :-) |
| 13:32 | bbloom | dnolen: by that i mean downstream analysis, like my CPS transform |
| 13:33 | dnolen | bbloom: yes, I understand the utility of the fix, but we absolute need to gem-sym bindings for JS unless we introduce significantly more complicated backend machinery - I'd like to have a fix by Friday since this is a pretty nasty issue for all users of CLJS |
| 13:33 | bbloom | dnolen: ok. are you going to be around irc for a little while? i've got a couple random things to take care of, but i'll find some time in the next few hours to dig into this |
| 13:34 | dnolen | bbloom: I'll be around, thx much. |
| 13:59 | uvtc | Why doesn't the clojars page for quil https://clojars.org/quil display its project url? Quil's project.clj file has :url set, and the version is 1.6.0. |
| 13:59 | uvtc | And 1.6.0 is what's displayed at clojars. |
| 14:02 | uvtc | Sorry, perhaps I should ask that on a different channel. |
| 14:03 | TimMc | Was :url added after the last release? |
| 14:04 | TimMc | Check the project.clj in the JAR artifact from clojars. |
| 14:04 | uvtc | Oh, right, TimMc. Good eye dear. |
| 14:08 | bbloom | "One's sentiment toward JavaScript flips between elegance and disgust without transiting intermediate states." -- http://matt.might.net/articles/javascript-warts/ |
| 14:08 | bbloom | truer word have never been spoken :-P |
| 14:09 | Frozenlock | I'm storing a java class in a `let' and using it further in my code, but I get an error. Is there something that prevents me from doing it? Some kind of special form behavior? (let [my-class some-class] (new my-class some-argument)) |
| 14:10 | bbloom | dnolen: does Herwig's patch fix the issue? http://dev.clojure.org/jira/secure/attachment/11606/0002-CLJS-401-gensym-let-names-in-statement-context.patch |
| 14:11 | bbloom | dnolen: maybe go with that and back out aea65a693 ? |
| 14:12 | TimMc | Frozenlock: I think new takes a literal symbol. |
| 14:12 | TimMc | &(let [foo StringBuffer] (new foo)) |
| 14:12 | lazybot | java.lang.IllegalArgumentException: Unable to resolve classname: foo |
| 14:13 | bbloom | dnolen: hacky gensyms seems like the only quick fix. anything more elegant would require deeper JS analysis |
| 14:13 | bbloom | "el-cheapo gensyming" as he describes it, heh |
| 14:13 | Frozenlock | TimMc: Is there a workaround? I don't know in advance what will be the class... |
| 14:14 | TimMc | j.l.Class has some appropriate constructor methods. |
| 14:14 | Frozenlock | Thanks! |
| 14:14 | TimMc | &(let [foo StringBuffer] (.newInstance foo)) |
| 14:14 | lazybot | ⇒ #<StringBuffer > |
| 14:15 | Frozenlock | Magic :) |
| 14:15 | TimMc | Frozenlock: And I would bet that there are some nice helper methods in the Clojure compiler that you could use for non-nullary constructors. |
| 14:17 | dnolen | bbloom: yeah that patch actually look ok |
| 14:18 | tgoossens | Hi |
| 14:18 | tgoossens | I'm here to epxress my frustrations |
| 14:18 | dnolen | bbloom: thanks for giving it a look, i'll give it a shot and add some more tests cases later. |
| 14:18 | tgoossens | At university I have to do (obligated) teamwork in java |
| 14:19 | bbloom | dnolen: then let's go with that so we un-break everybody. revert aea65a693 and apply that patch. |
| 14:19 | tgoossens | And |
| 14:19 | uvtc | hi tgoossens . |
| 14:19 | tgoossens | the rest of my team just doesn't get it. How to write simple code |
| 14:19 | tgoossens | apparently they like |
| 14:19 | tgoossens | instanceof |
| 14:19 | tgoossens | and switch case |
| 14:19 | bbloom | dnolen: that also means that the :shadow keys aren't necessary in the analyze phase, but we can address that later |
| 14:19 | tgoossens | so now. We have monstercode |
| 14:19 | tgoossens | that 1) doesn't work |
| 14:20 | tgoossens | 2) is hell to debug |
| 14:20 | tgoossens | But I can't seem to convince them |
| 14:20 | tgoossens | it seems like "if its not complicated it is not smart / good" |
| 14:20 | uvtc | tgoossens: Do you have a specific question about Clojure? |
| 14:20 | dnolen | bbloom: I think we still need that for namespaces right? |
| 14:21 | technomancy | tgoossens: that's Java 101. anything simple is viewed with suspicion. |
| 14:21 | bbloom | dnolen: oh ugh yeah, duh, right |
| 14:21 | tgoossens | lol |
| 14:21 | tgoossens | No. Just implicitly expressing that I like the way things go in clojure :D |
| 14:22 | uvtc | Aye, she's a fine ship she is. |
| 14:22 | mpan | tgoossens: not inherently wrong to use instanceof or switch, though I'm sure -- like most tools -- they can be misused |
| 14:23 | mpan | and if your model for hierarchical relationships is expressed using inheritance, well you've got to put distinguishing logic somewhere, whether as overloaded methods, externally in some control flow block, etc |
| 14:25 | Frozenlock | TimMc: You example works fine, but for my class I get an error saying that it doesn't have the .newInstance method o_O |
| 14:25 | TimMc | Then you don't have a Class. |
| 14:26 | TimMc | or you're trying to give it more args |
| 14:26 | mpan | just curious what you get if you ask it for its type |
| 14:26 | bbloom | dnolen: when you're satisfied that this issue is resolved, i'd like to discuss my experiences working with the compiler with regard to :env, state, codeine, etc. i think i understand the issues better now & this lets issue helped my understanding a bit too |
| 14:27 | bbloom | s/codeine/codegen/ |
| 14:27 | tgoossens | mpan: Please don't tell me this is good: http://pastebin.com/edNSBXFX |
| 14:28 | dnolen | bbloom: sure, I'm pretty sure Herwig's patch will fix the issue. It just pushes gensym into the compiler and out of analysis. |
| 14:28 | bbloom | dnolen: yup, let me know how it goes |
| 14:28 | dnolen | bbloom: rather you patch removed it, and Herwig's patch put it back in the backend. |
| 14:28 | mpenet | Raynes: can lazybot run on password protected servers? (I would like to run it on a grove.io server) |
| 14:28 | mpan | tgoossens: meh, not particularly emotional about it one way or the other |
| 14:28 | tgoossens | hehe |
| 14:28 | mpenet | Raynes: it seems it is not the case after a quick look, but I prefer to ask before diving into the source |
| 14:28 | dnolen | bbloom: if you're referring to some of the thoughts you were working out earlier go for it. |
| 14:29 | bbloom | dnolen: that's what i get for trying to be clever :-) |
| 14:29 | tgoossens | but it's out of context of course |
| 14:29 | mpan | you could perhaps convince them to refactor it to be more OO if you shift a lot of the responsibility on the individual objects themselves |
| 14:29 | tgoossens | problem: time damnit |
| 14:29 | bbloom | dnolen: so i ran into an issue with :env in a few odd cases. for example, it's perfectly valid to have let statements that don't have a body (let [x 1]) |
| 14:30 | bbloom | dnolen: in such a case, there are no body statements to get the :env from |
| 14:30 | bbloom | dnolen: if you need the :env in which x is a local, you don't have an easy way to get that |
| 14:30 | mpan | tgoossens: I figure, just for me personally, my past employment has drastically relaxed my standards for the sort of code which will offend me personally, but I suppose that's getting off-topic at this point |
| 14:30 | TimMc | switch statements are always trouble. |
| 14:30 | bbloom | dnolen: one possible solution would be to say that there's really an implicit do there: (let [x 1] (do)) |
| 14:30 | TimMc | Sometimes there's not much you can do, though. |
| 14:31 | bbloom | dnolen: however, a similar situation applies to def |
| 14:31 | tgoossens | oh |
| 14:31 | tgoossens | don't forget |
| 14:31 | tgoossens | the code isn't working :p |
| 14:31 | mpan | well, that's a separate issue which you all must work hard to resolve |
| 14:31 | bbloom | dnolen: so my thought is that there really needs to be a before and after :env |
| 14:31 | TimMc | If Java had syntactic abstraction, you could write "xcase", which would be like "case" with an implicit break at the end of each clause. |
| 14:31 | mpan | it will occur regardless of your choice of language or style |
| 14:32 | bbloom | dnolen: @namespaces is really just the after-env |
| 14:32 | bbloom | dnolen: does that make sense so far? |
| 14:33 | bbloom | dnolen: i need to step out for a minute, so i'll just say the last bit and hopefully that makes sense without clarification |
| 14:34 | bbloom | dnolen: if the codegen phase emitted AST nodes instead of having the side effect of printing code to *out*, then we could have a similar thing for JS |
| 14:34 | bbloom | dnolen: emitting a var could have an after-env with a binding in it |
| 14:35 | bbloom | dnolen: which would have made this whole issue trivial: we could have looked at the js-env side-by-side with the cljs-env to compute the shadowed symbol |
| 14:36 | dnolen | bbloom: yeah not completely following. you should probably write this up somewhere. |
| 14:37 | dnolen | bbloom: also probably needs a more interesting use case then gen-syming let bindings for me to see the point. |
| 14:37 | bbloom | dnolen: eh, ok. i'll put that on the list of things to write up when i release my CPS transform (assuming i ever get it working robustly enough to announce it) |
| 14:37 | dnolen | then avoiding gen-syming I mean. |
| 14:38 | hiredman | emitting strings is pretty meh |
| 14:38 | bbloom | hiredman: yeah, i looked into emitting GClosure AST nodes & it looks promising, but i've got too many random projects going on at once already :-P |
| 14:39 | bbloom | gotta run |
| 14:41 | hiredman | emitting gclosure ast nodes directly is not an alternative that occured to me, very interesting |
| 14:43 | tufflax | I'm doing (apply conj a-coll a-possibly-empty-list) but when the list is empty it's an error, but I simply don't want to add anything. Is there a nice way to work around that problem? |
| 14:45 | ro_st | does (partial) evaluate its args? |
| 14:45 | TimMc | It's a fn, so yes, the args are evaluated. |
| 14:45 | jonasac | is there are reasonable way to tame the stacktraces from running lein test, everytime a test fails my screen fills up |
| 14:46 | ro_st | ok so if i want to cache a result locally, i needn't do so separately if i'm using it in a call to partial |
| 14:47 | technomancy | jonasac: yeah, but it involves convincing chouser to release longbottom |
| 14:48 | mpenet | Raynes: nevermind, I managed to get it working |
| 14:48 | jonasac | technomancy: btw thanks for leiningen, new to clojure, was having a really rough time with everything until i met leiningen last night :) |
| 14:49 | technomancy | heh; cool =) |
| 14:49 | zerokarmaleft | tufflax: i think you want reduce instead |
| 14:50 | tufflax | zerokarmaleft yeah that works thanks |
| 14:51 | dnolen | hiredman: it could be interesting, tho it's not at all clear if AST rep is something you can expect to be stable. |
| 14:51 | technomancy | wow, sometimes you just don't realize how good you have it: https://mobile.twitter.com/jreichhold/status/263338857397907456?p=v |
| 14:52 | AdmiralBumbleBee | java programmers have it good |
| 14:52 | egghead | hey Raynes, I'm playing with conch for a little process manager i'm working on, is there any way to get it to find things in the project/resources? (sh/proc "interpreter" "somefile.script") searches project/somefile.script instead of project/resources/somefile.script |
| 14:52 | technomancy | job security? |
| 14:52 | AdmiralBumbleBee | they're not using C, that's a pretty massive thing to be happy about |
| 14:54 | ro_st | technomancy: find-file-in-project is now precisely what i need. thanks for your help yesterday |
| 14:54 | ro_st | and you, mpenet |
| 14:54 | Frozenlock | TimMc: http://stackoverflow.com/questions/9167457/in-clojure-how-to-use-a-java-class-dynamically?lq=1 The constructor fn solved all my problems :) |
| 14:54 | hiredman | dnolen: yeah going to gclosure's ast had not occured to me, I was thinking more a long the lines of delaying generating strings as long as possible, generate some clojurescript defined js ast that can be further manipulated before being turned in to strings (or the gclosure ast) |
| 14:54 | Frozenlock | /s/constructor/construct |
| 14:55 | ro_st | AdmiralBumbleBee: see if you can find a way to use juxt to improve your mood. i'm pretty sure that's one of the things you can use it for. |
| 14:55 | technomancy | I don't use it very often |
| 14:55 | ivan | surely it's not a leak if you lose your references to the map? |
| 14:56 | uvtc | juxt? |
| 14:56 | clojurebot | juxt is a little hard to grok but it's the best thing ever |
| 14:56 | ro_st | i still don't understand juxt |
| 14:57 | ro_st | macros are easier |
| 14:57 | normanrichards | anyone know how to invoke a db function using clojureql? for example, something to the effect of: (conj! events {:name "blah" :occured_at "now()"}) |
| 14:57 | bbloom | ,((juxt inc dec) 5) |
| 14:57 | clojurebot | [6 4] |
| 14:57 | bbloom | that's the best example i've come up with for juxt |
| 14:58 | ro_st | ok, so return a seq of the results of each successive fn to the args |
| 14:58 | uvtc | The example that the just docs include makes sense to me: ((juxt a b c) x) => [(a x) (b x) (c x)] |
| 14:58 | ro_st | yeah |
| 14:58 | technomancy | ro_st: no, return a function that calculates such |
| 14:59 | ro_st | oh, yes |
| 14:59 | technomancy | ,(map (juxt inc dec) (range 5)) |
| 14:59 | clojurebot | ([1 -1] [2 0] [3 1] [4 2] [5 3]) |
| 14:59 | tomoj | &((juxt min max) 1 2 3) |
| 14:59 | lazybot | ⇒ [1 3] |
| 14:59 | bbloom | uvtc: that makes sense to me too, but not everybody has mastered what i'd call "haskell signature reading skills" |
| 14:59 | ro_st | where have you found good use for it, technomancy? |
| 15:00 | ro_st | wait, i can use juxt to turn (map fn1 (map fn2 coll)) into (map (juxt fn1 fn2) coll) right? |
| 15:00 | technomancy | it works great when paired with destructuring |
| 15:00 | technomancy | you can turn 3 lines in a let into one |
| 15:00 | technomancy | ro_st: no, that's comp |
| 15:00 | ro_st | oh. right |
| 15:01 | TimMc | francis-: clojure.lang.Reflector/invokeConstructor looks good. |
| 15:02 | TimMc | francis-: Sorry, that was meant for Frozenlock. |
| 15:02 | dnolen | hiredman: it could be interesting, but it just sounds like writing a lot more code and adding another step since we still probably want to go through Closure. hard to see a big benefit. |
| 15:03 | bbloom | dnolen: i pseudo-code-ported a few of the uglier emit methods to pure functions & they saw substantial reductions in size. |
| 15:03 | bbloom | dnolen: it also lets you reuse more logic b/c you are more free to re-arrange the order of evaluation without fear of side effects. that means even more savings when applied across multiple emit methods |
| 15:03 | bbloom | dnolen: clearly very low priority, but IMO worth exploring |
| 15:06 | hiredman | it is kind of amusing that compilers are often pointed to as an example of functional programming, but clojurescripts compiler is not a function |
| 15:06 | dnolen | bbloom: yeah, side effect aspect of emitting strings sucks. tying in to closure AST might be worth it if the win is big enough - tho I suspect it will means we won't be able to track closure compiler so nimbly. |
| 15:08 | bbloom | dnolen: there is a helper method interface, IIRC called IR.java, which seems to be reasonably stable, but i really didn't dig in too much |
| 15:08 | dnolen | bbloom: http://code.google.com/p/closure-compiler/source/list?path=/trunk/src/com/google/javascript/rhino/Node.java&start=2249, this is the relevant file no? |
| 15:09 | bbloom | dnolen: one of them |
| 15:09 | bbloom | dnolen: the Node class has lots of pseudo nodes for optimizations, etc |
| 15:09 | bbloom | dnolen: see also http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/rhino/IR.java?spec=svn1996&r=1996 |
| 15:10 | dnolen | bbloom: so that file the only one we would need to deal w/? |
| 15:11 | bbloom | dnolen: maybe? i looked at this a long while ago |
| 15:11 | bbloom | dnolen: this is also why i asked about the js* form |
| 15:12 | bbloom | dnolen: b/c there is no obvious way to do the js* form in a glosure AST world |
| 15:12 | bbloom | dnolen: however, i did come up with some hack to emit a js fragment, so that you could incrementally move towards a functional approach (i.e. one emit method at a time) |
| 15:14 | dnolen | bbloom: I agree this looks intriguing. But probably a lot of potholes. I'm curious if this would make compile times w/o optimizations slower / faster. |
| 15:14 | bbloom | dnolen: my guess? initially, slower, but ultimately faster |
| 15:14 | bbloom | dnolen: slower since you go from cljs ast -> js ast -> string -> js ast -> string |
| 15:15 | bbloom | dnolen: but once *all* of the emitter is converted, you can call the compiler directly |
| 15:15 | bbloom | dnolen: you won't need to run the js parser |
| 15:15 | dnolen | bbloom: the slowest thing about closure isn't the parser - it's advanced optimization. it dominates everything. |
| 15:16 | bbloom | dnolen: i believe that :-) |
| 15:16 | bbloom | dnolen: we could probably also get free source maps |
| 15:16 | bbloom | dnolen: i believe the gclosure Node class is semi-mutable |
| 15:16 | bbloom | dnolen: with the only mutable bits being things like line/column metadata |
| 15:16 | dnolen | so in the worst case everything everything else gets slower, advanced optimization roughly the same. |
| 15:17 | dnolen | bbloom: yes free source maps would be nice. |
| 15:17 | bbloom | we could pretty easily wrap the static public methods if IR.java to call .setLine on each node |
| 15:18 | bbloom | dnolen: i don't think worst case is slower. i think slower is just an intermediate step |
| 15:18 | bbloom | once you're a 100% AST step, you cut out the disk completely |
| 15:18 | bbloom | and there is no to string or from string intermediate step |
| 15:18 | bbloom | which, intuitively, has to be faster? right :-P |
| 15:19 | bbloom | but like you said, advanced optimizations remain the bottleneck |
| 15:19 | bbloom | so the primary advantages would be functional purity, code size reduction, ease of reasoning, and free-ish source maps |
| 15:19 | bbloom | clear disadvantage would be the lose of js* |
| 15:19 | bbloom | however, it could be replaced by js** which returns AST nodes ;-) |
| 15:20 | goracio | my compilation time of cljs file with 200 loc takes 20-25 sec usually with simple or whitespaced optm |
| 15:20 | dnolen | bbloom: right |
| 15:20 | tomoj | goracio: with a fresh jvm? |
| 15:20 | bbloom | i have a branch somewhere that i attempted to eliminate js* |
| 15:20 | bbloom | let me look... |
| 15:20 | goracio | but cljbuild auto take 4-5 sec |
| 15:20 | tomoj | ah right |
| 15:20 | dnolen | goracio: you mean 25000+200 lines of JS |
| 15:21 | goracio | dnolen: i guess so don't understand why 25k needed |
| 15:21 | bbloom | dnolen: see https://github.com/brandonbloom/clojurescript/commits/no-js-form |
| 15:21 | aaelony | n |
| 15:22 | hiredman | I have a 50 line cljs file that takes 17-20 seconds in andvanced mode |
| 15:22 | goracio | tomoj: fresh jvm ? 7 version i use |
| 15:22 | dnolen | goracio: because you 200 lines of CLJS wouldn't do anything w/ the other 6500 lines of cljs.core |
| 15:22 | dnolen | w/o |
| 15:22 | bbloom | dnolen: it would also be nice to be able to memoize the output of a compilation unit |
| 15:22 | bbloom | dnolen: so in the case of core, we could keep the AST in memory :-) |
| 15:23 | dnolen | bbloom: that's true |
| 15:23 | bbloom | see those last 3 commits on that branch |
| 15:24 | goracio | dnolen: 6500 ok and what for others ? _)) |
| 15:24 | dnolen | goracio: sorry, not following. others? |
| 15:24 | TimMc | dnolen: 6500 < 25000 |
| 15:25 | TimMc | 15:20 < dnolen> goracio: you mean 25000+200 lines of JS |
| 15:25 | goracio | dnolen: 25k lines minus 6500 18,5k left |
| 15:25 | dnolen | goracio: sorry just mistyped. |
| 15:25 | bbloom | dnolen: step one is minimizing usage of js* |
| 15:26 | dnolen | goracio: every CLJS app needs to load the other >6500 lines of cljs.core. w/o any optimization this will become 25000 lines of JS |
| 15:26 | bbloom | dnolen: which is already a goal :-) |
| 15:26 | TimMc | goracio: It's just like how your Clojure program won't run without the Clojure JAR file being included. |
| 15:26 | bbloom | although js* to js/ isn't much of a win, heh |
| 15:26 | goracio | actually it's google closure code if we look at it in browser |
| 15:26 | dnolen | bbloom: yeah, I think there's like 5 places in core, and the only other place we use it for inlining low level ops. |
| 15:26 | bbloom | dnolen: yup, i think we reaaaallly need better inlining support in cljs |
| 15:26 | TimMc | Except with CLJS it can't be linked. |
| 15:27 | bbloom | dnolen: we do a lot of inlining hacker via macros, where true inlining could help |
| 15:27 | dnolen | bbloom: why? |
| 15:27 | bbloom | dnolen: b/c i feel like a human compiler |
| 15:27 | bbloom | dnolen: isn't that reason enough to do anything in the lisp world? :-) |
| 15:27 | hiredman | silly bbloom, humans are computers, not compilers |
| 15:28 | dnolen | bbloom: have you needed to do much inlining w/ when writing CLJS? |
| 15:28 | bbloom | dnolen: no, just in core |
| 15:28 | TimMc | hiredman: Nonsense, I've been asked to compile a report before at work. |
| 15:28 | dnolen | bbloom: so my question remains, why? |
| 15:28 | ivan | V8 inlines small functions |
| 15:28 | hiredman | TimMc: as a computer you where asked to run a compiler routine |
| 15:28 | hiredman | were |
| 15:29 | dnolen | I haven't heard of anyone doing writing their own inlining macros in CLJS since we cover the bases |
| 15:29 | bbloom | right, core takes the suffering so that real apps don't have to |
| 15:29 | bbloom | but i want to eat the cake too: we shouldn't need a macro-version of every major bit operation in core :-) |
| 15:30 | dnolen | bbloom: in so many ways not a priority. That likes 100 lines of code in core.clj |
| 15:30 | bbloom | dnolen: i wasn't proposing it as a priority :-) |
| 15:30 | goracio | so with clojure it appears that we can make pretty big apps without classes and objects stuff )) |
| 15:31 | bbloom | dnolen: i think minimizing js* usage should be, however |
| 15:31 | goracio | just wrote pretty big app from scratch took about 2 weeks and it was pretty easy and fun |
| 15:32 | dnolen | bbloom: yes, I think it appears in only 5? 7? places in core.cljs now. happy to take patches the remove the remaining cases that can be removed. |
| 15:32 | bbloom | dnolen: what about core.clj ? |
| 15:32 | bbloom | dnolen: did you look at that random old branch i linked to? |
| 15:33 | dnolen | bbloom: yes we already talked about that - the inlining macros are the other case. |
| 15:34 | bbloom | dnolen: two separate issues. inlining vs js* usage. the js* operates on strings, not AST nodes |
| 15:34 | bbloom | dnolen: the inlining macros have various bugs, btw |
| 15:34 | bbloom | dnolen: max and min both evaluate their arguments multiple times |
| 15:35 | dnolen | bbloom: patches welcome ;) |
| 15:35 | bbloom | dnolen: instanceof evaluates it's arguments in reverse order |
| 15:36 | bbloom | dnolen: i apparently can't contribute any patches without simultaneously breaking everything ;-) |
| 15:36 | dnolen | bbloom: heh, low hanging fruit & compiler improvements not the same kind of patch :) |
| 15:36 | dnolen | bbloom: I'd happily take inlining macro fixes as one patch |
| 15:37 | bbloom | on a tangential personal note: i quit my job. anybody looking for a clojure dev in seattle? :-P |
| 15:38 | dnolen | bbloom: too bad you're not coming to the Conj |
| 15:38 | TimMc | bbloom: I'll keep an ear out. Does Seajure still exist? |
| 15:39 | emezeske | goracio: I'm not sure "pretty big app" and "in two weeks" are compatible facts :P |
| 15:39 | bbloom | TimMc: it does. i haven't been to it yet and can't go to the next one on thursday, but they apparently happen on the first thursday of each month. i'll try to make it to the next one |
| 15:40 | hiredman | next seajure meeting is this thursday at u. zoka |
| 15:40 | bbloom | hiredman: i've already volunteered to help out at the TechStars demo day on thursday; and i'm playing in the startup poker tournament that night too :-) |
| 15:41 | hiredman | I may or may not be there, and I may or may not have a a clojure powered robot |
| 15:41 | TimMc | bbloom: Is moving to Finland an option? :-P |
| 15:41 | goracio | emezeske: it' all depends of course but if consider that it is my first project in clojure and func lang then it's ok |
| 15:42 | bbloom | TimMc: no, but SF or NY are on the table |
| 15:42 | tomoj | bbloom: I'd love to hire you |
| 15:42 | TimMc | bbloom: I think ohpauleez's company does some Clojure stuff in NY. |
| 15:42 | tomoj | but can't afford you right now |
| 15:43 | bbloom | tomoj: heh :-) |
| 15:43 | bbloom | TimMc: paul moved to portland |
| 15:43 | TimMc | oop |
| 15:43 | emezeske | goracio: By all means, be happy with your first project! I'm not trying to trivialize it. I just wanted to point out that it's probably not really a data point for "clojure is suitable for large programs." |
| 15:44 | tomoj | bbloom: hopefully that will change in ~3 weeks |
| 15:44 | bbloom | tomoj: what's your startup? |
| 15:44 | bbloom | (i presume it's a startup, if you're expecting a financial event like that, heh) |
| 15:45 | TimMc | Why do you assume a startup? Maybe it's for homework help. :-P |
| 15:46 | uvtc | hehehe |
| 15:46 | bbloom | the ~3 weeks comment implied a financing to me, but maybe i've just been around too many startups |
| 15:47 | TimMc | Or maybe tomoj runs a turkey farm, and the Thanksgiving sales will provide money for the rest of the year. |
| 15:48 | bbloom | oh, this game is fun... maybe tomoj is planning a bank heist |
| 15:49 | hiredman | maybe he has been in contact with some helpful nigerians |
| 15:49 | bbloom | are there unhelpful nigerians? |
| 15:49 | goracio | emezeske: so i mean it appears that good apps can be written with only functions without classes and objects and inheritance stuff and so on |
| 15:50 | goracio | emezeske: i think oop is overcompicated and there is a choice like clojure that is good ) |
| 15:53 | emezeske | goracio: I agree. |
| 15:53 | tomoj | bbloom: pm? |
| 15:55 | bbloom | tomoj: anytime |
| 15:58 | Frozenlock | I have a java class that requires a float. Is there a way to make it accept any number and convert it on-the-fly? |
| 15:59 | bbloom | ,(doc float) |
| 15:59 | clojurebot | "([x]); Coerce to float" |
| 16:00 | Frozenlock | er.. yes.. I'm searching a more universal answer, I have many of those class requiring specific datatypes. |
| 16:01 | andrewmcveigh | If I want to use a worker queue in clojure, is the best option still a java BlockingQueue, or similar? |
| 16:01 | bbloom | Frozenlock: depends. do you have an interface to reify? can you just simply use a function instead of a method? |
| 16:03 | Frozenlock | Well I could wrap each class in a function, each making sure the type is correct and coercing them if needed. |
| 16:03 | hiredman | andrewmcveigh: nothing wrong with a nice linkedblockingqueue |
| 16:03 | Frozenlock | I have ~15 of these classes. |
| 16:04 | andrewmcveigh | hiredman: cheers. It's how I did it last time. Just wanted to make sure I'm not missing anything new/better/etc., in the Clojure world. |
| 16:05 | TimMc | Frozenlock: What is it? |
| 16:05 | Frozenlock | bacnet4j |
| 16:12 | jcromartie | every time my friend hits me up with some kind of programing problem, it's something Clojure solves already… I'll get him one day |
| 16:24 | TimMc | Frozenlock: Sounds like a Clojure wrapper might be really useful. |
| 16:26 | jonasac | can somone point me in the right direction for using (binding) im following the examples, but still getting an IllegalStateExeption in the repl |
| 16:26 | tomoj | bbloom: so cljs-cps could be used to implement something like http://taskjs.org/ , but is more powerful, right? |
| 16:26 | Frozenlock | TimMc: Yeah I think also... all these classes and subclasses are becoming really heavy in my code. |
| 16:28 | jcromartie | jonasac sure |
| 16:30 | bbloom | tomoj: precisely |
| 16:32 | bbloom | tomoj: the goal is more akin to C#'s async/await keywords |
| 16:32 | AntelopeSalad | if i do... (:require [compojure.response :as response]) , why doesn't it work when i call response/header later on? |
| 16:32 | tomoj | huh |
| 16:32 | tomoj | async/await seem like task.js to me |
| 16:32 | jonasac | jcromartie: if i do (def x0) and then call (binding [x 1] (var-get #'x)) i get an IllegalStateException saying "Can't dynamically bind non-dynamic var" |
| 16:33 | AntelopeSalad | note: the code above is taken directly from the official github page for compojure |
| 16:33 | tomoj | but I never did c# - you get the full power of delimited continuations? |
| 16:33 | bbloom | tomoj: yeah, pretty much the same thing |
| 16:33 | jcromartie | jonasac: yes, you need to add the :dynamic metadata to your dynamic vars |
| 16:33 | jcromartie | (def ^:dynamic x 0) |
| 16:34 | jonasac | ow, the book didnt mention that :p |
| 16:34 | tomoj | ah, so your main use case for cps is just async/await? me too |
| 16:34 | jcromartie | jonasac: it's new-ish |
| 16:34 | xeqi | AntelopeSalad: are you looking for ring.util.response/header ? http://ring-clojure.github.com/ring/ring.util.response.html#var-header |
| 16:34 | bbloom | tomoj: not really. c# special cases functions that are marked with the async keyword. those functions must return objects of type ITask or ITask<T>, which are just promises with optional continuations, and then turns the async function into a state machine |
| 16:35 | jcromartie | jonasac: the fundamental docs on clojure.org are good reading, and I don't mean that in a condescending way… I go there all the time http://clojure.org/vars |
| 16:35 | hiredman | difficult to see the difference |
| 16:35 | jonasac | i guess this while chapter falls out then cause it uses binding to bind to functions passed in (making a stubbing framework), unless i do that to all the functions in my code |
| 16:35 | AntelopeSalad | xeqi: yep, thanks -- then compojure.util :as response to call it as response/header? |
| 16:35 | jonasac | while == whole |
| 16:35 | bbloom | tomoj: that works great for C# b/c a state machine with a switch statement will outperform a whole bunch of lexical closures tangled together, but it's a less general approach. it really doesn't scale in terms of complexity to a language like closure |
| 16:35 | jcromartie | jonasac: I think it's since 1.3 |
| 16:35 | jcromartie | jonasac: what book? |
| 16:35 | AntelopeSalad | oh wait, it's ring not compojure hah |
| 16:35 | jonasac | clojure in action |
| 16:35 | bbloom | tomoj: there are a few other use cases for a CPS transform |
| 16:35 | jonasac | chapter 8.2 |
| 16:35 | bbloom | tomoj: tail call optimizations is one |
| 16:36 | bbloom | tomoj: another is composeable (aka delimited) continuations |
| 16:36 | bbloom | tomoj: that is shift and reset |
| 16:36 | Frozenlock | TimMc: I've often use java interop, but is there some rules of thumb one should follow when doing a wrapper? |
| 16:36 | jcromartie | yeah Clojure 1.3 came out just before Clojure in Action |
| 16:36 | jcromartie | I think |
| 16:37 | jcromartie | jonasac: typically you don't need a whole lot of dynamic vars |
| 16:37 | jcromartie | and you can also use let |
| 16:37 | bbloom | tomoj: continuations also let's you do some fancy server side cleverness like pg does with arc and HN, but there are a lot of folks who think that's not a great idea :-P |
| 16:37 | AntelopeSalad | xeqi: i'm actually not sure now, i was trying to implement some code that someone pasted here the other day -- i'm getting aliasing errors now where it doesn't make sense |
| 16:37 | AntelopeSalad | they make a call to response/header |
| 16:38 | tomoj | seaside-esque? |
| 16:38 | xeqi | jonasac: if you're just wanting to redefing functions for a test you might want ##(doc with-redefs) |
| 16:38 | lazybot | java.lang.SecurityException: You tripped the alarm! with-redefs is bad! |
| 16:38 | xeqi | hah |
| 16:38 | bbloom | tomoj: yeah, that smalltalk framework |
| 16:38 | bbloom | tomoj: simplest case is pg's "arc challenge" http://paulgraham.com/arcchallenge.html |
| 16:39 | xeqi | AntelopeSalad: it should be that function but hard to tell without the paste showing how its used |
| 16:39 | AntelopeSalad | k, one sec |
| 16:40 | AntelopeSalad | what was that site that supported clojure highlighting for pastes? |
| 16:40 | AdmiralBumbleBee | refheap |
| 16:40 | AntelopeSalad | thanks |
| 16:40 | AdmiralBumbleBee | and gist |
| 16:41 | egghead | anyone itc going to the LA clojure meetup this thursday? |
| 16:41 | AntelopeSalad | xeqi: https://www.refheap.com/paste/6268 , the important bits are probably lines: 12, 16-21 and 35 |
| 16:41 | AntelopeSalad | i also don't know if 34 will work, will worry about that later |
| 16:41 | AntelopeSalad | the repl is crying that compojure.response is already aliased |
| 16:42 | xeqi | AntelopeSalad: did you restart your repl after aliasing it? |
| 16:43 | xeqi | or remove the ns? |
| 16:43 | jonasac | xeqi: with-redef was just what i needed :) |
| 16:43 | AntelopeSalad | every time i make a change i run: (require 'hello-world.core :reload-all) in the repl |
| 16:43 | AntelopeSalad | that is when the alias problem comes up |
| 16:43 | xeqi | if I understand correctly, that doesn't remove the old ns and redo it |
| 16:43 | AntelopeSalad | "alias response already exists in the namespace, aliasing compojure.response" |
| 16:44 | AntelopeSalad | i don't even see how that's aliased though |
| 16:44 | AntelopeSalad | because i never aliased it |
| 16:44 | xeqi | you didn't load the file with it aliases as described in your original question? |
| 16:45 | AntelopeSalad | load it in what sense? it never properly gets loaded because of the alias error |
| 16:45 | AntelopeSalad | i am running lein repl manually |
| 16:45 | AntelopeSalad | start the repl, do the reload all command, start the server |
| 16:46 | AntelopeSalad | it seems you're right though, i really don't know what i'm doing haha |
| 16:46 | AntelopeSalad | someone recommended to :reload-all as the "right" way to reload code |
| 16:47 | AntelopeSalad | i just changed :as response to :as responsefoo and then changed my fn call to responsefoo/header and it failed with no such var |
| 16:47 | AntelopeSalad | (after doing a reload-all) |
| 16:47 | AntelopeSalad | that confirms that reload-all isn't pickuping up a NS change right? |
| 16:47 | AntelopeSalad | *picking |
| 16:49 | TimMc | Frozenlock: I don't have any specific recommendations, sorry. |
| 16:49 | TimMc | I guess just try to make something that hides all the insanity that it makes sense to hide. |
| 16:56 | AntelopeSalad | xeqi: i'm a bit more confused now, i googled to see if anyone is even using util.response and this code came back: https://github.com/ibdknox/noir/blob/master/src/noir/statuses.clj |
| 16:56 | AntelopeSalad | problem is, the guy doesn't reference ring-resp anywhere -- why is he even including it? |
| 16:59 | xeqi | AntelopeSalad: most likely was meaning to replace L28-29 and forgot about it |
| 17:00 | AntelopeSalad | any thoughts on how to solve this? |
| 17:00 | AntelopeSalad | i tried reloading with just (use 'ns) in the repl, same aliasing error as before |
| 17:01 | jcromartie | AntelopeSalad: sounds like :reload-all is broken |
| 17:01 | xeqi | did you restart your repl? |
| 17:01 | AntelopeSalad | no, i did not restart it |
| 17:01 | jcromartie | xeqi: the goal is to avoid restarting it |
| 17:02 | AntelopeSalad | i'll restart it though now and see |
| 17:02 | AntelopeSalad | same problem |
| 17:02 | AntelopeSalad | have to go, zzz... i didn't expect something so silly to be 2 hours of debugging haha -- will try again tomorrow |
| 17:03 | AntelopeSalad | if the guy who wrote ring is here, please update your docs to include samples on how to use the code you've written -- beginners to the language cannot figure this stuff out with no documentation |
| 17:04 | jcromartie | AntelopeSalad: which part of ring? |
| 17:04 | jcromartie | AntelopeSalad: sorry I haven't followed the whole discussion |
| 17:06 | jcromartie | all this talk about continuations in web apps… what about representing a HTTP session as a lazy seq? |
| 17:07 | jcromartie | that the session is a single sequence of requests -> responses |
| 17:10 | TimMc | Continuation IDs in URLs work great until you want to bookmark something. |
| 17:11 | TimMc | or use back/forward after being AFK for 15 minutes |
| 17:12 | bbloom | oh yeah, it's annoying as hell as an end user. i wouldn't actually recommend writing an app with the same bugs as HN :-P |
| 17:13 | jcromartie | heh |
| 17:14 | ivan | hey, if you have a durable lazy seq... |
| 17:14 | emezeske | Yeah, the only anoying thing is the non-durability |
| 17:15 | jcromartie | same problems as seaside though |
| 17:15 | jcromartie | and only slightly less debuggable |
| 17:15 | bbloom | i think it's a fundamentally failed approach b/c it's effectively the opposite of conservative garbage collection |
| 17:15 | technomancy | heh; "HREF considered harmful" |
| 17:15 | bbloom | you have external demands on resources that you don't know about |
| 17:15 | jcromartie | I dunno, I liked the idea of Seaside but I had a lot of issues |
| 17:15 | jcromartie | hm, yeah |
| 17:16 | dnolen | jcromartie: the continuation thing is actually good for something very specific that no-one bookmarks - complex form flows |
| 17:16 | bbloom | but i think that applies to sessions, full stop. |
| 17:16 | bbloom | dnolen: even complex form flows suck... what if i'm on page 4 of 10 in a survey and then close my laptop and go for a walk? |
| 17:17 | bbloom | the nature of http is stateless |
| 17:18 | dnolen | bbloom: I'm not saying there aren't other ways to deal w/ the issue, but it's improvement. I haven't messed w/ JS browser history to support enough to say whether it sucks more or not |
| 17:18 | bbloom | *shrug* session state is a hack and always will be |
| 17:19 | bbloom | the only way around it is to have a persistent connection (or some kind of long polling to simulate a persistent connection) |
| 17:19 | jcromartie | then might as well say all sessions such |
| 17:19 | jcromartie | suck |
| 17:19 | bbloom | but even then, you need to support disconnect/reconnect |
| 17:19 | bbloom | again, consider the long survey and a closed laptop |
| 17:19 | dnolen | bbloom: perhaps, in anycase DabbleDB seemed to get some good mileage out of the approach. Perhaps other people are catching w/ pure JS apps? I can't say. Haven't done complex forms in a long time. |
| 17:20 | dnolen | catching up |
| 17:21 | bbloom | i think that blurring the line between the server and the client is fundamentally a bad idea |
| 17:22 | bbloom | i much rather a rich client app that maintains some in memory state and a server that is either totally stateless or connection oriented |
| 17:22 | hiredman | fallacies of network computing? |
| 17:22 | bbloom | totally stateless --> session oriented |
| 17:22 | bbloom | er i mean totally stateless --> totally session-less |
| 17:23 | bbloom | hiredman: yup: http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing |
| 17:37 | tomoj | oh, good, I can stop thinking about the arc challenge now :) |
| 17:40 | bbloom | tomoj: it's still a worthwhile mental exercise :-) |
| 17:50 | TimMc | Oh man, I just read that. So ridiculous! |
| 17:51 | TimMc | If you can have an arbitrary web lib off to the side, there's no challenge. |
| 17:53 | jcromartie | The Arc Challenge is silly: he's starting with a language that defines a form that creates an HTTP handler in a running server, presumably? |
| 17:53 | jcromartie | I mean, that's all I can gather from the (defop …) form |
| 17:56 | TimMc | Yeah, right after saying that it's general purpose. |
| 18:01 | Frozenlo` | Can I use extend-type on a class to control how a new instance is created? |
| 18:01 | gfredericks | like hook into the class's constructor? |
| 18:03 | Frozenlo` | gfredericks: Yeah, like that :P |
| 18:04 | Frozenlo` | I suppose I could make my own protocol with a method 'new2' |
| 18:04 | gfredericks | I do not believe the jvm would go along with that plan |
| 18:05 | gfredericks | Frozenlock: even then it'd be a method on instances rather than the class |
| 18:05 | gfredericks | maybe you could extend it to java.lang.Class if you don't mind the same behavior for all classes... |
| 18:06 | gfredericks | then you'd have to instantiate via reflection...I really don't know a lot about this. |
| 18:07 | bhenry | what is an alternative to partition where i can still have a smaller list at the end if the original collection doesn't divide evenly? |
| 18:07 | amalloy | ~partition |
| 18:07 | clojurebot | partition is probably not what you want; see partition-all. |
| 18:07 | bhenry | thanks! |
| 18:34 | etherealG | hi, I noticed on 4clojure the order of the problems seems to be a lot harder if done as it takes you through them. simple stuff like recursion comes much later than more complicated ones like interleave. anyone know which order to do them in if learning clojure from scratch? |
| 18:35 | AimHere | The problems are rated Elementary, Easy, Medium and Hard or something |
| 18:36 | AimHere | You could go by that |
| 18:38 | tomoj | bbloom: yeah |
| 18:42 | tomoj | I'm thinking you could get enough of the good stuff that arc has, separate the client and server better, and get by with just async/await |
| 18:47 | antares_ | Monger 1.3.3 is released: http://blog.clojurewerkz.org/blog/2012/10/31/monger-1-dot-3-3-is-released/ |
| 18:50 | tomoj | async/await plus a little more.. |
| 19:30 | nDuff | Hrm. |
| 19:30 | nDuff | For some reason nrepl.el is trying to use complete.core, but not require'ing it |
| 19:30 | nDuff | so I have to explicitly do that myself. |
| 19:34 | brainproxy | nDuff: I had that problem; does it happen when you do nrepl-jack-in, or only when you're connecting from emacs to an already running nrepl server? |
| 19:36 | technomancy | hm; looks like it changed since I originally added completion |
| 19:36 | technomancy | my version requires it correctly =) |
| 19:36 | brainproxy | technomancy: any luck with your attempt to get namespace (and dependent namespace) reloading working? |
| 19:36 | brainproxy | i.e. when using nrepl.el |
| 19:37 | nDuff | brainproxy: I don't use nrepl- |
| 19:37 | nDuff | erm, nrepl-jack-in at all, so can only speak to the latter case. |
| 19:37 | technomancy | brainproxy: I got it working, but it was ugly. I don't remember if it got merged to master. |
| 19:37 | brainproxy | nDuff: okay sure; how are you invoking the nrepl server? |
| 19:38 | brainproxy | i mean, are you doing so from the command line w/ lein, or are you embedding it w/in some project |
| 19:38 | nDuff | Neither |
| 19:38 | nDuff | Using gradle because lein doesn't support Ivy |
| 19:39 | nDuff | ...my build.gradle invokes clojure.tools.nrepl.cmdline/-main with args ['--port', '6678'] |
| 19:39 | brainproxy | okay, maybe i'm confused; you are using nrepl.el to connect to an nrepl server? |
| 19:39 | brainproxy | ah gotcha |
| 19:40 | brainproxy | technomancy: have you had luck with ritz-swank? |
| 19:41 | technomancy | haven't tried it |
| 19:41 | brainproxy | I've made several attempts to get it working to no avail; but have no problems with swank-clojure |
| 19:41 | brainproxy | okay |
| 19:44 | scottj | brainproxy: I had trouble with it last time I tried. time before that it worked great. I'd contact author he's very responsive |
| 20:46 | holo | hi |
| 20:46 | mpan | hi |
| 20:47 | Scriptor | hey holo |
| 20:49 | holo | hey Scriptor |
| 20:49 | mpan | By any chance, does anyone have a recommendation for a genetic algorithm library? I imagine it would probably be in Java and work through interop, so the convenience of that would be a factor. |
| 20:52 | gfredericks | ~ |
| 20:52 | clojurebot | Titim gan éirí ort. |
| 20:53 | mpan | hm, internet connection flaking out on me |
| 20:54 | mpan | btw what's ~ meant to do? random quote from the bot's collection? |
| 20:54 | gfredericks | no I sent it accidentally |
| 20:54 | mpan | is there documentation of the bots' commands? |
| 20:54 | gfredericks | was playing with the ssh client interface |
| 20:54 | antares_ | ~maven |
| 20:54 | clojurebot | Help, I'm trapped in an XmlFactoryFactory! |
| 20:54 | gfredericks | I think "~" asks clojurebot to comment on the empty string about which he apparently doesn't know anything |
| 20:54 | gfredericks | clojurebot: is an empty string |
| 20:54 | clojurebot | Or, for instance, foo.toString().length() is (.. foo toString length) |
| 20:54 | mpan | ~test |
| 20:54 | clojurebot | forget latest is 1382 |
| 20:55 | gfredericks | clojurebot: |is| an empty string |
| 20:55 | clojurebot | read-string |is| as unsafe as eval unless *read-eval* is bound to false. |
| 20:55 | gfredericks | I apparently don't know how to make him respond to "~" |
| 20:56 | mpan | wait huh? when do you eval at read-time? |
| 20:56 | mpan | I'm blanking on any examples |
| 20:56 | gfredericks | when you use #= |
| 20:57 | gfredericks | I don't know of any use cases that aren't addressed by the newer data readers |
| 20:57 | mpan | sorry, but what's hash-equals? |
| 20:57 | gfredericks | reader eval :) |
| 20:57 | mpan | that sounds scary |
| 20:57 | gfredericks | you'll have to try it at the repl as I think the bots disable it |
| 20:57 | gfredericks | try (read-string "(1 2 #=(+ 3 4) 5)") |
| 20:58 | mpan | is it the same as eval except when? |
| 20:58 | gfredericks | I think so |
| 20:58 | mpan | what's the need to upset the usual semantics of read? |
| 20:59 | mpan | or rather, what was |
| 20:59 | gfredericks | I think just when you want to read in objects that don't have their own syntax |
| 20:59 | hiredman | try (read-string "#=(+ (+ 3 4) 5)") |
| 20:59 | gfredericks | hiredman: that's slick; so it just supports top-level function calls? |
| 20:59 | mpan | what are "objects that don't have their own syntax"? |
| 21:00 | gfredericks | mpan: e.g., records |
| 21:00 | gfredericks | queues |
| 21:00 | gfredericks | finger trees |
| 21:00 | mpan | wait huh? |
| 21:00 | hiredman | gfredericks: I think, I forget, it's been I while since I've paid attention to eval reader |
| 21:00 | gfredericks | I've never had a real use for #= |
| 21:00 | hiredman | records have a syntax now |
| 21:00 | gfredericks | hiredman: looks like it also calls macros as functions |
| 21:00 | mpan | even so, why would you want them at read-time? |
| 21:00 | mpan | rather than at eval-time? |
| 21:01 | mpan | like, why would you want the eval-ed representation? |
| 21:01 | gfredericks | maybe for data that you're only reading rather than evaling? |
| 21:01 | hiredman | mpan: because the reader can read other things besides code |
| 21:03 | gfredericks | so it looks like it reads everything in the list, expects the first item to be a symbol that it resolves to a function, and then calls that function on the other (uneval'd) arguments |
| 21:03 | gfredericks | e.g., #=((comp inc +) 4) doesn't work either |
| 21:07 | Cubic | How do I supply a type hint for a non-primitive array? |
| 21:08 | mpan | all right, thanks guys |
| 21:09 | amalloy | &(class (into-array ["x"])) |
| 21:09 | lazybot | ⇒ [Ljava.lang.String; |
| 21:11 | Cubic | &(defn [x] ^[Ljava.lang.String x) |
| 21:11 | lazybot | java.lang.RuntimeException: Unmatched delimiter: ) |
| 21:11 | Cubic | That's not valid clojure |
| 21:11 | mpan | why does (read-string "{:a {:b :c}}") produce what looks to be an exception at the repl yet still yields the expected result? |
| 21:11 | mpan | or, what does the bot say about ##(read-string "{:a {:b :c}}") |
| 21:11 | lazybot | ⇒ {:a {:b :c}} |
| 21:12 | gfredericks | mpan: no idea what sort of exception you're seeing |
| 21:12 | gfredericks | mpan: works fine for me |
| 21:12 | mpan | uh, I can't even reproduce it |
| 21:12 | mpan | https://www.refheap.com/paste/6272 |
| 21:13 | mpan | I would expect it to be deterministic, but, well... I guess something happened |
| 21:13 | gfredericks | I feel like it could have been some kind of stale exception from the previous command |
| 21:13 | gfredericks | I've had spooky repls like that before |
| 21:13 | gfredericks | not lately |
| 21:14 | mpan | previous line was a genuine exception produced |
| 21:14 | gfredericks | but anyhow that exception looks like the one generated by my last reader-eval example |
| 21:14 | mpan | yes that |
| 21:14 | gfredericks | did it print the exception twice then? |
| 21:14 | mpan | yes |
| 21:14 | gfredericks | heckiphino |
| 21:14 | mpan | oh but, the first time was printing it as the result |
| 21:14 | gfredericks | ah ha |
| 21:14 | mpan | and the other time was printing it as an error message |
| 21:15 | gfredericks | spooky repl still |
| 21:15 | mpan | i.e. the first one was prefixed by #< and the second time wasn't |
| 21:15 | mpan | suggesting one was the toString() and the other was... uh... something |
| 21:20 | mpan | gfredericks: wait, would that constitute a repl bug? if so, should I report it somewhere? |
| 21:29 | gfredericks | mpan: probably; repls are complicated. I wouldn't know what to suggest. |
| 21:31 | mpan | the repl that lein uses is at its core nrepl? so this gets reported to nrepl? |
| 21:33 | antares_ | mpan: it uses REPLy |
| 21:34 | mpan | is REPLy on top of nREPL? |
| 21:35 | mpan | oh, hm |
| 21:35 | Cubic | lein repl does create an nrepl server if I'm not completely mistaken |
| 21:35 | xeqi | reply is a frontend to nrepl, think client server |
| 21:35 | mpan | so if there's what appears to be a bug in what appears to be the repl itself? is that in nrepl? |
| 21:35 | Cubic | amalloy_: thanks, got it to work |
| 21:39 | xeqi | mpan: I'd start by filling it with reply, trptcolin is good about tracking things down and pushing it to nrepl when needed |
| 21:39 | xeqi | though (read-string "{:a {:b :c}}") works fine in `lein repl` for me |
| 22:03 | amalloy | my suspicion is that mpan's repl was in some weird/broken state based on something totally unrelated, which cased the first eval-attempt to fail. later attempts worked fine because it was no longer in that state. ie, i don't think nrepl maintainers can ever repro this from just the paste above |
| 22:05 | gfredericks | at the very least his previous command, which actually generated the exception, would be needed |
| 23:34 | lil`nbv4 | when i type `lein ring server` it says "That's not a task. Use "lein help" to list all tasks." i'm using lein 1.7, what could the problem be? |
| 23:37 | technomancy | lil`nbv4: best to get on leiningen 2 |
| 23:37 | xeqi | lil`nbv4: do you have :plugins [[lein-ring "0.7.5"]] in your project.clj? |
| 23:42 | lil`nbv4 | xeqi: I do now :) i am new to clojure, thanks |
| 23:46 | xeqi | then I also recommend using lein2 |