#clojure logs

2009-11-21

00:30scottjCan Java call Clojure code? What's the class and method names of Clojure code?
00:32hamzayes, http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips#Invoking_Clojure_from_Java
00:32scottjhamza: thanks
00:33hamzai've even seen people call clojure from ruby.
00:33hamzaJRuby that is
01:01technomancyhttp://github.com/technomancy/clojure-gem
01:22arohnertechnomancy: looks good, except that you have sane, clojure names
01:23arohnerthe ruby community won't appreciate it unless you come up with your own terms like filter => select
01:23arohner:-p
01:26_atohehe yeah... I spend so much time looking through the rdoc for Array trying to remember what they called filter and reduce
01:27technomancyarohner: I kind of abandoned the project once it was clear that it wasn't going to net me a speaking gig at RubyConf. =)
01:28arohnertechnomancy: NIH?
01:29technomancyarohner: nah, it was just that stuarthalloway also proposed a Clojure talk, and he's a better speaker than I am. =)
01:30technomancydespite allegations of him being a scotch-soaked jerk, which I can refute.
01:30scottjload up Smalltalk, give the method finder the arguments and result that you would get from the method you're looking for, look the resulting method name up in ruby.
01:34arohnerscottj: which would be fine, except that Matz always talks about stealing some from perl, some from smalltalk, some from lisp
01:34arohnerit seems like the only thing he stole from lisp is "map"
01:35arohneranyways, I'm going to sleep
01:35chr(clojure.core/add-classpath "/Users/chr/src/clojure/src/compojure/compojure.jar")
01:36chrfollowed by (ns hello-world (:use compojure))
01:36chrdoes not quite work:
01:36JayMarohner: cons
01:36JayMand others
01:36chrI get "java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:0)"
01:37chrHow do I tell a running clojure about a jar for a library?
01:37_ato~add-classpath
01:37clojurebotadd-classpath is bad, avoid it. I mean it!
01:38nanodustwhy?
01:38_atounfortunately you can't reliably, set the classpath before you start it and your life will be much simpler
01:38_atobecause the top-level java classloader can't be changed
01:38_atoclojure makse it's own URL classloader, which can be
01:38chr_ato: OK, I'll try that, then.
01:38_atowhich is what add-classpath does
01:39_atobut stuff that's at the top-level can't see stuff that's not properly somehow and everything gets mighty confused
01:41nanodustoh, i'll go read jvm specs for whole picture
01:44hamzacan anyone tell me why this is failing?
01:44hamza,(apply hash-map [["test" 0.9912407071619299]])
01:44clojurebotjava.lang.IllegalArgumentException: No value supplied for key: ["test" 0.9912407071619299]
01:44hamzai have a bunch of these pairs in a vector
01:45_atonanodust: if you can figure out how to fix it you'll make a *lot* of people happy ;-)
01:51_atochr: by the way, do you know about M-x swank-clojure-project ?
01:52_atoit'll set the classpath for you and start swank if you tell it your project directory
01:56chr_ato: I looked for it earlier, seemed like a good idea
02:11bradbeveridgeDoes lein work 'out of the box' for OS X 10.5?
02:11bradbeveridgeIt appears to assume some things about my setup & the mkdir implies it should be run from a consistent place
02:12technomancybradbeveridge: I don't know if anyone's tried it, but I can't think of a reason why it would fail.
02:13technomancyyou can place it anywhere on your $PATH
02:13mrSpechello
02:13bradbeveridgeright, but the mkdir -p classes at the top of the script will make a directory in the place that the script is run from, right?
02:14technomancyoh, it should be run from within the project you're working on, yes.
02:14bradbeveridgelein also appears to assume that I have Java setup correctly (which I probably don't)
02:14bradbeveridgedo I need Maven setup first?
02:14technomancybradbeveridge: most of lein works without maven
02:15technomancyyou only need it to install the project you're working on in your local mvn repo
02:15bradbeveridgeOK, let me try again now that I know about it being project centric
02:16bradbeveridgeI'm certainly downloading more stuff...
02:16cgordonI'm still trying to understand vars. What happens if two threads execute something like "(def some_var "some_val")" at the same time? I presume they both change the root binding. Is there a race condition?
02:16technomancycgordon: yes, but def should never get called at runtime.
02:16cgordonah, alright
02:17cgordonso it's mostly for newbies like me playing in the repl? :)
02:17bradbeveridgetechnomancy: OK, that appears to be working - no idea what the problem was last night for me
02:17technomancywell, during development you call it all the time
02:17technomancybradbeveridge: awesome
02:17bradbeveridgethanks for the good work, easy install of packages is awesome
02:18cgordontechnomancy: and general best practice is to only use (binding ...) with variables that start and end with asterix? (like *command-line-args*)
02:18_mstyeah, seconded. I'm having a nice time getting all of my old code to build with lein :)
02:19cgordoncan anyone explain this comment, from "http://clojure.org/vars": Bindings created with binding cannot be seen by any other thread. Bindings created with binding can be assigned to, which provides a means for a nested context to communicate with code before it on the call stack.
02:20bradbeveridgeis there any way to list the packages on clojars?
02:21_atotype "0" into the search box
02:21_atoa browse feature is coming, technomancy's prettying up my code and adding it as we speak :)
02:21bradbeveridgesweet!
02:22bradbeveridgeand (I'm stupid) how does one grab stuff from clojar?
02:22_mst_ato: heh, I'd already tried '%', '*' and various others ;)
02:22technomancycgordon: yes, *earmuffs* are visual indicators that you intend to rebind a var with binding
02:22hiredmancgordon: which part don't you understand?
02:22_atobradbeveridge: just add it the :dependencies list in your project.clj and run: lein deps
02:23cgordonhiredman: I understand that "binding" changes the value of a var for everything *down* the stack. I don't understand how it can change the value for things above it on the stack
02:23cgordonunless I just have my up and down confused
02:23hiredmancgordon: the binding form doesn't
02:23hiredmanbut once you have bound a var using binding, you can use set! to change its value
02:24cgordonah, and that changes it for things above it on the stack?
02:24_atoI probably should change the leiningen heading on the jars page to "add to leiningen project.clj" or something
02:24hiredmannot above the binding form
02:24bradbeveridge_ato: Oh, I get it now :) Clojar is more about linking libs together, not 'getting stuff' to look at code or whatever
02:24cgordonso why does that comment say: which provides a means for a nested context to communicate with code before it on the call stack
02:25hiredmancgordon: it provides a means to do that with in the scope of the binding form
02:25cgordonah, alright, so it's not talking about code above the binding form
02:25cgordongot it, thanks
02:25technomancybradbeveridge: clojars is about finding what :dependencies forms to put in your project.clj
02:25technomancyand having a place to serve the jars from over HTTP
02:26technomancy(but the latter is handled for you)
02:26_atobradbeveridge: We're shortly going to add links to the source code, project home pages etc from the jar pages so it should be a bit easier to find the source
02:27bradbeveridgeFor some reason I was thinking that lein/clojars was about "I wrote this cool app, here's how you get it". Now that I get it, my questions are pretty daft
02:27bradbeveridgethanks for the help
02:28_atobradbeveridge: I'm thinking about covering that at some point as well, but for now it's more about libraries and building
02:35bradbeveridgeone more stupid question I think - now that I have my testing project setup, what's the best way to connect with Slime? Normally I launch from Emacs, but I expect I probably want to launch from the lein repl? (lein slime?)
02:40technomancybradbeveridge: add [swank-clojure "1.0"] as a :dev-dependency in project.clj
02:40technomancythen run lein deps and you should be able to M-x swank-clojure-project
02:41bradbeveridgeok, I've done that now - where do I find swank-clojure-project? Latest swank?
02:43technomancybradbeveridge: yeah, you can pull it in through the Emacs package manager
02:43technomancyhttp://github.com/technomancy/swank-clojure/blob/maven/README.md
02:43bradbeveridgeOK, I'll go try that - thanks a bunch
02:43technomancynp
02:54bradbeveridgeawesome - technomancy & _ato you guys rock! I love seeing how nicely the Clojure community is growing
02:54bradbeveridgethanks for the work
02:58chrClojure can't seem to find compojure.jar.
02:58chrMy java process was started like this: /usr/bin/java -classpath /Users/chr/src/clojure/clojure.jar:/Users/chr/src/clojure/src/compojure/compojure.jar clojure.main --repl
03:00chrstill
03:00chrERC> still (ns hello-world (:use compojure)) gets a NoClassDefFoundError
03:02_mstI think compojure has more dependencies than just the compojure.jar file
03:03_mstthe 'deps' and task in the compojure distribution pulled a bunch of .jar files into deps/, if I recall correctly
03:04chrhttp://en.wikibooks.org/wiki/Compojure/Getting_Started says: "This will generate the compojure.jar file. Put this in your Java classpath."
03:05chr_mst: Shouldn't the compojure.jar contain the dependencies?
03:06_mstI don't think it does--see the "hello world with embedded jetty" example in the next session
03:06_mstit adds all the .jar files in the deps directory to the classpath
03:06_mstif you're on java 1.6 you can run java with -classpath 'deps/*' and it will automatically add all those .jar files to your classpath
03:07chr_mst: You're right -- it's a little confusing.
03:07chr_mst: I seem to be on java 1.6.0_15...
03:08_mstyep, that should be fine
03:08_mstso from your compojure directory: java -classpath '*:deps/*' clojure.main --repl
03:09_mstshould do the trick
03:09fanaticohttp://gist.github.com/240050 <- Anyone want to take a quick look over this code. I can't seem to figure out where I made the mistake in `par-word`.
03:09chrmst: I'll try to hook that into slime/swank.
03:12_mstfanatico: your call to bind returns a function that expects one argument
03:12_mstwhich you bind to 'ne-world', and then call with no arguments when you do (ne-world)
03:14fanatico_mst: thanks.
03:14_mstno problem
03:19chrwhich swank-clojure on github?
03:25duncanmla la la
03:26_mstchr: although I'm not currently using it, I'd have a look at technomancy's one
03:30chrtechnomancy: http://github.com/technomancy/swank-clojure/tree/maven says: git clone git://github.com/technomancy/clojure-mode.el
03:30chrtechnomancy: did you mean git clone git://github.com/technomancy/clojure-mode ?
04:16kzarSupposing I have a struct variable that I created with def and I want to inc one of it's attributes how can I do that? The only way I can see so far is to call def again passing all of the attributes
04:17hiredmanno
04:17hiredmannever call def again
04:18kzarhiredman: Is there a way to do it? I know it's not good practice normally, I don't use it for most stuff
04:19hiredmannever do it
04:19kzarhiredman: Ok thanks for your help
04:19hiredman:)
04:19hiredmanhow you don't do it depends on context
04:19hiredman,(update-in {:a 1} [:a] inc)
04:19clojurebot{:a 2}
04:20hiredman,(let [a (ref {:a 1})] (dosync (alter a update-in [:a] inc)) a)
04:20clojurebot#<Ref@16a9a4c: {:a 2}>
04:21hiredman,(let [a (atom {:a 1})] (swap a update-in [:a] inc) a)
04:21clojurebotjava.lang.Exception: Unable to resolve symbol: swap in this context
04:21hiredman,(let [a (atom {:a 1})] (swap! a update-in [:a] inc) a)
04:21clojurebot#<Atom@1a648f9: {:a 2}>
04:21hiredman,(let [a (agent {:a 1})] (send-off a update-in [:a] inc) (await a) a)
04:21clojurebot#<Agent@f4aaca: {:a 2}>
04:22hiredmanthinking about redefing stuff is a symptom of an imperative mindset
04:24kzarhiredman: Yea I know, I'm just making a crappy game as practice / to learn clojure and at the moment the position for something is set with def
04:24hiredman:|
04:25kzarhiredman: It's not the best solution, probably not how I'm going to keep it and of no real concequence anyway because there will only be one of the item
04:25hiredmanthat doesn't sound right
04:25hiredmankzar: if you are going to learn, it is best to learn correctly
04:25kzarhiredman: Yea I know but I just wanted to see if it would move on the screen when I updated the coords
04:25kzarhiredman: Well you learn by doing and with that you must concede some of what you do is wrong
04:26hiredmaneh?
07:57gerry`jsr166y will be included in jdk7
07:59gerry`will par branch be merged in new?
08:00_atoJDK 7 isn't coming until at least the end of next year apparently
08:01gerry`when the next clojure release?
08:02gerry`oh, closures coming to jdk7
08:04gerry`any benefits to clojure?
08:07_atoI trhink the main benefit to clojure would be that first class functions will be standardised so the different JVM languages will play better together. as far as I can tell they don't add any extra functionality over Clojure's closures, but I'm no JVM expert
08:14gerry`i don't know whether closures have to involve bytecode changes
08:20gerry`#(int i,String s) (i+s.length()) just like clojure #(fn [] ())
08:21gerry`,#(fn [#^String x] (.length x))
08:21clojurebot#<sandbox$eval__4933$fn__4935 sandbox$eval__4933$fn__4935@ec4789>
08:33_atoyeah maybe it means clojure can skip the class generation part, it'd be nice to have less of those gensymed class files spewed out
08:37gerry`should ask rhickey
08:40gerry`,#int(int,String)
08:40clojurebotNo dispatch macro for: i
08:41gerry`(int,String)=>int
09:06gerry`,((eval (symbol "compare")) 3 4)
09:06clojurebotDENIED
09:07gerry`,(doc eval)
09:07clojurebotDENIED
09:10the-kenny,(map inc [1 2 3])
09:10clojurebot(2 3 4)
09:22gerry`,(doc var)
09:22clojurebotTitim gan éirí ort.
09:23gerry`,(doc apply)
09:23clojurebot"([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."
09:26gerry`,(.seq [1 2 3])
09:26clojurebot(1 2 3)
09:27gerry`,(seq? [1 2 3])
09:27clojurebotfalse
09:27gerry`,(.seq {:a 1 :b 2})
09:27clojurebot([:a 1] [:b 2])
10:05djorkwhat was the syntax to make a variable for inside a macro?
10:06djorksorry, total brain fart
10:07the-kennydjork: You mean a gensym'd symbol?
10:07djorkah yes
10:07djorkgensym was it
10:08the-kennyI think something like foo# was an auto-gensym
10:08djork,~(name foo#)
10:08clojurebotjava.lang.Exception: Unable to resolve symbol: foo# in this context
10:08djorkoops
10:08djorkoops
10:08djork,`(name foo#)
10:08clojurebot(clojure.core/name foo__4980__auto__)
10:08djorkthere we go
10:08djorkonly in syntax-quote
10:19djorkis there a definitive explanation of unquote-splicing?
10:19the-kennydjork: It isn't very complicated. What do you want to know?
10:21the-kenny,(macroexpand-1 '(let [seq (range 10)] `(do ~@seq)))
10:21clojurebot(let* [seq (range 10)] (clojure.core/seq (clojure.core/concat (clojure.core/list (quote do)) seq)))
10:21the-kennyhm no, something's wrong.
10:21djorklet's see
10:22the-kenny,(let [seq (range 10)] `(do ~@seq))
10:22clojurebot(do 0 1 2 3 4 5 6 7 8 9)
10:22djorkI think it only applies to & arguments to a macro
10:22the-kennyah
10:22djorkah ha
10:22djorkthere we go
10:22djorkso it expands the seq
10:22the-kennyYes
10:22djorkI'm trying to make a hash-map out of the tail-end of a macro's args
10:22the-kennyUseful for [& body] in arguments
10:22djorkso
10:22djorkyeah
10:23djork,(let [hash-args [:foo :bar :bat :baz]] `(hash-map ~@hash-args))
10:23clojurebot(clojure.core/hash-map :foo :bar :bat :baz)
10:25ohpauleezit's essentially the same as python's *args.
10:25ohpauleezif that helps you any
10:25the-kennyIt's also like common lisps ,@args :p
10:26ohpauleezyes, perhaps a better example
10:26ohpauleezhaha
10:35djorkhmm
10:35djorkevery time I load this file I get a higher line number with this error
10:58the-kennyIs there a nice description of lexical and dynamic scope?
11:06michaeljaakahi!
11:06michaeljaakaanyone used clojure.contrib.accumulators?
11:06michaeljaakawhat is it?
11:07michaeljaakahow to use it?
11:07michaeljaakaI found using immutable types quite hard
11:07michaeljaakafor example I have map
11:07michaeljaaka{ "one" [ 12 3 4] "two" [ 5 6 7 ] }
11:07michaeljaakaany time I want to update [ 1 2 3 4]
11:08michaeljaakaI have to extract it by (get map "one" []) then conj to it, and finally assoc
11:08michaeljaakaall made in a transaction with alter for ref
11:08michaeljaakais there any simpler way?
11:23djorkmichaeljaaka: you could simplify your life by using keywords as hash-map keys
11:24michaeljaakahow?
11:24djork,(let [x {:foo [1 2 3]}] (println (:foo x)))
11:24clojurebot[1 2 3]
11:24michaeljaakabut when I want to add a value to collection of [ 1 2 3] ?
11:25the-kennyI think there is assoc-in or something like this
11:25djorknot quite
11:26djorkassoc-in just does assoc in a nested map
11:26djork,(doc assoc-in)
11:26clojurebot"([m [k & ks] v]); Associates a value in a nested associative structure, where ks is a sequence of keys and v is the new value and returns a new nested structure. If any levels do not exist, hash-maps will be created."
11:42Chousukeassoc-in works for any nested associative structure
11:42Chousukeso it's fine for vectors too
11:42Chousukethough I'm not sure if it can add elements... hmm
11:42Chousuke,(assoc [1 2 3] 3 4)
11:42clojurebot[1 2 3 4]
11:43Chousukeapparently it can
11:43Chousukethere's also update-in
11:44the-kennyIt can, if you supply the length.
11:44Chousuke,(update-in {:foo {:bar [1 2 3]}} [:foo :bar] conj 'hello)
11:44clojurebot{:foo {:bar [1 2 3 hello]}}
11:45the-kennyOh, that's a cool function.
11:46Chousukeit takes a seq of keys as the second argument, and works like alter etc. otherwise
11:46Chousukeand as with assoc-in, vectors are fine too. the keys are just integers
11:58djorkwhat's the canonical way to tell if a value is in a vector
11:58djorkoh wait
11:58djorkthe vector is a function of its elements right
11:58djorkno
11:58djorkhm
11:59djorkah sets
11:59djorkright
11:59mjmdjork: i think the common way is to convert it to a set, then do that
11:59djorkI should be using a set in the first place
11:59mjmvector is a function of its indices
11:59djorkof stop-words symbols
12:00mjmdjork: oh. then there you go :)
12:00djorkyup
12:08Chousukeof course, if the vector is sorted you can always do a binary search
12:15djorkChousuke: yah, but a set works better in this case... it's a set of stop words
12:15djork'#{of in the at} etc
12:31qedanyone here see s. halloway this morning at rubyconf?
12:40solussdif i have a function that takes a variable number of args and I want to pass it a seq, how can I 'explode' the seq when i pass it in [to it appears to be a bunch of args, rather than just one]
12:41solussd*so it
12:43nanodustapply?
12:43the-kennysolussd: (apply fn seq)
12:43the-kenny,(apply + (range 100))
12:43clojurebot4950
12:44solussdyep.. that's what I wanted. I always forget about apply
12:44defni still don't understand what difference exists between apply and reduce
12:45the-kennydefn: (apply + [1 2 3]) is like (+ 1 2 3). (reduce + 1 2 3) is (+ 1 (+ 2 3)) or something like this
12:45defnah
12:45defnreduce is faster
12:45defnbased on what i was reading from cgrand
12:46the-kennyBut it isn't the same as apply. In this example yes, but in others don't
12:46defnnod
12:47the-kennySorry.. bad english
12:48defnnp :)
12:48defn(:)
12:49michaeljaakaChousuke: thanks for poiting update-in it was very helpful
12:50michaeljaaka,(doc do)
12:50clojurebotIt's greek to me.
12:50michaeljaakacan someone explain what "do" does?
12:50the-kennydo is a special op
12:50michaeljaakait is not documented
12:50the-kennymichaeljaaka: It runs every function in it and returns the value of the latest
12:50the-kennymichaeljaaka: http://clojure.org/special_forms
12:51the-kennyOh sorry, wrong link
12:51solussdhow can i convert a seq of integers to a java array of doubles? right now i'm using (to-array [1 2 3]), but i dont want to have to iterate through them casting them individually as doubles
12:51michaeljaakaok, I have found the description there
12:51michaeljaakaso I can run (do (+ 1 2) ( + 4 5) )
12:51michaeljaakaand so on
12:52michaeljaakathis is helpful for expresion where one expression is expected
12:52the-kenny,(do (print 42) :foobar)
12:52clojurebot:foobar
12:52clojurebot42
12:52michaeljaakabut I want to put more than one
12:52the-kennyExactly
12:52the-kennyBut it only makes sense for methods with side effects (except for the last one)
12:52michaeljaakaok, thanks!
12:56michaeljaakabtw. anyone have seen line-seq ?
12:57michaeljaakaI core.clj
12:57michaeljaakain core.clj
12:57michaeljaakaI have question
12:57michaeljaakais this function consuminc the stack?
12:57michaeljaakabecause it is made with recursion
12:57the-kennymichaeljaaka: recursion or recur?
12:57michaeljaakarecursion
12:58michaeljaakathe last statment is
12:58michaeljaakaline-seq with arg
12:58michaeljaakaso it is recursion
12:58michaeljaakaso if there is a very long file
12:58michaeljaakaI can get stackoverflow?
12:58the-kennyI think so.. But I'm not very experienced there :)
13:01qedis (defn make-adder [x] (fn [z] (+ x z))) (def add-2 (make-adder 2)), the same as (def add-2 (partial + 2))?
13:01opqdonutyeh
13:01qedty
13:03solussdnevermind- into-array is what i was looking for
13:20chrI did "git clone git://github.com/technomancy/clojure-mode"
13:20chrShould there then be a swank-clojure.clj in ./slime ?
13:21Chousukeprobably not.
13:21ChousukeI think the projects were separated.
13:24chrmaacl: Pardon me, I pasted the other link.
13:24chrmaacl: It was "git clone git://github.com/technomancy/slime.git" that created a ./slime directory.
13:25maaclchr: sorry?
13:26chrhttp://github.com/technomancy/swank-clojure/tree/maven lists two links to git repos.
13:27chrslime.git and clojure-mode.el. I meant slime.git, which created a slime directory.
13:31chrmaacl: Let me rephrase, please.
13:31chrmaacl: I did "git clone git://github.com/technomancy/slime.git".
13:31spuzsolussd: also have a look at double-array: http://clojure.org/api#toc231
13:32chrmmaccl: That got me a directory named "slime". Inside it, I expected some mention of clojure.
13:33spuzmichaeljaaka: line-seq is lazy, so no you can't get a stack overflow
13:33chrmaacl: But "cd slime; grep clojure *" lists nothing.
13:33spuzI believe lazyness in this case will magically remove the recursion
13:37maaclchr: think you should send to mmaccl
13:47solussdim calling a java function that takes a Vector, how can I "cast" a clojure seq to a java Vector?
13:50spuzsolussd: Vector takes a Collection as an argument
13:51spuzso perhaps (Vector. yourseq)
13:51solussdright- implements the collections interface.
13:51solussdthanks
13:51canderaI'm trying to understand the semantics of ref/dosync. I've written some test code that has unexpected behavior. Basically, I've started a couple of threads, and in one I loop, starting a transaction, incrementing a simple ref to a counter, and then committing. In the other thread, I start a thread and loop, reading the ref. I was a bit surprised to find that the reading thread shows some of the updates. I would have
13:51canderathought that the transaction would show me the start-of-transaction value of the ref throughout the lifetime of the tx. What am I missing?
13:52spuz,(java.util.Vector. (range 10))
13:52clojurebot#<Vector [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>
15:19chrHi, could you give me a hand in getting started with a new swank-clojure install?
15:21chrM-x slime stops with the *inferior-lisp* buffer reporting "Could not locate swank/swank__init.class or swank/swank.clj on classpath".
15:21chrWhich files should I put in ~/.clojure?
15:22chrSo far, there is clojure-1.0.0.jar and compojure.jar in ~/.clojure
15:23chrEarlier today I had a working install of an older slime with LW and clojure support.
15:24chrI removed most of what I had in order to fit in with the "demolish the house in order to install a fridge"-ideology of the guides to installing swank-clojure.
15:26the-kennychr: Check if you classpath is correct
15:26the-kennyYou have to make sure that the .clj files from swank-clojure are accessible there too
15:27chrI don't have any swank-clojure, I'm afraid.
15:28chrThere are a few .el-files in /Users/chr/.emacs.d/elpa/swank-clojure-1.0, but that's all.
15:29djorkaw what the heck did I do? "Don't know how to create ISeq from: java.lang.Character"
15:29chrHow do I get the .clj files from swank-clojure that you are referring to?
15:29djorkthe line it's complaining about is (defmethod command :default
15:31the-kennychr: add them to swank-clojure-extra-classpaths in your .emacs
15:31the-kenny(I had to play around a bit with these paths until I got everything right)
15:32chrwhere do they come from? Which git repo?
15:32the-kennyhttp://github.com/jochu/swank-clojure
15:33robwolfechr: here there is full description of slime configuration for clojure: http://riddell.us/tutorial/slime_swank/slime_swank.html
15:33the-kennyswank-clojure is the backend for slime which connects slime to common lisp's slime
15:35chrI did "git clone git://github.com/jochu/swank-clojure.git"
15:35chrThe README babbles along about elpa, the possibly deprecated "M-x clojure-install" etc.
15:36chrInvoking clojure-install in emacs tells me to visit technomancy's pages.
15:39robwolfechr: have you looked at this link I provided? there is really simple step by step guide
15:40djorkany tips on figuring out a cryptic file-loading error?
15:40hiredmandjork: I doubt that is the whole of the line, and the whole of the exception
15:41djorkk
15:41hiredmanI wonder why people keep exceptions like some kind of scarce resource
15:42hiredman"I have a problem" "we will need more than that" "here is one line from the exception" "we need more" "here is another line" …
15:42djorkhiredman: here's my source up to the offending line and the full exception
15:42djorkhttp://paste.lisp.org/display/90864
15:42djorkjava.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character (server.clj:28)
15:43djork(past the offending line)
15:43djorkI'm loading this from the repl
15:45hiredman,(doc defmulti)
15:45clojurebot"([name docstring? attr-map? dispatch-fn & options]); Creates a new multimethod with the associated dispatch function. The docstring and attribute-map are optional. Options are key-value pairs and may be one of: :default the default dispatch value, defaults to :default :hierarchy the isa? hierarchy to use for dispatching defaults to the global hierarchy"
15:47hiredmandjork: have you looked at what the command function is being passed as an argument?
15:47djorkit's not being called yet
15:48hiredmanoh right
15:48hiredman,(doc defmethod)
15:48clojurebot"([multifn dispatch-val & fn-tail]); Creates and installs a new method of multimethod associated with dispatch-value. "
15:48hiredman^- no docstring
15:49djorkah...
15:50djorkthanks that was simple.... for some reason I thought defmethod had a docstring
15:50djorkcomments it is, then
15:56spuzrhickey: Am I right in thinking that Clojure will unroll a function call that is only made once within another function?
15:56spuz(not sure if Rich's around, but worth a try)
15:58hiredmanspuz: I doubt it
15:58chrI have swank-clojure .clj files in ~/src/swank-clojure/src/
15:58hiredmanclojure relies on hotspot to do most optimization
15:58kotarakhotspot maybe does it?
15:58hiredmanbut hotspot may or may not do it, depending on this, that, or the other
15:59spuzThis is what I'm seeing when looking at a call stack from VisualVM
15:59chrIs there a compile command that makes a jar from these .clj files?
15:59spuzI'm not sure if it is Clojure or hotspot, it seems more likely to me that it would be Clojure but who knows..
16:00spuzI could have the wrong end of the stick of course, I don't know much about JVM optimisation
16:00hiredmanchr: I would ask again when technomancy is in
16:00hiredman~seen technomancy
16:00clojurebottechnomancy was last seen in #clojure, 797 minutes ago saying: np
16:01kotarakchr: you have to that (more or less) manually. Most peoply use ant, maven, clj-gradle or now leiningen.
16:01hiredman,(float (/ 797 60 24))
16:01clojurebot0.5534722
16:01hiredmankotarak: the jar making is a yak shaving expidition, he wants to get swank-clojure working
16:02hiredmanand he is not sure how to do it, so he is asking about everything under the sun
16:02twbrayhiredman: technomancy is at rubyconf
16:02chrhiredman: to bad you're already hired ;)
16:02hiredmanchr: and I vim
16:02hiredmantwbray: I imagine that's not perminent, so he'll be back sometime
16:02twbrayYeah, it ends in a couple hours
16:03chrhiredman: I sure have tried most wrong apporaches to getting slime to work with clojure...
16:20chrI guess moving src/swank-clojure/src/main/clojure/swank to ~/.clojure/ was wrong, too.
16:21chrBut it worked.
16:26technomancychr: do you need to compile a recent version for some reason, or do you just need a jar to use?
16:40vyIs there any equivalent of read-lines in c.c.duck-streams to read lines from a string? Actually, I want to read whole stream into a seq, but wondering if such a functionality already exists.
16:41the-kennyI think there is such a function in core. line-seq?
16:41the-kenny,(doc line-seq)
16:41clojurebot"([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."
16:41vythe-kenny: Oh! Thanks.
16:42hiredmantechnomancy: he doesn't actually want a jar, he wants swank-clojure to work, and is stumbling down various alleys and deadends in the attempt
16:42hiredman(maybe swank-clojure needs to be a jar, so I'd better ask how to make a jar)
16:43technomancychr: do you want a standalone slime repl, or one attached to a project?
16:43technomancyhiredman: it needs to be a jar, but nobody should have to build it by hand unless they are actually hacking swank-clojure itself
16:45lispnikchr, did you try loading clojure-mode.el, evaling it and then run the clojure-install function?
16:45vyWhat's wrong with (use 'clojure.contrib.duck-streams :only '(reader))?
16:45technomancylispnik: that's actually deprecated now; swank-clojure.el performs that task.
16:46technomancyI mean, it still works, but using elpa is easier
16:49lispnikthat's nifty, good to know
16:51technomancyclojurebot: elpa is a package manager for Emacs: http://tromey.com/elpa
16:51clojurebot'Sea, mhuise.
17:02_atoanyone know if there's an opposite to clojure.xml/parse anywhere?
17:14DapperDantechnomancy: is there a page on your blog where one can browse your previous posts?
17:14DapperDani'm looking for it because there are no next/prev links on the posts themselves
17:14_atoDapperDan: http://technomancy.us/list
17:14_atotheere are next/prev links it's just there not obvious
17:15_atothey're at the bottom of the page
17:15_atoabove the comments
17:15_atothe double arrow
17:16DapperDanato: sweet! how'd you find that? you must have scoured the page. and the /list link, i would have thought was to the home page rather than a list. thanks anyway..
17:19_atoDapperDan: heh.. I couldn't find the next/prev either but the Conkeror browser has a really neat feature where you tap [[ or ]] and it'll scour the page looking for next or prev links and follow them.
17:22technomancyDapperDan: just follow the <meta rel="next/prev"> links. =)
17:24hiredman_ato: there is a clojure.xml/emit
17:25hiredmanit prints out the xml, so you might want to use with-out-str
17:27_atohiredman: ah cool, thanks! I should have checked the source instead of assuming clojure.org/api would have everything ;-)
17:27hiredmanemit has no docstring
17:27hiredman:/
17:33djorkis it possible to "reset" a namespace?
17:33djorklike reset user in the REPL
17:34hiredmandjork: checkout the functions on http://clojure.org/namespaces
17:35djorkthat would be smart of me
17:36technomancydjork: (doseq [[name var] (ns-map my-ns)] (ns-unmap namespace name))
17:37djorkcool stuff
17:37djorkI'm using namespaces for this MUD style game
17:37djorktreating a ns as a "realm"
17:37djorkseems to be working pretty well
17:39technomancyI think that won't touch refer'd vars
17:50djorkhow can I print to a stream other than *out*
17:51djorkI have re-bound *out* and stored away the original as *server-out*
17:51_ato(.println *server-out* "hi!")
17:54_mstor if you're using duck streams you can (with-out-writer *server-out* (println "just like old times"))
18:12qedin pragprog's clojure book they start very early with defstruct person :first :last... they then use (defrecord..)
18:12qedoh nvm, he's alluding to creating a macro defrecord
18:56kzarIs there a function like filter I can use to get the index of the results instead of / as well as the values?
19:00chouseryou can use seq-utils indexed to get pairs of [index value], then filter on just the value part
19:07kzarchouser: thanks I got that working
19:25kzarI'm trying to pass a function to my new filter-indexed function but it keep saying 'Unable to resolve symbol: blah in this context' where blah is the function I'm passing. I tried to emulate the filter function and I can't see how my code is different
19:26the-kennykzar: You should show us the code ;)
19:26the-kennylisppaste8: url
19:26lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
19:32kzarwhoops I forgot to paste it heh
19:33lisppaste8kzar pasted "filter-index" at http://paste.lisp.org/display/90876
19:50kzaroh I think it's because do is a special form not a function, you get the same problem using it with filter. Also my function's broken anyway.. oh well
19:52JAS415well if you do identity it works
19:52JAS415so that is good
19:53kzarJAS415: Oh yea, I used seq instead of do and it's fine actually :) I just remembered seq can be used like that
19:54lisppaste8kzar annotated #90876 "solution" at http://paste.lisp.org/display/90876#1
21:22cgordon_are there any good examples of using the lazy-xml libraries somewhere?
21:29qedis there any way to do multi-line comments
21:29qedor would that require a modification to the reader
21:30qedlike: ;~this is a mutli-line
21:30qedcomment ~;
21:31qedthe reason i bring it up is because i think things like (partial + 10), would benefit, readability wise
21:31qedif there was some sort of way of saying "there will be a variable here"
21:32qedlike (partial + 10 %) or something
21:32_ato(comment ...) works some of the time
21:32_ato#_"..." also works some of the time
21:33_atoneither of them are perfect as they evaluate to nil instead of not being read at all
21:33_atooh wait
21:33_ato#_"..." doesn't
21:33_atoexcellent, use that
21:34_ato,[1 2 5 #_"three sir" 3]
21:34clojurebot[1 2 5 3]
21:51chouseror a comma
21:51chouser(partial + 10 ,)
21:52qedchouser: yeah i thought of the comma
21:52qedi just didnt know if there was any other way to make it more obvious
21:53hiredmantree commas
21:53hiredmanthree
21:53qedyeah that was my next thought after typing that line :)
21:57qedi guess you could also (def ! 0) (partial + x !)
21:58qedoops
21:58qed(partial + !)
21:58qed(partial + 2 !)
21:58qedsomething like that
22:14weissjanyone here use emacs/paredit? it doesn't work right w clojure for me. (map inc |[1 2 3]) and run paredit-wrap-round gives (map inc ([1 ) 2 3])
22:15weissjit doesn't recognize the square braces
22:16_atoweissj: :/ it works for me
22:16_atoI get: (map inc ([1 2 3]))
22:18_atoI'm using paredit 21 and clojure-mode 1.6
22:23djork_I can feel the power :)
22:23djork_my friend and I are writing MUDs... he's using C# and I'm using clojure
22:24djorkI changed the way a command worked, and tried it out on a live connection without breaking it or restarting the server
22:24djorkbboyah
22:24djorkbooyah
22:24djorkI mean
22:25djorknot to sound like a douchebag or anything
22:37qedomg that's cool: (defmacro unless [expr form] (list 'if expr nil form))
22:37danlarkinqed: when-not
22:37qedsure sure, but that's still a cool idea
22:37qedis all im saying
22:38qedthis is my first experience with macros
22:38_atoqed: ah, you've been missing out :D
22:40_atoqed: checkout this piece of macro evil I just wrote: http://gist.github.com/240401 (you can ignore the stuff at the top just look at the last lines, the "defview")
22:41_atowhen I eval that file it translates the clojure code into javascript and inserts it into couchdb as a view :D
22:42hiredman_ato: excellent
22:44qed_ato: not totally sure what's going on there yet :)
22:46qedI don't understand the syntax quote yet
22:46qedhow does that work
22:47_atoqed: it probably doesn't make sense unless you've used couchdb. But basically I'm using scriptjure to the that (defview .... [doc] (if (== ... ) ...))) into: "function (doc) {\nif ((doc.type == \"users\")) { \nemit(null, doc)\n };\n }\n"
22:47_atoso I can write views for couchdb (which are in javascript) straight into my application as clojure code and in the background they're magically turned into javascript and sent to the database
22:48qedwhoa.
22:48qedwhat calls the macro function?
22:48_atoit's at the top-level so it just gets called when the code is loaded
22:49qedah ok
22:49qedim just reading about "when to use macros"
22:49qedi barely understand the unless example so far, but i can see how they're very powerful, im not particularly sure how defview works though
22:50qedthe syntax quote and the ([bindings]... in the beginning have me a little off
22:50_atooh right.. I don't need that extra parens around the bindings
22:50_atoI added it because I was going to have arity overloading but then changed my mind
22:51_atosyntax quote is pretty easy, basically:
22:51_ato,'(foo (+ 1 2))
22:51clojurebot(foo (+ 1 2))
22:51_atonormal quote, right, leaves everything unevalauted
22:51qedin general youd' only use those when you had something like ([])([args*])([& args])
22:51qedright?
22:51_ato,`(foo ~(+ 1 2)))
22:51clojurebot(sandbox/foo 3)
22:51qedwhoa, what happened there
22:51_atosyntax quote lets you "unquote" in the middle with ~
22:52_atoand it also resolves all the symbols with the namespace they're in (that's where the sandbox/ bit comes from)
22:52_atothe reason it does that is so that if you define a macro in one file and use it another things work okay
22:53_atobut generally you can just think of it as a template
22:53_ato,`[1 2 3 4 ~(+ 2 3) 6 7]
22:53clojurebot[1 2 3 4 5 6 7]
22:53qedso if you do `(blah ~a ~b), the bindings you defined in the defmacro [a b]
22:53_atoyeah exactly
22:53qedwont be evaluated until they are used as a macro
22:53qedah, kind of like the whole lazy eval thing
22:53qedwhere you only execute the body when you call it
22:54_ato(defmacro m1 [x] `(foo x))
22:54_ato(defmacro m2 [x] `(foo ~x))
22:54_ato(m1 5) => (foo x)
22:54_ato(m2 5) => (foo 5)
22:55qedah-ha, i see
22:55_atooh and:
22:55qedit's just a way for you evaluate vars *now* inside the template
22:55_ato(defmacro m3 [x] `(foo ~@x))
22:55qedoooo
22:55_ato(m3 [1 2 3]) => (foo 1 2 3)
22:55_atothe "splicing unquote"
22:56qedso ~@ is just for a coll?
22:56_atoyes
22:56qedokay, wow, i feel like i learned more about clojure in like 4 hours than i have in the last 3 weeks
22:57_ato(m2 [1 2 3]) => (foo [1 2 3])
22:57qedsure, that makes sense
22:57qedwow, that's cool
23:00qedthanks again _ato
23:00_atono worries
23:00_atomacros are where lisps really shine compared to most other languages
23:01_atosome people find them terrifying but to me the seem a lot simpler than the way metaprogramming works in say python or ruby
23:01qedso wait one more way to explain the ~ is that where a quote ', defers evaluation, a ~ enforces evaluation
23:02qedyeah i learned some metaprogramming in ruby
23:02qedand this seems way less roundabout
23:02_atoyeah, note that ~ only works with syntax-quote `
23:02_atoeg:
23:02_ato,'(a ~b c)
23:02clojurebot(a (clojure.core/unquote b) c)
23:02qedsure
23:03qedwait that was a ', not a `
23:03qed,`(a ~b c)
23:03clojurebotjava.lang.Exception: Unable to resolve symbol: b in this context
23:03_ato,`(a ~(+ 1 2) c)
23:03clojurebot(sandbox/a 3 sandbox/c)
23:03qed,'(a ~b c)
23:03clojurebot(a (clojure.core/unquote b) c)
23:03_ato,'(a ~(+ 1 2) c)
23:03clojurebot(a (clojure.core/unquote (+ 1 2)) c)
23:03qedahhhh ok
23:04_atomost of the reader macros get turned into normal macros
23:04_atoeg
23:04qed,'(str \a ~\b \c)
23:04clojurebot(str \a (clojure.core/unquote \b) \c)
23:04_ato,(quote (a b c))
23:04clojurebot(a b c)
23:04_ato,''(a b c)
23:04clojurebot(quote (a b c))
23:04_atoetc
23:04qedsure
23:04qedit's like a ~~
23:04qedin symbolic logic
23:05qed,'''(a b c)
23:05clojurebot(quote (quote (a b c)))
23:05qed,''''(a b c)
23:05clojurebot(quote (quote (quote (a b c))))
23:05qedoh maybe not
23:06qed,(not (not '(a b c)))
23:06clojurebottrue
23:06qed,(not (not (not '(a b c))))
23:06clojurebotfalse
23:09_ato,'`(evil (~test ~@fish))
23:09clojurebot(clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/evil)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list test) fish)))))
23:10cgordon_does anyone have example code that uses the lazy-xml libraries?
23:11qed_ato: hehe
23:12qedso, before i get to the answer in this book: (var my-symbol) is the verbose version of part of what happens during a (let [...])?
23:12chouserno
23:13chouserlocals (as created by let) and vars have almost nothing in common
23:13qedk
23:13_atoqed: vars are used by (def ...)
23:13qedahh
23:13_atoand (binding [...] ...)
23:17cgordon_If I have a list like ("start", ... some stuff ...., "end", "start", ... more stuff ..., "end", ...) and I want to write a function that takes it as input and produces: ( ("start", ... some stuff ..., "end"), ("start", ... more stuff ..., "end"), ...), what should I do? I'm having a hard time figuring out how to write this function (very much a functional programming novice)
23:18hiredman,(doc split-with)
23:18clojurebot"([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]"
23:19hiredman,(split-with (partial = :end) [:start 1 2 3 :end :start 4 5 6 7 :end])
23:19clojurebot[() (:start 1 2 3 :end :start 4 5 6 7 :end)]
23:19hiredman,(split-with (partial not= :end) [:start 1 2 3 :end :start 4 5 6 7 :end])
23:19clojurebot[(:start 1 2 3) (:end :start 4 5 6 7 :end)]
23:19hiredmananyway
23:19hiredmanuse fnparse :P
23:20cgordon_hiredman: that just splits it into two parts, right?
23:20hiredmancgordon_: you do it again with the remainder
23:20hiredmanover and over
23:20cgordon_ah, i see
23:20hiredmanI think there is a partition-with in contrib
23:20qedthere is
23:20hiredman,(doc partition-with))
23:20clojurebotPardon?
23:20hiredman,(doc partition-with)
23:21clojurebotI don't understand.
23:21hiredmanor not
23:21hiredman,(doc add)
23:21clojurebot"clojure.contrib.accumulators/add;[[acc item]]; Add item to the accumulator acc. The exact meaning of adding an an item depends on the type of the accumulator."
23:21hiredmanhmm
23:21qedi could have sworm
23:21qedsworn
23:22qed,(doc partition-by)
23:22clojurebot"clojure.contrib.seq-utils/partition-by;[[f coll]]; Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy seq of lazy seqs."
23:22hiredmanstill not optimal
23:23cgordon_should help, I just need some code to study
23:23hiredmanyou would need to toggle start inside f
23:23qedyeah
23:23hiredmanyou could definitly use reduce
23:24carkah i was thinking state machine, but reduce sounds good
23:24qed,(doc group-by)
23:24clojurebot"clojure.contrib.seq-utils/group-by;[[f coll]]; Returns a sorted map of the elements of coll keyed by the result of f on each element. The value at each key will be a vector of the corresponding elements, in the order they appeared in coll."
23:26cgordon_how would you use reduce to solve that problem?
23:26cgordon_seems like the accumulator would have to be fairly complex
23:29hiredman,(reduce (fn [blob token] (if (= :end token) (update-in blob [:out] conj (conj (:scratch blob) token)) (update-in blob [:scratch] conj token))) {:out [] :scratch } [:start 1 2 3 :end :start 5 6 7 :end])
23:29clojurebot3
23:29hiredmanwhat?
23:31hiredman,(reduce (fn [blob token] (if (= :end token) (update-in (update-in blob [:out] conj (conj (:scratch blob) token)) (constantly [])) (update-in blob [:scratch] conj token))) {:out [] :scratch []} [:start 1 2 3 :end :start 5 6 7 :end])
23:31clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$update-in
23:31hiredmananyway
23:31hiredman,(reduce (fn [blob token] (if (= :end token) (update-in (update-in blob [:out] conj (conj (:scratch blob) token)) [:tmp] (constantly [])) (update-in blob [:scratch] conj token))) {:out [] :scratch []} [:start 1 2 3 :end :start 5 6 7 :end])
23:31clojurebot{:tmp [], :out [[:start 1 2 3 :end] [:start 1 2 3 :start 5 6 7 :end]], :scratch [:start 1 2 3 :start 5 6 7]}
23:31cgordon_well, it didn't say "42"
23:31hiredmanthe 3 is a bug in ArrayMap
23:31hiredmanwell, not a bug
23:31hiredmanit is weird behaviour
23:32hiredman,((comp :out reduce) (fn [blob token] (if (= :end token) (update-in (update-in blob [:out] conj (conj (:scratch blob) token)) [:tmp] (constantly [])) (update-in blob [:scratch] conj token))) {:out [] :scratch []} [:start 1 2 3 :end :start 5 6 7 :end])
23:32clojurebot[[:start 1 2 3 :end] [:start 1 2 3 :start 5 6 7 :end]]
23:32hiredmansomething like that, but actually working
23:32cgordon_right, I think I get the idea
23:32hiredman,((comp :out reduce) (fn [blob token] (if (= :end token) (update-in (update-in blob [:out] conj (conj (:scratch blob) token)) [:scratch] (constantly [])) (update-in blob [:scratch] conj token))) {:out [] :scratch []} [:start 1 2 3 :end :start 5 6 7 :end])
23:32clojurebot[[:start 1 2 3 :end] [:start 5 6 7 :end]]
23:33hiredman
23:33qedthat's terribly ugly
23:33hiredmanpffft
23:33hiredmanshows what you know
23:34qedit's an honest observation
23:34hiredmanif you want pretty, use parser library
23:34hiredmanlike fnparse
23:36carkclojurebot: paste?
23:36clojurebotlisppaste8, url
23:36lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
23:37lisppaste8cark pasted "start-end" at http://paste.lisp.org/display/90883
23:38carktho that's not quite functional style
23:45cgordon_cark: thanks, what isn't functional about that?
23:46carkit's functional, should be efficient too, not sure about the style, it get the job done anyways =P
23:46carklooks like a lot of code for such a small thing to do
23:47qedyeah that's bothering me
23:47qedim sitting here searching
23:47qedbut your solution looks like all there is