#clojure log - Jun 26 2011

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

5:30 shanmu: Hi, what is the best way to get xml back from a zipped parsed xml seq, in clojure 1.3?

5:31 I find that xml/emit and prxml both donot emit proper xml when passed a zipped parsed xml....

5:57 fliebel: What would you use for a mail server, where I need to send email from Clojure and store emails in a fancy noSQL db for a sweet web app?

5:58 I'm thinking some UNIX workhorse where I just mess around with the maildir. But I also found Apache James.

6:25 shanmu: Hi, what is the best way to get xml back from a zipped parsed xml seq, in clojure 1.3?

6:44 matthias__: (doc constantly)

6:44 clojurebot: "([x]); Returns a function that takes any number of arguments and returns x."

6:45 matthias__: ,(doc constantly)

6:45 clojurebot: "([x]); Returns a function that takes any number of arguments and returns x."

10:48 matthias__: ,(- 1)

10:48 clojurebot: -1

12:32 daaku: i'm using hiccup to write a few reuseable "widget" type things (drop-down menus, nav-bars etc). i want to allow for a "family" to be specified, which adds a class to all the html elements created by the widget, and i'm wondering what would be good design for this

12:33 the idea is that for say a drop-down menu, there'd be a <ol> containing <li> containing <a>, and i'd want the "family" to be applied to all three (with some added prefix/suffix)

13:15 Ian_Corne: ,(dotimes [i 10] (println i))

13:15 clojurebot: 0

13:15 1

13:15 2

13:15 3

13:15 Ian_Corne: oho

13:15 clojurebot: 4

13:15 5

13:15 6

13:15 7

13:15 8

13:15 9

13:15 Ian_Corne: sorry :)

13:18 semperos: for config files that don't get kept under version control (e.g. for db credentials), do folks normally just use Clojure datastructures for the config file?

13:25 chouser: semperos: sure is an easy place to start

13:27 semperos: works for me

13:28 chouser: semperos: do remember to 'read' it, not 'load' it

13:30 semperos: that was part of my uncertainty, how to actually structure it

13:30 and then "read" it in

13:30 vs. just using a normal Clojure file with var's and providing an example file with blank files

13:30 *blank values

13:34 I see macourtney used a normal namespaced file with default values, and documented instructions for changing them: https://github.com/macourtney/Conjure/blob/master/conjure_core/test/config/db_config.clj

13:40 Ian_Corne: is there a way to get back the time value from a (time exp) ?

13:48 fliebel: Ian_Corne: time is a really simple macro, so I think your best bet would be to write one that returns the time, instead of prints it.

13:48 $source time

13:48 sexpbot: time is http://is.gd/1COGB7

13:49 Ian_Corne: ah thnx

14:17 fliebel: &(map #(cond (= (rem % 15) 0) 'fizzbuzz' (= (rem % 5) 0) 'buzz' (= (rem % 3) 0) 'fizz' :else %) [1 3 5 15 16]) ; to tired to get even this right

14:17 sexpbot: ⟹ (buzz buzz buzz fizzbuzz buzz)

14:18 fliebel: &(= (rem 1 5) 0) ; so where does the buzz come from?

14:18 sexpbot: ⟹ false

14:21 AWizzArd: Anybody in for a type-hint challenge?

14:24 fliebel: someone em-brace me, I just used single-quotes...

14:25 AWizzArd: Who is expert for removing reflection warnings by setting the right type-hints? :-)

14:26 fliebel: AWizzArd: Not me, but you could show me some code :)

14:27 &(map class ['aap' 1]) ; weird... to much Python

14:27 sexpbot: ⟹ (clojure.lang.Symbol java.lang.Integer)

14:28 AWizzArd: I have a HBox h and two Labels l1 and l2. I want to add the Labels to the HBox, and this is how it is done: (.addAll (.getChildren h) (to-array [l1 l2]))

14:29 fliebel: AWizzArd: What does the warning say?

14:29 AWizzArd: This is the HBox: http://download.oracle.com/javafx/2.0/api/javafx/scene/layout/HBox.html and when you follow getChildren you see it returns an ObservableList: http://download.oracle.com/javafx/2.0/api/javafx/collections/ObservableList.html

14:30 No warning so far, but ithe ObservableList also has a setAll method. One can replace the .addAll by .setAll in my code and it still works fine.

14:30 fliebel: AWizzArd: You said you had reflection warnings?

14:30 AWizzArd: But, and now my challenge comes: .setAll has two implementations where one has the signature boolean setAll(java.util.Collection<? extends E> col)

14:31 So, I tried (.setAll (.getChildren h) [l1 l2]) <-- but this produces a reflection warning.

14:31 call to setAll can't be resolved

14:32 fliebel: Maybe (.setAll (.getChildren h) ^java.util.Collection [l1 l2]) ?

14:33 AWizzArd: Tried that.

14:33 Also I am using all literal types, so the compiler should know that a vector is a Collection.

14:34 I just can’t remove that reflection warning.

14:34 fliebel: I suppose that because getChildren does not give a warning, h, and the return value of that can be resolved.

14:34 AWizzArd: h is bound in a let, so Clojure knows its type. The type of .getChildren is also clear. This is why (.setAll (.getChildren h) (to-array [l1 l2])) works fine, without a reflection warning.

14:35 fliebel: AWizzArd: So, why can't you use that?

14:36 AWizzArd: I can. I am just curious how I can solve such a challenge in principle.

14:37 I would assume that a correct type hint exists. So, this is more a general approach to understand problemsolving in Clojure better, instead of solving the concrete problem at hand.

14:38 fliebel: Right... Could you try vector-of?

14:38 amalloy: AWizzArd: maybe you can gist a snippet?

14:38 fliebel: that's only good for primitives

14:39 fliebel: amalloy: Right, I just figured that out :(

14:39 amalloy: I was thinking it was because arrays have actual types, and vectors are just objects. But these <E> things are just casts anyway...

14:40 amalloy: yeah. my issue is i'm not even sure what the two type signatures *are* that AWizzArd is trying to distinguish between, nor what types his actual objects are

14:41 AWizzArd: amalloy: in the repl I set *warn-on-reflections* to true and then did (let [h (HBox.), l1 (Label.), l2 (Label.)] (.setAll (.getChildren h) (to-array [l1 l2]))) which works. But when I remove the to-array call it gives me the reflection warning.

14:42 amalloy: http://download.oracle.com/javafx/2.0/api/javafx/collections/ObservableList.html

14:42 That interface lists two .setAll methods.

14:43 fliebel: *my* problem is that I can't see how the vararg one wouldn;t work for a list.

14:43 AWizzArd: The first one takes a Collection, and (isa? clojure.lang.PersistentVector java.util.Collection) ==> true

14:43 fliebel: the vararg one gets auto-translated into an array from Java

14:43 amalloy: fliebel: varargs are a fiction

14:44 fliebel: I mean, the difference between adding one list to the other or add ing the *elements* of said lis to the other is kind of ambiguous I think.

14:44 AWizzArd: So, in Java one would say: h.setAll(l1, l2); <== the second .setAll, with the vararg

14:44 amalloy: AWizzArd: IPersistentVector doesn't extend java.util.Collection, but PersistentVector does extend it. it may be the compiler is only hinting with the appropriate interface

14:45 fliebel: AWizzArd: Now do h.setAll(l1), what am I trying to do here?

14:45 AWizzArd: fliebel: this is the vararg call, because l1 is not a Collection.

14:46 (instance? Collection [l1 l2]) ==> true

14:46 amalloy: AWizzArd: doesn't address my point

14:46 fliebel: AWizzArd: Okay, h.setAll([l1]) then. It could be both, right?

14:46 amalloy: He tried hinting with java.util.Collection

14:47 AWizzArd: That also didn’t help.

14:48 fliebel: AWizzArd: What I'm trying to say is... maybe when you used the array, it used the fake-vararg one, but when you used the vector, it could be both.

14:48 maybe not...

14:49 amalloy: fliebel: that's only a concern in java, not in clojure

14:49 because the clojure compiler doesn't provide javac's sugar for accessing varargs without coercing to array

14:49 fliebel: amalloy: So are there 2 functions, one with a collection and one with an aray, or is there just one and some syntax for Java?

14:50 amalloy: there are two

14:50 AWizzArd: amalloy: so your guess right now is that it could be in the Clojure compiler itself, that stops me from being able to hint the type here.

14:51 amalloy: i think that's pretty unlikely

14:51 i bet dnolen would know how to do it, for example

14:52 AWizzArd: Yes, or rhickey might also have an idea ;)

14:52 gfrlog: is there a way to unchunk a chunked seq?

14:52 fliebel: gfrlog: Yea, it's in JoC, and on the blog of fogus.

14:53 gfrlog: I think I just found the latter, thanks

14:54 fliebel: Hm, what about (fn [s] (lazy-seq (cons (first s) (recur (next s)))))))))) or whatever...

14:55 gfrlog: fliebel: do you mean that in a recursive way?

14:55 fliebel: yea

14:55 gfrlog: like passing (next) to the outer function maybe?

14:55 amalloy: fliebel: can't recur across a lazy-seq

14:56 fliebel: amalloy: Oh, well, give it a name and use that then...

14:56 gfrlog: fliebel: ah I didn't even see (recur) somehow

14:56 thought you had left it out

14:56 amalloy: fliebel: or use https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/seq.clj#L32 -- amirite?

14:57 gfrlog: I use amalloy-utils as a drop-in replacement for clojure.contrib

14:57 amalloy: o/

14:57 gfrlog: \o

14:57 fliebel: gfrlog: As in, just change the import?

14:58 gfrlog: fliebel: yep, works every time.

14:58 fliebel: amalloy: amirite?

14:59 amalloy: am i right

14:59 gfrlog: $google amirite

14:59 sexpbot: First out of 90300 results is: amirite? Share your thoughts, ideas and jokes and see if people agree.

14:59 http://www.amirite.net/

14:59 gfrlog: I dunno about that

14:59 amalloy: but said quickly, usually to imply "of course i'm right"

14:59 gfrlog: $google amirite urban dictionary

14:59 sexpbot: First out of 700 results is: Urban Dictionary: amirite

14:59 http://www.urbandictionary.com/define.php?term=amirite

15:00 gfrlog: oh it's on wiktionary too

15:48 fliebel: "I would have included Clojure, as I find the language itself not without its merits, but the current implementation is 4 times slower than plain Java and skewed the graph badly" http://lists.nongnu.org/archive/html/chicken-users/2011-03/msg00070.html

15:49 Looks like a job for dnolen :)

15:49 gfrlog: it's hello world?

15:49 doesn't that mean it's measuring language startup time?

15:49 fliebel: gfrlog: Yea

15:49 gfrlog: okay, so not a serious issue then?

15:49 fliebel: gfrlog: Still silly that Clojure apparently loads 4 times as much as java.

15:50 gfrlog: it's okay that clojure has slow startup, because the JVM starts up so fast that it evens out

15:51 amalloy: srsly? "I wrote hello world and it was so slow in clojure that it's a bad language"?

15:51 gfrlog: amalloy: no, he just didn't want the graph to be unreadable

15:51 maybe if he used a log scale he could have fit everything better

15:52 C and Bash are already like 4 pixels long as it is

15:52 amalloy: i see. at least he was measuring for cli scripting

16:01 derp: how does one convert a character to an int?

16:01 gfrlog: ,(int \x)

16:01 clojurebot: 120

16:01 gfrlog: that's probably it

16:02 fliebel: derp: But note that ##(int \4) might not do what you expect.

16:02 sexpbot: ⟹ 52

16:02 gfrlog: hmm

16:02 derp: ,(int \4)

16:02 clojurebot: 52

16:02 gfrlog: it didn't occur to me he might think of it that way

16:02 rpglover64: what's ## do?

16:03 gfrlog: rpglover64: triggers sexpbot mid-line

16:03 fliebel: rpglover64: Invoke sexpbot

16:03 rpglover64: got it

16:03 thanks

16:03 gfrlog: ,(map #(- (int %) 48) [\1 \2 \3 \8 \9])

16:03 clojurebot: (1 2 3 8 9)

16:03 Raynes: &(Integer/parseInt \3)

16:03 sexpbot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.String

16:03 Raynes: Shame.

16:03 gfrlog: ,(map #(- (int %) 48) [\1 \2 \3 \8 \9 \0])

16:03 clojurebot: (1 2 3 8 9 0)

16:03 gfrlog: I didn't expect \0 to work

16:04 fliebel: &(Integer/parseInt (str \3 \3))

16:04 sexpbot: ⟹ 33

16:04 gfrlog: cuz I'm dum

16:05 ,(let [sexpbot-trigger "##(+ 7 8)"] (first sexpbot-trigger))

16:05 sexpbot: ⟹ 15

16:05 clojurebot: \#

16:05 gfrlog: \o/

16:05 what do I win?

16:05 oh wait....

16:06 &(let [sexpbot-trigger "##(+ 7 8)"] (first sexpbot-trigger))

16:06 sexpbot: ⟹ 15

16:06 gfrlog: aah

16:06 fascinating

16:06 rpglover64: huh?

16:06 gfrlog: I woulda put a bunch of money on it going the other way

16:06 fliebel: gfrlog: I've been thinking about creating a loop with these bots...

16:06 gfrlog: rpglover64: I'm experimenting with triggering two things at the same time

16:07 fliebel: I wanted to do that a while back, but sexpbot's damn arrow character messes the whole thing up

16:07 rpglover64: ,5

16:07 clojurebot: 5

16:07 derp: can one access a string like a vector?

16:07 rpglover64: ##5

16:07 ##5

16:07 ...

16:07 gfrlog: derp: strings are seqable...

16:07 rpglover64: ##(5)

16:07 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

16:07 gfrlog: derp: so I guess it depends on what you mean

16:07 Raynes: fliebel: Good luck with that.

16:07 gfrlog: Raynes: remove that blasted arrow!

16:08 how else can #clojure be made a fun-house?

16:08 fliebel: Raynes: Or change the arre into a comma :D

16:08 gfrlog: lol

16:08 Raynes: Maybe you just need to make him throw a comma exception. ;)

16:08 amalloy: gfrlog: i think it would have made more sense for & to apply first, but when i added ## i was really excited and made it a priority

16:08 gfrlog: amalloy: I think you just wanted me to lose a bet

16:08 amalloy: it'd be really cool if it did both

16:09 derp: gfrlog: I am not explaining this well, but I guess I want to be able to get a specific member of a string

16:09 amalloy: not my fault you don't read the sexpbot commits logs from last october

16:09 &(doc subs)

16:09 sexpbot: ⟹ "([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive."

16:10 fliebel: What's the name of these codes that eval to themselves?

16:10 amalloy: quine

16:10 rpglover64: quines

16:10 derp: something like "take", but doesn't return earlier members

16:10 amalloy: derp: see above: subs

16:10 fliebel: derp: nth

16:11 amalloy: fliebel: nth might convert to a seq for strings

16:11 gfrlog: fliebel: if the bots could talk to each other, we'd need a kind of two-step quine

16:11 fliebel: amalloy: Yea, subs is right, but nth is like take without the earlier stuff.

16:12 amalloy: i see nth treats strings as CharSequence

16:12 fliebel: gfrlog: you could fork sexpbot and configure it to have & as a prefix and tigger on the arrow.

16:12 derp: why do certain seq commands follow different orders for arguments?

16:13 gfrlog: fliebel: I tried forking both bots back in the day, but couldn't get either of them set up

16:13 derp: like take wants the num first and collection 2nd, but nth is the reverse

16:13 gfrlog: derp: it is the ineffable will of Bob

16:13 amalloy: derp: nth drives me nuts

16:14 most sequence things take [arg arg coll], not [coll arg]

16:15 fliebel: amalloy: Hm, I swear I had some config file for sexpbot. where to look?

16:15 amalloy: fliebel: ~/.sexpbot/info.clj

16:15 derp: hmm, okay

16:15 gfrlog: haha! sex!

16:16 fliebel: amalloy: uhoh, since when does it throw log4j exceptions?

16:17 derp: ,(subs "Hello" 2)

16:17 clojurebot: "llo"

16:17 gfrlog: man how I never done heard of subs before?

16:17 derp: okay, so what function does the reverse of subs?

16:17 gfrlog: also why clojure.org/api doesn't have any chunked-seq functions listed?

16:17 amalloy: derp: also subs

16:17 derp: if I wanted "He" instead?

16:18 gfrlog: ,(subs "Hello" 0 2)

16:18 clojurebot: "He"

16:18 derp: ah

16:18 I don't know why, I just assumed the default behavior would be that one

16:19 gfrlog: derp: I think that's how substring functions work in a lot of languages

16:19 amalloy: derp: then you'd need to know the length of the string to get the opposite behavior

16:20 fliebel: amalloy: all my plugins seem to be missing. what happened?

16:20 derp: ah, I hadn't thought of that, I guess that is pretty sensible

16:21 amalloy: fliebel: i'd guess they're either gone, or in a different place than you're looking :P. not much information there to solve the problem with

16:21 fliebel: amalloy: I just kep removing untill it ran :)

16:25 amalloy: Where do I get a current set of plugins?

16:25 derp: if I run (count *string*) on some big string, but this string does not change, and call it often, does that poorly affect performance?

16:26 amalloy: fliebel: sexpbot.plugins.*, each should be a plugin. or you can copy the info.clj from the git repo

16:27 derp: no

16:27 strings are counted at construction time

16:27 * gfrlog is glad count is smart

16:28 derp: okay, but what about in the general case? does clojure do some sort of fancy auto memoization for repeated calls to functions with the same args?

16:28 * gfrlog hopes so

16:28 amalloy: no

16:29 derp: really?

16:29 gfrlog: amalloy: it oughta, eh?

16:29 at least for the immutables?

16:29 amalloy: that would be terrible

16:29 gfrlog: amalloy: why? unpredictable performance?

16:29 amalloy: clojure should presume you care more about speed than space?

16:29 fliebel: &1

16:29 derp: well

16:29 sexpbot: ⟹ 1

16:30 amalloy: and who wants to write the type system that makes it clear what's referentially transparent and what isn't?

16:30 gfrlog: eh...I guess

16:30 derp: well

16:30 I mean you could have a lru cache or something

16:30 amalloy: derp: don't put it in the language, though. that's nuts

16:30 gfrlog: I would just have the immutable collections know their own sizes

16:30 amalloy: lots of people have written lru-cache memoization functions already; you can just use them

16:31 gfrlog: mostly they do

16:31 gfrlog: lazy seqs apparently don't

16:31 derp: okay

16:31 amalloy: gfrlog: surprise?

16:31 gfrlog: amalloy: nope

16:32 amalloy: I mean of course they don't know them automatically

16:32 I mean even after repeated calls

16:32 amalloy: gfrlog: again, space/speed tradeoff. plus, it would be awkward

16:33 gfrlog: I don't think it can be that awkward. But I agree that it's cleaner to let the user decide what's important.

16:33 s/can/has to be

16:33 sexpbot: <gfrlog> I don't think it has to be be that awkward. But I agree that it's cleaner to let the user decide what's important.

16:33 amalloy: they'd have to implement Counted in order to have their .count method called, so (counted? (map inc [])) would return true even though it's clearly not counted

16:33 gfrlog: I've never heard of counted

16:33 amalloy: clojure.lang.Counted

16:34 &(supers (class {}))

16:34 sexpbot: ⟹ #{clojure.lang.MapEquivalence clojure.lang.IPersistentMap java.util.Map clojure.lang.ILookup java.io.Serializable java.util.concurrent.Callable clojure.lang.Counted clojure.lang.Associative clojure.lang.IPersistentCollection java.lang.Runnable clojure.lang.IEditable... http://gist.github.com/1047945

16:34 gfrlog: hmm

16:34 fliebel: yay! did it, in #tempchan

16:34 gfrlog: amalloy: I guess I wouldn't have done it that way

16:34 amalloy: fliebel: bring him into #sexpbot, he can hang out

16:34 gfrlog: amalloy: I would've made count part of ISeq and let the seq itself choose whether to optimize

16:35 fliebel: whatdjado?

16:35 fliebel: amalloy, gfrlog: added the harpoon as a prefix and launched 2 boys.

16:35 amalloy: haha

16:35 gfrlog: alright, well get to quine writing I guess

16:35 fliebel: &((fn [x] (list x (list (quote quote) x))) (quote (fn [x] (list x (list (quote quote) x)))))

16:35 sexpbot: ⟹ ((fn [x] (list x (list (quote quote) x))) (quote (fn [x] (list x (list (quote quote) x)))))

16:35 gfrlog: fliebel: http://blog.sigfpe.com/2008/02/third-order-quine-in-three-languages.html

16:36 fliebel: gfrlog: sexpbot can do haskell and a couple more, so maybe...

16:36 derp: um, is there a way to easily rename a function/variable and all occurrences of it in emacs?

16:36 gfrlog: fliebel: it looks like he sorta found a way to build them automatically

16:36 maybe not, I didn't quite understand it

16:37 derp: I guess something like the eclipse refactor/rename?

16:40 technomancy: derp: there's slime-who-calls, which will show you all usages. no automated rename though.

16:41 amalloy: technomancy: that works?

16:41 technomancy: ohh.... there might be in tcrayford's mode.

16:41 amalloy: I'm not sure how accurate is. it's slow enough that I never use it

16:43 derp: technomancy: thank you

16:43 technomancy: derp: probably wouldn't be too hard to implement

16:43 just have bigger fish to fry myself

16:44 for moving between namespaces without renaming you can use slamhound: http://github.com/technomancy/slamhound

16:44 derp: I'd try it myself if emacs didn't scare the bejesus out of me

16:44 technomancy: it's a pretty crappy dialect

16:45 I mean, for a lisp

16:46 * gfrlog thinks logo is a pretty crappy dialect for a lisp

16:47 * gfrlog is currently translating an inefficient functional program into an efficient procedural global-variables one

16:49 AWizzArd: gfrlog: this is what the compiler should do :-)

16:49 gfrlog: AWizzArd: totally agreed :( :(

16:49 AWizzArd: it makes it that much more painful that this is being compiled to run on the JVM

16:51 lnostdal-laptop: (try ... (catch ... (loop ... (recur ...)))) ;; isn't possible? .. i can kind of understand why recuring to the "outside" of a try/catch block is tricky; but within the catch "sub-block"?

16:51 gfrlog: lnostdal-laptop: that looks messy if nothing else

16:51 lnostdal-laptop: (..i'm getting "Cannot recur from catch/finally" .. but i'm recuring within it..)

16:51 amalloy: lnostdal-laptop: i think i've seen a bug report with a fix attached. what version of clojure?

16:52 lnostdal-laptop: 1.3-something (from git), amalloy

16:52 i can try upgrading to latest master .. lessee

16:52 technomancy: clojurebot: CLJ-31

16:53 clojurebot: It's greek to me.

16:53 technomancy: ,botsmack

16:53 clojurebot: java.lang.Exception: Unable to resolve symbol: botsmack in this context

16:53 technomancy: ~botsmack

16:53 clojurebot: clojurebot evades successfully!

16:53 technomancy: http://dev.clojure.org/jira/browse/CLJ-31

16:53 amalloy: http://dev.clojure.org/jira/browse/CLJ-667

16:53 technomancy: oh snap

16:54 amalloy: technomancy: attached patch claims it will fix 31 too

16:54 lnostdal-laptop: ah, yeah, that looks like what i'm doing

16:54 i can apply it and try

16:55 technomancy: cools

16:55 clojurebot: #31

16:55 clojurebot: 31. Simplicity does not precede complexity, but follows it.

16:55 * technomancy is enlightened

16:56 gfrlog: clojurebot: 42

16:56 clojurebot: Pardon?

16:56 gfrlog: clojurebot: #42

16:56 clojurebot: 42. You can measure a programmer's perspective by noting his attitude on the continuing vitality of FORTRAN.

17:10 oc: clojurebot: #1

17:10 clojurebot: 1. One man's constant is another man's variable.

17:17 lnostdal-laptop: with some adjustments the patch seems to work fine

17:17 :)

17:29 kiras: if anyone would take the time to critique my code and offer some advice on how to improve it, i'd appreciate it: https://gist.github.com/1047989

17:31 amalloy: kiras: generate-random-points doesn't need to exist

17:31 or could be implemented more easily, anyway

17:31 just (repeatedly n #(generate-random-point x-n y-n z-n))

17:32 kiras: amalloy: ah... that's cool, i didn't know about that function

17:32 amalloy: c.c.math/floor can generally be replaced by int, and it looks like that's true here

17:32 gfrlog: kiras: using lazy-seq and recursion can usually be avoided...

17:34 so for example the sierpinski-points function...

17:34 kiras: amalloy: will creating an int from a floating point number will always result in it being rounded down?

17:34 gfrlog: ,(int 3.9)

17:34 clojurebot: 3

17:34 gfrlog: ,(int -3.9)

17:34 clojurebot: -3

17:35 gfrlog: down-towards-zero I guess

17:35 amalloy: kiras: see https://gist.github.com/1047993

17:35 kiras: gfrlog: ah... yeah, guess i should have just tried that. didn't see a note of it when i did (doc int). guess that behavior shouldn't ever change, i hope

17:35 amalloy: i don't know anything about what your code is actually doing, but these are ways that jump out at me to make it simpler

17:36 * gfrlog is staring real hard at the sierpinksk-points function trying to decide what it does

17:36 kiras: http://en.wikipedia.org/wiki/Sierpinski_triangle in case you haven't seen it before

17:36 gfrlog: kiras: I mean more algorithmically

17:37 so you're just creating n points, where each one is based on the last one?

17:37 kiras: gfrlog: basically

17:37 gfrlog: okay

17:37 we can use iterate for that

17:38 (iterate #(sierpinskisize % tri) initial-point)

17:38 kiras: gfrlog: i have a triangle, i choose an initial point inside it at random. then i choose a vertex at random and draw the point halfway between the initial point and the vertex

17:38 gfrlog: so that ^ there will be an infinite lazy seq, starting with the initial-point

17:39 if you want to exclude the initial point, which I think your function does, then you'll want to call (rest) on it

17:39 kiras: gfrlog: i do

17:39 gfrlog: and then you can use (take) to limit the size

17:39 so (take n (rest ...))

17:39 where ... is the code above

17:40 I guess that's the only use of lazy-seq/recur other than the one amalloy already addressed

17:41 amalloy: gfrlog: i get tired of writing (take-while (complement nil?) (rest (iterate f coll))): defined that as (iterations f voll)

17:41 *coll

17:41 gfrlog: in amalloy-utils?

17:41 amalloy: yeah

17:42 gfrlog: amalloy: assuming (f nil) crashes, do you know if that expression is guaranteed to never call (f nil)?

17:42 it makes me nervous

17:42 amalloy: yeah i remember you having this bizarre fear a while ago

17:42 gfrlog: I remember bringing it up

17:43 I'm pretty sure you said it can't

17:43 maybe I just have this traumatic childhood experience where I thought that's what was happening :/

17:44 amalloy: gfrlog: seriously if you're worried about that happening you should never use iterate

17:45 gfrlog: amalloy: you mean with fragile functions, or ever at all?

17:45 kiras: using slime, what's the best way to restart the repl, so to speak? say i just deleted a function and i compile the file it used to be in, the old definition is still available in the repl.

17:45 amalloy: ever at all is what i meant

17:45 gfrlog: amalloy: why do you say such things?

17:45 amalloy: to mock your fragile sensibilities

17:46 gfrlog: because using my actual fragile sensibilities would make your tests more complicated?

17:47 (with-redefs [gfrlog/fragile-sensibilities (constantly nil)] (is ...))

17:47 amalloy: tests are for people who know fear

17:47 gfrlog: oh golly are you one of those rich-hickey followers?

17:47 amalloy: or write imperative for loops. man do those things need tests

17:48 gfrlog: I do not understand the test-haters at all

17:48 especially in a dynamic language

17:49 amalloy: are there really test-haters, or just people who don't enjoy writing tests?

17:49 gfrlog: I don't enjoy writing them, I enjoy having them

17:49 particularly after I leave a project sitting for three months and have to come back and fix a bug

17:52 being able to sit in your hammock and design a bug-free program before you start typing is fine and good, but when somebody else inherits it they haven't had the same hammock time

17:56 amalloy: hm. my new apartment's balcony has two hooks hanging from the ceiling. i wonder if i could install a hammock. they seem too close together

17:57 derp: I finally did it

17:57 I think I've written the worst clojure program ever: https://gist.github.com/1048023

17:58 I know I am really overusing let, but I don't get how to avoid it

17:58 gfrlog: derp: doesn't partition do that?

17:58 amalloy: well it's...wrong

17:58 gfrlog: ,(doc partition)

17:58 clojurebot: "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."

17:58 gfrlog: (partition 5 1 (range 10))

17:58 amalloy: your if statement is a no-op

17:58 gfrlog: ,(partition 5 1 (range 10))

17:58 clojurebot: ((0 1 2 3 4) (1 2 3 4 5) (2 3 4 5 6) (3 4 5 6 7) (4 5 6 7 8) (5 6 7 8 9))

17:59 derp: wow

17:59 amalloy: the first one, that is

17:59 derp: that would have made life easy

17:59 technomancy: kiras: depends how you launched it. M-x clojure-jack-in again works

17:59 derp: amalloy: what do you mean?

17:59 amalloy: you wrote (if test then) else

18:00 derp: well I was assuming that the if statement would return to the parent function

18:00 gfrlog: ,(->> "9834258722394" (map #(new Integer (str %))) (partition 5 1) (map #(apply * %1)) (apply max))

18:00 clojurebot: 2240

18:00 derp: does it have to have an else statement; can't I assume that the next function will execute?

18:00 gfrlog: I think that's the whole euler problem in one line

18:01 kiras: technomancy: i don't seem to have clojure-jack-in available to me

18:01 amalloy: &(let [x 1] (if true x) 2)

18:01 sexpbot: ⟹ 2

18:01 amalloy: http://www.ibm.com/developerworks/opensource/library/os-eclipse-clojure/ is a great article i read when i was learning clojure, solving just this problem

18:03 derp: amalloy: thanks, that looks very informative

18:07 * gfrlog thinks it could be fun to do euler again now that he knows clojure weller

18:08 amalloy: gfrlog: there's this cool site, 4clojure.org - you should try it :)

18:08 gfrlog: :-P

18:10 ,(hash :-P)

18:10 clojurebot: 1013999587

18:12 gfrlog: oh dang euler's got a lot of new problems from a couple years ago

18:15 amalloy: gfrlog: turns out the answer to all of them is pi, though. dang math

18:15 gfrlog: some of these seem to have almost nothing to do with programming

18:15 except that you need something to crunch big numbers for you once you've solved the problem on paper

18:15 agnaldo4j: Hello all

18:15 gfrlog: agnaldo4j: hello

18:15 agnaldo4j: i'm from Brasil

18:16 i want to learn more about clojure language

18:16 i develop about 10 years with java

18:17 sorry my english

18:17 gfrlog: agnaldo4j: how do you want to learn?

18:18 agnaldo4j: i don't know, i guess contributing with project

18:18 gfrlog: agnaldo4j: you haven't used clojure at all yet?

18:18 agnaldo4j: solving bugs, implementing features

18:18 amalloy: agnaldo4j: you might like www.4clojure.org - it's a good teaching site for many skill levels

18:18 gfrlog: amalloy: dangit that's what I was about to do :|

18:19 amalloy: derp: you too, even though gfrlog will tease me for suggesting my site

18:19 agnaldo4j: I bought a book, and i have training about it

18:19 * gfrlog goes off to register 5clojure.org

18:20 agnaldo4j: cool, amolloy, thank you

18:20 amalloy: gfrlog: try OVER9THOUSANDclojure.org

18:21 gfrlog: Oops! Google Chrome could not find over9thousandclojure.org

18:21 amalloy: yeah you're registering it

18:22 agnaldo4j: yah, OVER9THOUSANDclojure.org not encontred

18:22 gfrlog: agnaldo4j: it was a joke

18:22 agnaldo4j: ops not found

18:23 hahaha, ok

18:24 i think develop my unit tests on clujure, this is correct?

18:24 gfrlog: agnaldo4j: you can use clojure.test for testing, if that's what you're asking

18:24 agnaldo4j: or clojure is only for concurrent service, not for this?

18:25 gfrlog: agnaldo4j: http://clojure.github.com/clojure/clojure.test-api.html

18:25 agnaldo4j: i have a java application with tests on junit, but i want reduce my cust with that

18:26 i think with clojure i will write less code

18:26 this is a correct way to start to use a clojure in a project?

18:27 gfrlog: agnaldo4j: you're going to use clojure within a java project?

18:28 agnaldo4j: initially testing this application with java clojure

18:28 initially testing this java application with clojure

18:29 gfrlog: agnaldo4j: I've never heard of anybody doing that, but I suppose it's possible

18:29 amalloy: gfrlog: wut. people do it all the time. it's the stealthy way to get clojure included at work

18:29 gfrlog: amalloy: now I've heard of anybody doing that

18:31 I guess I can't see what sort of advantage it would be. I just imagine having a bunch of (is (= 10 (Foo/bar)))

18:31 actually I don't think I've ever seen a java project that was really testable

18:31 so I just don't know what good java is :(

18:46 agnaldo4j: today i use a java application with hibernate, but i dint undertand how use it with clojure and STM

18:46 *dint == don't

18:46 *undertan == understand

18:47 rpglover64: http://hpaste.org/48382

18:47 I don't understand why the two forms are different

18:48 does "recur" have unintuitive behavior with nested "fn"s?

18:48 or am I just doing something stupid?

18:51 amalloy: rpglover64: #(foo) is the same as (fn [] (foo)), not (fn [] foo)

18:51 if you wrapped the inner fn with () in the second version they would be identical

18:52 well. i'm not sure about identical, because it's not clear what you're trying to do with % and nil. are they supposed to get passed in or what

18:52 rpglover64: yes

18:53 this is supposed to find the second to last element in a list

18:53 derp

18:53 I hate it when something stupid confuses me

18:53 thanks amalloy

18:54 amalloy: rpglover64: you should come in sometime when brehaut's around. he can probably ease the haskell transition, though you seem to be doing well anyway

18:55 rpglover64: I played with scheme before I played with haskell, and the clojure docs are _really_ good

18:56 amalloy: speaking of which, have you looked at www.clojuredocs.org? it's more in-depth than the repl docs

18:57 agnaldo4j: sorry my questions related about java. but my transition will be slow

18:58 lnostdal-laptop: hmm, am i being stupid or is this java jdbc quite horrible? i.e. it doesn't actually seem to work much at all :} ..

18:58 stuff quite*

18:58 agnaldo4j: and i have to evangelize my coworks do that too

18:59 amalloy: lnostdal-laptop: if jdbc didn't work the internet would probably collaps

18:59 e

18:59 * rpglover64 is amazed at www.clojuredocs.org

18:59 * rpglover64 had been getting by on http://clojure.org/cheatsheet

18:59 amalloy: rpglover64: i wish we had hoogle though

18:59 lnostdal-laptop: amalloy, perhaps java.jdbc is still very much work in progress then ...(?)

18:59 amalloy: lnostdal-laptop: oh, the clojure wrapper around it is, for sure

19:00 rpglover64: yeah, but once you get function overloading and lose static types, hoogle becomes less powerful

19:00 lnostdal-laptop: ok, cool .. so what do people use as of now?

19:00 amalloy: bug seancorfield if you have issues

19:00 rpglover64: sure. it's not clear how we could *get* hoogle or i'd write it

19:00 lnostdal-laptop: ..i'm trying to communicate with postgresql

19:00 amalloy: $findfn 1 5 6 ;; this is nice though

19:00 sexpbot: [clojure.core/+ clojure.core/unchecked-add]

19:01 rpglover64: you'd probably have to write a type inferencer for clojure (at least for simple types) first

19:02 amalloy: rpglover64: dnolen has been spending a lot of time on a logic engine. he expects one use of it will eventually be an optional type system

19:03 rpglover64: mmmmm, static types :)

19:06 amalloy: static types? you keep your filthy mouth shut

19:07 rpglover64: :(

19:07 amalloy: i kid. i think it'd be a good addition. haskell is pretty neat, and i've barely scratched the surface

19:07 rpglover64: :)

19:07 lnostdal-laptop: no one is using clojure + postgresql ? .. or perhaps mysql?

19:07 rpglover64: yeah, static types are sometimes a pain in the ass, but I

19:08 've gotten to the point where they help me catch more bugs than they cause frustration

19:11 agnaldo4j: thanks, i will return with more questions, hehehe

19:18 seancorfield__: amalloy: just saw you respond on the mailing list about clojure.java.io - i was just reading the source (to learn) and couldn't see an obvious way to read bytes from a binary file

19:18 i'm not very familiar with the underlying java streams stuff tho'

19:19 amalloy: read into what

19:20 seancorfield__: if you wanted to read a stream of raw bytes, for example

19:20 i see how to read lines of chars from a (reader "somefile")

19:21 but not how to read bytes... i'm sure i'm just missing something obvious?

19:21 amalloy: readers are for characters

19:21 streams are for bytes

19:21 seancorfield__: ah, ok

19:23 so i'd do (with-open [s (input-stream "somefile")] ...) ?

19:24 and what function would turns s into a seq of bytes?

19:25 * seancorfield__ wonders if he should just look in the atlas for file stuff :)

19:26 amalloy: seancorfield: dunno. the function must exist somewhere, but i don't actually use that stuff much

19:26 seancorfield__: hmm, the atlas didn't help much in this case

19:30 (.read s) apparently... just need to figure out EOF now :) guess i need to read the java docs... ugh! makes me feel dirty...

19:31 amalloy: seancorfield__: (.read s) will be super-slow, if you care

19:33 the method-call overhead will be big, even if you layer a BufferedInputStream in there. you have to call (.read s ary offset len) or whatever it is

19:33 seancorfield__: true... the JavaDocs say -1 is returned for EOF

19:33 yup, just seen that in the JavaDocs...

19:38 rpglover64: I'm confused between "future" and "delay"

19:38 they seem very similar to me

19:39 amalloy: rpglover64: a future immediately starts a new thread to compute the value

19:39 rpglover64: ah

19:39 amalloy: a delay only does anything if you force it

19:39 rpglover64: right

19:39 delays make sense to me (haskell-land !)

19:40 and with that one-line summary, so do futures now

19:40 amalloy: *chuckle*

19:41 seancorfield__: and then there's promise/deliver which i think is pretty cool :)

19:44 rpglover64: seancorfield__: that's kinda like haskell's Par monad and the IVars associated with it

21:25 gfrlog: ,@(delay :wut)

21:25 clojurebot: :wut

21:29 rpglover64: ,(future (do (Thread/sleep 1000) :ohai)

21:29 clojurebot: EOF while reading

21:29 rpglover64: ,(future (do (Thread/sleep 1000) :ohai))

21:29 clojurebot: #<core$future_call$reify__5500@147545b: :pending>

21:30 gfrlog: ,(future (do (Thread/sleep 1000) (prn :ohai)))

21:30 clojurebot: #<core$future_call$reify__5500@123ef32: :pending>

21:30 rpglover64: ,(let [f (future (do (Thread/sleep 1000) :ohai))] (@f)

21:30 clojurebot: EOF while reading

21:30 rpglover64: ,(let [f (future (do (Thread/sleep 1000) :ohai))] (@f))

21:30 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :ohai

21:30 gfrlog: clojurebot may not like futures

21:30 rpglover64: i give up

21:31 gfrlog: ,(let [f (future (do (Thread/sleep 1000) :ohai))] @f)

21:31 clojurebot: :ohai

21:31 gfrlog: no need to call the result of @f

21:33 rpglover64: ah

21:34 that bit of difference is going to take some getting used to

21:34 gfrlog: difference from haskell?

21:34 you can use (deref f) if you like that better

21:38 rpglover64: yeah; there are no nullary functions in haskell

21:38 gfrlog: what's nullary about it?

21:39 rpglover64: "(@f)" vs "@f"

21:39 the former is a function call

21:39 the latter is a value

21:39 gfrlog: no, the latter is a call to deref

21:39 @f := (deref f)

21:39 rpglover64: and the former is ((deref f))

21:39 gfrlog: right

21:40 rpglover64: the @ isn't what's messing me up

21:40 gfrlog: I'm confused then, since (@f) was wrong in that context

21:40 pdk`: what is the issue then

21:41 rpglover64: pdk`: I'm just commenting how from a haskell background, "(a)" and "a" are indistinguishable

21:41 gfrlog: ah

21:41 rpglover64: and how I need to readjust

22:07 Raynes: &(let [f (future (do (Thread/sleep 1000) :ohai))] (@f))

22:07 sexpbot: java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :ohai

22:08 Raynes: Oh, I see, you were calling a future.

22:08 I can't be bothered to read entire backlogs.

22:08 amalloy: Raynes is really earning his Reading merit badge this weekend

22:09 Raynes: keyword*

Logging service provided by n01se.net