#clojure logs

2012-04-08

01:00muhooamalloy: has anything come of this yet? https://gist.github.com/1911278 it looks fantastic
01:01amalloydon't ask me, dude
01:01amalloyobserve the "Fork of..." line
01:01muhooah
01:02amalloyit looks a lot like STUN to me, but i'm clearly uneducated in the area
01:02laurusHow do I choose which version of Clojure runs when I run "lein repl" ?
01:04amalloyyou need a project, with a version set in project.clj
01:05autodidaktoamalloy: outside of a project, what does lein repl do?
01:05amalloy*shrug*
01:05laurusamalloy, oh, I see. I am using inferior-lisp mode in Emacs, but I have it set to run "lein repl" as the launch command.
01:05laurusautodidakto, I believe it runs the version of Clojure that Leiningen itself uses.
01:06autodidaktolaurus: any reason why you're not using swank-clojure?
01:06laurusautodidakto, it just seemed more complicated to set up :)
01:06offby1b
01:07autodidaktolaurus: it's super simple and well worth it
01:07laurusautodidakto, ok I will try it sometime soon. I just started learning Clojure for real recently
01:07laurusThanks:)
01:08autodidaktolaurus: you have the clojure-mode package?
01:08clojurebotHuh?
01:08laurusautodidakto, yes thanks :)
01:08autodidaktousing lein1, correct?
01:09laurusautodidakto, I'm not sure
01:09autodidaktothen yes, it's one :)... lein -v will confirm
01:09autodidaktoinstall swank-clojure plugin with "lein plugin install swank-clojure 1.4.2"
01:10autodidaktoand you're done. clojure-mode is the client, swank-clojure the server (if i remember correctly)
01:10autodidaktoM-x and do "clojure-jack-in"
01:10amalloythat's only going to work if he's already in a directory with a project.clj, right?
01:10autodidaktowhile you're in project
01:11laurusautodidakto, thanks!
01:11autodidaktothe buffer has to be in a project, yeah. I think subdirectories work... testing
01:12autodidaktoamalloy: confirmed, you dont have to be in the "root" dir of your project
01:12amalloyright
01:12autodidaktolaurus: np. technomancy did all the work
01:13autodidaktoamalloy: best practices for a loading a.. um... detatched/scratch swank-clojure repl... I'm not sure
01:14amalloyi imagine lein swank followed by M-x slime-connect would still work
01:16autodidaktolaurus: btw, reference for swank-clojure (check out the commands) -> https://github.com/technomancy/swank-clojure
01:16laurusThanks!
01:17autodidaktoamalloy: "Couldn't find project.clj, which is needed for swank"
01:17laurusIs there any reason not to run lein version 2?
01:18autodidaktolaurus, not every plugin has updated to lein2, and as a newbie you dont have much to gain
01:19autodidaktofollowing the Upgrading page, you could download and install it with the name "lein2" and it won't collide with "normal" lein
01:23laurusThanks for the help!
01:40autodidaktoJust realized how to monetize clojure -> Rich Hickey Merchandise. Hammocks, Curly Wigs...
03:19lnostdalhum, why not? "java.lang.IllegalArgumentException: :volatile-mutable or :unsynchronized-mutable not supported for record fields"
03:22amalloybecause record fields are public, and mutable fields are private
03:23lnostdalah, yeah .. but, erm, what if i want some of these fields to be private? .. it implicitly makes "getters" for the fields i guess
03:23lnostdalkey-style ones it seems
03:23amalloythen don't use a record
03:24lnostdalright
03:24lnostdali'll deftype and build things up from there
06:09wmealing_not sure if my last line got through... sorry if it did and you got this already.
06:10wmealing_I'm wanting to build the insides of a let [x y] form the problem is when i attempt to build it, it gets evaluated (i think) what am I doing wrong ? (code provided in a second)
06:10wmealing_http://hastebin.com/nibuxoveli.lisp
06:10AimHereWe got you announcing that you'd provide code
06:10wmealing_yep, and there it is ^
06:11wmealing_i know the code doesn't try to use it there, but the functions i'm trying to use are there.
06:11wmealing_line 38 is what i'm trying to replace.
06:20amalloywmealing_: there is not enough information provided to know what your problem is, let alone fix it. what do you hope will happen, and what happens instead?
06:24progo:)
06:27wmealing_amalloy, yes i guess that really is the problem, the terms are foreign to me and I don't know how to explain the problem correctly.
06:29wmealing_[ *event-plugin-dir* (:event-plugin-dir config#) *action-plugin-dir* (:action-plugin-dir config#) , for each for the directories configured to be in scope for the body (line 40)
06:30mega`Cr8: :D love it
06:30mega`Cr8: you cant stay with vim?
06:34Cr8mega`: I'm trying to get a nice slime-like setup for clojure
06:35Cr8Cr8: I use VimClojure, but it's hard to keep actually working, with nailgun and all
06:35mega`Cr8: slime and emacs is awesome
06:35Cr8also it might be helpful anyway since the only people at work who are super opinionated about how code should be formatted use emacs and put the correct emacs lines at the top of the files that they care about
06:37jszakmeisterCr8: Have you looked at slimv for Vim?
06:37jszakmeisterI'm actually working on getting it setup in my environment right now.
06:37jszakmeisterSean Devlin has a nice video on it: <http://vimeo.com/38372260&gt;
06:38Cr8jszakmeister: would like something that has a slightly tighter integration than slim
06:38Cr8at least as much as vimclojure/nailgun does
06:38Cr8*slimv
06:38Cr8I -like- vimclojure/nailgun, it's just annoying to get it working
06:38jaenIncidentally is there any syntax hilighting thing that does rainbow parens or forms highlighting?
06:38jszakmeisterI *think* so, but I haven't trudged to deeply in it all.
06:39Cr8jaen: vimclojure does =P
06:39jaenWell yes
06:39jaenSohuld have been more specific
06:39jaenI mean on the intarwebs
06:39jaenAny script for that or pastebin service
06:39jaenThat does that?
06:39Cr8ah
06:39jaenOr would one need to write it by hand
06:39wmealing_amalloy, dont worry about it.. its either too hard, or i'm expecting too much too soon.. either way. thanks.
06:44Cr8jszakmeister: ah, hang on, this might be what I need :)
06:45jszakmeisterCr8: great!
06:52RaynesCr8: The Vim stuff is going to get significantly better soon.
06:52RaynesNo more nailgun.
06:52danielwhen you visit https://graph.facebook.com/19292868552 in chrome, it's nicely formatted. When i grab it in clojure and try to put it in a <pre> block, it's badly formatted :(
06:53danielRaynes: oh really?
06:53RaynesYeah. It's going to use nrepl.
06:53danielgreat, how soon?
06:53RaynesWhich lein2 already supports.
06:53jszakmeisterRaynes: for VimClojure?
06:54RaynesI'm not sure. A basic Haskell client already exists in the VimClojure repo. It is working AFAIK, but there aren't any docs yet.
06:54Raynesjszakmeister: Yes.
06:54jszakmeisterNice!
06:55Cr8Raynes: oh good :)
06:56Cr8Raynes: I've been watching kotarak's bitbucket repo waiting for the nrepl stuff to materialize
06:57Cr8but there's no actual vim-side support for any of it in the repo yet
06:57Cr8just some experiments with the haskell helper client
07:04autodidaktoCr8: just spent the last 4 days tweaking my emacs setup (coming from vim)... init.el via vim too :)
07:05autodidaktoCr8: VimClojure/Nailgun works well though. What is it that you're missing?
07:08autodidaktoRaynes: What's with the haskell thing anyway? Brining Vim and Clojure together? That's just weird.
07:09RaynesIt is a client between Vim and Clojure.
07:10autodidaktoRaynes: right right, we talked about it a few days ago. development branch but no info about how to set it up
07:10autodidakto"I need to get vim to connect to an nRepl.. I know, haskell!"
07:10Cr8autodidakto: good way to run it from lein2 =P
07:11autodidaktoCr8: hrm, yeah. that's a pain
07:11autodidaktowill be fixed eventually though
07:11Cr8i -can- do it, it's just really annoying
07:11Cr8i mean
07:12Cr8i've had a working vimclojure/nailgun setup on -windows- before =P
07:13Cr8urgh, and slimv's highlighting sucks =/
07:14autodidaktosorry crash, what i miss?
07:16Raynes<Cr8> urgh, and slimv's highlighting sucks =/
07:18autodidaktough, emacs.app doth crashith
10:39makkalothi, i know when i dosync i have a snapshot of my refs, but how does clojure knows which refs i'm going to use so it takes their snapshots ?
10:41gfredericksmakkalot: maybe it doesn't have to know ahead of time?
10:42makkalotgfredericks, but then i wont have a snapshot of all refs as it is stated in docs
10:43gfredericksI don't know how the stm is implemented, but it seems conceivable to me that it could "snapshot" all of them in some cheap way, and note which ones you deref and use that info when committing
10:43gfredericksmostly I say this because what you're referring to would be an obvious hole in the system otherwise
10:46makkaloti found that it maybe useful http://java.ociweb.com/mark/stm/article.html
10:57mega`makkalot: its like a linked list were things cant get gc before transactions do
10:57mega`makkalot: that's my understanding
10:59makkalotmega`, you mean tsm has linked list of versions of refs, and just gives back an point in that linked list, that would make sense ...
11:01mega`makkalot: like a reversed stack everytime a transaction commits it adds a stack window but only older living transaction has a view of the older windows of the stacks
11:04makkalotmega`, nice explanation
11:43kahlinhmm, help? =) I'm loading a .clj file with load-file. the .clj contains one deftype statement and returns the class that is implemented. How do I use that class from the code that calls load-file? (i.e. how do I create a new instance of the type in the .clj??)
11:50masondesumorning everyone
12:00kurtharrigerkahlin: java classes need to be imported still even if they were created with defrecord or deftype.... an easier way to go about it is to define a factory function in the clj file and use that to create a new instance
12:01kahlinkurtharriger: hmm, ok, so the clj would return the factory function and then i use apply to call it?
12:02jtoyi want to calculate a value, then set it in redis, then return that value, would I wrap that in a doall or something else?
12:03jtoyit seems like do could be fine
12:05kahlinkurtharriger: yeah, that works. thanks!
12:05kurtharrigerkahlin: cool
12:08beffbernardI'm trying to bind a thread-local var representing a connection but I'm getting a var$unbound.. I'm probably just doing something dumb..
12:08beffbernardhttps://refheap.com/paste/1927
12:10kurtharrigerjtoy: do would work and is also implicit in many contexts such as when or an fn: (defn set-and-return [db table v] (redis/set db table v) v)
12:11jtoykurtharriger: i ended up implemented as so : (let [computed (….)] (do (redis/set db table v) v) , it seems to work, thx!
12:12kurtharrigerbeffbernard: (ls "/") is evaluated before with-connection* is called and its result is passed as the second parameter.. thus when ls is called *zk* is not bound
12:14beffbernardkurtharriger: I figured as much… any obvious way to defer the initialization of ls?
12:15jtoycan I set a value in an if statement and if a value is returned use it for the if result? like (if (value = get_value) value (compute_value ) ) ?
12:15kurtharrigeryour intent seemed to be to pass a function to with-connection* not the result.. you can do this a couple different ways: (with-connection* zk-spec #(ls "/") (with-connection* zk-spec (partial ls "/"))
12:15kurtharrigeranother option is to make with-connection* a macro instead of a function
12:17kurtharrigerI think it would look like this: (defmacro with-connection* [zk-spec & body] `(binding [~*zk* (connect ~zk-spec)] ~@body))
12:20kurtharrigerbeffbernard: actually think its just ~*zk* not ~*zk* here, but something like that anyway
12:20beffbernardkurtharriger: Passing #(ls "/") worked like I had originally wanted
12:20beffbernardHowever the var is still unbound with the macro
12:21beffbernardbut I can debug that later
12:21kurtharrigercool
12:34hcumberdaleHi! ;)
12:34mega`Hello
12:35hcumberdaleHow to implement http://codex.wordpress.org/Function_Reference/wpautop in clojure?
12:35hcumberdaleDetects double line breaks an replaces them with <p></p> around the paragraph
12:36mega`you need it?
12:37hcumberdaleyeah mega`
12:37hcumberdaleI migrate from my wordpress blog to a clojure blog system
12:38hcumberdaleand I want to copy the data 1:1
12:38hcumberdalewordpress has this ugly feature autoenabled
12:38hcumberdaleSo I need to emulate it to get my content fixed
12:39hcumberdalehttp://core.trac.wordpress.org/browser/tags/3.3.1/wp-includes/formatting.php << wpautop is ugly!
12:39antares_hcumberdale: if all you need is to split content into paragraphs, chances are, a regular expression may be sufficient
12:39kurtharriger(defn wpautop [text] (str "<p>" (string/replace text #"\n\n" "</p><p>" ) "</p>"))
12:39antares_ah, so the source is available
12:39antares_what's the problem then
12:40hcumberdaleantares_: the source is ugly, no functional style and full of regular expressions
12:41hcumberdaleThere must be an easy way to do this in clojure without ~loc
12:41hcumberdale~30loc
12:41clojurebotTitim gan éirí ort.
12:41krunaldohcumberdale: dunno, seems to be quite a lot of special cases handled in the code
12:42krunaldohcumberdale: unless you implement a parser for the wordpress formating language regex is the easiest way to go
12:42hcumberdaleyeah damn! I've seen it
12:43hhutchI'm stumped with this java interop issue, can anybody point at what I'm doing wrong? https://gist.github.com/2338359
12:43hcumberdaleSeems the function caused trouble,...
12:43hcumberdaletry (do (.setDefaultFlowStyle DumperOptions.FlowStyle.BLOCK))
12:45hhutchhcumberdale: same issue, ClassNotFoundException DumperOptions.FlowStyle.BLOCK java.net.URLClassLoader$1.run (URLClassLoader.java:202)
12:46hcumberdalehhutch: do you use leiningen? jsrc path set? reference.class available at classpath?
12:46hhutchi use leiningen yes...
12:47hcumberdalewhy do you create the object in java? It is also easy to do this in clojure!
12:47beffbernardhcumberdale: nested classes are accessed with $
12:48kurtharrigerhcumberdale: there is probably a java library somewhere that implements markdown to html conversion you could use from clojure
12:48hcumberdaleAhh, I understand you want the java code like the clojure code
12:48hhutchhcumberdale: yes
12:48hcumberdalekurtharriger: yes, but this is not a markdown issue!
12:49hcumberdaleWordpress does a special format thing,...
12:49hcumberdale(defn wpautop [text] (str "<p>" (string/replace text #"\n\n" "</p><p>" ) "</p>")) is fine, but does not handle special cases
12:50mega`it missed if its crap betwen the \n\n
12:50kurtharrigerhhutch: I'm guessing that FlowStyle is an inner class so you need to (import 'org.yaml.snakeyaml.DumperOptions$FlowStyle) then use FlowStyle/BLOCK
12:50mega`but you can use regex for that
12:51kurtharrigerhhutch: sorry I think that should be (import '[org.yaml.snakeyaml DumperOptions$FlowStyle]) then use DumperOptions$FlowStyle/BLOCK
12:52hhutchhahha, i just figured that out on my, thank kurtharriger
12:52hhutch:)
13:10hcumberdaleIs there a better way to write this?: (map (fn [x] (update-in x [:content] #(wpautop %))) (posts-by-category "Welcome"))
13:11mega`hcmuberdale: theres a for macro
13:12mega`&(doc for)
13:12lazybot⇒ "Macro ([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost ... https://refheap.com/paste/1930
13:13konris there a (for) with indexing? I'd like to iterate over a seq but keep track of my position
13:13mega`(for [x (posts-by-category "Welcome")]
13:13mega` (update-in x [:content] wpautop))
13:14mega`konr: theres a map-indexed
13:17Raynes&(for [[i x] (map vector (range) [1 2 3])] [i x])
13:17lazybot⇒ ([0 1] [1 2] [2 3])
13:17konrnow that's neat!
13:17mega`&(map-indexed vector (range 10))
13:17lazybot⇒ ([0 0] [1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9])
13:17RaynesPoor mans indexing. ;)
13:18RaynesBut I'd use map-indexed unless you have a real reason for using for.
13:18RaynesJust because it is designed for what I did above.
13:22hcumberdalethx mega`
13:22hcumberdaleis there an adavantage of "for" oder the map,... solution?
13:23Chousukemap-indexed is faster I think
13:23Iceland_jackmap and for do different things
13:23Iceland_jacksometimes for is clearer, sometimes it's not
13:24ibdknoxfor is almost always clearer if you're not using a named function
13:24Iceland_jackNot quite sure I agree
13:24ibdknoxcounter example?
13:25Iceland_jackwhy?
13:25clojurebotwhy is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone
13:25ibdknoxhaha
13:25Iceland_jackbut then again non-map comprehensions confuse me
13:26ibdknox(map (fn [[x y]] (+ x y)) some-seq)
13:26ibdknoxvs
13:26ibdknox(for [[x y] some-seq] (+ x y))
13:26Iceland_jackYou're very eager to show this
13:27ibdknoxnot really, I was more curious to hear the counter :)
13:27Iceland_jackwell I just said I wasn't sure whether I agree
13:27ibdknoxmy experience has generally shown that to be true, but there are lots of things I've not done
13:28Iceland_jackpossibly compound functions, I also dislike for since it isn't immediately obvious what you're attempting to do
13:28Iceland_jackbecause of its versitility
13:28Iceland_jack*sa
13:30beffbernardibdknox: what anonymous functions? (map #(+ %1 %2) some-seq) is pretty readable to me
13:30ibdknoxthat's not equivalent to what I wrote :)
13:31ibdknoxthe example you gave would actually be done just as (map + seq1 seq2)
13:31beffbernardhaha ok, my bad but my question still stands ;)
13:31ibdknoxI think most of the time you end up doing that, it's really just a named function in disguise
13:32ibdknoxbut yeah, if you don't need destructuring or any of that, absolutely
13:32ibdknoxI think that's plenty clear
13:32Iceland_jackhm
13:32ibdknoxmany #()'s used in maps are just comps or juxts waiting to happen
13:32Iceland_jackheh
13:32ibdknoxfilter is a different story though
13:32ibdknoxunfortunately
13:35Iceland_jackI prefer to see what's going on early in each expression
13:35Iceland_jackbut for has its moments
13:36ibdknoxI totally agree map with a named function is the clearest solution
13:36ibdknox(map inc some-seq) is immediately obvious
13:36ibdknoxmuch more so than the for would ever be
13:36Iceland_jackYes, I think so.
13:37ibdknoxassuming well-named functions of course ;)
13:37ibdknox(map do-shit some-seq) isn't very helpful :D
13:38Iceland_jackI favour filter and map, possibly more than I should.
13:38AimHereHmm, if I've defined a type as in (deftype Foo [bar baz wibble]), is there a way from outside the type that I can access the field 'wibble', say?
13:38Iceland_jackBut I fear it may be an old habit
13:38AimHereIt's easy if it's a record
13:40pipelineso i have an emacs virgin at hand
13:40pipelinedoes anyone have a tutorial they prefer to the one built-in to emacs
13:40Iceland_jackDoes anyone like the built-in one?
13:42pipelinei found it to be tolerable
13:42Iceland_jackWell I assume today's kids aren't impressed by navigation commands
13:54hcumberdaledamn!! wpautop
13:54hcumberdalethe existing code looks like perl. Write only.
13:58mega`hcumberdale: if you whant to write it in a simular stile you can use print and redirect the output
13:58hcumberdalemega`: I think about how to handle this issue
13:59hcumberdalemaking an wordpress compability switch to turn it on or off and save the information with the post?
14:00mega`sorry i dont get what you mean
14:08hcumberdaleDoes anyone know if there is a clojure lib to generate a tagcloud?
14:18devnjersey-clj -- heh
14:19TimMcamalloy discovered this weirdness with booleans, and I've played around with it some more -- any ideas? https://gist.github.com/2338038
14:20TimMcThis is in response to that thread on the ML about (Boolean. false), but it's more than that.
14:20devnhow do i get lein2?
14:20devncolor me confused.
14:21TimMcAlso, amalloy is a lazy bum who has probably stuffed himself with Easter candy to the point of coma. That's the only possible explanation for why he's not in #clojure on a Sunday afternoon.
14:21llasramTimMc: Whoa. How. What.
14:21llasramOhhhhh, macro-expansion!
14:22TimMchmm
14:22devnso...seriously...what is the proper way to upgrade from lein 1
14:22devnblow away ~/.lein, ~/.m2?
14:22TimMcllasram: Ah, that certainly clears up part of the mystery.
14:23devndo i want to get this: https://raw.github.com/technomancy/leiningen/preview/bin/lein
14:23TimMcdevn: I think you want to download that as lein2.
14:23hcumberdaledevn: good question, likely the same that I want to ask
14:23devnheh
14:24llasramdevn: I didn't need to blow anything away. I just grabbed the preview/bin/lein script and stashed in it in ~/bin as lein2 +x
14:24devnim just replacing my lein1 -- might as well go all the way
14:24devnmy version is now 2, but no plugins are showing up
14:25devnduh: https://github.com/technomancy/leiningen/wiki/Upgrading
14:30TimMcllasram: Updated the gist to ne simpler, but I'm still having trouble understanding why f* is behaving the way it is.
14:36llasramI think it's because the different clojure.lang.Compiler expression types are not entirely consistent in their treatment of Boolean objects
14:36llasram&(identical? false (eval (Boolean. false)))
14:36lazybotjava.lang.SecurityException: You tripped the alarm! eval is bad!
14:36llasramHaha, of course
14:37llasramTimMc: But try it out at home to see what I mean
14:40llasramOr better: https://gist.github.com/2339031
14:41llasramI think the cases I've add to the bottom really boil it down
14:56devnis there any way to suppress warnings for plugins being loaded in leiningen?
15:06RaynesDon't use plugins that produce warnings.
15:07devn:\ kibit
15:30devnibdknox: cljs-template is awesome.
15:32jtoywhat way would you guys recommend to get a new list of n, n+1 from a list of [1 2 3 4], so[ [1 2] [ 2 3] [ 3 4]] ?
15:32devn,(partition 2 1 [1 2 3 4])
15:32clojurebot((1 2) (2 3) (3 4))
15:32sjljtoy: that looks like (partition 2 1)
15:33devnjtoy: more generally, it sounds like what you're describing might be:
15:33devn,(partition 2 1 (range 0 10))
15:33clojurebot((0 1) (1 2) (2 3) (3 4) (4 5) ...)
15:36jtoycool, i never had to use that
15:36jtoyhow could partition be useful in general? (besides the case I just used it for ?)
15:36sjl,(into {} (partition 2 [:key1 1 :key2 2])
15:36clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
15:37sjl,(into {} (partition 2 [:key1 1 :key2 2]))
15:37clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry>
15:37sjlhrm
15:42FullmoonLet's say I have a sequence of results from a java library, and i want to call call a method on all of them
15:43FullmoonCurrently, I use something like (map (fn [rec] (.toString [rec]) records)
15:43FullmoonHow can I get a reference to the '.' function, curried with the value toString?
15:44sjl,(map (memfn toLowerCase) ["FOO" "BAR"])
15:44clojurebot("foo" "bar")
15:44sjlFullmoon: ^^
15:45llasramMy understanding is that memfn is deprecated. Idiomatic usage seems to be to just use #()
15:46llasramOf course in the .toString case, you can just use str :-)
15:47bbloomback in ruby-land, i used to use ActiveSupport's Array.wrap pretty frequently for writing functions that conveniently handle a single or collection for a particular argument — in clj function would look like: (fn [x] (if (sequential? x) x [x]))
15:47bbloombut i wonder 1) is something like this already in core? (i spent some time exploring the code, didn't see it) and 2) if it isn't there, why not? is it a bad idea for some reason?
15:48FullmoonAh, nice, thanks.
15:48Fullmoon,(macroexpand (.toString))
15:48clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Malformed member expression, expecting (.member target ...)>
15:48Fullmoon,(macroexpand '(.toString java-object))
15:48clojurebot(. java-object toString)
15:50llasrambbloom: AFAIK, there isn't something like that in core. And probably just because clojure.core can't have every possible useful little function in it :-)
15:51bbloomllasram: of course :-) it just seemed like core has sooo many useful little functions for sequences, that i felt like i might have been missing something obvious
15:51llasram bbloom: Here's the basic Clojure form of it which seems to be fairly common: https://github.com/sritchie/jackknife/blob/master/src/jackknife/seq.clj#L65
15:51bbloomlike "oh, that's just the degenerate case of FOO" where Foo is some common function i use every day and don't think about
15:52bbloomah, didn't consider List
15:52bbloomthanks :-)
15:52llasramnp
16:00FullmoonI think I miss something obvious, but how can I get a random element from a set?
16:03sjl,(rand-nth (seq #{:a :b}))
16:03clojurebot:b
16:05jtoyhow do I convert lists into tuples?
16:06bbloomzipping them?
16:06progowhat kind of tuples?
16:06jtoyvector
16:06llasramFullmoon, sjl: NB that that will O(n). If you have a large set and/or you'll be pulling many random values from it, you'll probably want to turn it into a vector first and use rand-nth on the vector
16:06Iceland_jackjtoy: (map vector ...)?
16:07Iceland_jackcheck out Wikipedia's page on convolution
16:07progojtoy, yeah but you can make tuples out of lists in many ways :)
16:11jtoyhmm, how would you guys turn this into bigrams? (map str (partition 2 1 (.split "make this into bigrams" "\\s+")))
16:13llasram&(->> "make this into bigrams" (#(.split %1 "\\s+")) (partition 2 1) (map vec))
16:13lazybot⇒ (["make" "this"] ["this" "into"] ["into" "bigrams"])
16:13llasramjtoy: Like that?
16:14jtoy["make this" "this into "into bigrams"]
16:16llasramOh, clojure.string/join then?
16:16llasram&(->> "make this into bigrams" (#(.split %1 "\\s+")) (partition 2 1) (map #(clojure.string/join " " %1)))
16:16lazybot⇒ ("make this" "this into" "into bigrams")
16:16jtoyoh, oops
16:16konrdoes anybody know how to display an image on compojure, either from a path or an object?
16:19jtoywhy does this destroy my strings:
16:19jtoy&(map vec (map #(clojure.string/join " " %) (partition 2 1 (.split "make this into bigrams" "\\s+"))))
16:19lazybot⇒ ([\m \a \k \e \space \t \h \i \s] [\t \h \i \s \space \i \n \t \o] [\i \n \t \o \space \b \i \g \r \a \m \s])
16:20llasramjtoy: You're mapping `vec` over each string, treating each string as a sequence of characters and turning that into a vector of characters.
16:20llasramI think you want just (vec ...), not (map vec ...) ?
16:21jtoyah yes
16:26danielGreetings People of Clojure. I have a few questions for you guys if you're willing to help out a lisp newbie
16:26danielI'm coming from Haskell so I'm familiar with fp
16:27llasramdaniel: Welcome to #clojure! Plenty of helpful people are around :-)
16:27danielFirst of all, how does one implement a stack-based problem in clojure? Should I use the Java library's stack, or is there a roll-your-own technique using sequences in clojure?
16:30danielIf I were to use the Java stack, I think I'd have to write something in a non-functional style ("while not empty pop then do something"). How do I do this in a more idiomatic way?
16:31jtoyhow would I make it into this form? ["make this"] ["this into"] ["into bigrams"] ?
16:31llasramdaniel: Probably easiest to use Clojure datastructures. Using vectors, you can use `conj` to add something to the end, `peek` to get the last item, and `pop` to get a copy of the vector sans the last time
16:31llasrams,time,item,
16:33jtoythis doesn't work:
16:33jtoy&(map [#(clojure.string/join " " %)] (partition 2 1 (.split "make this into bigrams" "\\s+")))
16:33lazybotjava.lang.IllegalArgumentException: Key must be integer
16:34jtoyor this:
16:34jtoy%(map #([%]) (map #(clojure.string/join " " %) (partition 2 1 (.split "make this into bigrams" "\\s+"))))
16:34llasramjtoy: Yeah, one of the things you just have to learn: while `vec` creates a vector with the same items as the collection provided as an argument, the `vector` function creates a vector containing the values provided as arguments themselves
16:34danielllasram: Thanks - I found this http://nakkaya.com/2010/12/02/a-simple-forth-interpreter-in-clojure/
16:34llasram&((juxt vec vector) "example")
16:34lazybot⇒ [[\e \x \a \m \p \l \e] ["example"]]
16:34danielllasram: which is pretty much exactly what you suggested :)
16:36llasramdaniel: Cool beans. Do note that the semantics for vectors vs seqs and lists is slightly different. `conj` adds items to the end of the former, but the beginning of latter. It's useful, but potentially confusing at first
16:37mpenetdaniel: this table can be helpful http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html
16:40danielAnother question: Does a '!' at the end of a function name mean that the function mutates global state? Is this rule or convention?
16:40mpenetdaniel: convention
16:40mega`daniel: it can mutate it's arguments to
16:41danielmega`: Analogous to passing by reference in C/C++?
16:41mega`daniel: or just a object like a file a http conection or something
16:46jtoyllasram: i don't know what that means yet, but will keep testing, thx
16:48llasramjtoy: Oh, didn't mean to be obtuse: ##[(vec "example") (vector "example")]
16:48lazybot⇒ [[\e \x \a \m \p \l \e] ["example"]]
16:49jtoyyeah, I'll just memorize for now, but I mean I don't understand the why difference of dec vs vector
17:29emezeskeAny midje experts in here? I can't seem to figure out how to mock a function to say that it should throw an exception.
17:29emezeskeI tried (provided (whatever) => (throws Exception)), but that doesn't seem to work.
17:33mega`https://github.com/marick/Midje/blob/master/examples/adder-webapp/test/adder/core_test.clj
17:33mega`emezeske: it uses the throws syntax
17:34mega`emezeske: anny diference from yours?
17:34emezeskemega`: Yeah, I can get the throws thing to check that a function-in-test does throw
17:34emezeskemega`: But I can't get it to say "this mocked-out function should throw an exception"
17:35senthili'm having trouble understanding how nailgun can help dev. process (i get the repl inside vim part)
17:39emezeskesenthil: I think the simplest advantage is that you can send forms to the REPL with hotkeys (e.g. \et \ef etc)
17:39emezeskesenthil: So you don't have to copy+paste things into it to see what happens
17:42senthilemezeske: is it similar to "lein repl", but faster boot up?
17:42mega`emezske: http://clojuredocs.org/midje/midje.semi-sweet/only-mocked they will trow if you use them :p not so nice maybe
17:43emezeskemega`: Hey, that might do the trick! Ugly, but practical :)
17:43emezeskemega`: Thanks a bunch
17:44emezeskesenthil: It is similar to lein repl. I don't think the boot time is any different, but you just leave the nailgun server running all the time so you never really pay attention to boot time anyway
17:45senthilemezeske: is there a debug option in this?
17:45clojurebotExcuse me?
17:47andyfingerhutIRC question, probably specific to the IRC client one uses. I know I can do "/whois <name>" to see, among other things, how long a person has been on and how long idle. Is there any way to get a big table of that info for everyone in the room, and sort it by idle time?
17:47emezeskesenthil: You mean like a stepping debugger as part of vimclojure? No, I don't think so. For that I *think* you want "slimv"
17:48senthilemezeske: yea i tried it earlier, but couldn't get it to work
17:48mega`andyfingerhut: what is you are doing lol :D
17:49andyfingerhutmega`: nothing nefarious, I think :-) Just seems like something someone else might have already implemented.
17:50senthilwhat's the difference between vimclojure and slimv? (aside from former not having a debugger)
17:51emezeskesenthil: googling "vimclojure vs slimv" returns: http://www.deepbluelambda.org/programming/clojure/programming-clojure-with-vim
17:53hobbyistin REPL, is there a way to place the caret at the beginning of line, word and en of line?
17:54amalloyhobbyist: the readline keyboard shortcuts work in most environments
17:54senthilemezeske: i guess i might've to bit the bullet and learn emacs
17:55amalloyeg, addressing your specific questions, C-a, M-b, and C-e
17:56emezeskesenthil: Seems like just getting slimv to work would be easier than switching your editor, but YMMV I guess. Obviously a lot of people like emacs.
17:56mega`emacs is a dream :D
17:57emezeskemega`: ^_^
17:57hobbyistamalloy: IDEA does not seem to
17:58amalloywell you said "repl" - god only knows what IDEA's particular GUI does
18:01hobbyisttrue: I was hoping, should repl have one, IDEA would pick it up
18:05amalloyi'm sure IDEA rolls its own from the ground up and just communicates line-at-a-time with the lein repl
18:05amalloyor perhaps even just with the clojure repl
18:08dnolenok monster CLJS patch including all optimizations - https://github.com/clojure/clojurescript/compare/all-optimizations
18:08dnolenbasic operations are nearly 2X faster, with some operation >5X faster
18:08dnolenwould love it if somebody would build the ClojureScript jar from this branch and try it out to make sure everything works ok for them.
18:09mega`dnolen: brb
18:10andyfingerhutdnolen: I've not used ClojureScript for anything yet. Are there any kind of built-in tests that can be invoked from the CLI that would be useful to run on multiple OS/JavaScript combinations for testing purposes? I might be able to do that while creating something similar for the Clojure/JVM prescreening stuff.
18:10emezeskeIf anyone's using lein-cljsbuild, see this command for how you can test HEAD without building a JAR: https://github.com/emezeske/lein-cljsbuild/issues/58#issuecomment-5013471
18:10emezeskeOr, instead of HEAD you could always checkout dnolen's branch
18:10dnolenemezeske: thx
18:11dnolenandyfingerhut: there is not, tho I test all my changes against V8, SpiderMonkey, and JavaScriptCore
18:11andyfingerhutWhat steps do you go through to test your changes? Do you do it in a browser, or CLI?
18:12dnolenandyfingerhut: CLI
18:12amalloyandyfingerhut: there is ./script/test, which runs some tests
18:12amalloyit's not nearly as thorough as jvm-clojure's tests, but it's a little safety net
18:14andyfingerhutjvm-clojure's tests may be thorough compared to ClojureScript's, but they seem like they could use some beefing up.
18:15mega`dnolen: my project seems to work :P
18:15dnolenmega`: EXCELLENT!
18:15amalloyandyfingerhut: really? i mean, of course when i submit a patch i add a test, but the impression i get is that they're testing most of clojure's interesting features
18:16andyfingerhutamalloy: I'm not saying there is nothing there, but some of those test files for Clojure/JVM have no tests in them at all.
18:19andyfingerhute.g. test/clojure/test_clojure/atoms.clj is a placeholder with a couple of comments on what someone thought might be tested there some day
18:19emezeskednolen: I'm pretty sure all-optimizations works for my project
18:19dnolenemezeske: great!
18:20emezeskednolen: Is there anything obvious I could look for in the output javascript to make sure that the all-optimizations branch was really used?
18:20emezeskednolen: actually, nevermind, I can just do a diff with the output from before
18:22emezeskednolen: Yeah, it's definitely using the all-optimizations branch, and it works just fine
18:23dnolenemezeske: that's great to hear.
18:23emezeskeOh, nice, if(cljs.core.truth_(q >= 0)) is now just (q >= 0). That's an epic win.
18:25dnolenemezeske: also multi-arity fns that are not used higher don't cost any more than regular fns.
18:25amalloydnolen: "higher order", right?
18:25dnolenemezeske: this means almost 1.5-2X boost for even simple things like reduce.
18:25emezeskeWow, nice!
18:25dnolenamalloy: yes
18:26emezeskeHmm, unexpected: the file size of my minified source grew by ~40%
18:27emezeskeBy minified I mean :advanced optimizations
18:27dnolenemezeske: what about after gzipping? how does the size fare? I should definitely look into that.
18:27emezeskednolen: Lemme see
18:28dnolenemezeske: I'll check here too.
18:28oakwisednolen: works for my project
18:28dnolenoakwise: can you let me know about file size comparisons?
18:29emezeskednolen: Gzipped, the old :advanced js is ~20% smaller than the new :advanced js
18:30groovemonkeyquestion: How can I change/add something inside of a nested map? I've tried (assoc-in map-to-modify [location-to-modify-in-map] modification) but the <modification> just gets added to the first level of the map.
18:30emezeskednolen: Interestingly, :whitespace optimized, the old and new are very very close in size
18:30andyfingerhutgroovemonkey: See if update-in does what you wish
18:30dnolenemezeske: k thx, looking into it here.
18:31groovemonkeyandyfingerhut: thank you! I've been trying assoc-in mixed with get-in, etc.
18:34dnolenmega`: if you could report files size differences between the two branches that would helpful - thx
18:35oakwisednolen: :whitespace = basically same size, :advanced = 248k up from 183k, :advanced+gzip = 50k up from 41k
18:36dnolenhmm, k I haven't noticed this since I was just using CLJS tests. They're not affected because of course they use large chunks of the API anyway.
18:42dnolenemezeske: is lein-cljsbuild 0.1.7 out?
18:42groovemonkeypardon my noobness, but I"m still having a problem creating a new version of a map:
18:43groovemonkeyuser=> (def mainmap {:one {:eins "un"} :two {:zwei "deux"}})
18:43groovemonkey#'user/mainmap
18:43groovemonkeyuser=> (update-in mainmap [:three] "trois")
18:43groovemonkeyClassCastException java.lang.String cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:602)
18:43groovemonkey
18:44andyfingerhutgroovemonkey: last arg to update-in is a function that takes the old value and returns a new one. You could try (update-in mainmap [:three] (fn [x] "trois"))
18:45groovemonkeyandyfingerhut: ahhh, just ignoring the input arg and returning what I want to return? Thank you! I'll try that right away.
18:45amalloythat's just assoc-in
18:48mega`dnolen: it removes one line
18:48dnolenmega`: heh
18:51groovemonkeyamalley and andyfingerhut: thanks, I think assoc-in solved it.
18:51groovemonkeyamalloy*: thanks
18:55mega`dnolen: the size seem to be the same
18:59amalloygroovemonkey: your IRC client will probably tab-complete usernames
19:03ScorchinWhat's the preferred way to wrap ENUMS? I'd prefer to pass around functions/maps instead of Java Enums. Is there a simple way to convert a string into the equivalent Enum?
19:04oskarthTrying to do (map link-fn coll) where link is a defpartial macro (webnoir). How do I either a) pass arguments to the resulting link-fn b) conditionally change which link-fn I map coll with?
19:05oskarthfeels like a silly question but can't get my head around how to do deal with the defpartial macro
19:07offby1It seems that clojure dynamic variables are roughly equivalent to Racket's "parameters". Anyone here know enough Racket to tell me if I'm understanding that right?
19:08dnolenoffby1: they are similar I think. sometimes referred to fluid vars as well.
19:10offby1And I'm guessing there was a time when any top-level variable whose name *began-and-ended-with-astersisks* was automatically made dynamic, but that's no longer the case
19:10offby1"earmuffs"
19:10amalloythat was never actually the case
19:10dnolenemezeske: hmm seems like the size issue boils down 1 line ...
19:10dnolendown to
19:11amalloyrather, every var was dynamic
19:11offby1ah
19:11offby1but with 1.3 that's different, right?
19:12offby1You gotta explicitly ask for dynamic-ness
19:12offby1dynamism
19:13dnolenoffby1: yes
19:18offby1*nod
19:24sritchietechnomancy, is there a way to get dev dependencies into leiningen 2's generated pom?
19:24sritchietechnomancy: trying to get interop w/ intellij working
19:41amalloysritchie: i think lein2 uses depot to generate POM, which is at https://github.com/flatland/depot/blob/develop/src/depot/pom.clj
19:42amalloyit would probably be pretty easy to add a handler for dev-dependencies
19:42sritchieamalloy: great, thanks
19:42sritchieI'll take a look this evening
19:50dnolenhmm I wonder if the all-optimizations branch isn't a classic size vs. speed tradeoff.
20:11amalloydnolen: i imagine the truthiness-optimizations are strictly a win, but adding another "version" of multi-arity functions should be a space/speed tradeoff, right?
20:18gfredericksdoes cljs varargs use js varargs?
20:21dnolenamalloy: yes the size problem is coming from the multi-arity stuff - looking into a solution right now.
20:22llasramsritchie: A bit late, but normal :dependencies in the :dev profile get added to the POM dependencies, just like lein1 :dev-dependencies did
20:24ibdknoxI would rather have size for speed in this case
20:28dnolenibdknox: yes, I think it's non-starter if average code grows by >20%
20:29dnolenibdknox: I think I may have a solution tho, I think my particular approach was frustrating advanced compilation.
20:30andyfingerhutCan I put in a plug for larger code size? More data traffic for companies like Cisco to sell more equipment :)
20:33Cyrikis there some way to do a post-order tree traversel with a zipper?
20:35mdeboardCyrik: Isn't that one of the built-ins
20:35mdeboardI mean, in the zip module
20:36mdeboardCyrik: Oh, sorry, you actually use clojure.walk/postwalk
20:38Cyrikwell the problem withh postwalk is that its not tail-recursive, so it builds up the stack
20:38Cyrikzippers dont do that but the built in next does a pre-order traversel:(
20:44AWizzArdThere is also prewalk
20:44AWizzArdAnd walk
20:55dnolenHUZZAH!
20:55dnolenemezeske: ibdknox: oakwise: and whoever else please try all-optimizations branch now if you can - no more size explosion
21:00laurusIs there some kind of way to interact with the program Cytoscape through a Clojure REPL?
21:02oakwisednolen: solid! It's down to almost exactly where the master version is now
21:03dnolenoakwise: SWEET
21:04dnolenoakwise: yes it should only be slightly larger - waaay faster :)
21:04oakwiseawesome. free speed!
21:05oakwiseup next: unreal engine software renderer in cljs?
21:10gfredericks,(-> nil false? false?)
21:10clojurebottrue
21:32lynaghkWould it be possible for me to redefine clojure.lang.Ratio#toString?
21:33lynaghkI can use defmethod with print-method to get it to print out as a float, but as far as I can tell I can't have (str (/ 1 2)) ;;=> "0.5"
21:34dnolenlynaghk: I don't think that's possible.
21:34lynaghkdnolen: nooooooooooooooo
21:34llasramMaybe using something like HotSwap?
21:34gfrederickslynaghk: why are you using ratios if you don't like them?
21:34llasramYeah, what is it you're ultimately trying to do?
21:34lynaghkgfredericks: I'm dividing.
21:35sritchielynaghk: but why use ratios?
21:36sritchie(defn div [& xs] (float (apply / xs)))
21:36lynaghksritchie: it's library code that's doing the division.
21:37sritchiehow about (def num-str (comp str float))
21:37lynaghkllasram: I'm printing out to HTML. I've already patched hiccup so that ratios are printed as floats, but I have some other bits of code that is building up strings
21:37sritchieor (def num-str (comp str (fn [x] (if (ratio? x) (float x) x)))
21:38lynaghksritchie: I'm using clojure.string/join. But, yeah, I might give that approach a go and exclude clojure.core/str and define my own replacement
21:38lynaghkI haven't done a ton of namespace/var gymnastics before though
21:38sritchielynaghk: you could alter-var-root and replace the normal str with that one I defined
21:40llasramlynaghk: I have a hard time seeing this turning out well :-) Even if you had floats everywhere, wouldn't you want to control e.g. how many digits ended up in your string representation? Having arbitrarily many digits I can't imagine giving good results
21:40sritchie,(binding [str (comp str (fn [x] (if (ratio? x) (float x) x)))] (str (/ 1 2)))
21:40clojurebot#<IllegalStateException java.lang.IllegalStateException: Can't dynamically bind non-dynamic var: clojure.core/str>
21:40lynaghksritchie: that sounds great, I'll give that a shot. I didn't know about alter-var-root, thanks.
21:55lynaghksritchie: yep, that worked great, thanks.
21:56lynaghkllasram: yeah, it's a gross hack. I'm definitely open to suggestions.
22:05technomancysritchie: I think in preview3 dependencies from :dev are going to end up in the pom as test-scoped
22:05xeqithey do
22:05technomancycool
22:05xeqi*will
23:03emezeskednolen: No, lein-cljsbuild 0.1.7 is not out yet
23:03emezeskednolen: Checking the file size now!
23:03emezeskednolen: Nice, the file size is totally normal with the latest all-optimizations
23:04dnolenemezeske: great!
23:19autodidaktoif you haven't check out minnow yet, you should. Successor to clooj. Our all-in-one newbie's DrRacket ide. Early alpha, needs support. Will help clojure adoption methinks
23:19autodidaktohttps://github.com/stephenalindsay/minnow
23:20wkelly3
23:30emezeskeI kind of have started to feel like there's no good reason to declare things as namespace private (e.g. defn- etc).
23:30emezeskeDoes anyone else feel the same way? Or can anyone convince me that I'm crazy?
23:31autodidaktoi'm not sure if it's the same thing, but i've heard debate over the utility of declaring things private (in my ruby experience anyway)
23:31emezeskeHmm, maybe it's good for APIs to document which things are just helper functions
23:31autodidaktodocumentation vs code -declarations... yeah
23:32amalloyemezeske: i'm against defn- in general, but i do it sometimes
23:32emezeskeamalloy: So, like, by default you don't defn-? When do you special-case it?
23:32autodidaktobut defn- is a bit like code-documenting itself... do you find times in which you want to use a private function and regret making it -?
23:32amalloylike, i prefer to declare my helper functions with letfn: (letfn [(helper [x] ...)] (defn public [x] ...))
23:33emezeskeautodidakto: Yeah, self-documentation is good
23:33amalloybut not every context supports closures, like the body of a defrecord/deftype can't be a closure
23:33emezeskeamalloy: I had never thought to wrap my defns that way, interesting...
23:34amalloyautodidakto: more often, someone else defines a function as private/helper for their library, but it turns out to be a generally-useful function that others would rather use
23:35autodidaktoamalloy: letfn is like defining (anonymous) functions inside of a function (like in scheme) ?
23:35autodidakto,(doc letfn)
23:35clojurebot"([fnspecs & body]); fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+) Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body."
23:36autodidaktoi guess i shouldnt say (anonymous)
23:36emezeskeamalloy: That's been my experience, I just get irritated because I have to jump through hoops to call such a function
23:36amalloyor sometimes i do defn- when letfn would work. the two reasons so far have been (a) functions f and g need the same helper, but they have to be far away from each other in the source, or (b) the letfn itself is large
23:37autodidaktoemezeske: same in ruby. you do ugly .send(:method) stuff to get around the private-ness. It's like, anti-code... heh
23:37emezeskeautodidakto: Yeah
23:37amalloyi've found that for some reason (defn- x [] ...) (defn y ...) is more readable than (letfn [(x [] ...)] (defn y ...) when x is large, even though i can't see why that should be the case
23:40autodidaktoamalloy: letfn seems like cleaner encapsulation, but it also kind seems like you have to "load that function (y) mentally" everytime you try to read x
23:40amalloyright
23:42autodidaktoletfn inside your letfn? :)
23:45mysteryman101I am calling a static method in a Java class which I have written, which iterates through some data about 2000 times from Clojure and returns a list. Even when type hinting the static method parameters and return value it runs about 100 times slower than the Java implementation. Any ideas on why this may be? I assumed once a static method in Java is called from Clojure it will run at the same speed as if it were called from Java
23:45mysteryman101code?
23:47emezeskeI really like the letfn idea, because it makes clear the scope of the helper functions
23:47xeqidoesn't letfn cause the same "this function exists and is generally useful but I can't get to it" issue?
23:48technomancyemezeske: calling a defn- is ugly because it's likely to break in future versions
23:49emezeskexeqi: Yeah, it definitely does that. I'm kind of thinking, though, for me at least, I'll only use letfn for small-scoped functions
23:49emezesketechnomancy: Yeah, that's true. There's a tradeoff though, between depending on a function you shouldn't, and copy-pasting it.
23:50technomancyif you think the public API should include it, you should open a bug
23:50amalloyxeqi: it does, but i kinda feel like since left is "more" private than defn-, authors will tend to err more on the side of public. if you use defn-, you can cavalierly make things "private" because someone can still use it if they really want to
23:50emezesketechnomancy: I agree.
23:50technomancyusing defn- means you get to say "I told you so" when other peoples' code breaks =)
23:51technomancyoh man; this is weird: https://github.com/technomancy/sketchbook/blob/master/project.clj
23:52autodidaktoxeqi: lefn shouldn't be generally usefully. just slightly more useful than anonymous functions, but clearly... yeah i dunno.. maybe ruby's anonymous blocks are a middle ground... big enough to not be #(+ 1 %), but still too specific to have a real name
23:52autodidaktoxeqi: meh, weird example. nvm :P
23:54autodidaktogood point, the syntax is inconsistent..
23:55amalloytechnomancy: reify, proxy, multi-arity fns...almost every syntactic construct for defining multiple functions uses parens to isolate
23:55technomancymulti-arity fns are totally different
23:56technomancyyou don't have an identifier in the call position
23:56autodidaktohrm. letfn[(name [args] body)]...(defn name [args] body). hmm
23:58autodidaktoyou could use let[defname fn([args] body)] though, right? (i may be confusing the syntaxt, sorry)
23:59technomancythat doesn't give you mutual recursion, but that's what I always use because I've never needed mutual recursion