#clojure log - Apr 08 2012

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

1:00 muhoo: amalloy: has anything come of this yet? https://gist.github.com/1911278 it looks fantastic

1:01 amalloy: don't ask me, dude

1:01 observe the "Fork of..." line

1:01 muhoo: ah

1:02 amalloy: it looks a lot like STUN to me, but i'm clearly uneducated in the area

1:02 laurus: How do I choose which version of Clojure runs when I run "lein repl" ?

1:04 amalloy: you need a project, with a version set in project.clj

1:05 autodidakto: amalloy: outside of a project, what does lein repl do?

1:05 amalloy: *shrug*

1:05 laurus: amalloy, oh, I see. I am using inferior-lisp mode in Emacs, but I have it set to run "lein repl" as the launch command.

1:05 autodidakto, I believe it runs the version of Clojure that Leiningen itself uses.

1:06 autodidakto: laurus: any reason why you're not using swank-clojure?

1:06 laurus: autodidakto, it just seemed more complicated to set up :)

1:06 offby1: b

1:07 autodidakto: laurus: it's super simple and well worth it

1:07 laurus: autodidakto, ok I will try it sometime soon. I just started learning Clojure for real recently

1:07 Thanks:)

1:08 autodidakto: laurus: you have the clojure-mode package?

1:08 clojurebot: Huh?

1:08 laurus: autodidakto, yes thanks :)

1:08 autodidakto: using lein1, correct?

1:09 laurus: autodidakto, I'm not sure

1:09 autodidakto: then yes, it's one :)... lein -v will confirm

1:09 install swank-clojure plugin with "lein plugin install swank-clojure 1.4.2"

1:10 and you're done. clojure-mode is the client, swank-clojure the server (if i remember correctly)

1:10 M-x and do "clojure-jack-in"

1:10 amalloy: that's only going to work if he's already in a directory with a project.clj, right?

1:10 autodidakto: while you're in project

1:11 laurus: autodidakto, thanks!

1:11 autodidakto: the buffer has to be in a project, yeah. I think subdirectories work... testing

1:12 amalloy: confirmed, you dont have to be in the "root" dir of your project

1:12 amalloy: right

1:12 autodidakto: laurus: np. technomancy did all the work

1:13 amalloy: best practices for a loading a.. um... detatched/scratch swank-clojure repl... I'm not sure

1:14 amalloy: i imagine lein swank followed by M-x slime-connect would still work

1:16 autodidakto: laurus: btw, reference for swank-clojure (check out the commands) -> https://github.com/technomancy/swank-clojure

1:16 laurus: Thanks!

1:17 autodidakto: amalloy: "Couldn't find project.clj, which is needed for swank"

1:17 laurus: Is there any reason not to run lein version 2?

1:18 autodidakto: laurus, not every plugin has updated to lein2, and as a newbie you dont have much to gain

1:19 following the Upgrading page, you could download and install it with the name "lein2" and it won't collide with "normal" lein

1:23 laurus: Thanks for the help!

1:40 autodidakto: Just realized how to monetize clojure -> Rich Hickey Merchandise. Hammocks, Curly Wigs...

3:19 lnostdal: hum, why not? "java.lang.IllegalArgumentException: :volatile-mutable or :unsynchronized-mutable not supported for record fields"

3:22 amalloy: because record fields are public, and mutable fields are private

3:23 lnostdal: ah, yeah .. but, erm, what if i want some of these fields to be private? .. it implicitly makes "getters" for the fields i guess

3:23 key-style ones it seems

3:23 amalloy: then don't use a record

3:24 lnostdal: right

3:24 i'll deftype and build things up from there

6:04 * wmealing tips his hat, 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)

6:09 wmealing_: not sure if my last line got through... sorry if it did and you got this already.

6:10 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)

6:10 http://hastebin.com/nibuxoveli.lisp

6:10 AimHere: We got you announcing that you'd provide code

6:10 wmealing_: yep, and there it is ^

6:11 i know the code doesn't try to use it there, but the functions i'm trying to use are there.

6:11 line 38 is what i'm trying to replace.

6:20 amalloy: wmealing_: 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?

6:23 * Cr8 trying to learn emacs again, using vim to edit my init.el >.>

6:24 progo: :)

6:27 wmealing_: 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.

6:29 [ *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)

6:30 mega`: Cr8: :D love it

6:30 Cr8: you cant stay with vim?

6:34 Cr8: mega`: I'm trying to get a nice slime-like setup for clojure

6:35 Cr8: I use VimClojure, but it's hard to keep actually working, with nailgun and all

6:35 mega`: Cr8: slime and emacs is awesome

6:35 Cr8: also 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

6:37 jszakmeister: Cr8: Have you looked at slimv for Vim?

6:37 I'm actually working on getting it setup in my environment right now.

6:37 Sean Devlin has a nice video on it: <http://vimeo.com/38372260>

6:38 Cr8: jszakmeister: would like something that has a slightly tighter integration than slim

6:38 at least as much as vimclojure/nailgun does

6:38 *slimv

6:38 I -like- vimclojure/nailgun, it's just annoying to get it working

6:38 jaen: Incidentally is there any syntax hilighting thing that does rainbow parens or forms highlighting?

6:38 jszakmeister: I *think* so, but I haven't trudged to deeply in it all.

6:39 Cr8: jaen: vimclojure does =P

6:39 jaen: Well yes

6:39 Sohuld have been more specific

6:39 I mean on the intarwebs

6:39 Any script for that or pastebin service

6:39 That does that?

6:39 Cr8: ah

6:39 jaen: Or would one need to write it by hand

6:39 wmealing_: amalloy, dont worry about it.. its either too hard, or i'm expecting too much too soon.. either way. thanks.

6:44 Cr8: jszakmeister: ah, hang on, this might be what I need :)

6:45 jszakmeister: Cr8: great!

6:52 Raynes: Cr8: The Vim stuff is going to get significantly better soon.

6:52 No more nailgun.

6:52 daniel: when 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 :(

6:53 Raynes: oh really?

6:53 Raynes: Yeah. It's going to use nrepl.

6:53 daniel: great, how soon?

6:53 Raynes: Which lein2 already supports.

6:53 jszakmeister: Raynes: for VimClojure?

6:54 Raynes: I'm not sure. A basic Haskell client already exists in the VimClojure repo. It is working AFAIK, but there aren't any docs yet.

6:54 jszakmeister: Yes.

6:54 jszakmeister: Nice!

6:55 Cr8: Raynes: oh good :)

6:56 Raynes: I've been watching kotarak's bitbucket repo waiting for the nrepl stuff to materialize

6:57 but there's no actual vim-side support for any of it in the repo yet

6:57 just some experiments with the haskell helper client

7:04 autodidakto: Cr8: just spent the last 4 days tweaking my emacs setup (coming from vim)... init.el via vim too :)

7:05 Cr8: VimClojure/Nailgun works well though. What is it that you're missing?

7:08 Raynes: What's with the haskell thing anyway? Brining Vim and Clojure together? That's just weird.

7:09 Raynes: It is a client between Vim and Clojure.

7:10 autodidakto: Raynes: right right, we talked about it a few days ago. development branch but no info about how to set it up

7:10 "I need to get vim to connect to an nRepl.. I know, haskell!"

7:10 Cr8: autodidakto: good way to run it from lein2 =P

7:11 autodidakto: Cr8: hrm, yeah. that's a pain

7:11 will be fixed eventually though

7:11 Cr8: i -can- do it, it's just really annoying

7:11 i mean

7:12 i've had a working vimclojure/nailgun setup on -windows- before =P

7:13 urgh, and slimv's highlighting sucks =/

7:14 autodidakto: sorry crash, what i miss?

7:16 Raynes: <Cr8> urgh, and slimv's highlighting sucks =/

7:18 autodidakto: ugh, emacs.app doth crashith

10:39 makkalot: hi, 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:41 gfredericks: makkalot: maybe it doesn't have to know ahead of time?

10:42 makkalot: gfredericks, but then i wont have a snapshot of all refs as it is stated in docs

10:43 gfredericks: I 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:43 mostly I say this because what you're referring to would be an obvious hole in the system otherwise

10:46 makkalot: i found that it maybe useful http://java.ociweb.com/mark/stm/article.html

10:57 mega`: makkalot: its like a linked list were things cant get gc before transactions do

10:57 makkalot: that's my understanding

10:59 makkalot: mega`, 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:01 mega`: 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:04 makkalot: mega`, nice explanation

11:43 kahlin: hmm, 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:50 masondesu: morning everyone

12:00 kurtharriger: kahlin: 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:01 kahlin: kurtharriger: hmm, ok, so the clj would return the factory function and then i use apply to call it?

12:02 jtoy: i 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:03 it seems like do could be fine

12:05 kahlin: kurtharriger: yeah, that works. thanks!

12:05 kurtharriger: kahlin: cool

12:08 beffbernard: I'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:08 https://refheap.com/paste/1927

12:10 kurtharriger: jtoy: 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:11 jtoy: kurtharriger: i ended up implemented as so : (let [computed (….)] (do (redis/set db table v) v) , it seems to work, thx!

12:12 kurtharriger: beffbernard: (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:14 beffbernard: kurtharriger: I figured as much… any obvious way to defer the initialization of ls?

12:15 jtoy: can 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:15 kurtharriger: your 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:15 another option is to make with-connection* a macro instead of a function

12:17 I think it would look like this: (defmacro with-connection* [zk-spec & body] `(binding [~*zk* (connect ~zk-spec)] ~@body))

12:20 beffbernard: actually think its just ~*zk* not ~*zk* here, but something like that anyway

12:20 beffbernard: kurtharriger: Passing #(ls "/") worked like I had originally wanted

12:20 However the var is still unbound with the macro

12:21 but I can debug that later

12:21 kurtharriger: cool

12:34 hcumberdale: Hi! ;)

12:34 mega`: Hello

12:35 hcumberdale: How to implement http://codex.wordpress.org/Function_Reference/wpautop in clojure?

12:35 Detects double line breaks an replaces them with <p></p> around the paragraph

12:36 mega`: you need it?

12:37 hcumberdale: yeah mega`

12:37 I migrate from my wordpress blog to a clojure blog system

12:38 and I want to copy the data 1:1

12:38 wordpress has this ugly feature autoenabled

12:38 So I need to emulate it to get my content fixed

12:39 http://core.trac.wordpress.org/browser/tags/3.3.1/wp-includes/formatting.php << wpautop is ugly!

12:39 antares_: hcumberdale: if all you need is to split content into paragraphs, chances are, a regular expression may be sufficient

12:39 kurtharriger: (defn wpautop [text] (str "<p>" (string/replace text #"\n\n" "</p><p>" ) "</p>"))

12:39 antares_: ah, so the source is available

12:39 what's the problem then

12:40 hcumberdale: antares_: the source is ugly, no functional style and full of regular expressions

12:41 There must be an easy way to do this in clojure without ~loc

12:41 ~30loc

12:41 clojurebot: Titim gan éirí ort.

12:41 krunaldo: hcumberdale: dunno, seems to be quite a lot of special cases handled in the code

12:42 hcumberdale: unless you implement a parser for the wordpress formating language regex is the easiest way to go

12:42 hcumberdale: yeah damn! I've seen it

12:43 hhutch: I'm stumped with this java interop issue, can anybody point at what I'm doing wrong? https://gist.github.com/2338359

12:43 hcumberdale: Seems the function caused trouble,...

12:43 try (do (.setDefaultFlowStyle DumperOptions.FlowStyle.BLOCK))

12:45 hhutch: hcumberdale: same issue, ClassNotFoundException DumperOptions.FlowStyle.BLOCK java.net.URLClassLoader$1.run (URLClassLoader.java:202)

12:46 hcumberdale: hhutch: do you use leiningen? jsrc path set? reference.class available at classpath?

12:46 hhutch: i use leiningen yes...

12:47 hcumberdale: why do you create the object in java? It is also easy to do this in clojure!

12:47 beffbernard: hcumberdale: nested classes are accessed with $

12:48 kurtharriger: hcumberdale: there is probably a java library somewhere that implements markdown to html conversion you could use from clojure

12:48 hcumberdale: Ahh, I understand you want the java code like the clojure code

12:48 hhutch: hcumberdale: yes

12:48 hcumberdale: kurtharriger: yes, but this is not a markdown issue!

12:49 Wordpress does a special format thing,...

12:49 (defn wpautop [text] (str "<p>" (string/replace text #"\n\n" "</p><p>" ) "</p>")) is fine, but does not handle special cases

12:50 mega`: it missed if its crap betwen the \n\n

12:50 kurtharriger: hhutch: I'm guessing that FlowStyle is an inner class so you need to (import 'org.yaml.snakeyaml.DumperOptions$FlowStyle) then use FlowStyle/BLOCK

12:50 mega`: but you can use regex for that

12:51 kurtharriger: hhutch: sorry I think that should be (import '[org.yaml.snakeyaml DumperOptions$FlowStyle]) then use DumperOptions$FlowStyle/BLOCK

12:52 hhutch: hahha, i just figured that out on my, thank kurtharriger

12:52 :)

13:10 hcumberdale: Is there a better way to write this?: (map (fn [x] (update-in x [:content] #(wpautop %))) (posts-by-category "Welcome"))

13:11 mega`: hcmuberdale: theres a for macro

13:12 &(doc for)

13:12 lazybot: ⇒ "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:13 konr: is there a (for) with indexing? I'd like to iterate over a seq but keep track of my position

13:13 mega`: (for [x (posts-by-category "Welcome")]

13:13 (update-in x [:content] wpautop))

13:14 konr: theres a map-indexed

13:17 Raynes: &(for [[i x] (map vector (range) [1 2 3])] [i x])

13:17 lazybot: ⇒ ([0 1] [1 2] [2 3])

13:17 konr: now that's neat!

13:17 mega`: &(map-indexed vector (range 10))

13:17 lazybot: ⇒ ([0 0] [1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9])

13:17 Raynes: Poor mans indexing. ;)

13:18 But I'd use map-indexed unless you have a real reason for using for.

13:18 Just because it is designed for what I did above.

13:22 hcumberdale: thx mega`

13:22 is there an adavantage of "for" oder the map,... solution?

13:23 Chousuke: map-indexed is faster I think

13:23 Iceland_jack: map and for do different things

13:23 sometimes for is clearer, sometimes it's not

13:24 ibdknox: for is almost always clearer if you're not using a named function

13:24 Iceland_jack: Not quite sure I agree

13:24 ibdknox: counter example?

13:25 Iceland_jack: why?

13:25 clojurebot: why is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone

13:25 ibdknox: haha

13:25 Iceland_jack: but then again non-map comprehensions confuse me

13:26 ibdknox: (map (fn [[x y]] (+ x y)) some-seq)

13:26 vs

13:26 (for [[x y] some-seq] (+ x y))

13:26 Iceland_jack: You're very eager to show this

13:27 ibdknox: not really, I was more curious to hear the counter :)

13:27 Iceland_jack: well I just said I wasn't sure whether I agree

13:27 ibdknox: my experience has generally shown that to be true, but there are lots of things I've not done

13:28 Iceland_jack: possibly compound functions, I also dislike for since it isn't immediately obvious what you're attempting to do

13:28 because of its versitility

13:28 *sa

13:30 beffbernard: ibdknox: what anonymous functions? (map #(+ %1 %2) some-seq) is pretty readable to me

13:30 ibdknox: that's not equivalent to what I wrote :)

13:31 the example you gave would actually be done just as (map + seq1 seq2)

13:31 beffbernard: haha ok, my bad but my question still stands ;)

13:31 ibdknox: I think most of the time you end up doing that, it's really just a named function in disguise

13:32 but yeah, if you don't need destructuring or any of that, absolutely

13:32 I think that's plenty clear

13:32 Iceland_jack: hm

13:32 ibdknox: many #()'s used in maps are just comps or juxts waiting to happen

13:32 Iceland_jack: heh

13:32 ibdknox: filter is a different story though

13:32 unfortunately

13:35 Iceland_jack: I prefer to see what's going on early in each expression

13:35 but for has its moments

13:36 ibdknox: I totally agree map with a named function is the clearest solution

13:36 (map inc some-seq) is immediately obvious

13:36 much more so than the for would ever be

13:36 Iceland_jack: Yes, I think so.

13:37 ibdknox: assuming well-named functions of course ;)

13:37 (map do-shit some-seq) isn't very helpful :D

13:38 Iceland_jack: I favour filter and map, possibly more than I should.

13:38 AimHere: Hmm, 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:38 Iceland_jack: But I fear it may be an old habit

13:38 AimHere: It's easy if it's a record

13:40 pipeline: so i have an emacs virgin at hand

13:40 does anyone have a tutorial they prefer to the one built-in to emacs

13:40 Iceland_jack: Does anyone like the built-in one?

13:42 pipeline: i found it to be tolerable

13:42 Iceland_jack: Well I assume today's kids aren't impressed by navigation commands

13:54 hcumberdale: damn!! wpautop

13:54 the existing code looks like perl. Write only.

13:58 mega`: hcumberdale: if you whant to write it in a simular stile you can use print and redirect the output

13:58 hcumberdale: mega`: I think about how to handle this issue

13:59 making an wordpress compability switch to turn it on or off and save the information with the post?

14:00 mega`: sorry i dont get what you mean

14:08 hcumberdale: Does anyone know if there is a clojure lib to generate a tagcloud?

14:18 devn: jersey-clj -- heh

14:19 TimMc: amalloy discovered this weirdness with booleans, and I've played around with it some more -- any ideas? https://gist.github.com/2338038

14:20 This is in response to that thread on the ML about (Boolean. false), but it's more than that.

14:20 devn: how do i get lein2?

14:20 color me confused.

14:21 TimMc: Also, 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:21 llasram: TimMc: Whoa. How. What.

14:21 Ohhhhh, macro-expansion!

14:22 TimMc: hmm

14:22 devn: so...seriously...what is the proper way to upgrade from lein 1

14:22 blow away ~/.lein, ~/.m2?

14:22 TimMc: llasram: Ah, that certainly clears up part of the mystery.

14:23 devn: do i want to get this: https://raw.github.com/technomancy/leiningen/preview/bin/lein

14:23 TimMc: devn: I think you want to download that as lein2.

14:23 hcumberdale: devn: good question, likely the same that I want to ask

14:23 devn: heh

14:24 llasram: devn: 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:24 devn: im just replacing my lein1 -- might as well go all the way

14:24 my version is now 2, but no plugins are showing up

14:25 duh: https://github.com/technomancy/leiningen/wiki/Upgrading

14:30 TimMc: llasram: Updated the gist to ne simpler, but I'm still having trouble understanding why f* is behaving the way it is.

14:36 llasram: I think it's because the different clojure.lang.Compiler expression types are not entirely consistent in their treatment of Boolean objects

14:36 &(identical? false (eval (Boolean. false)))

14:36 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

14:36 llasram: Haha, of course

14:37 TimMc: But try it out at home to see what I mean

14:40 Or better: https://gist.github.com/2339031

14:41 I think the cases I've add to the bottom really boil it down

14:56 devn: is there any way to suppress warnings for plugins being loaded in leiningen?

15:06 Raynes: Don't use plugins that produce warnings.

15:07 devn: :\ kibit

15:30 ibdknox: cljs-template is awesome.

15:32 jtoy: what 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:32 devn: ,(partition 2 1 [1 2 3 4])

15:32 clojurebot: ((1 2) (2 3) (3 4))

15:32 sjl: jtoy: that looks like (partition 2 1)

15:33 devn: jtoy: more generally, it sounds like what you're describing might be:

15:33 ,(partition 2 1 (range 0 10))

15:33 clojurebot: ((0 1) (1 2) (2 3) (3 4) (4 5) ...)

15:36 jtoy: cool, i never had to use that

15:36 how could partition be useful in general? (besides the case I just used it for ?)

15:36 sjl: ,(into {} (partition 2 [:key1 1 :key2 2])

15:36 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

15:37 sjl: ,(into {} (partition 2 [:key1 1 :key2 2]))

15:37 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry>

15:37 sjl: hrm

15:42 Fullmoon: Let'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:43 Currently, I use something like (map (fn [rec] (.toString [rec]) records)

15:43 How can I get a reference to the '.' function, curried with the value toString?

15:44 sjl: ,(map (memfn toLowerCase) ["FOO" "BAR"])

15:44 clojurebot: ("foo" "bar")

15:44 sjl: Fullmoon: ^^

15:45 llasram: My understanding is that memfn is deprecated. Idiomatic usage seems to be to just use #()

15:46 Of course in the .toString case, you can just use str :-)

15:47 bbloom: back 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:47 but 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:48 Fullmoon: Ah, nice, thanks.

15:48 ,(macroexpand (.toString))

15:48 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Malformed member expression, expecting (.member target ...)>

15:48 Fullmoon: ,(macroexpand '(.toString java-object))

15:48 clojurebot: (. java-object toString)

15:50 llasram: bbloom: 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:51 bbloom: llasram: 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:51 llasram: 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:51 bbloom: like "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:52 ah, didn't consider List

15:52 thanks :-)

15:52 llasram: np

16:00 Fullmoon: I think I miss something obvious, but how can I get a random element from a set?

16:03 sjl: ,(rand-nth (seq #{:a :b}))

16:03 clojurebot: :b

16:05 jtoy: how do I convert lists into tuples?

16:06 bbloom: zipping them?

16:06 progo: what kind of tuples?

16:06 jtoy: vector

16:06 llasram: Fullmoon, 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:06 Iceland_jack: jtoy: (map vector ...)?

16:07 check out Wikipedia's page on convolution

16:07 progo: jtoy, yeah but you can make tuples out of lists in many ways :)

16:11 jtoy: hmm, how would you guys turn this into bigrams? (map str (partition 2 1 (.split "make this into bigrams" "\\s+")))

16:13 llasram: &(->> "make this into bigrams" (#(.split %1 "\\s+")) (partition 2 1) (map vec))

16:13 lazybot: ⇒ (["make" "this"] ["this" "into"] ["into" "bigrams"])

16:13 llasram: jtoy: Like that?

16:14 jtoy: ["make this" "this into "into bigrams"]

16:16 llasram: Oh, clojure.string/join then?

16:16 &(->> "make this into bigrams" (#(.split %1 "\\s+")) (partition 2 1) (map #(clojure.string/join " " %1)))

16:16 lazybot: ⇒ ("make this" "this into" "into bigrams")

16:16 jtoy: oh, oops

16:16 konr: does anybody know how to display an image on compojure, either from a path or an object?

16:19 jtoy: why does this destroy my strings:

16:19 &(map vec (map #(clojure.string/join " " %) (partition 2 1 (.split "make this into bigrams" "\\s+"))))

16:19 lazybot: ⇒ ([\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:20 llasram: jtoy: You're mapping `vec` over each string, treating each string as a sequence of characters and turning that into a vector of characters.

16:20 I think you want just (vec ...), not (map vec ...) ?

16:21 jtoy: ah yes

16:26 daniel: Greetings People of Clojure. I have a few questions for you guys if you're willing to help out a lisp newbie

16:26 I'm coming from Haskell so I'm familiar with fp

16:27 llasram: daniel: Welcome to #clojure! Plenty of helpful people are around :-)

16:27 daniel: First 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:30 If 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:31 jtoy: how would I make it into this form? ["make this"] ["this into"] ["into bigrams"] ?

16:31 llasram: daniel: 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:31 s,time,item,

16:33 jtoy: this doesn't work:

16:33 &(map [#(clojure.string/join " " %)] (partition 2 1 (.split "make this into bigrams" "\\s+")))

16:33 lazybot: java.lang.IllegalArgumentException: Key must be integer

16:34 jtoy: or this:

16:34 %(map #([%]) (map #(clojure.string/join " " %) (partition 2 1 (.split "make this into bigrams" "\\s+"))))

16:34 llasram: jtoy: 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:34 daniel: llasram: Thanks - I found this http://nakkaya.com/2010/12/02/a-simple-forth-interpreter-in-clojure/

16:34 llasram: &((juxt vec vector) "example")

16:34 lazybot: ⇒ [[\e \x \a \m \p \l \e] ["example"]]

16:34 daniel: llasram: which is pretty much exactly what you suggested :)

16:36 llasram: daniel: 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:37 mpenet: daniel: this table can be helpful http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html

16:40 daniel: Another question: Does a '!' at the end of a function name mean that the function mutates global state? Is this rule or convention?

16:40 mpenet: daniel: convention

16:40 mega`: daniel: it can mutate it's arguments to

16:41 daniel: mega`: Analogous to passing by reference in C/C++?

16:41 mega`: daniel: or just a object like a file a http conection or something

16:46 jtoy: llasram: i don't know what that means yet, but will keep testing, thx

16:48 llasram: jtoy: Oh, didn't mean to be obtuse: ##[(vec "example") (vector "example")]

16:48 lazybot: ⇒ [[\e \x \a \m \p \l \e] ["example"]]

16:49 jtoy: yeah, I'll just memorize for now, but I mean I don't understand the why difference of dec vs vector

17:29 emezeske: Any 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:29 I tried (provided (whatever) => (throws Exception)), but that doesn't seem to work.

17:33 mega`: https://github.com/marick/Midje/blob/master/examples/adder-webapp/test/adder/core_test.clj

17:33 emezeske: it uses the throws syntax

17:34 emezeske: anny diference from yours?

17:34 emezeske: mega`: Yeah, I can get the throws thing to check that a function-in-test does throw

17:34 mega`: But I can't get it to say "this mocked-out function should throw an exception"

17:35 senthil: i'm having trouble understanding how nailgun can help dev. process (i get the repl inside vim part)

17:39 emezeske: senthil: I think the simplest advantage is that you can send forms to the REPL with hotkeys (e.g. \et \ef etc)

17:39 senthil: So you don't have to copy+paste things into it to see what happens

17:42 senthil: emezeske: is it similar to "lein repl", but faster boot up?

17:42 mega`: emezske: http://clojuredocs.org/midje/midje.semi-sweet/only-mocked they will trow if you use them :p not so nice maybe

17:43 emezeske: mega`: Hey, that might do the trick! Ugly, but practical :)

17:43 mega`: Thanks a bunch

17:44 senthil: 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:45 senthil: emezeske: is there a debug option in this?

17:45 clojurebot: Excuse me?

17:47 andyfingerhut: IRC 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:47 emezeske: senthil: You mean like a stepping debugger as part of vimclojure? No, I don't think so. For that I *think* you want "slimv"

17:48 senthil: emezeske: yea i tried it earlier, but couldn't get it to work

17:48 mega`: andyfingerhut: what is you are doing lol :D

17:49 andyfingerhut: mega`: nothing nefarious, I think :-) Just seems like something someone else might have already implemented.

17:50 senthil: what's the difference between vimclojure and slimv? (aside from former not having a debugger)

17:51 emezeske: senthil: googling "vimclojure vs slimv" returns: http://www.deepbluelambda.org/programming/clojure/programming-clojure-with-vim

17:53 hobbyist: in REPL, is there a way to place the caret at the beginning of line, word and en of line?

17:54 amalloy: hobbyist: the readline keyboard shortcuts work in most environments

17:54 senthil: emezeske: i guess i might've to bit the bullet and learn emacs

17:55 amalloy: eg, addressing your specific questions, C-a, M-b, and C-e

17:56 emezeske: senthil: 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:56 mega`: emacs is a dream :D

17:57 emezeske: mega`: ^_^

17:57 hobbyist: amalloy: IDEA does not seem to

17:58 amalloy: well you said "repl" - god only knows what IDEA's particular GUI does

18:01 hobbyist: true: I was hoping, should repl have one, IDEA would pick it up

18:05 amalloy: i'm sure IDEA rolls its own from the ground up and just communicates line-at-a-time with the lein repl

18:05 or perhaps even just with the clojure repl

18:08 dnolen: ok monster CLJS patch including all optimizations - https://github.com/clojure/clojurescript/compare/all-optimizations

18:08 basic operations are nearly 2X faster, with some operation >5X faster

18:08 would 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:09 mega`: dnolen: brb

18:10 andyfingerhut: dnolen: 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:10 emezeske: If 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:10 Or, instead of HEAD you could always checkout dnolen's branch

18:10 dnolen: emezeske: thx

18:11 andyfingerhut: there is not, tho I test all my changes against V8, SpiderMonkey, and JavaScriptCore

18:11 andyfingerhut: What steps do you go through to test your changes? Do you do it in a browser, or CLI?

18:12 dnolen: andyfingerhut: CLI

18:12 amalloy: andyfingerhut: there is ./script/test, which runs some tests

18:12 it's not nearly as thorough as jvm-clojure's tests, but it's a little safety net

18:14 andyfingerhut: jvm-clojure's tests may be thorough compared to ClojureScript's, but they seem like they could use some beefing up.

18:15 mega`: dnolen: my project seems to work :P

18:15 dnolen: mega`: EXCELLENT!

18:15 amalloy: andyfingerhut: 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:16 andyfingerhut: amalloy: 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:19 e.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:19 emezeske: dnolen: I'm pretty sure all-optimizations works for my project

18:19 dnolen: emezeske: great!

18:20 emezeske: dnolen: Is there anything obvious I could look for in the output javascript to make sure that the all-optimizations branch was really used?

18:20 dnolen: actually, nevermind, I can just do a diff with the output from before

18:22 dnolen: Yeah, it's definitely using the all-optimizations branch, and it works just fine

18:23 dnolen: emezeske: that's great to hear.

18:23 emezeske: Oh, nice, if(cljs.core.truth_(q >= 0)) is now just (q >= 0). That's an epic win.

18:25 dnolen: emezeske: also multi-arity fns that are not used higher don't cost any more than regular fns.

18:25 amalloy: dnolen: "higher order", right?

18:25 dnolen: emezeske: this means almost 1.5-2X boost for even simple things like reduce.

18:25 emezeske: Wow, nice!

18:25 dnolen: amalloy: yes

18:26 emezeske: Hmm, unexpected: the file size of my minified source grew by ~40%

18:27 By minified I mean :advanced optimizations

18:27 dnolen: emezeske: what about after gzipping? how does the size fare? I should definitely look into that.

18:27 emezeske: dnolen: Lemme see

18:28 dnolen: emezeske: I'll check here too.

18:28 oakwise: dnolen: works for my project

18:28 dnolen: oakwise: can you let me know about file size comparisons?

18:29 emezeske: dnolen: Gzipped, the old :advanced js is ~20% smaller than the new :advanced js

18:30 groovemonkey: question: 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:30 emezeske: dnolen: Interestingly, :whitespace optimized, the old and new are very very close in size

18:30 andyfingerhut: groovemonkey: See if update-in does what you wish

18:30 dnolen: emezeske: k thx, looking into it here.

18:31 groovemonkey: andyfingerhut: thank you! I've been trying assoc-in mixed with get-in, etc.

18:34 dnolen: mega`: if you could report files size differences between the two branches that would helpful - thx

18:35 oakwise: dnolen: :whitespace = basically same size, :advanced = 248k up from 183k, :advanced+gzip = 50k up from 41k

18:36 dnolen: hmm, 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:42 emezeske: is lein-cljsbuild 0.1.7 out?

18:42 groovemonkey: pardon my noobness, but I"m still having a problem creating a new version of a map:

18:43 user=> (def mainmap {:one {:eins "un"} :two {:zwei "deux"}})

18:43 #'user/mainmap

18:43 user=> (update-in mainmap [:three] "trois")

18:43 ClassCastException java.lang.String cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:602)


18:44 andyfingerhut: groovemonkey: 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:45 groovemonkey: andyfingerhut: ahhh, just ignoring the input arg and returning what I want to return? Thank you! I'll try that right away.

18:45 amalloy: that's just assoc-in

18:48 mega`: dnolen: it removes one line

18:48 dnolen: mega`: heh

18:51 groovemonkey: amalley and andyfingerhut: thanks, I think assoc-in solved it.

18:51 amalloy*: thanks

18:55 mega`: dnolen: the size seem to be the same

18:59 amalloy: groovemonkey: your IRC client will probably tab-complete usernames

19:03 Scorchin: What'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:04 oskarth: Trying 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:05 feels like a silly question but can't get my head around how to do deal with the defpartial macro

19:07 offby1: It 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:08 dnolen: offby1: they are similar I think. sometimes referred to fluid vars as well.

19:10 offby1: And 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:10 "earmuffs"

19:10 amalloy: that was never actually the case

19:10 dnolen: emezeske: hmm seems like the size issue boils down 1 line ...

19:10 down to

19:11 amalloy: rather, every var was dynamic

19:11 offby1: ah

19:11 but with 1.3 that's different, right?

19:12 You gotta explicitly ask for dynamic-ness

19:12 dynamism

19:13 dnolen: offby1: yes

19:18 offby1: *nod

19:24 sritchie: technomancy, is there a way to get dev dependencies into leiningen 2's generated pom?

19:24 technomancy: trying to get interop w/ intellij working

19:41 amalloy: sritchie: i think lein2 uses depot to generate POM, which is at https://github.com/flatland/depot/blob/develop/src/depot/pom.clj

19:42 it would probably be pretty easy to add a handler for dev-dependencies

19:42 sritchie: amalloy: great, thanks

19:42 I'll take a look this evening

19:50 dnolen: hmm I wonder if the all-optimizations branch isn't a classic size vs. speed tradeoff.

20:11 amalloy: dnolen: 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:18 gfredericks: does cljs varargs use js varargs?

20:21 dnolen: amalloy: yes the size problem is coming from the multi-arity stuff - looking into a solution right now.

20:22 * dnolen crosses fingers

20:22 llasram: sritchie: A bit late, but normal :dependencies in the :dev profile get added to the POM dependencies, just like lein1 :dev-dependencies did

20:24 ibdknox: I would rather have size for speed in this case

20:28 dnolen: ibdknox: yes, I think it's non-starter if average code grows by >20%

20:29 ibdknox: I think I may have a solution tho, I think my particular approach was frustrating advanced compilation.

20:30 andyfingerhut: Can I put in a plug for larger code size? More data traffic for companies like Cisco to sell more equipment :)

20:33 Cyrik: is there some way to do a post-order tree traversel with a zipper?

20:35 mdeboard: Cyrik: Isn't that one of the built-ins

20:35 I mean, in the zip module

20:36 Cyrik: Oh, sorry, you actually use clojure.walk/postwalk

20:38 Cyrik: well the problem withh postwalk is that its not tail-recursive, so it builds up the stack

20:38 zippers dont do that but the built in next does a pre-order traversel:(

20:44 AWizzArd: There is also prewalk

20:44 And walk

20:55 dnolen: HUZZAH!

20:55 emezeske: ibdknox: oakwise: and whoever else please try all-optimizations branch now if you can - no more size explosion

21:00 laurus: Is there some kind of way to interact with the program Cytoscape through a Clojure REPL?

21:02 oakwise: dnolen: solid! It's down to almost exactly where the master version is now

21:03 dnolen: oakwise: SWEET

21:04 oakwise: yes it should only be slightly larger - waaay faster :)

21:04 oakwise: awesome. free speed!

21:05 up next: unreal engine software renderer in cljs?

21:10 gfredericks: ,(-> nil false? false?)

21:10 clojurebot: true

21:32 lynaghk: Would it be possible for me to redefine clojure.lang.Ratio#toString?

21:33 I 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:34 dnolen: lynaghk: I don't think that's possible.

21:34 lynaghk: dnolen: nooooooooooooooo

21:34 llasram: Maybe using something like HotSwap?

21:34 gfredericks: lynaghk: why are you using ratios if you don't like them?

21:34 llasram: Yeah, what is it you're ultimately trying to do?

21:34 lynaghk: gfredericks: I'm dividing.

21:35 sritchie: lynaghk: but why use ratios?

21:36 (defn div [& xs] (float (apply / xs)))

21:36 lynaghk: sritchie: it's library code that's doing the division.

21:37 sritchie: how about (def num-str (comp str float))

21:37 lynaghk: llasram: 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:37 sritchie: or (def num-str (comp str (fn [x] (if (ratio? x) (float x) x)))

21:38 lynaghk: sritchie: 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:38 I haven't done a ton of namespace/var gymnastics before though

21:38 sritchie: lynaghk: you could alter-var-root and replace the normal str with that one I defined

21:40 llasram: lynaghk: 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:40 sritchie: ,(binding [str (comp str (fn [x] (if (ratio? x) (float x) x)))] (str (/ 1 2)))

21:40 clojurebot: #<IllegalStateException java.lang.IllegalStateException: Can't dynamically bind non-dynamic var: clojure.core/str>

21:40 lynaghk: sritchie: that sounds great, I'll give that a shot. I didn't know about alter-var-root, thanks.

21:55 sritchie: yep, that worked great, thanks.

21:56 llasram: yeah, it's a gross hack. I'm definitely open to suggestions.

22:05 technomancy: sritchie: I think in preview3 dependencies from :dev are going to end up in the pom as test-scoped

22:05 xeqi: they do

22:05 technomancy: cool

22:05 xeqi: *will

23:03 emezeske: dnolen: No, lein-cljsbuild 0.1.7 is not out yet

23:03 dnolen: Checking the file size now!

23:03 dnolen: Nice, the file size is totally normal with the latest all-optimizations

23:04 dnolen: emezeske: great!

23:19 autodidakto: if 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:19 https://github.com/stephenalindsay/minnow

23:20 wkelly: 3

23:30 emezeske: I kind of have started to feel like there's no good reason to declare things as namespace private (e.g. defn- etc).

23:30 Does anyone else feel the same way? Or can anyone convince me that I'm crazy?

23:31 autodidakto: i'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:31 emezeske: Hmm, maybe it's good for APIs to document which things are just helper functions

23:31 autodidakto: documentation vs code -declarations... yeah

23:32 amalloy: emezeske: i'm against defn- in general, but i do it sometimes

23:32 emezeske: amalloy: So, like, by default you don't defn-? When do you special-case it?

23:32 autodidakto: but 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:32 amalloy: like, i prefer to declare my helper functions with letfn: (letfn [(helper [x] ...)] (defn public [x] ...))

23:33 emezeske: autodidakto: Yeah, self-documentation is good

23:33 amalloy: but not every context supports closures, like the body of a defrecord/deftype can't be a closure

23:33 emezeske: amalloy: I had never thought to wrap my defns that way, interesting...

23:34 amalloy: autodidakto: 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:35 autodidakto: amalloy: letfn is like defining (anonymous) functions inside of a function (like in scheme) ?

23:35 ,(doc letfn)

23:35 clojurebot: "([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:36 autodidakto: i guess i shouldnt say (anonymous)

23:36 emezeske: amalloy: That's been my experience, I just get irritated because I have to jump through hoops to call such a function

23:36 amalloy: or 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:37 autodidakto: emezeske: same in ruby. you do ugly .send(:method) stuff to get around the private-ness. It's like, anti-code... heh

23:37 emezeske: autodidakto: Yeah

23:37 amalloy: i'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:40 autodidakto: amalloy: 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:40 amalloy: right

23:41 * emezeske goes to use letfn all over the place.

23:42 autodidakto: letfn inside your letfn? :)

23:45 mysteryman101: I 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:45 code?

23:47 emezeske: I really like the letfn idea, because it makes clear the scope of the helper functions

23:47 xeqi: doesn't letfn cause the same "this function exists and is generally useful but I can't get to it" issue?

23:48 technomancy: emezeske: calling a defn- is ugly because it's likely to break in future versions

23:49 emezeske: xeqi: 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:49 technomancy: Yeah, that's true. There's a tradeoff though, between depending on a function you shouldn't, and copy-pasting it.

23:50 technomancy: if you think the public API should include it, you should open a bug

23:50 amalloy: xeqi: 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:50 emezeske: technomancy: I agree.

23:50 technomancy: using defn- means you get to say "I told you so" when other peoples' code breaks =)

23:51 oh man; this is weird: https://github.com/technomancy/sketchbook/blob/master/project.clj

23:52 autodidakto: xeqi: 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:52 xeqi: meh, weird example. nvm :P

23:53 * technomancy hates letfn because it's the only place where seeing "(foo" means something other than "calling foo"

23:54 autodidakto: good point, the syntax is inconsistent..

23:55 amalloy: technomancy: reify, proxy, multi-arity fns...almost every syntactic construct for defining multiple functions uses parens to isolate

23:55 technomancy: multi-arity fns are totally different

23:56 you don't have an identifier in the call position

23:56 autodidakto: hrm. letfn[(name [args] body)]...(defn name [args] body). hmm

23:58 you could use let[defname fn([args] body)] though, right? (i may be confusing the syntaxt, sorry)

23:59 technomancy: that doesn't give you mutual recursion, but that's what I always use because I've never needed mutual recursion

Logging service provided by n01se.net