#clojure log - Oct 20 2008

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

0:00 AWizzArd: well, one can code object oriented in all programming languages.. but usually this is done mostly in imperative ones

0:00 sohail: ok...

0:00 AWizzArd: Just see what the ML and Haskell guys are doing. After doing this a few months you won't miss anything

0:00 sohail: well let me create a bad object for you: {:Shape :Circle}

0:00 \o/ no radius!

0:00 anyway, this was just something I was thinking while going through the reference

0:01 I might just write something to straight-jacket myself

0:01 AWizzArd: multimethods are just a subset of pattern matching

0:01 Clojure has no pattern matching (by descision) so it gives us destructuring and multimethods

0:03 sohail: AWizzArd, thanks for your help

0:03 whenever one encounters something new, one always attempts to make it fit past experiences

0:03 rukubites: sohail: yes, lisp has always been about great power, and it is up to you to exert the great responsibility.

0:03 hoeck: sohail: right :)

0:03 AWizzArd: of course one does.. but try to forget oop fully and dive into pure functional programming

0:04 sohail: see something else that bothers me is that everything is typeless

0:04 no it isn't

0:04 damnit, you can figure out the type of a struct right

0:04 AWizzArd: you can

0:04 sohail: how?

0:05 AWizzArd: (class (struct foo 10 20))

0:05 ==> #=clojure.lang.PersistentStructMap

0:05 just think of other names

0:06 defstruct confuses you, because it absolutely has nothing to do with structures

0:06 sohail: AWizzArd, but how can I determine that (struct foo 10 20) was of type foo?

0:06 AWizzArd, probably

0:06 AWizzArd: as you know them from C, Lisp, whatever. Nothing with structs, nothing with classes

0:07 rukubites: sohail: if it contains the keys a foo contains.

0:07 AWizzArd: what is the type of this (list 'foo 10 "hallo") ?

0:07 sohail: a list?

0:07 AWizzArd: right

0:07 and whatever it contains, it will not change

0:08 a Structured Map is a different data type

0:08 sohail: ok so what if I have an app that is filled with structs all over the place which I created using (struct foo ...), and now I need to dispatch on the different foos?

0:08 seems I have no options

0:08 AWizzArd: it is like a list that you write on a piece of paper.. you write columns with headlines, and then add rows

0:08 like a table in sql

0:09 sohail: well I have very inefficient options (compare all the keys!)

0:09 AWizzArd: (defstruct ..) could have been named as: (create-new-table ...)

0:09 sohail: I understand that

0:09 AWizzArd: yes

0:09 sohail: it's a collection of stuff

0:09 AWizzArd: you can go on and build up structures as you know them

0:09 sohail: so it seems the right way to get away from that is to always have some indirection

0:09 AWizzArd: but defstruct has nothing to do with them

0:10 arohner: sohail: the keys in a struct do not define a type

0:10 sohail: so there can be no types like cats and dogs?

0:10 AWizzArd: struct is short for 'Structured Map'

0:10 sohail: for now thing that there are no types such as cats and dogs

0:11 think

0:11 sohail: ok

0:11 AWizzArd: but of course you could always implement the abstractions to have them

0:11 Clojure wants to leave the land of types

0:11 that was yesterday

0:11 Clojure is doing it more general

0:11 no dispatch on types

0:12 sohail: I ese

0:12 see

0:12 this is the philosophy of the language

0:12 yes, quite different!

0:12 AWizzArd: it may be unfortunate that the name (defstruct ..) reminds people of something

0:12 it is very difficult to stop ones brain to do its associational work

0:12 sohail: so it is typeless

0:12 well, the type system is fixed

0:12 AWizzArd: everything has a type

0:12 rukubites: AWizzArd: To be fair, it is also used as the basis of polymorphism, which encourages the thought of it as an object.

0:13 AWizzArd: ok

0:13 arbscht: sohail: you can tag an object either with a property, or with metadata, if necessary

0:14 sohail: arbscht, sure

0:14 but then we are getting into object system on top of clojure territory

0:15 arbscht: there is common ground, naturally

0:15 AWizzArd: you will just need some weeks-months training in functional programming, and you will see that Clojure is 4-dimensional and you can give up 2-dimensional thinking :-)

0:16 sohail: perhaps

0:16 I just don't see what doing everything by the seat of your pants has to do with functional programming :-)

0:16 but I'm willing to find out!

0:16 * sohail clicks on "Metadata" chapter

0:17 walters: sohail: the main thing about clojure is immutable data structures; objects tend to be mutable

0:18 sohail: walters, I find that totally orthogonal to not being able to extend the type system, but that's just me

0:18 I should shut up now before I piss you all of and then no one will help me

0:18 s/of/off/

0:21 AWizzArd: wait, I give you another example

0:22 (defmulti foo (fn ([collection] (first collection)) ([a b] (+ a b))))

0:22 You understand this so far?

0:23 arohner: sohail: I understand your ... anxiety. I've been in that situation when learning clojure

0:24 and by type system, what you really want is to assert that a collection of data fits into a pattern

0:24 i.e. your shape example, a circle would be {:shape :circle, :radius 3}, right?

0:28 AWizzArd: sohail: just have a look how you can use multimethods in this paste:

0:28 lisppaste8: AWizzArd pasted "Generality of multimethods" at http://paste.lisp.org/display/68846

0:29 rukubites: I am curious why defmulti only supports one argument.

0:29 AWizzArd: rukubites: in my example you see they support not only one, but even mixed

0:29 one and the same multimethod can have one arg or three

0:29 rukubites: Oh hang on, yes.

0:31 I was getting sidetracked by the example which only uses defstruct. Another example using something like evenp would be cool.

0:33 AWizzArd: Your example is convincing me that clojure is quite cool. :)

0:35 AWizzArd: rukubites: (foo [\H 2 3])

0:35 rukubites: You can do something like (defmulti foo (fn [&more args] (map class-of args))) or the equivalent? Sorry I can't actually write proper clojure being as I have looked at it only today.

0:35 AWizzArd: it's turing complete

0:36 rukubites: My example is meant to mean that you define a dispatch that polymorphs according to each of its argument's classes.

0:36 AWizzArd: in the method that you provide to the macro "defmulti" you can do whatever you want

0:36 rukubites: Yes. Would the above work something like what I intended?

0:36 arohner: AWizzArd: wow, that's more powerful than I thought multimethods were

0:38 rukubites: And of course you can just write a macro which expands to defmulti to more easily express how you want your polymorphism to work.

0:38 AWizzArd: You can think of it this way: (defmulti foo dispatch-fun) means: when you do (foo something) then dispatch-fun will be called with something. This will yield a value. Then all multimethods are checked until one is found whose second argument is equal to the value from the call (dispatch-fun).

0:38 Then the function you provided to that multimethod is called with "something"

0:40 So, (foo 2 4) ==> it calls my (fn ..) that was provided in (defmulti foo ...). As it has two args the second branch is used: (fn [a b] (+ a b)). For the args 2, 4 it yields 6.

0:41 Now the foo-method that has the key 6 will be called with the args 2 and 4. This is (defn foo [arg1 arg2] (* arg1 arg2)). So, the result is 8.

0:44 this is much better than dispatching on types only

0:46 rukubites: Sorry for a silly question... I want to access java.lang.Object.getClass() on object foo. How...?

0:47 Oh got it.

0:47 (. foo getClass)

0:49 AWizzArd: and I forgot again how to call System.out.println

0:51 no right (.println System/out "huhu Leute")

0:52 I'll go to bed, n8

1:04 lisppaste8: rukubites annotated #68846 with "More polymorphism" at http://paste.lisp.org/display/68846#1

1:04 rukubites: That's my first clojure code.

1:04 (from a fulltime CL programmer)

1:13 sohail: rukubites, where do you work anyway

1:13 <arohner> i.e. your shape example, a circle would be {:shape :circle, :radius 3}, right?

1:13 yes, that is all I want

1:13 to ensure a specific pattern automatically

1:15 rukubites: sohail: I am actually a contractor, been working on a common lisp project for a few days short of a year. I telecommute from Australia.

1:15 sohail: rukubites, ah, I see

1:17 rukubites: sohail: And with respect to your problem, you are probably going to have to write your own object-verification functions and slot them into defmulti.

1:17 For fun, that's what I did in my link above, using a function "classes-of".

1:18 Though that solution is brittle and unworkable IRL.

1:18 sohail: rukubites, sure :-)

1:43 Pupeno: So, if I am using a functional programming language, I can stop worrying about ORM?

1:44 rukubites: ORM?

1:44 H4ns: Pupeno: yes - you need to worry about how to persist your data, but ORM will not be your solution anyway

1:44 * H4ns would argue that ORMs are a non-solution anyway, but that does not apply to clojure

1:53 Pupeno: rukubites: Object Relational Mapping.

1:53 burkelibbey: When I run slime-eval-last-sexp on a sexp with a line break in it (eg. (+ 2 <\n> 2) ), I get "insert-before-markers: Invalid character: -1, #o37777777777, #xffffffff". Anyone seen that before?

1:53 rukubites: Pupeno: Ahhh yes. E.G. AllegroCache.

1:54 Pupeno: rukubites: in object oriented programming languages you end up using one ORM or another whenever you want to talk to a DB, and you can see that some people, like H4ns believes none should be used. It's a very heated debate with no clear solution.

1:54 rukubites: that doesn't sound like an ORM, but I'm not sure.

1:54 burkelibbey: Eg. ActiveRecord, DataMapper, and so on.

1:56 rukubites: Well I get the idea. We have dealt with issues of objects <--> DBs on my project, just wasn't aware of the term.

1:57 "AllegroCache is a high-performance, dynamic object caching database system."

1:57 It's by Franz.

1:58 Pupeno: rukubites: yes, I don't think that's an ORM. cl-sql is ORMish.

1:59 burkelibbey: The impression I get is that AllegroCache provides its own persistence layer, where a true ORM just interfaces between the language and a (usually SQL-based) database backend

1:59 rukubites: Postmodern then. :-)

2:00 We are currently using the solution of 128gb ram :(

2:00 Pupeno: burkelibbey: right, you have to have something Relational there to Map to.

2:02 mmhhh... this web frameworks should be broken down into libraries, for HTML generation, for SQL, etc... both Compojure and Webjure seems to suffer from all-in-one-monolithic-pack.

2:04 rukubites: burkelibbey: By the way, your swank example works fine for me.

2:04 burkelibbey: rubikites: Yeah, I figured as much. I'm not sure what I've done wrong. I'll probably go update all my elisp stuff. Thanks.

2:06 err, I suck at reading

2:06 sorry about that massive typo

2:06 rukubites: I like rubikites. :D

2:06 burkelibbey: haha

2:06 rukubites: It helps if I capitalize it as RukuBites.

2:06 tWip: Pupeno: webjure now has html and sql stuff in their own files and namespaces

2:07 burkelibbey: Much better :)

2:07 tWip: For my needs, HTML generation is very much a core functionality in anything resembling a web framework... so it is included

2:09 RukuBites: burkelibbey: Now try doing slime-eval-print-last-expression on your example...

2:11 Lau_of_DK: Morning gents

2:12 burkelibbey: rukubites: Hmmm, weird. That just gives me "Evaluation aborted" regardless of what I'm evaluating.

2:12 RukuBites: Yes it does.

2:13 Pupeno: tWip: yes, that's good (own files).

2:13 RukuBites: burkelibbey: I've been told that it is to do with swank/eval-and-grab-output not being implemented.

2:13 It is my 100% favourite feature of SLIME. :(

2:14 Pupeno: tWip: eventually, someone will come with a different way of generating html and there would be an endless debate of the-better-vs-the-built-in, and that can be ugly, like what is happening now in Django or Rails.

2:14 Anyway, have to go now, to code for money. See you latter!

2:15 burkelibbey: RukuBites: too bad. I only ever played with CL for a couple of days, but liked that feature.

2:16 tWip: Pupeno: I have no problem with that. This is open source, you can always fork if you need something different

2:16 I'm doing the "scratch my own itch" thing :)

2:25 RukuBites: burkelibbey: Well as my second function to write in clojure, I will attempt to implement it. :-)

2:25 burkelibbey: Awesome, my swank problem is fixed. I just git pull'd clojure-mode, swank-clojure, and slime.

2:25 rukubites: ooh, I hope it works out. good luck!

2:26 RukuBites: Sorry, very silly question... does clojure support multiple return values?

2:27 I think the answer is no, just not 100% sure.

2:27 hoeck: RukuBites: no, not the way cl does, but its easy to return a literal vector and destructure the return value

2:28 RukuBites: Of course it is. :-) The issue was in implementing the above function. It is much easier now.

2:30 hoeck: RukuBites: what does eval-and-grab-output?

2:31 RukuBites: C-j in *slime-scratch*

2:32 It returns (a b) where a = *standard-output* of form and b = print-value of form.

2:32 a and b are strings.

2:33 (slime-eval-print-last-expression) is the emacs function.

2:34 hoeck: aha, yeah, missing that too

2:35 RukuBites: *nod* I thought so since I pulled all the stuff fresh this morning.

2:36 But I really feel like I'm coding with one hand tied behind my back without it.

2:39 How is Clojure for streams? Does it just rely on java stuff? I looked but am not sure of the topic on the main page. I want to rebind *OUT* and store it as a string.

2:41 Ooooh, with-out-str. Sweet.

2:59 *victory*

3:01 hoeck: RukuBites: can you paste it??

3:01 RukuBites: Am pasting.

3:01 * hoeck is tired from copying output from the slime-repl

3:02 lisppaste8: RukuBites pasted "Swank function for C-j in *slime-scratch*" at http://paste.lisp.org/display/68852

3:03 * burkelibbey approves

3:03 RukuBites: Me too and this is my fourth function written for the language.

3:03 Is it the correct idiom for clojure?

3:05 I will post it to the list as well, since it works decently for me.

3:05 Next on the list is to get slime to treat (in-ns ...) the same as it does (in-package ...)

3:09 * hoeck binds C-j to slime-eval-print-last-expression

3:09 hoeck: RukuBites: works perfectly, thanks!

3:10 jdz: RukuBites: why is there a with-out-str in there?

3:10 burkelibbey: RukuBites: Yes, much thanks.

3:10 RukuBites: jdz: Because that captures the *out* of the function.

3:10 jdz: RukuBites: and i think [retval nil] should be put a line above

3:11 RukuBites: *out* of which function?

3:11 RukuBites: (defn test-fn [] (do (println "Test") (+ 2 2)))

3:11 Try C-j on (test-fn) and you will see.

3:16 burkelibbey: Anyone have an opinion on paredit-mode?

3:16 RukuBites: I like typing my own pars.

3:16 burkelibbey: That's kind of how I'm feeling so far.

3:17 RukuBites: Also I think it rebinds C-j! :( :(

3:17 burkelibbey: ack, that's no good :P

3:19 rukubites: Have you relocated your parentheses, or do you just use shift+9/0 ?

3:20 I'm considering swapping mine with [] in clojure mode, but I'm not sure if I'll be able to deal with it being different everywhere else

3:22 RukuBites: burkelibbey: I just leave them as is, shift 9 and shift 0. My old laptop had euro and dollar keys just to the left and right of the "up" arrow, and I rebound them but never used it.

3:23 I found the hook for the in-package to in-ns.

3:23 burkelibbey: hmk. Well I need some sleep, thanks for al the help

3:23 nice

3:47 lisppaste8: RukuBites pasted "(in-ns 'foo) support for clj buffers in slime." at http://paste.lisp.org/display/68853

3:48 RukuBites: I think I will be quiet now. :-)

4:36 Lau_of_DK: Is anybody here able to explain (defn find= ...) from clj-me.blogspot.com ?

5:38 clp8: Can someone give me a had getting swank-clojure to work? I think I have the paths set correctly, but swank-clojure does not agree, because it can't find the clojure.lang.repl class. relevant part of my .emacs and the error is pasted here: http://paste.lisp.org/display/68860

5:52 Lau_of_DK: Try using absolute paths and no ~/

5:52 +t

5:55 clp8: Lau_of_DK: doesn't help

5:55 Lau_of_DK: it will be part of the solution

5:55 Did you otherwise follow instruction from the wiki ?

5:56 clp8: are you thinking that maybe ~ interferes with the jvm?

5:56 yes

5:56 everything is found, including clojure.jar, except that the repl class is not found

5:56 Lau_of_DK: ~/ is not accepted in elisp

5:56 But I notice that you dont set (setq inferior-lisp-program ...) , why not +

5:56 ?

5:57 clp8: if you're sure...because ~ works throughout the rest of my .emacs

5:57 hold on

5:57 i'm not sure why not

5:57 Lau_of_DK: really? it broke mine

5:57 I would put this in run-clojure

5:58 (setq inferior-lisp-program "/path/to/java -cp /path/to/clojure.jar")

5:58 clp8: I'm not setting it because I'm not using inferior-lisp mode directly, I'm using swank

5:58 (or, at least, trying)

5:59 i followed this: http://en.wikibooks.org/wiki/Clojure_Programming#Emacs_.2F_Slime_Integration

5:59 Lau_of_DK: ok, then Im blank. I set emacs up to run swank/slime, which works perfectly, just following the direction from the wiki

6:00 http://en.wikibooks.org/wiki/Clojure_Programming#Emacs_.2F_inferior-lisp

6:01 clp8: that isn't slime...that is using inferio-lisp-mode

6:02 *inferior

6:03 Lau_of_DK: skip to the section below

6:03 clp8: then we are indeed using the same guide

6:03 would you mind pastebinning the clojure section of your .emacs?

6:04 Lau_of_DK: I wouldnt mind, but its a home Im afraid, at work atm

6:04 H4ns: lisppaste8: url

6:04 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

6:04 clp8: i'm starting to think that my problem is related to using an old version of clojure. most of these guides are refering to a file called clojure-lang-1.0-SNAPSHOT.jar , and I have a file called something else

6:05 lisppaste8: H4ns pasted "Clojure related section from my .emacs" at http://paste.lisp.org/display/68861

6:06 H4ns: clp8: clojure-lang-1.0-SNAPSHOT.jar is the file that you get when you compile clojure from source.

6:06 clp8: (at least that is what i got)

6:07 clp8: hmmm. Perhaps I should do that, then

6:08 your line; (setq swank-clojure-binary "/home/hans/bin/clojure")

6:08 H4ns: clp8: does clojure work for you on the command line?

6:08 clp8: yes

6:08 but, I was going to ask, does that line link to? a binary, or a directory?

6:08 H4ns: clp8: it is a shell script

6:08 clp8: that launches clojure?

6:09 H4ns: clp8: i like that better than referring to the jar from emacs, as i will have the same setup in slime and on the command line

6:09 clp8: yes, with the right classpath and stuff.

6:09 clp8: ie, something that contains java -cp clojure.jar foo.bar.repl?

6:09 H4ns: exactly

6:09 clp8: i might try that, then

6:09 darn, I have a lecture :(

6:09 H4ns: it is a bastardized version from the clojure-extras git

6:09 clp8: i have to go, but I will be back in 50 minutes to bug this channel some more :) thanks for the help guy

6:10 *guys

6:10 Lau_of_DK: np

7:11 clp8: H4ns: that does not help me. It seems that java simply doesn't find the clojure.lang.repl class

7:17 hoeck: clp8: have you looked at the commandline params of the running jvm?

7:17 clp8: no, I haven't

7:17 how should I do that?

7:18 hoeck: on which os?

7:19 clp8: solaris

7:20 hoeck: then use ps or top

7:23 clp8: hmmm

7:26 hoeck: regarding slime, it worked for me by only setting things for swank-clojure using m-x customize-group swank-clojure

7:26 clp8: slime has always worked for me

7:27 it's just getting clojure to load right

7:27 i don't suppose you know what file clojure.lang.repl is defined it?

7:27 *in

7:28 hoeck: yeah, sorry, i meant setting swank-clojure classpaths

7:29 Repl.java :)

7:32 clp8: does evaling (swank-clojure-cmd) in emacs-scratch-buffer return correct classpaths?

7:36 clp8: hoeck: evaling this worked: (setq swank-clojure-extra-classpaths (list "/aber/clp8/Desktop/clojure/src/jvm/clojure/lang/"))

7:37 but it prints a bunch of exceptions and slime doesn't work right. this makes me think that classpaths are not set, or, at least, not set right

7:42 hoeck: clp8: evaling (swank-clojure-cmd) should return something like ("java" "-cp" "/..../clojure.jar:more-classpaths" "clojure.lang.Repl")

7:44 clp8: the only extra classpath is the one for REPL that I added myself

7:44 are classpaths recursive? could I just add the top of the clojure tree?

7:45 H4ns: clp8: no. you need to specify all the jars on the command line. very new jre's accept wildcards, too.

7:46 clp8: I see. This isn't mentioned in any of the wiki guides, though

7:46 i'll do that now

7:48 ...I only have one jarfile; clojure.jar

7:51 i think I might try building clojure from source, see if that improves the situation

7:51 I can't understand why java isn't looking in clojure.jar for the repl class

7:59 if I give the directory with clojure.jar in it, slime seems to work...sort of

8:31 AWizzArd: Moin

8:41 duck1123: is Stuart Halloway around? (or does anyone know what his nick is?)

9:04 * drewr had dinner with rhickey last night!

9:05 arbscht: cool :)

9:06 AWizzArd: May I get an autograph? :-)

9:43 RadioApeShot: Hi #clojure

9:44 I am trying to get the latest version of swank-clojure running under my emacs

9:44 AWizzArd: yeah, I had that too some days ago ;-)

9:44 RadioApeShot: But seem to be stuck

9:44 (add-to-list 'load-path "/path/to/swank-clojure")

9:44 (require 'swank-clojure-autoload)

9:45 My emacs chokes on (require 'swank-clojure-autoload) saying I need to set the path to the clojure jar

9:45 But the readme indicates I do this after require-ing swank-clojure-autoload

9:46 duck1123: I have mine set before, if that helps

9:48 H4ns: RadioApeShot: http://paste.lisp.org/display/68861 works for me

9:49 RadioApeShot: thanks

9:51 lisppaste8: AWizzArd pasted "Emacs config for Clojure+Slime" at http://paste.lisp.org/display/68867

10:00 AWizzArd: RadioApeShot: any progress?

10:12 hmm, was the svn restructured a bit?

10:13 Chouser: I don't think so. What are you seeing?

10:14 AWizzArd: Chouser: I was probably mistaken, nevermind

10:15 RadioApeShot: Sorry

10:16 Friend came in with boy troubles

10:16 So if I setq the clojure location before require-ing M-X Slime does bring up a clojure

10:16 But I get an error about *e

10:17 And a lot of Java stuff.

10:17 And then the REPL does show up

10:17 But I can't send s-expr to it.

10:18 Should I set up a lisp-paste or something with the backtrace?

10:18 duck1123: is that old swank-clojure or old clojure itself

10:18 someone had this problem the other day

10:18 I would recommend getting the latest of everything

10:19 AWizzArd: RadioApeShot: what version von Emacs do you have and what version of Java? Did you start Clojure with M-x clojure ?

10:21 As you can see, there was a function (clojure) defined which will call (slime 'clojure) and not try to run slime with Common Lisp.

10:23 RadioApeShot: Emacs 23, Java 1.6 (b11).

10:24 And there does not appear to be an interactive function called clojure on my system.

10:24 It may be an old clojure.

10:24 It is the latest binary release.

10:24 duck1123: I'm pretty sure that was the fix

10:24 RadioApeShot: Should I try to build clojure from something more recent

10:24 Ok

10:24 I have the source here already

10:24 duck1123: *e was recently added

10:25 this chan isn't publicly logged, is it?

10:25 arbscht: it is

10:25 RadioApeShot: get svn clojure

10:25 duck1123: http://clojure-log.n01se.net/

10:27 AWizzArd: I also had the problem with *e

10:27 because I downloaded the "binary Clojure" from the website first, and didn't compile my own via ant from svn

11:05 How can I call java.lang.String.hashCode()?

11:06 sohail: isn't it (. java.lang.String hashCode)?

11:06 wwmorgan_: AWizzard: (.hashCode "foo") ?

11:06 AWizzArd: wwmorgan_: yes.. but if I want to go the full path

11:07 I want to learn how to do it.. for example: System.out.println() ==> (.println System/out "foo")

11:07 wwmorgan_: You mean make sure you're calling String hashcode instead of Object hashCode?

11:08 AWizzArd: from that I would say: the method I want to call comes first, and then the rest of the path, delimited by slashes and not dots, so that would give me: (.hashCode java/lang/String "foo")

11:08 but this does not work

11:09 wwmorgan_: you could also do (. "foo" hashCode)

11:10 AWizzArd: But how can I know which hashCode method I am calling?

11:10 RadioApeShot: AWizzArd: Newest Clojure fixed it.

11:10 Thanks

11:10 AWizzArd: RadioApeShot: yes right, I had the same... just have a freshly compiled clojure.ant. Enjoy hacking! :-)

11:11 wwmorgan_: AWizzArd: Since clojure uses reflection to find the method to call at run-time, I think you'll get the closest fit if you don't specify which hashCode to call, ie the String hashCode

11:11 you could also use a type tag to specify which hashCode to call at compile-time

11:12 AWizzArd: So you think there is no way to enforce calling a specific method?

11:12 wwmorgan_: (let [string "foo"] (.hashCode #^String string))

11:13 alternatively (let [string "foo"] (.hashCode #^java.lang.String string))

11:20 Chouser: AWizzArd: in the .println example, System/out is not part of the "path" to the method, it's an instance of java.io.PrintStream

11:22 AWizzArd: i think these paths are called packages in Java?

11:22 Chouser: java and java.io are packages; java.io.PrintStream is a class.

11:24 AWizzArd: so how can I reference the three different categories of a "path"? I need sometimes the dot, sometimes the slash, telling what the package is, what the Object, and what the method is.

11:25 sometimes it is with a dot in the front, sometimes it is dotMethodName in the front (no space between dot and the method)

11:27 bbl

11:27 Chouser: the full name of a class includes the package path to it. In Java and Clojure these are separated with a dot.

11:29 to refer to a static field (like "out" in System) or method, use a slash (since in this case the class is just acting like a namespace)

11:30 System/out or java.lang.System/out (or you can use the older syntax (. System out) or (. java.lang.System out))

11:32 to refer to an instance field or method (like hashCode in String), use the leading dot and an instance (.hashCode "foo") (or you can use the older syntax (. "foo" hashCode))

11:34 in this last case (using an instance), if the compiler doesn't know the type of the instance, Clojure will have to do some reflection at runtime.

11:35 This reflection may be too slow in some cases, so it can be helpful to give the compiler a type hint: (.hashCode #^String "foo") or (.hashCode #^java.lang.String "foo")

11:36 sorry, that example doesn't work because of the literal string. Try: (def x "foo") (.hashCode #^String x)

11:38 alvin__: in the case of the literal string you wouldn't need a hint?

11:39 Chouser: alvin__: I would guess not. Anyway, you're not allowed to provide one. :-)

11:39 In general you can find out if reflection will be done at runtime by doing: (set! *warn-on-reflection* true)

11:40 If you do that in the Repl and then (.hashCode x), you'll see a little warning that the hashCode method will have to be looked up at runtime.

11:41 * alvin__ scribbles in notebook

11:44 Chouser: but don't go crazy with the type hints -- code looks so much better without them, make sure you really need the speed improvement first.

11:57 alvin__: what's the best way to iterate through a java array? is (loop) the only option?

11:58 wwmorgan_: alvin_: you can call seq on a java array, and then all of clojure's iterative capabilities are avaiable to you

12:00 alvin__: O.O

12:05 gnuvince: Does anybody know if Rich's presentation and pannel at Lisp50 are going to be video-tapped?

12:07 arbscht: oopsla events are typically recorded

12:07 the talks, anyway

12:09 gnuvince: great

12:10 albino: lisp50 is separate from oopsla, no?

12:10 alvin__: is there anybody here who's worked with JMX?

12:11 gnuvince: alvin__: they show it in the OOPSLA schedule

12:13 alvin__: gnuvince: you mean albino :)

12:16 bbl

12:42 AWizzArd: re

12:46 Chouser: thanks for the explanations

12:46 Chouser: yw

12:47 gnuvince: What's the function (or method) to get the numerical value of a char?

12:47 For example, (ord \A) => 65

12:48 wwmorgan_: gnuvince: (int \A) => 65

12:48 gnuvince: Duh... thanks wwmorgan_ :)

12:51 AWizzArd: What is preferrable? (.toString 123) or (format "%d" 123)?

12:52 kotarak: AWizzArd, why not (str 123)?

12:52 AWizzArd: good, thx

12:56 Lau_of_DK: Evening gents

12:56 arbscht: hi lau

12:56 duck1123: hey lau

12:56 kotarak: Lau_of_DK, hi. Got a solution for euler-37

12:57 Lau_of_DK: Then post it on the wiki :)

12:57 kotarak: ok.

12:57 Lau_of_DK: oh wait

12:57 Did you succeed in removing strings ?

12:58 kotarak?

12:58 kotarak: yes

12:58 Lau_of_DK: Wow - I cant wait to see it

12:58 Can you just post it below my solution with the note: Optimized to run without strings...or something like that :)

12:59 kotarak: I have it on a different machine. Will remake it from memory. But will take a minute....

12:59 Lau_of_DK: hehe

12:59 Hun: damit vergleichbar

12:59 woopsy

13:03 arbscht: the clojure-euler wiki navigation has become quite confusing

13:04 Lau_of_DK: arbscht, sorry about tht

13:04 I moved all the single digit values into triple-digits, but I lack the rights to delete the original ones, so I need to get a hold o achim_p

13:04 arbscht: I see

13:04 Lau_of_DK: Just know that there are now duplicates, nothing has been removed, but it would be nice to have it start at 001 and end at 210

13:05 arbscht: what will we do in 15 years when project euler reaches 1000? :)

13:05 Lau_of_DK: Make a new wiki :)

13:05 arbscht: heh

13:08 Lau_of_DK: Question guys: On clj-me.blogspot.com cgrande wrote a routine called (defn find= ...), in it he declares a variable like this

13:08 (let [ [s1 & etc]

13:08 What does that syntax mean ?

13:09 duck1123: is that for destructuring?

13:09 Chouser: destructures a seq, the first going into s1, the rest into etc

13:10 Lau_of_DK: so when the argument is a seq of seqs, then the first seq goes into s1, and the others into etc ?

13:10 Chouser: (let [[a & b] '(1 2 3)] {:a a :b b}) -> {:b (2 3), :a 1}

13:10 Lau_of_DK: sure

13:10 sohail: does clojure make it possible to load/save clojure compiled files?

13:11 kotarak: sohail, not yet, but in work

13:11 Lau_of_DK: Chouser, thanks alot! Where do you guys pick up this stuff, have you got a secret book ?

13:11 Chouser: sohail: there are no clojure compiled files.

13:11 sohail: then what does the compiler do?

13:11 I meant compiled representation actually :-)

13:12 kotarak, how does a large clojure (doesn't exist yet?) project handle compiling everything on startup then?

13:13 kotarak: sohail, it does so on startup, I suppose.

13:13 lisppaste8, url

13:13 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

13:13 Chouser: Lau_of_DK: sorry, friend, it's all on the web site: http://clojure.org/special_forms

13:13 Lau_of_DK: click on "let"

13:13 sohail: kotarak, sounds slo

13:13 w

13:13 Chouser: sohail: the compiler is relatively simple, so it runs pretty fast.

13:14 AWizzArd: is there a way to know how many threads are running in parallel in a running Clojure program?

13:14 Chouser: sohail: pre-compiled to .class files is coming.

13:14 sohail: Chouser, great :-)

13:15 Chouser: usually called "AOT compilation", just so you know what people are talking about when you see it.

13:15 AWizzArd: sohail: did you see my example from yesterday? About the generality of multimethods? http://paste.lisp.org/display/68846

13:15 walters: AWizzArd: there are some decent free tools around the JVM - VisualVM is one

13:15 AWizzArd: walters: danke

13:15 walters: AWizzArd: but there are plenty others

13:15 sohail: AWizzArd, I did

13:16 thanks for that

13:16 AWizzArd: so, in your dispatch method you can protect from bad number of args, and so on

13:16 sohail: I still think that there will eventually be a straight-jacket on top of clojure

13:16 yep

13:16 but I think this should be automatic

13:16 AWizzArd: it already is there, at runtime

13:18 sohail: yeah but if you're lucky, all you'll get is an exception which tells you nothing about what really happened

13:19 AWizzArd: sohail: then write something like the Erlang Dialyzer for Clojure

13:20 you can prove tons of stuff about code before running it

13:20 lisppaste8: kotarak pasted "euler-37 and prime?" at http://paste.lisp.org/display/68876

13:22 Lau_of_DK: WELL done kotarak

13:22 Thats a fantastic (trunc )

13:22 gnuvince: let doesn't allow the definition of recursive bindings?

13:23 kotarak: Lau_of_DK, it has to go only one way. The other way is handled in candidate generation

13:23 Lau_of_DK: Double your gun, double your fun,... and speed

13:24 sohail: AWizzArd, still not the same thing

13:24 but again, I'm probably wrong in wanting what I want

13:24 AWizzArd: not the same as?

13:24 sohail: same thing as what I want

13:24 AWizzArd: what do you want?

13:25 sohail: an ABCL that doesn't cause java 1.6 to segfault

13:25 ;-)

13:25 kotarak: gnuvince, no, there is no letrec

13:25 arbscht: gnuvince: let is not letrec. however, you can label functions like so (fn foo [] ... (foo))

13:26 gnuvince: I was trying the infinite fibonacci sequence thing from Haskell. It works with def, but not with let.

13:26 dmiles: sohail, java -version

13:29 sohail: dmiles, I know, I know

13:29 but this app will be run on all sorts of versions so I need to make sure it works on all 1.6

13:30 (it's .06 btw)

13:30 dmiles: IcedTea6 1.3 Runtime Environment (build 1.6.0_0-b12) OpenJDK 64-Bit Server VM (build 1.6.0_0-b12, mixed mode)

13:30 works pretty good

13:30 sohail: unfortunately, I won't control what it runs under

13:30 dmiles: oh true

13:31 sohail: I can't bring myself to write Java

13:31 dmiles: whenever my jvm gets buggy i just reclock my computer or increase airflow

13:31 that does almost always solve it

13:31 sohail: :-/

13:32 dmiles: i dunno, seems like this new one lets me clock higher meaning its probly slower jvm

13:39 AWizzArd: Does the jvm offer extrem lightweight threads? Some that it manages the jvm itself? Something lightweight as Erlang or Haskell threads?

13:41 it would be nice if only on physically available cores/cpus native threads were running, and the rest would be lightweight threads which can be initialized 1000x faster and consume much less memory

13:47 walters: AWizzArd: you can change the stack size I believe; but basically like all optimization problems don't worry about it unless it truly is a problem for your app that shows up in measurements

13:48 AWizzArd: I am about to port my common lisp Genetic Programming system to Clojure. I will have ten thousands of programs that need to be run to test their fitness.

13:48 It makes no sense if 10k threads get started on just 2 cpu cores.

13:49 walters: i think using a thread pool gets you pretty far

13:49 AWizzArd: As I see it, Clojure automatically parallelizes stuff

13:49 in this one video Rich showed an example of ants running around

13:50 duck1123: watching that video right now

13:50 tWip: for some value of automatically

13:50 duck1123: I though he said though that clojure does NOT parallelize automatically

13:50 AWizzArd: he had no threadpool there and no real management for concurrency (besides for checking if space is already taken by some other and, so that not two of these beasts can be on the same field on the "chessboard")

14:05 Chouser: you can have thousands of agents with actions scheduled on them, and they will queue up for available CPUs.

14:06 AWizzArd: Chouser: I will have to read more about that. Still didn't look into concurrency stuff yet (refs/agents).

14:57 lisppaste8: karmazilla pasted "wonder if this can be optimized" at http://paste.lisp.org/display/68886

15:01 wwmorgan_: karmazilla: optimized for time/space or refactored to be more clojure-y?

15:01 karmazilla: time

15:01 takes 8 seconds to run on my machine

15:02 wwmorgan_: http://en.wikipedia.org/wiki/Sieve_of_Atkin

16:06 Lau_of_DK: Does clojure provide some way of getting the actual digits?

16:06 user=> (reduce + (map #(Math/pow % %) (range 1 11)))

16:06 1.0405071317E10

16:08 arbscht: Lau_of_DK: what are "the actual digits"?

16:09 Lau_of_DK: user=> (reduce + (map #(int (Math/pow % %)) (range 1 11)))

16:09 2552554964

16:09 something like that

16:09 a pure int result

16:10 arbscht: Math/pow returns a double, so that would seem to be the only way

16:11 wwmorgan_: (str (BigDecimal. (reduce + (map #(Math/pow % %) (range 1 11))))) => "10405071317"

16:12 Lau_of_DK: BigDecimal - Thats the stuff

16:12 Thanks wwmorgan_

16:14 arbscht: or, (reduce + (map #(.pow (bigint %) %) (range 1 11)))

16:16 alvin__: i need to go through a seq and add items to a hash map depending on the current value from the seq... what's the best way to code this kind of behaviour?

16:18 gnuvince: alvin__: loop/recur sounds like the obvious candidate

16:20 alvin__: gnuvince: ok, let me try it... i'll get back some time tomorrow :D

16:24 aperotte: hello all, is there a way to import all of the classes in a package or a jar at once?

16:25 or is that just wasteful and lazy on my part:-[

16:30 cemerick: aperotte: No, there's no built-in way to do that. It's a conscious design decision iirc

16:31 gnuvince: Does Clojure have a for-each function when you're not interested in the return value?

16:32 wwmorgan_: gnuvince: (doc doseq)

16:33 gnuvince: Cool, thanks.

16:34 aperotte: cemerick: ok, thanks

16:43 Chouser: gnuvince: if you're trying to accumulate data in a hash, say counting the occurences of each value in a seq, you may be able to use merge-with

16:45 user=> (apply merge-with + {} (for [i [:a :b :a :c :a :b]] {i 1}))

16:45 {:c 1, :a 3, :b 2}

16:46 if you don't need to handle hash key collisions, it's even easier with (into)

16:49 scottj: How do you set *out* to the repl or stdout? I'm using compojure and I think it's changed *out*

16:52 Chouser: scottj: wrap (binding [*out* foo] ... ) around your expression

16:55 scottj: Chouser: oh, I guess what I mean is, what is the value of foo for stdout/repl?

16:57 Chouser: oh! I don't know that. You could try System/out even though it doesn't give the same value that the REPL has by default for *out*

16:58 wwmorgan_: The default repl value for *out* is (java.io.OutputStreamWriter. System/out (java.nio.charset.Charset/forName "UTF-8"))

17:18 Chouser: can anyone think of a nice simple concrete example of objects that would have methods dispatching on different attributes?

17:19 like if you had a {:shape circle :radius 5}, you'd want an area method that dispatches on :shape

17:19 But if I want to demonstrate dispatching on something other than :shape, what would I add?

17:20 the only thing I've thought of so far is a fill pattern like :fill checkerboard :gridsize 1

17:20 which seems kinda lame.

17:21 maybe I should use cars instead of shapes, and have a MPG-estimate method dispatch on 4wd vs 2wd, and have longevity-estimate dispatch on model of vehicle.

17:22 lame. *sigh*

17:24 Hun: Chouser: i used opcodes for a cpu simulator for this

17:24 each opcode gets 2 to 3 parameters in this ISA, each can be immediate, a register, an address or a indirect address

17:25 defining that with generic functions was reeeally easy (CLOS though). should suffice as an example if the listeners have any assembler experience

17:28 Chouser: one method per opcode?

17:28 Hun: true

17:29 Chouser: but don't they all dispatch on cpu type or something?

17:29 Hun: it was amazingly fast, only slightly slower than a hand-tuned table-based dispatch

17:29 no, it was a single experimental cpu. not much use for a type there

17:29 take the easiest one

17:29 Chouser: so what did they dispatch on?

17:29 Hun: move

17:30 that one gets 2 operands, source and destination

17:30 on the operands

17:30 so that i could take into account that i could do just about anything with varied costs, except memory=>memory which errors

17:30 (it was a pretty stupid design, taking bad things from x86)

17:31 Chouser: ok, I think I understand. thanks!

17:32 Hun: think in combinations of operands and you might find a lot of interesting uses for generic functions

17:51 danlarkin: In university we had to write an assembler macro-expander in assembler... you're bringing back bad, bad memories with your opcode talk

17:52 Hun: i did one in lisp because the team that should write the assembler took to long. was about 40 lines :)

17:54 danlarkin: I'm jealous

17:54 it was that class that made me decide low-level programming was not for me

17:55 although it was invaluable to learn it... poor kids these days with no foundation!

17:58 (it was only 2 years ago that I left school, so I'm speaking facetiously)

18:00 Hun: hehe

18:00 i'm still in college. doing a HW-Design course this term, together with some compilers :)

18:10 danlarkin: Hun: which college do you attend?

18:11 Hun: university of applied sciences augsburg

18:11 germany

18:11 i'm in my seventh term now

18:17 danlarkin: I'm out, peace!

18:19 scgilardi: I see by the schedule that Rich's talk is starting right now

18:33 achim_p: amazing, look at cgrands take on subsets(-by-card) (http://clj-me.blogspot.com/, compared to http://paste.lisp.org/display/68832). still parsing it, mentally ...

22:26 crathman: what is the integer divide function in clojure?

22:27 Chouser: quot

22:28 crathman: chouser: thx

22:30 nicknull: is clojure fast?

22:30 how fast is it compared to java? to other lisps?

22:41 Chouser: nicknull: with care, clojure can run as fast as Java

22:51 nicknull: would it be suitable to write an application that uses fairly heavy numerical computing(image recognition)?

22:52 Chouser: nicknull: I've not done it, but I think rhickey's hoping to use Clojure in heavy math apps like audio analysis.

22:53 take a bit of care with your inner loops, take advantage of multiple cpus, and let us know how it goes. :-)

22:57 nicknull: cool

22:57 he works with audio analysis?

22:57 is tomhickey his brother?

22:57 gnuvince_: Yes, he is.

22:57 nicknull: or they just occupate the same namespace?

22:57 ok

22:57 gnuvince_: And Rich seems to work with super fun stuff: election projection systems, finger printing analysis, audio analysis, broadcast automation systems, etc.

22:58 I'm really jealous of the election projection thing.

22:58 I'm Canadian, but I enjoy following American politics.

23:09 Chouser: gnuvince_: wow, that's ... something. Most Americans don't even like following American politics.

23:11 gnuvince_: Chouser: I'm weird like that :)

23:11 Chouser: gnuvince_: well I do like it, so I guess I can empathize. Never really tried to follow any other country's politics.

23:12 gnuvince_: Chouser: It's different when your neighbor is the biggest and most powerful country in the world.

23:13 Plus, some things happening there are really interesting

23:13 The very large difference between the SF liberal crowd and the Bible Belt conservative crowd

23:17 Chouser: gnuvince_: indeed! And each completely at a loss to understand the other.

23:18 nicknull: gnuvince: now im jealous to that sthe sutff i wanna do. datamining, machine learning, signal analsyis etc

23:18 gnuvince_: Being a mostly liberal guy myself, I'm hoping to see you guys elect Obama ;)

23:19 Chouser: gnuvince_: ah, well now we have a problem. :-)

23:19 gnuvince_: Chouser: McCain man?

23:20 nicknull: i also like to follow american politics. have quite the effec ton the rest of the world...

23:20 Chouser: hm, pretty off topic...

23:21 nicknull: McWar

23:22 tomhickey: is rich using matlab? is he using clojure and matlab together?

23:33 crathman: I see lazy-cons.... is there a way to declare a function lazy?

23:34 Chouser: nope, just return that lazy-cons.

Logging service provided by n01se.net