#clojure log - Aug 05 2011

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

0:01 scottj: flazz: I don't know, (= (Foo. 1) (Foo. 1)) works

0:02 amalloy: flazz: = works. but as always, reconsider whether you need records or a plain hashmap would do

0:02 technomancy: amalloy: I bet there's a better name for haskell's juxt if you use latex

0:04 amalloy: everything looks better with some latex

0:49 Generic_Dumbass: i followed the steps on this page and got "1.2.0 MASTER SNAPSHOT" on my Ubuntu rather than 1.2.1, bummer http://riddell.us/ClojureOnUbuntu.html

0:54 amalloy: clojurebot: blog posts?

0:54 clojurebot: make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive

0:54 amalloy: hiredman: dang it, teach this bot about blog posts

0:55 Generic_Dumbass: blog posts get out of date quickly. once you have clojure installed, please do not write a popular blog post about how you made it work

0:55 clojurebot: lein?

0:55 clojurebot: lein is http://github.com/technomancy/leiningen

0:55 amalloy: go there instead

0:55 Generic_Dumbass: Lol, ok, I won't

0:56 Thanks

1:11 kephale: is there a way to have arrays of hash-maps? i need indexed access of an array of maps

1:16 oh object-array… derr

1:19 amalloy: kephale: vectors have fast indexed access too

1:19 arrays are mutable and thus a tremendous pain

1:37 tomoj: lobotomy: if you make any progress on that puzzle problem I'd love to hear about it :)

1:38 some math problems cause me to stay up all night scribbling, this is one. but don't have any more time to think about it now

1:42 amalloy: tomoj: what problem is that?

1:43 tomoj: representation of happy cube shapes for a solver

1:43 http://happysolver.sourceforge.net/

1:43 I was just thinking about shapes in a 3d grid, though, ignoring the representation of the ragged edges

1:44 CodeWar: in hour 1 of clojure ... dumb question ... can I receive an arbitrary String Buffer containing Clojure code and execute it?

1:45 tomoj: ..receive from where?

1:45 CodeWar: tomoj, ideally off a socket

1:45 tomoj: :(

1:45 CodeWar: *from

1:45 tomoj: who's on the other end?

1:46 CodeWar: I d like to pass code as data .. sender queues code moves on ... receiver(s) load balance receive code execute

1:47 right now receivers have certain Java objects setup and we use JMS messages to ivnoke them .. I m wondering

1:47 if with clojure we dont need to setup these Java objects as receivers instead ship the code directly

1:47 tomoj: it's possible

1:47 CodeWar: YES!!

1:47 and I don;'t have to ship .CLASS files right?

1:47 tomoj: uh

1:48 if you need any AOT features you have to compile it

1:48 CodeWar: well ok receiver can be expected to have some libraries

1:48 whats AOT?

1:48 tomoj: like gen-class, which generates java classes

1:48 if you eval it at runtime it won't do anything

1:49 you have to compile it Ahead Of Time

1:49 CodeWar: fair enough so you ll receive text .. compile generate class and execute it... fine!!

1:49 tomoj: eval is the key, by the way, but I'm almost reluctant to tell you

1:49 CodeWar: We can setup a code cache to avoid regenerations

1:49 tomoj: it seems unlikely that that is a reasonable thing to do

1:49 CodeWar: ok whats the catch

1:50 tomoj: but what you are talking about sounds more complicated than I feel qualified to advise about

1:50 CodeWar: our stuff is needlessly complicated.... yes

1:51 but my take home is that I can ship code as data have the receiver compile and run .. sure it can throw exceptions if it doesnt like xyz

1:51 tomoj: hmm

1:51 I guess, just really try to think of a way to do something without eval before using eval

1:51 in general

1:51 CodeWar: why so

1:51 tomoj: if you're writing a repl you don't have to think about it

1:52 eval can just be used to do terrible nasty things I guess

1:52 but if your thing is not terrible and nasty..

1:52 CodeWar: tomoj, I m in hour 1 of clojure .. quickly whats eval and REPL

1:52 tomoj: read-eval-print-loop

1:52 CodeWar: meaning what exactly

1:52 tomoj: &(class '(+ 1 2))

1:52 lazybot: ⇒ clojure.lang.PersistentList

1:52 tomoj: &(eval '(+ 1 2))

1:52 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

1:52 tomoj: oh, duh

1:52 CodeWar: ah ok .. interpreter right?

1:52 tomoj: it returns 3

1:52 CodeWar: interpret and run

1:53 tomoj: do you have a repl running?

1:53 CodeWar: no I dont .. just found out what it is

1:53 you were tellign me about eval .. and why its bad ... please continue

1:53 tomoj: so just reading about clojure so far?

1:53 CodeWar: yes

1:53 read the code-as-data part and my lights went on

1:54 we re evaluating writing a query language but if clojure works in sending code as data and it runs on top of JVM and has these libraries heck why not

1:57 ok googlling it seems its not eval but (eval (read-string ...)) that I want

1:57 tomoj: are you generating this code on the fly?

1:58 or do programmers write it ahead of time?

1:59 CodeWar: programmers pul it out of their ass and submit .. server/receiver doesn't know how he gets it

1:59 my goal is to let client.submit(code-as-string) do a basic syntactic check and pass the string over to server

1:59 tomoj: ah

2:00 sounds like hell

2:00 for the programmer I mean

2:00 CodeWar: well these are SQL programmers used to queries ..

2:00 tomoj: now they're getting clojure exceptions back

2:00 guarantee they're not going to be happy about them :)

2:00 CodeWar: we re threatening to give them another query language .. instead clojure looks much more complete

2:01 what exceptions?

2:01 tomoj: if they make any mistakes, attempting to eval the code will cause an exception to be thrown

2:01 CodeWar: tell me this .. can I take an arbitrary string and do basic syntactic test on it without executing it?

2:01 tomoj: yes

2:01 but that doesn't guarantee that the code will run without throwing an exception

2:01 CodeWar: perfect.. I d like clients to do this before submitting ...

2:01 yes yes understood

2:01 tomoj: ..or successfully compute the intended result

2:02 CodeWar: syntax check means they dont submit Harry Porter

2:02 tomoj: I never want to have to debug clojure I can only run by submitting to some external clojure

2:02 er, external server

2:02 well..

2:02 no

2:02 &(read-string "Harry Porter")

2:02 lazybot: ⇒ Harry

2:02 CodeWar: You let me worry about that .. what we have in place is worse than that so :-)

2:02 tomoj: "Harry Porter" is valid lisp code

2:03 CodeWar: &(read-string "(Harry Porter)")

2:03 lazybot: ⇒ (Harry Porter)

2:03 CodeWar: sh*t

2:03 tomoj: that's going to try to call a function called Harry and throw an exception

2:06 amalloy: CodeWar: tomoj is trying to tell you not to use eval, but he's also trying to be polite. if you like, i can tell you that using eval for this is nutso crazy

2:07 CodeWar: amalloy, thanks I need brutal answers .. it will save me hours/days later

2:07 amalloy, are you opposed to the idea or the idea of using clojure for it

2:07 tomoj: yeah, I think it's crazy, but I only think that because I've heard so many people say eval is evil

2:07 I never bothered to think about why really

2:07 amalloy: "code is data" in lisps generally refers to the ability, through macros, to construct code out of data *at compile time*

2:07 (if you prefer, "manipulate code like data"

2:08 MasseR: amalloy: That's actually quite difficult to grok :D

2:08 amalloy: you absolutely can use eval for this, and it would be far from the worst use of eval i've ever heard of, but it would be a lot more work than "we'll just send code over the wire and all our dreams will come true". another approach will be easier

2:09 CodeWar: amalloy, how about a simple examlpe to illustrate the do-es and don'ts of taking code-as-data principle

2:09 amalloy, there is not another approach.. currently Java and C programmers use builder pattern to prepare a command buffer which is shipped and executed on the server

2:09 amalloy: sounds great

2:10 CodeWar: yes it givse them a DSL but limited in ability ... in reading clojure it appears if the promise of code-as-data is true

2:10 then I can give them a DSL with conditionals / loops / macros / expansions

2:11 zvrba: unfortunately, "code is data" does not enable self-modifying code :(

2:11 tomoj: maybe they can just submit jars, like hadoop?

2:11 then they can run and test the clojure code on their machine

2:11 CodeWar: is that what hadoop does ... submit entire jars? ;-) well yes that is a possiblity

2:11 zvrba: btw, is clojure an interpreter or compiler?

2:11 amalloy: zvrba: clojure is none of those things

2:11 it is a language

2:11 tomoj: don't necessarily have to have all the code needed at runtime in the jars they submit either

2:11 zvrba: amalloy: but its implementation?

2:12 CodeWar: well its a bit more complex than that but I can explain how the server side works if folks are interested..

2:12 zvrba: amalloy: does it interpret S-exprs directly or does it compile them to some bytecode?

2:12 amalloy: it is compiled, at the moment, but so what? you could write an interpreter

2:12 zvrba: i could, but it's not feasible.

2:12 hiredman: compiler, which in some limited cases for interactive use it interprets

2:13 https://github.com/hiredman/Arkham

2:15 CodeWar: hiredman, not sure if this is relevant for me but *eval is evil* aside I m trying to understand the feasibility and then try to appreciate the real life problems of ..

2:15 <a> compiling arbitrary user passed in string <b> shipping the compiled form of <a> <c> executing <b>

2:16 zvrba: CodeWar: the problem is that the user can pass a string that will format your hard drive.

2:17 CodeWar: for example.

2:17 amalloy: CodeWar: one example of how this can go wrong, presuming you're smart enough not to expose this api to the public and create "clojure injection vulnerabilities"

2:17 CodeWar: security is a nightmare ... point noted and respected .. enxt

2:17 *next

2:17 zvrba: CodeWar: or copy all your private files to some server.

2:17 amalloy: even your best-trusted engineers will make mistakes and, for example, bring the server to its knees by accidentally sending it a fork bomb or a memory leak or...

2:17 CodeWar: zvrba, or empty my ex gfs bank account .. understood

2:18 zvrba: CodeWar: or download CP.

2:18 amalloy: CP?

2:18 oh

2:18 zvrba: child porn

2:18 CodeWar: zvrba, these are all virtualization problems not language problems .. any language can and crap things .. next problem please

2:18 zvrba: CodeWar: well, yes, with a proper sandbox you can limit what resources are available.

2:19 amalloy: CodeWar: the point is that these are neither language problems nor virtualization problems. they're problems you introduce by your "algorithm", which is "let other people supply the algorithm"

2:19 CodeWar: what he can or cannot do is meant to be checked by OS / virtualiation layer and other sandboxing layers not give the programmign language a tough time

2:19 amalloy, point noted ...

2:20 zvrba: CodeWar: but how do you prevent the user-supplied code from modifying the rest of your program's logic?

2:21 CodeWar: zvrba, you submit a stringbuffer which *is* your program ... if it doesnt throw exceptions generate runtime errors it may succeed

2:21 hiredman: if the clojure compiler had more hooks to guide compilation it would be easier to sandbox clojure code

2:21 CodeWar: succeed here means side effects of program on server data are globally visible

2:21 zvrba: CodeWar: but that code executes in some larger context? how do you prevent it from modifying it?

2:22 CodeWar: hang on let me write some pseudo code .. the bulk of logic is not in clojure its in primitives

2:22 hiredman: *shrug* there are things you can do

2:22 ataggart: has anyone here successfully done anything in the repljs? I get errors for every little thing.

2:23 hiredman: I may even start allowing defs in clojurebot, given that it runs sandbox code in a seperate clojure runtime now

2:24 so sandboxed code would have to try pretty hard to alter the clojure runtime that is actually executing clojurebot

2:24 ,*clojure-version*

2:24 clojurebot: {:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"}

2:24 CodeWar: http://pastebin.com/0AP6UJF7

2:24 hiredman: (clojurebot is running under 1.2)

2:25 CodeWar: I only need clojure as a glorified DSL ... with loops conditionals and variables .. no real code or function calls will happen there

2:25 we expose atoms and tiles for real code and its memory and until (transact ...) succeeds side effects are not globally visible

2:26 but what I m taking away from here is .. its probably better to execute clojure on the client have it spit out the command buffer then ship commandbuffer .. only problem is now I ll need to write my own command buffer interpreter on the server

2:27 zvrba: i guess it would be possible to write a macro that parses a DSL

2:27 or returns an empty list on error

2:27 CodeWar: and generates the command buffer... soudns pretty good

2:27 perhaps I could do that in LISP ... I dont really need JVM here

2:28 well I have truly 4 functions .. serial concurrent wait stream .. I d like to use the language to actually invoke these cals on the server

2:29 else I ll have to write my own command buffer interpreter

2:30 guess while explaining the problem I answered my own queries ... 4 commands write your own interpreter .. let cleints use Java/C builder pattern to generate cmd buffer

2:30 amalloy: CodeWar: writing a DSL intepreter is just Not Hard

2:30 CodeWar: yes

2:31 I ll start with a switch statement and see where I go from there thanks everybody

3:03 lobotomy: tomoj, i have already solved the happy cube probem ;)

3:03 but that was in java... the clojure version will look rather different, for obvious reasons

3:03 (haven't had time to proceed with that yet)

3:05 tomoj: oh, right, you already figured out the part I'm stuck on

3:06 how do you represent a target shape?

3:06 lobotomy: at which level?

3:07 tomoj: hmm.. so you're filling in faces of the shape, you need to know which faces in the shape are open, and for a given face, which other faces you need to check for edge compatibility

3:07 at that level I guess

3:09 or do you cut the problem differently

3:09 lobotomy: the user at first gives a bunch of 3-d coordinates that define where the shape extends to

3:09 e.g. [0,0,0], [0,0,1], [0,1,0] is an L kind of shape

3:10 then i loop through those, constructing a basic cube at each point, and merging it with the existing structure, linking the edges together and eliminating redundant edges

3:10 also i keep track of holes, eliminating redundant ones; a Hole is basically a collection of 4 MutableEdges

3:12 tomoj: so the only shapes are multiple cubes stuck together?

3:12 lobotomy: hmm... there's not really a shape; there's just a "graph" of sorts consisting of MutableEdge objects

3:12 tomoj: right, I mean..

3:12 lobotomy: anyway, every possible shape for the arbitrary case is basically "cubes melded together"

3:13 tomoj: the only structures you ask the thing to solve for are multiple cubes

3:13 no faces can be missing or something

3:13 lobotomy: hm, you mean you want to also solve for e.g. a "double decker" structure, but with the top piece missing?

3:14 tomoj: I don't, but I was thinking of the problem that way

3:14 representing arbitrary collections of faces in a grid really

3:15 lobotomy: yeah, some other kind of representation might be better for this, i haven't really explored it that much

3:15 clojurebot: amac: So it's a seq of connections? And what do you do with them? I understand what disjoined sets look like, but the representation and iteration is where I run into trouble.

3:15 tomoj: how about a 2x2 cube with nothing inside?

3:15 oh

3:15 that's just 8 cubes and you remove the guts?

3:15 lobotomy: yeah

3:16 tomoj: oh, hmm

3:16 lobotomy: consider the double decker; it's just two cubes, with the two holes in the middle removed, redundant edges removed, the appropriate edges linked together

3:16 tomoj: I didn't think well about it :)

3:16 I thought you could have two cubes stuck together with the inside face included

3:17 looking at the pieces it is obvious that isn't possible

3:17 lobotomy: building the arbitrary structures was by far the hardest part of this. took me months to get it correct (well, i wasn't working on it full time, but still). debugging was quite hilarius ;)

3:17 tomoj: wait.. could it be??

3:17 lobotomy: hey, you could have the piece in the middle be halfway inside one cube and halfway inside the other ;)

3:18 amalloy: clojurebot: wow, well done on the contribution so on-topic i thought it might be someone else saying it

3:18 clojurebot: I'll be in the brig with a bottle

3:19 tomoj: basically can you build two cubes with one missing face which fit together?

3:19 er, no

3:19 lobotomy: you could, but isn't that more demanding?

3:19 for each five-piece cube with one missing face: find all other five-piece cubes with missing faces that happen to fit it

3:20 instead of just a simple dfs on the whole thing

3:21 well, if you want the dfs to find every solution, then that'll take the same amount of time as the previous idea, but... ;)

3:21 tomoj: I mean can you build a six-piece cube where one face has spots left open

3:21 by using pieces that don't really fit together

3:22 I am going to have to buy some of those..

3:24 lobotomy: hahah, this indeed demands that you have a set of the physical cubes, otherwise it's so much less fun ;)

3:37 MasseR: Damn, I still haven't grokked the (ns syntax :/. I get 'Don't know how to create ISeq from clojure.lang.Keyword' when trying to (ns foo.bar.baz :use ['foo.hello])

3:38 amalloy: two mistakes there, i'm afraid

3:38 MasseR: why don't you pick an open-source project (doesn't matter which) and compare their ns forms to yours?

3:39 Generic_Dumbass: So (rem 1 4) is 1, and (/ 1 4) is 1/4. What operator gives 1 / 4 = 0, equivalent to what Python outputs?

3:39 MasseR: amalloy: Even that would be overkill. I have somewhere in my harddrive examples, loads of them. Rather I'm trying to learn by making mistakes :)

3:39 amalloy: Generic_Dumbass: i think that's the "use shitty math" flag

3:39 lobotomy: ,(int (/ 1 4))

3:39 clojurebot: 0

3:40 amalloy: &(quot 1 4)

3:40 lazybot: ⇒ 0

3:40 Generic_Dumbass: facepalm. thanks

3:40 tomoj: MasseR: (doc ns)

3:40 amalloy: tomoj: man, the ns docs suck

3:40 tomoj: the example there corrects your first mistake

3:40 amalloy: ~ns form

3:40 clojurebot: Don't bash in place

3:41 amalloy: ...

3:41 tomoj: also, you don't quote things inside ns like you do when calling use/require/etc directly

3:42 MasseR: tomoj: The problem was/is that I don't really know what I'm doing (yet). Meaning that I can't see the difference between a function that takes keywords and arguments, compared to function that takes evaluated arguments

3:42 tomoj: ns is a macro

3:43 it gets to decide what to evaluate and what not to

3:43 it doesn't evaluate anything though

3:43 MasseR: Which doesn't make it easier to reason :D

3:43 tomoj: at least, I don't think it does..

3:44 sure, but at least (doc ns) doesn't contain any '

3:44 leonid: ,(doc ns)

3:44 clojurebot: "([name docstring? attr-map? references*]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class .....

3:44 MasseR: "except the arguments are unevaluated and need not be quoted"

3:45 Somehow it seems now plain as day, compared to last week when I checked from clojure api docs o.O

3:45 tomoj: the use/require docs are hard to understand at first

3:45 but as it says each arg is either a lib name or prefix list or flag

3:45 raek: clojurebot: ns form |is| http://blog.8thlight.com/articles/2010/12/6/clojure-libs-and-namespaces-require-use-import-and-ns

3:45 clojurebot: Roger.

3:45 tomoj: huh

3:46 (use [foo]) actually works though

3:46 er, (use '[foo]) :)

3:46 raek: yeah, zero options

3:46 (use '(foo)) is different

3:47 zero namespaces starting with the prefix "foo"

3:47 tomoj: oh, right

3:47 s/lib name/libspec/

3:53 amalloy: raek: the thing is, i know technomancy taught him about the ns form already. but i can't ever say the right words to get clojurebot to say what he's learned

5:40 wjlroe: I'm trying to set SSL options to be used by Leiningen (for deploying artifacts and downloading dependencies), and this hook in init.clj isn't working: https://gist.github.com/1127209 Anyone know why I get that error?

6:15 ejackson: I think I have found a bug in clojure.test where the report multimethod is not declared dynamic, and hence libaries such as clojure.test.junit, which rebind it, don't work. Anybody have time to give it a quick glance ?

6:35 jsankey: ejackson: see http://groups.google.com/group/clojure-dev/browse_thread/thread/232e2a080a932520/b29528df06b580f7

6:36 ejackson: jsankey: cool, thanks.

7:01 ordnungswidrig: hi

7:01 duke39: 'ello

7:02 ordnungswidrig: I'm looking for a simple RPC lib in clojure.

7:32 jonasen: I'm struggling with macros in clojurescript. Where should I put my macros so that they are available to my cljs scripts? I'm compiling my project with 'cljsc src/ > app.js'?

7:32 chouser: jonasen: you need to use :require-macros in your .cljs file's (ns ...)

7:33 jonasen: chouser: I have that. but I keep getting FileNotFoundExceptions. It's a classpath issue I think

7:34 chouser: ah, sure.

7:35 jonasen: chouser: also, I think the docs are wrong as they say :refer-macros instead of :require-macros

7:36 chouser: I put my foo.clj in the same dir as my foo.cljs

7:39 jonasen: chouser: That don't seem to work for me.

7:57 chouser: my foo/bar.cljs has (:require-macros [foo.bar :as fb])

7:57 then I use macros from foo/bar.clj like: (fb/mymacro ...)

7:58 I don't think I'm doing anything else worth noting.

7:59 jonasen: and you can compile it with cljsc?

8:21 JochenR: question: is there a way to catch multiple exceptions in one clause like in new java 7

8:23 like (try ... (catch [ExA ExB] e (dosomething e)))

8:24 Vinzent: btw, what do you think about binding *error-handler* and "pushing" it to stack instead of try\catching? is there any libs using this approach?

8:25 JochenR, not with standard try\catch, i think

8:25 jonasen: chouser: Here is a gist of the problem https://gist.github.com/1127420

8:26 JochenR: hmm, is it possible to expand a macro to multiple forms

8:28 Vinzent: no, you should wrap the outer form in your macro

8:28 JochenR: (would allow a kind of catch* macro to generate multiple catch clauses))

8:28 raek: JochenR: let it expand to a do form

8:28 (catch ...) is not macroexpanded

8:28 JochenR: raek: I believe catch-es will only work on top level below try

8:29 Vinzent: JochenR, you need try* as well

8:29 JochenR: Vincent: looks like you are right :-(

8:29 raek: what Vinzent said. :) try is a special form and defines the meaning of catch, which does not exist on its own

8:29 ,catch

8:29 clojurebot: raek: Titim gan éirí ort.

8:29 Vinzent: (but I believe it's already done, try googling for try+ (can't remember the name of that lib...))

8:30 JochenR: I tried to google, but try and catch are not very unique terms :-)

8:31 raek: I made a lib that has a try+ form, but I dunno if that's the one you are thinking of

8:31 JochenR: ah try+, found it. Thanks Vinzent!

8:31 raek: is this yours at github/scgilardi?

8:32 raek: no, I'm "raek" at github too

8:33 JochenR: thanks a lot, will check it out!

8:35 Vinzent: raek, so, when you was writing that lib, you thinking about bindable hanlder instead of usual try\catch?

8:35 MasseR: \o/ My programming clojure book came in today

8:36 Vinzent: it looks more functional and allows to pass context easily

8:39 raek: Vinzent: no, I just wanted a way to define new "exceptions types" in Clojure

8:39 a condition system like error-kit would be more nice

8:40 kephale: amalloy: long delayed reply W.R.T. array v vector, is there a better way to set the value at an index in a vector than the concat based techniques? i'm porting an experiment that is mostly "random-access" R/Ws to a 40,000 element collection. it is the kind of thing that would normally make me consider wrapping some java code. i've had some issues in the past with using vectors in such situations

8:40 Vinzent: MasseR, congrats! :) is it halloway's book or the new one? (they have very similar names, always mixing them up)

8:41 raek, ah, ok

8:41 MasseR: Vinzent: Sorry, I'm horrible with peoples names :D

8:41 I doubt I've even read who wrote it

8:41 raek: kephale: assoc

8:42 vectors are built to support random access updates

8:42 ,(assoc (vec (range 10)) 5 100)

8:42 clojurebot: [0 1 2 3 4 ...]

8:43 raek: ,(assoc (vec (range 10)) 4 100)

8:43 clojurebot: [0 1 2 3 100 ...]

8:43 kephale: raek: oh…. i should have known that… thanks!

8:44 raek: concat does not work on a data structure directly, but on a sequential view ("sequence") of the data structure (which you can accuire by calling seq or rseq on it)

8:44 Vinzent: btw, why assoc works on vectors, but dissoc doesn;t work?

8:44 raek: Vinzent: vectors don't allow "holes" in the index range

8:44 but you can dissoc the last element, I think

8:45 ,(dissoc [0 1 2] 2)

8:45 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap>

8:45 Vinzent: no, I mean this behaviour: (dissoc [1 2 3] 0) => [2 3]. it may be implemented with subvec

8:45 kephale: hrm… although not now, i do need dissoc in a similar situation

8:45 now that Vinzent brought it up, that was the situation where concat was a huge slowdown

8:45 raek: Vinzent: that operation is not possible to do efficiently on a vector the way they are structured

8:46 you need to rebuild the internal tree for all the elements after the one you want to remove

8:46 Vinzent: raek, but subvec calls is O(1)

8:47 raek: I was thinking of the general case of removing one element in the middle

8:47 but I'm not totally sure how subvec is implemented

8:48 kephale: i've had an issue with a 10,000 element collection that needs 1,000 elements removed

8:48 raek: kephale: so why do you need to remove them by index?

8:48 kephale: in code that is agent based, so the removing process turns out to be really expensive since the elements to be removed aren't contiguous

8:49 raek: kephale: would (vec (filter predicate the-vector)) work?

8:50 kephale: raek: not really, the process goes like: grab 7 random indices, compare the values of a key, remove element with the minimum

8:50 raek: hrm

8:50 a set is better if you easilly want to remove an element

8:51 bu then you need to be able to pick some random elements

8:52 kephale: raek: good point about sets, i'm going to have to check to see if that would work

8:53 raek: if you somehow can get 7 random elements from a set, I don't think you need vectors and indices at all

8:54 kephale: i am thinking a clever predicate for select might work for getting hte random elements

8:54 the*

8:57 depy: Guys.. I heard that in lisp (clojure) you shape the language so that it solves the problem better not like in OO where you shape the problem so you can solve it with OO

8:58 but, haven't seen any good sample/program that would show this style.. any suggestions where to look?

8:59 ordnungswidrig: depy: practical common lisp has a section about this where the author is "deriving" a unit test library.

8:59 depy: it's not clojure but easily translatable

9:00 depy: http://amzn.to/qI3oQk

9:01 depy: which chapter? :)

9:03 Hodapp: OO is like violence. If it doesn't work, you just need more of it.

9:04 ordnungswidrig: Hodapp: *g+

9:04 Hodapp: bah?

9:04 depy: I mostly agree with you. but it's the most popular so it's gonna stick with us for a while ...

9:04 ordnungswidrig: depy: chapter 9, page 103++

9:05 depy: thank you!

9:05 ordnungswidrig: Hodapp: I mean't "*g*"

9:06 Vinzent: depy, you can take a look at compojure syntax, or cgrand's moustache (and enlive), or clojureql, also try googling "clojure binary files parsing" (or something similar) - there is small example of building sort of DSL on top of the java api

9:07 depy: Will do that...

9:08 Havent really found time to learn clojure properly.. Gotta do the diploma first :/

9:09 wjlroe: This is crazy - every time I try to compile something on Linux that uses a Java library, `lein compile` just hangs doing nothing

9:11 Hodapp: depy: It is interesting to see, though, how OO has varied so much from its original instantiation by Alan Kay.

9:12 depy: Don't know much about that I must say.. ^^

9:12 Hodapp: Look it up sometime. He wrote extensively on it.

9:13 depy: Will do

9:14 jcromartie: depy: another good book is SICP

9:14 http://mitpress.mit.edu/sicp/

9:14 Hodapp: I need to read SICP

9:14 jcromartie: depy: it gets into the kind of composition and abstraction that really works well in Lisp

9:15 and concepts like closure (not anonymous functions) of a set of functions over their inputs

9:15 combine that with macros that fit your problem, and you get pretty close to a "sweet spot" as you can get in any language

9:15 Hodapp: I was going to use the 1986 videos with Sussman and perhaps lead a group through SICP with me

9:15 but that's a big time investment

9:15 jcromartie: yea

9:15 depy: But it's surprising how many people still write procedural code. I'm Java programmer and I have 4 coworkers that use php. And most of the code they wrote is still more like procedural than OO.

9:16 jcromartie: depy: I think it's the default for people to think in steps

9:16 depy: I agree

9:16 jcromartie: and I make full use of let bindings to do the step-by-step sort of stuff where it is simple

9:16 depy: Hodapp I'm waiting for Clojure SICP to be finished.. :P (bad excuse actually)

9:17 Hodapp: depy: psh :P

9:17 jcromartie: depy: yes, bad excuse... Racket is nice!

9:17 Hodapp: I wonder how well SICP could be adapted to Clojure

9:17 jcromartie: Hodapp: it would be pretty simple

9:17 edw: depy: I would guess that an inexperienced procedural programmer might make less of a mess than an OO one. Playing with a knife vs a shotgun...

9:17 dnolen: I think that SICP in Clojure wouldn't be very useful IHMO

9:17 Hodapp: dnolen: Why's that?

9:18 dnolen: SICP is not that functional, you'll be fighting an uphill battle once you get the parts that involve state.

9:18 depy: There's SICP book for clojure in progress I think

9:18 MasseR: The link was in here yesterday

9:18 depy: http://sicpinclojure.com/ <-

9:18 jcromartie: SICP doesn't introduce assignment for a while, and when it does I think atoms would be fine

9:18 dnolen: Scheme and Clojure are different enough that it will be very frustrating

9:19 ambrosebs: dnolen: that was my first reaction

9:19 Hodapp: hmmm

9:19 ambrosebs: scheme is so simple

9:19 edw: Most people's minds get blown way before the non-functional parts of SICP. And Clojure isn't some Haskell-like state-hater of a language.

9:19 jcromartie: and once they get to assignment, they go on to streams and it's back to functional style

9:20 section 3.3 introduces modeling with mutable data. 3.4 addresses concurrency, and 3.5 introduces infinite lazy sequences of inputs that map to outputs as a better way to manage state

9:20 the rest can all be done with atoms for local state just fine

9:20 dnolen: this SICP in other languages in just baffling to me. You have an amazing easy to install Scheme - Racket, why add complexity to an already tough book.

9:20 jcromartie: yeah I'll say it again: Racket is *nice*

9:21 edw: jcromartie: Yes, SICP realizes that assignment is a Pandora's Box and reflects an intelligent, not Clojure-incompatible way of thinking about.

9:23 Hodapp: if you're going through SICP, is Racket a good Scheme implementation to use?

9:23 edw: I see Clojure as a godsend. I am a Schemer at heart trying to get stuff done in the Real World.

9:24 Hodapp: Ugh, no. Try Scheme48.

9:24 ambrosebs: edw: ah, so these people do exist :)

9:24 edw: ambrosebs: My web framework in Scheme: https://github.com/edw/magic

9:25 depy: how hard is to go from clojure to for example lisp, scheme, ... ?

9:25 or is it better to learn lisp/scheme first then go clojure?

9:25 edw: Hodapp: Scheme48 has a module for SICP-compatibility, I believe. As does MIT Scheme.

9:26 depy: I'm sorry, I missed the beginning of your conversation; what are you expeirenced with right now, language-wise?

9:26 depy: java :) and I know just a little of clojure

9:27 And I'm not very interested in scala :P

9:27 dnolen: depy: if you want to learn Clojure learn Clojure. Scheme is very much a different language.

9:27 personally I'm not much of a fan of standard Scheme outside of papers. Racket is more my speed.

9:28 edw: I think Scheme might be a nice "now for something completely different" way of getting completely away from Java Land and learning some concepts that will come in very handy for you as you program in Clojure, JavaScript, and many other languages. But I think the best way to learn Clojure...is to learn Clojure.

9:28 Vinzent: depy, I think it's better to learn java (if not already), then go to clojure :)

9:28 depy: I know java.. :)

9:28 So Clojure then... :)

9:30 edw: dnolen: I think the Racket people are fundamentally unhinged. The whole point of Scheme (and Lisp) is to keep the syntax insanity at bay, yet they've undertaken a profound pollution of Racket with a million little distinct domain-specific languages. It's insanity and a repudiation of what's appealing about Scheme and other Lisps.

9:31 ambrosebs: edw: re: web framework, I must confess I've never seen a real scheme project in the wild

9:31 facinating :)

9:32 dnolen: edw: not surprising they are language researchers. But there's a core set of functionality that is quite useable.

9:33 edw: dnolen: I hear you, but I'm reminded of a comment from the art director of Wired magazine, to the effect that you can't make progress if you don't make mistakes. My question to the art director, and to those guys down in Texas, is whether it's vitally important to publish your mistakes.

9:34 dnolen: edw: and then you have the opposite, standard Scheme which is so anemic every Scheme implementation feels compelled to reinvent data structures, concurrency constructs, all with different apis. Yuck.

9:36 edw: dnolen: I and much of the Scheme community don't disagree about the folly of a minimal, crystalline, "perfect" Scheme.

9:38 dnolen: edw: I'm sure, but the community is fractured along those lines.

9:38 edw: dnolen: With Racket, there's so much kruft that it's hard to find the useful stuff. For example, they have a datalog implementation in there, but it's extreemely difficult to figure out how to use it from Scheme because there's so much information about their pointless from-the-ground-up DSL.

9:39 dnolen: edw: I'm not in disagreement about that.

9:40 edw: dnolen: True. And that's why I've written several orders of magnitude more lines of Clojure than Scheme in the last six months. Again, I'm a Schemer trying to get by in the Real World, and I love Clojure as Clojure.

9:40 kjeldahl: On data read with table.read, I can scale a column with data$Col=data$Col/data$Col[1] (scale to 1 based on first value). On a table read with read.zoo this fails miserably, setting all rows to a constant 1. I've tried going back and forth between data.frames and zoo objects, but that fails in other ways (for me). Any easy ways of doing such operations directly on the zoo column?

9:41 Oops, wrong channel, sorry.

9:49 edw: depy: BTW, if you're interested in learning Scheme at some point, you should check out Geiser, a very appealing alternative to SLIME that works with Racket and Guile. It works inside Emacs which given your background may not be something that you're already familiar with. http://www.nongnu.org/geiser/

9:51 dnolen: Geiser is awesome

9:57 edw: dnolen: Yeah, it's what led me to give Racket another try.

9:58 depy: what's Geiser?

9:58 edw: Check out the link I posted above.

10:00 depy: I prefer vim :D

10:00 But could not get clojure plugin runnign in vim :/

10:02 edw: When Michael Schumacher asked me if I wanted to drive his car for a few hot laps, I asked if it used Bosch sparkplugs, he said no, so I declined and instead drove an '84 Taurus that did.

10:04 depy: No funny... :)

10:04 not*

10:04 edw: Sometimes tools choose you...

10:05 Even outside Soviet Russia.

10:05 * kephale chuckles

10:07 cemerick: In a world where certifiable geniuses prefer notepad, tool preference is purely cultural.

10:08 edw: Out of curiousity, who's the Notepad-using genius?

10:09 kephale: cemerick: perhaps a slightly hyperbolic statement

10:09 edw: Of course.

10:09 We are friends here. We understand.

10:10 cemerick: part making a point, part being a PITA ;-)

10:10 kephale: mmm, but when it comes down to the vim v. emacs argument, you're right on

10:11 cemerick: edw: It was someone working on/at a particle accelerator — I think the one on Long Island.

10:11 edw: cemerick: My attitude is if a tool does something you need, suck it up and learn it. I have yet to see anything for vi that rivals SLIME, which I consider a disgusting kludge that happens to work,

10:11 cemerick: Brookdale something. Anyway.

10:12 It's the "need" part that gets tricky.

10:12 edw: cemerick: A close collaborator of mine used Notepad for HTML extensively back in '99. She was one of the brightest people I've ever worked with.

10:14 cemerick: All I *need* that only Emacs provides is Paredit and good indenting in general. Is there anything else with a Clojure mode anywhere as nice as clojure-mode + paredit?

10:14 cemerick: => (= (* 2 *anecdote*) *data)

10:14 true

10:14 nice! :-D

10:14 As long as the proportion of our time that we spend typing code into the computer is low (and hopefully declining!), editor selection is a non-issue in the large.

10:14 jcromartie: edw: as far as I know, Emacs+paredit is unmatched by any other editor

10:15 cemerick: ccw's paredit impl is surely more basic, but perfectly reasonable IMO.

10:15 edw: cemerick: CCW?

10:15 chouser: cemerick: keep saying that. I want it to be true.

10:15 jcromartie: what is ccw?

10:15 kephale: counterclockwise

10:15 cemerick: ccw?

10:15 jcromartie: when people watch me code with Paredit, they are always amazed, because there's really nothing like that for editing the structure of other panguages

10:15 clojurebot: ccw is http://github.com/laurentpetit/ccw

10:16 chouser: re: typing (key bindings) being low priority

10:16 pyr: editor wars are so 1990's

10:16 cemerick: that's totally not the right link

10:16 http://code.google.com/p/counterclockwise/

10:16 clojurebot: ccw is http://code.google.com/p/counterclockwise/

10:16 clojurebot: You don't have to tell me twice.

10:16 cemerick: 'course, the github one will linger

10:16 edw: jcromartie: Yes, there's no reason there should be a similar thing for C-like langs. Splicing, barfing, slurping. I sometimes use Paredit keys while editing JS.

10:17 And then I cry a little.

10:17 When it doesn't work.

10:17 jcromartie: hah

10:17 ejackson: i violated my 'never upgrade anything - it'll just break' rule today to move up to 1.3. Ensued an upgrade of the entire toolchain. The swank etc went really nicely. Insist on getting CDT working now.

10:17 jcromartie: well Paredit has its issues with Clojure... {} doesn't work right

10:17 cemerick: I've long used the "expand selection" shortcut in eclipse/netbeans for non-lisps.

10:17 timvisher: hey all

10:17 ejackson: jcromartie: there are ways around that

10:18 edw: Oh gawd, Eclipse!

10:18 jcromartie: ejackson: I guess I could bind { to input {}

10:18 cemerick: edw: surely a sign of the coming apocalypse ;-)

10:18 timvisher: i've discovered a bug in my web app where I kick off two requests and basically end up with a bug in my implementation of shared state where I get duplicate entries that I don't want

10:18 edw: cemerick: LOL.

10:18 timvisher: i'm trying to figure out how to write a test that exposes that bug so that I can fix it and be defended from it in the future

10:19 ejackson: jcromartie: i nicked this snippet off somebody: https://gist.github.com/1127627

10:19 edw: jcromartie: { inserts a balanced pair for me. It doesn't work for you?

10:19 jcromartie: ooh nice ejackson

10:19 timvisher: do i need to get into the Executors framework or something like that or is there a simpler way to get that going?

10:19 jcromartie: edw: nope

10:19 edw: In Emacs?

10:19 ?!

10:20 jcromartie: Seriously, { doesn't work for you in Emacs+clojure-mode+paredit?

10:20 jcromartie: nope

10:21 timvisher: jcromartie: what's your mode line read like?

10:21 edw: How old is your Paredit? It works fine for me.

10:21 timvisher: mine (Clojure Hi Paredit hs mate o^o ws Fill)

10:21 edw: Get thee to Riastradh's ftp server!

10:21 jcromartie: [(Clojure Slime Paredit AC)]

10:22 timvisher: hmm

10:22 you appear to be in a recursive edit

10:22 does typing C-M-c remove those brackets?

10:22 edw: jcromartie: I have version 22 of Paredit. What's yours?

10:22 jcromartie: no, it raises the Debugger

10:23 timvisher: ah, perhaps C-]

10:23 jcromartie: 20

10:23 timvisher: hmm

10:23 try M-x abort-recursive-edit

10:24 i don't know why it would, but i'm wondering if recursive editing messes with your bindings

10:24 jcromartie: I'm restarting Emacs :P

10:24 timvisher: has this worked for you in the past?

10:24 jcromartie: because I've got some mess going on with my clojur emode hooks

10:24 dunno

10:25 timvisher: how did you install everything?

10:25 did you use elpa?

10:25 edw: timvisher: OMG, do you really want to hear the answer to that? :)

10:25 jcromartie: timvisher: yes

10:25 timvisher: ok

10:26 edw: to what, my original question when i got here, or to what i just asked jcromartie? :)

10:26 jcromartie: after a clean restart, with mode of (Clojure Paredit AC), { just inserts {

10:26 timvisher: cause i really want to know the answer to that. :)

10:26 what does C-h k { return for you?

10:27 for me it's bound to paredit-open-curly

10:27 jcromartie: self-insert-command

10:27 I think I need to update paredit

10:27 timvisher: well that's your problem

10:27 C-h v paredit-mode-map

10:27 liquidproof: hey guys, what's the difference between a future and an agent

10:29 jcromartie: Elpa paredit is only v 20

10:29 timvisher: have you udpated elpa to technomancy's version?

10:29 joly: liquidproof: an agent has a message queue and processes messages sent to it. A future runs a single computation. I believe their threads are pulled from the same thread pool

10:29 timvisher: are you on 23 still?

10:30 jcromartie: hm, yeah probable

10:30 timvisher: M-x version

10:30 jcromartie: Emacs 23.3.1

10:30 package-el-version is 0.9

10:30 liquidproof: joly: I see, thanks

10:31 timvisher: jcromartie: i'd work through this post: http://technomancy.us/144

10:31 that should get you going with the elpa that everyone's actually using and updating

10:32 mine's 1.0

10:32 i'm still on 23 as well

10:32 i have paredit version 22 installed

10:33 jcromartie: hm

10:33 timvisher: very strange though that the paredit.el file that is linked to in the documentation for the paredit-open-curly function doesn't actually appear to define that function, nor is it defined in paredits mode map

10:33 jcromartie: maybe time to nuke my elpa then

10:33 timvisher: i have no idea how it's working

10:33 it's possible

10:33 i believe that's what i ended up doing when i did the manual package.el upgrade outlined in that post

10:34 jcromartie: *le sigh*

10:34 package.el depends on tabulated-list

10:34 WTF i sthat

10:35 timvisher: ah, it looks like those might be generated at runtime, that makes sense

10:35 lol, that's interesting

10:36 jcromartie: I'm using this

10:36 http://emacsformacosx.com/

10:36 it looks like it doesn't have tabulated-list-mode

10:37 timvisher: well, i'm out of 'expertise' at this point, but gl. https://gist.github.com/1127670 is the exact copy of package el that i'm using

10:37 jcromartie: that's different from the one in technomancy's post

10:37 timvisher: i don't have tabulated-list-mode installed either

10:38 ejackson: jcromartie: yeah, my setup is identical

10:38 timvisher: i did download it awhile ago so it's probably different considering that technomancy linked to head

10:38 HEAD*

10:38 ejackson: and rebuilding everything today there was no mention of tabulated-list-mode

10:39 timvisher: jcromartie: is your .emacs heavily customized?

10:39 i installed the version of emacs i'm running using brew, also

10:39 don't know what the differences are there

10:39 oh well, gotta get back to work

10:39 jcromartie: timvisher: yes

10:40 ejackson: jcromartie: I pulled paredit out of elpa/marmalade

10:43 jcromartie: what's your .emacs look like, with regards to package.el?

10:43 because now I've got more issues

10:44 ejackson: nothing fancy: https://gist.github.com/1127677

10:46 jcromartie: alright I think I've got it

10:46 clojure mode, paredit, etc. all back in action

10:46 slime

10:46 yay

10:46 OK thanks guys

10:46 and { works :P

10:46 all to save me a }

10:47 ejackson: that's how it goes

11:26 dnolen: pattern matching is going to take a lot of pain out of macro writing.

11:26 paul__: hello peoples!

11:27 PPPaul: hello peoples

11:27 jweiss: is there a way to prevent the repl from deref'ing a promise object just by trying to print out an object containing one? eg, at the repl put {:hi (promise)} - i'd like it to print something like {:hi <promise$objectblahblah>}

11:28 PPPaul: i'm using lein, and i have a dir struct like: src -> transaction_migration -> import_inv

11:29 raek: jweiss: I think you can redefine the print multimethod implementation for promises or something

11:29 PPPaul: i want my ns name to be small, am i allowed to name it just import_inv, or do i have to name it transaction-migration.import-inv?

11:29 raek: I know people have done this for refs

11:29 jweiss: another solution is to set *print-level*

11:29 jweiss: raek: ok, that is what i thought, any idea what it should do to get the <> string like when it's a java object?

11:30 i suppose i could just print "<promise>"

11:30 raek: I think it does something like (format "#<%s %s>" (class x) (str x))

11:31 stuartsierra: 1.3 betas print "Pending" things as <TypeOfThing :pending>

11:31 jweiss: (str (promise)) blocks too :)

11:31 oh fun and i can't even C-c C-c out of it in slime either

11:32 raek: yeah, the .toString implementation of promises calls str on its content I think

11:33 jweiss: oh wait nvm "clojure.core$promise$reify__5542@3fa768de"

11:36 raek: jweiss: (System/identityHashCode x) should yield the number after the @, I think

11:36 jweiss: raek: how does print-method match a promise object?

11:37 not even sure where to look in the source

11:38 raek: jweiss: this seems to be the implementation: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_print.clj#L90

11:41 (defmethod print-method Object [o, ^Writer w] (.write w "#<") (.write w (.getSimpleName (class o))) (.write w ">"))

11:41 jweiss: ^ this could be a workaround.

11:41 jweiss: raek: isn't the IDeref one at the bottom the 1.3 impl?

11:41 i think i'll just use that

11:42 ah hm, no clojure.lang.IPending

11:42 oh well

11:43 i can mess with it

12:14 TallAdam: general question: I don't come from a functional background, more OO, so I keep wanting to use protocols and records to do type dispatches going back to my encapsulation/polymorphic tendencies. Am I mixing metaphors?

12:15 technomancy: TallAdam: polymorphism via protocols is not the only way to do encapsulation in clojure

12:15 stuartsierra: Protocols/records are good for polymorphism. Clojure discourages encapsulation in the data-hiding sense.

12:15 TallAdam: technomancy: go on...

12:15 mdrogalis: stuartsierra: I noticed that. Why is that?

12:15 technomancy: TallAdam: I find that there are very few things that really need polymorphism in Clojure. I'd say I've needed it maybe five times in two years personally.

12:16 TallAdam: technomancy: I know, me too, but given the tool, I am settling back into old grooves

12:16 technomancy: try using private defns and namespaces for encapsulation instead of thinking about encapsulation from the data perspective.

12:16 stuartsierra: mdrogalis: When data is hidden inside objects, you are essentially defining a new API for dealing with that particular type of data. Clojure prefers all data to be accessible through the same API.

12:17 technomancy: encapsulation should be about making it clear what parts of your API you intend to keep stable vs what's an implementation detail

12:17 it has nothing to do with coupling data to behaviour

12:17 TallAdam: technomancy: is it more performant to call the protocol multi method on a record and have it dispatch according to type, than to interrogate it and dispatch accordingly?

12:17 technomancy: or it shouldn't anyway

12:17 mdrogalis: stuartsierra: That's a very interesting philosophy.

12:18 technomancy: TallAdam: 95% sure you shouldn't think about performance at that level at all right now

12:18 mdrogalis: Hahah

12:18 technomancy: rule 2 of optimization (for experts only): don't do it. (yet.)

12:19 (rule 1 is simply don't do it.)

12:21 timvisher: anyone have a recommendation for easily creating a test that involves concurrent access to a function that changes state?

12:21 TallAdam: Another general question to the world at large: in my Aquamacs, the parenthesis gets bold font, when the cursor is over it to show the matching parenthesis (also bold), because of the size of the bold font, my whole screen moves down a pixel to accommodate. Has anyone else had this problem? its driving me nuts!

12:23 timvisher: TallAdam: M-x describe-face RET show-paren-match

12:24 in reference to my concurrent test, do i need utilize something like the Executors framework for that?

12:24 TallAdam: you can customize that face and it should get rid of your problem

12:25 or you could just use the starter kit

12:25 TallAdam: timvisher: but it is useful - are all bold faces 1 pixel bigger? I like the bold, just not the moving

12:25 timvisher: is there a starter kit for aquamacs?

12:26 timvisher: ah, i was assuming that your face specified a different height

12:26 it doesn't?

12:26 TallAdam: no - just weighrt

12:26 weight

12:26 timvisher: i'm just assuming that technomancy's starter kit works on AquaMacs. I may be making an ass of my self. :)

12:26 TallAdam: Height: unspecified

12:26 Weight: bold

12:26 timvisher: that's interesting

12:26 TallAdam: Slant: unspecified

12:26 Foreground: #7cb8bb

12:27 timvisher: i don't believe bold faces take up more height than non in vanilla emacs, but i don't know if font-handling is different in AquaMacs

12:28 technomancy: aquamacs is general is not well-supported

12:28 the most obvious reason being that it's not portable

12:29 TallAdam: ok - thanks for the help guys

12:30 timvisher: sorry for being misleading! :)

12:31 so no one's written a test for a concurrency bug lately?

12:31 ejackson: have mercy - swank.cdt is unbelievable.

12:34 dnolen: ok cl-format is awesome

12:34 (println (pp/cl-format false "~{~{~:[.~;~:*~a~]~^|~}~^\n~}" [[1 nil 4] [3 4 5] [5 6 7]]))

12:34 ,(println (pp/cl-format false "~{~{~:[.~;~:*~a~]~^|~}~^\n~}" [[1 nil 4] [3 4 5] [5 6 7]]))

12:34 clojurebot: 1|.|4

12:34 3|4|5

12:34 5|6|7

12:34 * technomancy wonders if fearsome isn't a better description

12:35 opqdonut: indeed

12:36 cemerick: write-once

12:37 ejackson: technomancy: you could go frenchie and utter a "Formidable" :)

12:37 dnolen: still better than writing pointless code for printing tables, which I want it for.

12:47 edw: Don't want to sound like a caveman, but building a OS X Emacs from source fetched from the git repo.

12:48 Err, it's easy to do so. That's what I meant.

12:52 Does CDT require 1.3?

12:53 ejackson: doubt it, but i'm using it there

12:54 edw: Thanks. Reading the docs, which dwell on 1.3, though there is a mention of the 1.2 sources in the example package docs.

12:57 Scripture: is there a version of the filter function that takes the index as an argument as well as the element?

13:14 pyr: hi

13:14 is there a way to determine a function's arity(ies)

13:14 in clojure

13:16 Bronsa: pyr: (:arglist (meta #'function))

13:33 pyr: Bronsa: thanks!

13:33 mdrogalis: ,(meta [])

13:33 clojurebot: nil

13:36 timvisher: anyone know what the simplest way to spin up 2 threads and execute a single function is in clojure?

13:36 trying to write a test to expose a concurrency bug

13:36 raek: ExecutorService.invokeAll maybe

13:37 or (doseq [f fs] (future-call f))

13:38 timvisher: future-call looks interesting

13:38 raek: or see one of the last example here http://blog.raek.se/2011/01/24/executors-in-clojure/

13:38 timvisher: i was hoping to avoid learning the Executor framework

13:39 nice blog post, though

13:39 i'll definitely put that on my reading list

13:39 i'll give future-call a spin and see if that will suffice

14:08 ibdknox: what would one have to do to add something to the classpath at runtime?

14:10 ataggart: ,(doc add-classpath)

14:10 clojurebot: "([url]); DEPRECATED Adds the url (String or URL object) to the classpath per URLClassLoader.addURL"

14:12 ibdknox: hah, that's what I get for assuming it would be complicated

14:12 thanks ataggart

14:13 ataggart: np, though bear in mind it's deprecated for a reason.

14:13 ibdknox: and that reason is?

14:13 I'm trying to rig something up to leiningen for ClojureScript

14:14 so while in general I would say using something like this would be a terrible idea, I think this might be the best solution in this case :(

14:15 technomancy: IIUC it's deprecated because you aren't always using the classloader that clojure thinks you are (if you're in an IDE or tomcat or whatever)

14:16 I don't know of anything that would cause it to break from leiningen or a bare repl

14:16 ibdknox: mkay

14:16 technomancy: thanks

14:17 ataggart: has anyone tried using the cljs repl? I was getting errors for every little thing.

14:17 ibdknox: if you use brepl, I made it *much* more resilient

14:18 ataggart: I just found it odd that (doc foo) would error out on something like "user.doc is not defined"

14:18 and is followed up by a stacktrace

14:18 ibdknox: basically any exception in the included repl kills it

14:19 ataggart: are clojure.core names no included by default? stepping through the Quick Star, it bombed on trying to require since "user.require is not defined"

14:20 ibdknox: require doesn't exist in CLJS

14:20 amalloy: ataggart: require is only supported in the ns form, as i understand it

14:21 ibdknox: https://github.com/ibdknox/brepl

14:21 ataggart: ah, so cljsc/build is meant to be required and called from the clojure repl, not the cljs repl?

14:21 ibdknox: has require

14:21 ataggart: yes

14:21 ataggart: it's little things that that that need to be made clear in the docs

14:21 thx

14:23 along with mentioning that seeing a bunch of warnings from gclosure about using "this" when running the cljsc is to be expected (assuming it *is*)

14:25 ibdknox: ataggart: hmm I suspect "this" isn't doing what you think it is

14:27 ataggart: I'm not the one using it. I was just compiling the little hello.cljs in the quick start

14:29 ibdknox: weird, I don't get any warnings

14:29 and that sample doesn't use "this"

14:31 ataggart: yes, I assumed it was in the js emitted by cljsc

14:31 are you using the latest from github?

14:34 ibdknox: ataggart: I am

14:42 ataggart: odd. I'll look into it when I get back home.

14:45 ibdknox: stuartsierra: any thoughts on potentially getting :use in ClojureScript?

14:46 stuartsierra: Why me? :)

14:46 ibdknox: haha

14:46 technomancy: to put :use in clojurescript you'd either need to give it the bad behaviour of bare-use-by-default or make it incompatible with clojure

14:46 ibdknox: rumor has it you mentioned something about doing require as a function

14:46 stuartsierra: ClojureScript is, in part, an experiment to see what we can do without.

14:46 ibdknox: technomancy: how so?

14:47 stuartsierra: I can say that I miss it, greatly.

14:47 stuartsierra: `require` as a unction would useful for the REPL, but it can only work in the REPL.

14:47 technomancy: ibdknox: in retrospect it was a mistake to make (:use foo.bar) refer all vars in bar by default.

14:47 mattmitchell: what's the right way to sort a hash-map by value... where the value is an integer and the highest should be first?

14:48 i'm using sort-by... but it comes out backwards

14:48 tomoj: there isn't any

14:48 oh

14:48 ibdknox: stuartsierra: I assume because of how goog.require works?

14:48 stuartsierra: yes

14:48 amalloy: mattmitchell: don't sort by value?

14:48 or, don't use a hashmap?

14:48 ataggart: mattmitchell: sort by values of sort by keys?

14:48 amalloy: $google clojure priority queue

14:48 tomoj: mattmitchell: it takes an extra param, comp

14:48 lazybot: [Big Dingus » Blog Archive » Finding primes with Erlang and Clojure] http://bigdingus.com/2008/07/01/finding-primes-with-erlang-and-clojure/

14:48 tomoj: mattmitchell: pass >

14:48 ataggart: s/of/or

14:48 lazybot: <ataggart> mattmitchell: sort by values or sort by keys?

14:49 mattmitchell: well, what i want is a list of keys, but sorted by their values

14:49 ibdknox: stuartsierra: even in the REPL I had to change how require writes out script tags for brepl

14:49 mattmitchell: i wouldn't use a hash for this normally, but that's what i'm getting from an outside "api" service

14:50 stuartsierra: mattmitchell: (sort-by the-map (keys the-map))

14:50 ibdknox: technomancy: I don't doubt it, but could you explain the thinking behind that?

14:50 mattmitchell: so... {:a 10 :b 2 :z 1000} => [:z :a :b]

14:50 ok i'll try that...

14:50 amalloy: stuartsierra: oh, that's much nicer than what i was thinking

14:50 tomoj: you still need the >

14:51 stuartsierra: (sort-by (comp - the-map) (keys the-map)) to reverse the order.

14:51 tomoj: :)

14:52 mattmitchell: stuartsierra: very nice :)

14:52 stuartsierra: thx

14:52 tufflax: or just (keys (sort-by val > the-map))

14:52 technomancy: ibdknox: why it's a bad idea in clojure or why it's not in cljs?

14:52 mattmitchell: thanks everybody! you're all too clever :)

14:53 ibdknox: technomancy: the former

14:53 tomoj: intuitively that seems like it would be slower than (map key (sort-by val > coll))

14:53 is it?

14:53 mattmitchell: tufflax: what is the > doing?

14:53 technomancy: ibdknox: it's easier to refactor if the dependencies between namespaces are explicit

14:53 tomoj: tufflax: whoa

14:53 amalloy: tomoj: you think (map key x) is faster than (keys x)? that seem unlikely

14:53 mattmitchell: tufflax: works perfectly... just curious

14:53 tomoj: amalloy: no, all the value lookups

14:53 tufflax: mattmitchell it's the comparator

14:54 technomancy: there are exceptions (useing clojure.test in a test or using the implementation from the test namespace) but it's a bad deafult

14:54 mattmitchell: ahh ok

14:54 nice

14:54 tomoj: amalloy: instead of just getting paired kvs directly from the map

14:55 tufflax: I never knew keys called seq on its arg

14:55 tufflax: i didn't either until a few moments ago

14:56 ibdknox: technomancy: are you opposed to having :use with bare-by-default in cljs?

14:57 redline6561: Hey. Just saw the discussion of Ring 1.0. I'm curious, did anything ever come of the async work? I know there had been some cross-pollination with aleph...

14:58 technomancy: ibdknox: I don't care either way for cljs, but it seems like cljs may be a good place to experiment with a use replacement that could then be ported to clojure

14:58 stuartsierra: yes

14:58 technomancy: it's easier to experiment with things like that in cljs since there isn't such an expectation of stability there

15:00 ibdknox: fair enough

15:00 tomoj: is there some reasonably sane way to implement partition with reduce

15:00 amalloy: tomoj: not lazily, of course

15:01 tomoj: I can see the basic idea but feel like I want deques

15:01 opqdonut: no, not really

15:01 tomoj: oh, no need for laziness

15:01 ..and I only need step=1

15:03 technomancy: I'd be happy if :require supported a :refer [x y z] that worked exactly like :use's :only. then :use could be deprecated and nothing would break.

15:03 ibdknox: technomancy: that'd work for me too

15:03 technomancy: but this whole issue is subject to staggering amounts of bikeshedding

15:03 everyone wants to get their say in

15:03 ibdknox: haha

15:04 I just want something that works

15:04 having to alias *everything* is beyond annoying

15:04 technomancy: theoretically with slamhound you don't even have to write :use/:require/:import anyway, they can just be infered

15:04 * ibdknox looks up slamhound

15:04 technomancy: it's not quite practical yet to the point where you can use it for everything

15:05 ibdknox: interesting

15:06 how does it decide when there's a name collision?

15:06 technomancy: currently it picks the shorter one unless it had a match for that in the ns form already

15:07 ibdknox: mm

15:08 stuartsierra: Looking up names is the the one place where I wish for an IDE sometimes.

15:08 technomancy: have you tried slamhound?

15:08 stuartsierra: not yet

15:09 ibdknox: we just need to come up with a way to put slamhound into our editors :D

15:09 problem solved ;)

15:09 arohner: man, is it just me, or does google not know how to search github?

15:09 stuartsierra: arohner: It's not just you.

15:09 technomancy: ibdknox: I have elisp for it, but it currently doesn't wrap at 80 columns, so I don't use it.

15:09 ibdknox: technomancy: I'm one of the crazy vim users

15:09 stuartsierra: Somebody just needs to hurry up and rewrite Emacs in Clojure. ;)

15:09 ibdknox: haha

15:10 that would be fun

15:10 technomancy: stuartsierra: elisp as a compilation target.

15:10 one of these days

15:10 ibdknox: lol

15:10 stuartsierra: technomancy: that's an interesting idea, shouldn't even be that hard

15:10 Especially once Elisp gets lexical scope.

15:11 technomancy: just need to find a willing volunteer

15:11 * technomancy glances around furtively

15:11 ibdknox: not it.

15:11 stuartsierra: noses

15:11 redline6561: noes!

15:11 * arohner has his doubts that elisp will ever get lexical scope, or multithreading

15:11 technomancy: ibdknox: too busy with your clojure->vimscript compiler? that's understandable.

15:11 stuartsierra: arohner: it's in the next Emacs release

15:11 technomancy: arohner: it's got lexical scope already

15:11 redline6561: But, of course, Elisp *has* lexical scope. Just not in a debian package yet. ;)

15:11 technomancy: threading is implemented in a branch

15:11 ibdknox: haha client-side cljs framework first ;)

15:12 I already have hiccup over DOM objects

15:12 now I just have to the rest of everything goog.* does ;)

15:12 + do

15:13 arohner: why didn't CL ever get around to making an elisp backend?

15:13 seems like they had motive and opportunity.

15:14 stuartsierra: arohner: They tried writing an editor in CL and failed.

15:14 ibdknox: editors are very difficult to write

15:14 zvrba: so lisp is good enough for AI, but not for an editor? ;)

15:14 ibdknox: before I took over C# and VB, I was on the VS editor team

15:15 arohner: ibdknox: what editor do you use for clojure?

15:15 ibdknox: arohner: VIM :)

15:15 arohner: ibdknox: any emacs users in the VS editor team?

15:15 I feel like all modern IDEs have failed to learn from emacs

15:16 ibdknox: most people used VIM if not VS itself

15:16 I don't think we had any emacs folks there

15:17 like me, they hated pressing the ctrl key all the time ;)

15:18 * amalloy is trying out some foot pedals as backups for ctl/meta

15:18 arohner: ibdknox: sure, but that's not the appeal of emacs

15:18 1) never needing to take your hands off the keyboard. 2) the entire thing is built on an extensible programming language

15:19 technomancy: arohner: ignoring 2) is a failing of all modern software apart from mozilla, to b efair.

15:19 amalloy: arohner: in fairness, i think that's the goal of vim too. emacs users just don't feel they succeeded

15:19 technomancy: it's not just an IDE problem

15:19 tufflax: hahaha amalloy i never thought of that, brilliant

15:19 amalloy: but vim does a damn sight better than a lot of things

15:20 arohner: technomancy: sure, but it's quite obvious how valuable it is in your editor. Other modern software doesn't have an easy example to steal from

15:20 redline6561: technomancy +1

15:20 amalloy: tufflax: i'm hardly the first to think of it. there's even a song from ages-ago about needing footpedals to use (some other editor) properly

15:20 tufflax: hehe

15:21 redline6561: Did you buy them or make them amalloy?

15:21 amalloy: redline6561: http://www.kinesis-ergo.com/

15:21 redline6561: Nice. Thanks/

15:21 tomoj: arohner: frustrating how little people appreciate what 1) means

15:21 gtrak: I'm having a hard time getting the lein checkouts functionality to work with slime/swank, anyone have a better guide than what's on the lein faq? getting a noClassDefFoundError on a class that I'm hacking on in a dependency project, though I'm compiling it through slime

15:21 tufflax: I find the thought of someone using pedals so funny

15:23 gtrak: emacs-drumset-mode

15:24 tomoj: amalloy: you convinced me. found anything better than http://www.fentek-ind.com/FootPedal.htm#afp3usb ?

15:25 amalloy: tomoj: i've only had my set since wednesday

15:25 tomoj: s/better/significantly cheaper/

15:25 amalloy: hah. no

15:26 the kinesis ones are charging for the brand, i'm sure

15:26 i think i'd have gotten the ones you just linked to, if i'd found them

15:26 tomoj: hmm

15:26 kinesis ones seem the same price

15:26 amalloy: so far i've found that three pedals are too confusing, and only really use two

15:27 tomoj: exactly

15:27 for two individual pedals

15:27 amalloy: tomoj: the kinesis ones are like $15 more from their website; if you order from amazon instead it's about the same

15:27 (ie, about $15 cheaper)

15:27 tomoj: cool, thanks

15:28 the multipedal units make no sense - where's the snare?

15:28 amalloy: tomoj: c'mon, optional input jack for one more device! you could hook up a snare

15:29 tomoj: but it won't fit between my legs

15:30 stuartsierra: Anybody tried using a pedal for SHIFT?

15:31 ibdknox: the cruise control for awesome: a pedal for capslock ;)

15:32 amalloy: stuartsierra: shift is the third pedal i can never remember to use. but once or twice it's been handy when i sit down to write some lengthy plain-text

15:32 eg, a docstring

15:34 wink: it's hard to resist a "driving stick shift" pun now

15:35 arohner: hrm. If I got used to pedals, taking my laptop out would become difficult...

15:36 and listening to music while typing would either become difficult, or make me type in the rhythm of the song

15:38 Generic_Dumbass: try-clojure.org results: Clojure> (defn squar­e [x] (* x x))

15:38 #'sandbox158157/square

15:38 Clojure> (square 4)

15:39 Unable to resolve symbol: square in this context

15:39 heh

15:40 amalloy: what, uh...what are you getting at?

15:41 mefesto: Generic_Dumbass: just tried it myself and it worked... typo?

15:41 Generic_Dumbass: *slinks away guiltily*

15:41 amalloy: Generic_Dumbass: when you're done playing with try-clojure, perhaps try out 4clojure.com?

15:42 Generic_Dumbass: indeed

15:45 gtrak: is it possible to hack on a class on a dependency project and compile it in slime/swank? I get Unknown location:

15:45 error: java.lang.NoClassDefFoundError: Could not initialize class ...__init even after I've C-c C-k'd the ns

15:45 tomoj: any other exceptions?

15:46 arohner: gtrak: yes, I do it every day

15:46 gtrak: no

15:47 arohner: gtrak: it's probably a typo, where you have a foo.bar that doesn't exactly match the name of a class or ns

15:47 gtrak: I must be missing something simple... I've added a symlink to the project under checkouts

15:47 tomoj: "Could not locate" is different from "Could not initialize", isn't it?

15:47 that looks like what I get when something goes wrong during class initialization. when that happens I get the real exception once, and thereafter only an unhelpful exception until I restart the jvm

15:48 gtrak: hmm...., well let me retry it, just for kicks, arohner do you happen to have a jar of the dependency in the lib directory?

15:48 tomoj: you need to have the dep in your dependencies even if it's a checkout dep

15:48 gtrak: I deleted mine, it didn't seem to sync when I made a change, tomoj, I have it listen in lein yes

15:49 arohner: gtrak: yes. I typically have the jar in lib/, and a copy of the source in another dir. Then I open the source file and C-c C-k it

15:49 amalloy: (inc arohner)

15:49 lazybot: ⟹ 1

15:49 gtrak: arohner, are you using the checkouts feature?

15:50 arohner: gtrak: no

15:50 tomoj: gtrak: and the version for the dep in your project.clj matches the version in its project.clj?

15:50 amalloy: gtrak: i do the same thing, and i don't use checkouts

15:50 gtrak: ha, weird

15:50 then I'll stop trying to use checkouts

15:50 tomoj: amalloy: do you use M-.?

15:50 amalloy: just edit the source file wherever you happen to have it on disk - C-c C-k doesn't care what file you're telling it to load

15:51 jweiss: is there a way to get a thread dump in emacs when you've run M-x lein-swank

15:51 amalloy: tomoj: yes?

15:51 tomoj: better not just edit it _wherever_ you happen to have it on disk

15:51 e.g. in the jar in lib

15:51 where M-. takes you

15:51 amalloy: wherever you happen to have [the source file] on disk

15:51 yes, using M-. to take you to an edit location is not usually right

15:52 (though not uniformly wrong, either)

15:52 tomoj: with checkouts deps and the project itself it works out

15:52 arohner: jweiss: you can get stack traces in emacs w/ swank. Is that what you mean?

15:52 amalloy: tomoj: meh. i have the source files open anyway in another buffer

15:52 tomoj: yeah, me too

15:53 jweiss: arohner: no, i'm doing stuff with concurrency, and one thread seems to be holding up the repl, want to know what is happening

15:53 amalloy: checkout deps are adding a level of complexity for no particular reason

15:53 tomoj: then when I use M-. I have two copies open

15:53 then I switch to checkouts

15:53 amalloy: tomoj: i believe that's only true if you haven't done C-c C-k on the source version yet

15:53 after that, i think emacs knows to go to the "right" place when you M-. it

15:54 arohner: amalloy: yes, because the metadata on where the code came from has changed

15:54 when you first load it, the var says "I came from foo.jar"

15:54 after a compile, it says "I came from foo.clj"

15:54 tomoj: amalloy: you're right

15:55 amalloy: there are plenty of reasons for me to want to use lein instead of cake, but checkout deps ain't one of them

15:55 tomoj: oh

15:56 thought we were talking lein-without-checkouts vs lein-with-checkouts

15:56 if you happen to need to add a new file, you need a checkout dep or to go hack on the project itself, right? quite rare, though

15:56 amalloy: doesn't really matter? i wouldn't use checkouts if i were using lein either

15:58 tomoj: "using M-. to take you to an edit location is not usually right" -- it strikes me that this is peculiar given M-.'s name

15:58 amalloy: heh

15:59 can't argue there

15:59 gtrak: lein needs to become the new eclipse to fix that

16:03 I work on a 160 project eclipse workspace in java, and it 'just works' mostly, but that's because eclipse has full control of everything

16:03 kephale: i

16:04 cemerick: whew, 160!

16:04 gtrak: very modular :-)

16:05 cemerick: "only" 58 here

16:05 and that includes a pile of open source stuff :-P

16:05 amalloy: man, i never had more than like twenty

16:09 sritchie: hey all, one quick question -- I'm writing a macro that needs to take in a java classname, but it seems that defmacro interprets all inputs as symbols

16:09 for example, (defn printer [x] (.getName x)) returns java.lang.String for (printer String), while subbing defmacro for defn returns String.

16:10 so, the question is, is there a better way to do this than (defmacro printer [x] (.getName (eval x)))

16:10 amalloy: sritchie: well, all inputs *are* symbols

16:10 you acan use resolve instead of eval, but i'm pretty sure there's something still better

16:11 cemerick: hard to beat resolve there

16:11 amalloy: eg, (defmacro printer [x] `(.getName ~x)) unless there's some reason you want the macro to expand to a string?

16:13 sritchie: here's the function I'd been writing

16:13 https://gist.github.com/1128401

16:13 I tacking resolve onto the parameter inside that anonymous function does the job

16:16 gtrak: another question, it seems lein test (namespace) runs differently from clojure-test-mode on a buffer... any way to reconcile that?

16:17 I have a bunch of tests that fail from emacs that work from lein

16:17 seancorfield: define "fail"

16:17 classpath issues?

16:21 gtrak: no idea, extremely hard to parse the output

16:23 throws an exception of some sort

16:24 the test file starts up a jetty with a text fixture and does some requests on it

16:24 so I'm getting back html stacktraces

16:24 works fine with lein test

16:25 kjeldahl_: Anybody know how to exit "repl" mode inside "lein interactive"? If I press ctrl-D it exits all the way out of interactive mode..

16:27 gtrak: seancorfield, "Caused by: java.util.concurrent.RejectedExecutionException" some kind of threadpool not being initialized

16:27 where should I look

16:29 PPPaul: can someone help me out with my macro?

16:29 (defmacro def-csv-importer [table-name & fields]

16:29 `(let [name# ~table-name

16:29 struct-name# (str name# "-fields")]

16:29 (defstruct struct-name# ~@fields)))

16:29 i'm looking at tutorials and they aren't helping too much

16:30 i want my macro to write out a defstruct

16:31 gtrak: does it have to be a macro?

16:32 PPPaul: well, i want it to do more than just that

16:32 but this is the start

16:33 i want it writing out variables and functions as well

16:33 clojurebot: functions are maps

16:35 technomancy: gtrak: you need to upgrade swank to 1.3.2 or higher

16:35 PPPaul: currently my macro isn't doing what i want with regards to making a string out of the 'table-name'

16:35 technomancy: clojurebot: RejectedExecutionException in swank |means| you need to upgrade swank to 1.3.2 or higher.

16:35 clojurebot: c'est bon!

16:36 gtrak: damn!

16:38 is it possible to override the swank globally and ignore what's in the project.clj? I have buddies that use old lein that don't have this problem, I think it's a problem with 1.6 only, right?

16:38 technomancy: gtrak: yeah, use lein plugin install swank-clojure 1.3.2

16:39 it *should* take precedence over project.clj, but I'm a bit fuzzy on the details

16:39 best to remove it from project.clj if you can, unless you want to have it in production

16:39 gtrak: maybe I can persuade them

16:40 technomancy: tell em technomancy sent you =)

16:40 my advice is to only include in :dev-dependencies things that are required for tests and builds to occur. if you have plugins for your own convenience like swank or clj-stacktrace, those are the responsibility of the user since tastes vary

16:42 gtrak: that makes sense

16:47 hmm, seems to work now

17:05 PPPaul: i have 2 macros, i would like them to produce the same result.

17:05 (defmacro tester [table-name & fields]

17:05 `(defstruct ~table-name ~@fields))

17:05 (defmacro tester1 [table-name & fields]

17:05 `(let [struct-name# ~table-name]

17:05 (defstruct struct-name# ~@fields)))

17:05 what would i change in the second one to do this (while keeping the let statement)

17:06 amalloy: not possible

17:06 PPPaul: oh

17:06 hiredman: PPPaul: I suggest you write out the expansion of your macro and try to run it

17:07 amalloy: defstruct (and every def) needs a literal symbol as its first arg. you can't (let) a name in the expansion scope and then use that, because it doesn't know about let

17:07 hiredman: once you write the code your macro generates outside of the defmacro, it should be obvious why it doesn't work

17:07 PPPaul: i want my macro to produce a def, function, and struct based on a name

17:07 amalloy: good advice

17:07 PPPaul: try what hiredman suggests. write out the actual code you want to produce, and see how you can get there

17:08 PPPaul: i have the code, i am trying to figure out how to get there... this is my first time writing macros

17:08 i'm reading tutorials and stuff

17:08 amalloy: PPPaul: so gist the goal code or something

17:09 PPPaul: ok, give me a sec

17:13 https://gist.github.com/1128542

17:13 hope that you guys can help me understand macros :D

17:19 i think what i want is very simple... i'm not sure what i'm doing wrong

17:20 zippy314: Why does tunning clojure tests from lein test, but the trying to do the same test from emacs-swank-clojure test mode, fails with a ClassNotFoundException?

17:23 (s/tunning/running/) correction: Why does running clojure tests from lein test, but the trying to do the same test from emacs-swank-clojure test mode, fails with a ClassNotFoundException?

17:26 amalloy: zippy314: fwiw, you can just write s/tunning/running and lazybot will repeat your (fixed) message for you

17:26 PPPaul: why doesn't this macro work? (defmacro tester2 [table-name & fields]

17:26 `(def (symbol (str \* ~table-name \*))))

17:27 amalloy: PPPaul: observe that in your gist, there is no let

17:27 zippy314: amalloy: I did! But I think that my client intercepts it first...

17:27 amalloy: haha

17:27 Raynes: foo bar bat

17:27 s/bat/baz/

17:27 lazybot: <Raynes> foo bar baz

17:27 PPPaul: i know there is no let... but i was told to use let with autogens to avoid redundant evaluations

17:28 Raynes: zippy314: What client is that? o.o

17:28 zippy314: Raynes: colloquy

17:28 amalloy: PPPaul: but you don't want to evaluate anything!

17:28 Raynes: Yeah, I can't tolerate colloquy.

17:28 PPPaul: i guess i'm really confused

17:29 amalloy: spoiler: (defmacro whatever [name] `(do (defstruct ~(symbol (str name "-fields")) ...) (def ...)))

17:29 PPPaul: :D

17:29 i need the do?

17:30 Raynes: A macro only expands to a single form. Therefore, if you need it to expand to multiple forms, you wrap it in a 'do', which makes it all one big form.

17:30 amalloy: just like any other function, a macro can only return a single form

17:30 PPPaul: i tried the ~(symbol...) but i get an error

17:31 thanks for the info

17:31 Raynes: It's a bouncy house of fun, really.

17:33 PPPaul: thanks... i was putting the '~' in the wrong place

17:50 Cozey: Good evening. Why can't i create deftype feld with a hyphen?

17:51 hiredman: Cozey: what version of clojure?

17:51 Cozey: 1.3

17:51 amalloy: Cozey: that was a bug in some version that's been fixed

17:51 Cozey: oh

17:51 amalloy: cemerick probably knows the ticket number, even

17:51 Cozey: 1.3.0-beta1 i'm using

17:51 what should i use then?

17:51 hiredman: deftype fields are java fields and java field names cannot contain '-'

17:51 amalloy: http://dev.clojure.org/jira/browse/CLJ-819

17:52 i guess i was wrong about it having been fixed

17:52 it works in 1.2.1 - time to downgrade? :)

17:58 Cozey: :-)

17:58 nah, i'll drop the hyphen and go for good ol' camel case haha

18:06 has anyone stumbled upon an issue when lein swank uses stale class files in target/ directory instead of modified sources?

18:06 even when restarted?

18:08 technomancy: that's clojure, not leiningen

18:24 momox: is it possible to rewrite this snippet using map? http://pastebin.com/2js7MFSv

18:25 ibdknox: (map sleep-print (range 10))

18:25 hiredman: of course

18:25 ibdknox: incorrect

18:25 ibdknox: ah

18:25 momox: it should return a sequence of function calls

18:26 not the value of the calling the function

18:27 amalloy: certainly you *can* write it with map

18:27 i think the for is probably clearer

18:27 ibdknox: (map (fn [i] #(sleep-print i)) (range 10))

18:27 would work I think

18:36 momox: ibdknox: yes, it works...thank you for your help

18:37 ibdknox: momox: I agree with amalloy though, that should probably stay as a for

18:37 it's more obvious what it's doing there

18:38 amalloy: (map #(...)) is something i only use in a ->> pipeline

18:38 momox: yes...i agree too, but I was just curious on how to a express that using a map

18:39 amalloy: example, please?

18:39 amalloy: (for [x xs] anything) => (map (fn [x] anything) xs)

18:39 will work every time

18:39 &(->> (range) (filter even?) (map #(* 2 %)) (take 4))

18:39 lazybot: ⇒ (0 4 8 12)

18:49 momox: amalloy: thank you for your explanation

19:06 seancorfield: Java interop Q... I have a Java object with public fields and no setters... what's the right / recommended syntax for setting those fields? I'm drawing a blank :(

19:07 amalloy: set!

19:08 seancorfield: ah, that's why i was drawing a blank... thank you!

19:09 just found it halfway down the java interop page http://clojure.org/java_interop - man, that's ugly

19:09 amalloy: ugly how?

19:10 seancorfield: the example shows (set! (. instance member) expr) but i assume (set! (.member instance) expr) also works?

19:10 amalloy: should, yeah

19:10 seancorfield: thanx

19:10 * seancorfield grumbles at the authors of the MongoDB Java driver

19:14 triyo: .quit

19:14 oops

19:14 * triyo forgot the the forward-slash

19:15 seancorfield: it would be cleaner to have a map from clojure-y name/value to member access on MongoOptions but i know i can't just do (defn opt [o m v] (set! (. o m) v))

19:16 do i have to define a macro for that or can i do it in a function with some magic combination of ~ ` etc?

19:17 hiredman: it's called reflection

19:17 it's how you do that kind of thing

19:17 seancorfield: i went with a macro (defmacro opt! [o m v] `(set! (. ~o ~m) ~v))

19:19 hiredman: https://github.com/hiredman/ring-jetty--adapter/blob/master/src/ring/adapter/jetty+.clj

19:21 seancorfield: meh, the macro doesn't really do what i want either... and that code listing is not helpful as a whole without a bit more commentary on which part, specifically, addresses my question

19:22 after all, i'm not trying to call methods here, i'm trying to set fields

19:22 hiredman: sure, you can set fields with reflection as well

19:23 the listing takes a map of options and turns it into calls to setters for those options, but it could set ields too

19:23 fields

19:25 it's actually even easier if you use clojure.lang.Reflector instead of java's reflection apis directly

19:45 nishant: has anyone used clj-ssh for scp'ing ?

20:00 seancorfield: hiredman: any reason you used split / mapcat in that field name conversion rather than clojure.string/replace with #"-." ?

20:00 or #"-[a-z]" i guess

20:01 hiredman: lazy I guess

20:01 ~hiredman

20:01 clojurebot: hiredman <3 XeLaTeX

20:01 hiredman: ~hiredman

20:01 clojurebot: hiredman is slightly retarded

20:01 hiredman: hmmm

20:01 ~hiredman

20:01 clojurebot: hiredman is lazy

20:01 hiredman: thats the one

20:02 oh, well, actually for camel casing

20:02 it uppercases the words at the edges

20:03 seancorfield: ah, so it also uppercases the first letter... gotcha

20:09 cemerick: amalloy: I have it fixed locally, will be adding a patch to the ticket shortly.

20:32 jcromartie: clojure-jack-in just sits there...

20:32 Starting swank server...

20:32 oh

20:32 because /bin/bash: lein: command not found

20:36 hiredman: right, you need lein on your path

20:37 jcromartie: and not just on my path

20:37 I use lein from bash

20:37 in ~/bin/lein

20:38 ok now *swank* is filling with lisp code

20:38 is it loading slime?

20:38 hiredman: yes

20:38 jcromartie: because I already have slime

20:38 that will cause problems, won't it

20:39 technomancy: well, the whole point of jack-in is you don't have to already have slime installed

20:39 or maybe half the point

20:39 if you want to get technical

20:39 jcromartie: :P

20:39 man, this morning I had it all set up, and I went down this road because { wasn't working correctly in paredit

20:40 hiredman: uh, that is just clojure-mode

20:40 technomancy: probably from paredit 20 instead of 22 actually

20:40 jcromartie: yup

20:41 there we go

20:48 hiredman: technomancy: 22 doesn't seem to do curly braces for me

20:48 and curly praces aren't in the place where it looks like brackets are listed

20:48 braces

20:51 amalloy: hiredman: paredit defines curly-brace functions but doesn't bind them to anything. clojure-mode sets the bindings

20:51 provided you have paredit 21+

20:52 hiredman: my elpa-to-submit has paredit 22

20:54 amalloy: well, if you haven't updated clojure-mode since...2008, it looks like...it might not have that code :P

20:54 hiredman: I work with phil, of course I have an updated clojure-mode

20:54 amalloy: yeah, not a serious suggestion

20:56 technomancy: I've noticed the curly braces don't work with paredit in slime-repl, but I've never noticed them not work in clo-mo

20:56 man it is so obvious that today's dinosaur comic was written by a programmer: http://www.qwantz.com/index.php?comic=2015

20:58 hiredman: ugh, so describe-key { even says it is bound to open-curly

20:58 er

20:58 paredit-open-curly

21:10 jcromartie: heh :) I'm not the only one huh

21:14 amalloy: technomancy: it's not hard to configure them to work in the repl too

21:14 oh. no, that's just dumb

21:15 i have them configured to work better than default syntax-table wise, but i don't turn on paredit in my repl

21:31 dnolen: https://gist.github.com/1128891

21:31 :D :D :D :D

21:34 chouser: nice

21:36 dnolen: god bless maranget

21:38 hiredman: it has the inverse key/value thing just like map destructuring? (makes sense just hadn't thought about it)

21:38 dnolen: hiredman: yes, I want pattern matching to follow destructuring as closely as possible.

21:39 hiredman: nice

21:41 dnolen: i don't think people will generally do this, but this is fun, https://gist.github.com/1128901

21:42 oops just cleaned that up

21:43 hiredman: mmmm

21:44 dnolen: hiredman: ?

21:46 hiredman: matching matching is a wonderful thing

21:48 jcromartie: maybe off topic, but why is Clojure a single .jar, and Scala is not?

21:48 or, *how* is Clojure a single .jar while Scala is not

21:48 it seems like quite a feat

21:58 dnolen: it never ceases to amaze what 600 lines of Clojure can do ...

22:24 amalloy: jcromartie: you can jar up your whole hard drive, and then it's one jar. i'm not sure how that's a meaningful measurement of anything

22:28 jcromartie: what's the "clean" way to restart clojure-jack-in

22:31 after slime-disconnect or slime-quit-lisp, running clojure-jack-in yields: "error in process filter: Symbol's value as variable is void: Process [2 times]"

22:31 amalloy: reinstall your operating system

22:32 (disclaimer: the internet is a bad place for blindly following advice. don't actually do that)

22:32 jcromartie: right

23:00 drewr: jcromartie: hit , in your repl

23:01 at least that's how I do it; not sure what it eventually calls

23:06 fmw: are there problems with doseq in clojurescript? I'm suppose I'm just using it incorrectly: https://gist.github.com/1128963 ? I'm getting notified that something in core.js is undefined (see the provided paste)

23:27 hmm, I've applied the doseq-related fix at http://dev.clojure.org/jira/browse/CLJS-39 but that doesn't fix my problem

23:54 technomancy: jcromartie: kill *swank* and re-run M-x clojure-jack-in

Logging service provided by n01se.net