#clojure logs

2011-09-01

00:00amalloygaze__: you don't really need to model state very often. ring, for example, is basically the only webserver anyone uses, and it's side-effect-free unless you introduce your own side effects
00:01gaze__so it's probably time to rethink my problem.
00:02amalloygaze__: for example, ftp is a pretty interactive medium, but you can describe what you want to do "all in one go" before you connect
00:03amalloy(-> "myserver.com" (connect) (commands [:cd "/tmp"] [:ls (fn [filenames] (doseq [n filenames] (println n)))])
00:04solussdwhat is the reason (google didn't help me here) that (meta my-macro) doesn't work, but (meta #'my-macro) does?
00:04solussd,(meta cond)
00:04clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/cond, compiling:(NO_SOURCE_PATH:0)>
00:04solussd,(meta #'cond)
00:04clojurebot{:macro true, :ns #<Namespace clojure.core>, :name cond, :arglists ([& clauses]), :added "1.0", ...}
00:04sridamalloy: this doesn't overflow http://dpaste.com/606448/
00:05amalloy&(meta first)
00:05lazybot⇒ {:line 53}
00:05amalloy&(meta #'first)
00:05lazybot⇒ {:ns #<Namespace clojure.core>, :name first, :file "clojure/core.clj", :line 48, :arglists ([coll]), :doc "Returns the first item in the collection. Calls seq on its\n argument. If coll is nil, returns nil.", :added "1.0"}
00:06sridbut that looks ugly; thinking ...
00:06amalloysrid: right. now that you've written it in a correct and fast way, consider ##(into () (range 5))
00:06lazybot⇒ (4 3 2 1 0)
00:07sridinteresting, but doesn't work with vectors ##(into () (vec (range 5)))
00:07lazybot⇒ (4 3 2 1 0)
00:07sridwhat
00:08amalloygaze__: you see what i mean? instead of modeling state at the API level and making the user deal with it, you have them pass "continuation/response" functions for commands that they might need to decide what to do after
00:08gaze__yeah, that does make sense.
00:08srid##(into [] (range 5))
00:08lazybot⇒ [0 1 2 3 4]
00:09sridamalloy: ok, though I was doing the recursion exercise from http://www.cis.upenn.edu/~matuszek/cis554-2010/Assignments/clojure-01-exercises.html
00:09amalloyyou're still left with the problem of how to manage state, but it's hidden from the user and you can work it out in whatever ugly way you like
00:09amalloysrid: which is why i made you fix it before i gave you the easy answer :)
00:09sridthat's good then
00:12sridamalloy: now i compresed it down to http://dpaste.com/606454/ and I feel good about myself
00:12amalloysrid: now compress it some more, using loop instead of multiple arities
00:13solussdamalloy: so what's the {:line 53} output?
00:14amalloysolussd: how much do you understand about vars and metadata?
00:15sridamalloy: http://dpaste.com/606456/ - i like the multiple arities version, though.
00:16solussdvars hold references to objects and metadata is data about a var? I know both clojure books I read gloss over vars as if it isn't an important topic. :/
00:17amalloyvars are important, but you're not really wrong about them
00:17amalloywhat you're wrong about is metadata: metadata is data about an object
00:17amalloy&(map class [#'first first])
00:17lazybot⇒ (clojure.lang.Var clojure.core$first)
00:17solussdattached to the var though, right?
00:18amalloysolussd: *shrug* metadata can be attached to anything
00:18amalloywhich is why (meta first) returns one thing, and (meta #'first) returns another
00:18amalloythey both have metadata; what you get depends on who you ask
00:19amalloythe data created by defn is attached to the var, not the function
00:19solussdok. so why is there metadata for a var referencing a macro, but not the symbol for the macro itself (I know that is the wrong way to say that)
00:20amalloythe macro itself is not a thing. it is not an object; it only exists in the sense that when the compiler sees its name it goes and looks up some code
00:20solussdthat makes sense- and defmacro adds metadata to the var then?
00:21solussdso, why does (meta myfunction) work?
00:21amalloybecause functions *are* things, *are* objects
00:21amalloy&(let [x map] (x inc [1 2 3]))
00:21lazybot⇒ (2 3 4)
00:21amalloy&(let [x and] (x inc [1 2 3]))
00:21lazybotjava.lang.Exception: Can't take value of a macro: #'clojure.core/and
00:22amalloy(meta some-fn) only "works" in the sense that there's no error. you still don't get the docstring
00:23solussddoes fn add metadata to the object it creates?
00:24amalloytry it and see
00:24solussdyes. :D
00:25amalloynot much, though, right? ##(meta (fn []))
00:25lazybot⇒ nil
00:26solussdok. var re-cap. A var can reference an object. A symbol can name a var. When a symbol is resolved you get the value of the var it refers to. #'something returns the var that the symbol something refers to.
00:27amalloysounds good
00:27solussdguess you never worry about the distinction between a symbol and a var[iable] in, say, C, because you compile. :D
00:28amalloynothing to do with having to compile
00:29amalloythe reason you don't worry about the distinction is you don't have the power to introspect source code. symbols have no value for C programmers; what could you do with them?
00:30solussdthat makes sense
00:30sridI bet there is no TCO version for flattening a list - http://dpaste.com/606461/
00:31amalloysrid: correct, that's impossible
00:31solussdI keep getting this feeling that lisp/clojure would have made a lot more sense early on had I never been exposed to C/C++/etc- that it would have been easier to learn too.
00:32solussd*(than c/c++)
00:32amalloy(except by implementing your own version of a stack, stored on the actual heap)
00:36sridseq can't be destructured in a loop?
00:36sridn/m, i was using loop in place of recur
00:40sridi'm close to implementing a TCO version of flatten, debugging a bug ...
00:43amalloythe bug that it's impossible? (though of course see my point about reimplementing the stack yourself)
00:45sridamalloy: http://dpaste.com/606486/
00:46amalloysrid: that's not what's generally meant by "flatten". what do you expect it to return for the input [a [b [c d]]]?
00:47amalloyeg, compare to the flatten in clojure.core: ##(flatten '[a [b [c d]]])
00:47lazybot⇒ (a b c d)
00:47sridsame
00:48sridI used list, instead of vec.
00:48sridamalloy: try running it (with lists, not vec), works for me.
00:49amalloyhm
00:50sridan interesting exercise is to compare this with core.clj's tree-seq based implementation.
00:51sridi'm not sure about the algo. complexity of `concat`. it returns a seq, so doesn't construct a new list. but still, wondering how efficient it (and its later lookups) are.
00:52amalloyi see. the stack is hidden inside of concat
00:52sridah
00:58amalloyi can't figure out an input to break it, though, so i might be wrong
01:06sridi really need to understand more of how seq's work under the hood.
01:09amalloysrid: http://people.csail.mit.edu/meyer/6001/FT97/psets/ps9/ps9.ps seems to be all about implementing a tail-recursive flatten, and it does so with an explicit stack. i *think* this supports my claim that you need a stack, but i need to think more about it
01:10amalloyeither way you would probably find it interesting
01:10sridthanks
01:11sridthat link is down?
01:12amalloyit worked two minutes ago
01:12amalloyand works for me now
01:13sridtimes out for me, always. i have access to the google cache, though.
01:13amalloyweird. maybe your client can't...handle postscript files...? this sounds bizarre even as i say it
01:14sridconnection to people.csail.mit.edu|128.30.2.148 times out. i'll try from work. ok, really off to bed.
01:16amalloyyes, lst is your stack of "items to be processed"
01:17amalloyneat implementation, anyway
02:41amalloyamcnamara: you around?
02:50amcnamaraamalloy: yep
02:50amalloyamcnamara: i was just about to push a new version of 4clojure, and saw you've been making some changes. anything that you want to be pulled in?
02:51amcnamaraI sent off a pull request ~30 minutes ago, I think you were copied on it... though I'm not too familiar with github's pull system.
02:52amalloyoh man, two pull requests in the last hour, apparently
02:52amalloyi was CC'd, but it doesn't forward my notifications to my email. i wonder if i disabled that myself
02:52amcnamaraahh
02:52amalloyoh never mind. the other pull request was on some other project
02:53amalloyif you're going to do much developing (sounds like you want to), you should join us in #4clojure
02:54amcnamaradone, didn't know there was a channel
02:54amcnamara:)
02:54amcnamarayeah, I think 4clojure is great.
03:22michaelr525hello!
03:54michaelr525http://acooke.org/cute/Optimising1.html
03:54michaelr525Interesting stuff..
04:23roger_I want to create a string from a list containing two characters. I don't get what's wrong with (apply str (\a \b))
04:25roger_It gives the same casting error as (str (\a \b))
04:25dbushenko(\a \b) -- is a function
04:26dbushenkofunction \a with parameter \b
04:26dbushenkoyou should use (apply str \a \b)
04:27dbushenkosorry, (apply str [\a \b]) -- like that
04:28roger_OK, or use (apply str '(\a \b))
04:28dbushenkoyep
04:28roger_Thanks!
04:30dbushenkonp
04:36amalloyroger_: make sure you understand the difference between [a b] and '(a b) though
04:36amalloybecause it's pretty important
04:37roger_but: (= [\a \b] '(\a \b)) gives true?
04:37amalloytry it for something that's not a constant
04:37amalloy&(let [a 1, b 2] {:quoted '(a b) :unquoted [a b]})
04:37lazybot⇒ {:quoted (a b), :unquoted [1 2]}
04:40roger_amalloy: euh, I'm just reading chapter 2 of 'programming clojure', I'm not yet familiar with let and &.
04:41amalloywell, & is just to get lazybot to sit up and take notice
04:41amalloyconsider this instead
04:41amalloy,'((+ 1 2) 3)
04:41clojurebot((+ 1 2) 3)
04:42amalloy,[(+ 1 2) 3]
04:42clojurebot[3 3]
04:42roger_what's the difference between clojurebot and lazybot?
04:43roger_&'((+1 2) 3)
04:43lazybot⇒ ((1 2) 3)
04:43amalloynot much. i just hoped you'd find , less distracting than &
04:43roger_&'((+1 2) 3)
04:43lazybot⇒ ((1 2) 3)
04:44amalloywhoa, that doesn't look right at all. is that a bug in lazybot?
04:44roger_&[(+ 1 2) 3]
04:44lazybot⇒ [3 3]
04:44amalloy&'+1
04:44lazybot⇒ 1
04:45amalloy&(read-string "+1")
04:45lazybot⇒ 1
04:45amalloy&(read-string "(+1)")
04:45lazybot⇒ (1)
04:45amalloy,(read-string "(+1)")
04:45clojurebot(1)
04:45amalloy,+1
04:45clojurebot1
04:45amalloy,'(+1)
04:45clojurebot(1)
04:45amalloywhy on earth isn't +1 a valid symbol?
04:46amalloyat any rate, roger_, you should be putting a space between + and 1
04:46amalloybut i'm surprised it broke in this particular way, instead of a different way
04:48roger_oh right, I was trying to type to quickly
04:49roger_I like the => in lazybot's answer better
04:50amalloy$mail Raynes someone likes the arrow!
04:50lazybotMessage saved.
04:51amalloy,'a1
04:51clojurebota1
04:51michaelr525what's the difference between ,( and &(?
04:52michaelr525,1
04:52clojurebot1
04:52michaelr525&1
04:52lazybot⇒ 1
04:52michaelr525except the arrow :)
04:52Fossiit's two bots
04:52Fossithey can do different things
04:52michaelr525ah, right
04:52Fossialthough for & and , they are mostly the same
04:53michaelr525ah
04:53raek,(println "&(+ 1 2)")
04:53clojurebot&(+ 1 2)
04:53lazybot⇒ 3
04:53raekouch.
04:53Fossidon't know if they use the same sandbox though
04:53michaelr525hehe
04:53Fossilol
04:53michaelr525think of the possibilities
04:54Fossiyou can't make one of them spam, but both :D
04:54michaelr525hmm, maybe someone can add a spell checker to one of the bots?
04:54raek$mail Raynes lazybot shoould probablly ignore clojurebot to avoid bot feedback loops
04:54lazybotMessage saved.
04:54amalloyraek: i dare you
04:55amalloyclojurebot can't hear lazybot because of lazybot's ⇒
04:55amalloy(which afaik is the only reason ⇒ is there)
04:55raekyup.
04:55michaelr525too bad, it could have been funny
04:55amalloyraek: mind if i delete your $mail?
04:55amalloysince that is in fact not needed
04:55raekamalloy: sure
04:55amalloy$login
04:56lazybotYou've been logged in.
04:56raekgo ahead
04:56amalloy$unmail raek Raynes
04:56lazybotDeleted unread messages from raek to Raynes
04:56amalloy$logout
04:56lazybotYou've been logged out.
04:56amalloymichaelr525: the person who can add a spell checker is YOU. though tbh i'm not really sure how you would use it?
05:02amalloymichaelr525: https://github.com/flatland/lazybot/wiki/Plugin-quick-start-guide if you're interested in contributing
05:07michaelr525sure, I'm interested, I just have to put my work and family adside for a while ;)
05:08amalloyokay, i was about to go to bed but i realized "+1" is just the number one with a "positive" sign in front. that's why they're parsing as 1
05:09amalloyso eg ##'-+1 will parse just fine as a symbol
05:09lazybot⇒ -+1
05:09amalloynight
05:09roger_and dream on!
05:16michaelr525It's noon here
05:16michaelr525Although a nap would be just fine :)
05:43wunkisomeone willing to help me out with the following compojure route: https://gist.github.com/7a23e06ad21d43710701
05:43wunkishouldn't in the above code, the `user` parameter get populated with the `user` from the request map?
05:56rata_hi
05:56rata_in enlive, how do you select a td tag that doesn't have a child a tag?
06:15rata_I did it! =)
06:17dbushenkowunki, probably -- no
06:18dbushenkoyou have to add :user to the route
06:21nizzeHi!°
06:21nizzeI was reading about defmulti and defmethod and I already know about pattern matching
06:22nizzeWhat is the real difference between multiple dispatch and pattern matching
06:22nizze?
06:26thorwilnizze: i guess it's free-form do it all yourself vs having a decision tree written for you
06:27nizzeSo multiple dispatch is superset of pattern matching?
06:28thorwili think they are orthogonal
06:32nizzeThanks!!
06:35thorwilnizze: looking at the examples at https://github.com/swannodette/match might give you a better idea of what pattern matching is
06:36thorwil(elsewhere you would have to deal with the syntax of languages like erlang or haskell)
06:51wunkidbushenko: but I have the signed in user in the request map, I really need it from there.
07:34khaliGman Joy of Clojure is one disappointing book so far.. i've halfway through have learnt nothing, except perhaps boredom
07:35dbushenkokhaliG, You've started with the wrong book
07:35dbushenkoJoC is an excellent book for advanced clojure programmers
07:35dbushenkoit's not for beginners
07:35khaliGdbushenko, and i've yet to come across anything advanced
07:36khaliGseems a waste of 150 pages when it hasnt got hard yet??
07:36lazybotkhaliG: Definitely not.
07:36dbushenkoJoC discovers many subtle thins which you'll not find in any clojure book
07:37khaliGdbushenko, hmmm. hopefully the latter half is more interesting :/
07:37dbushenkowhere did you stop?
07:38khaliGi'd have to check the bookmark, haven't got it handy
07:40khaliGdbushenko, but to be fair i should finish it first :)
07:40dbushenkoto my personal mind, Practical Clojure and Clojure in Action -- are the books to start
07:41dbushenkoJoy of Clojure is good when you want to extend your knowledge on the topics which you already know
08:52gtrak`what's the best idiom for mocking stuff with 1.3's dynamic var change? It seems dirty to change the source code for the sake of the tests... akin to having fields/methods be protected when they should really be private
08:53chousergtrak`: with-redefs
08:54gtrak`oh, wow
08:54gtrak`how's that different from binding?
08:54gtrak`in 1.2?
08:55chouserwith-redefs changes the root binding, so the new value is visible in all threads
08:56chouserwhich is (a) better for tests because it worths with things like pmap where binding didn't and (b) doesn't require the var be dynamic.
08:57gtrak`well that's better overall, I'm surprised all the places i've read that talk about vars requiring dynamic don't mention it
08:57chouserkhaliG: Sorry you're disappointed with the book. How long have you been using Clojure? Do you have background in other Lisps or functional languages?
08:58chousergtrak`: JoC p. 299 :-)
08:59gtrak`oh :-)
08:59gtrak`I've read the var chapter, it wasn't in there :-)
09:00chouserah. Actually, with-redefs didn't exist when we were wrote the Var chapter.
09:00chouserIt didn't exist when we wrote the testing chapter either, so we wrote it for the book and then Clojure 1.3 took it as well.
09:02khaliGchouser, I spoke too soon, i'll give more useful feedback once i've finished reading. To answer your question, I've got about 2-3 months of experience writing clojure and i'm coming from a CL background
09:03chouserkhaliG: Hey, if you can't speak your mind on IRC, then what's it good for? :-)
09:05chouserkhaliG: If you haven't dug very deepling into persistent collections yet, I could hope chapters 5 and 6 and perhaps 10 and 11 might have some useful bits for you.
09:05chouser s/deepling/deeply/
09:09gtrak`always impressed by how pliant the core language constructs are, lisp is cool
09:16khaliGchouser, excellent :)
10:07rindolfHi all.
10:07jolyhello
10:08rindolfWhen I run the program in http://clojure.roboloco.net/?p=703 it prints the "Elapsed time" thingy and then takes a lot of time to exit. htop shows that it has several threads running on 0% CPU. I'm on Mageia Linux 2 (CAuldron). Why does it happen?
10:09rindolfjoly: hi.
10:09manutterrindolf: do you need to call shutdown-agents or something?
10:09rindolfmanutter: don't know.
10:10manutterI remember hearing something about that, but I don't recall the exact details
10:11rindolfmanutter: yes, now it exits immediately after printing the elapsed time.
10:11manutter:)
11:04tsdhCan someone explain me this compile error? http://pastebin.com/cKzGwcg5
11:07tsdhThe protocol defines exactly those methods, and I've already extended it to some java types before. For that record, I simply want to delegate the resolving stuff to the graph (one of those java types).
11:18hugodtsdh: I think you have to specify each overload as a separate sexpr
11:20tsdhhugod: Really? It would be strange if the syntax varies between `extend-protocol', `extend-type', and `defrecord', but I'll try it...
11:22tsdhhugod: You are right.
11:24hugodtsdh: it is also assymetric with the defprotocol syntax - I always end up getting the syntax wrong for this
11:24Mike|homeSo here's what gets me about Clojure. I still don't get how abstractions are built. Yeah, namespaces are cool, but objects just feel so -right-, you know? Is it normal to think like that or am I just being whiny?
11:25HET2Mike|home: objects are not so much about abstraction as they are about encapsulation
11:25RaynesIt's normal at first. You don't 'get it' immediately.
11:25RaynesAt least, not if you're human.
11:26RaynesI got it immediately because I'm a robot.
11:26Mike|homeI think I disagree HET2. I think they're useful for both.
11:26tsdhhugod: Well, once you know it...
11:26HET2Mike|home: that's not my opinion, it's Alan Kay's opinion, the guy who invented the OOP paradigm
11:26Mike|homeHm.
11:26HET2Mike|home: classes are all well and good but OOP is about objects not so much about types
11:27Mike|homeI guess I disagree with the big man, then.
11:27Mike|homeThat makes sense, yeah.
11:27HET2Mike|home: in fact I have been finding that thinking about types when you program is usually less flexible than ignoring them
11:27Mike|homeSo then what's Clojure's take on building abstractions and encapsulating data, HET2?
11:27chouserMike|home: "objects" in OOP are a giant bundle of features that turn out to be essentially unrelated to each other.
11:28HET2Mike|home: that said, nothing keeps you from using OO in a lisp
11:28Mike|homechouser: That sounds a bit biased. That's bad OOP programming
11:28chouserClojure provides most of those features unbundled from each other so you can take what you need.
11:28raekencapsulation can be obtained by functions closing over locals
11:28Mike|homeI think good objects are clean cut, short sections of the domain languages
11:28Mike|homeLanguage, rather*
11:28HET2raek: yeah but then you end up with #(lambda) that you know nothing about
11:28Mike|homeraek: That's really interesting. I never thought of it like that.
11:29Mike|homechouser: What are some of those features?
11:29HET2Mike|home: thats the whole point of lisp dialects ;)
11:29Mike|homeHaha, okay.
11:29Mike|homePretty new to Lisp, so yeah excuse the lack of uh.. Lisp culture.
11:29HET2hence naming Clojure Clojure I suppose...
11:29HET2Mike|home: of course my opinion is worth exactly what you pay for it
11:30chouserMike|home: the features are hard to name, but I'll try. again. :-) ...
11:30raek(defn make-counter [init] (let [state (atom (dec init))] (fn [] (swap! state inc))))
11:30gtrak`Mike|home, http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html
11:31Mike|homegtrak: I think I read this a long time ago..
11:31HET2raek: eeek ! modifiers
11:31Mike|homeI think its time to read it again. Haha.
11:31gtrak`it's pretty awesome :-)
11:32HET2Mike|home: of course when you insist on explicitly modifying state you loose the parallelizability benefits that functional programming gives you
11:32Mike|homeI don't think that having a nice construct for encapsulation and abstraction implies mutability.
11:32raekHET2: a name ending in ! usually means that the function has a side-effect that will not be controlled by the transaction system
11:33raek(but not all these functions have a name ending in !)
11:33coopernursehey folks. we've been having a discussion about session implementations on the clj-noir group.
11:33gtrak`Mike|home, of course it implies mutability, what else would be encapsulated? if it's not mutable, then a static function is just as good
11:33chouserIn OOP an object is how you do: a single function, a group of related data (a value), a group of related functions, inheritence, data hiding (encapsulation), an identity (container for mutable data), etc.
11:33HET2Mike|home: the very essence of objects as in object orientation is that you encapsulate mutable data
11:33coopernurseseems like ring doesn't have a built in session store that uses the HttpSession, which is sort of what you'd want in any sort of clustered environment (e.g. GAE or a cluster of tomcat/weblogic servers)
11:33coopernurseso I wrote one here. comments welcome.. I may issue a pull request to the ring project for this. https://github.com/coopernurse/votenoir/blob/master/src/votenoir/httpsession.clj
11:34chouserMike|home: Clojure provides every one of those things, but discretely so that when you see a thing, you can tell what it's being used for.
11:34Mike|homechouser: Sounds like you're hinting at language features. Where can I find them?
11:34chouserIn Clojure a single function is just that, no need for an object instance around it.
11:34Mike|homeRight.
11:35chouserA group of related data can be a map, vector, set, record instance, or type instance.
11:35Mike|homegtrak`: Always seemed to me that an object, even if its immutable, is still good because you can package data with its respective functions.
11:35HET2Mike|home: not a language feature
11:35coopernursegtrak`: thanks for the link, that Yegge post is interesting
11:35chousera group of related functions can be a namespace or a protocol.
11:35Mike|homeHah, HET2, well now I'm very confused. :)
11:35HET2Mike|home: the language itself is quite slim in lisp dialects
11:36HET2Mike|home: because the language is flexible, paradigms are implemented ontop of it
11:36Mike|homeMakes sense so far, chouser.
11:36chouserinheritence can be done with multimethods or protocols
11:36Mike|homeAre multimethods like multiple arity?
11:36chouserdata hiding can be done with private vars in a namespace, or closed-over values in a function
11:36chouseridentity is done with refs, atoms, agents, or dynamic vars
11:36Mike|homeOkay, still sounds pretty sane.
11:37HET2Mike|home: maybe you should have a look at SICP and/or brian harvey's CS61A lectures on youtube
11:37jolymultimethods allow multiple dispatch, and even arbitrary dispatch
11:37HET2Mike|home: it's scheme but a lot of what he teaches holds for any lisp
11:37raekMike|home: methods in OOP let you do different things depending on the type of the object, multimethods let you do different things depending on any property (type, value or anything) of any of the parameters
11:37Mike|homeHET2, obviously I'd get something out of it. But what do you think that I'm just 'not getting'?
11:38Mike|homeIf that made sense, heh
11:38HET2Mike|home: closures ;)
11:38chouserSo for each of these categories, Clojure provides more than one option with various tradeoffs. It provides a vocabulary for thinking about design problems that's not really possible when you lump all of those categories into a single idea of "an object"
11:38Mike|homeHET2: Got'cha :)
11:38HET2Mike|home: in most oop languages they are treated as a bastard child
11:38Mike|homeI guess I understand what they -are-, but now how they're used in the wild.
11:38gtrak`very little of all this stuff is actually a language feature though, it's built on top of functions, macros, etc...
11:39HET2Mike|home: the idea is that you treat functions as data and vice versa
11:39Mike|homeThis is all very interesting
11:39Mike|homeHET2: Yeah, I understand that.
11:39HET2Mike|home: well that's the core difference between lisp and c ;)
11:39gtrak`functions are just objects after all
11:39Mike|homeObjects without data?
11:39gtrak`they can have data
11:40gtrak`think of a beefed up anonymous inner class
11:40Mike|homePassed as parameters only though, right? Unless its a closure
11:40HET2Mike|home: C++ and java are just not very object oriented. have y ou done any smalltalk?
11:40gtrak`yes
11:40Mike|homeI haven't, HET2.
11:41HET2Mike|home: in an OOP language theoretically everything is an object. the number 1, a method and an object which has a state and selectors are all objects
11:41HET2Mike|home: in c++/java that radicality has been abandoned for performance or so they say
11:41chouserthe content of this conversation is actually why we wrote JoC -- to comrehensively answer the question "so what?"
11:41Mike|homeHET2: Yeah, I've heard that too
11:41HET2chouser: would you mind expanding JoC
11:41Mike|homeWhat's JoC?
11:41joly"Actually I made up the term 'object-oriented', and I can tell you I did not have C++ in mind." -- Alan Kay
11:42HET2joly: ;)
11:42gtrak`smalltalk is about message-passing, which implies late-binding
11:42HET2gtrak`: one could argue OOP is about message passing and late-binding
11:42raekJoC = Joy of Clojure, chouser's and fogus's book
11:42jolyThe Joy of Clojure, a wonderful book I'd highly recommend
11:43HET2joly: thx
11:43gtrak`HET2, but also the polymorphism is limited in java/C++
11:43gtrak`in clojure you can dispatch based on any function of the arguments, instead of just the type of the first
11:44HET2gtrak`: further up in your chat buffer i argued against type systems ;)
11:44Mike|homeI'll check it out :)
11:44HET2gtrak`: or at least ones that are part of the language
11:44gtrak`types are just strings, a virtual lookup is just a hash lookup
11:45HET2gtrak`: the use for types in java/c++ is to enforce discipline and to allow optimization
11:45HET2gtrak`: which makes the language less flexible and more verbose imho
11:45gtrak`agreed
11:45gtrak`I learned C, C++, java, clojure in that order
11:47gtrak`HET2, the jit is plenty fast, and you can still get the performance in clojure with records and protocols
11:47gtrak`but you don't have to enforce it on people
11:48zippy314,(+ 1 1)
11:48clojurebot2
11:49gtrak`in java you'd have to pay for doing something unconventional by writing a lot more code
11:54zippy31415,(+
11:55clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
11:55zippy31415,(+ 2 3)
11:55clojurebot5
12:37icey For those of you deploying websites built in Clojure: how do you profile your applications?
12:38coopernurseicey: I haven't done any hard core profiling yet. what level of detail are you looking for? like which URLs are slow, or low level profiling metrics about function execution times?
12:39arohnericey: I use visualvm
12:39arohnerit's not amazing, but it's free and works well enough
12:39iceycoopernurse: Right now I'm mostly concerned with the first issue - just knowing what my general execution times for a url look like
12:39iceyarohner: checking it out now, thanks
12:40arohnericey: for URL execution times, I'd just use (time) in a middleware
12:40iceyarohner: Is it pretty straightforward to translate what visualvm reports to specific locations in your code?
12:40coopernursearohner: that's a good suggestion.
12:41coopernursewhat I've also done in the past is put my java app server behind nginx, and configured nginx to log request times in the access log (apache can do something similar)
12:41arohnericey: yes
12:41clojurebotTitim gan éirí ort.
12:41arohnerI use the sampler, which gives slightly less accurate results, but doesn't take 5 minutes to recompile everything
12:41Raynesclojurebot = multilingualbot
12:42iceylet's say you discover a route that performs strangely; 80% of the time it's fast, but sometimes it really bogs down. What are the troubleshooting / tracing steps you take - attach visualvm to the production JVM you're running and watch for the hiccups?
12:42icey(sorry, i'm new to the jvm ecosystem; so i don't have any java background to transfer over :|)
12:43arohnerI haven't seen much of that (non-determinism), but yeah, I'd start with visualvm
12:43arohnerit has a monitor to tell you how much CPU time is spent, how much time GC'ing
12:44arohnerit's not very good at telling you the individual times for each URL hit
12:44arohnerwhat kind of performance hit are you seeing?
12:44iceyarohner: I just picked a random scenario. To be honest, my biggest concern is doing something suboptimal when I write code since I'm new to Clojure, and I'd like to be able to profile everything to make sure I'm not shooting myself in the foot :)
12:45arohnerthe hardest part about profiling is knowing what the results *should* look like
12:46arohnerIs 1M ops/second fast? I don't know, unless I've seen it do 5M ops/second before
12:47iceyarohner: that's a pretty good point. i have a habit of trying to measure everything to get a feel for how things ought to look. it may not be a good habit, but its' been informative for me in the past
12:47arohnericey: it's certainly better to measure than to not measure :-)
12:48iceyi don't have a formal cs background, so i end up learning things as i need them... but first i have to discover that i need them :)
12:48coopernurseicey: if you're using mysql, the slow query log is very useful
13:25gtrak`icey, write clean idiomatic code, then measure, then make it faster as neede
13:55TimMcHey, I just thought of a possibly good reason for macros to not be pure functions.
13:56TimMcWhat if you had a logging or assertion macro that checked a configuration file to see whether it should drop in the relevant calls?
13:57amalloyTimMc: that's how clojure.core/assert works
13:57amalloy(it checks a var binding, not a file)
13:57TimMcnice
14:08S11001001if you make all your functions return sequences and wrap their bodies with lazy-seq, they'll all return really fast :)
14:10TimMcS11001001: Look how fast I can create an infinitely long data structure! ##(time (range))
14:10lazybotExecution Timed Out!
14:10TimMcOh bother, it's trying to print it.
14:10TimMc##(= (time (range)))
14:10lazybot⇒ "Elapsed time: 0.489627 msecs" true
14:13S11001001impressive speed
14:13S11001001which would put clojure's infinite loop time faster than Linux's
14:14TimMcLinux's?
14:14phenom_,(take 10 (range 1 1000))
14:14clojurebot(1 2 3 4 5 ...)
14:14S11001001(5s, according to Torvalds)
14:15phenom_,(take 2 (range))
14:15clojurebot(0 1)
14:15phenom_,(doc time)
14:15clojurebot"([expr]); Evaluates expr and prints the time it took. Returns the value of expr."
14:15phenom_(time (+ 1 2))
14:15amalloychouser: i read "Clojure provides every one of those things, but discretely" as "discreetly" the first time, and surprisingly it still made sense. "Hey, y'know, if you need X it's over here. Don't get all excited about it, people might be watching."
14:15phenom_,(time (+ 1 2))
14:15clojurebot"Elapsed time: 0.085 msecs"
14:15clojurebot3
14:34gtrak`,(time (+ 1 2))
14:34clojurebot"Elapsed time: 0.084 msecs"
14:34gtrak`,(time (+ 1 2))
14:34clojurebot3
14:34clojurebot"Elapsed time: 0.082 msecs"
14:34clojurebot3
14:34gtrak`keeps getting faster
14:34manutterpractice makes perfect
14:35Raynesraek: That isn't really necessary. If a feedback loop is possible, I generally consider it a bug that needs to be fixed.
14:37amalloydamn it, Raynes, i $unmailed that. stupid lazybot, did you not delete it??
14:37lazybotamalloy: What are you, crazy? Of course not!
14:38Raynesamalloy: It certainly wasnt unmailified.
15:05turbofailis there any standard function for merging a set of sorted sequences?
15:06wabashA question that probably has been asked before: If I understand FP decently enough, how difficult/impossible is it (and/or is it a bad idea?) to take my codebase in Java, and transform certain parts to clojure?
15:06wabashalready, in java, there are places I use more FP style stuff, like java's pseudo-closures, and recursion.
15:07technomancyturbofail: maybe into?
15:07technomancyturbofail: since each sorted thing can have its own sort function you need to specify which to use
15:08turbofailthey're not mappings, they're just sequences
15:08amalloywabash: there exist libraries for functional programming in java, and you can do functional-oriented stuff without them, as you've noticed
15:08wabashYes indeed.
15:08amalloya lot of the benefits you don't get to keep, though, in a mutable-by-default setting
15:09turbofaillike the input to the merge function of a merge sort
15:09nizzeHi! I'm learning clojure & compojure. My project has these listed as deps: clojure, contrib, compojure, lein-ring. When I do lein deps it's pulling huge amount of stuff.
15:09amalloyturbofail: it's pretty rare to want to do that outside of an actual mergesort
15:10nizzeMost of which seems to be Java. Why?
15:10amalloyring depends on it
15:10amalloyor compojure does
15:10wabashamalloy: It's partly this: The codebase I have does stuff that may or may not be amenable to rewrite in clojure from scratch. I simply don't know because I don't know clojure that well. But certain parts of it map very nicely to FP paradigms, and I'm kinda shoehorning them into FP even though they are java.
15:10technomancyturbofail: (into (sorted-set-by #(mod % 12) [...]) (sorted-set-by even? [...])) ; is going to be different if you swap the order of the args
15:10nizzeYeah, that I inferred. But why do they have such a huge amount of deps?
15:10wabashamalloy: Are you saying this: if I mix clojure and java, the immutability of Clojure goes away?
15:11amalloywabash: i think i answered a question you didn't ask
15:11amalloyyes
15:11wabash:)
15:11technomancyturbofail: oh... never mind; I see what you mean
15:11amalloynizze: 4clojure is a pretty simple website, and its lib/ directory has 50 jar files
15:11technomancythe seq has been sorted, not that the seq is inherently sorted
15:12turbofailyeah
15:12coopernursenizze: yeah, welcome to java. lots of deps. thankfully we have tools to manage it
15:12wabashamalloy: So, if you have a pure clojure app, it's nice with immutable data objects, and everyone is happy. So if you decide then that you are going to use a java lib because it nicely and conveniently does exactly what you need purpose wise, and you add it and make calls, *all* of your clojure immutability goes away?
15:12technomancyturbofail: I don't think there's anything built-in for that apart from just (sort (concat a b)), which is not going to be fast
15:12amalloyno, it's not the case the the immutability goes away
15:12nizzeIn Ruby we, too, have deps. But not so much of them.
15:13wabashamalloy: oh, ok good.
15:13amalloybut you lose a lot of the *benefits* of immutability
15:13amalloylike being able to reason about a function in isolation without worrying about some global state
15:13nizzeWhy compojure guys are using Java stuff and not coding those libs in Cojure?
15:13arohnerturbofail: I don't think there's a built in fn, but it's fairly straightforward to write using loop & recur
15:13arohnernizze: composure is almost purely clojure, but it uses a java webserver
15:13wabashamalloy: So taking a pure clojure app, and adding a small part that uses a java lib, does not mess up the clojure part. However, that java part is suceptible to the typical failings of java?
15:13amalloynizze: complain again when you've written an entire production-ready webserver yourself?
15:14technomancyturbofail: you could try (sort (interpose a b)); that'll probably be a bit faster but still naieve
15:14turbofailarohner: sure, just wanted to know if i was duplicating work or not
15:14amalloyheh, interpose. that would be funny. interleave makes a little more sense
15:14technomancynizze: probably because that's really boring?
15:14nizzeOkay.
15:14technomancyamalloy: hah; interleave is what I meant
15:14turbofailthe only reason this came up was because of some silly problem that came up on programming praxis
15:15amalloywabash: you can try. some issues will leak through
15:15coopernursenizze: here's one cool thing though. you can do: lein ring war and it will generate a .war file that seals up your app+all deps
15:15amalloybut you can carefully wall them off
15:15coopernursethat you can deploy to any java servlet container (tomcat, jetty, weblogic, resin, etc). with no external dependencies
15:15nizzecoopernurse: Oh, nice!
15:15coopernurseso that's the rationale behind the madness (in part)
15:15nizzeOkay.
15:15wabashamalloy: Thank you so much.
15:16nizzeThanks for help :)
15:16coopernurseas opposed to the ruby/python world where you have to manage virtualenvs and make sure everything's installed
15:17turbofail5/6ths of my answer to the problem was implementing the sequence merge
15:18amalloyturbofail: really? it's not a very long function, even to merge N sorted seqs
15:18turbofailthe program was 12 lines of actual code
15:18turbofailso basically there was two lines of other stuff, the rest was just the merge
15:22nizzeUhm now I got it. I see it installed Jetty, which in turn pulled in lots of other stuff
15:23coopernursenizze: exactly. and most of that stuff are just dev dependencies.. so if you create a war it won't include them, as the servlet container you deploy to will have them already built in
15:25coopernursenizze: and not to confuse you, but you might take a look at noir, which is a layer on top of compojure that provides a more full featured microframework for clojure. http://webnoir.org/
15:26amalloyturbofail: https://gist.github.com/1187034 for your entertainment
15:28amalloythough for reasons i don't understand it looks like github is showing two copies of the file
15:29amalloyhm, the code is also wrong. that 10 snuck in at the wrong end
15:29amalloyoh right. the input seqs weren't sorted, haha
15:38michaelr525hello!
16:08nizzeWhat is the preferred way to use clojure with vim?
16:09michaelr525Edit code..
16:19coopernursequestion about underscores as input param names - are they special? it seems you can use them more than once
16:19coopernursein the same param list
16:20hiredman,((fn [a a a] a) 1 2 3)
16:20clojurebot3
16:20coopernurseI see - so you can use the same name more than once in general
16:20michaelr`heyo!
16:21hiredmanconvetion says _ as an argument names you ignore it, but just a convention
16:21clojurebot( is http://xkcd.com/859/
16:21coopernurseok, great. thanks
16:23TimMcclojurebot: What triggered you there?
16:23clojurebotExcuse me?
16:24amalloyTimMc: he likes to jump in at random on occasion
16:24TimMccoopernurse: _ is syntactic in some other languages, though
16:24amalloy(true; not joke)
16:24TimMcamalloy: I know that it will take 1 in n msgs as directly-addressed.
16:25amalloywhat made him come up with that particular answer is anyone's guess
16:25amalloyclojurebot: ) is http://xkcd.com/224/
16:25clojurebotIn Ordnung
16:25ibdknoxlol
16:25ibdknoxwho taught it German?
16:25ibdknox;)
16:26TimMcThis didn't seem to be a factoid lookup based on anything hired⁠man had said.
16:26gtrak`what about http://xkcd.com/297/ ?
16:26TimMcamalloy: It usually seems to cue on a single token and use that for a lookup.
16:26TimMcclojurebot: 2 3 4 5
16:26clojurebotIt's greek to me.
16:26TimMchrmph
16:27amalloyclojurebot: 2 3 4 5?
16:27clojurebotPardon?
16:27TimMcclojurebot: +
16:27clojurebot(+ 2 10) reply 12
16:27TimMcclojurebot: +
16:27clojurebot(+ 2 10) reply 12
16:27mukeclojurebot: rand-int
16:27clojurebotGabh mo leithscéal?
16:28michaelr525clojurebot: can you teach me clojure?
16:28clojurebotPardon?
16:28hiredman1d12
16:28clojurebot8
16:28gtrak`1d13
16:28clojurebot10
16:28gtrak`huh?
16:29michaelr52599999999..999999999999999999999999999999999999
16:29muke(rand-int 10)
16:29michaelr525clojurebot: 999..99999999999999999999999999999999999999999999999999999999999999999
16:29clojurebotExcuse me?
16:29gtrak`1d14
16:29clojurebot6
16:29gtrak`1d1
16:29clojurebot1
16:29mukeclojurebot: (rand-int 10)
16:29gtrak`1d2
16:29clojurebot1
16:29clojurebotCool story bro.
16:29gtrak`1d3
16:29clojurebot1
16:29michaelr525clojurebot: 2^999999999999999999999999999999
16:29clojurebotCool story bro.
16:30TimMcclojurebot: Now, why wouldn't you be responding to infix notation?
16:30clojurebotinfix is not worth the trouble; see http://groups.google.com/group/clojure/browse_thread/thread/319a1c77ed718ba/3e4be7484b7cbe38
16:30TimMcclojurebot: botsnack
16:30clojurebotThanks! Can I have chocolate next time
16:31mukeclojurebot: chocolate
16:31clojurebotGabh mo leithscéal?
16:32TimMcMy work here is done.
17:22seancorfieldanyone here going to the Bay Area Clojure Meetup tonight?
17:25seancorfieldmm, bbq
17:31mmarczykamalloy: ping?
17:43mtmseancorfield: I'll be there
17:47seancorfieldmtm: cool! amit probably can't make it so he asked me to run things... i'll try to make sure i get there a bit earlier than i normally do...
17:48seancorfieldpizza is taken care of, so it'll just be facilitation... no fixed topic, so open discussion... we can see what sort of projects folks are working on and maybe get some ad hoc talks :)
17:52mtmspiffy
17:53scottjseancorfield: can you push an updated congomongo snapshot to clojars?
18:02amalloymmarczyk: hi
18:05amalloylooking at your latest revision now. looks like magic
18:09mabes_pprint is truncating my collection with "..." (I'm writing to file, not REPL). What var do I need to set or dynamically bind to avoid this?
18:10mabes_I've tried *print-length* but that didn't help
18:12jlimabes_: maybe *print-level* is what you want
18:12jliactually, nevermind, I don't think so
18:13mabes_jli: yeah, my collection isn't nested.. just long.. prn-str works fine, but I want the formatting pprint provides
18:15mabes_looking at the source *print-length* should do it.. hmm...
18:16joegalloprint-dup?
18:17joegallonah, ignore me
18:20seancorfieldscottj: sure... is it worth doing a non-snapshot release yet?
18:22scottjseancorfield: I haven't been following closely I just upgraded from 1.4 and need something from a few days ago. I certainly welcome a non-snapshot release soon
18:24scottjis there anyway with maven/clojars to depend on a specific snapshot or is that the nature of snapshots?
18:26technomancyyou can use dated snapshots
18:26scottjwhat's the format on that?
18:26mmarczykamalloy: hi! :-) writing that was *so* much fun, thanks for the idea
18:27technomancyscottj: just take the version number from the filename in lib
18:32scottjtechnomancy: so for noir-1.1.1-20110809.143608-35.jar is it [noir "1.1.1-20110809.143608-35"]?
18:33technomancyshould be
18:40amalloymmarczyk: yeah, it was really interesting. glad you liked it
18:40jliamalloy: what is this awesome thing?
18:41amalloyhttp://stackoverflow.com/questions/7240947/is-a-transparent-macrolet-possible/7256432
18:41mmarczykamalloy: I'm writing this up properly now, with some design notes
18:42mmarczykanyway, this tool you mentioned :-)
18:42mmarczykdo you have it ready?
18:42mmarczykselective test-running tool, I mean
18:44hiredmanyou know lein has test selectors?
18:44amalloymmarczyk: cake and lein both have something like it already; i was adding a more convenient syntax for tagging tests
18:45mmarczykhm, I vaguely remember that
18:45mmarczykthough I haven't look at test.clj in lein in ages :-(
18:45mmarczyksyntactic sugar, then; cool
18:57dnolenhmm I'm thinking about using a pre-allocated exception to implement backtracking in match if recur does not appear in any actions - optimization for complex patterns like red-black tree balancing, anyone see a potential problem w/ that?
18:58seancorfieldscottj: i pushed an updated congomongo-0.1.7-SNAPSHOT.jar to clojars
18:58scottjseancorfield: ty
19:41[swift]i think i may have found a bug in clojurescript; string? seems to return true for keywords in clojurescript, while it returns false for keywords in clojure
19:43hiredman[swift]: someone decided to implement keywords in clojure with strings prefixed by certain characters
19:43hiredmaner
19:43hiredmanclojurescript
19:45[swift]hiredman: googling about i found that this bug has already been reported, and building in production (rather than debug) mode fixes the problem
19:46[swift]it's a bummer, though.. clojurescript takes a long time to build, especially with optimizations on
19:59dnolenhmm backtracking via pre-allocated exceptions doesn't look so bad
20:00chewbrancadnolen: here's a fun idea, use matching rather than exception handling for control flow ;-)
20:00chewbrancacould get tricky in a hurry though
20:02dnolenchewbranca: not sure I follow. I'm just using exceptions here as a form of jump.
20:03chewbrancadnolen: yeah I'm just saying you could theoretically use pattern matching for flow control in your pattern matching lib, so it would look like (match [(some-match-function)] [:success] (proceed) [:error] (backtrack))
20:05chewbrancafun idea, would get rough to debug, but I just find it interesting because I'm a big fan of using pattern matching for flow control, and technically you could implement back tracking if your initial match predicate recursively went down the tree
20:06chewbrancamaybe that's just crazy iono, thought it was interesting and I'm not a huge fan of exception handling for flow control
20:07dnolenchewbranca: seems like a bootstrapping problem since match macro comes last. yeah exceptions for flow control, yuck. But here I'm using it to follow the literature.
20:07dnolenso match will be hybrid decision tree / backtracking implementation.
20:08chewbrancadnolen: see that's the thing, exceptions just seem odd and out of place, I completey agree that bootstrapping match inside of match most likely would not work and would not be a good idea, but if you've already got your data structure and a decision tree, back tracking just seems like it should be stepping back up the tree and taking previous execution paths
20:10dnolenchewbranca: it sounds like it would, but I don't think it will in practice. this optimization is for non overlapping patterns.
20:11dnolenwhen we backtrack, we already know we don't need to test again because there was a wildcard there in other case.
20:11chewbrancadnolen: ahhh ok, yeah I'm not familiar with the implementation, I just figured if backtracking was merely stepping back up the tree and taking a different branch then that would be the way to go
20:12dnolenchewbranca: so I think we actually get the benefit of decisions tree and backtracking. test everything once, small code size.
20:12chewbrancaor is it more backtracking for when you failed to match on a particular column (like x y z columns from your demo) and then you need to move onto another column which is its own tree
20:15chewbrancadnolen: alright I gotta run, great job on the matching lib, I'm having a lot of fun with it
20:15dnolenchewbranca: on simple values you don't need to backtrack, it matches or it doesn't. however some patterns are deeply nested. then you need to backtrack once you saw that it didn't match, but we only need to move back up to the nearest shared subtree (hopefully I'm making sense), because we're already sharing as much as possible.
20:17dnolenchewbranca: thx!
20:18chewbrancadnolen: ahhh ok, yeah that does make more sense, so instead of merely returning to the parent, you can return up an entire path to a much higher point as you know that you took the only possible branches on that subpath
20:18chewbrancaalright, now I must run, clojure and bbq awaits!!
20:18dnolenchewbranca: exactly.
20:27mmarczykamalloy: would you care for a pull request for flatland/useful with the latest revision of w-t-t + tests? (with tweaks to make w-t-t accept a vector of symbols yet still use a set of keywords for tagging)
20:34amalloymmarczyk: yes, please. i like the macrolet version much more than mine
20:36mmarczykamalloy: cool! I'll send it soon then
20:49mmarczykamalloy: done
20:52amalloythanks!
21:32user317are agents the way to go when dealing with statefull java classes? to interface with the interactive brokers api i need to implement this class which gets called when a bunch of events happen, so i am thinking of using an agent to keep track of state as the events occur, is that the recommended approach?
21:32user317i have a haskell background, so in haskell i would have pushed the events into a channel and lazy processed then as they arrive
21:39scottjif you're only interested in the latest state of the agent, sure
21:40scottjand if you need async
21:46user317how else would i do this? the agent can be on top of a sequence or some other data structure, so i can keep track of all the events that i get
21:47user317i dont see a blocking api, comming from haskell, i thought i could build a blocking generator for a sequence
21:51scottjI don't have relevant experience, but there is something called channels not sure if it's related to haskell's https://github.com/ztellman/lamina/wiki/Channels
21:53user317cool, thanks
21:55user317ah, looks like lazy channel seq does what i was thinking of
21:55user317my question is though, is that the right approach?
21:56scottjseveral people have attempted to build IB libs over the years, no one's released one afaik. the old ml thread "design patterns for event driven applications" mentions IB specifically
21:56scottjhopefully someone with experience in this area will chime in
21:57user317i dont really need a lib, i just write one off processes, i have halfassed haskell bindings via their posix api, i just wanted to play around with clojure, its the new cool thing apparently :)
21:59user317the "good" part of using a lazy evaluated list for events its that i can write parsers on top of them, so the state machine is captured in the parser
22:00scottjdid you checkout that thread?
22:01scottjit's got IB, lazy sequences, and haskell, should be right up your alley
22:01user317hehe, i started that thread :)
22:01scottjhaha, long term project :)
22:01user317i ended up not using clojure, i found it easier at the time to write bindings
22:03user317cool, well i'll give it another shot :)
22:04user317i think this time ill find a silver bullet
22:12sriddo I really need to have a project.clj for running M-x clojure-jack-in? how else can I get a clojure shell?
22:13scottjsrid: idk never used clojure-jack-in but you can do lein repl
22:13sridi like to have repl in emacs, so that i can send changed buffers to it directly
22:13scottjwhy not create a playground lein app?
22:14sridyea, i have one. its annoying to have to open it everytime
22:15scottjsrid: so write an interactive emacs function to open it for you and run clojure-jack-in
23:23amalloyScriptor: ping
23:23Scriptoramalloy: pong