#clojure logs

2010-05-26

01:01bmasonman I'm glad I read this channel... reduce *is* the bomb
02:59bartjer, is there anyone here who knows russian?
03:12unfo-i heard google does
03:13technomancyunfo-: heyo
03:15bartjunfo: apparently google's translate engine is having problem translating a russian page to english - "http://www.yell.ru/all/2000002-%252000125-%251000083/en/146/small"
03:15bartjI know this is terribly off topic to the channel but...I wanted to know what language this phrase "bezopasnost' dorozhnogo dvizheniya - oborudovanie" from the above page is in
03:17bmasonhttp://encyclopedia.farlex.com/Komitet+Gosudarstvennoy+Bezopasnost
03:17bmasonperhaps it is a name?
03:19waterless_cloudmight be ukranian
03:21bartjI think it is a business category, because it says so on this page - "http://www.yell.ru/EASY%20PARKING/all/en/7003483/643/entry" but weirdly google translate is not able to find the translation for - "bezopasnost' dorozhnogo dvizheniya - oborudovanie"
03:22bartjwaterless_cloud: phrase does not work either from "Ukranian to English" on Google Translate for the phrase - "bezopasnost' dorozhnogo dvizheniya - oborudovanie"
03:28waterless_cloudGIBDD Gosudarstvennaya Inspectsiya Bezopasnosti Dorozhnogo Dvizheniya (Russian: Federal Road Safety Service)
03:29bartjwaterless_cloud: I don't understand
03:30waterless_cloudand reference here
03:30waterless_cloudhttp://en.russia.edu.ru/tips/sec/1331/
03:30waterless_cloudseems to be traffic cops
03:39vu3rddtechnomancy: would you like to include a maven po.xml in the leiningen repo for other folks who are doing similar things as me?
03:40technomancyvu3rdd: no, the pom is an generated artifact of project.clj
03:40technomancygenerated artifacts generally don't belong in source control; they should just be re-created on-demand
03:41vu3rddtechnomancy: yes, but building leiningen itself without using lein is a problem in that case, right? And the generated pom does not build a useful jar
03:41technomancyoh, what's missing in the generated pom?
03:41technomancyI haven't actually tried it in this case
03:42vu3rddit creates an empty jar
03:42npoektophi! is there a function like doseq which collects results?
03:42vu3rddI had to use the maven-clojure-plugin to compile leiningen.core (or anything which needs to be aot compiled)
03:42vu3rddalso add resources for the source files to be included
03:43technomancyhmm... I'd rather fix the pom task so it generated a useful pom.
03:43somniumnpoektop: for
03:44vu3rddtechnomancy: Yes, I thought about that too. pom task definitely needs some care.
03:45npoektopsomnium, thanks!
03:45technomancyvu3rdd: I don't use it myself, so I'm reliant on contributions from others to get it well-polished.
03:45vu3rddtechnomancy: ok
03:45vu3rddtechnomancy: I understand the hint
03:46technomancyfrom you or others. =)
03:46technomancyIDE-users, etc.
03:46vu3rddtechnomancy: sure, I will look at it.
03:47technomancyvu3rdd: have you thought about waiting for the stable 1.2 release to perform the packaging? it shouldn't be too far off now.
03:47vu3rddtechnomancy: I don't use IDE myself though. But most java projects use mvn and hence it is quite well supported in GNU/Linux world
03:47technomancyvu3rdd: oh, I just meant that in the past the pom task has mostly been used for IDE interop
03:47vu3rddtechnomancy: I was thinking of packaging 1.1.0. Also debian does not have maven-ant-tasks, so I will have to package that too..
03:49vu3rddtechnomancy: java packaging has been a pain. I have never faced so many issues in plain old C world.
03:49technomancyyes, it's tricky to do systemwide java packages. most of the java ecosystem assumes it's installed on a per-user basis
03:49vu3rddtechnomancy: do you plan to add some verbosity/logging support in lein so that during debugging it cabe turned on?
03:50technomancyvu3rdd: it's crossed my mind, but it's not a high priority right now.
03:50vu3rddtechnomancy: debian solves it quite nicely. The systemwide jars you install becomes your local maven repo
03:50vu3rddtechnomancy: ok
03:51technomancyhmm... I have often had issues with systemwide debs for things like hudson and solr that have turned me towards using tarballs.
03:51technomancyactually no, hudson worked decently, but solr was totally broken last time I checked
03:52vu3rddtechnomancy: perhaps true. I think it is still evolving. But debian has got some good basic infrastructure for maven in place.
03:52technomancydid you say you were planning on packaging the latest lein with clojure 1.1.0? because I don't think that will work; there are some things in lein right now that rely on clojure 1.2-snapshot
03:52vu3rddNo, I mean packaging lein-1.1.0
03:53technomancyoh, I see. that would probably be better, though I think 1.2 will not be too far away if you want to wait.
03:53vu3rddtechnomancy: yes, that is what I thought after talking to you yesterday
03:53technomancylein 1.1.0 has a bug in the repl task (due to a bug in clojure) that makes it use the wrong version of clojure for the project repl
03:54technomancybut lein 1.2.0 has a bug in the repl task due to a bug in ant that makes it break on some platforms.
03:54technomancyvery annoying!
03:54vu3rddoh.. ok
03:54ordnungswidrigvu3rdd: check if the bug in ant isn't fixed by debian
03:55vu3rddordnungswidrig: maven-ant0tasks is not yet in debian
03:55technomancyordnungswidrig: the ant developers have no plans to fix the bug. =(
03:55ordnungswidrigvu3rdd: oh, debian and maven the long story
03:56ordnungswidrigtechnomancy: maybe the debian maintainers have
03:56ordnungswidrigI tried packaging maven for debian 3 years ago. *horrible*
03:56vu3rddordnungswidrig: I will check. ant version on debian is 1.8.0. I use unstable tree
03:57vu3rddordnungswidrig: The current situation is quite ok. Java is sort of a first class citizen in the debian world now
03:57ordnungswidrigvu3rdd: can maven be build from source now? IIRC maven needs some heavy "external" bootstrapping
03:58ordnungswidrigvu3rdd: even upstream maven used to need some existing maven jars to build itself
03:58vu3rddordnungswidrig: http://wiki.debian.org/Java/Maven2
03:58vu3rddordnungswidrig: lots of pain
03:59technomancyordnungswidrig: I'd be thrilled... but it's unlikely.
04:01ordnungswidrignow i'm sure it was a good decision to drop this task
04:01vu3rddtechnomancy: clojure/clojure-contrib 1.1.0 is already in unstable/testing
04:01technomancyoh, cool
04:06vu3rddpackaging maven-ant-tasks is going to be a bit tough because they build a shaded (uder)jar
04:06vu3rdds/uder/uber
04:06vu3rddI don't think debian "allow" that
04:10ordnungswidrigvu3rdd: you mean shading=
04:10vu3rddordnungswidrig: yes
04:11ordnungswidrigvu3rdd: shading does not make sense in a distribution environment as there is only one version of each dependency available anyway
04:12ordnungswidrigvu3rdd: but it makes sense for a build tool, where you want to avoid the version blues
04:12vu3rddordnungswidrig: yes. It is like going back to those old days of static libraries
04:12ordnungswidrigvu3rdd: you've heard of nixos linux?
04:13vu3rddordnungswidrig: no
04:14ordnungswidrigvu3rdd: they do package management like a hybrid of git and gentoo :-) Symlinking until your inodes smoke. Every package can have it's one "view" to other packages and versions.
04:14vu3rddordnungswidrig: oh.. ok. I will look at it
04:28bozhidarll
04:28bozhidarops, sorry - I thought I was in the terminal buffer ;-)
05:25ravagreetings
05:25cgrandhi
05:25Lajlarava, bow before me.
05:25LajlaI am the second best programmer in the world.
05:26LajlaRise, my friend.
05:26ravagreat and merciful 2nd best
05:27ravadost thow know compojure? for yonder #compojure is fairly dead this eve
05:28Lajlarava, I actually barely know clojure.
05:28ravaheh
05:28LajlaI'm just a Scheme programmer infiltrating here.
05:28ravaew, scheme
05:28LajlaStill deciding if I want to learn Clojure or not.
05:28Lajlarava, why?
05:28ravajust prefer common lisp
05:28ravano real or objective reason
05:29Lajlarava, well, there must be a subjective one?
05:30ravaasdf for one
05:32ravadislike lexical scope only
05:33ravacouple other odds and ends
05:33ravathose are what came to mine
05:34ravai've not even looked at scheme in 2 + years though
05:37LauJensenhaha <Lajla> I'm just a Scheme programmer infiltrating here.
05:37LauJensen<rava> ew, scheme
05:37LauJensen
05:39LajlaThere are some times yes when it would be easier if a variable could be given dynamic scope too.
05:39LajlaBut still, you shall be executed for your bad taste, just like Oscar Wilde and Alan Turing.
05:45Chousukescheme has fluid-let, doesn't it?
05:49naeucould someone clarify a clearly flawed understanding of basic computing that's currently in my head. Why does (byte 2r11111111) produce -1 (or raise an exception in 1.2 snapshot). Doesn't a bit consist of 8 bits, and are they not all allowed to be 1?
05:50Chousukea byte consists of 8 bits
05:50Chousukebut a number in base-2 can be as large as you want
05:51Chousuke2r... is not notation for bitfields, but numbers in base 2
05:51Chousukethough hm
05:51Chousuke,2r11111111
05:51clojurebot255
05:52Chousuke,(byte 2r11111111)
05:52clojurebotjava.lang.IllegalArgumentException: Value out of range for byte: 255
05:52cgrandbytes in java are signed
05:52Chousukeah, right.
05:52Chousukeyeah
05:53naeuok, so the max is 127 for byte consisting of 7 bits?
05:53cgrand-128 to 127
05:54naeuah ok, so the range is the same (255) just the integer which generates a given list of bits is offset by -128
05:56cgrandnot really offset: 0 is still 0, not -128
06:00cgrandunsigned byte 0..127 = signed byte 0..127; unsigned byte 128..255 = signed byte -128..-1
06:01hoecknaeu: http://en.wikipedia.org/wiki/Two%27s_complement
06:03hoeck,(bit-and 0xff (byte -1)) ;; to get the unsigned value of a byte
06:03clojurebot255
06:09patrkrisWhat's the easiest way to run a project set up with leiningen? Using Eric Lavigne's leiningen-run? Seems to get me strange output - [null] prepended to every line i output.
06:14naeuhoeck: thanks
06:14naeuso what's the simplest way of creating a byte represented by the string 11111111
06:15cgrand,(Byte/parseByte "11111111" 2)
06:15clojurebotjava.lang.NumberFormatException: Value out of range. Value:"11111111" Radix:2
06:17hoeck,(.byteValue (Integer/parseInt "11111111" 2))
06:17clojurebot-1
06:17cgrandthx
06:18naeuthanks
06:19naeualso whilst I'm in a questioning mood, is there a nice way to iterate over a sequence with for side effects, but with the iteration yielding an index?
06:19naeuessentially i'd like a side-effect focussed equivalent of map-indexed
06:20hoeckdorun + map-indexed ?
06:23naeuhoeck: nice, thanks so much
06:52LajlaChousuke, 'Scheme' doesn't, that is R5RS doesn't.
06:52LajlaBut it's easy to add it.
06:52LajlaThe Scheme standard itself is extremely minimal, things like when, let*, fluid-let* are all just extensions written in Scheme
06:55bartjcan anyone give a use-case for map-indexed - so that I could write some code using it?
07:09bartjanyone?
07:27mikemlooking at clojure.core source, I see something like this: (fn defn (&form &env name & fdecl] ...) -- what does the leading & in &form and &env mean?
07:32reZoohai
07:33bartjmikem: my guess - that they are optional arguments
07:34mikembartj: hm I thought optional arguments are suffixed with a *
07:36bartjmikem: the general convention is to use *earmuffs* for things intended for rebinding. Reference: http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards
07:43hoeckmikem: those are some macro-only?, compiletime? args while expanding the macro, &env resolves to the current lexical environment, &form to the current form
07:44patrkrishow do I get the Class<T> of Integer? Tried Integer/TYPE, but that is apparently not it.
07:45hoeckmikem: sorry, those are arguments the macro-expansion function takes when called
07:45hoeck,Interger
07:45clojurebotjava.lang.Exception: Unable to resolve symbol: Interger in this context
07:45hoeck,Integer
07:45clojurebotjava.lang.Integer
07:46patrkrishoeck: just like that? cool :)
07:48hoeckyeah, Integer/TYPE returns the primitive type int
07:49bartjwhat is the use of #^ while defining function
08:11_na_ka_na_hi, is there any built in fn to convert an ns into file system path ?
08:12_na_ka_na_currently I'm have to do -
08:12_na_ka_na_,(.replaceAll "a.b.c" "\\." (str java.io.File/separator java.io.File/separator))
08:12clojurebot"a//b//c"
08:12_na_ka_na_File/separator is two times coz of windows
08:19mikemhoeck: ah great, thanks for that clarification
08:20hoeckmikem: to see what they contain, you can use a dummy macro like this: (defmacro foo [] (println &env &form))
08:21hoeckmikem: and expand in a let: (let [x 10] (foo))
08:38mikemalso in clojure.core source, I see the ^ symbol used to denote metadata as well as type hints (ie: http://github.com/richhickey/clojure/blob/master/src/clj/clojure/core.clj#L124) -- is the ^ context aware?
08:40mikemi guess it must be
08:40chouserno
08:41chousertype hints *are* metadata
08:41mikema lightbulb just went on over my head :P of course!
08:41chouser"^FooType foo" is just short for "^{:tag FooType} foo"
08:42mikemthanks :)
08:48_na_ka_na_hey can anyone solve my regex mystery, I'm not so proficient in Java,
08:48_na_ka_na_,(let [m (.matcher #"(.+)\.([^\.]+)" "a.b.c")] (.matches m))
08:48clojurebottrue
08:49_na_ka_na_,(let [m (.matcher #"(.+)\.([^\.]+)" "a.b.c")] (.groupCount m))
08:49clojurebot2
08:49_na_ka_na_,(let [m (.matcher #"(.+)\.([^\.]+)" "a.b.c")] (.group m 0))
08:49clojurebotjava.lang.IllegalStateException: No match found
08:49_na_ka_na_Please tell me why the above fails?
08:50rhickeychouser: want to discuss recur?
08:50chouserrhickey: sure
08:50_na_ka_na_nvm got it
08:50_na_ka_na_,(let [m (.matcher #"(.+)\.([^\.]+)" "a.b.c")] (if (.matches m) (.group m 0)))
08:50clojurebot"a.b.c"
08:50chouser_na_ka_na_: clojure has re- functions that make these things easier.
08:51rhickeyfirst and foremost, recur is about no stack usage - goto
08:51rhickeywith loop, the target is labelled by loop
08:52chouseryep, I'm with you so far
08:52rhickeywith fns, the target is the same fn, with the same arglist. The 'this' is the fn, and implicit
08:52rhickeyyou can't goto another method in the same this, or to another this
08:53chouserhmmm
08:53rhickeyto do so would be a proper method call with stack overhead
08:55chouserbecause the fn is a java method and you can't change the value of 'this' within it.
08:56rhickeybecause you can't recur out of a method
08:57rhickeynaming this is what's broken as it is really not an argument supplied in the normal way
08:57chouserwhen you recur to a fn, locals are actually re-assigned, right?
08:58rhickeybut doing so is useful and preferred
08:58rhickeychouser: yes
08:58chouserand the JVM won't let you reassign 'this' even if you wanted to.
08:58rhickeybut technically, rebound
08:59rhickeychouser: 'this' is not an argument, nor a local in Java
08:59chouserright
08:59chouserno way to refer to it in the bytecode such that it could be rebound
08:59rhickeythere's nothing to rebind
09:01rhickeyplacing this in the arglist just makes it appear like something it's not
09:01rhickeybut we've done that
09:02rhickeybut that shouldn't swap our thinking around
09:02rhickeythis is not an argument
09:02chouserno, it's more of a debate.
09:02chousersorry, j/k
09:02rhickeyaargh
09:02chouserok, I'm with you
09:03rhickeyone way out is top forbid recur to method head in deftype/record method bodies, force using loop
09:03rhickeybut that seems like a loss
09:04chouserMy concern was cheifly if it might actually be a argument on some hosts, or be able to act like one, that the behavior of the JVM here would lock us out of capabilities these other hosts might provide.
09:04rhickeydoing so would make it obvious, because people that tried to loop-rebind this would find they couldn't then use it without using '.'
09:05chouser*sigh* I don't follow.
09:06rhickeyif recur to head was forbidden in deftype/record method bodies, you'd be forced to say (foo [this x] (loop [x x] ... (recur new-x)))
09:07chouseryes, I see that.
09:07rhickeybut if you wanted to recur with this ... (loop [this this x x] ... (recur new-this new-x))
09:07rhickeybut why would you do that if you didn't want to use this?
09:08rhickeyand if you did want to use this, you'd find yourself needing to use '.'
09:08chouserah, instead of plain names to refer to your own fields, for example.
09:08rhickeyand thus I hope understand why this isn't a bindable recur target, you must call another method to use it
09:09rhickeyyes, or explicit field ref
09:11rhickeyso, the this 'arg' is truly special, and it is surprising only recur exposes that
09:12chouserok, it that last point that finally makes it click for me
09:12rhickeyI think the choice of propagating the specialness to recur is least appeal atm
09:13rhickeyso either we call out this arg, and thus why it can't be in recur, or disallow recur to deftype/record method head
09:13chouserin the method bodies x means (.x this), but if you could rebind 'this' those would mean different things. or something. just broken.
09:13rhickeywe have the former right now
09:14djpowellI'm no fan of throwing the kitchen sink into clojure, but I would have liked to see some version of clojure.contrib.repl-utils/show brought across with clojure.repl - it was very handy to have, especially if you are used to using an IDE to remember all your method names.
09:20chouserdjpowell: I'm with you on that.
09:21chouserrhickey: I think the current behavior of recur is good, now that I understand why.
09:22rhickeyso, what do people prefer - recur not pass this, or disallowed?
09:22rhickeychouser: oh good!
09:22chouserdisallowed doesn't seem any better
09:23_na_ka_na_rhickey: can you explain with an example how the first option would work?
09:23rhickeychouser: it would be better only in calling out methods as not first class fns, the heads of the latter being ok recur targets
09:24chouseryeah, and a more informative error message, etc.
09:24rhickey_na_ka_na_: (foo [this x] ... (recur new-x))
09:24_na_ka_na_rhickey: and inside the method body we can use (.a this) (.b this) as usual right?
09:24chouserBut the "what" is clearly documented as it is, and you can always use 'loop' to get explicit and clear behavior
09:25rhickey_na_ka_na_: inside you can just use a and b
09:25chouseras you said, you could even do (loop [this this] ...) if you want, but then the meaning of plain field symbols goes all wonky
09:25rhickeychouser: right, recur would not be inconsistent in any way
09:26_na_ka_na_great I think, then the first option sounds good
09:26_na_ka_na_but would require some calling out, as you said
09:27chousersome day the error case for recur could notice an attempt to use 'this' and give a more helpful error, but that's a nicety that's a whole different level of concern than I was trying to bring up.
09:27rhickeychouser: if you do (loop [this this] ...) I don't see any problem with plain fields. Do you think people will expect them to move to the new this?
09:28chouserno, they won't, or at least it'll be immediately obvious why they don't.
09:28_na_ka_na_I think people with lesser Java experience would, no?
09:28chouserno, I really don't think so.
09:29chouser(defrecord C [a] (foo [this] (prn a) (loop [this this] (prn a) (when a (recur other-c))))
09:30chouserI think it would seem magical and unexpected for the a's inside the loop to get new values on recur
09:31rhickeyyeah, and the lack of use of this in the body a sure sign of something wrong
09:31SinDocAny ideas as to making ADTs in Clojure?
09:31rhickeySinDoc: deftype
09:32chouserreally, the only answer I needed for my original concern was "what about plain symbols referring to fields?"
09:32chouserI wasn't considering those.
09:32chouserWith them in the picture, my argument (er, debate) falls apart.
09:32SinDocrhickey: Thanks, I'm on it.
09:34_na_ka_na_chouser: Can you explain what the intended behavior is in the above example .. when you recur with other-c ?
09:35rhickeychouser: still, that's more of the symptom than the root cause
09:35chouser_na_ka_na_: my point is that the intended behavior is a bit non-sensical
09:36_na_ka_na_My thinking is if at all people do that (i.e. loop [this this]) they'd expect it to change?
09:36rhickey(foo this [x] ... (recur new-x))
09:37chouser_na_ka_na_: Maybe it should use (.a this) inside the loop instead of just a
09:37chouserrhickey: yeah, that thought occured to me.
09:37chouseror maybe :as this up at the top. ;-)
09:37rhickeyis more akin to fn, but a break from the protocol sigs
09:37rhickeychouser: heh
09:38rhickeyno, it's better than :as at top by a lot
09:38rhickeythe alignment with self-naming fns is strong
09:38_na_ka_na_noobish question, but why is it at all necessary to keep a 'this' arg ?
09:39_na_ka_na_is it can never change, is there even any point ?
09:39_na_ka_na_s/is/if
09:39chouseryou need to be able to refer to it
09:39rhickey_na_ka_na_: for method self-calls and to pass your this to others
09:39chouserso you can pass it as an arg to other functions, that sort of thing.
09:40_na_ka_na_hmm, got it!
09:43_na_ka_na_what if, this were made a special symbol inside a method call? I mean, (defrecord C [a] (foo [x] (.. x, a, this all available..)))
09:44_na_ka_na_just like in Java
09:45chouser_na_ka_na_: These options have all been discussed. :-) Previously you could name the 'this' for the whole defrecord by saying ":as this"
09:46chouserone problem with that is that your protocol was (defprotocol P (foo [this x])) ...a different number of args
09:46_na_ka_na_chouser: oh, I'm late then, nvm
09:47chouserI don't know if that's the main reason rhickey changed it or if there was something else more compelling.
09:48_na_ka_na_hmm, but can be solved by saying this is special
09:48_na_ka_na_just checked, in Java you get invalid VariableDeclaratorId
09:48_na_ka_na_void f(int this){}
09:50Licenser_hmm anyone using enclojure?
10:01cemerickLicenser_: yes
10:10Licenser_cemerick: did you ever have the problem that you can't create new projects?
10:11cemerickLicenser_: I've never created a clojure-specific project in netbeans/enclojure. Just a regular java project with clojure dependencies is just fine.
10:12cemerick(i.e. either a netbeans-specific project, which you can configure through the UI, or a maven project, from which netbeans will pull all configuration / dependency info)
10:13Licenser_*nods* okay too sad
10:27cemerickLicenser_: why sad?
10:30somniumI'm a bit disappointed that (ahem) 'Fantom' has made it to the available plugins list ahead of Clojure
10:31cemericksomnium: this is in netbeans?
10:32cemerickoh, yup, there it is
10:40chouserugh, I hate discovering I've been building on an incorrect assumption
10:40bozhidarmost people do :-)
10:41Hodappwell, some people will argue for hours in the hopes that the assumption will prove correct or that people will start to believe it is
10:48chouserturns out this thing is an identity not a value.
10:49chouserspeaking of which, it's interesting that clojure's all about the split between identity and value, and it has functions 'identity' and 'val'.
10:52lpetitrhickey: reminder for you to add clojure.com ref in #clojure 's topic :)
10:55drewrquick macro question
10:55drewrhow can I get `((foo) (bar) (baz)) to expand to (foo) (bar) (baz)?
10:56lpetitdrewr: you can't
10:56bozhidarclojure.com?
10:56clojurebotclojure is not groovy
10:56drewrthe normal idiom is `(do ~@(....)), but the wrapping do won't work in this case
10:56somniumclojurebot: mechanic?
10:56clojurebotNo entiendo
10:56lpetitdrewr: but you can have `(do (defn (...)) (def ...)) at the top level
10:57chouserdrewr: a macro returns a single thing, it can't return 3 things
10:57lpetitdrewr: if the macro is called from top level, the do will be read as if each of its child were emitted in sequence
11:00drewrok
11:01drewrI should be able to expand it in a parent macro
11:01drewrjust wanted to make sure I wasn't missing an obvious hack
11:07cgrand,(-> (range 33) vec transient pop! count )
11:07clojurebotjava.lang.IllegalAccessError: Transient used after persistent! call
11:08cgrand,(-> (range 42) vec transient pop! count )
11:08clojurebot41
11:09Plouj(doc source)
11:09clojurebot"clojure.contrib.repl-utils/source;[[n]]; Prints the source code for the given symbol, if it can find it. This requires that the symbol resolve to a Var defined in a namespace for which the .clj is in the classpath. Example: (source filter)"
11:09Plouj(source doc)
11:09Ploujfor some reason my slime-repl doesn't find source
11:10Plouj,(source doc)
11:10clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
11:10bozhidarhave you required it?
11:10Ploujyeah
11:10bozhidaronly required or used?
11:11Ploujhumm
11:11Ploujactually it seems that (clojure.contrib.repl-utils/source doc) works
11:11Plouj(clojure.contrib.repl-utils/source doc)
11:11Plouj,(clojure.contrib.repl-utils/source doc)
11:11clojurebotjava.lang.ClassNotFoundException: clojure.contrib.repl-utils
11:11Ploujweird, I used to get that ClassNotFoundException too
11:13bozhidarI do a
11:13bozhidar(use 'clojure.contrib.repl-utils)
11:13bozhidarand (source source) for example works just fine for me
11:14bozhidarclojure 1.1
11:14Ploujhumm, that works for me too, now
11:16bozhidarwhen you do an import you have use the full namespace before the symbol unsless you used :as
11:18stuarthallowayanybody here write clojure code that uses Strings?
11:19stuarthallowayif so, take a look at https://www.assembla.com/spaces/clojure/tickets/359-promote-contrib-string and tell me what's right/wrong about this plan
11:24fogus_I might find better names for chop and chomp
11:29stuarthallowayfogus_: well do it then! :-)
11:30stuarthallowaythose names are common to the scripting languages, but if you've better ones I am all ears
11:30stuarthallowaymaybe EndOfStringCleanupFactoryCreator.getInstance.create.removeStuff(options)
11:31fogus_I suspected that they were.
11:31fogus_I suppose if they are ubiquitous then I'm the weird one here
11:31stuarthallowaystill, if you have any other names at all I would like to hear them
11:31canderaThere are only two hard problems in computer science: naming things, cache invalidation, and off-by-one errors.
11:31eikkedoes clojure have a 'zip' equivalent?
11:32somniumI think code like: (-> *nomnom* chomp slurp chop chop spit) is rather elegant
11:32cgrandeikke: (map vector coll1 coll2 ...)
11:32fogus_Is options a concrete realization of IDoWeirdStuffToStringsKeySet?
11:32eikkecgrand: ah, makes sense...thanks!
11:33dnolenstuarthalloway: why promote chomp if String.trim() is "similar and faster" ? I'm curious as to why that's not just called trim and have it call String.trim
11:33stuarthallowayif their semantics are identical then chomp will get dumped
11:34fogus_dnolen: chomp works on the end only
11:35bozhidarbtw should upper-case and lower-case actually be uppercase & lowercase?
11:35dnolenfogus_: ah
11:35stuarthallowaybozhidar: don't think so
11:35stuarthallowaythe Java versions camel case at the 'c'
11:35bozhidaraccording to the dictionary upper case and uppercase are both valid
11:36bozhidarand I think that for a function name the single word should be favoured
11:36stuarthallowayso we are being "consistent" with Java, in some odd sense
11:36bozhidarI assumed so
11:36arohnerdoes congomongo support sending JS to the server?
11:36bozhidarI'd prefered names like upcase/downcase - they sound more groovy ;-)
11:37stuarthallowayso nobody is going to say "you forgot my favorite string function"?
11:37somniumarohner: there's a method, db.eval on one of the db classes.
11:37bozhidarother than that I think the library's got what is generally needed
11:37arohnersomnium: and when querying?
11:37bozhidarsometimes there are separated ltrim/rtrim methods though
11:37somniumarohner: I found its quite easy to crash a mongod with it though
11:38arohnersomnium: oh, fun. Thanks for the warning
11:38stuarthallowaybozhidar: those exist in contrib, but are not (yet) on the list for promotion,
11:38somniumarohner: I think there's a $js or $eval key
11:39stuarthallowayin other news: we are going to start doing sublibrary builds for contrib
11:39bozhidarstuarthalloway: where are you promoting this string functions to?
11:40stuarthallowayto address the problems people have expressed around unnecessarily coarse dependencies + churn in contrib
11:40stuarthallowaybozhidar: clojure.string in clojure.jar
11:40bozhidargreat
11:40stuarthallowaythe sublibrary thing seems like boring detail work for someone (hoping to sucker sierra into it :-) )
11:40fogus_I got nothing for renames, the best I could do was remove-last for chop... chomp is so narrow in focus that any other name would be just as opaque
11:41bozhidarbtw I think I read in your book that your opinion was that stuff like String manipulation don't need clojure wrappers
11:41stuarthalloway... but the sublibraries should be an easy win for library users ... or am I missing some danger here?
11:42stuarthallowaybozhidar: string manipulation doesn't need clojure wrappers, but the community seems to like them, *and* some of the ones in contrib have usability or performance problems
11:42stuarthallowayso if they are going to be there, they might as well be right
11:43bozhidarsure
11:43bozhidarI'd probably prefer them myself if there are part of clojure.jar
11:44bozhidarsince I generally avoid using stuff from contrib, fearing the extent to which they were tested
11:44somniumis (upper-case "foo") => (.toUpperCase "foo") ?
11:45bozhidaryes
11:48fogus_Oh I see now. chop and chomp are Perlism.
11:49bozhidarfogus_: and Rubism as well
11:50somniumI wonder if haskell is the only language with a function called 'intercalate' in its std-library
11:52fogus_If we change chomp to rstrip, then we can add an additional lstrip, and then add ltrim and rtrim. too much? :p
11:53stuarthallowayfogus_: not seeing them used much in code to date...
11:54fogus_Fair enough. It might still be useful to rename chomp to rstrip
12:01bozhidarI think chomp will do fine
12:01bozhidarand there is no problem to have a couple of sinonyms for some function I guess
12:02bozhidarthis was one of the things I liked a lot about Ruby
12:02chouserI very very much dislike that about Ruby
12:02bozhidarfor me in Clojure a bad name choice was the count function
12:02yacini want to add jpcap to a lein project i'm working on. but it isn't in a mvn repo and it requires a C-Java JNI library to be compiled
12:02bozhidarI remember when I first needed it
12:02yacinhow should i go about packaging it?
12:02bozhidartrying (size ..)
12:02bozhidar(length ...)
12:03bozhidarwithout consulting the docs I'd never have figured out that I needed count...
12:04bozhidarchouser: I dislike the many leftovers from Perl and the end for end statements
12:04fogus_rstrip is much more descriptive and does not require that you have experience in some esoteric language. ;)
12:04bozhidarbut I don't think that the freedom of choice that Ruby's authors have given developers is that bad
12:05bozhidarthough it might be confusing indeed if you're not familiar with the language
12:05bozhidarfogus_: Perl is far from esoteric - after all it's far more popular than Clojure
12:06bozhidarfrom a JAPH's point of view probably Clojure is just as esoteric ;-)
12:06fogus_plus rstrip leaves the door open for lstrip... what does chomp provide? lchomp? champ?
12:06somniumhas anyone ported Acme::Buffy to clojure?
12:06fogus_bozhidar: Just kidding
12:07bozhidarfogus_: just kidding back ;-)
12:08bozhidarI used to do a lot of programming in perl some 5-6 years ago, but know I'm having hard time remembering even the basics
12:08bozhidarit was a fun ride while it lasted, though :-)
12:09bozhidarnow*
12:10fogus_Finally, rstrip works better in an overall StrippingProtocol (not what you think).
12:10rhickeyfogus_: rstrip is just about newlines?
12:10bozhidaryou should think more about strippers ;-)
12:10fogus_rhickey: yes
12:11rhickeyfogus_: and lstrip is also?
12:11fogus_yes
12:11rhickeyis that a real use case - leading newlines?
12:11bozhidarrhickey: fogus_ is not correct
12:12fogus_:(
12:12bozhidarrstrip/rstrip should generally strip every whitespace character
12:12cgrandrhickey or stuarthalloway: did you see https://www.assembla.com/spaces/clojure/tickets/358 ?
12:12bozhidarincluding newlines
12:13fogus_bozhidar: I thought that was trim/ltrim/rtrim's job?
12:13stuarthallowaycgrand: just claimed it
12:13bozhidarfogus_: true
12:13stuarthallowaythanks!
12:13bozhidarthat's why chomp is not exactly rstrip
12:14bozhidarsince at least in Perl it removed only the trailing newline
12:14bozhidarif any
12:14replacarhickey, stuarthalloway: are we going to do something about the mismatch between with-in-reader and line-seq? This messes up a nice file reading idiom.
12:14cgrandstuarthalloway: ok, thanks
12:14rhickeyreplaca: which mismatch?
12:14bozhidarin most languages - strip == trim
12:15replacawith-in-reader returns a PushbackReader and line-seq wants a BufferedReader (I think that's right)
12:16replacarhickey: yeah, that's it
12:17rhickeyreplaca: what's the fix?
12:19replacarhickey: dunno, I'm not sure I'm the one who knows all the issues (understanding what kind of readers we want where). Maybe with-input-reader should open a buffered reader (but I think other funcs want pushback readers) or maybe line-seq should be more relaxed about what kind of reader it takes.
12:19stuarthallowaybuild on top of a language with good IO abstractions? :-)
12:19fogus_bozhidar: Not in contrib.string, which is where I tried to constrain my focus. To me chomp and chop are meaningless names, but I do not have a heavy shell text processing background. strip and trim are descriptive and represent names that I might actually look for.
12:19replacarhickey: all I know is that they don't play well together :)
12:20replacarhickey: I'm happy to start a discussion on the list and try to surface all the issues and drive it to resolution if you'd like
12:21bozhidarfogus_: I tought we were have a more general discussion, about the naming -> what should it do. Sorry about that
12:21rhickeyreplaca: that would be great, thanks
12:21replacarhickey: k, I'll do it later on today
12:22bozhidarwere having*
12:22bozhidarI hate my typing...
12:22patrkriswhy is [null]
12:22patrkris... prepended to all output from leiningen?
12:25stuarthallowaypatrkris: level 1 answer: it's an ant thing
12:25patrkrisstuarthalloway: ah... any way to get around it?
12:25stuarthallowaymaybe -- years since I forgot ant
12:25patrkris:)
12:26stuarthallowayif there is a way, it probably would require some small change to lein to expose it
12:31ChousukeI think it actually has something to do with the logging facilities
12:32angermanit's not possible to have a tree-shaker for clojure, right?
12:36arohnerangerman: I don't think it's possible to do purely in clojure. it'd have to understand the host language as well
12:37angermanarohner: well I guess cleanly designed and separable librarys would make it not such much a problem :D
12:38angermanand otherwise I guess it could get really trick to figure out what is dynamically loaded ...
12:40mefestois there an existing function that will provide a lazy-seq of chars for a Reader?
12:44arohnermefesto: what are you trying to do?
12:44arohner,(seq "foo")
12:44clojurebot(\f \o \o)
12:44arohnersomnium: are you interested in a patch to congomongo that allows you to send arbitrary JS to the server?
12:45mefestoarohner: parsing some file and i need to be aware of newlines depending on if im in quotes or not
12:45Licenser_Writing clojure in windows is a sad experience :(
12:45mefestoso line-seq wouldn't work since a quote could be open on line 1 and closed on line 5
12:45arohnermefesto: oh, a java stream Reader, not a clojure compiler reader
12:45canderaLicenser_: agree. It's the ghetto.
12:45mefestoarohner: yeah, sorry for the confusion.
12:46Licenser_I tried emacs, ccw and enclojure all make me cry :/
12:46Licenser_Why can't my boss give me a MacBook :P
12:46Chousukemefesto: (repeatedly #(.read thereader)) should work
12:47canderaI settled on emacs, and I like it well enough, but it's definitely got more friction than on other platforms. But VirtualBox and Ubuntu are both free, so often I just go virtual.
12:48mefestoChousuke: i went this route since i wanted them to be chars, overkill?: https://gist.github.com/6d7c8a2c9bcd748b22fb
12:49mefesto,(char -1)
12:49clojurebotjava.lang.IllegalArgumentException: Value out of range for char: -1
12:49Licenser_candera: I use emacs on my mac but I don't like to do all the jar management by hand it makes me unhappy :P and I can't use maven/lein/whatever else
12:49QuiesceLicenser_: Yeah? What would you use on this hypothetical gift MacBook?
12:49Chousukemefesto: that's essentially what my suggestion does
12:49Licenser_Quiesce: AquaEmacs :P and a usefull internet connection hopefully
12:49Chousukemefesto: except it doesn't check for EOF, it includes in in the stream
12:51angermanyea, Aquamacs is pretty nice. ...
12:51angermanexcept when you run into C-; making the meta switch :D
12:51somniumarohner: sure
12:53drewrisn't there a flatten-1 somewhere that only flattens a sequence one list deep?
12:54drewrie: (flatten-1 '(1 2 (3 (4 5)))) -> (1 2 3 (4 5))
12:54drewror is it called something else?
12:54chouserapply concat
12:54drewrhm
12:54chouserhm, or maybe not in that case.
12:55chouser,(mapcat #(if (coll? %) % [%]) '(1 2 (3 (4 5))))
12:55clojurebot(1 2 3 (4 5))
12:55chouserdunno if there's a flatten-1 somewhere or not
12:56drewrmy contrived example isn't quite right
12:57drewr'((1 2) (3 4) ((5 6) (7 8))) -> ((1 2) (3 4) (5 6) (7 8)) is more like what I need
12:57drewrmy macro needs to end up with a list of single sexps
12:58chouserI assume it's not always just the last one that's grouped an extra level?
12:58drewrright
12:59chouser,(mapcat (fn [[x :as a]] (if (coll? x) a [a])) '((1 2) (3 4) ((5 6) (7 8))))
12:59clojurebot((1 2) (3 4) (5 6) (7 8))
13:00drewrah, thanks, I think that works
13:01KirinDaveI finally got around to reading "Multiple Dispatch in Practice"
13:02KirinDaveMan, it's really interesting how there seems to be this consistent but small desire for multiple dispatch
13:03drewrwhat's strange is that my solution worked if I called it as (foo '((...) (...))), but idn't when called as (foo (map bar '(....))); bar being what transformed the original forms into the nested forms
13:04drewr...which shouldn't have changed the behavior of the flatten
13:04drewrbut oh well
13:04zakwilsonGiven enough time, almost every project needs multiple dispatch or some sort of ugly hack to simulate it.
13:05KirinDavezakwilson: I was just surprised at how consistent that demand is
13:05KirinDaveAnd it's not for like 7 way dispatch, the majority is 2 term dispatch
13:07rhickeyKirinDave: and you can do clean, extensible 2-way dispatch using double dispatch and protocols, which don't have the problems of using interfaces for the same task
13:08KirinDaverhickey: When you say double dispatch you mean?
13:08rhickeyKirinDave: dispatching on 2 terms via 2 single-dispatches
13:08KirinDaveAh
13:09KirinDaveSo yeah, bouncing back and forth a la visitor?
13:09rhickeynormally that's a problem using interfaces, leading to the dreaded visitor
13:09rhickeybut protocols are not type intrusive, so it's clean and open
13:09KirinDaverhickey: I must confess, from a strictly aesthetic perspective I don't like that solution.
13:09KirinDaveprotocols DO make it easier.
13:10KirinDaveAnd the 2 dispatch system is more amenable to trace tree optimizations.
13:10KirinDaveStill, it just sticks in my teeth. :)
13:10rhickeynot just easier, substantively different in that it is open, double dispatch with interfaces can't be
13:11KirinDaveI understand and agree. :)
13:11KirinDaveI just like reading code where the double dispatch is clear
13:11KirinDaveSo md methods seem like a better notation to me. It's very clear what's happening.
13:27KirinDaveOh McCarthy
13:27KirinDavesrry
14:18islonis there a way to set the number of agent threads used by send-off?
14:18chouserno, it grows as needed.
14:21islonhmmm... strange... I used send-off to run a bat (java.lang.Process) that blocks forever, the second send-off I called (another different bat) never started
14:21chouserto the same agent?
14:22islonyes... ok I got it...
14:28cemericksending to one's own threadpool/executionservice is on my 1.3 list
14:28cemericksend-to, perhaps
14:30rhickeycemerick: send-to vs (agent ... :on-pool pool) ?
14:31rhickeyI don't think consumers want/need to know about the pool
14:31chouserthat would influence only send-off not send?
14:31rhickeychouser: both
14:32chouserhuh
14:32cemerickrhickey: that's why my first thought was send-to
14:32cemericksend and send-off are thin abstractions for what pool to use
14:33chouserit's not uncommon for me to use send and send-off on the same agent because it's the action that controls that decision.
14:33cemerickright
14:33islonthe :on-pool is implemented?
14:33cemerickno
14:33chouserseems weird to remove that option in order be able to use your own pool.
14:33rhickeyIf you are choosing its pool you must know how you are going to use it
14:33cemerickthe usage can be mixed, though
14:34fogus_I try not to think about pools
14:34rhickeycemerick: so choose a pool that works for both, certainly we could only have send-off
14:35rhickeybut providing a pool at every send-to is a catastrophe from an app modularity standpoint
14:35cemerickyeah, I can see that
14:36rhickeyreally, looking back I'd rather have had only send and force you to choose a pool at agent construction
14:36cemerickIn that case, the intended semantics of send and send-off would get blurry IMO. Blocking vs. non-blocking, ok, but again, you really do end up needing to know the specific characteristics of the corresponding pools.
14:36cemerickright, yes
14:37rhickeycemerick: if you always use blocking-is-ok there is only one semantic
14:37rhickeyeven if it doesn't ever block
14:38chouserI think that'd be fine with me.
14:38rhickeyso send == send-off, supply a pool to get a compute-only agent
14:38rhickeydeprecate send-off
14:38chousersure
14:39islonwhat about (binding [*agent-pool* my-pool] (do stuff...))
14:39chouserbinding-only args are baaad.
14:39chouserespecially in such close proximity to theads
14:40chouser(binding [*agent-pool* my-pool] (send foo #(do ... (send foo ...)))) ; sends to two different pools!
14:40islonright
14:43remleduffDo you think dynamic bound variables have been net positive to clojure? They seem to be where most of my head-banging problems have come from
14:44remleduffOnce you're used to them, it's less of an issue, but seems that (map some-fn-that-depends-on-dynamic-vars ...) is something everyone has tripped on at least once
14:44cemerickrhickey: sounds good to me
14:45chouserremleduff: I do wonder. My current take is that they're useful, but at the top of the list for ways to accidentally produce unintended behavior.
14:45hiredmanbinding is the doom of the world
14:45hiredman(unless you use it to emulate multiple returns)
14:45chouserheh
14:46remleduffI think that would be the top check I'd like to see in a clj-lint project ;)
14:49technomancyhiredman: botsmack
15:13bartjanyone from an information extraction background and using clojure here?
15:20cemerickbartj: hi :-)
15:20cemerickvery broad concept there
15:59remleduffIs there a difference between butlast and drop-last?
16:00chouserhardly. drop-last is lazy
16:01remleduffIs there a difference between chomp and butlast/drop-last?
16:02remleduffOh, chomp checks if it's a newline
16:02chouserand returns a string, presumably. butlast and drop-last return seqs
16:02chouseroh, I see where you're ogin
16:02chousergoin
16:02chousergoing
16:03chouserclojure.string/butlast instead of chop or less
16:03remleduffProbably slightly too big of a semantic difference
16:04chouserI think it's the same as chop -- drops one thing regardless of what it is
16:04chouserchomp/rtrim/rstrip are something else
16:06remleduffOh yes, I meant chop ;)
16:09fogus_Is butlast defined by its drop-iness or its seq-iness, or are they inseparable?
16:09tomojhuh?
16:10chouserbutlast should continue to return a seq, as it does now
16:10chouser,(butlast "abc")
16:10clojurebot(\a \b)
16:11chouserbut (clojure.string/butlast "ab") could certainly return "ab"
16:11fogus_That's kinda confusing no?
16:11chouserisn't that what clojure.string is all about?
16:12fogus_confusion?
16:12chouserright!
16:12fogus_:p
16:12chouserwait, no.
16:12chouserreusing names fron clojure.core, but applied to strings
16:12fogus_Well, that I'm not sure.
16:13chouserlike replace, and ... others I can't think of.
16:13tomojwhat does anyone think of the idea of having a single set of functions/macros paralleling map, filter, for, etc but which return the same type as their args, use transients or whatever speedups are available, and are implemented with protocols?
16:14tomojor is the seq abstraction too important to optionally abandon? hmm
16:14remleduffI really like the way protocols let you provide a default implementation and then specialize where appropriate, so I hope something like that happens
16:15chousertomoj: I think there have been a couple efforts in that direction
16:15tomojexcellent
16:15chouserclojure.contrib.generic or something, and I think sean devlin has done something else.
16:18tomojwonder what good names would be for those functions/macros
16:18fogus_That kinda leads into my whole reason for jumping on the string functions. I would like to see a different categories of protocols: 1) some that do something to X and return seqs and 2) some that do something to X and return things of type X 3) ???
16:19chouserhm... I wonder if it's the wrong approach.
16:19tomojyou would like to see #3 but don't know what it would be?
16:19fogus_not sure. It's not really formulated in my brain yet
16:20remleduffWhy do you need functions that return a seq, as long as everything knows how to produce a seq when needed?
16:20chouserA chain of seq-processing fns on a vector with vec around them all is almost certainly going to be more efficient than producing a vector at each step
16:20tomojeven with transients?
16:20tomojhadn't considered that possibility
16:20chousertransients would still be eager
16:20tomojah, hmm
16:21fogus_darn... gotta go
16:21chouserlazy seqs, esp with the cell stuff that rhickey has mentioned, may be as fast as a hand written loop that processes each item fully before proceeding to the next.
16:21tomojI guess the use case I am thinking of is doing a small chain near the inner loop and not wanting to do hashmap->seq->hashmap or whatever
16:21chousersuch that intermediate objects not even be created.
16:21tomojnice
16:22chousereven 1.1 has chunked seqs that can beat some naive hand-written loops.
16:22chouserso perhaps something that conveniently wraps the whole chain for you...
16:23chouser(same-type->> my-vector (map ...) (filter ...) (partition ...) ...)
16:23tomojwhen we're working with seqables qua data not qua seqs, I wonder if this would still be faster
16:23tomoje.g. transforming a bunch of small maps with filter or something in the inner loop
16:24tomojif the seqables are small I guess it won't matter a whole lot anyway
16:24hsjunnessonSo, hm..
16:24tomojor maybe it would matter more? gah, I'm just confused now
16:24chouserheh
16:24hsjunnessonOkay, so I asked this in #leiningen but no one there replied. I figured people here might have a bead on this.
16:25hsjunnessonI uploaded a few jars to clojars and it took a few tries before I "got it", so now I need to delete a couple of jars.
16:25tomojas the seqable grows, the O(n) conversion overhead (like (into {} ...)) becomes less visible, I guess
16:26chouserhsjunnesson: I wouldn't actually be surprised if there were no way to delete jars from clojars
16:26hsjunnessonThat's kind of what I'm afraid of.
16:26chouserhsjunnesson: you might send email to the maintainer
16:26hsjunnessonI'll have to do that, thanks.
16:29tomojI wonder if clojure is a good choice for a first language to teach to non-programmers
16:30technomancyhsjunnesson: yeah, you have to get _ato to do it for you =(
16:30chousertomoj: I wonder that too. The biggest worry I have is the Java interop -- so good for getting things done, but such a bag of complexity for someone who doesn't already know OOP
16:32tomojah, hmm, hadn't even thought about java interop :(
16:32tomojlearning only enough java to get by at the same time you learn clojure sounds terrible
16:33SynrGi know oop, but mostly via ruby. i'm only learning enough java to do clojure :/
16:34chouserif you could find enough fun and interesting exercizes that didn't require much (or any?) java calls, it might be perfect.
16:34chouserand now you could learn OOP via records and protocols before confronting all of Java's complexity
16:35SynrGmind you, i've read some java texts ... i've just never actually used it for anythign real
16:35SynrGso i don't have what i'd consider a working knowledge
16:36chouserI'd especially love to see if a new programmer has any trouble at all with immutable collections, locals, and even HOF -- things that those of us who started in BASIC/Pascal/C/etc. have had to struggle through.
16:37mefestoi think my first reaction to someone that has only programmed in clojure would be, "you spoiled brat!" ;)
16:37chouserheh
16:38chouserI would show them for(i=0; i<foo.length; i++) { if(skip(i)) { i++ } } ... and watch them panic
16:43_na_ka_na_Hi
16:43_na_ka_na_Ok, I come from the family of imperitive languages so macros and I are not really friends till now. I have a few basic qs reg. macros.
16:43_na_ka_na_My understanding is macros (only?) live to make code shorter and sweeter by spitting out mechanical code for you.
16:43_na_ka_na_For example if I'm repeatedly printing diff of two numbers, (println (- x y)),
16:44_na_ka_na_I can (defmacro print-mah-diff [x y] `(println (- ~x ~y))) ; and (print-mah-diff x y)
16:44_na_ka_na_But I've also seen macros such as (defmacro print-mah-diff [x y] (println (- x y))) (eg: gen-class)
16:44chouserthat is one use-case, yes
16:44_na_ka_na_What would be the purpose of such macros? Wouldn't a fn work too?
16:45mefesto_na_ka_na_: i think the general rule is that if you can do it with just a function... then you don't need macros
16:45mefesto_na_ka_na_: macros let you manipulate the forms before they are evaluated which can be very powerful
16:46mefesto_na_ka_na_: think manipulating an AST
16:46chousergen-class is a macro just so you don't have to quote things a bunch. It's a thin wrapper around generate-class which is a function
16:47remleduff_na_ka_na_: Your example calculates the substraction at compile time... it might be used for optimization of an expensive constant
16:48BorkdudeWhen is a array-map going to turn into a hash-map when conj-ing elements to it?
16:48_na_ka_na_chouser: Didn't quite get that, gen-class couldn't be a fn ?
16:49chousergen-class could be a function, but you give it a lot of symbol names for functions and classes that don't exist yet
16:49_na_ka_na_Hmm got it
16:49chouserif those were evaluated before being passed to a function, you'd get errors. So instead you'd have to quote all of them.
16:50chouserif generate-class weren't private, you could just call (generate-class '{:name ... :methods ...}) ...it would work fine.
16:50remleduff_na_ka_na_: macros are also for selective evaluation. You couldn't implement a short-circuiting "or" function as a function.
16:50chouserso that's another use-case for macros -- to simplify the interface to a function
16:51_na_ka_na_remleduff: we could quote the stuff to be ored?
16:51chouserwhat macros *are* is a hook into the compilation process. What they're *for* is anything you can dream up that needs to hook into the compilation process.
16:52chouser_na_ka_na_: not quite, because then you'd have to 'eval' those quoted things, which isn't quite the same
16:52_na_ka_na_Ok so I'm noting all of these points down, and will ponder over them next few days :P
16:53chouserwithout macros, 'or' could be a function that takes a bunch of no-arg functions.
16:53chouser(or-fn #(foo) #(bar) #(baz)) instead of (or (foo) (bar) (baz))
16:53_na_ka_na_chouser: how not same? I mean evaling the quoted things.
16:54chouserbut that would still be more work at runtime than what 'or' does now. So that's another use-case -- performance improvements by doing some work at compile time that would otherwise have to be done at runtime.
16:54chousernot the same because eval doesn't have access to the local environment where it's called.
16:55chousereg. this doesn't work: (let [a 1] (eval '(prn a)))
16:55_na_ka_na_Hmmm
16:55Borkdude_na_ka_na_: are you perhaps that guy who asked a Scala call-by-name/Clojure macro question on Twitter? :)
16:56_na_ka_na_One curious q : so how is (x || y) implemented in imperative langs w/o macros?
16:56chouser_na_ka_na_: direct compiler support, usually. you can't write your own.
16:56_na_ka_na_Borkdude: Nope
16:57chouser_na_ka_na_: some langauges have explicit support for delayed arg evaluation (scala), otherer are always lazy (haskell)
16:57_na_ka_na_Haven't touched Scala (yet)
16:57_na_ka_na_Hmm, that sounds interesting
16:57Borkdudechouser: he (the guy on Twitter) said he could do most macro's with Scala call by name... I wonder how far he would get, don't know Scala though
16:58chouserBorkdude: not far at all
16:59humphrejHi
16:59humphrejhere's an add-watch puzzler http://clojure.pastebin.com/N4TauWpV
16:59_na_ka_na_So how does the compilation work? Does the reader first macroexpand all macros and then compile stuff?
17:00humphrejshould a call to await cause a watcher-fn to update?
17:00_na_ka_na_What if there are nested macro calls like or, .. when is the next time macroexpand is called?
17:00chouserhumphrej: old value is the same as the new value -- you can ignore if you want.
17:01mefesto_na_ka_na_: i believe macro expand continues until all macros are fully expanded
17:01chouser_na_ka_na_: each top-level form goes through several stages before the next top-level form is touched.
17:01chouser1. read (text to nested data structures)
17:02chouser2. macroexpand of the outermost form, repeatedly until it is a special operator
17:03chouser3. analysis of that outermost special operator. depending on the op all kinds of special things may be done. frequently steps 2 and 3 are done recursively for one or more args to this outer special form
17:03humphrejchouser: yes but I'm thinking the equality test could be expensive if the agent state is large
17:04chouser4. walk the tree that results from the analysis, emitting bytecode
17:04chouser5. (optionally) save bytecode to .class files
17:04chouser6. load and run bytecode.
17:05chouser1 is "read time", 2-5 are "compile time" and 6 is "runtime"
17:05_na_ka_na_thanks! chouser take makes a lot of things clear, are these details somewhere on the clojure.org page?
17:06BorkdudeAm I right that an array-map of 8 kv's turns into a hash-map when conjed a new kv pair?
17:06_na_ka_na_one doubt: macroexpand won't expand inner level forms .. like for or .. right? they are expanded only at runtime?
17:06chousernote that step 2 involves calling functions provided by the user -- so what is "compile time" for the current top-level form is "runtime" for the macros being expanded.
17:06chouser_na_ka_na_: no, those inner levels are expanded as parts of the recursion at step 3
17:07BorkdudeWait, 9.
17:07_na_ka_na_Hmm so after step 3. macros no longer exist
17:07Borkdude,(type (conj (array-map 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8) [9 9]))
17:07clojurebotclojure.lang.PersistentHashMap
17:08chouserBorkdude: yeah, but you shouldn't rely on that.
17:08chouser_na_ka_na_: essentially, yes!
17:08Borkdudechouser: it could differ per OS or smth?
17:08_na_ka_na_lol that smiley looks nice in a data structure
17:08chouserBorkdude: per version of clojure
17:09Borkdudechouser: aha
17:16_na_ka_na_I was trying to do something like ... (defmacro m1 [x y] (println (+ x y)))
17:16_na_ka_na_(defmacro m2 [x y] (do (m1 x y) (println (- x y))))
17:16_na_ka_na_and it was not compiling .. I couldn't understand .. but now I do :)
17:16chouserwell! good.
17:17_na_ka_na_Is it idiomatic to do something like .. (defmacro m2 [x y] (do (macroexpand `(m1 ~x ~y)) (println (- x y))))
17:17chouserI don't think so. I have used macroexpand in a macro for the very first time last week, and it seems *very* specialized.
17:18_na_ka_na_Didn't quite follow the very specialized part
17:18chouserthe reason your m2 doesn't compile is because you're passing the symbols x and y to m1, which then tries to add them.
17:18_na_ka_na_yup
17:19chouseryou might want: (defmacro m2 [x y] `(do (m1 ~x ~y) (println (- ~x ~y))))
17:20Chousukeexcept that will evaluate x and y twice
17:20_na_ka_na_ya for that one can use let
17:20chouserusing eval, macroexpand, or anything with side-effects in a macro definition is pretty suspect.
17:21chouseractually, to a certain extent using defmacro is a bit suspect. :-P
17:21remleduffHmm, doesn't any macro that expands to def have side effects?
17:21Chousukeremleduff: no
17:21Chousukeremleduff: the code they expand to has side-effects, not the macro
17:22remleduffah, makes sense
17:22Chousukeit is possible to use the whole language in a macro. It's just not generally done. But I think for example using reflection to generate bindings for an API could be a good application of more complicated macrology.
17:23chouserChousuke: yes
17:23chouserbut you ought to be able to justify at each step why you're doing it in a macro instead of a function.
17:24ChousukeDoesn't penumbra do something like that btw?
17:25ChousukeIIRC reflects the jogl stuff and generates clojure functions/macros... Or maybe I'm confusing it with something else.
17:25chouserof course once you're in that deep you might want to do like clj-native and just call into the ASM lib directly.
17:27bozhidarI was wondering what is the idiomatic way in Clojure to cache a function return values
17:28chousermemoize
17:28bozhidarin a trivial example say we want to cache factorials between invocations
17:29bozhidarchouser: so I should basically just wrap my existing function with memoize and that's all?
17:30chouserfor trivial cases, that's it.
17:30_na_ka_na_bozhidar: even shorter is defn-memo (c.c.def)
17:34goodmike_mhHey, I'm the numbskull who asked on the Google group about how Agents are lock-free...
17:34goodmike_mhAre either of the authors of Agent.java online, and would you be willing to humor me?
17:35chouserPretty sure Agent.java is all rhickey.
17:35chouserbut others may be able to help
17:36goodmike_mhgit blame tells a different tale, chouser. :-)
17:36chouserhmph.
17:36Borkdudechouser: why is it that a conjed array-map sometimes returns a hash-map?
17:36goodmike_mhBut I'll take any help i can get
17:36bozhidarchouser, _na_ka_na_ : thanks
17:36chouserBorkdude: because array-maps are only efficient when they're small.
17:36goodmike_mhI can tell it's all about the agent's queue
17:37goodmike_mhThe queue can only be updated (e.g. given a new value) in an atomic compareAndSet
17:38goodmike_mhThen the actions in the queue are executed
17:38Borkdudechouser: so 9 (varying over Clojure versions) is kind of the flipping point of efficiency?
17:38chouserBorkdude: that's the conclusion currently implemented, yes.
17:39Borkdudechouser: still you can use array-maps bigger if you want, because of ?
17:40chousergoodmike_mh: almost. if enqueue takes the queue size from 0 to 1, it starts a chain of executions
17:41goodmike_mhchouser: Yeah, I saw that! I was a little confused by why there's an explicit action.execute in case the queue was empty before the compareAndSet
17:41chousergoodmike_mh: after each action is done, it's popped off the queue (CAS again), and if there is another action to be done it is executed
17:41chouserso each action on an agent triggers the execution of the next action on the agent
17:42goodmike_mhchouser: I assume there is a case in which the queue was non-empty at the end of Agent#enqueue. I'm not sure what happens then.
17:43chousergoodmike_mh: nothing happens then. it relies on the fact that whatever action is currently in the executor will trigger the next when it's done.
17:43goodmike_mhchouser: Whoa. OK. I think I see that.
17:44goodmike_mhchouser: so it's the atomic updating of the queue that keeps actions from overlapping. It looks like it makes the agent's actions execute in serial order. Is that right?
17:45chouseragent's actions execute in serial order, yes.
17:46goodmike_mhchouser: Thanks. I really appreciate being able to ask someone who wrote the code.
17:46goodmike_mhchouser: Even if he doesn't remember doing it. :-)
17:46chouserthe actions are kept from overlapping by the CAS on the queue and the use of that to make sure that only one place (either enqueue or the current action) triggers the next action.
17:47chouserI didn't write it! I tweaked the error handling a bit.
17:48goodmike_mhchouser: The CAS on the queue is really sweet.
17:48chouseryeah, that was definitely not me
17:48goodmike_mhchouser: Regardless, thanks for the explanation.
17:48chouseryou're welcome
17:50_na_ka_na_what does point 5. clojure.org/agents - "If during the function execution any other dispatches are made (directly or indirectly), they will be held until after the state of the Agent has been changed." mean?
17:53tomoj_na_ka_na_: if you send or send-off during the action you send(-off) to an agent, those will not happen until after the current agent is finished
17:53tomojI don't know the vocabulary to explain it better :(
17:55_na_ka_na_Hmm got that tomoj, I wanted to understand why that is so?
17:55tomojoh, hmm
17:55tomojwell, it's useful :)
17:56tomojnot sure if there is a better reason... can agent actions be retried?
17:58_na_ka_na_don't think agent actions are ever re-tried .. but one explanation might be that the other agent to which there is a dispatch might want to see the updated state? doesn't sound like a good reason tho.
17:59goodmike_mh_na_ka_na_: I *think* the reason for holding the dispatch is to prevent contention. The conversation chouser and I just had was about how agents serialize the actions that update their state. So they have to happen one after the other.
18:01goodmike_mh_na_ka_na_: It's fairly common for the fn sent to an agent to include a send of the same fn to the agent, with the understanding that "this will happen later"
18:01tomojlike ants.clj
18:01goodmike_mhyep
18:02_na_ka_na_goodmike_mh: you mean an agent in its action fn sends an action to itself again?
18:02kasperlangerI think it's to make actions on agents atomic (the A in ACID)
18:02goodmike_mh_na_ka_na_: exactly. the fn contains a line like (send *agent* foo)
18:03goodmike_mh*agent* being the Var holding a reference to the current agent.
18:03arkahncovered in http://blip.tv/file/812787 with relevant bits at 71:43, specifically 72:50
18:03goodmike_mh_na_ka_na_: Are you suggesting a case in which the function sends a function to a different agent?
18:04_na_ka_na_hmm ok that might be an explanation then, but I can't immediately see why an agent would send to itself again
18:04_na_ka_na_goodmike_mh: yes, it can be a common scenario no?
18:05arkahn_na_ka_na_: example code at the bottom of ants.clj http://tinyurl.com/322p5kf
18:06goodmike_mh_na_ka_na_: I'm not sure I would do that. :-) I prefer to coordinate state outside the current agent by opening a transaction (dosync) and updating refs. Let the coordinated state stay in refs.
18:06tomojan agent action can send send itself to its agent again to set up a sort of infinite loop
18:06tomojand the action can do some check for whether to send again or not in order to terminate
18:06arkahn_na_ka_na: a function sends off to itself after checking for whether it should continue running and executing a sleep so it doesn't sit and spin too fast
18:07tomojso it's a way to do the run loops you see in java threading stuff with agents
18:07_na_ka_na_goodmike_mh: not all situations would require coordination, for eg: agent a got a message, it just wants to tell agent b that it got a msg, doesn't care when agent b gets that msg
18:08arkahnit's my understanding that agents only provide for coordination so state change (i.e. the function in send or send-off) can happen safely
18:09arkahnyou're also guaranteed on order (it's fifo)
18:10arkahnyou can read an agent at any time but aren't guaranteed you'll see the latest changes
18:10goodmike_mh_na_ka_na_: Hmmm. An agent is primarily a way of encapsulating some state and controlling its updating. You have to provide behavior. They're not like objects in other languages with their own behavior. So I'm not sure that message-passing is the right approach here.
18:11goodmike_mh_na_ka_na_: In Clojure >= 1.1 promises are used to pass values between threads. Agent B might block on a promise until agent A sets it. You'd want to send-off the fn to B that blocks.
18:13goodmike_mhJust a thought. Please, no one go out and architect their systems based on my semi-informed comments.
18:15arkahnEver since I learned about functions self-sending, I've wondered if it's currently common/idiomatic. I guess it's safe to say that Rich thought it was back in the day, whenever ants.clj was written.
18:16arkahnit seems like a working contortion of the original intent for agents, but maybe I just don't know enough ; )
18:18nDuffI've got a loop/recur where I'm getting "recur arg for primitive local: remaining must be matching primitive"; however, to me, the types look like they should match. Is there a way to determine what the expected vs actual types are?
18:18_na_ka_na_goodmike_mh: what would be a good way to implement the following scenario: agent A, agent B are doing independent work.. A reaches a state when it wants to inform B about it, but B might be busy, so it doesn't want to be synchronous
18:20_na_ka_na_kasperlanger: I didn't quite follow the atomicity part you mentioned
18:21kasperlangerIf the function you send to an agent has no side effect except possibly mutating the agent and sending of stuff to other agents you know the whole thing will either happen completely or not at all
18:21kasperlangerThat's a really nice property to have
18:24arkahnnDuff: could you use 'class' to verify type?
18:25_na_ka_na_kasperlanger: but isn't is possible that after the agent state is mutated, action is sent to another agent which fails ?!
18:25_na_ka_na_i mean the act of sending fails, not the action of other agent
18:25nDuffarkahn, ...explicitly wrapping the argument in question with (int ...) resolved the issue; I'm presuming the other value was being boxed to an Integer, perhaps?
18:26kasperlangerYes the action on the second agent may fail
18:26kasperlangerThe atomicity property only holds on a single send not the whole chain of sends
18:27kasperlangeroh
18:27arkahnnDuff: not sure without seeing the code
18:27_na_ka_na_didn't quite get, but how does point 5. ensure that? or if point 5. wasn't there how can the whole action not be atomic?
18:28kasperlangerI don't think sending fails since it's all local stuff but I'm speculating now :)
18:28SinDocI'm using Clojure 1.2.0-master and have trouble with deftype
18:29SinDoc(deftype point [x y])
18:29arkahnkasperlanger: I don't think sending ever fails - but the assumption of state may have changed so you can determine at the time the function executes whether you'd like the function to complete
18:30arkahnkasperlanger: ... trying to remember what that precondition check is called ...
18:31nDuffarkahn, http://gist.github.com/415170; the comments at the end of the file point where the issue occurs
18:32herdrickquestion: lein new project_name gives you a project.clj with dependencies that are out of date, I think. org.clojure/clojure "1.1.0
18:32herdrickoops
18:32nDuff(this is some of my first clojure code, by the way, so I'm fully expecting -- and would welcome -- any critique / comments re obvious failings re practices / style failings)
18:33herdrickok, so the default org.clojure/clojure version according to lein new is 1.1.0
18:33herdrickisn't that obsolete?
18:34herdrickah, I see that's the newest version in Clojars
18:34remleduff1.2 isn't out just yet
18:36_na_ka_na_chouser: the eval behavior of clojure struck me, coz eval in Perl happens in lexical scope, what implications do the two behaviors have ?
18:37herdrickokremleduff: ok, thanks
18:41islon"lein help" gives me Exception in thread "main" java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Named (help.clj:5)
18:42SinDocI pasted a simple deftype interaction; http://paste.lisp.org/display/100539
18:44SinDocThe syntax is probably not correct but this is what I understand from (doc doctype)
18:44SinDoc*deftype
18:44tomojdon't use new
18:44tomojbut your example still doesn't work for me after fixing that
18:45tomojbut e.g. this works: (deftype Point [x y]) (def pt (Point. 1 2)) (.x pt)
18:45remleduffdeftype defines no functionality, you want defrecord
18:45tomojalso, (defrecord Point [x y]) (def pt (Point. 1 2)) (:x pt)
18:45tomojyeah
18:46islonhow do I start swank with my lein project? i tried "lein swank" but it gives me "swank is not a task. Use "help" to list all tasks."
18:46remleduffislon: Do you have lein-swank in your dev-dependencies, and have you run lein deps?
18:46skeeterbugislon, i had that problem, upgrading lein worked for me
18:46Raynesislon: You need to add swank-clojure to your project.clj file.
18:46SinDoci thought fields were keywords
18:46Raynesremleduff: lein-swank is obsolete.
18:46Raynesremleduff: lein swank is bundled with the new swank-clojure.
18:46remleduffoh, I should upgrade :)
18:47tomojhttp://github.com/technomancy/swank-clojure explains
18:47Raynes[swank-clojure "1.2.1"]
18:47islonthanks, is there a way to lein self upgrade? like "lein upgrade"?
18:47RaynesPut that in your dev-dependencies
18:47Rayneslein update, I believe.
18:47skeeterbugyeah, lein update, but i think older versions didn't have that command
18:47RaynesNo, it's lein upgrade
18:47tomojSinDoc: not on a raw deftype, apparently. for defrecord, yeah
18:48islonwow, works =)
18:49remleduffSinDoc: deftypes are not maps, so they have no default functionality for keyword lookup. There was an earlier version of deftype that defined some map functionality magically for you if you implemented IPersistentMap or something like that, but Rich wisely split it up into deftype with nothing magic and defrecord which is always map-like.
18:50SinDocYeah, i saw that defrecord implements IPersisistentMap
18:51SinDocAre there recent examples of deftype?
18:51SinDochttp://paste.lisp.org/display/90329
18:52SinDocI found this but doesn't work given the recent changes
18:54_na_ka_na_Hey guys I'm writing 2 macros .. first is straightforward .. (defmacro m1 [x] (println "m1 got" x)) ..
18:54tomojSinDoc: https://gist.github.com/ad9cad85dc72c41dd52b
18:54tomojthat seems to work
18:54_na_ka_na_but in the second, i want to simulate something like :
18:54_na_ka_na_(defmacro m2 [y] (macroexpand `(m1 ~y)) (println "m2 got" y))
18:55_na_ka_na_only w/o the macroexpand part ..
18:55_na_ka_na_how can it be done ?
18:56SinDoctomoj: You're a grace; thanks
18:56SinDocit uses defrecord though
18:56tomoj_na_ka_na_: have you tried macroexpanding?
18:56tomojSinDoc: yes, because that's what you should use to do that example nowadays
18:57tomojdeftype has similar syntax but no automatic :real :imaginary access
18:57_na_ka_na_tomoj: didn't get what you meant ?
18:57tomoj_na_ka_na_: I mean, for example, have you tried (macroexpand-1 '(m1 3)) ?
18:57_na_ka_na_yes
18:58tomojso you noticed, then, that it expands to nil?
18:58_na_ka_na_yup
18:58tomojso why would you want to expand nil and stick that in m2?
18:58tomojanyway.. (defmacro m2 [y] `(do (m1 ~y) (println "m2 got" ~y))) maybe?
18:58SinDoctomoj: I'm looking for a way to write ADTs and currently I was hoping to write an abstraction that does memory management so I should export thinks like cons, car, cdr, etc.
18:59_na_ka_na_no but the above definition of m2 work s ... it calls m1
18:59_na_ka_na_i mean the macroexpand one
18:59tomojyes, the one I just pasted calls m1 as well
18:59arkahnnDuff: it has to do with code in clojure/src/jvm/clojure/lang/Compiler.java near "public static class RecurExpr implements Expr". I'm not understanding it all yet, other than it looks like it's thrown off by the method call you make to #^java.nio.ByteBuffer .remaining which returns a java int. So far, it looks to me like the implementation recur doesn't like mixing boxed and unboxed primitives. Maybe immediately box the return value with Integer
18:59arkahnright away? All subsequent clojure manipulations would then treat it like a clojure Number ... maybe
18:59tomojit expands like (m2 5) -> (do (user/m1 5) (clojure.core/println "m2 got" 5))
19:00tomojSinDoc: dunno how to help you, good luck
19:01SinDoctomoj: thanks for the help
19:01nDuffarkahn, ...hmm. Would you suggest testing this against a newer upstream (this is 1.1) and filing a ticket if the behavior is unchanged?
19:02_na_ka_na_tomoj: but I want both macros to run at compile time, the one you pasted runs at run time
19:02_na_ka_na_I mean macroexpand m2 should return null
19:03tomojI see
19:03arkahnnDuff: I really don't know. What was the design goal for recur? To be able to mix clojure and java primitives? You could always file a ticket and find out. Unfortunately, I've probably been using clojure for as long or less than you have, so I'm not the best person to ask ; )
19:03_na_ka_na_thats how (defmacro m2 [y] (macroexpand `(m1 ~y)) (println "m2 got" y)) will work
19:03tomojyeah
19:03tomojweird
19:03arkahnnDuff: fwiw (which isn't much, considering my noob-ness) I like your code
19:04nDuffarkahn, heh -- thanks (both for taking the time to look into the issue, and providing at least some kind of feedback that I wasn't making _really_ obvious errors)
19:05arkahnnDuff: np! It's always nice to get a sanity check ... I just hope what I dug up was sane
19:05tomoj_na_ka_na_: I think you might be stuck with the macroexpand, then, not sure
19:06tomoj_na_ka_na_: just curious, what's the point?
19:06_na_ka_na_tomoj: I'm trying to write a macro wrapper over gen-class
19:08tomojand you can't wrap gen-class with a normal-style macro? never would have thought otherwise, interesting
19:08tomojI thought you were struggling with macros, but you know them better than I :D
19:11_na_ka_na_tomoj: Not sure about that, but I've been struggling alright! This is like my 2nd macro which I've had to write .. I'm done with the macroexpand solution .. but chouser above said that one shouldn't use macroexpand inside a macro
19:14_na_ka_na_What's the easiest way to run arbitrary shell commands from Clojure, example I want to, cd into a directory, and kick off a process from there ..
19:25_na_ka_na_found c.c.shell
19:28_na_ka_na_,(sh :cmd "echo Hello Thr" :return-map true)
19:28clojurebotjava.lang.Exception: Unable to resolve symbol: sh in this context
19:28_na_ka_na_(sh :cmd "echo Hello Thr" :return-map true) throws an exception for me .. java.lang.IllegalArgumentException: No matching method found: exec for class java.lang.Runtime
19:31chouser_na_ka_na_: try (sh "echo" "Hello" "There" :return-map true)
19:32_na_ka_na_oh I thought you forgot to mention the :cmd key in the docs .. after looking at the source
19:32_na_ka_na_wasn't sure how to pass the cmd
19:33chouseryeah, the docs could use some help there
19:35ihodesanyone in here familiar with Enlive
19:35ihodes?
19:36ihodesi've been getting "java.lang.NullPointerException ", pointing to a line where i defsnippet, is the issue.
19:38_na_ka_na_chouser: maybe you could put your example above in the docs .. and this for Win XP works for me.. (sh "cmd.exe" "/c" "echo" "Hello" "There" :return-map true)
20:05ihodesanyone here yet? i'm really interested in learning enlive, but i'm having a small problem i'm sure someone's seen before
20:14islonis clojure.contrib.json the best way to read json in clojure?
20:14ihodesas far as i know, it's the only way. and if it's in contrib, chances are it does what it's supposed to to, well.
20:20ihodesfair enough. technomancy, would you be able to answer a quick question re enlive for me?
20:20ihodesi've been getting "java.lang.NullPointerException ", pointing to a line where i defsnippet, is the issue.
20:20islonwell, json parsing is not that difficult
20:20danlarkinihodes: no!
20:20danlarkinhe's busy helping me
20:21technomancyI've only used enlive once... I was pretty confused the whole time.
20:21ihodesah, ok haha. for some reason i'd thought you'd somehow been involved. wrooong person. know someone who might be able to help? frustrating little problem
20:22technomancycgrand is the author; there's also dnolen who's written some docs for it
20:22technomancyneither is around now =
20:22technomancy=\
20:22technomancynor lau
20:22ihodesnoticed that. siiigh. it looks so nice, but mystery error is a pain.
20:22ihodesyeah lau did what i'm trying to do with it ahah, though i didn't know until last night
20:25hugodihodes: I think a NPE at that line means that the path to the template is not being found
20:26ihodesunfortunately, it's an absolute path right now, so I don'tt hink that's it.
20:28ihodesthough now i've changed the selector for the snippet and get this: java.lang.ArrayIndexOutOfBoundsException: 1 ---- on the same line
20:31ihodeshttp://pastie.org/979148 is the snippet that is being hated on. there's definitely a file there. i require enlive in as html.
20:44herdricksay, can anyone tell me why this: (ns user (:use [incanter.core :only (abs)])) gives me "java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol"
20:44herdrickwhile this: (ns user (:use [clojure.set :only (union)]))
20:44herdrickworks fine ?
20:45herdricksubstituting various things for clojure.set works fine too
20:45herdricklike clojure.contrib.combinatorics
20:45herdrickor whatever
20:45herdrick(assuming you replace union with something in one of those packages
20:45herdrick)
20:46tomojis that the exact code which caused the error?
20:47herdrickyep
20:48tomojcan you try both and pastie the repl session?
20:48herdricksure
20:48herdrickbrb
20:48tomojI'm just boggled
20:50herdrickhttp://pastie.org/979167
20:50herdrickthis is a fresh install of swank-clojure
20:50herdrickand the first time i'm using lein
20:50tomojno idea why that could happen
20:51herdrickso probably something wrong with what i'm doing there
20:51tomojdoes (use '[incanter.core :only (abs)]) also give the error?
20:51herdrickyep, identical error
20:51tomojand, does the error come with a stacktrace? I wonder where the error is happening?
20:51tomojmaybe it's inside incanter? that's the only explanation I can think of..
20:52tomojyour syntax looks perfect to me
20:52herdrickwhereas (use '[incanter.coreBAD :only (abs)]) gives what you'd expect: "Could not locate incanter/coreBAD__init.class or incanter/coreBAD.clj on classpath: ... "
20:52herdrickbrb
20:52hugodihodes: the braces around the snippet selector argument look wrong to me
20:53tomojherdrick: what versions of incanter and clojure are you depending on?
20:54herdrickhere's the stacktrace and it's cause: http://pastie.org/979169
20:54herdrickincanter 1.2.3
20:54herdrickclojure 1.1.0
20:57tomojhmm
20:57herdrickuh oh -
20:57herdricklooks like incanter's project.clj file wants clojure 1.2.0
20:57tomojI think incanter 1.2.3 requires clojure 1.2.0
20:57tomojyeah
20:57herdrickroger
20:58tomojthat's the only way this error makes sense to me, anyway
20:58herdrickok, thanks, that's probably it
20:59herdricki was following this blog post from November: http://data-sorcery.org/2009/11/20/leiningen-clojars/
20:59herdrickwhich is like 14 clojure dog years ago
20:59herdrickmy bad ;)
20:59tomojhehe
21:01DrakesonIs there a facility to work with paths (like file system paths)?
21:01replacaDrakeson: I use java.io.File
21:03Drakesonreplaca: maybe I miss something. How do you do (path :home "foo/bar") using java.io.File ?
21:04Drakesonis there something easier than (str (System.getProperty "user.home") "/" "foo/bar") ?
21:11replacaDrakeson: More corrrect would be (File. (System.getProperty "user.home) (File. "foo") "bar)
21:11replacaI think - I'm not buried in that java space
21:12replacaeasy to imagine a path func that did (path :home "foo" "bar")
21:16herdricktomoj: ok, that worked
21:16herdrickthanks!
21:18herdrickBy the way, since Clojure 1.2 isn't in lein-space, I just went with the older version of Incanter that is OK with Clojure 1.1
21:19herdrickbut now I've got a bunch of Incanter 1.2.3 jars in my /lib dir of my lein-created project
21:19herdrickthose shouldn't be a problem, right?
21:19ihodeshugod: i tried removing them: no luck. it's also a selector from david nolen's tutorial :\
21:19herdrickunless i were to use swank-clojure-project (the avoidance of which was the point of this whole switch to lein)
21:23bhenryherdrick lein clean && lein deps
21:23herdrickbhenry: ok. but is it important?
21:23bhenryyes
21:24herdrickwill swank or anything else pick up those extra jars in lib?
21:25Drakesonherdrick: What are you trying to do?
21:25herdrickDrakeson: just curious about the issue
21:26herdrickmy problem was solved above
21:27Drakesonoh sorry
21:28bhenryherdrick: everything in lib/ is on your class path. so if you (use 'some-project) you won't know which one you'll get (that's if it doesn't error, i'm not sure what would happen, but I know it's important). someone speak up if i'm misdirecting herdrick.
21:29tomojherdrick: what do you mean 1.2.3 isn't in lein-space?
21:29herdrickbhenry: i was thinking lein would manage that, and generate a custom classpath using only the jars of the deps and their deps, recursively, etc
21:29tomojno, you need to remove duplicate jars
21:29tomojbhenry is correct
21:30herdrickNo, Clojure 1.2 isn't in lein-space
21:30tomojoh, hmm
21:30tomojyou mean that you can't get it with lein?
21:30herdrickwell, *i* couldn't in a couple of tries
21:30tomojyou can: [clojure "1.2.0-master-SNAPSHOT"] and [clojure-contrib "1.2.0-SNAPSHOT] or something like that
21:30herdricki'm new to lein tho
21:30herdricktomoj: bhenry: ok, thanks for the info on lein and classpaths
21:31tomojalso would need to use 1.2.3-SNAPSHOT for incanter
21:31ihodesanyone here an enlive expert yet? ;) still having a fun little NullPointerException http://pastie.org/979148
21:31herdricktrying that
21:31tomojbut using an old version and 1.1.0 is not too bad either
21:31tomojihodes: what's {[:.cg-post]} supposed to be?
21:31tomojI'm surprised that doesn't cause an error
21:32tomoj,'{[:.cg-post]}
21:32clojurebot1
21:32tomojuh, what?
21:32bhenryherdrick, if you have a lot of dependencies in your projects, and you're updating them a lot, alias lcd to lein clean && lein deps then just use that every time. it hardly takes any additional time, since lein stores things in a local repository on your computer.
21:32tomojoh, the error message is "1", haha
21:32ihodesit's a selector: Noel used it in his tutorial: (def *section-sel* {[:.title] [[:.content (nth-of-type 1)]]})
21:32ihodesnolen*
21:32ihodeshttp://github.com/swannodette/enlive-tutorial/
21:32tomojihodes: ok, but your {} is wrapped wrong
21:33tomojyou've got it just around [:.cg-post]
21:33tomojwhich looks like a map with a key with no value, which is illegal
21:33ihodestrue: i did change it to "[:.cg-post]" in the version i'm playing with now
21:33tomojah
21:33ihodesthat was a mistake in the pastie when i was messing with stuff, i'm sorry!
21:33herdricksay, i've been using [org.clojure/clojure "1.1.0"] instead of [clojure "1.1.0"] does that matter?
21:33tomojno problem
21:33herdrickbhenry: ok, thanks looks like a good tip
21:34ihodestomoj: the problem remains, though, unfortunately
21:34tomojherdrick: nope, clojure is just an abbreviation for org.clojure/clojure
21:34herdrickok
21:34tomojwell, I'm betting the problem can't be determined without seeing the html, but not sure
21:34tomojand I am not an enlive expert, good luck
21:35ihodesit's a compile-time error though
21:35tomojah
21:35ihodesas it occurs when i'm loading the file into the repl
21:35tomojthat's odd, must be bad syntax then
21:36ihodesit looks exactly like the syntax in nolen's tutorial, i *think*. gah. ben banging my head against a wall about this for a while. it's what happens when you code in C the first half of the day, and then clojure the other half.
21:37tomojyou need something to bind to the keys destructuring map
21:37tomoj(I think)
21:37ihodesi don't quite understand?
21:37tomojI mean, [{:keys [title author pubdate post-text]} <something needs to go here>]
21:38tomoje.g. the tutorial has [{:keys [title data]} model]
21:38tomojthough I can't tell where model came from
21:38tomojoh, maybe that's just an extra param?
21:39tomojyeah, I was wrong, just the {:keys ..} should work too it seems
21:39ihodesyeah it's just an additional arg: the {:key..} thing is just destructuring a map
21:41ihodesjava.lang.NullPointerException (render_index.clj:19) is the exception, too
21:46tomojwhat's on line 19, the start of the defsnippet?
21:47ihodesyep
21:59tomojihodes: I don't think this problem is your fault
22:00tomojthe examples from the tutorial seem to do the same thing
22:01ihodesthat simultaneously good to hear. and awful! in his examples, it all seems to work. he is using compojure 0.3.2, which might be the cause of the problems, but it's highly unlikely as .4 doesn't change much, and nothing that enlive relies on.
22:01tomojit seems like load-html-resource is being called with nil
22:01tomojwhich clojure is he using?
22:01ihodesthe thing is, his examples work in the lein-powered environment he has on hit.
22:01tomojhuh, he doesn't have any clojure in his project.clj
22:01remleduffNPEs in enlive have always meant "couldn't find your template" for me
22:01ihodesi'm going to have to build up his examples (M-w, C-y) in a new project
22:02tomojremleduff: yeah, but..
22:02tomojoh, hmm
22:02tomojdoes it try loading from the classpath?
22:02remleduffWhat do you get if you just do (html-resource "your_template.html")
22:02hugodihodes: the path should be relative
22:02tomojrather than taking it as an absolute file path
22:02tomojI see
22:02hugodit uses the resource loader
22:02ihodesah, let me give that a go
22:02ihodesso an absolute path *won't* work?
22:02tomojso the html file needs to be in resources/ I guess, and you need to have that directory there before you start up swank
22:03tomoj(does `lein swank` add resources/ to the classpath?)
22:03remleduffresources is a recommendation rather than a requirement. Current lein adds it to classpath, but there were older versions that didn't
22:03tomojswannodette just sticks his html files in src along with the clj
22:04ihodeslet me try just doing that
22:05tomojyou'll need to use the relative path from src/ if you put them there
22:05tomoje.g. "foo/bar.html" for src/foo/bar.html, I mean
22:06ihodesok, so i moved the template to the same folder my render-index.clj is in (the file I've been futzing with) and change the path from absolute to clogs/template_index.html (clogs being my project's name), and it appears to now work.
22:07ihodeswell, i'm on to other exceptions on other lines anyway. which is progress.
22:07remleduffhehe
22:08ihodesso is there a nice way I can have the HTML files in other folders..? I had in my project.clj …:resources-path "html") and my html (templates) in that folder. i thought that'd work, but it didn't so I tried absolute path which also didn't. any clues as to why those things don't work?
22:09remleduffI'm not sure what resources-path does, but by the time lein reads your project.clj it's too late to change the classpath so I can't imagine it working. Probably just using resources would work
22:11ihodesresources-path should be setting the name of the resources to folder to whatever i specify–apparently it doesn't work, as I just tested and I *can* refer to my template at recoures/template.html
22:11ihodeswhich is nice. odd. now I have another cryptic error.
22:13remleduffWhat's that?
22:14ihodestomoj: before you scroll off the screen, thank you :) remleduff: one of these buggers: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character (render_index.clj:28)
22:16ihodessolved.
22:31ihodesthanks for the help, all. i'm running into more off errors, so i'm going to call it a night and do some set theory.
22:31ihodesodd* errors. finals time is not a good time to try to start a new project. cheers, and thanks again.
22:36remleduffWhy might M-x slime give me "let: Symbol's function definition is void: swank-clojure-reset-implementation"?
22:37tomojsomething is looking for swank-clojure-reset-implementation and you don't have it
22:37tomojI guess you probably figured that much out :(
22:38remleduffI usually use lein swank to start up, was trying to start up a repl without a project this time
22:39remleduffI'm so bad with emacs still
22:40tomojremleduff: do you have swank-clojure installed from elpa?
22:53defntechnomancy: did you change the URL for your package.el repo
23:00remledufftomoj: I have swank-clojure 1.1.0 from ELPA, yes.
23:03tomojremleduff: I think you need to upgrade
23:04tomojit looks like swank-clojure-reset-implementation is in 1.2.0 but not 1.1.0
23:06herdrickso you've got to keep your version of swank-clojure installed in ELPA synched with your swank-clojure jars in your lein projects?
23:06remleduffI thought swank-clojure was added to your project. What does swank-clojure in emacs do?
23:06herdricktomoj: is that true?
23:06tomojherdrick: I don't know if that's true or not
23:06tomojswank-clojure from elpa is no longer even required
23:07herdrickoh, really?
23:07tomojsome stuff will not work without it
23:07tomojpresumably M-x slime for example
23:07tomojI don't know what problems a version mismatch might cause
23:07herdrickhmm
23:07herdrickperhaps better to delete it then
23:07tomojremleduff: swank-clojure in emacs is not needed if you only connect to externally started swank servers
23:08tomojbetter to ask technomancy
23:08tomojabout version mismatches I mean
23:09herdrickive got a related question: when i drop a jar (in this case, an apache commons one) into my /lib under my lein project, it is not picked up by slime/swank until and restart the swank instance
23:09herdrickis there a better way?
23:09remleduffhendrick: Nope :\
23:09technomancydefn: haven't touched that in a while, no.
23:10technomancyremleduff: swank-clojure in emacs isn't really needed
23:10technomancyyou just need slime + clojure-mode
23:10remleduffBut swank-clojure is what provides M-x slime if I'm just wanting to play with one-off stuff?
23:10herdricktomoj: remleduff: technomancy: ok, thanks
23:13remleduffDuh, have to (require 'swank-clojure) if I want to use stuff provided by it (including M-x slime)
23:13technomancyremleduff: yeah, that's true
23:14tomojyou shouldn't have to require it, I think...
23:14tomojbut if it works, who cares
23:15SinDocCan a type refer to itself?
23:16RaynesSinDoc: I believe so.
23:17remledufftechnomancy: How do you usually start up swank if you're hacking on clojure itselfl?
23:17SinDocRaynes: thanks, would you know how?
23:17RaynesSinDoc: You have to instantiate the class directly, because the factory functions aren't there yet.
23:17technomancyremleduff: I start a repl in swank and then edit clojure in the jar file itself
23:19SinDocRaynes: if I need the name of the class in order to instantiate it then it wouldn't work since the name won't have been bound yet.
23:24RaynesSinDoc: http://gist.github.com/415409
23:31remleduffAnyone got a good way to check if a deftype has successfully implemented all the abstract methods its inherited, and not forgotten any?
23:47SinDocremleduff: checking the protocols it has implemented using reflection?
23:50SinDocRaynes: Thanks, I tried your solution; it still can't reify itself but it's fine for now
23:51Raynes:(
23:51RaynesSorry I couldn't be more helpful. <3
23:52SinDocRaynes: FWIW, I found out that my initial requirement wasn't valid to begin with