#clojure log - Feb 02 2008

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

8:21 scramflot: sweet, there's a room

8:22 rhickey: welcome

8:22 scramflot: thanks

8:26 I'm new to lisp. is learning any 'lisp-1' language the same as learning clojure? I get the feeling it's not, from the 'differences with other lisps' page

8:28 rhickey: There will be a lot that is similar

8:29 scramflot: So could I learn clojure by reading a book about lisp-1?

8:31 rhickey: There's one sense in which Lisp is a set of ideas, which you can move around, and another in which each Lisp is a language with it's own syntax and semantics, which don't travel as well. Certainly don't expect to bring code between them.

8:34 scramflot: rgr. Well, I went through the whole website and it's really geared towards people who already know Lisp. Which is cool.. It's pretty early I guess.

8:35 rhickey: I hope to add more material for newcomers to Lisp

8:35 scramflot: When running the argcount example on the functional_programming page, I'm seeing it just return all the arguments

8:36 mmm, nevermind

8:36 must have been a typo when I typed it in

8:37 rhickey: ok

8:38 scramflot: sweet, works as advertised

8:46 rhickey: what other lisp-1 dialect is very well documented?

8:47 Or, better yet, a document that teaches lisp-n dialects

8:49 I just read that scheme was a lisp-1

9:21 reading htdp.. I got a long way to go ;)

9:21 anyone still here?

10:55 I'm trying to figure out how the make-adder function works on the http://clojure.sourceforge.net./features/functional_programming.html page

10:56 (defn make-adder [x] (let [y x] (fn [z] (+ y z)))) (def add2 (make-adder 2)) (add2 4) -> 6

10:58 I'm seeing x and z as the parameters being sucked in from the outside, but how is it determining to stick the 2 and the 4?

11:00 so the def is "closing over" the value of x after it has been assigned? how does clojure know to reach down into add2 and stick 4 into z?

11:02 what if I had another (fn [asdf] (...)) after (fn [z] (...))

11:02 how would it know which one to pick from?

11:07 jonathan_: hi, anything happening?

11:08 scramflot: jonathan_: not much.. I was asking a question and no one was hearing me

11:08 care to take a stab at it?

11:08 jonathan_: shoot

11:09 scramflot: I'm trying to figure out how the make-adder function works on the http://clojure.sourceforge.net./features/functional_programming.html page

11:09 (defn make-adder [x] (let [y x] (fn [z] (+ y z)))) (def add2 (make-adder 2)) (add2 4) -> 6

11:09 I'm seeing x and z as the parameters being sucked in from the outside, but how is it determining to stick the 2 and the 4?

11:09 jonathan_: ok, hee hee

11:09 scramflot: so the def is "closing over" the value of x after it has been assigned? how does clojure know to reach down into add2 and stick 4 into z?

11:09 what if I had another (fn [asdf] (...)) after (fn [z] (...))

11:09 how would it know which one to pick from?

11:10 jonathan_: the return value is a function

11:10 it takes a single parameter

11:10 and adds y

11:10 where y is the x that you originally passed in

11:10 scramflot: oh.. wait.. so...

11:11 jonathan_: forget the x

11:12 you'll building a little box that has a little string that connects to y

11:12 scramflot: you're actually.. add2, one could say, "resolves" to (fn [z] (+ 2 z))

11:12 jonathan_: yep

11:12 scramflot: oooh, I get it now

11:12 Yea, cause I started experimenting to try to figure it out, and...

11:13 jonathan_: now, if you have things like that, you can generate a little 'adder' that does anything

11:13 just map it onto a list

11:13 scramflot: I put two (fn [blah] (...))s in there

11:13 and the last expression is the one that returned

11:14 (one was an add, the other a subtract.. it subtracted)

11:14 jonathan_: yeah, if you do (fn [] (expr) (expr)) it generally gives you back the last one if that's syntactically valid

11:15 I still haven't worked through the pmap example

11:15 scramflot: I did (let [] (fn [] ())(fn [] ()))

11:16 jonathan_: try this ... make a couple of functions, then use (apply (comp fn1 fn2) [arg])

11:16 the comp glues the functions together

11:16 scramflot: comp is builtin?

11:16 jonathan_: yep

11:17 scramflot: you were saying, about mapping lists?

11:20 jonathan_: I did this thing at work for merging lists of date ranges

11:20 they could be timetables, or scheduling or pretty much anything

11:20 but you can build a function to tweak a date range

11:21 and another, and another, then compose them

11:21 then use map to apply all the tweaks

11:22 have you tried the new stuff?

11:24 scramflot: how bout, (defn make-operator [x y] (let [myx x] (fn [a b] (myx a b)))) (def myadd (make-operator '+)) (myadd 2 2) -> 4 ??

11:24 nah, this is my first time looking at clojure, and I'm a bit of a spectator programmer anyway.. hit and run thus far

11:25 Was that correct? to apostraphize the +?

11:25 jonathan_: you might need to adapt to call plus

11:26 scramflot: I was thinking maybe I should be sending in a function to myx

11:27 that takes a and b

11:27 no?

11:27 jonathan_: I haven't tried that ...

11:28 but you do (reduce + '(1 2 3))

11:28 ^can

11:29 the best source of 'idiom' is probably the boot.clj file

11:29 scramflot: I messed that up.. make-operator should have one param

11:30 jonathan_: doh ...

11:30 scramflot: anyway.. yea? you think a newb can digest it?

11:31 jonathan_: I'm digesting it and I'm a newb

11:31 I fall short of understanding those 'm' things

11:31 but I can just about cope with the STL

11:32 scramflot: STL? C++?

11:32 jonathan_: And I'm more productive in Clojure than ... than ever

11:32 yeah lame 'enterprise' C++ is my thing

11:33 scramflot: I'm an arm-chair programmer.. passing java knowledge, jack-of-a-few-trades.. I'm a sys-admin

11:33 jonathan_: Clojure is a million times cleaner than Perl

11:34 All my Perl code eventually collapses on itself

11:34 I dunno if everyone has that experience

11:34 scramflot: Never had to write perl

11:35 might look into the regexs in perl 6 though

11:35 looks cleaner

11:35 jonathan_: it'll be dead if you can't run perl5 code on it

11:36 perl used to be my language for doing prototypes and what not

11:37 scramflot: oooh, I did it: (defn make-operator [x] (let [myx x] (fn [a b] (myx a b))))

11:37 jonathan_: cool

11:37 scramflot: (def myadd (make-operator +))

11:37 (myadd 3 4)

11:37 -> 7

11:37 that's sweet

11:37 jonathan_: read the boot.clj file

11:38 it's an awesome into to lisp programming

11:38 ^intro

11:38 scramflot: cool

11:38 I guess I will then

11:38 jonathan_: defining java interface and having it actually work is pretty sweet too

11:39 the new code in svn has a gui data inspector in 100 lines of code

11:40 have you looked at Arc?

11:43 scramflot: that's actually what brought me here

11:43 jonathan_: I have it installed, has some neat stuff in it

11:44 scramflot: Arc hit the news, then everyone was dissing it and saying things like "what does arc bring to the table? at least ikarus and clojure are doing neat things!" and that made me want to find out what clujure was

11:44 jonathan_: it still has the typical problem that I can't get at Oracle, or build a decent GUI

11:45 * on Win/OSX/Linux

11:45 but with pure java I can do all these things on any platform

11:45 scramflot: You played with gui building in clojure?

11:45 jonathan_: I build in Netbeans, then just load it

11:46 works great, just stick the class on the -cp

11:46 or you can build dynamically

11:46 see inspector.clj

11:46 scramflot: where does the event handling go?

11:46 in clojure?

11:47 jonathan_: (. mygui (addEventLister (implement (handler (fn[blah] ...

11:47 implement is a built in

11:47 yep

11:47 scramflot: oh, what does the . do?

11:47 (been wondering that)

11:47 jonathan_: java instance methods

11:48 look at the hello world example

11:48 scramflot: the one here? http://clojure.sourceforge.net./features/functional_programming.html

11:48 jonathan_: http://clojure.sourceforge.net/reference/getting_started.html

11:49 (. javax.swing.JOptionPane (showMessageDialog nil "Hello World"))

11:49 method calls go in () like a function

11:49 fields go without the ()

11:49 scramflot: ok, yea... so what is . actually doing?

11:50 jonathan_: calling a java method on an object, or class (if a static)

11:50 showMessageDialog must be a static method, since we're calling it on a class

11:51 scramflot: ok

11:52 so, what would be JOptionPane.showMessageDialog() becomes that

11:52 jonathan_: all we need is someone to stitch the java reflection into a table model ... and we'll have a smalltalk style class browser

11:52 scramflot: that would be sweet

11:52 jonathan_: it'd be easy if I knew java libs better

11:53 oh, you want this page http://clojure.sourceforge.net/reference/java_interop.html

11:53 for all the '.' stuff

11:53 .. chains

11:54 scramflot: I fricken love prefix notation

11:55 jonathan_: yeah, me too, and I haven't really grasped macros yet

11:55 in fact at all

11:56 scramflot: me neither.. haven't tried to grasp it yet.. I hear you can build the language with it though (roughly)

11:56 jonathan_: boot.clj is largely built from it

11:56 scramflot: right

11:57 I've actually been wanting to try to implement a visual ide

11:57 where you build a program visually

11:57 jonathan_: be nice to have it really dynamic

11:58 so you didn't even have to hit run

11:58 scramflot: And the analog I want to use is the file browser

11:58 right

11:58 prefix notation works well with this idea, cause the whole program can be broken down into a directory tree

11:58 jonathan_: my dad got our first computer, and spent hours typing in a program, and he was pissed because it didn't do anything ... he didn't think he needed to do anything else

11:59 RUN

11:59 scramflot: hahahah

11:59 jonathan_: It was full of mistakes, it wouldn't have run correctly anyway

12:00 scramflot: yea, so.. dynamic like squeak, right?

12:01 jonathan_: I guess, no eperience of that sadly

12:01 look cool

12:02 scramflot: you can use the gui to drill down into the code that is actually running the gui, and change it in real time

12:02 jonathan_: cool, sounds like a Lisp or Smalltalk

12:02 scramflot: squeak is smalltalk 80 I believe

12:03 jonathan_: yeah, I always kinda think the syntax sucks

12:03 it's really bumpy

12:03 from the objective-c perspective (ie. basic cocoa programming)

12:04 squeak looks similar right?

12:04 scramflot: I've only seen it from the gui.. I'm not too familiar with the actual code view

12:05 and I don't know smalltalk

12:05 I'm only now learning lisp

12:06 jonathan_: I'm really enjoying it, and getting smugger by the day

12:06 scramflot: :)

12:06 I can see why

12:08 and having access to all the java libraries at the same time kicks ass

12:08 jonathan_: yeah, I kinda do management now, and I spent a few days writing a resolver for fuel rates for gas pipeline in C++, that's the main coding I've done in 8 months ... so I need to stay in practice

12:08 and yes, the java libraries are great ...

12:09 scramflot: I'm a system/network admin for the army.. so if I could find the time to get really good at a language, I could apply it to work.. but it's just finding the time first

12:10 jonathan_: I think it's like anything else, you just have to find a use for it and keep trying

12:10 it is easy ... < 100 lines to put an Oracle table in a Swing gui

12:11 it takes a while to understand, but all the bits are there

12:11 scramflot: I've used the io language (back in the day) to install anti-virus updates on a small network of windows boxes in afghanistan.

12:11 jonathan_: cool

12:11 are there any other good jvm languages ... scala?

12:11 is io on jvm?

12:11 scramflot: no

12:11 io is definately cool though

12:12 jonathan_: it looked 'terse' from what I've seen

12:12 scramflot: some say io has some problems, but it sure is sweet

12:12 I was coding in it in no time

12:13 very intuitive

12:13 jonathan_: Cool, it's been on my list of things to look at for a while

12:13 along with Scala and Lua

12:13 scramflot: The biggest complaint I heard was that it's so extremely reflective and runtime-modifiable that a security model is non-existent

12:14 practically any piece of code can modify any part of the system

12:14 jonathan_: yeah, that seems to be an Arc complaint

12:14 though I don't know how

12:14 scramflot: I've studied a bit on scala.. it looks even more verbose than java though..

12:15 just not very pretty

12:15 jonathan_: yeah, I have like three Haskell books

12:16 it's really inpenetrable

12:16 Scala looked pretty unpleasant

12:16 scramflot: by that you mean, hard to learn?

12:16 jonathan_: yeah, really finicky

12:17 I really enjoy being able to just try stuff out 'at the prompt'

12:17 scramflot: yea, haskell is the purely functional, no side-effects, etc. right?

12:17 jonathan_: there's various escape hatches

12:17 but in theory, yes

12:18 actually, I write functionally in Clojure

12:18 scramflot: Yea, I'm a bit too intimidated by Haskell to really go after it

12:19 any time soon, at least.. If I was in school for it, then sure

12:19 jonathan_: you can do stuff like (assoc mystuff key (assoc (get mystuff key) subkey newval))

12:20 which creates a copy of a hash with one subkey edited

12:20 scramflot: ah

12:20 does copying everything cause a memory issue?

12:21 jonathan_: not so far ... I've used that technique with 10 of 1000 of records with no hiccups

12:22 I'm writing a caching data server with undo and shared sessions

12:22 and I'll get fired if the prototype doesn't work

12:22 sweeeet

12:23 scramflot: yea

12:23 jonathan_: so far I've replaced 4000 lines of C++ with about 500 lines of Clojure

12:24 scramflot: wow.. so your really getting into it... how long have you been using clojure?

12:24 jonathan_: whereas before I would have used Perl and DBI

12:25 second week on Jan maybe

12:25 not long at all, it really is an easy language if you can handle the way functions and scope works

12:26 tcl is a bit clojureish

12:26 stick something in ( ) and it gets evaluated

12:26 scramflot: I don't see a lot of '() in the examples

12:27 jonathan_: in tcl?

12:27 scramflot: in clojure

12:27 delayed evaluation

12:27 jonathan_: yeah, it certain has less than Lisp

12:28 scramflot: it's just still has it, right? it's just not required as much?

12:28 jonathan_: Yeah Rich has fixed a lot of crappy syntax from Lisp

12:29 like (let ((x 1)(y 2)) (... becomes (let [x 1 y 2] ( ... which reads a lot better

12:29 scramflot: yea.. I'm still on the fence

12:30 I think I like it.. but.. it _is_ more syntax

12:30 jonathan_: my only complaint so far is that (apply fn [args]) the [] seems not needed

12:30 more syntax than what?

12:30 scramflot: than just using ( )

12:31 as the universal code container

12:31 jonathan_: yeah, and more special forms like . etc

12:31 but it all fits together pretty well

12:31 I have a *lot* of things work first time

12:32 scramflot: I'm surprised I got that make-operator thing to work so quick

12:32 jonathan_: Plus the performance rocks

12:32 scramflot: really?

12:32 sweet

12:33 jonathan_: all the stuff you really do in real code is probably running on the metal in the java libs

12:33 so my JDBC code runs faster than C++ on my windows box

12:34 scramflot: wow

12:34 scala is fast too

12:34 jonathan_: Yeah, if it weren't for people hating on Java, the JVM would have taken over the world

12:34 Thanks Microsoft

12:35 <insert bad words here>

12:35 scramflot: what do you think about parrot?

12:36 jonathan_: Haven't looked at it yet

12:36 scramflot: the vm that aims to run all dynamic languages

12:36 jonathan_: Does it have libraries? Does it run all the perl odules?

12:37 scramflot: perl6 will run on it.. I think they're trying to port perl 5 to it

12:37 so then both will run eachother's libraries

12:37 jonathan_: if they can slide perl5 onto it that'll help

12:37 scramflot: and they'd like to see python and ruby on there as well

12:37 and then they can all share libraries

12:37 jonathan_: but most Perl programmers are probably writing pretty basic perl

12:38 It's horrible to read, and tricky to debug

12:38 scramflot: well, I don't think anyone expects that perl 5 will go away after 6 is out

12:39 well, 6 is out now

12:39 jonathan_: yeah, it's just too useful

12:40 It's funny, I always seem to need to connect to a database

12:40 I totally choose languages based on libraries

12:40 oh, for sql lite, there's a pure java one

12:41 scramflot: I think I've heard about it

12:41 jonathan_: check this out http://www.zentus.com/sqlitejdbc/

12:42 it emulates Unix in Java I think

12:42 Just amazing

12:43 The sqlite executable is inside the Java jar

12:43 so you have sqlite on any platform in Clojure

12:44 scramflot: yea.. jetty's pretty sweet too

12:44 jonathan_: Is that the web server?

12:44 scramflot: yea, web-app server

12:44 what do they call it, web-app-container?

12:45 like tomcat, but small

12:45 jonathan_: Yeah, I need to look into that, I'd sure like to build some web apps

12:45 scramflot: embeds right into your application

12:46 jonathan_: so you would you do web pages? define code to template them out?

12:46 I've been on VC6 since 2001, it's like the web never happened at my office

12:47 scramflot: uh.. you'll have to look into it.. I think jetty does cgi but I think most people use that other java server backend language thing.. forgot what it was called

12:47 seen this: http://hsqldb.sourceforge.net/ ??

12:48 (about jetty.. like asp, but for java? jsp? I can't remember)

12:49 jonathan_: awesome, thanks

12:49 scramflot: hsqldb is fast

12:49 jonathan_: I've seen the name and assumed it was Haskell

12:49 Don't IBM have something also

12:49 derby?

12:50 scramflot: I think that's something similar.. not sure

12:50 hsqldb vs. others: http://hsqldb.sourceforge.net/images/imola_retrieve.jpg

12:52 jonathan_: haha

12:52 what a bizarre graph

12:52 scramflot: yea

12:54 jonathan_: actally, it might be fun to write a sql gui in clojure

12:55 you're 70 % towards most business apps if you have that

12:56 scramflot: hey, if you have any gui/closure stuff built.. example-ware kind of stuff, I'd love to see it..

12:57 jonathan_: yeah, we need to get like a wiki going or something

12:57 scramflot: yes

12:57 jonathan_: plus get the boot.clj file documented

12:57 plus get an index of all the functions

12:58 I discovered compose (comp fn1 fn2) totally by accident

12:58 and memfn is cool too

12:58 scramflot: rich was here before you got here. I asked him about documentation.. he said "I hope to add more material for newcomers to Lisp"

12:59 jonathan_: I think the best thing is to read example code

12:59 scramflot: same here.. my fav format is cookbook

12:59 jonathan_: once you have the (), that's the syntax

13:00 actually, I just remembered how I found Clojure, there's a Lisp user group page where Rich did a talk

13:01 http://lispnyc.org/wiki.clp?page=past-meetings

13:01 scramflot: awesome

13:02 jonathan_: The presentation is really good

13:03 scramflot: NYC huh.. where'bouts in the city is it?

13:03 jonathan_: Dunno, I'm in Tx

13:03 scramflot: I might have to go to one

13:03 I'm a couple hours away, but there aint nothing going on up here in fort drum

13:04 jonathan_: yeah, I have something on a website somewhere to get a Lisp group going in Houston

13:04 but nothing yet

13:05 But there's one other language that I do really enjoy ... Javascript

13:05 But it's just Lisp in drag

13:06 I think it can do all the same tricks

13:07 scramflot: hmm.. Javascript might be a great language, but I've been averse to letting any website run it on my browser whenever they want.

13:08 albino: I came by because of the arc posts myself

13:08 jonathan_: you guys have the same story

13:08 albino: heh, well at least we follow up :)

13:08 scramflot: yea, same here

13:09 jonathan_: I was at least hoping for an Arc compiler

13:09 I guess it sort of is

13:09 I'm a convert to the JVM

13:09 Especially now it's open

13:09 scramflot: perhaps I would be excited about arc if I new enough about Lisp in general, but for now I think clojure has quite a few benefits

13:11 jonathan_: the syntax sucks less in Arc, but it seems like it doesn't add a whole lot

13:13 It seems like with concurrency, everyone has to move towards functional programming

13:13 scramflot: actually, io probably got me interested in all these languages.

13:15 jonathan_: and what pushed you towards io?

13:15 scramflot: hype... and then it was really simple to start hacking..

13:16 I still play around with it from time to time

13:18 jonathan_: it does look interesting

13:19 actually, it's really easy to port Java code into Clojure, like simple web servers and stuff

13:20 the worst part is ocasional broken library behavior

13:21 and insane verbosity for InputBufferedStreamReader and friends

13:21 scramflot: aye

13:22 do you ever juts cut and paste large multi-line code blocks into the repl?

13:22 s/juts/just

13:22 jonathan_: Yes, that's how I work

13:23 scramflot: do you see anything wrong with this?

13:23 jonathan_: then build it into a file once it's debugged

13:23 scramflot: (import '(javax.swing JFrame JLabel JTextField JButton)

13:23 '(java.awt.event ActionListener)

13:23 '(java.awt GridLayout))

13:23 (defn celsius []

13:23 (let [frame (new JFrame "Celsius Converter")

13:23 temp-text (new JTextField)

13:23 celsius-label (new JLabel "Celsius")

13:23 convert-button (new JButton "Convert")

13:23 fahrenheit-label (new JLabel "Fahrenheit")]

13:23 (. convert-button

13:23 (addActionListener

13:23 (implement [ActionListener]

13:23 (actionPerformed [evt]

13:23 (let [c (. Double (parseDouble (. temp-text (getText))))]

13:23 (. fahrenheit-label

13:23 (setText (strcat (+ 32 (* 1.8 c)) " Fahrenheit"))))))))

13:23 (doto frame

13:23 (setLayout (new GridLayout 2 2 3 3))

13:23 (add temp-text) (add celsius-label)

13:23 (add convert-button) (add fahrenheit-label)

13:23 (setSize 300 80) (setVisible :t))))

13:23 (celsius)

13:23 er. how bout I just get the link for you...

13:23 http://clojure.sourceforge.net/features/jvm_hosted.html

13:24 there.. sorry about that

13:24 jonathan_: works for me ...

13:25 scramflot: hhmm.. yea, it works now here too

13:25 jonathan_: 25 oC = 77 F

13:25 you might have missed a bracket

13:25 scramflot: the first time I pasted it in, I was cutting from the pdf of the presentation

13:25 aye

13:25 jonathan_: probably a fancy '

13:25 `

13:25 scramflot: ah, I've heard of pdfs doing that

13:25 jonathan_: the repl doesn't like tabs

13:26 notepad2 untabify

13:26 damn, a repl in netbeans would be great

13:27 netbeans kicks visual studios ass

13:28 scramflot: I do like netbeans the best, but I really want to like eclipse

13:28 jonathan_: I think I tried it once, then moved on

13:29 scramflot: it's just slow

13:29 jonathan_: yeah, netbeans is faster than visual studio now

13:29 mainly because visual studio is so crappy

13:30 Build big .NET projects is terrible

13:30 dependency hell

13:30 assembly hell

13:30 Our apps *have* to be installed locally now

13:31 It's 10x worse than Java ever was

13:31 scramflot: hmm

13:34 jonathan_: It's a shame because the .NET guy did turbo pascal originally I believe

13:35 I wonder ... if that still exsts

13:40 bgeron: we use delphi at school, but it's proprietary :(

13:41 jonathan_: aren't there a bunch of free pascal compilers that do the same thing?

13:42 bgeron: yes

13:42 jonathan_: That's cool, what kind of stuff do you write?

13:42 bgeron: but they don't do GUI design as ugly as delphi does, which why I must use delphi

13:43 it's not that cool, actually ;) last time I had to write a program that drew random points on a plane, then let you rotate/shift a duplicate of that plane

13:44 you get the illusion of circles then

13:44 and when you right-rotate, then shift right, the circle moves down (because the points down are first shifted left, then right again so there's the center)

13:45 jonathan_: I think that sounds pretty neat

13:45 you're not far off rotating shapes

13:45 bgeron: I'm not sure about that

13:46 jonathan_: graphics is fun

13:46 bgeron: agree, but this did not really extend to graphics in general

13:46 the painting routing (blegh, painting) was changed to paint each point twice

13:49 jonathan_: what would happen if you shifted the plane in 3d

13:49 you'd get donuts right?

13:50 bgeron: not with shifting, I think

13:50 jonathan_: sorry rotating

13:50 bgeron: you get a donut if you wrap it or something

13:51 jonathan_: damn, time for a snack

14:40 jgracin: hi all!

14:41 jonathan_: hi, what's happening?

14:42 jgracin: Today, I was trying to figure out the way to implement function "disassemble" but no luck.

14:42 Seems that the version of ASM is a bit cut down.

14:42 No ASMifier... and stuff.

14:44 jonathan_: I haven't looked at the source ... what does Clojure use that for?

14:44 jgracin: for bytecode generation

14:46 jonathan_: so like recur jumps and stuff?

14:46 jgracin: Clojure instantly compiles all function definitions into JVM bytecode.

14:47 when you evaluate (defn f [] 1) it is compiled into JVM bytecode.

14:47 jonathan_: I've been using it for prototyping and I know it's fast but I wasn't sure what is going on underneath

14:47 jgracin: I was trying to see what does the compiled code looks like.

14:48 jonathan_: the actually jvm instructions?

14:48 jgracin: Actually, I was getting surprisingly slow results on some trivial benchmarks so I wanted to check the JVM instructions.

14:48 jonathan_: are you type hinting?

14:50 jgracin: Yes, I am, but I'm not sure if the hints are ignored cause I can't see the code that gets produces. :-)

14:50 produced.

14:51 summing a range of numbers, from 1 to n

14:51 takes very long time

14:51 compared to SBCL, and GCC.

14:52 and I'm sure that SBCL and GCC didn't optimize the loop out.

14:53 jonathan_: user=> (dotimes n 100 (time (reduce + (range 1 1000))))

14:53 "Elapsed time: 1.572 msecs"

14:54 "Elapsed time: 1.003 msecs"

14:54 "Elapsed time: 0.997 msecs"

14:54 "Elapsed time: 1.559 msecs"

14:54 like that?

14:54 jgracin: Yes. GCC sums from 0 to 2 000 000 000 in 1.7 seconds.

14:55 jonathan_: hahahah

14:55 what kind of speed in raw Java?

14:55 jgracin: and java version is even faster (around 1 second), but I'm not sure what the compiler does to it.

14:55 jonathan_: GCJ?

14:56 or javac?

14:56 jgracin: javac

14:57 jonathan_: wow, that's impressive, but seems like a limited benchmark

14:57 jgracin: Of course, it's stupid, but it was just a sanity check.

14:57 :-) a stupid sanity check.

14:57 Let me show you the code....

14:58 jonathan_: I've had some great results with JDBC, in fact Clojure makes it pretty easy to build up big bundles of data recursively, and it is really quick

14:58 sure

15:01 jgracin: it's here http://www.inge-mark.hr/~gracin/bm.clj

15:02 Oh, maybe it's because of overflow in sum!

15:03 jonathan_: aha

15:03 jgracin: I couldn't have been so stupid

15:03 jonathan_: lol

15:03 Is the 'loop' necesary

15:05 maybe the loop is better than having an alt parameter set

15:06 jgracin: I'd have to have a 'sum' parameter in the function lambda list.

15:06 jonathan_: add a single param form that calls the two param form

15:06 (reduce + '(1 2 3)) must have two forms

15:07 I was really surprised when that worked

15:09 I would have pasted some code but my clip is messed up

15:09 scramflot: (dotimes n 5 (time (reduce + (range 1 1000000000)))) -> java.lang.OutOfMemoryError: Java heap space ;)

15:10 jonathan_: http://pastebin.com/d53bad58e

15:12 Handles merging date ranges together ... it's a tad long-winded

15:12 jgracin: thanks, I'll have a look. I'm not sure I understand what you said the above, which part were you surprised with?

15:12 jonathan_: doesn't reduce normally need an accumulator?

15:13 arrggg

15:13 (+ 1) = 1???

15:13 jgracin: oh, I see

15:13 jonathan_: it must special case the first call

15:15 The more functional programming I see, the more I like it

15:15 jgracin: I've just check CLHS and it says that the function to reduce must accept no arguments, and two arguments.

15:15 (+) = 0

15:16 jonathan_: lol, You are leaving Common Lisp, thanks for visiting

15:16 jgracin: that's probably what Clojure does as well. It's easy to check.

15:16 First call is the call with no args.

15:17 jonathan_: user=> (+)

15:17 0

15:17 user=> (*)

15:17 1

15:17 user=>

15:17 so I wonder where that comes from?

15:18 (defn reduce

15:18 ([f coll]

15:18 (if (seq coll)

15:18 (reduce f (first coll) (rest coll))

15:18 (f)))

15:18 ([f val coll]

15:18 (if (seq coll)

15:18 (recur f (f val (first coll)) (rest coll))

15:18 val)))

15:18 That's the actual code

15:21 jgracin: of course, makes sense.

15:22 jonathan_: yeah, I love that all the neat stuff is in boot.clj

15:22 jgracin: I wonder why CL mandates that the function must be able to take no arguments.

15:23 jonathan_: no arguments = nil? easier to compose ?

15:25 jgracin: jonathan_: nice talking to you. bbl.

15:25 jonathan_: ttl

16:14 (seq (.. interface (getClass) (getMethods)))

16:14 (def interface

16:14 (implement [ActionListener]

16:14 (actionPerformed [evt]

16:14 (print (str evt)))))

16:15 pretty sweet, can reflect into the Proxy0 objects that implement generates

16:30 hey jg, made any progress on figuring out if you can reflect method code?

16:33 jgracin: nope. I've put it aside for the moment. I'm currently reading JVM specification. :-)

16:33 jonathan_: k

16:35 jgracin: JVM code looks very unusual to someone having only experience with x86 and Sparc.

16:36 I have some catching up to do.

16:37 btw, I haven't solved that benchmark problem. Even without those overflows, the speed is rather low.

16:42 this code http://pastebin.com/d5126d011 is 20 times slower than the equiv. Java or CL code.

16:43 jonathan_: haha, we had Sun 3/50's at uni and we ran 3 guys to a box

16:44 that was kinda slow

16:44 20x slower seems like a reasonble trade for 20x easier to write

16:52 Hey Rich, thanks for such an awesome language!!

16:53 rhickey: you're welcome!

16:56 jonathan_: I have a question, can we call the classloader and get access to the compiled 'class' files in memory? (just playing really)

16:57 rhickey: not officially - they can't be serialized for reuse without dealing with the constants

17:00 jonathan_: constants?

17:01 rhickey: literals, quoted things etc

17:01 i.e. some of the code really is data and would need to be reconstituted

17:02 jonathan_: ok, what actually comes out of the code generation ... is there a class file in mmory?

17:03 rhickey: yup, plus some data literals that get passed through the classloader

17:03 jonathan_: ahhhh, I should have started at the repl ;-)

17:12 scramflot: rhickey: hi.. jonathan_ helped me out and explained some of the questions I had. Pretty kick ass!

17:15 rhickey: great!

17:15 jonathan_: so if you compile a closure, you have to fixup any outside vars when you load?

17:16 rhickey: every function becomes a class and its ctor takes any closed-over vars

17:17 jonathan_: ahh, that's really neat

17:17 scramflot: jonathan_ brought up a good point. There should be a wiki where we can post up snippets and examples.

17:19 rhickey: I was hoping to use Google code for wiki and issue tracking but they don't support CPL projects

17:22 scramflot: wha? that's wild

17:22 jonathan_: patents?

17:22 rhickey: no they only support a few licenses in order to reduce proliferation

17:23 jonathan_: ah ok (the non-sinister reason ;-) )

17:24 rhickey: just looking now - seems like sourceforge has wiki support, I'll look into it

17:24 scramflot: eh.. sf's community tools are ug'

17:25 there's wiki-books too

17:25 some languages just link to that

17:25 (or open-source projects in general)

17:25 rhickey: I know, I've avoided the other sf stuff other than code/web hosting

17:27 jonathan_: I learnt 10x more playing with the code in boot.clj than reading lisp books, so an annotated version of that up on a web might be awesome

17:27 rhickey: interesting idea

17:29 jonathan_: it's interesting that so much of the language is in boot.clj ...

17:29 scramflot: Yea, with an intro to help someone understand the boot.clj

17:30 rhickey: That's what's so cool about Lisp, just implement the core and then the rest of the language in itself

17:30 scramflot: the syntax, etc... like, for instance, it could be because I'm so unfamiliar with functional languages in general, but... I had to ask jonathan_ about:

17:30 jonathan_: memfn and comp in the resultset-seq code ... I had to go runing to boot.clj to find out what that was all about

17:30 scramflot: (defn make-adder [x] (let [y x] (fn [z] (+ y z))))

17:31 now, after his explaining, I understand that add2 simply resolves to (fn [z] (+ 2 z))

17:31 rhickey: I think every function is documented on the web site now (memfn, comp etc)

17:32 jonathan_: cool, does that include namespaces now ...

17:32 rhickey: yes, functions returning functions is a higher order thing you might not see much outside of functional/lisp languages

17:33 not namespaces yet, I try to keep the docs in sync with the release so people downloading don't get mixed messages - I hope to make a release soon

17:34 jonathan_: ah ok, of course, that makes sense

17:34 scramflot: I've seen namespaces talked about, in the reference maybe?

17:35 rhickey: they've been greatly enhanced recently, so are due for a doc update

17:35 I put a decent description in a message on the google group

17:36 scramflot: ah, that'd be it then

17:36 jonathan_: yep, and I noticed that class has gone away

17:37 rhickey: not needed, just use the classname

17:37 jonathan_: yeah nice

17:37 Errr, yeah, I had a question: If I had a server that serves as a 'cache' for some data in an Oracle db, how would I sensibly access that and update it ... I was just (def *cache* ...) ing it, which works, but it seems like I'd want to put it in a ref or something?

17:38 *it = the bundle of hashes

17:38 rhickey: Yes, use a ref - which you can put in a var - (def cache (ref {}))

17:40 jonathan_: cool, having Clojure makes prototyping even business software fun

17:41 and pure Java oracle drivers are just icing

17:42 scramflot: for add2, is it possible to reach return a copy of add2, changing the value of 2 to 3?

17:43 rhickey: you can't 'get at' the closed-over locals in a fn - fn values are opaque

17:43 jonathan_: unless you write an accessor and return that?

17:44 scramflot: but can I copy, changing a closed over value, without rewriting the whole function?

17:44 so, return a new function, with a different value

17:44 rhickey: Not exactly sure - what code do you want to write?

17:46 scramflot: well, I'm just thinking about it.. listened to some of your talk a while ago actually.. and you said something like "lispers are used to being able to type into the repl, change the code, and polish the product" etc, etc.. something like that

17:47 I'm wondering how I'd modify a buggy function without having to rewrite the whole thing

17:48 rhickey: Ah - ok. If some fn bar calls foo, and you redefine foo, the next call to bar will use the new foo.

17:48 try it

17:50 scramflot: oh, so keep functions relatively small... the group of functions modular.. and it's easily modifiable. But returning a new function with one of it's values changed isn't what it's about, right?

17:51 rhickey: Right, the "values" of the function are private to it

17:53 jgracin: scramflot: One keeps the source of functions in the editor which is connected to the repl and then you don't actually rewrite anything. Sorry if I'm stating the obvious.

17:54 you change the stuff in the editor and send the new definition to the REPL, i.e. the Lisp image.

17:54 scramflot: jgracin: yea, I'm tracking that it can be done that way... be back in a min.. to get deeper at my curiousity here

17:57 jonathan_: is there a way to use SLIME?

17:58 or similar?

17:58 jgracin: jonathan_: I use Clojure mode and paredit.

17:59 rhickey: not right now - someone who knows more about the protocol might take a crack at it. I'm hoping the new first-class namespaces will facilitate things like that.

18:00 jonathan_: Yeah, I just paste from TextEdit or notepad2 right now

18:01 jgracin: rhickey: the ASM in the Clojure sources is a stripped down version 3.0, am I right? I cannot find some classes like ASMifier... and stuff.

18:02 jonathan_: Clojure mode uses inferior-mode, so it's much easier than copy-paste.

18:02 rhickey: right - subset of ASM to keep the size down.

18:03 with debug off clojure.jar is < 250k

18:03 jgracin: rhickey: I was trying to write a "disassemble" function but I failed. Do you think it's achievable with what's currently in the Clojure?

18:04 rhickey: Nope, but it's possible to see what's going on by:

18:04 putting full ASM in your classpath,

18:05 swap the import comments on the top of Compiler.java,

18:06 swapping the cv initialization with the line below in Compiler.FnExpr.compile()

18:07 Then Clojure will spew full disassembly of everything it compiles (i.e. my dirty laundry :)

18:08 That's what I do to debug code-gen

18:10 jgracin: Cool, thanks, I'll try that. Have you considered adding this functionality to the main code?

18:11 rhickey: yes, unfortunately it doubles the size of ASM's contribution to Clojure's size (it's almost 50% right now)

18:13 scramflot: back.. so can you do something like: (defn make-operator [x] (let [myx x] (fn [a] (let [mya a] (myx mya b))))) ?

18:13 embedding a let inside a let

18:13 and a function inside a function

18:16 jgracin: Bed time for me. Bye all!

18:17 rhickey: you can, but I wonder if make-adder hasn't set you off on the wrong track - most functions are defined directly with defn and not by a function-defining-function like make-adder

18:18 scramflot: I'm not under the impression that that is prescribed method of function composition.. I was just wondering about how deep one could layer the closures

18:19 rhickey: indefinitely deep

18:20 scramflot: doing so too deeply would result in brittle code though, right?

18:21 rhickey: yes, the deeper you get the more difficult it becomes to independently test the parts

18:21 scramflot: cause you can't really modify the nested structure much

18:22 rhickey: you can't modify it at all - all those locals are immutable

18:24 jonathan_: I've been surprised at how quick it is to use assoc to generate updated copied of hashes ... that completely rocks

18:26 rhickey: HotSpot can do a great job optimizing all of the final stuff in the persistent classes

18:27 jonathan_: yeah I always like to write the simplest functional type code ... and it's always been plenty fast so far

18:27 try to anyway

18:31 do you know of any interesting uses of Clojure yet Rich?

18:32 rhickey: None I can talk about, but I was thinking of asking on the group

18:34 jonathan_: That'd be cool, it seems like there's a few people coming and looking around, esp. with all the Arc buzz going on

18:35 rhickey: Yup, the arc release has caused people to look at Clojure

18:37 I think Clojure has more to offer, but I'm biased :)

18:38 jonathan_: I completely agree ... the indexers, refs, stm mainly stuff I haven't got to yet, but I've written a GUI in 500 lines that kicks the ass of 4000 lines of C++ ... so I'm pretty sold

18:39 great for prototyping ideas that people don't think can be made to happen ...

18:40 though a simple undo/redo stack is considered 'impossible' at my company, as are 'splitters' in a GUI .... it's like a research project

18:40 rhickey: Well, keep blogging about your success with Clojure - it helps

18:41 jonathan_: I sure will, I honestly haven't ever enjoying writing code as much .... only Javascript comes close

18:41 oh, why is [] required on apply ?

18:41 for the args

18:42 rhickey: The last arg to apply must be a collection/seq - is that what you mean?

18:43 jonathan_: right

18:43 sorry phrased it badly, couldn't apply be & rest ?

18:45 rhickey: then it would only collect args and still not give you a way to apply a fn to an arglist already in hand.

18:45 jonathan_: ok, I'll go read the code ... ohhh I think I understand, thanks

18:46 rhickey: Dinner time here - bye all!

18:46 jonathan_: k byee

23:11 rhickey: I added a Clojure Programming book to wikibooks.org - just an outline right now

23:27 jonathan_: wow, that's awesome

23:28 I'll go take a look

23:31 what's it under Rich? I can't see anything

23:31 rhickey: http://en.wikibooks.org/wiki/Clojure_Programming

23:33 jonathan_: cool, just needs some content :)

23:34 rhickey: yup

23:37 jonathan_: I've been in a greek restaurant for the last 3 hours, so I'm a tad dazed

23:38 rhickey: today is over for me, bye all

Logging service provided by n01se.net