#clojure log - Apr 27 2011

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

0:48 mreynolds: Hmm, problem 15 doesn't like #(* % 2), says it's being passed the wrong number of args

0:49 Clinteger: problem 15?

0:49 mreynolds: https://www.4clojure.com/problem/15

0:49 Sorry, was stuck on a while back when they posted this site into the chat room

0:49 Clinteger: ah. perhaps try #4clojure ;)

0:49 mreynolds: OH

0:49 Right

0:49 thanks

1:11 seancorfield__: it's even got it's own channel now??

1:11 Clinteger: small in comparison to this channel, but yes lol

1:16 lancepantz: yeah, so check this one out

1:16 java.lang.RuntimeException: java.lang.Exception: No such var: clojure.core/if (NO_SOURCE_FILE:0)

1:16 how screwed does that mean i am?

1:17 hiredman: if is a special form, no var

1:18 lancepantz: does that imply i'm calling it outside of parens somethere?

1:18 *where

1:18 hiredman: #'clojure.core/if

1:18 ,#'clojure.core/if

1:18 clojurebot: java.lang.Exception: Unable to resolve var: clojure.core/if in this context

1:19 hiredman: ,(ns-resolve 'clojure.core 'if)

1:19 clojurebot: nil

1:19 lancepantz: right

1:19 guess i'll keep lookin

1:19 hiredman: something like that

1:20 lancepantz: thanks dude

2:52 prkchp_sndwch: hello, I'm trying to set up overtone using the command "lein repl". how do I have the repl load a clojure file I've written?

2:57 seancorfield__: (load-file "path/to/file.clj")

3:07 prkchp_sndwch: thanks sean

3:31 justinlilly: http://pastebin.com/2f9w2JqR -- does anyone have a better way to write this seemingly simple function?

3:32 * justinlilly grumbles and finds repeat.

3:41 seancorfield__: (zero? left) instead of (= left 0)

3:41 otherwise i guess it's fine... i can't remember what i did for that problem :)

3:48 avysk: If you don't want to use repeat, you can do with (for [_ (range i)] item) :)

3:49 justinlilly: is there sugar for doing (= myvar '())

3:49 empty? doesn't work as it throws an exception if it gets something like an int.

3:54 Belaf: Hello everybody! I've got a question about using clojure.contrib.logging together with clojure.test: is there an easy way (e.g. by binding some special variable) to redirect the logging coming from tests to a different logfile ?

3:55 seancorfield__: just fyi, in 1.3.0 c.c.logging has become https://github.com/clojure/tools.logging

3:57 Belaf: allright, thanks, but I'm still on 1.2.0. Maybe there will be some way only in 1.3.0?

3:58 seancorfield__: i haven't looked at c.c.logging yet, sorry

3:58 avysk: nice use of for!

4:00 Belaf: I've found some "java level" way of switching to a different logfile, I'll try that one, waiting for something better :)

4:06 raek: Belaf: don't know any solution to the redirection problem, but you can use clojure.tools.logging in 1.2.0 or 1.2.1 just fine

4:07 Belaf: You mean it's already there? Going to check it, thanks!

4:08 raek: yup. [org.clojure/tools.logging "0.1.2"]

4:08 Belaf: Oh, now I got it, for 1.2.0 it's a separate package.

4:10 raek: the version of tools.logging does not follow the clojure versioning

4:12 fliebel: So, how do projects actually get into the new contrib?

4:13 raek: something like this http://groups.google.com/group/clojure-dev/browse_thread/thread/12e9f47aa54bc969

4:13 fliebel: oh, okay

4:15 * fliebel 's membership is still pending, and CA is lost. Adds CA to mental todo list.

4:22 solar_sea: Hi. How do I alias a namespace within another one ? I've tried (ns my-ns (:require [clojure.contrib.math :as math])), but then math/ doesn't resolve. Fully quallified - it works.

4:23 Belaf: Any advantage in using "clojure / tools.logging" vs "clojure.contrib.logging", except maybe being ready for clojure 1.3.0 ?

4:58 mrBliss: Just got my copy of The Joy of Clojure in the mail!

5:06 Kerris: I wish some projects would take donations. :(

6:49 clgv: I want to use the latest stable version of Incanter but no frequently updated snapshot. what do I supply to leiningen's project.clj? only 1.2.2 without the "-SNAPSHOT"?

6:53 ok that seemed to have worked

7:07 raek: clgv: these are the versions available on clojars: http://clojars.org/repo/incanter/incanter/

7:07 1.2.3 seems to be the latest non-snapshot

7:13 clgv: raek: oh ok thanks. I did try to find out the version number on their homepage ;)

7:15 I would love a standalone jar of it. it really spams my lib directory ;)

7:33 mholmqvist: Hi, I'm trying to use java.util.ServiceLoader to load a service that is implemented in Clojure using :gen-class. I get a ServiceConfigurationError with cause: Provider could not be instantiated: org.foo.Bar java.lang.ExceptionInInitializerError

7:34 I have read that Clojure uses the context classloader and that I should set it before trying to load Clojure classes as in http://dev.clojure.org/jira/browse/CLJ-260

7:36 The implemented service is in an external jar-file and I use a URLClassLoader to load the jar. Anyone got any hints?

7:38 Further down is: java.io.FileNotFoundException: Could not locate org/foo/Bar__init.class or org/foo/bar.clj on classpath.

7:42 AH! Never mind. I used the wrong ClassLoader when calling Thread.currentThread().setContextClassLoader. It's working now.

7:42 clojurebot: Paul Graham is the creator of the other new lisp

7:44 Kerris: Arc?

7:44 clojurebot: POLO! nya nya you can't see me

7:44 Kerris: oh, it's clojurebot. =_=

7:49 ilyak: hi *

7:49 Why does (print "a") (print "b") differs from (map print ["a" "b"]) in ccw?

7:55 thorwil: ilyak: not just in ccw

7:59 ilyak: map takes and evaluates to a seq. whereas the first is too separate forms

7:59 s/too/two/

8:00 how to use Enlive's text? it should return the content of a node, but i need it inside of a transfomation ...

8:29 ilyak: I have a mystical problem

8:30 I have a transient {} for which I do a lot of (assoc! it key (+ increment (get it key 0)))

8:30 and after I do some millions of that, it has only 8 keys - there should be like fifty

8:31 Which are, coincidentally, keys that would have the biggest values, but not in exactly sort order

8:41 clgv: ilyak: minimal example?

8:42 ilyak: It seems that after 8 keys I can no longer assoc! new keys

8:43 when I assoc! key doesn't materialise in map

8:43 I'll try to make one

8:44 clgv: I have a guess: do you use the result of assoc! to continue?

8:44 I was told that you need to and not doing so will only work in special cases

8:46 ilyak: What does it return? Should I?

8:46 I think I'll paste my function

8:47 http://pastebin.com/eBB8XujM

8:48 clgv: &(loop [lst [[1 2] [3 4] [5 6]] tm (transient {})] (if-let [p (first lst)] (recur (rest lst) (assoc! tm (first p) (second p))) (persistent! tm))

8:48 sexpbot: ⟹ {1 2, 3 4, 5 6} ; Adjusted to (loop [lst [[1 2] [3 4] [5 6]] tm (transient {})] (if-let [p (first lst)] (recur (rest lst) (assoc! tm (first p) (second p))) (persistent! tm)))

8:51 clgv: ilyak: seems like you do not use the return of assoc!

8:52 you seem to want something like encapsulated mutable state. I have seen people doing that via atoms

8:52 so you could place your transient into an atom

8:52 raek: ilyak: transients should be use the same way as the ordinary ones. they might change *some* things in place (this is just an optimization), but you should not rely on that it changes anything in place

8:53 ilyak: raek: So I have to write it using ref?

8:54 clgv: ilyak: no. an atom will suffice

8:54 raek: if you want something that mutates, you need to use a ref, atom, var or agent

8:54 atoms and vars are pretty lightwight

8:55 clgv: ilyak: maybe like that: http://pastebin.com/t1TqbfUt

8:55 raek: sometimes, even a loop/recur can be an alternative to mutation

8:56 ah, now I saw your code.

8:56 an atom here is a very good fit, as clgv suggested

8:57 ilyak: clgv: thanks I'll look into it

8:58 clgv: ilyak: you may have to correct a paranthesis or two ;)

9:00 raek: ilyak: http://pastebin.com/nGm3QRXu

9:01 yeah, don't trust the parenthesis balance in mine too... :)

9:02 changes: removed transients and changed swap expression to (swap! counts update-in [major] (fnil + 0) (count listens))

9:03 clgv: raek: hmm well you are right - no need for transient anymore since its calling schedule isnt that tight anymore

9:08 fortxun: is Rich Hickey around?

9:08 clgv: $seen rhickey

9:08 sexpbot: rhickey was last seen quitting 1 week ago.

9:08 fortxun: ahh

9:10 $help

9:10 sexpbot: You're going to need to tell me what you want help with.

9:10 fortxun: $help message

9:10 sexpbot: Topic: "message" doesn't exist!

9:12 clgv: $help msg

9:12 sexpbot: Topic: "msg" doesn't exist!

9:13 clgv: $help /msg

9:13 sexpbot: Topic: "/msg" doesn't exist!

9:13 clgv: ah you might mean "mail"?

9:14 $help mail

9:14 sexpbot: clgv: Send somebody a message. Takes a nickname and a message to send. Will alert the person with a notice.

9:17 jamesswift: tired and blind to why this isn't working, can anybody point out the obvious to me? http://pastebin.com/rBT4809Y

9:17 *gets ready to slap forehead*

9:18 clgv: jamesswift: what exactly are you trying to do?

9:18 jamesswift: trying to get the value of :menuName from the map

9:19 clgv: but I'm getting nil

9:19 clgv: where do you construct the map?

9:19 for a short example: ##(let [map {:menuName "hello2"}] (map :menuName))

9:19 sexpbot: ⟹ "hello2"

9:20 jamesswift: clgv: it's actually passed in a request (compojure route) ... er. I think I realise why i'm stupid. it's strings in ring requests not keywords. I knew I just had to say it 'out loud' to realise why i was stupid. thanks for listening :)

9:21 clgv: I think I forget this at least once a month

9:22 ##({"menuName" "hello"} "menuName")

9:22 sexpbot: ⟹ "hello"

9:52 clgv: is there an abbreviation for (reduce #(reduce + %) mat) on matrices?

10:04 cemerick: clgv: (def msum (partial reduce #(reduce + %))) ?

10:05 clgv: cemerick: lol. I thought there might have been something built-in for matrice like structures ;)

10:05 cemerick: clgv: no need when you can define msum yourself :-)

10:06 Though I'll bet there are at least a couple of matrix op libraries floating around.

10:06 clgv: is that the shortest way to convert a double matrix? ##(map seq (make-array Double/TYPE 3 3))

10:06 sexpbot: ⟹ ((0.0 0.0 0.0) (0.0 0.0 0.0) (0.0 0.0 0.0))

10:17 choffstein: Does anyone have some 'production' code where they use protocols that I can look at. I've read lots of 'gentle introductions' to them, and while I think I get the general gist of them, I don't really know a practical example of where I would use them in my code.

10:19 jlf: choffstein: maybe http://blog.higher-order.net/2010/05/05/circuitbreaker-clojure-1-2/ ?

10:19 choffstein: I'll give it a read. Thanks :)

10:20 jlf: np

10:26 clgv: choffstein: one case where use them is when you want functions that have a lot of state so that using partial gets ugly

10:26 and for having real java-interfaces

10:26 choffstein: clgv: not quite sure if I follow. What do you mean functions that have a lot of state?

10:27 clgv: choffstein: hm I guess you can rewrite that: if you need objects similar to those in java (but in general immutable)

10:28 choffstein: Hmmm, I see. I'll keep poking around. I feel like i'm going around the answer in circles ... eventually i'll understand it

10:30 clgv: I use them for my configuration object and for the specification objects

10:30 I think the case with the specification objects is the most fitting

10:31 The protocol has a method that creates a function. internally the function is provided with "constant" parameters via partial.

10:32 the specification has a hierarchy with different specification types for different purposes, but all do create functions

10:33 $findfn 0.12345 0.12

10:33 sexpbot: []

10:39 choffstein: hmmmm

10:39 that ... confuses me more :D

10:46 clgv: ok, simpler then: one interface (= protocol) with different implementations^^

11:25 &(- 0.0)

11:25 sexpbot: ⟹ -0.0

11:25 clgv: that feels odd

11:42 TimMc: clgv: Floating point is like that.

11:42 clgv: TimMc: yeah. but it makes no sense ;)

11:43 TimMc: ,((juxt pos? zero? neg?) [1 0.0 -0.0 -1])

11:43 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number

11:43 TimMc: bah

11:43 ,(map (juxt pos? zero? neg?) [1 0.0 -0.0 -1])

11:43 clojurebot: ([true false false] [false true false] [false true false] [false false true])

11:44 clgv: like expected

11:48 TimMc: I have actualy used negative zero vs. positive zero on occasion.

12:02 manutter: ,(= 0.0 -0.0)

12:02 clojurebot: true

12:02 manutter: fascinating

12:05 sritchie: does anyone have any experience with thrift serialization, for java?

12:14 choffstein: Anyone aware of any component based web frameworks for Clojure like SmallTalk's Seaside or Ruby's Wee?

12:15 TimMc: ,(== 0.0 -0.0)

12:15 clojurebot: true

12:21 thorwil: choffstein: afaik there doesn't exist any ready-for-action non-spartan web framework for clojure

12:21 choffstein: figured :)

12:24 thorwil: choffstein: if that changes or changed, something might appear on http://clojure-libraries.appspot.com/category/27 or http://clojars.org/search?q=web

12:25 choffstein: okay. thanks

12:43 amalloy: sritchie: i do

12:44 sritchie: amalloy: I just figured out my issue -- I had been using backtype's thrift jarfile from clojars, which had an earlier version of thrift than I'd been using to generate my java source

12:46 just pushed 0.5.0 to clojars -- http://clojars.org/redd/thrift

12:48 TimMc: Any recommendation for writing CLojure shell scripts?

12:48 ("Don't" is an acceptable answer.)

12:49 amalloy: TimMc: jark?

12:49 manutter: Took the words right out of my mouth

12:49 amalloy: i haven't tried it, but it claims to be for this purpose

12:50 manutter: I've played with it a little, looks promising

12:51 http://icylisper.in/clojure/jark.html

13:13 TimMc: More specifically, can I just drop a shebang onto a .clj file?

13:14 Raynes: TimMc: Yes, you can. Check out the cake README (the part about shell scripts) and/or jark's documentation about it.

13:14 amalloy: TimMc: i think there's some kind of limitation about how long the shebang line can be, though, bizarrely, which doesn't play nice with the bloated command lines java uses

13:15 (a limitation in the shell, not in clojure)

13:15 TimMc: Raynes: Nice, thanks.

13:17 justinlilly: amalloy: you should be able to easily fix that with another command somewhere. `echo "./big-java-program" > ~/bin/java-prog` then add #!/path/to/java-prog at the top.

13:34 TimMc: Hrm. Running with the cake shebang does not preserve the working directory.

13:35 amalloy: TimMc: java hates working directories

13:35 TimMc: :-(

13:35 amalloy: the jvm has a cwd, which doesn't change after jvm launch

13:35 Raynes: TimMc: There isn't really anything that can be done about that. Can't change the working directory at runtime.

13:36 amalloy: so with eg cake, which has a persistent jvm, the cwd will always be wherever the jvm was launched from

13:36 dnolen: TimMc: but cake preserves it's own cwd

13:37 amalloy: i imagine jark will do something like detect where you are when you invoke jark, and pass that as a parameter to the script you want to run

13:37 dnolen: TimMc: I got them to add that feature a while back

13:38 TimMc: I'd be happier with explicit cwd anyway.

13:40 I'll stick with this shitty Bash script for now.

13:42 david`: any of you guys using emacs on os x?

13:42 dnolen: david`: yup

13:43 david`: do you use emacs or aquamacs?

13:45 dnolen: still at nyu

13:47 dnolen: david`: Cocoa Emacs, http://emacsformacosx.com/. No teaching at nyu at the moment, but perhaps again in the future.

13:47 david`: I went to Gallatin

13:48 NYU was a lot of fun

13:48 dnolen: david`: cool! agreed.

14:07 TimMc: oh my god how can bash be this fucked up

14:08 amalloy: TimMc: whiner. i don't like programming in bash, but for shell-related stuff it's pretty powerful

14:08 choffstein: I'm running into an issue where it seems like data is being treated lazily and then an error is cropping up later in my program in a totally "unrelated" section. In on part of my program, I am dividing one number by another. About 100 lines later, when I try to print this data, I get a divide by zero error. Is there any way to force evaluation of the thunks?

14:09 TimMc: amalloy: I just changed the start of my iteration from 1 to 0, and my file renumbering script stopped working -- apparently because an arithmetic operation returning 0 is an error code or something.

14:09 technomancy: choffstein: sure; doall will do that

14:09 choffstein: okay, thanks

14:10 amalloy: TimMc: "apparently...or something" tends to be a complaint associated with "i don't understand what is going on", not "what is going on is clearly wrong". just sayin', seems wrong to leap to the assumption that bash is doing something crazy

14:11 TimMc: amalloy: Yeah, I know. BUt seriously, all I changed was the initial value of a counter.

14:14 markoman: i have a strange problem with saving datastore on appengine magic. it seems its not possible to save inside for loop

14:17 amalloy: lazy?

14:17 clojurebot: lazy is hard

14:18 amalloy: close enough, clojurebot

14:18 markoman: ok, i solved it. cant do (for (save (new ...))) but need to do (save (for (new ...)))

14:19 TimMc: amalloy: The built-in "let" arithmetic command gives a non-zero exit value on a zero result. :-(

14:21 amalloy: TimMc: huh. i've never used let. i agree it seems kinda weird

14:21 TimMc: ANyway, that interacted poorly (and mysteriously) with my use of set -o errexit

14:23 and I use *that* because bash takes a "let's keep going anyway and see what happens!" approach to error handing by default.

14:42 amalloy: TimMc: && and ||?

14:44 that is, i don't even know what errexit is, so take this with a grain of salt, but it sounds like swatting a fly with a bulldozer, while && and || would give you more fine-grained control

14:52 TimMc: amalloy: When I write scripts that bash (hah!) on the filesystem, I prefer to have unexpected error cases stop the program entirely.

14:53 amalloy: TimMc: right. that's what && is for?

14:53 createnewfile && mv newfile oldfile

14:54 TimMc: How would you apply that to `for f in *.jpg ; do ... done` ?

14:55 Anyway, I solved my specific issue with `let "n = i * 2" || true`

14:56 amalloy: TimMc: use while instead of for, i think

14:56 but i dunno

14:56 i don't do a lot of scripting really

14:56 TimMc: hmm

14:56 I try to avoid it.

14:57 I'll check out while, though.

15:23 raek: amalloy: what was the variable called for custom 2-space indented forms in clojure-mode?

15:34 sritchie: hey all -- I've got a function that works great, until I add a single entry to the let statement, after which it fails

15:34 https://gist.github.com/945001

15:35 if i insert a println, it looks like it hits the else statement for the first four loops and does fine, when throws this exception when it has to travel down the second path in cond

15:35 bulters: sritchie: I'm no expert, but iirc in a normal let pos is not directly available

15:36 sritchie: But that could've been some other lisp :P

15:36 sritchie: ,(let [x 5 y (inc x)] y)

15:36 clojurebot: 6

15:37 sritchie: maybe the fact that it's inside the loop is the issue, though

15:37 raek: sritchie: if you reload the namespace with (require 'the-ns :reload), you will get line numbers in the stack trace

15:38 bulters: sritchie: then consider my remark not typed ;-)

15:39 sritchie: raek: hmm, I didn't see a change

15:39 hiredman: sritchie: offset is nil

15:39 sritchie: I think it's zero

15:39 raek: maybe 'pos' could be nil

15:40 sritchie: oh, yeah

15:40 hiredman: sritchie: I think you are wrong

15:40 sritchie: no, offset is zero -- pos becomes nil on the recursion when the list empties out

15:41 that's the issue! good stuff

15:46 amalloy: raek: clojure-defun-indents iirc

15:46 but it's under the clojure-mode group, so you can find it that way too

16:08 raek: amalloy: thx

18:02 lacker: hi all. i am having a problem with leiningen. when I run my project with `lein run` it works fine, but when I run an uberjar I get a "Could not find the main class: mo.core. Program will exit."

18:02 technomancy: lacker: probably missing :gen-class?

18:02 lacker: ah yes, that token is nowhere in my code. where should that go?

18:03 technomancy: it goes in the ns form of the namespace containing -main

18:03 lein help tutorial under Uberjar shows it

18:03 lacker: ok cool thanks. is that generated by `lein new` and I deleted it at some point, or is it just a step that I have to do?

18:04 technomancy: it's not included by default

18:05 lacker: where is this tutorial you refer to? sorry for asking noob questions here when I should be reading docs

18:07 technomancy: just run "lein help tutorial"

18:08 Somelauw: I wonder whether you can create a game and program it is functionally as possible.

18:09 brehaut: Somelauw: with 'as possible' : yes

18:09 lacker: thanks technomancy

18:10 technomancy: sure

18:11 Somelauw: But wouldn t games have a lot of mutable state?

18:12 Like objects disappearing and character doing attacks and such?

18:12 brehaut: it depends?

18:12 you'll have to have some mutable state

18:12 like any real program*

18:12 *bag of caveats im sure

18:14 Somelauw: Yes, but that makes me wonder to what extend you should use immutable state and at which point you should stop using it.

18:15 Since technically you can pass a list of all games object in a recursive function, but that is probably to painful.

18:15 raek: Somelauw: you might find this interesting: http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf

18:15 especially slide 52

18:15 and then there's http://prog21.dadgum.com/23.html

18:15 "Purely Functional Retrogames"

18:20 from the retrogame series: "When I first mused over writing a game in a purely functional style, this had me stymied. One simple function ends up possibly changing the entire state of the world? Should that function take the whole world as input and return a brand new world as output? Why even use functional programming, then?"

18:21 I believe that for programs that has essensial state, making the whole part functional might not be the most convenient way to do it

18:22 one of the powers of Clojure is that it lets you hande state in a well-defined and pretty way, when you need it

18:23 brehaut: (inc raek)

18:23 sexpbot: ⟹ 8

18:23 no_mind: if I have to iterate over a sequence without any side-effects. Which language construct is the fastest ? doseq or for ?

18:23 hiredman: without?

18:25 raek: a purely functional core, and a layer for managing state on top of that, seems to be the pattern I have seen so far

18:26 but where to draw the line between the purely functional part and the state managing part is the real question... :)

18:30 Somelauw: Yes, but maybe your website will explain it.

18:31 I was thinking that mutable state might be good when modelling something that has mutable state in reallife.

18:42 no_mind: any AI based application written in clojure yet ? Looking for some application based on agent to be precise

19:11 TimMc: no_mind: doseq is intended for side effects, for is intended to collect results

19:43 mec: Could someone take a look at my persistent double linked list code? remove-node, add-before, and add-after share too much structure but I'm not sure how to refactor them. https://github.com/mecdemort/mec/blob/master/double_list.clj

19:51 Somelauw: Hmm, I know something about functional programming, but I really should learn how to write an actual application in a fp language.

20:13 mec: Does implementing Associative assume constant time lookup?

20:47 scottj: in slime when there's an error during C-c C-k anyone have the error window with details stop opening/displaying in the last few months? not sure if it's a bug in my setup

20:48 hiredman: I've seen the issue with clojure 1.3, maybe if you upgrade your swank-clojure?

20:48 I haven't played with 1.3 + swank for sometime, so I dunno if it still happens

21:00 sritchie: amalloy: if you have a second, I had a quick question about thrift -- if I declare a field in a struct that takes a list of values, say, list<FireTuple> series, inside of a struct called TimeSeries

21:00 is (TimeSeries. [(FireTuple. 0 0) (FireTuple. 1 2)]) the right way to populate that list?

21:00 timeseries doesn't seem to care what's inside that list

21:00 s/list/vector

21:00 sexpbot: <sritchie> timeseries doesn't seem to care what's inside that vector

21:03 amalloy: sritchie: dunno. you asked about thrift in java, not in clojure :P

21:04 sritchie: haha, fair point

21:05 amalloy: what's the answer in java?

21:05 can a struct take any sort of collection, to populate a list?

21:05 amalloy: sritchie: turns out i actually don't know that either. i haven't really worked with very complex types - i just declared a struct that groups together some basic data types

21:06 but i don't know what constructors get created. i'd do more like (doto (TimeSeries.) (.setSeries [(FireTuple. 0 0)...]))

21:06 since i know it creates setters

21:09 sritchie: amalloy: interesting, you're right, here -- looks like the constructor doesn't typecheck

21:10 but using (doto (TimeSeries.) (.addToSeries (FireTuple. 0 0))) works out

21:18 hiredman: ,(doc instance?)

21:18 clojurebot: "([c x]); Evaluates x and tests if it is an instance of the class c. Returns true or false"

21:35 scottj: hiredman: does a description of your compilation errors open? what version of swank-clojure are you using?

22:02 SergioTapia: hello

22:03 $karma hiredman

23:24 chrissbx: How do you append strings in clojure? Once again I'm at a loss searching for the right docs...

23:25 For example the cheatsheet doesn't mention that, even though it's got two sections about strings.

23:25 jdmmmmm: chrissbx: (str "a" "b")

23:26 ,(str "a" "b")

23:26 clojurebot: "ab"

23:26 chrissbx: hum. I wonder what's the logic about this name?

23:26 Well I'll just eat it.

23:27 jdmmmmm: I think it just makes a string out of anything you pass in.

23:27 ,(str "ab" 12 '[:a :b])

23:27 clojurebot: "ab12[:a :b]"

23:28 chrissbx: yeah, that's what I expected, kind of a constructor.

23:29 But to take two of them and make a new one... (shrugs)

23:29 jdmmmmm: along the lines of vec

23:29 chrissbx: Well I haven't learned about that yet :)

23:29 jdmmmmm: Java strings are immutable; making new ones in inevitable.

23:34 * chrissbx mumbles something about the wonderful world of overloads

23:36 chrissbx: Is there a rule which ops do automatic conversions of types, btw?

23:36 Like, is it only these constructor-like ops like str, vec?

23:36 well, forget about vec already, that won't convert I guess.

23:36 jdmmmmm: vec will:

23:37 ,(vec '(:a :b :c))

23:37 clojurebot: [:a :b :c]

23:37 jdmmmmm: Of course, it's not really "converting" -- it's creating a new one.

23:39 chrissbx: Hu, but unlike str which also takes single characters, vec doesn't take single elements to make up a vector.

23:39 That'd be "vector".

23:40 ah "vec" actually doesn't take multiple arguments.

23:40 (That's what I thought when you said str was along the lines of vec.)

23:40 amalloy: chrissbx: most operations implicitly convert their arguments to a seq

23:41 because that's how first/rest work

23:43 chrissbx: Is there a "reduce" that folds from the right?

23:44 called fold-right or foldr in some languages

23:44 amalloy: chrissbx: not a built-in

23:45 as i understand things this is because foldl can process elements from a seq on demand, but foldr would have to realize the whole seq all at once and build up a deep stack to evaluate even the first fold

23:46 chrissbx: I want something like (reduce (fn[r v] (cons (str v "=") (cons v r))) '() '(a b c))

23:46 but output ("a=" a "b=" b "c=" c) instead of ("c=" c "b=" b "a=" a)

23:47 What you say seems the wrong way around: fold-right can process the input lazily, fold-left can't.

23:47 amalloy: chrissbx: usually you can get that sort of thing by using a vector and conj instead of a list and cons

23:47 chrissbx: Assuming that we're talking about lazy linked lists where the first cell is the left-most

23:47 jdmmmmm: ,(map #(str % "=" %) '(a b c))

23:47 clojurebot: ("a=a" "b=b" "c=c")

23:48 chrissbx: But I need two cons for each element; one stringified, the other not.

23:48 amalloy: chrissbx: maybe you can explain to me how foldr can process inputs lazily. i saw that in a haskell text but can't really understand it

23:48 chrissbx: So I can't use map.

23:48 jdmmmmm: ,(mapcat #(list (str % "=") %) '(a b c))

23:48 clojurebot: ("a=" a "b=" b "c=" c)

23:50 chrissbx: amalloy: say the output looks like ("a=" a "b=" b "c=" c); if you take "first", it will have to evaluate as far as getting the element "a" from the input list.

23:51 But say the output looks like ("c=" c "b=" b "a=" a), which is what reduce gives, taking "first" will need the input till the last element, c.

23:51 That's the short answer; the longer would be to go through each step of the evaluation.

23:52 In an eager language, reduce (or fold-left) doesn't need stack, because it can build the output while walking the input in forward direction.

23:53 amalloy: &(reduce #(conj %1 (str %2 "=") %2) [] '(a b c))

23:53 sexpbot: ⟹ ["a=" a "b=" b "c=" c]

23:53 amalloy: fwiw

23:53 chrissbx: Whereas in the same eager language, fold-right needs to build up a stack of intermediate results while walking the input.

23:53 But that's not what you suggested was happening here.

23:54 * chrissbx looks up conj

23:55 amalloy: chrissbx: that is what's happening here. clojure is an eager language at its root, but with lots of laziness options built on top

23:56 chrissbx: Hm you said "as i understand things this is because foldl can process elements from a seq on demand,"

23:57 amalloy: its input seq

23:57 chrissbx: I concentrated on the "on demand" part, meaning lazy eval of the input

23:58 What I want to say is: if you prefer solutions in terms of "efficiency", then in an eager language, fold-left could be preferrable because it doesn't need stack,

23:58 amalloy: seancorfield: bad news: two more 4clojure problems

23:58 chrissbx: whereas in a lazy language (lazy input seq) fold-right would be preferrable because in this case it *doesn't* need stack and in addition doesn't evaluate the input more than required for the part of the output that's needed.

Logging service provided by n01se.net