2010-05-26
| 01:01 | bmason | man I'm glad I read this channel... reduce *is* the bomb |
| 02:59 | bartj | er, is there anyone here who knows russian? |
| 03:12 | unfo- | i heard google does |
| 03:13 | technomancy | unfo-: heyo |
| 03:15 | bartj | unfo: 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:15 | bartj | I 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:17 | bmason | http://encyclopedia.farlex.com/Komitet+Gosudarstvennoy+Bezopasnost |
| 03:17 | bmason | perhaps it is a name? |
| 03:19 | waterless_cloud | might be ukranian |
| 03:21 | bartj | I 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:22 | bartj | waterless_cloud: phrase does not work either from "Ukranian to English" on Google Translate for the phrase - "bezopasnost' dorozhnogo dvizheniya - oborudovanie" |
| 03:28 | waterless_cloud | GIBDD Gosudarstvennaya Inspectsiya Bezopasnosti Dorozhnogo Dvizheniya (Russian: Federal Road Safety Service) |
| 03:29 | bartj | waterless_cloud: I don't understand |
| 03:30 | waterless_cloud | and reference here |
| 03:30 | waterless_cloud | http://en.russia.edu.ru/tips/sec/1331/ |
| 03:30 | waterless_cloud | seems to be traffic cops |
| 03:39 | vu3rdd | technomancy: would you like to include a maven po.xml in the leiningen repo for other folks who are doing similar things as me? |
| 03:40 | technomancy | vu3rdd: no, the pom is an generated artifact of project.clj |
| 03:40 | technomancy | generated artifacts generally don't belong in source control; they should just be re-created on-demand |
| 03:41 | vu3rdd | technomancy: 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:41 | technomancy | oh, what's missing in the generated pom? |
| 03:41 | technomancy | I haven't actually tried it in this case |
| 03:42 | vu3rdd | it creates an empty jar |
| 03:42 | npoektop | hi! is there a function like doseq which collects results? |
| 03:42 | vu3rdd | I had to use the maven-clojure-plugin to compile leiningen.core (or anything which needs to be aot compiled) |
| 03:42 | vu3rdd | also add resources for the source files to be included |
| 03:43 | technomancy | hmm... I'd rather fix the pom task so it generated a useful pom. |
| 03:43 | somnium | npoektop: for |
| 03:44 | vu3rdd | technomancy: Yes, I thought about that too. pom task definitely needs some care. |
| 03:45 | npoektop | somnium, thanks! |
| 03:45 | technomancy | vu3rdd: I don't use it myself, so I'm reliant on contributions from others to get it well-polished. |
| 03:45 | vu3rdd | technomancy: ok |
| 03:45 | vu3rdd | technomancy: I understand the hint |
| 03:46 | technomancy | from you or others. =) |
| 03:46 | technomancy | IDE-users, etc. |
| 03:46 | vu3rdd | technomancy: sure, I will look at it. |
| 03:47 | technomancy | vu3rdd: have you thought about waiting for the stable 1.2 release to perform the packaging? it shouldn't be too far off now. |
| 03:47 | vu3rdd | technomancy: 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:47 | technomancy | vu3rdd: oh, I just meant that in the past the pom task has mostly been used for IDE interop |
| 03:47 | vu3rdd | technomancy: 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:49 | vu3rdd | technomancy: java packaging has been a pain. I have never faced so many issues in plain old C world. |
| 03:49 | technomancy | yes, it's tricky to do systemwide java packages. most of the java ecosystem assumes it's installed on a per-user basis |
| 03:49 | vu3rdd | technomancy: do you plan to add some verbosity/logging support in lein so that during debugging it cabe turned on? |
| 03:50 | technomancy | vu3rdd: it's crossed my mind, but it's not a high priority right now. |
| 03:50 | vu3rdd | technomancy: debian solves it quite nicely. The systemwide jars you install becomes your local maven repo |
| 03:50 | vu3rdd | technomancy: ok |
| 03:51 | technomancy | hmm... I have often had issues with systemwide debs for things like hudson and solr that have turned me towards using tarballs. |
| 03:51 | technomancy | actually no, hudson worked decently, but solr was totally broken last time I checked |
| 03:52 | vu3rdd | technomancy: perhaps true. I think it is still evolving. But debian has got some good basic infrastructure for maven in place. |
| 03:52 | technomancy | did 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:52 | vu3rdd | No, I mean packaging lein-1.1.0 |
| 03:53 | technomancy | oh, I see. that would probably be better, though I think 1.2 will not be too far away if you want to wait. |
| 03:53 | vu3rdd | technomancy: yes, that is what I thought after talking to you yesterday |
| 03:53 | technomancy | lein 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:54 | technomancy | but 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:54 | technomancy | very annoying! |
| 03:54 | vu3rdd | oh.. ok |
| 03:54 | ordnungswidrig | vu3rdd: check if the bug in ant isn't fixed by debian |
| 03:55 | vu3rdd | ordnungswidrig: maven-ant0tasks is not yet in debian |
| 03:55 | technomancy | ordnungswidrig: the ant developers have no plans to fix the bug. =( |
| 03:55 | ordnungswidrig | vu3rdd: oh, debian and maven the long story |
| 03:56 | ordnungswidrig | technomancy: maybe the debian maintainers have |
| 03:56 | ordnungswidrig | I tried packaging maven for debian 3 years ago. *horrible* |
| 03:56 | vu3rdd | ordnungswidrig: I will check. ant version on debian is 1.8.0. I use unstable tree |
| 03:57 | vu3rdd | ordnungswidrig: The current situation is quite ok. Java is sort of a first class citizen in the debian world now |
| 03:57 | ordnungswidrig | vu3rdd: can maven be build from source now? IIRC maven needs some heavy "external" bootstrapping |
| 03:58 | ordnungswidrig | vu3rdd: even upstream maven used to need some existing maven jars to build itself |
| 03:58 | vu3rdd | ordnungswidrig: http://wiki.debian.org/Java/Maven2 |
| 03:58 | vu3rdd | ordnungswidrig: lots of pain |
| 03:59 | technomancy | ordnungswidrig: I'd be thrilled... but it's unlikely. |
| 04:01 | ordnungswidrig | now i'm sure it was a good decision to drop this task |
| 04:01 | vu3rdd | technomancy: clojure/clojure-contrib 1.1.0 is already in unstable/testing |
| 04:01 | technomancy | oh, cool |
| 04:06 | vu3rdd | packaging maven-ant-tasks is going to be a bit tough because they build a shaded (uder)jar |
| 04:06 | vu3rdd | s/uder/uber |
| 04:06 | vu3rdd | I don't think debian "allow" that |
| 04:10 | ordnungswidrig | vu3rdd: you mean shading= |
| 04:10 | vu3rdd | ordnungswidrig: yes |
| 04:11 | ordnungswidrig | vu3rdd: shading does not make sense in a distribution environment as there is only one version of each dependency available anyway |
| 04:12 | ordnungswidrig | vu3rdd: but it makes sense for a build tool, where you want to avoid the version blues |
| 04:12 | vu3rdd | ordnungswidrig: yes. It is like going back to those old days of static libraries |
| 04:12 | ordnungswidrig | vu3rdd: you've heard of nixos linux? |
| 04:13 | vu3rdd | ordnungswidrig: no |
| 04:14 | ordnungswidrig | vu3rdd: 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:14 | vu3rdd | ordnungswidrig: oh.. ok. I will look at it |
| 04:28 | bozhidar | ll |
| 04:28 | bozhidar | ops, sorry - I thought I was in the terminal buffer ;-) |
| 05:25 | rava | greetings |
| 05:25 | cgrand | hi |
| 05:25 | Lajla | rava, bow before me. |
| 05:25 | Lajla | I am the second best programmer in the world. |
| 05:26 | Lajla | Rise, my friend. |
| 05:26 | rava | great and merciful 2nd best |
| 05:27 | rava | dost thow know compojure? for yonder #compojure is fairly dead this eve |
| 05:28 | Lajla | rava, I actually barely know clojure. |
| 05:28 | rava | heh |
| 05:28 | Lajla | I'm just a Scheme programmer infiltrating here. |
| 05:28 | rava | ew, scheme |
| 05:28 | Lajla | Still deciding if I want to learn Clojure or not. |
| 05:28 | Lajla | rava, why? |
| 05:28 | rava | just prefer common lisp |
| 05:28 | rava | no real or objective reason |
| 05:29 | Lajla | rava, well, there must be a subjective one? |
| 05:30 | rava | asdf for one |
| 05:32 | rava | dislike lexical scope only |
| 05:33 | rava | couple other odds and ends |
| 05:33 | rava | those are what came to mine |
| 05:34 | rava | i've not even looked at scheme in 2 + years though |
| 05:37 | LauJensen | haha <Lajla> I'm just a Scheme programmer infiltrating here. |
| 05:37 | LauJensen | <rava> ew, scheme |
| 05:37 | LauJensen | |
| 05:39 | Lajla | There are some times yes when it would be easier if a variable could be given dynamic scope too. |
| 05:39 | Lajla | But still, you shall be executed for your bad taste, just like Oscar Wilde and Alan Turing. |
| 05:45 | Chousuke | scheme has fluid-let, doesn't it? |
| 05:49 | naeu | could 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:50 | Chousuke | a byte consists of 8 bits |
| 05:50 | Chousuke | but a number in base-2 can be as large as you want |
| 05:51 | Chousuke | 2r... is not notation for bitfields, but numbers in base 2 |
| 05:51 | Chousuke | though hm |
| 05:51 | Chousuke | ,2r11111111 |
| 05:51 | clojurebot | 255 |
| 05:52 | Chousuke | ,(byte 2r11111111) |
| 05:52 | clojurebot | java.lang.IllegalArgumentException: Value out of range for byte: 255 |
| 05:52 | cgrand | bytes in java are signed |
| 05:52 | Chousuke | ah, right. |
| 05:52 | Chousuke | yeah |
| 05:53 | naeu | ok, so the max is 127 for byte consisting of 7 bits? |
| 05:53 | cgrand | -128 to 127 |
| 05:54 | naeu | ah ok, so the range is the same (255) just the integer which generates a given list of bits is offset by -128 |
| 05:56 | cgrand | not really offset: 0 is still 0, not -128 |
| 06:00 | cgrand | unsigned byte 0..127 = signed byte 0..127; unsigned byte 128..255 = signed byte -128..-1 |
| 06:01 | hoeck | naeu: http://en.wikipedia.org/wiki/Two%27s_complement |
| 06:03 | hoeck | ,(bit-and 0xff (byte -1)) ;; to get the unsigned value of a byte |
| 06:03 | clojurebot | 255 |
| 06:09 | patrkris | What'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:14 | naeu | hoeck: thanks |
| 06:14 | naeu | so what's the simplest way of creating a byte represented by the string 11111111 |
| 06:15 | cgrand | ,(Byte/parseByte "11111111" 2) |
| 06:15 | clojurebot | java.lang.NumberFormatException: Value out of range. Value:"11111111" Radix:2 |
| 06:17 | hoeck | ,(.byteValue (Integer/parseInt "11111111" 2)) |
| 06:17 | clojurebot | -1 |
| 06:17 | cgrand | thx |
| 06:18 | naeu | thanks |
| 06:19 | naeu | also 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:19 | naeu | essentially i'd like a side-effect focussed equivalent of map-indexed |
| 06:20 | hoeck | dorun + map-indexed ? |
| 06:23 | naeu | hoeck: nice, thanks so much |
| 06:52 | Lajla | Chousuke, 'Scheme' doesn't, that is R5RS doesn't. |
| 06:52 | Lajla | But it's easy to add it. |
| 06:52 | Lajla | The Scheme standard itself is extremely minimal, things like when, let*, fluid-let* are all just extensions written in Scheme |
| 06:55 | bartj | can anyone give a use-case for map-indexed - so that I could write some code using it? |
| 07:09 | bartj | anyone? |
| 07:27 | mikem | looking 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:32 | reZo | ohai |
| 07:33 | bartj | mikem: my guess - that they are optional arguments |
| 07:34 | mikem | bartj: hm I thought optional arguments are suffixed with a * |
| 07:36 | bartj | mikem: 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:43 | hoeck | mikem: those are some macro-only?, compiletime? args while expanding the macro, &env resolves to the current lexical environment, &form to the current form |
| 07:44 | patrkris | how do I get the Class<T> of Integer? Tried Integer/TYPE, but that is apparently not it. |
| 07:45 | hoeck | mikem: sorry, those are arguments the macro-expansion function takes when called |
| 07:45 | hoeck | ,Interger |
| 07:45 | clojurebot | java.lang.Exception: Unable to resolve symbol: Interger in this context |
| 07:45 | hoeck | ,Integer |
| 07:45 | clojurebot | java.lang.Integer |
| 07:46 | patrkris | hoeck: just like that? cool :) |
| 07:48 | hoeck | yeah, Integer/TYPE returns the primitive type int |
| 07:49 | bartj | what 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:12 | clojurebot | "a//b//c" |
| 08:12 | _na_ka_na_ | File/separator is two times coz of windows |
| 08:19 | mikem | hoeck: ah great, thanks for that clarification |
| 08:20 | hoeck | mikem: to see what they contain, you can use a dummy macro like this: (defmacro foo [] (println &env &form)) |
| 08:21 | hoeck | mikem: and expand in a let: (let [x 10] (foo)) |
| 08:38 | mikem | also 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:40 | mikem | i guess it must be |
| 08:40 | chouser | no |
| 08:41 | chouser | type hints *are* metadata |
| 08:41 | mikem | a lightbulb just went on over my head :P of course! |
| 08:41 | chouser | "^FooType foo" is just short for "^{:tag FooType} foo" |
| 08:42 | mikem | thanks :) |
| 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:48 | clojurebot | true |
| 08:49 | _na_ka_na_ | ,(let [m (.matcher #"(.+)\.([^\.]+)" "a.b.c")] (.groupCount m)) |
| 08:49 | clojurebot | 2 |
| 08:49 | _na_ka_na_ | ,(let [m (.matcher #"(.+)\.([^\.]+)" "a.b.c")] (.group m 0)) |
| 08:49 | clojurebot | java.lang.IllegalStateException: No match found |
| 08:49 | _na_ka_na_ | Please tell me why the above fails? |
| 08:50 | rhickey | chouser: want to discuss recur? |
| 08:50 | chouser | rhickey: 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:50 | clojurebot | "a.b.c" |
| 08:50 | chouser | _na_ka_na_: clojure has re- functions that make these things easier. |
| 08:51 | rhickey | first and foremost, recur is about no stack usage - goto |
| 08:51 | rhickey | with loop, the target is labelled by loop |
| 08:52 | chouser | yep, I'm with you so far |
| 08:52 | rhickey | with fns, the target is the same fn, with the same arglist. The 'this' is the fn, and implicit |
| 08:52 | rhickey | you can't goto another method in the same this, or to another this |
| 08:53 | chouser | hmmm |
| 08:53 | rhickey | to do so would be a proper method call with stack overhead |
| 08:55 | chouser | because the fn is a java method and you can't change the value of 'this' within it. |
| 08:56 | rhickey | because you can't recur out of a method |
| 08:57 | rhickey | naming this is what's broken as it is really not an argument supplied in the normal way |
| 08:57 | chouser | when you recur to a fn, locals are actually re-assigned, right? |
| 08:58 | rhickey | but doing so is useful and preferred |
| 08:58 | rhickey | chouser: yes |
| 08:58 | chouser | and the JVM won't let you reassign 'this' even if you wanted to. |
| 08:58 | rhickey | but technically, rebound |
| 08:59 | rhickey | chouser: 'this' is not an argument, nor a local in Java |
| 08:59 | chouser | right |
| 08:59 | chouser | no way to refer to it in the bytecode such that it could be rebound |
| 08:59 | rhickey | there's nothing to rebind |
| 09:01 | rhickey | placing this in the arglist just makes it appear like something it's not |
| 09:01 | rhickey | but we've done that |
| 09:02 | rhickey | but that shouldn't swap our thinking around |
| 09:02 | rhickey | this is not an argument |
| 09:02 | chouser | no, it's more of a debate. |
| 09:02 | chouser | sorry, j/k |
| 09:02 | rhickey | aargh |
| 09:02 | chouser | ok, I'm with you |
| 09:03 | rhickey | one way out is top forbid recur to method head in deftype/record method bodies, force using loop |
| 09:03 | rhickey | but that seems like a loss |
| 09:04 | chouser | My 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:04 | rhickey | doing so would make it obvious, because people that tried to loop-rebind this would find they couldn't then use it without using '.' |
| 09:05 | chouser | *sigh* I don't follow. |
| 09:06 | rhickey | if 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:07 | chouser | yes, I see that. |
| 09:07 | rhickey | but if you wanted to recur with this ... (loop [this this x x] ... (recur new-this new-x)) |
| 09:07 | rhickey | but why would you do that if you didn't want to use this? |
| 09:08 | rhickey | and if you did want to use this, you'd find yourself needing to use '.' |
| 09:08 | chouser | ah, instead of plain names to refer to your own fields, for example. |
| 09:08 | rhickey | and thus I hope understand why this isn't a bindable recur target, you must call another method to use it |
| 09:09 | rhickey | yes, or explicit field ref |
| 09:11 | rhickey | so, the this 'arg' is truly special, and it is surprising only recur exposes that |
| 09:12 | chouser | ok, it that last point that finally makes it click for me |
| 09:12 | rhickey | I think the choice of propagating the specialness to recur is least appeal atm |
| 09:13 | rhickey | so either we call out this arg, and thus why it can't be in recur, or disallow recur to deftype/record method head |
| 09:13 | chouser | in the method bodies x means (.x this), but if you could rebind 'this' those would mean different things. or something. just broken. |
| 09:13 | rhickey | we have the former right now |
| 09:14 | djpowell | I'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:20 | chouser | djpowell: I'm with you on that. |
| 09:21 | chouser | rhickey: I think the current behavior of recur is good, now that I understand why. |
| 09:22 | rhickey | so, what do people prefer - recur not pass this, or disallowed? |
| 09:22 | rhickey | chouser: oh good! |
| 09:22 | chouser | disallowed doesn't seem any better |
| 09:23 | _na_ka_na_ | rhickey: can you explain with an example how the first option would work? |
| 09:23 | rhickey | chouser: it would be better only in calling out methods as not first class fns, the heads of the latter being ok recur targets |
| 09:24 | chouser | yeah, and a more informative error message, etc. |
| 09:24 | rhickey | _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:24 | chouser | But the "what" is clearly documented as it is, and you can always use 'loop' to get explicit and clear behavior |
| 09:25 | rhickey | _na_ka_na_: inside you can just use a and b |
| 09:25 | chouser | as you said, you could even do (loop [this this] ...) if you want, but then the meaning of plain field symbols goes all wonky |
| 09:25 | rhickey | chouser: 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:27 | chouser | some 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:27 | rhickey | chouser: 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:28 | chouser | no, 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:28 | chouser | no, I really don't think so. |
| 09:29 | chouser | (defrecord C [a] (foo [this] (prn a) (loop [this this] (prn a) (when a (recur other-c)))) |
| 09:30 | chouser | I think it would seem magical and unexpected for the a's inside the loop to get new values on recur |
| 09:31 | rhickey | yeah, and the lack of use of this in the body a sure sign of something wrong |
| 09:31 | SinDoc | Any ideas as to making ADTs in Clojure? |
| 09:31 | rhickey | SinDoc: deftype |
| 09:32 | chouser | really, the only answer I needed for my original concern was "what about plain symbols referring to fields?" |
| 09:32 | chouser | I wasn't considering those. |
| 09:32 | chouser | With them in the picture, my argument (er, debate) falls apart. |
| 09:32 | SinDoc | rhickey: 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:35 | rhickey | chouser: still, that's more of the symptom than the root cause |
| 09:35 | chouser | _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:36 | rhickey | (foo this [x] ... (recur new-x)) |
| 09:37 | chouser | _na_ka_na_: Maybe it should use (.a this) inside the loop instead of just a |
| 09:37 | chouser | rhickey: yeah, that thought occured to me. |
| 09:37 | chouser | or maybe :as this up at the top. ;-) |
| 09:37 | rhickey | is more akin to fn, but a break from the protocol sigs |
| 09:37 | rhickey | chouser: heh |
| 09:38 | rhickey | no, it's better than :as at top by a lot |
| 09:38 | rhickey | the 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:39 | chouser | you need to be able to refer to it |
| 09:39 | rhickey | _na_ka_na_: for method self-calls and to pass your this to others |
| 09:39 | chouser | so 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:45 | chouser | _na_ka_na_: These options have all been discussed. :-) Previously you could name the 'this' for the whole defrecord by saying ":as this" |
| 09:46 | chouser | one 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:47 | chouser | I 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:50 | Licenser_ | hmm anyone using enclojure? |
| 10:01 | cemerick | Licenser_: yes |
| 10:10 | Licenser_ | cemerick: did you ever have the problem that you can't create new projects? |
| 10:11 | cemerick | Licenser_: I've never created a clojure-specific project in netbeans/enclojure. Just a regular java project with clojure dependencies is just fine. |
| 10:12 | cemerick | (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:13 | Licenser_ | *nods* okay too sad |
| 10:27 | cemerick | Licenser_: why sad? |
| 10:30 | somnium | I'm a bit disappointed that (ahem) 'Fantom' has made it to the available plugins list ahead of Clojure |
| 10:31 | cemerick | somnium: this is in netbeans? |
| 10:32 | cemerick | oh, yup, there it is |
| 10:40 | chouser | ugh, I hate discovering I've been building on an incorrect assumption |
| 10:40 | bozhidar | most people do :-) |
| 10:41 | Hodapp | well, 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:48 | chouser | turns out this thing is an identity not a value. |
| 10:49 | chouser | speaking of which, it's interesting that clojure's all about the split between identity and value, and it has functions 'identity' and 'val'. |
| 10:52 | lpetit | rhickey: reminder for you to add clojure.com ref in #clojure 's topic :) |
| 10:55 | drewr | quick macro question |
| 10:55 | drewr | how can I get `((foo) (bar) (baz)) to expand to (foo) (bar) (baz)? |
| 10:56 | lpetit | drewr: you can't |
| 10:56 | bozhidar | clojure.com? |
| 10:56 | clojurebot | clojure is not groovy |
| 10:56 | drewr | the normal idiom is `(do ~@(....)), but the wrapping do won't work in this case |
| 10:56 | somnium | clojurebot: mechanic? |
| 10:56 | clojurebot | No entiendo |
| 10:56 | lpetit | drewr: but you can have `(do (defn (...)) (def ...)) at the top level |
| 10:57 | chouser | drewr: a macro returns a single thing, it can't return 3 things |
| 10:57 | lpetit | drewr: if the macro is called from top level, the do will be read as if each of its child were emitted in sequence |
| 11:00 | drewr | ok |
| 11:01 | drewr | I should be able to expand it in a parent macro |
| 11:01 | drewr | just wanted to make sure I wasn't missing an obvious hack |
| 11:07 | cgrand | ,(-> (range 33) vec transient pop! count ) |
| 11:07 | clojurebot | java.lang.IllegalAccessError: Transient used after persistent! call |
| 11:08 | cgrand | ,(-> (range 42) vec transient pop! count ) |
| 11:08 | clojurebot | 41 |
| 11:09 | Plouj | (doc source) |
| 11:09 | clojurebot | "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:09 | Plouj | (source doc) |
| 11:09 | Plouj | for some reason my slime-repl doesn't find source |
| 11:10 | Plouj | ,(source doc) |
| 11:10 | clojurebot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 11:10 | bozhidar | have you required it? |
| 11:10 | Plouj | yeah |
| 11:10 | bozhidar | only required or used? |
| 11:11 | Plouj | humm |
| 11:11 | Plouj | actually it seems that (clojure.contrib.repl-utils/source doc) works |
| 11:11 | Plouj | (clojure.contrib.repl-utils/source doc) |
| 11:11 | Plouj | ,(clojure.contrib.repl-utils/source doc) |
| 11:11 | clojurebot | java.lang.ClassNotFoundException: clojure.contrib.repl-utils |
| 11:11 | Plouj | weird, I used to get that ClassNotFoundException too |
| 11:13 | bozhidar | I do a |
| 11:13 | bozhidar | (use 'clojure.contrib.repl-utils) |
| 11:13 | bozhidar | and (source source) for example works just fine for me |
| 11:14 | bozhidar | clojure 1.1 |
| 11:14 | Plouj | humm, that works for me too, now |
| 11:16 | bozhidar | when you do an import you have use the full namespace before the symbol unsless you used :as |
| 11:18 | stuarthalloway | anybody here write clojure code that uses Strings? |
| 11:19 | stuarthalloway | if 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:24 | fogus_ | I might find better names for chop and chomp |
| 11:29 | stuarthalloway | fogus_: well do it then! :-) |
| 11:30 | stuarthalloway | those names are common to the scripting languages, but if you've better ones I am all ears |
| 11:30 | stuarthalloway | maybe EndOfStringCleanupFactoryCreator.getInstance.create.removeStuff(options) |
| 11:31 | fogus_ | I suspected that they were. |
| 11:31 | fogus_ | I suppose if they are ubiquitous then I'm the weird one here |
| 11:31 | stuarthalloway | still, if you have any other names at all I would like to hear them |
| 11:31 | candera | There are only two hard problems in computer science: naming things, cache invalidation, and off-by-one errors. |
| 11:31 | eikke | does clojure have a 'zip' equivalent? |
| 11:32 | somnium | I think code like: (-> *nomnom* chomp slurp chop chop spit) is rather elegant |
| 11:32 | cgrand | eikke: (map vector coll1 coll2 ...) |
| 11:32 | fogus_ | Is options a concrete realization of IDoWeirdStuffToStringsKeySet? |
| 11:32 | eikke | cgrand: ah, makes sense...thanks! |
| 11:33 | dnolen | stuarthalloway: 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:33 | stuarthalloway | if their semantics are identical then chomp will get dumped |
| 11:34 | fogus_ | dnolen: chomp works on the end only |
| 11:35 | bozhidar | btw should upper-case and lower-case actually be uppercase & lowercase? |
| 11:35 | dnolen | fogus_: ah |
| 11:35 | stuarthalloway | bozhidar: don't think so |
| 11:35 | stuarthalloway | the Java versions camel case at the 'c' |
| 11:35 | bozhidar | according to the dictionary upper case and uppercase are both valid |
| 11:36 | bozhidar | and I think that for a function name the single word should be favoured |
| 11:36 | stuarthalloway | so we are being "consistent" with Java, in some odd sense |
| 11:36 | bozhidar | I assumed so |
| 11:36 | arohner | does congomongo support sending JS to the server? |
| 11:36 | bozhidar | I'd prefered names like upcase/downcase - they sound more groovy ;-) |
| 11:37 | stuarthalloway | so nobody is going to say "you forgot my favorite string function"? |
| 11:37 | somnium | arohner: there's a method, db.eval on one of the db classes. |
| 11:37 | bozhidar | other than that I think the library's got what is generally needed |
| 11:37 | arohner | somnium: and when querying? |
| 11:37 | bozhidar | sometimes there are separated ltrim/rtrim methods though |
| 11:37 | somnium | arohner: I found its quite easy to crash a mongod with it though |
| 11:38 | arohner | somnium: oh, fun. Thanks for the warning |
| 11:38 | stuarthalloway | bozhidar: those exist in contrib, but are not (yet) on the list for promotion, |
| 11:38 | somnium | arohner: I think there's a $js or $eval key |
| 11:39 | stuarthalloway | in other news: we are going to start doing sublibrary builds for contrib |
| 11:39 | bozhidar | stuarthalloway: where are you promoting this string functions to? |
| 11:40 | stuarthalloway | to address the problems people have expressed around unnecessarily coarse dependencies + churn in contrib |
| 11:40 | stuarthalloway | bozhidar: clojure.string in clojure.jar |
| 11:40 | bozhidar | great |
| 11:40 | stuarthalloway | the sublibrary thing seems like boring detail work for someone (hoping to sucker sierra into it :-) ) |
| 11:40 | fogus_ | 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:41 | bozhidar | btw I think I read in your book that your opinion was that stuff like String manipulation don't need clojure wrappers |
| 11:41 | stuarthalloway | ... but the sublibraries should be an easy win for library users ... or am I missing some danger here? |
| 11:42 | stuarthalloway | bozhidar: 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:42 | stuarthalloway | so if they are going to be there, they might as well be right |
| 11:43 | bozhidar | sure |
| 11:43 | bozhidar | I'd probably prefer them myself if there are part of clojure.jar |
| 11:44 | bozhidar | since I generally avoid using stuff from contrib, fearing the extent to which they were tested |
| 11:44 | somnium | is (upper-case "foo") => (.toUpperCase "foo") ? |
| 11:45 | bozhidar | yes |
| 11:48 | fogus_ | Oh I see now. chop and chomp are Perlism. |
| 11:49 | bozhidar | fogus_: and Rubism as well |
| 11:50 | somnium | I wonder if haskell is the only language with a function called 'intercalate' in its std-library |
| 11:52 | fogus_ | If we change chomp to rstrip, then we can add an additional lstrip, and then add ltrim and rtrim. too much? :p |
| 11:53 | stuarthalloway | fogus_: not seeing them used much in code to date... |
| 11:54 | fogus_ | Fair enough. It might still be useful to rename chomp to rstrip |
| 12:01 | bozhidar | I think chomp will do fine |
| 12:01 | bozhidar | and there is no problem to have a couple of sinonyms for some function I guess |
| 12:02 | bozhidar | this was one of the things I liked a lot about Ruby |
| 12:02 | chouser | I very very much dislike that about Ruby |
| 12:02 | bozhidar | for me in Clojure a bad name choice was the count function |
| 12:02 | yacin | i 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:02 | bozhidar | I remember when I first needed it |
| 12:02 | yacin | how should i go about packaging it? |
| 12:02 | bozhidar | trying (size ..) |
| 12:02 | bozhidar | (length ...) |
| 12:03 | bozhidar | without consulting the docs I'd never have figured out that I needed count... |
| 12:04 | bozhidar | chouser: I dislike the many leftovers from Perl and the end for end statements |
| 12:04 | fogus_ | rstrip is much more descriptive and does not require that you have experience in some esoteric language. ;) |
| 12:04 | bozhidar | but I don't think that the freedom of choice that Ruby's authors have given developers is that bad |
| 12:05 | bozhidar | though it might be confusing indeed if you're not familiar with the language |
| 12:05 | bozhidar | fogus_: Perl is far from esoteric - after all it's far more popular than Clojure |
| 12:06 | bozhidar | from a JAPH's point of view probably Clojure is just as esoteric ;-) |
| 12:06 | fogus_ | plus rstrip leaves the door open for lstrip... what does chomp provide? lchomp? champ? |
| 12:06 | somnium | has anyone ported Acme::Buffy to clojure? |
| 12:06 | fogus_ | bozhidar: Just kidding |
| 12:07 | bozhidar | fogus_: just kidding back ;-) |
| 12:08 | bozhidar | I 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:08 | bozhidar | it was a fun ride while it lasted, though :-) |
| 12:09 | bozhidar | now* |
| 12:10 | fogus_ | Finally, rstrip works better in an overall StrippingProtocol (not what you think). |
| 12:10 | rhickey | fogus_: rstrip is just about newlines? |
| 12:10 | bozhidar | you should think more about strippers ;-) |
| 12:10 | fogus_ | rhickey: yes |
| 12:11 | rhickey | fogus_: and lstrip is also? |
| 12:11 | fogus_ | yes |
| 12:11 | rhickey | is that a real use case - leading newlines? |
| 12:11 | bozhidar | rhickey: fogus_ is not correct |
| 12:12 | fogus_ | :( |
| 12:12 | bozhidar | rstrip/rstrip should generally strip every whitespace character |
| 12:12 | cgrand | rhickey or stuarthalloway: did you see https://www.assembla.com/spaces/clojure/tickets/358 ? |
| 12:12 | bozhidar | including newlines |
| 12:13 | fogus_ | bozhidar: I thought that was trim/ltrim/rtrim's job? |
| 12:13 | stuarthalloway | cgrand: just claimed it |
| 12:13 | bozhidar | fogus_: true |
| 12:13 | stuarthalloway | thanks! |
| 12:13 | bozhidar | that's why chomp is not exactly rstrip |
| 12:14 | bozhidar | since at least in Perl it removed only the trailing newline |
| 12:14 | bozhidar | if any |
| 12:14 | replaca | rhickey, 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:14 | cgrand | stuarthalloway: ok, thanks |
| 12:14 | rhickey | replaca: which mismatch? |
| 12:14 | bozhidar | in most languages - strip == trim |
| 12:15 | replaca | with-in-reader returns a PushbackReader and line-seq wants a BufferedReader (I think that's right) |
| 12:16 | replaca | rhickey: yeah, that's it |
| 12:17 | rhickey | replaca: what's the fix? |
| 12:19 | replaca | rhickey: 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:19 | stuarthalloway | build on top of a language with good IO abstractions? :-) |
| 12:19 | fogus_ | 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:19 | replaca | rhickey: all I know is that they don't play well together :) |
| 12:20 | replaca | rhickey: 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:21 | bozhidar | fogus_: I tought we were have a more general discussion, about the naming -> what should it do. Sorry about that |
| 12:21 | rhickey | replaca: that would be great, thanks |
| 12:21 | replaca | rhickey: k, I'll do it later on today |
| 12:22 | bozhidar | were having* |
| 12:22 | bozhidar | I hate my typing... |
| 12:22 | patrkris | why is [null] |
| 12:22 | patrkris | ... prepended to all output from leiningen? |
| 12:25 | stuarthalloway | patrkris: level 1 answer: it's an ant thing |
| 12:25 | patrkris | stuarthalloway: ah... any way to get around it? |
| 12:25 | stuarthalloway | maybe -- years since I forgot ant |
| 12:25 | patrkris | :) |
| 12:26 | stuarthalloway | if there is a way, it probably would require some small change to lein to expose it |
| 12:31 | Chousuke | I think it actually has something to do with the logging facilities |
| 12:32 | angerman | it's not possible to have a tree-shaker for clojure, right? |
| 12:36 | arohner | angerman: I don't think it's possible to do purely in clojure. it'd have to understand the host language as well |
| 12:37 | angerman | arohner: well I guess cleanly designed and separable librarys would make it not such much a problem :D |
| 12:38 | angerman | and otherwise I guess it could get really trick to figure out what is dynamically loaded ... |
| 12:40 | mefesto | is there an existing function that will provide a lazy-seq of chars for a Reader? |
| 12:44 | arohner | mefesto: what are you trying to do? |
| 12:44 | arohner | ,(seq "foo") |
| 12:44 | clojurebot | (\f \o \o) |
| 12:44 | arohner | somnium: are you interested in a patch to congomongo that allows you to send arbitrary JS to the server? |
| 12:45 | mefesto | arohner: parsing some file and i need to be aware of newlines depending on if im in quotes or not |
| 12:45 | Licenser_ | Writing clojure in windows is a sad experience :( |
| 12:45 | mefesto | so line-seq wouldn't work since a quote could be open on line 1 and closed on line 5 |
| 12:45 | arohner | mefesto: oh, a java stream Reader, not a clojure compiler reader |
| 12:45 | candera | Licenser_: agree. It's the ghetto. |
| 12:45 | mefesto | arohner: yeah, sorry for the confusion. |
| 12:46 | Licenser_ | I tried emacs, ccw and enclojure all make me cry :/ |
| 12:46 | Licenser_ | Why can't my boss give me a MacBook :P |
| 12:46 | Chousuke | mefesto: (repeatedly #(.read thereader)) should work |
| 12:47 | candera | I 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:48 | mefesto | Chousuke: i went this route since i wanted them to be chars, overkill?: https://gist.github.com/6d7c8a2c9bcd748b22fb |
| 12:49 | mefesto | ,(char -1) |
| 12:49 | clojurebot | java.lang.IllegalArgumentException: Value out of range for char: -1 |
| 12:49 | Licenser_ | 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:49 | Quiesce | Licenser_: Yeah? What would you use on this hypothetical gift MacBook? |
| 12:49 | Chousuke | mefesto: that's essentially what my suggestion does |
| 12:49 | Licenser_ | Quiesce: AquaEmacs :P and a usefull internet connection hopefully |
| 12:49 | Chousuke | mefesto: except it doesn't check for EOF, it includes in in the stream |
| 12:51 | angerman | yea, Aquamacs is pretty nice. ... |
| 12:51 | angerman | except when you run into C-; making the meta switch :D |
| 12:51 | somnium | arohner: sure |
| 12:53 | drewr | isn't there a flatten-1 somewhere that only flattens a sequence one list deep? |
| 12:54 | drewr | ie: (flatten-1 '(1 2 (3 (4 5)))) -> (1 2 3 (4 5)) |
| 12:54 | drewr | or is it called something else? |
| 12:54 | chouser | apply concat |
| 12:54 | drewr | hm |
| 12:54 | chouser | hm, or maybe not in that case. |
| 12:55 | chouser | ,(mapcat #(if (coll? %) % [%]) '(1 2 (3 (4 5)))) |
| 12:55 | clojurebot | (1 2 3 (4 5)) |
| 12:55 | chouser | dunno if there's a flatten-1 somewhere or not |
| 12:56 | drewr | my contrived example isn't quite right |
| 12:57 | drewr | '((1 2) (3 4) ((5 6) (7 8))) -> ((1 2) (3 4) (5 6) (7 8)) is more like what I need |
| 12:57 | drewr | my macro needs to end up with a list of single sexps |
| 12:58 | chouser | I assume it's not always just the last one that's grouped an extra level? |
| 12:58 | drewr | right |
| 12:59 | chouser | ,(mapcat (fn [[x :as a]] (if (coll? x) a [a])) '((1 2) (3 4) ((5 6) (7 8)))) |
| 12:59 | clojurebot | ((1 2) (3 4) (5 6) (7 8)) |
| 13:00 | drewr | ah, thanks, I think that works |
| 13:01 | KirinDave | I finally got around to reading "Multiple Dispatch in Practice" |
| 13:02 | KirinDave | Man, it's really interesting how there seems to be this consistent but small desire for multiple dispatch |
| 13:03 | drewr | what'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:04 | drewr | ...which shouldn't have changed the behavior of the flatten |
| 13:04 | drewr | but oh well |
| 13:04 | zakwilson | Given enough time, almost every project needs multiple dispatch or some sort of ugly hack to simulate it. |
| 13:05 | KirinDave | zakwilson: I was just surprised at how consistent that demand is |
| 13:05 | KirinDave | And it's not for like 7 way dispatch, the majority is 2 term dispatch |
| 13:07 | rhickey | KirinDave: 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:08 | KirinDave | rhickey: When you say double dispatch you mean? |
| 13:08 | rhickey | KirinDave: dispatching on 2 terms via 2 single-dispatches |
| 13:08 | KirinDave | Ah |
| 13:09 | KirinDave | So yeah, bouncing back and forth a la visitor? |
| 13:09 | rhickey | normally that's a problem using interfaces, leading to the dreaded visitor |
| 13:09 | rhickey | but protocols are not type intrusive, so it's clean and open |
| 13:09 | KirinDave | rhickey: I must confess, from a strictly aesthetic perspective I don't like that solution. |
| 13:09 | KirinDave | protocols DO make it easier. |
| 13:10 | KirinDave | And the 2 dispatch system is more amenable to trace tree optimizations. |
| 13:10 | KirinDave | Still, it just sticks in my teeth. :) |
| 13:10 | rhickey | not just easier, substantively different in that it is open, double dispatch with interfaces can't be |
| 13:11 | KirinDave | I understand and agree. :) |
| 13:11 | KirinDave | I just like reading code where the double dispatch is clear |
| 13:11 | KirinDave | So md methods seem like a better notation to me. It's very clear what's happening. |
| 13:27 | KirinDave | Oh McCarthy |
| 13:27 | KirinDave | srry |
| 14:18 | islon | is there a way to set the number of agent threads used by send-off? |
| 14:18 | chouser | no, it grows as needed. |
| 14:21 | islon | hmmm... 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:21 | chouser | to the same agent? |
| 14:22 | islon | yes... ok I got it... |
| 14:28 | cemerick | sending to one's own threadpool/executionservice is on my 1.3 list |
| 14:28 | cemerick | send-to, perhaps |
| 14:30 | rhickey | cemerick: send-to vs (agent ... :on-pool pool) ? |
| 14:31 | rhickey | I don't think consumers want/need to know about the pool |
| 14:31 | chouser | that would influence only send-off not send? |
| 14:31 | rhickey | chouser: both |
| 14:32 | chouser | huh |
| 14:32 | cemerick | rhickey: that's why my first thought was send-to |
| 14:32 | cemerick | send and send-off are thin abstractions for what pool to use |
| 14:33 | chouser | it'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:33 | cemerick | right |
| 14:33 | islon | the :on-pool is implemented? |
| 14:33 | cemerick | no |
| 14:33 | chouser | seems weird to remove that option in order be able to use your own pool. |
| 14:33 | rhickey | If you are choosing its pool you must know how you are going to use it |
| 14:33 | cemerick | the usage can be mixed, though |
| 14:34 | fogus_ | I try not to think about pools |
| 14:34 | rhickey | cemerick: so choose a pool that works for both, certainly we could only have send-off |
| 14:35 | rhickey | but providing a pool at every send-to is a catastrophe from an app modularity standpoint |
| 14:35 | cemerick | yeah, I can see that |
| 14:36 | rhickey | really, looking back I'd rather have had only send and force you to choose a pool at agent construction |
| 14:36 | cemerick | In 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:36 | cemerick | right, yes |
| 14:37 | rhickey | cemerick: if you always use blocking-is-ok there is only one semantic |
| 14:37 | rhickey | even if it doesn't ever block |
| 14:38 | chouser | I think that'd be fine with me. |
| 14:38 | rhickey | so send == send-off, supply a pool to get a compute-only agent |
| 14:38 | rhickey | deprecate send-off |
| 14:38 | chouser | sure |
| 14:39 | islon | what about (binding [*agent-pool* my-pool] (do stuff...)) |
| 14:39 | chouser | binding-only args are baaad. |
| 14:39 | chouser | especially in such close proximity to theads |
| 14:40 | chouser | (binding [*agent-pool* my-pool] (send foo #(do ... (send foo ...)))) ; sends to two different pools! |
| 14:40 | islon | right |
| 14:43 | remleduff | Do 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:44 | remleduff | Once 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:44 | cemerick | rhickey: sounds good to me |
| 14:45 | chouser | remleduff: 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:45 | hiredman | binding is the doom of the world |
| 14:45 | hiredman | (unless you use it to emulate multiple returns) |
| 14:45 | chouser | heh |
| 14:46 | remleduff | I think that would be the top check I'd like to see in a clj-lint project ;) |
| 14:49 | technomancy | hiredman: botsmack |
| 15:13 | bartj | anyone from an information extraction background and using clojure here? |
| 15:20 | cemerick | bartj: hi :-) |
| 15:20 | cemerick | very broad concept there |
| 15:59 | remleduff | Is there a difference between butlast and drop-last? |
| 16:00 | chouser | hardly. drop-last is lazy |
| 16:01 | remleduff | Is there a difference between chomp and butlast/drop-last? |
| 16:02 | remleduff | Oh, chomp checks if it's a newline |
| 16:02 | chouser | and returns a string, presumably. butlast and drop-last return seqs |
| 16:02 | chouser | oh, I see where you're ogin |
| 16:02 | chouser | goin |
| 16:02 | chouser | going |
| 16:03 | chouser | clojure.string/butlast instead of chop or less |
| 16:03 | remleduff | Probably slightly too big of a semantic difference |
| 16:04 | chouser | I think it's the same as chop -- drops one thing regardless of what it is |
| 16:04 | chouser | chomp/rtrim/rstrip are something else |
| 16:06 | remleduff | Oh yes, I meant chop ;) |
| 16:09 | fogus_ | Is butlast defined by its drop-iness or its seq-iness, or are they inseparable? |
| 16:09 | tomoj | huh? |
| 16:10 | chouser | butlast should continue to return a seq, as it does now |
| 16:10 | chouser | ,(butlast "abc") |
| 16:10 | clojurebot | (\a \b) |
| 16:11 | chouser | but (clojure.string/butlast "ab") could certainly return "ab" |
| 16:11 | fogus_ | That's kinda confusing no? |
| 16:11 | chouser | isn't that what clojure.string is all about? |
| 16:12 | fogus_ | confusion? |
| 16:12 | chouser | right! |
| 16:12 | fogus_ | :p |
| 16:12 | chouser | wait, no. |
| 16:12 | chouser | reusing names fron clojure.core, but applied to strings |
| 16:12 | fogus_ | Well, that I'm not sure. |
| 16:13 | chouser | like replace, and ... others I can't think of. |
| 16:13 | tomoj | what 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:14 | tomoj | or is the seq abstraction too important to optionally abandon? hmm |
| 16:14 | remleduff | I really like the way protocols let you provide a default implementation and then specialize where appropriate, so I hope something like that happens |
| 16:15 | chouser | tomoj: I think there have been a couple efforts in that direction |
| 16:15 | tomoj | excellent |
| 16:15 | chouser | clojure.contrib.generic or something, and I think sean devlin has done something else. |
| 16:18 | tomoj | wonder what good names would be for those functions/macros |
| 16:18 | fogus_ | 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:19 | chouser | hm... I wonder if it's the wrong approach. |
| 16:19 | tomoj | you would like to see #3 but don't know what it would be? |
| 16:19 | fogus_ | not sure. It's not really formulated in my brain yet |
| 16:20 | remleduff | Why do you need functions that return a seq, as long as everything knows how to produce a seq when needed? |
| 16:20 | chouser | A 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:20 | tomoj | even with transients? |
| 16:20 | tomoj | hadn't considered that possibility |
| 16:20 | chouser | transients would still be eager |
| 16:20 | tomoj | ah, hmm |
| 16:21 | fogus_ | darn... gotta go |
| 16:21 | chouser | lazy 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:21 | tomoj | I 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:21 | chouser | such that intermediate objects not even be created. |
| 16:21 | tomoj | nice |
| 16:22 | chouser | even 1.1 has chunked seqs that can beat some naive hand-written loops. |
| 16:22 | chouser | so perhaps something that conveniently wraps the whole chain for you... |
| 16:23 | chouser | (same-type->> my-vector (map ...) (filter ...) (partition ...) ...) |
| 16:23 | tomoj | when we're working with seqables qua data not qua seqs, I wonder if this would still be faster |
| 16:23 | tomoj | e.g. transforming a bunch of small maps with filter or something in the inner loop |
| 16:24 | tomoj | if the seqables are small I guess it won't matter a whole lot anyway |
| 16:24 | hsjunnesson | So, hm.. |
| 16:24 | tomoj | or maybe it would matter more? gah, I'm just confused now |
| 16:24 | chouser | heh |
| 16:24 | hsjunnesson | Okay, so I asked this in #leiningen but no one there replied. I figured people here might have a bead on this. |
| 16:25 | hsjunnesson | I 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:25 | tomoj | as the seqable grows, the O(n) conversion overhead (like (into {} ...)) becomes less visible, I guess |
| 16:26 | chouser | hsjunnesson: I wouldn't actually be surprised if there were no way to delete jars from clojars |
| 16:26 | hsjunnesson | That's kind of what I'm afraid of. |
| 16:26 | chouser | hsjunnesson: you might send email to the maintainer |
| 16:26 | hsjunnesson | I'll have to do that, thanks. |
| 16:29 | tomoj | I wonder if clojure is a good choice for a first language to teach to non-programmers |
| 16:30 | technomancy | hsjunnesson: yeah, you have to get _ato to do it for you =( |
| 16:30 | chouser | tomoj: 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:32 | tomoj | ah, hmm, hadn't even thought about java interop :( |
| 16:32 | tomoj | learning only enough java to get by at the same time you learn clojure sounds terrible |
| 16:33 | SynrG | i know oop, but mostly via ruby. i'm only learning enough java to do clojure :/ |
| 16:34 | chouser | if you could find enough fun and interesting exercizes that didn't require much (or any?) java calls, it might be perfect. |
| 16:34 | chouser | and now you could learn OOP via records and protocols before confronting all of Java's complexity |
| 16:35 | SynrG | mind you, i've read some java texts ... i've just never actually used it for anythign real |
| 16:35 | SynrG | so i don't have what i'd consider a working knowledge |
| 16:36 | chouser | I'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:37 | mefesto | i think my first reaction to someone that has only programmed in clojure would be, "you spoiled brat!" ;) |
| 16:37 | chouser | heh |
| 16:38 | chouser | I 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:44 | chouser | that 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:45 | mefesto | _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:45 | mefesto | _na_ka_na_: macros let you manipulate the forms before they are evaluated which can be very powerful |
| 16:46 | mefesto | _na_ka_na_: think manipulating an AST |
| 16:46 | chouser | gen-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:47 | remleduff | _na_ka_na_: Your example calculates the substraction at compile time... it might be used for optimization of an expensive constant |
| 16:48 | Borkdude | When 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:49 | chouser | gen-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:49 | chouser | if those were evaluated before being passed to a function, you'd get errors. So instead you'd have to quote all of them. |
| 16:50 | chouser | if generate-class weren't private, you could just call (generate-class '{:name ... :methods ...}) ...it would work fine. |
| 16:50 | remleduff | _na_ka_na_: macros are also for selective evaluation. You couldn't implement a short-circuiting "or" function as a function. |
| 16:50 | chouser | so 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:51 | chouser | what 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:52 | chouser | _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:53 | chouser | without macros, 'or' could be a function that takes a bunch of no-arg functions. |
| 16:53 | chouser | (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:54 | chouser | but 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:54 | chouser | not the same because eval doesn't have access to the local environment where it's called. |
| 16:55 | chouser | eg. this doesn't work: (let [a 1] (eval '(prn a))) |
| 16:55 | _na_ka_na_ | Hmmm |
| 16:55 | Borkdude | _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:56 | chouser | _na_ka_na_: direct compiler support, usually. you can't write your own. |
| 16:56 | _na_ka_na_ | Borkdude: Nope |
| 16:57 | chouser | _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:57 | Borkdude | chouser: 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:58 | chouser | Borkdude: not far at all |
| 16:59 | humphrej | Hi |
| 16:59 | humphrej | here'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:00 | humphrej | should 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:00 | chouser | humphrej: old value is the same as the new value -- you can ignore if you want. |
| 17:01 | mefesto | _na_ka_na_: i believe macro expand continues until all macros are fully expanded |
| 17:01 | chouser | _na_ka_na_: each top-level form goes through several stages before the next top-level form is touched. |
| 17:01 | chouser | 1. read (text to nested data structures) |
| 17:02 | chouser | 2. macroexpand of the outermost form, repeatedly until it is a special operator |
| 17:03 | chouser | 3. 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:03 | humphrej | chouser: yes but I'm thinking the equality test could be expensive if the agent state is large |
| 17:04 | chouser | 4. walk the tree that results from the analysis, emitting bytecode |
| 17:04 | chouser | 5. (optionally) save bytecode to .class files |
| 17:04 | chouser | 6. load and run bytecode. |
| 17:05 | chouser | 1 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:06 | Borkdude | Am 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:06 | chouser | note 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:06 | chouser | _na_ka_na_: no, those inner levels are expanded as parts of the recursion at step 3 |
| 17:07 | Borkdude | Wait, 9. |
| 17:07 | _na_ka_na_ | Hmm so after step 3. macros no longer exist |
| 17:07 | Borkdude | ,(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:07 | clojurebot | clojure.lang.PersistentHashMap |
| 17:08 | chouser | Borkdude: yeah, but you shouldn't rely on that. |
| 17:08 | chouser | _na_ka_na_: essentially, yes! |
| 17:08 | Borkdude | chouser: it could differ per OS or smth? |
| 17:08 | _na_ka_na_ | lol that smiley looks nice in a data structure |
| 17:08 | chouser | Borkdude: per version of clojure |
| 17:09 | Borkdude | chouser: 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:16 | chouser | well! 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:17 | chouser | I 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:18 | chouser | the 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:19 | chouser | you might want: (defmacro m2 [x y] `(do (m1 ~x ~y) (println (- ~x ~y)))) |
| 17:20 | Chousuke | except that will evaluate x and y twice |
| 17:20 | _na_ka_na_ | ya for that one can use let |
| 17:20 | chouser | using eval, macroexpand, or anything with side-effects in a macro definition is pretty suspect. |
| 17:21 | chouser | actually, to a certain extent using defmacro is a bit suspect. :-P |
| 17:21 | remleduff | Hmm, doesn't any macro that expands to def have side effects? |
| 17:21 | Chousuke | remleduff: no |
| 17:21 | Chousuke | remleduff: the code they expand to has side-effects, not the macro |
| 17:22 | remleduff | ah, makes sense |
| 17:22 | Chousuke | it 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:23 | chouser | Chousuke: yes |
| 17:23 | chouser | but you ought to be able to justify at each step why you're doing it in a macro instead of a function. |
| 17:24 | Chousuke | Doesn't penumbra do something like that btw? |
| 17:25 | Chousuke | IIRC reflects the jogl stuff and generates clojure functions/macros... Or maybe I'm confusing it with something else. |
| 17:25 | chouser | of course once you're in that deep you might want to do like clj-native and just call into the ASM lib directly. |
| 17:27 | bozhidar | I was wondering what is the idiomatic way in Clojure to cache a function return values |
| 17:28 | chouser | memoize |
| 17:28 | bozhidar | in a trivial example say we want to cache factorials between invocations |
| 17:29 | bozhidar | chouser: so I should basically just wrap my existing function with memoize and that's all? |
| 17:30 | chouser | for trivial cases, that's it. |
| 17:30 | _na_ka_na_ | bozhidar: even shorter is defn-memo (c.c.def) |
| 17:34 | goodmike_mh | Hey, I'm the numbskull who asked on the Google group about how Agents are lock-free... |
| 17:34 | goodmike_mh | Are either of the authors of Agent.java online, and would you be willing to humor me? |
| 17:35 | chouser | Pretty sure Agent.java is all rhickey. |
| 17:35 | chouser | but others may be able to help |
| 17:36 | goodmike_mh | git blame tells a different tale, chouser. :-) |
| 17:36 | chouser | hmph. |
| 17:36 | Borkdude | chouser: why is it that a conjed array-map sometimes returns a hash-map? |
| 17:36 | goodmike_mh | But I'll take any help i can get |
| 17:36 | bozhidar | chouser, _na_ka_na_ : thanks |
| 17:36 | chouser | Borkdude: because array-maps are only efficient when they're small. |
| 17:36 | goodmike_mh | I can tell it's all about the agent's queue |
| 17:37 | goodmike_mh | The queue can only be updated (e.g. given a new value) in an atomic compareAndSet |
| 17:38 | goodmike_mh | Then the actions in the queue are executed |
| 17:38 | Borkdude | chouser: so 9 (varying over Clojure versions) is kind of the flipping point of efficiency? |
| 17:38 | chouser | Borkdude: that's the conclusion currently implemented, yes. |
| 17:39 | Borkdude | chouser: still you can use array-maps bigger if you want, because of ? |
| 17:40 | chouser | goodmike_mh: almost. if enqueue takes the queue size from 0 to 1, it starts a chain of executions |
| 17:41 | goodmike_mh | chouser: 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:41 | chouser | goodmike_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:41 | chouser | so each action on an agent triggers the execution of the next action on the agent |
| 17:42 | goodmike_mh | chouser: 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:43 | chouser | goodmike_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:43 | goodmike_mh | chouser: Whoa. OK. I think I see that. |
| 17:44 | goodmike_mh | chouser: 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:45 | chouser | agent's actions execute in serial order, yes. |
| 17:46 | goodmike_mh | chouser: Thanks. I really appreciate being able to ask someone who wrote the code. |
| 17:46 | goodmike_mh | chouser: Even if he doesn't remember doing it. :-) |
| 17:46 | chouser | the 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:47 | chouser | I didn't write it! I tweaked the error handling a bit. |
| 17:48 | goodmike_mh | chouser: The CAS on the queue is really sweet. |
| 17:48 | chouser | yeah, that was definitely not me |
| 17:48 | goodmike_mh | chouser: Regardless, thanks for the explanation. |
| 17:48 | chouser | you'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:53 | tomoj | _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:53 | tomoj | I 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:55 | tomoj | oh, hmm |
| 17:55 | tomoj | well, it's useful :) |
| 17:56 | tomoj | not 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:59 | goodmike_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:01 | goodmike_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:01 | tomoj | like ants.clj |
| 18:01 | goodmike_mh | yep |
| 18:02 | _na_ka_na_ | goodmike_mh: you mean an agent in its action fn sends an action to itself again? |
| 18:02 | kasperlanger | I think it's to make actions on agents atomic (the A in ACID) |
| 18:02 | goodmike_mh | _na_ka_na_: exactly. the fn contains a line like (send *agent* foo) |
| 18:03 | goodmike_mh | *agent* being the Var holding a reference to the current agent. |
| 18:03 | arkahn | covered in http://blip.tv/file/812787 with relevant bits at 71:43, specifically 72:50 |
| 18:03 | goodmike_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:05 | arkahn | _na_ka_na_: example code at the bottom of ants.clj http://tinyurl.com/322p5kf |
| 18:06 | goodmike_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:06 | tomoj | an agent action can send send itself to its agent again to set up a sort of infinite loop |
| 18:06 | tomoj | and the action can do some check for whether to send again or not in order to terminate |
| 18:06 | arkahn | _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:07 | tomoj | so 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:08 | arkahn | it'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:09 | arkahn | you're also guaranteed on order (it's fifo) |
| 18:10 | arkahn | you can read an agent at any time but aren't guaranteed you'll see the latest changes |
| 18:10 | goodmike_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:11 | goodmike_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:13 | goodmike_mh | Just a thought. Please, no one go out and architect their systems based on my semi-informed comments. |
| 18:15 | arkahn | Ever 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:16 | arkahn | it seems like a working contortion of the original intent for agents, but maybe I just don't know enough ; ) |
| 18:18 | nDuff | I'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:21 | kasperlanger | If 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:21 | kasperlanger | That's a really nice property to have |
| 18:24 | arkahn | nDuff: 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:25 | nDuff | arkahn, ...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:26 | kasperlanger | Yes the action on the second agent may fail |
| 18:26 | kasperlanger | The atomicity property only holds on a single send not the whole chain of sends |
| 18:27 | kasperlanger | oh |
| 18:27 | arkahn | nDuff: 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:28 | kasperlanger | I don't think sending fails since it's all local stuff but I'm speculating now :) |
| 18:28 | SinDoc | I'm using Clojure 1.2.0-master and have trouble with deftype |
| 18:29 | SinDoc | (deftype point [x y]) |
| 18:29 | arkahn | kasperlanger: 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:30 | arkahn | kasperlanger: ... trying to remember what that precondition check is called ... |
| 18:31 | nDuff | arkahn, http://gist.github.com/415170; the comments at the end of the file point where the issue occurs |
| 18:32 | herdrick | question: 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:32 | herdrick | oops |
| 18:32 | nDuff | (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:33 | herdrick | ok, so the default org.clojure/clojure version according to lein new is 1.1.0 |
| 18:33 | herdrick | isn't that obsolete? |
| 18:34 | herdrick | ah, I see that's the newest version in Clojars |
| 18:34 | remleduff | 1.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:37 | herdrick | okremleduff: ok, thanks |
| 18:41 | islon | "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:42 | SinDoc | I pasted a simple deftype interaction; http://paste.lisp.org/display/100539 |
| 18:44 | SinDoc | The syntax is probably not correct but this is what I understand from (doc doctype) |
| 18:44 | SinDoc | *deftype |
| 18:44 | tomoj | don't use new |
| 18:44 | tomoj | but your example still doesn't work for me after fixing that |
| 18:45 | tomoj | but e.g. this works: (deftype Point [x y]) (def pt (Point. 1 2)) (.x pt) |
| 18:45 | remleduff | deftype defines no functionality, you want defrecord |
| 18:45 | tomoj | also, (defrecord Point [x y]) (def pt (Point. 1 2)) (:x pt) |
| 18:45 | tomoj | yeah |
| 18:46 | islon | how 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:46 | remleduff | islon: Do you have lein-swank in your dev-dependencies, and have you run lein deps? |
| 18:46 | skeeterbug | islon, i had that problem, upgrading lein worked for me |
| 18:46 | Raynes | islon: You need to add swank-clojure to your project.clj file. |
| 18:46 | SinDoc | i thought fields were keywords |
| 18:46 | Raynes | remleduff: lein-swank is obsolete. |
| 18:46 | Raynes | remleduff: lein swank is bundled with the new swank-clojure. |
| 18:46 | remleduff | oh, I should upgrade :) |
| 18:47 | tomoj | http://github.com/technomancy/swank-clojure explains |
| 18:47 | Raynes | [swank-clojure "1.2.1"] |
| 18:47 | islon | thanks, is there a way to lein self upgrade? like "lein upgrade"? |
| 18:47 | Raynes | Put that in your dev-dependencies |
| 18:47 | Raynes | lein update, I believe. |
| 18:47 | skeeterbug | yeah, lein update, but i think older versions didn't have that command |
| 18:47 | Raynes | No, it's lein upgrade |
| 18:47 | tomoj | SinDoc: not on a raw deftype, apparently. for defrecord, yeah |
| 18:48 | islon | wow, works =) |
| 18:49 | remleduff | SinDoc: 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:50 | SinDoc | Yeah, i saw that defrecord implements IPersisistentMap |
| 18:51 | SinDoc | Are there recent examples of deftype? |
| 18:51 | SinDoc | http://paste.lisp.org/display/90329 |
| 18:52 | SinDoc | I 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:54 | tomoj | SinDoc: https://gist.github.com/ad9cad85dc72c41dd52b |
| 18:54 | tomoj | that 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:56 | SinDoc | tomoj: You're a grace; thanks |
| 18:56 | SinDoc | it uses defrecord though |
| 18:56 | tomoj | _na_ka_na_: have you tried macroexpanding? |
| 18:56 | tomoj | SinDoc: yes, because that's what you should use to do that example nowadays |
| 18:57 | tomoj | deftype has similar syntax but no automatic :real :imaginary access |
| 18:57 | _na_ka_na_ | tomoj: didn't get what you meant ? |
| 18:57 | tomoj | _na_ka_na_: I mean, for example, have you tried (macroexpand-1 '(m1 3)) ? |
| 18:57 | _na_ka_na_ | yes |
| 18:58 | tomoj | so you noticed, then, that it expands to nil? |
| 18:58 | _na_ka_na_ | yup |
| 18:58 | tomoj | so why would you want to expand nil and stick that in m2? |
| 18:58 | tomoj | anyway.. (defmacro m2 [y] `(do (m1 ~y) (println "m2 got" ~y))) maybe? |
| 18:58 | SinDoc | tomoj: 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:59 | tomoj | yes, the one I just pasted calls m1 as well |
| 18:59 | arkahn | nDuff: 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:59 | arkahn | right away? All subsequent clojure manipulations would then treat it like a clojure Number ... maybe |
| 18:59 | tomoj | it expands like (m2 5) -> (do (user/m1 5) (clojure.core/println "m2 got" 5)) |
| 19:00 | tomoj | SinDoc: dunno how to help you, good luck |
| 19:01 | SinDoc | tomoj: thanks for the help |
| 19:01 | nDuff | arkahn, ...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:03 | tomoj | I see |
| 19:03 | arkahn | nDuff: 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:03 | tomoj | yeah |
| 19:03 | tomoj | weird |
| 19:03 | arkahn | nDuff: fwiw (which isn't much, considering my noob-ness) I like your code |
| 19:04 | nDuff | arkahn, 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:05 | arkahn | nDuff: np! It's always nice to get a sanity check ... I just hope what I dug up was sane |
| 19:05 | tomoj | _na_ka_na_: I think you might be stuck with the macroexpand, then, not sure |
| 19:06 | tomoj | _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:08 | tomoj | and you can't wrap gen-class with a normal-style macro? never would have thought otherwise, interesting |
| 19:08 | tomoj | I 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:28 | clojurebot | java.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:31 | chouser | _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:33 | chouser | yeah, the docs could use some help there |
| 19:35 | ihodes | anyone in here familiar with Enlive |
| 19:35 | ihodes | ? |
| 19:36 | ihodes | i'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:05 | ihodes | anyone here yet? i'm really interested in learning enlive, but i'm having a small problem i'm sure someone's seen before |
| 20:14 | islon | is clojure.contrib.json the best way to read json in clojure? |
| 20:14 | ihodes | as 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:20 | ihodes | fair enough. technomancy, would you be able to answer a quick question re enlive for me? |
| 20:20 | ihodes | i've been getting "java.lang.NullPointerException ", pointing to a line where i defsnippet, is the issue. |
| 20:20 | islon | well, json parsing is not that difficult |
| 20:20 | danlarkin | ihodes: no! |
| 20:20 | danlarkin | he's busy helping me |
| 20:21 | technomancy | I've only used enlive once... I was pretty confused the whole time. |
| 20:21 | ihodes | ah, 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:22 | technomancy | cgrand is the author; there's also dnolen who's written some docs for it |
| 20:22 | technomancy | neither is around now = |
| 20:22 | technomancy | =\ |
| 20:22 | technomancy | nor lau |
| 20:22 | ihodes | noticed that. siiigh. it looks so nice, but mystery error is a pain. |
| 20:22 | ihodes | yeah lau did what i'm trying to do with it ahah, though i didn't know until last night |
| 20:25 | hugod | ihodes: I think a NPE at that line means that the path to the template is not being found |
| 20:26 | ihodes | unfortunately, it's an absolute path right now, so I don'tt hink that's it. |
| 20:28 | ihodes | though now i've changed the selector for the snippet and get this: java.lang.ArrayIndexOutOfBoundsException: 1 ---- on the same line |
| 20:31 | ihodes | http://pastie.org/979148 is the snippet that is being hated on. there's definitely a file there. i require enlive in as html. |
| 20:44 | herdrick | say, 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:44 | herdrick | while this: (ns user (:use [clojure.set :only (union)])) |
| 20:44 | herdrick | works fine ? |
| 20:45 | herdrick | substituting various things for clojure.set works fine too |
| 20:45 | herdrick | like clojure.contrib.combinatorics |
| 20:45 | herdrick | or whatever |
| 20:45 | herdrick | (assuming you replace union with something in one of those packages |
| 20:45 | herdrick | ) |
| 20:46 | tomoj | is that the exact code which caused the error? |
| 20:47 | herdrick | yep |
| 20:48 | tomoj | can you try both and pastie the repl session? |
| 20:48 | herdrick | sure |
| 20:48 | herdrick | brb |
| 20:48 | tomoj | I'm just boggled |
| 20:50 | herdrick | http://pastie.org/979167 |
| 20:50 | herdrick | this is a fresh install of swank-clojure |
| 20:50 | herdrick | and the first time i'm using lein |
| 20:50 | tomoj | no idea why that could happen |
| 20:51 | herdrick | so probably something wrong with what i'm doing there |
| 20:51 | tomoj | does (use '[incanter.core :only (abs)]) also give the error? |
| 20:51 | herdrick | yep, identical error |
| 20:51 | tomoj | and, does the error come with a stacktrace? I wonder where the error is happening? |
| 20:51 | tomoj | maybe it's inside incanter? that's the only explanation I can think of.. |
| 20:52 | tomoj | your syntax looks perfect to me |
| 20:52 | herdrick | whereas (use '[incanter.coreBAD :only (abs)]) gives what you'd expect: "Could not locate incanter/coreBAD__init.class or incanter/coreBAD.clj on classpath: ... " |
| 20:52 | herdrick | brb |
| 20:52 | hugod | ihodes: the braces around the snippet selector argument look wrong to me |
| 20:53 | tomoj | herdrick: what versions of incanter and clojure are you depending on? |
| 20:54 | herdrick | here's the stacktrace and it's cause: http://pastie.org/979169 |
| 20:54 | herdrick | incanter 1.2.3 |
| 20:54 | herdrick | clojure 1.1.0 |
| 20:57 | tomoj | hmm |
| 20:57 | herdrick | uh oh - |
| 20:57 | herdrick | looks like incanter's project.clj file wants clojure 1.2.0 |
| 20:57 | tomoj | I think incanter 1.2.3 requires clojure 1.2.0 |
| 20:57 | tomoj | yeah |
| 20:57 | herdrick | roger |
| 20:58 | tomoj | that's the only way this error makes sense to me, anyway |
| 20:58 | herdrick | ok, thanks, that's probably it |
| 20:59 | herdrick | i was following this blog post from November: http://data-sorcery.org/2009/11/20/leiningen-clojars/ |
| 20:59 | herdrick | which is like 14 clojure dog years ago |
| 20:59 | herdrick | my bad ;) |
| 20:59 | tomoj | hehe |
| 21:01 | Drakeson | Is there a facility to work with paths (like file system paths)? |
| 21:01 | replaca | Drakeson: I use java.io.File |
| 21:03 | Drakeson | replaca: maybe I miss something. How do you do (path :home "foo/bar") using java.io.File ? |
| 21:04 | Drakeson | is there something easier than (str (System.getProperty "user.home") "/" "foo/bar") ? |
| 21:11 | replaca | Drakeson: More corrrect would be (File. (System.getProperty "user.home) (File. "foo") "bar) |
| 21:11 | replaca | I think - I'm not buried in that java space |
| 21:12 | replaca | easy to imagine a path func that did (path :home "foo" "bar") |
| 21:16 | herdrick | tomoj: ok, that worked |
| 21:16 | herdrick | thanks! |
| 21:18 | herdrick | By 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:19 | herdrick | but now I've got a bunch of Incanter 1.2.3 jars in my /lib dir of my lein-created project |
| 21:19 | herdrick | those shouldn't be a problem, right? |
| 21:19 | ihodes | hugod: i tried removing them: no luck. it's also a selector from david nolen's tutorial :\ |
| 21:19 | herdrick | unless i were to use swank-clojure-project (the avoidance of which was the point of this whole switch to lein) |
| 21:23 | bhenry | herdrick lein clean && lein deps |
| 21:23 | herdrick | bhenry: ok. but is it important? |
| 21:23 | bhenry | yes |
| 21:24 | herdrick | will swank or anything else pick up those extra jars in lib? |
| 21:25 | Drakeson | herdrick: What are you trying to do? |
| 21:25 | herdrick | Drakeson: just curious about the issue |
| 21:26 | herdrick | my problem was solved above |
| 21:27 | Drakeson | oh sorry |
| 21:28 | bhenry | herdrick: 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:29 | tomoj | herdrick: what do you mean 1.2.3 isn't in lein-space? |
| 21:29 | herdrick | bhenry: 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:29 | tomoj | no, you need to remove duplicate jars |
| 21:29 | tomoj | bhenry is correct |
| 21:30 | herdrick | No, Clojure 1.2 isn't in lein-space |
| 21:30 | tomoj | oh, hmm |
| 21:30 | tomoj | you mean that you can't get it with lein? |
| 21:30 | herdrick | well, *i* couldn't in a couple of tries |
| 21:30 | tomoj | you can: [clojure "1.2.0-master-SNAPSHOT"] and [clojure-contrib "1.2.0-SNAPSHOT] or something like that |
| 21:30 | herdrick | i'm new to lein tho |
| 21:30 | herdrick | tomoj: bhenry: ok, thanks for the info on lein and classpaths |
| 21:31 | tomoj | also would need to use 1.2.3-SNAPSHOT for incanter |
| 21:31 | ihodes | anyone here an enlive expert yet? ;) still having a fun little NullPointerException http://pastie.org/979148 |
| 21:31 | herdrick | trying that |
| 21:31 | tomoj | but using an old version and 1.1.0 is not too bad either |
| 21:31 | tomoj | ihodes: what's {[:.cg-post]} supposed to be? |
| 21:31 | tomoj | I'm surprised that doesn't cause an error |
| 21:32 | tomoj | ,'{[:.cg-post]} |
| 21:32 | clojurebot | 1 |
| 21:32 | tomoj | uh, what? |
| 21:32 | bhenry | herdrick, 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:32 | tomoj | oh, the error message is "1", haha |
| 21:32 | ihodes | it's a selector: Noel used it in his tutorial: (def *section-sel* {[:.title] [[:.content (nth-of-type 1)]]}) |
| 21:32 | ihodes | nolen* |
| 21:32 | ihodes | http://github.com/swannodette/enlive-tutorial/ |
| 21:32 | tomoj | ihodes: ok, but your {} is wrapped wrong |
| 21:33 | tomoj | you've got it just around [:.cg-post] |
| 21:33 | tomoj | which looks like a map with a key with no value, which is illegal |
| 21:33 | ihodes | true: i did change it to "[:.cg-post]" in the version i'm playing with now |
| 21:33 | tomoj | ah |
| 21:33 | ihodes | that was a mistake in the pastie when i was messing with stuff, i'm sorry! |
| 21:33 | herdrick | say, i've been using [org.clojure/clojure "1.1.0"] instead of [clojure "1.1.0"] does that matter? |
| 21:33 | tomoj | no problem |
| 21:33 | herdrick | bhenry: ok, thanks looks like a good tip |
| 21:34 | ihodes | tomoj: the problem remains, though, unfortunately |
| 21:34 | tomoj | herdrick: nope, clojure is just an abbreviation for org.clojure/clojure |
| 21:34 | herdrick | ok |
| 21:34 | tomoj | well, I'm betting the problem can't be determined without seeing the html, but not sure |
| 21:34 | tomoj | and I am not an enlive expert, good luck |
| 21:35 | ihodes | it's a compile-time error though |
| 21:35 | tomoj | ah |
| 21:35 | ihodes | as it occurs when i'm loading the file into the repl |
| 21:35 | tomoj | that's odd, must be bad syntax then |
| 21:36 | ihodes | it 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:37 | tomoj | you need something to bind to the keys destructuring map |
| 21:37 | tomoj | (I think) |
| 21:37 | ihodes | i don't quite understand? |
| 21:37 | tomoj | I mean, [{:keys [title author pubdate post-text]} <something needs to go here>] |
| 21:38 | tomoj | e.g. the tutorial has [{:keys [title data]} model] |
| 21:38 | tomoj | though I can't tell where model came from |
| 21:38 | tomoj | oh, maybe that's just an extra param? |
| 21:39 | tomoj | yeah, I was wrong, just the {:keys ..} should work too it seems |
| 21:39 | ihodes | yeah it's just an additional arg: the {:key..} thing is just destructuring a map |
| 21:41 | ihodes | java.lang.NullPointerException (render_index.clj:19) is the exception, too |
| 21:46 | tomoj | what's on line 19, the start of the defsnippet? |
| 21:47 | ihodes | yep |
| 21:59 | tomoj | ihodes: I don't think this problem is your fault |
| 22:00 | tomoj | the examples from the tutorial seem to do the same thing |
| 22:01 | ihodes | that 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:01 | tomoj | it seems like load-html-resource is being called with nil |
| 22:01 | tomoj | which clojure is he using? |
| 22:01 | ihodes | the thing is, his examples work in the lein-powered environment he has on hit. |
| 22:01 | tomoj | huh, he doesn't have any clojure in his project.clj |
| 22:01 | remleduff | NPEs in enlive have always meant "couldn't find your template" for me |
| 22:01 | ihodes | i'm going to have to build up his examples (M-w, C-y) in a new project |
| 22:02 | tomoj | remleduff: yeah, but.. |
| 22:02 | tomoj | oh, hmm |
| 22:02 | tomoj | does it try loading from the classpath? |
| 22:02 | remleduff | What do you get if you just do (html-resource "your_template.html") |
| 22:02 | hugod | ihodes: the path should be relative |
| 22:02 | tomoj | rather than taking it as an absolute file path |
| 22:02 | tomoj | I see |
| 22:02 | hugod | it uses the resource loader |
| 22:02 | ihodes | ah, let me give that a go |
| 22:02 | ihodes | so an absolute path *won't* work? |
| 22:02 | tomoj | so the html file needs to be in resources/ I guess, and you need to have that directory there before you start up swank |
| 22:03 | tomoj | (does `lein swank` add resources/ to the classpath?) |
| 22:03 | remleduff | resources is a recommendation rather than a requirement. Current lein adds it to classpath, but there were older versions that didn't |
| 22:03 | tomoj | swannodette just sticks his html files in src along with the clj |
| 22:04 | ihodes | let me try just doing that |
| 22:05 | tomoj | you'll need to use the relative path from src/ if you put them there |
| 22:05 | tomoj | e.g. "foo/bar.html" for src/foo/bar.html, I mean |
| 22:06 | ihodes | ok, 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:07 | ihodes | well, i'm on to other exceptions on other lines anyway. which is progress. |
| 22:07 | remleduff | hehe |
| 22:08 | ihodes | so 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:09 | remleduff | I'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:11 | ihodes | resources-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:11 | ihodes | which is nice. odd. now I have another cryptic error. |
| 22:13 | remleduff | What's that? |
| 22:14 | ihodes | tomoj: 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:16 | ihodes | solved. |
| 22:31 | ihodes | thanks 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:31 | ihodes | odd* errors. finals time is not a good time to try to start a new project. cheers, and thanks again. |
| 22:36 | remleduff | Why might M-x slime give me "let: Symbol's function definition is void: swank-clojure-reset-implementation"? |
| 22:37 | tomoj | something is looking for swank-clojure-reset-implementation and you don't have it |
| 22:37 | tomoj | I guess you probably figured that much out :( |
| 22:38 | remleduff | I usually use lein swank to start up, was trying to start up a repl without a project this time |
| 22:39 | remleduff | I'm so bad with emacs still |
| 22:40 | tomoj | remleduff: do you have swank-clojure installed from elpa? |
| 22:53 | defn | technomancy: did you change the URL for your package.el repo |
| 23:00 | remleduff | tomoj: I have swank-clojure 1.1.0 from ELPA, yes. |
| 23:03 | tomoj | remleduff: I think you need to upgrade |
| 23:04 | tomoj | it looks like swank-clojure-reset-implementation is in 1.2.0 but not 1.1.0 |
| 23:06 | herdrick | so you've got to keep your version of swank-clojure installed in ELPA synched with your swank-clojure jars in your lein projects? |
| 23:06 | remleduff | I thought swank-clojure was added to your project. What does swank-clojure in emacs do? |
| 23:06 | herdrick | tomoj: is that true? |
| 23:06 | tomoj | herdrick: I don't know if that's true or not |
| 23:06 | tomoj | swank-clojure from elpa is no longer even required |
| 23:07 | herdrick | oh, really? |
| 23:07 | tomoj | some stuff will not work without it |
| 23:07 | tomoj | presumably M-x slime for example |
| 23:07 | tomoj | I don't know what problems a version mismatch might cause |
| 23:07 | herdrick | hmm |
| 23:07 | herdrick | perhaps better to delete it then |
| 23:07 | tomoj | remleduff: swank-clojure in emacs is not needed if you only connect to externally started swank servers |
| 23:08 | tomoj | better to ask technomancy |
| 23:08 | tomoj | about version mismatches I mean |
| 23:09 | herdrick | ive 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:09 | herdrick | is there a better way? |
| 23:09 | remleduff | hendrick: Nope :\ |
| 23:09 | technomancy | defn: haven't touched that in a while, no. |
| 23:10 | technomancy | remleduff: swank-clojure in emacs isn't really needed |
| 23:10 | technomancy | you just need slime + clojure-mode |
| 23:10 | remleduff | But swank-clojure is what provides M-x slime if I'm just wanting to play with one-off stuff? |
| 23:10 | herdrick | tomoj: remleduff: technomancy: ok, thanks |
| 23:13 | remleduff | Duh, have to (require 'swank-clojure) if I want to use stuff provided by it (including M-x slime) |
| 23:13 | technomancy | remleduff: yeah, that's true |
| 23:14 | tomoj | you shouldn't have to require it, I think... |
| 23:14 | tomoj | but if it works, who cares |
| 23:15 | SinDoc | Can a type refer to itself? |
| 23:16 | Raynes | SinDoc: I believe so. |
| 23:17 | remleduff | technomancy: How do you usually start up swank if you're hacking on clojure itselfl? |
| 23:17 | SinDoc | Raynes: thanks, would you know how? |
| 23:17 | Raynes | SinDoc: You have to instantiate the class directly, because the factory functions aren't there yet. |
| 23:17 | technomancy | remleduff: I start a repl in swank and then edit clojure in the jar file itself |
| 23:19 | SinDoc | Raynes: 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:24 | Raynes | SinDoc: http://gist.github.com/415409 |
| 23:31 | remleduff | Anyone got a good way to check if a deftype has successfully implemented all the abstract methods its inherited, and not forgotten any? |
| 23:47 | SinDoc | remleduff: checking the protocols it has implemented using reflection? |
| 23:50 | SinDoc | Raynes: Thanks, I tried your solution; it still can't reify itself but it's fine for now |
| 23:51 | Raynes | :( |
| 23:51 | Raynes | Sorry I couldn't be more helpful. <3 |
| 23:52 | SinDoc | Raynes: FWIW, I found out that my initial requirement wasn't valid to begin with |