#clojure log - Jun 04 2010

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:08 Blackfoot: is there a faster way for developing GUI apps that doesn't involve lein uberjar every change?

0:45 konr: When I need to add methods to a class, there is no other way than using gen-class, right?

0: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.

0:47 I use enclojure and its repl server lib at the moment, FWIW.

0:47 keeping a close eye on ccw, though

0:48 Blackfoot: cemerick: hrm ok, i will give those a try thanks

0:48 cemerick: konr: or use gen-interface/defprotocol, and include the method definition in your deftype/defrecord

2: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?

2:13 note: intranet site with mostly trustworthy employees (trustworthy in that they aren't very tech savvy to mess with security)

3: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?

3:24 basically, get "acb" for instance

3:34 raek: (defn swap [coll index-a index-b] (assoc coll index-a (get coll index-b) index-b (get coll index-a)))

3:34 tomoj: can't assoc strings, though

3:34 raek: hrm, right

3:34 tomoj: but I guess you could go through seqs

3:34 er, vectors

3:35 raek: yes, do (vec) on coll

3:35 tomoj: is it always gonna be a string?

3: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)))))

3:38 (str-swap "foo" 0 3) => "oof"

3:39 I haven't looked in the javadoc, though

4:01 vIkSiT: oooh thats a good one.. raek, thanks for the pointer

4:01 tomoj, hmm, could be any seq really

4:02 tomoj: that's unfortunate

4:02 well, maybe not, hmm

4:05 oh, yeah, it is, I think

4:06 if it's any seq, you don't have constant time access to the nth element

4:06 so swapping will be difficult

4:06 vIkSiT: ah good point

4: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

4:08 (and store them all in memory at once)

4:36 LauJensen: Morning all

4:40 esj: Morning el'Lau !

6: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

6:57 one thing I would suggest is to not overload invoke like that

7: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.

7:11 rhickey: cgrand: the other big problem in general is the semantic difference between operations on boxed and unboxed ints

7:12 I'm surprised actually that the non-hinted fib isn't much slower

7:13 cgrand: I guess it's -XX:+DoEscapeAnalysis at work

7:13 rhickey: cgrand: not turned on here, plus going through different math ops

7:15 cgrand: by difference in semantics you mean the promotion of ints to long etc. ?

7:15 rhickey: cgrand: the whole boxed number tower stuff, possible promotion to BigIntegers etc

7:16 cgrand: did you compare hfib to fib in Java on same machine?

7:17 cgrand: no but I can, wait

7:17 rhickey: I'm wondering if all the math in hfib is primitive

7:17 and the cost of the (int 1) (int 2)

7:21 cgrand: heh, yeah, you are not getting what you think you are getting here, yet

7:21 i.e. this wins here for me:

7:21 (defn fibn [n] (let [n (int n)](if (>= (int 1) n) 1 (+ (fibn (dec n)) (fibn (- n (int 2)))))))

7:25 cgrand: rhickey: java for fib(38) : around 360ms

7:25 wires: sorry, i'm just dropping in halfway, but you can work with primitives in closure? I thought everything is boxed?

7:26 rhickey: cgrand: see ^^, I don't think you are getting prim args through the recursive calls

7:27 LauJensen: wires: sure

7:28 wires: http://bestinclass.dk/index.clj/2010/03/functional-fluid-dynamics-in-clojure.html

7:28 wires: LauJensen: using java interop?

7:28 rhickey: cgrand: in fact, I'm wondering if the inline is in play while compiling the body

7:28 wires: LauJensen: thanks, let me check that post

7:29 lpetit: wire: s/closure/clojure/g

7:29 cgrand: rhickey: at some point I traced it to check which method was invoked, and the specialized invoke was called

7:29 rhickey: cgrand: going to breakfast here, I'm sure you'll figure it out - bbl

7:32 wires: lpetit: sorry :) i know that :)

7:32 lpetit: wires: sorry, couldn't resist ;-)

7:32 wires: lpetit: hehe

7:33 lpetit: it's always good to have a few spelling nazi's in the room ;)

8:20 * defn thinks about using Jython, JRuby, Clojure, and jPerl in the same application -- just to see if the world explodes...

8:24 rhickey: cgrand: your perf problem is having to go through the var to get 'this' for the inlined call

8:25 cgrand: rhickey: thanks, I checked that a pure reify solution was around 800ms

8:26 rhickey: cgrand: definterface + deftype 400 ms here

8:27 cgrand: rhickey: something along these lines http://gist.github.com/425352 ?

8:28 rhickey: cgrand: http://gist.github.com/425352#comments

8: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" ?

8:29 rhickey: ideally, the message could indicate what the current namespace was for the last redef of the protocol impl for a certain type

8:30 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".

8:30 rhickey: lpetit: I don't want to solve theoretical problems, let's see if we actually have this problem in practice first

8:31 lpetit: rhickey: always the same scheme. lpetit envisions an hypothetical future problem, rhickey's pragmatism wins ;-)

8: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

8: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.

8:35 LauJensen: I opensourced bestinclass.dk: http://bestinclass.dk/index.clj/2010/06/best-in-class--now-open-sourced.html

8: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

8: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.

8:36 rhickey: lpetit: I'll be ready to listen when you first encounter this problem

8:37 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

8:38 the crash isn't due to a second def, but a wrong def

8: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.

8:44 s/on/one/

8: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.

8:44 lpetit: s/wroneg/wrong def/

8:44 sexpbot: s/on/one/

8:44 LauJensen: I favor the warning - or something at least - if anything can go wrong, eventually it will go wrong

8:50 TimMc: LauJensen: I see the github repo of bestinclass -- cool.

8:53 LauJensen: :)

8:53 TimMc: This will be good for me to paw through. I learn best from example.

8:56 cgrand: rhickey: thanks, I added a disclaimer to my post and linked to this discussion

9:26 LauJensen: Best In Class #10 on Hacker News, hooray :)

9: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")

9:28 is there a way to avoid fully qualifying it ?

9:28 chouser: carkh: it's "just" a class. import it.

9:28 carkh: ahh ok

9:28 let me try this =P

9:29 indeed this works, thanks !

9:37 lpetit: carkh: I guess there's also some work in progress in master fo automatically creating factory fns for records

9:38 carkh: that would definetly help

9:38 eevar2: LauJensen: how is business? clojure an easy sell?

9:39 lpetit: carkh: I cannot retrieve it in the commits. Maybe I was just dreaming :-(

9:39 carkh: heh well no big deal anyways, just a convenience thing

9: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?

9:58 defn update-in

9:58 ~defn update-in

9:58 clojurebot: Gabh mo leithscéal?

9: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 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 chouser: i get an OutOfMemoryError before i hit 6mil

10:06 chouser: you're holding the head

10:06 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 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 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 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 ticket #372 in Assembla, but it seems stuartsierra isn't seeing it on his machine

10:15 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 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 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 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 got the context wrong. "update-in" kind of sounded like what i want.

10:44 Licenser: *g*

10:45 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 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 (defn merge-but [[ & ms] [& sub-ms] exclude]

10:54 (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 (defn merge-data [old-data new-data key]

11:03 (for [i old-data]

11:03 (let [d (first (select #(= (key i) (key %)) new-data))]

11:03 (if d d i))))

11:03 please don't mind the var names :)

11:04 Licenser: but why would you expect in the second map b to stay_

11:04 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 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 or the right/left side does not have the key?

11:07 then you keep the left one right?

11:07 bytecoder: yes, right.

11:08 Licenser: http://gist.github.com/425518

11:09 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 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 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 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 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 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 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 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 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 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 ah

11:24 s/with/without/

11:25 sexpbot: ah

11:25 chouser: sexpbot: not helpful.

11:25 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 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 I sort of think the two are not mutually exclusive.

11:28 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 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 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 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 There's really only one way to build an arch. :-)

11:34 (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 So we have this problem of being unable to build adequate specs.

11:34 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 that's the problem.

11:35 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 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 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 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 lpetit: Already what LLVM can accomplish given a codepath and some modules is _astonishing_.

11:43 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 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 * KirinDave salivates.

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 lpetit: Well the only type of static type checking really useful for errors is haskell's style.

11:48 lpetit: The java style is ultimately a red herring in error correctness.

11:49 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 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 * cemerick is talking entirely pragmatically, of course

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 (str (let [f "foo"] (reify Object (toString [] f))))

11:58 ,(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 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 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 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 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 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 if the default is UTF-8, at least one can rely on a fixed behaviour for reading non-ascii characters

14:51 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 </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 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 just start clojure with the correct classpath

14:55 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 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 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 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 raek: Wouldn't I need to in order to specify the jar files to include?

15:01 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 it

15:02 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 * chouser hasn't really dug into lein or maven yet

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 That's a big part of going with Clojure. That and I've always wanted to learn a lisp.

15:05 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 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 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 , (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 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 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 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 by end of summer some of that should be landing in jruby 1.6

15:13 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 something like this: ({:A 1} {:A 2} {:A 3} {:C 1} {:C 2})

15:14 to this: ({:A [1 2 3]} {:C [1 2]})

15:15 I tried:

15:15 , (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 , (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 Before anyone else. Even chouser. :)

15:24 Maybe when he's asleep.

15:24 chouser: Mmmm, sleep...

15:25 bartj: chouser: perhaps, I can run this?

15:25 (zipmap (keys {:C [1 2], :A [[1 2] 3]}) (map #(into [] (flatten %)) (vals {:C [1 2], :A [[1 2] 3]})))

15:26 , (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 i'm having trouble reading lisp / clojure code

15:27 my eyes don't know where to start at

15:27 in C++, I look from left to right

15:27 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 ,(+ 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 (reduce

15:29 #(merge-with

15:29 (partial conj [])

15:29 %1 %2)

15:29 [{: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 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 ,(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 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 is it possible / easy to implement a metacircular evaluator in clojure?

15:37 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 yes

15:45 trptcolin: codemonsta: jakemcc has gotten the furthest i know about

15:45 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 i suppose i'd really want to hack the compiler instead of the evaluator

15:51 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 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 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 but, it's acceptable if I have to

15:57 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 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 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 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 .net rocks much harder than the java library

16:02 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 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 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 well, we = me

16:06 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 chouser: Or maybe the average rubyist is just not getting what I was saying...

16:10 chouser: But I am seeing a lot of http://www.michaelharrison.ws/weblog/?p=303#more-303

16:10 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 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 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 They're the most difficult kind of relationship, requiring basically full knowledge of the underlying class.

16:22 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 _fogus_: Want to really get weirded out? Check out eigenclasses

16:23 cemerick: by quite a ways, yeah

16:23 I think the term is actually from the python side, no?

16:23 KirinDave: eigen?

16:23 Or monkeypatch

16:23 cemerick: monkeypatching

16:23 codemonsta: can / should one do simulation modeling in Clojure creating and extending structures?

16:23 '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 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 in C++, you'd have karen->GetPerson()->GetEntity()->GetPosition();

16:27 and that's really terrible

16:28 you could write forwarding methods at each level for each facet, but that's also terrible

16:28 not sure if clojure has the same issues

16:29 the alternative is automatic forwarding to implement is-a via has-a, and I don't recall what languages have that

16:30 * _fogus_ learned everything he knows about eigenclasses from MenTaLguY

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 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 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 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 I'm pretty angry at _why for nuking redhanded

16:35 it was a big part of our collective memory

16:35 codemonsta: the advantage of is-a is establishing semantic type relationships

16:36 has-a generally does not impose a type semantic

16:36 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 someone wiped a community code base?

16:39 KirinDave: MenTaLguY: I suspect it was designed as an elaborate prank.

16:39 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 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 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 not sure it's such a great language otherwise, but it does manage concurrency pretty well

16:45 codemonsta: ah, ya, actors

16:45 i prefer clojure's agents tho

16:45 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 well, cheap STM, anyways

16:49 bartj: I almost always use reduce where apply would suffice - I think

16:49 , (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 and is most likely more efficient

16:50 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 in the case of apply, you're just calling str with five arguments

16:50 in the case of reduce, you're calling str four times

16:51 (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:52 * MenTaLguY wonders if this is a FAQ

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 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 zeromq or something

16:57 (I forget if that has clojure bindings)

16:58 actor/reactor pattern I guess

16:58 agents are more about mobile data in a way

16:58 with agents, you take the code to the data

16:58 with actors etc. you take the data to the code

16:58 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 that kind of thing also

17:00 I guess also things like the big implementations of MapReduce

17:00 in those cases you're basically farming out your map/reduce functions to where the data lives

17:01 the essential thing, though, is that if you want concurrency/parallelism, you have to farm things out to multiple physical places

17:01 whether multiple cores or nodes on a network or whatever

17:02 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 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 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 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 Clojure has one of the best STM implementations I've ever seen

17:10 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 But as an actual solution, it's really not applicable.

17:11 MenTaLguY: pretty much

17:12 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 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 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 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 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 Specifically, regarding libs.

17:29 `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 Urgh, never mind... this is just CCW getting itself into a bad state.

17:31 Project -> Clean fixed it.

17:31 (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 and byte too?

17:40 TimMc: Anyone here use Eclipse + CCW?

17:40 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 1) I want to run my core.clj file, which launches a ring server.

17:42 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 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 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 an exception is being thrown

17:50 in the function

17:52 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 perhaps its doing (str "something" "here") internally

17:54 korre: println also adds spaces

17:54 ,(println "hej" "world")

17:54 clojurebot: hej world

17:55 onkara: yes it does

17:56 how do I configure contrib-logging to use log4j

17:56 or rather how do I find which logging system it is using ?

17:57 korre: im nott a java land guru :p

17:57 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 close

17:58 BTW how does clojure perform on .net

17:58 ?

18:05 korre: seams it uses the first login system it can find

18:06 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:08 * riddochc has belatedly decided on some answers for the poll on the ml...

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 gtg

18:35 mmarczyk: riddochc: I don't agree at all

18:37 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 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 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 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 that's about HtDP, of course

18:41 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:00 * riddochc is waffling between emacs and vim.

19:00 * riddochc ducks from ensuing flamewar. ;)

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 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 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 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 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 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 er.. a couple

21:51 Raynes: defn: However, the "Once you go Emacs, you never go back." remark was just a joke.

21:52 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 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 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 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 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 But that's just me.

21:55 Let's not turn this into an argument. :p

21:55 <3

21:57 * Raynes just discovered M-.

21:57 Raynes: :D

21:59 lancepantz: what is that editing the definition of?

21:59 (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 I couldn't find a function a minute ago.

22:00 So SLIME found it for me.

22:00 :D

22:00 tomoj: e.g. M-. on defn brings you to core.clj

22:00 lancepantz: oh, wow

22:00 that' is awesome

22:01 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 but it's not interactive and not bound

22:09 lancepantz: i see

22:10 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 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 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 it does work in the repl if i use the ns

22:17 tomoj: I know

22:17 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 have you compiled the functions you're testing with?

22:18 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 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 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 fwiw

22:25 Raynes: Cool.

22:25 lancepantz: yeah

22:26 tomoj: didn't know that, thanks

22:26 and it's a stack, nice

22:26 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 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 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 strangely the macroexpansions I see there are uglier now than they used to me

22:29 be

22:30 defn: cool

22:30 im not sure how ill use that

22:31 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 C-c M-p is kind of a handy one FWIW

22:33 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 whoa..cool

22:34 what else can you do with ,*

22:34 tomoj: defn: ,h for example :)

22:37 never tried +p and -p before, cool

22:40 codemonsta: I'm going to invent the next mainstream programming language

22:40 it will use MOP

22:40 'Mort-Oriented Programming'

22:40 it will make stupid things easy and smart things impossible

22:41 lancepantz: oh, like lein

22:41 sorry, sorry

22:41 codemonsta: hehe

22:41 defn: cool

22:41 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 i want to decouple the client-side part of walton from the server-side stuff

22:45 and ive never built anything like that before and am kind of clueless as to where to start

22:45 i want people to be able to query my server and get example data

22:45 from the client-side

22:45 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 our front end is rails

22:46 defn: yeah you mentioned some code a week ago

22:46 anything go online yet?

22:46 <-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 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 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 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 i feel that others find that it's just too arcane for them or something

23:12 i sympathize with them because it took me a good 4 months to even understand how to think functionally

23:13 i looked for definitions of FP and of course found all sorts of crazy ideas on what FP is truly

23:13 i think the whole "no side effects" thing is totally misunderstood at first by a lot of OOP programmers

23:14 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"...

Logging service provided by n01se.net