#clojure logs

2011-10-15

00:02amalloyThreeCups: it may help to understand that use is a combination of require/refer
00:03ibdknox,(doc refer)
00:03clojurebot"([ns-sym & filters]); refers to all public vars of ns, subject to filters. filters can include at most one each of: :exclude list-of-symbols :only list-of-symbols :rename map-of-fromsymbol-tosymbol For each public interned var in the namespace named by the symbol, adds a mapping from the name of the var to the var to the current namespace. Throws an exception if name is already mapped to somethin...
00:03amalloyrequire causes code to be loaded, and refer creates aliases in your current namespace to already-loaded symbols
00:03ibdknoxwow
00:03ibdknoxself-referential
00:03nappingcarllerche: The name just sounded like something for making xss attacks
00:03carllercheheh… it's the opposite :P
00:16ThreeCupsibdknox, amalloy: thanks. I'm slowly wrapping my head around this :)
01:21bsteuberis it possible to execute js for simulating a button click with clj-http?
01:26jedahustrange clojurescript behaviour
01:26jedahu(- 1) ; => 1
01:26clojurebot0
01:26jedahuthe defn of - in cljs.core is correct
01:28nappingbsteuber: I've seen some java libraries that could
01:28jedahu(cljs.core/- 1) ; => 1
01:29ibdknoxthe math ops are inlined now
01:29jedahuibdknox: I am using v0.0-838-g567be71
01:29jedahujust pulled a minute ago
01:30nappingHttpClient (which clj-http wraps) claims not to: http://hc.apache.org/httpcomponents-client-ga/primer.html
01:30ibdknoxjedahu: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L57
01:30bsteubernapping: until now I just found selenium but it controls an actual browser and thus might be slow for data mining
01:32bsteuberthanks anyways - gotta leave..
01:32nappingI think it was over 10 years ago, but I remember something that included a dom and a javascript interpreter (is Rhino that old?)
01:32jedahuibdknox: thanks. in that case, is there a negation function/macro lying around?
01:32nappingXerces and Rhino, IIRC
01:33jedahuor can - be fixed to behave like cljs.core/- ?
01:33ibdknoxjedahu: (- 0 1)
01:33ibdknox,(- 3)
01:33clojurebot-3
01:34ibdknox,(- 0 3)
01:34clojurebot-3
01:34jedahuibdknox: fair enough
01:34nappingAh, HtmlUnit
01:34nappingis there any way to leave a message?
01:40amalloynapping: in irc, you mean?
01:40nappingon clojurebot, I was thinking
01:40amalloy$mail napping lazybot will take messages for you
01:40lazybotMessage saved.
01:41napping$mail bsteuber The library was HtmlUnit. It seems to still be active
01:41lazybotMessage saved.
02:02Raynes$mail napping I wouldn't rely on that though. lazybot isn't very aggressive and will only NOTICE people when they have messages. If they don't have NOTICEs set up to direct to whatever channel they're in, it may be a while before they see it or they may never see it at all.
02:02lazybotMessage saved.
02:03Raynesamalloy: Now, let's see if he ever actually gets that message. Should be fun.
02:04scottjlame on github's search page they have languages split into popular and everything else and common lisp and scheme are both in the popular section and clojure is in the everything else despite clojure having a higher popularity ranking on github
02:05Raynesscottj: I hate how far down I have to scroll in the dropdown in gists.
02:05amalloyevery pixel an insult
02:06ibdknoxseriously.
02:06ibdknoxwe should petition
02:06scottjRaynes: looks like you can type Clojure in the drop down
02:08Raynesscottj: Still, it's blasphemy.
02:53FrankLHow can I update the clojure version counterclockwise uses to 1.3.0?
02:54FrankLI tried googling, but couldn't really find a guide
02:55mikeraFrankL works for me just by including the Clojure 1.3 jar in the build path rather than the 1.2 version (I do this with Maven usually, but I think it works by just editing the standard build path as well)
02:56FrankLthanks mikera, i'll try that
03:01FrankLhm, just changing the build path and refreshing the project doesn't work
03:02FrankLalthough i haven't changed the clojure-src.jar
03:03amalloychouser: i just looked at the new, 1.3 impl of doc. i can't see a reason for not quoting the first half of the if-let - it means that if i did, say, (defn print-&-doc [] (doc &)), that would print the docs once at compile time instead of every time the function is called
03:05FrankLah, nevermind, i only changed the src attachment the first time, now it works
03:05FrankLthanks mikera!
03:05mikeranp! glad you got it to work, these things can be fiddly sometimes.......
03:15mikeraanyone had luck getting Pallet to work with Clojure 1.3?
03:16Raynesdakrone: You wouldn't happen to be around, would you?
03:37todunWhen defining my function using defn, I want to pass a list as a parameter. The syntax seems to be to use square brackets for parameters. However the syntax for lists are parentheses(circular brackets). do I do this: defn function-name [a-list] ...) or do I do defn function-name2 (another-list) ...)? I'm new to clojure so sorry if this sounds silly.
03:38mikeratodun just do (defn my-fun [listname] .....)
03:38brehauttodun: the arguments vector is independant of the types of the variables you pass
03:38todunWhen I call my function in the REPL, do I do (function-name [1 2 3]) or do I do (function-name2 (1 2 3 4)) ?
03:39mikerathe former is best
03:39todunmikera: brehaut ok. that is a bit confusing. I see that there are seqs, lists, vectors, sets. All with different syntaxes for defining them.
03:39mikera(1 2 3 4) won't work since it will try to apply "1" as a function to the arguments 2, 3 and 4 which is probably not what you want....
03:40mikerayou can do (my-fun '(1 2 3 4)) though if you like, which will pass a list rather than a vector
03:40brehauttodun: you almost never define lists in your code; they are more frequently used at the macro level
03:40todunmikera: so parens are like function scopes all the time in clojure?
03:40brehauttodun: no, they are sometimes macros or special forms
03:41todunbrehaut: is clojure doing type inferencing then? if so, how does it infer type if its structure is not specified?
03:41brehauttodun: and they represent many list like things when printed to the repl (seqs, cons, lists etc)
03:41brehauttodun: it does type inference for purposes of avoiding reflective calls in interop but its a dynamically typed language
03:43amalloytodun: i think you are barking up the wrong tree. (foo bar) always indicates "call the function foo with argument bar", unless (a) foo is a macro itself, or (b) that list is surrounded by a macro or special form that dictates otherwise
03:43todunbrehaut: I just read up on macros and it seems they're like interfaces in java or python's modules.
03:43brehaut,(map (juxt class pr-str) [(list 1 2 3) (map inc [0 1 2]) (cons 1 ())])
03:43clojurebot([clojure.lang.PersistentList "(1 2 3)"] [clojure.lang.LazySeq "(1 2 3)"] [clojure.lang.Cons "(1)"])
03:43amalloysorry, they are nothing like interfaces or modules though
03:43brehauttodun: not at all
03:43brehauttodun: macros allow you to effectively write compiler plugins
03:44brehauttodun: namespaces are roughly analogous to pythons modules and protocols are roughly analogous (but way better) than javas interfaces
03:44todunamalloy: brehaut uhm. ok.
03:44todunbrehaut: I've not seen protocols yet.
03:45todunnot sure if I've seen macros.
03:45amalloymacros are a concept that no other languages really have
03:45brehauttodun: you dont need them yet
03:45todunbrehaut: ok.
03:45amalloy(no other non-lisps, that is)
03:45todunI'll keep writing my recursive methods and come back if I fall into a conceptual rut...
03:46todun, '(1 2 3)
03:46clojurebot(1 2 3)
03:46toduncool!
03:46amalloytodun: brehaut's summarization of macros as compiler plugins is good, and a useful way to think of things. you're using macros all the time, you just don't know about it
03:46brehautyou should be trying to learn how _not_ to be writing recursive methods
03:46todunamalloy: ok.
03:46todunbrehaut: how so?
03:46brehauttodun: functional programming includes lots of abstractions that take care of the recursion for you; eg, map reduce filter etc
03:46brehautreduce is a particular recursive pattern
03:47amalloy&(if-let [x 1] (inc x) :no-such-thing)
03:47lazybot⇒ 2
03:47amalloy&(macroexpand '(if-let [x 1] (inc x) :no-such-thing))
03:47lazybot⇒ (let* [temp__3586__auto__ 1] (if temp__3586__auto__ (clojure.core/let [x temp__3586__auto__] (inc x)) :no-such-thing))
03:47todunamalloy woah.
03:48todunamalloy: I've just done some reading on TOC, lazy seq, regular recursion.
03:48brehauttadah!
03:48mikera:-) todun you should probably ignore that stuff for now!
03:48amalloytodun: if-let is a pre-built "plugin" for the compiler that turns "function calls" that start with 'if-let into slightly more useful code
03:48todunamalloy: trying to implement a bunch of problems using all these techniques.
03:48todunmikera: ok.
03:49amalloyheh, well. using every technique all at once will just lead to a soupy mess, probably
03:49todunbrehaut: Arthur C Clarke comes to mind here...
03:49mikeranot that it's not useful, but there is a lot to take in at once... took me a couple of months before I got comfortable with macros....
03:50todunamalloy: how does let work? also, how does letfn work? I couldn't understand what it was quite doing in the examples I looked at.
03:50mikera,(let [x 10] (* x x ))
03:50clojurebot100
03:50todunmikera: ok. I'll avoid it for now. but I have a feeling I'll need it when I reach concurrency.
03:51brehauttodun: have you joined 4clojure?
03:51todunbrehaut: nope. I can join?
03:51mikerayeah you will need it, but i'd suggest getting the basics nailed first, especially the stndard syntax, higher order functions etc.
03:51mikera4Clojrue is a great way to start!
03:52todun,(reverse (1 2 3 4))
03:52clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
03:52amalloytodun: www.4clojure.com
03:52mikera,(reverse '(1 2 3 4))
03:52clojurebot(4 3 2 1)
03:52todun,(reverse [ 1 2 3 4])
03:52clojurebot(4 3 2 1)
03:52mikerayou need the ' to make a list......
03:52todun,(reverse [1 2 3 [1 2 3]))
03:52clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: )>
03:53todunwhy does the second one give an error?
03:53mikeraunmatched brackets, you want:
03:53amalloy([[])) doesn't balance
03:53mikera'(reverse [1 2 3 [1 2 3]])
03:53mikera,(reverse [1 2 3 [1 2 3]])
03:54clojurebot([1 2 3] 3 2 1)
03:54brehautalso, if you are reversing a vector (rather than a sequence or list) you might want rseq instead of reverse
03:55todunbrehaut: that's why I asked my earlier questions. I want a list specifically.
03:56brehauttodun: why? its not common to want a list specifically in clojure
03:56todun, '(1 2 3 (1 2 3))
03:56clojurebot(1 2 3 (1 2 3))
03:56todunbrehaut: ok.
03:57todunamalloy: I have corresponding brackets, why doesn't it balance?
03:57Raynes[[] <-- Note the lack of second ].
03:57amalloyyour, uh...your statement is untrue
03:58todunRaynes: amalloy yes. thanks.
03:59todun,(reverse '(1 2 3 '(1 2 3)))
03:59clojurebot((quote (1 2 3)) 3 2 1)
03:59todunI was warned about clojure and its brackets.
04:00brehaut
04:00clojurebotHuh?
04:00brehautyou prefer to type more of them?
04:00brehautor you'd prefer only parens?
04:01todunbrehaut: indifferent.
04:02mikeraClojure usage of brackets is actually very logical, it's just different from C-like languages. I usually need less in Clojure than I do in Java for the same code.
04:03todunmikera: I'm yet to find that out or not.
04:03brehauttodun, python's equivalent of your expression above is [1,2,3,[4,5,6]][::-1] which is equally brackety, and has additional punctuation not needed in clojure
04:05todunbrehaut: I'm not decrying clojure. just saying that I've really not done much in it to say one way or another. In fact, these will be my first non-example clojure code I'll be writing.
04:05todun:)
04:09mikerahttp://www.infoq.com/presentations/Clojure-in-the-Field is a good video for some of this stuff
04:11todunmikera: thanks.
04:13mikeraother things is 4Clojure (http://www.4clojure.com/), well worth doing 20-30 of these problems. a nice bonus is that you get to see how other people solved the probelms too......
04:14brehautmikera: or 80-90…
04:14brehauti dont have a problem. i could quit whenever i want
04:15amalloybrehaut: i have a stash of four problems i haven't solved yet, for when the cravings get really bad
04:15brehautamalloy: ive got mostly involved or mathy ones left
04:16amalloywell, me too. i actually left them unsolved cause i wasn't really interested :P
04:16brehauthah :)
04:16brehautwe cant all be chouser i guess
04:21brehaut102 has taught me i dont know the string ns at all well enough
04:21todunis there a way to kill the currently running command in the REPL without quitting the REPL?
04:22brehautit depends
04:22brehautwhat repl ?
04:23todunlein repl
04:23brehauti think you might be out of luck
04:25todunbrehaut: ok. thanks.
04:27amalloybrehaut: wait till you get to 117. some of the solutions will make you wonder if the authors have ever seen a library that isn't about strings
04:28brehautamalloy: that looks like a PITA
04:28brehautand i am fearful of how you would do that as a strings problem
04:28amalloyyeah, my solution is pretty awful
04:28amalloyamcnamara has a good solution that makes sense, but chouser and youz do some WEIRD string stuff i can't understand at all
04:28brehauthaha
04:29brehauti bashed out a game of life solution last night
04:29brehauti went and looked at some of the solutions
04:30brehautmine is the 4yo with crayons version
04:30amalloy*laugh*
04:30brehautall the basic elements are there, but its really crude
04:31brehautyouz solution confuses the crap out of me
04:33amalloy(- -1 w) is something that almost seems like it can't make sense
04:34brehauthah yeah
04:34brehautits not an idiomatic construction thats for sure ;)
04:35Raynesyouz is God.
04:42amalloyhe's more like loki. a Trickster
04:43brehauthaha excellent
05:06archaici rebound ; to 'paredit-open-paren .. best decision ever
05:08amalloyarchaic: so you can't write any comments? i prefer swapping the "shift-ness" of numbers and symbols; 9 isn't such a hard key to reach for, and i can still pepper my everyday speech with semicolons
05:10archaiccomments is C-; now since i use alot less than paren
05:10amalloythe important thing is you're customizing, though. don't stick with inferior tools, and don't listen to strangers like me who tell you your setup is silly
05:12amalloyand there's a nice parallel with java/c which is covered with semicolons
05:25todunI'm getting errors I can't quite understand when I do this http://pastebin.com/TiAg30gZ
05:26raektodun: (defn z n ...) --> (defn z [n] ...)
05:26todunraek: but n is just a number, does it need [n} ?
05:26raekbut the cond clauses don't make much sense
05:27todun*[n]
05:27raektodun: yes, a function can have more than one argument
05:27todunraek: uhm ok. thanks.
05:28raekjust like you need the ()s in java: public static void main(String args[]) ...
05:28todunraek: that does make sense. thanks.
05:28raektodun: cond takes alternating conditions and expressions. you have 3 forms on the middle line and only one on the last
05:29todunraek: uhm. I don't quite follow.
05:29raekif n is even, is cond going to return z or (/ n 2)?
05:30todunraek: alternating conditions as in conditions that don't match?
05:30todunraek: oh. so it's not sequential?
05:30todunraek: meaning it does not do the first, second then last?
05:31raekit is sequential. lets say you have (cond c1 e2 c2 c2 c3 e3 :else e4)
05:31raekif it check c1 first. if it's true, cond will evaluate and return e2
05:31raek*it will check
05:31raekif c1 was false, c2 is checked
05:32raekif c2 is true, then e2 is evaluated and returned
05:32raekso cond is like "if (..) .. else if (..) .. else if (..) .. else"
05:33raekwhat I
05:33raekI'm confused about is "z (/ n 2)"
05:33raekif (even? n) returns true, then z is evaluated and returned
05:34raekif (even? n) returns false, (/ n 2) is the new condition to check
05:34raekwhich doesn't make much sense, since it's a number
05:34raekdid you mean (z (/ n 2))
05:34todunraek: ok.
05:35todunraek: if I have a function.
05:36toduna function to me is when I use defn, and I call it within its definition(recursion), do I put a space between the function name and the arguments?
05:36raektodun: a function call is always wrapped in a pair of parens
05:36todunwhat I did was call z(/ n 2) is this illegal?
05:36raekyes, that's not clojure syntax
05:37todunraek: I see. the example I was following for cond didn't have a function call but just literals. I projected that case to function calls.
05:37todunraek: so that's why I get a strange result for that case. thanks.
05:37raekif you for instance say (+ 2 z (/ n 2)), that would mean "take the sum of 2, the function z, and the expression (/ n 2)". i.e. z is not called
05:38raek(+ 2 (z (/ n 2))) means "take the sum of 2 and what you get when you call z with (/ n 2)"
05:39todunraek: ok.
05:39raektodun: http://pastebin.com/LYS2XBYV
05:40raekso in clojure, the parenthesis are never optional
05:41todunraek: I get an error when I try this http://pastebin.com/EBCevmWi
05:41todunillegalArgsExcetion.
05:41todunthanks for the least.
05:41todun*list
05:41archaic(+ 1 2 3)
05:41clojurebot*suffusion of yellow*
05:41raektodun: you didn't fix the (defn z [n] ...) problem
05:42raekand the :else line has an error
05:43todunraek: sorry I did. I just didn't change the pastebin right.
05:43todunlet me repost
05:43raekwhat you should have is (cond c1 e2 c2 e2 :else e3)
05:43todunraek: ok.
05:43raekbut what you have is (cond c1 e1 c2 e2 (:else e3))
05:44raeksorry, it should be "c1 e1" in the first line
05:44todunoh. so :else is a function?
05:44todunI thought it was a keyword?
05:44raekno, it's a keyword
05:44raekwhich is a value
05:45raek:else evaluates to :else, since keywords are self-evaluating (like numbers)
05:45archaicis (dorun (map ..)) idiomatic to force a map for side-effects?
05:45todunhttp://pastebin.com/kfxN5inh
05:45raekand the rule for conditions in clojure is that false and nil are falsy, and everything else (including keywords) are truthy
05:46amalloyclojurebot: who taught you (+ 1 2 3) is *suffusion of yellow*, anyway?
05:46raekarchaic: either that or (doseq ...)
05:46clojurebotI don't understand.
05:46todunraek: uhm. ok.
05:46raekso :else is a condition that is always true
05:46todunraek: like a default value.
05:47raekyou could have written true instead of :else there, (as you would do in common lisp) but it's ideomatic to use :else in clojure
05:47todunor a java pass or perhaps continue
05:47raektodun: yes, it's the last catch-all case
05:48raektodun: but the parentheses around :else and (z (+ (* 3 n))) shouldn't be there
05:49raekthose parentheses will make that whole thing the condition and then there's no expression for it (since the contents of 'cond' will now be an odd number of forms)
05:49todunbut I thought it ought to be around functions, like z?
05:50raekbut you don't want to unconditionally call :else with the result of (z (+ (* 3 n))), right?
05:51raek'cond' is a special form, so it doesn't work like a function call
05:51raekit's a macro that gets translated into a bunch of ifs
05:51todunraek: uhm ok. et me do some debbuging.
05:52raek(cond c1 e1 c2 e2 c3 e3) --> (if c1 e1 (if c2 e2 (if c3 e3 nil)))
05:52raekthe if special form has the syntax (if <condition> <then expression> <else expression>)
05:53raektodun: this is what you function should look like: http://pastebin.com/94trLBhS
05:54raeknote that in clojure whitespace and newlines are not part of the syntax
05:54raekonly the parentheses determine the structure of the code
06:18todunraek: uhm. ok.
06:20todunraek: instead of using z, I can usee recur, so it does TOC?
06:30todunis there a way to check for duplicates?
06:31llasramDuplicate which?
06:32archaicthere are functions frequencies and distinct that may do what you need
06:35todunllasram: (duplicates? '(1 1 2 2 3))
06:36todunarchaic: ok. let me read up on those.
07:11todunwhat is the value of an empty list?
07:11todunor rather, how to test if a list is empty?
07:11opqdonut,(doc empty?)
07:11clojurebot"([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"
07:11opqdonutalso, you can compare to '()
07:12opqdonutwhich is slightly different
07:16todunopqdonut: thanks.
07:16todunopqdonut: I tried '() but got an error.
07:16todunopqdonut: sorry. take that back.
07:16todunI was trying ()?
07:25BorkdudeI'm trying to push to heroku, how do I get a 'local' jar up there?
07:25BorkdudeQuestion was also asked on the Clojure google group: http://groups.google.com/group/clojure/browse_thread/thread/4045276f24444a69
07:32todunhow to find the head of a list in clojure? is there like a term called head ? also is the only way to find the nest element (head (next a-list))? thanks.
07:33archaic_(first [1 2 3])
07:33archaic(rest [1 2 3])
07:33todunarchaic_: thanks.
07:34todun,(first [1 2 3])
07:34clojurebot1
07:45daniel__thats a vector...
07:45daniel__,(peek '(1 2 3))
07:46clojurebot1
07:46daniel__for a list
07:48todun,(if (= (compare (first [1 2 3]) (first (rest [ 1 2 3])) ) 0) (remove (first [1 2 3]))
07:48clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
07:48todunwhy is this wrong?
07:49todunI thought if takes only condition & expression.
07:49todunor no?
07:51raekif takes one condition and two expressions
07:51raekand remove takes a function and a collection
07:51raek,(remove even? [0 1 2 3 4])
07:52clojurebot(1 3)
07:52raekand you can use (= x y) instead of (= (compare x y) 0)
07:53todunraek: ok. let me refine it. thanks.
07:58todunreak: if I want to know the result of remove in the following, how do I get it?
07:59todun,(if (= (first [1 2 3]) (first (rest [ 1 2 3])) ) (remove (first [1 2 3])))
07:59clojurebotnil
08:04raektodun: that call to remove doesn't make any sense
08:04toduncan I do assignment in clojure?
08:04todunraek: no sense in what way?
08:04raekwell, you usually don't do it for computations
08:04raek(assignments)
08:05raekyou can use let, which introduces a name for a value (but doen't allow you to reassign it)
08:05raek,(doc remove)
08:05clojurebot"([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns false. pred must be free of side-effects."
08:05raekremove take two arguments, and you only pass it one
08:05raekalso, remove does not do what I think you think it does
08:06raekif you want a new sequence where the first element is missing, use rest
08:06todunraek: uhm. ok. let me rework it.
08:06raektodun: also, that code snippet returns nil since the condition is false
08:07raek(if condition then-expr) = (if condition then-expr nil)
08:07todunraek: ok.
08:07raekthe else branch defaults to a constant nil if you don't supply it
08:08raektodun: it's better to think of functions as thing that receives some values and make a new value, rather than a thing that changes stuff
08:09raekyou can think of the expression (rest coll) as a name for "coll, but without the first element"
08:09todun,(if (= (first [1 1 3]) (first (rest [ 1 1 3])) ) (remove (first [1 1 3]) [1 1 3]) )
08:09clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
08:10raektodun: remove does not take an element as the first argument. it takes a predicate
08:10todunraek: ha. uhm. ok. I misread that then. sorry.
08:10raek(let [coll [1 1 3], x (first coll)] (remove (fn [element] (= element x)) coll))
08:10raek,(let [coll [1 1 3], x (first coll)] (remove (fn [element] (= element x)) coll))
08:10clojurebot(3)
08:11raekyou can write that predicate as #(= % x) or even #{x}
08:11todunraek: I see.
08:12todunraek: if I want to yield the list after the remove, how do I do so?
08:13raekremove yields the list
08:13todunin particular, the output is (3) but I expect it to be (1 3)
08:13raektodun: but filter removes *all* occurances where the predicate matches
08:13todunI dont use filter.
08:14raektodun: if you just want to get a list without the first element (whatever it is) use "rest"
08:14raektodun: sorry, remove
08:14todunraek: ok. let me try that.
08:14raekfilter does the opposite (keep the elements where the predicate return true)
08:14raek,(rest [1 2 3 4])
08:14clojurebot(2 3 4)
08:15todunraek: ha yes. the imperative mind-set trap was not letting me see that optimization. thanks.
08:16raekin functional languages, the expression is the building block, not the statement
08:16raekand you describe values, rather than side-effects
08:17todunraek: how do I use let to ensure I'm working with the modified list?
08:17raekif returns a value too (namely the value of either the then-expression or the else-expression, depending on the value of the condition)
08:17raek,(let [rest-of-the-list (rest [1 2 3 4])] .... use rest-of-the-list-here ...)
08:17clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: .... in this context, compiling:(NO_SOURCE_PATH:0)>
08:18raektodun: you just give a name to the result of the if or the rest call or whatever and then use that name in another expression
08:19raek,(let [foo (rest [1 2 3 4])] (reverse foo))
08:19clojurebot(4 3 2)
08:19raek,(reverse (rest [1 2 3 4]))
08:19clojurebot(4 3 2)
08:20todunraek: is this functional, this internal side-effecting that I'm proposing?
08:20raekwhat side-effect?
08:20raeklet is side-effect free
08:20todunraek: giving names and passing them like you did.
08:21raekto give names to values is indeed functional
08:21todunraek: uhm. ok.
08:21raekyou cannot change the values themselves in clojure
08:21raekso [1 2 3] will always be [1 2 3]
08:21raek(let [original [1 2 3], changed (rest original)] ...)
08:22raekinside the let, original still refers to [1 2 3] and changed refers to (2 3)
08:23raekso the standard libary functions don't actually change collections, they return new variants of the old values
08:23raekand the old values are still available
08:23todunraek: um. ok.
08:23todun, (if (= (first (name [1 1 3])) (first (rest name)) ) (rest name) )
08:23clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.Named>
08:24todundo I have to use the square brackets?
08:24raekwhat are you doing with the 'name' function here?
08:24raek( ) means call a function
08:24todunmaking it [1 1 3]
08:24raek(name [1 1 3]) <-- what do you want this to do?
08:25todunI want it to be called by first, rest
08:25todun(if (= (first name)) (first (rest name)) ) (rest name) )
08:25todunname = [1 2 3]
08:25raekthen you need to let it first
08:26raek"name" is also a function in the standard library
08:26raek,(let [name [1 1 3]] (if (= (first name) (first (rest name))) (rest name) "something here"))
08:26clojurebot(1 3)
08:28todunraek: ok. thank.
08:29raekalso "let" is a special form, so (let ...) is not a function call
08:29todunraek: special form?
08:29raekit's hard-coded in the compiler
08:30raek(let ...) has special rules for how the "..." is interpreted
08:31raekso you don
08:32raek't evaluate the [name [1 1 3]] thing. the compiler looks at it and emits code that stores the [1 1 3] gives it a name
08:32todunraek: I see. just like the way TOC works.
08:33todun*TCO
08:37todunwhen I write this function to remove duplicates, I get the following error: not connected.
08:37todunhttp://pastebin.com/gk2ftEnP
08:38todunand it really an error per se, it is just that when I compile, I get the message splash at the bottom.
08:42todunI just realized it was referring to the swank server closing.
08:43todunWhen I try to reconnect, it keeps saying Connection closed. How is this possible?
08:43todunI thought the server was on my machine?
08:56todunI'm trying to do a reversal of a list. Even if the input is a list of lists, I want this nesting to be reversed. To this end, I use recur. But I don't think I have the logic right. Any comments, critiquing will be appreciated: http://pastebin.com/qYete3fb
09:39BorkdudeIs it possible to push to heroku and let the server find jars based on pom.xml instead of project.clj?
09:40BorkdudeFor a Clojure project that is of course
09:53BorkdudeSolved it through a push to clojars instead...
09:53Borkdude(the local but now not local anymore jar problem)
10:12BorkdudeIs it possible to remove one of your groups and jars from clojars?
10:15BorkdudeI want my jar to be in the group org.clojars.borkdude
10:15Borkdudeso the group twitter-utils may be removed
10:17Borkdude(so I don't get in the way of someone else maybe one day wanting this name for a project)
10:55kylpoWoop woop! Finally have some time to start learning clojure this weekend :)
10:56Borkdude:-)
11:10BorkdudeHmm. What is supposed to be the outcome of (= (list) [])
11:12BorkdudeI suppose lists and vectors are compared by elements, regardless of their type
11:15floatbothis lein install supposed to be like mvn install:install-file? because only the latter works properly :( I mean, with subprojects, I want to install them to the local repo and then lein deps on the main project should get them from it. But it only works after mvn, not lein install
11:16Borkdudehave you tried lein localrepo?
11:16Borkdudehttps://github.com/kumarshantanu/lein-localrepo
11:17floatbothyeah
11:18floatbothit requires version and group/artifact id, it's kinda the same thing
11:18floatbothbut looks like shell magic should work, like lein localrepo coords *.jar | xargs lein localrepo install
11:18Borkdudefloatboth: lein localrepo worked for me
11:18floatbothwhat's the point of lein install then?
11:19Borkdudedunno :)
11:23tomojfloatboth: does the bit after defproject for the project you ran `lein install` on match the group/artifactid?
11:25floatbothhmm
11:26floatbothlooks like it's ok, "installing this.jar into ~/.m2/repository/group/artifact/this.jar"
11:29floatbothaaah, got it, lein sub was running it on the main project too before installing subprojects
12:00duck1123Generally speaking, if I get reflection warnings from a 3rd party library, then that's not really my problem, right? I'm trying to eliminate some of the reflection in my library and am wondering if I should be concerning myself with reflection in dependencies
12:09SqueeseOk, so reading pragmatics clojure book and "installing examples dependancies" with lein, it's spitting me maven error messages, supposedly not finding a package - where can I browse these packages and fix it? Is there a reposatiry somewhere?
12:10dnolenduck1123: the only problem is suboptimal interop perf from the dependency. You should let the lib author know.
12:13SqueeseYah, I sent mail, it's a beta release of the book
12:16Squeeseoh well, http://build.clojure.org/ didnt make me any smarter, guess I'll butter up the patience :)
12:23SqueeseOk, so, I cant use (require 'deps) since the lein deps spits errors, can I modify "dep path" myself or maybe enter repl with a file loaded (wanting to try the examples)
12:25daniel__(ns evolve.core
12:25daniel__sry
12:25daniel__ (nth (iterate #(doto (str ((fitness-fn target) %) " " (evolve % (fitness-fn target))) println) source) generations))
12:26daniel__can anyone tell me why this prints the fitness an increasing number of times for each iteration?
12:26daniel__it should be like: 100 blah; 200 blak; 300 blay; but instead its more like 100 blah; 100 200 blak; 100 200 300 blay;
12:30robermanndaniel: I think the problem is using iterate
12:30robermann,(doc iterate)
12:31clojurebot"([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"
12:31BorkdudeSqueese: what book is this?
12:31SqueesePragmatic programmers, Programming Clojure
12:33daniel__robermann: yeah, i see
12:33daniel__hmmm
12:34robermann(interleave [100 200] ["blah" "blak"])
12:34robermann,(interleave [100 200] ["blah" "blak"])
12:34clojurebot(100 "blah" 200 "blak")
12:39robermannor maybe you could use the repeatedly function
12:45daniel__robermann: maybe, ill have to think it through
12:46daniel__with repeatedly can i pass back what is returned as % like with iterate?
12:46daniel__in fact, nvm
12:46daniel__that defeats the point
12:47daniel__i might be able to work it in to my evolve method somehow as a side effect
12:47duck1123daniel__: can't you just map over the results and print them outside of the iterate? That way you're keeping that iterate fn side effect free?
12:49daniel__duck1123: im not sure i know what you mean
12:49Squeeseok, this.. is.. sexy.. why? I have no idea, its just.. sexy: (def sexy {:key "val"}) and then (:key sexy) or (sexy :key)
12:49Squeeseis this general Lisp or Clojure specific?
12:50duck1123daniel__: instead of printing inside the iterate function, pass that seq to a mapping form that does the print. The laziness should still give you the progress you'r looking for
12:53BronsaSqueese: afaik only clojure has it
12:53Squeesekk
12:54robermanndaniel__: i think duck1123 is suggesting something like: (map #(println %) (range 1 10))
12:55daniel__the range being the iterate
12:55daniel__ok, think i get it
12:55daniel__let me try
12:55robermannyes
12:55duck1123robermann: exactly.
12:59duck1123Is there something I can pass to lein to put it into a strictly offline mode? If I'm maxing out my internet connection, then lein deps will take a long time to complete even if it's not apparently fetching snapshots.
13:01daniel__ (nth (map #(doto (str ((fitness-fn target) %) " " %) println) (iterate #(evolve % (fitness-fn target)) source)) generations))
13:01daniel__works :) just looks a mess
13:02duck1123daniel__: that's when -> and ->> start to become your friend
13:04daniel__duck1123: i guess now would be a good time to learn what they do then :)
13:04daniel__and commit it to memory this time :p
13:05robermanndaniel__ BTW, are you working on anything like http://www.pawfal.org/dave/blog/2011/10/evolving-musical-bytecode-3/ ?
13:06duck1123(-> (fitness-inner-fn) (iterate source) println (nth generations))
13:07daniel__no robermann, but it looks interesting
13:08robermannok, i was just curious too, because recently I read http://www.pawfal.org/dave/blog/2011/10/evolving-musical-bytecode/ , where do exists a "fitness" function
13:09daniel__im just evolving a string into another string...an experiment to learn clojure really
13:10duck1123daniel__: are you converting the problem from your work in a different language, or is this something all new?
13:10daniel__duck1123: all new
13:11daniel__although it would be a lot simpler in another language at the moment
13:11duck1123I've been converting my large ruby application at work to clojure. It's difficult to translate an existing process sometimes
13:11daniel__i like clojure but i think you have to know it well to get the benefits
13:11duck1123Of course now I curse the days I have to work in Ruby
13:12duck1123It's really a progression of things clicking
13:12daniel__yep, i also came from ruby and i find it much easier to think of how to solve a problem in terms of ruby than clojure
13:12daniel__but its v early days
13:13robermannI translated stack traces/source code into music, just to stay on strange topics: www.codesounding.org
13:14daniel__i now think i want a map to map the map :p i want to add line numbers
13:14duck1123I find that I'm very much spoiled by Clojure's correct concurrency without having to think about it when working in Ruby. I'm always saying "Well, if this was in Clojure, I'd just ... and be done"
13:15duck1123->> puts the output of the previous form into the collection spot of the next form
13:15duck1123(->> coll (map fn1) (map fn2) (filter pred1) first)
13:16daniel__,(expmacro -->)
13:16clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: expmacro in this context, compiling:(NO_SOURCE_PATH:0)>
13:16daniel__,(expandmacro -->)
13:16clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: expandmacro in this context, compiling:(NO_SOURCE_PATH:0)>
13:17duck1123,(macroexpand '(->> coll (map fn1) (map fn2) (filter pred1) first))
13:17clojurebot(first (clojure.core/->> (clojure.core/->> (clojure.core/->> coll (map fn1)) (map fn2)) (filter pred1)))
13:17duck1123(first (filter pred1 (map fn2 (map fn1 coll))))
13:18daniel__ok
13:18duck1123I believe comping those 2 map fns may be better than 2 maps, but you get the idea
13:18daniel__btw, in this case is there an opposite of macroexpand? it should be fairly easy to take an expression and turn it into -->
13:19daniel__->>*
13:19duck1123well, turning things into a macro is really more for your benefit than the compiler.
13:20duck1123I'd love to see someone write something for clojure-mode though
13:20daniel__yes, but to make sure i dont make any mistakes moving things around
13:21duck1123unit tests :)
13:21daniel__:)
13:21duck1123anyway, I'm off. good luck
13:21daniel__alright, thanks
13:23daniel__robermann: interesting stuff, you wrote that in clojure?
13:24robermannno, it was in java, it started on 2006
13:24robermannbut the "sonification" core is now delegated to Max/MSP patches
13:24robermannor Pure Data
13:25robermannthe more interesting java library was jsyn
13:26ziltiI've seen this piece of code in a presentation (defn describe [[head & tail]] (body here)) and wondered what would happen if it's possible to split the arg in more than two parts. It turned out that [[first & second & tail]] doesn't work. So is the [[x & y]] only syntactic sugar for head and tail?
13:27ziltirobermann: What did you write? I joined too late but it sounds interesting
13:29Borkdudezilti: how about (defn describe [[a b & tail]] [a b tail])
13:30robermann_zilti: we were speaking of www.codesounding.org
13:31ziltiBorkdude: Thanks :)
13:31robermann_having some spare time it would be interesting to add a plugin for using overtone
13:32Borkdudezilti: & means: all the rest of the args
13:32ziltirobermann_: That framework sounds like a fun, interesting project. :)
13:32robermann_yes, it started as a joke / challenge
13:33ziltiBorkdude: I'm very new to Clojure. I knew & usually means "varargs" but I didn't know the syntax of [[ ... ]]
13:33Borkdudenp
13:33robermann_zilti: but someone used similar techincs for software metrics: http://sourceforge.net/apps/wordpress/codesounding/2010/08/27/translating-software-metrics-into-music/
13:34ziltirobermann_: The second example sounds damn futuristic
13:35ziltirobermann_: Does it only work with Java?
13:36robermann_the second example is based on JSyn: http://www.softsynth.com/jsyn/
13:36robermann_you can also "pipe" the event to Max/MSP patches
13:36robermann_(or pure data)
13:36robermann_via UDP packets
13:37Squeesewhy is the quote used here: (require '[clojure.string :as str]) how is the vector list intepreted?
13:37BorkdudeSqueese: if the quote wasn't there you'd have to quote every single element (except :str) in the vector
13:38Borkdude~[a b c]
13:38Squeeseso its the same as (require ['clojure.string :as 'str]) ?
13:38clojurebotbartj: it's not broken. Unless you know the performance hit there is actually a problem, I'd recommend leaving it alone.
13:38BorkdudeSqueese: yes
13:38SqueeseBorkdude: hmm, thanks :)
13:38Borkdude,(+ 1 2 3)
13:38clojurebot6
13:38Borkdude,[a b c]
13:38clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0)>
13:39Borkdude,'[a b c]
13:39clojurebot[a b c]
13:39Borkdude,['a 'b 'c]
13:39clojurebot[a b c]
13:39Borkdudesee? ;-)
13:39Squeeseyeah :)
13:40robermann_zilti: it should be a trivial exerices to use overtone to play the sounds; overtone is written in clojure (http://overtone.github.com/)
13:42Squeeseha wow, '[a b '(c d)) gives me: [a b (quote (a b))] did I get a vector with symbos a, b and a list with symbos quote etc?
13:42Squeesesymbols*
13:42Borkdude,(quote ')
13:42clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: )>
13:43Borkdudeeh
13:43Squeese, '[a [
13:43clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
13:43Squeeseops
13:43Squeese, '[a '(b)]
13:43clojurebot[a (quote (b))]
13:43Borkdude' is a reader-macro for quote
13:43BorkdudeI think
13:44Borkdude(quote [1 2 3]) => [1 2 3]
13:44Squeesefunny :)
13:44daniel__what function do i need here? (map #(???) ("line" "line" "line")) = ("1 line" "2 line" 3 line")
13:44Borkdude(quote '[1 2 3]) becomes (quote (quote [1 2 3])) => (quote [1 2 3])
13:44Borkdudedaniel__ take a look at map-indexed
13:45daniel__thanks Borkdude
13:46Borkdude,(map-indexed (fn [idx itm] (str idx " " itm)) ("line" "line"))
13:46clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
13:46Borkdudefuck, I should try those out first ;)
13:46SqueeseIm happy I choose to look into Clojure when deciding between lisp's, not really happening in #scala :P
13:46alandipert,(map (partial apply str) (range) (repeat \space) '("list" "list" "list"))
13:46clojurebot("0 list" "1 list" "2 list")
13:46Squeese+anything
13:47alandipertmap-indexed would be better if it weren't for the space you need to add
13:48Borkdude,(map-indexed (fn [idx itm] (str idx " " itm)) ["line" "line"])
13:48clojurebot("0 line" "1 line")
13:48Borkdudemore readble imho
13:49daniel__yep, thanks for the example
13:50Borkdudealandipert: I bet you are fond of Haskell? ;)
13:51alandipertkinda... i definitely lost the taste for naming intermediate variables somewhere on my quest
13:52Borkdudeccorn: what's up, I saw "What action to take on ccorn" in my Aquamacs
13:52Borkdudeccorn: didn't know what it was so I ignored it...
13:54daniel__,(map-indexed (fn [idx itm] (str idx " " itm)) (repeatedly #(inc %) 1))
13:54clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: sandbox$eval28$fn__31 cannot be cast to java.lang.Number>
13:55daniel__has to be a vector?
13:55daniel__,(map-indexed (fn [idx itm] (str idx " " itm)) (vec (repeatedly #(inc %) 1)))
13:55clojurebot#<ClassCastException java.lang.ClassCastException: sandbox$eval59$fn__62 cannot be cast to java.lang.Number>
13:55daniel__,(map-indexed (fn [idx itm] (str idx " " itm)) (vector (repeatedly #(inc %) 1)))
13:55clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: sandbox$eval90$fn__93 cannot be cast to java.lang.Number>
13:56daniel__,(map-indexed (fn [idx itm] (str idx " " itm)) [1, 2, 3])
13:56clojurebot("0 1" "1 2" "2 3")
13:58Borkdudedaniel__: I think you meant (iterate inc 0)
13:58dnolenibdknox: (- 1), yet another stupid bug in my compiler macro additions. that's fixed now.
13:58Borkdudebut if you do that here, it will cause map to go over an infinite seq..
13:58dnolenif anyone knows how to run the CLJS tests I'm all ears.
13:58ibdknoxdnolen: :)
13:58ibdknoxno idea
13:59Borkdudedaniel__: so you could do (take 10 (iterate inc 0)) or just (range 10)...
13:59daniel__Borkdude: yeah...and nvm, i got my code working :)
14:00ibdknoxdnolen: there used to be a tests script I though
14:00daniel__ (nth (map-indexed (fn [idx itm] (doto (str idx " " ((fitness-fn target) itm) " " itm) println)) (iterate #(evolve % (fitness-fn target)) source)) generations))
14:00dnolenibdknox: it's there but it doesn't actually run the tests
14:00dnolenit just builds the file, and I don't see how to run what it produces.
14:01ibdknoxhm
14:01ibdknoxyeah I dunno
14:02ibdknoxyou could compile the tests and run them in the browser?
14:03ibdknoxdnolen: other option: add the test dir to your classpath for the repl and run the test_runner
14:05ibdknoxuhoh
14:06ibdknoxI'm not sure that telling people they shouldn't voice opinions is the way to go :/
14:06ziltihttp://vimeo.com/10896148 (Clojure - Stuart Halloway) seems to be a really awesome presentation for programmers coming from a non-lisp language
14:08dnolenibdknox: I think the point is that some posts are just opinions - not technical discussion. I've done my fair share of opinion mongering :D
14:09ibdknoxdnolen: Opinions are incredibly important in any community, whether it be technical or not
14:10dnolenibdknox: to a point yes. but don't we have blogs for that?
14:12ibdknoxdnolen: sure, but the mailing list is also a central meeting place for the community. Some opinions are not valuable, others should be discussed. There's no better place for the latter
14:12ibdknoxdnolen: The cost of allowing the latter is that you'll get some of the former. That's how communities go.
14:13dnolenibdknox: I don't think the post is necessarily about recent discussions. I think it's about a lot of threads that have astray in the past.
14:13jliI'm profiling some clojurescript. it seems like the reader is pretty slow, and 20% of the time is spent in cljs.core.truth. does this make sense?
14:14ibdknoxdnolen: fair enough. I just know my knee jerk reaction to the email wasn't a good one. I suspect for newish people setting a tone like that will force them away :/
14:14ibdknoxjli: how old is your clojurescript?
14:14dnolenjli: possible, I did some work on inlining truth, but in browsers like Chrome after advanced optimizations it didn't seem to be the bottleneck. Some more scientific benchmarking required tho.
14:15jli20% truth_, 9.4% _equiv, 3.2% _count, 3.2% PushbackReader$read_char
14:15ibdknoxjli: where are you running it?
14:15jliibdknox: master as of last night
14:15jliibdknox: in Firefox 7
14:15jli(is that what you mean?)
14:15ibdknoxyep
14:16dnolenjli: can you try that in Chrome as well?
14:16jliit seems a lot faster in Chrome
14:16ibdknoxjli: also, can you put a gist up of what you're running?
14:16jlidnolen: what can I use for profiling in Chrome?
14:16dnolenjli: the Web Inspector
14:16ibdknoxjli: it has dev tools in it
14:17dnolenjli: the problem w/ inlining truth via the CLJS compiler is that it's not a code size win. You really want something like V8 Crankshaft to do that work for you.
14:23jliyeah, chrome is a lot faster. 2.5% _equiv, 2.3% call, 1.3% truth_
14:23jlidnolen: you mean Chrome's JS engine is doing the inlining?
14:23dnolenjli: yes
14:24jlihuh, I wonder if that's the main difference?
14:24ibdknoxprobably
14:24jlitruth_ is all over the place
14:24jli327k calls
14:24dnolenjli: most likely. The JS engines really should do that work for us.
14:25dnolenjli: truth_ is good. It removes all the crazy semantics around JS truthiness / falsiness
14:25ibdknoxdnolen: I sincerely hope we don't change the property syntax
14:25jliyeah
14:25jliI'm going to manually inline truth_ in my compiled cljs and see if it's faster in firefox
14:26dnolenibdknox: What's your concern after the discussion?
14:26ibdknoxdnolen: it's conflating concepts that don't belong together. Interop should be interop. Map-like keyword access should be reserved for maps.
14:29dnolenibdknox: I think rhickey's points about the issue are sound. It's not about interop so much as it's about being able disambiguate property / method calls. We don't have that luxury in JS.
14:29dnolenibdknox: my main concern was only around setting.
14:34ibdknoxdnolen: his point is that early users were confused by it. Every single one of those early users was a Clojure programmer... They're the only ones that *would* be confused. A JS person already knows of this distinction
14:35dnolenibdknox: it's also not map-like keyword access really. the dot operator is a special form and not composable.
14:35dnolenibdknox: that's not entirely true, (.foo x 1 2) will be a fn call. (.foo x) won't.
14:36dnolenplenty to trip up people who don't know anything about Clojure.
14:36ibdknoxI think that's an ambiguity that shouldn't exist, but I may be in the minority there
14:38dnolenibdknox: if we don't got there, the above confusion will still exist. the change removes ambiguities around calling conventions.
14:40dnolenibdknox: also some JS apis will do multi-arity stuff via arguments. So in the current system you have to write (. x (foo)) (.foo x 1) (.foo x 1 2)
14:40ibdknoxthat's not trueh
14:40dnolenwith the proposed change, (.foo x) (.foo x 1) (.foo x 1 2), I think that's a win.
14:40ibdknox-h
14:40ibdknox(. x (foo)) (. x (foo 1)) (. x (foo 1 2))
14:41ziltidnolen what about doto?
14:42dnolenibdknox: the problem here is that . tries to uphold the Lisp convention. fn first. that's abandoning it.
14:43ibdknoxdnolen: my argument isn't really a technical one, it's about fitting in. Keywords have 0 meaning in the languages that are interop'd with, symbols map logically with the things people are used to.
14:43ibdknoxdnolen: I've always thought of it as the function being dot
14:43ibdknoxdnolen: the thing I'm doing it to is x, and what I'm doing is applying some function to it. It's very much like the threading operators which make a lot of sense to me
14:43sridcan I avoid the `range` in (reduce #(...) val (range (dec (count arg1))))?
14:44ibdknoxdnolen: it's actually more internally consistent with Clojure I think
14:44sridelements of range arrya will be ignored in the reduce fn
14:44sridhere's the complete function, https://gist.github.com/1289963
14:45dnolenibdknox: (. x (foo)) was always considered a degenerate form as far as Lisp conventions go in Clojure. If . is a function, then it's something like Obj-C msg_send, which just isn't true at all.
14:46jliheh: cljs.core.truth_("\ufdd0'else")
14:47zilti"(defn index-filter [pred coll] (when pred (for [[idx elt] (indexed coll) :when (pred elt)] idx)))" I don't understand that at all. How does that work?
14:48dnolenjli: https://github.com/clojure/clojurescript/tree/80-inline-truth, I have branch w/ truth inlining
14:49Borkdude,(doc index-filter)
14:49clojurebotCool story bro.
14:50Borkdudezilti, this isn't a std clojure function?
14:51Borkdudezilti: (when pred ...) just means: when a predicate is provide
14:51Borkduded
14:51Borkdudezilti: thes rest is a standard for with :when guard
14:52ibdknoxdnolen: like I said, I have no technical ground to stand on and since it's been firmly declared that's what I need, I'll just leave it be.
14:52ziltiBorkdude: I don't understand that part that's going on in the for part. indexed is supposed to be a function returning pairs
14:53Borkdudezilti: I don't think indexed is in clojure.core, keep-indexed is
14:53ziltiBorkdude: Yes, I know it isn't in the core. I have that code from a presentation slide
14:54Borkdudezilti: (keep-indexed pred coll) is what we would write nowadays I think
14:55ziltiBorkdude: Instead of the whole thing inside the for block?
14:57dnolenibdknox: I agree w/ you as far as aesthetics are concerned. But I just can't see what would be better for JS property access.
14:57dnolenwe lose a semantic wart and gain an aesthetic one
14:57ibdknoxdnolen: just leave it be. This is a documentation issue, not something we should special case in the language. This is a result of the host platform
14:58dnolenibdknox: but ClojureScript already removes so many problems that exist in the host.
14:58Borkdudezilti: for example (keep-indexed #(if (even? %2) %1) (range 100 110))
14:58dnolenibdknox: proper scoping rules, fixes truthiness/falsiness, etc.
14:58ibdknoxthat's true, but should we really add syntax that only matters for JS?
14:58ibdknoxdnolen: this is only for interop
14:59Borkdudezilti: it means: I'm only interested in the indexes for the numbers in the range that are even
14:59ibdknoxdnolen: I agree, Clojure abstracts JS away... but you can't abstract the host from features designed to interact with it
14:59Borkdudezilti: so it is slightly different than I said at first
15:00ziltiBorkdude: Apparently a long way to go for me. Where does the second argument in the anonymous function come from?
15:00Borkdudezilti: so: (defn index-filter [pred coll] (keep-indexed #(if (pred %2) %1) coll))
15:01Borkdudezilti: if you wish: (defn index-filter [pred coll] (keep-indexed (fn [idx elt] (if (pred elt) idx)) coll))
15:01dnolenibdknox: rhickey seemed OK w/ moving forward without addressing it, but fundamental issues like this can end up really creating headaches down the line.
15:01Borkdude#(... %1 %2) is an anonymous function, %1 is the first argument, %2 the second, etc
15:01dnolenibdknox: I think by now he has a good idea of what sort of things plague newcomers to a language :)
15:02ibdknoxdnolen: Ok, so how about a convention that is property accessors are done by (aget x "foo") and make (.foo x) always mean call a method if this is really something that has to be done
15:02ibdknoxdnolen: I'm not new to languages either :)
15:02ibdknoxdnolen: and I would argue he generally doesn't care about newcomers, but maybe that's me being cynical based on all of his communications lately
15:03ziltiBorkdude: I know, but where are the arguments from? Where's the idx arg from and where's the elt argument from?
15:03dnolenibdknox: aget is prevents advanced optimization
15:03ibdknoxdnolen: I meant less that exact mechanism, and instead something like it. Sorry, that was misleading
15:03Borkdudezilti: keep-indexed expects a function of two arguments, the index and the element
15:03jlidnolen: if code is testing truth on an expression, do you use a local variable or avoid inlining it?
15:03Borkdudezilti: it will index the collection and then apply the function to every index and element of the collection
15:04dnolenibdknox: I don't think that's true at all, but I think he does expect the community to do that work.
15:04dnolenjli: if truth test is an expression context, no inlining
15:04dnolenibdknox: ah a new special form
15:04Borkdudezilti: so a bit like indexed, only less explicity
15:04Borkdude-y
15:05dnolenibdknox: (js-get x foo) ?
15:06ibdknoxdnolen: given that it's only specific to JS... I guess. Though we could make it something more general as to mean "interop property accessor"
15:06ibdknoxthat way it's at least sensical in other contexts, even if it's unlikely to be used
15:06ibdknoxhell
15:07ibdknoxwe could extend get to do it
15:07ziltiBorkdude: Ah it needs a function taking two args. Now I see. Thanks! But, getting back to "(defn index-filter [pred coll] (when pred (for [[idx elt] (indexed coll) :when (pred elt)] idx)))" again, how does that destruction work?
15:07Borkdudezilti: keep-indexed is more general than indexed, but you can do the same with it:
15:07ibdknox(get x foo)
15:07Borkdude,(keep-indexed #(vector %1 %2) ["foo" "bar"])
15:07clojurebot([0 "foo"] [1 "bar"])
15:07ibdknoxI guess it'd be (get x 'foo)
15:08dnolenibdknox: yeah can't overload get like that, 'foo might be a real key in a ObjMap
15:08ibdknoxdnolen: yeah
15:08Borkdudezilti: ah, for has the same destructuring (I think) as let, defn etc
15:09ziltiBorkdude: It's less about what the code does now, it's more about what is the exact syntax for that destruction thingy - is there an info document somewhere or can you describe that in a few words?
15:09dnolen(-get x foo)
15:09Borkdudeso: (let [[a b] [1 2]] a) => 1
15:10Borkdudezilti: just google on clojure destructuring
15:10ibdknoxdnolen: Maybe we do need to solve this problem, but I don't think the weird syntax proposed is that solution. If we're just doing it for JS, we should do something that makes more sense. Maybe it is (-get ..) or something similar, maybe it's something else entirely.
15:10ibdknoxdnolen: either way, adding a specific syntax to a space that's already confusing isn't the right thing to do
15:10dnolenibdknox: -get would interesting, - already connotates a low level op. it also mans dot operator is always fn call
15:10Borkdude,(for [[a b] [[1 2] [3 4]]] a)
15:10clojurebot(1 3)
15:10jliBorkdude: zilti: I always look at the docs for let http://clojure.org/special_forms#Special%20Forms--(let%20[bindings*%20]%20exprs*)
15:11dnolens/man/means
15:11lazybot<dnolen> ibdknox: -get would interesting, - already connotates a low level op. it also meanss dot operator is always fn call
15:11ziltiBorkdude: Oh. indeed. I searched for "clojure destruction" which didn't give me anything useful
15:11ibdknoxdnolen: that's the kind of consistency we should go for I think
15:12Borkdudezilti: the simple case of for is (for [a [some-seq]] ....), in every iteration a becomes the next element from some-seq
15:12Borkdudezilti: with destructuring you just destructure on the next element from some-seq
15:13dnolenibdknox: I like the idea of -get, posted on the ML.
15:13ziltiBorkdude: Thanks a lot. I'll take a look at that. But for today I'm kinda tired and have already learned a lot...
15:14Rayneshttp://stackoverflow.com/questions/3337888/clojure-named-arguments
15:14jliblah, so truth inlining reduced the # of calls pretty dramatically, but I couldn't get rid of it everywhere. dnolen: crankshaft is probably able to inline functions even applied to expressions, right?
15:15dnolenjli: I would think so.
15:15Borkdudezilti: ok, have fun and be careful, because Clojure is addictive
15:15dnolenjli: yeah it's impossible to inline truth everywhere because of expression contexts.
15:15jliyeah, okay. I guess I'll quit trying to read-string 500 records at a time
15:16dnolenif(var x = foo(); ..) { … } sadly not allowed in JS.
15:16jliboo
15:17dnolenjli: out of curiosity how long is that taking?
15:24jampartnewbie Q: is there really no way to extend a "class" (datatype) in Clojure?
15:25dnolenibdknox: I'm liking this -get compiler idea macro more and more. We can validation and ensure that x in (-get foo x) must be a symbol.
15:26dnolenjampart: there's no subclassing in Clojure if that's what you mean.
15:26ibdknoxdnolen: yeah, it allows for a much greater degree of flexibility and is internally consistent :)
15:27dnolenibdknox: hopefully people bite, fingers crossed.
15:27jlidnolen: to read 490 records (~98k of text) and render relatively straight-forward HTML from it is ~5.5s in Firefox 7 and ~1.8s in Chrome.
15:27ibdknoxjli: with the inlining?
15:28ibdknoxjli: you're dealing with seq performance there I bet...
15:28dnolenjli: yeah curious about how long that takes w/ inlining, this is a good benchmark.
15:29ibdknoxdnolen: are you interested in sitting down with folks and talking about the pods stuff at the Conj?
15:29dnolenibdknox: haha, I hardly know anything about Pods, nor how that concept could be leverage efficiently in ClojureScript :)
15:30jampartdnolen: so protocols are the only means of subtyping? Can't even subtype records?
15:30jliibdknox: dnolen: that was without. with my manual inlining, it's maybe ~4.7 in firefox and ~1.2 in chrome. dnolen: I'll try your branch later and also try to get more accurate timing
15:30ibdknoxdnolen: haha I don't either. So I guess maybe the correct thing to say is, would you be interested in working on an efficient seq-like thing
15:30dnolenjampart: no subtyping.
15:31dnolenjampart: protocols aren't really subtyping.
15:31jampartdnolen: so even protocols can't be "derived", as in Haskell's type conditions?
15:32dnolenjampart: don't know Haskell that well, but yes from what I understand Haskell support derivation - Clojure does not.
15:33dnolenibdknox: definitely interested in the discussion. we should corner rhickey and get him to give us some pointers.
15:58btbyI'm new to Clojure. I'm currently going through Peter Norvig's AI book and was wondering if there was an easy way to leverage the Java code for the book (https://code.google.com/p/aima-java/)? I'd like to use Clojure as my exercise language, considering that the original book had Common Lisp as implementation language.
16:02Borkdudebtby, there is a Peter Norvig AI/Lisp book
16:03Borkdudebtby: highly recommendable: http://norvig.com/paip.html
16:04BorkdudeAt the time, I found it the best programming book I ever read (halfway through my CS studies)
16:05btbyBorkdude: Thanks! I've heard about it, but assumed AI: Modern Approach to be a proper superset. Now I'll look closer.
16:05Borkdudebtby: those are two different books
16:05Borkdudebtby: the one I mentioned is more about Lisp and shows the power of the language using AI examples
16:06Borkdudebtby: the other one is more about AI and the code is just there to illustrate how things works in AI
16:06Borkdudebtby: at least, that is how I understood it while reading both ;)
16:06btbyBorkdude: I'm using AIMA (the non-Lisp one) for the course I'm taking at the moment.
16:08Borkdudebtby: I don't really get the question. The lisp code is up here: http://aima.cs.berkeley.edu/lisp/doc/overview.html
16:08Borkdudebtby: apparently the Java code is also available. Would you like to use it from Clojure?
16:08Borkdudebtby: or translate it to Clojure
16:09btbyBorkdude: Yup, using Java from Clojure if it's possible, although if the modification of Common Lisp code is not hard, I'd assume that to be more educational.
16:09Borkdudebtby: it would definitely a cool project to make a Clojure port ;-)
16:09Borkdudebr
16:09Borkdudebe
16:10btbyChallenge accepted, then. =)
16:11btbyBut in case I need Java to do that last-minute assignment, is it still possible?
16:11Borkdudebtby: you can do Java interop in Clojure, yes?
16:12Borkdudebtby: http://clojure.org/java_interop
16:13gfredericksso what happens if you try to use clojure 1.3 and one of the deps asks for 1.2?
16:14btbyBorkdude: Thanks!
16:23amalloygfredericks: in conflicting dependencies, the one specified in the top/main level wins
16:23gfrederickshuh. I never would have guessed that.
17:15duck1123do you need to type hint this when doing gen-class methods, or does it already know the type of that one?
17:34arohnerduck1123: clojure will infer the types if you're overriding methods. For new methods that don't override anything, you'll need hints
17:35amalloyarohner: he was asking about hinting the `this` parameter. i'd be surprised if whether you override a method influences clojure's ability to infer that
17:35arohneroh, right. reading comprehension FTW
17:47droidboihi
17:50droidboii am nu 2 this
17:55droidxmxwhat does an N at the end of an int mean?
17:57gregha following M means BigDecimal, but I'm not sure what N means
17:58greghsee http://clojure.org/reader for details
17:59droidxmxgregh: ok thx
17:59ibdknox,(type 1N)
17:59clojurebotclojure.lang.BigInt
18:00ibdknoxdroidxmx: ^
18:00droidxmxcool
18:02droidxmx'nox: nice one
18:02gregh,(type 1M)
18:02clojurebotjava.math.BigDecimal
18:03greghso does /reader need to be updated to add N?
18:08droidxmx,1
18:08clojurebot1
18:08todunI was using emacs to work and the swank server connection closed. This is confusing me because I thought it is a server running on my local machine. Is this normal?
18:09droidxmxnice
18:09Apage43todun: if the jvm it was running in died or crashed for some reason
18:10todunApage43: I see. what if there is no warning?
18:10todunApage43: the jvm doesn't give any warning. can it still just randomly crash?
18:10ivan`is there an Anki or Mnemosyne deck with Clojure flashcards anywhere?
18:14Apage43todun: *shrug* depends what caused it to blow up
18:14todunso I shouldn't worry about it I guess..
18:14todunthanks.
18:15Apage43probably not. If it keeps happening you might want to care more.
18:17todunApage43: ok.
18:25kanjaI'm having a ton of trouble getting slime installed with clj - I keep getting errors like: "Symbol's function definition is void: 
18:25kanjadefine-slime-contrib" when trying to enter slime mode. I found the offending line in swank-clj's definition, but I don't know where slime-contrib should be. Any ideas?
18:26amalloydon't use swank-clj. it's like a hundred years old
18:26amalloyer
18:26amalloyno, that's ritz's new name, isn't it? i'm not sure now
18:27kanjait's in the package.el repository, and most of the install walkthroughs I see use it...
18:29amalloykanja: from https://github.com/pallet/ritz it looks like swank-clj was renamed to ritz, not the other way round. but anyway, i was thinking of slime-clj, which definitely is old :P
18:30kanjaamalloy: ah - yeah I'm tyring to get slime-clj installed. If that's old, what should I use instead?
18:31amalloykanja: have you looked at that github link? he seems to bundle slime-ritz with the swank package
18:33amalloyi never got ritz working, myself; i still use the older swank-clojure with one of technomancy's snapshots of slime
18:33kanjaI'm kind of a newb with slime/swank actually - I'm not really sure how to use it
18:37todunI am writing the following routine to remove duplicates. I think the problem is with the second condition to cond, but whenever I try to give it an independent expression, the emacs indentation complains that it's wrong: http://pastebin.com/kWDvPDQ8
18:37todunany help is appreciated. thanks.
18:40amalloytodun: you seem to have included (rest lst) inside of the (and) test instead of after it
18:40todunamalloy: yes. I realize that. but emacs complained about my indentation when I did otherwise. and I get an exception when I run it.
18:41todunrun it with both the (rest lst) in and out of the and block(is that what it's called?).
18:41amalloyemacs is not complaining about your intentation; cond just doesn't indent in a very readable manner
18:41amalloyyour exception is due to there being other issues
18:41todunamalloy: that figures :P
18:42amalloyfor example, (rd (lst)) should probably be (rd lst)
18:43todunamalloy: oh. I can leave the list out of parens?
18:43todunI see. ok.
18:43amalloyit's nothing to do with "can you leave it out". parens always (except when they don't, as discussed yesterday) mean "call the stuff inside as a function"
18:44todunamalloy: ok. sorry. I keep thinking of lists like an exception. thanks.
18:48todunamalloy: thanks. it compiles now. testing it...
18:52todunamalloy: now I get a stackoverflow. I know if you do recursion in clojure for large values without using compiler optimizations you get SO. But for small values what could be causing my SO? http://pastebin.com/ynVTZiwt
18:52amalloy:else (rd lst) - your else clause just starts the same job over again without simplifying it
18:54todunamalloy: I thought doing that in cond's and clause took care of it in the call back to the function, or no?
18:54Apage43also you can recur there, no?
18:54todunApage43: ok I will try that.
18:54Apage43todun: you haven't modified lst..
18:55todunApage43: I'm wary of that because I try it for another function I write and I get my REPL hanging...
18:55todunApage43: modified lst?
18:55Apage43(rd lst)
18:55Apage43will call rd with exactly what it was originally called with
18:56Apage43so naturally if you hit that branch it'll be an infinite loop
18:56todunApage43: will call recur in place of else solve that problem, no?
18:56Apage43.. no.
18:56todunuhm ok.
18:57Apage43What are you intending to pass to the function when you call it again?
18:58toduna list
18:58Apage43containing...
18:59todunfor example
18:59todungiven (1 2 3 1 4 1 2), returns a sequence containing the elements (1 2 3 4),
18:59todunin some order.
19:00Apage43well yes that's what you want rd to do
19:00Apage43but specifically i'm talking about the part where you're recurring
19:00Apage43what do you want to pass to rd in the next step
19:01todunApage43: oh ok.
19:02todunApage43: I want to give it the list
19:02todunthat is reduced
19:02todunfrom the previous steps.
19:05archaicis there a way to directly destructure a map in the binding: into ks and vals? ie (defn [m] (let [ks (keys m) v (vals m)] ...)
19:05Apage43sorry, can't wrap my head around what you're trying to do =/
19:05gfredericksarchaic: well what you have there would certainly work if that's what you want. But there's a whole syntax for destructuring maps too
19:05gfrederickse.g., assigning specific keys to specific names
19:06archaicyea thats what i mean
19:06gfredericksand a few other features
19:06gfredericksbut what you did there is not translatable into map destructuring
19:06gfredericksso I'm not sure what specifically you want
19:06todunApage43: was that directed at me?
19:06Apage43,(let [map {:a 1 :b 2}] (let [{a :a b :b} map] [a b]))
19:06clojurebot[1 2]
19:07gfredericksarchaic: that ^ there is certainly an example
19:07gfredericksarchaic: and this here I just googled seems to go over it in detail: http://blog.jayfields.com/2010/07/clojure-destructuring.html
19:08archaicI wanted something like (defn [[ks val] m]) where ks and vals are the keys and vals in m, rather than what I first wrote, since I seem to be using that alot
19:09gfredericks,(let [m {:a 1 :b 2 :c 44}, [ks vs] ((juxt keys vals) m)] [vs ks])
19:09clojurebot[(1 44 2) (:a :c :b)]
19:09archaicyah that works, would that be reasonable macro?
19:09gfredericksarchaic: aside from that kind of ugly mess, there's not direct support. I'm curious why you end up doing it a lot though.
19:11gfredericksalso I don't know what you meant by "would that be a reasonable macro?"
19:11gfrederickssince what I did was not a macro
19:12archaicI know, I meant wrapping what you did to get rid of the 'uglyness
19:13gfredericksrather than a macro I would just def (juxt keys vals) somewhere and use that
19:13gfredericks(def kvs (juxt keys vals)) and then (let [[ks vs] (kvs m)] ...)
19:13archaicyeah that works, thanks
19:14gfrederickssure
19:16archaici still haven't found need to write a macro ever yet though :\ in about 3 months of clojure
19:16gfredericksthat's a good sign.
19:18archaicexcept if your trying to learn them
19:19gfrederickswhy would you be trying to learn them if you don't need them? :)
19:23todunis it possible to pass the name given to a function in a let binding to the argument of a recursion?
19:23gfrederickso_o
19:23amalloytodun: first of all, you know distinct already exists, right? you're implementing remove-duplicates for practice?
19:24todunamalloy: yes.
19:24todunto practice my recursion
19:24amalloyokay. well i think your algorithm is impossible, so working on your syntax is not going to help
19:24todunamalloy: oh. sigh.
19:25todunI'll appreciate any suggestions. thanks.
19:25amalloyin order to remove duplicates of some sub-list x, you need to know what elements have already been "selected" to return in the previous iterations
19:25todunamalloy: so. using let can help, no?
19:25todunas in binding that output to the next call.
19:26todun*recursive.
19:28gfrederickstodun: is your code posted somewhere?
19:28todungfredericks: yes. let me repost it...
19:28amalloytodun: here's a quick sketch i put together trying to stick to simple language features: https://gist.github.com/1290310
19:29archaictodun, I would do something like (reduce some-fn #{} coll) where some-fn uses contains? to check for duplicate
19:29todungfredericks: http://pastebin.com/ynVTZiwt
19:30amalloythe key point is that you have to manually track what elements have already been returned - given just the "current" sub-list you can't tell which elements of it to return
19:30todunamalloy: archaic seeing allot of new notation here. will take me a second to comprehend it all.
19:31todunamalloy: ok. so using a compare between adjacent elements is not a good idea?
19:31amalloytodun: then how would you fix '(1 2 1) into just '(1 2)?
19:32todunthat's why I was simultaneously checking if the list was distinct.
19:34Apage43todun: checking if distinct is distinct?, btw. distinct removes duplicates.
19:34todunApage43: yes. it is sort of backwards. I was hoping to learn the different forms of recursion in clojure.
19:35amalloytodun: you're implementing distinct yourself. if you use it as part of your solution, you might as well just make it your whole solution
19:35amalloy(def rd distinct)
19:36gfredericksbrilliant!
19:36todunamalloy: true :)
19:36Apage43you can always look at how distinct is implemented. Mind it is lazy: https://github.com/clojure/clojure/blob/f5f827ac9fbb87e770d25007472504403ed3d7a6/src/clj/clojure/core.clj#L4413
19:37gfrederickshuh. I didn't know it was lazy. ##(take 5 (distinct (range)))
19:37lazybot⇒ (0 1 2 3 4)
19:37gfrederickswell I'll be.
19:37todunApage43: thanks.
19:38todunamalloy: I'm still looking at your code and you use recur. I have code I wrote that uses recur. It compiles fine but it runs like for ever on small input. I think I'm missing the point of all these recursion optimizations. Can I post it?
19:39amalloyyou can post anything you want :P. in this case i was using recur mostly because i wanted a loop, not because i wanted to "optimize" it
19:39todunamalloy: ok. thanks. http://pastebin.com/5txqZnU8
19:40todunamalloy: that is so counter-intuitive that I'm not sure I understand. how can you use(surely you did and it works) recur to make a loop?
19:40todunamalloy: or is this idiomatic clojure?
19:40gfredericksironically, this recursive reversal seems like a great non-use-case for loop/recur
19:41gfredericksi.e., the simplest way is to use traditional recursion
19:41gfredericks(defn rreverse [coll] (reverse (map rreverse coll)))
19:42gfredericksexcept I forgot the base case
19:42gfrederickswell it works for infinitely nested lists anyways :)
19:43gfrederickstodun: the problem with using recur for rreverse is that recur only lets you make one recursive call. If you want to rreverse every element in the input list, you'd want to recurse for each element.
19:44gfrederickswhich you can't do with recur
19:44todungfredericks: I see.
19:44todungfredericks: will a lazy seq do something similar?
19:45gfredericksrecur has a lot more in common with imperative languages' loops than with the things that you would normally do recursively in an imperative language
19:45Apage43recur is not a function call. it means "rebind these vars and jump to the recursion point (beginning of the fn, or loop, usually)"
19:45todungfredericks: since lazy seqs should only do work when they have.
19:45gfrederickstodun: I think that's kind of a separate issue.
19:45todunApage43: ok.
19:45todungfredericks: oh?
19:46gfrederickstodun: mostly because I don't see how it relates :)
19:46gfrederickstodun: your whole goal at the moment is to learn recur, is that correct?
19:46todungfredericks: yes. or recursion in general.
19:47gfrederickswhat other languages are you familiar with?
19:47archaicohhh I didn't know you could do nested destructuring nice.. refactor time (defn binding-test [{[x & xs] :content}] [x xs]
19:47todungfredericks: though I'm brand new to programming, I've dabbled in quite a few.
19:47todunjava, scala, python.
19:48todunI'm not particularly good in any of them. but I'm still learning. so if I say something that doesn't make sense..well, you know why.
19:48gfrederickshuh. I hadn't prepared a general recursion lecture.
19:49gfredericksI assume you came across the term "tail call" recently?
19:50todunyes. sort of.
19:50todungfredericks: especially in my clojure readings.
19:50todunTCO.
19:51gfredericksyeah
19:51amalloywhen i was learning lisp, i had this idea that it was all about writing recursive functions, especially tail-recursive
19:51todunamalloy: oh.
19:51amalloyand in some ways, it is, but mostly you can let the standard-library functions do all the recursion for you, and write your code in terms of map, reduce, and so forth
19:52todunamalloy: ok. relying on higher-order functions to do the work.
19:52amalloyright. like gfredericks's definition of deep-reverse in terms of map instead of manual recursion
19:52todunamalloy: sadly, that doesn't help my agenda of learning recursion.
19:53gfrederickstodun: do you have any actual problems/projects you're working on, or are you simply trying to learn clojure?
19:54amalloy&(letfn [(rreverse [coll] (if (sequential? coll) (reverse (map rreverse coll)) coll))] (rreverse [1 2 [3 4 5 {6 7} [8 9]]]))
19:54lazybot⇒ (((9 8) {6 7} 5 4 3) 2 1)
19:54todunamalloy: I think clojure can be instructive in this way, because it has so many idiomatic ways of doing recursion. I just have to
19:54todunamalloy: both actually.
19:55gfrederickstodun: I think the "so many ways" that you're thinking of is really just an unfortunate side-effect of the JVM rather than an intentional language feature
19:55todunamalloy: one is one for school hw. another is for learning programming.
19:56todungfredericks: ok.
19:56gfredericksideally there's just one way to do recursion, and TCO happens whenever possible
19:57todungfredericks: ok. how so?
19:57gfredericksa function calls itself
19:57gfredericksthat's how it works in haskell and erlang.
19:57todungfredericks: uhm. ok. that makes sense.
19:57gfredericksI think (loop) is just syntactic sugar, as you could do the same thing with (fn ...)
19:58amalloyyes
19:58todungfredericks: not too familiar with the mechanics in those languages but I've seen they do allow TCO(at least erlang)
19:58gfredericksamalloy: do you know why loop is listed as a special form?
19:58todungfredericks: actually I was just reading up on loop now.
19:59amalloygfredericks: technically only loop* is a special form
19:59Apage43todun: exactly. because they have TCO, the optimization happens automatically
19:59todungfredericks: it seems like a way to do any kind of recursion you want.
19:59amalloybut the docs are pretty vague about it
19:59ibdknoxI think I'm missing the point of Clojure-Dev list :/
19:59Apage43todun: clojure does not have TCO, which is why it has recur
19:59gfredericksamalloy: I just read today that "several special forms are actually implemented as macros" and it was weird. Made me think I don't know what "special form" means, because I thought it was mutually exclusive with macros.
19:59amalloygfredericks: loop *could* be implemented as a macro on top of fn, but for performance reasons it is not
20:00todunApage43: ok. I know scala has TCO and it relies on the JVM too.
20:00todunApage43: why is clojure different?
20:00gfredericksamalloy: okay, that makes sense of it
20:00gfredericksamalloy: assuming that the quote I just mentioned was mildly incorrect and the starred versions are the actual special forms
20:00amalloygfredericks: you're right, special forms and macros are distinct and non-overlapping. but if you pretend that loop* doesn't exist, then loop is kinda like a special form
20:01gfredericksamalloy: so you think the docs page claims that let/fn/loop are special forms just for simplicity?
20:01amalloyyes
20:01Apage43todun: Scala can do what clojure's recur does, but it can't do TCO when the tail-call is not to the same function
20:01gfrederickskay. my world is right again.
20:02gfredericksApage43: but clojure can't do it even when it is to the same function. I assume that's because it's dynamic.
20:03Apage43right
20:03amalloygfredericks: clojure could do that but chooses not to. dynamism doesn't enter the picture
20:03Apage43clojure could just detect where you could use recur and replace it with recur
20:03todunApage43: I thought scala couldn't do mutual recursion but could tco?
20:03Apage43but if we force you to use recur you can more easily understand when you are and aren't going to be consuming stack
20:04gfredericksamalloy: what's the rationale then?
20:04amalloygfredericks: <Apage43> but if we force you to use recur you can more easily understand when you are and aren't going to be consuming stack
20:05Apage43you absolutely -know-, in clojure, that if you aren't using recur you are adding a stack frame
20:05gfredericksamalloy: so clojure just hates implicit TCO regardless of the jvm?
20:05ibdknoxeh
20:05todunApage43: so recur is like tco then, like the book says, no?
20:06ibdknoxas hiredman said it the other day, if the JVM had TCO, Clojure would have TCO too
20:06amalloyi don't think so. if tco to other functions were possible, clojure probably wouldn't demand a special annotation saying "please do it"
20:07gfredericksokay, so it prefers all or nothing
20:07gfredericksrather than "just to self"
20:07ibdknoxgfredericks: consistency is king
20:07ibdknoxwithout consistency, it's impossible to be "simple"
20:08gfredericksI'm still confused about why dynamism has nothing to do with it.
20:08gfrederickswould it not be a problem if a function altered the var it pointed to and then invoked that var "recursively"?
20:09Apage43recur is nice compared to automatic self-call optimization because you can't THINK it's going to work, have it compile and run, and then perform really badly because it couldn't do the optimization
20:09Apage43if recur won't work, it won't compile
20:09ibdknoxApage43: I'm with you, I think being explicit in this case is valuable
20:10gfrederickss/it pointed to/that pointed to it/
20:10lazybot<gfredericks> would it not be a problem if a function altered the var that pointed to it and then invoked that var "recursively"?
20:10Apage43gfredericks: that's not self-recursion anymore, and not even scala can do that
20:11gfredericksApage43: I'm not arguing it is I'm arguing the compiler couldn't tell that's not happening
20:11gfredericksso how is it possible to implement self-recursion in clojure?
20:12gfredericksI'm specifically responding to amalloy's "clojure could do that but chooses not to. dynamism doesn't enter the picture
20:12gfredericks"
20:15amalloygfredericks: i think it's pretty hard to write code that does that even without implicit tco
20:15gfredericksyou mean unintentionally?
20:15amalloyeven on purpose you have to try pretty hard
20:16gfredericks(defn foo [& args] (foo (alter-var-root! foo ...)))?
20:16amalloyno good
20:16gfrederickshow come?
20:16amalloy&(macroexpand '(defn foo [& args] (foo (alter-var-root! foo inc))))
20:16lazybot⇒ (def foo (.withMeta (clojure.core/fn foo ([& args] (foo (alter-var-root! foo inc)))) (.meta (var foo))))
20:16amalloythe internal foo is not referring to the var at all,but to the local function name
20:17gfredericksokay, so then write it like the expanded version but without the function name
20:17gfredericks(def foo (fn [& args] (foo (alter-var-root! foo ...))))
20:18amalloygfredericks: and now foo gets evaluated for the function call before the alter-var-root happens
20:18Apage43it could just choose not to do the optimization for unnamed functions
20:18amalloyi'm just saying, it might be possible to trick the compiler, but it's very hard to write code that does that and is otherwise correct
20:19gfredericksokay
20:19amalloybut anyway that's *not* a self-call anymore - it's a function calling to a named var
20:20amalloywhich happens to, for the moment, contain the same functino
20:21gfredericksI guess I didn't imagine an implicit-self-call-TCO implementation that distinguished, but I guess that'd be the way it would have to go, and it would still be useful based on what you just lernt me about the defn macro
20:22Apage43very good reason to leave them alone once you set them =P
20:23amalloy(binding [binding let] (...profit???))
20:23gfrederickslol
20:24gfredericksI figured out just in my own head that that wouldn't compile
20:26amalloy&(with-bindings {#'binding #'let} (binding [inc dec] (inc 1)))
20:26lazybot⇒ 2
20:27amalloythat one compiles but doesn't actually do anything, which makes it more fun
20:31droidxmxhi
20:32gfredericksdroidxmx: hi
20:32droidxmxhi gf
20:32droidxmxsup
20:33gfredericksvars
20:34droidxmx?
20:34droidxmxvars?
20:34clojurebothttp://www.slideshare.net/mudphone/fun-with-vars
20:34gfredericks(inc clojurebot)
20:34lazybot⟹ 6
20:35droidxmxwhat is that?
20:37gfrederickswhat is what? vars?
20:38droidxmxyes
20:38gfredericksholy crap how did I go this long without knowing about with-out-str?
20:39gfredericksdroidxmx: clojure.org/vars
20:40gfredericksdroidxmx: I only mentioned it because it was the last thing that was talked about before you showed up
20:43amalloyhah, another excellent reason not to waste space by saying hi to everyone when you arrive. if you do, gfredericks will start talking nonsense at you
20:44duck1123So in 1.3, unchecked-divide is just / right?
20:49amalloyduck1123: that would surprise me. 1.3 doesn't default to ratios anymore?
20:50duck1123right... so where did unchecked divide go?
20:50dnolen,*clojure-version*
20:50clojurebot{:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"}
20:50dnolen,(/ 1 2)
20:50clojurebot1/2
20:51dnolen,unchecked-divide
20:51clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: unchecked-divide in this context, compiling:(NO_SOURCE_PATH:0)>
20:51duck1123I'm trying to compile aleph with 1.3 (ie. check all the things)
20:52gfredericksmaybe it's what you get when you pass floats to /?
20:54amalloy,(find-doc "unchecked")
20:54clojurebot-------------------------
20:54clojurebotclojure.core/*unchecked-math*
20:54clojurebot While bound to true, compilations of +, -, *, inc, dec and the
20:54clojurebot coercions will be done without overflow checks. Default: false.
20:54clojurebot-------------------------
20:54clojurebotclojure.core/unchecked-add
20:54clojurebot([x y])
20:54clojurebot Returns the sum of x and y, both long.
20:54clojurebot Note - uses a primitive operator subject to overflow.
20:54clojurebot-------------------------
20:54amalloyuhoh
20:54clojurebotclojure.core/unchecked-add-in...
20:54gfredericksI guess that would imply it doesn't exist in the same sense though
20:54dnolenduck1123: unchecked-divide probably doesn't make much sense - long / integer will get you a ratio.
20:55dnolenduck1123: if you coerce to double / float, you don't need unchecked.
20:55amalloydnolen: perhaps just use quot?
20:55duck1123in the place I found it, it was dividing 2 longs. I presume the unchecked- was for speed
20:58dnolenduck1123: fwiw I had a similar problem in core.logic, you can abstract away the difference between 1.2.0 / 1.3.0 with a macro over the specific operation.
21:24gfrederickshuh...the special forms page suggests that docstrings should be short: 1-3 lines
21:28duck1123gfredericks: that was before marginalia
21:29gfrederickswait is this awesome?
21:30duck1123marginalia would be more awesome if it extracted my doc strings correctly
21:30gfrederickswhy doesn't it?
21:30duck1123for the projects it works for, it looks awesome
21:31duck1123there's some odd bug, there's a ticket in for it, but I haven't looked too deeply
21:31duck1123it pulls out all my ;; comments, but none of my docstrings
21:32gfrederickshuh.
22:54kanjaI'm trying to get ritz swank working, and I'm getting "FileNotFoundException Could not locate swank/swank__init.class or swank/swank.clj on classpath" when I'm attempting to load slime - I'm assuming that I need to alter my classpath, but I don't know how - can someone point me to a resource on setting my classpath?
23:34duck1123kanja: do you have swank-clojure declared as a dependency?
23:36amalloyduck1123: that's frowned on these days anyway, right? supposed to install it as a plugin instead
23:37duck1123right, but he's using ritz, and if it's anything like the maven plugin, you need to declare it
23:37duck1123using lein, sure, you should just install it as a plugin
23:38kanjaduck1123: I think I don't? I attempted to install it via `lein plugin install ritz 0.1.7`
23:38kanjabut that doesn't do anything with emacs, does it?
23:38kanjaer nm, stupid quesiton
23:38duck1123using ritz, you still call mvn to do stuff, right?
23:39kanjaI have no idea :(
23:39duck1123I would try declaring swank as a dependency
23:39amalloyi thought there was a lein-ritz
23:39duck1123is there? I thought it was just for maven
23:40duck1123I'm thinking of Zi
23:40amalloyif anyone out there is developing stuff for clojure users that only works for maven, we should probably find out where they live and kill them
23:40duck1123well then, try installing the swank plugin as well
23:40kanjaarg, why is getting slime setup so hard :(
23:41kanjatry installing the swank plugin?
23:41duck1123lein install plugin swank-clojure 1.4.0-SNAPSHOT
23:41kanjathanks
23:42kanjathat seemed to do something
23:42duck1123I think there's a more stable version, but that works well for me with 1.3
23:44duck1123amalloy: I think a maven plugin is an acceptable exception for maven only
23:45kanjastill not swank on my classpath...
23:46amalloyi don't even really know what a maven plugin is, so i can't argue this point
23:46kanjaWhy were people saying not to use swank-clojure? That was updated two days ago
23:47duck1123You're not supposed to declare swank as a dependency of your project
23:47ibdknoxyeah, no more swank deps :p
23:47duck1123there have been a lot of changes to swank, and people were linking to old versions and it was causing problems
23:48duck1123with lein's plugin system, there's no need
23:48duck1123Of course, I say this knowing that I declare swank as a runtime dependency
23:48duck1123But that's only because I launch a swank server as a side effect of starting my server
23:49kanjaso m-x slime breaks, but closjure-jack-in works? Why the extra command?
23:49duck1123kanja: try lein-swank then M-x slime-connect
23:50duck1123it's really pretty easy
23:50duck1123I have a fn called slime-connect-to-server that connects to the default host port that I have bound to a key combo, it's effortless to connect
23:51duck1123er: lein swank
23:53kanjaYeah, that works. Thanks!
23:53kanjaWhy does just m-x slime blow up then?
23:54duck1123M-x slime tries to start the server. Since it's designed for common lisp, it's a PITA
23:54amalloykanja: that's trying to use CL slime
23:54kanjaahhhh
23:54kanjaI see
23:54kanjamakes sense
23:55kanjano wonder it's blowing up on the swank dependency then
23:55duck1123clojure-jack-in tries to eliminate the need to run lein swank
23:56kanjavery cool
23:56kanjasorry I'm such a newb at this, I'm just starting to get setup with the clj ecosystem
23:57duck1123just to check, are you using an up to date emacs, using the starter kit? getting everything from elpa?
23:58kanjaYeah I'm using elpa, although that's pretty new to me. I've been stuck in a rut with my emacs conf for a long time
23:58kanjarunning emacs 23.3.1