#clojure log - Aug 11 2009

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:00 lrenn: Apologies if this is a silly idea, but how about version of let that isn't guaranteed sequential but runs the binding forms in a new thread. Call it plet.

0:01 hiredman: *shrug*

0:02 (let [[a b c d] (pcalls foo bar baz bloop)])

0:02 tomoj: there has got to be a better way to do this: https://gist.github.com/faafe19ec35ed632339c

0:02 basically want to map over a bunch of maps, but I'm only interested in changing a deeply nested key

0:03 hiredman: update-in

0:03 tomoj: hiredman: awesome. thank you

0:03 lrenn: hiredman: very nice. thanks.

0:04 prospero_: is there a way to test whether something is a particular type of struct-map?

0:05 hiredman: type tag your struct-maps

0:05 prospero_: so there's no implicit metadata?

0:06 tomoj: I read a mailing list discussion about that a couple days ago

0:06 the type is stored internally but is not accessible, apparently

0:06 prospero_: link?

0:06 oh, well never mind

0:06 that's a little weird, though

0:06 hiredman: *shrug*

0:07 tomoj: the best solution I saw did type tagging with a special constructor function

0:07 hiredman: that is the why to do it

0:07 tomoj: you could make a special macro for defining structmaps that built a constructor that tags I suppose

0:08 dnolen: tomoj: http://github.com/swannodette/spinoza/tree/master all but abandoned, but a point of reference for exactly that.

0:09 i wrote that early in my fiddlings with clojure. i think it's a fairly pointless pursuit now tho.

0:09 tomoj: why pointless?

0:10 prospero_: so is a struct just a well-documented map, then?

0:10 tomoj: bit faster too I think

0:10 prospero_: ok

0:10 hiredman: well, for the specified keys

0:11 dnolen: you just get so little from a constructor approach when you have already have robust data types, multi-methods, and hierarchies.

0:11 it's also just un-clojure-y.

0:12 hiredman:

0:12 tomoj: I wonder if my current data structure isn't clojure-y

0:12 I have a seq of maps, keys in which contain seqs of maps, keys in which contain seqs of maps

0:13 hiredman: sounds gnarly

0:13 tomoj: update-in helps a little but it's still ugly to twiddle something deep in there

0:14 dnolen: tomoj: why do you need such deeply nested data? that seems weird in general unless your manipulating xml or something.

0:14 tomoj: courses have one or more sections, each section has one or more meetings

0:16 dnolen: tomoj: what doesn't your code look like now that you're using update in?

0:16 update-in

0:21 tomoj: dnolen: https://gist.github.com/faafe19ec35ed632339c

0:21 not any better really...

0:21 a bit of duplication removed I suppose

0:22 I guess I need map-and-update-in which detects whether the key points to a map or other seq and maps the later keys onto other seqs

0:23 hypothetical use case for a much gnarlier dataset: (map-and-update-in the-courses [:sections :meetings :instructor :grad-students :address] update-grad-student-address)

0:24 looks fun to write.. :/

0:25 dnolen: tomoj: why not

0:25 (map #(update-in % [:sections :meetings :time] parse-meeting-time) the-courses)

0:25 might be a typo

0:25 tomoj: hmm

0:25 dnolen: oh you want to update every meeting?

0:25 tomoj: I didn't think update-in worked that way

0:25 indeed

0:26 :sections and :meetings point to lists

0:26 update-in expects only maps

0:26 (I though)

0:26 dnolen: only partly true

0:26 ,(update-in [1 2 3] [0] inc)

0:26 clojurebot: [2 2 3]

0:27 tomoj: ah, right

0:27 but I mean I can't get it to map the update over the list, I think

0:27 the nested lists, I mean

0:32 JAS415: map it over nested lists

0:32 hmm

0:33 isn't there an assoc-in or something

0:33 tomoj: less powerful version of update-in, I think

0:33 still doesn't traverse nested lists afaik

0:34 but I think it's a simple function to do what I want, gonna try writing it in a few

0:35 JAS415: ,(update-in {:a [0 1 2 3] :b [4 5 6 7]} [:a 0] inc)

0:35 clojurebot: {:a [1 1 2 3], :b [4 5 6 7]}

0:36 JAS415: ,(update-in {:a [0 1 2 3] :b [4 5 6 7]} [:a] (fn [x] (map inc x)))

0:36 clojurebot: {:a (1 2 3 4), :b [4 5 6 7]}

0:37 JAS415: ,(update-in {:a [0 1 2 3] :b [4 5 6 7]} [:a] (fn [x] (map (fn [_] :foo) x)))

0:37 clojurebot: {:a (:foo :foo :foo :foo), :b [4 5 6 7]}

0:37 tomoj: JAS415: that's what I'm doing now, https://gist.github.com/faafe19ec35ed632339c/676cbd39a24b8d33908a946b33bb2f5eb1c12820

0:37 JAS415: :-)

0:38 might consider a helper function to abstract that out

0:38 tomoj: map-and-update-in :)

0:38 JAS415: ya

0:38 tomoj: gonna write it in a few

0:44 JAS415: ,(macroexpand-1 '(-> 1 2 3 4 5))

0:44 clojurebot: (clojure.core/-> (clojure.core/-> 1 2) 3 4 5)

0:44 JAS415: (macroexpand '(-> 1 2 3 4 5))

0:45 ,(macroexpand '(-> 1 2 3 4 5))

0:45 clojurebot: (5 (clojure.core/-> (clojure.core/-> (clojure.core/-> 1 2) 3) 4))

1:00 JAS415: ,(list 'defmacro 'created ['p] `(code ...)))

1:00 clojurebot: (defmacro created [p] (sandbox/code ...))

1:11 tomoj: https://gist.github.com/faafe19ec35ed632339c

1:11 probably a prettier way to do it

1:11 I mean, there probably is a prettier way than that gist

1:12 JAS415: ah its recursive

1:12 i see

1:12 tomoj: I don't plan to nest anything deep enough to blow the stack :)

1:12 JAS415: does it change it from a vector to a lazy-seq?

1:13 tomoj: yeah, because of the map

1:13 JAS415: hmm

1:13 tomoj: I don't care too much right now cus my data isn't vectors anyway

1:13 JAS415: ah

1:13 lazy seqs can get tricky

1:13 tomoj: I guess (vec (map ..)) solves that?

1:14 hiredman: (defn map! [func coll] (into (empty coll) (map func coll)))

1:14 JAS415: ah cool

1:15 tomoj: preserves type?

1:15 hiredman: sort of

1:15 JAS415: looks like it

1:15 do vectors hold metadata?

1:15 hiredman: ,((fn [func coll] (into (empty coll) (map func coll))) inc #{1 2 3})

1:15 clojurebot: #{2 3 4}

1:24 tomoj: hrmm

1:25 missed a bunch of edge cases

1:25 but... (map-and-update-in the-courses [:sections :meetings :time] parse-meeting-time))

1:25 woot

1:36 jwhitlark: Does anyone know how to create an interface, (not implement one), other than gen-interface? The DBus api requires an interface be passed to it so it knows what methods to create on the proxy object.

1:52 JAS415: edge cases are always the worst

2:10 tomoj: graaawwl

2:10 the worst indeed

2:10 I think the number of edge case problems I have is a sign that I'm thinking about this function in the wrong way

2:10 there's probably some simple two liner

4:01 Anniepoo: clojurebot: paste

4:01 clojurebot: lisppaste8, url

4:01 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

4:02 Anniepoo pasted "the case of the missing metadata" at http://paste.lisp.org/display/85182

4:02 Anniepoo: I'm attempting to add some metadata to some data

4:03 it's not getting added

4:03 arbscht: what is the data?

4:04 Anniepoo: it's vectors, a long list of them

4:04 when I compile the list this code is supposed to be adding some metadata

4:06 lisppaste8: Anniepoo annotated #85182 "a shorter version" at http://paste.lisp.org/display/85182#1

4:06 Anniepoo: sorry, it's getting late

4:06 here's the gist of it

4:06 arbscht: I think you want with-meta rather than the reader syntax

4:07 ,(map meta (map (fn [x] #{:foo 1} x) [[2] [3]]))

4:07 clojurebot: (nil nil)

4:07 arbscht: ,(map meta (map (fn [x] (with-meta x {:foo 1})) [[2] [3]]))

4:07 clojurebot: ({:foo 1} {:foo 1})

4:07 Anniepoo: ok, can you articulate why this is different?

4:08 I'm obviously missing something simple about the reader macros

4:10 arbscht: as I understand it: #^{} is evaluated at read time, when x is a symbol. in with-meta, x is evaluated and metadata is added to the vector

4:10 Anniepoo: ah! perhaps I'm adding my metadata to the var, not the contents?

4:11 8cD Annie was sorta awake during the clojure talk

4:20 whoo hoo, it's printing what looks like the correct gibberish to drive the robot

4:21 tomorrow I wire it up

4:22 Thanks for all the help, folks

4:22 clojurebot: for is a loop...in Java

4:23 tdrgabi: I'm trying to build a sorted-map using a collection of keys & values. I tried (sorted-map '(1 2 3 4)) and (sorted-map [1 2 3 4]). I receive "No value supplied for key: [1 2 3 4]". I tried apply "(sorted-map (apply '(1 2 3 4)))" and received: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

4:23 how can I build the sorted-map ?

4:24 i know it works as (sorted-map 1 2 3 4) ... but I have the keys & values in a seq

4:25 tomoj: tdrgabi: (apply sorted-map keyvals)

4:26 tdrgabi: tomoj: thank you.

7:23 paolino: hello folks, I made my mind around this language, without using it,it is targetted to eliminate ruby and python , just I was wondering if it's alive like smalltalk. But yes , amazing is the feature selection, I wish the best for clojure

7:25 opqdonut: "alive like smalltalk"

7:25 you are surely joking

7:25 andyfingerhut: I don't think it has a chance of eliminating Ruby or Python any time soon -- very active development and useful stuff implemented in those languages.

7:25 Nor do I think that was its intent.

7:25 Is Clojure useful, too? Certainly.

7:26 paolino: opqdonut: I was not, actually :-/

7:27 andyfingerhut: scripting with clojure seems better than both ruby and python, given the jvm

7:27 clojure: from clojure.org, "... designed to be a general-purpose language ... robust infrastructure for multithreaded programming ...", the latter of which describes neither ruby not python, har har

7:28 paolino: clojure: exactly, but also lbraries are generally more industrial strength in java

7:29 I'm a java detractor also :), but realistic about the libraries

7:31 opqdonut: the REPL seems very "alive", but I'm probably "hyped" by the examples

7:32 opqdonut: ah

7:32 i thought alive as in the community or development

7:32 smalltalk is pretty much dead afaict

7:34 paolino: also being just a haskell fan, I like to create a working GUI interactively, with no gtk2hs and friends, with all the portability problems and building issues

7:34 clojure is even simpler then both python and ruby in that sense

8:16 cemerick: hrm, I hadn't seen this before: java.lang.IllegalArgumentException: recur arg for primitive local: dist must be matching primitive

8:17 andyfingerhut: You probably have a type declaration like (int ...) or (double ...) in a loop binding, but in the recur, the Clojure compiler doesn't have enough information to determine that the type matches.

8:17 cemerick: I guess I figured the loop binding would just get boxed if the compiler saw any recurs that provided non-primitive args

8:17 andyfingerhut: yeah, I knew what was going on, just hadn't seen it before :-)

8:23 and actually, the initial loop binding was Double/MAX_VALUE, so I wasn't even thinking about whether the value was primitive or not.

8:24 andyfingerhut: weird. Doesn't look primitive to me.

8:25 ,(class Double/MAX_VALUE)

8:25 clojurebot: java.lang.Double

8:25 andyfingerhut: ,(class (double 5.0))

8:25 clojurebot: java.lang.Double

8:25 andyfingerhut: good enough, I guess

8:25 cemerick: andyfingerhut: you're passing it to the class fn, which boxes

8:25 it's defined as a "public static final double" in j.l.Double

8:26 andyfingerhut: are there any writeups about when boxing/unboxing occur in Clojure? Or you just absorb it over time? Or read the source?

8:27 cemerick: Chouser came up with a utility that reported what types the compiler sees for a particular form. Don't remember where it is, though.

8:27 It was definitely some black majick :-)

8:27 andyfingerhut: there are some odd corner cases, but in general, any function boundary will cause boxing.

8:39 Chouser: repl-utils/expression-info

8:40 andyfingerhut: grazie, signoure!

8:40 Um, I mean, thanks. Vacation to Italy makes me want to use two of the 30 words of Italian I know :)

8:41 Chouser: andyfingerhut: perfectly acceptible. clojurebot has raised the bar on such things.

8:43 cemerick: Chouser: you'll be happy to know that I've not had to care about zf/auto at all yet.

8:44 Chouser: cemerick: interesting. I forget -- these are nested vectors?

8:45 cemerick: no, the primary hierarchy is formed by nested spatial indexes

8:46 mostly neighbor graphs, an RTree here and there

8:49 Chouser: do you have data in the interior nodes or just at the leaves?

8:49 cemerick: my query 'language' is pretty tortured at the moment though. I'd like to basically have an xpath-esque syntax, but I've not yet bitten the bullet, so I've got queries like [\\ :foo some-pred]

8:50 Chouser: the former. Every level of the hierarchy is potentially relevant, depending on what's being done.

8:51 andyfingerhut: OK, this is an example of "give someone an inch, and they'll take a mile", but is there already anything like repl-utils/expression-info, except that it can annotate subexpressions of an entire function definition?

8:52 Chouser: The reason for zf/auto is so that xml queries don't end up looking like [:html children :head children :body ...]

8:53 xpath uses a plain / for that, but I couldn't find a syntax I liked, so I made it implicit

8:53 cemerick: yeah, I know. I'm just using / as a proxy for zf/children *shrug*

8:54 Chouser: andyfingerhut: should be doable -- how would you indicate which sub-expressions you want? or would you just do the whole thing and produce a few pages of output?

8:54 cemerick: oh, ok. well, that's why you haven't had to mess with it then. :-)

8:54 cemerick: [\\ :foo / :bar / :baz] was good enough for me, as you can't be certain that a :foo predicate should return children or not

8:55 actually, I've written queries like [\\ :foo /], just to return children of :foo's :-P

8:55 Chouser: cemerick: that may be better anyway.

8:56 cemerick: Chouser: you don't like using a fn arg from clojure.core as part of your query language? ;-)

8:56 Chouser: :-P

8:58 andyfingerhut: what would you want to know about each sub-expression? Just primitive true/false? The class also, or even more?

8:58 hm. I think one problem would be indicating which sub-expression each bit of info is talking about.

8:59 by the time the compiler is done with them, the expressions are unprintable and hard to recognize.

8:59 andyfingerhut: Chouser: Hmmm. I guess what leads me to ask is the desire to find places where there is boxing/unboxing going on that you might not otherwise know about, either because you're relatively new to Clojure (i.e. me still), or because there is a lot of code to look through and tune.

9:00 but flagging other sources of inefficiency besides boxing/unboxing could be useful as well.

9:00 Chouser: this sort of thing will be much easier after c-in-c

9:01 in fact, then the compiler output will be printable. Not sure how painful it might be to look at, but it'd be easy to get a dump at the repl of everything the compiler has concluded.

9:01 andyfingerhut: ok. I don't have a burning need for this -- just sounds like something nice to have around.

9:02 Chouser: ok. then I'll try to stop thinking about it...

9:02 cemerick: heh, clojure.core/explain :-P

9:02 Chouser: hiredman: how's the reader coming along?

9:03 andyfingerhut: It's the kind of thing that people could be pointed at when they want to know how to tune their code, besides *warn-on-reflection*

9:03 Chouser: reflection is a much bigger cost, but yeah I understand.

9:06 cemerick: once float and double primitive args are available, a lot of tuning should just go away, I'd think

9:16 osaunders: Has anyone considered a whitespace sensitive Clojure?

9:17 andyfingerhut: like Python?

9:17 osaunders: Sure.

9:17 To cut down on the parens.

9:18 Chouser: osaunders: yes, but the proposal has the same difficulties as it does for all the lisps

9:18 osaunders: Chouser: What are those?

9:19 opqdonut: people always suggest that, then they program in lisp for a while and forget about this perceived need

9:19 Chouser: specifically, the majority of people who were ever interested in the idea, by the time they know the target language well enough to approach success, stop minding the parens.

9:19 AWizzArd: ~seen kotarak

9:19 clojurebot: kotarak was last seen quiting IRC, 921 minutes ago

9:19 andyfingerhut: Blues Brother movie reference: Jake and Elwood check out an apartment right next to the elevated train in Chicago. Very noisy when it goes by right outside the window. "How often does the train go by?" asks Jake. "So often you won't even notice it," Elwood responds.

9:20 (referring to parens in Lisp)

9:20 * eevar2 would take parens over whitespace any day

9:20 osaunders: Hm, OK.

9:21 Chouser: somebody did it for CL. Looked pretty good, and it still was never popular. I wonder if I can find a link...

9:21 osaunders: But there's no technical reason why it can't be done is there?

9:21 clojurebot: http://clojure.org/rationale

9:21 cark: the reader is not programmable in clojure

9:21 so that wouldn't be possible

9:21 Chouser: osaunders: there are the normal technical challenges, but a pre-processor is entirely possible.

9:22 opqdonut: aa

9:22 -aa

9:22 cark: right, withh a pre-processor, but that would suck big time !

9:22 osaunders: Yeah, OK.

9:23 cark: unless you make a repl too

9:23 Chouser: not sure how nice whitespace would be at the repl anyway. a bit painful in python.

9:23 cark: true

9:23 osaunders: WS doesn't work in REPLs generally, yeah.

9:23 cark: anyways don't you dare take my parenthesis away =)

9:24 Chouser: you could also patch the reader directly. would make it a bit more difficult for others to try it out, but it's certainly an option.

9:24 osaunders: You like typing huh?

9:24 @cark ^

9:24 andyfingerhut: http://xkcd.com/297

9:24 cark: i like cut/paster full forms with a single keystroke

9:25 osaunders: What are cut/paster full forms?

9:25 cark: cut/paste

9:25 well parenthesis allow for easy editing

9:25 osaunders: You paste all the parenthesis?

9:25 cark: and navigating too

9:26 are you familiar with emacs? (i guess vim is good too)

9:26 osaunders: Parenthesis denote the data structures.

9:26 andyfingerhut: cark is probably referring to special features in emacs and vi/vim for selecting/cutting/pasting entire subexpressions at a time

9:26 osaunders: I would describe indentation as allowing for easy editing.

9:27 I use TextMate mainly. I have a passing familiarity with vim.

9:27 andyfingerhut: Ah, OK.

9:27 Actually that sounds incredibly cool.

9:27 Chouser: in vim y% copies a whole expression, even without any special support for lisp or clojure.

9:28 osaunders: But would be achieved with whitespace sensitivity also.

9:28 *could be

9:28 cark: with these tools, you cut/paste your forms, not thinking about indentation, then let them reindent your code

9:28 Chouser: there may be something similar in a specail python config file, but I don't know.

9:29 cark: and most important is the navigation, get inside a form, go two forms forward, dopwn one, delete next form, up up paste

9:30 too bad i can't express myself in english good enough to convey the fun of it

9:30 osaunders: cark: It sounds pretty cool actually.

9:30 cark: the learning curve is pretty steep though

9:31 andyfingerhut: osaunders: Your idea, or something like it, has been proposed in many variants by many people. While many seem to be turned off by the parens, many are not, and/or get used to them. Some come to love them, especially with nice support in their text editor of choice for handling them. So far, the proposals for fewer parens in Lisp have never caught on among people who do Lisp development.

9:31 Chouser: osaunders: http://www.dwheeler.com/readable/

9:32 cark: right, people have come up with that idea for 50 years, and we still have parenthesis

9:32 osaunders: lol

9:32 Damn.

9:32 I'm surprised you guys even took me seriously at all.

9:33 cark: hey there was progress, in clojure we have [] and {} now =)

9:33 andyfingerhut: not to say it never will, but there is a bit of inertia, or even strong preference, to keep them.

9:34 I've read an article or two somewhere years ago about making source code stored internally in XML or something similar, and then having potentially multiple display formats, depending upon what you were doing, or developer preference.

9:34 osaunders: :-S

9:35 Sort of like Smalltalk images only with XML.

9:35 * osaunders doesn't like XML much at all.

9:35 cark: the idea has some merit, but when you want to do macros, you'd rather directly see the parse tree

9:35 andyfingerhut: I think for a fewer-paren option in a Lisp, to catch on, would probably have to be an option, and have to allow different developers to view it in their preferred style.

9:36 osaunders: andyfingerhut: Problem with that is that you create a two-tier community.

9:36 Like with braces in C.

9:37 cark: anyways what's important is the semantics of the language, as opposed to the window dressing

9:37 andyfingerhut: well, if anyone could look at code written by others in their preferred style, either with a little config, or pressing a button to switch view styles, then the main issue left is all the arguing and name-calling, which I agree is often a bigger problem :)

9:37 Chouser: cark: I think syntax matters.

9:38 cark: yes it does, what i mean is that we have something that works pretty well already

9:38 we're past that

9:38 Chouser: maybe it shouldn't, or shouldn't matter as much, or we should have tools that automatically convert to our favorite syntax, or whatever. But in practice, today, syntax matters.

9:38 yeah

9:39 cark: what make clojure great are data structures and concurrency

9:39 osaunders: Does anyone want to be my learn Clojure buddy?

9:39 cark: literal syntax for those data structures is a plus, but we could live without it i think

9:41 speaking of which , does anybody know of a persistent baanced ternary tree implementation for the jvm ?

9:41 osaunders: Guess not. :-(

9:41 andyfingerhut: osaunders: What's the pay? :) Seriously, hanging around #clojure might be a decent way -- why have just one teacher?

9:41 osaunders: andyfingerhut: Hm. OK. I'll stick around.

9:42 tomoj: osaunders: what does being a learning buddy involve?

9:42 osaunders: tomoj: Helping each other to learn. Probably just over IRC.

9:43 tomoj: Perhaps both trying to write the same thing in Clojure and then compare solutions.

9:43 tomoj: that last sounds kinda fun

9:44 osaunders: We should probably do it in channel so that more experienced people can chime in.

9:44 tomoj: I'm here most all the time anyway

9:44 Chouser: there are a bunch of project euler solutions around that are great for that.

9:45 osaunders: Chouser: Link?

9:45 tomoj: ah project euler

9:45 had forgotten about that, good idea

9:46 osaunders: "Mathematical problems" :-S

9:46 Chouser: oh, not really. more logic than math really.

9:46 andyfingerhut: I'm growing a collection of solutions to the problems on the language shootout benchmark web site, in Clojure. You can look at them here if you like: http://github.com/jafingerhut/clojure-benchmarks/tree/master

9:46 I've used Scheme and Lisp marginally after learning them 20 years ago, but am newer to Clojure-specific things.

9:47 tomoj: I think stuff like project euler would be great for getting my head into clojure-space

9:47 Chouser: I mean, I guess you could solve them using math if you want, but you don't need much math for the first 30 or 40 problems at least.

9:47 osaunders: Hm.

9:47 Chouser: A collection of Clojure solutions to PE problems. But don't look until you've tried it -- that's cheating and less fun: http://clojure-euler.wikispaces.com/

9:48 * osaunders is a scarey cat

9:49 andyfingerhut: It can be daunting when you see how much is there. Best to pick one thing that looks interesting, and dive in on just that one.

9:51 osaunders: OK well I'm going to the pub for a beer.

9:51 And then I'm going to dig in a bit.

9:51 Chouser: the problems start pretty easy. I found PE to be fun and very educational.

9:51 osaunders: tomoj: I'm on GTalk if you like.

9:51 and MSN.

9:52 Or maybe just here is better.

9:52 * osaunders suspects freenode is actually more reliable than GTalk and MSN actually.

9:53 tomoj: bitlbee kicks me off of gtalk frequently

9:53 osaunders: Hm, OK. I'll just hang around on here then.

9:53 tomoj: I've stopped bothering to reconnect

9:53 osaunders: Alright bbl

10:06 tomoj: hmm

10:07 oh, "hmm" revoked

10:30 jayfields: How do I get access to static inner classes?

10:31 Chouser: pkg.name.Outer$Inner

10:32 jayfields: thanks Chouser

12:23 osaunders: ~seen tomoj

12:23 clojurebot: tomoj was last seen in #clojure, 136 minutes ago saying: oh, "hmm" revoked

12:24 tomoj: hallo

12:24 osaunders: Hey

12:24 How much Clojure do you know?

12:25 tomoj: dunno, not much

12:25 osaunders: How long have you been doing it?

12:25 tomoj: I lightly read the "Programming Clojure" book

12:25 been playing around for maybe a week or two

12:26 osaunders: OK, because today is day 2 for me.

12:26 Do you know what (def blah) does? Without the init part.

12:26 weissj: osaunders: i started picking it up a few weeks ago, been pretty cool so far

12:27 osaunders: it makes it so you can use that var later in the file

12:27 otherwise you have to def things before you use them

12:27 so you put those (def blah) at the top

12:27 maybe there's some other purpose, but that what i've used it for

12:28 tomoj: sounds right to me

12:28 osaunders: weissj: Oh. But there's a difference between (def blah) and (def blah nil) isn't there?

12:28 tomoj: (def blah) leaves blah unboand

12:28 er, unbound

12:28 osaunders: Right so you'll still get an error if you access it?

12:28 tomoj: indeed

12:28 weissj: but i believe that still does the trick - you can now put a reference to blah anywhere in the file

12:29 it'll compile at least :)

12:29 anywhere below that def, i mean

12:29 osaunders: Yeah, I don't really see the point in that.

12:29 cemerick: (declare blah) is more idiomatic for vars you want to establish but not define

12:29 weissj: osaunders: you'll see, when you start writing functions, you'll have to keep reordering them to make sure the ones at the top level are at the bottom of the file

12:30 ie, if a calls b, b must be before a in the file

12:30 osaunders: weissj: Ah, OK.

12:30 weissj: using a bunch of defs at the top frees you to use any order

12:30 osaunders: I'm used to languages where it doesn't care about that.

12:30 -1 for Clojure

12:30 weissj: yeah, i have heard some talk in this channel of fixing that

12:31 tomoj: also perhaps you want to use the var only with per-thread bindings

12:31 in that case no reason to give it a root binding

12:31 cemerick: weissj: Rich said it was *way* more trouble than it's worth a couple of weeks ago.

12:31 weissj: cemerick: oh ok

12:31 it's not that big a deal to me

12:31 when other langs have macros, then i'll complain about something like this in clojure :)

12:32 osaunders: Hehe, yeah.

12:32 weissj: cemerick: why is it so much trouble? have to add extra passes to the reader i guess

12:33 or maybe it does more than 1 pass already?

12:33 Chousuke: not to the reader, but to the compiler I guess.

12:33 weissj: Chousuke: oh right

12:33 cemerick: weissj: I don't know remember what the details were, but at least part of it has to do with name resolution

12:34 weissj: ok

12:34 osaunders: I might try the first of this Euler problems.

12:35 weissj: osaunders: if you haven't got a copy of 'programming clojure' it's really helpful

12:35 osaunders: http://projecteuler.net/index.php?section=problems&id=1

12:35 weissj: Yeah I have. Do you think I should read it fully first?

12:35 weissj: osaunders: no, that's boring :) use it as a reference

12:35 osaunders: weissj: OK, good.

12:36 weissj: it also helps to know where to look for stuff on the clojure website. for instance, "syntax" stuff like what does the # symbol mean, etc, that's on the Reader page.

12:36 tomoj: how do you get a PersistentList of Characters back into a String? Java?

12:37 weissj: str doesn't do it?

12:37 tomoj: no :(

12:37 weissj: it should :)

12:37 tomoj: ,(str '(\f \o \o))

12:37 clojurebot: "(\\f \\o \\o)"

12:37 weissj: wow, that's unexpected

12:37 tomoj: I don't know if it should

12:38 it would have to go through every list it was ever passed to check whether that list is a list of only Characters

12:38 weissj: yeah maybe not, if it's supposed to turn a list into a string representation of the list

12:38 tomoj: on the other hand,

12:38 ,(str \f \o \o)

12:38 clojurebot: "foo"

12:38 tomoj: ..and thus

12:38 weissj: map it

12:38 tomoj: ,(apply str '(\f \o \o))

12:38 clojurebot: "foo"

12:38 weissj: apply rather :)

12:39 nachtalp: hi everybody

12:39 osaunders: Might be a shorthand for (apply str ())

12:39 nachtalp: Hi!

12:40 * osaunders starting to solve Euler 1

12:40 tomoj: I got a bit of a head start

12:40 :)

12:40 wanna compare solutions?

12:41 osaunders: I'll probably take ages. My friend is talking to me also.

12:41 Sure, when I'm done :-)

12:41 nachtalp: does anybody have experience using clojureql? seems i'm not getting the way i'm supposed to deal with result sets properly...

12:42 osaunders: tomoj: Constructing a range first?

12:43 weissj: osaunders: that's seems the easiest to me

12:44 tomoj: osaunders: I didn't use range, but that's a perfectly valid way

12:44 I like to be lazy :)

12:44 osaunders: I'm not really sure what approach to take because I'm thinking in imperative terms

12:44 tomoj: though since you have to sum them all up anyway it doesn't really matter I suppose

12:45 except maybe my way won't blow the heap if you summed it up to HUGE numbers

12:45 weissj: osaunders: think of the range 1..1000 as a set, you're testing each member, then adding the numbers that pass the test

12:45 range isn't lazy?

12:45 osaunders: Oh I have an idea!

12:45 weissj: ,(doc range)

12:45 clojurebot: "([end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0 and step to 1."

12:46 tomoj: oh, you're right

12:46 guess my way is just more verbose then

12:46 osaunders: ,(reduce + (range 0 100))

12:46 clojurebot: 4950

12:46 osaunders: Now I just need to filter.

12:46 weissj: osaunders: you've pretty much got it

12:46 well, except the filter function :)

12:58 osaunders: Hm, I think I have my parens mixed up here.

12:58 weissj: osaunders: paren-matching editor is a must have :)

12:59 tomoj: paredit-mode is a must have :P

12:59 weissj: tomoj: what's that

12:59 tomoj: emacs mode for editing lispish things

13:00 technomancy: paredit is badass

13:00 weissj: tomoj: yeah i know emacs has good support but i just can't bring myself to start learning another obscure editor command set

13:00 tomoj: maybe other editors can barf/slurp, I dunno

13:01 osaunders: Can you re-def something in the REPL?

13:01 weissj: osaunders: yep

13:01 osaunders: OK, good.

13:02 * osaunders wanted to make sure it wasn't silently pretending to

13:02 weissj: osaunders: for euler problems you can probably use just the repl

13:03 osaunders: I think I have a solution but it isn't compiling

13:03 tomoj: doesn't sound like a solution then

13:03 osaunders: ,(doc if)

13:03 clojurebot: "/;nil; "

13:04 tomoj: special form

13:04 osaunders: Yeah, by "a solution" I mean "a broken".

13:04 I have a broken.

13:04 tomoj: http://clojure.org/special_forms#toc2

13:05 osaunders: tomoj: thnx

13:07 OK I have 2318

13:07 tomoj: nope :(

13:07 osaunders: That's wrong?

13:08 tomoj: indeed

13:08 osaunders: Does seem quite high.

13:08 tomoj: for problem one you mean?

13:08 osaunders: Yeah.

13:08 tomoj: it's too low

13:08 osaunders: Oh

13:08 233168?

13:08 tomoj: ja

13:08 osaunders: Yay! :-)

13:09 tomoj: can't you type it in or something?

13:09 osaunders: Seeded the range wrong

13:09 tomoj: I haven't gotten past the ones I'd already solved before in other languages yet

13:10 osaunders: You've already done #1 then I guess.

13:10 tomoj: yep

13:10 osaunders: So that was what you meant by head start.

13:11 tomoj: well, that and I also started working on them in clojure before you

13:11 on number 5 now

13:11 osaunders: http://pastebin.com/m3d47796

13:12 tomoj: http://gist.github.com/165965

13:13 osaunders: Wow.

13:13 Nice/

13:13 What does the # mean?

13:13 Meta or something?

13:13 Chousuke: anonymous function

13:14 #(foo) is short for (fn [] (foo))

13:14 tomoj: with % as the arg

13:14 or %1, %2, etc

13:14 osaunders: :-O

13:14 Chousuke: (and %& for the "rest" arg)

13:14 osaunders: OK.

13:15 cark: tomoj : just a little thing : (dec n) instead of (- n 1)

13:15 tomoj: cark: ah, thanks

13:15 cark: and zero? instead of (= x 0)

13:15 tomoj: that's nice too

13:16 osaunders: Thnx cark.

13:16 Chousuke: osaunders: btw, to avoid having to nest ifs, learn the cond form

13:17 osaunders: ,(doc cond)

13:17 clojurebot: "([& clauses]); Takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical true, cond evaluates and returns the value of the corresponding expr and doesn't evaluate any of the other tests or exprs. (cond) returns nil."

13:18 osaunders: Kinda like switch

13:18 Chousuke: not really.

13:18 (cond test expr test2 expr test3 expr3 :else expr4)

13:18 osaunders: Why have if at all?

13:19 Chousuke: cond is based on if

13:19 osaunders: Couldn't you just go straight to cond?

13:19 Chousuke: ,(macroexpand '(cond test expr))

13:19 clojurebot: (if test expr (clojure.core/cond))

13:19 tomoj: (if pred foo bar) is cooler than (cond pred foo :else bar)

13:19 osaunders: Ah yes, OK.

13:20 Chousuke: ,(macroexpand '(cond test expr test2 expr))

13:20 clojurebot: (if test expr (clojure.core/cond test2 expr))

13:20 Chousuke: recursive macros ftw

13:20 oh, and :else is the idiomatic form of an "always true" test, not special syntax.

13:21 tomoj: better than 't

13:21 Chousuke: yeah, though it would work as well. :p

13:21 tomoj: Chousuke: while you're at it, do you know what the heck condp is for?

13:21 osaunders: Chousuke: Yeah

13:22 tomoj: I've read the docs several times but it seems very strange

13:22 cark: (condp = (get-the-keyword) :a (println "got an a"))

13:22 hiredman: ,(condp = 1 1 :foo 2 :bar)

13:22 clojurebot: :foo

13:22 hiredman: ,(condp = 2 1 :foo 2 :bar)

13:22 clojurebot: :bar

13:23 osaunders: ,({1 :foo, 2 :bar} 1)

13:23 clojurebot: :foo

13:24 osaunders: ,({1 :foo, 2 :bar} 2)

13:24 clojurebot: :bar

13:24 tomoj: hrmm

13:24 osaunders: hiredman: Similar?

13:24 hiredman: no

13:24 osaunders: Oh I guess condp has the = thing.

13:24 hiredman: condp is more like a switch statement

13:24 ,(condp < 1 1 :foo 2 :bar)

13:24 clojurebot: java.lang.IllegalArgumentException: No matching clause: 1

13:24 tomoj: but you get to decide the comparison

13:24 that's pretty nifty

13:25 hiredman: ,(condp > 1 1 :foo 2 :bar)

13:25 clojurebot: :bar

13:25 Chousuke: condp is for cases where the cond test expressions are always of the form (predicate expr someconstantexpr)

13:25 tomoj: yeah I think I see it now

13:25 Chousuke: eg, (= 1 (get-choice)), (= 2 (get-choice)) etc.

13:26 tomoj: don't get the deal with the :>> unary function

13:26 what kind of unary function would you call on the result of a predicate?

13:26 Chousuke: tomoj: the predicate can return other than true or false.

13:26 tomoj: sure, but I guess I just can't think of a usage example

13:26 cark: tomoj : also (take (- 10 1) (iterate inc 1)) is = to (range 1 10)

13:27 tomoj: cark: yeah, I had thought range wasn't lazy

13:27 Chousuke: tomoj: for example, maps can work as a predicate

13:27 clojurebot: for is a loop...in Java

13:28 Chousuke: tomoj: because if the value exists in the map, it's returned, and is usually non-false.

13:28 tomoj: and using :>>, you can also use the value retrieved in the result expression, without the need to look it up again

13:32 osaunders: is camelCase commonplace in Clojure?

13:32 cark: nope we use lisp-case

13:32 osaunders: Hypens?

13:32 cark: yes

13:32 tomoj: camelCase just for java interop

13:33 osaunders: Hypens are much better than underscores.

13:33 Anyway, so now that I've got my Euler #1 working can I write a test to prove that it is?

13:34 Do you guys do that sort of thing.

13:35 tomoj: osaunders: see http://github.com/richhickey/clojure/blob/master/src/clj/clojure/test.clj

13:40 osaunders: tomoj: ok

13:42 tomoj: hmm.. problem number 8 is puzzling

14:17 osaunders: Is there a difference between ; and ;;?

14:17 andyfingerhut: style

14:17 duck11232: emacs indents them differently

14:17 andyfingerhut: semi-idiomatic to use ;; for a full line comment

14:17 ; for a comment at the end of a line after some code

14:18 * technomancy wishes more people would use that convention

14:18 andyfingerhut: but the first ; make everything else a comment.

14:18 osaunders: OK, thanks.

14:18 * osaunders is off again

14:32 bradford: I find that I would often like to destructure the arg to a fun but also be able to let bind the structured arg as well, becasue i need to refer to both within the fn. any ideas?

14:39 Chouser: ,(let [[a b :as all] [1 2 3 4]] {:a a, :b b, :all all})

14:39 clojurebot: {:a 1, :b 2, :all [1 2 3 4]}

14:39 brool: bradford: there's the :as keyword for destructuring, is that what you want?

14:44 bradford: brool, thanks, exactly!

14:44 oh wait, Chouser was forst on the ball with that one, thanks Chouser

14:44 and as always, thanks be to clojurebot

14:45 Chouser: clojurebot: botsnack!

14:45 clojurebot: thanks; that was delicious. (nom nom nom)

14:47 bradford: ,(let [{a :a b :b :as all} {:a 1 :b 2 :c 3}] {:a a, :b b, :all

14:47 all})

14:48 ,(let [{a :a b :b :as all} {:a 1 :b 2 :c 3}] {:a a, :b b, :all all})

14:48 even works on maps, cool

14:48 ,(let [{a :a b :b :as all} {:a 1 :b 2 :c 3}] {:a a, :b b, :all all})

14:48 clojurebot: {:a 1, :b 2, :all {:a 1, :b 2, :c 3}}

14:48 bradford: there we go :-)

14:49 damn leading whitespace

14:49 cark: ,(let [{:keys [a b c]} {:a 1 :b 2}] (+ a 2))

14:49 clojurebot: 3

14:49 cark: i like that form better

14:51 bradford: yea, i have used both and not sure my fav way for map destructuring yet. i was thinking of creating a new fn that works with vector or map of params by default, so doesn't require any :keys or {} destructuring...I think I saw that someone had creted something like this

14:55 tomoj: does reduce hold the head of a lazy seq?

14:56 Chousuke: no

14:56 tomoj: great

15:35 I have created a monster http://gist.github.com/166067

15:36 hiredman: which one is that?

15:36 tomoj: 20x20 grid, max product along a diagonal or up/down left/right

15:37 Chousuke: tomoj: I think that's pretty good.

15:37 tomoj: maybe breaking it up into smaller functions would make it look less monstrous

15:38 or maybe clojure still just looks opaque to me

15:38 hiredman: I think I have about 15 functions I defined to help solve problem 11

15:38 Chousuke: tomoj: I'm finding it harder to describe it in english than in clojure :p

15:39 hiredman: ~hiredmans euler.clj

15:39 clojurebot: hiredmans euler.clj is so embarassing

15:39 Chousuke: for all groups of four numbers, collect their product and return the maximum of the resulting set?

15:40 tomoj: yup, where "group" is a diagonal or up/down left/right

15:40 Chousuke: yeah.

15:40 I think your code is not a monster as I could tell that much from it. :P

15:40 Chouser: which problem #

15:40 tomoj: 11

15:41 if I showed that code to any of my friends in CS I think they'd run screaming

15:41 Chousuke: heh

15:41 and I thought it was simple :P

15:42 then again, your friends in CS probably could code up algorithms that would make me run away screaming

15:42 tomoj: maybe not, I guess they were forced to learn haskell and lambda calculus etc after I left CS

15:43 is (filter identity ..) idiomatic?

15:44 I always feel funny when I do it

15:44 hiredman: there is always (remove nil? …)

15:45 Chouser: (filter identity ...) is fine

15:45 tomoj: (remove nil? ...) seems more readable

15:45 since that's exactly what I'm always trying to do

15:45 Chouser: they don't mean the same

15:46 hiredman: close

15:46 tomoj: (filter identity ...) will also remove false?

15:46 Chouser: ,(filter identity [0 1 false nil 2 3])

15:46 clojurebot: (0 1 2 3)

15:46 Chouser: ,(remove nil? [0 1 false nil 2 3])

15:46 clojurebot: (0 1 false 2 3)

15:46 hiredman: for project euler it is pretty easy to pretend true/false don't exist

15:46 Chousuke: hmm

15:48 you could add a :let [line ...] in the for and use :when (not-outside-bounds line)

15:48 hiredman: my euler.clj has lazy-cons all over the place

15:48 Chouser: oops

15:49 tomoj: Chousuke: ah, nice

15:49 I still haven't figured out all the little options on the different binding forms

15:50 Chousuke: for is a multitool .P

15:52 it does loop, let, filter, take-while all in one

15:52 where loop is not really loop but anyway

15:53 the implementation of for is also rather daunting :P

15:53 Chouser: tomoj: not shabby at all.

15:54 tomoj: jeez

15:54 daunting indeed

15:54 it looks like it's trying to be ascii art

15:54 Chouser: and it needs chunking support now.

15:54 Chousuke: rhickey did request a chunked-seq version of it, and I thought I could do it, but then I saw it and decided to do something else...

15:55 so now I'm writing a reader :P

15:55 Chouser: Chousuke: oh, are you?

15:55 for c-in-c?

15:55 tomoj: :O

15:55 I always thought you two were the same person

15:55 Chousuke: yeah. Though I'm not sure if it'll turn out good enough to be actually usable.

15:56 I also have an implementation of syntax-quote as a macro.

15:56 though I haven't tested it yet :P

15:57 http://github.com/Chousuke/clojure/commits/clojure-reader

15:57 hiredman: testing a reader seems to be a bit of a bugger

15:57 Chousuke: not usable yet.

15:57 hiredman: http://github.com/hiredman/reader/blob/49959a987394c08183c69888b637645c657646d0/hiredman/reader.clj

15:58 Chousuke: heh

15:58 hiredman: I think mine works, but only because it calls out to LispReader

15:58 Chousuke: my reader avoids using java calls

15:58 currently, it wants a sequence of lines.

15:59 hiredman: my plan is/was to slowly remove all wall-hack calls to LispReader

15:59 very pedestrian

15:59 Chousuke: heh.

16:00 I decided I didn't want to bother with state in my reader, so I'm hoping I actually never need to "unread" the underlying stream.

16:01 hiredman: well the reader can return a pair of what was read and what remains of the input

16:01 Chousuke: which is what my reader does.

16:02 hiredman: excellent

16:03 Chousuke: I'm a bit worried about stack space consumption though.

16:03 Chouser: you're using recursion?

16:04 Chousuke: my reader blows up if you have a nested list some hundreds over 2000 deep

16:04 Chouser: haha

16:04 hiredman: time for trampoline?

16:04 Chousuke: the java reader blows up around 9000

16:04 cark: i think it's ok =/

16:04 Chouser: Chousuke: stop worrying.

16:04 Chousuke: Chouser: I have postponed most of the worrying until the reader is in somewhat usable state :)

16:05 Chouser: good

16:05 Chousuke: if someone needs to read hugely nested things they can just increase the stack space anyway!

16:06 cark: won't a reader in clojure be too slow though ?

16:06 Chousuke: I'm not worrying about that either, yet :)

16:07 cark: right, premature optimization ...

16:07 Chousuke: I don't think reading is a common operation though.

16:07 hiredman: cark: that depends on all kinds of things

16:07 Chousuke: of course, it'll impact startup time.

16:07 cark: it is common to me !

16:07 i use it for data files

16:07 hiredman: actually a lot of LispReader is implemented using AFns

16:08 each AFn being a "reader macro"

16:08 and there is a dispatch table for selecting reader macros

16:08 Chousuke: hm

16:08 now I notice my syntax-quote still doesn't work :(

16:09 I need to move doall up in core.clj it seems :P

16:09 hiredman: I am leary of the idea of syntax-quote as a macro

16:09 Chousuke: it is a macro in most lisps isn't it?

16:09 only called quasi-quote or something.

16:10 hiredman: Chousuke: I could just be mistrustful of change

16:10 Chousuke: but... I think core.clj could use a reorganisation. Moving some of the little java wrappers in their own file would probably help a lot :P

16:10 Chouser: rhickey wants it moved out of read time

16:10 hiredman: Chouser: so I should get over it I guess

16:11 * Chouser shrugs

16:11 Chousuke: there are so many functions that are just (instance? whatever ...)

16:11 or (clojure.lang.RT/Whatever ...)

16:11 Chouser: macroable?

16:13 Chousuke: Chouser: no, but could be moved into core_host.clj or something

16:13 it's annoying to put new things in core and having to move many of the little wrappers up because they're defined later than necessary :P

16:33 tomoj: hmm

16:33 someone's brute force C/C++ solution to problem 14 too 29 hours

16:34 s/too/took/

16:34 mine took a couple minutes in clojure

16:34 and I searched quadruple the search space unnecessarily

16:34 odd..

16:35 Chouser: that's the other side of the high-level/low-level language performance discussion.

16:35 tomoj: you can be stupid with low-level language?

16:36 Chousuke: "how easy is it to write the faster algorithm"? :)

16:36 tomoj: ah

16:36 Chouser: Chousuke: right

16:37 if a more efficient algorithm means I have to worry about memory ownership, multiple classes to hold different pieces of internal data, etc. it easier to just write the slower algorithm.

17:02 tomoj: can you use lazy-seq to make a seq where each element is a function of all the previously generated elements?

17:02 mathematical function, I mean, not clojure function

17:04 Chouser: yes

17:04 :-)

17:04 hiredman: you just need a reference to the head of the seq

17:05 tomoj: ah, I see

17:05 hiredman: or to carry around the intermediate results

17:05 depending on the function

17:08 http://clj-me.blogspot.com/2008/06/primes.html <-- example using lazy-cons

17:09 tomoj: no longer exists, right

17:09 hiredman: yeah

17:10 this is just an example, you have to interprolate to a modern approach

17:11 AWizzArd: http://lambda-the-ultimate.org/node/3560

17:12 Chouser: your mathematical function actually needs all the previous values, or just the result of applying itself to all the previous values?

17:12 hiredman: AWizzArd: excellent

17:13 tomoj: now that I think about it a bit more

17:13 it either needs all the previous values, or a related calculated value

17:13 which is not the value that goes in the seq

17:13 AWizzArd: Clojure is even preparing at least to some extent to these vector units

17:14 Chouser: ok, it's pretty common to use recur or iterate and the filter out what you want in a later chain...

17:14 clojure's better at describing this than english

17:14 clojurebot: clojure is the best way to learn java

17:15 tomoj: I think I have done stuff like that before

17:15 just not lazily

17:15 Chouser: (map first (reduce (fn [[return-val internal-val]] [compute-return compute-internal]) ...))

17:16 or if you have no input seq, use iterate instead of reduce

17:18 tomoj: Chouser: thanks... I think I need sleep

17:18 something is not clicking

17:20 ah, found lazy-seq-fibo in programming clojure

17:21 Chouser: well, that may be more helpful than this, but since I don't know what you're actually trying to do:

17:21 (take 10 (map first (iterate (fn [[rv iv]] [(- iv 2) (* iv 3)]) [:foo 1])))

17:21 ,(take 10 (map first (iterate (fn [[rv iv]] [(- iv 2) (* iv 3)]) [:foo 1])))

17:21 clojurebot: (:foo -1 1 7 25 79 241 727 2185 6559)

17:21 tomoj: that actually looks about right

17:22 with appropriate substitutions

17:22 thanks

17:24 Chouser: though if each internal value depends only on the previous, and the return value depends only on one internal value (as in that example), it's probably cleaner to use two links in the seq chain:

17:24 ,(take 10 (map #(- % 2) (iterate #(* % 3) 1)))

17:24 clojurebot: (-1 1 7 25 79 241 727 2185 6559 19681)

17:24 b4taylor: I wish to create a byte[] for java.io.FileInputStream.read(byte[]), is make-array the way to go about doing this?

17:25 Chousuke: into-array might be easier

17:25 hmm

17:25 or not, if you want an empty one :)

17:25 b4taylor: I need an empty one.

17:25 Chousuke: then make-array, yeah

17:25 b4taylor: So my problem arising when I need to give it the type to create.

17:26 Chousuke: use Byte/TYPE

17:26 b4taylor: (make-array byte 256) gives me a cast exception saying byte is the clojure type.

17:26 Ah ok.

17:26 Sweet.

17:26 Thanks.

17:29 Oh crud, unsigned bytes. Forgot about that :p

18:35 andyfingerhut: I know about #^ints, #^doubles, etc. for type hints of Java arrays of primitives. I also know that I can use #^"[Ljava.lang.Object;" as a type hint for a Java array of Objects, but is there a nicer name for that? It seems to help speed up aget/aset on such arrays.

18:42 Chousuke: andyfingerhut: not yet. :P

18:42 andyfingerhut: ok, no big deal.

19:00 hiredman: ~literal [1] problem

19:00 clojurebot: <reply>People have a problem and think "Hey! I'll use a regular expression!". Now they have two problems....

19:01 burkelibbey: Heh, I multiplied two complex numbers with regular expressions once to avoid writing a script in bash >_>

19:02 summary: I agree with clojurebot.

19:05 JAS415: haha

19:06 burkelibbey: So I think this is largely because I have a poor understanding of how namespaces work, but: http://gist.github.com/166172

19:07 I'm trying to write a macro to load application.controllers.X and run the invoke method in it

19:07 Is that a horrible idea, or am I missing something, or...? Help appreciated :P

19:07 Chousuke: you're trying to use namespaces as a plugin mechanism?

19:07 burkelibbey: s/method/function

19:08 I guess, yeah

19:08 Chousuke: yeah, I think that's not such a good idea :P

19:09 burkelibbey: is there a way to automatically load all the sub-namespaces of another namespace, without hard-coding the whole list?

19:09 Chousuke: not really.

19:10 burkelibbey: I guess I'd have to just look through the filesystem

19:10 bah

19:10 Chousuke: subnamespaces are not related to their parent namespaces in any way other than the common part of the path

19:10 burkelibbey: ok

19:11 Chousuke: if you need a plugin mechanism, multimethods might be useful

19:12 each plugin could just do a defmethod on some common multimethod

19:12 burkelibbey: hmm, yeah, there's an idea.

19:12 andyfingerhut: I love clojurebot's brain. So much more interesting than Eliza.

19:12 burkelibbey: thanks

19:15 duck1123: are there any good projects to look at that do a lot with command line params in clojure?

19:16 I had hope with corkscrew, but it does a lot of it in sh, and that's not what I want

19:32 andyfingerhut: It's not as featureful as things I've seen in other languages, but have you seen clojure.contrib.command-line/with-command-line?

19:33 i.e. Perl's GetOptions has lots more bells and whistles.

21:19 JAS415: welp

21:19 eventually i'll know java well enough to use clojure properly :-P

23:34 Chouser: I knew chunked map would be hard, but I thought doseq might be pretty easy.

23:35 now I'm not so sure.

Logging service provided by n01se.net