# #clojure log - Jul 19 2011

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

0:00 amalloy: &(re-seq #"(.)((?!\1).)" "aacbb")

0:00 lazybot: ⇒ (["ac" "a" "c"])

0:00 amalloy: &(re-seq #"(.)((?!\1).)" "aaccbb")

0:00 lazybot: ⇒ (["ac" "a" "c"] ["cb" "c" "b"])

0:07 methods: amalloy: yea the backrefs did work

0:09 amalloy: yes, i can see that

0:12 methods: woo ! I added it to my bot..

0:14 I know it's not clojure (yet) :] https://gist.github.com/6f71751ce21b6296ce37

1:01 brehaut: can anyone think of a better way of implementing (defn pivot [p xs] (loop [prior [] [h & r] xs] (if (p h) [prior h r] (recur (conj prior h) r))))

1:02 eg (pivot {#1,2,3} [4 5 3 6]) => [4 5] 3 (6)

1:02 amalloy: brehaut: sounds like a split-with

1:02 brehaut: amalloy: almost but not quite

1:03 at least, if it is i havent worked out a nice way yet

1:03 amalloy: (defn pivot [p xs] (let [[prior [h & r]] (split-with p xs)] [prior h r]))

1:03 probably (complement p)

1:06 brehaut: amalloy: excellent

1:06 hmm. no not quite

1:06 (pivot #{1,2,3} [4]) => [(4) nil nil] but should be [nil nil (4)]

1:07 amalloy: i think your impl yields the same thing?

1:07 brehaut: if it does it broken too then ;)

1:07 hah

1:07 no mine recurses indefinately at that point

1:07 amalloy: isn't 4 before the pivot? i don't see how you can claim it's after

1:08 if the pivot is nowhere

1:08 brehaut: hmm pivot is a bad name

1:08 because you are correct if its actually a pivot

1:09 i think i am too tired to write this code properly; ignore me

1:18 grantm: anybody ever seen the error "can't eval locals"?

1:19 im trying to teach myself macros by just jumping in... its kinda confusing

1:20 say i do (defmacro simple [x] (eval x))

1:20 amalloy: grantm: good policy. not familiar with the error, but gist up a macro and a stack trace (if you can get one; sometimes it's hard with macros) and i'll have a looksie

1:20 grantm: heh, i can do that too

1:20 although its just one more line :)

1:21 amalloy: grantm: on the wholel, anytime you use eval (especially in macros), huge blaring alarm sirens should go off in whatever room you're in. sometimes it's good, but...

1:21 *whole

1:21 haha

1:21 alright, i'll keep that in mind

1:21 let me explain what i was trying to do

1:22 and maybe you can tell me a better idea :)

1:22 im trying to make a simple lispy templating language, just for fun

1:22 i want something like (html (body "yay")) to return "<html><body>yay</body></html>"

1:23 that means that html is a function that wraps it's args with html... and similarly with basically any other tag function... so i figured i could make a macro that creates a wrapping function given a string

1:24 the reason i (thought i) had to use eval was because if you pass in a symbol to my create-wrapper macro, it makes a <symbol> wrapper instead of a <(eval symbol> wrapper

1:25 but that's separate from the weird thing i put on gist

1:25 amalloy: grantm: so this is because macros are explicitly about *generating code*, not about "doing things" at runtime

1:26 grantm: okay

1:26 amalloy: if you had a macro like (wrap-with-whatever [tagname body]), say

1:26 you couldn't call it like (let [tagname "test"] (wrap-with-whatever tagname "the-body"))

1:27 because no macro can go from the symbol "tagname" to "test" - at *compile time*. the value "test" only exists at runtime

1:27 grantm: aaah. interesting.

1:29 scottj: grantm: certainly not humourous

1:29 sorry, my copy paste is broken

1:29 grantm: haha

1:30 scottj: (defmacro html [body] `(hiccup/html [:html (into [] '~body)]))

1:30 grantm: so to summarize, if i find myself trying to turn symbols into values in a macro, that's a bad sign?

1:30 scottj: (html (body "yay")) => what you had

1:30 amalloy: grantm: yeah. one sec while i gist something up

1:31 grantm: cool, thanks

1:34 grantm: nice, ok, let me get my head around this :P

1:34 amalloy: yeah, (fn [x] (fn [y] ...))) can be unsettling

1:36 grantm: updated the gist with a different way of writing it, if that's clearer

1:39 grantm: ok yup it makes sense

1:39 the second one

1:39 ;)

1:40 oh, the first one is almost the second one

1:40 amalloy: grantm: it is the second one

1:40 they're the same, except the second one uses global defs instead of local bindings

1:40 grantm: okay, i see

1:42 amalloy: then if you want to, you can paper this over with a layer of macros, that does the repetitive work of creating the dozens of (foo-wrapper) functions for you using the html-wrapper function

1:42 grantm: the (def x (html-wrapper "x"))?

1:43 amalloy: right

1:44 (defmacro def-wrappers [& tags] (cons `do (for [tag tags] `(def ~tag (html-wrapper ~tag))))), (def-wrappers html body table ...)

1:45 except i guess it needs to be (html-wrapper '~tag) or (html-wrapper ~(str tag))

1:45 grantm: but wait, when you do `(def ~tag (html-wrapper ~tag)), one has to be a string and one a symbol right?

1:46 amalloy: grantm: meh. the symbol will get converted to a string by the (str) call in html-wrapper

1:46 grantm: okay interesting

1:46 i think i have a better conceptual framework for macros

1:46 amalloy: &(str "<" 'test ">")

1:46 lazybot: ⇒ "<test>"

1:47 grantm: haha, cool.

1:49 amalloy: so macros are great, but they're kinda for three purposes: (1) convenience wrappers over functions, (2) introducing new syntactic constructs, such as (when-let), (3) when functions simply won't do

1:49 (3) and (2) are pretty closely related; it's amazing how many things you can do with functions

1:49 grantm: clarification on 3? :)

1:50 amalloy: 3 is mostly a restatement of 2: most things that can't be done by functions are new constructs

1:51 but one example is when someone else has written a macro, and you want to layer some more stuff over that

1:51 macros don't compose very well, so you usually have to wrap their macro with one of your own that does the substitutions you want

1:53 grantm: interesting.. alright

5:06 bsteuber: so what was the new thing Rich's been talking about?

5:10 raek: I think the talk is 6:45 PM on wednesday, New York time

5:44 bsteuber: oh ^^

5:51 is there a way for resetting swank to the initial state without restart?

5:51 for example, to clean polluted multimethods

5:51 calling (remove-ns ..) by hand and recompiling all seems a bit painful

6:58 dbushenko: hi all!

7:13 bsteuber: is there a version of some returning the element, not the predicate applied to the element?

8:23 solussd: is there a media playback framework for clojure, ala FMJ or JMF?

8:23 bendlas: you can just use one of them

8:23 fliebel: solussd: Well, you can use those Java things... or try JNA + VLC :)

8:24 bendlas: also, i've made good experiences with gstreamer-java

8:24 solussd: thanks!

8:24 fliebel: bendlas: Can gstreamer play ALAC? That's why I used VLC

8:26 bendlas: TBH, i don't even know ALAC

8:27 fliebel: bendlas: Apple Lossless Audio Codec

8:28 bendlas: it probably does, after installing gstreamer-bad and gstreamer-ugly

8:29 =-0987654321`+

8:29 whoops, wiped my KB, sry ^^

8:33 fliebel: bendlas: http://imgur.com//gallery/i7zEm

8:35 bendlas: lol

8:59 ogonzalez: bsteuber: you can use (comp first filter)

9:19 bsteuber: ogonzalez: oh yeah, more elegent than (some #(when (pred %) %) coll)

9:26 dbushenko: bsteuber: yesterday you've advised me to make a jar for Clojure-WebApp -- it is done now, just have a look

9:58 bsteuber: dbushenko: looks good

9:59 how do you want users to talk to the db?

10:00 clojureql? or some custom active-record clone you're going to write?

10:02 dbushenko: for now it is contrib-sql (or something like that which is a standard for clojure). I'm not going to rewrite that layer. Also, the user is free to use any libraries here, e.g. clojureQL

10:03 what really will be usefull -- is detailed documentation with lots of examples

10:03 there are lots great of libraries for clojure which are not so popular -- just because nobody knows how to use them

10:05 bsteuber: indeed

10:05 dbushenko: for instance, if you look at my code, you'll see tons of comments

10:05 I made this because I want make it easier for the other users to evolve the framework

10:06 I need help in developing the Clojure-WebApp so I try to make my source friendly to newcomers

10:07 bsteuber: if you're quite new to clojure, doing a big project like this might be quite hard, I suppose

10:07 well maybe it's not that big with all the existing stuff ^^

10:07 dbushenko: this is the reason :-D

10:08 also what I've learned from it is that Clojure is very-very expressive

10:08 My framework is very small but it does many interesting things:

10:08 bsteuber: indeed

10:08 dbushenko: routing, templating and so on

10:09 bsteuber: if you know what you want, just a bunch of small namespaces will make it most of the time

10:09 dbushenko: that's why I'm not afraid of what I'm doing. I need not so much code to make good things

10:11 well, I know what I want in the nearest future. I exepriment with what I have and evolve it. If at some time my design will cause problems -- then I will change it as I've already done two times starting from ClojureBlog

10:12 bsteuber: ideally, your stuff is split into so many functions that even "big refactorings" don't involve that many changes

10:12 dbushenko: probably -- yes..

10:13 bsteuber, OK, I have to get back to home. See you!

10:54 timvisher: hey all

10:57 if you were of the mind to serve up a static file via an http

10:57 *** server for functional testing, but didn't want to have to remember

10:57 to start that server before each test, how would you go about

10:57 starting up a server before the relevant tests each time they're run?

10:57 sorry for the filling!

10:58 kumarshantanu: timvisher: start up the daemon via system init script?

10:59 timvisher: is that a clojure specific thing or do you mean starting the server as soon as my system starts as a whole?

10:59 kumarshantanu: the latter

11:00 timvisher: ah

11:00 kumarshantanu: or do your tests have different places to serve static files from?

11:00 timvisher: well, I'd prefer not to have the server running all the time as it's only used for my testing

11:01 kumarshantanu: then script your tests in a way that it starts up the daemon before the tests are run, and closes it afterwards

11:01 timvisher: i'm wondering if there's a simple wrapper I could use from ring to start up a little instance of jetty or something

11:01 kumarshantanu: lein-daemon plugin?

11:01 timvisher: I can imagine how to do that, is there anything pre-written?

11:01 ah

11:01 I'll check that out

11:01 kumarshantanu: lein-daemon can start and stop things

11:02 and if you use lein 1.6.1, you get a key called :extra-classpath-dirs that won't be included in the JAR or WAR

11:02 you can use that to place your daemon startup/shutdown code

11:03 timvisher: that looks promissing

11:04 ok

11:04 well thanks for the idea

11:04 kumarshantanu: \m/

11:04 jcromartie: for some reason I can't use the metadata key :type

11:04 (in a defn)

11:06 (defn ^{:type :foo} f [x] x)

11:06 that fails

11:07 errp

11:07 sorry (defn ^{:type :foo} f [x] x)

11:07 err... yeah

11:07 kumarshantanu: jcromartie: it is working for me

11:08 jcromartie: that fails with java.lang.ClassCastException: clojure.lang.Var cannot be cast to clojure.lang.IObj

11:08 kumarshantanu: ,(defn ^{:type String} foo [] "foo")

11:08 clojurebot: DENIED

11:08 jcromartie: if I change :type to :types it works

11:08 kumarshantanu: access it thus -- (meta #'foo)

11:10 jcromartie: and thus -- (type #'foo)

11:11 Hodapp: wow... pretty much every single web-service technology I've dealt with has been fugly, and in the case of Java it's completely riddled with made-up terms that are then used very loosely

11:12 I greatly look forwardd to being able to mess with Clojure when I get home...

11:12 jcromartie: kumarshantanu: is that what (type var) does

11:12 ah I see

11:12 kumarshantanu: jcromartie: the :type key should be associated with a class, not a keyword

11:12 jcromartie: yeah

11:12 jweiss: doing my first multithreaded program in clojure - not quite sure which tools to use. i have a single tree (zipper) data structure, and i want all children of a node to be processed by multiple threads (which will update that node). agents/atoms/refs?

11:13 kumarshantanu: jcromartie: this should work -- (defn ^{:type clojue.lang.Keyword} foo [] "foo")

11:14 jcromartie: it doesn't, because I believe :type is reserved

11:14 kumarshantanu: jcromartie: #'foo is same as (var foo)

11:14 jcromartie: yes I know

11:14 kumarshantanu: typo above, i meant this -- (defn ^{:type clojure.lang.Keyword} foo [] "foo")

11:15 jcromartie: yeah

11:15 well that's reserved by Clojure for that purpose

11:15 I think

11:15 kumarshantanu: yes, it is used for type hints i guess

11:20 jcromartie: so speaking of type hints

11:21 kumarshantanu: got to head home...

11:21 jcromartie: I figure it would be possible to add (optional) static type checking to clojure using metadata

11:22 this is a totally crude draft v0.0.1alpha https://gist.github.com/f2e6713ba14261115dde

11:22 kumarshantanu: jcromartie: i thought pre/post conditions are better suited at that

11:22 jcromartie: they can't be applied statically

11:22 like, what if you wanted static checking?

11:22 to say (typecheck some-code ...)

11:23 just as an analysis

11:23 kumarshantanu: not sure if that's possible in Clojure without changing the language

11:23 jcromartie: you don't think?

11:23 we'll see

11:23 it would be entirely imposed by the programmer

11:24 kumarshantanu: for standalone analysis, with metadata....perhaps it's possible as long as you have a metadata repo

11:25 leaving for home...

12:33 lnostdal-laptop: hm, so what's the difference between send and send-off? .. in the docs i see, briefly, that send-off is for potentially blocking calls; does it perhaps use a different thread pool than send?

12:34 TeXnomancy: lnostdal-laptop: correct

12:34 lnostdal-laptop: thanks, TeXnomancy

13:08 i seem to do something like this a lot: (assoc m :something (conj (:something m) more-stuff)) ;; perhaps there's an already existing shortcut in the clojure api? .. my mind is on a sugar low at the moment, browsing .....

13:08 raek: lnostdal-laptop: update-in

13:08 lnostdal-laptop: raek, thanks!

13:08 raek: (update-in m [:something] conj more-stuff)

13:09 lnostdal-laptop: ..very nice..

13:09 :)

13:09 dnolen: lnostdal-laptop: assoc-in, get-in also useful.

13:09 lnostdal-laptop: yeah

13:11 dnolen: ,(assoc-in {} [:foo :bar] 1)

13:11 clojurebot: {:foo {:bar 1}}

13:19 amalloy: lnostdal-laptop: you can also combine update-in with assoc to perform multiple insertions at the same level: ##(update-in nil [:a] assoc :b 1 :c 2)

13:19 ,(update-in nil [:a] assoc :b 1 :c 2)

13:19 clojurebot: {:a {:c 2, :b 1}}

13:19 dnolen: and for ultimate power you have zippers.

13:20 amalloy: man, i just got an email about an eclipse bug i filed a year ago. "Fixed in CVS head". people still use cvs?

13:21 ieure: amalloy, Humans are disgusting.

13:21 Masochists.

13:21 CVS is the CBT of SCM.

13:22 amalloy: you have something against cognitive behavioral theory?

13:23 Scriptor: amalloy: cock and ball torture, clearly

13:25 stuartsierra: wow, wrong time to walk into the room.

14:20 redline6561: What's the difference between lein swank and lein repl?

14:21 (Sorry if I missed an earlier obvious resource...)

14:21 dnolen: redline6561: lein repl is a standalone repl, lein swank is generally for connecting to from Emacs

14:21 redline6561: dnolen: Aha. That makes a lot of sense. Thanks.

14:21 dnolen: clojurebot: ~max

14:22 clojurebot: maxine is http://research.sun.com/projects/maxine/

14:22 dnolen: clojurebot: max people

14:22 clojurebot: max people is 317

14:52 mattmitchell: how do i create a Character?

14:53 kumarshantanu: \s is a Character

14:53 (seq "hello") ;; will produce a sequence of Character objects

14:53 mattmitchell: similarly, \space is also a Character

14:54 mattmitchell: and this - http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/char

14:58 lnostdal-laptop: hmmm, clojure is kinda like common lisp; most things fit together quite nicely .. each thing is quite trivial in isolation, but it is composed nicely; that's the key i guess

15:06 Cozey: i cannot lein deps 1.3.0-master-SNAPSHOT - what am i missing?

15:06 do i need to add some repository?

15:06 sorry - full name is : org.clojure:clojure:jar:1.3.0-master-SNAPSHOT

15:08 mattmitchell: kumarshantanu: thanks!

15:08 technomancy: Cozey: you need to add the clojure snapshots repo

15:08 it's listed on confluence

15:09 Cozey: but i wasn't doing it on my old setup - and it worked. or i have forgottne. and now on new setup i need to do it ?

15:09 technomancy: Cozey: IIRC clojure/core deprecated the old snapshots server and the new ones are available elsewhere

15:10 Cozey: ahh. because i have them in local maven repo perhaps

15:10 so what should be used now?

15:10 -alpha?

15:10 technomancy: alphas and snapshots are both available, it depends on what you want.

15:10 dnolen: lnostdal-laptop: not so surprising since rhickey is a big CL fan, rhickey circa 2000 on comp.lang.lisp http://groups.google.com/group/comp.lang.lisp/msg/fb3e3efa3b0f1f12

15:11 ^ the birth of Clojure?

15:11 Cozey: technomancy: i want 1.3 - and as developed as possible, but also bugfree as possible, so i guess alpha4 would be smart

15:11 technomancy: you probably want beta1 then

15:12 Cozey: and what repo is that ?

15:13 here is don't see betas

15:13 ahh ok

15:13 contrib doesnt have it

15:13 technomancy: thanks! it clears things

15:16 hugod: another use for elisp injection - rename your slime buffers after your projects, so you keep separate slime repl histories for each project

15:18 lnostdal-laptop: dnolen, yeah, i know his background .. i used several of his CL<-->Java libraries back in, hm, 2005-6 or so :)

15:19 dnolen: lnostdal-laptop: heh, cool.

15:36 bpr: i'm having a hard time getting tests to report useful failure information with the latest clojure-mode and slime available in marmalade. Is this a known bug?

15:37 gtrak: does clojure-mode autocomplete java?

15:38 lnostdal-laptop: nope, gtrak .. (at least not here)

15:38 ..it'd be great though

15:38 vijaykiran: gtrak: I didn't see the java autocompletion - only works on the words in the file I think

15:39 amalloy: gtrak: it couldn't really work very well without static type information

15:39 where do you look to find a completion for (.setMe<tab>?

15:40 vijaykiran: gtrak: may be jdee can help - I didn't use it though

15:40 gtrak: hmm, it seems the slime repl can do it though

15:40 lnostdal-laptop: oh, indeed it can

15:40 clojurebot: It's greek to me.

15:40 lnostdal-laptop: ..i guess static methods?

15:41 amalloy: *shrug* it's just guessing based on god knows what

15:41 gtrak: the classpath that lein set up for it?

15:44 amalloy, well, you could do imports easily enough

15:45 amalloy: gtrak: how would that be useful? i import java.sql.ResultSet, then i do (.getD<tab> -- how does it know to look at the java.sql.Date class?

15:45 it can't know that i was planning to get a date field out of a ResultSet when i haven't even mentioned ResultSet yet

15:48 gtrak: of course it wouldn't be as useful as the full parse tree reading your mind, but say you're declaring imports, you could go import Dat<tab> and get a list of java.util.Date, etc..

15:51 buddywilliams: What is the different between sharp-quote and using a fn symbol? Ex. (map #'+ '(1 2 3) '(10 100 1000)) and (map + '(1 2 3) '(10 100 1000))

15:51 gtrak: the .getD would be broken, but (. Classname (.getD<tab> could work

15:51 buddywilliams: ,#'+

15:51 clojurebot: #'clojure.core/+

15:51 buddywilliams: ,+

15:51 clojurebot: #<core\$_PLUS_ clojure.core\$_PLUS_@8fb65>

15:52 amalloy: ,@#'+

15:52 clojurebot: #<core\$_PLUS_ clojure.core\$_PLUS_@8fb65>

15:52 buddywilliams: So they return different values

15:52 frou100: Is anyone familiar with the unix tool netcat? I'm trying to use it to send text to lein's socket repl and am having a problem.

15:52 gtrak: frou100, I used it once and it's pretty self-explanatory

15:52 amalloy: ,(var +)

15:52 clojurebot: #'clojure.core/+

15:53 amalloy: ,'#'+

15:53 clojurebot: (var +)

15:53 buddywilliams: gtrak were you talk to me previously?

15:53 gtrak: buddywilliams, no

15:53 buddywilliams: okay, thanks

15:53 amalloy: buddywilliams: anyway, those are the interesting examples. #'foo is a var, in fact is shorthand for (var foo); if that doesn't answer your question, probably time to get more familiar with what a var is

15:54 buddywilliams: sounds like a plan

15:54 I am just diving in here so I am sure there is much to get familiar with

15:54 raek: if you do (.<tab> it will list all methods it knows of

15:54 buddywilliams: but if var is simply a normal variable then that doesn't seem to difficult

15:55 amalloy: buddywilliams: clojure doesn't have variables

15:55 it has locals, vars, and refs

15:55 frou100: gtrak: I give netcat a file on its stdin to send to the repl. I'd expect netcat to close and exit once it has sent the data but it just sits indefinitely.

15:55 amalloy: s/refs/reference types

15:55 lazybot: <amalloy> it has locals, vars, and reference types

15:55 buddywilliams: sounds like I need to do some reading

15:55 the clojure site doesn't seem to explain exactly what things are

15:55 just how to call them

15:56 I'll poke around some more

15:56 gtrak: frou100, there's some option for that

15:57 buddywilliams: http://clojure.org/vars

15:57 that's was easy :_

15:57 :)*

15:58 gtrak: frou100, http://linux.die.net/man/1/nc "After the file has been transferred, the connection will close automatically."

15:58 raek: well, you could argue that Clojure has variables in the mathematical sense

15:59 gtrak: frou100, maybe you're using a version from 1997

16:00 frou100: gtrak: that is exactly the behaviour I want. Just checking, homebrew on OSX installed gnu netcat 0.7.1

16:01 gtrak: maybe try < instead of |

16:02 frou100: I do: netcat localhost 5659 <\$REPL_INPUT >\$REPL_OUTPUT 2>&1

16:05 sritchie: if I'm defining a macro, is there some way to get the namespace in which the macro's being used?

16:06 if I wanted to prefix some.namespace to something, for example, when (mydefn cake ...) was called inside of some.namespace

16:06 ahead-of-time syntax quoting, I guess that'd be?

16:13 jcromartie: sritchie: what's the actual purpose?

16:14 sritchie: so, hadoop requires AOT compilation on classes, so I can invoke jobs with "hadoor jar path some.namespace.ClassName ..."

16:14 arj: anyone know what Riches talk tomorrow is going to be about? :)

16:14 sritchie: https://gist.github.com/1093590

16:15 jcromartie: I wanted a macro that would write out the gen-class, set main to true, assign the proper prefix, etc, and wanted it to set the :name value to be some.namespace.SuppliedName

16:15 so, (defjob SuppliedName [x] ...) etc would create some.namespace.SuppliedName

16:17 arj: has anyone tried running clojure on java7 yet?

16:19 frou100: oh well, gtrak, I don't think this is possible. my dubious plan b is to start netcat in the background, record its pid, then kill it after a second

16:20 gtrak: frou100, yea, I don't know, seems like it should work

16:24 jonabbey: i've run clojure on java 7, no issues in basic interaction with the repl and leiningen

16:25 arj: jonabbey: cool thx

16:25 sritchie: jcromartie: looks like that gist gets the job done

16:25 pao: hi all, would it be possible to define a "lazy" _or_ implementation in clojure? are macros needed?

16:26 > (+ 1 1)

16:26 hsbot: No instance for (GHC.Show.Show (a0 -> a0)) arising from a use of `M8168114599624083945.show_M8168114599624083945' Possible fix: add an instance declaration for (GHC.Show.Show (a0 -> a0))No instance for (GHC.Num.Num (a1 -...

16:27 pao: > let myor x y = x || y in myor True undefined

16:27 hsbot: True

16:28 pao: > let myor x y = x || y in myor True (error "foo")

16:28 hsbot: True

16:28 pao: that's lazy

16:28 jcromartie: or is short-circuited

16:28 it's a macro

16:28 pao: jcromartie, so with a macro I could implement a lazy myor, right?

16:29 Raynes: Kind of.

16:29 pao: jcromartie, what do you mean with "short-circuited"?

16:29 Raynes, could you elaborate? :-)

16:29 jcromartie: ,(or true (println "hi"))

16:29 clojurebot: true

16:29 gtrak: how would you guys go about doing a 'find-callers' in clojure-mode?

16:29 jcromartie: ,(or nil (println "hi"))

16:29 clojurebot: hi

16:30 pao: ,(+ 1 1)

16:30 clojurebot: 2

16:30 Raynes: All the 'or' macro does is prevent latter arguments from being evaluated until when/if they need to be. I'm not sure it can be called laziness, but it acheives the same effect. I have trouble calling it 'laziness' because of what macros can do.

16:31 pao: jcromartie, I know that or implementation is "lazy", the question is: do I have a chance to implement function that are lazy in the evaluation of their parameters as or is?

16:31 Raynes: Or, better yet, how macros work, I suppose.

16:31 gtrak: Raynes, in other languages, this short-circuited behavior is called laziness too

16:32 Scriptor: or basically rewrites itself into an if expression, which I guess you could call lazy

16:32 pao: Raynes, thanks ... I guess that macros are the tool for "lazyness"... I'll pospone my understanding till macro chapter :-)

16:32 Scriptor: in that the else part of an if expression isn't necessarily evaluated

16:35 pao: > let myor x y = x || y in myor False (error "foo")

16:35 hsbot: *Exception: foo

16:38 pao: thanks everyone

16:38 good night!

16:39 technomancy: gtrak: slime gives you completion on class names and static methods. instance methods are impossible to complete without type hints, and type hints are rare enough that nobody's bothered to hook them up to completion.

16:52 pmbauer: Has anyone run into issues with "lein swank" after upgrading to lein 1.6.1?

16:52 jonabbey: what kind of issues?

16:52 technomancy: pmbauer: agent/future issues are solved by swank 1.3.2

16:52 pmbauer: I'm getting a rather opaque stack trace whenever I add incanter as a dependency

16:53 lein repl, test etc work fine

16:53 I tried swank 1.3.2 as well as swank-1.4.0-SNAPSHOT

16:53 technomancy: pmbauer: incanter bundles an obsolete swank snapshot

16:53 pmbauer: ah

16:54 technomancy: need to file a bug report for incanter and use an exclusion for now

16:54 pmbauer: I was beginning to suspect it was incanter's fault ... I'll clone incanter's repo and see about fixing that dependency

16:55 The stack trace was particularly unhelpful (IllegalArgEx with no source file)

16:55 Thanks

16:55 technomancy: no problem

16:59 pmbauer: Success. Thanks again, Phil!

17:01 mjg123: I've vector, contains room-reservations like {:start ... :end ... :name ...}

17:01 - when I want to add a new reservation I need to make sure it doesn't clash with one, then add it

17:01 can I do this check-then-add with (atom []) ?

17:02 amalloy: sure

17:02 mjg123: "do this" == avoid the race-condition of someone adding another reservation between my check & my add?

17:03 amalloy: there are certainly ways you can do it with (atom []), and ways you could misuse an atom so as to not achieve your goal

17:03 mjg123: :)

17:03 I'm just trying to get the hang of the difference between atom & ref

17:04 so I could do (swap! reservations (my-function-which-does-check-and-insert-if-possible)) ?

17:04 amalloy: indeed

17:05 mjg123: cool

17:05 then how do I know if my insert was successful or not?

17:05 fail => swap! returns nil ?

17:06 technomancy: mjg123: if it fails it'll be retried

17:06 mjg123: OK

17:06 but if it fails that is a permanent case - it will never succeed

17:06 technomancy: I mean if there's a concurrency conflict

17:07 mjg123: oh, I see :)

17:07 frou100: you mean the difference between failing to do an atomic swap, and failing by the definition of your app logic?

17:07 technomancy: if you're checking for validity in your function then it's up to you

17:07 mjg123: yes, what frou100 said

17:09 Maybe I wasn't clear...

17:10 I've an atom, and I want to swap! in a new value, but only if the current value is in a suitable state

17:10 obvs I can't check-current-state then swap!

17:11 because of the race condition

17:11 technomancy: if you need to signal a failure without changing the value of the atom, then an exception is probably your best bet.

17:11 mjg123: ah - OK

17:11 amalloy: blurgh

17:12 technomancy: that makes me sick as a solution, if i've understood his problem

17:13 technomancy: how else would you return more than one value from your swapping function?

17:13 amalloy: mjg123: do you need to *know* that the swap decided not to add anything, or are you content to just have it return either the previous value or a new one?

17:14 technomancy: you can either do like (atom [reservations succeeded-flag]), and update both

17:14 mjg123: I need to know if the attempt to add was unsuccessful, yes

17:14 stuartsierra: You need a ref. Then you can return whatever you need from the transaction.

17:15 mjg123: if it was a sql-type database, I'd need a transaction.

17:15 so I wonder if I need a re

17:15 stuartsierra: E.g., (dosync (if … (do (alter my-ref …) :success) :fail)

17:15 amalloy: a ref is the easiest solution, for sure

17:15 mjg123: Well I'll do that then :)

17:15 stuartsierra: Atoms are just degenerate Refs.

17:15 amalloy: i take a perverse joy in trying to do everything with atoms

17:16 technomancy: a ref is better if you don't consider reserving over an already-reserved slot an exceptional case.

17:17 bpr: quick question: if i have something like (definline get-sessions [] @*sessions*) where *sessions* is private in the namespace, can other namespaces use get-sessions to see the current value of the *sessions* reference?

17:17 mjg123: thanks guys :)

17:17 fliebel: i take a perverse joy in trying to do everything with pure functions ;)

17:18 amalloy: fliebel: that's a socially-approved joy

17:18 you don't get to eat lunch with the cool kids if that's your perverse joy

17:18 Raynes: fliebel: I once wrote a webserver using nothing but pure functions.

17:18 I guess that was Chuck Norris. Or Jon Skeet.

17:19 Hodapp: psssh. I didn't eat lunch with the cool kids - I ate lunch with the weird group who included the neice of the dean of the school.

17:19 bpr: i'm wondering if the definline will be smart enough to fully qualify the *sessions* name in the other namespace? If it does, will the :private-ness of the name cause issues at that point?

17:19 Hodapp: which meant I'd never get in trouble for anything.

17:19 amalloy: bpr: it probably will work fine. but...definline? really? what for?

17:20 bpr: nah, i'm actually using defn, but i was curious about that case

17:20 tbatchelli_: hey, here is a poll to see what people think Rich Hickey will announce tomorrow. Please cast your vote :) -- http://svy.mk/pptW0I

17:20 bpr: the reason i'm not exporting the name directly, is because i'm not sure how i'm going to implement it

17:20 fliebel: tbatchelli_: I dodn;t even knwo he was announcing something. I'm not a good fanboy.

17:21 tbatchelli_: also, don't cast your vote if you *know* what he'll talk about ;)

17:21 fliebel, he is, supposedly, tomorrow in NYC

17:21 (it's all for fun, by the way)

17:21 Raynes: Man, a poll? Really?

17:22 I'm almost hoping he announces something entirely uninteresting just so I get the (perverse) joy of seeing everyone's jaw hit the floor.

17:22 technomancy: fliebel: five demerits!

17:22 Raynes: iTeXL

17:22 fliebel: technomancy: five what?

17:22 technomancy: err--iTeX?

17:23 fliebel: I'm with Raynes on this, though I do hope CinC will be around soon.

17:23 clojurebot: First, out of 181000 results is:

17:23 demerits - definition of demerits by the Free Online Dictionary ...

17:24 technomancy: hmm... that didn't come out quite right

17:24 ~dict demerits

17:24 clojurebot: Huh?

17:24 technomancy: lazybot: dict demerits

17:24 lazybot: technomancy: noun: Plural form of demerit

17:24 technomancy: lazybot: botsnack!

17:24 lazybot: dict demerit

17:24 lazybot: technomancy: noun: A quality or characteristic deserving of blame or censure; a fault.

17:24 technomancy: no, the other definition.

17:24 dang it

17:26 technomancy: fliebel: it's like when Snape is all "Five points from Gryffondor!" because they did something they weren't supposed to or whatever.

17:27 fliebel: technomancy: All because I didn't know about the ANN? :( I don;t want to know what happens when I do mutable state in a macro... or whatever.

17:27 technomancy: clojurebot: demerits is <reply>Ten points from Griffindor! http://29.media.tumblr.com/tumblr_kuqfz5zPOD1qz4eedo1_500.jpg

17:27 clojurebot: c'est bon!

17:28 technomancy: fliebel: just messing with you

17:28 pjstadig: get back to work technomancy!

17:28 Raynes: fliebel: He's foreign. Doesn't understand humor.

17:29 fliebel: technomancy: Where are you from? Raynes: I'm Dutch, so at least I understand Python.

17:29 Raynes: ;)

17:29 Chousuke: mutable state in a macro. hrrr

17:29 even better, global mutable state

17:30 technomancy: fliebel: man I don't even know. I grew up in Indonesia but I'm from the US.

17:30 so I know a few words of Dutch.

17:30 Chousuke: I only know what clojurebot knows

17:31 technomancy: like stroopwafel

17:31 Scriptor: fliebel: Netherlands Duth or Vlaams?

17:31 Chousuke: of dutch, that is

17:31 fliebel: Scriptor: Duth ;)

17:31 Scriptor: gah

17:32 fliebel: Chousuke: Clojurebot speak dutch?

17:32 clojurebot: No entiendo

17:33 amalloy: fliebel: he might have a dutch reply in there somewhere

17:33 Chousuke: yeah

17:33 Scriptor: argh, why couldn't making a simple http server in java be as simple as with python

17:33 fliebel: Scriptor: Are you playing with NIO?

17:34 Scriptor: fliebel: nope, I'm thinking of using enlive to make a highly basic slide maker that can run in its own server

17:34 but first, how to server

17:35 fliebel: Scriptor: Jetty is easy. NIO is not...

17:36 Scriptor: ooh jetty, forgot about that

17:38 brehaut: Scriptor: its a one liner with the ring adapter

18:04 lnostdal-laptop: hm, so ... is Netty the thing Java/JVM/Clojure peeps go for when AJAX/Comet/WebSockets/ReverseHTTP is an important thing?

18:07 wilfredh: quick question about tracebacks

18:07 dnolen: lnostdal-laptop: Netty seems popular, Aleph is the Clojure library furthest along trying to build an idiomatic layer over it.

18:07 wilfredh: if I have an exception raised in foo/a.clj how do I distinguish it from an exception in bar/a.clj? It makes finding the offending code tricky

18:08 amalloy: wilfredh: the name of the class throwing the exception will have either foo or bar in it

18:09 lnostdal-laptop: dnolen, yeah, i saw aleph .. i couldn't get it to work with 1.3 though

18:09 wilfredh: I can't see where: "Exception in thread "main" java.lang.Exception: No such namespace: ring (comments.clj:14)" (I have two files called comments.clj)

18:10 amalloy: wilfredh: well, that's a compiler exception, raised while parsing the file, not raised from within the file

18:10 lnostdal-laptop: ..i might check it out closer later; i did patch it here, banging my head against it for a while .. but gave up eventually :)

18:10 wilfredh: amalloy: ah, my mistake. So there's no way of finding which file had the compile exception?

18:11 amalloy: i don't think so. the compiler isn't very loud about that sort of thing

18:11 but seriously, debugging *part* of a stacktrace is not very productive. if you want definitive answers, gist the whole thing up and link to it

18:12 technomancy: wilfredh: I found that to be a huge annoyance until I switched to clj-stacktrace

18:12 it's nicer in every way

18:12 especially the aligned frames

18:12 wilfredh: amalloy: I'm happy fixing it, it's just slowing me down

18:13 technomancy: thanks, I'll check it out

18:14 technomancy: wilfredh: this hasn't made it into a release yet, but you may find it useful: https://github.com/mmcgrana/clj-stacktrace/blob/lein-hook/src/leiningen/hooks/clj_stacktrace_test.clj

19:05 rbuchmann: so, I figured out that (-> {blah} (assoc :a 1) (apply dissoc [:b :c])) doesn't do what I thought it would :)

19:06 Is there an elegant way to use apply with threading?

19:09 amalloy: meh

19:09 you can write that as (-> (blah) (assoc :a 1) ((partial apply dissoc) [:b :c]))

19:10 rbuchmann: hm, okay... better then (dissoc (assoc ...)), especially in longer chains

19:10 amalloy: but that's hardly elegant. i don't find i often need to do this, which is probably a common feeling; that's probably why no solution has ever become popular

19:11 rbuchmann: the result is pretty funny though, because of the way maps work as functions :)

19:12 &(-> {} (assoc :a 1) (apply dissoc [:b :c]))

19:12 lazybot: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: PersistentArrayMap

19:12 amalloy: &(-> {} (assoc :a 1) (apply dissoc [:b]))

19:12 lazybot: ⇒ :b

19:12 amalloy: more amusing imo

19:12 rbuchmann: exactly :)

19:13 that was what I was trying to get

19:13 and what happened in my code

19:13 ...

19:16 Maybe you can help me with something else... On my laptop, the following happens:

19:16 (def t (agent 0))

19:16 (send t inc)

19:16 @t => 0

19:16 no matter what I do

19:16 send-off doesn't work either

19:17 in a swank-clojure repl from emacs

19:17 any idea?

19:24 the "same" swank from exactly the same leiningen project does this correctly on any other platform I've tried it on

19:24 I am a little out of ideas

19:26 technomancy: rbuchmann: you need swank 1.3.2

19:26 lein 1.6 includes a workaround for a clojure thread pool flaw that breaks old versions of swank

19:26 rbuchmann: so its a swank bug?

19:26 ah, I see

19:27 thank you

19:27 technomancy: np

19:27 need to put that in the swank readme or something

19:27 rbuchmann: yeah, that would definitely help ^^

19:29 are there instances where (apply f [...]) doesn't work when f is defined as (def f g), where g is a variadic function?

19:30 I'm getting weird (wrong number of arguments supplied [0]) exceptions when using clj-processing (which does that for example for fill, background, etc

19:32 using it as a (very cool, thanks for that technomancy) checkout dependency, if that helps or is in any way related

19:33 technomancy: I don't think you can get those kind of issues just by doing (def f g)

19:33 if (apply g [...]) works, applying f will work too

19:33 rbuchmann: thats what i'd expect

19:33 hmm

20:05 lnostdal-laptop: slime or swank-clojure or whatever is pretty stupid; maps pointing to each other leads to infinite loops

20:06 ..dynamic var with cycle detector is needed i guess

20:07 ..i recall already seen structures being replaced by #1 in a CL context .. then the previously mentioned structure got a #1 prefix so one could see

20:08 technomancy: sounds great, want to implement it?

20:08 lnostdal-laptop: not really

20:08 :)

20:08 technomancy: that makes two of us

20:10 lnostdal-laptop: ..i'm just wrapping stuff in a thingy which returns nil for now; when exploring things in the repl

20:10 Raynes: I wrap all my stuff in thingies.

20:10 lnostdal-laptop: yeah, lisp makes that easy

20:27 amalloy: lnostdal-laptop: printing #1# is probably not that hard, but printing it readably sounds harder. i think CL lets you type in self-referential objects that way

20:27 lnostdal-laptop: yup, amalloy .. not something i've used a lot

20:28 yeah, #1# .. not just #1

20:28 ..as i said above

20:28 amalloy: well, some of both

20:28 #1=(a . #1#)

20:29 actually i guess printing is harder than reading

20:29 i dunno. everything is hard

20:30 brehaut: lets go shopping?

20:31 amalloy: brehaut: i was actually in the middle of reading about the history of that phrase

20:31 brehaut: its an accident right?

20:31 amalloy: what is?

20:32 brehaut: that phrase/

20:33 amalloy: well. apparently there was a talking barbie doll whose phrases included "Math class is tough!" and "Want to go shopping?"

20:35 brehaut: so separate phrases rather than one?

20:35 and they ran together quickly by accident?

20:36 amalloy: brehaut: http://itre.cis.upenn.edu/~myl/languagelog/archives/002892.html is my source

20:36 brehaut: cheers

20:36 amalloy: out of 270ish phrases, each doll got loaded with four of them

21:08 ibdknox: what's the replacement for clojure.contrib.duck-streams?

21:08 pickles1: clojure.contrib.duck-ponds?

21:08 clojurebot: clojure bot is not immune to ,(iterate inc 0)

21:23 amalloy: ibdknox: clojure.java.io, mostly

22:07 dnolen_: so Oracle is implementing it's own JavaScript.

22:09 Hodapp: dnolen_: bah?

22:09 dnolen_: announced at JVM lang summit, http://www.wiki.jvmlangsummit.com/images/c/ce/Nashorn.pdf

22:11 interesting Jigsaw+Clojure presentation there

22:16 cemerick: dnolen: do you see materials for that anywhere, or are you just referring the talk being being on the schedule?

22:16 er, dnolen_ ^^

22:16 dnolen_: cemerick: I did not see any materials.

22:16 and JetBrains announces it's own statically-typed lang for the JVM Kotlin

22:16 cemerick: Man, bummed I wasn't there for the Gosu talk.

22:18 methods: gosu talk ?

22:18 cemerick: yeah, http://www.wiki.jvmlangsummit.com/Main_Page

22:18 dnolen_: Comparing Kotlin & Scala http://confluence.jetbrains.net/display/Kotlin/Comparison+to+Scala

22:18 cemerick: Damn, no one fell for the trolling. ;-)

22:19 dnolen_: cemerick: heh, I almost said something but I've taken a vow to not to respond to anything w/ the words Gosu.

22:19 cemerick: dnolen_: Wise man.

22:20 Kotlin looks pretty sane.

22:21 dnolen_: cemerick: it does, first class delegation is pretty cool.

22:24 methods: what in the world is kotlin

22:25 dnolen_: methods: a new programming language being created by JetBrains

22:28 cemerick: I wonder if they'll eat their hat and build proper tool support beyond IntelliJ

22:29 justinko: is the convention to put function arguments on a new line?

22:29 methods: just another java look alike ?

22:30 justinko: seems random for what people do

22:31 brehaut: justinko: it makes sense when you have docstrings and multiple aritys

22:31 cemerick: so, challenger to Scala, challenger to Groovy (Gosu), where's the challenger to Clojure?

22:33 justinko: what do you guys think about Noir?

22:38 technomancy: gosu is one of those boring-on-purpose languages, right?

22:38 like fantom?

22:48 icey: cemerick: I can't think of anything from the "Functional lisp on the JVM" angle, but from the "functional lisp" angle I guess there's Qi/Shen

23:03 DeusExPikachu: anyone go through the logic-starter tutorial?

23:04 dnolen_: DeusExPikachu: I think a couple people have, are you running into trouble w/ it?

23:05 DeusExPikachu: no, was just curious, I'm just trying to walk through typedo atm, I think I understand geto now

23:06 honestly I got lost with the tutorials walkthrough, i'm just trying to decipher it myself

23:06 dnolen_: DeusExPikachu: well let me know if you have questions, I helped write the type inferencer in that tutorial.

23:41 technomancy: DeusExPikachu: yeah, I didn't find it very illuminating either

23:42 lots of text and samples without explaining much of what was actually happening.

23:47 DeusExPikachu: I found the stuff before the walkthrough helpful

23:48 dnolen_: technomancy: I'm interested in making this simpler, what do you mean by "what was actually happening"?

23:48 DeusExPikachu: but with all the context going through the failures first made me confused

23:48 I think I got it now though, I think to present the material probably explaining the successful base cases first would be a better approach

23:49 also is there a design decision to switch the order of args for geto vs typedo?

23:49 dnolen_: DeusExPikachu: by walk through do you mean the very end of the tutorial?

23:49 DeusExPikachu: yeah, the code walkthrough

23:49 before that is fine imo

23:50 technomancy: dnolen_: "s# represents a successful goal" <= what's s#? a symbol? why's it gen-symmed? I don't see goals being defined until I've already asked myself "wait, what's a goal again" several times.

23:51 why are we calling run*? shouldn't run expand into a macro that calls run* for us?

23:51 dnolen_: DeusExPikachu: I think the order for geto is natural for what it does, I think typedo is natural for what it does as well. But I think that's a minor point.

23:52 technomancy: "The run returns () because typedo returns a failed goal." wait, we just said above that u# represents failed goals.

23:52 DeusExPikachu: dnolen_, I was thinking probably geto on its own, the arg order makes sense, but for the purposes of the tutorial, unless I'm familiar with geto before hand, I think renaming geto and changing the order would make it easier to digest

23:52 dnolen_: technomancy: x# is a valid symbol outside of macro.

23:52 technomancy: it's just skipping around without explaining how each steps relates to the last

23:53 dnolen_: technomancy: it can certainly be improved, feedback like this is great.

23:53 technomancy: dnolen_: it's technically legal, but unidiomatic.

23:54 I suspect that it's breaking a lot of the rules of clojure style because it's a very literal port, but it would help a lot to state that at the top.

23:55 dnolen_: technomancy: sure, but miniKanren programs in general can't be read as Clojure anyhow.

23:55 amalloy: technomancy: perhaps more importantly it means you can't write a macro that expands into a use of s# or u#

23:55 well. you could. ~'u#, but blech

23:56 dnolen_: amalloy: valid point, but u# and s# are there purely for pedagogical reasons, not tools that you actually use.

23:56 amalloy: zoiks. then it seems crazy to pick a pedagogical point that "sounds" like something else (gensyms)

23:57 or...no, you're saying that s# and u# are real things, but are implementation details you wouldn't actually use?

23:57 DeusExPikachu: its namespaced though, I don't see the problem of the notation

23:58 the special semantics of symbol# only apply in a `()

23:58 dnolen_: amalloy: #s isn't valid in Clojure it's valid in Scheme. I could use s or u, but again, to me it's pointless bikeshedding. It's there until the point that people are familiar enough with core.logic that I can remove them or put them in beginners name space.

23:58 amalloy: DeusExPikachu: yes, we've been over that. it's still confusing

23:59 dnolen_: ah. so this is a...remnant from its scheme roots, where you would write #s and #u?

23:59 dnolen_: amalloy: I have to balance beween people who approach core.logic via The Reasoned Schemer and those people who don't.

Logging service provided by n01se.net