#clojure log - Nov 28 2010

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

0:12 KirinDave: Hum

0:12 What is the difference between defvar and def?

0:14 Does defvar just give a more convenient syntax for dropping vars for things like documentation purposes?

0:24 pppaul: (ns your.namespace.here

0:24 (:require '[clojure.string :as str])) gives me an error

0:24 java.lang.Exception: lib names inside prefix lists must not contain periods (NO_SOURCE_FILE:50)

0:25 nm, i'm not supposed to quote the vector

0:26 found it on this site: http://clojure.github.com/clojure/clojure.string-api.html#clojure.string/split

1:12 replaca: KirinDave: yeah, that's right.

1:13 KirinDave: replaca: Figured

1:14 replaca: KirinDave: I think that part of the thought is also that defvar is in itself documentation (that this is a ver and not a memoized function or some other thing you could do with def)

1:16 s/ver/var/

1:16 sexpbot: <replaca> KirinDave: I think that part of the thought is also that defvar is in itself documentation (that this is a var and not a memoized function or some other thing you could do with def)

1:30 Guest43529: quit

1:54 ossareh_: I've a situation where I need to rewrite a function, I think the correct way to do this is with a defmacro. essentially something like this: (wrap-this (some-fn "x") (some-fn "y")) -> (some-fn "x" "y") (some-fn "y" "y")

1:55 additionally I want to check whether the forms have a second argument and augment it if it is there.

1:55 However when I do this I end up with the following output: Unable to resolve symbol: f__41681__auto__ in this context

1:56 (defmacro add-arg [fn] (let [[f#] fn] (prn f#) `(f# "x"))) - called as (add-arg (prn))

1:56 Raynes: You don't want to use gensym outside of syntax quote.

1:57 Just name it f and then refer to it as ~f in the syntax quote.

1:58 ossareh_: Thanks, Raynes!

1:58 Raynes: user=> (macroexpand '(add-arg (prn)))

1:58 prn

1:58 (f__2635__auto__ "x")

1:59 ossareh_: cool - that works - let me work this into my larger requirement.

1:59 Raynes: Macroexpand is your best friend. Treat him well, and he'll always be there for you.

2:04 ossareh_: ye - I rely on it pretty heavily, got caught out by the gensym stuff.

2:05 is there something from your macroexpand output that should have triggered something for me?

2:06 Raynes: ossareh_: Well, now that I think about it, not really. Since you didn't know to not use gensym outside of syntax quote, it made perfect sense.

2:52 ossareh: and in the same vein (i.e. rewriting forms) what is the correct way to iterate [& forms] without executing each form? (defmacro add-arg [& forms] (for [[fn] forms] `(~fn "x"))) => (macroexpand '(add-arg (prn) (prn)) => ((prn "x") (prn "x")). Where as I want (prn "x") (prn "x")

3:01 also, I chose to use for since using map (my first attempt) requires I ~@ forms which seems to then be executing the (prn) arguments

3:13 hoeck: ossareh: macros can only return a single expression

3:15 ossareh: but it could expand into (do (prn "x") (prn "x"))

3:16 and it doesn't matter what code map or for or whatever you are using in the macro, what matters is the right quoting and unquoting

3:18 e.g. with map: (defmacro add-arg [& forms] `(do ~@(map (fn [fn] `(~fn "x")) forms)))

3:18 ossareh: ahh, the splice being up front... of course!

3:24 thanks hoeck that did the trick :)

3:26 hoeck: ossareh: you're welcome :)

4:53 neotyk: Good morning!

4:55 LauJensen: Morning!

4:57 neotyk: How does one declare contract for interface from Clojure to Java?

4:57 now I return map-of-maps

4:58 but have no way to be sure that for new entities I will follow same syntax

8:11 lyonscf: hey guys, I

8:11 I'm having a little bit of trouble with webmine

8:11 I can't seem to find a resource for including the ilb

8:12 in the (use 'foo.bar.webmine) format

8:16 oh wait, nevermind

8:17 just read into the core

8:17 the namespace is webmine.core

8:17 Thanks anyway :)

8:27 rhickey: anyone try *unchecked-math* yet?

8:36 fliebel: morning

8:45 jaley: hi guys! can anyone give me a little advice on how best to interoperate with Quartz (the scheduler) from clojure? I don't like that insists on constructing job objects itself from a provided class, because this way i think i'd need to write loads of boiler plate wrappers around clojure functions to get the callback... any suggestions?

8:47 raek: jaley: I don't have any experience with Quartz, but interop with cron4j is very simple: (doto (it.sauronsoftware.cron4j.Scheduler.) (.schedule "30 16 * * 1-5" #'some-function) .start)

8:48 I don't know if cron4j provides what you are looking for, but using it requires minimal amount of boilerplate

8:49 jaley: raek: that looks simpler, thanks

8:49 raek: (the example runs some-function 16:30 every Monday-Friday)

8:49 jaley: raek: the problem i have with Quartz is that the interface to add a job is: addJob(JobDetail, Trigger, Class) - where the service creates the job instance based on the class you pass in

8:50 LOPP: why the quote on #'some-function

8:50 raek: I have an IRC bot that I like to hack on while it's running

8:51 LOPP: do you have to change the code if you stop using the quote?

8:51 jaley: raek: so with quartz i don't think i could avoid a load of gen-class...

8:51 raek: the var-quote lets me redefine that function and next time the task is executed, it will use the new version

8:52 LOPP: I think you need to restart the scheduler (which is pretty simple too) if you want it to use the new version

8:52 hrm, I might be wrong in this case. if you put the function in a datastructure, you need the var-quote

8:53 but for function parameters...

8:53 LOPP: because I had to make special code to have functionality where I could use either var-quoted fns or normal fns

8:53 for instance #() ones

8:55 raek: ok, it turns out that when passing the function directly as an argument, you don't need the var-quote

8:56 LOPP: these things confuse me :D

8:57 I always have to determine need for quotes with testing

9:02 raek: I think that when a symbol represents a var, the compiler will compile in a reference to the var itself rather than its value

9:02 locals introduced by let and function parameters are different

9:04 LOPP: I think of this in a different manner

9:05 compiler evaluates vars whenever they are part of an expression

9:06 that includes passing them as function parameter or adding them to a data structure

9:06 so if I add a fn to a data structure, the var will get evaluated and value added to the list

9:07 a function using the list of fns will get the same fn every time even if I change the function bound to the var

9:08 when the var of fn is passed as an argument to the function, it gets evaluated to value each time it's called so changing function bound to var changes the behavious of the program

9:08 anyway that;'s how I see it

9:09 lyonscf: What's the best practice for declaring static global vars?

9:09 Is it just a def at the top of the file?

9:09 raek: LOPP: makes sense

9:11 lyonscf: a globally accessible value would be a simple def

9:11 lyonscf: thanks raek. :)

9:11 raek: what do you mean by "static"?

9:11 lyonscf: static meaning constant

9:12 but obviously the focus is on immutability in Clojure.

9:14 LOPP: I hear in 1.3 vars will be immutable by default

9:14 so you'll basically get public static final stuff

9:16 raek: they can still be redefined, I think

9:16 but they cannot be dynamically rebound with 'binding'

9:19 LOPP: doesn't that kinda defeat the purpose

9:22 raek: in 1.3, when a var is redefined, functions using it will be recompiled at the first time they are called after the redefinition, IIRC

9:22 so there is some "var version" check on each function entry, I think

9:23 redefining a var should only be done when correcting a running system, or during development, though

9:25 LOPP: doesn't that incur a performance penalty though

9:25 raek: it is a lot faster than the current implementation

9:25 if I understand things correctly

9:28 but yes, having a language allowing interactive development cannot be exactly as fast as a purely compiled language

9:28 but the HotSpot JVM makes a really good job

9:28 and the 1.3 stuff lets it do much more of its magic

10:07 LOPP: so you are saying that var version check is done now too

10:16 raek: I think think this is in the master branch now

10:32 jarpiain: references to non-:dynamic vars are compiled into calls to Var.getRawRoot() that just returns the private volatile instance field

10:35 jaley: not in the doc string, but does anyone know if there's a keyword option to add a watch function to an agent?

10:36 i mean for the agent function, of course. just to avoid needing add-watch

11:31 djpowell: is unchecked-math supposed to work with binding?

11:32 (binding [*unchecked-math* true] (byte 200)) fails

11:32 but (set! *unchecked-math* true) (byte 200) works

11:35 ah - does it only affect what is compiled?

11:35 ok that makes sense

11:37 I think. I'm not sure how you would go about turning it on and resetting it tho?

12:20 zmyrgel: hi, how can I test if item implements protocol/

12:20 ?

12:37 kaiser: hi, guys

12:37 Guest43491: i'd like to execute n times a function and get the last result...what's the best construction for this?

12:38 raek: is this for java interop?

12:38 Guest43491: no

12:40 in fact, i want to accomplish the following...

12:40 i have a function 'a'

12:40 and the result must be the input of the same function 'a'

12:41 and i want to execute this function n times...

12:41 raek: sounds a bit like iterate

12:41 ,(doc iterate)

12:41 Guest43491: i have performance issues

12:41 raek: &(doc iterate)

12:41 sexpbot: ⟹ "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"

12:41 Guest43491: so, i'm reading about lazy-seq with recursion...

12:42 Licenser: evening

12:42 Guest43491: hmm...gonna try this iterate...

12:43 raek: &(take 10 (iterate inc 0))

12:43 sexpbot: ⟹ (0 1 2 3 4 5 6 7 8 9)

12:43 Licenser: iterate passes the result of the current call to the next call

12:45 Guest43491: thanks

12:46 raek: &(let [compose-n-times (fn [f n] (fn [x] (nth (iterate f x) n))), plus-10 (compose-n-times inc 10)] (plus-10 5))

12:46 sexpbot: ⟹ 15

12:48 opqdonut: &(let [compose-n-times (comp (partial reduce comp) repeat) plus-10 (compose-n-times 10 inc)] (plus-10 5))

12:48 sexpbot: ⟹ 15

12:52 slyrus_: technomancy: thanks!

12:58 Guest43491: thank you raek

13:29 miltondsilva: Hi

13:32 I have a vector like [:f :- :push :f :pop] and would like to generate code like ((forward) (rotate) (push-matrix (forward))) do I need a macro to do this?

13:33 raek: no

13:33 chouser_: no, though once you've generated the code you'll need either a macro or 'eval' to run it.

13:34 miltondsilva: hmmm ok but is it easier with one? I've never felt the need to use macros so I haven't learn how to used them

13:34 raek: you could do a function that interprets that vector and executes the functions

13:35 miltondsilva: I was trying to use strings and read-string + eval.. but somehow it's getting a bit ugly

13:35 raek: the :f and :- case should be pretty simple:

13:37 (defmacro foo [x] (if (empty? x) nil `(do ~(case (first x) :f `(forward) :- `(rotate)) (foo ~(rest x)))))

13:37 or somehing like that

13:38 miltondsilva: there is no need to go through strings

13:39 a macro is just an ordinary clojure function that takes unevaluated code expressions as its arguments and returns some new code

13:39 chouser: raek: replace "just" with "like" and I'll let it go. :-)

13:40 raek: right.

13:40 the &env thingy?

13:40 chouser: yes, and &form

13:41 miltondsilva: hmm.. thanks I think I can do it now

13:53 Intertricity: Is there any documentation on using .Net in the clojure-clr implementaiton?

13:54 *implementation

13:54 like how to access dictionaries, or the system libraries

13:55 Raynes: chouser: Why is &form useful?

13:58 chouser: Raynes: I think primarily for pulling metadata off the form and the first symbol

14:02 jjido_: can I tell Clojure to tell the JVM to reload a Java class?

14:02 chouser: you can generate a new class with the same name with deftype and defrecord, but otherwise no

14:03 jjido_: ok

14:03 chouser: you may be able to use some other tool to do that, javarebel or whatever, but I don't know if anyone has gotten such things working with clojure

14:04 jjido_: I will just restart the JVM no big deal.

14:50 Intertricity: wow clojure is hard xD

14:51 I have to chew on chunks of tutorials for a while to grasp the concept

14:51 Derander: Intertricity: have you had any experience w/ functional programming before?

14:52 Intertricity: Derander, not really, I just did basic C and Python before that

14:53 Derander: makes sense then :-)

14:53 Intertricity: hehe

14:54 With the beginnings of clojure on clr though, I want to try porting my .Net program over to clojure

14:54 I've been waiting for the clr implementation to start learning it

14:54 Derander: it's fun

14:55 not a java fan?

14:55 Intertricity: Derander, do you know where I can get docs on how to use clojure-clr to access the .Net libraries like system or dll's?

14:55 Derander, the library I use is all .Net unfortunately

14:55 Derander: no, unfortunately, I have no idea. I've never used clojure-clr.

14:55 Intertricity: aw nutbunnies

14:56 I was originally using ironpython

14:56 but I long to see parenthesis in my code xD

14:56 Derander: right

14:56 :P

14:56 raek: for interfacing with .net classes, I suspect it should work like java interop in "clojure-jvm"

14:56 Derander: that would be my guess too

14:56 hoeck: Intertricity: I only managed it to compile clojure-clr once and ran a simple hello-world windows dialog

14:57 Intertricity: hoeck, they have binaries available now

14:57 hoeck: Intertricity: and does it now run on mono?

14:57 Intertricity: I wouldn't know, sorry

14:57 raek: Intertricity: ​http://clojure.org/java_interop

14:57 Intertricity: raek, ty :)

14:58 hoeck: the interop seemed the same as on (java-)clojure, import classes and then call .methods on them

14:58 Intertricity: I dont' know much about java if any, I wonder if it's simlar to this to laod a dll?

14:58 *load

15:01 hoeck: Intertricity: how do you load a dll in .net?

15:02 Intertricity: clr.AddReference("System", "OpenMetaverse","OpenMetaverseTypes")

15:02 from OpenMetaverse import *

15:02 raek: in java-land, you start the jvm instance with a classpath option. the classpath is a list of directories and jar-files that contains .class-files

15:02 Intertricity: I see

15:04 Hm. well tihs is a little closer http://www.mail-archive.com/clojure@googlegroups.com/msg24944.html

15:04 but nothing about dll's

15:08 hoeck: Intertricity: the assemblies may reside in some dll, and on windows it may be enough when your dll is on the search path

15:09 Intertricity: hoeck, how would I define the path myself? I usually keep the library I'm working with close to my sourcefile atm

15:09 or if you have any past code that shows it, that would be even better >.>

15:09 I can't find docs or examples

15:10 hoeck: don't know about .net, but win32 dlls have to reside in %PATH% or . or win\system32\ or so

15:11 If you have a working IronPython solution, the just try that (System.Reflection.Assembly/LoadWithPartialName "System.OpenMetaverse.OpenMetaverseTypes")

15:12 followed by an (import '(System.OpenMetaverse OpenMetaverseTypes))

15:12 if IronPython finds that dll without tweaking, clojure-clr should do the same

15:12 Intertricity: hoeck, ty :)

17:44 jweiss_: i'm trying to introduce clojure to co-workers in the most painless way possible. I think the labrepl tutorial is great, but I don't want them to go thru the pain of installing the prereqs until they're "hooked". I can host the labrepl webapp for them, but any suggestions how to host a repl?

17:45 i checked out http://tryclj.licenser.net/ , but there's no cut/paste.

17:45 Raynes: jweiss: try-clojure.org is the actual domain.

17:46 I use jquery-console which doesn't support copy and paste.

17:46 In any case, there is no way to run a server-side REPL without sandboxing, and even then it may not be totally safe.

17:47 jweiss_: Raynes: googling "try clojure" links to the address i pasted. but yeah i know that is not the official url

17:47 Raynes: since it's just co-workers and I can run it on a vm, i'm not concerned with security

17:48 \some paredit functionality would be nice

17:48 Raynes: That it would. It most likely wont happen though. At least, not while jquery-console is being used.

17:50 jweiss_: Raynes: yeah, i wish there was a way to "webify" a slime session

17:51 but i don't see how a browser is going to take over those keybindings

17:51 trying to convince someone to use clojure without them knowing of paredit's existence, well, it doesn't help clojure's cause :)

17:55 lucian: Raynes: wouldn't a java applet work too?

17:55 Raynes: lucian: Yes, but applets are ugly and meh.

17:55 http://github.com/Raynes/webrepl

17:57 lucian: Raynes: wouldn't it also be easier on the server?

17:57 Raynes: Yes, but applets are still ugly and meh. :p

17:58 jweiss_: an applet would be pretty straightforward actually. still no paredit, but no need for security

17:58 lucian: Raynes: yeah, they do tend to be ugly

17:58 Raynes: jweiss: If you want, you're welcome to use webrepl.

17:58 It's ugly as sin, but it'll do the trick.

17:59 jweiss_: Raynes: let's see how ugly :)

17:59 * jweiss_ loads it up

18:00 jweiss_: Raynes: how do i run it

18:00 Raynes: Aren't there instructions in the README?

18:00 jweiss_: Raynes: no

18:00 not the readme on the github page, anyway

18:00 Raynes: That sucks. I don't remember how to run it.

18:00 jweiss_: hehe

18:02 Raynes: i think you left JConsole out of the deps in project.clj

18:02 Raynes: It's included in the source.

18:02 jweiss_: ah

18:03 lein doesn't seem to know how to build it

18:03 Raynes: I would be more helpful, but I'm in the process of moving stuff to a new server. Trying to get sexpbot up and running there.

18:03 KirinDave: Hum.

18:03 jweiss_: Raynes: that's ok, i'll figure something out :)

18:04 KirinDave: Is there any consensus on best practices in clojure for using protocols and deftype?

18:04 Raynes: jweiss: lein repl and then use webrepl.core, and then run -init

18:04 KirinDave: For example, what's the right way to make default behavior?

18:04 jweiss_: Raynes: thx

18:04 KirinDave: I had hoped I could do something like: (extend-protocol tester Object (c [d] (a d))), (extend-protocol tester java.lang.Integer (a [b] (inc b)))

18:05 And have (c 1) return 2.

18:06 But it seems like if you omit a function definition from a protocol map for a given type, it won't try to call the method on a more general type.

18:15 brehaut: is there an XML-RPC library that works with ring?

18:33 Raynes: Oops. Forgot to run it in screen. ._.

18:36 dnolen: a much faster implementation of miniKanren for Clojure - https://github.com/swannodette/logos for the logic / relational programming fans. Lots of Clojure specific additions and tweaks.

19:26 markj9: anyone have a minute to offer suggestions on why lein is now giving me this error http://pastie.org/1331111

19:51 brehaut: what is the naming conventions for defrecord types? is it camel cased like a java class?

20:08 * Raynes yawns

20:16 jweiss_: anyone noticed that labrepl doesn't build anymore? it has a dev dep on autodoc-0.7.0, which depends on clojure-contrib 1.1.0-master-SNAPSHOT, which unsurprisingly is no longer available in the repo

20:18 Raynes: jweiss: :exclude it's autodoc dependency.

20:19 jweiss: There is an example of using exclusions in sample.project.clj in the Leiningen repository.

20:19 jweiss_: Raynes: i know how to fix it for myself. but i'm setting up my co-workers to check out the source from github and their source will be wrong

20:19 Raynes: Oh.

20:19 jweiss_: i was wondering if there was a different command than lein deps i could run that would bypass the dev deps

20:20 i suppose i could just build an uberjar and distribute that

20:21 but i was hoping not to have to host anything

20:21 i guess i could fork the project on guthub

20:21 that's probably the easiest

20:22 KirinDave: Am i the only person a little frustrated by non-seq laziness in clojure?

20:27 replaca: KirinDave: what do you mean exactly by non-seq laziness?

20:27 KirinDave: you mena like vecors not being lazy?

20:27 s/mena/mean/

20:27 sexpbot: <replaca> KirinDave: you mean like vecors not being lazy?

20:28 replaca: ok, I'm going to give up on typing now :)

20:29 KirinDave: replaca: Ha

20:29 replaca: I mean like how you have to force delays.

20:30 replaca: Yes, force is idempotent on non-delay objects, but then I'm writing force everywhere on the off chance client code sends my library a delay.

20:30 It'd be better if the force was implicit.

20:31 replaca: KirinDave: isn't that just the definition of a delay? "That which needs to be forced"?

20:31 KirinDave: replaca: Well i wish I had a (lazy ...) then

20:31 ,(doc lazy)

20:31 Damn it

20:31 The Secret™ fails again.

20:31 replaca: KirinDave: make it.

20:32 KirinDave: replaca: I am not sure how.

20:32 I suspect it's a pretty non-trivial thing.

20:32 Gonna have to go into the compiler to do it properly.

20:33 replaca: KirinDave: why, can't you just wrap a delay in an object that implements IDeref which does a force, then the regular deref?

20:33 KirinDave: replaca: Doesn't deref already force?

20:33 replaca: or am I misunderstanding your use case?

20:34 KirinDave: replaca: The fact that I have to explicitly force values means I need to expect laziness and just force everything before using it.

20:34 replaca: This clutters up the code pretty significantly.

20:35 I think from a library-writer's perspective, this means that you won't handle implicit client laziness very often without sacrificing a lot of code readability.

20:35 replaca: oh, I see

20:35 KirinDave: It'd be great if, if someone passed me in a delay to my library, it was auto-forced at the appropriate time.

20:35 replaca: yeah, you're right, I think

20:35 KirinDave: But like I said, I think it'd need compiler and stdlib support

20:36 If it was more like scala's lazy keyword, we'd see laziness used a lot more in clojure code, I think.

20:36 Part of the popularity of seqs is their magic.

20:36 You don't have to explicitly force seq values, that happens implicitly as you move along the seq.

20:37 replaca: so what you're after is "(let [foo (magic (bar baz))] foo)" to have bar called when foo is referenced?

20:38 KirinDave: Yes.

20:38 But _not_ if, say, foo is just passed as a function argument

20:38 Or put into a let.

20:39 It has to be "used" for some definition of used that is not just handling.

20:39 replaca: KirinDave: actually, you are explicitly forcing the seq: you call next

20:39 you're just so used to that that you don't consider it

20:39 KirinDave: replaca: Well, the stdlib supports that very aggressively.

20:39 replaca: yup. sure does

20:39 KirinDave: replaca: I probably have written "next" like 3 times in my clojure experience.

20:40 So delay could be the mechanism if the stdlib aggressively supported it.

20:40 It'd take an audit of the whole stdlib tho

20:41 It would also make clojure.lang.Delay the Invisible Man of the clojure library. :)

20:41 Because then #(class (delay 1)) would not be what people think it would be.

20:41 Derp, why'd I write #?

20:41 replaca: yeah, the decision about when to force is tough too. For how long to you jest keep all the dependent computions deferred and then do it.

20:42 Very much like Haskell when you drive it as far as you can

20:42 KirinDave: Yeah. That's why it'd need compiler support too.

20:42 Yeah, which would be nice.

20:42 I worry I am coming around to haskell.

20:42 I don't want to. I love the lisp legac.

20:42 s/c$/cy/

20:43 ha

20:43 replaca: See I'd rather go with Haskell if I could convince myself it would be anywhere close to as productive as Clojure

20:43 KirinDave: I suck.

20:43 replaca: That is the issue, isn't it

20:43 replaca: KirinDave: completely. and I don't think that even being close is possible

20:43 KirinDave: but you can do some cool stuff

20:44 KirinDave: but these days I can't convince myself to write in any other language than Clojure

20:44 KirinDave: of course, I lack your appreciation for C#

20:45 :)

22:30 ossareh: how would you improve this? (reduce (fn [acc x] (assoc acc (clojure.contrib.string/as-str (first x)) (second x))) {} {:k "k" :v "v"})

22:30 I feel like there is a smarter way to do this - I just don't know enough of the stdlib to know what I should be mapping

22:31 brehaut: ossareh well to start you could desctructure your args

22:31 (reduce (fn [acc [k v]] (assoc acc (clojure.contrib.string/as-str k) v)) {} {:k "k" :v "v"})

22:32 ossareh: (reduce (fn [acc [k v]] (assoc acc (clojure.contrib.string/as-str k) v)) {} {:k "k" :v "v"})

22:32 ah

22:32 heh

22:32 :)

22:36 chouser: what does as-str do again?

22:36 brehaut: Like clojure.core/str, but if an argument is a keyword or symbol,

22:36 its name will be used instead of its literal representation.

22:36 chouser: ,(name ":k")

22:36 er

22:36 & (name :k)

22:36 sexpbot: ⟹ "k"

22:36 chouser: & (name "k")

22:36 sexpbot: ⟹ "k"

22:37 chouser: like that?

22:37 brehaut: apparently so

22:37 ossareh: huh, didn't know about name

22:37 thanks for that

22:37 saves me a (use) :)

22:38 chouser: it wasn't always that way

22:39 ossareh: damn straight. I started just over a year ago and it was hard back then.

22:39 you core people have nailed it, thanks chouser et al.

22:41 chouser: ossareh: you really want a map with keys matching the values?

22:43 ossareh: chouser: {:foo "bar"} => {"foo" "bar"}

22:43 chouser: ah

22:43 &(let [m {:k1 "k2" :v3 "v4"}] (zipmap (map name (keys m)) (vals m)))

22:43 sexpbot: ⟹ {"v3" "v4", "k1" "k2"}

22:43 chouser: not really any better

22:43 ossareh: form-dot-clj gives you :keywords, expects strings back.

22:44 I know so little about zipmap - I prefer readability of the reduce solution.

22:44 * chouser nods

22:47 chouser: & (apply conj {} (map (fn [[k v]] [(name k) v]) {:k1 "k2" :v3 "v4"}))

22:47 sexpbot: ⟹ {"v3" "v4", "k1" "k2"}

22:48 brehaut: chouser, is there an advantage to using apply conj over into there?

22:48 chouser: no!

22:48 use into

22:48 & (into {} (map (fn [[k v]] [(name k) v]) {:k1 "k2" :v3 "v4"}))

22:48 sexpbot: ⟹ {"k1" "k2", "v3" "v4"}

22:48 chouser: slipped my mind

22:54 brehaut: i wonder how common that pattern of (fn [[a b]] [(fun-a a) (fun-v b)]) is

22:54 seems like it would be common enough to have something like (vec-apply fun-a fun-b)

22:55 that is the mutant offspring of juxt and vec

23:03 Raynes: chouser: You? Making a mistake? Surely not!

23:09 I must alert the Higher Order.

23:10 ossareh: lol @ ^

Logging service provided by n01se.net