#clojure logs

2009-08-11

00:00lrennApologies 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.
00:01hiredman*shrug*
00:02hiredman(let [[a b c d] (pcalls foo bar baz bloop)])
00:02tomojthere has got to be a better way to do this: https://gist.github.com/faafe19ec35ed632339c
00:02tomojbasically want to map over a bunch of maps, but I'm only interested in changing a deeply nested key
00:03hiredmanupdate-in
00:03tomojhiredman: awesome. thank you
00:03lrennhiredman: very nice. thanks.
00:04prospero_is there a way to test whether something is a particular type of struct-map?
00:05hiredmantype tag your struct-maps
00:05prospero_so there's no implicit metadata?
00:06tomojI read a mailing list discussion about that a couple days ago
00:06tomojthe type is stored internally but is not accessible, apparently
00:06prospero_link?
00:06prospero_oh, well never mind
00:06prospero_that's a little weird, though
00:06hiredman*shrug*
00:07tomojthe best solution I saw did type tagging with a special constructor function
00:07hiredmanthat is the why to do it
00:07tomojyou could make a special macro for defining structmaps that built a constructor that tags I suppose
00:08dnolentomoj: http://github.com/swannodette/spinoza/tree/master all but abandoned, but a point of reference for exactly that.
00:09dnoleni wrote that early in my fiddlings with clojure. i think it's a fairly pointless pursuit now tho.
00:09tomojwhy pointless?
00:10prospero_so is a struct just a well-documented map, then?
00:10tomojbit faster too I think
00:10prospero_ok
00:10hiredmanwell, for the specified keys
00:11dnolenyou just get so little from a constructor approach when you have already have robust data types, multi-methods, and hierarchies.
00:11dnolenit's also just un-clojure-y.
00:12hiredman
00:12tomojI wonder if my current data structure isn't clojure-y
00:12tomojI have a seq of maps, keys in which contain seqs of maps, keys in which contain seqs of maps
00:13hiredmansounds gnarly
00:13tomojupdate-in helps a little but it's still ugly to twiddle something deep in there
00:14dnolentomoj: why do you need such deeply nested data? that seems weird in general unless your manipulating xml or something.
00:14tomojcourses have one or more sections, each section has one or more meetings
00:16dnolentomoj: what doesn't your code look like now that you're using update in?
00:16dnolenupdate-in
00:21tomojdnolen: https://gist.github.com/faafe19ec35ed632339c
00:21tomojnot any better really...
00:21tomoja bit of duplication removed I suppose
00:22tomojI 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
00:23tomojhypothetical use case for a much gnarlier dataset: (map-and-update-in the-courses [:sections :meetings :instructor :grad-students :address] update-grad-student-address)
00:24tomojlooks fun to write.. :/
00:25dnolentomoj: why not
00:25dnolen(map #(update-in % [:sections :meetings :time] parse-meeting-time) the-courses)
00:25dnolenmight be a typo
00:25tomojhmm
00:25dnolenoh you want to update every meeting?
00:25tomojI didn't think update-in worked that way
00:25tomojindeed
00:26tomoj:sections and :meetings point to lists
00:26tomojupdate-in expects only maps
00:26tomoj(I though)
00:26dnolenonly partly true
00:26dnolen,(update-in [1 2 3] [0] inc)
00:26clojurebot[2 2 3]
00:27tomojah, right
00:27tomojbut I mean I can't get it to map the update over the list, I think
00:27tomojthe nested lists, I mean
00:32JAS415map it over nested lists
00:32JAS415hmm
00:33JAS415isn't there an assoc-in or something
00:33tomojless powerful version of update-in, I think
00:33tomojstill doesn't traverse nested lists afaik
00:34tomojbut I think it's a simple function to do what I want, gonna try writing it in a few
00:35JAS415,(update-in {:a [0 1 2 3] :b [4 5 6 7]} [:a 0] inc)
00:35clojurebot{:a [1 1 2 3], :b [4 5 6 7]}
00:36JAS415,(update-in {:a [0 1 2 3] :b [4 5 6 7]} [:a] (fn [x] (map inc x)))
00:36clojurebot{:a (1 2 3 4), :b [4 5 6 7]}
00:37JAS415,(update-in {:a [0 1 2 3] :b [4 5 6 7]} [:a] (fn [x] (map (fn [_] :foo) x)))
00:37clojurebot{:a (:foo :foo :foo :foo), :b [4 5 6 7]}
00:37tomojJAS415: that's what I'm doing now, https://gist.github.com/faafe19ec35ed632339c/676cbd39a24b8d33908a946b33bb2f5eb1c12820
00:37JAS415:-)
00:38JAS415might consider a helper function to abstract that out
00:38tomojmap-and-update-in :)
00:38JAS415ya
00:38tomojgonna write it in a few
00:44JAS415,(macroexpand-1 '(-> 1 2 3 4 5))
00:44clojurebot(clojure.core/-> (clojure.core/-> 1 2) 3 4 5)
00:44JAS415(macroexpand '(-> 1 2 3 4 5))
00:45JAS415,(macroexpand '(-> 1 2 3 4 5))
00:45clojurebot(5 (clojure.core/-> (clojure.core/-> (clojure.core/-> 1 2) 3) 4))
01:00JAS415,(list 'defmacro 'created ['p] `(code ...)))
01:00clojurebot(defmacro created [p] (sandbox/code ...))
01:11tomojhttps://gist.github.com/faafe19ec35ed632339c
01:11tomojprobably a prettier way to do it
01:11tomojI mean, there probably is a prettier way than that gist
01:12JAS415ah its recursive
01:12JAS415i see
01:12tomojI don't plan to nest anything deep enough to blow the stack :)
01:12JAS415does it change it from a vector to a lazy-seq?
01:13tomojyeah, because of the map
01:13JAS415hmm
01:13tomojI don't care too much right now cus my data isn't vectors anyway
01:13JAS415ah
01:13JAS415lazy seqs can get tricky
01:13tomojI guess (vec (map ..)) solves that?
01:14hiredman(defn map! [func coll] (into (empty coll) (map func coll)))
01:14JAS415ah cool
01:15tomojpreserves type?
01:15hiredmansort of
01:15JAS415looks like it
01:15JAS415do vectors hold metadata?
01:15hiredman,((fn [func coll] (into (empty coll) (map func coll))) inc #{1 2 3})
01:15clojurebot#{2 3 4}
01:24tomojhrmm
01:25tomojmissed a bunch of edge cases
01:25tomojbut... (map-and-update-in the-courses [:sections :meetings :time] parse-meeting-time))
01:25tomojwoot
01:36jwhitlarkDoes 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.
01:52JAS415edge cases are always the worst
02:10tomojgraaawwl
02:10tomojthe worst indeed
02:10tomojI think the number of edge case problems I have is a sign that I'm thinking about this function in the wrong way
02:10tomojthere's probably some simple two liner
04:01Anniepooclojurebot: paste
04:01clojurebotlisppaste8, url
04:01lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
04:02lisppaste8Anniepoo pasted "the case of the missing metadata" at http://paste.lisp.org/display/85182
04:02AnniepooI'm attempting to add some metadata to some data
04:03Anniepooit's not getting added
04:03arbschtwhat is the data?
04:04Anniepooit's vectors, a long list of them
04:04Anniepoowhen I compile the list this code is supposed to be adding some metadata
04:06lisppaste8Anniepoo annotated #85182 "a shorter version" at http://paste.lisp.org/display/85182#1
04:06Anniepoosorry, it's getting late
04:06Anniepoohere's the gist of it
04:06arbschtI think you want with-meta rather than the reader syntax
04:07arbscht,(map meta (map (fn [x] #{:foo 1} x) [[2] [3]]))
04:07clojurebot(nil nil)
04:07arbscht,(map meta (map (fn [x] (with-meta x {:foo 1})) [[2] [3]]))
04:07clojurebot({:foo 1} {:foo 1})
04:07Anniepoook, can you articulate why this is different?
04:08AnniepooI'm obviously missing something simple about the reader macros
04:10arbschtas 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
04:10Anniepooah! perhaps I'm adding my metadata to the var, not the contents?
04:11Anniepoo8cD Annie was sorta awake during the clojure talk
04:20Anniepoowhoo hoo, it's printing what looks like the correct gibberish to drive the robot
04:21Anniepootomorrow I wire it up
04:22AnniepooThanks for all the help, folks
04:22clojurebotfor is a loop...in Java
04:23tdrgabiI'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
04:23tdrgabihow can I build the sorted-map ?
04:24tdrgabii know it works as (sorted-map 1 2 3 4) ... but I have the keys & values in a seq
04:25tomojtdrgabi: (apply sorted-map keyvals)
04:26tdrgabitomoj: thank you.
07:23paolinohello 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
07:25opqdonut"alive like smalltalk"
07:25opqdonutyou are surely joking
07:25andyfingerhutI 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.
07:25andyfingerhutNor do I think that was its intent.
07:25andyfingerhutIs Clojure useful, too? Certainly.
07:26paolinoopqdonut: I was not, actually :-/
07:27paolinoandyfingerhut: scripting with clojure seems better than both ruby and python, given the jvm
07:27clojurefrom 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
07:28paolinoclojure: exactly, but also lbraries are generally more industrial strength in java
07:29paolinoI'm a java detractor also :), but realistic about the libraries
07:31paolinoopqdonut: the REPL seems very "alive", but I'm probably "hyped" by the examples
07:32opqdonutah
07:32opqdonuti thought alive as in the community or development
07:32opqdonutsmalltalk is pretty much dead afaict
07:34paolinoalso 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
07:34paolinoclojure is even simpler then both python and ruby in that sense
08:16cemerickhrm, I hadn't seen this before: java.lang.IllegalArgumentException: recur arg for primitive local: dist must be matching primitive
08:17andyfingerhutYou 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.
08:17cemerickI guess I figured the loop binding would just get boxed if the compiler saw any recurs that provided non-primitive args
08:17cemerickandyfingerhut: yeah, I knew what was going on, just hadn't seen it before :-)
08:23cemerickand actually, the initial loop binding was Double/MAX_VALUE, so I wasn't even thinking about whether the value was primitive or not.
08:24andyfingerhutweird. Doesn't look primitive to me.
08:25andyfingerhut,(class Double/MAX_VALUE)
08:25clojurebotjava.lang.Double
08:25andyfingerhut,(class (double 5.0))
08:25clojurebotjava.lang.Double
08:25andyfingerhutgood enough, I guess
08:25cemerickandyfingerhut: you're passing it to the class fn, which boxes
08:25cemerickit's defined as a "public static final double" in j.l.Double
08:26andyfingerhutare there any writeups about when boxing/unboxing occur in Clojure? Or you just absorb it over time? Or read the source?
08:27cemerickChouser came up with a utility that reported what types the compiler sees for a particular form. Don't remember where it is, though.
08:27cemerickIt was definitely some black majick :-)
08:27cemerickandyfingerhut: there are some odd corner cases, but in general, any function boundary will cause boxing.
08:39Chouserrepl-utils/expression-info
08:40andyfingerhutgrazie, signoure!
08:40andyfingerhutUm, I mean, thanks. Vacation to Italy makes me want to use two of the 30 words of Italian I know :)
08:41Chouserandyfingerhut: perfectly acceptible. clojurebot has raised the bar on such things.
08:43cemerickChouser: you'll be happy to know that I've not had to care about zf/auto at all yet.
08:44Chousercemerick: interesting. I forget -- these are nested vectors?
08:45cemerickno, the primary hierarchy is formed by nested spatial indexes
08:46cemerickmostly neighbor graphs, an RTree here and there
08:49Chouserdo you have data in the interior nodes or just at the leaves?
08:49cemerickmy 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]
08:50cemerickChouser: the former. Every level of the hierarchy is potentially relevant, depending on what's being done.
08:51andyfingerhutOK, 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?
08:52ChouserThe reason for zf/auto is so that xml queries don't end up looking like [:html children :head children :body ...]
08:53Chouserxpath uses a plain / for that, but I couldn't find a syntax I liked, so I made it implicit
08:53cemerickyeah, I know. I'm just using / as a proxy for zf/children *shrug*
08:54Chouserandyfingerhut: 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?
08:54Chousercemerick: oh, ok. well, that's why you haven't had to mess with it then. :-)
08:54cemerick[\\ :foo / :bar / :baz] was good enough for me, as you can't be certain that a :foo predicate should return children or not
08:55cemerickactually, I've written queries like [\\ :foo /], just to return children of :foo's :-P
08:55Chousercemerick: that may be better anyway.
08:56cemerickChouser: you don't like using a fn arg from clojure.core as part of your query language? ;-)
08:56Chouser:-P
08:58Chouserandyfingerhut: what would you want to know about each sub-expression? Just primitive true/false? The class also, or even more?
08:58Chouserhm. I think one problem would be indicating which sub-expression each bit of info is talking about.
08:59Chouserby the time the compiler is done with them, the expressions are unprintable and hard to recognize.
08:59andyfingerhutChouser: 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.
09:00andyfingerhutbut flagging other sources of inefficiency besides boxing/unboxing could be useful as well.
09:00Chouserthis sort of thing will be much easier after c-in-c
09:01Chouserin 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.
09:01andyfingerhutok. I don't have a burning need for this -- just sounds like something nice to have around.
09:02Chouserok. then I'll try to stop thinking about it...
09:02cemerickheh, clojure.core/explain :-P
09:02Chouserhiredman: how's the reader coming along?
09:03andyfingerhutIt'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*
09:03Chouserreflection is a much bigger cost, but yeah I understand.
09:06cemerickonce float and double primitive args are available, a lot of tuning should just go away, I'd think
09:16osaundersHas anyone considered a whitespace sensitive Clojure?
09:17andyfingerhutlike Python?
09:17osaundersSure.
09:17osaundersTo cut down on the parens.
09:18Chouserosaunders: yes, but the proposal has the same difficulties as it does for all the lisps
09:18osaundersChouser: What are those?
09:19opqdonutpeople always suggest that, then they program in lisp for a while and forget about this perceived need
09:19Chouserspecifically, 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.
09:19AWizzArd~seen kotarak
09:19clojurebotkotarak was last seen quiting IRC, 921 minutes ago
09:19andyfingerhutBlues 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.
09:20andyfingerhut(referring to parens in Lisp)
09:20osaundersHm, OK.
09:21Chousersomebody did it for CL. Looked pretty good, and it still was never popular. I wonder if I can find a link...
09:21osaundersBut there's no technical reason why it can't be done is there?
09:21clojurebothttp://clojure.org/rationale
09:21carkthe reader is not programmable in clojure
09:21carkso that wouldn't be possible
09:21Chouserosaunders: there are the normal technical challenges, but a pre-processor is entirely possible.
09:22opqdonutaa
09:22opqdonut-aa
09:22carkright, withh a pre-processor, but that would suck big time !
09:22osaundersYeah, OK.
09:23carkunless you make a repl too
09:23Chousernot sure how nice whitespace would be at the repl anyway. a bit painful in python.
09:23carktrue
09:23osaundersWS doesn't work in REPLs generally, yeah.
09:23carkanyways don't you dare take my parenthesis away =)
09:24Chouseryou 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.
09:24osaundersYou like typing huh?
09:24osaunders@cark ^
09:24andyfingerhuthttp://xkcd.com/297
09:24carki like cut/paster full forms with a single keystroke
09:25osaundersWhat are cut/paster full forms?
09:25carkcut/paste
09:25carkwell parenthesis allow for easy editing
09:25osaundersYou paste all the parenthesis?
09:25carkand navigating too
09:26carkare you familiar with emacs? (i guess vim is good too)
09:26osaundersParenthesis denote the data structures.
09:26andyfingerhutcark is probably referring to special features in emacs and vi/vim for selecting/cutting/pasting entire subexpressions at a time
09:26osaundersI would describe indentation as allowing for easy editing.
09:27osaundersI use TextMate mainly. I have a passing familiarity with vim.
09:27osaundersandyfingerhut: Ah, OK.
09:27osaundersActually that sounds incredibly cool.
09:27Chouserin vim y% copies a whole expression, even without any special support for lisp or clojure.
09:28osaundersBut would be achieved with whitespace sensitivity also.
09:28osaunders*could be
09:28carkwith these tools, you cut/paste your forms, not thinking about indentation, then let them reindent your code
09:28Chouserthere may be something similar in a specail python config file, but I don't know.
09:29carkand most important is the navigation, get inside a form, go two forms forward, dopwn one, delete next form, up up paste
09:30carktoo bad i can't express myself in english good enough to convey the fun of it
09:30osaunderscark: It sounds pretty cool actually.
09:30carkthe learning curve is pretty steep though
09:31andyfingerhutosaunders: 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.
09:31Chouserosaunders: http://www.dwheeler.com/readable/
09:32carkright, people have come up with that idea for 50 years, and we still have parenthesis
09:32osaunderslol
09:32osaundersDamn.
09:32osaundersI'm surprised you guys even took me seriously at all.
09:33carkhey there was progress, in clojure we have [] and {} now =)
09:33andyfingerhutnot to say it never will, but there is a bit of inertia, or even strong preference, to keep them.
09:34andyfingerhutI'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.
09:34osaunders:-S
09:35osaundersSort of like Smalltalk images only with XML.
09:35carkthe idea has some merit, but when you want to do macros, you'd rather directly see the parse tree
09:35andyfingerhutI 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.
09:36osaundersandyfingerhut: Problem with that is that you create a two-tier community.
09:36osaundersLike with braces in C.
09:37carkanyways what's important is the semantics of the language, as opposed to the window dressing
09:37andyfingerhutwell, 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 :)
09:37Chousercark: I think syntax matters.
09:38carkyes it does, what i mean is that we have something that works pretty well already
09:38carkwe're past that
09:38Chousermaybe 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.
09:38Chouseryeah
09:39carkwhat make clojure great are data structures and concurrency
09:39osaundersDoes anyone want to be my learn Clojure buddy?
09:39carkliteral syntax for those data structures is a plus, but we could live without it i think
09:41carkspeaking of which , does anybody know of a persistent baanced ternary tree implementation for the jvm ?
09:41osaundersGuess not. :-(
09:41andyfingerhutosaunders: What's the pay? :) Seriously, hanging around #clojure might be a decent way -- why have just one teacher?
09:41osaundersandyfingerhut: Hm. OK. I'll stick around.
09:42tomojosaunders: what does being a learning buddy involve?
09:42osaunderstomoj: Helping each other to learn. Probably just over IRC.
09:43osaunderstomoj: Perhaps both trying to write the same thing in Clojure and then compare solutions.
09:43tomojthat last sounds kinda fun
09:44osaundersWe should probably do it in channel so that more experienced people can chime in.
09:44tomojI'm here most all the time anyway
09:44Chouserthere are a bunch of project euler solutions around that are great for that.
09:45osaundersChouser: Link?
09:45tomojah project euler
09:45tomojhad forgotten about that, good idea
09:46osaunders"Mathematical problems" :-S
09:46Chouseroh, not really. more logic than math really.
09:46andyfingerhutI'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
09:46andyfingerhutI've used Scheme and Lisp marginally after learning them 20 years ago, but am newer to Clojure-specific things.
09:47tomojI think stuff like project euler would be great for getting my head into clojure-space
09:47ChouserI 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.
09:47osaundersHm.
09:47ChouserA 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/
09:49andyfingerhutIt 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.
09:51osaundersOK well I'm going to the pub for a beer.
09:51osaundersAnd then I'm going to dig in a bit.
09:51Chouserthe problems start pretty easy. I found PE to be fun and very educational.
09:51osaunderstomoj: I'm on GTalk if you like.
09:51osaundersand MSN.
09:52osaundersOr maybe just here is better.
09:53tomojbitlbee kicks me off of gtalk frequently
09:53osaundersHm, OK. I'll just hang around on here then.
09:53tomojI've stopped bothering to reconnect
09:53osaundersAlright bbl
10:06tomojhmm
10:07tomojoh, "hmm" revoked
10:30jayfieldsHow do I get access to static inner classes?
10:31Chouserpkg.name.Outer$Inner
10:32jayfieldsthanks Chouser
12:23osaunders~seen tomoj
12:23clojurebottomoj was last seen in #clojure, 136 minutes ago saying: oh, "hmm" revoked
12:24tomojhallo
12:24osaundersHey
12:24osaundersHow much Clojure do you know?
12:25tomojdunno, not much
12:25osaundersHow long have you been doing it?
12:25tomojI lightly read the "Programming Clojure" book
12:25tomojbeen playing around for maybe a week or two
12:26osaundersOK, because today is day 2 for me.
12:26osaundersDo you know what (def blah) does? Without the init part.
12:26weissjosaunders: i started picking it up a few weeks ago, been pretty cool so far
12:27weissjosaunders: it makes it so you can use that var later in the file
12:27weissjotherwise you have to def things before you use them
12:27weissjso you put those (def blah) at the top
12:27weissjmaybe there's some other purpose, but that what i've used it for
12:28tomojsounds right to me
12:28osaundersweissj: Oh. But there's a difference between (def blah) and (def blah nil) isn't there?
12:28tomoj(def blah) leaves blah unboand
12:28tomojer, unbound
12:28osaundersRight so you'll still get an error if you access it?
12:28tomojindeed
12:28weissjbut i believe that still does the trick - you can now put a reference to blah anywhere in the file
12:29weissjit'll compile at least :)
12:29weissjanywhere below that def, i mean
12:29osaundersYeah, I don't really see the point in that.
12:29cemerick(declare blah) is more idiomatic for vars you want to establish but not define
12:29weissjosaunders: 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:30weissjie, if a calls b, b must be before a in the file
12:30osaundersweissj: Ah, OK.
12:30weissjusing a bunch of defs at the top frees you to use any order
12:30osaundersI'm used to languages where it doesn't care about that.
12:30osaunders-1 for Clojure
12:30weissjyeah, i have heard some talk in this channel of fixing that
12:31tomojalso perhaps you want to use the var only with per-thread bindings
12:31tomojin that case no reason to give it a root binding
12:31cemerickweissj: Rich said it was *way* more trouble than it's worth a couple of weeks ago.
12:31weissjcemerick: oh ok
12:31weissjit's not that big a deal to me
12:31weissjwhen other langs have macros, then i'll complain about something like this in clojure :)
12:32osaundersHehe, yeah.
12:32weissjcemerick: why is it so much trouble? have to add extra passes to the reader i guess
12:33weissjor maybe it does more than 1 pass already?
12:33Chousukenot to the reader, but to the compiler I guess.
12:33weissjChousuke: oh right
12:33cemerickweissj: I don't know remember what the details were, but at least part of it has to do with name resolution
12:34weissjok
12:34osaundersI might try the first of this Euler problems.
12:35weissjosaunders: if you haven't got a copy of 'programming clojure' it's really helpful
12:35osaundershttp://projecteuler.net/index.php?section=problems&id=1
12:35osaundersweissj: Yeah I have. Do you think I should read it fully first?
12:35weissjosaunders: no, that's boring :) use it as a reference
12:35osaundersweissj: OK, good.
12:36weissjit 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:36tomojhow do you get a PersistentList of Characters back into a String? Java?
12:37weissjstr doesn't do it?
12:37tomojno :(
12:37weissjit should :)
12:37tomoj,(str '(\f \o \o))
12:37clojurebot"(\\f \\o \\o)"
12:37weissjwow, that's unexpected
12:37tomojI don't know if it should
12:38tomojit would have to go through every list it was ever passed to check whether that list is a list of only Characters
12:38weissjyeah maybe not, if it's supposed to turn a list into a string representation of the list
12:38tomojon the other hand,
12:38tomoj,(str \f \o \o)
12:38clojurebot"foo"
12:38tomoj..and thus
12:38weissjmap it
12:38tomoj,(apply str '(\f \o \o))
12:38clojurebot"foo"
12:38weissjapply rather :)
12:39nachtalphi everybody
12:39osaundersMight be a shorthand for (apply str ())
12:39osaundersnachtalp: Hi!
12:40tomojI got a bit of a head start
12:40tomoj:)
12:40tomojwanna compare solutions?
12:41osaundersI'll probably take ages. My friend is talking to me also.
12:41osaundersSure, when I'm done :-)
12:41nachtalpdoes anybody have experience using clojureql? seems i'm not getting the way i'm supposed to deal with result sets properly...
12:42osaunderstomoj: Constructing a range first?
12:43weissjosaunders: that's seems the easiest to me
12:44tomojosaunders: I didn't use range, but that's a perfectly valid way
12:44tomojI like to be lazy :)
12:44osaundersI'm not really sure what approach to take because I'm thinking in imperative terms
12:44tomojthough since you have to sum them all up anyway it doesn't really matter I suppose
12:45tomojexcept maybe my way won't blow the heap if you summed it up to HUGE numbers
12:45weissjosaunders: think of the range 1..1000 as a set, you're testing each member, then adding the numbers that pass the test
12:45weissjrange isn't lazy?
12:45osaundersOh I have an idea!
12:45weissj,(doc range)
12:45clojurebot"([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:46tomojoh, you're right
12:46tomojguess my way is just more verbose then
12:46osaunders,(reduce + (range 0 100))
12:46clojurebot4950
12:46osaundersNow I just need to filter.
12:46weissjosaunders: you've pretty much got it
12:46weissjwell, except the filter function :)
12:58osaundersHm, I think I have my parens mixed up here.
12:58weissjosaunders: paren-matching editor is a must have :)
12:59tomojparedit-mode is a must have :P
12:59weissjtomoj: what's that
12:59tomojemacs mode for editing lispish things
13:00technomancyparedit is badass
13:00weissjtomoj: yeah i know emacs has good support but i just can't bring myself to start learning another obscure editor command set
13:00tomojmaybe other editors can barf/slurp, I dunno
13:01osaundersCan you re-def something in the REPL?
13:01weissjosaunders: yep
13:01osaundersOK, good.
13:02weissjosaunders: for euler problems you can probably use just the repl
13:03osaundersI think I have a solution but it isn't compiling
13:03tomojdoesn't sound like a solution then
13:03osaunders,(doc if)
13:03clojurebot"/;nil; "
13:04tomojspecial form
13:04osaundersYeah, by "a solution" I mean "a broken".
13:04osaundersI have a broken.
13:04tomojhttp://clojure.org/special_forms#toc2
13:05osaunderstomoj: thnx
13:07osaundersOK I have 2318
13:07tomojnope :(
13:07osaundersThat's wrong?
13:08tomojindeed
13:08osaundersDoes seem quite high.
13:08tomojfor problem one you mean?
13:08osaundersYeah.
13:08tomojit's too low
13:08osaundersOh
13:08osaunders233168?
13:08tomojja
13:08osaundersYay! :-)
13:09tomojcan't you type it in or something?
13:09osaundersSeeded the range wrong
13:09tomojI haven't gotten past the ones I'd already solved before in other languages yet
13:10osaundersYou've already done #1 then I guess.
13:10tomojyep
13:10osaundersSo that was what you meant by head start.
13:11tomojwell, that and I also started working on them in clojure before you
13:11tomojon number 5 now
13:11osaundershttp://pastebin.com/m3d47796
13:12tomojhttp://gist.github.com/165965
13:13osaundersWow.
13:13osaundersNice/
13:13osaundersWhat does the # mean?
13:13osaundersMeta or something?
13:13Chousukeanonymous function
13:14Chousuke#(foo) is short for (fn [] (foo))
13:14tomojwith % as the arg
13:14tomojor %1, %2, etc
13:14osaunders:-O
13:14Chousuke(and %& for the "rest" arg)
13:14osaundersOK.
13:15carktomoj : just a little thing : (dec n) instead of (- n 1)
13:15tomojcark: ah, thanks
13:15carkand zero? instead of (= x 0)
13:15tomojthat's nice too
13:16osaundersThnx cark.
13:16Chousukeosaunders: btw, to avoid having to nest ifs, learn the cond form
13:17osaunders,(doc cond)
13:17clojurebot"([& 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:18osaundersKinda like switch
13:18Chousukenot really.
13:18Chousuke(cond test expr test2 expr test3 expr3 :else expr4)
13:18osaundersWhy have if at all?
13:19Chousukecond is based on if
13:19osaundersCouldn't you just go straight to cond?
13:19Chousuke,(macroexpand '(cond test expr))
13:19clojurebot(if test expr (clojure.core/cond))
13:19tomoj(if pred foo bar) is cooler than (cond pred foo :else bar)
13:19osaundersAh yes, OK.
13:20Chousuke,(macroexpand '(cond test expr test2 expr))
13:20clojurebot(if test expr (clojure.core/cond test2 expr))
13:20Chousukerecursive macros ftw
13:20Chousukeoh, and :else is the idiomatic form of an "always true" test, not special syntax.
13:21tomojbetter than 't
13:21Chousukeyeah, though it would work as well. :p
13:21tomojChousuke: while you're at it, do you know what the heck condp is for?
13:21osaundersChousuke: Yeah
13:22tomojI've read the docs several times but it seems very strange
13:22cark(condp = (get-the-keyword) :a (println "got an a"))
13:22hiredman,(condp = 1 1 :foo 2 :bar)
13:22clojurebot:foo
13:22hiredman,(condp = 2 1 :foo 2 :bar)
13:22clojurebot:bar
13:23osaunders,({1 :foo, 2 :bar} 1)
13:23clojurebot:foo
13:24osaunders,({1 :foo, 2 :bar} 2)
13:24clojurebot:bar
13:24tomojhrmm
13:24osaundershiredman: Similar?
13:24hiredmanno
13:24osaundersOh I guess condp has the = thing.
13:24hiredmancondp is more like a switch statement
13:24hiredman,(condp < 1 1 :foo 2 :bar)
13:24clojurebotjava.lang.IllegalArgumentException: No matching clause: 1
13:24tomojbut you get to decide the comparison
13:24tomojthat's pretty nifty
13:25hiredman,(condp > 1 1 :foo 2 :bar)
13:25clojurebot:bar
13:25Chousukecondp is for cases where the cond test expressions are always of the form (predicate expr someconstantexpr)
13:25tomojyeah I think I see it now
13:25Chousukeeg, (= 1 (get-choice)), (= 2 (get-choice)) etc.
13:26tomojdon't get the deal with the :>> unary function
13:26tomojwhat kind of unary function would you call on the result of a predicate?
13:26Chousuketomoj: the predicate can return other than true or false.
13:26tomojsure, but I guess I just can't think of a usage example
13:26carktomoj : also (take (- 10 1) (iterate inc 1)) is = to (range 1 10)
13:27tomojcark: yeah, I had thought range wasn't lazy
13:27Chousuketomoj: for example, maps can work as a predicate
13:27clojurebotfor is a loop...in Java
13:28Chousuketomoj: because if the value exists in the map, it's returned, and is usually non-false.
13:28Chousuketomoj: and using :>>, you can also use the value retrieved in the result expression, without the need to look it up again
13:32osaundersis camelCase commonplace in Clojure?
13:32carknope we use lisp-case
13:32osaundersHypens?
13:32carkyes
13:32tomojcamelCase just for java interop
13:33osaundersHypens are much better than underscores.
13:33osaundersAnyway, so now that I've got my Euler #1 working can I write a test to prove that it is?
13:34osaundersDo you guys do that sort of thing.
13:35tomojosaunders: see http://github.com/richhickey/clojure/blob/master/src/clj/clojure/test.clj
13:40osaunderstomoj: ok
13:42tomojhmm.. problem number 8 is puzzling
14:17osaundersIs there a difference between ; and ;;?
14:17andyfingerhutstyle
14:17duck11232emacs indents them differently
14:17andyfingerhutsemi-idiomatic to use ;; for a full line comment
14:17andyfingerhut; for a comment at the end of a line after some code
14:18andyfingerhutbut the first ; make everything else a comment.
14:18osaundersOK, thanks.
14:32bradfordI 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:39Chouser,(let [[a b :as all] [1 2 3 4]] {:a a, :b b, :all all})
14:39clojurebot{:a 1, :b 2, :all [1 2 3 4]}
14:39broolbradford: there's the :as keyword for destructuring, is that what you want?
14:44bradfordbrool, thanks, exactly!
14:44bradfordoh wait, Chouser was forst on the ball with that one, thanks Chouser
14:44bradfordand as always, thanks be to clojurebot
14:45Chouserclojurebot: botsnack!
14:45clojurebotthanks; that was delicious. (nom nom nom)
14:47bradford ,(let [{a :a b :b :as all} {:a 1 :b 2 :c 3}] {:a a, :b b, :all
14:47bradford all})
14:48bradford ,(let [{a :a b :b :as all} {:a 1 :b 2 :c 3}] {:a a, :b b, :all all})
14:48bradfordeven works on maps, cool
14:48bradford,(let [{a :a b :b :as all} {:a 1 :b 2 :c 3}] {:a a, :b b, :all all})
14:48clojurebot{:a 1, :b 2, :all {:a 1, :b 2, :c 3}}
14:48bradfordthere we go :-)
14:49bradforddamn leading whitespace
14:49cark,(let [{:keys [a b c]} {:a 1 :b 2}] (+ a 2))
14:49clojurebot3
14:49carki like that form better
14:51bradfordyea, 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:55tomojdoes reduce hold the head of a lazy seq?
14:56Chousukeno
14:56tomojgreat
15:35tomojI have created a monster http://gist.github.com/166067
15:36hiredmanwhich one is that?
15:36tomoj20x20 grid, max product along a diagonal or up/down left/right
15:37Chousuketomoj: I think that's pretty good.
15:37tomojmaybe breaking it up into smaller functions would make it look less monstrous
15:38tomojor maybe clojure still just looks opaque to me
15:38hiredmanI think I have about 15 functions I defined to help solve problem 11
15:38Chousuketomoj: I'm finding it harder to describe it in english than in clojure :p
15:39hiredman~hiredmans euler.clj
15:39clojurebothiredmans euler.clj is so embarassing
15:39Chousukefor all groups of four numbers, collect their product and return the maximum of the resulting set?
15:40tomojyup, where "group" is a diagonal or up/down left/right
15:40Chousukeyeah.
15:40ChousukeI think your code is not a monster as I could tell that much from it. :P
15:40Chouserwhich problem #
15:40tomoj11
15:41tomojif I showed that code to any of my friends in CS I think they'd run screaming
15:41Chousukeheh
15:41Chousukeand I thought it was simple :P
15:42Chousukethen again, your friends in CS probably could code up algorithms that would make me run away screaming
15:42tomojmaybe not, I guess they were forced to learn haskell and lambda calculus etc after I left CS
15:43tomojis (filter identity ..) idiomatic?
15:44tomojI always feel funny when I do it
15:44hiredmanthere is always (remove nil? …)
15:45Chouser(filter identity ...) is fine
15:45tomoj(remove nil? ...) seems more readable
15:45tomojsince that's exactly what I'm always trying to do
15:45Chouserthey don't mean the same
15:46hiredmanclose
15:46tomoj(filter identity ...) will also remove false?
15:46Chouser,(filter identity [0 1 false nil 2 3])
15:46clojurebot(0 1 2 3)
15:46Chouser,(remove nil? [0 1 false nil 2 3])
15:46clojurebot(0 1 false 2 3)
15:46hiredmanfor project euler it is pretty easy to pretend true/false don't exist
15:46Chousukehmm
15:48Chousukeyou could add a :let [line ...] in the for and use :when (not-outside-bounds line)
15:48hiredmanmy euler.clj has lazy-cons all over the place
15:48Chouseroops
15:49tomojChousuke: ah, nice
15:49tomojI still haven't figured out all the little options on the different binding forms
15:50Chousukefor is a multitool .P
15:52Chousukeit does loop, let, filter, take-while all in one
15:52Chousukewhere loop is not really loop but anyway
15:53Chousukethe implementation of for is also rather daunting :P
15:53Chousertomoj: not shabby at all.
15:54tomojjeez
15:54tomojdaunting indeed
15:54tomojit looks like it's trying to be ascii art
15:54Chouserand it needs chunking support now.
15:54Chousukerhickey 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:55Chousukeso now I'm writing a reader :P
15:55ChouserChousuke: oh, are you?
15:55Chouserfor c-in-c?
15:55tomoj:O
15:55tomojI always thought you two were the same person
15:55Chousukeyeah. Though I'm not sure if it'll turn out good enough to be actually usable.
15:56ChousukeI also have an implementation of syntax-quote as a macro.
15:56Chousukethough I haven't tested it yet :P
15:57Chousukehttp://github.com/Chousuke/clojure/commits/clojure-reader
15:57hiredmantesting a reader seems to be a bit of a bugger
15:57Chousukenot usable yet.
15:57hiredmanhttp://github.com/hiredman/reader/blob/49959a987394c08183c69888b637645c657646d0/hiredman/reader.clj
15:58Chousukeheh
15:58hiredmanI think mine works, but only because it calls out to LispReader
15:58Chousukemy reader avoids using java calls
15:58Chousukecurrently, it wants a sequence of lines.
15:59hiredmanmy plan is/was to slowly remove all wall-hack calls to LispReader
15:59hiredmanvery pedestrian
15:59Chousukeheh.
16:00ChousukeI 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:01hiredmanwell the reader can return a pair of what was read and what remains of the input
16:01Chousukewhich is what my reader does.
16:02hiredmanexcellent
16:03ChousukeI'm a bit worried about stack space consumption though.
16:03Chouseryou're using recursion?
16:04Chousukemy reader blows up if you have a nested list some hundreds over 2000 deep
16:04Chouserhaha
16:04hiredmantime for trampoline?
16:04Chousukethe java reader blows up around 9000
16:04carki think it's ok =/
16:04ChouserChousuke: stop worrying.
16:04ChousukeChouser: I have postponed most of the worrying until the reader is in somewhat usable state :)
16:05Chousergood
16:05Chousukeif someone needs to read hugely nested things they can just increase the stack space anyway!
16:06carkwon't a reader in clojure be too slow though ?
16:06ChousukeI'm not worrying about that either, yet :)
16:07carkright, premature optimization ...
16:07ChousukeI don't think reading is a common operation though.
16:07hiredmancark: that depends on all kinds of things
16:07Chousukeof course, it'll impact startup time.
16:07carkit is common to me !
16:07carki use it for data files
16:07hiredmanactually a lot of LispReader is implemented using AFns
16:08hiredmaneach AFn being a "reader macro"
16:08hiredmanand there is a dispatch table for selecting reader macros
16:08Chousukehm
16:08Chousukenow I notice my syntax-quote still doesn't work :(
16:09ChousukeI need to move doall up in core.clj it seems :P
16:09hiredmanI am leary of the idea of syntax-quote as a macro
16:09Chousukeit is a macro in most lisps isn't it?
16:09Chousukeonly called quasi-quote or something.
16:10hiredmanChousuke: I could just be mistrustful of change
16:10Chousukebut... 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:10Chouserrhickey wants it moved out of read time
16:10hiredmanChouser: so I should get over it I guess
16:11Chousukethere are so many functions that are just (instance? whatever ...)
16:11Chousukeor (clojure.lang.RT/Whatever ...)
16:11Chousermacroable?
16:13ChousukeChouser: no, but could be moved into core_host.clj or something
16:13Chousukeit'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:33tomojhmm
16:33tomojsomeone's brute force C/C++ solution to problem 14 too 29 hours
16:34tomojs/too/took/
16:34tomojmine took a couple minutes in clojure
16:34tomojand I searched quadruple the search space unnecessarily
16:34tomojodd..
16:35Chouserthat's the other side of the high-level/low-level language performance discussion.
16:35tomojyou can be stupid with low-level language?
16:36Chousuke"how easy is it to write the faster algorithm"? :)
16:36tomojah
16:36ChouserChousuke: right
16:37Chouserif 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:02tomojcan you use lazy-seq to make a seq where each element is a function of all the previously generated elements?
17:02tomojmathematical function, I mean, not clojure function
17:04Chouseryes
17:04Chouser:-)
17:04hiredmanyou just need a reference to the head of the seq
17:05tomojah, I see
17:05hiredmanor to carry around the intermediate results
17:05hiredmandepending on the function
17:08hiredmanhttp://clj-me.blogspot.com/2008/06/primes.html <-- example using lazy-cons
17:09tomojno longer exists, right
17:09hiredmanyeah
17:10hiredmanthis is just an example, you have to interprolate to a modern approach
17:11AWizzArdhttp://lambda-the-ultimate.org/node/3560
17:12Chouseryour mathematical function actually needs all the previous values, or just the result of applying itself to all the previous values?
17:12hiredmanAWizzArd: excellent
17:13tomojnow that I think about it a bit more
17:13tomojit either needs all the previous values, or a related calculated value
17:13tomojwhich is not the value that goes in the seq
17:13AWizzArdClojure is even preparing at least to some extent to these vector units
17:14Chouserok, it's pretty common to use recur or iterate and the filter out what you want in a later chain...
17:14Chouserclojure's better at describing this than english
17:14clojurebotclojure is the best way to learn java
17:15tomojI think I have done stuff like that before
17:15tomojjust not lazily
17:15Chouser(map first (reduce (fn [[return-val internal-val]] [compute-return compute-internal]) ...))
17:16Chouseror if you have no input seq, use iterate instead of reduce
17:18tomojChouser: thanks... I think I need sleep
17:18tomojsomething is not clicking
17:20tomojah, found lazy-seq-fibo in programming clojure
17:21Chouserwell, that may be more helpful than this, but since I don't know what you're actually trying to do:
17:21Chouser(take 10 (map first (iterate (fn [[rv iv]] [(- iv 2) (* iv 3)]) [:foo 1])))
17:21Chouser,(take 10 (map first (iterate (fn [[rv iv]] [(- iv 2) (* iv 3)]) [:foo 1])))
17:21clojurebot(:foo -1 1 7 25 79 241 727 2185 6559)
17:21tomojthat actually looks about right
17:22tomojwith appropriate substitutions
17:22tomojthanks
17:24Chouserthough 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:24Chouser,(take 10 (map #(- % 2) (iterate #(* % 3) 1)))
17:24clojurebot(-1 1 7 25 79 241 727 2185 6559 19681)
17:24b4taylorI wish to create a byte[] for java.io.FileInputStream.read(byte[]), is make-array the way to go about doing this?
17:25Chousukeinto-array might be easier
17:25Chousukehmm
17:25Chousukeor not, if you want an empty one :)
17:25b4taylorI need an empty one.
17:25Chousukethen make-array, yeah
17:25b4taylorSo my problem arising when I need to give it the type to create.
17:26Chousukeuse Byte/TYPE
17:26b4taylor(make-array byte 256) gives me a cast exception saying byte is the clojure type.
17:26b4taylorAh ok.
17:26b4taylorSweet.
17:26b4taylorThanks.
17:29b4taylorOh crud, unsigned bytes. Forgot about that :p
18:35andyfingerhutI 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:42Chousukeandyfingerhut: not yet. :P
18:42andyfingerhutok, no big deal.
19:00hiredman~literal [1] problem
19:00clojurebot<reply>People have a problem and think "Hey! I'll use a regular expression!". Now they have two problems....
19:01burkelibbeyHeh, I multiplied two complex numbers with regular expressions once to avoid writing a script in bash >_>
19:02burkelibbeysummary: I agree with clojurebot.
19:05JAS415haha
19:06burkelibbeySo I think this is largely because I have a poor understanding of how namespaces work, but: http://gist.github.com/166172
19:07burkelibbeyI'm trying to write a macro to load application.controllers.X and run the invoke method in it
19:07burkelibbeyIs that a horrible idea, or am I missing something, or...? Help appreciated :P
19:07Chousukeyou're trying to use namespaces as a plugin mechanism?
19:07burkelibbeys/method/function
19:08burkelibbeyI guess, yeah
19:08Chousukeyeah, I think that's not such a good idea :P
19:09burkelibbeyis there a way to automatically load all the sub-namespaces of another namespace, without hard-coding the whole list?
19:09Chousukenot really.
19:10burkelibbeyI guess I'd have to just look through the filesystem
19:10burkelibbeybah
19:10Chousukesubnamespaces are not related to their parent namespaces in any way other than the common part of the path
19:10burkelibbeyok
19:11Chousukeif you need a plugin mechanism, multimethods might be useful
19:12Chousukeeach plugin could just do a defmethod on some common multimethod
19:12burkelibbeyhmm, yeah, there's an idea.
19:12andyfingerhutI love clojurebot's brain. So much more interesting than Eliza.
19:12burkelibbeythanks
19:15duck1123are there any good projects to look at that do a lot with command line params in clojure?
19:16duck1123I had hope with corkscrew, but it does a lot of it in sh, and that's not what I want
19:32andyfingerhutIt's not as featureful as things I've seen in other languages, but have you seen clojure.contrib.command-line/with-command-line?
19:33andyfingerhuti.e. Perl's GetOptions has lots more bells and whistles.
21:19JAS415welp
21:19JAS415eventually i'll know java well enough to use clojure properly :-P
23:34ChouserI knew chunked map would be hard, but I thought doseq might be pretty easy.
23:35Chousernow I'm not so sure.