#clojure log - Jul 26 2009

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

0:09 hiredman: ~scala

0:09 clojurebot: Unfortunately the standard idiom of consuming an infinite/unbounded resource as a stream can be problematic unless you're really careful -- seen in #scala

0:38 Anniepoo: I'm crashing the compiler.

0:38 is that sufficiently unusual that I should file a bug somewhere?

0:43 hiredman: Anniepoo: are you sure you are feeding the compiler valid input?

2:22 http://software.intel.com/en-us/articles/intel-c-stm-compiler-prototype-edition-20/ <-- in 2007 intel released a c/c++ compiler with support for some kind of stm, go figure

2:27 slashus2: They have a neat little flash demo.

2:35 The tutorial is a little broken, but it is a neat illustration.

2:35 It is "undefined"

3:18 Fossi1: if you have a gen-class that uses a gen-class, how do you import them/ how do you infer the right build order?

3:22 hiredman: sounds like trouble

3:22 why are you gen-classing so much?

3:22 Fossi1: because i use the android api to create a view and other things

3:23 so i'm surrounded by interfaces i have to implement

3:23 hiredman: proxy

3:24 Fossi1: can try, but the question is still valid

3:24 hiredman: gen-class is really only if you need to provide a constant name for a class

3:25 Fossi1: it is, sure, and I don't know the answer, but I do know it should very much be a corner case

3:25 proxy is much prefered

3:25 and now new-new is almost here

3:25 Fossi1: hmmm. so, for creating a view, i could proxy from the main class ('activity')

3:26 is there a nice way to have a proxy in it's own file?

3:26 hiredman: what do you mean?

3:26 Fossi1: hmm. that didn't make sense

3:26 :)

3:27 hiredman: you still need gen-class to generate a program entrance point

3:27 but most implementation of interfaces shoudl be via proxy

3:31 Fossi1: i can't hold any state in the proxies though, right?

3:33 hiredman: the proxy "methods" are fns so you can close over anything you want

3:34 the real gotcha with proxies is you cannot add methods that don't exist in the superclass or implemented interfaces

3:35 ~gen-class

3:35 clojurebot: No, hiredman, you want gen-interface + proxy

3:37 hiredman: ~proxy

3:37 clojurebot: proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays.

3:37 hiredman: :|

3:37 Fossi1: hmmm

3:38 i don't know yet whether that will be a proble

3:38 hiredman: it really should not be, any methods used on an object should be part of its interface anyway

3:38 Fossi1: i guess i will defer the implementation to other namespaces anyway

3:39 yeah, and then again, it's not a big deal to add another interface

3:40 and think you just made my life a whole lot easier, thanks again :)

3:40 s/and/i

3:41 hiredman: no problem

3:43 I am sort of aghast that you went right to gen-class's complications and passed over proxy, most show up here wonder why the methods they try to tack on via proxy don't work

3:49 Fossi1: well, with such a lot of things to implement, and the compile step inbetween, i thought i'd rather gen-class things instead of adding another layer of indirection

3:50 but then again, as seid, it made my whole life a lot more complex

3:50 and if i wanted performance i c/should've used Java in the first place

3:52 hiredman: I don't think gen-class results in less layers of indirection then proxy

3:52 gen-class classes are just stubs that call out to the clojure functions

3:52 which seems to be more or less what proxies do

3:53 I have looked too much at the implementation of proxy

3:53 Fossi1: might be

3:54 overall, it prolly was a pretty stupid move :)

3:54 hiredman: new-new (which doesn't exactly exist yet) will apparently generate jvm byte code directly be more direct no stubs etc

3:57 Fossi1: figured from what i read here

3:58 when you change such stuff (from gen-class to proxy, ...) somehow slime goes nuts

3:59 anybody know a way to make it forget all bound/compiled things?

4:25 http://developer.android.com/reference/android/opengl/GLSurfaceView.html "Handling events" - how would one port that to clojure with proxies?

4:33 hiredman: so you have a function make-renderer which returns a proxy of GLSurfaceView or something and your main class calls the function and registers the proxy as the renderer

4:38 Fossi1: hiredman: was that an answer or a question?

4:39 hiredman: if you're not sure, it must not be an answer

4:53 Fossi1: lisppaste8: url

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

4:57 Fossi pasted "android setup" at http://paste.lisp.org/display/84212

4:58 Fossi1: almost works now

5:29 ok, now with the proxies, the constructors don't get called i guess

5:30 hiredman: eh

5:30 ,(doc proxy)

5:30 clojurebot: "([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, must be first. If not provid

5:32 Fossi1: actually, i guess it's something else

5:32 hiredman: Fossi1: I am pretty sure the superclass constructor should be called

5:32 Fossi1: there's lots of side effects going on in this code, so i guess that's it

5:35 the object i get from my state later is not the one i called setRenderer on

5:36 angerman: how do I unpack a list

5:36 e.g. ((+ 1 2) (+ 2 3)) -> 3 5

5:36 hiredman: angerman: apply

5:36 but what do you mean by unpack

5:36 angerman: basically I want to use (doto X Y)

5:37 hiredman: that will give you an error because 3 is not a function

5:37 ,((+ 1 2) (+2 3))

5:37 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

5:37 angerman: where Y is of the form ((.method "x") (.methdo "y"))

5:37 i basically generate Y using map

5:38 hiredman: eh?

5:38 still not making a lot of sense

5:38 angerman: ok

5:38 hiredman: what do you want to do?

5:38 angerman: (map (fn [[op key val]] `(.addFilter ~(name key) ~(op *filters*) ~val)) specs)

5:39 that's Y

5:39 and then I want to do (doto (Query. "X") Y)

5:39 hiredman: and why can't you?

5:40 angerman: because as far as I understand it. Y returns ((.addFilter ...) (.addFilter))

5:40 hiredman: no

5:40 well, yes

5:40 angerman: and (doto expects (doto (Query. "X") (.addFilter ...) (.addFilter))

5:40 hiredman: ah

5:40 angerman: so I have a set of parentesis too many

5:40 hiredman: this is in a macro yes?

5:40 angerman: no

5:41 hiredman: weird

5:41 ok

5:41 well,

5:41 angerman: but I guess I could put that map into a macro

5:42 I've to admit I'm quite new to clojure and haven't done any lisp aside from some elisp ...

5:43 hiredman: you seem to be constructing a list, is that want you want to do?

5:43 Fossi1: ,(apply doto (String. "X") '((.toString) (.toString))

5:43 clojurebot: EOF while reading

5:44 Fossi1: ,(apply doto (String. "X") '((.toString) (.toString)))

5:44 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Malformed member expression, expecting (.member target ...)

5:44 hiredman: Fossi1: doto is a special form

5:44 or a macro

5:44 Fossi1: yeah, that's why i wondered

5:44 hiredman: anyway, it is not applyable

5:44 but his example code just contructs a list and does not execute anything

5:45 which is just weird

5:46 angerman: how would it be done in a more lisp like way?

5:46 Fossi1: ah, damn you laziness and side-efects

5:46 hiredman: ,(map (fn [[op key val]] `(.addFilter ~(name key) ~(op {:a 1 :b 2}) ~val)) [[:a :b :c] [:e :f :g]])

5:46 clojurebot: ((.addFilter "b" 1 :c) (.addFilter "f" nil :g))

5:47 angerman: hiredman: exactly.

5:47 hiredman: ,(-> (map (fn [[op key val]] `(.addFilter ~(name key) ~(op {:a 1 :b 2}) ~val)) [[:a :b :c] [:e :f :g]]) (conj '(doto (Query. "X")) (conj 'doto))

5:47 clojurebot: EOF while reading

5:47 hiredman: ,(-> (map (fn [[op key val]] `(.addFilter ~(name key) ~(op {:a 1 :b 2}) ~val)) [[:a :b :c] [:e :f :g]]) (conj '(doto (Query. "X")) (conj 'doto)))

5:47 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$conj

5:48 hiredman: bah

5:48 ,(-> (map (fn [[op key val]] `(.addFilter ~(name key) ~(op {:a 1 :b 2}) ~val)) [[:a :b :c] [:e :f :g]]) (conj '(doto (Query. "X"))) (conj 'doto))

5:48 clojurebot: (doto (doto (Query. "X")) (.addFilter "b" 1 :c) (.addFilter "f" nil :g))

5:48 hiredman: ,(-> (map (fn [[op key val]] `(.addFilter ~(name key) ~(op {:a 1 :b 2}) ~val)) [[:a :b :c] [:e :f :g]]) (conj '(Query. "X")) (conj 'doto))

5:48 clojurebot: (doto (Query. "X") (.addFilter "b" 1 :c) (.addFilter "f" nil :g))

5:48 hiredman: generating something like that outside of a macro is just weird

5:49 generally a macro would generate a structure like that in place of a call to a macro

5:49 angerman: hiredman: I tried to wrap the generation of the list into a macro ... but I failed ...

5:49 hiredman: then it would get evaluated

5:49 I dunno if you want a macro

5:49 I have no idea what you are doing

5:49 angerman: well I have this (Query. "X") object

5:50 to which I want to apply the .addFilter methods.

5:50 hiredman: well

5:50 angerman: and I want to hand in something like (and (= :key1 "value1") (= :key2 "value2))

5:50 Fossi1: sounds like a job for a macro to me

5:50 hiredman: are you planning to then call eval on this?

5:51 angerman: I've looked at clojureql and came as far as breaking it into the ((= :key1 "value1) (= :key2 "value2"))

5:52 hiredman: not directly. I just intend to return the Query object

5:52 hiredman: angerman: but the filter methods will not be called

5:52 the result will be that datastructure

5:52 a literal list

5:53 '(doto (Query. "X") …

5:53 angerman: hiredman: yes that's why I though generating the literal list (.addFilter ...) (.addFilter ...) would be fine if I put them into arguments to the (doto (Query. "X") <here>)

5:53 hiredman: no

5:53 no

5:54 no

5:54 Fossi1: i think he got your point ;D

5:55 hiredman: a macro might be what you want, but as confused as confused as you apear to be about runtime vs. compiletime I don't think writing macros is a good idea

5:56 I kind of doubt a macro is what you want anyway, if you are trying to generate .addFilter calls based on information only around at runtime, then a macro won't work

5:58 your best bet is just to loop over your set of arguments to .addFilter

5:58 kylesmith: I have a security/sandboxing question. I wrote a dsl for a 'database' application. I wrote the dsl in such a way to allow arbitrary user code. Is there a way to sandbox user code running on my server? The alternative is to transfer the data to the user and let them bork their own machine, but even compressed, it would be in the range of 100MB. Thoughts?

5:59 hiredman: kylesmith: well, that sounds horrible

5:59 ~sandbox

5:59 clojurebot: sandbox is http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html

5:59 hiredman: have fun

5:59 angerman: hiredman: thanks and sorry. I'll try to loop over it

6:00 hiredman: nothing to applogize for

6:00 actually, use for and dorun or doall

6:01 (for [[op key val] specs] (.addFilter query-object (name key) (op *filters*) val))

6:02 you will need to wrap it in dorun or doall because for is lazy

6:03 kylesmith: hiredman: that looks like more than I need. Technically, I don't need full, arbitrary code. I might be talking out of my ass, but would creating a simple whitelist of clojure functions and forms work?

6:04 Fossi1: well, if you whitelist them, why not put them into the dsl in the first place?

6:04 hiredman: kylesmith: clojure has a lot of nooks and cranies, it might be easier to just write a mini interpreter

6:05 kylesmith: Perhaps combined with an execution timeout.

6:05 hiredman: clojurebot does blacklisting of some forms, but it is possible to get around that as Chouser demostrates over and over

6:06 ,(loop [] (recur))

6:06 clojurebot: Execution Timed Out

6:06 * Fossi1 is utterly confused by now thanks to those side-effects. Time for breakfast.

6:07 hiredman: http://github.com/hiredman/clojurebot/blob/52a02ce8dae22034444fa42e6c2f8f4bb9b986b0/hiredman/sandbox.clj clojurebot's sandbox

6:07 based on that earlier sandbox url

6:08 kylesmith: Fossi: I could do that, but mainly I just need to do simple things like (let [tmp (a common subexpression)] `[awesome dsl stuff ~(repeat 3 tmp) more awesome stuff])

6:08 hiredman: keep in mind it is possible to get clojure's reader to eval stuff, so make sure to read inside the sandbox

6:08 kylesmith: and the interpreter for my dsl is already getting complicated

6:10 hiredman: ,#=(java.util.ArrayList. '(1 2 3 4))

6:10 clojurebot: #<ArrayList [quote, (1 2 3 4)]>

6:10 hiredman: haha

6:10 cute

6:10 ,#=(java.util.ArrayList. (1 2 3 4))

6:10 clojurebot: #<ArrayList [1, 2, 3, 4]>

6:13 kylesmith: okay, so how would I use clojurebot's sandbox? I'm looking at eval-in-box [_string sb-ns], but what is sb-ns? sub-namespace? I assume _string is the user-string to eval

6:14 hiredman: what sort of devilry is Chouser able to get past this sandbox?

6:15 hiredman: kylesmith: not past the jvm sandbox

6:15 just past the blacklist

6:16 kylesmith: ahhh, that should be fine then

6:16 hiredman: the jvm sandbox stops you from messing with the filesystem, etc

6:17 kylesmith: yes, exactly. that's all I need.

6:17 hiredman: sb-ns is either the symbol naming the namespace, or the namespace object where the code will be evaluated

6:17 you will also need the example policy file in the root of the clojurebot git repo

6:18 kylesmith: anything wrong with just using the user namespace?

6:18 hiredman: which goes either in .java.policy or somehow you tell java where to find it

6:18 kylesmith: nope

6:18 ,*ns*

6:18 clojurebot: #<Namespace sandbox>

6:19 kylesmith: okay then. I don't need to implement the sandbox right now, but I'll probably be back here asking questions when I do. Thanks.

6:27 another question: Do standard code obfuscation tools work with clojure?

6:31 rdsr: Hi all how is the path parameter in the load function need to be specified if I were to all all files under a certain dir?

6:32 what I am doing is this (ns a.b.c) (load "./d/")

6:32 dir d contains some clojure files which i want to load

6:32 d is uder the dir b

6:33 s/uder/under/

6:39 hiredman: ,(doc load)

6:39 clojurebot: "([& paths]); Loads Clojure code from resources in classpath. A path is interpreted as classpath-relative if it begins with a slash or relative to the root directory for the current namespace otherwise."

6:40 hserus: how do i assign a function to a map and then evaluate it later?

6:40 hiredman: this is no assignment

6:40 you want to put a function in a map?

6:41 hserus: hiredman: yes

6:41 hiredman: you do it the sameway you add any other value to a map

6:41 rdsr: thks but I the problem is that while (load "./d/some-file") works

6:41 hiredman: ,(assoc {} :a (fn []))

6:41 clojurebot: {:a #<sandbox$eval__4154$fn__4156 sandbox$eval__4154$fn__4156@1d53bc5>}

6:41 rdsr: I can't seem to all all the files under dir d

6:41 hserus: how would i evaluate it later?

6:41 hiredman: hserus: how do you call a function?

6:42 hserus: ,((assoc {} :a (fn [])))

6:42 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap

6:42 hserus: ?

6:42 i get the same error

6:42 hiredman: because you are trying to call the map as a function

6:42 Fossi1: ,((:a (assoc {} :a (fn []))))

6:42 clojurebot: nil

6:42 hiredman: you don't want to call the map as a function

6:42 you want to call the function you put into the map as a function

6:42 so you need to take it out first

6:43 rdsr: load does not take wild cards, so you will need to roll your own function

6:44 rdsr: oh ok thks

6:44 Fossi1: rdsr: check find-namespaces or such in contrib

6:44 rdsr: thks i 'll check that

6:44 Fossi1: otherwise a filter and a file-seq does the trick pretty ok as well

7:05 hiredman: ,(let [cons (pl λxy λf (f x y)) cdr (pl λc (c λxy x))] (cdr (cons 1 2)))

7:05 clojurebot: 1

7:08 Fossi1: o_O

7:19 mapcat is *strange*

7:20 Chousuke: how so?

7:20 Fossi1: i understand the concept, but i find it twists my mind more than i can get it to do anything sensefull

7:20 same with reduce really

7:22 it's strange. i have this java class that sets a private value if and throws an exception the second time, but in a do, it doesn't blow

7:26 Chousuke: Fossi1: mapcat is just (apply concat (map f coll coll2 coll3 ...))

7:27 Fossi1: so the mapping operation returns a bunch of collections and concat concatenates them.

7:27 Fossi1: i *know* what it is and how it works

7:28 that still doesn't help with using it

7:28 Chousuke: Well, I haven't had much use for it either.

7:28 I suppose it's useful if you want to map a function that possibly needs to return multiple elements to replace the original

7:29 Fossi1: it's already cool for reordering things

7:29 ,(mapcat list [1 2] [3 4] [5 6])

7:29 clojurebot: (1 3 5 2 4 6)

7:29 Fossi1: or whatever

7:31 Chousuke: reduce is a bit trickier I guess.

7:31 but it's useful if you have to accumulate something.

7:34 Fossi1: yeah, that is the easy usecase

7:34 i just started to use it for other things as well

7:34 you can like, concat strings or such

7:35 hiredman: ,(pl (↕reduce range $ 10 λxy (+ x y)))

7:35 clojurebot: 45

7:35 Fossi1: hiredman: what the hell is that stuff? ;D

7:35 hiredman: Fossi1: (apply str …)

7:35 lbj: hiredman: What is this multitalented pl macro you did ?

7:35 hiredman: for string concat

7:36 lbj: ~pl?

7:36 clojurebot: the repl is holding onto the head of sequences when printing them.

7:36 Fossi1: hiredman: well, given your 'concat' is a little more complex

7:36 Chousuke: reduce can actually be used to implement map :P

7:36 hiredman: erm

7:36 Chousuke: which is fun.

7:36 hiredman: Chousuke: are you sure? I think it is the other way around

7:37 ~transform

7:37 clojurebot: transform is http://github.com/hiredman/odds-and-ends/blob/8a84e6ddbad9d71f714ba16c3e1239633228a7eb/functional.clj

7:37 Chousuke: ,((fn [f coll] (reduce (fn [acc x] (conj acc (f x))) [] coll)) [1 2 3 4])

7:37 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--4900$fn

7:37 Chousuke: hmm

7:37 hiredman: old version of pl is there

7:38 Chousuke: ,((fn [f coll] (reduce (fn [acc x] (conj acc (f x))) [] coll)) inc [1 2 3 4])

7:38 clojurebot: [2 3 4 5]

7:40 hiredman: ,(pl (↕reduce range $ 10 '() λxy (conj x (inc y))))

7:40 clojurebot: (10 9 8 7 6 5 4 3 2 1)

7:40 Fossi1: "ugh, read the source. this started as a very specific function and turned into a very generic one." <3

7:41 hiredman: it's the truth

7:41 Chousuke: hiredman: I can't read that pl stuff at all :P

7:41 * Chousuke prefers prefix notation

7:42 hiredman: it is mostly just for fun and playing with zippers

7:43 using macros + zippers for code transformation is neat

7:44 ,(pl (↕reduce range $ 10 '() λxy (↕conj inc $ y x)))

7:44 clojurebot: (10 9 8 7 6 5 4 3 2 1)

7:53 lbj: hiredman: What is that first character called, and how do you make it? (?reduce...

7:55 hiredman: dunno what it is called

7:56 lbj: Thank you for answering the first of two questions

7:56 hiredman: I make it by either pasting it from some place I have it already, or using a abbr I have defined in my .vimrc

8:05 Fossi1: i'm lost. if i (let [c JavaThing] (do (.changeSomething c) (.useC c))), c should be changed, right? or do i need to ref it or something?

8:06 hiredman: for starts you don't need a do there

8:06 implicit do in a let

8:07 Fossi1: hmmmm. i still like the do as kind of a clear sign that i'm about to use sideeffects

8:11 but still, the Thing NPEs on me, which could only really happen if it's not the instance i called the first method on

8:14 hiredman: sprinkle some prns around

8:32 Fossi1: hmmm. since the introspection on android is a little handicapped, it's kinda hard to tell, since this class has no getter either

8:46 ouch

8:46 in my proxy, i defined the method i'm supposedly calling all the time

8:46 thus shadowing it

8:52 so, there's the betrayal

8:53 i can't call super, right?

8:53 or can i just not call super in protected methods?

8:53 the docs are a bit ambiguous

9:13 ~gen-class

9:13 clojurebot: No, Fossi1, you want gen-interface + proxy

9:13 Fossi1: ~gen-interface

9:13 clojurebot: Gabh mo leithscéal?

9:13 Fossi1: ~gen-interface

9:13 clojurebot: Gabh mo leithscéal?

9:24 Fossi1: any hints on correct gen-interface usage?

9:48 phew

9:53 so now i'm back to the same problem i had with gen-class

9:54 how do you use these generates interfaces and how do you infer the right build order?

9:55 new twist to it: "Exception in thread "main" java.lang.NoClassDefFoundError: java/lang/"

10:00 i mean writing interfaces in java is not that bad, but that can't be *it*, can it?

10:07 Chousuke: I'm not even sure if gen-interface works anymore :P

10:07 it sounds like something pre-AOT

10:10 Fossi1: thing is: i have this proxied object that gets run in another thread and i can send it a message, but without another interface, i don't have a method of mine to call

10:14 StartsWithK: lisppaste8: help

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

10:14 rhickey: Chousuke: gen-interface should work fine

10:15 lisppaste8: StartsWithK pasted "gen-interface and proxy" at http://paste.lisp.org/display/84226

10:17 StartsWithK: is this what you are trying to do?

10:18 Fossi1: yeah, something like that

10:19 just that i get the above exception on compile and emacs naturally can't find the class at all

10:19 StartsWithK: aot step is ok?

10:19 you can see in your 'classes' directory com/exmaple/IFoo.class

10:20 Fossi1: yes

10:21 let me remove them and try again to be sure

10:23 actually, what are you supposed to put into that macro for no return value?

10:23 StartsWithK: [methodName [] void]

10:23 Fossi1: ah, void works much better than nil :)

10:24 StartsWithK: takes no args and returns nothing

10:24 blbrown_win: I am assuming Java doesn't have a similar syntax to this: a = 1e6

10:24 Fossi1: now it's compiling again

10:24 thanks

10:25 still, the precompile step is kinda unnice. now i have to tell emacs about the build dir as well

10:27 StartsWithK: blbrown_win: http://is.gd/1NxbM

10:30 blbrown_win: StartsWithK, you are one of those. RTFM.

10:30 looks like this might work. double d2 = 1.234e2

10:44 achim`: hi! is there a way to create a chunk from a java array?

10:44 rhickey: naming question for the day - what to name the things created by new new?

10:45 achim`: clojure.lang.ArrayChunk

10:51 achim`: rhickey: thanks! i wasn't sure whether that's part of the official api

10:54 rhickey: achim`: It's not, why do you need it?

10:59 achim`: rhickey: it would be handy for I/O: reading bursts of bytes into arrays, but hiding the array stuff. i have been doing this with seqs of arrays and was wondering whether it would work with chunked seqs

11:02 but ArrayChunk doesn't seem to work with primitive arrays

11:03 rhickey: achim`: just going to ask that

11:04 so, you could emulate what it does, but if you are trying to avoid boxing the bytes you might be better off with seqs of arrays for now

11:22 AWizzArd: anyone here used javacc for lexing purposes + Clojure?

11:24 achim`: rhickey: you're right. i just started looking at chunked seqs. also, there's no way to get to the array, once wrapped in an ArrayChunk (which makes sense in terms of immutability, of course)

11:24 sadly, java doesn't have readonly arrays

11:32 AWizzArd: is there a way similar to Java to check for a char being between a range? (if (<= 65 my-char 77) ...)

11:32 clojurebot: for is not used enough

11:32 rhickey: AWizzArd: coerce to int

11:32 AWizzArd: oki

11:32 rhickey: ,(int \A)

11:32 clojurebot: 65

12:30 rhickey: obj as special form name for new new?

12:30 (obj this [bases] [super-ctor-args]

12:30 :volatile [some captured names]

12:30 :other-flags tbd

12:30 (method1 [] ...)

12:30 (method2 [] ...))

12:31 this-name, :volatile, :other-flags all optional

12:32 pronunciation is a bit rough, objet like in French?

12:36 rottcodd: would object be too long?

12:37 rhickey: rottcodd: not necessarily

12:48 arbscht: object feels more natural than obj

12:48 rhickey: could also be new:

12:48 (new [bases] [super-ctor-args]

12:48 :as this

12:48 :volatile [some captured names]

12:48 :other-flags tbd

12:48 (method1 [] ...)

12:48 (method2 [] ...))

12:49 Chousuke: not necessarily a breaking change, is it?

12:50 rhickey: the bigger question is what to call what this creates? it is a little like an anonymous inner class (not quite) and a little like a closure (will eventually be used to implement fn)

12:50 Chousuke: new like that is not a breaking change

12:50 Chousuke: Classure? :P

12:51 arbscht: (being this [..] ...)

12:51 call it a "being"

12:52 Chousuke: Any reason you're not making the :options just a simple map? would be easier to work with from macros and all :/

13:04 achim`: i like obj, its creations being objs. one new concept, one new name. overloading new has its benefits (both make instances), but might also be more confusing

13:51 lbj1: How many bugs have been found in Core this year ?

14:12 achim`: hmmm ... probably a stupid question: is there a way to not retain head in a function that's passed a lazy seq and has to consume it entirely?

14:13 lbj1: You mean like dorun ?

14:17 Chousuke: it shouldn't retain the head if you don't explicitly hold on to it when you do recur :P

14:25 achim`: lisppaste8: url

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

14:26 achim pasted "off with its head" at http://paste.lisp.org/display/84232

14:27 achim`: i basically need "doseq-and-forget" :)

14:30 maacl: What is the easiest way of doing simple job scheduling (e.g. call a function every 10 min) in Clojure? I looked at http://bit.ly/gOgRx but this seems a little elaborate for something as simple.

14:31 Fossi1: i was about to say quartz

14:32 also, the job is pretty much already done, so why not use that?

14:32 lbj1: maacl: Depends on the job - For some tasks a worker-thread which calls it self with a given delay will suffice

14:33 achim`: maacl: Executors/newScheduledThreadPool

14:33 maacl: and then (.scheduleAtFixedRate ...)

14:33 maacl: Executors is in java.util.concurrent

14:36 maacl: ah - thanks for the feedback - will give Executors a look

14:44 Fossi1: man, i suck at designing 'stateless' systems ;D

14:45 i'm trying to get some design into things upfront, but i'm somehow captured in all those OO patterns

14:45 maybe i shouldn't worry about it at all and see where i arrive

14:49 lbj1: Which categories of programming would you normally argue are best suited for FP ?

14:58 achim`: is this correct?: when a function takes a lazy seq argument and has to consume it entirely to produce the result, the only way to not retain head is to recur without looping?

15:23 krumholt_: is there a good book about functional software design or functional algorithm design?

15:26 ataggart: rich put up an amazon bookshelf of the stuff he read when designing clojure

15:27 might be something in there

15:27 of course there's SICP if it's really new to you

15:27 like it is for me

15:28 lbj1: Which categories of programming would you normally argue are best suited for FP ?

15:28 krumholt_: ataggart, ok thanks.

15:28 ataggart: found it

15:28 http://www.amazon.com/gp/richpub/listmania/fullview/R3LG3ZBZS4GCTH/ref=cm_pdp_lm_title_1

15:28 krumholt_: oh fantastic thanks

15:28 Fossi1: lbj1: i don't get what that means

15:29 ataggart: lbj1: any where you can, I would think

15:29 lbj1: Fossi1: Would you say that FP is really suited for game development for instance? data parsers? etc..?

15:29 ataggart: all of the above

15:30 it's lke asking what OO is best for

15:30 so long as you're not having to write machine code, it's really up to you

15:31 lbj1: I'm not sure thats right, but ok, thats one view

15:31 duck1123: The only thing that FP really isn't good for is code you want to be brittle and hard to test.

15:31 ataggart: well if you have an opinion, feel free to voice it

15:31 Fossi1: from my opinion just now, game coding is a little weird

15:31 ataggart: duck1123: lol

15:32 Fossi1: so many side effects

15:32 ataggart: yes, side-effect heavy, or lots of state manipulation

15:32 Fossi1: but then again, every serious computer program has lots of in-/ and outputs

15:32 ataggart: but I read a neat article making the argument that there isn't as much of that as one initially supposes

15:32 let me see if I can find it

15:33 Fossi1: that'd be cool

15:33 ataggart: http://prog21.dadgum.com/23.html

15:33 that

15:33 Fossi1: i guess i'll have a look at some functional game engines on the way as well

15:33 ataggart: as Rich and others have said: a program without side-effects can only heat up your computer

15:34 duck1123: I think the snake game is a good example of how you would think to have a lot of mutable state, but if you think about the problems right, there is very little

15:34 lbj1: How little?

15:34 ataggart: yup, I'm glad he put that in the book

15:34 Fossi1: i guess it comes down to: have a loop, modify game state, push that into the rendering

15:34 ataggart: lbj1: have you read the clojure book yet?

15:34 hiredman: http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf <-- "The Next Mainstream Programming Languages: A Game Developer's Perspective"

15:34 lbj1: ataggart: No, and I dont plan to

15:35 duck1123: I think like < 10% of the code dealt with mutation

15:35 my book is in the other room

15:36 Fossi1: thanks hiredman

15:37 ataggart: It'd be really nice if we could collect these links on the clojure site somewhere

15:38 hiredman: clojurebot: delicious

15:38 clojurebot: delicious is http://delicious.com/clojurebot

15:38 hiredman: clojurebot posts all urls from the channel, tagged with nick+channel

15:38 ataggart: ah excellent

15:38 duck1123: it would be cool if clojurebot did something like the bot in #swig where he could track all the url's mentioned in chat

15:38 ataggart: lol

15:38 duck1123: nvm then

15:57 Fossi1: too much haskell for me :D

15:58 but interesting nevertheless

15:58 lbj1: Very

16:33 Fossi1: i sthe idiomatic way to add a single element to a seq: ,(concat '(1 2 3) '(4))?

16:34 hiredman: there is no idomatic way to add to the tail of a seq

16:34 you can do it, but it is just not how the structure is designed to be used

16:38 ataggart: or you can rephrase "add to the tail" to "start returning this other seqence when the first one is empty"

16:41 Fossi1: actually, i just want a smallish vector or something with a special value at the end

16:41 ataggart: ah, then use vec

16:42 Fossi1: ,(vector '(1 2 3) 4)

16:42 clojurebot: [(1 2 3) 4]

16:42 ataggart: (vec '(1 2 3))

16:43 ,(vec '(1 2 3))

16:43 clojurebot: [1 2 3]

16:43 Fossi1: and then?

16:43 ataggart: (conj (vec '(1 2 3)) 4)

16:43 ,(conj (vec '(1 2 3)) 4)

16:43 clojurebot: [1 2 3 4]

16:43 Fossi1: ah, conj

16:43 ataggart: conj on a vector adds at the end

16:44 Fossi1: but is it guaranteed that will always be that way?

16:44 ataggart: yup

16:44 (doc conj)

16:44 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

16:44 ataggart: ,(doc conj)

16:44 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

16:44 ataggart: guess the detail is elsewhere

16:44 but yes, vectors at the end, lists at the head

16:44 Fossi1: guess so as well

16:44 ataggart: ,(conj '(1 2 3) 4)

16:44 clojurebot: (4 1 2 3)

16:45 Fossi1: because i looked for that for a while

16:45 yes sir, my app works

16:46 i can now display a colored screen and make it change color randomly on touch

16:46 a small step for a game, a big step for me ;D

16:46 ataggart: excellent

16:46 "touch"?

16:46 Fossi1: clojure on android with opengles

16:47 ataggart: ah neat

16:47 Fossi1: took a while to set up, but there was quite a base to start from as well

16:48 or at least some bits n pieces :)

16:48 bedtime now, i need to get up at 7 and code some more :D

16:48 Raynes: One small step for games, one huge step for Clojurians.

16:52 Anniepoo: whoo hoo - Clojure on Android?

16:53 Fossi, how did this miracle come about?

17:00 Chouser: rhickey: I'm curious if you'd entertain syntax for newnew that avoids the sub-form (foo ...) when defining foo

17:00 proxy is currently one of the few places that (foo ...) means anything other than invoking foo.

17:02 maybe, for example: (new [AFn] [] (defm invoke [a b] ...))

17:06 hiredman: that would be the only place where def something doesn't result in a modification to global names

17:06 Chouser: fwiw, I think I prefer 'new' to 'obj'. "Use 'new' to create a 'Clojure object', which is Java object but whose methods can close over locals..."

17:07 hiredman: hm... Well, I'm not sold on a particular name, but I think any name would be nice compared to no name at all.

17:07 (method invoke [a b] ...)

19:59 wulfmax: ?

19:59 help

20:00 durka42: ?

20:00 wulfmax: sorry,typo

21:02 mebaran151: ,(+ 1 1)

21:02 clojurebot: 2

21:02 mebaran151: ,(defn xyz [] (+ 1 1))

21:02 clojurebot: DENIED

21:02 mebaran151: ,((defn xyz [] (+ 1 1)))

21:02 clojurebot: DENIED

21:02 mebaran151: ,((fn xyz [] (+ 1 1)))

21:02 clojurebot: 2

21:06 mebaran151: do fn's allow for names only to enable simpler recursion

21:07 hiredman: they are useful in a number of situations

21:07 like if you have an otherwise anonymous function that you send to an agent that wants to keep sending ittself off to an agent

21:07 a lazy-seq generated by a fn

Logging service provided by n01se.net