#clojure logs

2011-06-21

01:02jebberjebwhy is clojure named clojure?
01:03amalloyjebberjeb: closures, in java? *shrug*
01:53duncanmla la la
02:14sunniboquestion: i have a txt file that contains several Korean words. How can i extract only Korean words? any tips?
02:15CozeyHi - are you using jetty7? Or is clj community sticking to 6 ?
02:37raeksunnibo: that sounds like something that is hard to do 100% correctly. but one approach could be to split the input into words and filter those that contains any Hangul characters. do you think that would work?
02:59sunniboraek: the question is changed: i need to extract all Hangul characters. and i'm wondering the 'filter' part. Can i distinguish Korean chars from other chars?
02:59sunniboI saw a solution using Character/getType. The return value 5 represents 'Other Letter'.
03:00sunniboIf i assume that my txt file contains English alphabets and Korean characters only, I think this solution is not bad.
03:01raeksunnibo: my idea was to check whether the character is in a certain Unicode range, like "Hangul Syllables
03:01raek" range AC00–D7AF
03:01raek,(<= 0xAC00 (int \가
03:01clojurebotEOF while reading
03:02raek,(<= 0xAC00 (int \가) 0xD7AF)
03:02clojurebottrue
03:02sunnibothat sounds good.
03:02raeksunnibo: you can find the code charts for hangeul in the rightmost column here: http://www.unicode.org/charts/
03:02sunniboah. how can i get a character vector from a string?
03:02raekeach PDF begins with the range
03:03sunnibo"가나다" -> [\가 \나 \다]
03:03raeksunnibo: you can use a string like a sequence directly
03:03sunnibooh
03:03raek,(seq "가나다")
03:03clojurebot(\가 \나 \다)
03:03sunnibothanks a lot
03:03raek,(filter #(<= 0xAC00 (int %) 0xD7AF) "x가y나z다w")
03:03clojurebot(\가 \나 \다)
03:05raek,(filter #(any? (fn [c] (<= 0xAC00 (int c) 0xD7AF)) %) ["hello" "가나다" "åäö"])
03:05clojurebotjava.lang.Exception: Unable to resolve symbol: any? in this context
03:05raek,(filter #(some (fn [c] (<= 0xAC00 (int c) 0xD7AF)) %) ["hello" "가나다" "åäö"])
03:05clojurebot("가나다")
03:06sunniboyeah. wonderful code.
03:07sunnibookay. i extract all Korean characters now. and how can i remove duplicates? by set?
03:10sunnibo(\가 \나 \가) -> (\가 \나)
03:11sunnibo,(distinct '(\가 \나 \가))
03:11clojurebot(\가 \나)
03:25raeksunnibo: ah, just read the "i need to extract all Hangul characters" part...
03:26raeksunnibo: sets are good.
03:27raek,(into #{} (filter #(<= 0xAC00 (int %) 0xD7AF) "long text that may contain 가나다 some hangeul characters"))
03:27clojurebot#{\가 \다 \나}
03:28raeksunnibo: for the file I/O part, use (clojure.java.io/reader "filename" :encoding "UTF-8") to open a text file (you can skip the encoding part if it's UTF-8)
03:29raekdistinct uses a set internally to remember elements already seen. the distinct elements are left in-order, unlike in sets
03:30raek,(set "가나가")
03:30clojurebot#{\가 \나}
03:31sunniboraek: yes, i didn't say. txt files use UTF-8.
03:32sunnibothanks always.
04:06shtutgartIs there a function to remove nth element from the vector?
04:08shtutgartCurrently I use (remove nil? (assoc vector idx nil)) for this purpose (assuming vector doesn't have nils)
04:14raekshtutgart: no. vectors do not provide a non linear time way of changing the number of elements (inserting or deleting) in the middle
04:25raekwhy are you using indexes here? when you remove an element from the middle, the indexes of all element after the middle will change
04:26raekI think there is a simpler solution to the problem than using vectors and indexes
04:31shtutgartraek: idx is the index of an element that I want to delete
04:32shtutgart(my-remove-fn [:a :b :c] 1) => [:a :c]
04:35raek,(let [v [:a :b :c], i 1] (into (subvec v 0 i) (subvec v (inc i))))
04:35clojurebot[:a :c]
04:36raekshtutgart: you can do it like that, but I don't know if it is "what you really want"
04:36raek~xy
04:36clojurebotxy is http://mywiki.wooledge.org/XyProblem
04:36raekshtutgart: where does the index come from?
04:38shtutgartraek: from java code; they give me an array and an index
04:40raekshtutgart: what are you supposed to do with the array? modify it in place? return a new one?
04:41shtutgartI need to operate on item with given index and all other items, than return single value
04:43raekis this a ListModel or something similar?
04:43shtutgartI think your solution with subvecs completely fits me
04:43raekin that case, I guess you have to do this
04:44shtutgartraek: no, it's Vector
04:44raekjava-vector?
04:44shtutgartyes, from java.util
04:45raekI'm sorry, I
04:45raek'm confused
04:46raekare you changing a clojure vector, a java vector or a java array that you get from somewhere else?
04:46raekor are you implementing an interface or something?
04:48fliebelAny news about the Clojure survey?
04:49shtutgartSorry, I've sayed about array because recently it actually was array, but then it was changed to java.util.Vector. Anyway, the first thing I do is casting it to a clojure vector
04:51shtutgartraek: so I'm getting a java vector (that was array yesterday) and changing a clojure vector :)
05:04khaliGdid anyone attempt the icfp contest with clojure this year?
05:22CozeyHi, how to call a super method from overriden one, when using :gen-class?
05:37hoeckCozey: you add an :exposes-methods {super-method-name exposed-name, ...} to the :gen-class option and in you code invoke: (exposed-name this ...) to call the exposed super method
05:38Cozeymhm. thanks - i'll try that
05:38hoeckCozey: see also (doc gen-class)
05:57mrBlissfliebel: that rotating wheel on your blog drives me mad :-)
05:59fliebelmrBliss: Why? Imagine how the Python guy feels then.
08:48solussd_What's going on here: (type (conj (seq (vector 1 2 3)) 4))
08:48solussd_,(type (conj (seq (vector 1 2 3)) 4))
08:48clojurebotclojure.lang.Cons
08:48solussd_I expected a persistentVector, I got a Cons. :/
08:49solussd_I thought seq returned a seq(hence) on a collection, not change its type..
08:49ejacksonbut you called seq - so its no longer a vector ?
08:49solussd_*sequence
08:49solussd_,(type (seq [1 2 3]))
08:49clojurebotclojure.lang.PersistentVector$ChunkedSeq
08:50ejacksona seq is a seq, use into to put it back into a vector
08:50solussd_but it is?
08:50solussd_it seems that conj is returning a Cons
08:50clgvsolussd_: just use ##(type (conj (vector 1 2 3) 4))
08:50sexpbot⟹ clojure.lang.PersistentVector
08:51solussd_clgv, I know my example isn't what I'd really do.. just wondering why I end up with a Cons if I make it a seq before conj'ing
08:52clgvsolussd_: you switch to a different type by using seq - it's a sequence after that
08:52solussd_conj is suppose to do the 'optimal' thing- is adding to the left side of a (seq (vector 1 2 3)) optimal?
08:53ejacksonyup
08:53solussd_interesting
08:53raeksolussd_: seq returns a sequential view of the collection. the fact that it comes from a vector is abstracted away.
08:53clgvand clojure can only append to the front of the sequence via a cons when you call 'conj
08:53dnolen,(type (cons 4 '(3 2 1)))
08:53clojurebotclojure.lang.Cons
08:53dnolen,(type (let [x (cons 4 '(3 2 1))] (rest x)))
08:53clojurebotclojure.lang.PersistentList
08:53solussd_raek: does it still add to the underlying vector's tree?
08:54clgvsolussd_: no it does not
08:54raeksolussd_: in a singly linked list, appending to the front is the only reasonable append you can do
08:54raeksolussd_: no
08:54solussd_raek: ok, does (seq [coll]) actually turn it into a singly linked list?
08:54solussd_i.e. does it copy it?
08:54raek,(conj (rseq [1 2 3]) :x)
08:54clojurebot(:x 3 2 1)
08:55raeksolussd_: no. it's lazy.
08:55raekyou will create new seq objects when you traverse the seq, but they won't be created at the first seq call
08:56raeka vector seq is basically just a reference to the vector and an index
08:56solussd_ok. so a seq from a vector is a lazy singly linked list and when I add to it I'm linking to the front of the lazy list? :)
08:56raekwhen you call rest on it you get a new vector seq with the index incremented
08:56raeksolussd_: yes
08:57solussd_ok- and if I (into [] (conj (seq (vector 1 2 3)) 4)), is that at least efficiently "adding" the 4 to the underlying vector and returning it?
08:57raek...and when you call first on it you look up that index in the vector
08:58solussd_i.e. is it just returning a conj on the original vector?
08:58raeksolussd_: well, you construct a whole new vector
08:58solussd_raek: but does it share structure?
08:58raekthat does not share structure with the old one
08:58solussd_ah..
08:58raekseqs can share tails
08:59raekvectors can share, well, to the left
08:59solussd_,(vec (conj (seq (vector 1 2 3)) 4))
08:59clojurebot[4 1 2 3]
08:59raekand internal structure
08:59solussd_so that doesn't share structure either?
08:59raekno
09:00raekonly the operations that operate directly on the vector can result in a vector that shares structure
09:00solussd_so, the moral of the story is, don't use functions on vectors that return seqs unless you are planning on just iterating through the vector
09:00raekvec cannot tell that the seq is comming from a vector
09:00solussd_that makes sense. thanks!
09:01raekconj, pop, peek, assoc all return a vector that shares structure
09:03solussd_I was originally trying to understand how a PersistentQueue works under the hood- being a seq + vector
09:07clgvsolussd_: there is an explanation for that in "The Joy of Clojure"
09:07solussd_clgv: yeah.. that's what I'm reading and I'm not sure I "get" what happens when you pop
09:08clgvsolussd_: ok, maybe you just have to reread the paragraph. I thought it was quite well explained
09:09solussd_clgv: My questions is, when all the items on the seq are popped off, does it *then* wrap the vector in a new seq?
09:09raeksolussd_: yes
09:10raekit always has one vector and one seq
09:10solussd_well, then that makes sense. Juspt reread the paragraph.. makes sense.
09:10clojurebotIt's greek to me.
09:12raek[] (1 2) --> push 3 --> [3] (1 2) --> pop 1 --> [3] (2) --> push 4 --> [3 4] (2) --> pop 2 --> [3 4] () --> pop 3 --> [] (3 4) --> [] (4)
09:12solussd_thanks. that was the picture in my head
09:13clgv*g* ascii symbols in ones head isn't a good omen, is it? ;)
09:15raekhrm, displaying the seq and vector in the (1 2) [3 4] probably makes more sense.. :)
09:15solussd_clgv: I see in ascii.. don't you? doesn't everybody?
09:15clgvsolussd_: lol. :D
09:15solussd_:/
09:15clgvI can only see binary ;)
09:16clgvit's a gene defect
09:16solussd_maybe an evolutionary advantage
09:16stuartsierraThere are only 10 kinds of people...
09:17solussd_thanks everyone- back to rereading joy of clojure. I read it as a MEAP, but figured I should read the final. :D
09:18solussd_then someone needs to write a more advanced clojure book (or I need to find a day job writing clojure). :D
09:18raekThere are only 11 kinds of people...
09:18clgvstuartsierra: exactly :D
09:20raek(Those who understand Gray code, and those who do not.)
09:27CozeyHow can i invoke ant task from cake task?
09:28bendlasCozey: in leiningen you use lancet, I suppose you do the same in cake
09:29Cozeybendlas: oh? does lein uses lancets tasks as well?
09:29bendlasCozey: it does. some of them, anyway
09:30Cozeycake's ninjudd written something like unce for ant support in cake. but this doesn't look like an active project, and i can't get it to work under clj 1.3
09:30Cozeyuncle*
09:30bendlasright
09:30bendlasi remember
09:30Cozeymaybe lancet is the way to go
09:31bendlasyou should be able to use lancet anyway, after declaring it as a dev depencency
09:32Cozeyyep. i'm just starting to think that i should betray cake for lein... last few days all the missing cake features i stumbled into are working on lein
09:33Cozeyboth seem active..
09:35clgvCozey: lein is pretty active, I'd say.
09:35bendlasi feel that lein mostly is the canonical choice now
09:36bendlasonly (+) for cake is persistent JVM
09:36Cozeydoesn't lein has a plugin for that ?
09:36clgvthe only annoying thing when using lein is, that the uberjar building takes pretty long. dont know how that is in cake.
09:36bendlasOTOH (-) who wants to install ruby for building their clojure project?
09:37Cozeynever tried - i upload the dep jars separately so i don't have a huge uberjar which uploads long
09:37clgvwell, since I mentioned it: does anyone know a way to speed up building uberjars in leiningen?
09:38bendlasclgv: I found the ant task for packaging jars a bit faster
09:38bendlasmostly because it does less (i guess)
09:39bendlasuberjar always rebuilds before packaging (IIRC)
09:40bendlasif you want to try that, it's pretty easy with lancet:
09:40bendlas1) get filesets for application jar and all the libs
09:41bendlas2) call lancet/jar with it
09:41bendlass/it/them/
09:41sexpbot<bendlas> 2) call lancet/jar wthemh them
09:42Cozeywhat about lein + additional maven tasks?
09:42Cozeyunder cake it's impossible for instance to add a maven plugin to deploy to a server (like cargo plugin)
09:43Cozeybecase cake just uses maven to fetch deps, and always overwrites pom.xml
09:43Cozeyis this possible under lein ?
09:43bendlaslein writes a pom.xml
09:44Cozeyis it possile to have a pom-plugins.xml or something like it ?
09:44clgvhumm, it would probably speed up the whole uberjar taks if it had a prebuild dependency uberjar where my code just has to be added to
09:44Cozeyin general to integrate maven tasks with lein ones?
09:44dnolenhmm w/ groundess analysis and DCG optimizations I think core.logic can almost completely close the gap with SWI :D
09:45bendlasCozey: I'm not aware of something like that
09:48bendlasclgv: don't think so
09:48bendlasi think most of the time is spent in this line https://github.com/technomancy/leiningen/blob/master/src/leiningen/uberjar.clj#L75
09:49bendlasso .. try adding ':disable-implicit-clean true' to you project.clj
09:50clgvbendlas: nope, I deactivated that one
09:50clgvbendlas: I think most is spent in unzipping and zipping my dependencies
09:50bendlasclgv: and uberjar still takes significantly longer than plain jar?
09:51clgvhm yeah, I have already quite a lot of dependencies
09:52clgvbendlas: humm can I convince lein uberjar to run multithreaded?
09:52clgvthat would speed up compilation and unzipping as well
09:54bendlasclgv: doesn't look like it supported that
09:54jcromartieWhy is there both filter and keep?
09:54clgv;(
09:54bendlasbut that's probably the reason for the ant task being faster
09:54clojurebotReason is , and ought only to be the slave of the passions, and can never preted to any other office than to serve and obey them -- Hume
09:56bendlasjcromartie: filter works with a predicate and returns the original items
09:57bendlaskeep yields the results of the function
09:57bendlasalso filter filters by truthiness
09:57bendlasand keep keeps by non-nillnes
09:58jcromartieah, I missed that part
09:58jcromartie(the results)
09:59jcromartiekeep has a rather lengthy implementation in the Clojure source code
10:00jcromartiefor what is essentially (filter #(not (nil? %)) (map f coll))
10:01jcromartiemaybe it's more performant
10:01bendlasjcromartie: it does, but most of it is for chunked seqs
10:02bendlaswhich are indeed a perf opt
10:02jcromartiedon't filter/map already handle chunks
10:04bendlasthey do
10:05jcromartiewell I won't doubt the rhickey
10:05bendlasbut the impl of core fns is often unidiomatic for sake of performance
10:05jcromartieyeah
10:05jcromartieI can see how it would be, for keep
10:06clgvbendlas: using parallel execution has to be patched in here I guess: https://github.com/technomancy/leiningen/blob/8047e90837e0d8019a1f37d59901759966c7dfed/src/leiningen/compile.clj#L253
10:09bendlasclgv: maybe, but I suspect massive amounts of work would be wasted every build
10:09clgvbendlas: why?
10:09bendlasbecause the compiler goes to dependency namespaces and compiles them to
10:09clgvoh damn^^
10:10clgvwell so this is a problem of the compiler.
10:10bendlasdunno, is the compiler smart enough to recognize up-to-date .class files?
10:11clgvit has to analyse the project and build a topological sort of the source file dependency tree - then it could easily compile in parallel
10:12bendlasyep
10:12bendlasI suspect nobody is going to touch that, until C in C is underway
10:13clgv&(doc clojure.core/compile)
10:13sexpbot⟹ "([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath."
10:13clgv$source clojure.core/compile
10:13sexpbotclojure.core/compile is http://is.gd/INNeeK
11:40edoloughlinIs there a way of getting a directory listing without using Java?
11:42teromWhy would you want one?
11:42manutter,(doc line-seq)
11:42clojurebot"([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."
11:43edoloughlinterom: Purity? There are other non-Java file i/o functions
11:44manutterwell it was a nice thought
11:44teromedoloughlin: well you could then define some wrapper functions of our own, couldn't you?
11:45edoloughlinBack to (. something) - I just don't like the look of it...
11:46Fossithere was some file-list or such in ex-contrib iirc
11:48Fossifile-seq
11:48Fossiit's not recursive though iirc
11:49edoloughlinFossi: great! Don't need it to be recursive. Thanks.
11:52dnolenedoloughlin: to do many useful things in even in pure Clojure you better get used to (. something)
11:53dnolenI use (. something) when necessary and I'm not using *any* Java libs at all.
11:55manutterargh file-seq not line-seq
11:55manutterI was close
11:57dnolenfliebel: as it usual turns out I was entirely wrong about interleaving search being the bottleneck in core.logic. I always want to blame interleaving search :)
12:09fliebeldnolen: Why do you want to blame it, and why wasn't it the problem?
12:11dnolenfliebel: heh because I didn't have any better ideas? the issue is when you're parsing you really don't want to create a logic var and a unification operation on every single character you parse, which is why it was crazy slow.
12:11fliebeldnolen: So how does Prolog get away with not defining symbols and unification for every symbol?
12:12dnolenfliebel: groudness analysis. When parsing you know the input is completely ground, you don't need unification or logic vars at all.
12:13dnolenfliebel: it's actually kind of cool, basically if we have ground terms we can do some tricks behind the scenes to defer to regular Clojure fns.
12:14fliebeldnolen: That'd awesome yea
12:15dnoleninstead of nrevo taking taking 4100ms to reverse a list 1e3 times, it takes 18ms if we see that an argument is ground! Just like it does in Prolog.
12:35technomancybendlas: so are you interested in speeding up uberjar? =)
12:47ilyakhi *
12:47ilyakmy ccw in eclipse doesn't build my clojure files
12:47ilyakIt did for a brief period, but no longer
12:47ilyakAny ideas on how to make it build those?
12:48fliebelcemerick: Ah, there you are! I've been hitting refresh on your blog all day :P ... at least checked twice.
12:48ilyak(I mean compiling them to some directory)
12:49cemerickilyak: The builder only runs when you have a REPL running associated with the project.
12:50cemerickfliebel: don't stress, probably no results until Thursday-ish
12:52ilyakI started repl
12:53ilyakHow do I make it compile something?
13:03amalloy&(doc compile)
13:03sexpbot⟹ "([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath."
13:04ilyakObviously I want that to just happen when I use an IDE
13:06technomancyAOT compile or just regular compile?
13:10ilyakjust regularly compile (gen-classes) especially
13:10ilyakBecause I have code that depends on those gen-classes in runtime
13:10technomancygen-class requires AOT compilation
13:11technomancyif you do that from your IDE your project is going to have serious portability issues
13:12technomancyyour IDE should delegate that functionality to your build tool
13:15cemerickIt does (or, can); there are maven, gradle, and ant builders for Eclipse.
13:16CozeyIs putting clojure files directly under src/ is the only option in lein? Where should I put java sources, static web files, web.xml etc ?
13:16technomancyCozey: you can customize :source-path
13:17technomancyCozey: you can keep java in a separate path or in src/, whatever you please. not sure about the webby stuff.
13:17Cozeyok thanks - and how will this the be packaged? is there some source file / doc to read about it?
13:18Cozeyit depends how lein will war-pack it
13:18technomancywell that's up to the lein-ring plugin
13:18technomancyfor the built-in stuff "lein help tutorial" should cover you
13:19Cozeytutorial - thanks - i need that. I just left cake behind :'-/
13:26Cozeywhy even with sucessful tasks I get That's not a task. Use "lein help" to list all tasks.
13:26Cozey?
13:27technomancynever heard of that before. context?
13:27Cozeywait - i just noticed i have lein 1.3.1 installed in local/bin - it must be that
13:27Cozeyyep
13:28chouserargh!
13:30chouserstuartsierra: is it possible that lazy-test may consider two sets to be unequal if they are in a different order?
13:31chouseroh wait, maybe it's my fault. :-]
13:35amalloychouser: when i had trouble with set equality, it was because (not= (int 1) (long 1))
13:35amalloywell. they *are* =, but they don't hash the same
13:36Cozeytechnomancy: does lein have something like 'context' or 'profile' ?
13:37technomancyCozey: I don't know what that means.
13:37technomancyamalloy: fixed in 1.3 iirc provided you're not using java methods
13:38Cozeytechnomancy: a profile could be a specific configuration for running a project and packaging it: for instance a different sets of db configuration files, etc
13:40technomancyCozey: that's typically done by the classpath; you can put config in test-resources/ vs resources/ depending on if you want it in development vs the final product
13:40Cozeyok - and if have have a few flavours of the final product ?
13:41technomancydepends on how you're deploying it, I guess
13:51TimMc,(.hashCode (long 1))
13:51clojurebot1
13:51TimMcamalloy: Do you mean -1?
13:52chouseramalloy: ah, thanks.
13:52amalloy&(#{(long 1)} (int 1))
13:52sexpbot⟹ nil
13:52amalloyTimMc: ^
13:52TimMcAh, weird.
13:52chouserin my case I've got two things that look like maps, but one is a reify I made with broken hashCode and equiv
13:52chouserso definitely my fault.
13:53amalloychouser: i kinda think clojure.core/hash-set has a broken equiv
13:53chouserthat number-hashing problem is fixed in 1.3
13:53TimMcWhat's going on with that example, amalloy?
13:53TimMcThe .hashcodes are the same.
13:54Cozeytechnomancy: my setup is a bit strange - but i guess i'll just use lancet to generate wars - thanks!
13:54amalloyTimMc: i didn't look deeply into it. i'm guessing it tests with .equals rather than RT.equiv
13:54chouser& (= (long 1) (int 1))
13:54sexpbot⟹ true
13:54TimMcOK
13:54chouser& (.equals (long 1) (int 1))
13:54sexpbot⟹ false
13:54__name__& (== (long 1) (int 1))
13:54sexpbot⟹ true
13:54TimMcAh, so the hashes collide properly, but the equality check is bad.
13:55TimMcSeems likely.
13:55amalloyTimMc: yeah, just checked
13:55amalloyuses Util.equals, not Util.equiv
13:55amalloyin APersistentMap.java
13:59amalloyTimMc: actually the code is more labyrinthine than i thought; i'm now not actually sure i found that code that's to blame
14:03dnolenamalloy: that's a numerics issue, not a equals/equiv issue. and it's resolved in 1.3.0 as chouser said.
14:04amalloydnolen: cool beans
14:05amalloydnolen: fwiw, transliterated yesterday's java to clojure, and it's only about 5-10% slower
14:06dnolenamalloy: nice! that seems about right, 1.2.X right? seems like 1.3.0 has the 5-10% perf boost to make up the difference.
14:06amalloyyes, 1.2.1
14:06amalloyi tried 1.3 briefly but had some weird issues so gave up
14:24gfrlog`is there a standard ring middleware for the classic _method hack?
14:28seancorfield__Clojure got a little mention in Rod Johnson's keynote but he was a little dismissive of "language experiments" on the JVM
14:34dnolenseancorfield__: anything specific?
14:44seancorfield__dnolen: no, it was just his off-hand comments about non-java languages on the jvm - and he feels that java is the last breakout language, everything else will always be minority
14:45chouserreally? did he mention JavaScript?
14:45seancorfield__but he did tell his (mostly) java dev audience that java devs need to get used to learning new languages frequently :)
14:46seancorfield__at one point he commented that using noSQL datastores involved writing a lot more code than using RDBMS (in the context of hibernate / jpa)
14:46seancorfield__my response (on twitter) was that he's just using the wrong technology :)
14:52dnoleni found it interesting that 4square now has 150K of Scala.
14:52dnolenI can't imagine a Clojure project ever having that much code.
14:53ilyakWhy? If it's properly structured
14:54ilyakFor example, you might have a task framework and hundreds of tasks
14:54hiredmanthat is a lot of code
14:55dnolenilyak: if it's properly structured I don't see how you could *ever* get to 150K of Clojure.
14:55ilyakI once had a CMS which was 150k lines java
14:55seancorfield__150k lines of java is not big tho
14:55ilyakI managed to bring it down to something like 45k
14:55hiredmanour clojure code base at work is only 20,071
14:55technomancyI wonder how many people they have
14:55ilyakThere are some hairy features that mean a lot of code
14:56dnolen150K of anything should be enough to make anyone raving mad.
14:56chouserhiredman: wow, that's a *lot* of clojure
14:56technomancycould be spread across multiple codebases
14:56ilyakI've recently implemented one feature in clojure, and it's 600 lines
14:56technomancyhiredman: with tests?
14:56ilyakMaybe I can factor out some common code, but it won't compress much
14:57ilyak(counting all lines with wc -l, of course)
14:57hiredmantechnomancy: yes
14:57hiredmanwithout comments, blank lines, etc
14:57hiredmanusing cloc
14:57hiredmanchouser: yes
14:58TimMcCount the open parens. :-)
15:03wastreli sawa guy with a lisp t-shirt today
15:03wastrel(loop (print (eval (read))))
15:04wastrel^^^ the t-shirt
15:04stuartsierranice
15:10hugodhiredman: cloc supports clojure? or just generic lisp?
15:10hiredmangeneric lisp
15:10hiredmancloc --force-lang=lisp,clj
15:13hugodpallet totals 26,994
15:16dnolencore.logic 3451
15:16hiredmanhugod: to be fair pallet now seems to contain most of what was the jclouds clojure api
15:17hiredmanor I guess not, just abstractions on top of jcloud's
15:17hugodhiredman: I would say the latter
15:18hiredmanstill a lot of code
15:18hugod17823 without tests
15:44TimMcwastrel: (-> (read) (eval) (print) (loop)) :-P
15:44wastrelthat is not what the shirt said :[
16:01gfrlog`(->> (read) (eval) (print) (do (recur)) (loop []))
16:01gfrlog`that almost works :/
16:02chousergfrlog`: cool! what breaks?
16:02gfrlog`chouser: it's the diff between -> and ->>
16:02gfrlog`you want one for (do) and the other for (loop)
16:03gfrlog`,(doc read)
16:03clojurebot"([] [stream] [stream eof-error? eof-value] [stream eof-error? eof-value recursive?]); Reads the next object from stream, which must be an instance of java.io.PushbackReader or some derivee. stream defaults to the current value of *in* ."
16:03hiredmanyou can switch mid-stream
16:03gfrlog`oh I didn't know read was a function
16:03gfrlog`hiredman: please tell me what you mean and my code will become so much nicer.
16:03hiredman(-> (read) (eval) (print) (do (recur)) (->> (loop [])))
16:04gfrlog`ah of course; it's a bit of nesting but it's still very nice.
16:04gfrlog`I am humbled for never having thought of that.
16:07chouser(-> (read) eval println (do (recur)) (->> (loop [])))
16:07gfrlog`chouser: does (read) play nice with (eval)?
16:07hiredmanreally tou want prn
16:07gfrlog`when I run that at the repl I don't think (read) returns
16:07hiredmanyou
16:08chouserhiredman: yes
16:08hiredmanor pprint
16:08hiredmanif pprint didn't print vars ridiculously
16:08chouserooh
16:09gfrlog`anybody know if the original form is valid in clisp or scheme?
16:09chouserbah, pprint doesn't flush
16:11gfrlog`okay, so it works as long as I don't run it from a repl :)
16:12gfrlog`(ns foo) fails though
16:13chouser(fn -loop [_] (-> (read) eval prn -loop))
16:13cemerickWould it just be cheating to define a function loop*?
16:13cemerickchouuuuuuuuuuuuuser!
16:13chousercemerick: mua-ha-ha
16:14gfrlog`cemerick: loop* takes care of the recuring?
16:15technomancyprn is underrated
16:15gfrlog`(inc prn)
16:15sexpbot⟹ 1
16:15technomancyespecially for inserting debugging statements; if you use prn for debugging exclusively it's a lot easier to grep for stuff you accidentally left in
16:15cemerickgfrlog`: I misspoke — a separate loop* macro would make the (almost) original (loop* (print (eval (read)))) form "just work"
16:15gfrlog`cemerick: right.
16:16gfrlog`technomancy: and you use (println) for normal output?
16:17technomancyright
16:17gfrlog`yeah, that's how I use them too
16:18Raynestechnomancy: If only I'd remember to grep.
16:18technomancypre-commit hook can do it
16:22gfrlog`cemerick: could cheat even harder and exclude clojure.core/loop from the ns, and just call the macro (loop) :)
16:22gfrlog`I guess at that point you could cause almost any form to do anything you want.
16:23cemerickgfrlog`: feh, I forgot that loop* was the actual special form for loop. You can redefine loop freely; no need to exclude.
16:25chouseroh, nice. (fn loop [_] (-> (read) eval prn loop))
16:25chousercemerick: good call
16:25gfrlog`chouser: that'll fill the stack, right?
16:25chouserthat's T-shirt-worthy
16:25chousergfrlog`: yep
16:26Raynestechnomancy: Good idea.
16:26gfrlog`the best repls are ticking time bombs
16:26chouserso only a thousand or so commands before the JVM quits on you
16:26gfrlog`gives a human side to the repl; it needs a break.
16:28arohnerchouser: that makes a good #clojure_is, as well
16:28chouserhm, maybe!
16:29chouserwell, except that's not the real repl, thank goodness
16:29arohneryeah, but it's a repl that will fit in a tweet
16:29chouserheh
16:30gfrlog`heck you could probably fit two repls in a tweet
16:30gfrlog`four?
16:30gfrlog`,(count "(fn loop [_] (-> (read) eval prn loop))")
16:30clojurebot39
16:30chousergfrlog`: tweet it and I'll RT
16:31chouseror TimMc should
16:31gfrlog`truedat
16:32chouserpity about needing a dummy value when called
16:32chouserbut [&[_]] is too scary
16:33gfrlog`(fn loop ([] (loop nil)) ([_] (-> (read) eval prn loop)))
16:33gfrlog`and then it's no longer pretty
16:34chouserright
16:35cemerickThose that prefer to see the (mostly) original forms might like: https://gist.github.com/99f34654a5ec443834d6
16:36gfrlog`cemerick: I am surprised loop* works that way
16:36cemerickwhy?
16:36clojurebothttp://clojure.org/rationale
16:36chouserheh
16:36gfrlog`cemerick: I guess I assumed it was a function
16:36gfrlog`guess it's not
16:37gfrlog`also because the source of clojure.core/loop has so much stuff in it before it gets to loop*
16:37cemerickloop is a macro already, but that's an impl detail so that destructuring and such can be folded into loop
16:44RaynesHeh, Leiningen is on homebrew. Whataya know.
16:44RaynesI guess cake is too.
16:45cemerickscary
16:46edoloughlinI have a (def some-var (fn-that-gets-data)) in a .clj file I'm (require)'ing but (fn-that-gets-data) isn't called. Do I need an explicit (init) fn in that file?
16:53mabeswhy would renaming my jar cause the Main-Class to be undefined? (java.lang.NoClassDefFoundError) The manifest-file doesn't look like it depends on the jar name...
16:53mabessome fundamental jvm issue I don't understand I'm sure...
16:53cemerickedoloughlin: Either the file you want to load isn't actually being loaded, or fn-that-gets-data is being called, but doing something you're not expecting.
16:54Raynescemerick: You've seen me in person: would I look decent with green hair?
16:55cemerickedoloughlin: that is to say, no, you don't need an (init) fn (not sure what that would do you in general). If fn-that-gets-data is accessing a database or something, then having that happen when the file is loaded is generally not recommended, tho.
16:55cemerickRaynes: I'm not sure I would ever recommend green hair to anyone.
16:56cemerickThat said, it would look perfectly good on you. :-)
16:56RaynesSo far, you're the only person I've asked that didn't just say "do it".
16:56RaynesI was thinking of making an "I'm with @stuartsierra t-shirt" and dying my hair green before the Conj.
16:57RaynesMove the ending quote to wherever it is appropriate.
16:57RaynesGood thing I don't mismatch parentheses as well as I mismatch quotes.
17:00edoloughlincemerick: Thanks. It was at the bottom of a chain of (require)s that turned out to be broken. It's just (slurp)ing data from a text file.
17:04redingerRaynes: We joked about doing the green hair last year
17:04redingerIt's a joke that's been made this year, too
17:04redingerI doubt any of us will do it :)
17:04edoloughlin(declare) can't be used for non-public functions? A little inconvenient.
17:06Raynesredinger: I'm actually going to. I'll do it for all of you. I'll be the martyr.
17:07redingerYou should make sure Stuart's going to do blue this year. I haven't confirmed that yet
17:08RaynesHe should try pink.
17:09cemerickedoloughlin: (def ^:private foo) will do the same thing.
17:09stuartsierraPink is not my color.
17:10stuartsierraAnd green would make me look like a zombie.
17:11RaynesI bet he'd find it amusing that in my IRC client, his name is pink.
17:11TimMcgreen here
17:12wastrelgreen
17:12wastrel^5 TimMc
17:12wastrelRaynes: you're pink tho
17:13RaynesYou're olive green.
17:13edoloughlincemerick: Thanks.
17:17edoloughlincemerick: Doesn't seem to do what I need. I just wanted to forward-declare a private fn so I can keep all privates at the bottom of a file.
17:19hiredmanedoloughlin: if you use declare + defn- I think you should be fine
17:20edoloughlinhiredman: I tried that but I get a compile error.
17:26hiredmanoh really, which one?
17:28edoloughlinvar fn-name is unbound, when I try to call it
17:29edoloughlinJust checked, and it works in the REPL(!)
17:29edoloughlinAre there any gotchas with (declare) and namespaces?
17:34manutteredoloughlin: are you by any chance using your private fn inside a macro?
17:36edoloughlinmanutter: Had the same thought. The call was wrapped in a (dbg) macro but I've removed it and still get the same error.
17:36manutter,(macroexpand '(declare foo))
17:36clojurebotDENIED
17:37manutterclojurebot: :P
17:37clojurebotPardon?
17:37manutterOk, local repl: (macroexpand '(declare foo)) ==> (do (def foo))
17:39manutterdeclare isn't really doing anything fancy, hmm
17:39edoloughlinmanutter: Don't want to waste your time. The simple case works for me in the REPL. It's something specific/weird with my code. I'll bang away at it…
17:40manutteredoloughlin: np, I'm just killing time atm
17:45edoloughlinmanutter: Appreciated.
17:50edoloughlinmanutter: If you're still killing time and don't mind noob-Clojure, I've extracted the problematic code from my project: https://gist.github.com/1038986
17:51hiredman(def templates (get-templates "template-dir"))
17:52hiredmanyou are calling it before it is defined
17:52manutteryeah, the def happens immediately
17:52edoloughlinhiredman: I thought that's what (declare) is for?
17:53hiredmandeclare lets you reference a var before it is defined, not actually use it's value
17:53edoloughlinOy!
17:53edoloughlinThanks.
17:53hiredman(declare foo) (defn bar [] (foo 1)) (defn foo [x] (inc x))
17:54edoloughlinOne more, small step on the path to Enlightenment.
19:53ndimiduki have a question while debugging a multimethod dispatch
19:54ndimidukmy dispatch function looks like: (fn [a b & c] [(type a) (type b)])
19:54ndimidukand i installed a default method: (defmethod foo :default [a b & c]
19:54ndimiduk {:default [(type a) (type b)]})
19:55ndimidukfor debugging anyway
19:55ndimidukso invoking foo with parameters i expect to dispatch correctly hits my :default and prints the vector
19:56ndimidukbut when i remove the :default i get an exception No method in multimethod 'foo' for dispatch value: clojure.lang.LazySeq@bc83857c
19:56ndimidukthis is unexpected.
19:57dnolenndimiduk: were you expecting a silent failure?
19:57ndimidukmy method implementations are installed against vectors of classes
19:57ndimidukand i'm expecting isa? to correctly handle class hierarchies
19:57ndimidukwhich it does when i invoke it at the repl
19:58ndimidukdnolen: no, i was expecting dispatch to work the way i expected ;)
19:58dnolenndimiduk: so you're handling lazyseq ?
19:59dnolenwow Clojure 1.3.0 beta
19:59ndimiduktechnically yes. i'm dispatching against vectors of classes
19:59ndimidukso, [String Integer], for instance
19:59dnolenndimiduk: but where is the lazyseq coming from? it must be coming from somewhere.
20:00ndimiduki presume it's the vector itself
20:01ndimidukoh, curious
20:01ndimidukuser> (isa? [] clojure.lang.LazySeq)
20:01scgilardiI tried your dispatch function and passed 3 3 and 3 (long 3) and got the right behavior
20:01scgilardilike "no dispatch value for [Integer Integer]" for 3 3
20:01ndimidukuser> (isa? (type []) clojure.lang.LazySeq)
20:01ndimidukfalse
20:01hiredmancorrect
20:01scgilardi(clojure 1.2.1)
20:02hiredmanvectors are not sequences, lazy or otherwise
20:02ndimidukin that case, i have no idea where the LazySeq is coming from
20:02scgilardiwhat did you pass in?
20:03hiredmanI imagine you did a map or a filter on a vector, the result of which is a lazyseq
20:03ndimidukmy dispatch-fn is (fn [a b & c] [(type a) (type b)])
20:03technomancyhave you changed your dispatch function since starting your process?
20:04technomancyonce you set your dispatch function, it can never be changed
20:04hiredmanndimiduk: but what are a and b?
20:04ndimidukno, but i'll restart the vm
20:04amalloyndimiduk: you're never going to get (isa? [String Integer] [Object Object]) to be true, which it sounds like is what you were hoping for
20:04ndimidukit's so easy to do with M-x clojure-jack-in ;)
20:05scgilardihiredman: that dispatch-fn can't return a dispatch value that's a lazy seq
20:05ndimiduktechnomancy: maybe i had changed the dispatch-fn!
20:06ndimidukbecause this appears to dispatch correctly now
20:06ndimiduk"ah hah!"
20:06ndimiduk:D
20:06ndimidukthank you!
20:06technomancydon't thank me, blame whoever broke defmulti
20:06technomancyit used to work right
20:07technomancy=\
20:07ndimidukamalloy: i'm curious why you say that
20:07ndimiduk> (isa? [String Integer] [Object Object])
20:07ndimiduktrue
20:07hsbot Not in scope: `isa'Not in scope: data constructor `String'Not in scope: data constructor `Integer'Not in scope: data constructor `Object'Not in scope: data constructor `Object'Not in scope: `?'
20:08amalloyndimiduk: i see. i didn't realize isa? special-cased vectors for just this purpose
20:09amalloy~source isa?
20:09dnolenamalloy: otherwise multimethods would be much less useful.
20:09amalloydnolen: indeed, and i'd assumed that was the way of things
20:11ndimidukokay, related question
20:11ndimiduki cannot use the underscore trick in my dispatch vectors
20:11ndimiduk[_ String] doesn't work
20:11amalloyObject
20:12ndimidukgiven that i'm using class hierarchies, i should fall back on Object?
20:12ndimiduk*nod*
21:08amalloyndimiduk: fwiw, there's no "underscore trick" at the language level: _ is just another symbol, which conventionally means "i don't plan to use this"
21:08amalloy&((fn [_] (inc _)) 4)
21:08sexpbot⟹ 5
21:12ndimidukamalloy: oh, interesting. i thought it was a special case in the various macros and special forms.
21:12dnolen,(macroexpand '(fn [_]))
21:12clojurebot(fn* ([_]))
21:13ndimidukthere we have it!
21:13dnolen,(macroexpand '(let [[_ _ _] [1 2 3]])
21:13clojurebotEOF while reading
21:13dnolen,(macroexpand '(let [[_ _ _] [1 2 3]]))
21:13clojurebot(let* [vec__408 [1 2 3] _ (clojure.core/nth vec__408 0 nil) _ (clojure.core/nth vec__408 1 nil) _ (clojure.core/nth vec__408 2 nil)])
21:14ndimidukis there not macroexpand-all ?
21:14amalloyit's in clojure.walk
21:14ndimidukhow do i see let* expanded inline?
21:14ndimidukah
21:14amalloybut let* is the lowest level. it's not a macro
21:17gfrlog`is it a special form?
21:17gfrlog`,(macroexpand '(let [x 12] (inc x)))
21:17clojurebot(let* [x 12] (inc x))
21:18gfrlog`can't be a function...
21:19amalloygfrlog`: well, it's not a macro and it's not a function...
21:19gfrlog`then it must be a var!
21:19gfrlog`:)
21:19gfrlog`er, a symbol. Um. a value?
21:20amalloya mutable cons cell!!!1
21:20gfrlog`that's a variant of a prison cell?
21:21gfrlog`I think erlang lets you use cons cells as arbitrary 2-tuples
21:23gfrlog`I'm working in a language w/o persistent-immutable data structures, and I'm pretty sure the algorithm I'm writing practically requires them :|
21:23gfrlog`It's hard for me to tell if that's actually the case or if I've just been using clojure for so long that I can't tell the difference.
21:36rhdoengeswhat is a good resource from which to learn clojure?
21:36clojurebotI don't understand.
21:36rhdoengesI don't know lisp very well either.
21:41headlessClownRich Hickey's early talks on Clojure are a good start.
21:42headlessClownThere's also a small collection of books but I'd recommend the presentations first
21:50jcromartieAnybody using Compojure in a production app?
21:50jcromartieI'm basically flipping a coin between Rails and Compojure here.
21:52jcromartieI guess it's better to just try it :)
21:52TimMcGive people maybe 20 minutes to see your question.
21:53TimMc(I'm sure at least several people are using it in production.)
21:54amalloyjcromartie: well, 4clojure.com - not exactly enterprise-scale, but "production"
21:54jcromartieheh
21:54amalloyjcromartie: actually, i guess geni is using it too
21:54jcromartiewell we're about to undergo a big rewrite of our product
21:54jcromartiehttp://www.geni.com/ ?
21:54amalloyyeah
21:55jcromartieneat
21:55amalloyjcromartie: but i only started working here recently. check with ninjudd or lancepantz for an official statement about how *much* it's being used
21:56jcromartieah ha
21:56jcromartiewell this would be "from scratch"
21:56amalloyanyway, with that i guess i'm off. good luck with your rewrite
21:56jcromartieobviously certain frameworks give you a faster time to "get off the ground"
22:50rhdoengesheadlessClown: sorry, I left for a bit. I'll take a look at those presentations.
23:30Raynesamalloy: There is some Ruby in there as well. Not sure how much we're using Clojure for the web side. I'll have to ask Justin.