#clojure logs

2011-06-12

01:09grantmSay I want to do (new java.awt.Color my-list) where my-list is (255 0 0), so that I get (new java.awt.Color 255 0 0) in the end. The web says generally the right way is to use apply, but I can't seem to get it to work here (it gives a strange error). How do I do what I want?
01:10tomojfirst, (java.awt.Color. 255 0 0) is more idiomatic (just some syntax sugar for what you wrote)
01:10tomoj&(apply #(java.awt.Color. %1 %2 %3) [255 0 0])
01:10sexpbot⟹ #<Color java.awt.Color[r=255,g=0,b=0]>
01:11tomojugly, but works
01:11tomojyou can't apply 'new' or constructors since they're not actually functions, but you can create a function that just calls the constructor and apply it
01:13tomoj&(letfn [(color [[r g b]] (java.awt.Color. r g b))] (color [255 0 0]))
01:13sexpbot⟹ #<Color java.awt.Color[r=255,g=0,b=0]>
01:13tomojsomething like that could work too
01:17grantmthanks a lot! but all these ways seem to hardcode the number of arguments. is there a general way to not do that? (i guess you could build a macro for it?)
02:42Scriptor`hi everyone
11:56mudgehello
11:56mudgewhat is an "associative collection" ?
11:57mudgewhat does it mean if a data type is associative?
12:03mudgeanybody here today?
12:07mudgehey halfprogrammer
12:07mudgehey, how do I found out if a value is a sequence or not?
12:07halfprogrammerHi
12:08halfprogrammer(seq? BLAH)
12:09halfprogrammermudge: when you say seq, among collections (list, vecotrs, map and set) (seq? X) returns true only for list
12:09halfprogrammer,(seq? [1])
12:09clojurebotfalse
12:10halfprogrammermudge: If you are interested in getting true for the rest of the collection types too then use coll?
12:10halfprogrammer,(coll? [])
12:10clojurebottrue
12:11mudgethanks halfprogrammer
12:11TimMcmudge: Associative means there are key-value pairs.
12:12mudgeTimMc: oh, okay, thanks
12:12mudgethat explains it
12:12TimMcMaps (dicts in other languages) are the classic example.
12:12mudgeTimMc so vectors are also associative then, because vectors have numeric indexes
12:12TimMcYou might be able to call vectors associative (treating indices as keys) but that might be a stretch.
12:13mudgeyea!
12:13TimMcI think not, though -- maps are primarily accessed by key, not by ordering.
12:13TimMcWhat's the context?
12:13mudgeTimMc even sets could be considered associative because in a set the key of a value is the value
12:13TimMcThat's more of a hack, really. :-P
12:14mudgeyea
12:14mudgei am reading somewhere that says that all collections can be treated as sequences
12:14mudgeso I am wondering why all collections are not sequences if they can be treated as sequences
12:15mudgeso a map can be treated as a sequence?
12:15TimMcmudge: Sure!
12:15mudgewow, neat
12:16TimMc,(map identity {:a 5, :b 6})
12:16clojurebot([:a 5] [:b 6])
12:16TimMc,(type (first {:a 5, :b 6}))
12:16clojurebotclojure.lang.MapEntry
12:16halfprogrammermudge: as TimMc said don't rely on ordering of sets and maps
12:16mudgethen why are all collections not sequences?
12:16halfprogrammer,(sequential? {})
12:16clojurebotfalse
12:16TimMcmudge: It's the other way around -- sequences are collections
12:17TimMc,(coll? (seq '(1 2 3 4)))
12:17clojurebottrue
12:17mudgeTimMc, yes I see that
12:17mudgebut if all sequence functions can work on maps then why aren't maps sequences?
12:17__name__,(map #(* % 2) {1 2 3 4})
12:17clojurebotjava.lang.ClassCastException: clojure.lang.MapEntry cannot be cast to java.lang.Number
12:18__name__,(map #(%) {1 2 3 4})
12:18clojurebotjava.lang.IllegalArgumentException: Wrong number of args (0) passed to: MapEntry
12:18mudgelike duck typing, if it walks like a duck and quacks like a duck then it is a duck ----- so why aren't maps sequences if they sequence like a sequence?
12:18__name__,(map (fn [x] x) {1 2 3 4})
12:18clojurebot([1 2] [3 4])
12:19halfprogrammerI think we use the term sequence if there is a well defined order of iteration
12:19halfprogrammerthat is why vectors and lists are sequential
12:19halfprogrammeri mean (sequential? vec-or-lst) returns true
12:19__name__,(map (juxt first #(* 2 (second %)) {1 2 3 4})
12:19clojurebotEOF while reading
12:19__name__,(map (juxt first #(* 2 (second %)) {1 2 3 4}))
12:19clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$map
12:20__name__,(map (juxt first #(* 2 (second %))) {1 2 3 4})
12:20clojurebot([1 4] [3 8])
12:20mudge(seq '[4 5])
12:20mudge,(seq '[3 4])
12:20clojurebot(3 4)
12:20mudge,(seq? '[3 4])
12:20clojurebotfalse
12:21mudgehalfprogrammer: a vector is not a sequence
12:21__name__What's it with quoting the vector?
12:21halfprogrammer,(sequential? [3 4])
12:21clojurebottrue
12:21__name__That does not really make sense.
12:21__name__,(seq [3 4])
12:21clojurebot(3 4)
12:21mudgehalfprogrammer, try using seq?
12:21halfprogrammerseq? returns true for lazy sequences, I think
12:22thorwilhmm, using (defmulti valid-item-range #(nil? %)) things work as expected, but would be more readable in inversion. (defmulti valid-item-range #(not (nil? %))) and flipping true/false on the methods does not work here 0.o
12:26TimMcmudge: but a vector is Seqable
12:27TimMcThat is, it supports taking (seq) of it.
12:27mudgeOkay, but why is a map not a sequence if all the sequence functions work on it?
12:28TimMcmudge: (first) calls (seq) on its argument.
12:28mudgeTimMc --- I seeeeee, so a map doesn't support the sequence functions until seq is called on it
12:29TimMc,(type (seq {}))
12:29clojurebotnil
12:29TimMc,(type (seq {:a "not empty"}))
12:29clojurebotclojure.lang.PersistentArrayMap$Seq
12:29__name__,(seq {:a :foo})
12:29clojurebot([:a :foo])
12:29TimMc,(type {:a "not empty"})
12:29clojurebotclojure.lang.PersistentArrayMap
12:29TimMcYou get back a lightweight iterator over the map, basically.
12:30mudgeTimMc: i see, thanks
12:30TimMcNow that I tihnk about it, that's one of the things that tripped me up at the beginning too.
12:31TimMcmudge: NOw reread http://clojure.org/sequences -- it will probably make more sense.
12:31mudgeTimMc: okay, thanks
12:32TimMcI have to read the clojure.org pages more than once to really internalize the ideas, and it helps to bang my head against some code in the meantime. :-P
12:33mudgeTimMc: yea
12:33mudgeTimMc: do you have clojure stuff on github? i'm curious
12:33TimMcyep, though I can't vouch for the idiomatic-ness of it :-)
12:33halfprogrammer:P
12:34TimMchttps://github.com/timmc/CS4300-hw6 <- a ray tracer I made for a computer graphics class
12:34__name__neat
12:34__name__clojure raytracer
12:34TimMcSee the README for a link to a better one. :-P
12:34mudgecool
12:35TimMcI did all my CompGraph assignments in Clojure that semester.
12:35__name__It shows how Clojure still scares me :)
12:36TimMcOoh, a github bug!
12:36TimMcI have a file with a ? in its name.
12:36__name__github is bugged
12:36__name__Milestones are garbage.
12:38TimMcTry going to either of the first two files in this directory: https://github.com/timmc/CS4300-hw6/tree/master/dev
12:38TimMcI sent them a bug report.
12:38__name__Haha
12:39TimMcmudge: Oh, and you may wonder how ##(seq "foo") works, given that j.l.String doesn't implement Seqable... I suspect protocols are involved.
12:39sexpbot⟹ (\f \o \o)
12:40TimMcEither that or special-casing.
12:42mudgeTimMc: since String doesn't implement Seq, it looks like Seq turns the string into a list of characters
12:42TimMcYeah, I'm just wondering how it recognizes it.
12:42TimMchmmm...
12:43TimMc,(sequential? "foo")
12:43clojurebotfalse
12:43mudgeTimMc: maybe it recognizes it by checking to see if it is a String type
12:43TimMcOK, so there's ISeq, Iterable...
12:44TimMcand I still don't know the difference between seq? and sequential?...
12:46mudgeTimMc: me either
12:50__name__,iterable?
12:50clojurebotjava.lang.Exception: Unable to resolve symbol: iterable? in this context
12:51mrBliss`seq? is true when the argument is a sequence (generated by a seq call on something non empty). sequential? is true when calling seq on the argument would result in something for which seq? is true (unless it's empty).
12:52mudgemrBliss, thanks, where did you find that out?
12:53tomoj&((juxt sequential? (comp seq? seq)) {1 2})
12:53sexpbot⟹ [false true]
12:54TimMcmrBliss`: Not for strings.
12:54mrBliss`mudge: read the source
12:54TimMc,(seq? (seq "foo"))
12:54clojurebottrue
12:54TimMc,(sequential? "foo")
12:54clojurebotfalse
12:55mrBliss`TimMc: Yeah, it's not actually 100% correct, but in general (for [], {}, #{}...) it is ;-)
12:55tomojnot maps, see above
12:55TimMcwell, yeah...
12:55tomoj&((juxt sequential? (comp seq? seq)) #{1 2})
12:55sexpbot⟹ [false true]
12:55tomojnot sets either
12:56mudge&(+ 4 5)
12:56sexpbot⟹ 9
12:56halfprogrammerinteresting, I am looking at gvec.clj in clojure source file and apparently there is method for sequential. "clojure.lang.Sequential ;marker, no methods"
12:56mrBliss`tomoj: Ok, nvm :-)
12:57tomojsequential does not mean seqable
12:57mrBliss`https://gist.github.com/950144/51f669b6b62c386330e63071e8870853b0607acf
12:57tomojdidn't someone make a nice chart?
12:59halfprogrammermrBliss`: nice
12:59thorwilwhy does what i thought would be a simple boolean flip not lead to equivalent results: http://paste.pocoo.org/show/405093/ ?
12:59TimMcWho is swannodette again?
12:59grantmnoob question: if i do (defmacro my-apply (func args) (cons func args)), it works if i do like (my-apply + (1 2)) but fails if i do (define x (list 1 2)) (my-apply + x) because it doesn't know how to make a seq from a symbol. how do i let it know?
12:59mrBliss`TimMc: dnolen
13:00TimMcthanks
13:01tomojgrantm: is that clojure?
13:01grantmyup
13:01tomojparams need to be in vectors, there is no define
13:01grantmoh, i meant (def x (list 1 2))
13:01TimMcI don't think that's the issue.
13:01tomoj(defmacro my-apply (func args) ...) certainly shouldn't work at all
13:01TimMcgrantm: Run (macroexpand-1 `(my-apply + x))
13:02TimMcthen look at the cons
13:02grantmah my mistake, i was doing the params list with [], i just copied it wrong
13:02tomojah
13:03grantmi get "don't know how to create ISeq from symbol"
13:03mudgewhy does the reverse function return a list?
13:03TimMcgrantm: Ah, my bad.
13:03mudge&(reverse [3 4 5 6])
13:03sexpbot⟹ (6 5 4 3)
13:03TimMcRight, put a println in your macro.
13:03mudge&(type (reverse [3 4 5 6]))
13:03sexpbot⟹ clojure.lang.PersistentList
13:04thorwilmudge: maybe it's related to performance characteristics?
13:04mudgewhy does it return a list and not a vector because a vector was supplied as the argument
13:04TimMcgrantm: Your macro is getting arguments ['+ 'x], not ['+ '(1 2)]
13:04grantmright
13:05TimMcSo I think you want to use ~ to evaluate the second argument into a list.
13:09TimMcHmm, that's not quite right either.
13:09grantmTimMc: So the only way I can use ~ is if i'm returning something quoted (right?) I get as far as (defmacro my-apply [func args] `(~func ~@args)), but then when i run it i get the same error.
13:09halfprogrammerreverse code: (reduce conj () coll)
13:09TimMcgrantm: I think apply might actually be a special thing.
13:09halfprogrammerNot sure why it is implemented this way...
13:10grantmTimMc: Oh, that would be a shame...
13:12TimMcgrantm: Macros are syntax transformers, and apply actually works with values.
13:13grantmTimMc: How can I tell the difference in the future?
13:15TimMcI think it's really a rare example.
13:15manutterThe thing about macros is that they operate on the raw code *before* it actually executes
13:16TimMcLook at it this way... (my-apply + x) wants to take `+ and `x and turn it into (`+ `1 `2) ... but `x->(list 1 2) doesn't exist yet.
13:16manutterso if you say (defmacro foo [x] (bar ~x)), and then you call (foo y), the value for ~x evaluates to the *symbol* y, not the value of y
13:17grantmokay, i think that makes sense, thanks!
13:17manutterMacro expansion turns (foo y) into (bar y), and then the bar function actually looks to see what the current value of y is
13:17manutterthe macro-expander never checks the value of y
13:19TimMcgrantm: The macro expander doesn't even "know" that x is an available var...
13:20TimMcthat's the job of the implicit syntax-quote that happens when you call a macro.
13:20TimMc,`x
13:20clojurebotsandbox/x
13:22tomojimplicit syntax-quote?
13:25TimMctomoj: Well, when you call a macro, it gets fully resolved names.
13:26TimMcIt's getting the syntax from the reader, so you can think of it like syntax-quote having been applied to the expression.
13:27tomojis that new in 1.3.0 or something? or maybe I'm just not understanding what you mean
13:27tomojis this not a counterexample: (defmacro foo [x] (namespace x)) (foo +)
13:27TimMchrm
13:27TimMcmaybe I am wrong!
13:28TimMcBlah, I guess I was confusing it with something else.
13:28TimMcI should not give advice in here when I have not written Clojure in the past month. >_<
14:12mDuffMy expectation is that (identical? [:a] [:a]) would be true -- given as a clojure object is immutable, I would expect identical values to share identity -- but this isn't the case. What's the basis of my misunderstanding here?
14:13pdkit's probably producing a new vector object for each one
14:14mDuffWhat should I be using instead? I'm trying to find a common way to compare native collections in the API doc and coming up empty.
14:14dnolenmDuff: =
14:14mDuffahh; I tried ==, and it complained to me about being numeric-only
14:14dnolen,(= [:a] [:a])
14:14clojurebottrue
14:15mDuffthanks!
14:17TimMcmDuff: identical? is pointer comparison
14:17dnolenwhat's the best way to check if a class exists? Trying to work around the fact that 1.3.0 has ArityException and 1.2.0 does not.
14:18TimMc,(identical? 3 3)
14:18clojurebottrue
14:18TimMc,(identical? 300 300)
14:18clojurebotfalse
14:19TimMcdnolen: Reflection?
14:19TimMc:-/
14:21TimMcIf you don't mind try/catch, there's Class/forName
14:22TimMc,(Class/forName "ArityException")
14:22clojurebotjava.lang.ClassNotFoundException: ArityException
14:23dnolenTimMc: yeah I saw that
14:23TimMc,(Class/forName "String")
14:23clojurebotjava.lang.ClassNotFoundException: String
14:23TimMc,(Class/forName "java.lang.String")
14:24clojurebotjava.lang.String
14:28dnolenworks well enough for me.
14:34TimMcMake it a wrapper function I suppose?
14:34TimMcAlso, why do you need to reflect on this?
14:43dnolenTimMc: because ArityException doesn't exist in 1.2.0
14:43dnolenTimMc: I'm creating a macro to define the appropriate code depending on whether ArityException exists or not.
14:44fliebelHow would you explain the different attitude towards exceptions in Python and Clojure?
14:44dnolenfliebel: in Clojure exceptions are ... exceptional.
14:45dnolenfliebel: btw, the desire to make fact not be a macro has created a monstrous amount of macros :)
14:45fliebeldnolen: how so?
14:45dnolenfliebel: implementing IFn
14:48fliebeldnolen: rhickey just nuked this idea, but maybe you could generate a map and pass it to extend.
14:49dnolenfliebel: No I don't want any overhead.
14:50fliebeldnolen: Do you know if the exception thing is technical or just convention?
14:50dnolenfliebel: I remember being surprised at exception-for-flow-control in Python since I hadn't really seen that elsewhere.
14:50fliebel( http://jaynes.colorado.edu/PythonIdioms.html#eafp )
14:51dnolenI don't really like it.
14:51TimMcfliebel: a.k.a. the optimistic approach
14:56fliebelTimMc: What do you mean?
14:56TimMcfliebel: Assume there won't be an exception, but handle it if there is one.
14:57fliebelIt seems to be their primary type system.
14:58TimMcWhat does it have to do with their type system>
14:58fliebelTimMc: Duck typing, They don't check if something is something, but just try to act as if it where something.
15:00TimMcAh, yeah. That is kind of similar.
15:13dnolen400 lines of AFn.java in 48 lines of Clojure, https://gist.github.com/1021886
15:15dnolenactually more like 33 when you take out all the core.logic crap
15:18nickikdnolen, There is a question on stackoverflow about typesystems in Clojure. I am about to anwer it (you could have one in lisp but clojure doesn't is the short version) but i remember reading that core.logic does have something like that. Is that ture? (I have not looked at core.logic jet)
15:19dnolennickik: you could build something like that with core.logic yes, but I haven't done any work along those lines.
15:36mudgeClojure has a single primitive construct "loop"
15:36mudgebut what is a construct? how is it different than a form?
15:38dnolenmudge: it's one of the special forms, http://clojure.org/special_forms
15:38nickikmudge, there are just some things that the compiler has to know
15:39TimMcmudge: https://github.com/clojure/clojure/blob/1.2.x/src/jvm/clojure/lang/Compiler.java#L37
15:40nickikall the special forms are engouth to build the hole language. So if you want to reimplement the hole langauge you would have to build a compiler that just implements all the spezial forms (and a reader).
15:40TimMcwhole, even
15:41mudgebut what is the difference between a special form and a construct?
15:41fliebelHow many special forms does Clojure have? Scheme has 7, right?
15:42mudgeClojure also has exactly one primitive control flow construct:loop
15:42nickiki think its soemthing like 12
15:43fliebelHm, maybe if we drop Java interop, we can beat Scheme ;)
15:45Scriptordo the .net and javascript (if it exists) versions use the same operators reserved for java interop?
15:48tomojspecial-form-anchor references 16 special forms: #{'. 'def 'do 'fn 'if 'let 'loop 'monitor-enter 'monitor-exit 'new 'quote 'recur 'set! 'throw 'try 'var}
15:50TimMcmudge: "if" and "do" are also control flow constructs, as are "try" and "catch".
15:51TimMcfliebel: There's also the question of how many Clojure *needs*, vs. how many the compiler special-cases.
15:51mudgethen what is the difference between a form and a construct?
15:51TimMcSome of the special-cased forms could be implemented (less efficiently?) as macros.
15:51TimMcmudge: I'm not familiar with the term "construct".
15:54nickika form is basiclly everything right?
15:54TimMcyeah
15:54Scriptor`that's how I think of it
15:56TimMcA form is what the reader reads when you ask it to read one form. :-P
16:00leedaI have [sandbar "0.3.0"] in my :dependencies and I ran "lein deps", but when I try to do (:use sandbar.core) I get the following error: https://gist.github.com/b6d2e03a93eac874d048
16:01leedaIt looks like hiccup and sandbar are incompatible? I'm not even using hiccup in this namespace though.
16:06raekleeda: looks like this is a bug in sandbar that has been fixed in the snapshot version... https://github.com/brentonashworth/sandbar/commit/4c48185af93b5a86f5c5c38b8e2bcc8a8a676bc0
16:06leedaraek: Oh, cool. Thanks!
16:06raekthat's why you shouldn't use 'use' without :only, folk!
16:06leedayup
16:07TimMc"only use :use with :only"
16:17kephalehrm, so if one needs an entire namespace the proper thing to do is :require with :as?
16:17clojurebotnamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
16:25tomojTimMc: seems like the question of how many special forms we need is complicated by java interop
16:26tomojI mean, does it count if you can implement the rest of the special forms in terms of the basis you pick, or do you have to finish c-in-c?
16:34Tcepsa#join #emacs
16:34TcepsaWhoops, sorry >_<
16:36TimMckephale: Yeah, that seems to work pretty well. clojure.string (or whatever) :as s, etc.
16:37TimMctomoj: Yeah, I'm excluding Java interop, I don't know how it is even implemented.
16:37mudgeanybody know where the documentation is for ->>
16:37mudge?
16:38nickik,(doc <<-)
16:38clojurebotCool story bro.
16:38nickik,(doc ->>)
16:38clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."
16:38mudgenickik: I don't understand that documentation, is there further explanation on the web?
16:39mudgei don't know what " Threads the expr through the forms." means
16:40nickikits just puts the first argument you give it to the last position of the secend argument
16:41mudgenickik: can you give an example?
16:41nickik,(macroexpand-1 '(->> "test" (count))
16:41clojurebotEOF while reading
16:41nickik,(macroexpand-1 '(->> "test" (count)))
16:41clojurebot(count "test")
16:42Scriptormudge: check out clojuredocs.org
16:42nickik,(macroexpand-1 '(->> "test" (count) (+ 5) (- 4))))
16:42clojurebot(clojure.core/->> (clojure.core/->> "test" (count)) (+ 5) (- 4))
16:42Tcepsamudge: And then takes the result of _that_ and uses it as the last argument of the following function call, if there's another one, etc.
16:42leedahow would you write a function to turn all the keys of a map into keywords (if they are strings)?
16:44mudgei get it
16:44nickik(apply map (map (fn [[k v]] [(keyword k) v]) mymap))
16:44nickiksomething like that
16:45mudgeokay, what's the difference between -> and ->> ?
16:45nickikmudge, -> puts it to the second position, ->> to the last
16:45Tcepsanickik: should the first "map" in that be "hash-map"?
16:45nickikyes
16:46leedanickik: oh, thanks
16:46mudgenickik: thanks
16:46Scriptor,(doc hash-map)
16:46clojurebot"([] [& keyvals]); keyval => key val Returns a new hash map with supplied mappings."
16:47Scriptorhmm, why not call it map-hash?
16:48nickik(apply hash-map (mapcat (fn [[k v]] [(keyword k) v]) {"a" 1 "b" 2 "c" 3}))
16:49nickik,(apply hash-map (mapcat (fn [[k v]] [(keyword k) v]) {"a" 1 "b" 2 "c" 3}))
16:49clojurebot{:a 1, :c 3, :b 2}
16:49nickiknow it works
16:50tomojTimMc: well.. I meant more the java implementation than interop. e.g. "apply" isn't implemented using clojure's special forms, so is that cheating?
16:54hiredman,(let [m {:a 1}] (zipmap (keys m) (map inc (vals m))))
16:54clojurebot{:a 2}
16:55hiredman,(let [m {:a 1}] (zipmap (map name (keys m)) (vals m)))
16:55clojurebot{"a" 1}
17:00mudgeis it just me or is facebook really slow?
17:05nickikits build on php what did you think would happen?
17:14Scriptortbh, php that's compiled to C++
18:33void_meh, what should I do about cyclic load dependency?
18:33RaynesRedesign.
18:33void_that's the only way?
18:33RaynesYep.
18:41raekvoid_: in my expedience so far with Clojure, dependencies between namespaces with purely functional code tends to be cycle-free (or "layered") naturally
18:41raekthis is quite different from java, where classes often have to have cyclic dependencies
18:42void_I just didn't expect that having cyclic dependencies would break everything
18:42void_Just used to C.
18:42void_Anyway, I fixed it by redesigning.
18:53mudge (GET "/browse/*" request (let [[ns var] (str/split (get-in request [:params "*"]) #"/")]
18:53mudge (html
18:53mudge (layout
18:53mudge (namespace-browser (namespace-names))
18:53mudge (var-browser ns (var-names ns))
18:53mudge (var-detail ns var)))))
18:53mudgewhat is "request" in this: (GET "/browse/*" request (let [[ns var] (str/split (get-in request [:params "*"]) #"/")]
18:53mudge (html
18:53mudge (layout
18:53mudge (namespace-browser (namespace-names))
18:53mudge (var-browser ns (var-names ns))
18:53mudge (var-detail ns var)))))
18:53mudge?
18:53mudgewhere does request come from?
18:54raekmudge: gist.github.com next time :)
18:54raekmudge: from whatever calls your handler with a request
18:55raekí.e. probably jetty
18:55mudgeraek, okay, i will
18:59mudgewhat is this: #"/"
18:59mudgewhat is the # syntax?
19:00raekmudge: regex literal
19:01mudgereak, so #"/" is a regular expression that just means / then?
19:01raekyes
19:09dnolenIBM's Watson used Prolog ... need to implement DCG's for core.logic
19:10nickikdnolen, what how?
19:10nickiki mean for what?
19:12dnolenparsing
19:13nickikI think it was kind of cheating that watson got the "questions" as text.
19:14kephalenickik: it depends what you think they were advertising…
19:14kephalethe turing test has no speech recognition requirement
19:16nickikkephale, yeah but I thought the idea of watson was that it could play just like a human, with the same conditions.
19:17kephalewell, yeah they didn't achieve that requirement for sure. even though they made that cute point that it had a buzzer presser
19:17kephalebut, if you want to hassle them, a human has to carry its own energy store : P
19:17kephaleand presumably fit on the stage
19:18nickikhehe
19:18kephaleoh the imagery that comes to mind… : P
19:18nickiki gues that will take some more time.
19:19nickikgive moors law a couple moore (hehe) years.
19:19kephalelol
19:21nickikI want to be able to ask my phone questions.
19:21nickiklooking stuff up on wikipedia is to much work.
19:26TimMcnickik: I think they also imposed a slight delay on Watson.
19:28gigamonkeyWhen did they submit the text? When Trebek started reading the question or when he finished?
19:29TimMcdunno
19:42mudgeI am looking for a request function takes a URL string and returns a map of response data.
19:43mudgeanybody know what namespace the request function is in?
19:45brehautmudge: clj-http
19:45brehautprobably clj-http.core ?
20:09quotemstrWhat's the least ugly way of incorporating some imperative code in the middle of a -> sequence?
20:09brehautwrite a named function?
20:10quotemstrContext is here: http://paste.lisp.org/display/122594 It's not Clojure, but it is Clojure's thrush operator.
20:10brehaut-> isnt thrush; its a form rewriting macro
20:11brehautthrush is a function composition macro
20:11brehautquotemstr: http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/
20:11chouserthrush is a function composition function
20:11brehautwhoops yes
20:11chouser:-)
20:12quotemstrSure. I'm just wondering whether there's a more idiomatic way of embedding those assertions.
20:12brehautthanks chouser :)
20:12quotemstrAh.
20:12brehautmonads are a _less_ idiomatic way of production compositonal imperative code ;)
20:14brehauts/production/??/
20:14sexpbot<brehaut> monads are a _less_ idiomatic way of ?? compositonal imperative code ;)
20:14brehautproducing perhaps is what i meant
20:15brehautquotemstr: -?> might do what you want. its in contrib somewhere
20:16brehaut-?>
20:16brehaut,-?>
20:16clojurebotjava.lang.Exception: Unable to resolve symbol: -?> in this context
20:16brehautclojure.contrib.core
20:16brehauthttp://clojuredocs.org/clojure_contrib/clojure.contrib.core/-_q%3E
20:20[mattb]anyone here used clojure on android yet?
20:29quotemstrI guess what I _really_ want is do-notation.
20:29quotemstr[mattb]: AIUI, Dalvik doesn't run Clojure code well.
20:33[mattb]ah
20:33[mattb]I'm seeing lots of slow startup and memory hogging on google but it seems like that should be remediable
20:37quotemstrI wonder why nobody's added more elements of do-notation to ->.
20:38Scriptorquotemstr: which elements is it missing?
20:38quotemstrScriptor: Conditionals would be nice. I suppose it's not really a monad, so trying to shoehorn that idea into it might lead to unexpected surprise.
20:42Scriptor,(-> 3 (= 3) (if "hi" "hello"))
20:42clojurebot"hi"
20:43Scriptor,(-> 3 (= 4) (if "hi" "hello"))
20:43clojurebot"hello"
20:43Scriptorquotemstr: what's wrong with using conditionals like above?
20:43quotemstrScriptor: (if (something-p ...) ...)
20:44quotemstrScriptor: Also, your example destroys the "3" value, unless I'm missing something.
20:44Scriptorthat it does, unless you def it somewhere I guess
20:44Scriptorit's like using a stack language but with only one thing ever in the stack
20:45quotemstrRight: so you have to manage a stack yourself.
20:46quotemstrScriptor: And it's not trivial to shoehorn normal functions into that model. Without using an embedded lambda like my jezt-passthrough above, it's not clear how one could print "hi 3" instead of "hi".
20:47quotemstrOf course, it's also possible that my sense for functional programming has been forever ruined by exposure to LOOP. :-)
20:49quotemstrAnother idea is to create something like a half ->: instead of threading the last value into the next form's first argument position, it would just provide an anaphoric variable instead.
20:49Scriptorquotemstr: hmm, would it also be necessary to be able to print something like "hi 3 true" (given that the conditional returned true)
20:50Scriptorwhat's an anaphoric variable?
20:51quotemstrScriptor: A variable introduced to refer to some value previously computed, but not explicitly bound.
20:51Scriptorah, got it, like %1 and the like?
20:51quotemstrThe canonical example is AIF: (aif (* a b) (1+ it) 0)
20:51quotemstrYeah, I think you can look at them that way.
20:53TimMc,(if-let [a (+ 3 4)] (* a a) "no")
20:53clojurebot49
20:53TimMceh, that was already bound I guess
20:53tomojquotemstr: I think rich didn't like that idea
20:53Scriptorone idea I'm playing with is something like that, but use it to refer to a stack and make a pseudo-stack-lang
20:53quotemstrtomoj: Which one?
20:53tomojanaphora in a more powerful ->
20:54quotemstrI mean, I can get tolerable syntax with -> using ugly macros, but Haskell's solution looks cleaner to me.
20:54quotemstrtomoj: Ah, too bad.
20:54quotemstrtomoj: What about explicit bindings?
20:54TimMcI think people have written some explicit threading macros that give you something like (--> 5 (* 3 % %) (+ % 1) (println %))
20:54quotemstr(-> 4 (+ 2) (<- first (+ 2)) (= 2) ... (+ first))
20:55quotemstrTimMc: Any pointers?
20:55TimMcSorry, no.
20:55tomojquotemstr: what would explicit bindings look like?
20:55tomojTimMc's example is what I was thinking of, rich didn't like the semantics of % there I think
20:55Scriptorsomething like the <- example from above, tomoj
20:56tomojoh, I didn't notice that second arrow
20:56TimMctomoj: The problem being that % should really refer to the first thing only?
20:56tomojat least that it should only refer to one thing, iirc
20:56TimMcah, OK
20:57TimMcI'd like to see his reasoning on that.
20:57TimMcHe's usually right, in my opinion, but sometimes it isn't clear until I've heard him talk about it fo 15 minutes in a presentation. :-P
20:59Scriptoror at a bar!
20:59quotemstrHeh.
20:59tomojcan't seem to find the discussion
21:00tomojhardly anyone calls it "thrush" and searching for "thread[ing]" isn't exactly useful
21:01Scriptorwas it on irc? Any place to look at them publicly?
21:01Scriptor(look at the irc logs)
21:02tomojhttp://groups.google.com/group/clojure/msg/1eb5cf8fa3248049
21:03tomojhttp://clojure-log.n01se.net/
21:04tomojthat above the logs is rich on an arrow extension
21:04tomojthe rest of the discussion is pretty entertaining I think, crazy dude
21:04tomojI notice he says "And anything like let-> that allowed you to name the arg has the same problem. There is no good name, as the semantics of the parameter often change with each invocation." but don't really understand what he means
21:05tomojoh
21:05tomojthat's not your <- suggestion, he just means letting you name the % in TimMc's -->
21:06Scriptorlooks like the proposer is saying that the wildcard variable changes depending on the last form evaluated?
21:06quotemstrIndeed. My suggestion would make names consistent at least.
21:07tomojI do enjoy overusing the arrows and get a bit frustrated when there's one small piece that doesn't work..
21:08TimMcI think one take-away from that thread is that -> and ->> are already convenience macros, and that generalizing them is going one step too far.
21:08TimMci.e., if you need complexity, name it
21:09Scriptorright, otherwise you're getting kind of close to making an actual stack language
21:09TimMcI guess the places where I have really wanted it *are* in Java interop, though -- I need to call a whole damn chain of FactoryFactoryIterators or whatever to get the instance I want.
21:10Scriptordoesn't .. chain its arguments?
21:10Scriptor(sorry, clojure newb here)
21:17TimMcmeh, you get the idea
21:17TimMc"stitchpoints", they're called
21:19tomojI have never seen those
21:19Scriptorapparently Rich hates them too
21:19quotemstrTimMc: Also ungoogleable.
21:20quotemstrNearly. Found the logs.
21:22TimMcI wonder where I saw it then.
21:22TimMcI wonder if Rich is worried about the likely horrible misuses of a generalized stitching macro.
21:23Scriptorhe might not want them to be too commonly used, it's more of an imperative construct
21:23TimMcPeople would compose large chunks of code using it, and Clojure would maybe even become known for being unreadable to newcomers because of them.
21:23TimMc(worst-case scenario)
21:24TimMcI would certainly rather have people name things.
21:24ScriptorI liked LearnYouAHaskell describing functional programming as defining more than describing steps, so stitching does the reverse of that
21:26TimMcScriptor: Regarding imperative... one of Clojure's big selling points is easy Java interop, so easy imperative coding is actuallypretty important.
21:27TimMcOK, I'm out for the night.
21:40brweber2is that a form of map that is not lazy? I know it is trivial to force the evaluation, but I'm wondering what the most idiomatic way is?
21:41brweber2there, not that ... oops
21:48tomojwhy?
21:48clojurebotwhy not?
21:48tomojare you mapping with a side-effecting function?
21:58nathanmarzbrweber2: (doall (map ...))
21:58brweber2tomoj exactly, I am mapping a side effecting function
21:59tomojdon't do that :(
21:59brweber2nathanmarz: thanks. That's what I have, I was just wondering if there was an existing function I didn't know about that does that
21:59brehautbrweber2: doseq is more common for side-effecty sequence stuff
21:59tomojI prefer doseq, but if you're doall'ing it's not so bad since chunks won't bite you
22:00brweber2tomoj: brehaut: thanks!
22:01brehautbrweber2: it supports comprehension notation (like for) and has an implicit do
22:01tomoj&(->> (range) (map print) (take 3))
22:01sexpbot⟹ (012345678910111213141516171819202122232425262728293031nil nil nil)
22:01tomojthat's what scares me
22:03brweber2tomoj: You've got the whole chunk of 32 there... it realized them all even though you only need three. Which function introduced the chunking in your example?
22:04brehautbrweber2: range
22:04brehautrange and vectors are (currently) the only source (i think) of chunked seqs
22:04tomojwhich means this weirdness can be hidden if you pass unchunked seqs, then pass a chunked seq in and bam
22:05brweber2yeah, i wish default chunk size was 1... and you had to explicitly change it
22:05brweber2You'd still have this problem, but you'd have to introduce it yourself
22:06brehautits very rarely a problem in real code
22:06brehautside effects are the major complication
22:06brehaut(there is a niche of complex computations that are also bad with them, but they are rare)
22:07tomojackermann function or something?
22:08brehautthat sounds right
22:08brweber2brehaut: I simply prefer the easier to reason about solution as the default. Then again, I don't have to write a performant programming language, so I can espouse whatever naive opinions I may hold :)
22:08brehautbrweber2: the merits of both defaults were debated in great detail at the time it was implemted
22:09brweber2brehaut: I somewhat recall... I just haven't touched clojure in a while. Getting back into the swing ...
22:09brehautchouser wrote an explicit dechunker function somewhere i recall
22:09brehautget back into seesaw, its nicer than straight swing
22:10brweber2brehaut: Oh no, not that SWING! haha I wouldn't touch that with a ten foot pole
22:15dnolenyou easily can wrap ranges and vectors in a lazy-seq to defeat chunking.
22:16brehautoh of course. clever
22:16brehauti had tried list, but i don tthink that works
22:17brweber2dnolen: are you sure?
22:17dnolenbrweber2: not sure, positive.
22:18brweber2&(->> (lazy-seq (range)) (map print) (take 3))
22:18sexpbot⟹ (012345678910111213141516171819202122232425262728293031nil nil nil)
22:18brweber2dnolen: is that what you meant? Learn me! Learn me! ;)
22:18dnolenbrweber2: that's not what I'm calking about
22:18brweber2dnolen: Figured not since it doesn't seem to work. Which form do you mean?
22:20dnolen(defn lazier [x] (if x (lazy-seq (cons (first x) (lazier (next x))))))
22:23brweber2dnolen: Gotcha. That does the trick. Is that identical to the dechunker written by chouser mentioned before?
22:24dnolenbrweber2: no, that solution involves deftype.