2010-06-04
| 00:08 | Blackfoot | is there a faster way for developing GUI apps that doesn't involve lein uberjar every change? |
| 00:45 | konr | When I need to add methods to a class, there is no other way than using gen-class, right? |
| 00:46 | cemerick | Blackfoot: get a decent repl server library, and have your app open a repl port at startup. Then you can start it once, connect with a REPL, and code, load, and repeat iteration after iteration. |
| 00:47 | cemerick | I use enclojure and its repl server lib at the moment, FWIW. |
| 00:47 | cemerick | keeping a close eye on ccw, though |
| 00:48 | Blackfoot | cemerick: hrm ok, i will give those a try thanks |
| 00:48 | cemerick | konr: or use gen-interface/defprotocol, and include the method definition in your deftype/defrecord |
| 02:11 | bhenry | are there security issues i'm not seeing in using the password hash from a django project's postgres db and passing it to a clojure app as a private token stored in a user collection in a mongo db so users would only be required to login (and more importantly be created) one time? |
| 02:13 | bhenry | note: intranet site with mostly trustworthy employees (trustworthy in that they aren't very tech savvy to mess with security) |
| 03:24 | vIkSiT | hmm, if I have do a def like : (def a "abc") - is there a way I can get a value with two indices swapped? |
| 03:24 | vIkSiT | basically, get "acb" for instance |
| 03:34 | raek | (defn swap [coll index-a index-b] (assoc coll index-a (get coll index-b) index-b (get coll index-a))) |
| 03:34 | tomoj | can't assoc strings, though |
| 03:34 | raek | hrm, right |
| 03:34 | tomoj | but I guess you could go through seqs |
| 03:34 | tomoj | er, vectors |
| 03:35 | raek | yes, do (vec) on coll |
| 03:35 | tomoj | is it always gonna be a string? |
| 03:38 | raek | (defn str-swap [s index-a index-b] (let [v (vec s)] (apply str (assoc v index-a (get v index-b) index-b (get v index-a))))) |
| 03:38 | raek | (str-swap "foo" 0 3) => "oof" |
| 03:39 | raek | I haven't looked in the javadoc, though |
| 04:01 | vIkSiT | oooh thats a good one.. raek, thanks for the pointer |
| 04:01 | vIkSiT | tomoj, hmm, could be any seq really |
| 04:02 | tomoj | that's unfortunate |
| 04:02 | tomoj | well, maybe not, hmm |
| 04:05 | tomoj | oh, yeah, it is, I think |
| 04:06 | tomoj | if it's any seq, you don't have constant time access to the nth element |
| 04:06 | tomoj | so swapping will be difficult |
| 04:06 | vIkSiT | ah good point |
| 04:06 | tomoj | I think you could return a new lazy seq with the elements swapped, but it would have to process all the elements between i and j before returning its ith element |
| 04:08 | tomoj | (and store them all in memory at once) |
| 04:36 | LauJensen | Morning all |
| 04:40 | esj | Morning el'Lau ! |
| 06:57 | rhickey | cgrand: nice blog, although it falls short of what I would consider primitive support for fns - the ability to use them with map/reduce/filter et al |
| 06:57 | rhickey | one thing I would suggest is to not overload invoke like that |
| 07:10 | cgrand | rhickey, I know it's a short-sighted solution and not what you are aiming for. Thanks for confirming my second thougts about having named the method invoke. |
| 07:11 | rhickey | cgrand: the other big problem in general is the semantic difference between operations on boxed and unboxed ints |
| 07:12 | rhickey | I'm surprised actually that the non-hinted fib isn't much slower |
| 07:13 | cgrand | I guess it's -XX:+DoEscapeAnalysis at work |
| 07:13 | rhickey | cgrand: not turned on here, plus going through different math ops |
| 07:15 | cgrand | by difference in semantics you mean the promotion of ints to long etc. ? |
| 07:15 | rhickey | cgrand: the whole boxed number tower stuff, possible promotion to BigIntegers etc |
| 07:16 | rhickey | cgrand: did you compare hfib to fib in Java on same machine? |
| 07:17 | cgrand | no but I can, wait |
| 07:17 | rhickey | I'm wondering if all the math in hfib is primitive |
| 07:17 | rhickey | and the cost of the (int 1) (int 2) |
| 07:21 | rhickey | cgrand: heh, yeah, you are not getting what you think you are getting here, yet |
| 07:21 | rhickey | i.e. this wins here for me: |
| 07:21 | rhickey | (defn fibn [n] (let [n (int n)](if (>= (int 1) n) 1 (+ (fibn (dec n)) (fibn (- n (int 2))))))) |
| 07:25 | cgrand | rhickey: java for fib(38) : around 360ms |
| 07:25 | wires | sorry, i'm just dropping in halfway, but you can work with primitives in closure? I thought everything is boxed? |
| 07:26 | rhickey | cgrand: see ^^, I don't think you are getting prim args through the recursive calls |
| 07:27 | LauJensen | wires: sure |
| 07:28 | LauJensen | wires: http://bestinclass.dk/index.clj/2010/03/functional-fluid-dynamics-in-clojure.html |
| 07:28 | wires | LauJensen: using java interop? |
| 07:28 | rhickey | cgrand: in fact, I'm wondering if the inline is in play while compiling the body |
| 07:28 | wires | LauJensen: thanks, let me check that post |
| 07:29 | lpetit | wire: s/closure/clojure/g |
| 07:29 | cgrand | rhickey: at some point I traced it to check which method was invoked, and the specialized invoke was called |
| 07:29 | rhickey | cgrand: going to breakfast here, I'm sure you'll figure it out - bbl |
| 07:32 | wires | lpetit: sorry :) i know that :) |
| 07:32 | lpetit | wires: sorry, couldn't resist ;-) |
| 07:32 | wires | lpetit: hehe |
| 07:33 | wires | lpetit: it's always good to have a few spelling nazi's in the room ;) |
| 08:24 | rhickey | cgrand: your perf problem is having to go through the var to get 'this' for the inlined call |
| 08:25 | cgrand | rhickey: thanks, I checked that a pure reify solution was around 800ms |
| 08:26 | rhickey | cgrand: definterface + deftype 400 ms here |
| 08:27 | cgrand | rhickey: something along these lines http://gist.github.com/425352 ? |
| 08:28 | rhickey | cgrand: http://gist.github.com/425352#comments |
| 08:28 | lpetit | rhickey: what about having some *warn-on-protocol-impl-redef* (tentative name) to help users of libraries detect that some libraries one depends upon haven't respected the "protocol rule" ? |
| 08:29 | lpetit | rhickey: ideally, the message could indicate what the current namespace was for the last redef of the protocol impl for a certain type |
| 08:30 | lpetit | rhickey: I really fear the FUD coming in a few months if subtle problems arise. I would not like this problem to become Clojure's "oh no, don't use monkey patch *at all* of Ruby". |
| 08:30 | rhickey | lpetit: I don't want to solve theoretical problems, let's see if we actually have this problem in practice first |
| 08:31 | lpetit | rhickey: always the same scheme. lpetit envisions an hypothetical future problem, rhickey's pragmatism wins ;-) |
| 08:32 | rhickey | lpetit: the biggest difference is people monkey patch in Ruby because they *have to*, no one has to have duplicate protocol defs and social pressure might be enough to keep it that way |
| 08:33 | lpetit | rhickey: yes, maybe. I feel this way because me, as a library user, can be impacted by 2 libs I depend on in a very insidious way. |
| 08:35 | LauJensen | I opensourced bestinclass.dk: http://bestinclass.dk/index.clj/2010/06/best-in-class--now-open-sourced.html |
| 08:35 | rhickey | lpetit: then it becomes a quality of implementation thing for the libs, and a coordination effort for the community, but not something forced by a technicality |
| 08:35 | lpetit | rhickey: it's not just me breaking my own rules. Nothing will break, maybe for months, because nobody will notice that data are created slightly differently by another "almost semantically correct" implementation. I don't like this feeling. I can live with less compile time errors, because there will be (almost always) immediate runtime crashes. Not so easy with protocols redefs. |
| 08:36 | rhickey | lpetit: I'll be ready to listen when you first encounter this problem |
| 08:37 | rhickey | lpetit: libs can have 'almost semantically correct' versions of their own ordinary functions right now, causing runtime crashes. Again, just a quality of implementation issue |
| 08:38 | rhickey | the crash isn't due to a second def, but a wrong def |
| 08:44 | lpetit | rhickey: ok. It's just that in case of a wrong def, on can't know in advance something's will be wrong. With protocol redef, it could be done. |
| 08:44 | lpetit | s/on/one/ |
| 08:44 | sexpbot | rhickey: ok. It's just that in case of a wroneg def, one can't know in advance something's will be wroneg. With protocol redef, it could be donee. |
| 08:44 | lpetit | s/wroneg/wrong def/ |
| 08:44 | sexpbot | s/on/one/ |
| 08:44 | LauJensen | I favor the warning - or something at least - if anything can go wrong, eventually it will go wrong |
| 08:50 | TimMc | LauJensen: I see the github repo of bestinclass -- cool. |
| 08:53 | LauJensen | :) |
| 08:53 | TimMc | This will be good for me to paw through. I learn best from example. |
| 08:56 | cgrand | rhickey: thanks, I added a disclaimer to my post and linked to this discussion |
| 09:26 | LauJensen | Best In Class #10 on Hacker News, hooray :) |
| 09:27 | carkh | hello all, i'm giving another try to records and could not find a way to instanciate a record from another namespace easily, i need to do it this way : (cara.foo.MyRecord. "test") |
| 09:28 | carkh | is there a way to avoid fully qualifying it ? |
| 09:28 | chouser | carkh: it's "just" a class. import it. |
| 09:28 | carkh | ahh ok |
| 09:28 | carkh | let me try this =P |
| 09:29 | carkh | indeed this works, thanks ! |
| 09:37 | lpetit | carkh: I guess there's also some work in progress in master fo automatically creating factory fns for records |
| 09:38 | carkh | that would definetly help |
| 09:38 | eevar2 | LauJensen: how is business? clojure an easy sell? |
| 09:39 | lpetit | carkh: I cannot retrieve it in the commits. Maybe I was just dreaming :-( |
| 09:39 | carkh | heh well no big deal anyways, just a convenience thing |
| 09:57 | Licenser | smart people around, is there a reason (I mean not an implementation reason but a thought out one) that update-in does not work with [] the same way get-in does? |
| 09:58 | Licenser | defn update-in |
| 09:58 | Licenser | ~defn update-in |
| 09:58 | clojurebot | Gabh mo leithscéal? |
| 09:58 | Licenser | thank you clojurebot |
| 10:01 | chouser | it does seem unlikely that was intentional, doesn't it. |
| 10:02 | LauJensen | eevar2: Business is tough, selling Clojure is never an issue though |
| 10:03 | eevar2 | yea, recon it's finding decent clients which is the major issue |
| 10:04 | mefesto | does `iterate` use a constant amount of memory? |
| 10:04 | chouser | iterate returns a lazy seq |
| 10:05 | chouser | walking a lazy seq without holding the head uses a constant amount of memory, though it currently churns through (probably ephemeral) garbage |
| 10:05 | mefesto | chouser: hmmm ok am i doing this wrong? http://clojure.pastebin.com/SjaFmmCy |
| 10:06 | mefesto | chouser: i get an OutOfMemoryError before i hit 6mil |
| 10:06 | chouser | you're holding the head |
| 10:06 | chouser | xs is holding the entire seq, which is cached as you walk it. |
| 10:06 | mefesto | only using default jvm settings |
| 10:06 | Licenser | I hold my head when I have headache or bumped it, did you bump your variable? |
| 10:06 | mefesto | chouser: ahhh thanks |
| 10:07 | chouser | mefesto: if you get rid of the def and do (take 1e7 (iterate inc 1)) instead, it should work fine. |
| 10:08 | chouser | except you also need to use 'next' instead of 'rest' or you loop will never end |
| 10:09 | mefesto | chouser: thanks for the help, i was baffled :) |
| 10:10 | axi | hrm, gen-class doesn't work from the repl? |
| 10:10 | chouser | nope, must be AOT-compiled |
| 10:10 | axi | okay |
| 10:10 | axi | I guess I should just stop using classes |
| 10:11 | Leafw | axi: there goes a lifetime change :) |
| 10:11 | axi | lol |
| 10:12 | Licenser | axi: I managed to entirely stay away from classes save for the clj-swing lib which needs classes to interface with the java side, it is a great live when you get rid of classes |
| 10:12 | Licenser | hell many cultures made the same experience |
| 10:12 | chouser | gen-class is annoying, but you can work with classes via proxy, reify, definterface, defprotocol, defrecord, deftype -- all of which are much less annoying. |
| 10:13 | Licenser | yes defprotocol and deftype really are nice, just since its not stable yet the documentation is kind of sparse |
| 10:14 | trptcolin | do others get this same problem? http://gist.github.com/418759 |
| 10:15 | trptcolin | ticket #372 in Assembla, but it seems stuartsierra isn't seeing it on his machine |
| 10:15 | trptcolin | i was thinking maybe hash-ordering difference or something..? |
| 10:16 | Licenser | trptcolin: yes |
| 10:16 | mefesto | trptcolin: i get the same exception |
| 10:16 | Licenser | same for me |
| 10:16 | trptcolin | good, thought i was going crazy for a moment :) |
| 10:16 | Licenser | no stuart is, :P |
| 10:16 | Licenser | but in a good way I think |
| 10:19 | trptcolin | can anyone w/ assembla permissions update the ticket to reflect the fact that others are seeing it as well? i had permission to create the ticket but not add/edit |
| 10:19 | Licenser | trptcolin: It seems you have found the reason alredy, it seems that the test macro works with substitutions and also substituted the function argument |
| 10:19 | mefesto | has anyone here integrated clojure in a spring project? |
| 10:23 | mefesto | i was playing around with it but quickly felt like it was totally pointless. now im wondering if it would be better to build the "service layer" using clojure only and expose a restful interface |
| 10:33 | Licenser | chouser: nice code! |
| 10:39 | bytecoder | hello, i'm looking for something to the following, given two lists [{:a 1 :b 2} {:a 2 :b 1 :c 5}] and [{:a 1 :b 3}] and the key :a the result should be [{:a 1, :b 3} {:a 2, :b 1, :c 5} ] |
| 10:39 | bytecoder | basically, the elements of old data have to updated with new values. |
| 10:41 | chouser | Licenser: :-) thanks. |
| 10:41 | bytecoder | i have a farily simple implemention with me; little worried about its performance and don't want to redo if it's already there. |
| 10:41 | Licenser | I wonder if we can convince people to change update-in :P it would help me a great deal right now ^^ |
| 10:42 | bytecoder | Licenser: got it |
| 10:43 | Licenser | bytecoder: hm? |
| 10:44 | bytecoder | oops. |
| 10:44 | bytecoder | got the context wrong. "update-in" kind of sounded like what i want. |
| 10:44 | Licenser | *g* |
| 10:45 | Licenser | bytecoder: so remove the key from the second hashmap with dissoc then map over the first and merge |
| 10:47 | lpetit | ccw users around the corner ? |
| 10:48 | bytecoder | will it work in this case [{:a 1 :b 2} {:a 2 :b 1 :c 5} {:a 4 :b 6}] and [{:a 1 :b 3} {:a 4 :b 100}] too? |
| 10:50 | Licenser | lpetit: I used it a bit but am back to emacs |
| 10:51 | Licenser | bytecoder: epends on what you want the outcome to be |
| 10:51 | lpetit | wanted to know if some people had tried yesterday's release ... |
| 10:52 | bytecoder | ok. thanks for info. let me try that. |
| 10:54 | Licenser | bytecoder: user> (merge-but [{:a 1 :b 2} {:a 2 :b 1 :c 5}] [{:a 1 :b 3}] :a) ;=> ({:a 1, :b 3} {:a 2, :b 1, :c 5}) |
| 10:54 | Licenser | (defn merge-but [[ & ms] [& sub-ms] exclude] |
| 10:54 | Licenser | (map #(merge %1 (dissoc %2 exclude)) ms (concat sub-ms (repeat {})))) is the code |
| 11:00 | bytecoder | (merge-but [{:a 1 :b 2} {:a 2 :b 1 :c 5} {:a 4 :b 6}] [{:a 1 :b 3} {:a 4 :b 100}] :a) ;=> ({:a 1, :b 3} {:a 2, :b 100, :c 5} {:a 4, :b 6}) |
| 11:01 | Licenser | bytecoder: is that what you expect? |
| 11:02 | bytecoder | nope. i'm expecting ({:a 1, :b 3} {:a 2, :b 1, :c 5} {:a 4, :b 100}) |
| 11:02 | Licenser | ah I see |
| 11:03 | bytecoder | let me post my code which uses list comprehension. |
| 11:03 | bytecoder | (defn merge-data [old-data new-data key] |
| 11:03 | bytecoder | (for [i old-data] |
| 11:03 | bytecoder | (let [d (first (select #(= (key i) (key %)) new-data))] |
| 11:03 | bytecoder | (if d d i)))) |
| 11:03 | bytecoder | please don't mind the var names :) |
| 11:04 | Licenser | but why would you expect in the second map b to stay_ |
| 11:04 | Licenser | d |
| 11:04 | bytecoder | i don't see this to be functional at all. i'm sure it can be done better. |
| 11:04 | Licenser | o you want ONLY :a updated or anything but a? |
| 11:04 | bytecoder | i have two list of maps. wherever the key matches the right side data should just take over. |
| 11:04 | Licenser | I don't see why in map 2 :b should be 1 and not 100 |
| 11:04 | Licenser | ahh then I entirely missunderstood your problem |
| 11:05 | bytecoder | sorry. should have explained my question a little more. |
| 11:05 | Licenser | so if :a in the left map and :a in the right map have the same value you want the right map otherwise the left map? |
| 11:06 | bytecoder | yes right. |
| 11:06 | Licenser | and what happens if thre is no right side? |
| 11:06 | Licenser | or the right/left side does not have the key? |
| 11:07 | Licenser | then you keep the left one right? |
| 11:07 | bytecoder | yes, right. |
| 11:08 | Licenser | http://gist.github.com/425518 |
| 11:09 | Licenser | so the name is horrible for this function now :P |
| 11:11 | cemerick | chouser: anything short of clojure data structure semantics doesn't seem worthwhile. Or, at the very least, you'd be building something other than a clojure, it seems. |
| 11:12 | bytecoder | Licenser: ({:a 1, :b 3} {:a 2, :b 1, :c 5} {:a 4, :b 6}) still not ({:a 1, :b 3} {:a 2, :b 1, :c 5} {:a 4, :b 100}) |
| 11:12 | chouser | cemerick: yes, but I think some people want that sometimes. see scriptjure |
| 11:12 | bytecoder | Licenser: anyway, i think i can tweak it a bit to get it working. let me try. |
| 11:12 | cemerick | Oh, sure. And scriptjure is cool, bu tit's already there. :-) |
| 11:12 | bytecoder | Licenser: thanks again. |
| 11:12 | Licenser | ah I think I still got wrong what you want :) |
| 11:12 | Licenser | you're welcome |
| 11:13 | chouser | cemerick: yes. I should have mentioned it by name -- wasn't sure he knew of it. |
| 11:14 | TimMc | I'm curious about some of the design decisions in Clojure -- for instance, why have true, false and nil by reserved names, instead of #t, #f, and (I guess) #nil? |
| 11:14 | TimMc | Do any of the books cover that stuff? |
| 11:15 | mefesto | TimMc: i think i saw something on that in a video here http://clojure.blip.tv/ |
| 11:15 | mefesto | TimMc: one of the vids "clojure for lisp programmers" |
| 11:15 | chouser | TimMc: I've never heard that particular question. My guess, and that's all it is, is that the latter would have been considered uglier than necessary. |
| 11:15 | mefesto | TimMc: iirc, false is only in there for java interop |
| 11:16 | TimMc | mefesto: In at least one Scheme, false evaluates to #f. You can shadow the binding, though. :-P |
| 11:17 | TimMc | chouser: I like #t and #f because then you don't have to worry about self-evaluating symbols or whatever. '(foo bar true) is a list of symbols in Scheme, but two symbols and a boolean in Clojure. |
| 11:17 | chouser | ,(map type '(foo bar true)) |
| 11:17 | clojurebot | (clojure.lang.Symbol clojure.lang.Symbol java.lang.Boolean) |
| 11:18 | chouser | interesting point |
| 11:18 | TimMc | mefesto: Thanks for the link. |
| 11:18 | TimMc | chouser: It's one of my main annoyances with lisp. |
| 11:19 | chouser | TimMc: symbols aren't used much for data in clojure. |
| 11:19 | chouser | not that that really answers your question, but perhaps is why it doesn't come up much. |
| 11:20 | TimMc | chouser: True. You could easily argue that if you are trying to use 'true, you're doing something wrong -- but it does mildly violate the principle of least astonishment. |
| 11:22 | KirinDave | I've never liked the Principle of Least Astonishment. |
| 11:22 | KirinDave | Nearly every feature of every language that I really liked, I was astonished by. |
| 11:22 | chouser | heh |
| 11:22 | TimMc | :-D |
| 11:23 | KirinDave | Macros are a great example. I think most people are sort of astonished by what they represent. |
| 11:23 | KirinDave | In ruby, Eigenhacking probably as a similar woah-factor. |
| 11:24 | chouser | Actually, I think a lot of people don't understand the value of macros. |
| 11:24 | KirinDave | Hell, even lexical scope somewhat astonishing when you come from a land of dynamic scoping. |
| 11:24 | KirinDave | chouser: I meant most of the (subset of people who write them) |
| 11:24 | chouser | If they did, they'd quit inventing languages with it them. |
| 11:24 | chouser | ah |
| 11:24 | chouser | s/with/without/ |
| 11:25 | sexpbot | ah |
| 11:25 | chouser | sexpbot: not helpful. |
| 11:25 | chouser | actually, s/with it/without/ |
| 11:26 | TimMc | I interpreted the original statement as "stop making DSLs with macros!"... which seemed odd. |
| 11:27 | chouser | yeah, sorry. not my point. :-) |
| 11:27 | chouser | someday I'll spend some time in template haskell and see if that takes me anywhere interesting. |
| 11:28 | KirinDave | There was this article recently that the hackernewscrowd was nodding their head with about how we need to stop having tool wars and start working together. |
| 11:28 | KirinDave | I sort of think the two are not mutually exclusive. |
| 11:28 | KirinDave | So much of compsci history since 1980 has been trying to get the software industry to stop fucking around and getting software engineers to take their craft more seriously. |
| 11:29 | KirinDave | I'm not complaining about my salary, but part of the problem with these sorts of jobs is that they attract as many cash seekers as craft seekers. :( |
| 11:31 | chouser | KirinDave: I recommend making up for it by being underpaid to write a book. |
| 11:31 | cemerick | KirinDave: I don't think programming, as we understand it today, can ever be crammed into an "engineering" box that would lead to / require the kind of culture shift you're talking about. |
| 11:32 | KirinDave | cemerick: I don't know. I mean, how different is what we do from architecture? |
| 11:32 | cemerick | Hugely. The physics and patterns of architecture are well known, and irrefutable. |
| 11:32 | cemerick | Best way to build a webapp? No so much. :-) |
| 11:32 | KirinDave | chouser: Haha, after my powerset sales stuff vests I am fine with a bit of time off. I was thinking of spending 6 months as a barista for blue bottle. |
| 11:33 | KirinDave | chouser: I can make a decent latte, but I want to really get it down to a science. ;) |
| 11:33 | chouser | heh |
| 11:33 | KirinDave | cemerick: But that's more a matter of time. |
| 11:33 | cemerick | I disagree. |
| 11:33 | KirinDave | cemerick: And it's not like building techniques are locked in stone. |
| 11:33 | cemerick | Programming and software dev is far more akin to cooking than it is to engineering. If we can pull ourselves out of this primordial ooze of twiddling bits and describing how to do things relevant to the domains we're working in, then I think there's a chance. |
| 11:34 | cemerick | There's really only one way to build an arch. :-) |
| 11:34 | cemerick | (speaking of stone) |
| 11:34 | candera | It's even more like building machines that will come to your house and cook for you, actually. |
| 11:34 | KirinDave | i think the major difference between architecture and programming is that for an architect, the blueprint is the most succinct, correct representation of a potential building. For software engineers, the program they are planning to write is the succinct representation. |
| 11:34 | KirinDave | So we have this problem of being unable to build adequate specs. |
| 11:34 | KirinDave | We have to project down from high level specs to specifics. |
| 11:34 | cemerick | The program is a manifestation, not a formal representation. |
| 11:35 | KirinDave | Oh? |
| 11:35 | TimMc | I think it's easier to see bad architecture in buildings than in libraries. |
| 11:35 | KirinDave | What's the difference for thought? :) |
| 11:35 | cemerick | blueprint:building :: ????:code |
| 11:35 | KirinDave | cemerick: There is no real comparison. |
| 11:35 | KirinDave | that's the problem. |
| 11:35 | KirinDave | We can't fully spec out a piece of code without writing code. |
| 11:35 | cemerick | Exactly. :-) |
| 11:35 | TimMc | My pet peeve is that we don't have good visualization tools for large codebases. |
| 11:35 | mefesto | isn't code the blueprint and it's running state the building? |
| 11:36 | chouser | mefesto: I think that's closer. |
| 11:36 | mefesto | tdd fit into this conversation any? |
| 11:36 | KirinDave | mefesto: No, because the blueprint (if correct and complete) has all the data to specify the building. A spec for code does not. |
| 11:36 | cemerick | If we can find a way to describe things in formalities, then we can lift ourselves into a better place. |
| 11:36 | KirinDave | And I dunno if they exist for our work. |
| 11:36 | lpetit | any chance to see one day optional static type checking in clojure ? (as e.g. is provided optionally in Chi ) |
| 11:37 | chouser | and engineering+construction is like service maintenance |
| 11:37 | candera | I think if you asked guys who actually hammer nails, they might have a different opinion about the blueprint having all the data to specify the building. It specifies some projection of the building into idea space. |
| 11:37 | cemerick | lpetit: you mean Qi? |
| 11:37 | chouser | cemerick: but if that formality is sufficiently precise, isn't that just code in a new language? |
| 11:37 | KirinDave | chouser: Right. For compsci it's code all the way down. |
| 11:37 | lpetit | cemerick: oh yes Qi |
| 11:38 | cemerick | chouser: It might be "code in a new language", but it would be of a sort that is unambiguously the best way to represent what will eventually be built. |
| 11:38 | cemerick | Much like blueprints. |
| 11:38 | chouser | lpetit: I doubt it will look like it does in Qi, but yes I think so. Some day. |
| 11:38 | KirinDave | candera: Well the blueprint isn't providing a how-to-build-the-building list. It's providing a representation of the finished building. |
| 11:38 | KirinDave | lpetit: If SBCL can do it, why can't we? ;) |
| 11:39 | cemerick | ...and given that formalism, no one will give a shite what the thing is built in, just like most people don't care about building materials. |
| 11:39 | chouser | lpetit: perhaps datalog rules making assertions about code at compile time that encompass not just types of expressions but potentially a lot more |
| 11:40 | KirinDave | SBCL sort of shocks me with how amazing that compile ris. |
| 11:40 | mefesto | i like comparing software dev to gardening... continually growing software |
| 11:40 | candera | KirinDave: agreed. But what use is just the representation in the absence of finishing the building? I'm not actually arguing against your point. But the architecture analogy has caused (IMO) endless trouble in our profession. |
| 11:40 | KirinDave | I suppose it is the prime example of, “If You Spec It, They Will Build It.Æ |
| 11:40 | lpetit | chouser, cemerick: I'm asking because not so rarely, I can see on articles, etc., the fact that there is no static type checking as "one of the advantages of working in a 'dynamic' langage". But I really think it was first a design decision because, he, in a two-years man work, one cannot put everything !, and not having static type checking (optional one, of course) was certainly a way to... |
| 11:40 | KirinDave | candera: What does it matter if it's useful? |
| 11:40 | lpetit | ...save work (and thorough thougt about the nature of types, etc.). |
| 11:40 | mefesto | doesn't the blueprint view lead one towards big-upfront-design issues? |
| 11:41 | mefesto | where as "growing" lets you build on top of small working parts and incrementally proceed to new features |
| 11:41 | cemerick | KirinDave: It simply *cannot* be code all the way down, or we screwed. Look at some of those fairly elaborate (and successful in their niche) application builders that are entirely graphical. They get jobs done, and no one using them knows jack about code, or cares. That's the way it should be. |
| 11:41 | chouser | lpetit: I'm not sure that's quite right. There has been much effort put into keeping Clojure as dynamic as possible without sacrificing too much performance. |
| 11:41 | candera | KirinDave: I suppose whether or not it matters it's useful is a matter of perspective. :) |
| 11:41 | lpetit | chouser, cemerick: and I've always seen this as a poor argument, even a counter-productive argument, when told in the ears of Enterprise people. |
| 11:41 | cemerick | In other words, we need to put 90% of programmers out of work. :-D |
| 11:41 | KirinDave | lpetit: Ultimately dynamic type checking provides more room for optimization and analysis. The more detail you put in your code at compile time, the less latitude a runtime environment has to profile and fix it. |
| 11:42 | lpetit | chouser: maybe I didn't make my point as clear as I intended. |
| 11:42 | KirinDave | lpetit: As trace tree optimizations become cheaper and more well-understood, we're going to see shit like magical auto-unboxing of arithmetic, etc just as a side effect of even bigger optimizations. |
| 11:43 | KirinDave | lpetit: Already what LLVM can accomplish given a codepath and some modules is _astonishing_. |
| 11:43 | KirinDave | And garbage collectors are so good now that for a lot of use patterns they are faster than manual malloc. |
| 11:43 | lpetit | chouser: I'm not complaining. I'm just thinking that we should not place so much emphasis (some times) as not having static type checking as an advantage. |
| 11:43 | cemerick | lpetit: Having worked in scala for a year (not exactly a long time, but perhaps long enough?), I'm very skeptical of rich statically-typed langs. The boxes you can paint yourself into are exquisite and very, very painful. |
| 11:43 | Licenser | what is SBCL? |
| 11:43 | TimMc | KirinDave: |
| 11:44 | chouser | lpetit: perhaps not. But not *requiring* static type declarations is indeed an advantage. |
| 11:44 | TimMc | KirinDave: (Sorry.) What is "Eigenhacking"? |
| 11:44 | arohner | Licenser: a Common Lisp implementation |
| 11:44 | TimMc | It is apparently ungoogleable. |
| 11:44 | lpetit | cemerick: that's why making it optional is IMHO the line to draw |
| 11:44 | Plouj | Licenser: Steel Bank Common Lisp |
| 11:45 | lpetit | chouser: not in all environments. |
| 11:45 | chouser | lpetit: if the language required it, it would be required in all environments |
| 11:46 | KirinDave | TimMc: Eigenhacking is opening up the eigenclass of ruby objects and classes. |
| 11:46 | cemerick | lpetit: Perhaps. I'm not sure what that would look like, in a day-to-day sort of way. |
| 11:46 | KirinDave | TimMc: It's my word. I'm a big enough deal to be able to do that sort of thing. |
| 11:46 | cemerick | I suppose type hinting as we have now, but then the compiler errors out if you're attempting to access an undefined key on a defrecord instance? |
| 11:46 | lpetit | chouser: in Qi, as far as I understand it, it's optional. I sometimes like to change a type in my IDE, and see instantly all the red crosses spotting all the places I need to go. :) |
| 11:46 | TimMc | KirinDave: Thanks, "eigenclass" is actually getting me some results. (I don't know any Ruby.) |
| 11:47 | lpetit | chouser: OK, I've just done this all day long, so I'm biaised today :-D |
| 11:47 | lpetit | chouser: in java of course |
| 11:48 | KirinDave | Man, if ARM would write some instructions and hardware to directly support garbage collection in phones... |
| 11:48 | lpetit | KirinDave: I don't totally follow you. I'm not thinking about optimization, but about having, optionnally, the most errors reported as quick as possible. that's all. |
| 11:48 | KirinDave | A new era |
| 11:48 | KirinDave | lpetit: Well the only type of static type checking really useful for errors is haskell's style. |
| 11:48 | KirinDave | lpetit: The java style is ultimately a red herring in error correctness. |
| 11:49 | KirinDave | err. error vs. correctness |
| 11:49 | lpetit | cemerick: haskell did that well, no ? |
| 11:49 | cemerick | lpetit: I wouldn't know -- never spent enough time there. |
| 11:51 | lpetit | cemerick: by following the Qi tutorial once, I thought it would be as easy as : emit some (start-static) form to the compiler, and from now on it does its best to fail if the information it has on types for new functions/macro clashes. Later on, emit (stop-static) and you're back in the good old "fail at runtime" environment. |
| 11:52 | cemerick | That seems a little baroque. I'd rather have a compiler flag I can set! to true, but whatever. :-) |
| 11:52 | cemerick | I'd be perfectly happy if type-hinted host interop were statically enforced. That's a reasonable first compromise, I think. |
| 11:53 | lpetit | cemerick: no because you would not break other's code at compile time. Still let it a chance to fail at runtime :-p |
| 11:53 | lpetit | must leave, thanks for the chat |
| 11:57 | The-Kenny | (doc reify) |
| 11:57 | clojurebot | "([& opts+specs]); reify is a macro with the following structure: (reify options* specs*) Currently there are no options. Each spec consists of the protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [args*] body)* Methods should be supplied for all methods of the desired protocol(s) and interface(s). You can also define overrides for methods of Object. Note that a |
| 11:58 | The-Kenny | Are the examples in the doc for reify outdated? |
| 11:58 | The-Kenny | (str (let [f "foo"] (reify Object (toString [] f)))) |
| 11:58 | The-Kenny | ,(str (let [f "foo"] (reify Object (toString [] f)))) |
| 11:58 | clojurebot | java.lang.IllegalArgumentException: Must supply at least one argument for 'this' in: toString |
| 12:10 | carkh | ,(str (let [f "foo"] (reify Object (toString [this] f)))) |
| 12:10 | clojurebot | "foo" |
| 12:11 | The-Kenny | carkh: Yeah, I know. But the doc uses [] as the arglist. Looks outdated |
| 12:11 | carkh | oh ok |
| 12:12 | Licenser | coooookies! |
| 12:43 | _fogus_ | KirinDave: Finally got around to reading it. Nice. |
| 13:39 | islon | I have a vector and I want to process the items 5 by 5, which is a good function? |
| 13:42 | bhenry | can i have a map of structs? |
| 13:44 | dnolen | islon: (map #(partition 5 %) (partition 25 v)) ? |
| 13:44 | dnolen | bhenry: sure |
| 13:47 | islon | dnolen: yes, thanks |
| 13:54 | djpowell | any clojure.java.shell people online? |
| 14:12 | bhenry | i need help with the error i get with this. https://gist.github.com/e4ac084bfb54a723c147 |
| 14:13 | bartj | , (doc signal) |
| 14:13 | clojurebot | I don't understand. |
| 14:15 | bartj | bhenry: what are signal and other functions towards the end of your script? |
| 14:15 | candera | bhenry: Might be a swank/slime problem. You tried it from a bare REPL? |
| 14:17 | replaca | djpowell: what's up? |
| 14:17 | raek | bhenry: you'll have to use (:refer-clojure :exclude [type]) in your namespace declaration to avoid collision with clojure.core/type |
| 14:18 | raek | or simply rename type to something else, e.g. remark-type |
| 14:38 | bartj | is it possible to see the source code of the into function? |
| 14:39 | bhenry | raek: i had a feeling that was going to be used already |
| 14:39 | bhenry | bartj: those are part of the error in the comment. i don't know what they are, but they aren't in my function. |
| 14:40 | raek | bartj: (use 'clojure.contrib.repl-utils) (source into) |
| 14:42 | bartj | raek: thanks! |
| 14:43 | djpowell | replaca: oh, i just have a few suggested fixes to it |
| 14:44 | djpowell | replaca: bufferring the io via clojure.java.io; allowing specification of input encoding; reading streams in parallel threads to prevent stderr from filling the buffer and blocking; and probably using platform default encoding rather than utf-8 as the default |
| 14:45 | djpowell | i'll get a patch together, but wanted to discuss whether they are all a good idea first |
| 14:45 | raek | personally, I don't think "platform default encoding" makes any sense |
| 14:49 | raek | if the default is UTF-8, at least one can rely on a fixed behaviour for reading non-ascii characters |
| 14:51 | raek | the encoding should be considered a part of the data format, not an implementation detail |
| 14:52 | michaeltomer | I'm a complete Java and Clojure noob, so forgive the ignorance of this question: Can you include a JAR file from within a Clojure script? Kind of like how Ruby does " require 'MyAwesomeFile' " |
| 14:53 | raek | as a swede, one gets tired of ones "åäö" turning into "åäö" or "???" at random all the time... :) |
| 14:53 | raek | </rant> |
| 14:53 | chouser | michaeltomer: not usually. generally the .jar must be on the classpath when you start the JVM. |
| 14:53 | TimMc | raek: hear, hear |
| 14:54 | michaeltomer | Will that complicate things for distributing the files to endusers who probably don't have the JDK, and certainly don't have clojure-contrib in their classpath? |
| 14:54 | michaeltomer | Sorry, I'm a Ruby programmer by trade, so I've got some biases to overcome :) |
| 14:55 | raek | you can always ship the jar files with your program (if its license allowes it, of course) |
| 14:55 | raek | just start clojure with the correct classpath |
| 14:55 | raek | and you can use what's inside the jar |
| 14:55 | michaeltomer | That sounds easy enough. Thanks! |
| 14:55 | chouser | michaeltomer: I'll try to defend the JVM here, though my heart's not really in it... |
| 14:56 | raek | michaeltomer: I recommend looking into leiningen |
| 14:56 | raek | it's a build system that, among other things, handles dependencies |
| 14:56 | michaeltomer | chouser: That's okay. I could try to defend the speed of MRI, but my heart isn't in it either :) |
| 14:56 | chouser | michaeltomer: it's not uncommon to provide a single .jar with everything you need, sometimes called an uberjar. leiningen and maven both provde ways to build these based on a list of dependencies you provide. |
| 14:57 | Crowbar7 | MRI? |
| 14:57 | raek | however, when you program, you don't mention the jar file, only the things in it |
| 14:57 | michaeltomer | The canonical implementation of Ruby. Matz's Ruby Interpreter. |
| 14:58 | chouser | michaeltomer: another option is to provide a .jar with its dependencies available inside in a format that leiningen and maven can use. end-users with either can then ask for your .jar plus all its depenencies. |
| 14:58 | michaeltomer | My clumsy way of saying that Java may be rigid, but Ruby is slow. |
| 14:58 | chouser | its dependency list, that is. |
| 14:58 | michaeltomer | Sounds like I should start learning about Maven as well. |
| 14:58 | michaeltomer | I'm really looking for something simple. I'd rather not have to mess with build tools. |
| 14:59 | raek | if namespace my.random.project is in mrp.jar, you start clojure with -cp mrp.jar and write (:use my.random.project) in your namespace declaration in the file that uses the lib |
| 14:59 | raek | leiningen uses maven under the hood |
| 14:59 | michaeltomer | I like running scripts from my text editor, but it looks like I'm going to have to start running things from the command line. |
| 14:59 | raek | but only for dependency management, I think |
| 14:59 | michaeltomer | A bit of a bummer. |
| 15:00 | Licenser | michaeltomer: when you use leiningen lein-search might be nice for you since it is somewhat a frontend for the clojars webside that remotely reminds of ruby gems |
| 15:00 | raek | you don't have to run from the command line |
| 15:00 | michaeltomer | Licenser: Ah, that's what that is. That could be really handy. |
| 15:01 | michaeltomer | raek: Wouldn't I need to in order to specify the jar files to include? |
| 15:01 | michaeltomer | Unless using something like leiningen? |
| 15:01 | raek | well, you have to decide what dependencies you need to use before starting the clojure instance, true |
| 15:02 | michaeltomer | In this case, I'm doing the Mire tutorial which requires clojure-contrib |
| 15:02 | chouser | michaeltomer: for my own use, I have a directory full of jars (actually symlinks to jars) and a clojure startup script that puts them all on the classpath. |
| 15:02 | raek | but you can still configure, say emacs, to launch the repl with your jar in the classpath |
| 15:02 | raek | it |
| 15:02 | raek | it's just a matter of configuring the IDE |
| 15:03 | michaeltomer | raek: Fair enough, though it seems like overkill to configure my text editor just for one script. |
| 15:03 | raek | every project can have its own versions of its dependecies |
| 15:03 | chouser | and also all the jars that ubuntu has installed for me. So I can manually "install" a .jar by symlinking to it, or use apt. |
| 15:03 | dnolen | michaeltomer: if you want something like the convenience of gem, I'd go with lein. |
| 15:04 | michaeltomer | Like I said, these things seem easier in Ruby, but that trade comes with a massive drop in speed. |
| 15:04 | michaeltomer | That's a big part of going with Clojure. That and I've always wanted to learn a lisp. |
| 15:05 | michaeltomer | I'll check out leiningen. Thanks! |
| 15:05 | chouser | michaeltomer: I have felt exactly the same way about .jar management. |
| 15:05 | raek | I think that ruby have been designed with scripting in mind much more than clojure |
| 15:06 | chouser | Building Clojure on top the JVM is one of its biggest strengths, and also one of its biggest weaknesses. |
| 15:06 | raek | true. |
| 15:06 | michaeltomer | raek: That's a good point. |
| 15:06 | trptcolin | fwiw, i don't think the jar-loading thing is really a JVM limitation. for instance, JRuby allows you to dynamically load jars if you know the path, even if they're not on the classpath when you launch. |
| 15:07 | headius | michaeltomer: what sort of things cause a massive drop in speed on ruby? |
| 15:07 | trptcolin | i guess it's probably a difference in the way the classloader works? |
| 15:07 | chouser | (doc add-classpath) |
| 15:07 | clojurebot | "([url]); DEPRECATED Adds the url (String or URL object) to the classpath per URLClassLoader.addURL" |
| 15:07 | trptcolin | ah, interesting |
| 15:07 | Raynes | trptcolin: Clojure allowed that before, but the add-classpath function/macro was deprecated. |
| 15:07 | Raynes | Oh, too late. |
| 15:08 | headius | trptcolin: all java libs loaded from ruby code in JRuby are loaded via our own URLClassLoader |
| 15:08 | chouser | apparently it caused problems in various deployment situations. A pity. |
| 15:08 | michaeltomer | I'm thinking about using Clojure for offloading some data processing onto customer's computers. I need something that'll work on Windows, Linux, and OS X, and I would prefer it not be a nightmare to set up. Does Clojure fit that bill? |
| 15:08 | headius | pfft |
| 15:08 | michaeltomer | Hey, Charlie! A familiar face! |
| 15:08 | headius | URLClassLoader works fine when you need it...and when it causes problems...don't use it |
| 15:08 | headius | michaeltomer: hello! |
| 15:09 | michaeltomer | I'm a Rubyist treading into Java land. Slap some sense into me before I get hurt! |
| 15:09 | bartj | er, what gives? |
| 15:09 | bartj | , (doseq [entry ({:a 1} {:b 2})] (println entry)) |
| 15:09 | clojurebot | nil |
| 15:10 | trptcolin | ,({:a 1} {:b 2}) |
| 15:10 | clojurebot | nil |
| 15:10 | candera | bartj: did you mean that to be a vector? |
| 15:10 | michaeltomer | headius: I just mean the speed in general. Ruby isn't a terribly performant language, no offense to your awesome work on JRuby. |
| 15:10 | chouser | ,({:a 1} :a) |
| 15:10 | clojurebot | 1 |
| 15:10 | bartj | corrected...should have been - (doseq [entry '({:a 1} {:b 2})] (println entry)) |
| 15:11 | headius | doseq always makes me thing of The Most Interesting Man In The World |
| 15:11 | headius | think |
| 15:11 | chouser | bartj: a vector is more idiomatic unless you have a specific reason to quote that collection. |
| 15:11 | headius | michaeltomer: ok...that's fair to say, though it's mostly due to the main implementation being fairly naive |
| 15:11 | michaeltomer | headius: Absolutely. |
| 15:11 | headius | michaeltomer: I'm pretty sure I can get jruby to thwomp any other JVM dynlang very soon |
| 15:12 | headius | at least for straight-line execution perf |
| 15:12 | michaeltomer | headius: Including Clojure? If so, then you've got my attention. |
| 15:12 | bartj | chouser: er, no reason |
| 15:12 | headius | including clojure |
| 15:12 | headius | I've just started to play with dynamic optimizations in jruby that can turn dynamic calls into static, lift boxed math to primitives, and so on |
| 15:13 | headius | by end of summer some of that should be landing in jruby 1.6 |
| 15:13 | headius | but this is #jruby talk, so I'll shut up now |
| 15:13 | michaeltomer | headius: Sounds awesome. I'd be very interested in using JRuby, as my code is already in Ruby. I'd prefer not to rewrite if I can help it. |
| 15:13 | bartj | candera: yes vector would be better... |
| 15:13 | michaeltomer | headius: Sorry :) |
| 15:13 | headius | michaeltomer: feel free to talk in jruby, we can at least see if jruby handles your case faster right now |
| 15:14 | bartj | er, is it possible to group all values of a given key |
| 15:14 | bartj | something like this: ({:A 1} {:A 2} {:A 3} {:C 1} {:C 2}) |
| 15:14 | bartj | to this: ({:A [1 2 3]} {:C [1 2]}) |
| 15:15 | bartj | I tried: |
| 15:15 | bartj | , (into {} ({:A 1} {:A 2} {:A 3} {:C 1} {:C 2})) |
| 15:15 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap |
| 15:16 | bartj | I mean: |
| 15:17 | bartj | , (into {} '({:A 1} {:A 2} {:A 3} {:C 1} {:C 2})) |
| 15:17 | clojurebot | {:A 3, :C 2} |
| 15:18 | chouser | ,(reduce (partial merge-with vector) [{:A 1} {:A 2} {:A 3} {:C 1} {:C 2}]) |
| 15:18 | clojurebot | {:C [1 2], :A [[1 2] 3]} |
| 15:18 | chouser | hm, not quite... |
| 15:19 | pedroteixeira | ,(doc group-by) |
| 15:19 | clojurebot | "([f coll]); Returns a 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." |
| 15:21 | chouser | but he only wants the values, not the maps |
| 15:22 | pedroteixeira | remember there was a reduce-by function in groups, might help? |
| 15:22 | bhenry | candera: i just had to quote each struct form |
| 15:22 | chouser | ,(reduce (fn [m p] (let [[k v] (first p)] (assoc m k (conj (m k []) v)))) {} [{:A 1} {:A 2} {:A 3} {:C 1} {:C 2}]) |
| 15:22 | clojurebot | {:C [1 2], :A [1 2 3]} |
| 15:23 | chouser | the use of single-entry maps is a bit odd |
| 15:23 | candera | bhenry: Glad you found it. One day I'll actually answer a question successfully here. |
| 15:24 | candera | Before anyone else. Even chouser. :) |
| 15:24 | candera | Maybe when he's asleep. |
| 15:24 | chouser | Mmmm, sleep... |
| 15:25 | bartj | chouser: perhaps, I can run this? |
| 15:25 | bartj | (zipmap (keys {:C [1 2], :A [[1 2] 3]}) (map #(into [] (flatten %)) (vals {:C [1 2], :A [[1 2] 3]}))) |
| 15:26 | bartj | , (zipmap (keys {:C [1 2], :A [[1 2] 3]}) (map #(into [] (flatten %)) (vals {:C [1 2], :A [[1 2] 3]}))) |
| 15:26 | clojurebot | {:A [1 2 3], :C [1 2]} |
| 15:26 | chouser | yeah, or just use the reduce expr I gave. |
| 15:26 | bartj | chouser: yes, I did not look at that... |
| 15:27 | codemonsta | i |
| 15:27 | codemonsta | i'm having trouble reading lisp / clojure code |
| 15:27 | codemonsta | my eyes don't know where to start at |
| 15:27 | codemonsta | in C++, I look from left to right |
| 15:27 | codemonsta | that doesn't seem to work here |
| 15:27 | chouser | codemonsta: right. often it helps to read from the inside out. |
| 15:28 | dnolen | codemonsta: -> and ->> help with that |
| 15:28 | dnolen | ,(+ 4 (/ 5 (* 6 3))) |
| 15:28 | clojurebot | 77/18 |
| 15:28 | dnolen | ,(-> 6 (* 3) (/ 5) (+ 4)) |
| 15:28 | clojurebot | 38/5 |
| 15:29 | chouser | I tend to skim along from the outside in (left to right) picking up important words like 'defn', 'for', 'doseq', 'let' ... things that change the context in some way, but only keep them vaguely in mind. |
| 15:29 | dnolen | heh |
| 15:29 | candera | Here's an alternate solution. Looks cleaner, so I'm assuming that I'm missing something :) |
| 15:29 | candera | (reduce |
| 15:29 | candera | #(merge-with |
| 15:29 | candera | (partial conj []) |
| 15:29 | candera | %1 %2) |
| 15:29 | candera | [{:A 1} {:A 2} {:B 3} {:B 4}]) |
| 15:29 | chouser | ...then read from the inside out to get the real details, what each form returns and passes to the next. |
| 15:29 | candera | Whoops. Should have reformatted. Sorry. |
| 15:30 | dnolen | ,(+ (/ (* 6 3) 5) 4) |
| 15:30 | clojurebot | 38/5 |
| 15:30 | candera | ,(reduce #(merge-with (partial conj []) %1 %2) [{:A 1} {:A 2} {:B 3} {:B 4}]) |
| 15:30 | clojurebot | {:B [3 4], :A [1 2]} |
| 15:30 | bartj | codemonsta: I found this wonderful wonderful article on Stack Overflow when I was starting out - http://stackoverflow.com/questions/1894209/how-to-read-mentally-lisp-clojure-code |
| 15:30 | codemonsta | is using -> and ->> idiomatic? |
| 15:30 | codemonsta | it seems like one would want to avoid them |
| 15:30 | dnolen | codemonsta: yup |
| 15:31 | chouser | candera: that is nice. not sure what's wanted if a key shows up only once though. |
| 15:31 | chouser | ,(reduce #(merge-with (partial conj []) %1 %2) [{:A 1} {:B 3} {:B 4}]){:B [3 4], :A 1} |
| 15:31 | bartj | candera: thanks! |
| 15:31 | clojurebot | {:B [3 4], :A 1} |
| 15:32 | candera | chouser: Ah, good point. |
| 15:33 | codemonsta | reading clojure code make me cry because I can read 100 of lines of C++ code in a moments |
| 15:33 | codemonsta | reading 100 lines of clojure code, however... |
| 15:33 | chouser | codemonsta: ah, but 100 lines of clojure is actually like at least 200 of C++. And possibly more like 500 |
| 15:34 | bartj | codemonsta: after you learn to read clojure code, you will still cry... |
| 15:34 | Raynes | codemonsta: The 100 lines of Clojure you'd be reading would probably do about 10 times what the C++ code does. |
| 15:34 | chouser | it's more idea-dense, so don't be surprised if it takes longer to read. |
| 15:34 | bartj | codemonsta: But, those would be tears of joy and disbelief :) |
| 15:34 | trptcolin | and your mouse's scroll wheel will last much longer |
| 15:34 | codemonsta | so i shouldn't feel like a tard if I can't read clojure at the same rate I can read C++? |
| 15:35 | dnolen | codemonsta: certainly not |
| 15:35 | codemonsta | i feel like a first grader trying to read 'run spot run' over here |
| 15:36 | dnolen | that's 'map spot reduce' ;) |
| 15:36 | codemonsta | and all the other kids are laughing at me :) |
| 15:37 | codemonsta | is it possible / easy to implement a metacircular evaluator in clojure? |
| 15:37 | codemonsta | it would be nice to augment the language that way, if one were so inclined |
| 15:39 | dnolen | codemonsta: there's plenty to augment with the language as it is. macros go a looooooooooong way. you can autogenerate code from files on your disc at runtime if you want. |
| 15:39 | codemonsta | i can't hack eval then? |
| 15:40 | dnolen | codemonsta: you can, but eval is really slow, since it's not interpreted, eval just kicks in the compiler and puts that code right into the running program. |
| 15:40 | chouser | Clojure has eval. What would metacircular improve? (I'm not asking rhetorically) |
| 15:42 | codemonsta | someone was making an effort to 'port' SICP to clojure |
| 15:42 | wires | codemonsta: i'm not sure what you mean; isn't clojure itself metacircular? ie. it depends on JVM + clojure.jar to implement core functions? clojure is not an (self-) interpreter, right? |
| 15:43 | codemonsta | the concepts are not clear in my head |
| 15:44 | bartj | codemonsta: did you have a look at the SO link I pinged above? |
| 15:44 | codemonsta | I'd just like to be able to extend the language itself the same way its is done in SICP |
| 15:44 | codemonsta | yes |
| 15:45 | trptcolin | codemonsta: jakemcc has gotten the furthest i know about |
| 15:45 | trptcolin | see http://github.com/jakemcc/sicp-study |
| 15:46 | bartj | did anyone of you here do this: http://sicpinclojure.com/ |
| 15:48 | codemonsta | http://blog.n01se.net/?p=41 |
| 15:50 | codemonsta | i suppose i'd really want to hack the compiler instead of the evaluator |
| 15:51 | codemonsta | my goal is to work in a language that I can personally extend |
| 15:51 | chouser | macros are hooks directly into the compiler |
| 15:51 | wires | codemonsta: just start writing. macro will get you very far |
| 15:52 | codemonsta | macros transform expressions |
| 15:52 | codemonsta | but that's not the end-all |
| 15:52 | wires | codemonsta: if that's not enough, you can drop to java? |
| 15:53 | chouser | nah. macros will get you really really far |
| 15:53 | wires | indeed |
| 15:53 | codemonsta | but they're not as powerful as hacking the language |
| 15:53 | dnolen | codemonsta: there are certain things in sicp that you can't do (like implementing lazy evaluation). but if that's what you really want to explore why not hack on PLT Scheme? |
| 15:53 | wires | codemonsta: uhm. what specifically are you thinking about |
| 15:54 | codemonsta | I don't need to hack the language |
| 15:55 | codemonsta | I want to work in a language that's hackable if it come to needing it |
| 15:55 | nDuff | codemonsta, you might be surprised at how much of "the language" is actually defined through macros already |
| 15:55 | chouser | like... lazy-seq |
| 15:56 | wires | codemonsta: but what do you mean, hackable: you can write code that transforms your code, you can replace/reimplement the core implementations (which are just java), or you can add new 'elementary' functions using java interop |
| 15:56 | codemonsta | i mean I shouldn't have to drop to java to add special forms |
| 15:56 | codemonsta | but, it's acceptable if I have to |
| 15:57 | codemonsta | it's probably easier to hack the java than to hack, say, LLVM |
| 15:57 | chouser | if you really want to, you can write macros that generate java bytecode and load that right up. clojure-native actually does this, without a single line of Java. |
| 15:57 | codemonsta | still, that would only apply the JVM version |
| 15:57 | codemonsta | what if I want to deploy to .NET? |
| 15:57 | chouser | I'm sorry, what are you actually asking for? |
| 15:57 | codemonsta | I get to maintain a hack on each platform? |
| 15:58 | wires | codemonsta: start coding, then come back with concrete problem you can't do with macros |
| 15:58 | codemonsta | just asking for what lisps usually provide |
| 15:58 | chouser | is there a specific feature you'd like to add that you think cannot be done via macros? |
| 15:58 | wires | codemonsta: I was skeptical at first, but really just try it ;-) |
| 15:59 | codemonsta | I'm not skeptical, just trying to find the downsides of clojure |
| 15:59 | wires | haha |
| 15:59 | chouser | classpath |
| 16:00 | wires | codemonsta: dude, If you ask me... there are very little downsides... compared to haskell, c++, java, python etc.. |
| 16:00 | wires | codemonsta: this stuff is so elegant, it's mindblowing |
| 16:00 | codemonsta | perhaps, but one still needs to know the ugly spots |
| 16:00 | zakwilson | JVM startup time |
| 16:00 | zakwilson | JVM memory overhead |
| 16:00 | codemonsta | if it were up to me, my next project would be in Clojure |
| 16:00 | wires | agreed |
| 16:01 | dnolen | codemonsta: not as fast C++, classpath, young ecosystem, JVM startup times are downsides. |
| 16:01 | zakwilson | and the fact that I can't get a parallel map to run efficiently on the Mac Pro I'm using for the heavier number crunching |
| 16:02 | codemonsta | I wonder how far along the clr implementation is |
| 16:02 | codemonsta | .net rocks much harder than the java library |
| 16:02 | codemonsta | tho I bet there's mad issues with .net libs on the clr port as well |
| 16:03 | zakwilson | How does .NET's performance compare to the JVM? |
| 16:03 | codemonsta | but you're right, I just need to start writing clojure |
| 16:03 | codemonsta | If only I had a project I could use it for... |
| 16:03 | zakwilson | Create one |
| 16:04 | shoover | codemonsta: ICFP is in 2 weeks |
| 16:04 | codemonsta | i don't have time for hobby projects, sadly |
| 16:05 | codemonsta | all I have time to do is scan over new languages and annoy said language users on IRC |
| 16:05 | shoover | well played |
| 16:05 | wires | codemonsta: idea: find some crappy implementation of a java interface and re-implement that using clojure |
| 16:06 | codemonsta | hmmm |
| 16:06 | wires | codemonsta: we did that in our product and are now slowly learning and rewrite more and more |
| 16:06 | wires | well, we = me |
| 16:06 | wires | haha |
| 16:06 | KirinDave | Is Michael Harrison here? |
| 16:07 | zakwilson | That sounds like an awful way to learn Clojure... a good way to learn the Java interop part, but I find that part of the language a neccessary evil, not one of the interesting parts |
| 16:09 | chouser | Might be a good way to learn why it is you should learn Clojure, though. |
| 16:10 | wires | zakwilson: I started with toy programs, fib, graph algorithms etc. to get the idea |
| 16:10 | KirinDave | chouser: Maybe my blog post had a major error by neglecting to mention extending primitive types |
| 16:10 | KirinDave | chouser: Or maybe the average rubyist is just not getting what I was saying... |
| 16:10 | KirinDave | chouser: But I am seeing a lot of http://www.michaelharrison.ws/weblog/?p=303#more-303 |
| 16:10 | KirinDave | And I cannot parse it. |
| 16:11 | wires | zakwilson: We have a product and for us it made a lot of sense to rewrite some core parts in clojure, java interop hence unavoidable. |
| 16:11 | KirinDave | I thought I was very careful to mention divorcing inheritance from the issue. I think I said it at least twice. |
| 16:12 | dnolen | KirinDave: well it is a subtle thing. But yeah that post thoroughly misses the point. |
| 16:13 | KirinDave | dnolen: Look at the last example |
| 16:15 | dnolen | you can only respond to that with: huh? |
| 16:16 | codemonsta | clojure is strongly typed, right? |
| 16:16 | dnolen | on the other hand, there is a "hostiness" to protocols and types that you can only understand from "inside" Clojure. So perhaps the reponse isn't as off base as I'd like to believe. |
| 16:19 | codemonsta | so anyways, I write simulators for a living |
| 16:19 | bartj | chouser: thanks a lot! |
| 16:19 | codemonsta | and writing simulators generally involves modeling real world objects with structures |
| 16:20 | codemonsta | like struct Entity { String Identity; Vector3 Position; Matrix Orientation; }; |
| 16:21 | _fogus_ | KirinDave: I am perpetually perplexed by monkey-patching especially given that I know very little Ruby. |
| 16:21 | codemonsta | so that's usually my starting point |
| 16:21 | KirinDave | _fogus_: It's just class reopening. |
| 16:21 | joshua-choi | dnolen: Protocols and types are being used though to make Clojure more independent of the host, interestingly enough. |
| 16:21 | _fogus_ | KirinDave: But your post seemed pretty comprehensible |
| 16:21 | joshua-choi | in contrast |
| 16:21 | KirinDave | But people seem to think Mixins and inheritance solve the problem. |
| 16:21 | KirinDave | And they do not, but perhaps that is the subtlety. |
| 16:21 | codemonsta | then I usually use inheritance to extend structures like struct Person : Entity |
| 16:21 | KirinDave | in general is-a relationships have fallen out of fashion |
| 16:22 | KirinDave | They're the most difficult kind of relationship, requiring basically full knowledge of the underlying class. |
| 16:22 | KirinDave | has-a is far more reasonable for most uses. |
| 16:22 | codemonsta | Kirin, let's not get into that just yet |
| 16:22 | _fogus_ | Monkey patching seems like the bastard child of Scala's implicits |
| 16:22 | codemonsta | Is this a reasonable approach in closure? |
| 16:22 | cemerick | FYI, last call on dropping your 2¢ in the "State of Clojure" survey. It's going to get closed down around midnight tonight EDT: http://bit.ly/dCmlZL |
| 16:22 | KirinDave | _fogus_: I think it predates scala, but... |
| 16:22 | KirinDave | _fogus_: Want to really get weirded out? Check out eigenclasses |
| 16:23 | cemerick | by quite a ways, yeah |
| 16:23 | cemerick | I think the term is actually from the python side, no? |
| 16:23 | KirinDave | eigen? |
| 16:23 | KirinDave | Or monkeypatch |
| 16:23 | cemerick | monkeypatching |
| 16:23 | codemonsta | can / should one do simulation modeling in Clojure creating and extending structures? |
| 16:23 | codemonsta | 'by creating' |
| 16:23 | KirinDave | mp comes from python as a pejorative. Rubyists adopted the term as a prideful thing. |
| 16:23 | cemerick | yeah, that's what I thought |
| 16:24 | cemerick | it's a big smell in the py world |
| 16:24 | _fogus_ | KirinDave: I've looked into eigenclasses. |
| 16:24 | dnolen | codemonsta: yes. deftype, defrecord will do that. Though Clojure takes the "inheritance sucks" stance. Which is making more sense to me everyday. |
| 16:25 | codemonsta | I agree that inheritance suck, but in many languages, the extra indirection of has-a gets in the way |
| 16:25 | bartj | chouser: the only thing I am not sure is why you used (first p) |
| 16:25 | codemonsta | All major C-derived languages, for example |
| 16:27 | codemonsta | in C++, you'd have karen->GetPerson()->GetEntity()->GetPosition(); |
| 16:27 | codemonsta | and that's really terrible |
| 16:28 | codemonsta | you could write forwarding methods at each level for each facet, but that's also terrible |
| 16:28 | codemonsta | not sure if clojure has the same issues |
| 16:29 | codemonsta | the alternative is automatic forwarding to implement is-a via has-a, and I don't recall what languages have that |
| 16:31 | KirinDave | clever fellow, that one |
| 16:31 | bartj | dnolen: any nice articles explaining that stance? |
| 16:32 | codemonsta | my summary is that is-a can always be implemented as has-a very succinctly with just a bit of sugar |
| 16:33 | codemonsta | and the problem with is-a is that it permanently bind the relationship of the two objects |
| 16:33 | MenTaLguY | is it bad that I actually don't remember what I wrote about eigenclasses? |
| 16:33 | codemonsta | whereas has-a allows the relationship to change |
| 16:33 | dnolen | bartj: most of Clojure's source and literature on clojure.org :) |
| 16:33 | KirinDave | My problem is that I am just so sick and tired of the ruby community at large |
| 16:34 | KirinDave | There is a nasty problem with the ruby community of affecting DHH and crew. |
| 16:34 | codemonsta | there's also the old and true mantra of 'prefer containment to inheritance' |
| 16:34 | KirinDave | Now those guys know what they're doing, but many rubyists are web devs who don't have nearly the skills those people have either through effort or talent |
| 16:34 | codemonsta | !ggl |
| 16:34 | KirinDave | But they take a chip on their shoulders like, "Didn't you think of inheritance?" |
| 16:34 | dnolen | bartj: multimethods do support dispatching on hierarchy. |
| 16:34 | KirinDave | Or anything :) |
| 16:35 | KirinDave | Dispatching on string length ;) |
| 16:35 | raek | alef and go-lang has and interesting approach to has-a/is-a |
| 16:35 | _fogus_ | MenTalguY: most of my exposure was your frequent responses on _why's old redhanded blog |
| 16:35 | MenTaLguY | ahhh |
| 16:35 | MenTaLguY | I'm pretty angry at _why for nuking redhanded |
| 16:35 | MenTaLguY | it was a big part of our collective memory |
| 16:35 | codemonsta | the advantage of is-a is establishing semantic type relationships |
| 16:36 | codemonsta | has-a generally does not impose a type semantic |
| 16:36 | codemonsta | though I suppose that's less important in a dynamic languages |
| 16:37 | KirinDave | MenTaLguY: Can we be angry at him for a lot of things? |
| 16:37 | MenTaLguY | I wonder if the wayback machine has redhanded archived actually... |
| 16:37 | codemonsta | the difference between is-a and has-a really is semantics, so you can't discount either |
| 16:37 | KirinDave | MenTaLguY: I don't know or care what his deal was. He took a thing he only had partial ownership in |
| 16:37 | MenTaLguY | indeed |
| 16:38 | KirinDave | Also, yaml's code sucked. ;) |
| 16:38 | MenTaLguY | I'm not quite sure what the deal was with syck |
| 16:38 | codemonsta | what happened? |
| 16:38 | codemonsta | someone wiped a community code base? |
| 16:39 | KirinDave | MenTaLguY: I suspect it was designed as an elaborate prank. |
| 16:39 | KirinDave | MenTaLguY: Also I am sorta grumpy that everyone said to learn ruby through why's book. Why's book was the worst way to learn ruby for 90% of everyone who asked |
| 16:39 | KirinDave | But people loved comics so they're like YEAH! |
| 16:39 | MenTaLguY | codemonsta: roughly speaking, yes |
| 16:40 | codemonsta | and noone has a back up? |
| 16:40 | KirinDave | codemonsta: it was his blog |
| 16:40 | MenTaLguY | codemonsta: one of the major rubyists who ran a lot of key infrastructure and projects committed virtual suicide and took all of it with him |
| 16:40 | bartj | I thought there were copies on github |
| 16:40 | KirinDave | no |
| 16:40 | MenTaLguY | we managed to rescue a lot of it |
| 16:40 | KirinDave | not for redhanded |
| 16:40 | MenTaLguY | but, not of everything |
| 16:40 | codemonsta | ah |
| 16:40 | MenTaLguY | so it does seem that the wayback machine has redhanded archives |
| 16:41 | codemonsta | well, I was a bout to excoriate all of you for not having a back up of the repository, but a blog is a different matter |
| 16:41 | MenTaLguY | though unfortunately the wayback machine is pretty unreliable these days |
| 16:41 | MenTaLguY | I can't actually seem to *get* to the paages |
| 16:42 | codemonsta | seems to me though that clojure has best solved the general concurrency problem |
| 16:43 | onkara | hi guys I am using the CCW for eclipse and trying to create a clojure file in an existing java project and I keep getting this error "Cannot create Clojure file outside a java source folder" |
| 16:43 | codemonsta | what other language comes close to this? |
| 16:43 | onkara | though if I do that in a brand new project everything works fine |
| 16:44 | MenTaLguY | erlang, probably |
| 16:44 | MenTaLguY | not sure it's such a great language otherwise, but it does manage concurrency pretty well |
| 16:45 | codemonsta | ah, ya, actors |
| 16:45 | codemonsta | i prefer clojure's agents tho |
| 16:45 | codemonsta | doesn't scala have some concurrency semantics? |
| 16:46 | onkara | scala has erlang style actors |
| 16:46 | codemonsta | ah, ok |
| 16:46 | onkara | not sure if it has STM |
| 16:46 | codemonsta | STM FTW |
| 16:47 | codemonsta | well, cheap STM, anyways |
| 16:49 | bartj | I almost always use reduce where apply would suffice - I think |
| 16:49 | bartj | , (reduce str [\a \b \c \d \e]) |
| 16:49 | clojurebot | "abcde" |
| 16:49 | MenTaLguY | STM isn't actually a good solution in most cases |
| 16:49 | bartj | , (apply str [\a \b \c \d \e]) |
| 16:49 | clojurebot | "abcde" |
| 16:49 | bartj | is this frowned upon? |
| 16:49 | MenTaLguY | in that specific instance apply makes more sense |
| 16:50 | MenTaLguY | and is most likely more efficient |
| 16:50 | MenTaLguY | since you're (theoretically) not creating a bunch of intermediate string objects |
| 16:50 | bartj | is there some mental distinction I can make in this regard? |
| 16:50 | MenTaLguY | sure |
| 16:50 | MenTaLguY | in the case of apply, you're just calling str with five arguments |
| 16:50 | MenTaLguY | in the case of reduce, you're calling str four times |
| 16:51 | MenTaLguY | (str (str (str (str \a \b) \c) \d) \e) |
| 16:51 | bartj | MenTalguY: ok...got it |
| 16:51 | MenTaLguY | versus (str \a \b \c \d \e) for apply |
| 16:51 | Borkdude | ,(dotrace [str] (reduce str [\a \b \c \d \e])) |
| 16:51 | clojurebot | java.lang.Exception: Unable to resolve symbol: dotrace in this context |
| 16:51 | bartj | yeah, when you put it that way - it looks pretty bad |
| 16:51 | Borkdude | $(dotrace [str] (reduce str [\a \b \c \d \e])) |
| 16:51 | sexpbot | java.lang.Exception: Unable to resolve symbol: dotrace in this context |
| 16:53 | onkara | MenTaLguY: in what cases does STM makes most sense ? |
| 16:53 | MenTaLguY | when transactions are small and local |
| 16:54 | onkara | so how does one handle distributed transactions |
| 16:54 | Borkdude | ,(clojure.contrib.trace/dotrace [str] (reduce str [\a \b \c \d \e])) |
| 16:54 | clojurebot | java.lang.ClassNotFoundException: clojure.contrib.trace |
| 16:54 | onkara | through Agents ? |
| 16:54 | Borkdude | $(clojure.contrib.trace/dotrace [str] (reduce str [\a \b \c \d \e])) |
| 16:54 | sexpbot | java.lang.ClassNotFoundException: clojure.contrib.trace |
| 16:54 | Borkdude | hmm... |
| 16:54 | MenTaLguY | transactions and distribution are kind of inimical |
| 16:54 | Borkdude | actually in my REPL, this causes a StackOverflow.. wondering why |
| 16:54 | MenTaLguY | there are such things as distributed transaction managers, but they tend to be bottlenecks |
| 16:56 | onkara | yup agreed but then how does clojure handle distributed trasactions |
| 16:56 | MenTaLguY | it doesn't, nor do the clojure standard libraries |
| 16:56 | MenTaLguY | you're better off with message-passing for distributed stuff |
| 16:57 | onkara | MenTaLguY: thats the agent or reactor pattern ... right ? |
| 16:57 | MenTaLguY | well, I was thinking really distributed |
| 16:57 | MenTaLguY | zeromq or something |
| 16:57 | MenTaLguY | (I forget if that has clojure bindings) |
| 16:58 | MenTaLguY | actor/reactor pattern I guess |
| 16:58 | MenTaLguY | agents are more about mobile data in a way |
| 16:58 | MenTaLguY | with agents, you take the code to the data |
| 16:58 | MenTaLguY | with actors etc. you take the data to the code |
| 16:58 | MenTaLguY | er |
| 16:58 | KirinDave | hum |
| 16:58 | MenTaLguY | agents are more about mobile code in a way, sorry |
| 16:59 | KirinDave | Agents is a heavily loaded term in this space. |
| 16:59 | MenTaLguY | this is true |
| 16:59 | KirinDave | For example, when you say agents to me I think of systems like "aglets" |
| 16:59 | MenTaLguY | I'm thinking of agents in terms of what Clojure agents are specifically |
| 16:59 | KirinDave | Which were the very soul of code going to data. |
| 16:59 | MenTaLguY | yeah |
| 16:59 | MenTaLguY | that kind of thing also |
| 17:00 | MenTaLguY | I guess also things like the big implementations of MapReduce |
| 17:00 | MenTaLguY | in those cases you're basically farming out your map/reduce functions to where the data lives |
| 17:01 | MenTaLguY | the essential thing, though, is that if you want concurrency/parallelism, you have to farm things out to multiple physical places |
| 17:01 | MenTaLguY | whether multiple cores or nodes on a network or whatever |
| 17:02 | MenTaLguY | you can try to maintain the illusion of shared *local* storage (which is what STM tries to accomplish), but it breaks down after a while and you have to explicitly acknowledge the physical distance in practice |
| 17:03 | MenTaLguY | I think I'd go so far to say that STM simply doesn't scale unless you can find clever ways to partition the system (whether explicitly or implicitly) |
| 17:04 | MenTaLguY | which becomes harder the larger/less local your transactions are |
| 17:08 | onkara | MenTaLguY: I think you should blog about these limitations of STM ... and may be things will be improved upon ... FYI for the biggest selling point apart from functional and dynamic language that clj is was STM ... |
| 17:09 | onkara | i mean limitation of clj's implementation of STM |
| 17:09 | MenTaLguY | it's not a question of improving STM, it's kind of a physical laws of the universe thing |
| 17:09 | MenTaLguY | Clojure has one of the best STM implementations I've ever seen |
| 17:10 | MenTaLguY | but STM just isn't a suitable programming model for distributed computing |
| 17:10 | onkara | well i am just starting with clojure .... so I only understand things theoretically |
| 17:11 | MenTaLguY | there are places where STM is useful, for the record |
| 17:11 | KirinDave | Right, it's usefull as an underlying mechanism. |
| 17:11 | KirinDave | But as an actual solution, it's really not applicable. |
| 17:11 | MenTaLguY | pretty much |
| 17:12 | MenTaLguY | I still tend not to like it because it's hard to predict the performance characteristics under load, though Clojure again does a much better job than most any other mainstream STM implementation I've seen |
| 17:13 | MenTaLguY | I probably really should blog about this |
| 17:20 | onkara | hi guys since I am new to clojure (getting started) with CCW/Eclipse ... after trying the hello world example I want to try clojure.contrib.logging ... what jar do I need to (down)load to make that work |
| 17:21 | dnolen | onkara: the contrib jar |
| 17:21 | dnolen | if you have it just make sure it's on your classpath |
| 17:22 | onkara | dnolen: its in my classpath and this is what I am trying http://gist.github.com/425960 |
| 17:22 | onkara | but I get error java.io.FileNotFoundException: Could not locate clojure/contrib/logging__init.class or clojure/contrib/logging.clj on classpath: |
| 17:23 | dnolen | onkara:how are you starting clojure? |
| 17:23 | onkara | dnolen: what do you mean ? |
| 17:23 | onkara | you meant running the code ? |
| 17:24 | dnolen | oh yeah, sorry you're using CCW, then contrib hasn't been properly added to the classpath, or perhaps you need to restart the CCW repl (I don't use CCW so I can't say) |
| 17:25 | onkara | the clojure-contrib.jar that CCW has doesn't have logging.clj |
| 17:26 | dnolen | just get a more recent one and add the jar to your project, I would think. |
| 17:26 | onkara | dnolen: thanx will try that |
| 17:27 | TimMc | I'm having trouble getting CCW and leiningen to play well together. |
| 17:27 | TimMc | Specifically, regarding libs. |
| 17:29 | TimMc | `lein deps` puts all manner of jar files into ./lib... how do I get CCW or Eclipse to put those on the classpath? |
| 17:31 | TimMc | Urgh, never mind... this is just CCW getting itself into a bad state. |
| 17:31 | TimMc | Project -> Clean fixed it. |
| 17:31 | TimMc | (CCW was failing to see the jars, even though ./lib was on the build path as a class folder) |
| 17:38 | digash | does anybody knows why Numbers.java have no primitive implementations for short? |
| 17:39 | digash | and byte too? |
| 17:40 | TimMc | Anyone here use Eclipse + CCW? |
| 17:40 | TimMc | I'm having trouble figuring out how to invoke Clojure properly. |
| 17:41 | korre | invoke? |
| 17:41 | clojurebot | () invokes the form inside, but there is an implied str call. The semantics are different inside the interpolated string, necessarily so. |
| 17:41 | TimMc | I guess there are a couple of different use-cases. |
| 17:42 | TimMc | 1) I want to run my core.clj file, which launches a ring server. |
| 17:42 | TimMc | 2) I'd like a REPL that loads all the definitions from an open .clj file so that I can do some interactive programming. |
| 17:43 | onkara | hi guys I am trying a very simple logging excercise http://gist.github.com/425960 first of all I am getting this error "java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword" |
| 17:43 | korre | it excecutes the file every time you save i think |
| 17:43 | onkara | and second how can I ensure that I am using log4j and not java.logging |
| 17:43 | TimMc | Currently I'm getting weird errors, so I'm not sure if it's a classpath issue or a code issue. :-/ |
| 17:44 | korre | onkara: you whant an iseq from the name of the keyword? |
| 17:44 | korre | as in (seq (name some-key-word)) |
| 17:45 | onkara | korre: please bear with me I am very new to the whole clojure thing ... could you gist me an example so that I can better understand you ? |
| 17:46 | korre | so if you hawe the keyword :something and you whant a seq of the characters like (\s \o \m \e .......) |
| 17:46 | korre | is it a seq of the name you are after? |
| 17:47 | onkara | not really I am not after Seq of the name parameter |
| 17:47 | korre | o wait sorry Don't know how to create ISeq from: clojure.lang.Keyword" is from the exception :D |
| 17:48 | onkara | this is a very simple code I am just trying to test the integration of logging (may be log4j) in clojure |
| 17:48 | korre | so you are passing the keyword to something expecting a seq |
| 17:49 | onkara | korre: never mind that ... i am now getting a different error http://gist.github.com/425960 on line 9 |
| 17:50 | onkara | an exception is being thrown |
| 17:50 | onkara | in the function |
| 17:52 | onkara | seems that code is failing on the string concatenation |
| 17:52 | korre | (log/warn "params = " name) |
| 17:52 | onkara | yeah ... can't make out whats wrong with that ? |
| 17:52 | korre | you are intending to write (log/warn (str "params = " name)) i gess |
| 17:53 | onkara | ah |
| 17:53 | korre | name will be the second parameter to logg otherwize and it expects a throwable |
| 17:53 | onkara | interesting though that (println "something" "here") works fine |
| 17:53 | onkara | perhaps its doing (str "something" "here") internally |
| 17:54 | korre | println also adds spaces |
| 17:54 | korre | ,(println "hej" "world") |
| 17:54 | clojurebot | hej world |
| 17:55 | onkara | yes it does |
| 17:56 | onkara | how do I configure contrib-logging to use log4j |
| 17:56 | onkara | or rather how do I find which logging system it is using ? |
| 17:57 | korre | im nott a java land guru :p |
| 17:57 | korre | you can check the source code on github |
| 17:57 | onkara | you from the lisp world ? |
| 17:57 | korre | .net |
| 17:57 | onkara | ah |
| 17:57 | onkara | close |
| 17:58 | onkara | BTW how does clojure perform on .net |
| 17:58 | onkara | ? |
| 18:05 | korre | seams it uses the first login system it can find |
| 18:06 | korre | org.apache.commons.logging first then org.apache.log4j and last java.util.logging witch is the implementation i seam to get in my repl |
| 18:09 | riddochc | Best feature of clojure: Bringing Lisp to Java. Worst feature: Java. ;) |
| 18:09 | korre | allot of thinking is being put to fight with java api's :p |
| 18:16 | mmarczyk | riddochc: lol :-) |
| 18:27 | riddochc | I've been reading through SICP again. It seems very math-centric rather than programming-centric. I definitely understand why HTDP was written to substitute for it... |
| 18:32 | Borkdude | riddochc: same problem with Project Euler maybe |
| 18:34 | Borkdude | gtg |
| 18:35 | mmarczyk | riddochc: I don't agree at all |
| 18:37 | mmarczyk | not that SICP doesn't have it's cool math examples, but they always enter the stage so that a programming-related concept may be illustrated in an interesting setting |
| 18:37 | riddochc | mmarczyk: No? I'm not having difficulty with the math, but I think it makes it harder to focus on the programming problems. |
| 18:37 | mmarczyk | I actually find it easier to focus when there's something remotely interesting going on |
| 18:38 | mmarczyk | HtDP seems "reasonable" to me, considered in abstracto, but but when I actually tried reading it -- after SICP -- I just couldn't maintain my interest |
| 18:38 | mmarczyk | mostly because there was really no challenge |
| 18:39 | riddochc | Well, SICP is definitely more challenging. |
| 18:39 | mmarczyk | "take exactly these ingredients and put them together in precisely the following way" -- the challenge is not to yawn |
| 18:40 | mmarczyk | I don't know what happens in the later chapters, though, since I never managed to get to them... I suppose I could skip around, but by the time I was considering doing so, I'd decided to move on to another book |
| 18:40 | mmarczyk | that's about HtDP, of course |
| 18:41 | mmarczyk | all that despite my great admiration for the work of the PLT group |
| 18:44 | riddochc | Yeah, I'm pretty impressed with PLT. |
| 18:57 | arrummzen | Is Clojure a language people typically develop with an IDE (Like Java) or one people typically develop with an editor (Like Python)? |
| 18:59 | lancepantz | a majority use emacs |
| 18:59 | tomoj | that's surprising |
| 19:01 | arrummzen | hehe, I specifically formed my question to avoid the emacs vs. vim/eclipse vs. netbeans issue. |
| 19:01 | dnolen | arrummzen: both |
| 19:10 | TimMc | http://clojars.org/search?q=clojureql <-- how am I supposed to know which one I want? |
| 19:11 | TimMc | There's a [clojureql 0.9.7] pushed by laujensen... but also some 1.0.0 entries. |
| 19:20 | technomancy | TimMc: the one without the "org.*" qualifier is the canonical one |
| 21:39 | defn | arrummzen: it's really all about what you want to do, how you like to work |
| 21:40 | defn | arrummzen: lots of people are using plugins for IDEs like netbeans, lots of people like emacs + slime + paredit, some people prefer vimclojure and nailgun, etc etc |
| 21:40 | defn | arrummzen: i use emacs, but emacs is certainly not the "best" option -- it's just the one I happen to prefer |
| 21:45 | Raynes | arrummzen: I did a poll a while back. It showed that a large majority of people use Emacs and SLIME. Coming in second was Vim and VimClojure, followed by the various IDEs. Just some statistics. I use Emacs. |
| 21:46 | Raynes | There is no reason you shouldn't necessarily use an IDE if that's what you're comfortable with. |
| 21:47 | defn | IDE development is slow in general I think -- There might be a time in the future where I reconsider and choose a full IDE, but for the moment Emacs + paredit + slime has been good to me |
| 21:48 | tomoj | who do you think is more likely to answer a poll about editors, an emacs or vim user, or an IDE user? :) |
| 21:49 | Raynes | defn: I doubt that. Once you go Emacs, you never go back. |
| 21:49 | defn | tomoj: heh, touche |
| 21:49 | Raynes | tomoj: Don't hate on my statistics. |
| 21:49 | defn | Raynes: nah, I think that's a naive answer |
| 21:49 | Raynes | :p |
| 21:49 | defn | if we had a really incredibly refactoring code browser/IDE tailored for clojure, I bet people would switch |
| 21:49 | defn | incredible* |
| 21:50 | mabes | lol... tomoj has a point, any editor poll will be a biased sampling when left to people to volunteer |
| 21:50 | defn | there's always something better 'round the corner |
| 21:50 | arrummzen | I actually used emacs for coding for a long time. |
| 21:50 | Raynes | defn: I seriously, seriously doubt that. You're welcome to fantasize though. <3 |
| 21:50 | arrummzen | But I switched to Eclipse for Java development because it did so much refactoring/code fixing for me. |
| 21:50 | mabes | I know my team would easily pay a could hundred dollars a seat for a really, really nice IDE for clojure.. |
| 21:51 | mabes | er.. a couple |
| 21:51 | Raynes | defn: However, the "Once you go Emacs, you never go back." remark was just a joke. |
| 21:52 | Raynes | I use Emacs for everything. A new editor geared toward Clojure, however incredible, wouldn't get my attention. I know at least a few Emacsers who would probably agree. |
| 21:53 | defn | Raynes: either way I think it is smart to not be so sure about this particular issue (IDEs) -- I can see a plethora of reasons why one might switch |
| 21:53 | defn | Raynes: I'm an Emacser, but I might do my clojure development in a different IDE if it was better than Emacs -- I'd be a fool not to |
| 21:53 | defn | It's not inconceivable that something better could come along |
| 21:54 | Raynes | If you're familiar and comfortable with Emacs, there aren't too many reasons one would switch. You have a powerful editor that can do virtually anything you want it to. |
| 21:55 | Raynes | You're talking about an editor for Clojure. If a new fangled editor came along that was as awesome as Emacs (that includes being extensible and useful for other languages), of course I'd like inclined to switch to it. |
| 21:55 | Raynes | But I'm not going to leave my comfort zone for a new Clojure specific IDE just because. I'm productive enough in Emacs to not want to go that route. |
| 21:55 | Raynes | But that's just me. |
| 21:55 | Raynes | Let's not turn this into an argument. :p |
| 21:55 | Raynes | <3 |
| 21:57 | Raynes | :D |
| 21:59 | lancepantz | what is that editing the definition of? |
| 21:59 | lancepantz | (emacs newbie here) |
| 21:59 | tomoj | M-. will even reach inside jars |
| 21:59 | Raynes | lancepantz: Yes. It jerks you to the definition of something. |
| 21:59 | Raynes | I couldn't find a function a minute ago. |
| 22:00 | Raynes | So SLIME found it for me. |
| 22:00 | Raynes | :D |
| 22:00 | tomoj | e.g. M-. on defn brings you to core.clj |
| 22:00 | lancepantz | oh, wow |
| 22:00 | lancepantz | that' is awesome |
| 22:01 | lancepantz | what is the chord that shows you a function's signature in the minibuffer? |
| 22:05 | tomoj | space :( |
| 22:06 | lancepantz | heh, correct sir |
| 22:09 | tomoj | it looks like slime-echo-arglist will just show it without inserting a space |
| 22:09 | tomoj | but it's not interactive and not bound |
| 22:09 | lancepantz | i see |
| 22:10 | lancepantz | it seems to just work for core functions? |
| 22:10 | tomoj | no, it should work for any functions that are available in the namespace you're in |
| 22:11 | lancepantz | does not for me |
| 22:12 | codemonsta | what's the best clojure ide for a visual studio user? |
| 22:12 | tomoj | you mean, if you do (defn foo [bar & baz]) at the repl, and then type '(foo ', you don't see '([bar & baz])' ? |
| 22:14 | tomoj | I'm using clojure-mode 1.6 |
| 22:14 | lancepantz | i do at the repl, but if i have a buffer open that uses clojure.test, if i type '(deftest ' i don't see [name & body] |
| 22:15 | tomoj | is your repl in the same namespace as the buffer? |
| 22:16 | tomoj | I imagine it is based on where the repl is, not the buffer |
| 22:16 | lancepantz | i meant when i type in the buffer |
| 22:16 | lancepantz | it does work in the repl if i use the ns |
| 22:17 | tomoj | I know |
| 22:17 | tomoj | I'm asking if, while you're typing in the buffer, the repl is in the buffer's ns |
| 22:17 | lancepantz | no |
| 22:18 | tomoj | hmm, actually, that doesn't seem to matter, at least in 1.6 |
| 22:18 | tomoj | have you compiled the functions you're testing with? |
| 22:18 | tomoj | oh, deftest. well, have you compiled the buffer? |
| 22:19 | lancepantz | ah, bingo |
| 22:19 | tomoj | it talks to clojure to figure these things out instead of doing some deep analysis of the source code |
| 22:19 | lancepantz | i see |
| 22:21 | tomoj | I want a function that automatically cleans up my ns declaration |
| 22:21 | lancepantz | yeah, that would be awesome |
| 22:22 | lancepantz | i'd like to be able to move the files in the dir structure and have the ns declarations fixed |
| 22:22 | tomoj | it's a pain to remove things, because they will still be around |
| 22:23 | tomoj | and you won't find out you removed something you shouldn't have till your next session :( |
| 22:24 | defn | @ Raynes, lancepantz : M-, returns you to your previous position after M-.ing on something |
| 22:25 | defn | fwiw |
| 22:25 | Raynes | Cool. |
| 22:25 | lancepantz | yeah |
| 22:26 | tomoj | didn't know that, thanks |
| 22:26 | tomoj | and it's a stack, nice |
| 22:26 | tomoj | chase something down the rabbit hole and come right back out with a few keystrokes :) |
| 22:27 | lancepantz | that will save me so much time |
| 22:27 | lancepantz | usually i keep a browser open to the api docs |
| 22:27 | tomoj | what other nifty tricks are there? C-c C-m is one |
| 22:28 | tomoj | I feel like there must be some I haven't discovered yet |
| 22:28 | defn | what is C-c C-m |
| 22:29 | tomoj | macroexpand the form at point in a separate buffer which goes away with 'q' |
| 22:29 | tomoj | strangely the macroexpansions I see there are uglier now than they used to me |
| 22:29 | tomoj | be |
| 22:30 | defn | cool |
| 22:30 | defn | im not sure how ill use that |
| 22:31 | defn | i still couldnt write a macro to save my life :\ |
| 22:31 | lancepantz | while we're at it, if i enable clojure-mode in my repl, it insert's \n instead of \r when i press enter |
| 22:31 | defn | oh man -- using paredit and proper clojure-mode in slime is a weird problem IIRC |
| 22:31 | tomoj | in my experience it's bad to mess with the repl mode |
| 22:32 | defn | paredit alone is a pain |
| 22:32 | lancepantz | yeah, paredit acts differently too |
| 22:32 | defn | you need to explicitly define certain bindings and tell the repl what a { is, etc. |
| 22:33 | defn | C-c M-p is kind of a handy one FWIW |
| 22:33 | defn | do it in a file where you have eval'd the ns declaration |
| 22:33 | tomoj | also available as ,i when at the repl |
| 22:33 | defn | (ns foo.core)| C-x C-e, C-c M-p |
| 22:33 | defn | whoa..cool |
| 22:34 | defn | what else can you do with ,* |
| 22:34 | tomoj | defn: ,h for example :) |
| 22:37 | tomoj | never tried +p and -p before, cool |
| 22:40 | codemonsta | I'm going to invent the next mainstream programming language |
| 22:40 | codemonsta | it will use MOP |
| 22:40 | codemonsta | 'Mort-Oriented Programming' |
| 22:40 | codemonsta | it will make stupid things easy and smart things impossible |
| 22:41 | lancepantz | oh, like lein |
| 22:41 | lancepantz | sorry, sorry |
| 22:41 | codemonsta | hehe |
| 22:41 | defn | cool |
| 22:41 | defn | God I need a new project to be excited about |
| 22:42 | codemonsta | make an opengl game in clojure |
| 22:42 | defn | i dont like games |
| 22:42 | lancepantz | i like walton |
| 22:42 | defn | no desire to learn opengl |
| 22:42 | lancepantz | stay excited about it :) |
| 22:43 | defn | lancepantz: yeah i want to be, but it's all a mess and I want to redo it, but I keep getting stuck |
| 22:43 | lancepantz | know how ya feel |
| 22:44 | defn | the other thing is im sort of upset with the lack of options for doing web applications in clojure -- so ive been looking at integrating jruby + rails with ring and clojure |
| 22:44 | defn | i want to decouple the client-side part of walton from the server-side stuff |
| 22:45 | defn | and ive never built anything like that before and am kind of clueless as to where to start |
| 22:45 | defn | i want people to be able to query my server and get example data |
| 22:45 | defn | from the client-side |
| 22:45 | defn | people mentioned JSON, but again, just don't know where to start with building that functionality |
| 22:45 | tomoj | I guess the C-c C-d family is worth mentioning as well |
| 22:45 | lancepantz | yeah, i use compojure just to serve an http api |
| 22:45 | lancepantz | our front end is rails |
| 22:46 | defn | yeah you mentioned some code a week ago |
| 22:46 | defn | anything go online yet? |
| 22:46 | defn | <-cheater |
| 22:46 | lancepantz | tuesday is the big release |
| 22:46 | defn | I am scared of compojure due to lack of docs and would love to see how you do things |
| 22:46 | tomoj | moustache+ring+some json lib |
| 22:46 | defn | in fact, I'd like to give a talk about it at our local ruby group if you'd be okay with it |
| 22:47 | lancepantz | yeah ofcourse |
| 22:47 | defn | although i need to be careful |
| 22:47 | defn | i think the ruby guys are a little annoyed by my FP nazi tendencies |
| 22:48 | lancepantz | hahah |
| 22:49 | tomoj | my coworkers get annoyed too. luckily my boss is on my side :) |
| 22:49 | lancepantz | we're split |
| 22:49 | lancepantz | which is great, because i don't want to mess with the ruby stuff, and they don't want to mess with the clojure stuff |
| 22:53 | tomoj | why don't I ever use C-c C-d C-d ? :( |
| 22:56 | tomoj | I wonder how slime-who-calls and friends are implemented for CL |
| 23:12 | defn | some of them are very interested in doing FP in Ruby -- as much as they can anyway |
| 23:12 | defn | i feel that others find that it's just too arcane for them or something |
| 23:12 | defn | i sympathize with them because it took me a good 4 months to even understand how to think functionally |
| 23:13 | defn | i looked for definitions of FP and of course found all sorts of crazy ideas on what FP is truly |
| 23:13 | defn | i think the whole "no side effects" thing is totally misunderstood at first by a lot of OOP programmers |
| 23:14 | defn | one gets the sense that a lot of programmers dont even realize how many things they're mutating |
| 23:17 | ihodes | absolutely agree. i didn't get what FP was until I started doing it, and realizing how awesome it was. eventually found out that people call what I was doing "FP"... |