#clojure logs

2012-10-30

00:18jonasenbbloom: about cljs-412, I think the issues I raised here https://groups.google.com/d/msg/clojure-dev/Ge5uEqlUcJk/_b9xEVrKha8J might be related?
00:20bbloomjonasen: yes. there are some interrelated issues
00:20bbloomjonasen: var resolution is a bit of a mess at the moment
00:21bbloomjonasen: there's a bunch of janky tricks like (resolve … (dissoc env :locals) …)
00:21bbloomjonasen: and then resolve-var vs resolve-existing-var
00:22bbloomjonasen: 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:22jonasenbbloom: I fixed resolve-var/resolve-existing-var in my fork
00:22jonasenbbloom: at least I think I did :)
00:23jonasenbbloom: but that's several months ago... ClojureScript has moved on since then
00:23bbloomjonasen: heh, yeah and new complexity has crept in to the resolution code paths
00:23jonasenbbloom: yes
00:24bbloomjonasen: 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:24bbloomjonasen: that would be a great patch on it's own
00:25jonasenbbloom: If I remember correctly, the defprotocol (or was it deftype?) did some very strange things also.. duplicating the resolve-var
00:25bbloomjonasen: something is funky in there....
00:26jonasensorry, I mean the defprotocol macro dupicates the logic (badly) of resolve-var
00:26bbloomjonasen: a good goal would be to eliminate the *cljs-warn-on-undeclared* flag and to have it always be enabled
00:26bbloomjonasen: we should talk to dnolen and get his buy in on that
00:27bbloomjonasen: 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:31bbloomjonasen: 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:31bbloomand empty-vector
00:31bbloomsame goes for the static methods
00:31jonasenbbloom: I totally agree with that
00:32bbloomjonasen: 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:33jonasenbbloom: The reason for cljs.core.PersistentVector/EMPTY is that it's a straight port from the java source
00:33bbloomjonasen: unsurprising :-)
00:33jonasenbbloom: but it's the wrong way to do it IMO
00:33jonasenbbloom: and it confuses the analyzer
00:34bbloomjonasen: yup. that seems like a reasonable starting place. could you work up a patch for just that? open a ticket
00:35bbloomjonasen: and if there is a way to get the analyzer to detect that situation: have it emit a deprecated warning!
00:36jonasenbbloom: I talked to dnolen about it (a few months ago) and he wasn't too keen on accepting such a patch
00:36bbloomjonasen: what did he say about it?
00:36jonasenbbloom: I
00:36jonasenbbloom: I'd have to search the IRC logs :)
00:38bbloomjonasen: http://clojure-log.n01se.net/date/2012-06-20.html
00:39jonasenbbloom: that's the one!
00:39jonasenbbloom: sorry, gotta run!
00:40jonasenbbloom: But I'd love to talk about this stuff more.. there is a lot of fun work with the analyzer still!
00:40bbloomjonasen: i don't really buy the "pollution" argument :-P there are LOTS of top levels that should be ^:private
00:40bbloombut aren't
00:40bbloomjonasen: but cljs doesn't really respect private yet… heh
01:42tomojhmm https://www.refheap.com/paste/3e2aa9f9ae734ba5ac89aa71b clj->el would be nice
03:38tomojwhy does pmap look at the number of available processors?
03:39ivanwhat else would it do?
03:43tomojhttps://www.refheap.com/paste/bb37b0cf096f905d8ca995f9c
03:43tomojer
03:43tomoj(+ 2 (.. Runtime getRuntime availableProcessors)) is 6, here
03:44tomojyet it appears to use 32 threads at a time due to the chunkiness of range
03:44tomojmaybe that's just cus it's chunky..
03:44tomojah yes
03:44tomojwith s/(range)/(iterate inc 0)/ the behavior is as expected
03:56ebaxtHi, 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:19tomojdatomic.api/touch is confusingly named
04:20brainproxytomoj: how so?
08:20clgv,(type {:a 1})
08:20clojurebotclojure.lang.PersistentArrayMap
08:20degDoes metadata get passed along when, e.g. I create a new map by assoc'ing into an existing one?
08:21clgvdeg: yes
08:21degvery cool!
08:22clgv&(let [m (with-meta {:a 1} {:type :some-map})] (type (assoc m :b 2)))
08:22lazybot⇒ :some-map
08:22chouser_logone of the few ways lists differ from lazy seqs
08:24clgvchouser: you mean that lists keep metadata and lazy seqs do not, right?
08:24chouserwell, each step of a lazy seq keeps its own metadata
08:25clgvyes. the implementation would have to pass on the metadata from the head if that was desired
08:25chouser&(let [L (with-meta '(a b) {:foo :bar})] (meta (next L)))
08:25lazybot⇒ nil
08:25chouserha!
08:25chouser&(let [L (with-meta '(a b) {:foo :bar})] (next L))
08:25lazybot⇒ (b)
08:26chouseroh, next. That returns a lazy seq
08:26chouser&(let [L (with-meta '(a b) {:foo :bar})] (pop L))
08:26lazybot⇒ (b)
08:26chouser&(let [L (with-meta '(a b) {:foo :bar})] (meta (pop L)))
08:26lazybot⇒ nil
08:26chouserman, maybe I'm just plain wrong.
08:26chouser&(let [L (with-meta '(a b) {:foo :bar})] (type (pop L)))
08:26lazybot⇒ clojure.lang.PersistentList
08:27chouser&(let [L (with-meta '(a b) {:foo :bar})] (meta (conj L 'c)))
08:27lazybot⇒ {:foo :bar}
08:27chouser&(let [L (with-meta '(a b) {:foo :bar})] (meta (cons 'c L)))
08:27lazybot⇒ nil
08:27chouser&(let [L (with-meta (seq '(a b)) {:foo :bar})] (meta (conj L 'c)))
08:27lazybot⇒ {:foo :bar}
08:28chouser&(let [L (with-meta (map identity '(a b)) {:foo :bar})] (meta (conj L 'c)))
08:28lazybot⇒ nil
08:28chouserok, enough spam, sorry.
08:29clgvhumm interesting though
08:29degchouser: Ok, meta-question here... What is the lazybot that seems to be executing your code? Is that magic in some IRC client?
08:30clgvthe question is if you really need to use metadata on lists in practice
08:30clgvdeg: it's an irc bot
08:30degTriggered by the "& in front of the expression??
08:30lazybotdeg: What are you, crazy? Of course not!
08:30deg&(+ 40 2)
08:30lazybot⇒ 42
08:30degAha
08:31clgvdeg: but do try to not spam the channel much. it's good for examples to questions
09:09brainproxytyring again to get slime-ritz / lein ritz working ... anyone successfully using it?
09:26CubicIs there anything in core that would let me grab all fields from a class and expose them in my namespace?
09:26Cubic*all static final fields
09:33clgvCubic: no, there is not. maybe there is some lib to do that
09:33antares_Cubic: no
09:34CubicEh, well I guess it's too localized to belong there
09:34clgv&(loaded-libs)
09:34lazybot⇒ #{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:35CubicWhat's the difference between lazy bot and clojure bot?
09:36clgvCubic: lazybot is more advanced ^^
09:36clgvright lazybot???
09:36lazybotclgv: How could that be wrong?
09:37clgvCubic: the clojure.reflect namespace might help you to write a macro that imports those static final fields to local symbols.
09:38CubicI 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:44CubicJust 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:45clgv"This page does not existPage not found."
09:45Cubicclgv: Sorry http://ideone.com/AHYmr8
09:47clgvCubic: you would need to import the class to avoid full qualified class name
09:47clgvbut since the code is generated why bother?
09:48clgvor did you mean the class you give as param to the macro must be full qualified?
09:48CubicNo 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:48clgv,(resolve 'Integer)
09:48clojurebotjava.lang.Integer
09:49Cubicoh
09:49clgvthere is the trick ^^
09:49Cubicclgv: thanks I'll try that
09:50clgvbut you could easily skip that. replace (get-static-final-fields (Class/forName (str class))) by (get-static-final-fields ~class)
09:50clgvthen it should be resolved automatically
09:52clgvoh I overlooked your unquoting. well then it's not that easy^^
09:52clgvs/overlooked/missed/
09:53clgv(get-static-final-fields (resolve class)) should work
10:12tolsenmaybe 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:14clgvtolsen: my guess: the operation on the boxed doubles can check the operands whereas the native operation is just executed
10:15tolsenclgv: that makes sense
10:26tolsenhmm.. 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:27nDufftolsen: 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:27tolsennDuff: sure. sorry
10:32TimMcclgv: People who work in or with the advertising industry have to.
10:32nDuffclgv: 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:32clgvTimMc: for real? I'd argue that my job performs suffers from it^^
10:33nDuffclgv: 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:33nDuffs/to promote/to fund/
10:34mpan&(type 4.0)
10:34lazybot⇒ java.lang.Double
10:34clgvtolsen: you have to have a look at where the exception comes from: clojure.lang.Numbers.divide
10:34mpan(= 4.0 (Double. 4.0))
10:34clgvtolsen: so it's definitely a clojure bug or feature ;)
10:34goraciohi 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:34mpan&(= 4.0 (Double. 4.0))
10:34lazybot⇒ true
10:35nDuffgoracio: let doesn't return nil
10:35nDuffgoracio: it returns the last thing within it.
10:35mpangoracio: put what you want to return in the expr after all the bindings
10:35goraciohmm will check ..
10:35mpanlike, you have let, then a bunch of pairs of names and bindings, and then the expr you want
10:36mpanand the overall let-expr will evaluate to the expr
10:36mpanfor example, ##(let [a 1] 1.0)
10:36lazybot⇒ 1.0
10:36_ulises##(let [a 1])
10:36lazybot⇒ nil
10:36mpanI 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_ulisesso let can result in nil
10:37nDuff_ulises: I don't think anyone said it _can't_
10:37nDuff...not with statements taken in context, anyhow.
10:37_ulisesnDuff: 'course; I was just curious if it'd fail :)
10:37_ulisesnDuff: *fail with an exception along the lines of "let needs a body" or something
10:38_ulisesnot being cheeky
10:38mpan_ulises: that is very interesting but I don't know what it would be used for
10:39mpanI recall someone mentioned that / is treated specially?
10:40mpana while back I was wondering why / existed yet I wasn't allowed to define a / in the current ns
10:43Bronsauser=> (defn / [])
10:43BronsaWARNING: / already refers to: #'clojure.core// in namespace: user, being replaced by: #'user//
10:43Bronsa#'user//
10:43Bronsauser=> (in-ns 'a)
10:43Bronsa#<Namespace a>
10:43Bronsaa=> user//
10:43BronsaRuntimeException Invalid token: user// clojure.lang.Util.runtimeException (Util.java:170)
10:44jkkramer,((fn [& ∕] (let [[/ ∕] ∕] (#'/ / ∕))) 12 3)
10:44clojurebot4
10:46mpanI'm not sure what to make of that
10:46mpanis this generally not advisable to do, then>
10:46mpan?
10:47Bronsafwiw it's just a one-line patch to LispReader.java to make that work
10:47goracio##(let [a 1] 1.0)
10:48lazybot⇒ 1.0
10:48goraciois this form valid only here :) ? ##(let [a 1] 1.0)
10:48lazybot⇒ 1.0
10:48mpanthe use of ## is a special instruction to the bot
10:48goracioah i see now :)
10:49mpanit says, read-eval this, regardless of its position in the line
10:49mpanwhereas # must be at the start
10:49mpanthe rest of that is a standard s-expr
10:50mpanbtw perhaps I picked bad example values
10:50mpanthat could have just as easily been ##(let [a 1] "HELLO WORLD")
10:50lazybot⇒ "HELLO WORLD"
10:50mpanor ##(let [a 1] (+ a 1))
10:50lazybot⇒ 2
10:50mpanand usually, you'd want to do something with the bindings, as such ^
11:39sunkencityrylehI'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:40sunkencityrylehIn ruby i'd use each_with_object or inject if the other method is not available
11:40sunkencityryleh(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:41sunkencityrylehnow I do it like this in clojure (apply hash-map (flatten (map get-keypair acts))))
11:41augustlsunkencityryleh: inject === reduce basically
11:42sunkencityrylehaugustl: ok I'll take a look at reduce
11:46augustlsunkencityryleh: (reduce (fn [curr prev] (assoc curr (:id prev) prev) ) {} [{:id 1 :name "foo"}, {:id 2 :name "bar"}])
11:47augustlerr a bit weird naming but yeah
11:48technomancyis each_with_object new?
11:48technomancylooks kind of like a gross non-functional reduce
11:49technomancyif you're going to bash around something like that why not just close over it?
11:49technomancyoh ruby...
11:51augustltechnomancy: haha
11:51augustlas I suspected, it is added by Rails
11:51augustlso it's not in Ruby
11:52augustlRails brings out the best of Ruby, doesn't it
11:53sunkencityrylehit's from rails, it's inject but you don't have to do ;memo in the end :)
11:54technomancyyeah but what's the point of taking it as a block arg instead of using a closure?
11:55sunkencityrylehhm, it's a one-liner for fold-l ?
12:00sunkencityrylehI'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:01augustlsunkencityryleh: correct
12:04sunkencityrylehaugustl: it seems that there's something funky going on behind the scene there!
12:10TimMcfoo is the request?
12:12sunkencityrylehTimMc: another example: (def app (-> (handler/api app-routes) debug-session1 wrap-session debug-session2) debug-session2 is the middleware that gets run first
12:12TimMcgets run first == outermost?
12:12sunkencityrylehyes, the last one
12:12sunkencityrylehwouldn't -> wrap the other way?
12:13TimMcNo, this makes sense to me.
12:14TimMcIf foo were the request, you'd be right.
12:14sunkencityrylehhm
12:15sunkencityryleh'(-> '(1 2 3 4) rest rest rest first)
12:15hiredmansunkencityryleh: 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:15sunkencityryleh4
12:15sunkencityryleh(first (clojure.core/-> (clojure.core/-> (clojure.core/-> (quote (1 2 3 4)) rest) rest) rest))
12:15TimMcIt's not about ->.
12:15sunkencityrylehok so what am I missing?
12:15sunkencityrylehI
12:15sunkencityrylehm completely lost :)
12:15TimMcsunkencityryleh: 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:16sunkencityrylehTimMc: ah, thanks
12:17TimMcIn hiredman's analogy, each of those fns is a piece of wrapping paper.
12:17sunkencityrylehI need to meditate on this
12:19sunkencityrylehhiredman: Ok, now I see it (almost)
12:22sunkencityrylehwhen I macroexpand an expression with -> why is there still clojure.core/-> left
12:22sunkencityrylehin the expression
12:22hiredmanbecause macroexpand is not recursive
12:23sunkencityrylehhiredman: ok tnx
12:26TimMcsunkencityryleh: ##(let [incw (fn [f] #(f (inc %))), firstw (fn [f] #(f (first %))), stack (-> identity incw firstw)] (stack [0 2 4 6]))
12:26lazybot⇒ 1
12:27TimMcHere, identity stands in for the core of your app.
12:29TimMcHere's a version that does the wrapping in the opposite order:
12:29sunkencityrylehTimMc: tnx
12:29TimMc&(let [incw (fn [f] #(inc (f %))), firstw (fn [f] #(first (f %))), stack (-> identity firstw incw)] (stack [0 2 4 6]))
12:29lazybot⇒ 1
12:30bhenryhow can i take everything but the last three items in a vector?
12:31bhenryreverse drop 3?
12:31TimMcbutlast?
12:31bhenrybutlast only takes the coll
12:31hiredman,(doc drop-last)
12:31clojurebot"([s] [n s]); Return a lazy sequence of all but the last n (default 1) items in coll"
12:31bhenryboom. thanks hiredman
12:31TimMcAh, right.
12:31TimMc,(apropos 'last)
12:31clojurebot(last butlast drop-last take-last)
12:31hiredmancheckout the impl of drop-last, it is pretty cute
12:32hiredman~def drop-last
12:32TimMcOh, is that the one that uses drop and ternary map?
12:32hiredmandunno if that works
12:32hiredmanTimMc: yeah
12:32TimMcVery cute.
12:33technomancyoh that is clever
12:41goraciocan we save 2 values in session ( memory store) ? something like this (session/put! :key val key2 val2)
12:44thorbjornDXhaha, drop-last :P
13:01jcromartiesets are functions
13:01jcromartiebut *functions are sets*!
13:02jcromartieor close enough
13:02_ulisesyes! \o/
13:04bhenrycan things inside of a future start other futures?
13:05ohpauleezbhenry: Yes
13:05ohpauleezthey pull from the same pool though
13:19technomancylynaghk: mind if I pm?
13:25dnolenbbloom: ping
13:25bbloomdnolen: what's up?
13:26dnolenbbloom: 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:26dnolenbbloom: there are many more broken cases that have nothing to w/ the top level.
13:27dnolenbbloom: part of the issue is that CLJS-369 assumes that lexical scope exists in JS, it does not
13:27dnolenbbloom: 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:27technomancy(require '[clojure.dev.jira :as jira]) (add-watch (jira/issue 369) (partial email bbloom))
13:28dnolenbbloom: nested top level dos w/ lets are broken, very bad for macros
13:28bbloomdnolen: bah. sorry about this.
13:28dnolenbbloom: I'm kicking myself for not seeing this issue much earlier.
13:29bbloomdnolen: give me a few minutes to investigate/think
13:29dnolenbbloom: k
13:31dnolenbbloom: 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:31bbloomdnolen: yup. my primary motivation was to allow analysis to happen BEFORE introducing insane semantics :-)
13:32bbloomdnolen: by that i mean downstream analysis, like my CPS transform
13:33dnolenbbloom: 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:33bbloomdnolen: 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:34dnolenbbloom: I'll be around, thx much.
13:59uvtcWhy 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:59uvtcAnd 1.6.0 is what's displayed at clojars.
14:02uvtcSorry, perhaps I should ask that on a different channel.
14:03TimMcWas :url added after the last release?
14:04TimMcCheck the project.clj in the JAR artifact from clojars.
14:04uvtcOh, right, TimMc. Good eye dear.
14:08bbloom"One's sentiment toward JavaScript flips between elegance and disgust without transiting intermediate states." -- http://matt.might.net/articles/javascript-warts/
14:08bbloomtruer word have never been spoken :-P
14:09FrozenlockI'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:10bbloomdnolen: 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:11bbloomdnolen: maybe go with that and back out aea65a693 ?
14:12TimMcFrozenlock: I think new takes a literal symbol.
14:12TimMc&(let [foo StringBuffer] (new foo))
14:12lazybotjava.lang.IllegalArgumentException: Unable to resolve classname: foo
14:13bbloomdnolen: hacky gensyms seems like the only quick fix. anything more elegant would require deeper JS analysis
14:13bbloom"el-cheapo gensyming" as he describes it, heh
14:13FrozenlockTimMc: Is there a workaround? I don't know in advance what will be the class...
14:14TimMcj.l.Class has some appropriate constructor methods.
14:14FrozenlockThanks!
14:14TimMc&(let [foo StringBuffer] (.newInstance foo))
14:14lazybot⇒ #<StringBuffer >
14:15FrozenlockMagic :)
14:15TimMcFrozenlock: And I would bet that there are some nice helper methods in the Clojure compiler that you could use for non-nullary constructors.
14:17dnolenbbloom: yeah that patch actually look ok
14:18tgoossensHi
14:18tgoossensI'm here to epxress my frustrations
14:18dnolenbbloom: thanks for giving it a look, i'll give it a shot and add some more tests cases later.
14:18tgoossensAt university I have to do (obligated) teamwork in java
14:19bbloomdnolen: then let's go with that so we un-break everybody. revert aea65a693 and apply that patch.
14:19tgoossensAnd
14:19uvtchi tgoossens .
14:19tgoossensthe rest of my team just doesn't get it. How to write simple code
14:19tgoossensapparently they like
14:19tgoossensinstanceof
14:19tgoossensand switch case
14:19bbloomdnolen: that also means that the :shadow keys aren't necessary in the analyze phase, but we can address that later
14:19tgoossensso now. We have monstercode
14:19tgoossensthat 1) doesn't work
14:20tgoossens2) is hell to debug
14:20tgoossensBut I can't seem to convince them
14:20tgoossensit seems like "if its not complicated it is not smart / good"
14:20uvtctgoossens: Do you have a specific question about Clojure?
14:20dnolenbbloom: I think we still need that for namespaces right?
14:21technomancytgoossens: that's Java 101. anything simple is viewed with suspicion.
14:21bbloomdnolen: oh ugh yeah, duh, right
14:21tgoossenslol
14:21tgoossensNo. Just implicitly expressing that I like the way things go in clojure :D
14:22uvtcAye, she's a fine ship she is.
14:22mpantgoossens: not inherently wrong to use instanceof or switch, though I'm sure -- like most tools -- they can be misused
14:23mpanand 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:25FrozenlockTimMc: You example works fine, but for my class I get an error saying that it doesn't have the .newInstance method o_O
14:25TimMcThen you don't have a Class.
14:26TimMcor you're trying to give it more args
14:26mpanjust curious what you get if you ask it for its type
14:26bbloomdnolen: 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:27bblooms/codeine/codegen/
14:27tgoossensmpan: Please don't tell me this is good: http://pastebin.com/edNSBXFX
14:28dnolenbbloom: sure, I'm pretty sure Herwig's patch will fix the issue. It just pushes gensym into the compiler and out of analysis.
14:28bbloomdnolen: yup, let me know how it goes
14:28dnolenbbloom: rather you patch removed it, and Herwig's patch put it back in the backend.
14:28mpenetRaynes: can lazybot run on password protected servers? (I would like to run it on a grove.io server)
14:28mpantgoossens: meh, not particularly emotional about it one way or the other
14:28tgoossenshehe
14:28mpenetRaynes: it seems it is not the case after a quick look, but I prefer to ask before diving into the source
14:28dnolenbbloom: if you're referring to some of the thoughts you were working out earlier go for it.
14:29bbloomdnolen: that's what i get for trying to be clever :-)
14:29tgoossensbut it's out of context of course
14:29mpanyou 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:29tgoossensproblem: time damnit
14:29bbloomdnolen: 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:30bbloomdnolen: in such a case, there are no body statements to get the :env from
14:30bbloomdnolen: if you need the :env in which x is a local, you don't have an easy way to get that
14:30mpantgoossens: 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:30TimMcswitch statements are always trouble.
14:30bbloomdnolen: one possible solution would be to say that there's really an implicit do there: (let [x 1] (do))
14:30TimMcSometimes there's not much you can do, though.
14:31bbloomdnolen: however, a similar situation applies to def
14:31tgoossensoh
14:31tgoossensdon't forget
14:31tgoossensthe code isn't working :p
14:31mpanwell, that's a separate issue which you all must work hard to resolve
14:31bbloomdnolen: so my thought is that there really needs to be a before and after :env
14:31TimMcIf Java had syntactic abstraction, you could write "xcase", which would be like "case" with an implicit break at the end of each clause.
14:31mpanit will occur regardless of your choice of language or style
14:32bbloomdnolen: @namespaces is really just the after-env
14:32bbloomdnolen: does that make sense so far?
14:33bbloomdnolen: i need to step out for a minute, so i'll just say the last bit and hopefully that makes sense without clarification
14:34bbloomdnolen: 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:34bbloomdnolen: emitting a var could have an after-env with a binding in it
14:35bbloomdnolen: 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:36dnolenbbloom: yeah not completely following. you should probably write this up somewhere.
14:37dnolenbbloom: also probably needs a more interesting use case then gen-syming let bindings for me to see the point.
14:37bbloomdnolen: 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:37dnolenthen avoiding gen-syming I mean.
14:38hiredmanemitting strings is pretty meh
14:38bbloomhiredman: 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:39bbloomgotta run
14:41hiredmanemitting gclosure ast nodes directly is not an alternative that occured to me, very interesting
14:43tufflaxI'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:45ro_stdoes (partial) evaluate its args?
14:45TimMcIt's a fn, so yes, the args are evaluated.
14:45jonasacis there are reasonable way to tame the stacktraces from running lein test, everytime a test fails my screen fills up
14:46ro_stok 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:47technomancyjonasac: yeah, but it involves convincing chouser to release longbottom
14:48mpenetRaynes: nevermind, I managed to get it working
14:48jonasactechnomancy: btw thanks for leiningen, new to clojure, was having a really rough time with everything until i met leiningen last night :)
14:49technomancyheh; cool =)
14:49zerokarmalefttufflax: i think you want reduce instead
14:50tufflaxzerokarmaleft yeah that works thanks
14:51dnolenhiredman: it could be interesting, tho it's not at all clear if AST rep is something you can expect to be stable.
14:51technomancywow, sometimes you just don't realize how good you have it: https://mobile.twitter.com/jreichhold/status/263338857397907456?p=v
14:52AdmiralBumbleBeejava programmers have it good
14:52eggheadhey 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:52technomancyjob security?
14:52AdmiralBumbleBeethey're not using C, that's a pretty massive thing to be happy about
14:54ro_sttechnomancy: find-file-in-project is now precisely what i need. thanks for your help yesterday
14:54ro_stand you, mpenet
14:54FrozenlockTimMc: http://stackoverflow.com/questions/9167457/in-clojure-how-to-use-a-java-class-dynamically?lq=1 The constructor fn solved all my problems :)
14:54hiredmandnolen: 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:54Frozenlock/s/constructor/construct
14:55ro_stAdmiralBumbleBee: 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:55technomancyI don't use it very often
14:55ivansurely it's not a leak if you lose your references to the map?
14:56uvtcjuxt?
14:56clojurebotjuxt is a little hard to grok but it's the best thing ever
14:56ro_sti still don't understand juxt
14:57ro_stmacros are easier
14:57normanrichardsanyone know how to invoke a db function using clojureql? for example, something to the effect of: (conj! events {:name "blah" :occured_at "now()"})
14:57bbloom,((juxt inc dec) 5)
14:57clojurebot[6 4]
14:57bbloomthat's the best example i've come up with for juxt
14:58ro_stok, so return a seq of the results of each successive fn to the args
14:58uvtcThe example that the just docs include makes sense to me: ((juxt a b c) x) => [(a x) (b x) (c x)]
14:58ro_styeah
14:58technomancyro_st: no, return a function that calculates such
14:59ro_stoh, yes
14:59technomancy,(map (juxt inc dec) (range 5))
14:59clojurebot([1 -1] [2 0] [3 1] [4 2] [5 3])
14:59tomoj&((juxt min max) 1 2 3)
14:59lazybot⇒ [1 3]
14:59bbloomuvtc: that makes sense to me too, but not everybody has mastered what i'd call "haskell signature reading skills"
14:59ro_stwhere have you found good use for it, technomancy?
15:00ro_stwait, i can use juxt to turn (map fn1 (map fn2 coll)) into (map (juxt fn1 fn2) coll) right?
15:00technomancyit works great when paired with destructuring
15:00technomancyyou can turn 3 lines in a let into one
15:00technomancyro_st: no, that's comp
15:00ro_stoh. right
15:01TimMcfrancis-: clojure.lang.Reflector/invokeConstructor looks good.
15:02TimMcfrancis-: Sorry, that was meant for Frozenlock.
15:02dnolenhiredman: 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:03bbloomdnolen: i pseudo-code-ported a few of the uglier emit methods to pure functions & they saw substantial reductions in size.
15:03bbloomdnolen: 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:03bbloomdnolen: clearly very low priority, but IMO worth exploring
15:06hiredmanit is kind of amusing that compilers are often pointed to as an example of functional programming, but clojurescripts compiler is not a function
15:06dnolenbbloom: 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:08bbloomdnolen: 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:08dnolenbbloom: http://code.google.com/p/closure-compiler/source/list?path=/trunk/src/com/google/javascript/rhino/Node.java&amp;start=2249, this is the relevant file no?
15:09bbloomdnolen: one of them
15:09bbloomdnolen: the Node class has lots of pseudo nodes for optimizations, etc
15:09bbloomdnolen: see also http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/rhino/IR.java?spec=svn1996&amp;r=1996
15:10dnolenbbloom: so that file the only one we would need to deal w/?
15:11bbloomdnolen: maybe? i looked at this a long while ago
15:11bbloomdnolen: this is also why i asked about the js* form
15:12bbloomdnolen: b/c there is no obvious way to do the js* form in a glosure AST world
15:12bbloomdnolen: 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:14dnolenbbloom: 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:14bbloomdnolen: my guess? initially, slower, but ultimately faster
15:14bbloomdnolen: slower since you go from cljs ast -> js ast -> string -> js ast -> string
15:15bbloomdnolen: but once *all* of the emitter is converted, you can call the compiler directly
15:15bbloomdnolen: you won't need to run the js parser
15:15dnolenbbloom: the slowest thing about closure isn't the parser - it's advanced optimization. it dominates everything.
15:16bbloomdnolen: i believe that :-)
15:16bbloomdnolen: we could probably also get free source maps
15:16bbloomdnolen: i believe the gclosure Node class is semi-mutable
15:16bbloomdnolen: with the only mutable bits being things like line/column metadata
15:16dnolenso in the worst case everything everything else gets slower, advanced optimization roughly the same.
15:17dnolenbbloom: yes free source maps would be nice.
15:17bbloomwe could pretty easily wrap the static public methods if IR.java to call .setLine on each node
15:18bbloomdnolen: i don't think worst case is slower. i think slower is just an intermediate step
15:18bbloomonce you're a 100% AST step, you cut out the disk completely
15:18bbloomand there is no to string or from string intermediate step
15:18bbloomwhich, intuitively, has to be faster? right :-P
15:19bbloombut like you said, advanced optimizations remain the bottleneck
15:19bbloomso the primary advantages would be functional purity, code size reduction, ease of reasoning, and free-ish source maps
15:19bbloomclear disadvantage would be the lose of js*
15:19bbloomhowever, it could be replaced by js** which returns AST nodes ;-)
15:20goraciomy compilation time of cljs file with 200 loc takes 20-25 sec usually with simple or whitespaced optm
15:20dnolenbbloom: right
15:20tomojgoracio: with a fresh jvm?
15:20bbloomi have a branch somewhere that i attempted to eliminate js*
15:20bbloomlet me look...
15:20goraciobut cljbuild auto take 4-5 sec
15:20tomojah right
15:20dnolengoracio: you mean 25000+200 lines of JS
15:21goraciodnolen: i guess so don't understand why 25k needed
15:21bbloomdnolen: see https://github.com/brandonbloom/clojurescript/commits/no-js-form
15:21aaelonyn
15:22hiredmanI have a 50 line cljs file that takes 17-20 seconds in andvanced mode
15:22goraciotomoj: fresh jvm ? 7 version i use
15:22dnolengoracio: because you 200 lines of CLJS wouldn't do anything w/ the other 6500 lines of cljs.core
15:22dnolenw/o
15:22bbloomdnolen: it would also be nice to be able to memoize the output of a compilation unit
15:22bbloomdnolen: so in the case of core, we could keep the AST in memory :-)
15:23dnolenbbloom: that's true
15:23bbloomsee those last 3 commits on that branch
15:24goraciodnolen: 6500 ok and what for others ? _))
15:24dnolengoracio: sorry, not following. others?
15:24TimMcdnolen: 6500 < 25000
15:25TimMc15:20 < dnolen> goracio: you mean 25000+200 lines of JS
15:25goraciodnolen: 25k lines minus 6500 18,5k left
15:25dnolengoracio: sorry just mistyped.
15:25bbloomdnolen: step one is minimizing usage of js*
15:26dnolengoracio: 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:26bbloomdnolen: which is already a goal :-)
15:26TimMcgoracio: It's just like how your Clojure program won't run without the Clojure JAR file being included.
15:26bbloomalthough js* to js/ isn't much of a win, heh
15:26goracioactually it's google closure code if we look at it in browser
15:26dnolenbbloom: yeah, I think there's like 5 places in core, and the only other place we use it for inlining low level ops.
15:26bbloomdnolen: yup, i think we reaaaallly need better inlining support in cljs
15:26TimMcExcept with CLJS it can't be linked.
15:27bbloomdnolen: we do a lot of inlining hacker via macros, where true inlining could help
15:27dnolenbbloom: why?
15:27bbloomdnolen: b/c i feel like a human compiler
15:27bbloomdnolen: isn't that reason enough to do anything in the lisp world? :-)
15:27hiredmansilly bbloom, humans are computers, not compilers
15:28dnolenbbloom: have you needed to do much inlining w/ when writing CLJS?
15:28bbloomdnolen: no, just in core
15:28TimMchiredman: Nonsense, I've been asked to compile a report before at work.
15:28dnolenbbloom: so my question remains, why?
15:28ivanV8 inlines small functions
15:28hiredmanTimMc: as a computer you where asked to run a compiler routine
15:28hiredmanwere
15:29dnolenI haven't heard of anyone doing writing their own inlining macros in CLJS since we cover the bases
15:29bbloomright, core takes the suffering so that real apps don't have to
15:29bbloombut i want to eat the cake too: we shouldn't need a macro-version of every major bit operation in core :-)
15:30dnolenbbloom: in so many ways not a priority. That likes 100 lines of code in core.clj
15:30bbloomdnolen: i wasn't proposing it as a priority :-)
15:30goracioso with clojure it appears that we can make pretty big apps without classes and objects stuff ))
15:31bbloomdnolen: i think minimizing js* usage should be, however
15:31goraciojust wrote pretty big app from scratch took about 2 weeks and it was pretty easy and fun
15:32dnolenbbloom: 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:32bbloomdnolen: what about core.clj ?
15:32bbloomdnolen: did you look at that random old branch i linked to?
15:33dnolenbbloom: yes we already talked about that - the inlining macros are the other case.
15:34bbloomdnolen: two separate issues. inlining vs js* usage. the js* operates on strings, not AST nodes
15:34bbloomdnolen: the inlining macros have various bugs, btw
15:34bbloomdnolen: max and min both evaluate their arguments multiple times
15:35dnolenbbloom: patches welcome ;)
15:35bbloomdnolen: instanceof evaluates it's arguments in reverse order
15:36bbloomdnolen: i apparently can't contribute any patches without simultaneously breaking everything ;-)
15:36dnolenbbloom: heh, low hanging fruit & compiler improvements not the same kind of patch :)
15:36dnolenbbloom: I'd happily take inlining macro fixes as one patch
15:37bbloomon a tangential personal note: i quit my job. anybody looking for a clojure dev in seattle? :-P
15:38dnolenbbloom: too bad you're not coming to the Conj
15:38TimMcbbloom: I'll keep an ear out. Does Seajure still exist?
15:39emezeskegoracio: I'm not sure "pretty big app" and "in two weeks" are compatible facts :P
15:39bbloomTimMc: 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:40hiredmannext seajure meeting is this thursday at u. zoka
15:40bbloomhiredman: 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:41hiredmanI may or may not be there, and I may or may not have a a clojure powered robot
15:41TimMcbbloom: Is moving to Finland an option? :-P
15:41goracioemezeske: it' all depends of course but if consider that it is my first project in clojure and func lang then it's ok
15:42bbloomTimMc: no, but SF or NY are on the table
15:42tomojbbloom: I'd love to hire you
15:42TimMcbbloom: I think ohpauleez's company does some Clojure stuff in NY.
15:42tomojbut can't afford you right now
15:43bbloomtomoj: heh :-)
15:43bbloomTimMc: paul moved to portland
15:43TimMcoop
15:43emezeskegoracio: 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:44tomojbbloom: hopefully that will change in ~3 weeks
15:44bbloomtomoj: what's your startup?
15:44bbloom(i presume it's a startup, if you're expecting a financial event like that, heh)
15:45TimMcWhy do you assume a startup? Maybe it's for homework help. :-P
15:46uvtchehehe
15:46bbloomthe ~3 weeks comment implied a financing to me, but maybe i've just been around too many startups
15:47TimMcOr maybe tomoj runs a turkey farm, and the Thanksgiving sales will provide money for the rest of the year.
15:48bbloomoh, this game is fun... maybe tomoj is planning a bank heist
15:49hiredmanmaybe he has been in contact with some helpful nigerians
15:49bbloomare there unhelpful nigerians?
15:49goracioemezeske: 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:50goracioemezeske: i think oop is overcompicated and there is a choice like clojure that is good )
15:53emezeskegoracio: I agree.
15:53tomojbbloom: pm?
15:55bbloomtomoj: anytime
15:58FrozenlockI 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:59bbloom,(doc float)
15:59clojurebot"([x]); Coerce to float"
16:00Frozenlocker.. yes.. I'm searching a more universal answer, I have many of those class requiring specific datatypes.
16:01andrewmcveighIf I want to use a worker queue in clojure, is the best option still a java BlockingQueue, or similar?
16:01bbloomFrozenlock: depends. do you have an interface to reify? can you just simply use a function instead of a method?
16:03FrozenlockWell I could wrap each class in a function, each making sure the type is correct and coercing them if needed.
16:03hiredmanandrewmcveigh: nothing wrong with a nice linkedblockingqueue
16:03FrozenlockI have ~15 of these classes.
16:04andrewmcveighhiredman: 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:05TimMcFrozenlock: What is it?
16:05Frozenlockbacnet4j
16:12jcromartieevery 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:24TimMcFrozenlock: Sounds like a Clojure wrapper might be really useful.
16:26jonasaccan somone point me in the right direction for using (binding) im following the examples, but still getting an IllegalStateExeption in the repl
16:26tomojbbloom: so cljs-cps could be used to implement something like http://taskjs.org/ , but is more powerful, right?
16:26FrozenlockTimMc: Yeah I think also... all these classes and subclasses are becoming really heavy in my code.
16:28jcromartiejonasac sure
16:30bbloomtomoj: precisely
16:32bbloomtomoj: the goal is more akin to C#'s async/await keywords
16:32AntelopeSaladif i do... (:require [compojure.response :as response]) , why doesn't it work when i call response/header later on?
16:32tomojhuh
16:32tomojasync/await seem like task.js to me
16:32jonasacjcromartie: 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:33AntelopeSaladnote: the code above is taken directly from the official github page for compojure
16:33tomojbut I never did c# - you get the full power of delimited continuations?
16:33bbloomtomoj: yeah, pretty much the same thing
16:33jcromartiejonasac: yes, you need to add the :dynamic metadata to your dynamic vars
16:33jcromartie(def ^:dynamic x 0)
16:34jonasacow, the book didnt mention that :p
16:34tomojah, so your main use case for cps is just async/await? me too
16:34jcromartiejonasac: it's new-ish
16:34xeqiAntelopeSalad: are you looking for ring.util.response/header ? http://ring-clojure.github.com/ring/ring.util.response.html#var-header
16:34bbloomtomoj: 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:35jcromartiejonasac: 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:35hiredmandifficult to see the difference
16:35jonasaci 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:35AntelopeSaladxeqi: yep, thanks -- then compojure.util :as response to call it as response/header?
16:35jonasacwhile == whole
16:35bbloomtomoj: 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:35jcromartiejonasac: I think it's since 1.3
16:35jcromartiejonasac: what book?
16:35AntelopeSaladoh wait, it's ring not compojure hah
16:35jonasacclojure in action
16:35bbloomtomoj: there are a few other use cases for a CPS transform
16:35jonasacchapter 8.2
16:35bbloomtomoj: tail call optimizations is one
16:36bbloomtomoj: another is composeable (aka delimited) continuations
16:36bbloomtomoj: that is shift and reset
16:36FrozenlockTimMc: I've often use java interop, but is there some rules of thumb one should follow when doing a wrapper?
16:36jcromartieyeah Clojure 1.3 came out just before Clojure in Action
16:36jcromartieI think
16:37jcromartiejonasac: typically you don't need a whole lot of dynamic vars
16:37jcromartieand you can also use let
16:37bbloomtomoj: 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:37AntelopeSaladxeqi: 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:37AntelopeSaladthey make a call to response/header
16:38tomojseaside-esque?
16:38xeqijonasac: if you're just wanting to redefing functions for a test you might want ##(doc with-redefs)
16:38lazybotjava.lang.SecurityException: You tripped the alarm! with-redefs is bad!
16:38xeqihah
16:38bbloomtomoj: yeah, that smalltalk framework
16:38bbloomtomoj: simplest case is pg's "arc challenge" http://paulgraham.com/arcchallenge.html
16:39xeqiAntelopeSalad: it should be that function but hard to tell without the paste showing how its used
16:39AntelopeSaladk, one sec
16:40AntelopeSaladwhat was that site that supported clojure highlighting for pastes?
16:40AdmiralBumbleBeerefheap
16:40AntelopeSaladthanks
16:40AdmiralBumbleBeeand gist
16:41eggheadanyone itc going to the LA clojure meetup this thursday?
16:41AntelopeSaladxeqi: https://www.refheap.com/paste/6268 , the important bits are probably lines: 12, 16-21 and 35
16:41AntelopeSaladi also don't know if 34 will work, will worry about that later
16:41AntelopeSaladthe repl is crying that compojure.response is already aliased
16:42xeqiAntelopeSalad: did you restart your repl after aliasing it?
16:43xeqior remove the ns?
16:43jonasacxeqi: with-redef was just what i needed :)
16:43AntelopeSaladevery time i make a change i run: (require 'hello-world.core :reload-all) in the repl
16:43AntelopeSaladthat is when the alias problem comes up
16:43xeqiif I understand correctly, that doesn't remove the old ns and redo it
16:43AntelopeSalad"alias response already exists in the namespace, aliasing compojure.response"
16:44AntelopeSaladi don't even see how that's aliased though
16:44AntelopeSaladbecause i never aliased it
16:44xeqiyou didn't load the file with it aliases as described in your original question?
16:45AntelopeSaladload it in what sense? it never properly gets loaded because of the alias error
16:45AntelopeSaladi am running lein repl manually
16:45AntelopeSaladstart the repl, do the reload all command, start the server
16:46AntelopeSaladit seems you're right though, i really don't know what i'm doing haha
16:46AntelopeSaladsomeone recommended to :reload-all as the "right" way to reload code
16:47AntelopeSaladi just changed :as response to :as responsefoo and then changed my fn call to responsefoo/header and it failed with no such var
16:47AntelopeSalad(after doing a reload-all)
16:47AntelopeSaladthat confirms that reload-all isn't pickuping up a NS change right?
16:47AntelopeSalad*picking
16:49TimMcFrozenlock: I don't have any specific recommendations, sorry.
16:49TimMcI guess just try to make something that hides all the insanity that it makes sense to hide.
16:56AntelopeSaladxeqi: 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:56AntelopeSaladproblem is, the guy doesn't reference ring-resp anywhere -- why is he even including it?
16:59xeqiAntelopeSalad: most likely was meaning to replace L28-29 and forgot about it
17:00AntelopeSaladany thoughts on how to solve this?
17:00AntelopeSaladi tried reloading with just (use 'ns) in the repl, same aliasing error as before
17:01jcromartieAntelopeSalad: sounds like :reload-all is broken
17:01xeqidid you restart your repl?
17:01AntelopeSaladno, i did not restart it
17:01jcromartiexeqi: the goal is to avoid restarting it
17:02AntelopeSaladi'll restart it though now and see
17:02AntelopeSaladsame problem
17:02AntelopeSaladhave to go, zzz... i didn't expect something so silly to be 2 hours of debugging haha -- will try again tomorrow
17:03AntelopeSaladif 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:04jcromartieAntelopeSalad: which part of ring?
17:04jcromartieAntelopeSalad: sorry I haven't followed the whole discussion
17:06jcromartieall this talk about continuations in web apps… what about representing a HTTP session as a lazy seq?
17:07jcromartiethat the session is a single sequence of requests -> responses
17:10TimMcContinuation IDs in URLs work great until you want to bookmark something.
17:11TimMcor use back/forward after being AFK for 15 minutes
17:12bbloomoh 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:13jcromartieheh
17:14ivanhey, if you have a durable lazy seq...
17:14emezeskeYeah, the only anoying thing is the non-durability
17:15jcromartiesame problems as seaside though
17:15jcromartieand only slightly less debuggable
17:15bbloomi think it's a fundamentally failed approach b/c it's effectively the opposite of conservative garbage collection
17:15technomancyheh; "HREF considered harmful"
17:15bbloomyou have external demands on resources that you don't know about
17:15jcromartieI dunno, I liked the idea of Seaside but I had a lot of issues
17:15jcromartiehm, yeah
17:16dnolenjcromartie: the continuation thing is actually good for something very specific that no-one bookmarks - complex form flows
17:16bbloombut i think that applies to sessions, full stop.
17:16bbloomdnolen: 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:17bbloomthe nature of http is stateless
17:18dnolenbbloom: 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:18bbloom*shrug* session state is a hack and always will be
17:19bbloomthe only way around it is to have a persistent connection (or some kind of long polling to simulate a persistent connection)
17:19jcromartiethen might as well say all sessions such
17:19jcromartiesuck
17:19bbloombut even then, you need to support disconnect/reconnect
17:19bbloomagain, consider the long survey and a closed laptop
17:19dnolenbbloom: 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:20dnolencatching up
17:21bbloomi think that blurring the line between the server and the client is fundamentally a bad idea
17:22bbloomi much rather a rich client app that maintains some in memory state and a server that is either totally stateless or connection oriented
17:22hiredmanfallacies of network computing?
17:22bbloomtotally stateless --> session oriented
17:22bbloomer i mean totally stateless --> totally session-less
17:23bbloomhiredman: yup: http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing
17:37tomojoh, good, I can stop thinking about the arc challenge now :)
17:40bbloomtomoj: it's still a worthwhile mental exercise :-)
17:50TimMcOh man, I just read that. So ridiculous!
17:51TimMcIf you can have an arbitrary web lib off to the side, there's no challenge.
17:53jcromartieThe 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:53jcromartieI mean, that's all I can gather from the (defop …) form
17:56TimMcYeah, right after saying that it's general purpose.
18:01Frozenlo`Can I use extend-type on a class to control how a new instance is created?
18:01gfrederickslike hook into the class's constructor?
18:03Frozenlo`gfredericks: Yeah, like that :P
18:04Frozenlo`I suppose I could make my own protocol with a method 'new2'
18:04gfredericksI do not believe the jvm would go along with that plan
18:05gfredericksFrozenlock: even then it'd be a method on instances rather than the class
18:05gfredericksmaybe you could extend it to java.lang.Class if you don't mind the same behavior for all classes...
18:06gfredericksthen you'd have to instantiate via reflection...I really don't know a lot about this.
18:07bhenrywhat 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:07amalloy~partition
18:07clojurebotpartition is probably not what you want; see partition-all.
18:07bhenrythanks!
18:34etherealGhi, 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:35AimHereThe problems are rated Elementary, Easy, Medium and Hard or something
18:36AimHereYou could go by that
18:38tomojbbloom: yeah
18:42tomojI'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:47antares_Monger 1.3.3 is released: http://blog.clojurewerkz.org/blog/2012/10/31/monger-1-dot-3-3-is-released/
18:50tomojasync/await plus a little more..
19:30nDuffHrm.
19:30nDuffFor some reason nrepl.el is trying to use complete.core, but not require'ing it
19:30nDuffso I have to explicitly do that myself.
19:34brainproxynDuff: 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:36technomancyhm; looks like it changed since I originally added completion
19:36technomancymy version requires it correctly =)
19:36brainproxytechnomancy: any luck with your attempt to get namespace (and dependent namespace) reloading working?
19:36brainproxyi.e. when using nrepl.el
19:37nDuffbrainproxy: I don't use nrepl-
19:37nDufferm, nrepl-jack-in at all, so can only speak to the latter case.
19:37technomancybrainproxy: I got it working, but it was ugly. I don't remember if it got merged to master.
19:37brainproxynDuff: okay sure; how are you invoking the nrepl server?
19:38brainproxyi mean, are you doing so from the command line w/ lein, or are you embedding it w/in some project
19:38nDuffNeither
19:38nDuffUsing gradle because lein doesn't support Ivy
19:39nDuff...my build.gradle invokes clojure.tools.nrepl.cmdline/-main with args ['--port', '6678']
19:39brainproxyokay, maybe i'm confused; you are using nrepl.el to connect to an nrepl server?
19:39brainproxyah gotcha
19:40brainproxytechnomancy: have you had luck with ritz-swank?
19:41technomancyhaven't tried it
19:41brainproxyI've made several attempts to get it working to no avail; but have no problems with swank-clojure
19:41brainproxyokay
19:44scottjbrainproxy: I had trouble with it last time I tried. time before that it worked great. I'd contact author he's very responsive
20:46holohi
20:46mpanhi
20:47Scriptorhey holo
20:49holohey Scriptor
20:49mpanBy 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:52gfredericks~
20:52clojurebotTitim gan éirí ort.
20:53mpanhm, internet connection flaking out on me
20:54mpanbtw what's ~ meant to do? random quote from the bot's collection?
20:54gfredericksno I sent it accidentally
20:54mpanis there documentation of the bots' commands?
20:54gfrederickswas playing with the ssh client interface
20:54antares_~maven
20:54clojurebotHelp, I'm trapped in an XmlFactoryFactory!
20:54gfredericksI think "~" asks clojurebot to comment on the empty string about which he apparently doesn't know anything
20:54gfredericksclojurebot: is an empty string
20:54clojurebotOr, for instance, foo.toString().length() is (.. foo toString length)
20:54mpan~test
20:54clojurebotforget latest is 1382
20:55gfredericksclojurebot: |is| an empty string
20:55clojurebotread-string |is| as unsafe as eval unless *read-eval* is bound to false.
20:55gfredericksI apparently don't know how to make him respond to "~"
20:56mpanwait huh? when do you eval at read-time?
20:56mpanI'm blanking on any examples
20:56gfrederickswhen you use #=
20:57gfredericksI don't know of any use cases that aren't addressed by the newer data readers
20:57mpansorry, but what's hash-equals?
20:57gfredericksreader eval :)
20:57mpanthat sounds scary
20:57gfredericksyou'll have to try it at the repl as I think the bots disable it
20:57gfrederickstry (read-string "(1 2 #=(+ 3 4) 5)")
20:58mpanis it the same as eval except when?
20:58gfredericksI think so
20:58mpanwhat's the need to upset the usual semantics of read?
20:59mpanor rather, what was
20:59gfredericksI think just when you want to read in objects that don't have their own syntax
20:59hiredmantry (read-string "#=(+ (+ 3 4) 5)")
20:59gfrederickshiredman: that's slick; so it just supports top-level function calls?
20:59mpanwhat are "objects that don't have their own syntax"?
21:00gfredericksmpan: e.g., records
21:00gfredericksqueues
21:00gfredericksfinger trees
21:00mpanwait huh?
21:00hiredmangfredericks: I think, I forget, it's been I while since I've paid attention to eval reader
21:00gfredericksI've never had a real use for #=
21:00hiredmanrecords have a syntax now
21:00gfrederickshiredman: looks like it also calls macros as functions
21:00mpaneven so, why would you want them at read-time?
21:00mpanrather than at eval-time?
21:01mpanlike, why would you want the eval-ed representation?
21:01gfredericksmaybe for data that you're only reading rather than evaling?
21:01hiredmanmpan: because the reader can read other things besides code
21:03gfredericksso 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:03gfrederickse.g., #=((comp inc +) 4) doesn't work either
21:07CubicHow do I supply a type hint for a non-primitive array?
21:08mpanall right, thanks guys
21:09amalloy&(class (into-array ["x"]))
21:09lazybot⇒ [Ljava.lang.String;
21:11Cubic&(defn [x] ^[Ljava.lang.String x)
21:11lazybotjava.lang.RuntimeException: Unmatched delimiter: )
21:11CubicThat's not valid clojure
21:11mpanwhy does (read-string "{:a {:b :c}}") produce what looks to be an exception at the repl yet still yields the expected result?
21:11mpanor, what does the bot say about ##(read-string "{:a {:b :c}}")
21:11lazybot⇒ {:a {:b :c}}
21:12gfredericksmpan: no idea what sort of exception you're seeing
21:12gfredericksmpan: works fine for me
21:12mpanuh, I can't even reproduce it
21:12mpanhttps://www.refheap.com/paste/6272
21:13mpanI would expect it to be deterministic, but, well... I guess something happened
21:13gfredericksI feel like it could have been some kind of stale exception from the previous command
21:13gfredericksI've had spooky repls like that before
21:13gfredericksnot lately
21:14mpanprevious line was a genuine exception produced
21:14gfredericksbut anyhow that exception looks like the one generated by my last reader-eval example
21:14mpanyes that
21:14gfredericksdid it print the exception twice then?
21:14mpanyes
21:14gfredericksheckiphino
21:14mpanoh but, the first time was printing it as the result
21:14gfredericksah ha
21:14mpanand the other time was printing it as an error message
21:15gfredericksspooky repl still
21:15mpani.e. the first one was prefixed by #< and the second time wasn't
21:15mpansuggesting one was the toString() and the other was... uh... something
21:20mpangfredericks: wait, would that constitute a repl bug? if so, should I report it somewhere?
21:29gfredericksmpan: probably; repls are complicated. I wouldn't know what to suggest.
21:31mpanthe repl that lein uses is at its core nrepl? so this gets reported to nrepl?
21:33antares_mpan: it uses REPLy
21:34mpanis REPLy on top of nREPL?
21:35mpanoh, hm
21:35Cubiclein repl does create an nrepl server if I'm not completely mistaken
21:35xeqireply is a frontend to nrepl, think client server
21:35mpanso if there's what appears to be a bug in what appears to be the repl itself? is that in nrepl?
21:35Cubicamalloy_: thanks, got it to work
21:39xeqimpan: I'd start by filling it with reply, trptcolin is good about tracking things down and pushing it to nrepl when needed
21:39xeqithough (read-string "{:a {:b :c}}") works fine in `lein repl` for me
22:03amalloymy 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:05gfredericksat the very least his previous command, which actually generated the exception, would be needed
23:34lil`nbv4when 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:37technomancylil`nbv4: best to get on leiningen 2
23:37xeqilil`nbv4: do you have :plugins [[lein-ring "0.7.5"]] in your project.clj?
23:42lil`nbv4xeqi: I do now :) i am new to clojure, thanks
23:46xeqithen I also recommend using lein2