2009-01-24
| 00:00 | technomancy | is binding supposed to be non-recursive even though let is recursive? |
| 00:01 | technomancy | for instance, it seems odd that this works (let [number 1 number2 (* number 2)] number2) while (declare n1 n2) (binding [number 1 number2 (* number 2)] number2) this does not |
| 00:22 | Chouser | yes, let clauses happen in order, binding clauses happen simultaneously |
| 00:22 | eee | hello |
| 00:22 | Chouser | 'let's the exception I think -- besides binding, loop and fn calls are also simultaneous. |
| 00:22 | Chouser | eee: hi |
| 00:24 | eee | any interesting topics or debates? |
| 00:24 | rzezeski | Chouser, you by any chance see my last msg? I sent it a few hours ago, no one responded. |
| 00:25 | Chouser | yes, I see it. |
| 00:25 | eee | I'm lobbying to use s;ashes in namespace including the slash for the symbols. . . . no dots |
| 00:25 | eee | but that's from a newby |
| 00:26 | eee | i think it would have been easier to grok |
| 00:26 | Chouser | rzezeski: seems sensible. You could raise it on the google group. |
| 00:26 | eee | dots equal java |
| 00:26 | Chouser | eee: foo/bar/baz instead of foo.bar/baz ? |
| 00:26 | eee | yup |
| 00:27 | eee | i brought it up there. |
| 00:27 | eee | people taught me namespaces tonight |
| 00:27 | eee | i finally asked about it |
| 00:27 | eee | i just didn't get it |
| 00:27 | eee | at all |
| 00:27 | Chouser | when compiled, the file foo/bar/baz.clj becomes the class foo.bar.baz, which means its package and namespace are both foo.bar |
| 00:28 | Chouser | ah, I haven't read that thread yet. still watching the message count tick upwards. :-) |
| 00:29 | rzezeski | Chouser, thx for the input, will do |
| 00:29 | eee | so if I need some clojure stuff in a java app, I can use foo.bar |
| 00:29 | eee | woah |
| 00:29 | eee | i wonder |
| 00:29 | Chouser | rzezeski: I really don't know which way Rich will go on that. |
| 00:29 | eee | if you compile clojure |
| 00:30 | eee | then can you use it from clojure as if it were any old java? |
| 00:30 | Chouser | yep |
| 00:30 | eee | that would be perverse |
| 00:30 | eee | just wondering |
| 00:30 | eee | weird |
| 00:30 | Chouser | yes, Clojure makes no attempt to pretend it's anything other than Java |
| 00:30 | Chouser | well, JVM code anyway |
| 00:31 | eee | isi this language designed to make ones head exlode with possibilities :) |
| 00:31 | Chouser | :-) |
| 00:31 | rzezeski | Chouser, yea it's not that it really bothers me. However, if ppl come to rely on the fact that they can merge lists, sets, etc. then it could be harmful if in the future the impl changes and either merge doesn't work on those structures anymore, or produces different results, etc. |
| 00:32 | technomancy | Chouser: so let is the special case then; hmmm... I was pretty surprised just because I expected binding to work like let. |
| 00:32 | eee | like that there are two ways to do Java stuff is really confusing |
| 00:32 | Chouser | technomancy: you're not the first. |
| 00:32 | Chouser | rzezeski: yes, that's good point. |
| 00:33 | Chouser | eee: two ways? |
| 00:33 | Chouser | eee: as in .java code or .clj code? |
| 00:33 | eee | no |
| 00:33 | eee | i mean like |
| 00:34 | eee | how do you access a static Java thingy from clojure? |
| 00:34 | Chouser | (java.lang.Integer/parseInt "12") |
| 00:35 | rzezeski | btw, the google group has gone nuts the last few days, I read all the msgs and it's killing me trying to keep up. It's a good thing, but I feel like all I do is read |
| 00:35 | technomancy | Chouser: do you know the reason behind it? |
| 00:36 | Chouser | rzezeski: it keeps getting worse. I imagine we'll have to split things up somehow to help the right people to be able to ignore the right stuff, but I really am not sure how. |
| 00:36 | eee | that's only one way, Ch. Then isn't there (.parseInt "12") |
| 00:36 | Chouser | rzezeski: it's not clear to me that a "-dev" vs. "-user" split would be a good idea. |
| 00:36 | eee | (.parseInt Integer "12") |
| 00:36 | eee | i dunno |
| 00:37 | eee | i don't have any intuition for the pattern |
| 00:37 | Chouser | eee: nope, not anymore. That format is for instance methods: (.split "1,2,3" ",") |
| 00:37 | rzezeski | well, I think splitting it up just yet might be a little premature, it could just be a spike. However, if it keeps up I agree that some type of partition should occur. Maybe a beginners list (haskell has one) and a normal list? |
| 00:38 | eee | I know there are several ways to do, say, (new JFrame("hello world")).setVisible(true); |
| 00:38 | Chouser | rzezeski: but who would read the beginner's list? just beginners? :-) |
| 00:38 | Chouser | eee: sure, but that's true in any language, even in Java. |
| 00:38 | WizardofWestmarc | yeah was gonna say, that's not going to save the people who want to help the newbies |
| 00:38 | rzezeski | beginners, and anyone else who wants to lend a guiding hand. I feel like there are a lot of people eager to learn and teach others in the group. |
| 00:39 | technomancy | "I was having this problem..." / "Oh, I had that problem too. I wonder how to fix it." |
| 00:39 | technomancy | clearly the solution is to get people to use IRC more instead of email. =) |
| 00:39 | Chouser | technomancy: Rich has said that if 'let' were simultaneous (as it is in some other lisps) people would just write a macro to do it in order anyway (often called let* I believe), so we might as well have it this way built in. |
| 00:40 | rzezeski | Or maybe a "user" vs. "dev" list. The former being oriented towards end-user usage of Clojure, the later being oriented towards the guys who make Clojure work |
| 00:40 | WizardofWestmarc | chouser: yeah let* is what clojure's let acts like |
| 00:40 | technomancy | Chouser: totally makes sense for let; it's the let/binding difference that I wonder about. |
| 00:40 | Chouser | technomancy: and I think he's said the 'binding' can be more efficient by doing all its forms at once. I guess you can nest them if you want. :-) |
| 00:41 | WizardofWestmarc | what's odd about that idea is wasn't the whole point of making let equiv to let* to avoid such confusions? or am I misremembering? |
| 00:41 | technomancy | Chouser: I thought it might be efficiency. =) yeah, I'm gonna have to nest this sucker and be sure to comment it so I remember why it looks a bit funny. |
| 00:42 | Chouser | WizardofWestmarc: possibly, but I think 'let' can do that with no performance hit, while perhaps 'binding' cannot. |
| 00:42 | technomancy | seems like it'd be easier to make binding efficient sequentially than let, but my experience with implementing lisp has been pretty slim |
| 00:42 | eee | i like to pretend like a language designer because it is the only way I can understand clojure. I got, "that's dumb. it should be like this." I expect one of two answers: (1) "no because", or (2) wow, good point, or (3) (bonus) " get used to it" I suspect mostly type 1 and 3 for now since I'm new to functional languages |
| 00:42 | WizardofWestmarc | I don't see why binding vs let would have any additional efficiency |
| 00:43 | technomancy | eee: you get 3 a lot more with CL than clojure. =) |
| 00:43 | WizardofWestmarc | and if you're ever interested in Lisp implementation, I've heard great things about Lisp in Small Pieces, but haven't bought a copy yet |
| 00:43 | technomancy | WizardofWestmarc: probably some crazy JVM thing. =) |
| 00:44 | technomancy | WizardofWestmarc: I built a scheme from reading the Little Schemer; lots of fun but not very useful. |
| 00:44 | WizardofWestmarc | technomancy: good point I know very little about the jvm, it's JIT, etc |
| 00:44 | WizardofWestmarc | Lisp in small pieces is meant to build things more robust then a basic scheme compiler |
| 00:44 | technomancy | I guess in Small Pieces explains how to actually make it perform decently etc? but probably doesn't address VMs. |
| 00:44 | WizardofWestmarc | I dunno, the only point of the book is compiler stuff for a lisp |
| 00:44 | eee | yeah, 3 in CL since it's already ansi |
| 00:45 | eee | but hopefully a lot of (1), too |
| 00:45 | eee | i also hate debugging these languages so far |
| 00:45 | rzezeski | Lisp In Small Pieces is on my ever growing book queue. I can't wait to read it in 3 years :) |
| 00:45 | Cark | how do i do such thing with clojure : synchronized(dialog.getTreeLock()) { ... } |
| 00:45 | WizardofWestmarc | rzezeski: haha I understand that one |
| 00:46 | WizardofWestmarc | in just books I own it's insane |
| 00:46 | WizardofWestmarc | PAIP and AI:aMP I haven't finished yet |
| 00:46 | WizardofWestmarc | though I own both |
| 00:46 | Chouser | (doc locking) |
| 00:46 | clojurebot | Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances.; arglists ([x & body]) |
| 00:46 | WizardofWestmarc | also want to actually do SICP at some point, and may try it in clojure as a double learning excercise. |
| 00:47 | Cark | thanks chouser |
| 00:47 | rzezeski | Yea I have and addiction with buying CS books. So much so that I have an amazon visa card. I have about 20 books I haven't even cracked yet, it's sick |
| 00:47 | eee | does the clojurebot have a repl? |
| 00:47 | rzezeski | I don't know if I'd buy SICP, I think the video lectures are enough |
| 00:48 | WizardofWestmarc | I need to get the amazon visa |
| 00:48 | WizardofWestmarc | and why buy SICP? I have the pdf |
| 00:48 | Chouser | ,(print "I have a REPL") |
| 00:48 | clojurebot | I have a REPL |
| 00:48 | eee | (clojurebot eval '(println "hello world")) .. too bad I don't remember any clojure already |
| 00:48 | WizardofWestmarc | I think I spent 1k in amazon one year, at least 60% of which were in programming books |
| 00:48 | rzezeski | that's true it is free, but it's so F'ing long, I really just prefer to watch the videos :) |
| 00:48 | WizardofWestmarc | true |
| 00:48 | WizardofWestmarc | note I have the videos downloaded too |
| 00:48 | eee | nice! |
| 00:49 | rzezeski | Have you gone through the Art of Computer Programming yet? |
| 00:49 | WizardofWestmarc | oh god no |
| 00:49 | eee | ,(print "let's see") |
| 00:49 | rzezeski | Yea I own it, keep delaying |
| 00:49 | clojurebot | let's see |
| 00:49 | WizardofWestmarc | the entire series to date? |
| 00:50 | eee | that is amazing |
| 00:50 | rzezeski | no I have volume 1-3 |
| 00:50 | rzezeski | I think 4 recently came out |
| 00:50 | WizardofWestmarc | I also think so but not positive |
| 00:50 | hiredman | clojurebot: clojurebot is amazing |
| 00:50 | clojurebot | Roger. |
| 00:50 | hiredman | damn, I just clobbered something |
| 00:51 | rzezeski | I got two for christmas, The Little Schemer and Purely Functional Data Structures, but first I have to finish Practical Common Lisp |
| 00:51 | WizardofWestmarc | PFDC? The one that's all in ML? |
| 00:51 | technomancy | hiredman: don't you think he should warn you before you clobber things? |
| 00:51 | technomancy | so you'd have to say "forget thing" first? |
| 00:52 | rzezeski | it has impls in ML and Haskell |
| 00:52 | technomancy | rzezeski: Little Schemer is awesome. very enjoyable. |
| 00:52 | hiredman | technomancy: yeah, that is a good idea, I guess |
| 00:52 | rzezeski | I know Haskell (to an extent) but not ML |
| 00:52 | WizardofWestmarc | nod |
| 00:52 | technomancy | hiredman: just stealing ideas from fsbot |
| 00:52 | WizardofWestmarc | I dno't really know either. After Clojure I'll probably look at Haskell next |
| 00:52 | WizardofWestmarc | *don't |
| 00:52 | rzezeski | I came from Haskell to Clojure |
| 00:53 | hiredman | technomancy: infobot has the same behaviour |
| 00:53 | rzezeski | and I find Clojure to be pretty damn enjoyable |
| 00:53 | technomancy | ocaml has type inference, right? |
| 00:53 | WizardofWestmarc | I've spent some time in CL (SBCL mostly, on windows that's a giant pain) and scheme (PLT/mz) |
| 00:53 | WizardofWestmarc | yeah |
| 00:53 | WizardofWestmarc | I think both are worth knowing, for different reasons |
| 00:53 | WizardofWestmarc | the type system in haskell looks appealing to me, at least as something of a mental exercise. |
| 00:54 | WizardofWestmarc | though I'm sure Monads will break my brain a few times ;-) |
| 00:54 | rzezeski | Yea, I still plan to go through Real World Haskell |
| 00:54 | rzezeski | Yes, Monads are a bitch, and IO was a stumbling block for me in Haskell. |
| 00:55 | WizardofWestmarc | I think that's most people's stumbling block, from what I've heard |
| 00:56 | technomancy | I'm getting a "cannot recur" from catch/finally when I have a doseq in a finally block. is this illegal? |
| 00:56 | WizardofWestmarc | believe it doesn't work currently. |
| 00:57 | technomancy | WizardofWestmarc: bug? |
| 00:57 | WizardofWestmarc | don't recall, I just remember hearing about it before |
| 00:57 | eee | my shareware irc expired |
| 00:57 | Chouser | yeah, 'recur' is currently disallowed in a couple places where it might theoretically be okay. |
| 00:57 | WizardofWestmarc | eee: windows user ? |
| 00:58 | technomancy | Chouser: and doseq uses recur? |
| 00:58 | eee | mibbit is way better anyway. free and webbased |
| 00:58 | rzezeski | How's the joke go? You're consider a Haskell newbie once you've written a Monad tutorial? It's kind of like a rights-of-passage, which is cool in a way |
| 00:58 | Chouser | technomancy: oh. heh, yeah, it does. |
| 00:58 | WizardofWestmarc | mibbit annoys me because it chops my name short :( |
| 00:58 | technomancy | makes sense I guess |
| 00:58 | WizardofWestmarc | hence during the day I don't have the h :P |
| 00:58 | eee | not on my screen |
| 00:58 | WizardofWestmarc | I mean when I log in via it |
| 00:58 | WizardofWestmarc | I'm at home on Trillian atm |
| 00:58 | eee | wow, I can actually see everyone's comments separately |
| 00:59 | eee | glad I didn't buy that piece of junk |
| 00:59 | Cark | clojurebot: paste? |
| 00:59 | clojurebot | paste is http://paste.lisp.org/new/clojure |
| 00:59 | hiredman | ~paste is http://paste.lisp.org/new/clojure if it's working |
| 00:59 | clojurebot | Ok. |
| 00:59 | technomancy | cracks me up to think people think they can make money with an IRC client |
| 01:00 | eee | id that implemented in clojure? |
| 01:00 | hiredman | technomancy: like selling water |
| 01:00 | hiredman | eee: the pastebin is not |
| 01:01 | Cark | so here is a little story |
| 01:01 | Cark | earlier today i found that my app was leaking memory |
| 01:01 | Cark | i was ready to throw clojure out |
| 01:02 | lisppaste8 | eee pasted "untitled" at http://paste.lisp.org/display/74144 |
| 01:02 | Cark | i asked help here to find a program that would help me track the leak |
| 01:02 | Cark | and found out it was in the java.awt itself : http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6497929 |
| 01:03 | blbrown | what is the best approach for evaluating a string in clojure |
| 01:03 | lisppaste8 | cark pasted "java.awt.Dialog memory leak fix" at http://paste.lisp.org/display/74145 |
| 01:03 | blbrown | (eval '(+ 1 1)) Hmm, maybe I can try to get this form |
| 01:03 | Chouser | ,(load-string "(+ 1 2)") |
| 01:03 | clojurebot | 3 |
| 01:04 | blbrown | nice, the bot answered my question for me |
| 01:04 | eee | Chouser did it |
| 01:04 | eee | with the comma |
| 01:04 | eee | try yours with a comma first |
| 01:04 | Cark | so in conclusion : i hope i won't see too many of these java library bugs in the future |
| 01:04 | Chouser | Cark: wow |
| 01:04 | blbrown | oh |
| 01:05 | blbrown | ,(eval '(+ 1 1)) Hmm, maybe I can try to get this form |
| 01:05 | clojurebot | DENIED |
| 01:05 | blbrown | ,(eval '(+ 1 1)) |
| 01:05 | clojurebot | DENIED |
| 01:05 | WizardofWestmarc | eval's protected? |
| 01:05 | eee | well java is so easy that people will make stuff that sort of works all the time |
| 01:05 | WizardofWestmarc | (in the bot) |
| 01:05 | durka42 | um, eval is denied but load-string is allowed? |
| 01:05 | eee | and get paid a lot of money to do so |
| 01:05 | durka42 | that doesn't seem right |
| 01:05 | hiredman | durka42: oversite |
| 01:05 | eee | and get a lot of A's in schol |
| 01:05 | Cark | eee : but that comes straight from sun =/ |
| 01:05 | blbrown | ,(load-string "(new File |
| 01:05 | clojurebot | Eval-in-box threw an exception:EOF while reading string |
| 01:05 | Chouser | hiredman: what do you think about providing a way to target a clojurebot eval at a nick |
| 01:05 | eee | but never learn things like eak references |
| 01:05 | blbrown | ,(load-string "(new File 'abc')") |
| 01:05 | clojurebot | DENIED |
| 01:06 | eee | i resemble that remark |
| 01:06 | durka42 | hiredman: seems like there should be a better way to block that. can the security manager hook like internal RT.java functions? |
| 01:06 | blbrown | nice |
| 01:06 | Chouser | ,hiredman: (+ 1 2) |
| 01:06 | technomancy | blbrown: you can't use single-quotes for strings |
| 01:06 | Cark | eee : the thing is, with a good garbage collector it's pretty rare you need weak references |
| 01:06 | hiredman | durka42: dunno enough about security policy |
| 01:06 | Chouser | and have it respond: hiredman: 3 |
| 01:06 | blbrown | ,(load-string "(new File \"abc\")") |
| 01:06 | clojurebot | DENIED |
| 01:07 | blbrown | ,(load-string "(+ 1 2)") |
| 01:07 | clojurebot | DENIED |
| 01:07 | hiredman | "hot patched" |
| 01:07 | blbrown | interesting |
| 01:07 | WizardofWestmarc | using swank or some other way to connect to the java instance? |
| 01:07 | hiredman | ~ clojurebot is also hot patching enabled |
| 01:07 | clojurebot | c'est bon! |
| 01:08 | eee | ,(def a 3) |
| 01:08 | clojurebot | DENIED |
| 01:08 | eee | i figured |
| 01:08 | hiredman | nothing based on def works |
| 01:09 | WizardofWestmarc | to avoid polluting the namespace I assume? |
| 01:09 | blbrown | I ran the same code as Chouser, worked for him, not me |
| 01:09 | eee | ,(let [a \q] print a) |
| 01:09 | clojurebot | \q |
| 01:10 | WizardofWestmarc | hot patched to prevent it |
| 01:10 | hiredman | blbrown: I patched it in between |
| 01:10 | WizardofWestmarc | after chouser did it |
| 01:10 | eee | ,(let [a 3] print a) |
| 01:10 | clojurebot | 3 |
| 01:10 | blbrown | hiredman, nice |
| 01:10 | hiredman | by "patched" I mean I pasted some code into the repl |
| 01:10 | WizardofWestmarc | hey, that's all you need to do in erlang too and it's called hotpatching there :P |
| 01:11 | blbrown | hiredman, Actually, I might need code like that. I want to run a simple 'script' parse and restrict volatile code |
| 01:11 | hiredman | eee: that expression does not do what you think |
| 01:11 | hiredman | clojurebot: where are you? |
| 01:11 | clojurebot | http://github.com/hiredman/clojurebot/tree/master |
| 01:11 | eee | no? |
| 01:11 | hiredman | eee: you meant -> |
| 01:11 | hiredman | (let [a 3] (print a)) |
| 01:12 | Cark | ,(read "(+ 1 3)") |
| 01:12 | clojurebot | java.lang.ClassCastException: java.lang.String cannot be cast to java.io.PushbackReader |
| 01:12 | eee | oh |
| 01:12 | eee | duh |
| 01:12 | blbrown | ,(let [a 3] (println (+ 1 1)) |
| 01:12 | clojurebot | Eval-in-box threw an exception:EOF while reading |
| 01:12 | blbrown | ,(let [a 3] (println (+ 1 1))) |
| 01:12 | clojurebot | 2 |
| 01:12 | rzezeski | clojurebot: vim or emacs? |
| 01:12 | clojurebot | emacs is hard, lets go shopping! |
| 01:12 | rzezeski | lol |
| 01:12 | eee | so print nedn't take an arg |
| 01:12 | hiredman | nope |
| 01:12 | eee | ,(print) |
| 01:12 | clojurebot | nil |
| 01:12 | eee | i see |
| 01:12 | blbrown | I bet that is the first people do with a bot, check how secure it is |
| 01:12 | hiredman | eee: print did not even run |
| 01:12 | eee | i suck |
| 01:13 | hiredman | eee: unless a function is in parens it does not run |
| 01:13 | eee | oh |
| 01:13 | WizardofWestmarc | it just evaluates to the reference to that function |
| 01:13 | Chouser | or unless it's passed to a fn that runs it |
| 01:13 | eee | why let that be legal? |
| 01:13 | WizardofWestmarc | when you see the <BLAHBLAHSTUFFBLAH |
| 01:13 | hiredman | Chouser: sshhhh |
| 01:13 | WizardofWestmarc | |
| 01:13 | Chouser | ,(apply + 1 20 [300 4000]) |
| 01:13 | clojurebot | 4321 |
| 01:14 | hiredman | eee: first class function |
| 01:14 | hiredman | s |
| 01:14 | eee | i get it |
| 01:14 | eee | so |
| 01:14 | eee | |
| 01:14 | eee | is like |
| 01:14 | hiredman | ,(identity print) |
| 01:14 | clojurebot | #<core$print__3987 clojure.core$print__3987@aea710> |
| 01:14 | eee | ,3 |
| 01:14 | blbrown | ,(identify load-string) |
| 01:14 | clojurebot | DENIED |
| 01:14 | WizardofWestmarc | so you have to explicitly call identity with the bot? interesting |
| 01:14 | blbrown | ,(identify +) |
| 01:14 | clojurebot | java.lang.Exception: Unable to resolve symbol: identify in this context |
| 01:15 | blbrown | I don't get it, but still think the bot is cool and protected |
| 01:15 | blbrown | ,(identify '+) |
| 01:15 | clojurebot | java.lang.Exception: Unable to resolve symbol: identify in this context |
| 01:15 | hiredman | weird |
| 01:15 | Chouser | WizardofWestmarc: I think it just wants to match ,(...) before it attempts to run it |
| 01:15 | WizardofWestmarc | ah |
| 01:15 | technomancy | using *starred-names* is convention only for dynamically-bound vars that you intend to rebind further down, correct? |
| 01:15 | WizardofWestmarc | gotcha |
| 01:15 | eee | functions are types just like numbers . . . .so since I would expect |
| 01:15 | Chouser | technomancy: I think that's right. |
| 01:15 | eee | ,3 |
| 01:15 | eee | I should expect |
| 01:15 | eee | |
| 01:16 | eee | right? |
| 01:16 | hiredman | ,(identity +) |
| 01:16 | clojurebot | #<core$_PLUS___3182 clojure.core$_PLUS___3182@18e18a3> |
| 01:16 | technomancy | Chouser: since obviously you don't star function names, which are vars just like any other |
| 01:16 | Chouser | eee: yes. try it in your own repl |
| 01:16 | WizardofWestmarc | yeah earmuffs are "globals" |
| 01:16 | blbrown | ,(identity +) |
| 01:16 | clojurebot | #<core$_PLUS___3182 clojure.core$_PLUS___3182@18e18a3> |
| 01:16 | Chouser | eee: clojurebot's little IRC rules may be confusing things for you |
| 01:16 | technomancy | WizardofWestmarc: heh; earmuffs. |
| 01:16 | technomancy | globals that change though. |
| 01:16 | eee | nope |
| 01:16 | Chouser | technomancy: right. globals are nothing special |
| 01:16 | eee | thanks for catching that |
| 01:17 | WizardofWestmarc | which is why you tend to want to flag them with the *'s so you can tell when you're dealing with something scoped globally |
| 01:17 | Chouser | WizardofWestmarc: no, something that might change |
| 01:17 | WizardofWestmarc | well, you wouldn't care if it's scoped globally if you won't change it |
| 01:17 | Chouser | every 'def' and 'defn' is a global |
| 01:17 | eee | well, I can clock out |
| 01:17 | WizardofWestmarc | after all then the scope doesn't matter |
| 01:17 | eee | i learned something! |
| 01:17 | blbrown | thought you can change a value once it has been defined |
| 01:17 | blbrown | cant |
| 01:18 | WizardofWestmarc | symbols can point to different things |
| 01:18 | WizardofWestmarc | the thing pointed TO is immutable |
| 01:18 | eee | so remember to spread the word. namespaces are gonna be slash separated now |
| 01:18 | eee | :) |
| 01:18 | Chouser | in Clojure, symbols don't really point to anything. they're just names. |
| 01:18 | blbrown | great, another change |
| 01:18 | eee | just kidding |
| 01:18 | blbrown | scared me |
| 01:18 | eee | that was evil |
| 01:19 | durka42 | backslash separated? |
| 01:19 | eee | nevermind |
| 01:19 | hiredman | ,3 |
| 01:19 | hiredman | ,3 |
| 01:19 | hiredman | hmmm |
| 01:19 | eee | i was tryign to spread a rumor |
| 01:19 | rzezeski | Chouser, wow, those reddit ppl were pretty harsh on your "path to Clojure" post |
| 01:19 | eee | since I'm not used to anything |
| 01:20 | eee | I thought that would be easier for newbies |
| 01:20 | Chouser | rzezeski: yeah, that was fun for me. |
| 01:20 | WizardofWestmarc | progit or general reddit? |
| 01:20 | eee | i wanna see |
| 01:20 | eee | where is the post? |
| 01:20 | blbrown | rzezeski, where is the link |
| 01:20 | WizardofWestmarc | 'cause people in programming.reddit always seem to like to tear into people it seems like |
| 01:20 | rzezeski | http://www.reddit.com/r/programming/comments/7r2zu/my_path_to_clojure/ |
| 01:20 | WizardofWestmarc | though i still go there to find handy links and roll my eyes at people :P |
| 01:21 | eee | no one ever says anything mean about clojure |
| 01:21 | eee | from what i've seen |
| 01:21 | rzezeski | some of them are foaming at the mouth (figuratively speaking) |
| 01:21 | eee | let's see this thing |
| 01:21 | technomancy | this one is much worse than normal |
| 01:21 | rzezeski | it's sad |
| 01:21 | technomancy | some people see "java" and think "code monkey"... the idea of the JVM as a separate piece of engineering never really occurred to them |
| 01:21 | WizardofWestmarc | CL fanatics are definitley out there in the reddit community |
| 01:21 | WizardofWestmarc | since reddit 1.0 was written in CL |
| 01:22 | WizardofWestmarc | so they're a bit defensive |
| 01:22 | blbrown | eee, kind of a brain fart, that Clojure works with existing Java code runs on the JVM and is still a very productive language |
| 01:22 | WizardofWestmarc | and yeah, it can be hard to seperate the JVM from Java. I had to get used to that idea when I first started looking into clojure |
| 01:22 | Chouser | WizardofWestmarc: me too |
| 01:23 | durka42 | hmm, this is sort of interesting http://logand.com/sw/jmultimethod/ |
| 01:23 | WizardofWestmarc | I was like "ew, java" "wait, lisp macros, real vector support, and easy access to that many libraries?" "But... Java!" |
| 01:23 | rzezeski | I guess there will always be ppl hating for one reason or another |
| 01:23 | eee | here's the thing |
| 01:23 | technomancy | WizardofWestmarc: it's unfortunate that the "J" snuck into the name JVM; the CLR is a much better name. |
| 01:23 | eee | in the discussion group |
| 01:23 | WizardofWestmarc | I think it was that one video presentation of rich's where he goes on about how you can hate java but love the jvm that really helped me finish getting past that. |
| 01:24 | eee | read the post that has to do with streams |
| 01:24 | eee | today I was in there defending Rich about the avoidance of extra allocation |
| 01:24 | WizardofWestmarc | technomany: true, but how long was it before you saw much of other languages running against the JVM? |
| 01:24 | eee | and an NVIDIA guy echoed it |
| 01:24 | eee | but |
| 01:24 | eee | he talked about how C# worked right |
| 01:24 | eee | and java didn't |
| 01:25 | eee | interesting read |
| 01:25 | eee | and clojure MIGHT fix that |
| 01:25 | eee | or have a chance |
| 01:25 | WizardofWestmarc | well |
| 01:25 | blbrown | one more general comment, going back to Common Lisp, there seems to be a lot to add to a confusing API. For example, there is flet, labels, letrec...on and on. In clojure, it is just '(fn name ...) |
| 01:25 | WizardofWestmarc | one of the interesting things (to me) about clojure is it has a much stronger chance of exposing a lot of programmers to language constructs they might not have even touched otherwise |
| 01:26 | eee | i'm going to have a hard time trusting it's efficiency until I understand what it is doing |
| 01:26 | eee | as with any high-level language |
| 01:26 | gnuvince_ | If people had taught/learned JavaScript the way it's supposed to be used, everyone would be familiar with HOPs by now. |
| 01:27 | WizardofWestmarc | HOP? Higher Order Programming? |
| 01:27 | gnuvince_ | procedures |
| 01:27 | WizardofWestmarc | ah |
| 01:27 | Chouser | gnuvince_: yes, but instead they write pages of code to make JavaScript act like Java. ...and then pages more now that they have to follow all this Java-like ceremony. |
| 01:28 | WizardofWestmarc | well |
| 01:28 | blbrown | gnuvince, do people use Javascript outside of a web environment |
| 01:28 | WizardofWestmarc | a lot of programmers only know one way to program |
| 01:28 | rzezeski | Chouser: you talking about OO like frameworks in JS? |
| 01:28 | blbrown | Javascript is cool language, but I can't stand working with it in the context of web development |
| 01:28 | WizardofWestmarc | blbrown: tried jquery? |
| 01:29 | eee | nice little essay. I only skimmed it |
| 01:29 | eee | so far |
| 01:29 | eee | but I'll read it more thuroughly |
| 01:29 | blbrown | WizardofWestmarc, jquery is fine, but if you aren't using jquery...well |
| 01:29 | Chouser | rzezeski: I'm really just talking about Zimbra. I chose (poorly) to use its JS lib at work, and now we're mired in it. |
| 01:29 | WizardofWestmarc | right |
| 01:29 | WizardofWestmarc | browser issues suck I agree |
| 01:29 | eee | very impressive how much you challenge yourself |
| 01:29 | WizardofWestmarc | but that's why all the different libs (jQuery, mootools, and so on) all cropped up I'd argue |
| 01:30 | WizardofWestmarc | I doubt such robust libraries would have cropped up the way they did were it not for the need to hide browser implementation differences |
| 01:30 | rzezeski | Chouser: I don't know what Zimbra is, but I have seen articles about creating frameworks in JS that make it look all OO and behave like Java, and I just think to myself..."why?" |
| 01:30 | technomancy | hrm... how would a remove-first function work? |
| 01:30 | WizardofWestmarc | remove-first? You mean like (rest [coll]) ? |
| 01:30 | WizardofWestmarc | or what are you aiming for? |
| 01:31 | eee | what is the technology behind wordpress I wonder |
| 01:31 | blbrown | WizardofWestmarc, plus, if you have complex pages, complex CSS and in turn complex javascript,..like you said, supporting multiple browsers...it just becomes difficult to debug client side web |
| 01:31 | WizardofWestmarc | blbrown: yeah |
| 01:31 | technomancy | WizardofWestmarc: I mean "remove the first element from coll for which pred returns true" |
| 01:31 | WizardofWestmarc | ah |
| 01:31 | eee | PHP |
| 01:31 | eee | MySQL |
| 01:31 | rzezeski | Chouser, have you ever had the pain of having to use ExtJS? |
| 01:32 | Chouser | rzezeski: nope. |
| 01:32 | technomancy | I guess it could be built on top of partition-by |
| 01:32 | eee | there's a function partition-by? |
| 01:32 | eee | seems unnecesary |
| 01:32 | technomancy | my brain is done for the night though; now is a bad time to be writing new util functions. |
| 01:32 | technomancy | eee: well, it's contrib |
| 01:32 | technomancy | not core |
| 01:33 | eee | ah |
| 01:33 | eee | i'm out too. gnight |
| 01:33 | WizardofWestmarc | that reminds me, are there any docs for contrib aside from just browsing the source or (doc)ing through it? |
| 01:33 | rzezeski | Chouser, it's a "peach" of a Javascript Widget library. Makes everything look like a windows desktop. It annoys me everyday. |
| 01:34 | Chouser | rzezeski: ah. :-( |
| 01:35 | rzezeski | It clobbers all my CSS, creates massive amounts of DOM. So I know what it's like to work with a JS library you don't like. |
| 01:35 | blbrown | WizardofWestmarc, one more comment, I hope to work on this application. It will essentially 'compile' a web page. It will validate a XHTML document, validate the Javascript (maybe using Rhino) and possibly validate the CSS |
| 01:36 | blbrown | WizardofWestmarc, cut down on errors before deploying an app. Hmm, maybe I could even use clojure |
| 01:36 | WizardofWestmarc | don't see why not |
| 01:37 | blbrown | treating client side web content like some cheap script doesn't help anyone |
| 01:37 | WizardofWestmarc | I've been looking at text analysis as my way of finally getting serious about learning the language |
| 01:37 | blbrown | WizardofWestmarc, checked opennlp? |
| 01:37 | WizardofWestmarc | treating anything like it's cheap doesn't help the dev or end user. |
| 01:37 | WizardofWestmarc | no I hadn't |
| 01:38 | durka42 | technomancy: take clojure.core/remove, and change (recur pred (rest coll)) to (rest call) |
| 01:38 | WizardofWestmarc | oh interesting |
| 01:38 | WizardofWestmarc | *bookmarks* |
| 01:38 | durka42 | er, coll |
| 01:38 | blbrown | WizardofWestmarc, might be useful .... http://opennlp.sourceforge.net/README.html |
| 01:38 | technomancy | durka42: of course... thanks |
| 01:38 | technomancy | my brain is slow; glad you caught me before I signed off. =) |
| 01:39 | WizardofWestmarc | already going into my delicious acct, thanks for the tip :) |
| 01:39 | durka42 | :) |
| 01:40 | WizardofWestmarc | and since it's java based... mmm |
| 01:41 | blbrown | there are so many good Java libraries, it is going to take a while for other languages to end up with the same tools |
| 01:41 | blbrown | lucene/nutch/hadoop is my favorite |
| 01:42 | WizardofWestmarc | I want to try out terracata(sp) but have nothing in the pipe that warrants it. |
| 01:42 | technomancy | there's a lot of lousy ones too though unfortunately |
| 01:42 | blbrown | WizardofWestmarc, another good one |
| 01:42 | technomancy | terracotta wins for greatest potential to be a game-changer I think |
| 01:43 | WizardofWestmarc | technomancy: yeah I'd agree with that |
| 01:43 | WizardofWestmarc | especially as multi-core gets more and more common even for end users. Core 2's... the new i7 (which I want in my next desktop) etc |
| 01:43 | blbrown | would only work for server apps, batch processing though. Don't know if would be useful in the desktop realm |
| 01:43 | WizardofWestmarc | depends on what you're doing |
| 01:44 | durka42 | hiredman: it seems like clojurebot's responder methods are dispatched once. can I hand the bot/pojo back to the dispatcher after responding? |
| 01:45 | Puzzler | chouser: are you in charge of seq-utils? |
| 01:45 | durka42 | like, i want the ::deliver-messages responder to be called, but then for clojurebot to do whatever it would have done anyways |
| 01:45 | WizardofWestmarc | actually I wonder if I could do one of my old stand bys for learning a new language with Terracotta, a basic MUD engine heh |
| 01:45 | Chouser | Puzzler: I'm in charge of nothing. :-) |
| 01:45 | Chouser | and Stuart Sierra's name is at the top, so... |
| 01:46 | technomancy | WizardofWestmarc: I'm working on a MUD engine right now. |
| 01:46 | technomancy | it's fun |
| 01:46 | WizardofWestmarc | in clojure? |
| 01:46 | technomancy | WizardofWestmarc: yeah |
| 01:46 | Puzzler | Ok. I've got significantly faster versions of several of those functions. I'll let him know when I get a chance. |
| 01:46 | technomancy | clojurebot: mire? |
| 01:46 | technomancy | oh... he's gone |
| 01:47 | WizardofWestmarc | technomancy: hah nice |
| 01:47 | technomancy | WizardofWestmarc: https://github.com/technomancy/mire/tree |
| 01:47 | technomancy | about to commit some cleanups; hang on |
| 01:47 | WizardofWestmarc | technomancy: you basing the style of commands/etc on any particular existing MUDs? |
| 01:48 | WizardofWestmarc | ROM/ROT/Circle/etc |
| 01:48 | Chouser | Puzzler: great. the google group is the best place to start that sort of conversation. |
| 01:48 | technomancy | WizardofWestmarc: I haven't actually played a real MUD |
| 01:49 | technomancy | WizardofWestmarc: it's just a super-basic explanatory codebase. |
| 01:49 | WizardofWestmarc | technomancy: yet interested enough to write one? Interesting. Most people I know who like to write MUDs used to play them |
| 01:49 | WizardofWestmarc | technomancy: but then I was someone who was heavily into them during college, including helping code updates into one. |
| 01:49 | technomancy | WizardofWestmarc: it's the simplest thing I could think of to write that you still run into interesting concurrency problems with |
| 01:49 | technomancy | apart from a chat app, but that's lame |
| 01:49 | WizardofWestmarc | true |
| 01:50 | WizardofWestmarc | which is part of why I like writing them as well |
| 01:50 | WizardofWestmarc | good threading excercise |
| 01:50 | technomancy | except in this case you don't have to deal with any low-level stuff at all |
| 01:50 | WizardofWestmarc | right |
| 01:50 | technomancy | it's all refs and commute/dosyncs |
| 01:50 | technomancy | once streams get mainlined it'll be even simpler |
| 01:51 | WizardofWestmarc | which is why the idea is so interesting |
| 01:51 | WizardofWestmarc | usually one of my first reactions upon looking at a language is "would that be interesting to write a MUD in" haha |
| 01:52 | technomancy | battery dying; talk to you folks later. |
| 01:53 | Puzzler | What do you guys think of the up-and-coming stream stuff? |
| 01:54 | WizardofWestmarc | it sounds promising |
| 01:55 | WizardofWestmarc | being able to have non-seqed streams to avoid heavy memory use in large lazy constructs is really interesting when you only need one pass over the data |
| 01:55 | hiredman | durka42: you can try |
| 01:56 | durka42 | would i just want to call (responder bot pojo) again at the end of my function? |
| 01:56 | durka42 | after removing the conditions that led to the dispatch to my function |
| 01:56 | Puzzler | WizardofWestmarc: Actually, I think avoiding memory use from lazy constructs can even be useful for multiple passes over persistent but easily computable data. Streams don't really provide that though. But yes, I agree with you. |
| 01:57 | WizardofWestmarc | Puzzler: also true on the easily computable |
| 01:58 | WizardofWestmarc | the single pass is just the first thing I always think of with stream style objects |
| 01:58 | hiredman | durka42: why do you want to feed through the dispatcher twice? |
| 01:58 | durka42 | well, consider: |
| 01:58 | Puzzler | However, I'm not convinced that the Clojure approach to streams as a way of making iteration "more safe" is really necessary. Have you ever heard of anyone's program being buggy because of misusing iterators? |
| 01:58 | durka42 | 1. fred tells clojurebot to deliver a message to bob |
| 01:58 | durka42 | 2. bob comes in and tells clojurebot to deliver a message to fred |
| 01:58 | WizardofWestmarc | not off the top of my head |
| 01:58 | durka42 | 3. clojurebot sees bob and delivers fred's message |
| 01:58 | WizardofWestmarc | but then I don't claim to be highly educated on the specifics |
| 01:59 | durka42 | but since ::deliver-message just got called, ::leave-message is not called and bob's message doesn't get queued |
| 01:59 | Puzzler | I can't think of any time in my own programming life where this kind of encapsulation of iterators would have made any difference. In general, iterators are used in one spot in a program, usually as part of a for loop. |
| 01:59 | WizardofWestmarc | true |
| 01:59 | WizardofWestmarc | although, one interesting case I can think of |
| 01:59 | durka42 | or #2 can be, bob comes in and sends clojurebot ,(+ 2 3) which doesn't get eval'ed because ::deliver-message preempted it |
| 02:00 | WizardofWestmarc | if you have a stream of data that's being pulled across threads |
| 02:00 | Puzzler | I'd love to see an example of where traditional iterators would result in buggy code, but Clojure's approach would make a difference. |
| 02:00 | WizardofWestmarc | that protection could be handy |
| 02:00 | WizardofWestmarc | the stream being used to feed work to the threads |
| 02:01 | WizardofWestmarc | but yes if you create and destroy the iterator inside a small scoping, the issues don't exist |
| 02:04 | Puzzler | I'm very curious to see what kind of mechanisms Rich puts into Clojure to make generating functions easier to write. Python's yield, perhaps? |
| 02:04 | WizardofWestmarc | yield would certainly work |
| 02:04 | WizardofWestmarc | not sure how hard that would be to code with jvm bytecode |
| 02:05 | WizardofWestmarc | but at least from a programmer perspective it always felt elegant in python |
| 02:07 | WizardofWestmarc | perhaps a loop/recur special case/variant would work as well |
| 02:07 | WizardofWestmarc | though I guess you could argue that's same thing as yield |
| 02:13 | hiredman | clojurebot: hiredman? |
| 02:13 | clojurebot | hiredman is an evil genius. |
| 02:13 | hiredman | thats not right |
| 02:13 | hiredman | clojurebot: hiredman? |
| 02:13 | clojurebot | hiredman is lazy |
| 02:13 | hiredman | close enough |
| 02:14 | hiredman | anyone with the clojurebot code, if you notice it spinning in an infinite loop, mea culpa, fix just pushed to github |
| 02:14 | durka42 | hiredman: did my scenario make any sense? |
| 02:14 | hiredman | durka42: sorry, was distracted |
| 02:15 | durka42 | basically, the problem is that clojurebot gets distracted by delivering someone a message and forgets to process what they said |
| 02:15 | hiredman | I am not entirely adverse to the idea of passing through twice, but I think there are otherways to build such a thing |
| 02:16 | hiredman | I think your major problem right now would be that Joins and Parts don't go through dispatch |
| 02:16 | hiredman | (if you plan on deliverying message on join) |
| 02:17 | hiredman | I guess there is no reason they shouldn't |
| 02:17 | hiredman | the plumbing just isn't in place |
| 02:17 | durka42 | yeah, i was thinking i'd have to proxy onJoin |
| 02:20 | hiredman | hmmmm |
| 02:20 | hiredman | goodluck :P |
| 02:21 | durka42 | oh dear, i created an infinite loop |
| 02:21 | durka42 | cbtest left the chat room. (Excess Flood) |
| 02:23 | durka42 | hum, removing the nick from the message queue and calling responder at the end seems to work |
| 02:27 | Chouser | loop on the current method -- doesn't go back through dispatch |
| 02:28 | hiredman | myself and clojurebot are in #clojurebot |
| 02:29 | durka42 | would you like myself and answering-machine-mod-clojurebot to join you? |
| 02:29 | hiredman | you may |
| 02:39 | cads | hey Chouser, do you have a blog? |
| 02:40 | durka42 | blog.n01se.net isn't it |
| 02:40 | cads | I read something on a blog of one of the denizens of this channel, was trying to find the blog again |
| 02:41 | Chouser | yeah, that's right. |
| 02:41 | cads | yup, it was your my path to clojure, where you mention project euler. |
| 02:45 | cads | unrelated to why I wanted to find the article, is it just me that is totally stumped or simply doesn't know enough group theory to know where to begin with the laserbeam problem: http://projecteuler.net/index.php?section=problems&id=202 ? |
| 02:46 | hiredman | ~euler |
| 02:46 | clojurebot | clojure euler is http://clojure-euler.wikispaces.com/ |
| 02:47 | cads | hah! |
| 02:47 | cads | maybe I have to implement an algebraic precision raytracer and post on there |
| 03:13 | cads | oh man |
| 03:13 | cads | I've been looking at that problem for months, and now a near trivial solution dawns on me :P |
| 03:14 | cads | i feel stupid |
| 04:16 | Kerrisleep | cads: never underestimate the power of your subconscious mind :P |
| 04:20 | Puzzler | Who started the clojure-euler wiki? |
| 04:21 | Puzzler | Every other project euler wiki I've seen adheres to the spirit of Project Euler by protecting the solutions and revealing only to people who have solved the problems. |
| 04:21 | hiredman | http://clojure-euler.wikispaces.com/space/about |
| 04:51 | Lau_of_DK | Morning gents |
| 04:53 | Chousuke | Puzzler: the clojure euler wiki is dynamic! it lets you shoot yourself in the foot if you so wish :) |
| 04:55 | Puzzler | Chousuke: Yes, I see that. I think it's uncool to give away the answers. But I think the tools section of the wiki is a great idea. |
| 05:13 | cads | plus, if random people learn clojure to translate the solutions, isn't that just good exposure? |
| 05:16 | cads | certain of the problems in project euler are inaccessible, a tiered forum where discussion of relevant literature was visible to the unsolved public would be nice |
| 05:16 | hiredman | oh |
| 05:16 | hiredman | hey |
| 05:16 | hiredman | guys |
| 05:16 | hiredman | I had an idea |
| 05:17 | hiredman | maybe I should wait for rhickey |
| 05:17 | hiredman | but I won't |
| 05:17 | hiredman | instead of (scope ...) it should be (horizon ...) |
| 05:18 | hiredman | so we can steal and repurpose various blackhole terminology |
| 05:18 | hiredman | something conditions that depend on horizon, called outside of a horizon would be "naked" |
| 05:18 | hiredman | something with |
| 05:20 | cads | .. enough charge and rotational intertia would create a wormhole out of this universe |
| 05:20 | cads | ? |
| 05:20 | hiredman | horizons would hide icky io stuff |
| 05:21 | hiredman | still jhave the figure out what the "wormhole" analogue would be |
| 05:21 | cads | we still have to explain how particles that pass the horizon go off onto spacelike trajectories and lose touch with the rest of spacetime |
| 05:22 | cads | and the hawkings radiation, maybe leaky abstraction? |
| 05:23 | hiredman | cads: have you seen the (scope ...) stuff? |
| 05:24 | cads | I haven't, so I am a little out of the loop |
| 05:24 | hiredman | http://paste.lisp.org/display/73838 |
| 05:24 | cads | but i do know blackhole spacetime |
| 05:24 | hiredman | (scope ...) is a new thing rhickey is working on |
| 05:26 | hiredman | cads: so we can mine you for terms if this horizons thing takes off |
| 05:27 | cads | I tend to stretch analogies till they break :D |
| 05:27 | hiredman | clojurebot: scope is <reply> itym horizon |
| 05:27 | clojurebot | Roger. |
| 05:28 | cads | so if you think you'd need a concept of blueshifted external variables, consult me :D |
| 05:29 | hiredman | do you buy this new fangled "naked singularities may be possible" stuff? |
| 05:32 | cads | the solutions are there in the equations, I've see a simulation of the gravity waves that'd be coming off of a naked singularity. it's awe inspiring |
| 05:33 | cads | I forgot if there were perverse/uncomfortable consequences to them existing |
| 05:34 | cads | I think a naked singularity would tend to allow causality to be violated |
| 05:35 | cads | I'm not so sure about how those spacetimes look |
| 05:35 | cads | I wouldn't be shocked if such things could exist |
| 05:39 | cads | I forgot the motivation for the cosmic censorship hypothesis, but there are a lot of scientists who think the universe would not allow a singularity to be visible to the rest of the universe |
| 05:39 | hiredman | I happen to have an illustrated guide, thanks to this months sciam |
| 05:40 | cads | it seems a little silly |
| 05:41 | cads | but yeah, been simulations of it for a while. Wierd things happen, though, stuff that a theory of quantum gravity would probably explain more decisively |
| 05:42 | hiredman | seems like one of those would be useful |
| 05:42 | cads | I want for hyper exotic physics like that (holes to other universe, cmon!) to exist, how about you? |
| 05:43 | hiredman | sounds fun to me |
| 05:43 | hiredman | I think I'll need a singularity for my tardis |
| 05:47 | cads | hmm |
| 05:48 | cads | it seems like a main motivation behind the idea of no nakid singularities is the strong desire on the part of certain physicists for a universe that is deterministic |
| 05:49 | cads | also of concern would be much worse violations of causality, but I'd say that since our time on the whole seems pretty consistent, if naked singularities do exist they don't mess with time at a long range |
| 05:50 | hiredman | shows what you know |
| 05:50 | hiredman | :P |
| 05:50 | cads | what do you mean? |
| 05:51 | hiredman | "but I'd say that since our time on the whole seems pretty consistent" |
| 05:51 | hiredman | sure |
| 05:51 | hiredman | "seems" |
| 05:52 | cads | yeah, the seeming consistency of time could be an illusion our brain manufactures, to varying degrees |
| 05:53 | cads | but physics (again, seems to) have strong predictive power |
| 05:54 | cads | it could be that the inconsistent physics that happens instinctively stays away from scientific experiments for fear of being found out :D |
| 05:54 | cads | but it could explain nonsensical stuff humans come up with |
| 05:54 | cads | ... like this conversation at 5 am in the morning hehe |
| 06:03 | cads | does anyone maintain a deb package containing clojure? |
| 08:38 | pjb3 | Is there a function that will tell you if a symbol is "defined" (I know that's not the right term, but you know what I mean) |
| 08:39 | kotarak | maybe resolve? I returns nil if there is no Var of that name. |
| 08:39 | kotarak | s/I/It |
| 08:40 | pjb3 | user=> (resolve? x) |
| 08:40 | pjb3 | java.lang.Exception: Unable to resolve symbol: resolve? in this context (NO_SOURCE_FILE:3) |
| 08:40 | pjb3 | ,(resolve? x) |
| 08:40 | clojurebot | java.lang.Exception: Unable to resolve symbol: resolve? in this context |
| 08:40 | kotarak | resolve |
| 08:40 | kotarak | without ? |
| 08:40 | pjb3 | ,(resolve x) |
| 08:40 | clojurebot | java.lang.Exception: Unable to resolve symbol: x in this context |
| 08:40 | pjb3 | ,(resolve 'x) |
| 08:40 | clojurebot | nil |
| 08:40 | hoeck | pjb3: (ns-resolve *ns* 'foo) |
| 08:40 | kotarak | The ? was form my sentence. Maybe "resolve"? |
| 08:40 | kotarak | ;) |
| 08:40 | pjb3 | kotarak: gotcha |
| 08:41 | pjb3 | ,(doc some) |
| 08:41 | clojurebot | "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return true if :fred is in the sequence, otherwise nil: (some #{:fred} coll)" |
| 08:41 | pjb3 | (some #(resolve %) ['a 'b 'c]) |
| 08:41 | pjb3 | ,(some #(resolve %) ['a 'b 'c]) |
| 08:41 | clojurebot | nil |
| 08:41 | pjb3 | (some #(resolve %) ['a 'b 'str 'c]) |
| 08:42 | pjb3 | ,(some #(resolve %) ['a 'b 'str 'c]) |
| 08:42 | clojurebot | #'clojure.core/str |
| 08:42 | pjb3 | ,(reduce #(resolve %) ['foo 'str 'bar 'map]) |
| 08:42 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--551$fn |
| 08:44 | pjb3 | ,(filter #(resolve %) ['foo 'str 'bar 'map]) |
| 08:44 | clojurebot | (str map) |
| 08:48 | karmazilla | ,(filter resolve ['foo 'str 'bar 'map]) |
| 08:48 | clojurebot | (str map) |
| 09:09 | pjb3 | ,(filter resolve '(foo str bar map)) |
| 09:09 | clojurebot | (str map) |
| 09:14 | pjb3 | ,(for [[k v] {:x 1 :y 2}] (str (name k) "=" v)) |
| 09:14 | clojurebot | ("x=1" "y=2") |
| 09:14 | pjb3 | I just figured out that you can do that. Yay! |
| 09:22 | AWizzArd | Moin moin |
| 09:23 | hoeck | AWizzArd: moin :) |
| 10:46 | blbrown | wonder if it is bad clojure practice to put all my 'java imports' in one file (import ....) with a bunch of imports |
| 10:50 | kotarak | I'm not sure I understand you correctly. The imports for a namespace shoud go to the corresponding (ns ... (:import ..)). |
| 10:51 | blbrown | kotarak, OH, oops. I have a file call 'imports.clj' And I include all my import calls in there and then do '(load 'imports.clj') at the imports call |
| 10:52 | blbrown | isn't it the same thing |
| 10:53 | kotarak | Do you have problems with this style? |
| 10:53 | blbrown | kotarak, yours or mine. I don't have any with mine because I can just add imports to a file when needed |
| 10:54 | kotarak | "isn't it the same thing" sounded like some unexpected effect. |
| 10:56 | kotarak | blbrown: you can organise your source however you like... If it works for you... |
| 12:11 | pjb3 | ,(defn #^{:test (fn [] (assert (= 41 (foo))))} foo [] 42) |
| 12:11 | clojurebot | DENIED |
| 12:11 | pjb3 | lame |
| 12:12 | pjb3 | Anyway, when I define that foo function, and then run (test foo), it says no-test |
| 12:12 | pjb3 | What am I missing? |
| 12:15 | pjb3 | Ah, (test (var foo)) |
| 12:19 | Chouser | rhickey: I think definline has been broken since rev 1065, along with the 'ints', 'longs', etc. |
| 12:19 | Chouser | tries to print a closure |
| 12:29 | pjb3 | So when you have a failing assertion in a test |
| 12:30 | pjb3 | It prints something like Assert failed: (= 42 (f x)) |
| 12:30 | kotarak_ | Well. It throws an exception. |
| 12:30 | pjb3 | yeah, right and that's the name of the expcetion |
| 12:31 | pjb3 | What I'm wondering is there a way to get it to print (= 42 1) |
| 12:31 | pjb3 | Or Assert failed: (= 42 (f x), expected 42, got 41 |
| 12:32 | pjb3 | I suppose I could do that with a macro |
| 12:32 | pjb3 | assert-equals 42 (f x) |
| 12:32 | kotarak_ | You'll need test-is, fact or clojurecheck for that, I guess. |
| 12:32 | Chouser | there are other testing frameworks around that have had a good deal more work put into them than the builting 'test' function |
| 12:33 | cooldude127 | i wonder if it's productive to try implementing my data structures homework in clojure before i do it in java. maybe it will be easier to understand that way |
| 12:33 | kotarak_ | cooldude127: I would be careful with translating between languages.... Especially if the general mindset is so different. |
| 12:33 | Chouser | cooldude127: it seems likely your homework will rely on and/or build mutable things that will be require rather non-idiomatic Clojure code. |
| 12:34 | cooldude127 | kotarak_: i think it might be easier to understand the recursive algorithms at first without java's baggage |
| 12:34 | Chouser | I'm sure you can do it, but it might not end up looking much better than the Java you would have had to write. |
| 12:34 | cooldude127 | Chouser: i have to write the java anyway, it's just hard when writing the java to understand what i'm doing |
| 12:37 | Hun | i second doing it in a lisp first. that helps me a lot when developing in vhdl :) |
| 12:38 | pjb3 | Is there a function in clojure that already does this? (defn to-s [o] (if (keyword? o) (name o) (str o))) |
| 12:38 | cooldude127 | what would be the best way to represent tree nodes? a map with :data, :left, :right keys or a list? |
| 12:38 | pjb3 | Do you find yourself having to do that alot? |
| 12:38 | cooldude127 | pjb3: not that much. i usually know what i'm expecting, and just use one of the two |
| 12:39 | pjb3 | For example, I'm writing a function that produces an XML/HTML tag |
| 12:39 | pjb3 | so (tag :p "foo") # => "<p>foo</p>" |
| 12:40 | pjb3 | In designing the API, my thought is why not let people use a string for the tag name if they want to |
| 12:40 | pjb3 | (tag "p" "foo") # => "<p>foo</p>" |
| 12:40 | cooldude127 | cuz strings are evil? |
| 12:40 | cooldude127 | lol |
| 12:40 | pjb3 | Hence the need for the to-s |
| 12:41 | pjb3 | This probably shows the Rubyist in me |
| 12:41 | Chouser | I like :foo#bar.baz => "<foo id="bar" class="baz" />" |
| 12:41 | cooldude127 | i don't think it exists already, but it looks like the right thing for you |
| 12:41 | cooldude127 | Chouser: i can't believe that's a valid symbol |
| 12:41 | pjb3 | Chouser: Yeah, it will do that |
| 12:42 | Chouser | pjb3: there are libs that do that already. I don't know how heavy they are, though. |
| 12:42 | Chouser | ,(prn :foo#bar.baz) |
| 12:42 | clojurebot | :foo#bar.baz |
| 12:42 | pjb3 | But should I allow (tag "foo#bar.baz") as well? |
| 12:42 | pjb3 | In ruby, almost takes a symbol (what is called a keyword in Clojure) or a string |
| 12:43 | pjb3 | And just does arg.to_s in the body of the method |
| 12:43 | Chouser | pjb3: if you want, but that kind of conversion isn't terribly common outside specific DSLs like what you're building. |
| 12:43 | pjb3 | but in Ruby, :foo.to_s # => "foo" |
| 12:44 | Chouser | pjb3: (str :foo) does return a string, as I'm sure you've noticed, you just don't like the format for your particular usage. Seems pretty application-specific to me. |
| 12:45 | pjb3 | Chouser: yeah, and it's easy enough to write that to-s method to deal with it, I'm just wondering if everyone else ends up writing that same method |
| 12:45 | pjb3 | I guess not |
| 12:45 | pjb3 | Now we'll forever know which Clojure programmers are Ruby programmers |
| 12:45 | cooldude127 | haha |
| 12:46 | pjb3 | The ones that write to-s and use it in their code are :) |
| 12:46 | Chouser | I think there have been requests for 'name' to do something useful with strings, but I also think those have been shot down. |
| 12:47 | pjb3 | Yeah, that's what I figured, there's no reason to have (name "foo") not return "foo", other than syntactic vinegar |
| 12:47 | pjb3 | So I realized that I must be "Doing it wrong" in the eyes of Clojurians |
| 12:56 | pjb3 | test-is, very nice |
| 12:58 | dnolen | question on making multidimensional Float arrays in clojure. I understand that (def v1 (make-array (. Float TYPE) 2)) creates an float array. But do I make a container java array to hold them in clojure? |
| 13:01 | Chouser | dnolen: I don't think I understand the question. v1 names a Var that is acting as a sort of container for the array. what else do you need? |
| 13:01 | dnolen | Chouser: sorry for not being clear. How do you translate float[][] into Clojure?, i understand float[] |
| 13:02 | Chouser | ah, I see. |
| 13:02 | Chouser | ,(make-array Float/TYPE 10 10) |
| 13:02 | clojurebot | #<float[][] [[F@100aff5> |
| 13:03 | Chouser | that's a 10x10 array of float |
| 13:04 | dnolen | Chouser: nice, thanks, dur, I should have thought to check the sig of make-array. the answer in Clojure is so often so dead simple, it's surprising ;) |
| 13:04 | Chouser | :-) |
| 13:46 | pjb3 | Is there clojure function that takes a predicate function and returns a function that is the opposite of that? |
| 13:47 | pjb3 | ,(filter #(not (nil? %)) [1 nil 2 3 nil]) |
| 13:47 | clojurebot | (1 2 3) |
| 13:47 | pjb3 | ,(filter % [1 nil 2 3 nil]) |
| 13:47 | clojurebot | Eval-in-box threw an exception:arg literal not in #() |
| 13:47 | pjb3 | complement |
| 13:48 | pjb3 | ,(filter (complement nil?) [1 2 nil 3 nil]) |
| 13:48 | clojurebot | (1 2 3) |
| 13:49 | pjb3 | hmm..it's such a long word that is shorter to do #(not (f %)) than (complement f) |
| 13:49 | pjb3 | I guess it's more readable though |
| 13:51 | pjb3 | ,((complement filter) nil? [1 nil 2]) |
| 13:51 | clojurebot | false |
| 13:52 | pjb3 | I understand the idea of not having the complement of every predicate function defined, but some of the basic ones might be nice |
| 13:52 | pjb3 | (filter not-nil? [1 nil 2]) |
| 13:53 | pjb3 | ,(remove nil? [1 nil 2]) |
| 13:53 | clojurebot | (1 2) |
| 13:53 | pjb3 | ok, I guess that's the way to do it |
| 13:56 | durka42 | ,(filter identity [1 nil 2]) |
| 13:56 | clojurebot | (1 2) |
| 14:00 | pjb3 | ,(first nil) |
| 14:00 | clojurebot | nil |
| 14:00 | pjb3 | I like that that returns nil instead of throwing an exception |
| 14:02 | cooldude127 | yeah that is the right behavior imo |
| 14:02 | WizardofWestmarc | hm, getting a null pointer exception on this inner/outer loop construct and I can't figure out why. |
| 14:02 | WizardofWestmarc | http://paste.lisp.org/display/74161 |
| 14:02 | WizardofWestmarc | (doing project euler stuff) |
| 14:03 | danlarkin | without looking at the code I bet I know why! |
| 14:03 | WizardofWestmarc | shoot |
| 14:03 | danlarkin | but now I'll look to make sure :) |
| 14:03 | WizardofWestmarc | I'm probably doing osmething silly that I'll kick myself for once you point it out |
| 14:03 | WizardofWestmarc | *something |
| 14:04 | danlarkin | oh god no indenting |
| 14:04 | durka42 | see annotation |
| 14:04 | durka42 | not sure why it wasn't announced |
| 14:05 | WizardofWestmarc | yeah my emacs setup doesn't indent some reason. |
| 14:05 | jbondeson | give me some exmples to call this on |
| 14:05 | WizardofWestmarc | (used clojure box) |
| 14:05 | jbondeson | you don't have tab bound probably |
| 14:06 | danlarkin | ok, so the problem is indeed what I suspected |
| 14:06 | danlarkin | your (recur (rest outerlist)) is unchecked |
| 14:06 | danlarkin | it will always fire |
| 14:06 | WizardofWestmarc | oh |
| 14:06 | WizardofWestmarc | duhhh |
| 14:07 | dreish | It looks like both recurs are unchecked. |
| 14:07 | jbondeson | bad wiz |
| 14:07 | danlarkin | man I'm so good, I can debug code without even looking at it! |
| 14:07 | durka42 | danlarkin, clojure guru |
| 14:07 | danlarkin | hardly |
| 14:07 | dreish | Putting the first one on the same line as the conj makes the code much harder to read. |
| 14:08 | danlarkin | yeahhhh |
| 14:08 | dreish | In general, I try not to put anything on a line after a closing paren other than other closing parens, unless I'm sure it'll make the code easier to read. |
| 14:09 | danlarkin | this is useful, albeit too long to skim: http://mumble.net/~campbell/scheme/style.txt |
| 14:27 | dnolen | is there an existing functions for unwrapping Java arrays into Clojure vectors? I have one, but wondering if there's a tested one in conrib that I can use. I didn't see anything like this core. |
| 14:29 | kotarak | maybe (into [] the-array)? Or (vec array)? |
| 14:30 | dnolen | java arrays can't be treated as collections from what I can tell. |
| 14:30 | dnolen | oops wrong |
| 14:30 | dnolen | kotarak, that's right |
| 14:30 | dnolen | (vec array) |
| 14:31 | dnolen | thanks |
| 14:31 | kotarak | Ok. Good to know. :) (Was just a guess) |
| 15:17 | danlarkin | Lau_of_DK: ping |
| 15:17 | Lau_of_DK | pong |
| 15:18 | Lau_of_DK | danlarkin: I said PONG! :) |
| 15:18 | danlarkin | haha |
| 15:18 | kotarak | Lau_of_DK: Uh? I didn't know you are a bot! |
| 15:19 | danlarkin | how does "syrinx" sound? :) |
| 15:19 | Lau_of_DK | It sounds like the needle byw hich you can get an ebola vaccination, why ? |
| 15:19 | Lau_of_DK | ooh, you meant as an alternative to Cladjango ? :) |
| 15:19 | danlarkin | yes |
| 15:20 | durka42 | hey, if clojure cures highly infectious diseases i'm ok with that |
| 15:20 | Lau_of_DK | How did you come up with it? Any special meaning? |
| 15:20 | Lau_of_DK | durka durka? |
| 15:20 | durka42 | hmm? |
| 15:21 | danlarkin | it's a movement from 2112, a song by Rush :) |
| 15:21 | danlarkin | well, the movement is "The Temples of Syrinx" |
| 15:21 | Lau_of_DK | ah... |
| 15:21 | Lau_of_DK | danlarkin: I think, that you should keep thinking about it, but thats just my oppinion :) |
| 15:22 | danlarkin | :( |
| 15:26 | Lau_of_DK | Its because, I think you should find a name which reflects the awesome power of the framework you provide, like Skynet, or Webtrix :) |
| 15:27 | durka42 | i suggest that you do not call it Clojure on Clotheslines |
| 15:27 | danlarkin | gross |
| 15:28 | danlarkin | suggestion accepted |
| 15:35 | pjb3 | Why is there a defn- but no def- |
| 15:35 | pjb3 | ? |
| 15:40 | Lau_of_DK | danlarkin: Did you Gitit yet ? |
| 15:40 | danlarkin | Lau_of_DK: first I've gotta think of a good name! |
| 15:40 | dnolen | what's the fastest accessor for vectors? first/second seem kind of slow in maps. |
| 15:40 | pjb3 | danlarkin: a good name for what? |
| 15:41 | danlarkin | pjb3: a django clone/port/rewrite in clojure |
| 15:41 | danlarkin | django-esque |
| 15:41 | Lau_of_DK | danlarkin: How about "DynaWeb" ? :) |
| 15:41 | pjb3 | Reinhardt? |
| 15:44 | pjb3 | cljango? |
| 15:45 | danlarkin | eh |
| 15:46 | jpease | clojure on djangos |
| 15:46 | kotarak | cljango - no one serves faster |
| 15:47 | jpease | clojangure |
| 15:47 | Lau_of_DK | lol |
| 15:48 | rryan | if you want a django-esque name, you should go with some other famous jazz musician's name. Miles Davis? John Coltrane? Herbie Hancock? Coltrane or Trane is nice. |
| 15:48 | Lau_of_DK | That sounds like a type of monkey |
| 15:48 | pjb3 | I like coltrane too |
| 15:48 | pjb3 | Has a c and l in it too |
| 15:49 | rryan | wikipedia says he also went by 'Trane', which would be kind of railsey |
| 15:49 | pjb3 | Without being a ridiculous name like cljango :) |
| 15:49 | rryan | right :) |
| 15:50 | gnuvince_ | Is there a function in SLIME to modify an entry in slime-lisp-implementations or do I need to manually delete the old entry and put in a new one? |
| 15:50 | Lau_of_DK | danlarkin: How about "Easy web" "Dynamic web" "LispyWeb" "dotClojure" "Barkin' Larkin'" ? |
| 15:50 | pjb3 | How about ((((((django)))))))) |
| 15:50 | Hun | gnuvince_: just edit and C-M-x it |
| 15:50 | Hun | pjb3: that's a whole lot of indirections :) |
| 15:52 | rryan | hm, for reference, here's Jacob Kaplan-Moss's list of names that "Django" almost was: http://jacobian.org/writing/private_dancer/ |
| 15:52 | danlarkin | sorry guys, brb :-o |
| 15:53 | rryan | they're all fairly bad :) |
| 15:53 | pjb3 | tornado FTW! |
| 15:53 | durka42 | siljouette |
| 15:54 | rryan | siljouette is nice |
| 15:55 | Lau_of_DK | durka durka |
| 15:55 | jpease | i guess that's better than garbonjo |
| 15:56 | durka42 | yes Lau? |
| 15:56 | Lau_of_DK | durka, is your nick taken from Team America ? |
| 15:57 | durka42 | more or less, it rhymes with my real name |
| 15:57 | Lau_of_DK | oh.. Because when ever I see it, I think "durka durka" with a funny accent |
| 15:58 | durka42 | :) |
| 16:05 | Lau_of_DK | So whats your idea Karma? |
| 16:07 | karmazilla | figure out which qualities sets this framework apart from the rest, and then try brain-storming again with that in mind |
| 16:08 | Lau_of_DK | So youre saying we should stick with "Barkin' Larkin'" ? |
| 16:09 | rryan | it's hard to know what sets it apart before its written |
| 16:09 | Lau_of_DK | Django is pretty well defined rryan :) |
| 16:12 | hiredman | did y'all see my scope renaming idea? |
| 16:12 | hiredman | http://clojure-log.n01se.net/date/2009-01-24.html#05:16 |
| 16:15 | Lau_of_DK | Yep hiredman |
| 16:16 | durka42 | i like it |
| 16:19 | karmazilla | Naked singularities? Way over my head, though I get a vibe from the conversation that his Noodliness might be playing with the physicists again. :) |
| 16:21 | hiredman | the idea is we just steal the blackhole/event horizon terminology for (scope ...) |
| 16:22 | durka42 | nothing can escape from a horizon |
| 16:45 | danlarkin | boltdozer is an attractive name |
| 16:45 | danlarkin | hahah |
| 16:46 | danlarkin | Hmmm Trane is kinda cool.... |
| 16:54 | hiredman | neat |
| 16:54 | hiredman | comp works with keywords |
| 16:58 | pjb3 | ,(def i 0) |
| 16:58 | clojurebot | DENIED |
| 16:59 | pjb3 | If I have this: |
| 16:59 | pjb3 | (def i 0) |
| 16:59 | pjb3 | (defn f [x] (binding [i (+ i 2)] (println "i: " i) x)) |
| 16:59 | pjb3 | (f (f (f 1))) |
| 16:59 | pjb3 | Shouldn't that print increasing values for i? |
| 17:01 | pjb3 | no, it shouldn't :) |
| 17:04 | durka42 | no, because i is never modified |
| 17:04 | durka42 | and x is never used |
| 17:05 | pjb3 | Yeah, the reason I never changes is that the function isn't recursive so the binding of i just goes from 0 to 2 and back to 0 with each invocation of f |
| 17:05 | pjb3 | (defn f [x] (binding [i (+ i 2)] (println "i: " i) (if (> x 0) (f (dec x)) nil))) |
| 17:05 | karmazilla | (defmacro f [x] `(binding [i (+ i 2)] (println "i: " i) ~x)) :p |
| 17:06 | Chousuke | that function prints 2 and returns x, which is always 1 |
| 17:06 | Chousuke | so you basically call (f 1) thrice |
| 17:07 | pjb3 | Right, if you call the second f with (f 3), the bindings start doing stuff |
| 17:10 | danlarkin | http://en.wikipedia.org/wiki/Trane Trane seems to be taken |
| 17:34 | gnuvince_ | Does anyone know if there's a delay between pushing to github and seeing the change in the repo page? |
| 17:34 | danlarkin | gnuvince_: always been instant for me |
| 17:35 | gnuvince_ | danlarkin: check this out: |
| 17:35 | gnuvince_ | http://github.com/gnuvince/clojure-greatest-least/tree/master |
| 17:35 | gnuvince_ | See that it's from 16 hours ago? |
| 17:35 | danlarkin | yes |
| 17:35 | Chousuke | gnuvince_: are you sure you pushed it? :) |
| 17:36 | gnuvince_ | Now look here: http://github.com/gnuvince |
| 17:36 | gnuvince_ | See that I pushed changes not 10 minutes ago? |
| 17:37 | Chousuke | weird. :/ |
| 17:38 | gnuvince_ | Indeed |
| 17:38 | gnuvince_ | And if you clone the repo, you'll get the changes I just pushed. |
| 17:38 | Chousuke | I and you can get to them via the hash |
| 17:38 | gnuvince_ | Yes |
| 17:38 | gnuvince_ | But it should be my HEAD, should it not? |
| 17:39 | Chousuke | I suppose |
| 17:39 | Chousuke | might want to drop a mail to the github admins. |
| 17:45 | danlarkin | stop by #github |
| 17:45 | danlarkin | I've always received a quick response in there |
| 17:48 | gnuvince_ | Asking now |
| 19:17 | erohtar_ | danlarkin: are u here? |
| 19:18 | erohtar_ | does anyone know what kind of content clojure-json can parse from a file? im having some trouble reading what i think is valid json |
| 19:37 | danlarkin | erohtar_: ping |
| 20:33 | eee | hiyuz |
| 20:45 | eee | i had a macro in mind |
| 20:45 | eee | if anyone thinks it might be fun to teach how that works |
| 20:45 | eee | will put it to the test |
| 20:45 | eee | "whenever" |
| 20:46 | durka42 | to teach what |
| 20:46 | eee | is what it is |
| 20:46 | eee | how to make a macro |
| 20:47 | eee | it would be shorter than doing "loop" ...if ... recur |
| 20:47 | durka42 | well, a macro is basically a function that returns a list, that is evaluated as code |
| 20:47 | eee | oh |
| 20:48 | hiredman | ,(doc doseq) |
| 20:48 | clojurebot | "([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil." |
| 20:48 | eee | i was thinking a macro is what you did when you want to define a new "form" . . .not just a new function |
| 20:48 | durka42 | well, arguments to macros are not evaluated |
| 20:49 | eee | ok |
| 20:49 | durka42 | so i could write a macro safe-math and then call (safe-math (/ 1 0)) |
| 20:49 | durka42 | safe-math could check for division by zero and choose not to run that |
| 20:49 | eee | but the reason for a macro . . . betfore getting into what it is . . .is to, like, define a new syntax, sort of . . .a new keyword or pattern of keywords, right? |
| 20:50 | hiredman | a keyword is like :foo |
| 20:50 | eee | thats a key |
| 20:50 | eee | i thought |
| 20:50 | hiredman | so I know what you mean, but you should be careful |
| 20:50 | eee | ok |
| 20:50 | eee | so safe-math |
| 20:50 | hiredman | no, that is a datatype called a keyword |
| 20:50 | eee | that could just be a function |
| 20:50 | eee | with an if statement |
| 20:51 | hiredman | eee: no |
| 20:51 | eee | oh |
| 20:51 | eee | i get it |
| 20:51 | eee | nice example |
| 20:51 | eee | you guys are really smart |
| 20:51 | eee | :) |
| 20:52 | eee | it allows you to look at a list as a bunch of tokens and decide what to do with them. Otherwise it would evaluate the list by assuming the first arg is a function |
| 20:52 | eee | and you don't have to quote the list |
| 20:53 | eee | i was thinking (safe-math '(/ 1 0)) |
| 20:53 | hiredman | exactly |
| 20:54 | eee | seems like better documentation to make my function than yours |
| 20:54 | eee | my function lets you know that I have a chance to do whatever I want with that list |
| 20:55 | hiredman | *shrug* |
| 20:55 | eee | your function requires documentation to get that point across |
| 20:55 | durka42 | (defmacro safe-math [expr] (if (and (= '/ (first expr)) (some zero? (rest expr))) "careful!" expr)) |
| 20:56 | hiredman | eee: or you just say "any math inside done inside safe math is checked for unsafe operations" |
| 20:56 | hiredman | and the user of safe math doesn't need to know the details of how it is checked |
| 20:56 | eee | ok, so clojure relies on good documentation |
| 20:56 | hiredman | this is not a matter of documentation |
| 20:57 | hiredman | this is how computers are made to work |
| 20:57 | hiredman | abstraction and combination |
| 20:58 | eee | how would I see safe math in an API? |
| 20:58 | eee | (safe-math x)? |
| 20:58 | eee | without the question mark |
| 20:58 | hiredman | that seems reasonable to me |
| 20:58 | hiredman | on the otherhand, on clojure.org/api things that are macros are labeled as such |
| 20:59 | eee | ok |
| 20:59 | durka42 | if you call (safe-math (+ 2 3)) you get 5, but if you call (safe-math (/ 1 0)) you get "careful!") |
| 20:59 | hiredman | clojurebot: seen spooneybarger |
| 20:59 | clojurebot | spooneybarger was last seen joining #clojure, 1 minutes ago |
| 20:59 | hiredman | :P |
| 20:59 | eee | i'm letting this sink in some |
| 20:59 | durka42 | aha! you _have_ been playing with onJoin! |
| 21:00 | durka42 | all right, i have to go |
| 21:00 | durka42 | don't divide by zero |
| 21:00 | eee | ok |
| 21:00 | eee | thanks |
| 21:00 | hiredman | ,(/ 1 0) |
| 21:00 | clojurebot | java.lang.ArithmeticException: Divide by zero |
| 21:00 | durka42 | hey! |
| 21:01 | eee | ,(print '(/ 1 2)) |
| 21:01 | clojurebot | (/ 1 2) |
| 21:01 | eee | ok |
| 21:01 | eee | what I thought |
| 21:02 | eee | now how could I go from that list to get it to execute the first item |
| 21:02 | hiredman | eval |
| 21:02 | hiredman | ,(doc eval) |
| 21:02 | clojurebot | "([form]); Evaluates the form data structure (not text!) and returns the result." |
| 21:02 | eee | ,(print eval '(/1 2) |
| 21:02 | clojurebot | Eval-in-box threw an exception:Invalid token: /1 |
| 21:02 | eee | oops |
| 21:02 | eee | meant to back up |
| 21:02 | hiredman | clojurebot does not allow eval |
| 21:03 | eee | ,(print (eval '(/1 2))) |
| 21:03 | clojurebot | Eval-in-box threw an exception:Invalid token: /1 |
| 21:04 | hiredman | so the idea is read turns text like "(/ 1 3)" into a data structure like (list '/ 1 3) |
| 21:05 | hiredman | ,(list '/ 1 3) |
| 21:05 | clojurebot | (/ 1 3) |
| 21:06 | hiredman | and eval takes that data structure (a list) and applies the first item in the list to the rest of the list |
| 21:06 | eee | (print (eval '(/ 1 2))) works in my repl |
| 21:06 | eee | so |
| 21:06 | hiredman | it should |
| 21:06 | eee | I can define (safe-math x) but mine expects a quoted list |
| 21:06 | hiredman | ,(let [[function & args] (list '/ 1 3)] function) |
| 21:06 | clojurebot | / |
| 21:06 | eee | how would you know that |
| 21:06 | hiredman | ,(let [[function & args] (list '/ 1 3)] (apply function args)) |
| 21:06 | clojurebot | 3 |
| 21:07 | eee | I could write it as a regular definition |
| 21:07 | hiredman | er |
| 21:07 | hiredman | ,(/ 1 3) |
| 21:07 | clojurebot | 1/3 |
| 21:07 | hiredman | hmmmm |
| 21:08 | hiredman | ,(let [[function & args] (list '/ 1 3)] args) |
| 21:08 | clojurebot | (1 3) |
| 21:08 | hiredman | ,(let [[function & arction args)) |
| 21:08 | clojurebot | Eval-in-box threw an exception:Unmatched delimiter: ) |
| 21:08 | hiredman | ,(let [[function & args] (list '/ 1 3)] (apply function args)) |
| 21:08 | clojurebot | 3 |
| 21:09 | hiredman | ,(let [[function & args] (list '/ 1 3)] (apply (var function) args)) |
| 21:09 | clojurebot | java.lang.Exception: Unable to resolve var: function in this context |
| 21:09 | hiredman | ,(var '/) |
| 21:09 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol |
| 21:09 | hiredman | ,(var `/) |
| 21:09 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol |
| 21:09 | hiredman | ,(var /) |
| 21:09 | clojurebot | #'clojure.core// |
| 21:10 | hiredman | ,(let [[function & args] (list '/ 1 3)] (apply @function args)) |
| 21:10 | clojurebot | java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.IRef |
| 21:10 | hiredman | hmmm |
| 21:10 | hiredman | ah |
| 21:11 | eee | i'm struggling with this editor |
| 21:11 | ayrnieu | ,(let [[function & args] [/ 1 3]] (apply function args)) |
| 21:11 | clojurebot | 1/3 |
| 21:12 | hiredman | ayrnieu: cheater |
| 21:12 | hiredman | ,(let [[function & args] (list / 1 3)] (apply function args)) |
| 21:12 | clojurebot | 1/3 |
| 21:13 | hiredman | eee: what editor? |
| 21:13 | ayrnieu | ,(let [[function & args] '(/ 1 3)] (apply function args)) |
| 21:13 | clojurebot | 3 |
| 21:14 | eee | anyway |
| 21:14 | eee | this is what I could write: (defn safe-math [quoted-operation-and-params] (first quoted-operation-and-params)) |
| 21:14 | eee | that's not it |
| 21:14 | eee | cut and paste not working |
| 21:14 | eee | arg!!!!! |
| 21:14 | hiredman | lisppaste8: url? |
| 21:14 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 21:14 | hiredman | paste there |
| 21:14 | hiredman | if it is 3 more then three lines |
| 21:15 | ayrnieu | (defmacro safe-math [expr] (let [e (gensym)] `(try ~expr (catch java.lang.ArithmeticException ~e "careful!")))) (safe-math (/ (- 1 1))) => "careful!" |
| 21:15 | lisppaste8 | eee pasted "untitled" at http://paste.lisp.org/display/74187 |
| 21:16 | eee | so basically |
| 21:16 | eee | I didn't need a macro |
| 21:16 | eee | but you'd have to know |
| 21:16 | hiredman | uh |
| 21:16 | eee | to send in a quoted thing |
| 21:16 | hiredman | you still don't under stand |
| 21:16 | hiredman | understand |
| 21:16 | eee | you'd use it like this (safe-math '(/ 1 2)) |
| 21:17 | eee | and I argue that that is much better |
| 21:17 | eee | because it is self documenting |
| 21:17 | hiredman | well |
| 21:17 | hiredman | you are wrong |
| 21:17 | eee | that the callee obviosly has a chance to validate |
| 21:17 | ayrnieu | but you could not say (let [x 2] (safe-math '(/ 1 x))) |
| 21:18 | eee | sure I could |
| 21:18 | ayrnieu | compare with mine, that just wraps a (try ...) around the expression. |
| 21:18 | eee | my safe-math could throw |
| 21:18 | eee | if (first ...) is bogus |
| 21:18 | hiredman | ... |
| 21:19 | hiredman | eee: write or |
| 21:20 | hiredman | or only evaluates its arguments if it needs to |
| 21:20 | hiredman | can you imagine having to quote every form you try and pass to or? |
| 21:20 | eee | you mean there is a macro or? |
| 21:20 | hiredman | ,(or (println :a) (println :b)) |
| 21:20 | clojurebot | :a :b |
| 21:20 | ayrnieu | ,(macroexpand '(or 1 2 3)) |
| 21:20 | clojurebot | java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer |
| 21:20 | hiredman | ,(or (println :a) :a (println :b)) |
| 21:20 | clojurebot | :a |
| 21:20 | clojurebot | :a |
| 21:21 | ayrnieu | hm, works with this build. |
| 21:21 | eee | i think I see |
| 21:21 | ayrnieu | I get: (let* [or__3163__auto__ 1] (if or__3163__auto__ or__3163__auto__ (clojure.core/or 2 3))) |
| 21:21 | hiredman | arbscht: works at the repl too |
| 21:21 | hiredman | er |
| 21:21 | hiredman | ayrnieu: |
| 21:22 | eee | no I don't. still seems like (or) could be a function that takes two booleans. |
| 21:22 | eee | the booleans could be the result of functions |
| 21:22 | hiredman | eee: it could be |
| 21:22 | hiredman | but if the first function is true, do you need to run the second? |
| 21:22 | ayrnieu | hiredman, I mean that clojurebot dies on ,,(macroexpand '(or 1 2 3)) , which my build of clojure correctly expands. |
| 21:22 | eee | ahhhhhh |
| 21:23 | hiredman | ayrnieu: I know what you meant |
| 21:23 | hiredman | it works on my repl too |
| 21:23 | eee | hiredman explaind it |
| 21:23 | ayrnieu | ah. |
| 21:23 | eee | with a macro |
| 21:23 | hiredman | clojurebot has an interal call to macroepxand which maybe the problem |
| 21:23 | eee | you can do what you want |
| 21:23 | eee | you can intercept the evaluations |
| 21:23 | eee | you are sort of like a compiler at that point |
| 21:23 | hiredman | Yes |
| 21:23 | eee | you get to decide how evaluation happens |
| 21:24 | eee | like || in C++ |
| 21:24 | eee | is smart |
| 21:24 | eee | you can make custom smarts |
| 21:25 | hiredman | first clojure gets read which turns it into a bunch of data structures, lists mostly |
| 21:25 | eee | so |
| 21:25 | eee | wholey crap |
| 21:25 | hiredman | then macros get a change to alter those data structures, the nthe result gets evaluated |
| 21:25 | hiredman | Yes. |
| 21:25 | eee | this is big |
| 21:25 | hiredman | Holy Crap. |
| 21:25 | hiredman | clojurebot: macros? |
| 21:25 | clojurebot | Excuse me? |
| 21:26 | hiredman | clojurebot: macros is <reply>Holy Crap. |
| 21:26 | eee | this is big |
| 21:26 | clojurebot | In Ordnung |
| 21:26 | eee | check this out |
| 21:26 | eee | see if I'm right |
| 21:26 | hiredman | clojurebot: how did you respond when you firs learned about macros? |
| 21:26 | clojurebot | Holy Crap. |
| 21:26 | eee | there's a famous example of a functional quicksort that imperitive types criticize |
| 21:27 | eee | because you call filter twice on the partitioning |
| 21:27 | eee | and make two lists |
| 21:27 | eee | but |
| 21:27 | eee | if quicksort were a macro |
| 21:27 | eee | it could just LOOK like you filtered all less than pivot into one list . . .and all greater than pivot into another |
| 21:28 | eee | the implementation coud be whatever you want inside the macro |
| 21:28 | eee | huh? |
| 21:28 | hiredman | erm |
| 21:28 | hiredman | you could just do that with a function :P |
| 21:28 | eee | filter makes a pass through the whole list |
| 21:28 | eee | and mkes a sublist of all smaller than pivot |
| 21:28 | eee | filter makes another pass for all greater |
| 21:29 | lisppaste8 | ayrnieu pasted "safe-math" at http://paste.lisp.org/display/74190 |
| 21:29 | eee | but with a macro, it could just be specified AS IF that's what happened |
| 21:29 | eee | maybe? |
| 21:30 | eee | like a concat-partitions macro |
| 21:30 | hiredman | ... |
| 21:30 | hiredman | eee: general when manipulating actual datastructures, like stuff to be sorted, a regular function can do it just fine |
| 21:31 | hiredman | macros come into their own when you are manipulating the code |
| 21:31 | eee | (concat-partitions (<filter all less than x in list> (x) <filter all greater than x in list>) |
| 21:31 | eee | the naive implementation of above makes two passes through the list |
| 21:32 | eee | i wonder if macros can avoid that |
| 21:33 | eee | or maybe you just write a new filter method that returns two things in a list: element1 would be a list of everything that past the filter. element2 would be everything else that failed |
| 21:34 | eee | It's be a function that takes a list and a predicate and returns those two lists |
| 21:34 | eee | even though I digress. I wonder if I can do that efficiently |
| 21:35 | ayrnieu | you wonder if you can generate the two lists on the same walk through the list? |
| 21:35 | eee | well, given that I suck at clojure. I guess I could |
| 21:36 | eee | gonna see |
| 21:36 | eee | seems like a useful function |
| 21:36 | eee | would speed up quicksort |
| 21:37 | hiredman | ... |
| 21:38 | hiredman | eee: which year of cs are you in? |
| 21:39 | eee | i don't even remember how to run the repl in netbeans or send code to it |
| 21:39 | eee | which year? I'm done with school for right now |
| 21:39 | eee | MS degree |
| 21:39 | eee | just using quicksort since I understand it |
| 21:40 | hiredman | ok, just asking because that seems very academic :P |
| 21:40 | eee | it's an argument folks like to make about why imperitive langs are better |
| 21:41 | eee | you can pivot the data in place |
| 21:41 | eee | quicksort is supposed to be an in place algorithm |
| 21:41 | eee | partitioned in one pass |
| 21:41 | eee | but with macros |
| 21:41 | eee | i'm wondering if you can specify it however you want |
| 21:41 | eee | but the macro lets you really do something else |
| 21:42 | hiredman | clojure is not a pure functional language, so you can do mutable stuff with java arrays |
| 21:42 | eee | yeah |
| 21:42 | hiredman | etc |
| 21:42 | ayrnieu | (defn fold2 [f1 acc1 f2 acc2 list] (if (nil? list) [acc1 acc2] (recur f1 (f1 (first list) acc1) f2 (f2 (first list) acc2) list))) |
| 21:42 | cconstantine | clojure newbie here... I just downloaded the latest clojure and I can't get (dotimes ...) to work. Is there a known problem with it, or am I doing it wrong? |
| 21:42 | ayrnieu | although for a lisp-1 (*spit*), you may want to say 'lst'. |
| 21:43 | hiredman | cconstantine: latest means? |
| 21:43 | ayrnieu | constantine, how are you doing it? |
| 21:43 | cconstantine | clojure_20081217.zip |
| 21:43 | cconstantine | (def foo 10) (dotimes [i foo] (println "hello")) |
| 21:44 | cconstantine | I get a similar error when compiling ants.clj from the concurrency presentation |
| 21:44 | hiredman | ,(dotimes [i 10] (pr i)) |
| 21:44 | clojurebot | 0123456789 |
| 21:44 | gnuvince_ | What is the Clojure way of creating new data structures? Using structs? |
| 21:44 | hiredman | cconstantine: what exactly is the error |
| 21:45 | hiredman | gnuvince_: you mean nest data structures? |
| 21:45 | ayrnieu | it macroexpands to (let* [n__3864__auto__ (clojure.core/int bar)] (clojure.core/loop [foo (clojure.core/int 0)] (clojure.core/when (clojure.core/< foo n__3864__auto__) (pr foo) (recur (clojure.core/unchecked-inc foo))))) |
| 21:45 | ayrnieu | (dotimes [foo bar] (pr i)), does. |
| 21:45 | cconstantine | it's several pages, but I think the heart of it is: "java.lang.IllegalArgumentException: recur arg for primitive local: G__2293 must be matching primitive" |
| 21:45 | hiredman | cconstantine: better paste code |
| 21:46 | hiredman | lisppaste8: url |
| 21:46 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 21:46 | ayrnieu | (well, that turns out not to matter.) |
| 21:46 | hiredman | cconstantine: it does soundlike you may have a badly place recur |
| 21:46 | lisppaste8 | cconstantine pasted "untitled" at http://paste.lisp.org/display/74194 |
| 21:46 | hiredman | anyway, paste code + exception |
| 21:47 | gnuvince_ | hiredman: any kind. For instance, they were talking about finger trees in the Haskell community this week and I was wondering "how would one implement those in Clojure?" |
| 21:47 | pjb3 | The docs on http://clojure.org/reader say Keywords "They cannot contain '.' or name classes." |
| 21:47 | pjb3 | ,({:foo.bar "foo-bar"} :foo.bar) |
| 21:47 | clojurebot | "foo-bar" |
| 21:48 | hiredman | gnuvince_: just nest data structures |
| 21:48 | cconstantine | pjb3: was that for me? |
| 21:48 | hiredman | pjb3: a lot of that is not enforced |
| 21:48 | pjb3 | cconstantine: no, I was just noticing that |
| 21:48 | cconstantine | k |
| 21:48 | gnuvince_ | hiredman: does that really work? |
| 21:49 | pjb3 | hiredman: so keywords shouldn't contain periods? |
| 21:49 | hiredman | gnuvince_: of course it does |
| 21:49 | ayrnieu | constatine, your example WFM. Try the latest clojure on git? |
| 21:49 | hiredman | pjb3: *shrug* a lot of people are using keywords with periods, it seems like the doc is more likely to change then all the written code |
| 21:49 | cconstantine | hiredman: in case it's relavent I'm using MacOSX 10.5.6 nad java 1.5.... I bet I need java 1.6 don't I? |
| 21:50 | ayrnieu | constantine, 1.5 is fine. |
| 21:50 | gnuvince_ | hiredman: so the "logic" of the data structure is encoded not in the data itself, but in the functions defined for it? |
| 21:50 | cconstantine | ayrnieu: github? |
| 21:50 | hiredman | ah |
| 21:51 | hiredman | cconstantine: you may want to talk to rhickey are chouser because this looks like a bug. try (def f (Integer. 10)) |
| 21:51 | eee | how do you specify a predicate? |
| 21:51 | eee | trying to use filter |
| 21:52 | hiredman | eee: a predicate is any function |
| 21:52 | hiredman | nil is false |
| 21:52 | hiredman | not nil is true |
| 21:52 | eee | (filter (< 6) mylist) |
| 21:52 | hiredman | uh |
| 21:52 | eee | that doesn't work |
| 21:52 | hiredman | no |
| 21:52 | hiredman | a predicate needs to be a function |
| 21:52 | eee | < |
| 21:52 | cconstantine | hiredman: defining f as an Integer didn't help |
| 21:52 | eee | that's my function |
| 21:52 | hiredman | what filer is doing there is applying the , function to 6 |
| 21:52 | eee | less than |
| 21:53 | eee | less than 7 |
| 21:53 | hiredman | and try to use the result to filter the list |
| 21:53 | hiredman | but the rresult of (< 6) is not a function |
| 21:53 | hiredman | ,(> 6) |
| 21:53 | clojurebot | true |
| 21:53 | hiredman | so (> 6) is not a predicate |
| 21:53 | gnuvince_ | ,(fn [x] (> x 6)) |
| 21:53 | clojurebot | #<sandbox$eval__816$fn__818 sandbox$eval__816$fn__818@f2ea42> |
| 21:53 | hiredman | ^- that is function |
| 21:54 | hiredman | so it is a predicated |
| 21:54 | hiredman | predicate |
| 21:54 | eee | i see |
| 21:54 | cconstantine | ayrnieu: I'm having a hard time finding the latest clojure on git, or at least a definative clojure on git |
| 21:54 | hiredman | (small keyboard) |
| 21:54 | eee | mine is fewer character :) |
| 21:54 | hiredman | clojurebot: google codE? |
| 21:54 | clojurebot | Huh? |
| 21:54 | hiredman | clojurebot: google code? |
| 21:54 | clojurebot | Pardon? |
| 21:54 | gnuvince_ | cconstantine: use the subversion repos from Google Code |
| 21:54 | cconstantine | ok |
| 21:54 | hiredman | clojurebot: where isthe svn? |
| 21:54 | clojurebot | svn is http://clojure.googlecode.com/svn/trunk/ |
| 21:54 | ayrnieu | constantine, try starting at http://clojure.org/ |
| 21:54 | hiredman | ^- |
| 21:55 | cconstantine | ayrnieu: right, that points to a svn repo ;) |
| 21:55 | hiredman | ~ latest |
| 21:55 | clojurebot | latest is 1231 |
| 21:55 | hiredman | is the latest rev or close to |
| 21:59 | cconstantine | it builds to a clojure-slim.jar |
| 22:00 | cconstantine | ok, that works |
| 22:01 | cconstantine | ah, the excitement of a young language :) |
| 22:01 | pjb3 | cconstantine: there should be a clojure.jar too |
| 22:01 | pjb3 | I don't know what clojure-slim.jar is for |
| 22:02 | cconstantine | oh, there is... 'ls' was hiding it? |
| 22:02 | cconstantine | ok, clojure.jar works too |
| 22:03 | cconstantine | thanks :) |
| 22:04 | pjb3 | cconstantine: np, are you just getting started with Clojure? |
| 22:04 | cconstantine | yeah |
| 22:04 | cconstantine | I've done one minor project in CL and kinda liked it. Clojure looks much better :) |
| 22:04 | pjb3 | cool, what other languages are you familiar with |
| 22:05 | cconstantine | C/C++ (it's what I do for a living), some python and perl |
| 22:05 | pjb3 | yeah, Clojure is more elegant than any other Lisp, such as CL or Scheme, IMO |
| 22:06 | cconstantine | I might be able to argue that Scheme is more "pure" or something like that... but I sure as hell wouldn't want to make anything worthwhile in it |
| 22:06 | pjb3 | Yeah, I could see that argument about Scheme |
| 22:07 | cconstantine | before my CL project I decided on Scheme because it looked better, but I couldn't get any 'real' work done in it |
| 22:07 | pjb3 | It is less complex, has less syntax, etc |
| 22:07 | pjb3 | yeah, exactly though, there's just a lot of stuff you have to build yourself to use Scheme for anything |
| 22:07 | pjb3 | Good language to learn Lisp in though |
| 22:07 | cconstantine | I'm a little concerned that multi-methods are too complicated in clojure, but I'll fight that when I get there |
| 22:08 | pjb3 | They're not that bad |
| 22:08 | cconstantine | yeah... I can see how it's perfect for an undergrad lisp course |
| 22:08 | cconstantine | I think I should know more about the language before I tackle multi-methods |
| 22:08 | pjb3 | Any you can write a lot of productive code with Clojure without every writing a macro or a multimethod |
| 22:08 | cconstantine | yeah |
| 22:08 | pjb3 | which are the two most complicated things in Clojure |
| 22:08 | pjb3 | Macros are definitely more complicated than multimethods |
| 22:09 | cconstantine | hehe |
| 22:09 | cconstantine | I fell in love with macros from the CL project |
| 22:09 | cconstantine | I keep thinking at work: "Oh, this would be a prime case for macros!.... on right, C++" |
| 22:09 | pjb3 | You should get the book from http://pragprog.com, it does a pretty good job of explaining the language |
| 22:10 | eee | do is used for side effects, right? |
| 22:10 | pjb3 | Oh, well, if you understand macros than you are ahead of the game then :) |
| 22:10 | pjb3 | eee: Yeah, it's kind of like let without an bindings |
| 22:10 | eee | ,(do (print "hi") (print "yo")) |
| 22:10 | clojurebot | hiyo |
| 22:11 | pjb3 | ,(println "Can clojurebot print?") |
| 22:11 | clojurebot | Can clojurebot print? |
| 22:11 | pjb3 | ,(do (println "foo") (println "bar")) |
| 22:11 | clojurebot | foo bar |
| 22:11 | pjb3 | huh |
| 22:11 | eee | so I have an if clause . . . .put in one list if pass pred . . . else put in other list if fail pred. then recur no matter what. so the if and recur can be in a do? |
| 22:13 | pjb3 | what is the recur for, is it in a loop or recursively calling the function? |
| 22:13 | eee | yup |
| 22:13 | eee | i'm making a single pass function that returns two lists when given a list |
| 22:14 | eee | things that pass predicate in list 1 |
| 22:14 | eee | things that fail in list 2 |
| 22:14 | pjb3 | You might want to look at split-with |
| 22:15 | pjb3 | ,(split-with even? [1 2 3 4 5]) |
| 22:15 | clojurebot | [nil (1 2 3 4 5)] |
| 22:15 | pjb3 | so much for that |
| 22:15 | pjb3 | That's not the function I want thinking of |
| 22:16 | eee | so someone wrote it? |
| 22:16 | eee | no matter it is a challenge |
| 22:16 | pjb3 | No, there's a built in function that does it |
| 22:17 | pjb3 | maybe it's in clojure-contrib |
| 22:17 | eee | how do I return a list in my else clause |
| 22:17 | eee | quote it? |
| 22:17 | eee | i have two lists l1 and l2 |
| 22:17 | eee | time to return them in a list |
| 22:18 | pjb3 | eee: do you want to return a list of two lists? |
| 22:18 | eee | ok |
| 22:18 | eee | i need help |
| 22:19 | eee | where do I past my code |
| 22:19 | ayrnieu | eee: (defn fold2 [f1 acc1 f2 acc2 list] (if (nil? list) [acc1 acc2] (recur f1 (f1 (first list) acc1) f2 (f2 (first list) acc2) list))) |
| 22:19 | hiredman | lisppaste8: url? |
| 22:19 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 22:19 | pjb3 | http://paste.lisp.org |
| 22:19 | hiredman | ,(doc split-with) |
| 22:19 | clojurebot | "([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]" |
| 22:19 | eee | you wrote that aym? |
| 22:19 | ayrnieu | eee: (defn fold2 [f1 acc1 f2 acc2 list] (if (nil? list) [acc1 acc2] (recur f1 (f1 (first list) acc1) f2 (f2 (first list) acc2) (rest list)))) |
| 22:20 | ayrnieu | the 'rest' is probably important. |
| 22:20 | hiredman | ,(sort-by even? [1 2 3 4 5]) |
| 22:20 | clojurebot | (1 3 5 2 4) |
| 22:20 | pjb3 | hiredman: that doesn't do what he's talking about |
| 22:20 | eee | i see |
| 22:20 | hiredman | ,(split-with? even? (sort-by even? [1 2 3 4 5])) |
| 22:20 | clojurebot | java.lang.Exception: Unable to resolve symbol: split-with? in this context |
| 22:20 | eee | close tho |
| 22:20 | hiredman | ,(split-with even? (sort-by even? [1 2 3 4 5])) |
| 22:20 | clojurebot | [nil (1 3 5 2 4)] |
| 22:21 | hiredman | ,(split-with even? (sort-by odd? [1 2 3 4 5])) |
| 22:21 | clojurebot | [(2 4) (1 3 5)] |
| 22:21 | hiredman | :P |
| 22:21 | eee | aym . . . that's close, too |
| 22:21 | eee | but I would hide the storage |
| 22:21 | eee | leme cutnpaste |
| 22:21 | eee | hang on |
| 22:22 | lisppaste8 | eee pasted "filtrem" at http://paste.lisp.org/display/74198 |
| 22:22 | pjb3 | ,(let [f even? s [1 2 3 4 5] [(filter f s) (filter (complement f) s)])) |
| 22:22 | clojurebot | Eval-in-box threw an exception:Unmatched delimiter: ) |
| 22:22 | eee | it ain't quite right, but I bet it is close |
| 22:22 | pjb3 | ,(let [f even? s [1 2 3 4 5] [(filter f s) (filter (complement f) s)]) |
| 22:22 | clojurebot | Eval-in-box threw an exception:Unmatched delimiter: ) |
| 22:23 | pjb3 | ,(let [f even? s [1 2 3 4 5]] [(filter f s) (filter (complement f) s)]) |
| 22:23 | clojurebot | [(2 4) (1 3 5)] |
| 22:23 | eee | aha |
| 22:23 | eee | but that's doible pass |
| 22:23 | eee | look at my code |
| 22:23 | pjb3 | clojure.contrib.seq-utils/separate |
| 22:23 | eee | one pass |
| 22:24 | ayrnieu | eee, if you understand fold2 above, you can verily easily write your function. |
| 22:24 | eee | i wouldn't know how to look at that contrib code |
| 22:25 | eee | i see now |
| 22:25 | eee | aym |
| 22:25 | eee | can you tell me where I went wrong with mine? I see yours. it's nice |
| 22:26 | pjb3 | eee: you need to quote the final list that you return |
| 22:26 | pjb3 | er, not quote, list |
| 22:26 | ayrnieu | ,(if (list) 1 2) |
| 22:26 | clojurebot | 1 |
| 22:27 | pjb3 | ,(list '(1 2 3) '(4 5 6)) |
| 22:27 | clojurebot | ((1 2 3) (4 5 6)) |
| 22:27 | pjb3 | but the problem is the lists are empty |
| 22:27 | eee | i see |
| 22:27 | eee | i can't do that |
| 22:27 | pjb3 | because conj returns a new list |
| 22:27 | eee | several probs |
| 22:27 | eee | one |
| 22:27 | eee | you use [] |
| 22:27 | eee | to return new list |
| 22:27 | eee | I thought that was for vector |
| 22:28 | ayrnieu | I return a vector of the two lists, that is all. |
| 22:28 | eee | [acc1 acc2] |
| 22:28 | pjb3 | yeah, vector, list, they can be used pretty interchangably |
| 22:28 | ayrnieu | Yes, at the very end. |
| 22:28 | eee | could you say (list acc1 acc2) |
| 22:28 | ayrnieu | You could. |
| 22:28 | eee | ok |
| 22:28 | pjb3 | yes, that would give you a list of two lists |
| 22:28 | eee | that's how you return list, then |
| 22:29 | eee | cause (acc1 acc2) i don't think would work |
| 22:29 | ayrnieu | fold2 is a general function; it's something you'd write as soon as you said "I want to build two lists from two functions as I walk a list, one-pass", before you finish saying why you want to do this. |
| 22:29 | pjb3 | eee: no, that will try to call acc1 as a function, passing it acc2 |
| 22:29 | eee | my second problem is that i have a scope problem. I'm not actually adding to l1 and l2 |
| 22:29 | pjb3 | eee: right |
| 22:31 | eee | you send as many things to recur and you have defined in the loop |
| 22:32 | eee | and only the first time are they bound to the stuff in brackets |
| 22:33 | ayrnieu | (fold2 (fn [a b] (+ a b)) 0 (fn [a b] (* a b)) 1 (list 1 2 3 4 5)) => [15 120] |
| 22:36 | eee | now this version should accumilate! grrrrrr will cut n past |
| 22:36 | lisppaste8 | eee pasted "untitled" at http://paste.lisp.org/display/74201 |
| 22:37 | burkelibbey | So my distributed computing class handed out a bunch of Sun SPOTs to us. Does anyone know anything about running Clojure on Squawk or J2ME? (I'm a bit of a Java noob) |
| 22:37 | ayrnieu | (fold2 (fn [a b] (cons a (cons "," b))) [] (fn [a b] (str a b)) "" (list "hello" "there" "mon" "frere")) => [("frere" "," "mon" "," "there" "," "hello" ",") "freremontherehello"] ; reverse is useful. |
| 22:37 | eee | i think I know |
| 22:38 | burkelibbey | It complains about java.util.concurrent.Callable not being available. Is there any way to deal with that, or should I just not bother? :P |
| 22:38 | eee | that is quite generic |
| 22:38 | hiredman | burkelibbey: j2me is very limited |
| 22:38 | eee | mine only takes a pred and makes one as the NOT stuff |
| 22:38 | hiredman | and j2me what it does have is bits and pieces from jdk14 |
| 22:39 | hiredman | ayrnieu: I'd suggest conj instead of cons |
| 22:40 | burkelibbey | Hmm, ok. Too bad; embedded clojure would have been awesome. |
| 22:40 | hiredman | burkelibbey: it may work |
| 22:40 | hiredman | *shrug* |
| 22:41 | burkelibbey | So if it doesn't have java.util.concurrent.Callable, is there any way for me to bundle that in anyway? (recall: burkelibbey is a java noob) |
| 22:42 | lisppaste8 | pjb3 pasted "filtrem" at http://paste.lisp.org/display/74202 |
| 22:44 | lisppaste8 | pjb3 annotated #74202 with "updated" at http://paste.lisp.org/display/74202#1 |
| 22:44 | eee | got it |
| 22:45 | eee | i need a window |
| 22:45 | lisppaste8 | eee pasted "untitled" at http://paste.lisp.org/display/74203 |
| 22:45 | hiredman | clojurebot: fold2 is (defn fold2 [f1 acc1 f2 acc2 list] (if (nil? list) [acc1 acc2] (recur f1 (f1 (first list) acc1) f2 (f2 (first list) acc2) list))) |
| 22:45 | clojurebot | You don't have to tell me twice. |
| 22:45 | eee | looks like folks beat me to it |
| 22:45 | eee | :( |
| 22:46 | eee | i'm gonna post it to the group |
| 22:46 | pjb3 | eee: Using vectors makes things show up in the right order |
| 22:47 | eee | i'll just say "folks on the irc helped" . . . .oh, we car about order? I can do that |
| 22:47 | hiredman | ayrnieu: you a haskeller? |
| 22:47 | eee | mine is in the right order |
| 22:47 | eee | test it |
| 22:47 | pjb3 | eee: I agree |
| 22:47 | pjb3 | I was just pointing that out |
| 22:47 | pjb3 | Mine isn't, because I would using lists like you were in the original |
| 22:47 | eee | conj makes it in the right order |
| 22:48 | pjb3 | not if you use lists though |
| 22:48 | eee | really? |
| 22:48 | pjb3 | because conj'ing to a list puts it on the front |
| 22:48 | eee | conj works differently? |
| 22:48 | eee | oh |
| 22:48 | eee | i see |
| 22:48 | pjb3 | conj puts the items on the sequence wherever it is most efficient too |
| 22:48 | pjb3 | lists grow at the front, vectors grow at the end |
| 22:48 | eee | gonna go afk for a bit. thanks for the help |
| 22:49 | eee | i still didn;t learn how to write the harry macro I'm interested in. maybe next time |
| 22:49 | eee | also I'm gonna suggest this in the contribs, if it makes sense |
| 22:49 | eee | anyone want credit? |
| 22:50 | eee | pjb3 or ayrnieu |
| 22:50 | eee | i'll just leave window open |
| 22:50 | eee | be back |
| 22:50 | pjb3 | looks like you got it |
| 22:51 | pjb3 | it's already in contribs as separate, but as you said, this is one pass, so possibly more efficient |
| 22:53 | lisppaste8 | pjb3 annotated #74203 with "separate, more idiomatic version of filtrem" at http://paste.lisp.org/display/74203#1 |
| 22:55 | pjb3 | eee: BTW, if you time your version and the one in seq-utils, the one in seq-utils is faster |
| 22:57 | pjb3 | user=> (time (count (separate even? (range 1 1000000)))) |
| 22:57 | pjb3 | "Elapsed time: 1226.57 msecs" |
| 22:57 | pjb3 | user=> (time (count (clojure.contrib.seq-utils/separate even? (range 1 1000000)))) |
| 22:57 | pjb3 | "Elapsed time: 0.058 msecs" |
| 22:57 | pjb3 | Someday I'll understand that :) |
| 23:10 | ayrnieu | hiredman - God no. |
| 23:11 | hiredman | ok |
| 23:11 | hiredman | just curious |
| 23:26 | eee | how could it be faster? |
| 23:26 | eee | what did the code look like again? |
| 23:26 | eee | oh |
| 23:26 | eee | I guess less branching? |
| 23:26 | gnuvince_ | Are the two filters the most efficient way to write separate? |
| 23:27 | eee | you implemented separate as filtrem |
| 23:27 | eee | ? |
| 23:28 | eee | ,(take 5 (rand 400)) |
| 23:28 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: Double |
| 23:29 | eee | ,(take 5 (list (rand 400))) |
| 23:29 | clojurebot | (261.8843254985269) |
| 23:29 | eee | i don't know how to make a random list |
| 23:30 | eee | let's look at my google group info |
| 23:31 | eee | ,(take 5 (repeatedly (rand 400))) |
| 23:31 | clojurebot | java.lang.RuntimeException: java.lang.ClassCastException: java.lang.Double cannot be cast to clojure.lang.IFn |
| 23:31 | eee | ,(take 5 (repeatedly #(rand 400))) |
| 23:31 | clojurebot | (288.27871463886095 107.37500695219629 230.34487025923286 34.925482882785985 4.417318672644388) |
| 23:31 | eee | ,(take 5 (repeatedly #(rand-int 400))) |
| 23:31 | clojurebot | (376 155 189 317 334) |
| 23:32 | gnuvince_ | ,(replicate 5 (rand 400)) |
| 23:32 | clojurebot | (304.36713394163394 304.36713394163394 304.36713394163394 304.36713394163394 304.36713394163394) |
| 23:32 | gnuvince_ | hmm, right |
| 23:33 | hiredman | ,(map #(%) (replicate 5 #(rand 400))) |
| 23:33 | clojurebot | (151.64976810686377 263.74575502229595 131.77614419133334 24.905270563145486 188.07390169071687) |
| 23:34 | eee | i wonder if it's because mine uses vectors which could have a slower conj |
| 23:34 | eee | what's the contrib implementation? |
| 23:35 | hiredman | eee: why would conj on vectors be slower? |
| 23:35 | eee | well, when you run out of room on a vector |
| 23:35 | eee | you have to copy the whole vector somewhere else |
| 23:35 | hiredman | a vector is not an array |
| 23:35 | Chouser | actually... |
| 23:35 | eee | so you can guarantee random access in constant time |
| 23:36 | eee | i vector has contiguous memory probably |
| 23:36 | Cark | clojure vectors are not like that |
| 23:36 | eee | so conj is probably slower than on a list |
| 23:36 | Cark | how could they be persistent if they were ? |
| 23:36 | gnuvince_ | Clojure vectors are not contiguous |
| 23:36 | eee | ok |
| 23:36 | eee | true |
| 23:36 | eee | but |
| 23:37 | eee | i've seen persistent implementations of vectors |
| 23:37 | eee | and chincks are contiguous |
| 23:37 | eee | chunks |
| 23:37 | Chouser | clojure vectors are made of chunks, each an array of up to 32 items |
| 23:38 | eee | well can we test the time to conj 100000 things into a vector |
| 23:38 | eee | vice into a list? |
| 23:39 | gnuvince_ | ,(time (dotimes [_ 100] (let [xs []] (for [e 100000] (conj xs e))))) |
| 23:39 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer |
| 23:39 | Chouser | add an item to a vector of 31 items, I think it copies 31 of them. |
| 23:39 | eee | oh and that seperate isn't as concise as it could be |
| 23:39 | gnuvince_ | ,(time (dotimes [_ 100] (let [xs []] (dotimes [e 100000] (conj xs e))))) |
| 23:39 | clojurebot | "Elapsed time: 1867.717 msecs" |
| 23:39 | eee | it uses (filter (comkplement) |
| 23:39 | eee | instead of remove |
| 23:39 | gnuvince_ | ,(time (dotimes [_ 100] (let [xs ()] (dotimes [e 100000] (conj xs e))))) |
| 23:40 | clojurebot | "Elapsed time: 1382.68 msecs" |
| 23:40 | Cark | nearly constant time it seems |
| 23:40 | eee | well you can't tell much from one time, but the times aren't way off like they were with my thing |
| 23:44 | eee | testing right now |
| 23:44 | te | my name is Akmar and i am 7 yrs old and dad tied me in the basement and tell me to have all dos game by 7 o clock or i get no food plz help |
| 23:46 | eee | looks like i'm doing too big a test. computer is sweating |
| 23:46 | ayrnieu | te, things will get better after you fail to produce a game for a few days. |
| 23:46 | te | ayrnieu: *nod* |
| 23:47 | ayrnieu | te - but try something simple, like sokoban. |
| 23:52 | ayrnieu | my $CLASSPATH includes a path to clojure-contrib.jar , but how do I load it into clojure? |
| 23:53 | eee | i lost the code I was messing with when I killed netbeans |
| 23:54 | eee | drat |
| 23:55 | Cark | ayrnieu : (require 'clojure.contrib.math) |
| 23:55 | eee | i don't trust the timing |
| 23:56 | eee | i'm scaling things up by 10 times |
| 23:56 | eee | and getting faster timres |
| 23:56 | eee | times |
| 23:57 | eee | it must not be timing what I think |
| 23:57 | Cark | hotspot compiles while you use your functions |
| 23:57 | eee | ,(time (take 5000 (repeatedly #(rand-int 3000)))) |
| 23:57 | clojurebot | (730 1844 1225 2097 699 160 2801 621 1532 1853 592 1174 2769 900 2775 2162 958 299 1535 2612 165 1963 2548 2667 311 1968 214 1182 912 2875 2261 780 58 2001 2863 2554 2024 1732 718 1876 659 102 1471 2546 1648 1973 2607 725 947 1252 2326 1804 1075 623 88 2514 608 1294 2346 1219 2004 256 2567 2426 2025 1513 952 2142 2221 657 265 697 1518 1080 917 214 2597 1956 2912 1844 2758 988 422 1346 49 702 1655 1494 1879 2839 284 2191 1 |
| 23:57 | clojurebot | "Elapsed time: 0.658 msecs" |
| 23:57 | Cark | you might need to run the test repeatadly |
| 23:57 | eee | ,(time (take 5000 (repeatedly #(rand-int 3000)))) |
| 23:57 | clojurebot | (962 68 590 2174 2215 2482 1765 1831 2152 603 385 2903 98 2715 455 1458 2209 2832 1811 2882 2980 2257 441 2334 1829 2655 171 34 2425 1255 1919 887 1178 2930 1720 1712 1282 2033 396 2538 2881 952 2187 1162 330 2381 1801 296 167 367 2175 1284 232 1124 852 2455 2438 1642 142 1757 984 1964 269 347 1300 971 436 1333 2721 2344 2182 1816 2829 1214 2595 1855 571 2824 2815 1861 601 277 1877 1322 2932 1226 1287 2625 1756 1016 1732 |
| 23:57 | clojurebot | "Elapsed time: 0.568 msecs" |
| 23:58 | eee | ,(time (take 500 (repeatedly #(rand-int 3000)))) |
| 23:58 | clojurebot | (880 1117 1591 717 1933 1826 1376 736 1628 1162 1831 2945 2650 982 340 1756 735 2544 1026 1773 935 559 1914 702 428 744 262 1118 1562 1287 2736 1606 2964 1698 1513 2462 2998 2603 1550 2362 2434 42 2102 2961 1067 1827 1165 1556 1067 2475 1797 2474 1139 1177 2312 2896 1044 114 28 2331 777 372 1769 1948 1624 1458 427 382 1463 1302 1817 588 2080 1336 1667 2652 822 1034 2880 2367 2752 1964 2303 650 1498 1130 2939 2719 216 1967 |
| 23:58 | clojurebot | "Elapsed time: 0.535 msecs" |
| 23:58 | eee | i can run it 1000 times more |
| 23:58 | eee | and it will run for a long |
| 23:58 | eee | time |
| 23:58 | eee | long |
| 23:58 | eee | long |
| 23:58 | eee | time |
| 23:58 | Cark | well |
| 23:58 | eee | and then get same timing |
| 23:58 | Cark | you're mesuring the speed of the clojure compiler |
| 23:59 | ayrnieu | Cark - thanks. That clojure.contrib.math actually fails for me because it redefines 'mod', but I get the pattern. |
| 23:59 | eee | the computer sits and hangs for many seconds |
| 23:59 | eee | and then I get subsecond time printed out? |
| 23:59 | ayrnieu | ( java.lang.Exception: Name conflict, can't def mod because namespace: clojure.contrib.math refers to:#'clojure.core/mod (math.clj:118) ) |
| 23:59 | Cark | ah i guess they added it recently |