#clojure logs

2011-07-17

00:25Blackfootcan i update a hierarchy used in defmulti after the defmulti call?
00:28Blackfootoh i see :hierarchy can be a ref. nm
00:45amalloyBlackfoot: see ##(doc derive). if you want to *remove* links in the hierarchy tree, that's probably not a good idea
00:45lazybot⇒ "([tag parent] [h tag parent]); Establishes a parent/child relationship between parent and tag. Parent must be a namespace-qualified symbol or keyword and child can be either a namespace-qualified symbol or keyword or a class. h must be a hierarchy obtained from mak... http://gist.github.com/1087197
00:49Blackfootamalloy: no, wanted to add them. my confusion stemmed from the fact isa? doesn't work recursively through lists
00:49Blackfootbut it does through vectors, so i'm all good
00:49amalloyyeah, i was surprised to learn that vectors have that feature. it's handy
05:25PupenoI followed the instruction on getting started with Emacs with Clojure. I installed Emacs 23.3.1 and the packages. When I run clojure-jack-in it says Starting swank server... and gets stuck there. Any ideas how to find out what's going on? what's the problem? some logs?
05:27bsteuberPupeno: if you don't see error-messages in *slime-events* or *messages*, I'd assume you missed to install the slime-repl elpa package
05:28Pupenobsteuber: no buffer was open at all... I just did M-x package-install and choose clojure-mode
05:29PupenoOK... there were some buffers but not shown.
05:29PupenoProcess swank exited abnormally with code 1
05:29PupenoThat's not a task. Use "lein help" to list all tasks.
05:32Pupenolein repl works on the console.
05:32amalloyPupeno: lein --version
05:33PupenoLeiningen 1.6.0 on Java 1.6.0_26 Java HotSpot(TM) 64-Bit Server VM
05:33amalloyi suspect you have a version from before technomancy added jack-in to clojure-mode
05:33amalloyhm
05:33amalloywell, i don't use lein, but i'm pretty sure that version has support
05:34VinzentPupeno, do you have swank in your :dev-deps?
05:34PupenoVinzent: I don't know what that means, so probably not.
05:35VinzentPupeno, add [swank-clojure "1.3.1"] to your :dev-dependencies in project.clj
05:39PupenoWhere should that project.clj file be?
05:41VinzentPupeno, in the root of the project dir. lein new will create it for you.
05:41PupenoI don't have a project yet, I just wanted to play around... do I have to create a project for slime to work with cljure?
05:42VinzentYes.
05:43Vinzentlein new, then edit project.clj and add necessary dependencies, then lein deps, then jack-in from emacs
05:44PupenoVinzent: how do I tell emacs where the project is?
05:45VinzentPupeno, just open some file from that project, and run jack-in from that file
05:46Vinzent(or you can run lein swank manually, then slime-connect from emacs)
05:47PupenoI got this error now in the swank buffer: https://gist.github.com/1087404
05:50VinzentI think it's something wrong with your project.clj. Take a look at sample.project.clj in the leiningen repo on github.
05:51PupenoVinzent: it was created by lein: https://gist.github.com/1087410
05:52VinzentPupeno, but where the :dev-deps part? http://paste.lisp.org/display/123312 here is a sample
05:53PupenoVinzent: sorry, that was the generated one.
05:54PupenoAnd I did it wrong.... let's try again.
05:56PupenoSame thing.
05:56PupenoProcess swank exited abnormally with code 1
05:56PupenoThat's not a task. Use "lein help" to list all tasks.
05:57PupenoHold on.
05:57Vinzenthave you ran lein deps?
05:59PupenoNope
06:01PupenoSeems to be working now... :)
06:01PupenoAt least *swank* is getting thousands of expressions.
06:01PupenoSLIME!
06:01PupenoThanks Vinzent!
06:04Vinzentno problem :)
06:09tufflaxThis http://pastebin.com/D0kXBcYv takes forever to run. Running (map sk (range 1e6)) takes several minutes. What can I do to speed it up?
06:12PupenoNow I can get started preparing the conference showing how awesome Lisp is.
06:12tufflax...with a doall around the map call of course :p
06:18Vinzenttufflax, btw, in emacs the major part of time usually takes printing results to the buffer. Use (time ...) to know actual running time and *print-length* to avoid printing the whole sequence
06:21Vinzentabout the code itself, sorry I can't advice you anything new: try to use primitive types, maybe unchecked arithmetic operations
06:28tufflaxok, i'll try. thanks
06:28PupenoYay, now it also works in Aquamacs.
06:38minouIm new to clojure and lisp, i want to make a square 2 dimension vector which is gonna be a maze, i want to fill it in a loop with ones or zeroes, can anyone help me to do this? i have trouibles with modifying vector since its not easy to do mutations to state
06:40Vinzentminou, vectors are immutable; if you are really need state, you should read about atoms and refs.
06:41VinzentFirst, write a function that returns new vector filed with ones or zeroes
06:41minoui have one which returns a new vector filled with nils
06:41minoua new matrix
06:42minouits a matrix i mean 2-dimension vector
06:42minouthen i try to fill it through recursion and mantaining the matrix as accumulator variable, but i stuck because i cant do the recursion dont know why
06:43minouit says Can only recur from tail position
06:43minoubut i think i do it only in tail positions
06:44minouis it possible to do it with a while loop or a loop rebinding each time the matrix?
06:45VinzentCompiler doesn't lie; you have call to recur in the non-tail position if it tells you so :) Maybe you understand tail position wrong?
06:45VinzentMaybe it's possible, but it will be a bad piece of code
06:46minouyeah, surely i dont understand what it means....
06:47minoubut its a common piece of code, where can i see something similar?
06:47minoui will google it
06:48VinzentSorry, I can't give you good links about it, but I have definitely seen some blog posts about it
07:34tufflaxminou http://pastebin.com/UniJ1k6q
07:34tufflaxoh, he left
07:44bsteuberweird, I'm using Thread/setDefaultUncaughtExceptionHandler but when I do (Thread. #(/ 1 0)) it won't get called
08:02PupenoIn Slime RELP, how do I get the previous line?
08:02bsteuberPupeno: M-p
08:05PupenoIs there a name to call things that could me macros or functions? For example, "In a Lisp form, the first item is the .... and the rest are the arguments". What would ... be?
08:07bsteubermaybe verb
08:07Vinzentor command?
08:08bsteubercommand sound so imperative to me ^^
08:09frou100You know the socket repl that "lein repl" starts, is there a way for the client on the other end of the socket to get exception messages? Presumably they are stderr and not being sent.
08:09tufflaxPupeno operator maybe
08:10Vinzentwell, then "function" imo would be just fine (to not to overload listener with the details)
08:12bsteuberPupeno: for what do you need it anyways?
08:51Pupenobsteuber: to use the proper term when speaking.
09:05Pupenons is the proper way to create namespaces, and in-ns to switch to them when necessary, is that correct?
09:35bsteuberforfeit liest sich schöner ^^
09:36bsteubersorry, wrong tab :)
10:01raekPupeno: yes
10:01PupenoDoes this short macro make sense: https://gist.github.com/1087614
10:02PupenoIt feels good to code in Clojure again :)
10:02raek(ns refers all vars in clojure.core unless you say otherwise, so if you want to exclude something in clojure.core, using ns instead of in-ns won't work)
10:03Pupenoraek: ok. thanks. :)
10:04raekPupeno: the prints will happen at the times described in their texts, so yes
10:05Pupenoraek: thanks :)
10:15PupenoSo, ` is the same as ' except that it lets you escape things with ~, right?
10:15gfrlogPupeno: it also namespace-qualifies things
10:15gfrlog,['first `first]
10:15clojurebot[first clojure.core/first]
10:15PupenoYeah, I seen that... thanks.
10:15PupenoIs the comma for clojurebot ?
10:16gfrlogPupeno: yes
10:16Pupenook.
10:16mudgewhat does it mean for a var to be defined with ^{dynamic true} ?
10:16gfrlog&['first `first]
10:16lazybot⇒ [first clojure.core/first]
10:16gfrlogmudge: in clojure 1.3 that metadata is required to use the var with (binding ...)
10:16gfrlogpre-1.3 all vars are dynamic
10:17mudgegfrlog: thanks, I search google a lot for an explanation of this and I didn't fine it, do you have a source on the web?
10:17gfrloghmm
10:19gfrloga few brief mentions when I google for "clojure 1.3 ^:dynamic vars"
10:19gfrlogI don't think I've looked for it. I first heard about it when Rich talked about it at the conference last year.
10:21mudgegfrlog: ah thanks
10:22mudgegfrlog: thanks, which event? do you know if there is a video of the talk?
10:24gfrlogmudge: the first Clojure Conj. Rich gave two talks, and it should be the one that was not about hammocks.
10:24mudgegfrlog: ah, thanks
10:24gfrlogmudge: I've not seen it online, but it certainly should be. I'm googling now.
10:27mudgegfrlog: yea, I'm looking for it too
10:27gfrlogI've had no more luck this time then on previous tries. It's a shame too, because I've wanted to relisten to the part about vars. He explains why the change is a performance benefit, and I've forgotten the details of that.
11:03mudgejf
11:09gfrlogclojureql doesn't provide a way to lazily consume a large result-set without holding it in memory, does it?
11:13gfrlogfor that matter maybe clojure.contrib.sql/with-query-results doesn't provide that either :/
11:27VinzentI thought it's just a reference to the sequence, isn't it?
11:28gfrlogyeah. I think I've moved on past that and now the most logical explanation seems to be that my DB is spitting data back faster than clojure can reduce it. But that too seems implausible. :/
11:29gfrlogI do a SELECT * from a 12,000,000 record table and expect to be able to reduce the results without memory filling up
11:31Vinzenthm, maybe query result itself isnt't lazy at all?
11:31gfrlogas best I can tell both libraries do it lazily
11:31gfrlogc.c.sql defers to clojure.core/resultset-seq, which is certainly lazy
11:34amaco/
11:35Vinzentbut maybe data from db are coming in one big chunk, and then it is just wrapped in a lazyseq? (I really don't know, just thoughts)
11:35gfrlogsure, that's theoretically possible. But I would think all the java.sql stuff would be lazy by default...
11:36gfrlogunless for some odd reason there's db-server-side config that needs to take place
11:42gfrlogokay, now I've confirmed that my code isn't even running -- the driver must be eating up the result and not returning.
11:45gfrlogthe internets say the only way to make the mysql-jdbc driver lazy is with special arguments to Connection#createStatement. So looks like I'm dipping into java :/
11:49Vinzenthm, isn't it a candidate for clojureql issues list, what do you think? It'd perfect clojure libs\wrappers made things as lazily as it possible, especially with stuff like databases
11:49gfrlogVinzent: I think clojureql uses c.c.sql, and the issue is at the c.c.sql level
11:50gfrlogthis line would need some extra arguments: https://github.com/clojure/clojure-contrib/blob/6a0483d9e216ca00fc648a4b3673996b76a2785a/src/main/clojure/clojure/contrib/sql/internal.clj#L190
11:50Vinzentah, ok
12:53lnostdal-laptopi really don't understand why 1.3 has gone about this split thing with regards to clojure-contrib in the way it did
12:54gfrloglnostdal-laptop: I don't think that exactly coincides with 1.3...
12:55lnostdal-laptopoh
13:08mudgedoes anyone have any idea when clojure.contrib 1.3 stable release will be out?
13:08dnolen_mudge: there will be no such thing.
13:09mudgednolen: I understand that clojure.contrib will be broken up into multiple libraries
13:09mudgednolen: but I don't when to start using them
13:09gfrlogright away?
13:10mudgegfrlog: they are stable now?
13:10lnostdal-laptopthey are not stable, and not even remotely complete
13:10lnostdal-laptopafaict
13:10Vinzentsome of them are ready to use with clojure 1.2
13:11mudgeshould i look at each individual library to determine its status?
13:11Vinzentyeah, i think so
13:11gfrlogsome of the libraries seem to have not been copied at all
13:11gfrlogI think combinatorics was that way last time I checked
13:15lnostdal-laptopit's quite messy .. "they" should have let the Big Blob be as is; or make it both 1.2 and 1.3 compatible really .. then split it only when 1.3 was out and ready i think ... *shrug*
13:16lnostdal-laptoprelated issue; what replaces print-doc now?
13:17mudgethe good thing about clojure.contrib is it brings everything together nicely -- so you easily know where to look for functionality outside clojure.core
13:17mudgeor outside clojure.jar
13:17lnostdal-laptopi guess one could have that even when things are split up; a sort of meta-package
13:18mudgelnostdal-laptop: yea sounds good, so one could have the big jar with everything, or be able to break it up if one wanted to
13:18lnostdal-laptopyup
13:23mudgehey, does anyone understand how the unifycle works? http://fogus.me/fun/unifycle/
13:23dnolen_mudge: yes
13:24dnolen_mudge: but unifycle is now https://github.com/clojure/core.unify, or you can use https://github.com/clojure/core.logic
13:25mudgednolen_: thanks, i don't understand the example, so trying to figure it out
13:26gfrlogmudge: do you know how unification works?
13:26dnolen_mudge: core.unify is stand alone unification library, core.logic is more efficient and brings a logic engine.
13:26mudgegfrlog: not really
13:27tomojdoes it work with arbitrary lists? doesn't need to be infix?
13:27dnolen_mudge: unification takes two terms and attempts to make them equal.
13:27tomojright, so it doesn't care what's an operator or what's data?
13:28mudgehow can something make terms equal? they are equal or they are not
13:28gfrlogmudge: the terms can have variables
13:29dnolen_tomoj: unification will work w/ whatever data structures the implementation supports.
13:29gfrlogI expect he was asking about unifycle specifically
13:29gfrlogmudge: the symbols starting with ? in the example are variables
13:30mudgegfrlog: yes
13:30gfrlogcomparing the values in the two structures may imply a value for a particular variable, e.g. in the example ?x has to be 5
13:30dnolen_mudge: (unify '(?x 1) '(2 ?y)), unification will succeed with ?x bound to 2 and ?y bound to 1. (unify '(?x 1) '(2 2)) will fail.
13:31mudgednolen_: yes, i see
13:31gfrlog(unify '(?x ?x) (3 4)) will also fail
13:31mudgeby failing, does that mean it couldn't unify them?
13:31gfrlogcorrect
13:32gfrlognotice in the example that not all variables have to be bound in the result
13:33mudgegfrlog: yes, and are variables bound to functions too? or not? in (?x *) is ?x bound to * ?
13:34gfrlogI don't think there's a concept of function. It's just working with literals -- lists, symbols, numbers, etc
13:34mudgegfrlog, okay then (?x *) means that ?x is bound to the * symbol
13:35gfrlogmudge: no, it's a two-element list, with a variable and a symbol
13:36mudgegfrlog: so are variables only bound to numbers then? (?x *) is different then (?x 5) ?
13:36gfrlog(?x *) and (?x 5) cannot be unified, because * is different from 5
13:36gfrloga variable could be bound to a list as well
13:36mudgegfrlog: thanks
13:37gfrlog(?a ?b ?c) could unify with ((1 2) 3 ?z)
13:37mudgegfrlog: i see, thanks
13:37gfrlogyep
13:38mudgegfrlog: would this unify: (?a ?b ?c) and (* + /)
13:38gfrlogyes. The result would be (* + /)
13:38mudgegfrlog: cool, thanks
13:39gfrlogI should qualify this by saying I've never tried unifycle, I'm just going off of what I think I know about unification
13:39mudgegfrlog: so then the unifer just reduces two equal lists into the simplest form?
13:39mudgegfrlog: okay
13:40gfrlogmudge: well, the main thing it does is look at the varibles and see if there is any way the two lists can be shown to be equal by binding the variables one way or another
13:40gfrlogI suppose we're using the word "equal" in a kind of loose sense
13:40mudgegfrlog: yes, thanks
13:40gfrlogmaybe a better way to say it is that unification tries to find the least-specific structure that matches both of the inputs
13:41gfrlogwhere specificity refers to how much of the structure is a variable
13:41mudgegfrlog: yes, thanks
13:42gfrlogso when unifying (?a 2 ?x) and (3 ?b ?y), you get something like (3 2 ?x), where the last one is left as a variable because it can be
13:43mudgegfrlog: yes, with your help understanding this, i now understand the example give at http://blog.fogus.me/2010/09/27/unifycle-a-unification-library-for-clojure/
13:44mudgegfrlog: yes, i see that it tries to get rid of every variable if it can
13:44gfrlogmudge: good. The complicated part is when a variable occurs more than once within an expression
13:45gfrlogthat constrains the unifyer to match the same thing in both instances
13:45mudgegfrlog: that is interesting
13:45gfrlogthe primary context I've encountered unification in is natural language processing
13:45mudgegfrlog: was it helpful?
13:46mudgegfrlog: it would be interesting to see cases where a unifier would be useful
13:46gfrlogmudge: to the folks doing it, I'm sure :) I was just taking a class
13:46dnolen_gfrlog: mudge: unification is central to logic programming of all kinds.
13:47mudgegfrlog: now I have taken a class in unification, so thanks
13:47kephalemmm… unification is one of the more sophisticated logic-based pattern matching techniques
13:47gfrlogmudge: in NLP, the sort of structures handled were features of works, like tense, person, number, etc.
13:47gfrlogthe unification would happen when a rule of the language said that two words had to "agree" to some extent
13:47dnolen_https://gist.github.com/1083967
13:48dnolen_^ unification allows this tiny bit of code to type check, type reconstruct, and even produce the terms that satisfy the types.
13:49mudgednolen_: interesting
13:50mudgeI guess it is useful enough to go into clojure.core
13:51dnolen_mudge: you can build knowledge bases, http://stackoverflow.com/questions/6713424/how-do-i-express-this-logic/6719627#6719627
13:51kephalecan anyone point me to the place in the clojure source where binding expressions are evaluated for things like {:keys […]}, (:syms […]}
13:52gfrlogkephale: open the clojure.core source and grep for :syms? :)
13:53gfrlogkephale: one occurence: https://github.com/clojure/clojure/blob/f86db9cc68773dd3e4a166c1ff7b81e4a98aa602/src/clj/clojure/core.clj#L3403
13:55kephalegfrlog: aha, thanks. I've been using {:keys […]} a lot, so I figured I should know how that code works.
13:55gfrlogkephale: looks complicated to me :)
13:56gfrlogkephale: you know it's equivalent to {foo :foo, bar :bar, ...}, right?
13:58kephalegfrlog: yes, but I could probably take advantage of that a bit better and generate a map like that instead
13:58lnostdal-laptop..and another thing with 1.3; why doesn't it assume *these-things* are dynamic after printing a warning? .. it defaults to the non-safe option
13:59gfrloglnostdal-laptop: it defaults to the new behavior
13:59gfrloglnostdal-laptop: it'd be pretty weird if it changed its behavior based on the structure of your symbol
13:59lnostdal-laptopit should default to the new behavior, but not when the *'s are used .. it should warn (as it does) then, and do the safest thing ...
13:59lnostdal-laptopbased on history; not really
14:00gfrlogclojure 1.2 doesn't change its behavior based on the structure of your symbol
14:00gfrlogit's just a naming convention
14:00lnostdal-laptopi know this
14:00lnostdal-laptopthere everything was the same
14:00lnostdal-laptopthat's not the issue ofc.
14:00lnostdal-laptopusing non-dynamic variables is an optimization
14:01mudgewhy is core.unify in the list of 1.3 Contrib projects when it is part or going to be part of clojure.core ?
14:01mudgehttps://github.com/clojure/core.unify
14:01lnostdal-laptopi mean using them by default . .one that potentially breaks things and it certainly breaks things *like-these* more than once
14:01gfrloglnostdal-laptop: in 1.2, all vars are assumed to be dynamic. in 1.3, all vars are assumed to be not dynamic.
14:01lnostdal-laptopyes, i know this, gfrlog ..
14:02gfrloglnostdal-laptop: I think it might have been better called 2.0, because of all the breaking changes
14:02lnostdal-laptopbut it warns based on naming style in 1.3 .. and it should also fall on the safe side after printing that warning
14:02gfrlogbut I _don't_ think it should start examining your code for naming conventions and changing its behavior based on them
14:02mudgethe list of Contrib projects is here: http://dev.clojure.org/display/design/Contrib+Projects
14:02mudgeand core.unify is listed there for some reason
14:03kephalegfrlog: (fn keys-map [m] (zipmap (keys m) (map keyword (keys m))))
14:03gfrlogkephale: yes?
14:04kephalejust noting what I ended up with
14:04lnostdal-laptop(..the reason it should fall on the safe side of things is that this would lead to waaay less breakage..)
14:05gfrloglnostdal-laptop: why doesn't the warning take care of that?
14:06gfrloglnostdal-laptop: what you're proposing is a much more complicated change
14:06chrissbxIs there a "=" that returns false for separately allocated objects with the same contents? (pointer equality comparison)
14:06Chousukeidentical?
14:07chrissbxThanks
14:07gfrlog&(identical? (hash-map 4 5) (hash-map 4 5))
14:07lazybot⇒ false
14:07chrissbxIs there a "=" that only works for numbers, i.e. complains if the arguments are not numbers?
14:08gfrlogprobably not. You could write your own with a precondition.
14:08Chousukehm
14:08Chousukeisn't that ==
14:08Chousuke,(doc ==)
14:08clojurebot"([x] [x y] [x y & more]); Returns non-nil if nums all have the same value, otherwise false"
14:08gfrlog,(== () ())
14:08clojurebotjava.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to java.lang.Number
14:08gfrlogI learn more if I assume I know the answers to all the questions and then get corrected.
14:09chrissbxPerfect, thanks.
14:09gfrlogChousuke: does == do anything that = doesn't?
14:10chrissbxWell it asserts the types.
14:10chrissbxUseful for error checking.
14:10gfrlog:| That hardly seems like a reason to include a separate function in core
14:10gfrlogwhat if I want a version of assoc that only accepts maps?
14:11chrissbxEquality predicates are especially sensitive to the type issue, since they silently return false in buggy cases.
14:11gfrloghmm
14:12gfrlogit still only solves one instance of the problem
14:12gfrlogwhat if I want an == for keywords?
14:13chrissbxAgreed.
14:13chrissbxOther lisps still prominently provide number comparison, though.
14:13chrissbxMaybe because math is especially likely to break?
14:13chrissbxWhatever. I'm happy for the ==.
14:14dnolen_,(= 1 1.0)
14:14clojurebottrue
14:14gfrlogdnolen_: I even tried it with a ratio
14:14dnolen_this behavior is changed in 1.3.0
14:14dnolen_(= 1 1.0) is now false
14:14dnolen_(== 1 1.0) is now true
14:14gfrlogoh geez
14:14chrissbxheh:)
14:15gfrlogcan we please pull a Torvalds and call it 2.0? there's still time.
14:15chrissbxMaybe that was the reason :)
14:15gfrlogthis is embarrassing
14:15gfrlogit's not just poking at the big-ints anymore
14:16dnolen_gfrlog: these changes have been sitting around for like 8 months, plenty of time to get used to it.
14:16dnolen_threads galore on the ML and here on rationale
14:16gfrlogdnolen_: for those who are paying attention maybe
14:16gfrlogjust because there's a reason to break things doesn't mean you shouldn't indicate it in your numbering
14:17dnolen_gfrlog: if you think 2.0 and 1.3.0 distinction is significant. bikeshedding non-sense IMO.
14:19gfrlogdnolen_: so why do we have dotted version numbers at all? why not just increment an integer whenever something changes?
14:20dnolen_gfrlog: there's discussion on the ML about this as well, I don't have much more to say about it.
14:20gfrlogdnolen_: okay I'll go look. thanks.
14:20lnostdal-laptopit sure does have breaking changes
14:21dnolen_lnostdal-laptop: so did the other releases.
14:21lnostdal-laptopi guess 1.2.0 --> 1.2.1 didn't, then
14:22gfrlogdnolen_: in arithmetic?
14:25chrissbxWhat's the standard way to open a file for input (or output), to get at the stream.
14:26gfrlogchrissbx: check in clojure.java.io
14:28chrissbxThanks
14:29raekchrissbx: clojure.java.io/{input,output}-stream for binary (byte based) files and clojure.java.io/{reader,writer} for text (character based) files
14:37chrissbxI'm getting "java.io.BufferedReader cannot be cast to java.io.PushbackReader" when using reader with read
14:43raekyeah, you have to wrap the result of reader with (PushbackReader. )
14:43chrissbxAha.
14:43raekthere isn't any function for that in clojure.java.io unfortunately
14:44chrissbxWeird, it seems to me that reading s-expressions from a file would be one of the most standard things a Lisp system would do.
14:45chrissbxI'm finding myself not only implementing a read-all, but also binding java to get the offered functions from two clojure libraries to work together.
14:45VT_Entitythere's no easier way?
14:46chrissbxWhy is '`a evaluated to (quote user/a) and not to (quasiquote a)? Is quasiquote expanded by the reader, or is quasiquote still evaluated at macro expasion time but does quote not prevent macros from being evaluated?
14:48VT_EntityI think quasiquote means hold off until the macro is invoked.
14:49VT_Entityso, you can still shuffle around the code as data until you invoke the macro.
14:49VT_EntityI could be wrong though, still new at this.
14:54raekchrissbx: it is expanded by the reader
14:55chrissbxIn other lisps, (quote expr) means that expr is treated as a literal constant, i.e. unmodified. So I was expecting the result of (quote (quasiquote a)) to be (quasiquote a) as it is in Scheme.
14:56chrissbxNow I guess Clojure "mangles" the symbols in the reader (to add the namespace to them), whenever it sees quasiquote.
14:57gfrloghow do I run the tests in a clojure/maven project like clojure.java.jdbc?
14:57gfrlog`mvn test` doesn't seem to find anything to do
14:57VT_EntityI think you need to explicitly invoke auto gensym, no?
14:58raek,(read-string "`foo")
14:58clojurebot(quote sandbox/foo)
15:14gfrlogforking project, changing, compiling with maven, uploading to clojars: very hard.
15:23gfrlogI guess it's more the fact that I was doing two libs at the same time
15:23gfrlogand don't know how to use clojure/maven
15:25amalloychrissbx: reading files into s-expressions is pretty easy with slurp + read-string
15:28chrissbxamalloy: I need all expressions, so I wrote a read-all, but that expects a stream as an argument
15:28chrissbxread-string only reads 1 expr
15:29chrissbxAlso, why slurp the whole file into memory when reading expressions lazily from a stream would do.
15:30chrissbxBut if you meant to say that read-string and slurp are the reasons that the rest is totally incomplete, then I see the point.
15:32gfrlogso after an hour of furious patching I finally got clojure.java.jdbc + clojureql to read lazy result sets from mysql
15:33chrissbxgfrlog: interesting; when I last looked at the mysql protocol (or was it just libmysql?) about 5 years ago, it didn't support lazy reading of result sets.
15:33amalloygfrlog: "I learn more if I assume I know the answers to all the questions and then get corrected." so true
15:33gfrlogamalloy: :)
15:34gfrlogchrissbx: apparently it supports it if you pass particular arguments to [prepare|create]Statement, and then do this hacky thing with fetchSize
15:34chrissbxOk, will have to look at it some time. Thanks for the hints.
15:34gfrlogamalloy: it registers in my brain as embarrassment, which subconciously motivates me to remember
15:34gfrlog...or suppress
16:00StayInSkoolhi #clojure! what are good examples of (simpler for starters) open-source clojure (and compojure) apps to learn from?
16:01StayInSkoolso far I've found either really basic or rather complex examples
16:01amalloyStayInSkool: https://github.com/dbyrne/4clojure ?
16:03StayInSkoolamalloy: hmm, that sounds like a good starting place. thanks!
16:04amalloyStayInSkool: and feel free to bug us (okay, mostly just me these days) in #4clojure if you need some hints
16:06StayInSkoolthanks :D
16:10seancorfieldclojure.java.jdbc 0.0.4 on maven central - fixes reflection warnings, fixes transaction handling on Error thrown, code cleanup
16:11seancorfieldgfrlog: sounds like you had some problems with c.j.j?
16:11seancorfieldi use it with mysql all the time - anything i can do to help?
16:11seancorfieldor was it more around clojureql (which i don't use i'm afraid)?
16:14gfrlogseancorfield: it was regarding reading a ResultSet lazily
16:15gfrlogapparently the mysql driver only does it if you add some arguments to (.prepareStatement ...)
16:15gfrlogseancorfield: so I did this kind of thing: https://github.com/USCSoftware/java.jdbc/commit/7f9d45d2e88b82a4d28b706b4ebe8696827348ef
16:15seancorfieldah, i'm working on exposing machinery to allow users to operate on the PreparedStatement before it is executed
16:16gfrlogseancorfield: that might do the trick, I haven't looked at the methods on PreparedStatement to see if the configuration can be done _to_ it as well
16:17seancorfieldyeah, it may need just exposing as a way to pass in a function that creates the PreparedStatement appropriately
16:17seancorfieldwhoever design the Java API for the JDBC stuff should be taken out and shot - it's horrible to work with!
16:18lucianseancorfield: why not use clojureql?
16:19gfrlogi patched clojureql as well; it creates its statements on its own
16:19seancorfieldlucian: i maintain clojure.java.jdbc
16:19lucianoh
16:19seancorfieldyeah, clojureql is kinda standalone
16:20seancorfieldi tried it but didn't really like the approach
16:20luciani see
16:20seancorfieldat world singles we have some pretty gnarly joins and stuff and it was not very intuitive to read the clojureql forms for those
16:21seancorfieldalso, since i'm introducing clojure to an existing project and the team all know SQL, using c.j.j was a much easier transition for them
16:25gfrlogseancorfield: a simple first-try could be to allow (with-query-results) to take a PreparedStatement as well as a vector
16:25lucianright
16:32seancorfieldthat means the calling code has to do the uglies with the connection to create the PreparedStatement - i think i'd rather pass a map of parameters that the code uses to figure out the right call of .prepareStatement on the connection...
16:34amalloyseancorfield: isn't the point here that the client wants to do something complicated? better to let them do it, when they want control
16:35seancorfieldyeah, it's a matter of making a clean interface for the most common needs
16:35seancorfieldi haven't decided quite what's best yet
16:37seancorfieldpassing a map of {:type :forward-only :concur :read-only :fetch-size Integer/MIN_VALUE} seems like a nicer approach than making the user deal with the java directly, yes?
16:40amalloyseancorfield: that sounds fine, i'm sure. i don't really know what's going on here in general, but it seems to me like you should also give them a way to pass you an actual object they built, in case there's some feature you don't expose
16:41seancorfieldyes, probably that too
17:28ihodes(def π (Math/PI))
17:28ihodes,(def π (Math/PI))
17:28clojurebotDENIED
17:30amalloy&(let [π (Math/PI)] (* 2 π))
17:30lazybot⇒ 6.283185307179586
17:52chrissbxHm. I'm looking for a way to reformat Clojure code (wrapping and indentation); clojure.pprint has been suggested to me, but how am I supposed to make it indent it right?
17:52chrissbxIsn't there something that would just do it out of the box?
17:53chrissbxI've already written a Clojure printer in my Scheme-to-Clojure converter, if I'll have to figure out all rules to make the Clojure code wrapped and indented right myself anyway,
17:53chrissbxI can just as well add this to my printer.
17:55chrissbx(With the added benefit that I wouldn't be tied to using Clojure / the JVM as part of the conversion.)
17:55chrissbxYes, sounds like I could as well go that route;
17:55chrissbxexcept that I don't know any emacs code that does the wrapping.
17:56technomancyyes, that's trickier. so far I've punted on wrapping.
17:56_simonfHola - my first day using clojure. I'm having trouble seeing the clojure.contrib.math jar that I put in ~/.clojure. Running "CLOJURE_EXT=~/.clojure java -cp /usr/local/downl/clojure/clojure/clojure.jar clojure.main" does not help.
17:57chrissbxIt seems a bit funny to me how much stuff Scheme systems got done that the Clojure community doesn't seem to have solved yet.
17:57technomancychrissbx: is it really all that surprising? scheme has had many, many more decades.
17:58chrissbxI still find it surprising, because my impression is that there are more people using Clojure than all the Scheme systems together, but maybe that's a wrong impression.
17:59technomancy_simonf: you might have a better time starting at http://dev.clojure.org/display/doc/Getting+Started
17:59chrissbxThing is that most Scheme systems got things like these implemented independently, each with only a tiny community.
17:59technomancy_simonf: any time you're invoking "java" directly you're probably making things more complicated than they need to be, and there are a lot of bad docs out there, including clojure.org
18:00_simonftechnomancy: yeah, I already stumbled into bad docs
18:01chrissbxAlso, of course it's funny because Hickey *could* just have made Clojure a dialect of Scheme and borrowed much code.
18:01chrissbxBut then it wouldn't have been new and people wouldn't have flocked to it maybe. Dunno.
18:01_simonftechnomancy: yeah, I already stumbled into bad docs is about IDEs, which is less interesting. My Ubuntu's clojure is old, so I figured I'll build the jars from github.
18:01chrissbxAnyway, back to writing code.
18:02technomancyclojurebot: lein tutorial?
18:02clojurebotlein is http://github.com/technomancy/leiningen
18:02technomancy_simonf: ^^ I recommend starting there.
18:03technomancybuilding the jars by hand can be a bit of a rabbit trail
18:04_simonftechnomancy: I'm not sure what you mean. I use vim, so this page tells me to use vimclojure, which is a syntax highlighter. Does not tell me anything about getting the actual language.
18:05technomancy_simonf: generally it's coupled with a build tool
18:06technomancyhttp://lisp4fun.blogspot.com/2010/02/leiningen-and-vimclojure.html might be relevant
18:09Scorchin_simonf: lein gives you a simple build tool to hide away many of the issues involved with loading jars. It also simplifies a number of common tasks such as loading up your app into the repl, compiling, running tests and packaging
18:10_simonftrying now...
18:15raek_simonf: re your original problem: clojure.contrib.math is not included in clojure itself, so you need to add [org.clojure/clojure-contrib "1.2.0"] as a dependency in your project.clj and run "lein deps" to fetch it
18:15raek(assuming you are using clojure 1.2.0 or 1.2.1)
18:16_simonfraek: yup, I just figured this out
18:16Scorchinraek: He wasn't using lein to begin with. He's switching to use it now though, so that should be extremely useful!
18:16_simonflooks like in 1.3 individual contrib libraries are split out
18:16_simonfit's not clear how to specify them individually in project.clj
18:19technomancy_simonf: I don't know if math has been upgraded to 1.3 yet
18:19technomancyif you're starting out you should use the latest stable release, not the betas
18:25_simonfok, I got the compile cycle working, but this means I lost the REPL mode. I have to rebuild my jar after every edit
18:31raek_simonf: while developing its more common to keep a repl open and reload files when you change them instead of doing the compile cycle
18:31_simonfraek: ok
18:32raekit's simpler to develop in the repl if you think of the source files as holding the definitions of the functions you use in the repl (or in the -main function) rather than a script that is executed
18:33raek_simonf: if you have a file in src/myproject/core.clj, you can load it and enter its namespace with (doto 'myproject.core require in-ns)
18:33raekuse (require 'myproject.core :reload) to reload it
18:33amalloy(which is shorthand for (require 'myproject.core) (in-ns 'myproject.core)
18:34raekfor this to work you should also have a (ns myproject.core) at the top of the source file
18:34lnostdal-laptophm, i guess using transients inside agents won't do since agents execute using any random thread from a pool?
18:34_simonfhm - so I have to know which files I want to reload
18:34_simonfin the Python world, I'm mostly developing by running unittests until they pass
18:35_simonfthat seems to minimize overhead
18:35brehaut_simonf: (use :reload-all 'namespace)
18:36brehaut_simonf: or you could run lazy test which watches your source files and reloads them and runs tests automatically
18:37brehaut_simonf: or lein interactive
18:37amalloylnostdal-laptop: yeah, i'm afraid so
18:37_simonfawesome, reload-all works. Thank you everyone!
18:38_simonfI must say, Clojure is easier to get into than Haskell
18:38amalloyyou'd need to allocate a future and manage it yourself
18:52ihodes_simonf: Haskell is awesome though--i think you need just a bit more activation enegery with Haskell than you do with clojure to get going
18:52tufflaxHm, why it this so slow http://pastebin.com/bVHRKaKz
18:55tufflaxis*
18:56amalloytufflax: you're boxing and unboxing integers a lot
18:56tufflaxok, how can i avoid that
18:57tufflaxnot use an int array?
18:57amalloytypehints in the appropriate places, except i don't know what places those are. dnolen will know
18:58bsteubertufflax: which clojure version?
18:58tufflax1.2.1
18:58bsteuberexpect 1.3 to be a lot faster in these things
18:58tufflaxok, thats nice
19:34haploidcan defn define sequential execution without let, dorun, etc ?
19:35brehaut((fn [x] (prn "x is" x) (inc x)) 1)
19:35brehaut,((fn [x] (prn "x is" x) (inc x)) 1)
19:35clojurebot"x is" 1
19:35clojurebot2
19:35brehauthaploid: ^
19:36brehauthaploid: long version: functions have an implicit do
19:36brehauthaploid: dorun is quite different to do
19:36haploidok, cool, thanks
19:40haploidone other thing - does anyone know off the top of the head what "simpledb.core" is? trying to understand the noir-blog source, but google is not helpful here with understanding what the dependencies are/do
19:43brehauthaploid: perhaps an api for amazon's simpledb ?
19:45haploidyeah, could be, except the main libraries for simpledb in clojure appear to be "sdb" and "rummage" - and it wouldn't make sense that the noir folks would make having an aws account mandatory to run their example app.
19:45haploidweird
19:46brehauthaploid: https://github.com/ibdknox/simpledb
19:47brehauthaploid: its a trivial in memory db
19:47brehautthat serializes to a file using clj forms
19:47haploidah awesome, thanks.
19:47haploidwonder why google couldn't find it.
19:48brehautpresumably because amazon's simpledb is much more talked about
19:48brehautand google isnt friendly to precious code-ish queries (by default anyway)
19:49brehauts/precious/precise/
19:49lazybot<brehaut> and google isnt friendly to precise code-ish queries (by default anyway)
19:57Scriptorthere's always google code search
19:59gfrlogseancorfield: I left before the discussion with amalloy. I support both options -- I think your idea is good because the java.sql interface is pretty limited, so it might be that there's only a small set of things somebody could do anyhow. But amalloy's idea is good in principle, and probably can't hurt.
20:00brehautand in this case knowing to check ibdknox's github
20:15StayInSkoolwhat's the point of doing something like (fn add-five [x] (+ x 5)) 3) ?
20:16StayInSkoolisn't that still an anonymous function? what's the point of add-five?
20:16gfrlogStayInSkool: you can recurse
20:16StayInSkooloooooh
20:16StayInSkoollike in javascript
20:16gfrlogStayInSkool: true true
20:17StayInSkoolperfect, thanks!!
20:17gfrlogno probalo
20:17Scriptor,(class (defn foo [] "foo")
20:17clojurebotEOF while reading
20:17Scriptor,(class (defn foo [] "foo"))
20:17clojurebotDENIED
20:18gfrlogScriptor: come on man you know it ain't gonna let you def nuthin
20:18Scriptor:(
20:18gfrlogit's a var right?
20:33amalloygfrlog: yes, clojurelang.Var
20:33gfrlogamalloy: what was the thing I was going to say to you if you were around?
20:35amalloy$help mail
20:35lazybotamalloy: Send somebody a message. Takes a nickname and a message to send. Will alert the person with a notice.
20:35gfrlogamalloy: a notice? when?
20:36amalloygfrlog: next time they're spotted logging in or saying something
20:36gfrlogso if they're already logged in then it waits till they say something?
20:36amalloy$mail gfrlog like so
20:36lazybotMessage saved.
20:36gfrlogcome on lazy bot what did he want to tell me?
20:36gfrlogoh I bet it's in some other erc window
20:36gfrlogdamn you emacs
20:37amalloyyeah he PMs you. mails are definitely not public
20:37amalloyC-x b lazybot, probably
20:37gfrlognot seeing anything there actually
20:37amalloyhm
20:37amalloy$mail amalloy test
20:37lazybotMessage saved.
20:37amalloytest test
20:38gfrlog$mail amalloy giggle
20:38lazybotMessage saved.
20:38amalloygfrlog: well you were wrong, he PMs me just fine
20:38amalloyerrr, except i didn't get that one. puzzling
20:38gfrlogPM here stands for Prime Minister, right?
20:39amalloyoh, interesting. apparently he won't notify you of new mail more than once every five minutes
20:39amalloybut you can still read them by sending him the message "mail"
20:39gfrlogah there got it for the first time
20:40gfrlogmaybe cuz I used '/msg lazybot ...'
20:40gfrlogand erc likes that
20:40amalloydunno
20:40gfrlogI'm not going to technomancy's emacs talk, so I will never learn how all this works.
20:46amalloygrrrr. i love clojure, but exception-handling is often so much easier with mutable state
20:48technomancyamalloy: is it really mutable state you want, or just more flexible exception types?
20:49amalloytechnomancy: i'm not sure. i suspect there'd be an easy way to do it with slingshot, but since i'm not used to having better exceptions i'm not sure what it would be
20:50amalloymy current problem is i need to react in similar ways to a number of different conditions. i'm calling into a library which throws a "dumb" exception, and if it does i need to include part of my current environment (a loop binding) in the eventual result
20:51amalloywhich sounds like either making that binding a mutable semi-global, or catching the internal exception and then throwing something different
20:51technomancynah, slingshot can include the local context as part of the exception
20:52amalloyso, catch the dumb exception, and then throw a smart one which will automatically have local context bundled into it?
20:52technomancyoh, I didn't catch (har) that a separate library was throwing
20:53technomancyyeah, it's awkward when you have this divide between your code and dumb exception land
20:53technomancywhich I feel is part of why error-kit and c.c.condition didn't take off
20:53amalloyi mean, the library is clojail, which i have write access to. but either way, it wouldn't have access to the *calling* code's environment in order to include into the exception
20:54technomancyit sounds like chaining may be the way to go... and it sounds like that would be true in a mutable system too
20:54amalloytechnomancy: chaining as in re-wrapping the exception?
20:55technomancyright
20:55amalloyi don't even need to throw an exception. i know how to handle the error, i just have to unify the various error cases
20:56amalloymaybe i can just rewrite this whole function. it's pretty gross anyway
21:21zakwilsonSomething that's awesome about Clojure is that the usual programming advice of hiding the underlying implementation and exposing an unchanging API is a little different. Usually, the API and underlying implementation can just be based around Clojure data structures, and if the implementation changes those data structures still make a reasonable API.