#clojure log - Sep 10 2011

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

0:47 technomancy: srid: why not just schedule tasks in-process?

8:25 wiseen: is there a way to do something like this in clojure : https://gist.github.com/1208248 - specifically I don't know how to get x out of try/catch scope in to upper scope without using something like atom

8:27 btw. I'm new to clojure so I'm likely missing something obvious

8:27 akhudek: an atom is your only choice for something like that

8:28 although that style is not fucntional

8:28 perhaps there is another way to achieve your end goal?

8:29 or rather, I should say that that style is mutable, which you should generally try to avoid in clojure

8:29 wiseen: akhudek, well I need to catch only the exceptions thrown in foo and foward the result to bar or take a different route if foo throws - and let bar exceptions blow up

8:30 yeah I know it's mutable, but that's because try/catch introduces new scope, I'm not actually mutating value after initialization

8:31 so atom is the way then tnx.

8:31 akhudek: https://gist.github.com/1208255

8:31 wiseen: ah, but that will catch exceptions thrown by bar

8:32 akhudek: actually, I shouldn't even have x in there

8:32 yes, it will, but also those of foo

8:32 and since foo is thrown first

8:32 you could also do

8:32 wiseen: ah but I only need foo exceptions

8:33 akhudek: https://gist.github.com/1208256

8:34 wiseen: yeah I came up with that but is there a way to know that I took the exception path when I get to (bar x), since nil is a valid foo result

8:34 maybe a dummy object ?

8:35 or a unqiue exception :\

8:35 yeah I think that would actually work, exception that escapes the bar(x) but is caught after that line, tnx.

8:36 akhudek, tnx !

8:38 akhudek: No problem, although I still suspect that there is a more idiomatic way to accomplish whatever your end goal is.

8:39 Unless you are dealing with some really icky java interop.

8:42 wiseen: no not really, I'm trying to implement a map function that works on Observables (.NET RX) and I want to catch exceptions by mapped function and send it trough the error path of observer but I don't want to catch exceptions raised by observer callback, that should just bubble up if not handled in the callback... but this works !

8:50 akhudek: hmm, I see

9:50 supernova: where can i find a list of open source clojure projects

9:53 i am learning clojure and would like to read and contribute to clojure based projects. if anyone needs a hand let me know.

9:55 ebaxt: supernova: http://www.clojure-toolbox.com/

9:56 supernova: thats a handful full of projects. thanks!

9:56 ebaxt: supernova: np :)

10:24 dark_src: I want to build a website using clojure.. is there any framework?

10:26 upwardindex: dark_src: check out http://webnoir.org/

10:27 ebaxt: Thanks, that toolbox is something which will be very useful!

10:28 dark_src: something like GRAILS?

10:30 ebaxt: dark_src: Also check out this for a more detailed discussion on ring (sort of like rack) and Compojure. http://www.infoq.com/presentations/Clojure-and-the-Web

10:31 raek: http://brehaut.net/blog/2011/ring_introduction <-- this is a good introduction to the web stack too

10:31 dark_src: ebaxt: sure.

10:33 looking at conjure as well

10:33 https://github.com/macourtney/Conjure

10:39 ebaxt: can you share any other list of open source clojure projects

11:29 devn: dark_src: you can look at the list of projects I'm watching

11:29 there's a bunch of ruby projects and what-not mixed in

11:30 but it has most of the big projects from the last 2 years

11:30 https://github.com/devn

11:46 https://github.com/devn

11:46 whoops

11:47 gfrlog: that's a weird password

11:47 I certainly wouldn't have guessed it though

11:54 dark_src: devn: thanks!

12:35 tomh: is there a clojure bot here?

12:36 companion_cube: ,(+ 1 1)

12:36 clojurebot: 2

12:36 tomh: ,((fn [x] (filt­er (fn [x] (not=­ (/ x 2) 0)) x)) #{1 2 3 4 5})

12:36 (1 2 3 4 5)

12:36 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: filt­er in this context, compiling:(NO_SOURCE_PATH:0)>

12:37 tomh: hmm

12:37 ,((fn [x] (filt­er (fn [x] (not=­ (/ x 2) 0)) x)) #{1 2 3 4 5})

12:37 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: filt­er in this context, compiling:(NO_SOURCE_PATH:0)>

12:38 gfrlog: tomh: I'm seeing some blue dashes in there

12:38 tomh: blue dashes?

12:38 gfrlog: yeah, filt-er and not=-

12:39 I assume you can't and it's some bizarre character thing

12:39 tomh: oh hmm

12:39 ,((fn [x] (filt­er (fn [x] (not=­ (/ x 2) 0)) x)) #{1 2 3 4 5})

12:39 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: filt­er in this context, compiling:(NO_SOURCE_PATH:0)>

12:39 gfrlog: ,((fn [x] (filter (fn [x] (not= (/ x 2) 0)) x)) #{1 2 3 4 5})

12:39 clojurebot: (1 2 3 4 5)

12:39 tomh: O_O

12:39 it looks exactly the same here

12:40 gfrlog: ,((fn [x] (filter (fn [x] (not= (/ x 2) 0)) x)) #{1 2 3 4 5})

12:40 clojurebot: (1 2 3 4 5)

12:40 tomh: ,((fn [x] (filter (fn [x] (not= (/ x 2) 0)) x)) #{1 2 3 4 5})

12:40 clojurebot: (1 2 3 4 5)

12:40 gfrlog: that one I typed out manually

12:40 tomh: weird

12:40 gfrlog: the first one I copied and pasted from yours, trying to remove the dashes (but failing apparently)

12:40 tomh: maybe chrome is doing it

12:40 not sure

12:40 gfrlog: this is why we never should have left ascii and everybody with weird languages shoulda just redone their alphabet.

12:41 tomh: anyway, is there some nicer way to write partial functions in clojure?

12:41 gfrlog: yep

12:42 (fn [x] (not= (/ x 2) 0)) ==> #(not= (/ % 2) 0)

12:42 tomh: hmm ok

12:42 any idea why its returning the whole list rather than only the odds?

12:42 gfrlog: also, if you're simply currying, as is the case with your outer function, you can use partial

12:43 tomh: ok

12:43 gfrlog: ,(map #(/ % 2) #{1 2 3 4 5})

12:43 clojurebot: (1/2 1 3/2 2 5/2)

12:43 gfrlog: ,(map #(rem % 2) #{1 2 3 4 5})

12:43 clojurebot: (1 0 1 0 1)

12:43 gfrlog: that's what you want

12:43 tomh: oh, facepalm -.-

12:43 gfrlog: :)

12:45 tomh: of course, if you're doing more than just messing around, you might be interested in the built in function ##(doc odd?)

12:45 lazybot: ⇒ "([n]); Returns true if n is odd, throws an exception if n is not an integer"

12:45 tomh: just messing around

12:46 gfrlog: okay :)

12:46 tomh: dont think clojure is something I would use, but as a self-respected programmer, I should atleast have tried it -.-

12:46 gfrlog: why wouldn't you use it?

12:46 tomh: syntax

12:47 gfrlog: aw, but besides all the other best parts, that's the best part! :)

12:47 tomh: yeah... not for me :P

12:47 SergeyD: hi! Question for Emacs - SLIME users - how to go to the source of error after the failed slime-load-file? From the buffer that shows error, where there is a choice to press 0 to "quit to the SLIME top level "

12:47 gfrlog: tomh: it really starts shining when you find a use for macros

12:47 SergeyD: just pressing 0 does not move me to the error source

12:47 tomh: gfrlog: can you give me an example of that?

12:48 gfrlog: tomh: sure -- I assume you're not familiar with the -> macro yet?

12:48 tomh: not yet

12:48 no macro's at all

12:48 SergeyD: tomh, about macros - do you know Java annotations?

12:49 tomh: yeah, I used them

12:49 gfrlog: well you're likely using some macros without knowing it (e.g., defn)

12:49 tomh: haven't used defn yet

12:49 just started playing with it

12:50 gfrlog: essentially macros give you a way to specify a new syntax, which can be used to keep common repetitions out of code and keep it more readable

12:50 SergeyD: tomh, now imagine that for every meaningful annotations from Hibernate or JUnit or whatever you can easily see the code that implements that annotation - that is what macros do in LISP world in practive

12:50 tomh: ok

12:50 gfrlog: in the case of ->, the issue is that a lot of clojure (and lisp) expressions tend to get rather hairy and have forms like (a (b (c d e) f))

12:51 SergeyD: tomh, that is metaprogramming. It's too complex in Java as you can see from trying to find the code that implements @Entity for example

12:51 gfrlog: which is hard to read; in particular it often makes the most sense to try to read it backwards, which isn't fun

12:51 -> lets you convert that expression into (-> d (c e) (b f) (a))

12:51 tomh: how is that more readable

12:51 gfrlog: and now that I've written that out, I'm thinking the example might be more confusing than it should have been :)

12:52 tomh: hehe

12:52 gfrlog: I should have picked real functions instead of just letters

12:52 lemme think for a sec

12:52 even better I'll look through some code

12:52 I was just doing some java interop the other day and it came in real handy

12:52 tomh: SergeyD: I dont think it is too complex in java :P

12:53 SergeyD: tomh, really? So it's trivial for you to search implementations for every annotation you use? Then it would be extremely easy for you in Clojure

12:54 tomh: SergeyD: I just have more java experience than clojure

12:55 gfrlog: tomh: okay here's an example from just two days ago: https://gist.github.com/1208518

12:55 since it's interop I can probably add in a java equivalent too...

12:56 ...and so I did

12:56 tomh: ok, that looks somewhat readable

12:57 gfrlog: in this particular case you might argue that all we did is take something terrible and get it back to the palletability of java

12:58 but macros are much more general than that -- they essentially let you take any code and transform it into anything else before it gets evaluated.

12:58 tomh: but what exactly is ->, is it related to some CS concept or?

12:58 gfrlog: You could have such a thing in any language, but in clojure (lisp) it's particularly simple because of the code/data thing

12:58 tomh: I don't think so, it's just a syntactic helper

12:58 tomh: ok

12:58 similar to <- in haskell?

12:58 gfrlog: oh dear I have no idea

12:58 tomh: oh ok

12:59 I think it is similar

12:59 gfrlog: haskell doesn't have macros that I know of, but I don't know too much about haskell

12:59 tomh: well the <- is built-in syntactic sugar for the bind operation monads need to implement

12:59 raek: -> is nothing like <-

13:00 tomh: ok

13:00 raek: it's just a rewrite rule

13:00 gfrlog: my suspisions confirmed

13:00 raek: (-> a (f b c) (g d e)) is the same as (g (f a b c) e f)

13:00 and is usually pronounced "thread"

13:01 similarily, (->> a (f b c) (g d e)) is the same as (g e f (f b c a))

13:01 gfrlog: tomh: for me the power of macros is in keeping the code dry; in most other languages there's some minimum level of syntactic ceremony that simply can't be refactored out (more for java, less for e.g. ruby, but always there). With macros that's virtually not the case anymore.

13:03 aside from the bare syntactic atoms like parens and quotes and such, any other cruft can be removed

13:04 e.g., if you write a lot of functions of 0 args and get tired of the [], you can write a macro that adds it in for you

13:06 qed: Does anyone know if I can write nodejs with clojurescript without needing to do the following: (. os hostname "")

13:06 if I don't pass the "" it will return the function hostname

13:07 dnolen: (. os (hostname))

13:07 devn: oops nevermind

13:07 dnolen: should work I think.

13:07 devn: yes just got that

13:07 yeah, works now -- thanks dnolen

13:08 * gfrlog wonders if devn and qed are the same person

13:08 devn: they are, not sure how i even just did that

13:08 dnolen: anybody tried out the browser REPL yet?

13:08 devn: dnolen: is that merged into master now? i haven't looked recently

13:09 dnolen: devn: it was yesterday I think.

13:09 devn: sweet! /me pulls

13:09 ive heard it's impressive and cool

13:10 gfrlog: I would like somebody to put it up on a site somewhere I can try, as I have a lot of trouble getting a dev env for clojurescript set up

13:10 tomh: gfrlog: I guess I need to see some more before/after code before I can make my own judgement about those macros though

13:12 gfrlog: tomh: part of the argument is how easy they are to implement, because of the code-as-data. You essentially are writing a function that takes code as argument and returns different code. For example, the null-arity use case I just mentioned could be done like this:

13:12 (defmacro def-noarg-fn [fnname & body] `(defn ~fnname [] ~@body))

13:13 tomh: code-as-data == support for first class functions?

13:13 gfrlog: no, homoiconicity -- the fact that all lisp code is also a lisp data structure

13:13 (+ 4 8) is a list of 3 elements

13:13 clojurebot: *suffusion of yellow*

13:14 tomh: ah in that sense ok

13:14 raek: code-as-data == what you send to eval is not text, but data in the form of the data structures of the language

13:14 dnolen: tomh: for a deeper look at why macros are interesting you should look Art of the Metaobject Protocol. That book was written in 1990. It shows how you can build a object system more general than even Java - and tweakable, unlike Java. Macros let you write compilers for you language w/o leaving your language.

13:14 gfrlog: it's why macros are so easy. If you wanted macros in haskell, you'd have to learn to manipulate an unfamiliar abstract syntax tree.

13:15 tomh: ok

13:15 so in lisp you could write a function that replaces all occurences of (+ x y) to (- x y) for example?

13:15 gfrlog: sure

13:16 dnolen: tomh: you can embed entire programming language paradigms - Prolog for instance, and it can be efficient.

13:16 tomh: I see

13:16 qed: did 1.3 get released yesterday?

13:16 tomh: well personally, in the programs I write, i've not seen a lot of cases where I need such functionality

13:17 but maybe I should move into some area without trivial web code

13:17 gfrlog: tomh: it's the sort of thing you don't notice until you know it's possible

13:17 qed: i read through a bunch of the dev threads but ended up a bit confused about whether friday (yesterday) was the day or if this was going to wait until next week

13:17 raek: I don't think it's unusual for a library to define no macros at all

13:18 dnolen: tomh: because you don't have those glasses on. For a good treatment on the usefulness of combining Object Oriented, Functional, and Logic programming paradigms - http://www.amazon.com/Concepts-Techniques-Models-Computer-Programming/dp/0262220695

13:18 * gfrlog runs off to get the baby

13:18 raek: it depends on how well the stuff that the lib does can fit the clojure way of doing things

13:18 tomh: dnolen: thanks for the link

13:21 dnolen: tomh: Odersky's slides from Scala Days 2011, http://days2011.scala-lang.org/sites/days2011/files/01.%20Martin%20Odersky.pdf, has an interesting problem called phone coder. Nice small example of a real world program. Think about how much code it would take to express the program in the language you're most familiar w/

13:22 tomh: lets see

13:23 I could try to write it in haskell and expect similar results

13:23 michaelr525: hey

13:24 dnolen: tomh: when you're done, see if your code is as short / clean as this, https://gist.github.com/1107653. Here I'm mixing Clojure and the embedded Prolog library I wrote to get the program down to 23 lines.

13:25 tomh: dnolen: that looks like scala

13:25 dnolen: tomh: even a functional version can't be this clean because Prolog can infer which seq can concatenate to the final seq.

13:25 tomh: oh below

13:26 well to be fair, scala's version includes typed code

13:27 but it looks impressively short though :)

13:27 dnolen: tomh: I'm not talking about the typing. Just what tools you can reach for. Scala, you're stuck w/ Scala. Clojure - you can use a much larger chunk of CS to get to where you want to get - IMO.

13:28 tomh: why is that

13:29 companion_cube: dnolen: what do you mean by 'stuck with scala' ?

13:30 dnolen: tomh: because the language itself is extensible w/o hassle. Scala has pattern matching - with various known limitations. https://github.com/clojure/core.match, this is a pattern matching library I'm using based off a recent paper 2008, brings very efficient pattern matching to Clojure.

13:30 tomh: and the pattern matcher is itself fully extensible. this kind of thing usually requires compiler plugins.

13:31 companion_cube: you're stuck w/ larger number of choices imposed by the language designers is all that I mean.

13:31 companion_cube: on the other hand, scala is supposed to be faster and safer (because of static typing), right?

13:31 tomh: dnolen: ok thats a pretty cool use of macros

13:32 dark_src: ,(+ 1 1)

13:32 clojurebot: 2

13:32 dnolen: companion_cube: IME Scala is not faster. This pattern matcher is actually like 30X faster for arrays of primitive data. I don't have to wait for Scala to optimize that. I can optimize it myself.

13:32 tomh: in my own experience, when I write dynamic code and get bugs, I would avoid a whole lot of them if I used a statically typed language

13:33 companion_cube: dnolen: i was talking generally... static typing allows the compiler to optimize

13:33 dnolen: tomh: IME, the really nasty bugs are not dynamic typing bugs. those bugs needs tests. regardless of types.

13:33 companion_cube: tomh: the same, especially about compositionality

13:34 tomh: dnolen: yeah, the complex bugs, but the trivial bugs are usually type errors -.-

13:34 those consume most of my time

13:34 dnolen: tomh: complex bugs consume most of mine ;)

13:34 tomh: well I dont write complex apps atm, so I only have trivial bugs

13:35 like nullpointers, bad error handling

13:36 unpure code also has a lot of bugs

13:36 which could be solved by coding in a pure style

13:36 companion_cube: dnolen: in scala, you never pattern-match against arrays

13:36 dnolen: tomh: preconditions / postconditions are useful. at some point I'm planning on looking at adding types to Clojure but that's a ways off.

13:36 companion_cube: i just discovered it was possible :D

13:36 dnolen: tomh: Clojure encourages pure style.

13:36 tomh: yeah I know, clojure would be suitable to prevent those types as bugs as well

13:37 companion_cube: wow, map matching, awesome!

13:41 dnolen: tomh: static typing is good, but I don't think static typing is the final word on writing expressive code w/ less bugs w/o tiring our brains - http://dl.acm.org/citation.cfm?doid=1869459.1869462

13:42 oops meant to share this link, http://wadler.blogspot.com/

13:43 companion_cube: dnolen: imho static typing becomes more useful on bigger projects

13:43 becaue it allows to enforce some consraints on the communication between parts of the program

13:43 tomh: not sure if static typing tires my brains in the same way frustrating type bugs tire my brain :P

13:44 dnolen: companion_cube: I don't agree w/ that at all. bigger projects need organizational support, there's *lots* of ways to get that.

13:45 companion_cube: i find that dynamic typing allows errors to propagate more easily, of course you alos need organization and communication between developers

13:45 dnolen: even better are features which prevent code from getting big!

13:45 devn: im open to both -- it's a balance.

13:46 tomh: dnolen: whats dangerous is big dynamic code -.- like php\

13:46 or JS

13:46 companion_cube: dnolen: i'm not that convinced that dynamic typing brings a really better expressivity

13:46 (if you write real code and not clever one-liners)

13:47 tomh: well haskell also has a lot of clever one-liners, but with type inference you barely notice the typing going on

13:47 unless you try to write faulty code

13:48 devn: companion_cube: dnolen said that he didnt think static typing was the final word -- he didn't say that dynamic typing was the answer

13:48 companion_cube: right

13:49 devn: tomh: that's a good point -- but one might make the argument that there is some complexity lying beneath which can make reasoning about your program a bigger task, no?

13:50 dnolen: companion_cube: yeah I have no answers. But I had a lot of fun implementing core.logic https://github.com/clojure/core.logic. It's pretty damn powerful in my opinion - such things would be too tedious and less useful in languages like Scala / Haskell.

13:51 devn: I don't get Scala.

13:52 tomh: devn: well the reasoning is done by the type checker, and yes, you can write super duper complex code that results in very weird types, impossible to debug

13:52 devn: tomh: *nod*

13:52 tomh: I think the type checker also is O(n^2) in extreme cases

13:52 companion_cube: seems cool

13:52 dnolen: http://kanren.cvs.sourceforge.net/kanren/kanren/mini/type-inference.scm Oleg Kiselyov - type checker, inference, inhabitor. I want to write this kind of code :)

13:52 devn: tomh: It's been a couple of years since I toyed with Haskell, but wasn't there some sort of convention about specifying the types above the function to aid in readability?

13:52 tomh: devn: thats good practice yes

13:53 haskell programmers like to read what code does from reading the type, rather than the code ;)

13:53 devn: heh -- I should dust off my ghc

13:53 I miss you, xmonad.

13:53 tomh: you can get one without dust in the new platform releases

13:54 devn: tomh: so I can get a fancy dmg for OSX? Or is hombrew the right route nowadays? Any opinions there?

13:54 tomh: for haskell, get the platform dmg

13:54 devn: The last time I did anything I needed to pull down ghc and then wrestle with building cabal for 15-20 minutes

13:55 tomh: hehe

13:55 devn: add it to my PATH, etc.

13:55 tomh: ever play with...Yi is it? Qi?

13:55 The haskell editor?

13:55 tomh: well its probably offtopic here anyway, but http://hackage.haskell.org/platform/

13:55 no

13:55 devn: tomh: thanks

13:55 tomh: yi

13:56 devn: tomh: does that come with cabal?

13:56 tomh: and in the mean time, I will install clojure -.-

13:56 devn: yes, with everything

13:56 devn: woo! :) thanks again

13:57 icefox: Following the clojurescript quickstart guild when I run cljsc it has the following line: "hello.cljs goog.addDependency("../unjMi.js", ['hello'], ['cljs.core']);" How do I get it to generate umjMi.js?

13:58 hmm nm found it in the 'out' directory (wasn't expecting that)

14:00 What is the correct way to report buts? The clojurescript bootstrap script works on OS X, but not Ubuntu

14:00 /buts/bugs

14:01 dnolen: icefox: OpenJDK on Ubuntu right?

14:02 icefox: no clue honestly, not a java guy so if a jvm was installed on my system it wasn't intentional. Just ran the bootscript and when running the compiler it outputs a db starting with Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil

14:04 dnolen: icefox: I would try the mailing list, you should post the details of your environment (OS, JDK, JDK version).

14:04 icefox: yah I can post anything that would be helpful.

14:05 thanks i'll send something to the ml

14:06 Very excited about ClojureScript. Staring a new project that is running on a JS engine and the idea of being able to use Clojure for it is really cool

14:07 dnolen: icefox: it's pretty neat. you're brave for trying it out :) using it feels like Clojure 3 years ago.

14:08 icefox: having access to macros is pretty incredible.

14:09 icefox: well I have poked around with clojure and various lisps the last five years, but could never really use them. I was always tied to C++ especially hacking on WebKit, but now ...

14:09 tomh: so in what ways does clojure involve, the language itself is pretty compact right?

14:09 dnolen: tomh: ?

14:09 icefox: Yah I have my own butchered compiler for doing a really poor mans (and limited) version of macros for c++

14:09 can't wait

14:10 tomh: dnolen: I mean, what is different now from 3 years ago, just the libs?

14:10 dnolen: tomh: the tooling

14:10 tomh: ok

14:14 icefox: Where could I find the current api for accessing the dom other js functions etc?

14:15 It isn't mentioned on the Documentation page :)

14:21 dnolen: icefox: most of that functionality is provided by Google Closure. So you'll have to look at their docs. Some example in the ClojureScript repo as well.

14:22 icefox: thanks will do

14:38 Oh cool, looking at core.cljs it looks like calling existing js functionality like console.log(foo) is as simple as (js/console.log foo)

14:57 dnolen: ok ClojureScript browser REPL, mind blown.

14:59 gfrlog: dnolen: that can be done with a single minified JS file, right?

14:59 dnolen: gfrlog: not sure how it works yet, just playing around with the sample in the repo

15:00 gfrlog: dnolen: but I mean you had to compile it right?

15:00 and load it in the browser?

15:00 dnolen: gfrlog: yes I compiled the sample file (which has a ns decl and one line of code)

15:01 gfrlog: man we must not be looking at the same thing: https://github.com/clojure/clojurescript/blob/master/samples/repl/src/repl/test.cljs

15:01 dnolen: gfrlog: same file, the rest is just a comment.

15:01 gfrlog: oh ha

15:01 so it is

15:02 dnolen: anyhow, the compilation I cannot easily do, so I was hoping somewhere I could obtain a compiled version of that so I could post it somewhere and play with it in the browser

15:15 dnolen: whatever Bracha and Bak come up w/ it's gonna have to be pretty damn cool to beat this.

15:19 alandipert: dnolen: agreed

15:29 peteriserins: how to turn a string into an input stream?

15:30 gfrlog: uh...

15:30 do you mean an output stream?

15:30 hmm

15:30 ah no I see

15:31 would (new ByteArrayInputStream (.getBytes s)) do it?

15:34 peteriserins: gfrlog: looks good, I was hoping to use StringReader though

15:40 dnolen: full power of macros available to browser connected REPL ...

16:08 pauldoo: how do I test for reference equality in clojure? (equivalent of == in java)

16:09 alandipert: pauldoo: =

16:09 pauldoo: oh, I thought that called .equals() ?

16:10 alandipert: pauldoo: not necessarily

16:10 clojure.lang.Util/equiv

16:11 impl influenced by this interesting paper: http://www.pipeline.com/~hbaker1/ObjectIdentity.html

16:12 pauldoo: I understand that object equality is an entire interesting can of worms, but right now I'm just looking to test reference equality on Java objects exactly as == would..

16:12 (I'm messing about)

16:13 jkkramer: pauldoo: identical?

16:14 alandipert: = should give you that, is it not working as you'd expect?

16:14 jkkramer: ,(identical? [1] [1])

16:14 clojurebot: false

16:15 jkkramer: ,(let [x [1]] (identical? x x))

16:15 clojurebot: true

16:15 pauldoo: jkkramer: perfect, thank you :)

16:16 alandipert: = tests value equality, not reference equality

16:16 alandipert: ie, I want to detect if two references are the same object. Not just two different objects with same value.

16:17 alandipert: it's a silly thing to need, but I'm messing about

16:19 alandipert: i am surprised i have never needed identical?, maybe because of https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Util.java#L24

16:20 dnolen: cljs-watch + browser REPL = too good to be true.

16:21 alandipert: also, jkkramer: hi!

16:21 jkkramer: alandipert: hiyo :)

16:33 chewbranca: anyone have any recommendations for using slime and the emacs-starter-kit to work with both clojure and common lisp?

17:56 demolithion: @find gravity's rainbow

17:56 oops sorry

18:28 gfrlog: I'm terribly curious how clojurescript implements keywords and symbols

18:30 dnolen: as strings with unicode chars in them.

18:30 gfrlog: oh weird. so a subset of rare strings becomes off-limits?

18:35 dnolen: gfrlog: not off limits - but you do have the likelihood of false positives. seems comfortably unlikely tho.

18:36 gfrlog: dnolen: I would think in theory "false positives" could carry through to any arbitrary error. But agreed, it seems comfortable.

18:37 I certainly prefer it to not having clojurescript :)

18:39 dnolen: gfrlog: I'm starting to think ClojureScript is the Clojure killer app. I have a setup now that's more productive than dev'ing w/ CoffeeScript.

18:39 gfrlog: dnolen: any idea how far out the numerics are from being implemented?

18:40 dnolen: gfrlog: no.

18:40 gfrlog: I just sent in my CA today. That's the part I'm really itching to see. Been using doubles for way too long.

18:41 How is this browser-repl thinger supposed to work? The server-side repl is connected to the browser somehow?

18:50 icey: is there a commonly used clojure lib for sending email? or does everyone do it via java interop?

18:51 dnolen: gfrlog: yes, server side repl compiles the JS and sends it to the browser, browser returns result.

18:51 gfrlog: oooooh

18:51 okay I see.

19:00 peteriserins: how do I convert a curl post to a clj-http post?

19:01 I'm assuming I don't have to do %-escapes and +-escapes in clj-http, but getting different results

19:17 TimMc: dnolen: Does someone have a public CLJS REPL running?

19:18 dnolen: TimMc: ? No I'm talking about the new Browser REPL support in ClojureScript

19:20 TimMc: aw, OK

19:21 What is it exactly?

19:22 dnolen: TimMc: a Clojure REPL that can interact w/ a live browser environment

19:23 TimMc: Oh. I thought it could already do that...

19:23 dnolen: TimMc: no, standard ClojureScript REPL just compiles JS

19:23 TimMc: OK

19:24 And that resulting JS could already talk to the page, right?

19:25 dnolen: TimMc: standard REPL = compile ClojureScript -> JS -> eval in Rhino

19:25 TimMc: Ah!

19:25 dnolen: browser REPL = compile ClojureScript -> JS -> send to browser -> browser respond -> output in REPL

19:26 clojurebot: whose job is<reply>that is jarpiains job

19:27 TimMc: The "standard REPL" all happens on the server, then?

19:27 dnolen: TimMc: yes

19:27 gfrlog: TimMc: he just explained that to me 20 lines up :)

19:27 TimMc: OK, I'll read that again.

19:27 I think I need to throw away some preconceptions.

19:28 dnolen: I can manipulate the DOM, add animations, load new functions, all from the browser connected REPL

19:30 TimMc: So the browser keeps polling the server for things to run, effectively acting as a pull-based JS-eval server?

19:31 gfrlog: is there a built in function for turning a JS object into a CS map?

19:32 dnolen: TimMc: possibly I haven't looked closely at the implementation.

19:33 TimMc: Curious, so it reverses the notion of having the browser use the server as an evaluation environment.

19:34 dnolen: TimMc: it effectively means that I can use the Clojure REPL the same way I would use the WebKit JS console.

19:35 TimMc: dnolen: So, an interactive dev & debugging tool, not an architectural component.

19:35 dnolen: TimMc: yes.

19:35 TimMc: Although, I am sure there is something terribly clever one could do with that architecturally.

19:37 * gfrlog looks at clojure.core.match for the first time

19:42 dnolen: wow Emacs inferior-lisp mode + Browser REPL, even more fun.

20:13 ok I can see that ClojureScript is now the most efficiently development environment for JS applications by a very large margin.

20:14 gfrlog: dnolen: if only I could learn gclosure really really fast...

20:14 * gfrlog pokes around trying to find the bigints

20:14 dnolen: gfrlog: I'm learning it pretty quickly.

20:14 gfrlog: I swear there were bigints here somewhere

20:15 dnolen: being able to see your whole source file and redefine functions without refreshing the browser is an incredible productivity boost.

20:18 gfrlog: oh wait I think goog.math.Integer _is_ a bigint

20:26 man I'm having a terrible time trying to use gclosure stuff :/

20:37 even when I use goog.math in exactly the same way I see here, the compiler seems to ignore the require: https://github.com/clojure/clojurescript/blob/master/samples/twitterbuzz/src/twitterbuzz/layout.cljs

20:42 dnolen: I can already see that you'll have to pry core.match from my cold dead hands when using ClojureScript

21:02 gfrlog: https://gist.github.com/1209031

21:02 the compiler seems to output the right thing (which I believe is "new goog.math.Integer(...)")

21:03 but goog.math.Integer never gets loaded in the JS

21:03 (I'm using cljs-watch)

21:04 alandipert: are you compiling with gclosure advanced mode? if so, it might be removing it because it's never called

21:04 gfrlog: but it is called...

21:04 you mean my function is never called?

21:04 alandipert: right

21:04 gfrlog: do I need the exports metadata?

21:05 alandipert: that is one way to preserve it

21:05 the other is to switch to simple optimization mode, but i'm not familiar with how to do that with cljs-watch

21:05 gfrlog: is it ^:export or ^:exports? Either way it doesn't seem to work...

21:05 at least if grepping my target directory for Integer is any indication

21:06 and trying in the browser confirms it

21:09 see ^:export is correct, but of course still not working

21:27 dnolen: gfrlog: fwiw, I can't get that to work either.

21:27 gfrlog: dnolen: okay, I guess I give up then :)

22:05 I guess it's not an advanced-mode thing, is cljs-watch seems to use :simple by default

22:06 dnolen: gfrlog: I would ask on the ML probably some thing simple. At the REPL it works if I use load-namespace

22:06 gfrlog: dnolen: do you use any goog libs directly?

22:07 dnolen: gfrlog: goog libs works fine, but you trying to call a ctor not an fn.

22:07 gfrlog: dnolen: oh hmm. I guess the randInt function did work now that I think about it

22:08 I think I can do it without the constructor, I'll try that

22:12 and so it works

22:12 dnolen: thanks for the hint

22:12 dnolen: gfrlog: no problem.

23:10 wow … ClojureScript … wow

23:10 chewbranca: dnolen: oh?

23:10 dnolen: congrats on core.match btw ;-) that's awesome!

23:10 dnolen: chewbranca: thx!

23:11 chewbranca: ClojureScript is going to revolutionize clientside browser development.

23:12 chewbranca: dnolen: nice, what do you think are the key features that will be game changing?

23:13 dnolen: chewbranca: not having to refresh the browser to develop

23:13 chewbranca: https://gist.github.com/1209120

23:13 icefox: You get to use a lispy language for day to day work

23:13 dnolen: having access to all of Clojure amazing abstractions

23:13 chewbranca: macros!

23:13 icefox: Just need to make a firebug like plugin

23:14 dnolen: chewbranca: that file was created interactively sending code iteratively to the browser.

23:14 icefox: ?

23:14 icefox: you mean like source mapping?

23:14 icefox: yah

23:14 or someone already done that

23:14 ?

23:15 dnolen: icefox: no, source mapping is important, just need one browser to release good support for that.

23:15 icefox: anyone currently working on this?

23:15 disclaimer: I am on the webkit browser team at rim

23:16 chewbranca: dnolen: oh damn... I think I completely misunderstood the whole 'browser repl' idea, from that gist it looks like you can control a browser from a local cljs repl? I thought it was the other way around, just having a clojure script repl in the browser

23:16 dnolen: chewbranca: YES control the BROWSER from the REPL, sorry I'm excited.

23:16 chewbranca: dnolen: ok... that makes a TON more sense, that's badass

23:16 I'm very intrigued now

23:17 dnolen: chewbranca: it's not badass, it's like one of the the best thing I've ever seen!

23:17 icefox: Improving webkit's Inspector so the console tab could be a clojurescript console and the scripts would show clojure mapped are the two things I would see.

23:17 chewbranca: I've played with it to the extent that I switched all my openjdk installs to oracle jdk and got the twitter demo running, but haven't had a chance to go beyond that

23:17 that's very cool

23:18 dnolen: icefox: basic source mapping would be sweet, hopefully the vendors figure out some way to support syntax highlighting :) since you're a WebKit guy I guess you might know something about that :)

23:18 chewbranca: one thing I was wondering though: clojure itself makes very good use of the existing java ecosystem, and I know clojurescript makes great use of google's closure toolkit, but that ain't the only game in town in javascript land, and in the javascript world I'm knee deep in non google closure libs, what's the interop like for other javascript libs?

23:19 dnolen: chewbranca: notice that I'm using jQuery in that gist.

23:19 icefox: dnolen: haven't poked at inspector much, but something I will bring up with the guys next week to see how easy/hard that might be

23:19 dnolen: icefox: sweet!

23:20 icefox: no promises at this point, all just poking around, but very excited to finally get to write clojure code that is more than just toy apps

23:21 dnolen: icefox: of course. still, exciting times.

23:22 chewbranca: dnolen: I see you declare a wrapper for jquery, I'm assuming you can just call whatever functions on it comparatively to the java interop macros?

23:22 zerokarmaleft: dnolen: i'd love to see a screencast for that

23:23 dnolen: chewbranca: no wrapper for jQuery, just assigning it to a local def

23:23 zerokarmaleft: I'm working on it.

23:23 zerokarmaleft: right on

23:23 icefox: If you could compile clojurescripts compiler with nacl then you could ship it at least on chrome

23:23 chewbranca: dnolen: yeah by wrapper I meant getting a clojure link to it, just saying that it doesn't look like you're actively using it in that gist

23:24 dnolen: chewbranca: yeah, I had some code like (j "#foo") before

23:25 chewbranca: icefox: as for firebug, honestly it seems like firebug is less important, if you can control the browser with clojure, for anything non trivial, I would most likely rather use the clojure repl for inspection, the tricky part getting a mouse event to trigger inspection of a particular element inside the cljs repl

23:25 dnolen: that's cool though, very cool

23:26 icefox: chewbranca: yah need to poke around to see how hard firebug/inspector would be to extend.

23:27 Though I am just guessing I would really need to make a project or two to see what is really wanted

23:28 chewbranca: icefox: well firebug gets you 90% of the functionality you want, just need to be able to inspect elements, sending the events to the cljs repl without it necessarily needed to be listening for a specific event is the tricky part

23:29 let me rephrase if that didn't make much sense, the most useful thing that jumps out at me, is to be able to select an element or event in the browser, and say, send this to the cljs repl as an element that can be manipulated

23:30 dnolen: chewbranca: you can do that, there's no reason for the browser to communicate that to REPL

23:30 (def foo (j "#foo")) and you have that element

23:31 chewbranca: dnolen: sure there is, if I'm looking at a browser and want to inspect an element that does not have some sort of UUID or easily declaritive path, I want a simple way to operate on, that's one of the best parts of right click -> inspect element

23:32 so what I'm saying is right click -> send to cljs repl

23:33 dnolen: chewbranca: hmm I don't see what benefit that could have given the level of WebKit inspection tools. It would be more useful in a framework setting where a particular element is backed by some "object" or abstraction.

23:35 chewbranca: dnolen: on a daily basis I inspect elements in firebug that don't have a specific id or simple path extraction, and the ability to right click and inspect that element is hugely useful, and I would love to more easily be able to manipulate that element directly

23:36 dnolen: and I agree on webkit/firebug inspection tools being very solid, they get you 90% of the way there, but I see that as a useful way of filtering and searching for the dom elements you're interested in manipulating from the browser

23:36 icefox: yah bit weird now that you mention it that WebKit's inspector doesn't give you an easy console to an element you 'inspect'

23:36 chewbranca: icefox: exactly, I don't know how to do that in firebug either, ie inspect this element then give me a variable reference to it

23:37 dnolen: chewbranca: I see what you mean. From what I've played around with today, I think you could build an incredibly powerful dev environment with such capabilities w/o much effort. No need for plugins really. Just a some base ClojureScript file that adds said functionality.

23:38 chewbranca: dnolen: oh absolutely, and that's all I'm saying, that the only thing you need to extend past firebug is a direct GUI based way to get a programmatic reference to any individual dom element in a page

23:39 icefox: chewbranca: well in chrome you could write an extension that you can right click on and it dumps it to your repl

23:39 wiseen: Is there any reason why add-watch is not implemented on atoms in cljs ? It seems to me all that needs to be done is stick a map in to atom called watchers and dispatch in reset!/swap!/compare-and-set! - but I could be missing something ?

23:40 chewbranca: icefox: yeah that was my thoughts, I'm just not familiar enough with clojure/clojurescript to know what happens when you start dumping things directly into a repl when you could be halfway through typing an expression

23:59 st3fan: oh no 4clojure is failing .. what do i do now!?

Logging service provided by n01se.net