2009-12-07
| 00:17 | somnium | if you use clojure to generate code in 'blub' that depends on libraries that are not eclipse-compatible, but there is no dependency on clojure in the generated 'blub', are there any issues? |
| 00:25 | JAS415 | wait hut |
| 00:25 | JAS415 | what* |
| 00:26 | JAS415 | am i generating source code to blub or bytecode to blub? |
| 00:26 | JAS415 | and why am i generating blub code when i could be generating clojure code? |
| 00:26 | JAS415 | and what does eclipse have to do with it? |
| 00:26 | JAS415 | i dont even use eclipse, i use emacs |
| 00:28 | _ato | what does eclipse-compatible even mean? |
| 00:28 | _ato | or do you mean the EPL? |
| 00:29 | _ato | clojure in no way sets what license code you write that uses it has to be |
| 00:29 | _ato | it's a weak-copyleft |
| 00:29 | _ato | you just can't relicense clojure-itself to say GPL |
| 00:29 | JAS415 | oh its a license thing |
| 00:30 | _ato | yeah I had to read the sentence 5 times before I realised he was talking about licenses |
| 00:30 | _ato | because Eclipse-the-IDE-compatible makes absolutely no sense |
| 00:30 | _ato | so there's no issues |
| 00:30 | JAS415 | yeah |
| 00:32 | _ato | what the non-eclipse-compatible licenses say is another thing though. But if it's the GPL you're talking about I'd say that's probably okay. It's like using Visual Studio to compile a GPLed project. You don't have to supply the source code to visual studio |
| 00:33 | JAS415 | yeah or if you submitted a patch to clojure that used GPL code |
| 00:33 | JAS415 | that would be a no-no |
| 00:33 | somnium | pure-blub, not byte-code |
| 00:34 | JAS415 | im generating LFE into a text file |
| 00:34 | JAS415 | works great :-) |
| 00:35 | somnium | just wondering, playing with js generation that calls libs like mootools/dojo/jquery |
| 00:35 | JAS415 | oh like scriptjure |
| 00:35 | JAS415 | yeah that works |
| 00:35 | somnium | clojure-script lite kind-of |
| 00:36 | JAS415 | you can either include the (jquery for example) script file as a seperate link or you can slurp it and concatenate them (probably) |
| 00:36 | somnium | but a clojure generated jquery plugin mould be okay to release under whatever license? |
| 00:36 | JAS415 | oh |
| 00:36 | JAS415 | we are on licenses |
| 00:36 | JAS415 | i think the answer is 'yeah' |
| 00:38 | somnium | btw, anyone know how clojure finds tail positions? |
| 00:38 | _ato | looks for the last argument in every do form? |
| 00:38 | somnium | doing a bit of wheel reinvention implementing loop*, though its fun it its way |
| 00:39 | _ato | the recur I hacked into scriptjure looks like: (str "return arguments.callee(" (str/join ", " (map emit args)) ");") |
| 00:40 | somnium | hmm, need to add explicit return so really need to find last node |
| 00:40 | _ato | (that's a non-TCO version though) |
| 00:41 | somnium | _ato: not using scriptjure, but trying to implement loop* as a do-while for loop* and fn* |
| 00:41 | somnium | need to find every actual tail position though... probably need a zipper |
| 00:44 | somnium | do ... {blah} while (gensym__recur) |
| 00:44 | somnium | where is clojure's recur TCO implemented? |
| 00:47 | JAS415 | you could look at core.clj |
| 00:47 | hiredman | that's not in core.clj |
| 00:47 | _ato | RecurExpr in Compiler.java |
| 00:47 | hiredman | that's in the compiler |
| 00:47 | JAS415 | hmm |
| 00:47 | _ato | and various other places |
| 00:47 | somnium | yeah, ive read it, recur and loop* are special forms |
| 00:48 | JAS415 | right |
| 00:48 | JAS415 | but its like a goto or whatever, right? |
| 00:49 | _ato | gen.goTo(loopLabel); |
| 00:49 | _ato | does javascript have named loops? |
| 00:50 | _ato | oh well I guess it doesn't need to if you implement your script's while in terms of loop |
| 00:54 | timothypratley | ,(defmacro foo [form] `(println ~form)) |
| 00:54 | clojurebot | DENIED |
| 00:54 | JAS415 | you can probably implement loop in terms of while |
| 00:55 | timothypratley | (foo (1 2)) <--- doesn't do what I want :) |
| 00:55 | JAS415 | err |
| 00:55 | somnium | Ive got let* working, and destructuring will just-work (using js primitive arrays and objects), but was hoping someone knew a tail finder algorithm I could just use for TCO |
| 00:55 | JAS415 | you need (foo (list 1 2)) |
| 00:55 | JAS415 | otherwise it evaluates (1 2) |
| 00:56 | JAS415 | and 1 isn't a fn |
| 00:56 | timothypratley | Indeed, but being a macro... isn't there some way to avoid evaluating (1 2)? |
| 00:56 | _ato | ~'form |
| 00:56 | clojurebot | excusez-moi |
| 00:57 | _ato | or wait |
| 00:57 | _ato | it's the other way '~form is what you want |
| 00:57 | timothypratley | ah great! |
| 00:57 | JAS415 | yeah |
| 00:57 | somnium | ,`(println ~(str '(form))) |
| 00:57 | clojurebot | (clojure.core/println "(form)") |
| 00:57 | timothypratley | thanks.... mindboggling |
| 00:58 | _ato | might be more obvious why as: (quote ~form) |
| 01:00 | JAS415 | somnium, you can't do something like: |
| 01:01 | JAS415 | while (recur) |
| 01:01 | JAS415 | { |
| 01:01 | JAS415 | (set recur false) |
| 01:01 | JAS415 | (do stuff) |
| 01:01 | JAS415 | } |
| 01:01 | JAS415 | recur (bindings) |
| 01:01 | JAS415 | (set recur true bind-bindings) |
| 01:01 | JAS415 | and make recur like a macro-ey thing |
| 01:01 | JAS415 | and have that while for stand in for loop |
| 01:02 | JAS415 | of course you'd still have to detect if it is actually a tail |
| 01:03 | somnium | I want to be able to macroexpand a subset clojure code and compile it to executable js |
| 01:03 | _ato | it's sort-of annoying as you have to track the return value |
| 01:03 | somnium | _ato: yes |
| 01:04 | somnium | I tried to read clojurescript.clj to see how chouser did it but its impenetrable to me |
| 01:04 | _ato | you also need to deal with javascript's variable scoping, null out all the variables when you break out of the loop and such |
| 01:05 | somnium | no, scoping is easy with containing functions |
| 01:05 | _ato | ah right, I thought you were trying avoid the overhead of that |
| 01:05 | somnium | let* is more or less (function() { ...bindings ... body })() |
| 01:05 | _ato | but yeah, should be doable |
| 01:05 | _ato | ah |
| 01:06 | _ato | well that makes your return values easier then |
| 01:06 | _ato | cause you can just return |
| 01:06 | somnium | in what im hacking on anyway |
| 01:06 | _ato | if you wrap all loops in anonymous functions |
| 01:06 | hiredman | that is an odd way to do let |
| 01:06 | somnium | hiredman: how else to guarantee local scope? |
| 01:07 | hiredman | (function(...names..){body})(..values..) |
| 01:07 | somnium | hmm, almost the same no? |
| 01:08 | _ato | hmm |
| 01:08 | hiredman | sure, which is way your way seems so odd |
| 01:08 | hiredman | let as a λ like that is right out of sicp |
| 01:08 | somnium | js is quite lispy |
| 01:09 | hiredman | it's scheme minus the good bits |
| 01:09 | _ato | (function(x) { while(true) { if (x < 5) { x = x + 1; continue; } else { return x; } } })(0); |
| 01:09 | somnium | at least it has more than a cons-cell :p |
| 01:09 | _ato | would be something like: (loop [x 0] (if (< x 5) (recur (inc x)) x)) |
| 01:10 | hiredman | I've been tinkering with a lisp -> php compiler |
| 01:11 | hiredman | I'm stopped right now because I think I need to throw out my whol function call and recur implementation |
| 01:11 | somnium | If I can get recur working, it should be enough to start writing clojure in js in clojure, which sounds fun |
| 01:11 | hiredman | what I currently have won't support varargs nicely |
| 01:12 | hiredman | (or really at all) |
| 01:12 | somnium | I was planning on doing var |
| 01:12 | somnium | args with the arguments object in js |
| 01:12 | somnium | at least until its possible to get seq working |
| 01:12 | hiredman | yeah, matching the host is good |
| 01:13 | hiredman | I did not, and match php up to lisp can be maddening |
| 01:14 | hiredman | http://www.thelastcitadel.com/lab/pl/a.phps generated code |
| 01:16 | somnium | hiredman: it sounds so painful I cant imagine what compelled you :) |
| 01:18 | somnium | http://github.com/tenderlove/phuby |
| 01:18 | somnium | ^^ might be worth inspiration, or a laugh |
| 01:18 | technomancy | heh... phuby is so ridiculous |
| 01:18 | technomancy | (but it's ridiculous on purpose.) |
| 01:19 | hiredman | cute |
| 01:19 | technomancy | http://www.rubyconf.org/talks/60-worst-ideas-ever- |
| 01:28 | somnium | hiredman: I can hardly distinguish your php-compiler's output from idiomatic php |
| 01:28 | somnium | other than the gensyms |
| 01:31 | James__d | What does k-lined mean? |
| 01:32 | hiredman | somnium: well, I did run it through a beautifier for the nice formating |
| 01:33 | hiredman | but I would like the generated php code to be ok to deal with without the lisp source |
| 01:34 | somnium | hiredman: isnt 'being okay to deal with' always the achilles heel of php? |
| 01:34 | hiredman | :P |
| 01:43 | TheBusby | What's the best way to return the counts of various values in a list? Ex. '(1 2 2 3 3 3 44) into {1 1, 2 2, 3 3, 4 2} |
| 01:44 | TheBusby | er, the Example should be '(1 2 2 3 3 3 4 4) into {1 1, 2 2, 3 3, 4 2} |
| 01:45 | arbscht | ,(doc frequencies) |
| 01:45 | clojurebot | "([coll]); Returns a map from distinct items in coll to the number of times they appear." |
| 01:45 | arbscht | from c.c.seq-utils |
| 01:45 | TheBusby | arbscht, thank you! |
| 01:46 | hiredman | (apply merge-with + (map #(array-map % 1) (1 2 2 3 3 3 44))) |
| 01:46 | hiredman | ,(apply merge-with + (map #(array-map % 1) (1 2 2 3 3 3 44))) |
| 01:46 | clojurebot | java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn |
| 01:46 | hiredman | bleh |
| 01:46 | hiredman | ,(apply merge-with + (map #(array-map % 1) '(1 2 2 3 3 3 44))) |
| 01:46 | clojurebot | {44 1, 3 3, 2 2, 1 1} |
| 01:48 | timothypratley1 | ,(reduce #(assoc %1 %2 (inc (%1 %2 0))) {} [1 2 2 3 3 3 4 4]) |
| 01:48 | clojurebot | {4 2, 3 3, 2 2, 1 1} |
| 01:50 | timothypratley1 | (defmacro foo [f] `(def ~(symbol (str "foo" (count (meta (var f))))))) <--- how can I make this work? :) |
| 01:50 | arbscht | timothypratley1: that's pretty much how c.c.seq-utils/frequencies is implemented :) |
| 01:51 | somnium | timothypratley1: what is that supposed to do? |
| 01:51 | timothypratley1 | arbscht: yup frequencies is the way to go :) |
| 01:52 | timothypratley1 | somnium: I want a macro foo that I can call like (foo defn) |
| 01:52 | timothypratley1 | and it will def foo7 |
| 01:53 | timothypratley1 | so that I can create tests with deftest with a symbol that is dependent on meta-data of another var |
| 01:53 | timothypratley1 | (what a tongue twister) |
| 01:56 | timothypratley1 | The bit I'm stuck on is getting (var f) hmmm maybe I should be doing (resolve f) or something |
| 01:57 | timothypratley1 | omg - that actually works.... |
| 01:57 | timothypratley1 | sorry for the noise. |
| 02:03 | KirinDave | Man I see a red line in my history but I cannot find it. |
| 02:03 | KirinDave | Did someone mention my name or something? |
| 02:27 | KirinDave | Man, I love it |
| 02:28 | KirinDave | Someone hacker-newses my clojure chat |
| 02:28 | KirinDave | and within 2 hours someone says, "I have a better one in scala. Just install lift!" |
| 03:31 | LauJensen | Morning gents |
| 04:12 | cgrand | KirinDave: I'm interested to know what wasn't working for you with Enlive |
| 04:39 | Licenser_ | good morning clojure world! |
| 04:41 | Licenser_ | Is there a 'common and good aproach' for writing a clojure app that comunicates over network to send forth and back information/commands |
| 04:41 | Licenser_ | implementing a low level protocoll seems a bit of an overkill to me for just sending a bit of information |
| 04:42 | somnium | Licenser_: I dont know, but if you write a wrapper for nio do put it on github :P |
| 04:43 | cark | Licenser : both the server and client are clojure applications ? |
| 04:44 | Licenser_ | cark, yap |
| 04:44 | Licenser_ | somnium: what is nio? |
| 04:44 | clojurebot | What is meta |
| 04:44 | Licenser_ | and nice to hear from you again :) how is your mongo driver doing? |
| 04:44 | cark | well you can easily serialize clojure data structures by printing these then use clojrue reader to get data structures back |
| 04:45 | cark | is that enswering the question ? |
| 04:45 | cark | answering =/ |
| 04:46 | Licenser_ | cark: aside of not having a clue how to serialize or deserialzie (but I guess google will tell me that) yap that is what I was looking for I think |
| 04:46 | somnium | Licenser_: java.nio has tools for tcp/ip stuff, with os access to os streams, but a bit low level |
| 04:46 | cark | i'm not talking about real serialization, just printing, which is the same, and very easy |
| 04:46 | somnium | been using for my attempts to reimplement the mongo driver in clj |
| 04:47 | Licenser_ | somnium: ah I see, I don't really want to go into that low level, I mostly want something like sawpn a process, connect to a server be happy and not worry about anything as TCP or below |
| 04:48 | cark | ,(read-string (with-out-str (pr '(a b :a :b [1 2 3])))) |
| 04:48 | clojurebot | (a b :a :b [1 2 3]) |
| 04:48 | cark | so now you can devise your high lvl protocol based on it |
| 04:49 | cark | carefull about *read-eval* though |
| 04:49 | Licenser_ | cark: you're my hero |
| 04:50 | cark | =) |
| 04:50 | Licenser_ | cark: it's a entirely non critical application so I don't worry much about read-eval also I don't think I'll even need it |
| 04:50 | tomoj | munges structmaps though :/ |
| 04:51 | cark | wan't there a flag for that ? |
| 04:51 | cark | can't remember it now =/ |
| 04:51 | tomoj | *print-dup* ? |
| 04:51 | cark | ah could be yes |
| 04:51 | tomoj | that will just make structmaps print unreadably |
| 04:51 | tomoj | at least in my version |
| 04:52 | cark | ahwell anyways you get a standard map in the end, so i guess that's good enough for communications |
| 04:52 | Licenser_ | Yap it's good enough for me at least |
| 04:53 | tomoj | packing the regular maps you get back into structmaps wouldn't be too hard I guess |
| 04:53 | tomoj | well of course it wouldn't be hard, but I think it shouldn't slow you down much either |
| 04:54 | tomoj | ,^(read-string (binding [*print-dup* true] (with-out-str (pr (with-meta [] {:foo 3}))))) |
| 04:54 | clojurebot | java.lang.RuntimeException: java.lang.Exception: EvalReader not allowed when *read-eval* is false. |
| 04:54 | Licenser_ | Bottelneck won't be maps, rather waiting for the othser side to do something |
| 04:54 | Licenser_ | so I don't worry much about it |
| 04:54 | tomoj | oh |
| 04:55 | tomoj | well with *print-dup* and *read-eval* on, you get to keep your metadata |
| 04:55 | cark | i think a protocol should be as simple as possible, and decoupled from your internal representation anyways |
| 04:56 | Licenser_ | *nods* |
| 04:56 | tomoj | c.c.json is easy :) |
| 04:56 | cark | json isn't good enough in most cases |
| 04:57 | cark | i mean, no decimals ? |
| 04:57 | somnium | cark: strings! |
| 04:57 | cark | bleh that's ugly =) |
| 04:57 | cark | i have to do this for web stuff, but i hate it |
| 04:57 | tomoj | I really like it |
| 04:57 | tomoj | but the choice was already made for me by couchdb anyway |
| 04:57 | somnium | hopefully c.c.json will speed up a lot with types/protocols |
| 04:58 | cark | if you want speed i'm pretty sure there must be som good java json libraries |
| 04:58 | somnium | recursive multimethod calls really dont show closures strength |
| 04:58 | tomoj | hmm that's a good idea |
| 04:59 | tomoj | maybe I will try converting c.c.json to learn the new stuff |
| 04:59 | tomoj | still don't understand it at all |
| 04:59 | somnium | the one packed with mongo is crazy fast, and jackson is supposed to be really good |
| 05:00 | somnium | jackson has 200 or so classes though :/ |
| 05:00 | cark | oh nice a streaming api =P |
| 05:02 | somnium | cark: thats what was recommended to me, but I havent had the determination to wade through the javadoc yet |
| 08:07 | fliebel | Hey, What is a good Clojure editor? |
| 08:07 | Chousuke | emacs .) |
| 08:08 | fliebel | I tried emacs today, but its key combinations seem horrid to me. |
| 08:12 | fliebel | Maybe it's a good tool after having used it for years on the terminal, but for me it's not really friendly. |
| 08:13 | cemerick | fliebel: enclojure is pretty nice |
| 08:14 | fliebel | Hmm, seems like a good choice since NetBeans also supports Python and PHP if I remember correctly. Somehow Netbeans always make me think 'Java'. |
| 08:15 | cemerick | ...and ruby and C++ and scala and javascript... :-P |
| 08:15 | esj | i'd say emacs |
| 08:16 | esj | but really, nothing to get excited about |
| 08:16 | cemerick | I guess it's better to get the editor discussion of the week out of the way early |
| 08:16 | esj | yeah, then we can move onto seque :) |
| 08:17 | fliebel | esj: I find Clojure hard enough, I don't want to learn another 1000 keyboard commands. |
| 08:18 | tomoj | :D |
| 08:18 | esj | fliebel: fair play. |
| 08:18 | fliebel | esj: what's with seque? |
| 08:18 | cemerick | the number of commands isn't the problem, it's the lack of discoverability because of the 70's terminal UI. |
| 08:19 | tomoj | I love the lack of discoverability |
| 08:19 | tomoj | it means I am always finding new things :) |
| 08:19 | fliebel | At least it has the geek factor.... |
| 08:19 | esj | fliebel: blocking queues etc |
| 08:19 | cemerick | tomoj: yeah, I love a good game of "how the frig am I supposed to do X?" ;-) |
| 08:20 | tomoj | luckily that question doesn't come up very often for me |
| 08:20 | esj | cemerick: its usually C-x A-w C-% |
| 08:20 | tomoj | but "oh shit, I can do Y too??" happens often |
| 08:20 | cemerick | esj: see, I don't know if you're agreeing with me or not now. ;-) |
| 08:22 | esj | cemerick: emacs is well weird, no doubt, but uniformly weird - but it work the same on all my computers, OS/s, virtualised blah blahs etc. Time saver. |
| 08:23 | notallama | i was reading about emacs history the other day. more keyboards should have a cokebottle modifier. |
| 08:25 | esj | noallama: looking that up... |
| 08:28 | fliebel | is vim any better then emacs when dealing with keyboard shortcuts? |
| 08:29 | esj | fliebel: that's the question that has launched 1000 warships. |
| 08:30 | fliebel | I should have known that… especially with Lisp guys like you… Sorry… |
| 08:30 | esj | space-cadet keyboard: n. |
| 08:30 | esj | A now-legendary device used on MIT LISP machines, which inspired several still-current jargon terms and influenced the design of EMACS. It was equipped with no fewer than seven shift keys: four keys for bucky bits (‘control’, ‘meta’, ‘hyper’, and ‘super’) and three regular shift keys, called ‘shift’, ‘top’, and ‘front’ |
| 08:30 | esj | glorious ! |
| 08:30 | tomoj | what are my options for providing configuration for my library? take e.g. a database client library. I don't think I want to have to pass my database config to every library function (or do I?). I also don't think I want to put a binding that provides the config around every place I use the library. is there another way? |
| 08:32 | tomoj | or maybe one of these is good and I'm just thinking about it wrong |
| 08:32 | ordnungswidrig | hi all |
| 08:33 | esj | i'd be interested to hear what ppl think here ? I'd plump for *my-config* and keep the function interface tidy, but then i'm usually wrong :) |
| 08:33 | noidi | is it possible to tell whether a module is being run from a command line as a script, or loaded as a library? |
| 08:33 | noidi | I'd like to have something like python's `if __name__ == "__main__"` |
| 08:39 | cemerick | noidi: (when *command-line-args* ...), if memory serves |
| 08:40 | cemerick | hrm, no, that's probably not right |
| 08:40 | fliebel | Can't you check the namespace? (just a guess) |
| 08:40 | chouser | tomoj: having a rebindable var as the only way to pass in the db config is likely to get annoying in several contexts. |
| 08:41 | tomoj | yeah, it sounds annoying |
| 08:41 | chouser | tomoj: if possible, I'd recommend allow both -- a db arg that, if not given, defaults to *db* |
| 08:41 | tomoj | that doesn't sound too bad |
| 08:42 | chouser | noidi: hm, that's come up before. I have a vague memory of everyone reaching a consensus and then doing nothing about it. |
| 08:43 | noidi | :) |
| 08:43 | tomoj | -main is one way but requires compilation to classes :/ |
| 08:43 | noidi | there seems to be a bug in parsing the command line arguments... clojure seems to treat `'foo bar' baz` as `foo bar baz` |
| 08:44 | noidi | i.e. it doesn't understand command line arguments with spaces in them |
| 08:44 | chouser | on stackoverflow, someone's recommending *command-line-args*, but that doesn't seem quite right. |
| 08:45 | chouser | that'll be true for all libs if any command line args were given. |
| 08:47 | chouser | huh. it's quite a common question. |
| 08:55 | jonathanturner | I've googled around a bit, but I was wondering if clojure has a zip command. Something like (zip [1 2 3] [4 5 6]) over lazy sequences? |
| 08:55 | jonathanturner | I didn't know if the clojure one has a different name |
| 08:56 | chouser | ,(map vector [1 2 3] [4 5 6]) |
| 08:56 | clojurebot | ([1 4] [2 5] [3 6]) |
| 08:56 | chouser | so depending on what you want to do with it, you may be able to put the next operation right in the 'map' call. |
| 08:59 | fliebel | Can you define macros that do not use sexps? like define _some string_ to turn into (strong "some string") (whatever that might do)? |
| 09:00 | Chousuke | those are called reader macros, and no |
| 09:01 | jonathanturner | chouser: thanks, and that's lazy as well? |
| 09:01 | jonathanturner | I was thinking of the equivalent of a lazy seq that's pulling off zipped values |
| 09:02 | Chousuke | jonathanturner: map is lazy, so yes. :) |
| 09:02 | jonathanturner | Chousuke: cool, thanks |
| 09:02 | fliebel | Chousuke: would that be possible to implement… theoretically? It would be so cool to make your own data types and stuff... |
| 09:02 | noidi | fliebel, you could read the code in and modify the result before passing it to eval |
| 09:03 | Chousuke | fliebel: well, it wouldn't be too difficult to implement but Rich doesn't want to, at least for now |
| 09:04 | noidi | ,(eval (map #(if (= 1 %) 3 %) (read-string "(+ 1 2)"))) |
| 09:04 | clojurebot | DENIED |
| 09:04 | Chousuke | noidi: that's not quite as neat as a reader macro :P |
| 09:05 | fliebel | So, how many kinds of macros are there(that would be cool to have in Clojure)? |
| 09:05 | noidi | yeah, maybe not, I've never used common lisp so I don't know |
| 09:06 | Chousuke | fliebel: I think the primary reason for not having a user-extensible read-table is the namespacing issue |
| 09:06 | noidi | I don't like reader macros as an idea, but maybe that's just because I haven't used them |
| 09:06 | fliebel | I like anything that lets you fiddle with the language :D |
| 09:06 | Chousuke | noidi: clojure has many reader macros already. :) |
| 09:06 | Chousuke | noidi: they're just not user-definable. |
| 09:07 | noidi | yeah, I know |
| 09:07 | fliebel | Chousuke: where are they defined? |
| 09:07 | Chousuke | in the java source |
| 09:07 | Chousuke | LispReader.java |
| 09:07 | Chousuke | But hm, Common Lisp also has compiler macros |
| 09:07 | noidi | maybe I should learn a bit of CL and give them a try |
| 09:07 | Chousuke | I'm not sure what those do, though. |
| 09:08 | fliebel | What are compiler macros? I guess I asked about them a while back, without knowing they where compiler macros. |
| 09:08 | Chousuke | noidi: they're pretty useful sometimes but having them might lead to fragmentation (everyone has their own reader macros for things they think are important) and collision :/ |
| 09:08 | noidi | yeah, the collisions are the part that I'm worried about |
| 09:09 | Chousuke | If you can solve those issues though, maybe you could convince Rich to allow user access to the read table. I don't know :) |
| 09:10 | noidi | my ignorant gut-feeling is that you might as well go all the way and implement a proper parser instead of messing with Clojure's reader |
| 09:10 | noidi | if you want to use a language radically different from Clojure |
| 09:11 | cemerick | I'm guessing that a most if not all of use cases for userland reader macros will be addressed when things wind around to supporting java-in-parens, and similar |
| 09:11 | Chousuke | I've been thinking about having some reader pragma for enabling a user read-table, which would be specific to each loaded file or character stream |
| 09:11 | duper | Say for example I want to use Clojure on the .NET runtime instead of the JVM, what are the advantages it has over pre-existing LISPy .NET dialects, i.e. why would I want to use Clojure instead of something like IronScheme for example? |
| 09:12 | duper | (I'm coming from a Dr/Mz-Scheme and GNU guile background if that makes any difference) |
| 09:12 | Chousuke | so at the top of your source file you could say something like #reader:(use-read-table foo.bar/my-readtable) |
| 09:13 | fliebel | or like the ns definition at the top of some code, just allow users to specify their own read table. |
| 09:13 | Chousuke | the reader doesn't care about the ns declaration though. |
| 09:14 | Chousuke | but if readtable mods were made explicit in every source file, it might not be so bad to have them. |
| 09:15 | Chousuke | at least you'd always have a "warning" |
| 09:17 | stuartsierra | Once you start messing with the read table, though, you're basically implementing a parser. |
| 09:18 | fliebel | stuartsierra: A lot easier then writing your own language, don't you think? :D |
| 09:18 | stuartsierra | fliebel: maybe, but writing parsers really isn't that hard |
| 09:19 | chouser | duper: Clojure is unique from other lisps in it's first-class support of non-list collections (maps, sets), its seq abstraction, immutability, concurrency support, to name a few. |
| 09:19 | stuartsierra | And I've yet to see an example of user-defined reader macros that offers significant advantages over (function "string") |
| 09:21 | fliebel | stuartsierra: I think support for writing regexes or xml in your source is quite cool… sometimes… when used with caution… or not at all… |
| 09:21 | stuartsierra | :) |
| 09:23 | chouser | ok, guys. The first chunk of the (as yet untitled) book _fogus_ and I have been working on is about to go out for technical review. |
| 09:23 | cemerick | stuartsierra: we'd *love* to have a reader macro for our regex impl *shrug* |
| 09:23 | liebke | congrats chouser! |
| 09:24 | chouser | If any of you have the time to read the whole thing and respond over the course of a week or two (not sure what the deadline is exactly), I can forward your contact info to the Manning editor that's running the review process. |
| 09:24 | chouser | I guess send me a private message with your real name and email address if you're interested. |
| 09:25 | chouser | otherwise you can wait a couple more weeks, get the early-release PDF of the same content, and comment on the book forum which will be up by then. |
| 09:25 | chouser | liebke: thanks! |
| 09:26 | _fogus_ | liebke: Thanks! |
| 09:27 | liebke | hey _fogus_! So you still haven't settled the title issue yet? |
| 09:27 | aking | chouser: is it aimed at the beginner, intermediate or advanced user? |
| 09:27 | fliebel | Are you guys writing a Clojure book? |
| 09:27 | _fogus_ | liebke: not yet :( Reviewers would probably have a say in the matter |
| 09:28 | chouser | aking: intermediate or advanced. If you're an ambitious beginner it should be sufficient for you, but we're concentrating on really getting inside Clojure's head, thinking the way Clojure thinks about things. |
| 09:28 | chouser | fliebel: yes |
| 09:29 | shr3kst3r | sounds fun |
| 09:30 | aking | in that case, I'll submit my name :) |
| 09:31 | fliebel | chouser: I would appreciate an intermediate book, I'm tired of reading the same beginner stuff at every tutorial, but I'm still not capable of doing anything in Clojure. |
| 09:33 | noidi | chouser, sounds great! |
| 09:34 | noidi | imho there's a real need for a book that teaches OO programmers to think in a functional, lazy, immutable way |
| 09:35 | fliebel | noidi: +1 |
| 09:36 | chouser | Manning also has "Clojure in Action" coming, which I think is more of an intro book, though it also digs into several very practical real-world examples. I think. I haven't read it yet, but the TOC and first chapters are up. |
| 09:37 | rys | Agreed, something to stop the "hang on, what?" moments if you've never programmed functionally before would be cool |
| 09:39 | fliebel | chouser & _fogus_: Are you programmers writing a book or writers doing Clojure? I read the author of "Clojure in Action" say somewhere on the MEAP forum "This is the first time I'm writing a book", which makes me fear for the quality. |
| 09:41 | chouser | fliebel: we're programmers, but we each have blogs you can peruse to get a sense of how we write. Also, Manning has a great set of (mostly non-technical) editors who have been working to keep up the over-all quality of the content. |
| 09:42 | fliebel | chouser: ok, fine :) |
| 09:42 | esj | three cheers for more Clojure books ! Thanks chouser. |
| 09:42 | fliebel | Chouser: what is the address of your blog? |
| 09:43 | chouser | ok, thanks to everyone to volunteered, we'll pass your names along. |
| 09:44 | _fogus_ | Yes, thank you all. |
| 09:45 | chouser | fliebel: http://blog.n01se.net/?cat=14 |
| 09:45 | fliebel | thanks |
| 09:45 | chouser | fliebel: see also http://blog.fogus.me/ |
| 09:46 | ordnungswidrig | chouser: off topic but nice, your md-lvm-migration. Finally I see I'm not the only one trying such things :-) |
| 09:46 | chouser | ordnungswidrig: ah, yes ... I'm not the only author on that blog. But I endorse anything agriffis says about lvm :-) |
| 09:46 | _fogus_ | fliebel: You will ultimately be the judge if we can write or not, but I can say that we likely have the only Clojure book that quotes Dr. Seuss. |
| 09:48 | ordnungswidrig | chouser: oh, I see. anyway lvm is great fun. Some years ago I remote-repartitioned a root server from a 2-partition installation of red hat into a lvm based debian. The reboots were exciting moment. No remote hands to my rescue... |
| 09:49 | chouser | ordnungswidrig: I can relate to that kind of excitement. :-) |
| 09:50 | ordnungswidrig | chouser: btw twitter fails in hrefing your blog's urls. It stops at "?". How annoying |
| 09:51 | chouser | ordnungswidrig: Clicking the links should work, I think, even though the url doesn't look right. |
| 09:55 | ordnungswidrig | can lein do multi-project builds= |
| 09:56 | ordnungswidrig | s/=/?/ |
| 11:10 | patrkris | were there a discussion going on about the CACM-article "Software transactional memory: why is it only a research toy?" once? Can't seem to find it on Google Groups. |
| 11:12 | reify | '"""""""""""""" |
| 11:16 | saml | give me a tutorial for clojure. how to set up a project (or be leech aside java project) and the tutorial should teach frequently used emacs key bindings |
| 11:18 | ordnungswidrig | saml: emacs can tell you itself |
| 11:19 | saml | but it tries to tell me too much |
| 11:19 | saml | well i'll figure out and write a tutotirl |
| 11:20 | fliebel | chouser: On your blog you're writing about Clojure-in-Clojure. Is this really going to happen soon? And will there be an implementation on Parrot? |
| 11:22 | ordnungswidrig | saml: there are a lot of emacs tutorials around. |
| 11:24 | saml | it shouldn't take more than 10 minutes for the first timer to figure out buffer navigation. emacs fails |
| 11:24 | _fogus_ | patrkris: http://groups.google.com/group/clojure/browse_thread/thread/82497ffad880de2b/ (maybe) |
| 11:25 | saml | never mind. i fail. i found a toturial |
| 11:25 | patrkris | _fogus_: exactly that, thanks |
| 11:29 | slyrus | so, unless I'm missing something obvious, tools like lancet and leiningen are designed for building jars. what do folks use for loading .clj files into an already-running clojure instance? |
| 11:31 | ordnungswidrig | slyrus: swank/slime |
| 11:32 | ordnungswidrig | slyrus: that's what I'd use |
| 11:32 | slyrus | ordnungswidrig: well, yeah, of course, i'm using swank/slime :) |
| 11:35 | slyrus | ordnungswidrig: yes, a slime-asdf-like contrib that provided slime-load-system that worked with clojure projects would be nice, but it's the underlying asdf-like infrastructure that i'm having trouble finding, not the slime wrapper for such |
| 11:36 | the-kenny | Everyone is waiting for M-x swank-lein :) |
| 11:36 | slyrus | I guess i'm looking for the clojurey equivalent to (asdf:oos 'asdf:load-op ...) |
| 11:36 | the-kenny | slyrus: (require 'namespace) |
| 11:36 | the-kenny | (with the classpth set to the right files) |
| 11:40 | slyrus | thanks the-kenny |
| 11:43 | MikeDev | the-kenny |
| 11:43 | MikeDev | the-kenny: pm please? |
| 11:43 | the-kenny | MikeDev: Sure |
| 11:43 | the-kenny | Do it ;) |
| 11:45 | KirinDave1 | the-kenny: I wanted to thank you and technomancy for your help yesterday. People seemed to like the chat server. |
| 11:46 | KirinDave1 | I need to redditwhore it today, tho |
| 11:47 | the-kenny | KirinDave1: You're welcome :) I'm pleased when I can help |
| 11:48 | KirinDave1 | Although the people on news.ycomb were… kinda ridiculous. |
| 11:48 | KirinDave1 | Things like, "That's cool, but this scala version written with lift is wayyyy cooler I mean totally." |
| 11:48 | cemerick | KirinDave: live by the YC, die by the YC :-) |
| 11:48 | KirinDave1 | Or, "Sure, but the Node.js will scale to thousands of users. Can Java do THAT?!" |
| 11:49 | KirinDave1 | I think I am going to make a series out of it. |
| 11:49 | KirinDave1 | next up is netty integration |
| 11:50 | cemerick | KirinDave: using what framework, do you think (or, none at all)? |
| 11:50 | KirinDave1 | cemerick: ? |
| 11:50 | KirinDave1 | cemerick: I dunno. I have never been a java man. |
| 11:50 | KirinDave1 | cemerick: Any suggestions would be greatly appreciated. |
| 11:51 | cemerick | KirinDave1: there's a bunch of clojure frameworks that simplify jetty deployment (even beyond the already-simple java-native paths) |
| 11:52 | KirinDave1 | cemerick: Jetty is a web framework, right? |
| 11:52 | cemerick | jetty is a webapp server |
| 11:52 | KirinDave1 | cemerick: I think I am going to keep this as a raw socket application. |
| 11:52 | KirinDave1 | cemerick: As in the spirit of the original node.js submission. |
| 11:53 | KirinDave1 | cemerick: But adding major speed+scalability and maybe even SSL without too much code would be a pretty powerful demo. |
| 11:53 | KirinDave1 | Don't you agree? |
| 11:53 | cemerick | indeed |
| 11:54 | KirinDave1 | So netty provides non-blocking event-driven IO support. |
| 11:54 | KirinDave1 | So I don't need to have a thread per user. |
| 11:54 | cemerick | hah, I was assuming 'netty' was a mistyping of jetty |
| 11:54 | KirinDave1 | No, I think jetty is a punned name? :) |
| 11:54 | KirinDave1 | Or netty. |
| 11:55 | KirinDave1 | No idea which came first. |
| 11:55 | KirinDave1 | Last time I did java for seriously was in college in 2003. |
| 11:55 | cemerick | jetty has been around for a *long* time, but that doesn't mean anything, I suppose |
| 11:55 | KirinDave1 | Back in the Java 2 days |
| 11:55 | KirinDave1 | I was happy to discover java.nio. |
| 11:55 | KirinDave1 | I consider java.io to be kind of java.io.whoops-sorry-about-that |
| 11:56 | KirinDave1 | and it looks like (and sounds like) java.nio is more like java.nio.relax-i-got-dis |
| 11:56 | KirinDave1 | Which is good, because in college I was so effing screwed by java efficiency issues on a few of my projects. |
| 11:58 | ordnungswidrig | is there a json pretty-printer for clojure? |
| 11:59 | ordnungswidrig | oh there it is: (org.danlarkin.json/encode-to-str {:a :b :c :d} :indent 4) |
| 12:00 | MikeDev | Is there an HTML parser in clojure that doesn't require external libs? |
| 12:01 | ordnungswidrig | MikeDev: HTML or XHTML? |
| 12:01 | hiredman | use tagsoup |
| 12:01 | MikeDev | HTML |
| 12:01 | hiredman | I should say "no, use tagsoup" |
| 12:01 | replaca | ordnungswidrig: or there's a "more sophisticated" but slower version in clojure.contrib.pprint.examples.json |
| 12:02 | replaca | ordnungswidrig: the pp version works more like a lisp pretty printer in that it keeps things together on a line when it makes sense |
| 12:02 | replaca | so it's "prettier" :-) |
| 12:05 | replaca | KirinDave1: that chat server example is sweet. Thanks for posting about it. |
| 12:06 | MikeDev | clojure.contrib.tagsoup? |
| 12:07 | MikeDev | does tagsoup require external jar file? |
| 12:09 | replaca | MikeDev: yeah. just google and you'll find it |
| 12:10 | replaca | MikeDev: it's a super-common java library |
| 12:10 | replaca | MikeDev: not a contrib piece |
| 12:10 | MikeDev | http://home.ccil.org/~cowan/XML/tagsoup/tagsoup-1.2.jar ? |
| 12:10 | replaca | MikeDev: sounds right |
| 12:11 | MikeDev | o great, it has no closure docs |
| 12:13 | the-kenny | MikeDev: I think there isn't a clojure-interface to tagsoup.. just call the java-methods |
| 12:14 | patrkris | MikeDev: there is a pretty neat interface to tagsoup, it's called enlive |
| 12:14 | the-kenny | Oh.. forget what I've said |
| 12:14 | patrkris | MikeDev: http://clj-me.blogspot.com/2009/01/enlive-yet-another-html-templating.html gives a pretty good idea of what you can do with it |
| 12:15 | MikeDev | good because i didnt see any docs on it at it's webpage even in java |
| 12:15 | patrkris | it's pretty cool, since you can select HTML elements using CSS-style selector syntax |
| 12:16 | replaca | patrkris: although enlive is mostly aimed at templating (i.e. transforming html) as opposed to reading |
| 12:16 | replaca | replaca: a cool project would be a tagsoup -> clojure.zip interface |
| 12:17 | patrkris | replaca: you are probably correct, but the link I gave above shows how well it can be used for reading HTML (scraping in this case of websites) |
| 12:17 | replaca | patrkris: yeah, I think it woulld just be a simplification of stuff Christophe haas already done in enlive |
| 12:18 | patrkris | replaca: as far as I can see it's right there :) |
| 12:18 | cgrand | I started enlive as a templating system but I think there are more people using it for screenscraping than for templating |
| 12:18 | dnolen | patrkris: enlive is very good at scraping, probably the simplest use of enlive really. enlive also uses clojure.zip. and at 600 LOC can't get much simpler I think ;) |
| 12:19 | MikeDev | What I'm trying to accomplish is fetching the text out of header tags |
| 12:19 | cgrand | (-> your-url duck-streams/reader html-source (select [:h1]) text) |
| 12:20 | MikeDev | my regexp isnt good enough though I was fairly warned by people in #perl |
| 12:20 | MikeDev | so it's my fault |
| 12:20 | MikeDev | it was quicker at the time though |
| 12:20 | MikeDev | cgrand thx |
| 12:20 | patrkris | MikeDev: forget about regex in this case :) |
| 12:21 | ordnungswidrig | parsing HTML with regex is your way to hell |
| 12:21 | MikeDev | lesson learned |
| 12:21 | MikeDev | but this isnt production code |
| 12:22 | patrkris | i think tagsoup is really good at handling almost any html you can throw at it (as far as I've read) |
| 12:22 | cgrand | MikeDev: oops, (map text (-> your-url duck-streams/reader html-source (select [:h1]))) |
| 12:23 | MikeDev | just letting me know that duck-streams reader html-source is what I want is fine |
| 12:24 | MikeDev | but thnx very much |
| 12:26 | Licenser | aloa |
| 12:30 | replaca | cgrand: it doesn't get much simpler than that. very cool - I seem to use only the complex use case and forgot about the simple one :-) |
| 12:35 | MikeDev | is text text that I'm supposed to be matching? |
| 12:35 | MikeDev | it would have to be a function though? |
| 12:36 | patrkris | MikeDev: not sure if I understand, but text is a function to get the textual contents of a tag |
| 12:36 | MikeDev | doesnt seem to be defined for me |
| 12:36 | MikeDev | i've use'd duckstreams and reader is defined |
| 12:37 | patrkris | yes, but these are from clojure-contrib |
| 12:38 | patrkris | have you referred to enlive correctly (it's on you classpath, you have imported it by means of use/refer/require)? |
| 12:38 | MikeDev | o i need enlive |
| 12:38 | MikeDev | okay |
| 12:38 | MikeDev | i thought i only needed duckstreams |
| 12:38 | patrkris | that must have been a big surprise for you :D |
| 12:39 | patrkris | you need enlive to be able to traverse the HTML from the duck-stream reader |
| 12:41 | MikeDev | I like how github does "hardcore archiving action" |
| 12:42 | patrkris | yeah :) alternatively you could just get git and clone the repository... probably less hardcore |
| 12:42 | patrkris | in the archiving-sense of the word |
| 12:46 | MikeDev | does enlive depend on tagsoup? |
| 12:47 | patrkris | yes |
| 12:48 | MikeDev | my system doesnt have git |
| 12:51 | hiredman | just get tagsoup |
| 12:51 | saml | tofu soup is good |
| 12:52 | hiredman | clojurebot: zipsoup? |
| 12:52 | clojurebot | Huh? |
| 12:53 | hiredman | http://github.com/hiredman/odds-and-ends/blob/master/newegg.clj <-- use the zipsoup function from here, Chouser wrote but I can't find the original anymore |
| 12:55 | MikeDev | what do you "use" for tagsoup? |
| 12:56 | cgrand | MikeDev: have you leiningen? |
| 12:57 | MikeDev | huh? |
| 12:58 | cgrand | Leiningen is a build tool that manages dependencies for you. |
| 12:59 | MikeDev | I just dl'ed the jar and included it in my classpath |
| 12:59 | cgrand | Anyway if you click download on github for enlive you should get a zip which include tagsoup |
| 12:59 | the-kenny | leiningen is really cool :) |
| 12:59 | MikeDev | but having a hard time finding API docs |
| 12:59 | MikeDev | let alone cloure docs |
| 13:00 | MikeDev | it is SAX compliant though |
| 13:00 | MikeDev | so that's sweet |
| 13:00 | MikeDev | whatever that is |
| 13:01 | MikeDev | http://home.ccil.org/~cowan/XML/tagsoup/tagsoup.pdf maybe |
| 13:01 | MikeDev | boy was that well hidden |
| 13:02 | cgrand | MikeDev: so you have contrib, tagsoup and enlive on your classpath? |
| 13:02 | KirinDave1 | Ah, am I not the only person having problems with enlive? :) |
| 13:02 | MikeDev | just contrib and tagsoup |
| 13:03 | MikeDev | and contrib is use'd |
| 13:03 | MikeDev | tagsoup is a jar |
| 13:03 | MikeDev | use'd within clojure |
| 13:05 | cgrand | ok, then copy the function startparse-tagsoup that hiredman pointed you to http://github.com/hiredman/odds-and-ends/blob/master/newegg.clj |
| 13:05 | cgrand | then (clojure.xml/parse url startparse-tagsoup) should return a tree of your HTML resource |
| 13:07 | cgrand | KirinDave1: I'd like you know what problems you encountered with enlive |
| 13:08 | cgrand | MikeDev: http://clojars.org/repo/enlive/enlive/1.0.0-SNAPSHOT/enlive-1.0.0-20091121.091400-3.jar if you still want to use enlive |
| 13:09 | MikeDev | and what does zip-soup return? |
| 13:10 | MikeDev | That tree zipped? |
| 13:10 | cgrand | yup |
| 13:10 | MikeDev | what does that mean |
| 13:10 | MikeDev | here let me see |
| 13:12 | MikeDev | Returns a zipper for xml elements (as from xml/parse), |
| 13:12 | MikeDev | given a root element |
| 13:12 | MikeDev | I wish I knew what a zipper was |
| 13:12 | MikeDev | let me see |
| 13:13 | MikeDev | navigation, editing, |
| 13:13 | MikeDev | and enumeration. |
| 13:14 | MikeDev | I hate trees in functional langs |
| 13:15 | cgrand | which tags do you want to retrieve? |
| 13:16 | MikeDev | header tags |
| 13:17 | MikeDev | BTW, if this wasnt due this second and for a job, I wouldnt be this stupid |
| 13:17 | cgrand | h1..h4, nothing else, no special classes or any other rules (only header in this div or...) |
| 13:17 | cgrand | ? |
| 13:17 | MikeDev | correct |
| 13:18 | MikeDev | I just need the header tag's text |
| 13:19 | cgrand | (map enlive/text (-> your-url duck-streams/reader enlive/html-source (enlive/select [#{:h1 :h2 :h3 :h4}]))) |
| 13:19 | cgrand | using zippers directly won't be easier |
| 13:20 | MikeDev | do I have to 'use' anything for enlive? |
| 13:20 | cgrand | (use 'net.cgrand.enlive-html) ; once enlive is on you classpath |
| 13:22 | cgrand | or (require '[net.cgrand.enlive-html :as enlive]) to match my code snippet |
| 13:23 | MikeDev | net.cgrand.enlive-htm |
| 13:23 | MikeDev | java.lang.NoSuchMethodError: clojure.lang.Namespace.importClass(Ljava/lang/Class;)Ljava/lang/Class; (exercises.clj:0) |
| 13:23 | cgrand | net.cgrand.enlive-html with a L after htm |
| 13:23 | MikeDev | (ns Exercises |
| 13:23 | MikeDev | (:use compojure clojure.contrib.duck-streams net.cgrand.enlive-html) |
| 13:23 | MikeDev | ) |
| 13:24 | MikeDev | see Exercises |
| 13:24 | MikeDev | -l was copying error |
| 13:24 | cgrand | ah ok |
| 13:24 | MikeDev | CLASSPATH=Compojure/compojure.jar:/usr/local/jline/jline.jar:tagsoup-1.2.jar:enlive-1.0.0.jar |
| 13:26 | MikeDev | :( |
| 13:26 | cgrand | classpath hell... |
| 13:28 | KirinDave1 | cgrand: Actually I'm just being glib |
| 13:28 | KirinDave1 | cgrand: After you put in that zipper patch, it worked. |
| 13:28 | KirinDave1 | cgrand: Are you open to patches? Some simple failure cases don't report very informative errors. |
| 13:30 | MikeDev | java -cp clojure.jar clojure.lang.Repl |
| 13:30 | MikeDev | Should that work? |
| 13:30 | cgrand | KirinDave1: ah, ok it was that bug and yes I'm open to patches |
| 13:30 | MikeDev | Hello? |
| 13:31 | KirinDave1 | cgrand: Cool. |
| 13:31 | MikeDev | Why does that work in a shell script but not in cmd line |
| 13:31 | cgrand | MikeDev: try to put your whole classpath after -cp |
| 13:31 | MikeDev | maybe because I mispelled clojure.jar |
| 13:32 | cgrand | MikeDev: ok, let's try simply java -cp clojure.jar:enlive.jar clojure.lang.Repl |
| 13:33 | MikeDev | yeah that's what I was gonna don |
| 13:33 | cgrand | and then (use 'net.cgrand.enlive-html) |
| 13:33 | MikeDev | nope |
| 13:33 | MikeDev | same error |
| 13:35 | cgrand | and both jars are in your working directory? |
| 13:35 | MikeDev | O I C. this is your code |
| 13:35 | MikeDev | yes they are |
| 13:36 | cgrand | oops I forgot to include tagousp in the classpath -- did you include it? |
| 13:36 | MikeDev | nope, will try |
| 13:36 | MikeDev | that works |
| 13:37 | cgrand | phew :-) |
| 13:37 | MikeDev | wait |
| 13:37 | cgrand | :-( |
| 13:37 | MikeDev | 1 sec |
| 13:37 | MikeDev | nope |
| 13:37 | MikeDev | do you have another build? |
| 13:38 | cgrand | you used the one from clojar? |
| 13:38 | MikeDev | i used the one you had me dl |
| 13:38 | MikeDev | i dont have git on my machine |
| 13:39 | MikeDev | and dont know how to build |
| 13:39 | cgrand | the one I directly linked to? |
| 13:39 | MikeDev | at least in this stuff |
| 13:40 | MikeDev | i dl'ed: |
| 13:40 | cgrand | this one: http://clojars.org/repo/enlive/enlive/1.0.0-SNAPSHOT/enlive-1.0.0-20091121.091400-3.jar ? |
| 13:40 | MikeDev | yes |
| 13:40 | MikeDev | let me do it again |
| 13:40 | MikeDev | can I rename it? |
| 13:41 | cgrand | sure |
| 13:41 | MikeDev | Which version of tagsoup u using? |
| 13:41 | MikeDev | i've got 1.l2 |
| 13:41 | MikeDev | 1.2 excuse me |
| 13:42 | cgrand | 1.2 too |
| 13:49 | MikeDev | DO I need to use anything for tagsoup??? |
| 13:54 | MikeDev | So if you do first <zipper> what does that mean? |
| 13:54 | MikeDev | how are the nodes in a zipper flattened? |
| 13:54 | stuartsierra | 48 cores on a chip http://arstechnica.com/business/news/2009/12/intel-demos-48-core-cloud-datacenter-on-a-chip.ars |
| 13:55 | MikeDev | but I wanted 49 :( |
| 13:56 | MikeDev | do you have to 'use' anything for tagsoup? |
| 13:57 | MikeDev | it would appear not |
| 14:04 | MikeDev | Is there any way to flatten a zipper? Children? |
| 14:06 | hiredman | tree-seq |
| 14:06 | hiredman | if you look at newegg.clj it is basically doing what you want to do |
| 14:07 | MikeDev | I am indeed |
| 14:07 | hiredman | it is grabbing all the td elements from a page, filter out things that don't have their class attribute set to "totalPrice" and picking the last one |
| 14:15 | MikeDev | comp: |
| 14:15 | MikeDev | comp f g is f(g)? |
| 14:18 | hiredman | (comp f g) |
| 14:18 | _fogus_ | ,((comp #(+ 3 %) #(+ 1 1))) |
| 14:18 | clojurebot | 5 |
| 14:18 | MikeDev | yes is that f(g) |
| 14:18 | hiredman | f(g) in what? |
| 14:18 | stuartsierra | more like f o g |
| 14:18 | MikeDev | normal language |
| 14:19 | hiredman | in algol like syntax f(g) is the function f applied to the argument g |
| 14:19 | hiredman | which comp is not |
| 14:19 | MikeDev | f(g(x)) |
| 14:19 | hiredman | ,(doc comp) |
| 14:19 | clojurebot | "([f] [f g] [f g h] [f1 f2 f3 & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc." |
| 14:19 | MikeDev | yes it's either g(f) or f(g) |
| 14:21 | _fogus_ | ,(let [f #(println "f o" %) g #(str 'g)] ((comp f g))) |
| 14:21 | clojurebot | f o g |
| 14:21 | hiredman | f(g) is not function composition in any syntax that I know of |
| 14:22 | MikeDev | and why use first? |
| 14:22 | MikeDev | I have junk at the end |
| 14:22 | MikeDev | is it to get rid of that |
| 14:22 | MikeDev | an extra nil? |
| 14:23 | hiredman | "junk at the end" |
| 14:25 | _fogus_ | ,(let [f #(println "f o" %) g #(str 'g %) u #(str 'u %) s #(str 's)] ((comp f g u s))) |
| 14:25 | clojurebot | f o gus |
| 14:25 | _fogus_ | Couldn't resist |
| 14:25 | chouser | heh |
| 14:27 | MikeDev | Yeah, when I do zipsoup I get a vector of what is my html ad then a nil |
| 14:28 | MikeDev | Yeah, when I do zipsoup I get a vector of what is my html and then a nil |
| 14:28 | devlinsf | Why is there space after the o? |
| 14:28 | MikeDev | 2 element vector |
| 14:28 | MikeDev | first gets rid of the nil |
| 14:28 | MikeDev | (partial tree-seq map? (comp seq :content)) appears to strip out the style |
| 14:29 | _fogus_ | devlinsf: println does that |
| 14:29 | devlinsf | _fogus_: Hmm... gonna have to experiment with that |
| 14:29 | hiredman | MikeDev: it doesn't |
| 14:30 | devlinsf | _fogus_: Oh, i get it! I was assuming that (println "a" "b") is the same as (println (str "a" "b")) |
| 14:30 | devlinsf | ,(println "a" "b") |
| 14:30 | clojurebot | a b |
| 14:31 | devlinsf | ,(println (str "a" "b")) |
| 14:31 | clojurebot | ab |
| 14:31 | devlinsf | _fogus_: Hmmm... Interesting behavior |
| 14:31 | Chousuke | I think println is supposed to print a newline |
| 14:31 | Chousuke | but clojurebot filters them out |
| 14:32 | devlinsf | I don't have access to a normal REPL now. |
| 14:32 | clojurebot | a is t |
| 14:32 | chouser | MikeDev: the fact that a zip loc is a two-element vector is an implementation detail. use 'node' to get the node at a loc |
| 14:32 | devlinsf | Can sombody quick run it at a normal REPL? |
| 14:33 | MikeDev | or use first |
| 14:34 | rhickey | fine-grained locals clearing - core and contrib - all tests pass! |
| 14:34 | rhickey | anyone got any test cases for head-retention? (no big files required please) |
| 14:35 | devlinsf | Chousuke: println doesn't interpose a newline |
| 14:35 | Chousuke | hm |
| 14:36 | eno | user=> (println "f o" "gus") |
| 14:36 | eno | f o gus |
| 14:36 | eno | nil |
| 14:36 | devlinsf | Try this at you REPL (println "a" "\n" "b") |
| 14:36 | devlinsf | Only one newline |
| 14:38 | MikeDev | (partial tree-seq map? (comp seq :content)) appears to add :content in front of every subvector |
| 14:38 | scellus | btw, what is pmap supposed to do (in the master branch) if i have a lazy seq of lazy seqs. i don't have an example, but i had problems until i wrote doall to realize elements for pmap. otherwise nothing parallelized. |
| 14:38 | hiredman | MikeDev: it doesn't |
| 14:39 | stuartsierra | rhickey: I was working on this |
| 14:39 | lisppaste8 | stuartsierra pasted "Laziness examples" at http://paste.lisp.org/display/91726 |
| 14:40 | MikeDev | well it appears to add something |
| 14:41 | hiredman | MikeDev: it doesn't |
| 14:42 | devlinsf | Chousuke: I just checked the source of println. It eventually calls pr. (pr "a" "b") appears to be the same as (pr (str-join " " ["a" "b"])) |
| 14:42 | devlinsf | Chousuke: That is to say, it injects a space |
| 14:43 | MikeDev | (first (zip-soup url)) |
| 14:44 | MikeDev | ((partial tree-seq map? (comp seq :content)) (first (zip-soup url))) |
| 14:44 | MikeDev | It appears to create a list of every subtag? |
| 14:44 | hiredman | MikeDev: does it? |
| 14:45 | MikeDev | yes |
| 14:45 | chouser | MikeDev: the fact that a zip loc is a two-element vector is an implementation detail. use 'node' to get the node at a loc |
| 14:45 | MikeDev | I'm talking about (partial tree-seq map? (comp seq :content)) |
| 14:45 | chouser | or don't use zip-xml at all if all you want is the tree and not a zipper |
| 14:46 | MikeDev | I dont think it makes a big diff and I'd prefer to follow hiredman as closely as possible |
| 14:47 | MikeDev | (partial tree-seq map? (comp seq :content)) appears to take the html tree and make a list with every subtag |
| 14:47 | MikeDev | the first tag is repeated, then the body tag, etc. |
| 14:48 | rhickey | where'd stuartsierra go? all of his tests work now. Any others? |
| 14:48 | rhickey | preferably non-tail usage of seqs, in lets etc |
| 14:49 | rhickey | stuartsierra: all of your examples now work, any others? |
| 14:49 | MikeDev | which makes it easier to search for tags |
| 14:50 | MikeDev | becaue they're all in a sequence now |
| 14:50 | stuartsierra | rhickey: awesome; I will try to come up with some more |
| 14:50 | MikeDev | next, you search for td tags with |
| 14:50 | MikeDev | (partial filter #(= :td (:tag %))) |
| 14:50 | stuartsierra | cgrand or Chouser had an example with large arrays |
| 14:51 | MikeDev | Please tell me if I'm wrong |
| 14:51 | MikeDev | I'm trying to learn |
| 14:51 | rhickey | stuartsierra: that one runs indefinitely - how long is it supposed to take when it doesn't fail? |
| 14:52 | Licenser | Hmm wow network programming (at lest server side) is incredible easy with clojure o.O I'm impressed! |
| 14:52 | chouser | I had one that would run forever if it didn't break. |
| 14:53 | hiredman | MikeDev: yes |
| 14:53 | chouser | rhickey: ,(let [s (iterate #(java.util.Arrays/copyOf % (count %)) (int-array (range 1e7)))] [(first s) (last s)]) |
| 14:54 | chouser | rhickey: rather, (let [s (iterate #(java.util.Arrays/copyOf % (count %)) (int-array (range 1e5)))] [(first s) (last s)]) |
| 14:54 | MikeDev | could I replace (= :td (:tag %)) with some kind of regexp for maching any h1-h6 |
| 14:54 | MikeDev | tags |
| 14:54 | MikeDev | yes I'm wrong? |
| 14:54 | chouser | it's meant to fail fast, not necessarily demonstrate somethng that's supposed to work. |
| 14:54 | rhickey | chouser: yeah, ran that, runs indefinitely |
| 14:55 | chouser | ok |
| 14:55 | cgrand | MikeDev: (#{:h1 :h2 :h3 :h4 :h5 :h6} (:tag %)) |
| 14:55 | rhickey | so, this is full liveness tracking for all locals |
| 14:55 | chouser | wait, really? I assumed that would be impossible |
| 14:55 | stuartsierra | me too |
| 14:55 | hiredman | MikeDev: you can replace it with any function that will return a logical true value for things you want to keep |
| 14:56 | rhickey | with liveness tracking, s is cleared before last is called |
| 14:56 | chouser | wow! |
| 14:56 | rhickey | yeah, Clojure's biggest incidental complexity now gone |
| 14:57 | rhickey | pending lots of testing, this was a very complex change |
| 14:57 | stuartsierra | awesome, amazing, unbelievable! |
| 14:57 | chouser | I can only imagine. |
| 14:57 | rhickey | I'd just like to run a few more tests if anyone's got any failure cases, before I push |
| 14:57 | chouser | at this rate we're never going to need clojure-in-clojure |
| 14:58 | cgrand | liveness tracking? awesome! |
| 14:58 | rhickey | chouser: I really wanted to wait, but too many people are tripping over it, and worse, designing clunky non-workarounds |
| 14:58 | stuartsierra | yes |
| 14:58 | ericthorsen | rhickey: is this change in the 'new' branch as well? |
| 14:58 | rhickey | so now, if you aren't using it any more, you aren't holding it |
| 14:58 | rhickey | ericthorsen: will be in a few minutes |
| 14:58 | rhickey | you can use large seqs in let etc |
| 14:59 | rhickey | no more limit to tail call clearing |
| 14:59 | rhickey | just one extremely painful lost weekend :) |
| 15:00 | stuartsierra | This is really going to make sequences much more powerful, instead of a clever trick. |
| 15:00 | rhickey | there must be some more examples in the group... |
| 15:00 | MikeDev | {}'s are sets? |
| 15:00 | stuartsierra | The most common case is reading a large file line-by-line. |
| 15:01 | stuartsierra | rhickey: I assume this will also work with iterator-seq? |
| 15:01 | rhickey | stuartsierra: it is independent of the type of seq |
| 15:01 | LauJensen | liveness tracking O_o? :) Does that incur some kind of overhead or how is that implemented? |
| 15:01 | MikeDev | So the last thing I need is to filter based on the text'edness of the content |
| 15:02 | rhickey | LauJensen: basically the last use of a local clears it (before the use) |
| 15:02 | rhickey | wherever that use occurs, not limited to tail call arg |
| 15:03 | rhickey | data structure inits, callis in the middle of do, lets, etc |
| 15:03 | LauJensen | Wow, cant wait to give that a test-drive |
| 15:03 | chouser | MikeDev: {} make a map, #{} makes a set |
| 15:03 | stuartsierra | rhickey: Is this pushed yet? I want to test with my hadoop wrapper lib. |
| 15:03 | rhickey | so, now based upon use, not merely local bound in scope |
| 15:03 | chouser | MikeDev: rather, {} is a map, #{} is a set |
| 15:04 | rhickey | I guess pushing it is the best way to get it tested... |
| 15:04 | stuartsierra | :) |
| 15:04 | Chousuke | yay |
| 15:04 | stuartsierra | Will this make it into 1.1 then? |
| 15:05 | chouser | heh |
| 15:05 | Chousuke | This is a big usability improvement for Clojure. It was sometimes pretty difficult to tell whether you were holding onto something or not :/ |
| 15:05 | stuartsierra | And all because of a bug in the JVM. :) |
| 15:06 | MikeDev | Would it be worng once I had a handful of headers to use regexps on the contents? |
| 15:06 | LauJensen | ~regex |
| 15:06 | clojurebot | Sometimes people have a problem, and decide to solve it with regular expressions. Now they have two problems. |
| 15:06 | chouser | this is true. |
| 15:07 | rhickey | stuartsierra: not in 1.1, no |
| 15:07 | cp2 | sounds neat |
| 15:07 | stuartsierra | chouser: Of every technology ever invented. |
| 15:07 | chouser | also true is that if you have some text you need to process, regex is frequently the best solution available. |
| 15:07 | chouser | stuartsierra: yessir |
| 15:08 | LauJensen | Whats the name of that functional text parser in Clojure, which gives an alternative to regex? |
| 15:08 | stuartsierra | rhickey: I guess that's reasonable, given the newness. |
| 15:08 | MikeDev | Okay so how should I approach finding only textful headers given that I have all of them in a map? |
| 15:08 | hiredman | LauJensen: fnparse? |
| 15:08 | MikeDev | A list of maps |
| 15:08 | LauJensen | hiredman: Thats the one |
| 15:09 | rhickey | stuartsierra: it's also a huge compiler change, and there are already a lot of huge compiler changes in new - I dread merging them |
| 15:09 | stuartsierra | rhickey: fair enough |
| 15:09 | rhickey | ok, it's up |
| 15:10 | LauJensen | MikeDev: Are you looking for items that are solely alpha-numerical ? |
| 15:10 | MikeDev | Pretty much |
| 15:10 | MikeDev | certainly no subtags |
| 15:12 | MikeDev | this is only an exercise |
| 15:13 | stuartsierra | rhickey: great, is it on a particular branch? |
| 15:13 | rhickey | new |
| 15:13 | stuartsierra | ok |
| 15:13 | rhickey | http://github.com/richhickey/clojure/commit/76c8f45293987b80e3599535dd86482e1180661d |
| 15:14 | MikeDev | I might do "[A-Za-z0-9 .-]" |
| 15:14 | MikeDev | I might do "[A-Za-z0-9 .-]+" |
| 15:14 | _fogus_ | That's a lot of green |
| 15:16 | rhickey | _fogus_: heh, I was just going to say - it doesn't look like much now, the hard part being figuring out how to enable the feature with minimal change |
| 15:19 | rhickey | we need to get 1.1 out so we can get 1.2 out |
| 15:19 | _fogus_ | rhickey: I take that back, relative to the total file size it's actually *not* a lot of green. Github just highlights the greeness in the commit view. |
| 15:21 | stuartsierra | rhickey: yes yes |
| 15:21 | MikeDev | What is #(= :td (:tag %)) |
| 15:21 | rhickey | feedback welcome on the locals clearing in new - be on the lookout for 2 things - 1)bad - premature clearing (set to null before last use), most likely will show up as NPE, 2)insufficient clearing - local stays around |
| 15:21 | hiredman | MikeDev: it is a function |
| 15:22 | MikeDev | what arg does it expect? |
| 15:23 | MikeDev | It's comparing its arg to what tag maps to to see if it's equal to td |
| 15:23 | MikeDev | but I dont understand how it doesn that |
| 15:24 | LauJensen | MikeDev: Do you know how to do the basic selecting with Enlive? |
| 15:24 | MikeDev | cgrand and I couldnt get enlive working for me |
| 15:24 | devlinsf | rhickey: if I'm reading assembla right, ticket 218 is the only thing holding up RC1 (or Beta 1, whatever you want to call it) |
| 15:25 | LauJensen | MikeDev: 'Cgrand .... couldnt get it working' is not a possible scenario |
| 15:25 | MikeDev | (map text (-> your-url duck-streams/reader html-source (select [:h1]))) |
| 15:25 | dnolen | I missed the early part of the locals clearing discussion, is not have to care about holding onto the head of a lazy data structure the main benefit or are there others? |
| 15:25 | rhickey | devlinsf: 1.1 is not waiting for patches, but all the peripheral stuff surrounding a release |
| 15:25 | MikeDev | What are you talking about |
| 15:25 | devlinsf | rhickey: docs, tests & stuff? |
| 15:26 | LauJensen | MikeDev: Enlive requires 2 things, enlive.jar and tagsoup.jar, put those on your class path, see in (System/getProperty "java.class.path") that they are there, and Enlive will work |
| 15:26 | MikeDev | i did that and got |
| 15:26 | drewr | looks like locals clearing breaks something in the socket code with swank-clojure |
| 15:27 | drewr | trying to isolate |
| 15:27 | hiredman | MikeDev: so the zip-soup function returns the html structure as a set of nested maps and vectors |
| 15:27 | MikeDev | java.lang.NoSuchMethodError: clojure.lang.Namespace.importClass(Ljava/lang/Class;)Ljava/lang/Class; |
| 15:27 | drewr | getting an NPE in a macro that I need to expand |
| 15:27 | hiredman | tree-seq flattens it out |
| 15:27 | rhickey | devlinsf: http://groups.google.com/group/clojure-dev/browse_frm/thread/be3f0a7c26ee2fd6 |
| 15:28 | hiredman | MikeDev: import is for java classes only |
| 15:28 | rhickey | dnolen: it is primarily a benefit for use of lazy seqs, yes |
| 15:28 | dnolen | i note that the locals clearing change breaks swank-clojure: java.lang.Exception: No such var: swank.swank/ignore-protocol-version (NO_SOURCE_FILE:3) |
| 15:28 | MikeDev | so |
| 15:28 | MikeDev | I dont use import |
| 15:28 | MikeDev | enlive must |
| 15:28 | devlinsf | rhickey: yeah, I'm in that thread. |
| 15:28 | dnolen | rhickey: fantastic |
| 15:28 | devlinsf | rhickey: So can I assume master is stable, and I can start testing that? |
| 15:28 | hiredman | MikeDev: I hear enlive depends on tagsoup |
| 15:28 | LauJensen | MikeDev: Try putting all 3 jars in the same directory and run java -cp clojure.jar:enlive.jar:tagsoup.jar clojure.main and then type import enlive |
| 15:29 | hiredman | LauJensen: import? |
| 15:29 | MikeDev | use |
| 15:29 | LauJensen | use, require, something :) |
| 15:29 | MikeDev | he told me to use |
| 15:30 | LauJensen | then use |
| 15:30 | hiredman | anyway, when I did newegg.clj I was thinking of using enlive or zip-filter, but by the time chouser answered the question I asked here, I had the tree-seq version working :P |
| 15:30 | LauJensen | If you do that, it will work, or you're on Windows |
| 15:30 | MikeDev | <cgrand> (use 'net.cgrand.enlive-html) ; once enlive is on you classpath |
| 15:30 | LauJensen | yes, thats correct |
| 15:30 | MikeDev | that's what causes the error above |
| 15:31 | hiredman | odd |
| 15:31 | MikeDev | he left |
| 15:31 | hiredman | where did you get the enlive jar from? |
| 15:31 | MikeDev | cgrand ent me a link |
| 15:31 | MikeDev | 1 sec |
| 15:31 | hiredman | what version of clojure are you using? |
| 15:32 | MikeDev | http://clojars.org/repo/enlive/enlive/1.0.0-SNAPSHOT/enlive-1.0.0-20091121.091400-3.jar |
| 15:32 | MikeDev | 1.0.0 |
| 15:33 | MikeDev | closure v1.0.0 |
| 15:33 | hiredman | j |
| 15:33 | MikeDev | is there something to print on the repl to doublecheck |
| 15:34 | hiredman | that enlive jar might not work with clojure 1.0 |
| 15:34 | hiredman | anyway |
| 15:34 | rhickey | devlinsf: yes, please use master |
| 15:34 | MikeDev | which should I try? |
| 15:34 | hiredman | you were 70 to 80 percent done with tree-seq |
| 15:34 | MikeDev | yeah |
| 15:35 | hiredman | before random people popped in and started suggesting you do other things |
| 15:35 | MikeDev | and u said I should do things that way |
| 15:35 | MikeDev | and u r smart |
| 15:35 | hiredman | #() is an anonymous function |
| 15:35 | MikeDev | plus it helps me learn |
| 15:36 | hiredman | #(a b %) ~= (fn [x] (a b x)) |
| 15:36 | MikeDev | well basically if I'm not using regexps, what do I use on the content of my headers? |
| 15:37 | jonase_ | I pulled the 'new' branch and now I get "java.lang.IllegalStateException: Var null/null is unbound. (matrix.clj:37)" when trying to load the code in http://gist.github.com/234535 |
| 15:37 | hiredman | MikeDev: you can use regexs or whatever you want |
| 15:37 | MikeDev | they told me not to |
| 15:37 | hiredman | MikeDev: you understand how filter works? |
| 15:37 | twbray | What's the idiomatic way to turn {:a 10 :b 20 } into {:a 11 :b 21}, i.e. do a map on a map and get a map? |
| 15:37 | hiredman | MikeDev: I imagine they were not paying attention and assumed you were parsing the entire html document with regexs |
| 15:37 | MikeDev | ok |
| 15:38 | MikeDev | i did clearly say I had the headers |
| 15:38 | MikeDev | but no complaints |
| 15:38 | lpetit | twbray: it depends, what do you want to do ? |
| 15:38 | lpetit | ,(doc merge-with) |
| 15:38 | clojurebot | "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)." |
| 15:38 | lpetit | whoops |
| 15:38 | MikeDev | filter takes a function, applies it to each element and returns those elements for which the functions returned true |
| 15:38 | Licenser | uch |
| 15:38 | hiredman | ,(let [m {:a 10 :b 20 }] (reduce #(update-in %1 [%2] inc) m (keys m)) |
| 15:38 | clojurebot | EOF while reading |
| 15:38 | hiredman | ,(let [m {:a 10 :b 20 }] (reduce #(update-in %1 [%2] inc) m (keys m))) |
| 15:38 | clojurebot | {:a 11, :b 21} |
| 15:39 | Chousuke | twbray: (into {} (map (fn [[k v]] [k (inc v)]) themap) will work |
| 15:39 | twbray | lpetit: I have a map. I want to produce a new map with the same keys and values produced by running a func over the input values |
| 15:39 | lpetit | twbray: you have the answer above :) |
| 15:39 | clojurebot | You will not become skynet |
| 15:39 | twbray | Chousuke: Thanks |
| 15:39 | hiredman | MikeDev: so you can write any function you want |
| 15:39 | lpetit | ,(doc map-vals) |
| 15:39 | clojurebot | Pardon? |
| 15:39 | MikeDev | yes |
| 15:40 | hiredman | I would first recommend filtering for headings, which I think chouser or Chousuke pasted a function for |
| 15:40 | MikeDev | that's what I'm doing I think |
| 15:40 | rhickey | lpetit: one question about a map-vals, should ht efn take the val or key + val, or [key val]? |
| 15:40 | MikeDev | here: |
| 15:40 | MikeDev | ((partial filter #(#{:h1 :h2 :h3 :h4 :h5 :h6} (:tag %))) ((partial tree-seq map? (comp seq :content)) (first (zip-soup URLArg)))) |
| 15:41 | MikeDev | that gets me the headers I want |
| 15:41 | hiredman | :( |
| 15:41 | hiredman | I guess |
| 15:41 | Chousuke | urgh, too much point-freedom |
| 15:42 | hiredman | so then you need to filter again based on whatever regex or what have you |
| 15:42 | rhickey | was anyone able to isolate the swank problem with fine-grained locals clearing? |
| 15:42 | MikeDev | ok |
| 15:42 | MikeDev | i was trying that |
| 15:43 | MikeDev | (partial filter #(re-find #"^[A-Za-z0-9 .-]+$" (:tag %))) |
| 15:43 | MikeDev | nope |
| 15:43 | MikeDev | oh, hell i mean content |
| 15:45 | lpetit | rhickey: is it a serious question, or was it asked to demonstrate that it's not possible to provide such a function ? |
| 15:45 | MikeDev | netsplits!!! |
| 15:46 | MikeDev | welcome back |
| 15:46 | MikeDev | java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.CharSequence |
| 15:46 | rhickey | lpetit: yes, serious, not a difficult function, just tricky to spec a useful version. Mapping inc across vals isn't too hard without it, but there aren't many k+v - taking functions around yet. |
| 15:46 | Chousuke | there's nothing wrong with using parametrised functions, you know. |
| 15:46 | Chousuke | why are you even using partials there? |
| 15:46 | hiredman | Chousuke: he doesn't know clojure so he is just copy and pasting me code around |
| 15:46 | rhickey | lpetit: that's what's held up something like map-vals |
| 15:46 | MikeDev | Chousuke, because hiredman and jesus wanted it that way |
| 15:47 | Chousuke | isn't that just (filter (comp :tag #{:h1 ...}) (tree-seq map? (comp seq :content) (first (zip-soup URLArg)))) |
| 15:47 | Chousuke | hiredman: you have a bad influence on people :( |
| 15:47 | hiredman | MikeDev: I didn't, I showed you an example of code that does something similar to what you want |
| 15:47 | hiredman | and you are cargo culting it |
| 15:47 | MikeDev | cargo culting: I like it |
| 15:48 | hiredman | http://en.wikipedia.org/wiki/Cargo_cult_programming |
| 15:48 | MikeDev | is that a real phrase? |
| 15:48 | Chousuke | hm, wait. args in comp are the wrong way around |
| 15:48 | MikeDev | I'd have said black boxing |
| 15:48 | Chousuke | try to write code that you understand yourself :) |
| 15:48 | hiredman | or at least try to understand the code you write |
| 15:49 | lpetit | rhickey: here are my own (freshly translated from french for your pleasure :-) versions I used at work : http://paste.lisp.org/display/91728 |
| 15:49 | MikeDev | i will when it's not due 5 hours ago |
| 15:49 | chouser | rhickey: have you thought at all about compiler-macros, or something like them? |
| 15:50 | hiredman | MikeDev: well, maybe it is for the best |
| 15:50 | rhickey | chouser: not too much |
| 15:50 | lpetit | rhickey: needs were value (not key+val). |
| 15:50 | rhickey | chouser: I'd much rather have symbol-macrolet |
| 15:52 | devlinsf | lpetit: I've been talking about this on the dev list for a while |
| 15:52 | stuartsierra | rhickey: someone did symbol-macrolet in contrib http://richhickey.github.com/clojure-contrib/macro-utils-api.html |
| 15:52 | devlinsf | http://groups.google.com/group/clojure-dev/browse_thread/thread/9a518c853bfbba8b |
| 15:52 | chouser | a macro that expands to something that includes a symbol-macrolet would be pretty powerful. |
| 15:52 | devlinsf | lpetit: I'm partial to a visitor solution now |
| 15:53 | lpetit | devlinsf: ? |
| 15:53 | devlinsf | lpetit: You'll see it at the end of the thread |
| 15:53 | thehcdreamer | Anyone know how I can uninstall gitosis from my server? Google isn't helping me |
| 15:53 | thehcdreamer | sorry wrong channel |
| 15:53 | chouser | devlinsf: I've read your latest proposal at least once -- sorry I haven't responded. My gut reaction is much more positive now. |
| 15:54 | devlinsf | chouser: Life happens |
| 15:54 | dnolen | rhickey: not sure if this helps, http://gist.github.com/251096, this is the source of the error and the related fns |
| 15:54 | devlinsf | chouser: Good to hear it |
| 15:57 | dnolen | rhickey: also this is the macroexpansion for the offending function, http://gist.github.com/251100 |
| 15:58 | MikeDev | hiredman, but you dont understand the business implications. Clojure is the sort of thing where I bet it's really hard to find someone who knows it so they're actually hiring newbies. To get a PHP job you need 5 years experience plus high volume experience the latter of which I'll never get |
| 15:58 | MikeDev | Plus when you do get a PHP job, you have a PHP job and why would you want that |
| 15:59 | Chousuke | :) |
| 15:59 | hiredman | MikeDev: sure, but you plainly don't know any clojure |
| 15:59 | MikeDev | I've been at it for 3 days. I can learn |
| 15:59 | Chousuke | Do you have the book? |
| 15:59 | MikeDev | not yet |
| 16:00 | arohner | lpetit: those functions look pretty similar to mine |
| 16:00 | lpetit | devlinsf: sorry, but I don't know exactly why, but when I read "visitor pattern", some warning flashes in the back of my head. Must read your (rather comprehensive!) post carefully, not sure I'll be able to do so right now. |
| 16:00 | MikeDev | If I get the job I will buy the soft and hard copy |
| 16:01 | rhickey | dnolen: thanks, I'll see what I can make of that |
| 16:01 | devlinsf | lpetit: No problem. Feel free to post or email any questions |
| 16:01 | lpetit | devlinsf: sure |
| 16:02 | Chousuke | MikeDev: anyway, try to avoid point-free style (the partials and comps) in the beginning |
| 16:02 | MikeDev | I just need to get this job. They'll help me learn it if I can just get my foot in the door |
| 16:02 | Chousuke | It's so easy to make code look magical when you omit the explicit parameters :/ |
| 16:03 | Chousuke | what's your current problem? |
| 16:03 | MikeDev | a couple of exercises. i've given up on the second |
| 16:03 | MikeDev | right now the problem is a regexp for the contents |
| 16:03 | MikeDev | of the headers |
| 16:05 | lpetit | arhoner: I guess lots of uses of maps are for easily accessing their values. And then, either the keys are not relevant for functions having to process the values (e.g. keys are at a different level of abstraction than the values, e.g. keys are technical identifiers, values are business meaningful), either the keys have some meaning at the same level of abstraction than the values, and then... |
| 16:06 | lpetit | ...chances are that the value already embeds the key value somewhere inside it. But that's just a quick generalization from the kind of problems I'm faced with, so maybe it's not true at all for most of the cases (I don't say "the general case", I don't think there exists a general case for such generic functions ?) |
| 16:06 | Chousuke | MikeDev: doesn't sound too difficult |
| 16:06 | MikeDev | and eventually I'd like to turn the list of maps into a list of 2ple vectors |
| 16:06 | MikeDev | ([headername headercontent] ...) |
| 16:06 | Chousuke | MikeDev: just keep in mind the structure of the data you're working with, and then filter and process it one step at a time. |
| 16:07 | MikeDev | when I think back to learning ML, this was not how I did it |
| 16:07 | arohner | lpetit: I don't need to go that far for an explaination. Often, I just need to transform a map, like |
| 16:07 | arohner | (map-keys keyword coll) |
| 16:08 | lpetit | arohner: I was testing my arguments on you, before explicitly directing them to Rich :-) |
| 16:08 | MikeDev | at least I can read what most stuff is now |
| 16:08 | MikeDev | types |
| 16:09 | Chousuke | MikeDev: well, say you have a list of strings and you want a list of all strings starting with "s", uppercased. The easiest way to do that is of course is to filter first, yielding another seq of strings, and then uppercase those |
| 16:09 | rhickey | dnolen: did swank-clojure work with the prior checkin of new branch? |
| 16:09 | dnolen | rhickey: yes, I did a git reset --hard HEAD^ just to make sure |
| 16:09 | MikeDev | U have all been very patient, ty |
| 16:10 | Chousuke | MikeDev: it really doesn't get much more complicated, if the problem really is just data filtering |
| 16:10 | Chousuke | MikeDev: and thanks to lazy seqs, you won't actually be going through all the data multiple times. |
| 16:12 | Chousuke | MikeDev: and remember, even maps can be treated as seqs of [key value] pairs |
| 16:12 | MikeDev | then maybe I wont have to convert that then |
| 16:13 | MikeDev | wait, yes I will |
| 16:13 | MikeDev | cuz I want [headername headertext] not [:tag h1, :content "blah"] |
| 16:14 | MikeDev | excuse me, {:tag h1, :content "blah"} |
| 16:14 | Chousuke | you have a seq of maps {:tag "h1", :content "blah"} or something? |
| 16:14 | Chousuke | and you want to select all "hN" tags, right? |
| 16:14 | MikeDev | ({:tag :h1, :attrs {:style "width: 200px; margin: 20px auto; text-align: center"}, :content ["Results Table"]} ...) |
| 16:14 | arohner | do deftypes respect *print-length* yet? I seem to be getting stackoverflows when printing a circular datastructure of deftypes |
| 16:15 | MikeDev | list of maps |
| 16:15 | MikeDev | I want to get all the tags whose content is text |
| 16:15 | hiredman | Chousuke: the selecting all the hN tags should already be taken care of |
| 16:15 | MikeDev | doesnt have subtags |
| 16:15 | Chousuke | hmm, right. |
| 16:16 | Chousuke | that's why you need the tree-seq |
| 16:16 | MikeDev | yes, it flattens |
| 16:16 | MikeDev | but some of the header tags could have ,a. tags |
| 16:16 | MikeDev | <a> tags |
| 16:16 | MikeDev | Or more likely with bad html, god knows what |
| 16:17 | Chousuke | well, filter those out after you've selected the header tags? |
| 16:17 | MikeDev | I dont wanna have to parse that crap further |
| 16:17 | MikeDev | so now that I have the header tags, I just wanna dump everything without nice text in it |
| 16:18 | Chousuke | that's another filter then, right? |
| 16:18 | MikeDev | yep |
| 16:18 | MikeDev | but this one I cant copy from hiredman |
| 16:18 | Chousuke | hmm. can't tagsoup sanitise html? |
| 16:19 | Chousuke | maybe it could remove any malformed crap for you. |
| 16:19 | MikeDev | according to it's site, htmltidy is what you'd want for that |
| 16:19 | Chousuke | ah. okay. |
| 16:19 | MikeDev | but this isnt production |
| 16:19 | Chousuke | well, maybe you can just use a regexp then :/ |
| 16:19 | MikeDev | this is just for an exercise |
| 16:20 | MikeDev | but I dont want it to bomb on certain sites like it was before |
| 16:20 | MikeDev | when I did this: |
| 16:20 | MikeDev | "<(h[1-6])>(?:<.*?>)*(.*?)(?:</.*?>)*</h[1-6]> |
| 16:20 | MikeDev | thought that was an attempt to drill down into tags |
| 16:21 | MikeDev | the worst thing about that was, it allowed <h1></h2> |
| 16:21 | Chousuke | maybe select h-tags without flattening first and then filter out any tag content from them? |
| 16:21 | MikeDev | i dont like that |
| 16:21 | Chousuke | update-in is pretty good for transforming maps |
| 16:22 | MikeDev | well it doesn't flatten recursively |
| 16:22 | MikeDev | it does a search and makes copies into a list |
| 16:22 | Chousuke | hmm :/ |
| 16:22 | MikeDev | think of it as any header subtree is added to a list |
| 16:24 | MikeDev | actually I suppose if someone did <h1><h2>srgwrg</h2></h1> i'd get the h2 |
| 16:24 | MikeDev | the list would be 2 elements, the h1 tag and the h2 tag |
| 16:25 | arohner | rhickey: I seem to have a bug, where I get a stack overflow if I try to print a deftype that contains a cycle with other deftypes. should I file a bug? |
| 16:26 | MikeDev | can you use - ' " in clojure regexps |
| 16:26 | arohner | actually, it's worse than just printing, because using slime to reload the file can also cause the stack overflow, if the last expression returns the type with a cycle |
| 16:27 | MikeDev | with escapes \? |
| 16:27 | MikeDev | dont think it's letting me |
| 16:28 | rhickey | potential fix for swank-clojure + fine-grained locals clearing up in new branch: http://github.com/richhickey/clojure/commit/6c0c37e048f49ee5cd3afa79ce461abbc6a0c367 |
| 16:28 | rhickey | arohner: yes, thanks |
| 16:29 | chouser | MikeDev: you can use \" in a literal regex to match " ... no need to escape ' |
| 16:29 | technomancy | rhickey: I haven't gotten a chance to give the new branch much attention; does it necessitate changes to swank-clojure? |
| 16:29 | chouser | ,#"'" |
| 16:29 | clojurebot | #"'" |
| 16:29 | arohner | rhickey: should I work on a patch? I'm effectively blocked. the fix looks simple, just add checks for *print-level* to print-deftype |
| 16:30 | rhickey | technomancy: hopefully not, I pushed a change today that broke swank, just pushed a fix - need someone to try it |
| 16:30 | rhickey | arohner: sure |
| 16:32 | MikeDev | how about POSIX character classes like [:alpha:] |
| 16:32 | chouser | MikeDev: everything Java regex supports. |
| 16:33 | chouser | MikeDev: http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html |
| 16:34 | arohner | rhickey: can you please promote me to member on assembla? |
| 16:36 | technomancy | rhickey: trying new+swank now. anything specific I need to do to trigger the potential problem or is it pretty obvious? |
| 16:37 | chouser | (deftype Foo [x]) fails with java.lang.IllegalStateException: Var null/null is unbound. for me, latest 'new' |
| 16:37 | chouser | anybody else seeing that? |
| 16:38 | rhickey | technomancy: got me, seems like it fell right down before |
| 16:39 | rhickey | chouser: yes, looking at it now |
| 16:40 | MikeDev | This seems to be serviceable: (re-seq #"<(h[1-6])>([^<>]+?)</h[1-6]>" HTMLArg) |
| 16:42 | ataggart | was the change from ^ to #^ just for consistency? |
| 16:43 | MikeDev | who me? |
| 16:44 | MikeDev | AFAIK #"blah" is a regexp pattern |
| 16:44 | chouser | ataggart: #^ hasn't changed. ^ is going away because (meta ...) is already there, ^ is not the inverse of #^, and ^ is wanted for other things |
| 16:44 | ataggart | ah, no I meant the change to the reader. https://www.assembla.com/spaces/clojure/tickets/215-Deprecate-^-reader-macro |
| 16:45 | ataggart | k |
| 16:46 | rhickey | chouser: fixed |
| 16:46 | technomancy | rhickey: hrm; looks like the example dnolen gave doesn't compile regardless of the new branch or swank version. =\ |
| 16:48 | technomancy | I'll try again if I see him come back online |
| 16:50 | rhickey | technomancy: this was is first report: i note that the locals clearing change breaks swank-clojure: java.lang.Exception: No such var: swank.swank/ignore-protocol-version (NO_SOURCE_FILE:3) |
| 16:50 | chouser | rhickey: great, thanks. |
| 16:51 | chouser | deftype objects seem to respect *print-level* for me |
| 16:53 | chouser | (deftype Foo [x]) (nth (iterate Foo 1) 20) |
| 16:53 | chouser | innermost prints as #:Foo{:x #:Foo#} if capped by *print-level* |
| 16:55 | rhickey | chouser: maybe the problem was mutually recursive structures? |
| 16:56 | arohner | my structure is mutually recursive. trying to reproduce with a smaller example now |
| 16:58 | chouser | not sure what you mean. this also works (nth (iterate (fn [x] #{(Foo x)}) 1) 20) |
| 16:59 | arohner | lisppaste8: url |
| 16:59 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 17:00 | lisppaste8 | arohner pasted "deftype circular explosion" at http://paste.lisp.org/display/91733 |
| 17:01 | chouser | are you sure you have *print-level* set? |
| 17:02 | arohner | chouser: arg, no, only *print-length* |
| 17:03 | chouser | ah, that'll do it. :-/ sorry. |
| 17:03 | arohner | well, thanks for "fixing my bug" |
| 17:03 | arohner | :-) |
| 17:03 | chouser | I generally set *print-length* to 103 and *print-level* to 15 |
| 17:03 | chouser | seems to work well most of the time for me. |
| 17:04 | MikeDev | So to what extent do people here think clojure has a bright business future? |
| 17:04 | arohner | I'm surprised the default for print-level is nil. once I had a circular structure, everything broke quickly |
| 17:05 | arohner | 102 is too small, but 103 is just right? |
| 17:05 | arohner | ;-) |
| 17:05 | chouser | exactly |
| 17:06 | hiredman | MikeDev: there are four or five startups with JRuby on Rails frontends and Clojure backends |
| 17:06 | chouser | arohner: don't want an even number in case it makes me think something is working (stopping at the right length) when it's not. |
| 17:06 | LauJensen | ~source -> |
| 17:06 | MikeDev | how long has the lang existed? |
| 17:07 | durka42 | two years |
| 17:08 | MikeDev | well basically the way you make money is by picking up a lang early, having it grow like crazy while getting 5 years experience with it |
| 17:08 | chouser | really? |
| 17:08 | MikeDev | then you're set |
| 17:08 | MikeDev | yep |
| 17:08 | chouser | huh |
| 17:08 | MikeDev | then you can consult wherever |
| 17:08 | hiredman | chouser: and here you thought it was in publishing books |
| 17:09 | chouser | if only I'd known! |
| 17:09 | MikeDev | chouser, you publish the book? |
| 17:09 | chouser | MikeDev: working on writing one. It's not out yet. |
| 17:13 | MikeDev | The company I want to work for is somehow gonna use it to make websites work on mobile phones more automagically |
| 17:13 | MikeDev | at least that's the plan |
| 17:14 | MikeDev | sound like a good idea? |
| 17:14 | MikeDev | good pairing of lang with problem? |
| 17:20 | the-kenny | hm.. I think clojure is well-suited for that problem |
| 17:21 | MikeDev | hi, well I gave up on the macro thing |
| 17:22 | the-kenny | MikeDev: I don't understand why you don't understand macros, so I can't help you... sorry. |
| 17:22 | MikeDev | well I think I kinda understand macros, just not how they could do what is in that problem |
| 17:23 | MikeDev | I understand how they can be used to replace text however |
| 17:26 | Chousuke | MikeDev: I think that's the problem. they are not text replacement :/ |
| 17:28 | Chousuke | macros are code-generating functions; and unlike most languages, Clojure code is made of lists and symbols and other data elements and structures. |
| 17:28 | the-kenny | MikeDev: they are there for modifying clojure syntax at compile time |
| 17:29 | hiredman | ,pl |
| 17:29 | clojurebot | java.lang.Exception: Can't take value of a macro: #'sandbox/pl |
| 17:29 | hiredman | excellent |
| 17:31 | hiredman | ,(pl reverse $ (↕reduce range $ 10 () λxy (↕conj inc $ y x))) |
| 17:31 | clojurebot | (1 2 3 4 5 6 7 8 9 10) |
| 17:32 | the-kenny | clojurebot: with-out-str |
| 17:32 | clojurebot | Excuse me? |
| 17:32 | Chousuke | MikeDev: anyway, to build the macro, start with manually coding one instance of the code your macro is supposed to generate |
| 17:33 | the-kenny | MikeDev: For an example take a look at with-out-str |
| 17:34 | hiredman | ,(macroexpand-1 '(with-out-str (println "foo"))) |
| 17:34 | clojurebot | (clojure.core/let [s__6049__auto__ (new java.io.StringWriter)] (clojure.core/binding [clojure.core/*out* s__6049__auto__] (println "foo") (clojure.core/str s__6049__auto__))) |
| 17:34 | the-kenny | MikeDev: For an example take a look at with-out-str at: http://github.com/richhickey/clojure/blob/master/src/clj/clojure/core.clj#L3129 |
| 17:34 | hiredman | (with-out-str (println "foo")) |
| 17:34 | hiredman | ,(with-out-str (println "foo")) |
| 17:34 | clojurebot | "foo\n" |
| 17:35 | the-kenny | It binds *out* to a string-writer and evaluates it's "arguments" in the let |
| 17:35 | the-kenny | s/let/context/ |
| 17:35 | Chousuke | ,(letfn [(foo [x] `(+ y ~x)] (foo 'somesymbol)) ; foo is basically a macro... it's just not marked as one, so its arguments need to be quoted and the result is not evaluated :) |
| 17:35 | clojurebot | Unmatched delimiter: ] |
| 17:35 | Chousuke | gah |
| 17:35 | the-kenny | whops, I pasted the code to wth-in-str, but it's basically the same |
| 17:35 | Chousuke | ,(letfn [(foo [x] `(+ y ~x))] (foo 'somesymbol)) |
| 17:35 | clojurebot | (clojure.core/+ sandbox/y somesymbol) |
| 17:41 | Chousuke | hmm |
| 17:42 | Chousuke | I suppose it might help to just think of the syntax-quoted form as a template rather than worry about constructing lists too much :/ |
| 17:44 | Chousuke | I guess it'd enable writing simple macros even without completely understanding them |
| 17:47 | piccolino | I'm trying to write a library that has some macros that generate Clojure code. And I'd like to be able to insert calls to private functions from the library's namespace into the code that gets output. But it seems I need to make those functions public for this to work at runtime. |
| 17:47 | piccolino | Is that corret? |
| 17:48 | piccolino | correct? |
| 17:48 | ataggart | yes. |
| 17:49 | jwhitlark | Am I doing something wrong, or does -Xbootclasspath not play nice with files like clojure.test? |
| 17:49 | chouser | piccolino: I don't know if it's passed to the level of idiomatic yet or not, but you can use the var instead |
| 17:49 | ataggart | since the funciton is actually being called from the ns intowhich the macro was expanded |
| 17:49 | MikeDev | thanks everybody |
| 17:49 | piccolino | The var? |
| 17:49 | chouser | piccolino: ((var myns/foo) ...) instead of (myns/foo ...) -- then foo can be private |
| 17:50 | jwhitlark | When I (use 'clojure.test) with the -Xbootclasspath, I get java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:0) |
| 17:50 | polypus | is there some convention for namespace naming of clojure projects hosted on github and clojars? like should i use my username in the namespace, etc? |
| 17:52 | piccolino | Oh, cool, thanks chouser. Wasn't aware of that. |
| 17:53 | chouser | piccolino: for short, (#'foo ...) |
| 17:53 | piccolino | Yeah, I just saw that in the docs. |
| 18:19 | technomancy | jwhitlark: I saw that too. |
| 18:19 | technomancy | jwhitlark: transitive requires inside -Xbootclasspath files are problematic |
| 18:20 | technomancy | you can solve it by requiring what clojure.test requires before you load clojure.test |
| 18:20 | technomancy | see leiningen/test.clj inside leiningen for an example |
| 18:20 | technomancy | (that was a crazy error to track down) |
| 18:21 | hiredman | http://www.tedneward.com/files/Papers/BootClasspath/index.html |
| 18:28 | dnolen | rhickey: seems like you figured out the issue? swank-clojure working for me again. |
| 18:32 | rhickey | dnolen: I think so - you weren't here when I put it up - thanks for the report! |
| 18:36 | jwhitlark | That's great. Thanks for all the help |
| 18:44 | devlinsf | rhickey: I'm going through a diff of core.clj between 1.0 and master. I'm finding a few things you might want to look at yourself before releasing 1.1 |
| 18:44 | devlinsf | rhickey: should I post them on the dev group? |
| 18:45 | drewr | fwiw, swank-clojure works for me again on new as well |
| 19:21 | technomancy | anybody used Joda time? does it support parsing dates of an unknown format? |
| 19:21 | technomancy | like just "give it your best shot to figure out what format it is"? |
| 19:24 | devlinsf | technomancy: I don't think so |
| 19:26 | devlinsf | technomancy: I've only used it a little. To me, it seemed that Joda's strength was time zones, dst, and date calculations |
| 19:27 | devlinsf | technomancy: It'll support all sorts of explicit parsing. Adding a Clojure front end to that would probably be straightforward |
| 19:29 | defn | Is there a good tutorial out there on how to build simple clojure applications? |
| 19:31 | defn | I've never used things like ant or maven in the past, leiningen looks cool, but I guess I don't really understand the big picture well enough to get how to use it |
| 19:32 | rhickey | devlinsf: yes, post to the group would be best - thanks |
| 19:33 | devlinsf | rhickey: n/p |
| 19:35 | dnolen | defn: lein makes it possible to build clojure apps simply. There's a lot of pain around managing dependencies and classpaths, particular because Clojure inherits a most if not all of these issues from Java. |
| 19:35 | dnolen | defn: good tutorial here, http://incanter-blog.org/2009/11/20/leiningen-clojars/ |
| 19:39 | defn | awesome, thanks dnlen |
| 19:59 | hiredman | I wonder if you could use the bootclasspath option to replace the system classloader with something more dynamic |
| 20:02 | rhickey | hiredman: -Djava.system.class.loader could be used for interactive use |
| 20:03 | hiredman | oh! |
| 20:08 | jwhitlark | dnolen: I'm trying the lein tutorial, and while it downloads the lein jar, It's not downloading the clojure jar it's expecting. |
| 20:09 | jwhitlark | Now, I've already got clojure, so I guess I could just hack up the lein script, but I wanted to see if there was a simple answer first... |
| 20:09 | dnolen | jwhitlark: what do you mean not downloading the clojure.jar it's expecting? |
| 20:10 | jwhitlark | lein self-install. The docs says it'll put a clojure jar in .m2, but it's just getting lein. |
| 20:10 | dnolen | jwhitlark: did you install lein from github? |
| 20:11 | jwhitlark | well, I pulled down the lein bin script from http://github.com/technomancy/leiningen/raw/master/bin/lein, and tried lein self-install |
| 20:12 | jwhitlark | I didn't clone the repo, but I got the script from there. |
| 20:12 | dnolen | jwhitlark: so nothing in .m2? |
| 20:13 | technomancy | jwhitlark: self-install only works with the stable branch; see the readme. |
| 20:13 | jwhitlark | jw@jw-cisco-dt:~/.m2$ find . |
| 20:13 | jwhitlark | . |
| 20:13 | jwhitlark | ./repository |
| 20:13 | jwhitlark | ./repository/leiningen |
| 20:13 | jwhitlark | ./repository/leiningen/leiningen |
| 20:13 | jwhitlark | ./repository/leiningen/leiningen/1.0.1-SNAPSHOT |
| 20:13 | jwhitlark | ./repository/leiningen/leiningen/1.0.1-SNAPSHOT/leiningen-1.0.1-SNAPSHOT-standalone.jar |
| 20:14 | jwhitlark | ah. |
| 20:14 | dnolen | jwhitlark: there you go, spoken by the man himself :) |
| 20:15 | jwhitlark | The tutorial on the Incanter site has a link to master. |
| 20:15 | technomancy | liebke: ^^ any chance you could fix that? |
| 20:16 | liebke | sure, where do you want me to point to? |
| 20:16 | technomancy | just the stable branch |
| 20:17 | liebke | http://github.com/technomancy/leiningen/raw/stable/bin/lein? |
| 20:18 | liebke | done |
| 20:18 | polypus | there's also this one |
| 20:18 | jwhitlark | There we go. That's working nicely. Thanks for the help. |
| 20:18 | polypus | http://zef.me/2470/building-clojure-projects-with-leiningen |
| 20:19 | jwhitlark | yea, that one seems to point to master instead of stable, also. |
| 21:07 | tolstoy | Anyone know what 'Can't refer to qualified var that doesn't exist' means in the context of a macro? |
| 21:07 | tolstoy | Hm. |
| 21:07 | JAS415 | is it inside a syntax quote? |
| 21:08 | JAS415 | because sq qualifies everything |
| 21:08 | JAS415 | so you might have forgotten to escape something |
| 21:08 | JAS415 | or gensym it |
| 21:08 | JAS415 | either/or |
| 21:09 | JAS415 | or it could be a typo |
| 21:09 | tolstoy | Yes, I was thinking I have a stray backquote or ~ or something in there. |
| 21:10 | JAS415 | yeah |
| 21:10 | JAS415 | qualified var refers to like namespace/varname |
| 21:11 | JAS415 | it might be more obvious if you macroexpand it |
| 21:12 | tolstoy | So, defmacro foo [name] `(do (println ~name)) |
| 21:12 | tolstoy | I'm running this as a script, so it'll be a bit of a task to macroexpand. I was hoping to avoid that.... |
| 21:13 | JAS415 | hm |
| 21:14 | JAS415 | you can't fire up a repl and past it in there? |
| 21:14 | tolstoy | Yes. I'll just need to get my classpath loading stuff working. |
| 21:14 | JAS415 | ah |
| 21:15 | JAS415 | is name a var? |
| 21:16 | tolstoy | It's a string. |
| 21:16 | JAS415 | hm |
| 21:17 | tolstoy | Ok, think I've got things set up to do macroexpand. |
| 21:19 | JAS415 | ok |
| 21:23 | tolstoy | If you're defining a macro you'd like to use everywhere, is there a namespace you can put it in so you don't have to always use the namespace? |
| 21:23 | tolstoy | I guess the right kind of require/use or something solves that. |
| 21:27 | JAS415 | yeah if you do a use then you don't have to namespace it |
| 21:27 | JAS415 | for repl you can also switch to the namespace itself |
| 21:28 | arohner | can anyone recommend a library for cron-like tasks? |
| 21:28 | arohner | i.e. go run this fn in an hour, or twice a day, etc |
| 21:30 | lisppaste8 | tolstoy pasted "can't refer to qualified var?" at http://paste.lisp.org/display/91745 |
| 21:30 | JAS415 | oh |
| 21:30 | hiredman | arohner: http://github.com/hiredman/clojurebot/blob/56f8e9d824c3447036a88fbfea027f518f4ce627/hiredman/schedule.clj |
| 21:30 | JAS415 | yeah can fix that |
| 21:30 | JAS415 | you need to do like ~'log-info |
| 21:31 | JAS415 | then i think it doesn't get qualified |
| 21:31 | tolstoy | I guess I'm wondering which "var" the error is talking about. ;) |
| 21:31 | tolstoy | Ok, I'll try that. |
| 21:31 | JAS415 | is talking about all the function names |
| 21:31 | hiredman | it doesn't expose all of the functionality of a scheduledthreadpoolexecutor |
| 21:32 | tolstoy | JAS415: Ah, right! Okay. I think I get it now. |
| 21:32 | JAS415 | the log-info functions will be in whatever ns it expands in |
| 21:33 | JAS415 | good :-) |
| 21:33 | arohner | hiredman: thanks |
| 21:33 | tolstoy | Right. It's so easy to forget that macros produce sexps. |
| 21:33 | hiredman | arohner: it's a start |
| 21:34 | tolstoy | Even when you remember it to yourself as you're writing them. |
| 21:35 | JAS415 | after a few months you get used to it |
| 21:35 | JAS415 | months/years |
| 21:36 | tolstoy | Yeah. |
| 21:47 | ataggart | tolstoy: just fyi, there's already logging stuff in contrib |
| 21:48 | tolstoy | Yes, I've seen that. Thought I'd just try this to demo to folks how "easy" it is to craft up stuff in closure. |
| 21:48 | ataggart | gotcha |
| 21:48 | tolstoy | However, using a macro to generate another macro is maybe not such a good idea. ;) |
| 21:49 | dnolen | tolstoy: actually that's a pretty common use case ;) |
| 21:49 | ataggart | it's macros all the way down |
| 21:50 | tolstoy | So, (defmacro foo [a] '(blah blah (defmacro other [].....)) |
| 21:51 | dnolen | tolstoy: more like (defmacro foo [a] `(bar (amacro baz ...))) |
| 21:52 | tolstoy | Well, but I want to create a macro which is defined at the time of the outer macro is, uh, compiled. |
| 21:52 | tolstoy | (let [foo val] (defn func ..) (defn func2 ..) (defmacro mac [] (use foo))) |
| 21:53 | tolstoy | But, like I say, it might not be such a hot idea. |
| 21:54 | tolstoy | Actually, it works, but the code that the embedded macro generates has a problem, and that's hard to debug. |
| 21:54 | tolstoy | I think a helper function is what's needed. |
| 22:09 | JAS415 | macros generating macros is hard |
| 22:10 | tolstoy | Yeah. |
| 22:10 | tolstoy | I want a defmacro to produce another defmacro, but only because I need it to have a reference to the "log" variable. |
| 22:11 | tolstoy | Probably I could just use something other than let. That might do it, actually. |
| 22:11 | defn | why does (def agent1 (agent 0)) (send agent1 increment 5) => 5, while @(send agent1 increment 5) => 0 |
| 22:11 | JAS415 | is helpful to use helper functions for that type of stuff |
| 22:11 | JAS415 | split complicated things out |
| 22:12 | defn | user.oO (send agent1 increment 5) #<Agent@4532be10: 40> |
| 22:12 | defn | user.oO @(send agent1 increment 5) 40 |
| 22:14 | defn | it's like it's always 1 call behind the current version |
| 22:18 | _mst | defn: agents are asynchronous so there's no guarantee your action will have been handled by the agent at the point you dereference it |
| 22:19 | _mst | so you might observe it in a state either pre or post update |
| 22:19 | defn | how do we know if we're at post update time? |
| 22:20 | _mst | you can call (await) on the agent to have the current thread blocked until your action has been dispatched |
| 22:20 | defn | ah-ha |
| 22:22 | defn | so if agent1 is 0, (await (send agent1 increment 10)) (await (send agent1 increment 10)) agent1 => 20 |
| 22:22 | defn | otherwise i'd get 10 |
| 22:22 | defn | err nevermind, deref'ing is different |