#clojure log - Jul 13 2011

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

1:21 chrissbx: Hm, how would you write this Scheme code in clojure?: (letrec ((a (lambda (x) ... b ..)) (b (lambda (x) ... a ..))) ...)

1:22 I guess (defn ) in a local scope?

1:22 amalloy: &(doc letfn)

1:22 sexpbot: ⟹ "Macro ([fnspecs & body]); Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body. fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+)"

1:23 chrissbx: ah ok. Thanks for your help, amalloy!

1:23 amalloy: but clojure's letfn only allows functions: you can't do a letrec with mingled functions/values

1:24 chrissbx: Yeah, I feared that already.

1:24 Will have to do dependency analysis, I guess.

1:24 Hm. Or why not just using (defn ) (def ) (defn ) in a local scope?

1:24 amalloy: um because that's wrong

1:25 it pollutes the scope with global vars, and isn't threadsafe, and any number of other problems

1:27 chrissbx: Something like: (defn locl [] (defn f [x] (g x)) (def x 1000) (defn g [y] (f (+ x y))) f)

1:27 except that this gives me "unable to resolve g"

1:27 Those aren't global vars, or are they??

1:29 &(defn locl [] (defn f [x] x) (def x 1000) (defn g [y] (f (+ x y))) g)

1:29 sexpbot: java.lang.SecurityException: You tripped the alarm! def is bad!

1:30 chrissbx: whatever, then: ((locl) 10)

1:30 amalloy: yes, they are

1:30 chrissbx: ugh

1:30 I'm not going to complain.

1:31 amalloy: vars are always global

1:31 (except when they're not, see with-local-vars)

1:31 (that doesn't solve your current problem)

1:31 chrissbx: ehr, what are those introduced by let ?

1:31 amalloy: locals. bindings, whatever

1:31 chrissbx: hm alright.

1:31 amalloy: but a var is specifically things of class ##(class #'inc)

1:31 sexpbot: ⟹ clojure.lang.Var

1:32 chrissbx: So, using letfn is the only way to go, I guess? And doing dependency analysis myself.

1:33 Going to save that for tomorrow.

1:33 amalloy: yeah, though tbh i don't know how scheme's letrec resolves the issue

1:33 chrissbx: Usually a dependency analysis, too.

1:34 At least that's what some systems do; will have to read the spec for whether that's strictly necessary.

1:38 Well, R5RS says it's an error to expect to be able to refer to other variables from expressions other than functions.

1:38 But some systems implement it.

1:39 amalloy: chrissbx: you're writing it in scheme, you said?

1:39 chrissbx: Ye

1:39 s

1:39 But I'm not in the mood to cannibalize the system I'm using to do the analysis.

1:39 amalloy: if you wrote it in clojure you could use it as an embedded scheme interpreter

1:40 ie, (defn x [] (scheme (letrec ...)))

1:41 chrissbx: Well.. I guess you mean to say, once I've solved the letrec conversion issue.

1:41 amalloy: well, i wasn't addressing letrec specifically. bad example

1:42 just that if you write it in scheme, it has to be some external preprocessor you run on scheme files

1:42 if you write it in clojure, you can intermingle the two

1:42 chrissbx: Maybe my converter will be able to convert itself. Right now I'm not interested in that capability.

1:43 amalloy: i don't understand. what capability are you interested in, then? automatically porting whole scheme apps?

1:43 chrissbx: Yes

1:43 Well, and learning Clojure.

1:44 amalloy: it seems so unlikely any non-toy will ever convert totally automatically, and you would probably learn more clojure by writing in it

1:45 chrissbx: Ok, and learning how to translate from Scheme to Clojure.

1:45 including learning how to write such a translator.

2:22 amalloy: hah, i like the "resolution" to the "build tool for clojure/java" thread. guys, shut up, go cure cancer

3:12 * kumarshantanu agrees with amalloy

4:06 pyr: hi, can deconstruction be applied in binding ?

4:07 i.e: (binding [[*sym-a* *sym-b*] (get-vector)] (do-something-else))

4:08 ihodes: did you test it out?

4:08 pyr: in a large namespace, i'll test it out on the repl right now

4:09 yeah, doesen't work

4:09 ihodes: yeah i just tried it too. never had before.

4:09 what are you trying to do?

4:10 pyr: so since it doesn't work and the documentation for binding mentions that bindings are made in parallel (unlike let)

4:10 what's the idiomatic way of having one dyn declaration depend on another

4:11 accomplishing the same as: (let [first-sym (create-something) second-sym (do-something-with first-sym)] ...)

4:11 ihodes: but affecting the global scope?

4:11 pyr: same than that but with binding

4:11 i could of course nest bindings

4:11 but that's ugly, maybe it's the only way

4:12 ihodes: why not use some other reference? seems like vars might not be the way to go

4:13 pyr: i have a macro that executes within the context of a connection

4:13 well, ok, I see what your saying, I have a good workaround

4:14 ihodes: good luck ;) sounds like a mess

4:18 pyr: ihodes: not that much :) but talking about it helped, as often

4:19 ihodes: pyr: good :) glad to be a cathartic outlet

5:40 kumarshantanu: pyr: (binding [foo (get-foo) bar (get-bar)] (do-something foo bar))

5:41 doesn't that work?

5:43 pyr: kumarshantanu: yes, of course

5:43 that's not what i was meaning to do

5:43 kumarshantanu: okay

6:43 shtutgart: How can I cast class in clojure? (need it for interop)

6:49 Ah, I can just provide type hint

6:58 clgv: shtutgart: you cant cast objects to classes in clojure but you can provide type hints that enable the compiler to omit reflection

7:03 hiredman: you can cast

7:03 ,(doc cast)

7:06 shtutgart: cast just throws exception if type of the object is wrong

7:07 hiredman: shtutgart: then it is wrong

7:08 are you sure you want to cast?

7:08 the jvm is stronglly typed, so you can't just cast things willy nilly

7:10 zakwilson: ,(cast Double 1)

7:10 clojurebot: java.lang.ClassCastException

7:11 zakwilson: This is unexpected though:

7:11 shtutgart: I have class A and need to call java method which requires class B which is a subclass of A; in such case I have to provide type hint

7:11 zakwilson: ,(cast Number 1)

7:11 clojurebot: 1

7:11 zakwilson: (isa? Number 1)

7:11 ,(isa? Number 1)

7:11 clojurebot: false

7:11 hiredman: ,(isa? Number (class 1))

7:11 clojurebot: false

7:12 hiredman: gah

7:12 ,(isa? (class 1) Number)

7:12 clojurebot: true

7:12 shtutgart: hm, or not...

7:12 hiredman: shtutgart: I would double check th type of the object

7:12 zakwilson: Oh, I had it backwards.

7:13 hiredman: makes isa? a pain in condp

8:05 Scriptor: is clj-http still the recommended http client for clojure?

8:22 clgv: when reading from a file with ObjectInputStream where I serialized clojure data with ObjectOutputStream I get the following exception: "java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.io.ObjectStreamClass" - does someone has an idea what the reason might be?

9:03 kumarshantanu: clgv: any example how are you using it?

9:04 clgv: kumarshantanu: yeah I can copy it for you

9:04 it's pretty straightforward

9:07 kumarshantanu: http://pastebin.com/Gc7S2PQU

9:07 kumarshantanu: ,(let [byt (java.io.ByteArrayOutputStream.) out (java.io.ObjectOutputStream. byt)] (.writeObject out [1 2 3 4]) (println (str byt)))

9:07 clojurebot: ��

9:08 clgv: kumarshantanu: I already worked around the header issue when appending. it works in some manual cases for multiple appending as intended.

9:12 kumarshantanu: clgv: what objects are you storing inside the vector before writing to the stream? (i.e. data-map)

9:12 I guess they need to implement the marker interface as well?

9:13 Serializable

9:13 clgv: kumarshantanu: only standard clojure datastructures and one deftype that implements Serializable

9:14 kumarshantanu: clgv: does it work when you omit the deftype object from the vector?

9:15 clgv: for one data-map it works with it. I can try it in general without it

9:20 kumarshantanu: clgv: maybe you try writing the deftype instance to an ObjectOutputStream separately to see if it's the deftype that causing the problem

9:20 and implement Externalizable if required

9:20 clgv: kumarshantanu: thats an additional option. I thought about Externalizable as well a few minutes ago.

9:21 it's annoying that the serialization implementation has noch real means for debugging

9:22 ok I omitted deftype and it still happens when I store two objects.

9:23 it's always the: "java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.io.ObjectStreamClass"

9:25 kumarshantanu: hmm, that's an array that can't be written to the stream -- obvious

9:25 can you convert the array into a vector before writing?

9:26 clgv: i suspect you will need to isolate the cases where serialization is breaking, an convert them under Serializable by some means

9:26 clgv: uhmm that exception is thrown during reading via ObjectInpuStream

9:26 kumarshantanu: s/an convert/and convert/

9:26 sexpbot: <kumarshantanu> clgv: i suspect you will need to isolate the cases where serialization is breaking, and convert them under Serializable by some means

9:27 clgv: I have only one case with a native array and this is a double array

9:27 writing the data to file does not throw any exception at all

9:28 kumarshantanu: Arrays get created as the java.lang.Array class, which doesn't implement Serializable

9:28 it can be read as primitive data nevertheless (just speculating here)

9:29 clgv: is that (array) what is causing the issue while reading back?

9:30 clgv: maybe if you can try converting the array into a vector before writing...should that help while reading back?

9:30 clgv: kumarshantanu: if I write one instance of data-map everything works well. it only happens when I actually append something

9:30 joegallo: ummmm... i'm not sure about some of that -- java arrays are not java.lang.Array (iirc there is no such class), and they are serializable.

9:31 kumarshantanu: ,(type (into-array String "foo" "bar"))

9:31 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: core$into-array

9:31 kumarshantanu: (type (into-array String ["foo" "bar"]))

9:32 ,(type (into-array String "foo" "bar"))

9:32 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: core$into-array

9:32 kumarshantanu: ,(type (into-array String ["foo" "bar"])) ;; at last

9:32 clojurebot: [Ljava.lang.String;

9:33 kumarshantanu: ,(.getComponentType (class (into-array String ["foo" "bar"])))

9:33 clojurebot: java.lang.String

9:34 kumarshantanu: clgv: true -- i mixed up something earlier i guess

9:35 joegallo: ,(instance? java.io.Serializable (into-array ["a" "b"]))

9:35 clojurebot: true

9:35 kumarshantanu: ,(supers (class (into-array [])))

9:35 clojurebot: #{java.io.Serializable java.lang.Cloneable java.lang.Object}

9:36 clgv: kumarshantanu: as far as I understand that know the ObjectInputStream is somehow expecting this ObjectStreamClass but finds actual data

9:36 *now

9:38 kumarshantanu: clgv: can you use reflection to see if the deftype includes a static variable called serialVersionUID ?

9:38 clgv: kumarshantanu: there is currently no deftype in the data anymore

9:39 kumarshantanu: ObjectStreamClass seems to be required when reading objects back -- uses serialVersionUID to determine which version

9:39 clgv: okay

9:39 clgv: one stacktrace: http://pastebin.com/aDvxNNZj

9:40 xian: Is it possible to get the function which is defined (via letfn) locally by its symbolic name?

9:45 kumarshantanu: clgv: I can write an array and read it back

9:45 ,(let [bos (java.io.ByteArrayOutputStream.) out (java.io.ObjectOutputStream. bos)] (.writeObject out (into-array [1 2 3 4])) (let [b (.toByteArray bos) bin (java.io.ByteArrayInputStream. b) in (java.io.ObjectInputStream. bin) ext (.readObject in)] (clojure.pprint/pprint ext)))

9:45 clojurebot: [1, 2, 3, 4]

9:46 clgv: kumarshantanu: yes. I tested this before. also works for vectors hashmaps list and most cases

9:46 s/and/in/

9:46 sexpbot: <clgv> kumarshantanu: yes. I tested this before. also works for vectors hashmaps list in most cases

9:49 clgv: kumarshantanu: ok I am now narrowing down the part of the data that causes the problem

9:50 kumarshantanu: clgv: okay, that's what i was thinking -- about narrowing it down to a small test case

10:06 clgv: closing in...

10:09 kumarshantanu: it is indeed the 2d double array and therefor in the case before the deftype that was wrapping it

10:11 kumarshantanu: clgv: ah okay

10:11 clgv: I am trying to get the same error with a minimal data-map now

10:13 kumarshantanu: can we create 2D arrays in Clojure?

10:14 shtutgart: ,(make-array int 10 10)

10:14 clojurebot: java.lang.ClassCastException: clojure.core$int cannot be cast to java.lang.Class

10:15 clgv: yeah like that as well ##(repeatedly 3 (repeatedly 3 rand))

10:15 sexpbot: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

10:15 clgv: yeah like that as well ##(repeatedly 3 #(repeatedly 3 rand))

10:15 sexpbot: ⟹ ((0.684066312440444 0.525795787150419 0.09663251276834983) (0.2233101514830721 0.18808849843110942 0.48354204576108295) (0.6133362272999827 0.30182543239240256 0.32658591964711126))

10:16 clgv: ups missing the conversion^^

10:16 here it is: ##(into-array (map into-array (repeatedly 10 #(repeatedly 10 rand))))

10:16 sexpbot: ⟹ #<Double[][] [[Ljava.lang.Double;@166eac1>

10:16 shtutgart: (to-array-2d (repeatedly 3 #(repeatedly 3 rand-int))

10:17 clgv: kumarshantanu: but writing those arrays in there works pretty well in the minimal examples :(

10:17 shtutgart: then ##(to-array-2d (repeatedly 3 #(repeatedly 3 (partial rand-int 10))))

10:17 sexpbot: ⟹ #<Object[][] [[Ljava.lang.Object;@17c2535>

10:17 kumarshantanu: ,(let [bos (java.io.ByteArrayOutputStream.) out (java.io.ObjectOutputStream. bos)] (.writeObject out (make-array Double 2 2)) (let [b (.toByteArray bos) bin (java.io.ByteArrayInputStream. b) in (java.io.ObjectInputStream. bin) ext (.readObject in)] (clojure.pprint/pprint ext)))

10:17 clojurebot: [[nil, nil], [nil, nil]]

10:20 kumarshantanu: clgv: can you print the data to see what it is before serialization, so that you can use the same data in the test?

10:23 paraseba: I'm having problems with leiningen 1.6.1 on clojure 1.3.0-beta1. Can't run tests inside an interactive session, I get IOException Stream closed

10:23 anyone else having this problem?

10:23 cant call run task inside interactive either, same error

10:24 clgv: kumarshantanu: it's a 120x120 double array

10:28 kumarshantanu: if I convert it to a vector of vector that works. but it takes twice as much space.

10:36 the hierarchy is: map -> map -> vector -> map -> array

10:38 kumarshantanu: clgv: i created a test project -- git@github.com:kumarshantanu/serial-test.git

10:38 maybe you can add the 2D double data to Data.java if you like

10:43 clgv: kumarshantanu: ok. just let me finish the Externalizable approach

10:47 clgv: I think you can just create a 2d array with random double values.

10:48 with 120x120 entries.

10:51 kumarshantanu: clgv: "lein test" is passing with 3x3 2D double array

10:51 i will try to put in more data there

10:58 clgv: it's really stupid that I can serialize something that cant be deserialized... :/

10:58 I would want it to fail on writing, if it cannot handle the array.

11:00 kumarshantanu: clgv: i added a random 2D double array data...it seems to work

11:00 pushed it

11:00 passing for 120x120 array

11:00 clgv: kumarshantanu: the problem is that it works in manual test as well... and everything is using the same functions

11:03 Scriptor: from the mailing list, anyone have any opinions on which would be more efficient? (cont...)

11:03 (reduce into [] (repeat n xs))

11:03 (apply concat (repeat n xs))

11:03 both take a vector, repeat, and flatten

11:03 clgv: kumarshantanu: I managed to save my deftype via externalizable in some simple examples

11:05 symbole: Scriptor: You can look at the source of each. Are you trying to do some optimization, or just curious?

11:06 Scriptor: symbole: someone asked how to do it in the mailing list, so just curious about whether mine is better or worse :)

11:06 clgv: kumarshantanu: but embedded in map->map->vector->map->deftype it does not work...

11:07 Scriptor: on first glance concat does seem to have a lot more overhead

11:08 symbole: Why?

11:08 clojurebot: why not?

11:08 symbole: Damn, clojure.org is down again?

11:09 Nevermind.

11:10 clgv: symbole: clojure.org is up and running

11:10 Scriptor: concat doesnt really do anything when it's calles since it's lazy

11:12 Scriptor: clgv: sure, but neither does reduce

11:12 clgv: Scriptor: reduce is not lazy as far as I know

11:12 dnolen: Scriptor: reduce is eager

11:13 Scriptor: oh, damn, I could've sworn it was lazy-seq'd

11:13 thanks for the clear-up guys!

11:14 symbole: Laziness doesn't say much about efficiency though.

11:14 paraseba: Scriptor: reduce _needs_ to do something, since it has to return something, is not like concat that can return a lazy-seq

11:16 Scriptor: paraseba: true, it doesn't know what type the accumulator will be so it can't guarantee that it's something you could lazy-seq, forgot about that bit

11:18 paraseba: Scriptor: it doesn't have nothing to "show" you before the whole seq is iterated

11:21 clgv: kumarshantanu: I have uploaded the data for you here: http://www.megafileupload.com/en/file/319690/bla-txt.html

11:21 kumarshantanu: it contains vectors instead of the arrays - but you can convert them easily

11:29 Scriptor: ah, forgot that concat always returns a list, you'd have to call vec on my solution if you want it in vector form

11:29 into uses conj so you get whatever type you pass

11:36 clgv: kumarshantanu: there seems to be a definite serialization error due to the hierarchie - but I dont know what causes it

11:44 kumarshantanu: I work around it by using the deftype that represents a compressed object at top level as well. this way it works

11:51 dnolen: anybody here use org-babel w/ Clojure much?

11:55 clgv: dnole: what is org-babel?

11:55 dnolen ^^

11:55 dnolen: clgv: http://orgmode.org/worg/org-contrib/babel/

11:56 clgv: org-mode is one of the fancier Emacs apps, org-babel seems like a pretty interesting way to do literate programming.

11:57 clgv: dnolen: ok, emacs internas are greek to me ;)

11:58 hugod: dnolen: I use it

11:58 dnolen: hugod: thoughts? tips?

11:58 hugod: I had to hack it to get it to use an existing repl, I seem to remember

12:00 dnolen: hugod: do you actually code your libs with it?

12:00 hugod: dnolen: I use it for pallet documentation - after the fact

12:02 dnolen: hugod: interesting, seems like it allows you to document your code in a deep way while making it easy to extract the actual source.

12:03 clgv: provided I use leiningen - what is the easiest way to get the version number that is defined in my project.clj when running my standalone.jar?

12:03 hugod: dnolen: it's useful to check that the documentation examples actually run

12:03 technomancy: dnolen: someone did a crazy rewrite of the starter kit using babel

12:04 I can't say I like the way org intersperses code and prose; cosmetically it just rubs me the wrong way

12:04 scgilardi: we've decided that should be ugly

12:05 technomancy: #+begin_src ; eww

12:05 scgilardi: hehe

12:05 scgilardi: is that a reference to the lack of def-?

12:05 scgilardi: busted!

12:15 dnolen: technomancy: is that so different from heavily documented code?

12:18 Scriptor: there's the whole literate code movement

12:23 devn: Does swank-clojure 1.3.2 work with clojure 1.3.0-beta1

12:23 It's broken for me...

12:23 technomancy: dnolen: maybe if I had it set up to font-lock right it would sit better with me

12:23 devn: I don't know. sounds believeable

12:23 devn: yay, technomancy is here.

12:24 dnolen: technomancy: (setq org-src-fontify-natively t) ;)

12:24 devn: annddd, I'm an idiot: I had another swank session started

12:29 hugod: technomancy: I got the lein style checkouts working from a maven plugin :)

12:33 technomancy: hugod: handy!

12:34 hugod: just need maven 3.0.4 to have it work with maven projects in the checkouts (as well as lein projects)

12:35 lightningzephyr: Is it just me, or if I don't upgrade lein every time I begin a new clojure project, I have dependency failures when I try to build?

12:36 Because, you know

12:36 That's kind of silly

12:42 technomancy: old versions of lein referenced build.clojure.org as a maven repo, which clojure/core has deprecated

12:42 lightningzephyr: Ah

12:42 I saw a thing on the internet

12:43 About a survey from people about their experiences with clojure

12:43 It was... illuminating

12:44 I was unaware there was a IRC room, for instance :)

12:44 Kind of helps when it seems most example code online stopped actually working a while ago

12:45 technomancy: man if you judged clojure by the mailing list, you would really be missing out

12:45 and yeah, rule 1 of clojure is don't trust blog posts

12:45 actually there's already a rule 1

12:45 rule 2

12:45 clojurebot: rule 2 is don't trust blog posts.

12:45 clojurebot: In Ordnung

12:45 lightningzephyr: lol

12:45 technomancy: clojurebot: rule one

12:45 clojurebot: rule one is if your answer to "how should I represent X" is "something that doesn't implement clojure.lang.IFn" then you are probably wrong.

12:46 lightningzephyr: LOL

12:46 best bot

12:46 also, technomancy -- that rings many bells

12:46 Surely I've seen that name attached to clojure related things?

12:46 hugod: technomancy that reminds me - were you referring to stevedore script functions?

12:51 technomancy: hugod: not really, just chiding the author of that pragprog article for using the term "dsl" when he meant "compiler"

12:53 hugod: it's true though that the exception you get on invocation errors for script functions could be a little more helpful

13:28 volton: Hi, how do I get Clojure to work nicely with swank and slime?

13:28 In Emacs I should say

13:29 I tried clojure-jack-in but all I got was: Copying 1 file to /Users/philipp/Desktop/Lisp/Firehose/lib

13:29 user=> Connection opened on local port 61889

13:29 #<ServerSocket ServerSocket[addr=localhost/,port=0,localport=61889]>

13:30 technomancy: volton: you have an old version of swank-clojure installed somewhere (either in lib/dev via project.clj or in ~/.lein/plugins)

13:35 volton: technomancy: I deleted .lein and installed leiningen again

13:35 Now I get the following in *Messages*: error in process filter: eval-buffer: Symbol's function definition is void: define-slime-contrib

13:35 error in process filter: Symbol's function definition is void: define-slime-contrib

13:42 technomancy: volton: my guess is you have an incompatible version of slime installed somewhere

13:42 volton: technomancy: I installed it with quicklisp, was that a bad idea?

13:43 technomancy: I don't know; isn't quicklisp for handling CL libs?

13:44 swank-clojure is only compatible with a single version of slime, probably not the one that CL wants to use

13:46 volton: technomancy: yes, I am trying to get CL and Clojure play along nicely. My version of slime is slime-20110619-cvs

13:47 technomancy: sorry, I don't know how to make that work.

13:48 volton: technomancy: why is swank-clojure dependent on one specific version of slime?

13:49 technomancy: volton: because slime breaks all the time, and I don't have the time or motivation to follow it closely

13:49 volton: technomancy: I see, that sounds reasonable ;-)

13:49 technomancy: also because slime devs refuse to release stable versions; they just expect people to follow CVS for everything

13:49 jcromartie: what's the best way to name fns that use side effects to retrieve data, like from a database? should it be "get-..." ?

13:51 volton: technomancy: thank you, in this case I guess I will stick with the Netbeans plugin

13:51 If only Maven would finish downloading the internet...

13:52 technomancy: it seems most people lose interest in CL once they learn clojure, so it hasn't proven to be much of a problem in practice

13:52 amalloy: jcromartie: i prefer fetch

13:52 java has polluted "get"

13:53 or read

13:53 volton: technomancy: you are right, I could just set my inferior lisp to lein repl and use that

13:54 jcromartie: amalloy: true

13:57 volton: I hope this is not a dumb question but is there an advantage to learning clisp instead of clojure?

13:57 Scriptor: volton: so the advantages of common lisp over clojure?

13:58 volton: Scriptor: yes

13:58 amalloy: uhhhmmm. i guess the advantage is "if you are the sort of person who will prefer knowing clisp to knowing clojure, you should learn clisp"

13:58 Scriptor: not a dumb question, just a huge question :p

13:58 technomancy: CL has better support for VAX filesystems

13:59 amalloy: CL's certainly got a more thorough reference manual

13:59 Scriptor: it's probably easier to quickly google for CL stuff

13:59 although clojuredocs.org helps

14:00 amalloy: Scriptor: not sure about that one really

14:00 clojure is a pretty unique word to put in a search; "common" and "lisp" could mislead google

14:00 symbole: CL doesn't require a VM.

14:01 amalloy: s/require/get to use

14:01 Scriptor: amalloy: true, but more often than not every time I search the initial result is just clojure.org/libraries, clojure.org/datatypes, etc.

14:01 amalloy: (but yes, it's an advantage in some ways)

14:01 fair point

14:02 technomancy: if you time-travel back to the 1980s, your CL knowledge will still be useful. clojure, not so much.

14:02 Scriptor: volton: you'd have proper TCO

14:02 symbole: CL has better tools.

14:03 technomancy: Scriptor: depends on the implementation. it's not required in the spec.

14:03 Scriptor: technomancy: clisp has it though, right?

14:03 technomancy: oh, dunno

14:03 I was under the impression it was rare

14:04 sjl: Scriptor: I think you have to do something special to enable it

14:04 Scriptor: really? I thought it was common, considering how often clojure's lack of it is brought up :)

14:04 technomancy: Scriptor: it's the schemers that complain

14:04 volton: Scriptor: I have still not figured out if TCO is something that you actually need

14:04 sjl: Scriptor: Yeah, (compile 'some-tail-recursive-function)

14:05 volton: From a noobie standpoint, clojure has a more modern feel to it, when it comes to function names for example

14:06 mapcar is just called map for example (as far as I know)

14:06 Scriptor: I think some CLers complain that Clojure's "mini-languages" make it less uniform, though I disagree

14:07 symbole: Scriptor: What mini-languages?

14:07 Scriptor: volton: being that it's a lisp 1 clojure is a bit nicer to use for functional programming, if you're into that

14:07 symbole: referring to this: http://blog.fogus.me/2010/03/23/clojures-mini-languages/

14:07 volton: symbole: http://blog.fogus.me/2010/03/23/clojures-mini-languages/ I guess

14:08 :-P

14:08 Scriptor: ah, the guy complaining is a schemer, not CL

14:08 symbole: CL has most of those too.

14:09 volton: Is clojure's support for parallelism really better than CLs?

14:10 technomancy: volton: CL's data structures are mutable by default, which is madness for parallelism

14:10 Baker's equality paper makes this really clear

14:10 clojurebot: equal rights for functional objects?

14:10 clojurebot: Your mock object is a joke; that object is mocking you. For needing it. -- rhickey

14:10 symbole: volton: I think locking is the predominant model.

14:10 technomancy: clojurebot: come on man, this is basic stuff.

14:10 clojurebot: c'est bon!

14:11 volton: technomancy: found the paper, I will have a look at it

14:11 technomancy: clojurebot: Equal Rights for Functional Objects is Baker's paper on equality and why it's impossible to define sensible equality in the presence of mutable data structures: http://home.pipeline.com/~hbaker1/ObjectIdentity.html

14:11 clojurebot: Ack. Ack.

14:12 technomancy: if you read that still want to pursue CL, more power to you; at least you'll know what you're getting into.

14:13 volton: technomancy: I think I will go with Clojure. I don't want to learn another language that requires locking for parallelism

14:17 Thank you guys, you definitely helped me make my mind up!

14:18 symbole: volton: You should go #lisp and ask them too.

14:20 technomancy: symbole: are you saying that #clojure may not be the #1 source for objective straight-up facts on which lisp dialect is the best? I'm shocked.

14:20 I actually had a CLer in #emacs try to convince me that Scheme and Clojure were "not lisp dialects" simply because they weren't CL.

14:21 it's always fun when you can shoot down an argument simply by linking to the wikipedia article for a given logical fallacy: http://en.wikipedia.org/wiki/No_true_Scotsman

14:22 volton: That's why I went here to ask, I'm a bit afraid of Lispers since I asked some questions in #emacs

14:23 Hodapp: technomancy: That's not entirely a "No true Scotsman" fallacy unless it's got a particular context.

14:24 technomancy: he linked to a naggum article that basically made that case.

14:24 volton: I read a blog post by someone once arguing that there was no point learning clojure as its best feature would surely make their way into CL over the next 10-20 years

14:25 Hodapp: technomancy: However, all of those things are definitely Lisps, they're just not Lisp. Or LISP. Or something like that.

14:26 technomancy: If it resembled "No Lisp would have that property." "Scheme has that property." "No _true_ Lisp would have that property." then it'd certainly be that.

14:27 technomancy: hm; yeah. it was basically a very circular definition, but I don't know if it followed that redefinition-by-exclusion pattern.

14:27 jweiss_: clojure.contrib.trace/dotrace expects a literal list of fn's to trace. what if i want that list to be computed?

14:27 i think i'm hosed unless i write my own trace macro

14:28 Hodapp: technomancy: Hurry up and say something stupid so I can make a pun about you not making a _true_ "no true scotsman" fallacy.

14:28 technomancy: Hodapp: oh man that would be so awesome.

14:28 I'm ashamed I didn't think of that myself

14:28 Hodapp: lol

14:29 pjstadig: no _true_ logician would have done that

14:29 Hodapp: 9_9

14:32 volton: Here's the post I was referring to, it's depressing: http://axisofeval.blogspot.com/2010/04/why-i-ignore-clojure.html

14:34 Hodapp: tl;dr HEY YOU KIDS GET OFF MY LAWN

14:35 technomancy: yeah, that is a naggum-level troll.

14:37 Hodapp: They're... Lisp hipsters. Lispsters?

14:37 "I used Lisp before it was popular."

14:40 symbole: I think it's only lispers on the internets. I've met real life lispers who has nothing but good things to say about Clojure.

14:40 jcromartie: Lispsters... oh no

14:40 I interviewed a guy who said "oh yeah, Lisp, that is probably my least favorite language... all the parentheses"

14:40 Hodapp: bleah, I hear that a lot

14:41 jcromartie: I had to show him paredit-mode

14:41 Hodapp: along with "I hate Python, whitespace indentation sucks"

14:41 jcromartie: he was a MS in CS

14:41 Hodapp: and a first-year CS student who hated Python because it was "too easy"

14:41 jcromartie: hah

14:41 too easy... go use Malbolg

14:41 *e

14:41 Hodapp: and he said that C++ was "pretty easy" and "pretty much the same as assembly"

14:42 jcromartie: I will accept "C is basically portable assembly language"

14:43 but C++... not so much

14:43 Hodapp: C++ is a clusterfuck that needs to be taken out back behind the shed and shot.

14:43 C, I am okay with.

14:43 The problem that I always hit is how many people think that C++ is simultaneously C and $higher_level_language

14:44 jcromartie: is there an idiomatic way to get a hash-map with only certain keys in it?

14:44 Hodapp: when really it sucks very badly at being either

14:44 jcromartie: I already have (into {} (filter (comp keys key) m))

14:44 mefesto: jcromartie: i think select-keys ?

14:45 jcromartie: ,(let [f (fn [keys m] (into {} (filter (comp keys key) m)))] (f {:x 1 :y 2 :z 3} #{:x :y}))

14:45 mefesto: ,(doc select-keys)

14:45 clojurebot: java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry

14:45 "([map keyseq]); Returns a map containing only those entries in map whose key is in keys"

14:45 jcromartie: erp

14:45 ah

14:45 nice

14:45 I should use find-doc

14:46 (more often)

14:47 jweiss_: is there a non-roundabout way to get a ns-qualified symbol from a non-qualified one?

14:48 all i can see is converting to strings and then using (symbol ns name)

14:49 mefesto: ,(resolve 'inc)

14:49 clojurebot: #'clojure.core/inc

14:49 jweiss_: mefesto: that is a var, not a symbol

14:49 mefesto: ah

14:49 jweiss_: i don't know how to go from var->symbol either

14:49 just the other way

14:53 amalloy: (comp symbol name)?

14:53 oh you're going the other way

14:53 ,(-> 'inc resolve meta :name)

14:53 clojurebot: inc

14:54 mefesto: ,(let [x (resolve 'inc)] (symbol (str (.ns x)) (str (.sym x))))

14:54 clojurebot: clojure.core/inc

14:54 mefesto: meh :-\

14:55 non-preferrable route :)

14:55 amalloy: why do you want to do that, anyway?

14:56 jweiss_: amalloy: i'm trying to grab all the fn's in a namespace and pass them to clojure.contrib.trace/dotrace

14:56 but since it's macro, i have to wrap it in another macro

14:56 amalloy: dotrace won't accept vars?

14:57 jweiss_: amalloy: hm... maybe it will

14:57 i'll try

14:57 amalloy: doesn't look like it, from the source

14:58 jweiss_: amalloy: yeah that is why i didn't try it before

14:59 yeah i get CCE

14:59 so no vars

14:59 boo

15:00 mefesto: any clojurians jump on google+ ?

15:01 symbole: Join my "Clojure is not a Lisp" circle. 8-)

15:01 jweiss_: i'm on google+

15:02 technomancy: I was on g+ until I "upgraded" my apps account and it decided not to be available for my organization; woo!

15:18 cemerick: Clojure isn't a lisp anymore?

15:18 Oh well, it was nice while it lasted.

15:22 mefesto: finally things at work quiet down enough that I can catch up on the mailing list and #clojure and today both are fairly quiet :)

15:48 Dranik: hi all!

15:48 how to use the ring's parameter :content-type to set utf8 encoding?

16:29 benhur: doseq

16:29 doseq

16:30 chouser: doseq!

16:30 do! seq!

16:31 cemerick: chouser: you just invented an Ook! dialect.

16:38 jcromartie: see seq, see seq do, doseq do

16:54 chouser: heh

16:57 jcromartie: so I've got an itching to implement a multimethod-based interface for messy table queries in ClojureQL

16:57 since our DB sucks

16:58 AWizzArd: What is algo.monads?

16:58 jcromartie: like, if I wanted to apply some restriction to a table without knowing which table it was and what columns it uses for the particular restriction

16:58 like, (limit-date foo "2011-07-01" "2011-07-10") might use different columns for different tables

16:59 seems like a good fit for the mutlimethod dispatch

16:59 (defmethod limit-date :tname)

16:59 err

16:59 defmulit

16:59 you know

17:02 AWizzArd: What is algo.monads?

17:02 hmm

17:04 dnolen: AWizzArd: probably Konrad Hinsen's monad library from contrib

17:16 chrissbx: What is iota called in Clojure again?

17:17 amalloy: chrissbx: start with telling us what iota does in scheme :P

17:18 chouser: hm. maybe 'atom'?

17:18 chrissbx: hm well range seems to be it.

17:18 I think iota is standard in mathematics, which is why I omitted an explanation.

17:18 amalloy: $google iota math

17:18 sexpbot: First out of 33300 results is: Greek letters used in mathematics, science, and engineering ...

17:18 http://en.wikipedia.org/wiki/Greek_letters_used_in_mathematics,_science,_and_engineering

17:18 chouser: hm, indeed. range.

17:19 amalloy: chrissbx: afaict from wiki, that's only true in apl, not in other math contexts

17:28 jonabbey: ,(doc when-not)

17:28 clojurebot: "([test & body]); Evaluates test. If logical false, evaluates body in an implicit do."

17:28 chrissbx: Hm, I've seen it used in other contexts than APL and Scheme.

17:29 But I'm not a mathematician; seems I've mis-concluded from having it seen relatively widely that it would come from there.

17:30 Haskell seems to prefer "range", too. "Range" seems a bit odd since (I think) that is defined in math also for reals (or maybe other stuff).

17:31 In fact I've implemented a "range" datatype in Scheme exactly to specify ranges with min and max without need to itemize.

17:31 Sushi_: Not necessarily a clojure question, but does anyone know of chars that could go to stdout that would destroy the terminal buffer?

17:31 I'm spitting something out that keeps ruining the terminal output before it

17:32 mefesto: Sushi_: maybe backspace characters? "\b" or maybe \backspace ?

17:32 chrissbx: (I implemented min and max or just min or just max, in fact)

17:33 Sushi_: mefesto, I'll look for those, thanks. It's weird because if I dump the output to a file it looks fine...

17:34 chrissbx: amalloy: http://en.wikipedia.org/wiki/Interval_(mathematics) seems closer to describe what "range" does. (Maybe hence the iota)

17:35 except that they default to real here.

17:35 Maybe a mathematician could enlight us.

17:35 devn: I'm a trained mathemagician.

17:43 AWizzArd: dnolen: It seems it was just recently added to build.clojure.org

18:53 mattmitchell: Is it possible to get the parent namespace? The one that "uses" another?

18:57 amalloy: no such thing exists

19:04 mattmitchell: amalloy: Were you answering my ns question?

19:04 amalloy: yes

19:04 mattmitchell: amalloy: Ok thanks

19:51 Cozey: Is it possible to define a macro creating a (defun )

19:51 and then use this macro with ^:private, so the ^:private applies to the (defun ) ?

19:53 cemerick: Cozey: if you just reuse the name provided by the user of the macro, then any metadata (including ^:private) will be carried along without you doing anything

19:53 And, it's defn, not defun ;-)

19:53 Cozey: oh yes. i just did some emacs lisp today :-)

19:54 what do You mean by reuse?

19:55 oh ok! it's working

19:55 :-)

19:55 how is it working?

19:55 btw?

19:56 how does clojure compiler knows how to apply this meta-annotation to the form returned ? (since the form could be anything)

19:56 cemerick: Cozey: The metadata is on the symbol, which you're just carrying over from the macro invocation to the form you emit from it.

19:56 Cozey: mmhm

19:56 and it works for all kinds of def's?

19:56 or maybe in reality there is just one kind of def

19:57 others being macros as well

19:57 Oh I love this language. why don't people already know it

20:00 Chousuke: Cozey: that's right :P

20:00 def is all you need

20:00 ,(macroexpand '(defn foo [x] (bar x)))

20:00 clojurebot: DENIED

20:00 Chousuke: oh right

20:00 blah

20:01 Cozey: I'll do that at home.

20:02 Chousuke: it just expands to a (def foo (fn ...)) :)

20:04 cemerick: Cozey: this might help? https://gist.github.com/562cc9580b0579de8179

20:05 amalloy: cemerick: flaunting your shiny new 1.3 features in front of us luddites. so cruel

20:06 Cozey: cemerick: ah.... I get it

20:07 so this meta is on lower level

20:07 good. I use 1.3 fortunately

20:13 cemerick: Cozey: it'd work on 1.2 too; 1.3 just adds the ^:foo shortcut for ^{:foo true}

20:14 Cozey: mhm

20:14 * cemerick anxiously awaits 1.4.0-SNAPSHOT builds (amalloy :-P)

20:16 amalloy: cemerick: clojure is way behind the times, using minor versions. should follow chrome/ff and switch to version 22

20:16 technomancy: might as well skip to 25 so it's ahead of elisp.

20:17 amalloy: technomancy: that would be so presumptuous. clojure isn't even a lisp

20:48 pcavs: amalloy: buhhh, whaaa? DId I miss something?

20:50 amalloy: pcavs: (11:20:55 AM) technomancy: I actually had a CLer in #emacs try to convince me that Scheme and Clojure were "not lisp dialects" simply because they weren't CL.

20:50 then a bunch more derision on that topic

20:51 pcavs: amalloy: oh boy...

20:52 amalloy: technomancy: What's the story of GUILE replacing ELisp? My friend said that they had a reasonably working Emacs on GUILE

20:53 that would be swell, what would you do with continuations on emacs? You could use AMB!

20:53 cemerick: I thought #emacs was supposed to be reasonably reasonable?

20:53 Scriptor: every channel has its bad apples

20:53 pcavs: oh, I have nothing against elisp, well besides the dynamic scope

20:54 Scriptor: doesn't the new version have lexical scope?

20:54 pcavs: well that'll screw up a whole bunch of elisp...

20:55 I remember looking at the .el's and being shocked to see bindings that only existed to take call another function with that variable getting shadowed...everything being a global variable is kind of scary =\

21:05 technomancy: lexical scope is opt-in for compatibility reasons

21:06 yeah, #emacs is usually pretty decent, but there's a CLer in there with a chip on his shoulder

21:08 he also argued that mutable strings and vectors in CL weren't a problem because you can just audit all the libraries you use to make sure none of them contain any mutation.

21:20 ssideris: so, and sorry for being so completely off-topic, who's buying a macbook air tomorrow

21:20 I'm trying really hard not to

21:20 (if the rumours are true)

22:08 cemerick: technomancy: any way to get lein to run javac before AOT-compiling Clojure?

22:09 s/before/after

22:09 sexpbot: <cemerick> technomancy: any way to get lein to run javac after AOT-compiling Clojure?

22:24 Scriptor: does anyone know of a list of 4clojure answers?

22:25 I keep getting the nagging feeling that mine aren't idiomatic enough

22:31 amalloy: Scriptor: youz has one on github

22:33 https://github.com/youz/4clojure-golf but obviously he focuses on short solutions rather than pretty

22:34 Scriptor: amalloy: thanks

22:42 ihodes: Scriptor: run by a gist/pastebin of a bunch in here

23:03 technomancy: cemerick: it should happen if there's a :java-src key in project.clj

23:03 oh, he left

23:43 jamiltron: I was wondering the same thing about 4clojure - I have many solutions, but several of them probably have much more Clojure-ish ways of doing them. Can I link a gist of one of the solutions to get some advice?

23:44 amalloy: jamiltron: knock yourself out

23:47 jamiltron: https://gist.github.com/1081904

23:54 I feel that sort of answer is more of a dirty form of Scheme than it is of Clojure.

23:55 amalloy: jamiltron: have to say that's pretty dreadful :)

23:55 one thing you're missing is that clojure has vectors, which append to the end instead of consing to the front, so your tail-recursive solutions don't have to end with a reverse

23:57 it also seems to me that you're basically reimplementing reduce, right? you consume exactly one element of n in every iteration, so you can use reduce to manage the "walk over the whole list" part of the problem

23:57 jamiltron: Oh so have the "n" in pack-iter be a empty vector, and then instead of using cons use conj instead.

23:58 too many insteads

23:58 amalloy: right, basically

23:59 if you'd like a hint on a really neat way of doing it, check out ##(doc partition-with)

23:59 sexpbot: java.lang.Exception: Unable to resolve var: partition-with in this context

23:59 amalloy: &(doc partition-by)

23:59 sexpbot: ⟹ "([f coll]); Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy seq of partitions."

23:59 jamiltron: Ah thanks

Logging service provided by n01se.net