2009-08-28
| 00:01 | technomancy` | heh... now I've switched it back and can't repro. |
| 00:01 | technomancy` | should have checked it in I guess |
| 00:02 | technomancy` | or at least stashed |
| 00:02 | cark | =) |
| 00:04 | technomancy` | http://github.com/technomancy/sketchbook/tree/master <= if you're curious |
| 00:04 | technomancy` | having some fun with Processing |
| 00:04 | technomancy` | even if the language itself is crap, calling it from Clojure is pretty nice. |
| 00:05 | krumholt__ | can someone tell me why (java.nio.IntBuffer/wrap (into-array [1 2 3 4 5])) is not working? |
| 00:06 | krumholt__ | ah i allready know |
| 00:06 | cark | ,(int-array [1 2 3 4]) |
| 00:06 | clojurebot | #<int[] [I@172bab9> |
| 00:06 | krumholt__ | yes that its |
| 00:06 | krumholt__ | thank you very much |
| 00:06 | cark | ,(into-array Integer/TYPE [1 2 3 4]) |
| 00:06 | clojurebot | #<int[] [I@26b12d> |
| 03:46 | AWizzArd | hiredman: ping |
| 03:58 | eevar2 | anyone here with commit rights to sourceforge's clojure-contrib? |
| 04:00 | eevar2 | i think someone should make a commit cleaning out all the files, like on google code. but maybe get rid of the license files as well; don't really need 3-4 different licenses to go along with your text file explaining that the project has moved |
| 04:03 | vIkSiT | hi all |
| 04:03 | vIkSiT | anyone around? |
| 04:03 | vIkSiT | I'm getting a compilation error on def.clj in clojure-contrib at line 106 |
| 04:04 | vIkSiT | [java] java.lang.Exception: Unable to resolve symbol: next in this context (def.clj:106) |
| 04:04 | vIkSiT | any ideas? |
| 04:05 | eevar2 | sure you use compatible versions of clojure and the contrib source? i.e. both from master, or both from an 1.0-branch on github? |
| 04:09 | vIkSiT | eevar2, hmm I think I have, although let me refresh to make sure |
| 04:12 | vIkSiT | eevar2, I guess I could use both versions from master? |
| 04:13 | AWizzArd | sounds good |
| 04:14 | eevar2 | yes, master and the 1.0 branches aren't compatible |
| 04:15 | eevar2 | trying to build (master) here now. just in case ;) |
| 04:15 | vIkSiT | curiously - vimclojure vs emacs-slime as mode of choice? |
| 04:15 | opqdonut | emacs |
| 04:15 | eevar2 | enclojure :p |
| 04:16 | vIkSiT | does anyone here use vimclojure at all? :) |
| 04:16 | eevar2 | if you're already damaged, you might as well stick with emacs |
| 04:16 | vIkSiT | hehe eevar2 - except, moved to using vim after that because of ssh and not liking emacs -nw - and now like it better |
| 04:17 | vIkSiT | hehe |
| 04:19 | eevar2 | my build of clojure, contrib & compojure, current master branch, went ok |
| 04:24 | AWizzArd | vIkSiT: I use emacs+slime. The author of VimClojure is often here (but not right now). Has many happy users. |
| 04:25 | vIkSiT | ah |
| 04:25 | AWizzArd | Last time I checked VimClojure had unique features. For example it can autocomplete the names of static methods. |
| 04:37 | vIkSiT | ah I see |
| 04:37 | vIkSiT | alrighty, thanks all |
| 06:44 | G0SUB | How do I access the values of a Java HashMap? |
| 06:45 | G0SUB | (mymap "key") throws an error. says it can't be cast into an IFn |
| 06:45 | G0SUB | keys are strings, by the way |
| 06:45 | AWizzArd | Use the method get |
| 06:45 | AWizzArd | (.get mymap "key") |
| 06:46 | G0SUB | AWizzArd: any way to convert that HashMap to an IFn? |
| 06:46 | jdz | i think into works, like (into {} mymap) |
| 06:46 | AWizzArd | Yes, use into |
| 06:46 | G0SUB | jdz: interesting. thanks. |
| 06:47 | AWizzArd | G0SUB: if your Map is very big then this operation is maybe not required. |
| 06:48 | AWizzArd | you could leave it as a j.u.HM |
| 06:48 | G0SUB | AWizzArd: makes sense |
| 06:49 | AWizzArd | Especially if it is a read-only object. When there are no writers, then read access is thread-safe |
| 06:57 | ole3 | Hello, I have to syncronize access to a struct. |
| 06:57 | ole3 | Is it better to put the whole struct into a reference or let the slot be references? |
| 07:06 | ole3 | ok |
| 07:14 | AWizzArd | in most cases it would make sense to put a whole struct instance into a ref. |
| 07:14 | AWizzArd | But, it can also make sense to have refs in refs, if you need to keep identity of objects in a collection which itself is in a ref. |
| 07:17 | ole3 | well in my struct is a stack and i have to push and pop elements from it. |
| 07:18 | ole3 | it is easy if that stack is in a ref. |
| 07:48 | Fossi | ole3: that sounds as if the stack should be one ref |
| 07:57 | Licenser | hmmm I wanted to write a few macros that make some things in compojure easyer (namely adding restfull resources) I'm not getting far sadly :/. I wonder if someone could be so nice and take a look and help me out? http://gist.github.com/176928 (as a warning I'm a beginner) |
| 07:58 | Fossi | might be totally unrelated, but the appengine has a deadline after 30 seconds and it's the second time that it fails while starting up in Keyword.intern/ConcurrentHashMap.putIfAbsent |
| 08:02 | ole3 | Fossi & AWizzArd: thanks for the response, the stack is now the ref. |
| 08:10 | Chousuke | Licenser: what do you seek to accomplish with that let in the resource macro? |
| 08:11 | Chousuke | oh, I see now. that won't work. |
| 08:11 | Licenser | that the 'inner macros' like list_items know how the resource is named |
| 08:11 | Licenser | I noticed that |
| 08:11 | Chousuke | ,(list `foo# `foo#) |
| 08:11 | clojurebot | (foo__2476__auto__ foo__2477__auto__) |
| 08:11 | Chousuke | autogensyms in different syntax quotes are never the same. |
| 08:11 | Licenser | I fear it's even 'bad style' since the macros like list_items would not be how is it clled, a function of it's values |
| 08:12 | Licenser | *nods* |
| 08:12 | Licenser | okay again something learned |
| 08:12 | Chousuke | you should instead make those macros use some globally bound *resource-name* |
| 08:12 | Licenser | o.o |
| 08:12 | Licenser | isn't that very badish? |
| 08:12 | Chousuke | then do (binding [*resource-name* whatever] (some-macros-here) (some-more-here)) |
| 08:12 | Licenser | ah okay binding localizes it? |
| 08:13 | Chousuke | dynamic global bindings are very common in lisps, and in clojure. |
| 08:13 | Fossi | who would be responsible for the Keywork.java code? rhickey? |
| 08:13 | Licenser | I love the (doc thing) |
| 08:13 | Chousuke | there are no global (uncontrolled) *variables* in clojure so it's all fine. |
| 08:13 | Licenser | Okay |
| 08:14 | Chousuke | also, don't use underscores |
| 08:15 | Chousuke | list-items, get-item, etc. are better. |
| 08:15 | AWizzArd | Fossi: yes |
| 08:15 | Licenser | Okay, thanks for the advice |
| 08:15 | Fossi | AWizzArd: k, i'll ask him later then |
| 08:15 | Licenser | wow something is working! |
| 08:17 | Licenser | okay it compiles, now just to get it working too ^^ |
| 08:18 | Chousuke | Licenser: also instead of all those nths you could do `(let [~p [(params :id)]] ...) or `(let [~p [(params :id) params]] ...) |
| 08:19 | Chousuke | eg. use destructuring. |
| 08:19 | Licenser | hmm sneaky |
| 08:19 | Chousuke | eh, not eg; ie. ;( |
| 08:19 | Licenser | thanks |
| 08:19 | Fossi | destructuring is the shit. |
| 08:20 | AWizzArd | ?? |
| 08:20 | AWizzArd | Wieso dasn? |
| 08:20 | Fossi | *the* shit. ask google :) |
| 08:25 | Chousuke | Licenser: http://gist.github.com/176962 this should work |
| 08:25 | Licenser | so * |
| 08:26 | Licenser | *looks at it* |
| 08:26 | Chousuke | your (do ~@body)'s were superfluous so I removed the dos |
| 08:26 | Licenser | hmm why ~'*resource-name* in the one macro? |
| 08:26 | Licenser | okay I had that from the macro documentation ^^ |
| 08:26 | Chousuke | because otherwise it would become qualified. |
| 08:27 | Chousuke | and you can't bind to qualified names I think |
| 08:27 | Licenser | ah it would resolve to the value you mean |
| 08:27 | Chousuke | no, I mean |
| 08:27 | Chousuke | ,`*warn-on-reflection* |
| 08:27 | clojurebot | clojure.core/*warn-on-reflection* |
| 08:27 | Chousuke | ,`~'*warn-on-reflection* |
| 08:27 | clojurebot | *warn-on-reflection* |
| 08:28 | Chousuke | maybe it's possible to use binding with qualified names though. |
| 08:28 | Chousuke | but with let it fails :) |
| 08:28 | Chousuke | (it helps people to not shoot themselves in the foot with macros) |
| 08:28 | Licenser | yes with let it did, I tried something like that :P |
| 08:29 | Chouser | binding is on vars, so it gets qualified either manually or automatically. |
| 08:29 | Licenser | I wanted to shoot myelf in the foot, or nearly did |
| 08:29 | G0SUB | Is it possible to create private defmulti & defmethods ? like defn- ? |
| 08:29 | Chousuke | (defmulti #^{:private true} foo) |
| 08:29 | G0SUB | Chousuke: Thanks. What about the defmethods? |
| 08:29 | Chousuke | they can't be private I think. |
| 08:30 | Chouser | you don't call them directly anyway -- they are reachable through the multi, so if that's private you're safe. |
| 08:31 | Licenser | hmmm |
| 08:31 | G0SUB | cool |
| 08:31 | G0SUB | Chousuke: I put the same metadata after the defmethod. it compiled fine. |
| 08:31 | Licenser | when a function takes arguments like (function a1 b1 a2 b2) can I pass it a list too? |
| 08:31 | Licenser | it will destruct it right? |
| 08:32 | Chouser | G0SUB: that metadata is probably being ignored. |
| 08:32 | G0SUB | Chouser: right. |
| 08:32 | Fossi | Licenser: you can use apply the list |
| 08:32 | Fossi | today no english me |
| 08:32 | Licenser | hmm hmm |
| 08:33 | AWizzArd | ,(re-find #".* \(" "foo (bar)") |
| 08:33 | clojurebot | "foo (" |
| 08:33 | AWizzArd | but I want only "foo" |
| 08:33 | G0SUB | What is the best way to figure out if the arg to a defmethod is a HashMap? I am using (identical? (type arg) (type {})) |
| 08:34 | Chousuke | AWizzArd: use capturing groups and take the first group? :/ |
| 08:34 | G0SUB | ,(re-find #"(.*) \(" "foo (bar)") |
| 08:34 | clojurebot | ["foo (" "foo"] |
| 08:34 | G0SUB | ,(re-find #"(.*) \(" "foo (bar)")[1] |
| 08:34 | clojurebot | ["foo (" "foo"] |
| 08:34 | Chouser | ,(re-find #".*(?= \()" "foo (bar)") |
| 08:34 | clojurebot | "foo" |
| 08:35 | AWizzArd | G0SUB: you can use instance? for the check |
| 08:35 | Chousuke | oh, right. :) |
| 08:35 | Chouser | positive zero-length lookahead assertion |
| 08:35 | AWizzArd | ,(instance? java.util.HashMap (java.util.HashMap.)) |
| 08:35 | clojurebot | true |
| 08:35 | Chouser | ,(map? {}) |
| 08:35 | clojurebot | true |
| 08:36 | AWizzArd | ,(map? (java.util.HashMap.)) |
| 08:36 | clojurebot | false |
| 08:36 | AWizzArd | so I check in my programs for being java.util.Map |
| 08:36 | AWizzArd | because I need to capture all those cases |
| 08:36 | AWizzArd | ,(doc map?) |
| 08:36 | clojurebot | "([x]); Return true if x implements IPersistentMap" |
| 08:36 | Chouser | ah |
| 08:37 | AWizzArd | Chouser: are you in for a very hard regex again? ;-) |
| 08:37 | AWizzArd | I think it is so hard that noone here can solve it. |
| 08:37 | Chouser | heh. well, statements like that are a good way to get me interested |
| 08:38 | AWizzArd | I got some funny file format that someone invented and I parse it with a function now. But I think a regex may be able to do it too. |
| 08:38 | AWizzArd | I have a string, similar to .csv, in which columns are separated either by , or ; |
| 08:38 | AWizzArd | "15,hello;30;4" |
| 08:38 | AWizzArd | but... |
| 08:39 | AWizzArd | it also contains strings in which , or ; may show up. Those should not be splitting. These strings are marked by the entries BEGIN;now some,,;;string is here;; with no\n splitting.;ENDTEXT; |
| 08:41 | AWizzArd | "93257,1257 ;1;341;NULL;BEGINTEXT,[zzz] MR813.txt[2009-04-21 14:44];ENDTEXT;BEGINTEXT;>> \r\n>> Hello, it is good; but not now. \"It\" is.\r\n>> Ok;ENDTEXT;BEGINTEXT;NULL,ENDTEXT;BEGINTEXT,NULL;ENDTEXT" |
| 08:41 | AWizzArd | This is an example input |
| 08:41 | Chouser | wow. so pretty. |
| 08:42 | AWizzArd | and it should split into "93256" "1257 " "1" "341" "NULL" "[zzz] MR813.txt[2009-04-21 14:44]" ">> \r\n>> Hello, it is good; but not now. \"It\" is.\r\n>> Ok" "NULL" "NULL |
| 08:42 | jdz | and nobody ever puts BEGINTEXT etc in those fields? |
| 08:42 | jdz | :) |
| 08:42 | AWizzArd | I hope. I don't know who invented it *sigh* |
| 08:43 | AWizzArd | But I assume that it does not happen. |
| 08:43 | AWizzArd | So, the [,;] should split only when not inside a BEGIN END block. |
| 08:43 | AWizzArd | And the BEGINs and ENDs need to be eliminated from the result. |
| 08:43 | Chouser | I assume the \" are just for Clojure, not in the file itself? |
| 08:44 | jdz | i think i'd create a filter that would escape those separators inside begin/end |
| 08:44 | AWizzArd | Chouser: right |
| 08:44 | jdz | ard remove begin/end themselves |
| 08:45 | AWizzArd | jdz: yes, I am doing it in a similar way, in a function. But they are important markers, because the [,;] inbetween must not split. |
| 08:45 | jdz | actually, i think using regular expressions here is more trouble than they help |
| 08:45 | AWizzArd | I was just curious weather this can be expressed with a regex. |
| 08:45 | AWizzArd | jdz: yup |
| 08:46 | AWizzArd | I think noone here can solve that |
| 08:46 | jdz | i'm not gonna trip on that one |
| 08:46 | jdz | i have my own devices to tinker with :) |
| 08:47 | AWizzArd | Yes. I think most people will just give up on it after a few tries. It is really complex, and easily solved in an ordinary function. |
| 08:48 | AWizzArd | Fossi: the BDFL arrived (Keyword.java). |
| 08:48 | Fossi | AWizzArd: ah, excellent :) super assistent ;) |
| 08:53 | Fossi | rhickey: (Keyword.java:25) if i read the javadoc right, putIfAbsent returns the old key if it already exists, so the check in :26 is unnecessary |
| 08:54 | Fossi | rhickey: that being said we have a strange problem on the app engine where we time out in initializing. it happened to be twice in that line, so could it be some concurrency issue? |
| 08:55 | Chouser | AWizzArd: (map #(or (% 1) (% 2)) (re-seq #"(?s)(?:^|[,;])(?:BEGINTEXT[,;](.*?)[,;]ENDTEXT|(?!BEGINTEXT)([^,;]+))" x)) |
| 08:55 | Fossi | ("it" happened: the timeout) |
| 08:55 | Chouser | now, who couldn't love a solution like that? :-P |
| 08:58 | ole3 | hello, how do i check if a process is still running? (.exitValue process) ? |
| 08:58 | Fossi | brb |
| 09:03 | jdz | ole3: solutions to Java related issues can also be tried in #java |
| 09:03 | jdz | (i hope) |
| 09:03 | ole3 | jdz: good idea, thank you. |
| 09:04 | AWizzArd | Chouser: let me test, one sec |
| 09:05 | Chouser | AWizzArd: (re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?<=^|,|;)(?!BEGINTEXT)[^,;]+" x) |
| 09:05 | Chouser | there, without the map. |
| 09:05 | bstephenson | hello, have a quick question for the clojure experts, if I could |
| 09:06 | bstephenson | I have a vector of hours (e.g. [0 1 2 0 4 3]) and a map of that holds the totals hours in each day used already (e.g., {:day1 0 :day2 2 :day3 3 :day4 7 :day5 6}. Is there a straightforward way (or any way, really) to add the vector values to the map values such that the nth vector value gets added to the value of "day-nth" in the map? The map and vector counts will always be the same. |
| 09:07 | jdz | bstephenson: hardcoding day names in your map keys seems to be a bad idea (to me) |
| 09:08 | bstephenson | how would you approach it? |
| 09:08 | AWizzArd | Chouser: looks good. You were the first who made that. I gave that puzzle to some friends so far and they gave up. |
| 09:09 | jdz | bstephenson: but anyway, you can have a separate map which will give you vector indices when given day names |
| 09:09 | jdz | bstephenson: well, why not use vectors of hours or maps in both cases? |
| 09:10 | bstephenson | well, I was using the map to use the assoc function to update the value, but I think now that you are probably correct, two vectors will work better than a vec and a map, they will always have the same index. |
| 09:11 | bstephenson | jdz: thx |
| 09:28 | rhickey | Fossi: how is the check unnecessary? If the key was there I need to return the old one, if not the new one. I can't just return the result of putIfAbsent as it will be null if it wasn't there |
| 09:30 | rhickey | Fossi: do you get a stack trace when you timeout? |
| 10:08 | liwp | Chouser: I think you need to add ENDTEXT to the negative lookahead as well |
| 10:08 | liwp | ,(re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?<=^|,|;)(?!BEGINTEXT|ENDTEXT)[^,;]+" "BEGINTEXT;foo;ENDTEXT") |
| 10:08 | clojurebot | ("foo") |
| 10:09 | liwp | Chouser: and thanks for all the effort you're putting into these regexp challenges, I'm learning a lot here |
| 10:11 | Chouser | ,(re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?=^|,|;)(?!BEGINTEXT)[^,;]+" "BEGINTEXT;foo;ENDTEXT") |
| 10:11 | clojurebot | ("foo") |
| 10:11 | liwp | maybe I messed up my copy pasting... |
| 10:11 | Chouser | oh, no, I think I did. |
| 10:11 | liwp | ,(re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?<=^|,|;)(?!BEGINTEXT)[^,;]+" "BEGINTEXT;foo;ENDTEXT") |
| 10:11 | clojurebot | ("foo" "ENDTEXT") |
| 10:12 | liwp | that's what I got earlier |
| 10:12 | AWizzArd | hmm |
| 10:12 | Chouser | the one I just pasted above is not right. please ignore it |
| 10:13 | AWizzArd | what is this (?s) thing with which it starts? |
| 10:13 | liwp | who knows ;-) |
| 10:14 | Chouser | liwp: yes, you're right. I had this in my command history, but somehow pasted the wrong one instead. I think this is right (and essentially the same as you have): |
| 10:14 | Chouser | (re-seq #"(?s)(?<=BEGINTEXT[,;]).*?(?=[,;]ENDTEXT)|(?<=^|,|;)(?!BEGINTEXT)(?!ENDTEXT)[^,;]+" "BEGINTEXT;foo;ENDTEXT;bar") |
| 10:14 | Chouser | the (?s) at the beginning says that . should also match \n for the rest of the regex |
| 10:15 | liwp | The other question mark stuff is related to lookaround: http://www.regular-expressions.info/lookaround.html |
| 10:16 | liwp | for those of us who didn't know how it all worked |
| 10:17 | Chouser | and if you ever think regex can't do something or other, keep this in mind: http://blog.n01se.net/?p=12 |
| 10:18 | liwp | urgh, some people have too much time on their hands |
| 10:19 | AWizzArd | There is this programming language Malbolge ( http://en.wikipedia.org/wiki/Malbolge ) in which only "Hello World" was the only program ever written. And this hello world program was not written by a human, but by a Lisp program :) |
| 10:20 | AWizzArd | If people really have a lot of time... |
| 11:06 | Fossi | rhickey: ah, ok, the documentation says it's equal to a if !contains, put else get, which would return the old one, so i didn't care to read the actual return documentation |
| 11:06 | Fossi | a little inconsisten there |
| 11:08 | Fossi | rhickey: is it ok if i pm you the stacktrace? |
| 11:10 | Fossi | (as a paste link of course) |
| 11:18 | lpetit_ | hello |
| 11:18 | lpetit_ | I can't seem to get rid of reflection warning here, missing something trivial I think :(let [to-name-fn #(-> #^File % |
| 11:18 | lpetit_ | .getPath |
| 11:18 | lpetit_ | (str2/drop (inc (-> *builds-dir* |
| 11:18 | lpetit_ | .getPath |
| 11:18 | lpetit_ | .length))) |
| 11:18 | lpetit_ | (.replace "/" "."))] |
| 11:19 | lpetit_ | The last call to .replace generates a "call to replace can't be resolved." |
| 11:20 | lpetit_ | .replace works on a String, and takes CharSequences as arguments. How can I indicate the "mutation" of the threaded argument ? |
| 11:27 | jdz | lpetit_: i'd try macroexpanding that form and look what's there |
| 11:30 | lpetit_ | ,(macroexpand '#(-> #^File % .getPath (.replace "/" "."))) |
| 11:30 | clojurebot | (fn* [p1__2529] (-> p1__2529 .getPath (.replace "/" "."))) |
| 11:31 | jdz | seems to me that the type tag is lost |
| 11:31 | jdz | or maybe not |
| 11:32 | jdz | ,(macroexpand '(-> p1__2529 .getPath (.replace "/" "."))) |
| 11:32 | clojurebot | (. (clojure.core/-> p1__2529 .getPath) replace "/" ".") |
| 11:34 | cark | str2/drop must be returning an Object |
| 11:34 | cark | so you could #^String (str2/drop ... |
| 11:34 | lpetit_ | I'll try, thanks (was working on the wrong s-exp :-( ) |
| 11:36 | lpetit_ | weird, I tried it but still same warning |
| 11:36 | cark | mhh |
| 11:37 | cark | *builds-dir* is untyped too |
| 11:38 | lpetit_ | Reflection warning, /home/lpetit/*******_tests.clj:28 - call to replace can't be resolved. |
| 11:41 | cark | and when you run it you have no errors ? |
| 11:42 | cark | could you paste your current code ? |
| 11:42 | lpetit_ | currently trying to cut it down to the minimum |
| 11:43 | lpetit_ | no error when running |
| 11:43 | Chouser | -> builds a new list for each step past the first |
| 11:44 | Chouser | ,(binding [*print-meta* true] (prn (macroexpand '(-> a #^Integer (b))))) |
| 11:44 | clojurebot | (b a) |
| 11:44 | lpetit_ | now that's interesting: |
| 11:44 | lpetit_ | 1:41 engine-tests=> #(.replace "/" ".") |
| 11:44 | lpetit_ | Reflection warning, NO_SOURCE_PATH:41 - call to replace can't be resolved. |
| 11:44 | lpetit_ | #<engine_tests$eval__250$fn__252 engine_tests$eval__250$fn__252@15d616e> |
| 11:45 | cark | mhh i know i resolved type warning within -> |
| 11:45 | lpetit_ | I also remember this demonstrated on the ml |
| 11:46 | lpetit_ | (note : working with clojure-1.0) |
| 11:46 | Chouser | -> could be patched to copy metadata from the given form to the produced one. |
| 11:46 | lpetit_ | don't misinterpret : it's not working with clojure-1.0, I'm using clojure-1.0 |
| 11:47 | lpetit_ | ,(binding [*print-meta* true] (prn (macroexpand '(-> a (#^Integer b))))) |
| 11:47 | clojurebot | (#^Integer b a) |
| 11:48 | lpetit_ | beh |
| 11:49 | lpetit_ | Maybe we're not focusing on the right problem, see: |
| 11:49 | lpetit_ | 1:43 engine-tests=> (fn [] (.replace "/" ".")) |
| 11:49 | lpetit_ | Reflection warning, NO_SOURCE_PATH:43 - call to replace can't be resolved. |
| 11:49 | lpetit_ | #<engine_tests$eval__262$fn__264 engine_tests$eval__262$fn__264@c5aa00> |
| 11:49 | Chouser | .replace needs 3 args |
| 11:50 | Chouser | only 2 within -> |
| 11:50 | lpetit_ | oh yes sorry |
| 11:50 | cark | chouser : indeed it's not working |
| 11:50 | lpetit_ | so the goes back to the -> , of course |
| 11:51 | cark | anyways you could insert a str call juste before the (.replace |
| 11:51 | lpetit_ | within -> it's normal the first is the threaded argument |
| 11:52 | lpetit_ | so in my original example with ->, there are 3 arguments to .replace |
| 11:53 | Chouser | try (#^String str2/drop ...) |
| 11:56 | lpetit_ | that's it ! |
| 11:58 | lpetit_ | I could also tackle it directly in clojure-contrib/str-utils2 : changing defs like (defn drop [#^String s n] into (defn #^String drop [#^String s n] |
| 11:58 | Chouser | str2 could use some hints splinkled around. |
| 11:58 | Chouser | yeah |
| 11:58 | lpetit_ | post collision :) |
| 11:58 | lpetit_ | ok I'll do it |
| 11:59 | lpetit_ | around the beginning of next week, it 6pm here in France, by guys |
| 11:59 | lpetit_ | and thx for all |
| 12:00 | hiredman | AWizzArd: pong |
| 12:51 | stuartsierra | commit 4b4f6ab5bcab58c4219eb50395bd366daea3ecc3: str_utils2.clj: added type hints for String return values; fixes #27 |
| 12:58 | fsodomka | hi all! |
| 12:58 | fsodomka | couple days ago I saw discussion about new possible multimaps and their syntax... some time ago I played with Rebol, so I wanted to point out its syntax if anyone wants to get inspired... |
| 12:58 | fsodomka | Values: http://rebol.com/docs/core23/rebolcore-3.html#section-2 |
| 12:58 | fsodomka | Evaluating Simple Values: http://rebol.com/docs/core23/rebolcore-4.html#section-4.2 |
| 12:58 | fsodomka | and their use: Conditional Blocks: http://rebol.com/docs/core23/rebolcore-4.html#section-6.1 |
| 12:58 | fsodomka | ... not sure if that helps... |
| 13:54 | Chouser | rathore: nice job posting! Sounds interesting. |
| 14:01 | cark | a sample executable jar build process using ant : http://github.com/cark/clj-exe-jar/tree/master |
| 14:02 | cark | ~executable jar? |
| 14:02 | clojurebot | Pardon? |
| 14:03 | cark | ~executable jar is a sample executable jar build using ant : http://github.com/cark/clj-exe-jar/tree/master |
| 14:04 | cark | hum |
| 14:04 | hiredman | :( |
| 14:04 | ababo | Hi there, please help me to figure out why casting to an interface is not working! |
| 14:04 | cark | clojurebot: don't do thhis to me ! |
| 14:04 | clojurebot | Pardon? |
| 14:04 | ababo | ,(cast javax.script.Invocable (.getEngineByName (javax.script.ScriptEngineManager.) "js")) |
| 14:04 | clojurebot | nil |
| 14:05 | ababo | That returns ScriptEngineManager instead of Invocable |
| 14:05 | stuartsierra | Clojure is dynamic, no need to cast anything. |
| 14:05 | ababo | When I try to call a method of the interface it fails. |
| 14:07 | Chouser | ,(doc cast) |
| 14:07 | clojurebot | "([c x]); Throws a ClassCastException if x is not a c, else returns x." |
| 14:08 | ababo | Aha, got it, thanks! |
| 14:08 | cark | is there some good soul that would provide me with the equivalent linux clojure startup script for the sample project i just linked ? |
| 14:08 | stuartsierra | ScriptEngine isn't required to implement the Invocable interface. |
| 14:09 | cark | equivalent to run-clojure.bat |
| 14:09 | stuartsierra | cark: there are sample launch scripts in contrib |
| 14:10 | Chouser | cark: line 2 looks like it would work as-is -- what does line 1 do? |
| 14:10 | cark | i'm at home and don't have a linux handy. I wouldn't want to screw an example |
| 14:11 | cark | chouser : line 1 changes current directory to the .bat file's directory |
| 14:11 | dmix | anyone recognize whats causing this error? http://gist.github.com/177119 I can't decipher it |
| 14:13 | cark | dmix : maybe show us the code that produces the error ? |
| 14:16 | hiredman | ~executable jar is a sample executable jar build using ant : http://github.com/cark/clj-exe-jar/tree/master |
| 14:16 | clojurebot | Ok. |
| 14:16 | hiredman | ~executable jar |
| 14:16 | clojurebot | executable jar is a sample executable jar build using ant : http://github.com/cark/clj-exe-jar/tree/master |
| 14:16 | cark | hiredman : thanks ! |
| 14:16 | ababo | My bad, method name is .invokeFunction but the example code has .invoke |
| 14:16 | ababo | Thanks for the input! |
| 14:20 | Chouser | #!/bin/bash |
| 14:20 | Chouser | cd "$(dirname $0)" |
| 14:20 | Chouser | cark: Those two lines instead of your first should do it. |
| 14:20 | cark | chouser : ok and the filename should be run-clojure.sh ? |
| 14:21 | Chouser | you could leave of the .sh, but sure. |
| 14:21 | cark | i'm a linux ignoramus |
| 14:21 | cark | ok thanks |
| 14:21 | hiredman | :( |
| 14:22 | hiredman | #!/bin/sh |
| 14:22 | hiredman | #!/bin/bash is horrible |
| 14:26 | hoeck1 | cark: and split paths on the java -cp line with a colon instead of a semicolon |
| 14:26 | Chouser | hiredman: oh? what OS do you use? |
| 14:26 | cark | ah yes indeed ! |
| 14:26 | Chouser | hoeck1: oh, good catch -- I missed that. |
| 14:26 | Chouser | hiredman: $() is a bash thing anyway -- /bin/sh wants me to use backquotes or something. |
| 14:27 | hiredman | Chouser: $() is a sh thing |
| 14:27 | hiredman | I use an OS that does not come with bash, and addon software doesn't get installed in / |
| 14:28 | Chouser | hiredman: so... not linux. :-) |
| 14:28 | cark | i think any linux user picky enough to want one or the other should be able to make the change |
| 14:29 | hiredman | cark: #!/bin/sh |
| 14:30 | cark | haha looks like i have to make a vm to test this anyways =/ |
| 14:31 | hiredman | two characters, and suddenly your shell script will run on any unix |
| 14:39 | rsynnott | and you'll want the permissions to be right |
| 16:03 | kotarak | Chouser: thanks for for! |
| 16:21 | hiredman | http://www.scala-lang.org/node/3069 "He found that it is, on average, 30% faster to comprehend algorithms that use for-comprehensions and maps, as in Scala, rather than those with the iterative while-loops of Java." |
| 16:23 | ankou | hi, I just read the chapter about lazy sequences in Programming Clojure and I am surprised that lazy sequences use normal recursion instead of tail-recursion but seam to work with large numbers as well? why? or is this a missunderstanding? |
| 16:24 | hiredman | ankou: sort of |
| 16:24 | hiredman | lazy-seqs sort of recur |
| 16:25 | hiredman | but the recursion and stack depth are controled by sequence consumption |
| 16:25 | kotarak | ankou: when the recursive call happens the original call, where the recursion was "started" already returned. So there is no build up of stack frames |
| 16:25 | hiredman | so if you consume the sequence, but throw away the parts you have already seen, you don't consume space |
| 16:25 | kotarak | you can still blow the stack by piling eg. map on map on map on map ... |
| 16:27 | kotarak | And - man - cl-format sure is on steroids... |
| 16:34 | Chouser | kotarak: I didn't write 'for', it's all I can do to understand it just enough to tweak a bit here and there. |
| 16:34 | Chouser | but you're welcome for the chunked version. It was hard! |
| 16:38 | Chouser | This has gotten a bit interesting recently: http://github.com/richhickey/clojure/graphs/impact |
| 16:40 | kotarak | github doesn't like me. :( The network graph for contrib seems frozen for days now. :( |
| 16:41 | kotarak | The small fixes could use some turbo. :| |
| 16:43 | rhickey | Chouser: neat, I'd never seen that view |
| 16:44 | Chouser | rhickey: btw, the finger tree paper does define deque ops, tail-l and tail-r. I just missed them somehow. |
| 16:45 | rhickey | oh, good |
| 16:46 | Chouser | so split is only useful or needed for annotated (measure/reduce) tree. |
| 16:46 | rhickey | okasaki famously left out delete from his example red black tree |
| 16:46 | Chouser | heh |
| 16:48 | Chouser | someone asked me last night why you didn't do finger trees in the first place. I had some guesses, but didn't know. |
| 16:48 | Chouser | instead of vectors, I suppose. |
| 16:48 | rhickey | so I wonder - how important are the annotated versions? |
| 16:48 | rhickey | finger tress are unlikely to touch the perf of the vectors |
| 16:50 | Chouser | annotations can give you random-access, priority queues, ordered sequences... |
| 16:51 | Chouser | also I suspect some clever application-specific uses. For testing I'm using the str fn for both measure and reduce, so I always have a correctly-ordered string representation of the whole collection. |
| 16:51 | rhickey | neat |
| 16:52 | rhickey | reigy working ok for you? |
| 16:52 | rhickey | reify |
| 16:52 | Chouser | not there yet. |
| 16:52 | Chouser | probably start trying to use it this weekend. |
| 16:53 | Chouser | the transition from haskell-ish to clojure is big enough by itself. I wanted to get a taste of that before I tried to figure out the right way to use reify. |
| 16:54 | rhickey | makes sense |
| 16:54 | Chouser | do you have a gut feeling about whether a node of 2 to 4 items should be an array of 4, an array of needed size, or 4 separate fields? |
| 16:55 | Chouser | oops, gotta go. I'll read the history later... |
| 16:56 | rhickey | Chouser: do the node of different N have different behavior? If you look at the different Clojure data structures you'll see a lot of Node polymorphism |
| 17:03 | lpetit | stuartsierra: hi, I saw you were quicker than me to add missing type hints on c.c.str-utils2 :) |
| 17:03 | lpetit | would you mind applying them on the compat branch, also ? (I didn't check, maybe already done ?) |
| 17:13 | stuartsierra | lpetit: ok |
| 17:17 | stuartsierra | ok, done |
| 17:18 | Chouser | rhickey: ah, I hadn't thought of that. I'll have to look again to see how transients are done now. |
| 17:18 | lpetit | stuartsierra: thanks a lot! |
| 17:19 | rhickey | Chouser: not just for transients, see e.g. PersistentTreeMap |
| 17:20 | rhickey | Okasaki's pattern matches turned into polymorphic dispatch |
| 17:23 | lpetit | stuartsierra: did not see the commit yet |
| 17:24 | lpetit | stuartsierra: did you make "clojure-contrib behaviour breaking changes" on the clojure-1.0-compatible branch ? (templating system, etc.) |
| 17:27 | lpetit | stuartsierra: I thought clojure-compatible was not only compatible with also clojure-1.0, but also just a maintenance branch of clojure-contrib, so that people know they have a "1.0 with no breaking changes clojure/clojure-contrib" duo ? |
| 17:29 | lpetit | stuartsierra: note that importing new functionality does no harm, but sometimes it has side effects as importing newer (incompatible ?) versions of some other dependencies ... |
| 17:31 | stuartsierra | Wait, did I just break the git repo? |
| 17:32 | stuartsierra | lpetit: no, I did not (intentionally) make any behavior-breaking changes |
| 17:33 | lpetit | stuartsierra: ok, glad to have been able to catch it, then. |
| 17:36 | lpetit | stuartsierra: woops, you pushed 110 commits from master to compat branch |
| 17:36 | stuartsierra | Damn. |
| 17:36 | stuartsierra | How the heck did that happen? |
| 17:37 | lpetit | stuartsierra: you did some sort of merge instead of a cherry pick |
| 17:37 | lpetit | stuartsierra: probably |
| 17:37 | stuartsierra | Great. Now I have to figure out how to fix that. |
| 17:38 | lpetit | stuartsierra: let's think about it together |
| 17:38 | stuartsierra | Anybody know how to fix this |
| 17:40 | lpetit | ok I'm pretty sure you did a merge (not a rebase) from what I can see from gitk |
| 17:40 | lpetit | so it will be very easy to do the reverse change |
| 17:40 | stuartsierra | ok, just cloned a new copy of clojure-contrib |
| 17:42 | lpetit | it's just a matter of making the compat label point to the rev with comment "repl-utils: Fix init state for...", that is rev e0080e640a2d9b79 |
| 17:42 | lpetit | now we must find the appropriate command :) |
| 17:44 | stuartsierra | yeah |
| 17:45 | lpetit | the simpler could be to do a git reset ...(options to determine) and if you have commit rights, to push it. It will definitely delete the wrong commit. |
| 17:45 | stuartsierra | I think it was an older commit, though. |
| 17:45 | lpetit | If nobody tried to checkout or fetch compat in the time interval, nobody will be harmed |
| 17:46 | stuartsierra | let's go with that assumption |
| 17:47 | lpetit | ok, so enter git reset --hard e0080e640a2d9b79 in your clone |
| 17:47 | stuartsierra | They seem to diverge on "build.xml: run compile-clojure in headless..." 3073f0dc0614cb8c95f2debd0b7e6a75c1736ece |
| 17:51 | stuartsierra | ok, did: git checkout origin/clojure-1.0-compatible |
| 17:51 | lpetit | no, chouser ported a correction in commit e0080e640a2d9b79 |
| 17:52 | lpetit | no, don't do that ! |
| 17:52 | stuartsierra | ok, clearly I don't understand git as well as I thought I did |
| 17:53 | lpetit | I'm not 100% sure, but pretty sure it's a bad thing : it is intended as being a mirror of what is on the remote |
| 17:53 | lpetit | I also have git repos for Counterclockwise, and work only on private trees that I push from time to time |
| 17:54 | lpetit | on your fresh clone, switch to your local branch for compat, maybe you have named it compat, maybe something else, so type git branch to see all your branches, and once you've localised it, git checkout <theRightName> |
| 17:55 | lpetit | then issue the command I stated previously : git reset --hard e0080e640a2d9b79 |
| 17:55 | lpetit | then try to push. If this does not work, there are some things in the configuration I don't master yet. |
| 17:56 | lpetit | you'll finish in the spam black list of everybody :-p |
| 17:57 | drewr | are you guys trying to push to the public repo after a local git reset --hard? |
| 17:57 | lpetit | :-$ |
| 17:58 | lpetit | oups, caught |
| 17:58 | stuartsierra | We're trying to erase a bunch of commits that I accidentally merged into the clojure-1.0-compatible branch. |
| 17:58 | drewr | you would have gotten away with it if it weren't for a couple of commits that just came in from others :-/ |
| 17:58 | stuartsierra | damn |
| 17:58 | stuartsierra | now what? |
| 17:59 | lpetit | drewr: no the problem is on the compat branch of clojure-contrib |
| 17:59 | drewr | git rebase origin/master :-) |
| 17:59 | stuartsierra | No, master is fine. It's only the clojure-1.0-compatible branch that I messed up. |
| 17:59 | drewr | at this point it's probably best to just leave it alone |
| 18:00 | lpetit | compat branch has just the last merge commit wrong. |
| 18:00 | drewr | the history will be a little dirty, but that's ok |
| 18:00 | lpetit | Seriously, for the compat branch, no big deal to quickly correct this ? |
| 18:00 | stuartsierra | Assuming we can figure out how. |
| 18:01 | lpetit | (is it me that is saying that) |
| 18:01 | lpetit | stuart, did you try my "instructions" ? |
| 18:01 | drewr | maybe the couple of msgs I saw were from you guys |
| 18:01 | stuartsierra | lpetit: not yet, hang on |
| 18:02 | drewr | as long as no one else has committed, you can "git reset --hard COMMIT_YOU_WANT && git push -f origin/clojure-1.0-compatible" |
| 18:02 | lpetit | I'll reproduce it locally too. |
| 18:02 | stuartsierra | Ok, starting fresh. |
| 18:03 | stuartsierra | git clone git@github.com:richhickey/clojure-contrib.git |
| 18:03 | stuartsierra | cd clojure-contrib |
| 18:03 | lpetit | git branch -r ; copy the name origin/clojure...compatible ... |
| 18:04 | stuartsierra | git checkout -b compat origin/clojure-1.0-compatible |
| 18:04 | lpetit | git checkout -b compat origin/clojure... ; compat will be the name of your branch |
| 18:04 | lpetit | ok |
| 18:05 | stuartsierra | git reset --hard e0080e640a2d9b79 |
| 18:05 | lpetit | now, the hard reset git reset --hard e0080e640a2d9b79 |
| 18:05 | lpetit | ok ! |
| 18:05 | lpetit | and the command from drew (thanks!) |
| 18:05 | stuartsierra | Now what do I push to? |
| 18:05 | stuartsierra | "git push origin/clojure-1.0-compatible" ? |
| 18:06 | stuartsierra | Or just "git push"? |
| 18:06 | lpetit | let's try that |
| 18:06 | lpetit | the fully specified first |
| 18:06 | drewr | you'll likely have to push -f |
| 18:07 | drewr | because the histories don't agree |
| 18:07 | stuartsierra | "error: src refspec clojure-1.0-compatible does not match any." |
| 18:07 | lpetit | true |
| 18:08 | lpetit | would -f help ? |
| 18:08 | drewr | not for that error |
| 18:08 | stuartsierra | same error |
| 18:08 | drewr | let me update and look aroudn |
| 18:08 | lpetit | based on the criteria of "shooting yourself on the feet", I would say git is way powerful than clojure :) |
| 18:09 | lpetit | stuart : and just git push -f |
| 18:09 | lpetit | if you still are in the compat branch, of course |
| 18:09 | drewr | stuartsierra: remove the slash |
| 18:09 | drewr | it should be "origin cloj..." |
| 18:09 | stuartsierra | did that |
| 18:10 | stuartsierra | lispaste: url |
| 18:10 | stuartsierra | lisppaste: url |
| 18:10 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 18:10 | drewr | you could do "git push origin :clojure-1.0-compatible && git push origin clojure-1.0-compatible" |
| 18:11 | drewr | that'll delete the branch and recreate it |
| 18:11 | lpetit | seems dangerous |
| 18:11 | stuartsierra | But git seems to be telling me that the branch doesn't exist in the first place |
| 18:11 | lisppaste8 | stuartsierra pasted "Trying to push to github" at http://paste.lisp.org/display/86203 |
| 18:11 | drewr | stuartsierra: what does "git branch -a" tell you? |
| 18:12 | lisppaste8 | stuartsierra annotated #86203 "git branch -a" at http://paste.lisp.org/display/86203#1 |
| 18:12 | lpetit | it may be because there are some implicit conventions, and since you did not give the same name to your local branch and the remote one, some more typing may be involved |
| 18:12 | drewr | ahh |
| 18:12 | stuartsierra | ah, pes |
| 18:12 | stuartsierra | yes |
| 18:12 | Chousuke | you should not use -f to push |
| 18:12 | drewr | so you would do... |
| 18:13 | drewr | since your local branch is a different name |
| 18:13 | stuartsierra | stuart@wsgrhl700c3:/tmp/clojure-contrib$ git push -f origin compat:clojure-1.0-compatible |
| 18:13 | stuartsierra | Total 0 (delta 0), reused 0 (delta 0) |
| 18:13 | stuartsierra | To git@github.com:richhickey/clojure-contrib.git |
| 18:13 | stuartsierra | + 69f810b...e0080e6 compat -> clojure-1.0-compatible (forced update) |
| 18:13 | Chousuke | if you use -f and push a branch that is not a descendant of the branch you're pushing to, you'll screw up other people's repos |
| 18:14 | drewr | Chousuke: that's what they're trying to do |
| 18:14 | stuartsierra | Chousuke: I know, normally I would not push -f, but in this case I already screwed up the repo and I'm trying to fix it. |
| 18:14 | Chousuke | ah, okay :) |
| 18:14 | drewr | stuartsierra: ok, so you got it? |
| 18:14 | stuartsierra | I think that did it. Look at http://github.com/richhickey/clojure-contrib/commits/clojure-1.0-compatible |
| 18:15 | lpetit | better, I'll do a fetch and see locally :) |
| 18:15 | drewr | looks good here |
| 18:16 | lpetit | yeah |
| 18:16 | lpetit | fiouu |
| 18:16 | stuartsierra | ok, phew |
| 18:16 | drewr | git log -1 --pretty=oneline |
| 18:16 | drewr | e0080e640a2d9b79564a3fb6eb7ee36be1882901 repl-utils: Fix init state for add-break-thread! |
| 18:16 | lpetit | oh sorry phew is fiouu in french :) |
| 18:16 | lpetit | yes that's what we wanted |
| 18:16 | stuartsierra | fiouu is a better spelling, anyway :) |
| 18:17 | lpetit | so now, stuart, please man git-checkout :-) |
| 18:17 | lpetit | no, man git-cherry-pick |
| 18:17 | lpetit | :à |
| 18:17 | lpetit | ;-) |
| 18:17 | stuartsierra | yeah, I still don't understand it. I did cherry-pick then push, what could be simpler? |
| 18:18 | lpetit | oh |
| 18:18 | stuartsierra | Wait, I know. |
| 18:18 | stuartsierra | I did "git checkout -b compat" without specifying which branch to track, so I got the master branch. |
| 18:18 | stuartsierra | Then pushed it back. |
| 18:19 | lpetit | yes, but how come it was then checked in the compat branch ? |
| 18:19 | lpetit | do you stil have the history of the commands? |
| 18:19 | Chousuke | hmm, yeah, master is still a descendant of the compat branch, is it? |
| 18:20 | lpetit | no, Chouser commited something on July |
| 18:20 | lpetit | stuart, it work, the reverse spamming has begun :) |
| 18:20 | lpetit | it works |
| 18:21 | stuartsierra | yay |
| 18:22 | lpetit | so now, let's try the cherrypick ? :-) git checkout compat && git cherry-pick -x 4b4f6ab5bcab58c4219e |
| 18:23 | stuartsierra | no, I'm going home. I'll try the cherry-pick when I'm more awake |
| 18:23 | lpetit | if it's possible to do this as a patch I can do it and then attach it to the issue |
| 18:23 | lpetit | at your convenience |
| 18:24 | Chousuke | well you can always do the cherrypick yourself and then use git format-patch |
| 18:24 | Chousuke | the end result will be the same. |
| 18:24 | stuartsierra | That won't help, will it? I (or someone) still have to push to the right branch. |
| 18:24 | stuartsierra | I just have to get good with git. |
| 18:25 | lpetit | ok, so we'll let this as an exercise for the reader :) |
| 18:25 | stuartsierra | yeah, g'night folks |
| 18:25 | Licenser | I think it is great to have those videos |
| 18:25 | lpetit | g'night |
| 18:26 | Licenser | night lpetit |
| 18:31 | drewr | whenever I'm about to venture into uncharted territory with git I always create a test repository, clone it, try whatever on the clone, and then push |
| 18:32 | drewr | you can do that in /tmp in 5 min |
| 18:32 | drewr | and they're both gone |
| 18:32 | drewr | (lpetit and stuartsierra that is) |
| 19:53 | JAS415 | is there a way to match and replace a string without java doing the regex machinations? |
| 19:58 | Chouser | what's wrong with Java doing it? I like contrib str-utils2/replace |
| 20:01 | dmiles_afk | are some you guy s masters at understanding verify errors? |
| 20:01 | dmiles_afk | javaclassloader verify errors that is |
| 20:02 | dmiles_afk | does clojure use invokeinterface ? or just invokevirtuals? |
| 20:03 | dmiles_afk | (thats eigther only invokevirtuals vs both) |
| 20:10 | dmiles_afk | ah it uses a private copy of ASM whichmakes it more transparent |
| 21:39 | lowlycoder | is there a macro for scheme-like define in clojure? one that acts more like letfn than defn? (i.e. define the function in the local lexical environment~ not the global one) |
| 21:42 | cemerick | lowlycoder: I *think* so. I remember someone asking something very similar, and there was either something in place, or perhaps in contrib? |
| 21:43 | lowlycoder | not finding it grepping for "define " in clojure-contrib |
| 21:43 | JAS415 | hmm |
| 21:43 | JAS415 | how do i replace a $ with an escaped $ in a string? |
| 21:43 | lowlycoder | then again~ i'm running clojure 1.0.0 with the relevant clojure-contrib |
| 21:43 | JAS415 | with a regex |
| 21:44 | JAS415 | you could just use letfn all over |
| 21:44 | lowlycoder | no; i have the indenting |
| 21:44 | lowlycoder | s/have/hate |
| 21:45 | JAS415 | oh, indenting |
| 21:45 | JAS415 | you could make a macro |
| 21:46 | tomoj | lowlycoder: didn't we already talk about this? |
| 21:46 | lowlycoder | yes; we concluded that clojure and scheme are different |
| 21:47 | tomoj | also that a macro for the inner defines alone wouldn't help |
| 21:47 | tomoj | you'd need to use a macro for the toplevel form |
| 21:47 | lowlycoder | of course not |
| 21:47 | lowlycoder | right |
| 21:47 | lowlycoder | this looks like a messy job |
| 21:47 | lowlycoder | and also screws up debugging support |
| 21:47 | lowlycoder | (like mismatching of source code lines) |
| 21:48 | lowlycoder | so i'm hoping someone else has handled this already |
| 21:48 | tomoj | macros mismatch source code lines? |
| 21:48 | cark | lowlycoder : are you looking for letfn ? |
| 21:49 | lowlycoder | no~ i'm looking for a macro that ends up writing letfn |
| 21:49 | JAS415 | um |
| 21:49 | lowlycoder | s/writing/calling |
| 21:49 | cark | what's the local envioronment you're talking about ? |
| 21:50 | JAS415 | i forget how define in scheme works |
| 21:50 | tomoj | I think you would need to macroexpand all the forms in the body, take the initial segment that start with def, and then turn those into a letfn that you wrap around the rest of the body |
| 21:50 | tomoj | or if you use "define" in the inner defines as well, it would be even easier |
| 21:50 | JAS415 | upi cam |
| 21:50 | cark | oh i see now |
| 21:50 | JAS415 | you can't just use let |
| 21:50 | lowlycoder | cark: it's hard to explain unless you use scheme; it's obvious if you do |
| 21:50 | JAS415 | ? |
| 21:51 | cark | i got it now |
| 21:51 | JAS415 | let = define.. |
| 21:51 | JAS415 | we're talking about lexical scope? |
| 21:51 | lowlycoder | yes |
| 21:51 | cark | i don't think you can access the environement from a macro in clojure |
| 21:52 | tomoj | sure you can |
| 21:52 | tomoj | just have the macro produce a letfn |
| 21:52 | cark | right but he wants to have the "define" valid after it is err ... defined |
| 21:53 | tomoj | that's why you need a macro |
| 21:53 | lowlycoder | cark: there we go :-) |
| 21:53 | tomoj | it needs to convert those into a proper letfn |
| 21:53 | JAS415 | have the define valid after is define |
| 21:53 | cark | but how would your macro know what are the next forms |
| 21:53 | JAS415 | hum |
| 21:53 | tomoj | it's just the rest of the body |
| 21:54 | tomoj | all the forms in the body besides the initial segment which start with "define" |
| 21:54 | JAS415 | hmm |
| 21:54 | JAS415 | well idunno |
| 21:54 | JAS415 | it sounds like a lot of work to reimplement scheme :-P |
| 21:54 | cark | that's what he wants (def bleh [] (define somefunc (fn [] (println "hello")) (somefunc)) |
| 21:55 | tomoj | cark: no, the new macro goes at the top level |
| 21:55 | tomoj | (define bleh [] (define somefunc (fn [] ...)) (somefunc)) |
| 21:56 | tomoj | in that case the toplevel define can take the initial segment of forms starting with "define" it its body and convert them into a letfn, then wrap that around the rest of the body |
| 21:56 | cark | ah in this case the define macro could walk the code and do it, yes |
| 21:56 | tomoj | you're right, seems impossible to add inner defines to defn |
| 21:57 | cark | but i don't like it, because the semantic of the outer define is not the same as the inside one |
| 21:57 | tomoj | well you could name it whatever |
| 21:57 | cark | mhh no scratch that |
| 21:58 | cark | it would be ok as the outer lexical scope is the namespace |
| 21:58 | tomoj | to really get this working like scheme you would have to define new versions of fn, let, letfn, defn |
| 21:58 | lowlycoder | where is richhickey? |
| 21:58 | tomoj | since inner defines can be used in all the scheme equivalents |
| 21:58 | lowlycoder | i want to hear his reasons for changing this |
| 21:59 | tomoj | changing it? |
| 21:59 | cark | well i want to hear your reasons to have it your way =P |
| 21:59 | tomoj | did clojure support inner defines at one time? |
| 21:59 | lowlycoder | yeah~ for making the semantics of defn clojure != scheme define |
| 21:59 | tomoj | clojure did not derive from scheme... |
| 21:59 | lowlycoder | all languages derive from scheme |
| 21:59 | tomoj | hah |
| 21:59 | JAS415 | no |
| 21:59 | cark | hehe |
| 22:00 | JAS415 | all languagse derive from fortran |
| 22:00 | JAS415 | :-( |
| 22:00 | JAS415 | fortran and algol |
| 22:00 | lowlycoder | all langauges derive from waving a magnet over a harddrive |
| 22:00 | JAS415 | :-( :-( |
| 22:00 | tomoj | I mean it's not like he took scheme and then said for each feature, "hmm.. should we keep this feature or change it?" |
| 22:01 | JAS415 | how do i replace a $ in a string with an escaped $? |
| 22:01 | JAS415 | i've got this far |
| 22:01 | JAS415 | (.replaceAll "$324" "\\$" "\$") |
| 22:02 | JAS415 | (.replaceAll "$324" "\\$" "\\$") |
| 22:03 | JAS415 | this far |
| 22:03 | Chouser | ,(.replaceAll "$324" "\\$" "\\$") |
| 22:03 | hiredman | oops |
| 22:03 | JAS415 | it returns $324 |
| 22:03 | tomoj | ,(.replace "$324" "$" "\\$") |
| 22:03 | clojurebot | "\\$324" |
| 22:03 | JAS415 | but i'm guessing i want \$324 |
| 22:03 | JAS415 | so i try to escape it |
| 22:04 | hiredman | you have to \\\\ |
| 22:04 | hiredman | ,(.replace "$324" "\\$" "\\$") |
| 22:04 | clojurebot | "$324" |
| 22:04 | hiredman | ,(.replace "$324" "\\\\$" "\\$") |
| 22:04 | clojurebot | "$324" |
| 22:04 | hiredman | ,(.replace "$324" "\\\\$" "\\\\$") |
| 22:04 | clojurebot | "$324" |
| 22:04 | JAS415 | ,(.replaceAll "$324" "\\$" "\\\\$") |
| 22:04 | clojurebot | java.lang.StringIndexOutOfBoundsException: String index out of range: 3 |
| 22:04 | JAS415 | oh i need 5 |
| 22:04 | JAS415 | okay |
| 22:04 | JAS415 | i was trying 4 |
| 22:04 | tomoj | I must not understand what you're trying to do.. |
| 22:05 | tomoj | you want to replace "$" in a string with "\\$" ? |
| 22:05 | JAS415 | well i got this string, which i'm going to use in a regular expression... |
| 22:05 | JAS415 | which i pulled from an 'unknown source' |
| 22:05 | JAS415 | so the internets |
| 22:06 | JAS415 | and it comes back something like "Blahblah $60,000" |
| 22:06 | hiredman | ,(.replace "$324" "$" "\\$") |
| 22:06 | clojurebot | "\\$324" |
| 22:06 | hiredman | like that? |
| 22:06 | JAS415 | wow |
| 22:06 | JAS415 | exactly like that |
| 22:06 | JAS415 | there's a plain old replace? |
| 22:06 | JAS415 | nice |
| 22:06 | tomoj | das hab ich auch gesagt.. |
| 22:06 | Chouser | oh, use \Q |
| 22:06 | Chouser | ,(re-seq #"\Q$1" "$1") |
| 22:06 | clojurebot | ("$1") |
| 22:09 | wtetzner_ | is there a function to check if a value is contained in a sequence? |
| 22:09 | wtetzner_ | i know there is contains?, but that checks if a key exists in something associative |
| 22:09 | JAS415 | nice (.replace works perfectly |
| 22:09 | Chouser | if you can use a set instead of a sequence, your life will be easier |
| 22:09 | JAS415 | i'll have to look up \Q |
| 22:10 | wtetzner_ | oh, that should be ok |
| 22:10 | wtetzner_ | thanks |
| 22:10 | hiredman | calling .contains is much faster than creating a set and testing for set membership |
| 22:11 | hiredman | fyi |
| 22:11 | cemerick | so, I've got this lib whose most significant hotspot is isa? and friends |
| 22:12 | cemerick | I did a bunch of profiling, and supers (and to a much lesser extent, bases) is the fundamental culprit |
| 22:12 | wtetzner_ | oh, thanks hiredman |
| 22:12 | wtetzner_ | so is .contains part of the collection interface, but doesn't have a corresponding clojure function? |
| 22:12 | cemerick | I memoized supers, and got a very large factor speed improvement -- perhaps up to an order of magnitude, but I haven't taken a precise measurement |
| 22:13 | cemerick | (memoizing bases helped a little more, but was far less impactful) |
| 22:13 | cemerick | Does it seem like memoizing supers (+ bases, perhaps) is a good idea in general? |
| 22:14 | cemerick | I'm thinking that using a WeakHashMap would be more correct, so as to allow dead classes to go away, etc. |
| 22:14 | hiredman | cemerick: if your hierarchs are not java classes, it seems like they can be mutated |
| 22:14 | cemerick | hiredman: bases and supers are only concerned with classes and interfaces |
| 22:14 | hiredman | oh |
| 22:14 | hiredman | of course |
| 22:15 | cemerick | so, I'm thinking that this might be a safe optimization to apply, but I'm unsure of any impact on touchy module systems |
| 22:15 | cemerick | ...and any other things I'm not thinking of. |
| 22:15 | cemerick | One way or the other, the perf improvement is very significant. |
| 22:16 | cemerick | anyway, I'm going to write some results up for a msg to the group, but I wanted to see if anyone had any immediate reasons why this would be a bad idea |
| 22:17 | hiredman | I wonder how good Class's .hashCode is |
| 22:18 | cemerick | hiredman: it doesn't override it |
| 22:19 | cemerick | which I *think* is good in this case |
| 22:19 | cemerick | e.g. if a new version of a class with the same name as another comes into supers/bases, it'll get its bases/supers recalculated |
| 22:19 | cemerick | that might actually be what saves me with the module systems |
| 22:19 | cark | the usage of isa? that needs to be optimzed, is it in a loop under your control ? |
| 22:20 | cemerick | cark: yes, but the size of the dataset isn't |
| 22:21 | cark | you could (binding [super (memoize super)] ...] ...) around your loops maybe ? |
| 22:21 | cark | or whatever function |
| 22:21 | cemerick | heh, that's sneaky :-) |
| 22:21 | cemerick | but, if this is safe, I'd like to see it made available to everyone's code |
| 22:22 | cark | mhh i don't think it is safe, i wouldn't want that a default in clojure |
| 22:22 | cark | some classes might be unloaded |
| 22:23 | cemerick | cark: that's why a weakhashmap would be more appropriate |
| 22:23 | Chouser | classes don't go away unless they're loaded by a classloader that goes away |
| 22:23 | cark | right |
| 22:24 | cark | this is a pretty obvious optimization, don't you think the java people would have done that already if it was a good idea ? |
| 22:24 | cemerick | cark: the point is, using a weakhashmap would allow those unloaded classes to get collected as they would be otherwise |
| 22:25 | Chouser | the supers of a class can't change, can they? |
| 22:25 | cemerick | nope. (JDK 7 majick aside) |
| 22:25 | Chouser | until we get interface injection, or whatever it's called. |
| 22:25 | cemerick | right |
| 22:26 | cark | hum if there's one exception, that's it, you can't do it anymore |
| 22:26 | cemerick | OK, quick numbers. Before memoization, 17165ms. After memoizing, 2749ms |
| 22:26 | cemerick | me likey :-) |
| 22:28 | cemerick | cark: exception? Like java.lang.Exception? |
| 22:28 | cark | nope i mean like "an exception to the rule that you can do it" |
| 22:28 | cark | like say jdk 7 =) |
| 22:29 | cemerick | oh, sure. If it's not safe, then that's it. |
| 22:29 | Chouser | well, you just need to know when to invalidate your cache |
| 22:29 | cemerick | jdk 7 is an externality until it actually exists in a meaningful way :-) |
| 22:30 | cemerick | Chouser: yeah, I'd assume interface injection would come with some kind of notification mechanism we could hook into |
| 22:31 | Chouser | actually didn't they say you had to do the injection before doing anything else with the class? |
| 22:31 | cemerick | I don't know... |
| 22:31 | cemerick | doesn't that defeat the point? |
| 22:32 | cark | are they trying to do something like c# extention methods ? |
| 22:34 | Chouser | ok, I remembered that wrong. Here's what I was thinking of: "For any given class and injectable interface, the injector method is called the first time the question arises whether the class implements the interface. (This could be an invokeinterface, an instanceof, or a reflective operation.) Just before the decision, the class is called an injection candidate." |
| 22:34 | cemerick | ah |
| 22:34 | cemerick | after injection, does a new class get consed up and swapped in for the old? |
| 22:41 | hiredman | I hope not |