#clojure log - Oct 05 2008

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

1:08 duck1123: how hard would it be to modify the documentation system to include a direct link to the actual source code

1:09 even better, it could use javascript or something to color code, and display inline

2:12 danlarkin: duck1123: that would be neat

5:02 Pupeno1: lisppaste8: url

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

5:02 Pupeno pasted "synthetize" at http://paste.lisp.org/display/67955

5:03 Pupeno1: Is there a better way to write that code? 5 lines of code and 2 are almost the same.

5:05 Hun: you could use pg's old aif-macro. that makes it at least a bit shorter

5:05 what does synthesize-content return? if it's just nil, what goes wrong when nil is used for :content?

5:12 hmm... intentional variable capture seems to be hard in clojure

5:13 lisppaste8: Hun pasted "Nonworking aif for clojure" at http://paste.lisp.org/display/67956

5:23 H4ns annotated #67955 with "dry" at http://paste.lisp.org/display/67955#1

5:26 hans_: dang. Pupeno1, seen my paste annotation?

5:27 Hun: i saw it

5:27 lisppaste8: hoeck annotated #67955 with "into" at http://paste.lisp.org/display/67955#2

5:28 H4ns: hoeck: also nice

5:29 hoeck: H4ns: more general, allows applying more "optional" keys

5:30 H4ns: hoeck: that is true. also, less visual clutter

5:30 Hun: hmm... is intentional variable capture just hard in clojure or doesn't work at all?

5:31 hoeck: H4ns: but the conj approach suits better when there will be only one optional entry

5:31 Hun: its possible, use ~'foo in your macro

5:34 lisppaste8: heock annotated #67955 with "conj" at http://paste.lisp.org/display/67955#3

5:36 H4ns: hoeck: you don't like [], {} for a reason?

5:37 never mind me.

5:37 * H4ns reads some more docs

5:48 Pupeno1: Thanks for the annotations.

5:49 The reason why I'm avoiding having content when it's nil is because I need to see the data and understand it, and having a content nil there makes it harder to read and understand the data.

6:04 lisppaste8: H4ns pasted "Trivial HTTP server" at http://paste.lisp.org/display/67958

6:04 H4ns: wow. having mastered the initial hurdles, using java libraries from clojure really is straightforward

6:25 Pupeno1: I really need a pretty print, isn't there one anywhere?

6:29 gs: does this help: http://blog.thinkrelevance.com/2008/9/16/pcl-clojure-chapter-3

6:30 if you scroll down a bit he uses the 'format' function to print the output

6:30 Pupeno1: gs: might do.

7:34 pmf: Is there a significant difference between (.method obj args) notation and (. obj (method args)) notation? I'm asking because I'm using a custom variant of doto that works not only on Java-methods, but also on regular (i.e. Clojure) functions that take an obj a first arg, allowing to do (doto-2 obj (.someMember args) (pr) (.someOther)).

8:09 glark: (defn $ [pred]

8:09 `(lambda (x) (,(first pred) x ,(first (rest pred)))))

8:09 why isnt that working? it works in common lisp

8:09 should expand ($ '(< 10)) to (lambda (x)(< x 10))

8:10 obv not needed in clojure bc fn is short

8:10 but i am oractiticng ninjaskills

8:10 H4ns: comma is white space in clojure, use ~ instead

8:12 oh, and yes, lambda is fn in clojure. are you sure that you've read enough of the introductory material? :)

8:18 rhickey: glark: the ninja way would be #(< % 10)

8:21 Hun: real ninja is (rcurry < 10) :)

8:22 glark: ok thanks

8:22 (defn $ [pred]

8:22 `(lambda (x) (~(first pred) x ~(first (rest pred)))))

8:22 doesnt work either. for soem reason it puts user in there...

8:22 (user/lambda (user/x) (< user/x 10))

8:22 when doing ($ '(< 10))

8:23 H4ns: glark: lambda does not exist in clojure

8:23 glark: lol im stupid haha

8:24 (defn $ [pred]

8:24 `(fn [x] (~(first pred) x ~(first (rest pred)))))

8:24 java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

8:29 (defn $ [pred]

8:29 `(fn (~[(first pred)] x ~(first (rest pred)))))

8:30 H4ns: lisppaste8: url

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

8:30 H4ns: glark: use that for code pastes

8:31 rhickey: Hun: I disagree - curry is not very ninja at all - can only bind args in order - rcurry is a great example of its limitations

8:32 Hun: when the functions are uncurried variadic, one can implement rcurry pretty easy... though it's ugly

8:33 rhickey: Hun: and binding the middle arg of three?

8:33 Hun: got me there :)

8:34 rhickey: #(foo %1 42 %2)

8:35 Hun: one could do a nasty hack and implement an ncurry, but that's even uglier than rcurry

8:35 rhickey: Hun: then I'd say what about first and third of four?

8:36 Hun: would work with ncurry twice. it'd create a lambda with & args and splice them around the call

8:37 rhickey: more proof

8:37 Hun: but your solution is nicer

8:40 fondue: hm, shouldn't this return false? (def a 1) (def b 1) (identical? a b)

8:40 lisppaste8: rhickey annotated #67956 with "aif" at http://paste.lisp.org/display/67956#1

8:41 rhickey: Hun: aif that works ^

8:42 Clojure tries to help with aliasing, so you need to explicit cause 'it to escape

8:42 Hun: ok

8:44 rhickey: but anaphora are discouraged in Clojure, they don't nest

8:44 Hun: maybe i should stop thinking CL when writing clojure :)

8:45 rhickey: fondue: while they are not guaranteed to be identical?, they're not prohibited either

8:45 identical? also use very infrequently in Clojure

8:45 used

8:47 fondue: ok, was just following the data structures screencast and typing things into my own repl for kicks, you seemed to get (identical? "foo" "foo") to turn up as false too, I got true

8:47 but I'll just ignore it :)

8:48 Hun: equality is generally a hard problem

8:48 rhickey: fondue: for strings the rules have changed since the screencast and identical? is guaranteed for string literals

8:49 fondue: right

8:49 rhickey: identical? is not about equality

8:49 Hun: true

8:50 rhickey: = in Clojure has sound semantics, at least when applied to Clojure objects and immutable Java ones

8:51 = pretty much implements egal, per Heny Baker: http://home.pipeline.com/~hbaker1/ObjectIdentity.html

8:53 Hun: cool. didn't know that paper yet. => reading

8:53 H4ns: in german, "egal" means "does not matter" which is slightly confusing :)

8:54 rhickey: H4ns: interesting

8:54 fondue: yes, I was enjoying =, I just thought it was odd that identical? didn't point out that they were different objects, which seemed to be its main purpose

8:54 as a side note, that is probably the best answer I have ever gotten in proportion to how basic the question was

8:55 rhickey: fondue: but it does do exactly that, but the language doesn't say that two 1's that occur in different places will be different objects

8:55 fondue: so it's employing a bit of cleverness and using the same object, since they're immutable anyway? they're both pointing to the secret 1-object?

8:55 rhickey: right

8:56 but not guaranteed

8:56 fondue: right

8:57 H4ns: rhickey: a class name in a new expression can't be computed, right? i tried (new (if <expr> <some-class-name> <another-class-name>) ...)

8:57 rhickey: had an interesting look at the cost of that optimization during the JVM summit - bottom line is that with proper escape analysis it might be better to allocate a new boxed 1 every time, sinc ethe test and cache lookup complicate the fast path

8:58 H4ns: right, Clojure is designed to be compiled - you can get runtime behavior by using reflection explicitly - see also clojure.lang.Reflector for useful reflection helpers like invokeConstructor()

9:00 but better in your case (if expr (This. ... ) (That. ...))

9:01 H4ns: rhickey: thanks, will look at that. coming from clos, i have a hard time coming back to a static object system.

9:01 fondue: an interesting optimization that, exactly the kind of emergent cleverness this new (to me) way of thinking seems to encourage

9:11 rhickey: H4ns: understood, although that dynamism is infrequently used. In any case, it is generally more useful, if someone is going to hand you something to create, for them to hand you a constructor-fn than a class name/object - like #(java.util.ArrayList. %&) - that way your code isn't hardwired to new, and the resulting call is fast - no reflection

9:14 glark: rich: what is your opinion aout haskell and python?

9:14 is it possible to create an objectsystem in clojure btw?

9:15 rhickey: glark: haskell is inspiring, python just ordinary, but serves its users

9:16 glark: hopefully some next-generation object system

9:16 prunedtree: rhickey : is there a way to iterate in clojure that isn't ridiculously slow that I missed ?

9:17 (or ridiculously low level like loop)

9:17 rhickey: doseq dotimes

9:17 prunedtree: are ridiculously slow. slower than interpreted languages

9:18 (well, probably faster than ruby/python/etc... but slower than, say, Lua for instance)

9:19 rhickey: the things you've been doing have been highly imperative - if you find loop too low level build higher level things with macros

9:19 prunedtree: and 100x slower than some JITs. I think it's the whole lasy sequence thing

9:20 it's great on paper but disastrous on the JVM. no lamba lifting, no strictness analysis. feels like haskell without GHC magic :/

9:21 H4ns: rhickey: the library i am using tries to be friendly by supplying a lot of tiny wrapper classes around base class functionality. i'll just use the base classes and provide a convenient functional wrapper around that. i'm very willing to not use classes and inheritance in my clojure programs.

9:21 but now for some family business. enough progress for today.

9:24 glark: (defn $ [pred] `(fn [x] (~(first pred) x ~(first (rest pred)))))

9:25 what am i missing?

9:29 Hun: you're defining a function that looks like a macro?

9:29 rhickey: glark: are you trying to write a macro?

9:31 glark: it works as a defun in commmon lisp

9:31 (defun $ (pred)

9:31 `(lambda (x) (,(car pred) x ,(car (cdr pred)))))

9:31 just an exercise

9:31 pointless kind of but...

9:34 Hun: in CL that would also just return a list

9:35 rhickey: is your problem the qualified user/x - you should be using auto-gensyms:

9:35 (defn $ [pred] `(fn [x#] (~(first pred) x# ~(first (rest pred)))))

9:35 ($ '(< 10)) -> (clojure/fn [x__2553] (< x__2553 10))

9:36 Clojure ` is not a hygiene free-for-all like CL

9:36 :)

9:41 glark: ok thanks

9:41 still get java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

9:41 though

9:43 rhickey: glark: when you are trying to use the result? That's because it's just a list of forms - unless you write a macro or eval it it's not going to turn into code

9:43 Hun: are you trying to call that directly?

9:43 you get a (non-evalled) sequence back

9:48 glark: (defmacro $ [pred] `(fn [x#] (~(first pred) x# ~(first (rest pred)))))

9:49 now it does hwt i wanted but when i wrote in cl i thought it has to be a macro but then i could do it so i assumed it wuld work inclojure too

9:49 rhickey: glark: please paste complete working CL

9:50 alec: Are the slides from the boston talk available in non-movie form? I don't see them on the website or in the files area of the Google group

9:50 rhickey: alec: good point, I'll put them up, just a sec...

9:52 http://groups.google.com/group/clojure/web/clojureforlispers.pdf

9:54 alec: thanks!

9:55 rhickey: alec: sure, although slides alone don't substitute for the talk (but should take less than 3 hours to read :)

9:57 glark: http://hpaste.org/10917

10:01 rhickey ^^^

10:01 alec: glark: are you trying to recreate haskell's associativity-changing operator, and if so, why do that in a language that doesn't do infix?

10:02 glark: wait it is not working when used with filter

10:02 no it wa sjus syntactic sugar for (lambda (x)(< x y))

10:02 not really needed since clojrue has its own

10:03 but dont see how the clojure-system works

10:04 (clojure/fn [x__1837] (< x__1837 10)) is what i get

10:04 when using defn, i watn a list, data as code...

10:07 Hun: are you confusing Common Lisp with Emacs Lisp? this is the only still alive lisp i know where this works

10:08 glark: ys emacslips +re clrequ

10:08 + require 'cl

10:10 Hun: that's an ugliness of elisp that you can funcall a list there imho

10:10 everywhere else you need a macro or an eval between

10:12 glark: ok but it is still not working here

10:12 user=> (filter ($ '(< 10)) '(12 3 4 55))

10:12 (12 3 4 55)

10:14 Hun: same happens with my implementation, too

10:14 (defn $ [pred]

10:14 #((nth pred 0) % (nth pred 1)))

10:14 i don't understand that one

10:14 Chouser: glark: what does (macroexpand '($ '(< 10)))

10:14 er, what does that return?

10:16 (filter ($ (< 10)) '(12 3 4 55)) seems to work

10:16 Hun: hmm

10:17 it works when i do a (list < 10) instead of a '(< 10)

10:17 (filter ($ '(< 10)) '(12 3 4 55)) => (12 3 4 55)

10:17 (filter ($ (list < 10)) '(12 3 4 55)) => (3 4)

10:18 Chouser: running macroexpand on those is enlightening

10:18 Hun: i have no macro in there, just a defn and a fn

10:18 Chouser: oh

10:19 Hun: ah

10:19 Chouser: oh, I see. I was looking at glark's macro implementation

10:19 Hun: list evaluates the < to clojure._LT___

10:19 the quote doesn't and includes a plain <

10:19 which somehow can get called though

10:20 ('< 3) => nil

10:21 ('< 3 5) => 5

10:21 with more it throws an exception

10:21 rhickey: glark: so, the code you've posted won't work in CL, as someone said auto-eval of lists may be an emacs lisp thing

10:22 so, this must be a macro - you want to manipulate code as data, then have the compiler continue to evaluate it

10:23 Hun: rhickey: what does happen back there? i seem to call a symbol and it works... can't find anything about that

10:24 rhickey: symbols, like keywords, are functions of associative things, like maps

10:25 ('a {'a 1 'b 2}) -> 1

10:27 Chouser: and apparently (get 3 5) simply returns nil

10:27 rhickey: when 'called' on something non-associative, return nil - found nothing

10:27 Hun: ok. but i don't understand what it's doing to those numbers a few lines up. with 2 args it seems to return the second one

10:27 rhickey: Chouser: no (get '< 3) returns nil

10:28 sorry (get 3 '<)

10:28 Chouser: the third param then is the notFound value

10:28 rhickey: right, the second case is the default value case

10:28 if you can't find '< in 3, return 5

10:29 Hun: ah, now i get it. i would have expected it to complain that 3 is not a collection

10:31 rhickey: Hun: others expected nil and won, apparenty :)

10:31 apparently

10:31 Hun: hehe

10:32 rhickey: iirc that behavior was useful in destructuring at least

10:33 Chouser: so that's a completely different problem from glark's, where by quoting the arg '(< 10), first and (first (rest...)) were operating on (quote (< 10)) instead of (< 10)

10:34 Hun: it then always returns the second arg (the number 10) which is always true

10:34 and therefore filter returns the original seq

10:34 rhickey: Chouser: yes, there's lot of confusion here solved by using macros - the right tool for this job

10:36 Chouser: well glark's was a macro (in the end) but I guess the idea of quoting the arg was left over from when the implementation was a fn

10:38 glark: well its still not working damn. thanks fo the tips though.

10:38 Chouser: glark: works for me

10:40 glark: chouser: which one and how do you call it?

10:41 lisppaste8: Chouser pasted "glark's macro" at http://paste.lisp.org/display/67975

10:42 glark: ah v nice

10:43 rhickey: don't ignore his "or of course the easiest:" at the bottom, that is the Clojure way to do this

10:45 Chouser: I hardly ever get to write macros in clojure -- there's almost always already an easier way to do it.

10:48 glark: ty very much all

10:48 im mostly in this to learn more about macros and stm

10:48 gonna port ,y spamfilter to clojure now as an exercise

10:58 how do i do progn in clojure?

10:59 Chouser: (do ...)

11:00 If I remember progn correctly. ;-)

11:08 Hun: yep

11:15 blackdog: hi Chouser how is clojurescript? I tried to tweak it a little, (prn (+ 1 2 3 4)) -> 8 :p, i added a clojure.lang.Numbers.add,

11:15 (+ 1 2) gives the correct answer

11:16 does that mean an issue in the PersistentList reduce?

11:20 Chouser: blackdog: yeah, I just noticed yesterday that add and minus were missing.

11:21 hm! not sure.

11:21 I'd have to look at the JS produced, but mine is all broken at the moment.

11:21 blackdog: ok, i used svn from yesterday,

11:22 anyway, it looks really interesting and i understand basically waht's going on, so i'll try a little hacking on it

11:22 Chouser: blackdog: cool.

11:23 As you noticed, there several bits of runtime support missing, and the parts that are there are not well tested.

11:23 I think the JS-emitting part is pretty solid, though we may be able to make performance and size improvements.

11:25 blackdog: yegge's js2.el is complaining about lack of ; in the bodies of most of the output

11:25 not too important i guess

11:26 maybe for compression tools it is though

11:31 Chouser: hm, I wonder if the

11:31 hm, I wonder if the \n interspersed with , is a bad idea

11:32 like, it could be interpreted as end-of-statement

11:46 StartsWithK: Chouser: Will you provide any way to extract parts of boot.js that are needed by clojurescripts?

11:50 blackdog: i think that's ultimately important, it's one of GWTs selling points

11:50 removing unused methods, classes

11:53 Chouser: I've been hoping I could get all of boot.js and clj.js compacted and gzipped down to around 20KB or so.

11:53 blackdog: that would be amazing,

11:55 Chouser: I'm currently at about 25KB, but that's without compacting clj.js at all, or using short names in boot.js

11:56 of course clj.js is also missing entire classes, so we'll see.

11:56 blackdog: 50K in total for runtime and boot will make it very competitive

11:57 StartsWithK: don't forget most of us will use something like jquery with clojurescript

11:57 so, total size i my opinion should be mesured when packed with jquery

11:57 but this will be awesome when finished :)

11:58 Chouser: jQuery's what, 9KB or so?

11:58 blackdog: 19K

11:58 i think compressed

11:59 Chouser: I've already got code in tojs to skip some parts of boot.clj (agents, etc.) so exposing that functionality somehow isn't out of the question, though it's complexity I'd rather avoid if possible.

12:00 StartsWithK: anyone got proguard (http://proguard.sourceforge.net/) to work with clojure?

12:00 that would reduce applet sizes too

12:01 when aot clojure->java that should work just fine i think

12:01 is finished*

13:22 Chouser: blackdog: The bug turned out to be in ArraySeq.reduce -- fixed, thanks!

13:22 blackdog: cool thanks

13:22 is it on svn?

13:35 StartsWithK: how can i dispatch on interface?

13:39 blackdog: maybe use bases or supers in the dispatch function for your multimethod?

13:39 StartsWithK: i can do (supers obj), and ill get set, but then i will have to dispatch for exact combination of interfaces

13:41 rhickey: StartsWithK: just use class as your dispatch function and the interface as the dispatch value

13:42 Chouser: blackdog: yes, it's in svn.

13:46 StartsWithK: thanks

13:54 and how could i dispatch on method signature? like in scala i can say type HasEventListener = { def addEventListener(e: Event) } and then i can write

13:55 implicit def ext(o: HasEventListener) = { do_something() }

13:55 i should use reflection for something like that?

14:10 rhickey: StartsWithK: you mean dispatch based on the presence of a method in the target? why would you do that?

14:20 StartsWithK: rhickey: swing has bunch of addXXXListener methods, but they are bund to some interface, in swt you have addSelectionListener(SelectionListener l) defined on multiple classes with same behavior but they don't share common base class or interface

14:21 rhickey: but that is not a dispatch issue - you can call (.addSelectionLister x ...) on any x that supports that method

14:23 StartsWithK: i have this new (doto) that can also use (defmulti patch) multimethod to 'add' new methods to some class

14:24 now i dispatch inside patch based on class, but i would like to restrict that to classes that have some base class and methods with eact signature

14:26 same thing is inside jetty, there is a lot of classes that have void addHandler(Handler h), they all do the same, but there is no common interface

14:30 rhickey: but you really have code that needs to say, if this thing supports handlers add one?

14:33 StartsWithK: http://pastebin.com/m5ea79f29 there is no addHandlerCollection method in jetty, i dispatch on base Handler class to inject this method, but that is wrong, not all Handler subclasses have addHandler

14:34 ups, there is no addHandlerList method

14:41 rhickey: StartsWithK: you are making up your own language there, injecting methods etc. The simple answer is to determine whether or not a class supports a method you'll have to use reflection. If you know the set of classes without a common base interface you'd like to group together, you can use the new ad-hoc hierarchy support:

14:41 (derive SomeHandler ::SupportsAddHandler) etc

14:43 this allows you to superimpose a parent, which you can use in dispatch, and while it requires enumeration of the relationships, it's not duck typed like the Scala - you make a concrete decision

14:44 Chouser: on the other hand, having creating a dispatch function that does the reflection to do duck typing wouldn't be *that* hard.

14:44 s/having//

14:45 StartsWithK: rhickey: do you consider it a bad sytle, this extended doto macro? It is 100% compatible with clojure/doto

14:46 Chouser: like when multimethod is dispatched i could check with reflection for existance of method and create new (derive) on the spot, that could work

14:46 rhickey: StartsWithK: yes, because I can't understand your program anymore - I'd expect to find any called methods in the Javadoc for the classes

14:48 this isn't really dispatch at all, it's just a predicate - hasThisProperty/method

14:49 the advantages of encoding as hierarchy are - non-duck, non-reflective

14:49 StartsWithK: yes, that could be a problem, i hope that at the end i will add something that will auto-generate documentation of patched (or shadowed) methods

14:50 rhickey: StartsWithK: why not call it something else my-doto

14:51 StartsWithK: no problem there, i used it only in larger composition, like gui creation, so maybe (build) could work

15:25 Chouser: we definitely need a sane way of prividing and maintaining "see also"s in function docs

16:01 blackdog: Chouser: if I want to reference JQuery from a cljs or any JS global, what's the magic? it seems to be trying to resolve in my namespace

16:02 Chouser: it's ok for it to generate a resolveVar to get to a JS global

16:03 blackdog: sorry, don't understand how to get the global, this is what i have (.html JQuery "#nice" "woot")

16:04 ah

16:05 clojure.JS.global?

16:05 l.JQuery?

16:05 oops

16:06 clojure.JS.global.JQuery

16:06 nope, nevermind :P

16:09 Chouser: (.html JQuery "#nice" "woot") should work -- is it not?

16:09 blackdog: i'm not getting nice filled with woot on my page, but maybe there's something daft

16:10 Chouser: what JS is being generated?

16:10 blackdog: oh it may be that I'm not calling it in the ready function

16:10 of jquery, so maybe the document hasn't been initalised properly

16:10 (function __ritchie_fn_2653(){

16:10 return ((clojure.JS.resolveVar("JQuery",ritchie)).html("woot"))}).apply(null,[]);

16:10

16:11 Chouser: ok, I think that ought to work. The resolveVar should find window.JQeury at runtime, do JQuery.html("woot")

16:12 blackdog: what in FF ?

16:12 in firebig?

16:12 bug, doh

16:14 Chouser: well, yeah you should be able to paste into firebug what you pasted here, and it should happen.

16:14 blackdog: i think it's me using query wrongly actually

16:14 Chouser: ok. I don't know anything about JQuery. :-)

16:17 blackdog: wait, if I do this (.html JQuery "#nice" "woot"), then I want it to translate to JQuery("#nice").html("woot")

16:17 Chouser: oh!

16:18 blackdog: and it's dropping the "nice" i think

16:18 no it's not

16:18 ok this is what i have now

16:18 Chouser: well, you'd have to write that (.html (JQuery "#nice") "woot") or something.

16:18 blackdog: clojure.JS.resolveVar("JQuery",ritchie)).html("#nice","woot"))

16:19 ah ok, it's my clojire :)

16:19 Chouser: well, except cljs isn't going to bahave well on (JQuery "#nice").

16:19 oh, maybe it will!

16:20 blackdog: clojure.JS.resolveVar("JQuery",ritchie).apply(null,["#nice"])).html("woot")

16:20 Chouser: yeah, give that a try.

16:20 blackdog: but i still don't see anything, which still may be down to the document not initialised

16:23 Chouser: well, you can try hand-written JS in whatever context you're trying to do generate .js now.

16:24 Once you've got that working, swap in the generated JS and get back to me. :-)

16:24 blackdog: yep

16:38 my mistake, JQuery, should have been jQuery

16:38 getting some output now

16:40 Chouser: ah, good.

16:43 I freely admit there's plenty of work to go on getting all this to tie in nicely.

16:43 blackdog: ok, next question if I want to call into namespace "test" and function setText from javascript how do i do it?

16:45 Chouser: you say namespace, so I assume setText is defined in a .clj or .cljs file somewhere?

16:45 blackdog: yes, (ns test)

16:45

16:45 (defn setText [t]

16:45 (.html (JQuery "#nice") t))

16:46 but i'll need to call clojure functions from jquery events

16:46 Chouser: well, this is the tie-in stuff that's not too pretty yet. You have to make sure that code is compiled to .js and that the .js is loaded into the browser page.

16:46 blackdog: yes, I've done that

16:47 it's working in the browser

16:47 Chouser: oh, ok. Then you can call it from JS like test.setText(t)

16:47 blackdog: that easy! awsome, i see there's a getMappings() function in there

16:47 but i didn't see anything else

16:47 Chouser: or from cljs like (test/setText t)

16:48 I don't think there's any way to set a JavaScript object property from cljs yet -- we'll probably need that.

16:49 but you should be able to pass the setText function into jQuery if needed.

16:50 I assume you realize you're in deep pre-release code here. :-)

16:51 blackdog: yes, no worries, i'm trying to help by applying it to things :)

16:54 aperotte: hello everyone ... does anyone have any experience with enclojure on ubuntu?

17:03 Chouser: aperotte: well, nobody else is jumping in -- I have run enclojure on Ubuntu, but I don't use it regularly.

17:04 blackdog: Chouser: this works in the browser ...

17:04 (ns test)

17:04

17:04 (defn setText [t]

17:04 (.html (jQuery "#nice") t))

17:05 and in the html

17:05 <script>

17:05

17:05 $(document).ready(function(){

17:05 test.setText("rocking")

17:05 });

17:05 </script>

17:05 H4ns: lisppaste8: url

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

17:05 blackdog:

17:05

17:05 H4ns: blackdog: can you use the paste bin please?

17:05 blackdog: yes

17:05 Chouser: blackdog: great.

17:06 blackdog: does emacs have a lisppaste command?

17:07 so i can select something and then paste it automatically?

17:07 H4ns: blackdog: not that i knew of it, but it's kind of a nice idea. let us know if you write or find it.

17:07 blackdog: jedit has one

17:08 quite useful

17:08 Chouser: http://agriffis.n01se.net/nopaste/

17:08 ^^ I use that

17:08 blackdog: thanks

17:14 aperotte: Chouser: I was having some difficulty, I'll try again. I just wanted to make sure that someone has had success before. Thanks

17:18 StartsWithK: blackdog: http://paste.pocoo.org/about/

17:18 i don't know how well it works, never tried it myself

17:19 blackdog: StartsWithK: i think the link Chouser gave me is what i want i can call it direcrlt from emacs

17:20 StartsWithK: blackdog: they clame to have emacs support, but link is broken :/

17:20 blackdog: ok :)

17:59 Chouser, jquery, clj.js, boot.js and a small test - 189K, with yui compressor

18:32 Chouser: blackdog: ouch

18:32 not gzipped though?

18:43 If I turn off *debug-fn-names* when generating boot.js, and then run clj.js and boot.js through the YUI compressor, I get 130KB of javascript, which gzips down to 22KB

18:43 blackdog: 0k cool, didn't know about that

18:45 Chouser: serving gzipped .js can be a bit tricky, though.

18:45 blackdog: oh, down to 22kb! wow

18:51 Chouser: of course that's without the html or jQuery

18:57 blackdog: Chouser: are maps, vectors and lists implemented?

18:57 danlarkin: I'm sad that macroexpand can't expand an invalid macro

18:57 H4ns: will i ever learn that i need (format "foo") not (format nil "foo") in clojure? couldn't that have been renamed? *whine* :)

18:57 danlarkin: I want to see what I'm doing wrong :-/

18:58 Chouser: danlarkin: PersistentHashMap, PersistentVector, and PersistentList should be -- no guarantees about buglessness, though

18:59 just search clj.js for \"PersistentList\" to find out if the class is implemented yet

18:59 blackdog: ok

18:59 Chouser: Sorted maps aren't there yet

19:00 Feel free to implement anything that's missing. :-) I generally open the .java in one window and clj.js in the other, and just translate.

19:00 H4ns: Chouser: clj.js is a clojure compiler in javascript?

19:01 Chouser: clj.js is clojure runtime in javascript (RT.java plus various other .java files)

19:01 tojs.clj is a clojure-to-javascript compiler written in clojure. :-)

19:01 both need to be renamed

19:01 H4ns: Chouser: ah, ok. *shiver*

19:01 :)

19:01 blackdog: the compiler is really just the normal clojure compiler with callbacks no?

19:02 Chouser: H4ns: I know, I know.

19:02 blackdog: sorta. It definitely leans very heavily on the normal clojure compiler.

19:02 H4ns: Chouser: i guess it is a fun thing to do, and people love such things. like the ocaml thing in js, and parenscript.

19:03 Chouser: well, writing code in clojure is so fun, and having to switch to JavaScript for the browser is a drag.

19:04 this lets you code for the browser but with macros, persistent data structures, destructuring, etc.

19:04 H4ns: Chouser: sure, i understand that. it is just the debug aspect that makes me shy away from such things.

19:04 Chouser: yeah, pre-clojure I was pretty down on any to-javascript compilers.

19:04 H4ns: Chouser: i may be just a lousy programmer, needing a debugger and all :) - i made my peace with javascript, and mochikit made that rather easy

19:05 Chouser: but maybe i'm becoming such a die-hard clojure hacker now that i'll choose clj.js in the future, too. javascript syntax is just a pain.

19:06 Chouser: the debugging is as terrible as it could be. All the var and local names are repeated in the JS by default, so finding your place isn't too bad.

19:06 s/is/isn't/

19:06 blackdog: :)

19:06 Chouser: freudian

19:07 H4ns: *chuckle*

19:07 i guess once i'm over all this "i want proper error messages" thing, i'll feel more comfortable with the thought.

19:07 * H4ns continues his wrestle fight

19:08 Chouser: you still get a lot of the compile-time errors, since it's the same compiler

19:08 H4ns: that actually is very nice. parenscript is more of a mock lisp.

19:26 Chouser: YUI compressor seems to introduce a bug

19:28 blackdog: did you see this http://yuiblog.com/blog/2008/02/11/helping-the-yui-compressor

19:28 give's some hints about problems with --verbose

19:34 Chouser: interesting -- points out some improvements I could make in tojs.clj

19:34 But it's screwing up my string literals, generating code with syntax errors in it.

19:37 blackdog: mmine is fine here

19:37 with the default options, no syntax errors in firebug

19:39 i downloaded latest version

19:48 Chouser: I have 2.3.6

19:48 blackdog: mmm, i have 2.3.5

19:49 thought i had the latest

19:49 i'll try upgrading see if it fubars

19:49 lisppaste8: danlarkin pasted "defmacro" at http://paste.lisp.org/display/68005

19:51 danlarkin: so that macro does not work, but if I take out the last line, it does work

19:51 but I want it to define the symbol _and_ add it to the v-list

19:51 H4ns: danlarkin: expand into a do maybe?

19:52 rhickey: right

19:52 danlarkin: d'oh

19:53 blackdog: Chouser: all is well with 2.3.6

20:06 yangsx: I cannot access http://clojure.blip.tv; is there any alternative URL to the videos there?

20:20 danlarkin: yangsx: works for me?

20:24 yangsx: danlarkin: probably because of access restriction in China

20:25 danlarkin: yangsx: wow that's a real shame

20:26 abrooks: yangsx: Are there other video sharing sites (such as youtube.com) which are accessible?

20:26 Chouser: or even better, video.google.com, since then you can download the original

20:26 abrooks: Chouser: I think you can download the .mov from Blip.

20:28 yangsx: abrooks: google's works for me

20:54 abrooks: rhickey: Have you thought of using Google Video? Was there anything in particular that pulled you to Blip.tv? Personally, I find Blip's lack of instant seek and thumbnail preview points fairly annoying. The player is not nearly as good as Google Video with regard to navigation as well. The screen casts are so excellent but it's hard to quickly pull up sections to share with friends (Google Video allows URI anchors to points ...

20:54 ... in the video).

20:58 rhickey: I tried Google Video but the resolution is really low

20:58 abrooks: Oh, hm. Good point.

20:58 Blip does look really nice.

20:59 I don't know of any Mac OS X screen capture programs which can capture to vector based Flash... there are several for X which are really nice.

20:59 rhickey: The best way to view is to download first

21:01 abrooks: rhickey: Yeah, I've often wanted to email someone a pointer to a particular section of a video as one can do like this: http://video.google.com/videoplay?docid=7760178035196894549#5m28s

21:02 (The #5m28s is the anchor into the video timeline)

21:03 rhickey: Would you be opposed to some of us downloading the original and uploading it to other video sharing sites?

21:08 rhickey: abrooks: I'd prefer not

21:08 abrooks: Okay. :)

21:09 rhickey: I agree the timeline pointers are neat. I'm terribly disappointed by the FLV format BLIP requires for the front page player. I can convert to the QuickTime in real time, FLVs take 8-16 hours to produce with Adobe's encoder

21:13 yangsx: rhickey: unfortunately, blip is not accessible to me from China :)

21:13 rhickey: yangsx: I understand, still thinking about that

21:14 yangsx: rhickey: and one can download higher resolution video files from video.google.com, e.g. with clive

21:17 rhickey: yangsx: what about itunes?

21:18 yangsx: rhickey: I haven't tried that, not sure

21:18 rhickey: they are there

21:20 H4ns: what could be the reason for a classnotfound exception, given that the jar is in place, contains the class and the classpath includes the jar? how does one debug such problems?

21:21 rhickey: H4ns: is the class public?

21:22 H4ns: rhickey: yes. in fact, i used it already, it worked, and now it does not.

21:22 rhickey: what is different?

21:22 H4ns: rhickey: is there some debug flag that i can use to trace jar file/class name resolution in the jvm, preferably without being overwhelmed?

21:23 rhickey: that is a very good question. i'd claim "nothing", but that obviously can't be the case.

21:31 java -verbose shows class loading information, and i was using the wrong script to start clojure

21:41 yangsx: I'm using Debian 64-bit. Is there a way to fetch files from the itunes with Linux. I'm still searching

22:17 ozzilee: Does the Repl have any way to get at the most-recently returned object?

22:18 Chouser: *1

22:18 ozzilee: Ah nice, thanks :-)

22:18 Chouser: np

22:20 ozzilee: Hmm, what's a good way to do something like while (foo.next()) { foo.bar() } ?

22:20 doseq maybe?

22:20 Chouser: foo.next() mutates -- is it an Iterator?

22:20 ozzilee: Jdbc4ResultSet

22:22 Chouser: (doc resultset-seq) ?

22:23 ozzilee: Heh wow, that's amazingly specific to this problem. Nice.

22:23 Chouser: Yeah, it's a bit unusual for boot.clj, but there you go.

22:25 ozzilee: All right, goal accomplished for the night, clojure is speaking to postgres. Thanks for the help.

22:26 Chouser: np

22:58 danlarkin: H4ns: I see @planet_lisp is up, good job

23:00 H4ns: danlarkin: thanks - well, it was kind of an end-to-end experience to test the deployability on freebsd and that. i still have a hard time being productive with clojure, but it is improving :)

23:00 danlarkin: what language do you use primarily?

23:01 H4ns: common lisp. which is near enough to clojure to make things relatively confusing :)

23:01 danlarkin: haha oh yes it must be fun for you

23:02 H4ns: what language are you coming from?

23:02 danlarkin: python

23:03 that's what I use for my day job, anyway

23:03 H4ns: propably not a bad background for learning clojure either. are you planning to do something real with clojure?

23:06 danlarkin: well yes, but it's pretty ambitious so it'll be slow going, especially while learning a new language

23:06 H4ns: :)

23:06 same thing here.

23:07 danlarkin: the parallelism language constructs will help immensely, though

23:07 that's why I'm not doing it in python

23:09 H4ns: that is what I hope will help me, too. I will also use a lot of java software as infrastructure, hoping that it holds up with the promises in terms of matureness

23:16 danlarkin: access to all of these existing java libraries is killer, though. that's the reason I hadn't started in CL yet

23:17 one of them, anyway

23:18 H4ns: yeah. at the moment i'm considering how to access all these libraries, though. handing pointers to mutable java objects into pure functions seems like not being the best way.

23:19 hand writing wrappers somehow does not seem like a good way, too. but i'm pretty sure that someone else already has thought about this. i'm just writing a group posting inquiring for some thoughts on this.

23:20 danlarkin: I suppose it could be done with a macro?

23:20 H4ns: danlarkin: depending on what you mean by "it"

23:21 making a macro that lets proxy look a little nicer for common cases certainly is not hard

23:21 creating a useable functional interface from large framework classes looks like being harder.

23:25 Chouser: H4ns: don't be afraid of Java

23:27 H4ns: i'm not afraid, i just don't know my way around. calling getters does not frighten, but disgust me :)

23:29 Chouser: i'm really looking for the idioms of other, more experienced clojure hackers. if passing java objects without disguise is the way to go, so be it. i'd just not want to be missing something that makes things nicer.

23:35 anyway, need sleep. cheers.

23:35 Chouser: g'night

Logging service provided by n01se.net