#clojure log - Jul 11 2012

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

0:48 noidi: sjl, save the worst error messages along with what they _should've_ said. that would make a great reference for when someone(tm) decides to do something about them :)

0:49 (re: https://twitter.com/stevelosh/status/222910504987926529)

0:50 sjl: noidi: heh, {#"No single method: .* of interface: .* found for function .*" (rand-nth ["You called a protocol method with the wrong arity" "Clojure/Lein fucked up the AOT compilation; run lein clean."])}

0:51 noidi: I don't think you should be AOT compiling anything unless you're doing interop

0:52 at least then you can just restart your REPL when things get weird, and everything gets recompiled

0:52 sjl: noidi: no, this problem persists across repl restarts

0:52 noidi: lein thinks the AOT compiled stuff is done even though I've changed a protocol

0:53 so it doesn't recompile it, and when I try to use the changed version it's still using the old one

0:53 dnolen: sjl: but what triggers AOT in the first place?

0:53 sjl: which certainly isn't going to work

0:53 dnolen: that's a wonderful question

0:53 dnolen: sjl: certainly not Clojure

0:53 sjl: dnolen: https://github.com/sjl/caves

0:54 grep -R aot . returns nothing

0:54 dnolen: sjl: are you re-compiling some namespaces interactively and not others?

0:54 noidi: I generally prefer multimethods to protocols, because they're slightly easier to deal with because of things like this

0:56 sjl: dnolen: okay I can consistently repro it, one sec

0:57 noidi: defmulti has defonce semantics, which is surprising and annoying, but once you know that you can redefine things (using ns-unmap) without restarting the repl

0:57 (well, surprising = annoying when it comes to programming)

1:03 sjl: dnolen: noidi: https://gist.github.com/3088120

1:05 dnolen: sjl: so that only occurs under lein repl, not interactive dev?

1:05 * Raynes has got to implement markdown rendering in refheap.

1:06 sjl: dnolen: if by interactive dev you mean lein swank then oh no, it definitely appears there too

1:06 dnolen: sjl: so this is a bug that exists in your code right now? what's at line 39?

1:06 sjl: dnolen: it's not a bug in my code. if you run 'lein clean; lein repl' the repl works again

1:08 dnolen: that sed call changes the name of the method in the protocol, and updates the places where it's used. The problem is that Clojure thinks the protocol method still has the old name

1:08 noidi: yeah, I can reproduce it

1:08 sjl: so when I try to use the updated name, it explodes

1:08 noidi: when I run "lein repl", it tells "All namespaces already :aot compiled."

1:08 dnolen: sjl: only lein2? or lein1 as well?

1:08 sjl: and by "Clojure thinks" I mean "something in the Clojure/leiningen chain thinks"

1:09 dnolen: sjl: Clojure doesn't AOT by default.

1:09 noidi: sjl, you have caves.core marked as containing the main class for the project

1:09 sjl: dnolen: hm, no idea. I can try it with lein1 if it's not much work to backport the project file I guess...

1:09 noidi: which means caves.core needs to be AOT compiled

1:09 AOT compilation is transitive

1:09 which triggers the compilation of the protocols

1:10 sjl: noidi: Okay, so that explains the AOT compilation, but not the failure to notice updates to the files and recompile.

1:10 noidi: lein only knows that caves.core is AOT'd -- it doesn't know that it should check the other namespaces for modifications and recompile them

1:11 dnolen: noidi: I'm confused as to why lein repl should trigger AOT

1:11 sjl: It know it needs to AOT them the first time...

1:11 dnolen: noidi: regardless of project settings

1:12 noidi: dnolen, that's probably to make lein repl nicer to use with gen-class

1:12 I used to do a lot of lein compile, repl before I noticed that lein does that by default

1:13 sjl, the transitive compilation bit is done by the Clojure compiler. lein just asks it to compile clojure.core.

1:13 so I think this could be considered a bug in lein

1:13 akhudek: I guess you could ask to to AOT the whole project as a not so nice work around...

1:14 of course beware of core.match if you do that, it doesn't work with AOT

1:14 sjl: lol

1:14 alias lein='lein2 clean; lein2'

1:14 problem solved.

1:15 akhudek: that works too :D

1:15 dnolen: akhudek: heh, yes - the warnings has since been added to the repo.

1:16 akhudek: dnolen: I discovered that the hard way :-(

1:16 dnolen: akhudek: sadly no patches yet.

1:17 akhudek: finding AOT bug are a PITA.

1:17 bugs

1:17 akhudek: I was pretty surprised that such a thing could even happen!

1:17 dnolen: akhudek: it easier than you think.

1:17 akhudek: I'll take your word for it. :-)

1:18 dnolen: akhudek: with enough dynamism your code can easily only make sense only at runtime.

1:18 noidi: I'd work around sjl's issue by adding (ns caves.core.Main (:gen-class :impl-ns caves.core)), and in project.clj set :main caves.core.Main

1:18 (or whatever, I never get the ns syntax right, but maybe you got the idea)

1:19 impl-ns does _not_ get transitively AOT'd so its requirements aren't either

1:19 seaword: I'm diving into my first clojure program using ring and can't get the wrap-reload syntax quite right. http://pastie.org/4235725

1:19 noidi: but yes, the AOT stuff is quite a trainwreck at the moment

1:19 seaword: I get this error: IllegalArgumentException Parameter declaration wrap-reload should be a vector

1:19 sjl: noidi: okay it's late, what exactly does that do?

1:19 seaword: Would be grateful for a nudge in the right direction, cheers.

1:19 noidi: sjl, do you have o'reilly's clojure book?

1:20 sjl, the impl-ns trick is mentioned somewhere in it

1:20 sjl: noidi: is that programming clojure?

1:20 noidi: wait a sec, I'll check the book right now

1:20 sjl: or clojure programming?

1:20 lol naming

1:20 ssutch: is there any difference between (defn a->b [x] x) and (defn a [x] x)

1:20 dnolen: akhudek: (def foo (partial bar baz)) was one bad pattern I used.

1:21 sjl: ssutch: ... one is named 'a' and one is named 'a->b'?

1:21 ssutch: that's what i figured

1:21 just wanted to make sure, what is the convention for using a->b?

1:21 dnolen: akhudek: extend-type was also a problem.

1:21 noidi: sjl, check the note on page 338 of Clojure Programming if you have it

1:23 sjl: noidi: the thing about the modification dates?

1:23 xumingmingv: hey guys, any comments on this? http://martinsprogrammingblog.blogspot.de/2012/02/why-is-clojure-so-slow.html

1:23 sjl: I'm quite sure the mtime is getting set when I save the file with Vim...

1:24 xumingmingv: My thoughts: "Get an SSD and don't use Clojure for shell scripts."

1:24 ivan: you can use -Xbootclasspath to reduce the startup time

1:25 that is, -Xbootclasspath/a:clojure.jar

1:25 noidi: sjl, nope, the note about gen-class and transitive dependencies. I'm talking about the o'reilly book with the bird on the cover... :P

1:25 by emerick, carper and grand

1:25 sjl: noidi: oh I have the rough cuts version -- I think the note you're talking about is on a different page for me

1:26 noidi: this thing? http://i.imgur.com/UgQLM.png

1:26 noidi: that's it

1:27 dnolen: xumingmingv: do you have some specific concern?

1:27 noidi: of course, if you don't really need to be able to run "java -jar caves.jar", just drop the :main from project.clj and be done with it >(

1:27 :)

1:27 sjl: noidi: so the solution is to make a special ns that uses some special ns voodoo to only generate one AOTed class

1:27 and then let the rest of the project be unAOTed

1:27 which means protocol definitions will be loaded from the clojure sources

1:28 roughly?

1:28 xumingmingv: dnolen: just feel not good when a language I like marked *slow*

1:28 akhudek: dnolen: why was the partial pattern bad for AOT?

1:28 dnolen: xumingmingv: what languages do you use that are *fast*?

1:28 noidi: sjl, instead of AOT'ing a class _containing_ functions that need stuff in other namespaces (which then get transitively AOT'd), you AOT a class that will, at runtime, load up the impl-ns and call functions in it

1:29 sjl, at least that's my understanding

1:29 dnolen: akhudek: partial combined with instance? I think specifically.

1:29 sjl: ah

1:30 akhudek: ah, interesting. I'll remember to try to avoid that in the project I'm using a lot of AOT in

1:30 sjl: Okay I think that's my limit of JVM bullshit for the night. Time to go to bed.

1:30 xumingmingv: dnolen: I use java at work

1:30 sjl: noidi: btw "Programming Clojure" and "Clojure Programming" both have birds on the covers :P

1:30 dnolen: xumingmingv: apologies I misread what you wrote. Martin (the writer) is actually a Clojure fan, certainly some of what he's says is true - idiomatic Clojure is often slower.

1:31 noidi: sjl, argh :D

1:31 dnolen: xumingmingv: and the community hasn't been proactive about updating the Alioth benchmarks to leverage 1.3 enhancements. We've got 3 more benchmarks to go before we have the full suite competitive w/ Java (and of course Scala)

1:37 xumingmingv: dnolen: thanks for the information

1:38 dnolen: xumingmingv: http://github.com/clojure/test.benchmark

1:38 adu: hey

1:39 is anyone here in the DC area?

1:39 xumingmingv: I found a stackoverflow question talking about this: http://stackoverflow.com/questions/4148382/why-does-clojure-do-worse-than-scala-in-the-alioth-benchmarks

1:39 but i dont quite agree with the accepted answer

1:39 dnolen: xumingmingv: yes, old question. run test.benchmark for yourself and see.

1:40 xumingmingv: better yet submit one of the 3 remaining benchmarks, then Alioth will be update to date and people can go back to complaining about too many parens ;)

1:41 xumingmingv: dnolen: haha

1:46 brainproxy: dnolen: in your study of prolog/datalog, did you spend any time with DES, "datalog educational system"?

1:46 http://www.fdi.ucm.es/profesor/fernan/des/

1:46 dnolen: brainproxy: I've seen it but I've never played around with it.

1:47 brainproxy: okay.. seems a bit harder to find datalog "stuff" vs. prolog books, articles, etc.

1:47 dnolen: brainproxy: to be honest I don't really understand Datalog that well - in fact I'm not even aware of any good explanations of how to implement it that aren't disk oriented.

1:47 brainproxy: i see

1:47 dnolen: brainproxy: I picked Stuart Halloway's brain about this at the last Conj (I'm assuming he was working on Datomic already) and he said the same.

1:48 brainproxy: but clearly they figured something out that works well enough for real queries as well as data structures.

1:48 brainproxy: is datomic a kind of datalog?

1:48 dnolen: brainproxy: it supports datalog style queries yes.

1:48 brainproxy: i mean that's my impression

1:49 I'm interested to understand the crossover between something like datomic w/ datalog style queries and a project like orientdb

1:49 which also has a relational query engine

1:49 akhudek: if you are interested in query compilation/datalog specifically

1:49 brainproxy: but isn't SQL to be sure

1:49 akhudek: I guess I could recommend my collegues recent book on using FOL proof systems for this

1:50 brainproxy: akhudek: link, ISBN?

1:50 akhudek: http://www.amazon.ca/Fundamentals-Physical-Design-Query-Compilation/dp/1608452786

1:50 brainproxy: akhudek: thanks

1:50 akhudek: if you do a google search, parts are available online as part of a class material

1:52 brainproxy: akhudek: cool.. I'm still just getting my little toe wet w/ prolog, but I've saved it for future reference

1:52 akhudek: brainproxy: if you have any questions on the topic, feel free to message me

1:52 brainproxy: thanks!

1:53 akhudek: brainproxy: I'm actively working on an implementation of what is discussed in that book (in clojure no less)

1:53 gerunddev: Is there a channel specifically for core.logic?

1:54 dnolen: gerunddev: here

1:54 brainproxy: dnolen: btw, I found another prolog primer.. http://www.ida.liu.se/~ulfni/lpp/

1:54 it has a much more mathematical approach

1:54 dnolen: akhudek: curious, are you actually building a in memory Datalog?

1:55 akhudek: dnolen: it's a first order logic theorem prover, all in memory

1:55 gerunddev: dnolen: Thanks. Know of any good primers on defne, defna, etc?

1:55 dnolen: brainproxy: you can avoid buying books but the Bratko one and the Sterling Shapiro one are excellent :)

1:56 brainproxy: Bratko 4th ed now covers CLP which is just around the corner for core.logic.

1:56 brainproxy: dnolen: I defeinitely am interested in the Bratko one

1:56 dnolen: akhudek: very cool :) open source one day?

1:56 brainproxy: but a number of comments suggested it's not a good first book

1:56 so I started looking for a "first book"

1:56 akhudek: dnolen: that's the idea :-)

1:56 dnolen: akhudek: sweet

1:57 noidi: sjl, btw. lein has a :skip-aot option to prevent AOT compilation of :main https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L97

1:57 brainproxy: the "Art of.." is supposed to be good for that purpose, but I like reading on ipad and mac, so opted for the book from springer.com, as I could pay and download it

1:57 dnolen: brainproxy: huh, not sure why people said that.

1:57 brainproxy: a lot of my understanding of how to actually use core.logic came from Bratko.

1:57 brainproxy: it's actually why I added the DB functionality right way.

1:57 brainproxy: so I could try the examples :)

1:57 noidi: sjl, I created a bug report for lein about this https://github.com/technomancy/leiningen/issues/679

1:58 brainproxy: interesting... okay, well maybe it would be fine for me to start with, but I'll get to it; also reading a proper Java book now, rather than just absorbing through clojure interop

2:00 as DES is built entirely w/ prolog, i.e. it rides on top of your prolog runtime of choice, i hope to study it as well, to see how a datalog system can emerge from prolog

2:03 gerunddev: Every core.logic demo shows that you can query goals in both directions. But I can't quite figure how to share code to do that.

2:03 dnolen: gerunddev: what do you mean?

2:06 gerunddev: (run* [q] (membero q '(1 2 3))) & (run* [q] (membero 2 q)), but I'd like to be able to use the same relationship with [item coll] then pass a value for one and bind the other to an lvar.

2:07 I thought something like (defne [item coll] (memero item coll)), but apparently I don't grok defne.

2:07 dnolen: gerunddev: defne/a/u are just for pattern matching sugar

2:08 gerunddev: just make a regular function. (defn my-rel [item coll] (membero item coll))

2:10 gerunddev: dnolen: I had gotten the impression that mixing functions and their logic cousins was a bad idea… now I can't even remember where I got that idea.

2:11 dnolen: gerunddev: yeah not true, the whole point of core.logic (really miniKanren) is that the two approaches can coexist.

2:12 amalloy: btw dnolen, what do the -a/e/o suffixes mean? i've been just putting an o at the end of my relation-based function names, but it feels cargo-cult because i don't know why

2:13 Raynes: I wish I had a condo.

2:13 * Raynes slaps his knee

2:13 madsy: Can I somehow set "lein trampoline cljsbuild repl-listen" to inferior-lisp-program in emacs?

2:14 When I do I get "Wrong type argument: stringp, nil"

2:14 dnolen: amalloy: I guess o generally mean the goal is pure, inputs and outputs don't matter.

2:15 amalloy: -a means soft cut, other branches will not be looked at (unlike conde)

2:15 Raynes: dnolen: I'll learn core.logic if you find something in refheap that could make use of it. :D

2:16 dnolen: amalloy: -u mean committed choice. not only with other branches not be looked at, all the goals after the first goal of a clause will only be run once.

2:16 "not only will"

2:16 Raynes: ha! kibit service?

2:16 gerunddev: dnolen: I can't even find what I read that made me think that now.

2:17 amalloy: he's surely missing some chances to use core.match to simplify his dispatch

2:17 Raynes: amalloy: There is so much I could use core.match for.

2:17 amalloy: My problem is that I purposely avoid it because if I had it, I'd use it for everything.

2:17 dnolen: amalloy: to be more specific, conde lines looks like this:

2:17 [(head) ... bunch of other goals ...]

2:17 Raynes: dnolen: That's a damn good idea.

2:18 I'm honestly going to open an issue for that.

2:18 gerunddev: As a famous author once said, "Contradictions do not exist. Whenever you think you are facing a contradiction, check your premises. You will find that one of them is wrong."

2:19 dnolen: amalloy: with conda, if a head succeeds, other [...] [...] are ignored. the remaining goals of the succeeding line can succeed many times (produce many answers)

2:19 amalloy: with condu, if a head succeeds those remaining goals can only produce one answer

2:19 Raynes: dnolen: If I wanted to get the mention of cake out of the core.logic readme, how would I go about that? Open a jira ticket? Ask you to do it for me? My CA is under a non-legal name and I haven't sent in a new one yet, so I can't just give you a patch.

2:19 :(

2:19 amalloy: i've at least figured out how conde/conda behave (still not 100% sure about condu), but i'm wondering what the dang letters mean

2:20 dnolen: Raynes: where do I meantion cake?

2:20 Raynes: dnolen: 'Usage'

2:21 dnolen: core.match, sorry.

2:21 I get your core.things mixed up all the time.

2:21 dnolen: amalloy: condu can be use to implement (onceo g). conda can't. condu can guarantee that g will only produce one solution.

2:22 Raynes: done

2:22 Raynes: Cool.

2:24 dnolen: amalloy: both are used for pruning search so should be used care - they both disable in many instances the ability to run programs "backwards".

2:26 amalloy: okay. i'll plan on continuing to have a great new usage for conda and then eventually rewrite it when i realize i was wrong

2:28 gerunddev: I'm hoping to use logic programming in a schema on read no-sql environment.

2:28 dnolen: amalloy: I believe their inclusion in miniKanren was to show they could get nearly all the functional of "real" Prolog as it's used in practice.

2:28 ssutch: if i just want to return a body as-is from an if exp, what would i do?

2:28 gerunddev: We currently have problems where document structures evolve over time, and writing migration scripts seems to defeat the purpose of using a no-sql datastore.

2:29 dnolen: amalloy: I've found them useful in making it easy to port Prolog. then it's fun to see if cuts can be eliminated w/o slowing things down too much.

2:29 ssutch: eg (if ((a) (b)) c) i want to get ((a) (b))

2:29 gerunddev: What if you could use rules to say, can this be interpreted as something valid?

2:29 amalloy: (or)

2:29 specifically, (or ((a) (b)) c)

2:30 ssutch: sorry, i didn't quite explain well enough

Logging service provided by n01se.net