2012-07-29
| 00:04 | muhoo | huh, suddenly realized i can write SPA's in cljs that compile down to one .js file, and then deploy it on apache or whatever, without clojure (once it's compiled) |
| 00:07 | howard_ | any Aussie friends? |
| 00:17 | Raynes | Crikey mate. |
| 00:27 | muhoo | flatstick |
| 00:35 | gert | howard_: kiwi here |
| 00:55 | howard_ | my developer manager is a kiwi D: |
| 00:55 | howard_ | :D |
| 00:56 | gert | I'm not a real kiwi though. just a dutchman posing as one |
| 00:56 | howard_ | hahaha |
| 00:56 | howard_ | Guten tag! |
| 00:56 | gert | that's german! |
| 00:56 | howard_ | oops |
| 00:56 | howard_ | sorry |
| 00:56 | howard_ | haha |
| 00:56 | gert | not that there's anything wrong with that :) |
| 00:57 | howard_ | Dutch is... west germantic |
| 00:57 | gert | so is english |
| 00:58 | howard_ | ok |
| 00:58 | gert | just sayin' :) |
| 00:58 | howard_ | "Dutch is grammatically similar to German, such as in syntax and verb morphology" |
| 00:59 | howard_ | Clojure is grammatically similar to Common Lisp, such as in syntax and macro |
| 00:59 | howard_ | hehe.. |
| 01:01 | nsxt | hmm... i've a string within a (let), which i want to use to call a function with the same name as the value. the ((resolve (symbol )) etc. trick doesn't seem to work - is this a scope issue that's biting me? |
| 01:02 | howard_ | dynamic code execution |
| 01:03 | howard_ | have a look at this: |
| 01:03 | howard_ | http://stackoverflow.com/questions/11069825/clojure-why-load-string-does-not-work-in-this-case |
| 01:03 | howard_ | i had some issue with dynamic code executing some time ago |
| 01:03 | howard_ | and there's bit more information in that post |
| 01:06 | nsxt | so how would i access that function, without resorting to eval? |
| 01:07 | howard_ | um.. |
| 01:07 | nsxt | let me refheap this to make it easier |
| 01:09 | howard_ | do you wanna use read-string? |
| 01:09 | nsxt | https://www.refheap.com/paste/3869 |
| 01:10 | nsxt | (useful.string/dasherize operation) evaluates to 'list-tables' |
| 01:11 | howard_ | let me try something |
| 01:11 | howard_ | i remember people said clojure cannot dynamically execute code in lexical binding |
| 01:12 | muhoo | wow, this noir-cljs browser/repl is fragile as hell |
| 01:12 | nsxt | thanks, howard_. also, i could be approaching this entirely the wrong way (first project)... |
| 01:13 | muhoo | neat hack though |
| 01:13 | howard_ | , (let [fun #(prn "ha")] ((resolve (symbol "fun")))) |
| 01:13 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 01:14 | howard_ | i think that is the problem you ran into |
| 01:14 | howard_ | clojure apparently does not support dynamically execute code and refer variables in lexical context |
| 01:15 | howard_ | , ((resolve (symbol "prn")) "ha") |
| 01:15 | clojurebot | "ha" |
| 01:15 | howard_ | see, that one works because prn is root binding, not lexical binding |
| 01:15 | nsxt | right. |
| 01:16 | howard_ | actually, i too am developing an application that requires such behaviour |
| 01:16 | howard_ | this problem has good workaroundability |
| 01:16 | nsxt | it seemed better to try something like this than to build up a map of strings to functions |
| 01:16 | howard_ | the solution I worked out is: make a map of keywords -> functions |
| 01:16 | nsxt | haha |
| 01:16 | howard_ | <3 |
| 01:16 | howard_ | bingo |
| 01:17 | nsxt | yeah, kind of a bummer, but if there's no way around it, then so be it |
| 01:17 | nsxt | thanks for the help |
| 01:17 | howard_ | i wish i could find a better solution |
| 01:17 | howard_ | dynamically execute code in lexical context will be so helpful |
| 01:18 | howard_ | there's another way, though |
| 01:18 | nsxt | hm? |
| 01:19 | howard_ | not very readable, not elegent |
| 01:19 | howard_ | you can put the whole lexical bindings into the evaluated string |
| 01:19 | howard_ | :D |
| 01:19 | nsxt | yeah, i thought about that |
| 01:19 | alandipert | the problem is to eval a function named after a string that's been let? |
| 01:19 | nsxt | but that reads like garbage |
| 01:19 | howard_ | yeah... |
| 01:19 | nsxt | alandipert: correct |
| 01:20 | alandipert | ,(let [x "+"] ((symbol x) 1 2)) |
| 01:20 | clojurebot | 2 |
| 01:20 | howard_ | symbol + is a root binding and it works |
| 01:20 | howard_ | however, if x was a function, it won't work |
| 01:21 | alandipert | oh, i see |
| 01:21 | alandipert | the function you want to invoke is a local |
| 01:21 | nsxt | i guess i could always use a function to extract the dasherized name |
| 01:21 | nsxt | so same thing as pulling it out of the let, except not destroying the readability |
| 01:21 | alandipert | yes, i think there is probably a better alternative - this would be an exceedingly rare thing to want to do |
| 01:22 | alandipert | macros do have access to the local environment via &env... if you want to keep hacking ;-) |
| 01:22 | nsxt | still, i'm glad i stumbled across it |
| 01:22 | alandipert | yup that's good stuff |
| 01:25 | alandipert | nsxt: btw, you know you can do: (let [f #(prn "hey")] (f)) ? |
| 01:27 | nsxt | the problem is that i don't want to define the function within the scope of let |
| 01:32 | alandipert | nsxt: https://www.refheap.com/paste/3871 super hacky and inadvisable, but shows you you can get at locals with a macro |
| 01:33 | nsxt | alandipert: ha, cool |
| 01:45 | muhoo | cljs stacktraces are so much more awesome than regular jvm stacktraces: https://www.refheap.com/paste/3872 |
| 01:57 | nsxt | this is driving me nuts, i'm still getting null pointer exceptions |
| 02:18 | samrat | how do I use a scala project(https://github.com/jiminoc/goose) in a clojure project? |
| 02:18 | samrat | I found a few tutorials, but they all involved a .jar file |
| 02:18 | samrat | and I'm not sure how to make the jar |
| 02:30 | alandipert | samrat: if you clone and 'mvn install' you should be able to add [com.gravity/goose "2.1.19"] as a lein dep |
| 02:31 | alandipert | otherwise maybe it can be found in a mvn repo somewhere |
| 03:30 | tos9 | So, clj will execute a .clj without any namespace declared, but clojure-py does not, and requires an ns. Why is that? |
| 03:32 | howard | clear |
| 04:01 | emezeske | tos9: Apparently JVM Clojure just uses the user namespace by default if no ns has been set |
| 04:01 | emezeske | tos9: There isn't a language specification per se |
| 04:02 | emezeske | tos9: The JVM implementation sort of is the "language specification", if you will |
| 04:02 | tos9 | emezeske: Aha cool I was looking for something that clarified whether the spec specified that or not. Good to know. |
| 04:02 | tos9 | (That there isn't one :) |
| 04:02 | emezeske | tos9: There might be something like that in the docs somewhere, but I am not aware |
| 04:03 | tos9 | I think as long as I'm aware of it I can remember to do it always, just hoping that the amount of implementation specific behavior I run into is going to be minimal :) |
| 04:03 | tos9 | (or documented :) |
| 04:04 | muhoo | emezeske: lein-cljsbuild or noir-cljs, which do you think i should use? :-) |
| 04:04 | emezeske | muhoo: Well, I'm a bit biased ... :) |
| 04:04 | muhoo | hehe |
| 04:05 | emezeske | I haven't used noir-cljs, so I honestly can't say |
| 04:05 | emezeske | I use lein-cljsbuild for my personal projects, surprise surprise |
| 04:05 | muhoo | fair enough. i spent a few hours trying to get noir-cljs to work, next step is to try yours instead |
| 04:07 | muhoo | tomorrow though. it's bed thirty now. |
| 04:23 | michaelr525 | good morning! |
| 04:34 | emezeske | muhoo: I hope it works out! |
| 08:35 | rfgpfeif1er | join #lwjgl |
| 08:35 | rfgpfeif1er | sorry |
| 08:36 | rbarraud | Need a leading '/' :) |
| 08:38 | hyPiRion | heh |
| 09:04 | augustl | want to run "java -jar plovr.jar serve config.js" automatically when I "lein ring server". Is that possible? |
| 10:29 | justin173 | what's everyone using to manage state in their cljs apps these days? I'm currently using a horrible combination of waltz, Clojurescript One style event dispatch, and route dispatching, and I really can't decide which one to stick with |
| 10:31 | pandeiro | justin173: i feel ya |
| 10:31 | pandeiro | i was using cljs one's dispatch but i think on my next project i will try waltz |
| 10:33 | justin173 | yeah waltz seems cool |
| 10:34 | pandeiro | what issues (if any) are you having, specifically? |
| 10:35 | justin173 | well, should I be using waltz for every little widget thing I have? |
| 10:35 | pandeiro | ah yeah, right |
| 10:35 | justin173 | like it's probably obvious it doens't need to track state for little collapse/expand text boxes |
| 10:35 | justin173 | but what about a widget that say has a main-image window then a list of thumbnails that allows you to cycle through them? |
| 10:36 | pandeiro | i think you could use it for all of it |
| 10:36 | pandeiro | i remember the cljs one dispatch functions for the little text box animation; something so simple had like 12 separate events dispatching |
| 10:37 | foodoo | I haven't really workey with Clojurescript before, but maybe this Closure Library is helpful for managing state? http://closure-library.googlecode.com/svn/docs/namespace_goog_storage.html |
| 10:39 | justin173 | foodoo: yeah that's part of the thing too, there's like a bunch of clojurescript only solutions, and then that doesn't even get into the google closure ways of doing thing. although to be honest the storage aspect isn't the thing I'm having difficulty with |
| 10:42 | pandeiro | justin173: i think maybe simpler widgets could just be written as one multimethod |
| 10:42 | pandeiro | i mean with different methods dispatched based on state |
| 10:42 | pandeiro | but that's basically waltz |
| 10:42 | pandeiro | from what i understand |
| 10:43 | justin173 | yeah |
| 11:32 | qerub | Is there any way to simplify (doseq [x xs] (f x)) using clojure.core? (map f xs) would do the trick, but I'm not interested in the return value. |
| 11:36 | pandeiro | (defn do-f [xs] (doseq [x xs] (f x))) ? |
| 11:36 | pandeiro | i know it's not clojure.core but it's a one-liner |
| 11:43 | Bronsa | (dorun (map f xs)) |
| 11:48 | qerub | pandeiro, Bronsa: Thanks! I'll go with dorun. |
| 12:06 | qerub | How do I check if a value is an ISeq? (Hint: it's not `seq?`.) |
| 12:07 | qerub | Something better than (or (seq? x) (vector? x)) would be nice. :) |
| 12:09 | antares_ | qerub: it is clojure.core/seq?, if all you care about if a structure implements ISeq |
| 12:09 | qerub | (seq? []) => false |
| 12:09 | qerub | Aren't vectors ISeq? |
| 12:10 | antares_ | ther are also coll? and sequential?, with coll? being typically what people want |
| 12:10 | qerub | Hmm, so vectors aren't ISeq. |
| 12:10 | Bronsa | they are Seqable |
| 12:11 | qerub | OK, this explains everything. Thanks. |
| 12:12 | wilfredh | is there a Clojure equivalent of Python's repr()? |
| 12:13 | wilfredh | i.e. (some-function [1 2 [3 4]]) => "[1 2 [3 4]]" |
| 12:14 | Bronsa | str? |
| 12:14 | clojurebot | brehaut: I think struct embedding is monkey patching / mixins, and interface embedding is duck typing / typeclasses |
| 12:14 | Iceland_jack | ,(str [1 2 [3 4]]) |
| 12:14 | clojurebot | "[1 2 [3 4]]" |
| 12:14 | qerub | ,(str "foo") |
| 12:14 | clojurebot | "foo" |
| 12:15 | qerub | repr("foo") => "'foo'" |
| 12:15 | Bronsa | ,(str (range 3)) |
| 12:15 | clojurebot | "clojure.lang.LazySeq@7480" |
| 12:15 | Bronsa | (pr-str (range 3)) |
| 12:15 | Bronsa | ,(pr-str (range 3)) |
| 12:15 | clojurebot | "(0 1 2)" |
| 12:15 | Bronsa | maybe you want pr-str instead of str |
| 12:15 | Bronsa | ,(pr-str "a") |
| 12:15 | clojurebot | "\"a\"" |
| 12:16 | wilfredh | ah, I should have thought of str |
| 12:16 | wilfredh | I'm trying to get the source of a given function, but it seems clojure.repl/source calls println which is what stopped it worked |
| 12:17 | wilfredh | *stopped it working |
| 12:17 | Bronsa | ,(with-out-str (println "derp")) |
| 12:17 | clojurebot | "derp\n" |
| 12:17 | wilfredh | perfect. thanks :) |
| 12:31 | antares_ | ,(prn [1 2 3]) |
| 12:31 | clojurebot | [1 2 3] |
| 12:31 | antares_ | ,(prn [1 2 { :a 1 }]) |
| 12:31 | clojurebot | [1 2 {:a 1}] |
| 12:38 | dp42 | Hi everyone, any recommendations on debugging a C2/clojurescript piece of code? The firebug pane is not quite helpful :) |
| 13:15 | the-kenny | dp42: Debugging is kinda hard. I'd give the REPL a shot. |
| 13:17 | harja | Question on macros. Is there a way to apply something for each element in body and expand that on runtime? I'd need to transform (1 2 3) to (do (foo-do 1) (foo-do 2) (foo-do 3)) |
| 13:19 | the-kenny | You want unsplice |
| 13:19 | the-kenny | ,`(do ~@(1,2,3)) |
| 13:19 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 13:19 | the-kenny | Whoops |
| 13:20 | the-kenny | ,`(do ~@(map (fn [a] `(foo ,a)) '(1 2 3))) |
| 13:20 | clojurebot | (do (sandbox/foo sandbox/a) (sandbox/foo sandbox/a) (sandbox/foo sandbox/a)) |
| 13:21 | the-kenny | gnah. Something like this :) |
| 13:21 | harja | the-kenny: wow, exactly what I was looking for |
| 13:21 | harja | thanks! |
| 13:24 | the-kenny | Let's make it correct and nice: (let [syms (for [a (range 4)] (list 'foo a)) ] `(do ~@syms)) |
| 13:43 | harja | the-kenny: Is this a good way to do this? https://gist.github.com/3200531 I'm just wondering about the eval-thing on the let form. I'm completely new to clojure and this macro thingy :) |
| 13:44 | the-kenny | harja: You almost never need eval. Let me take a look :) |
| 13:44 | the-kenny | why do you even eval notes? |
| 13:45 | harja | I need to get the result from executing the function (chord xx yy) |
| 13:45 | harja | if I did not put eval, it did not work the way I wanted |
| 13:45 | harja | it just mapped over the list (chord :A4 :major) |
| 13:45 | the-kenny | Why do you even use a macro there? :) |
| 13:46 | harja | Well, initially i tried (defn play-chord [ts chord] (at ts (map sampled-piano chord))) but it invoked it immediately |
| 13:47 | harja | and then I tried (defn play-chord [ts chord] (map #(at ts (sampled-piano %)) chords)) but it did not work either |
| 13:47 | harja | chords => chord |
| 13:47 | harja | it just got played immediately I executed the play-chord -function |
| 13:47 | harja | with the macro form, it works like it's supposed to |
| 13:48 | harja | the-kenny: how do I get rid of the eval? |
| 13:50 | the-kenny | I think you want (defn play-chord [ts notes] (doseq [n notes] (at ts (sampled-piano n)))) :) |
| 13:51 | harja | ooh :) |
| 13:51 | harja | works! |
| 13:51 | harja | doseq... okay |
| 13:51 | hyPiRion | Hm. |
| 13:51 | the-kenny | doseq is like a "conventional" while-loop, running a piece of code with side effects for each element in 'notes' |
| 13:52 | harja | the-kenny: yeah, seems logical. Thanks a lot! |
| 13:52 | the-kenny | Your map-version most likely didn't work because lazy evaluation. doseq isn't lazy |
| 13:52 | harja | But, getting to the original problem, supposing I want to do something like that with a macro |
| 13:52 | harja | is the eval necessary there? if it is not, how to overcome it? |
| 13:52 | hyPiRion | harja: I don't even think you need a macro here. |
| 13:53 | harja | well, supposing I want to generate code on the fly |
| 13:53 | the-kenny | hyPiRion: We had that already :) It's just theoretical now |
| 13:53 | harja | this is just purely hypothetical now |
| 13:53 | harja | yes |
| 13:53 | hyPiRion | Ah. |
| 13:53 | the-kenny | harja: You could move the whole map-thingy into the code emitted by the macro itself |
| 13:54 | the-kenny | Ew, no. You couldnt :) |
| 13:56 | hyPiRion | One would usually take use of apply here. |
| 13:58 | hyPiRion | Is overtone.live/at a macro? |
| 13:58 | harja | hyPiRion: yes |
| 14:08 | davidd` | hey guys, I'm confused about some terminology in clojure. what exactly is a form? is it just a list that's going to be executed e.g. (str "1" "2")? |
| 14:09 | davidd` | or is str the form in this case? |
| 14:09 | jjido | davidd`: I think it is the list |
| 14:09 | davidd` | awesome. thank you jjido. |
| 14:12 | harja | hyPiRion: Do you mean I replace eval with something like (apply (resolve (first notes)) (rest notes)) |
| 14:17 | hyPiRion | harja: If overtone.live/at was a function, you could have done (apply at (+ 1000 (now)) (map sampled-piano (chord :A4 :major7))) |
| 14:17 | hyPiRion | Though since you're dealing with side-effects, the-kenny's solution seems more appropriate. |
| 14:18 | devn | isn't there an apply-at? |
| 14:18 | devn | or something? |
| 14:18 | devn | maybe im just remembering wrong hyPiRion |
| 14:26 | harja | devn: Yeah! Actually there is :) |
| 14:26 | harja | Thanks for the info. |
| 14:26 | harja | The overtone cheat sheet did not mention that |
| 14:28 | hyPiRion | devn: I've not used overtone, so don't ask me ;) |
| 14:36 | gfredericks | $findfn pos? [-1 1 -3 3] [[1 3] [-1 -3]] |
| 14:36 | lazybot | [] |
| 14:38 | Bronsa | (juxt filter remove) |
| 14:38 | gfredericks | yeah deffing that now |
| 14:38 | gfredericks | good point that's too short to def |
| 14:38 | Bronsa | it traverses the seq twice though |
| 14:38 | gfredericks | yep |
| 14:38 | gfredericks | so does split-with |
| 14:39 | Bronsa | if I am not mistaken there is a function in flatland/useful that does that without traversing it twice |
| 14:39 | gfredericks | I would be shocked if there weren't |
| 14:39 | gfredericks | this is cljs though so even if I weren't lazy that wouldn't be immediately helpful |
| 14:40 | Bronsa | useful.seq/separate |
| 14:40 | Bronsa | oh, ok |
| 14:44 | wingy | anyone here knows why i would wanna use https instead of http for fetching libs like jQuery et al |
| 14:46 | hyPiRion | wingy: ...security? |
| 14:47 | wingy | hyPiRion: but for a lib file? |
| 14:48 | wingy | what kind of things am i prohibiting an hacker from doing? |
| 14:48 | Natch | some browsers will whine if your main pages are over ssl and you fetch stuff unencrypted |
| 14:48 | Natch | might become a user issue if that's something you need to consider |
| 14:48 | wingy | Natch: whine how? as console.logs or does the user sees those warnings? |
| 14:48 | Spaceghostc2c | brainproxy: I've decided to start learning clojure. :D |
| 14:49 | wingy | Spaceghostc2c: (y) |
| 14:49 | Spaceghostc2c | Now to locate the thread in the mailing list about restricting reader macros. |
| 14:49 | Natch | wingy: you've never visited a site with mixed connections in firefox? I get those dialogues all the time about site trying to fetch stuff. or maybe it's just send.. might be just send |
| 14:50 | presto | wingy, the user does see warnings, yes. |
| 14:50 | wingy | ok |
| 14:50 | wingy | i guess https it is then |
| 14:50 | wingy | quite impressive how you have added security by just adding an "s" :) |
| 14:51 | Natch | well it will probably prevent someone snooping from knowing what you're doing |
| 14:51 | Natch | and inject stuff mand in the middle |
| 14:51 | Natch | :P |
| 14:51 | Natch | *man |
| 14:58 | hyPiRion | wingy: as Natch said, it'll reduce the possibility for man-in-the-middle |
| 14:58 | wingy | hyPiRion: so they cant manipulate the jQuery file im fetching? |
| 14:58 | gfredericks | right |
| 15:02 | Spaceghostc2c | Generally, I do most things over https. But if whatever I'm transmitting has nothing to do with authentication or anything remotely important, I'll use http. |
| 15:03 | hyPiRion | wingy: Well, it'll be harder, at least. |
| 15:18 | Spaceghostc2c | Can I use lein to keep leiningen up to date? |
| 15:19 | Natch | Spaceghostc2c: "lein upgrade" |
| 15:19 | cmajor7 | is there a clojure lib that does registration/activation email thingy? |
| 16:30 | Frozenlock | How does one load a binary file in clojure? I tried slurp and spit for a simple copy, but the resulting file is not the same as the original :( |
| 16:39 | antares_ | Frozenlock: JVM distinguishes between binary streams and character streams. Also, encoding setting matters, especially on OS X. Use http://clojuredocs.org/clojure_core/clojure.java.io and maybe https://github.com/Raynes/fs/ |
| 16:41 | Frozenlock | Thanks a lot! |
| 16:54 | justin173 | stupid question but is there an easy wat to get a current index of an item in the middle of a doseq? |
| 16:57 | devn | justin173: could you make it indexed first? |
| 16:57 | devn | ,(map-indexed vector [1 2 3 4 5]) |
| 16:57 | clojurebot | ([0 1] [1 2] [2 3] [3 4] [4 5]) |
| 16:58 | justin173 | yup that's exactly what i'm looking for thanks! |
| 16:58 | devn | yw |
| 16:58 | justin173 | i swear I'm never going to fully learn the core api |
| 16:59 | devn | justin173: it takes some time to internalize it. it's easy to say: oh ill just use an atom! but usually, TAFFT (There's a Function for That) |
| 17:00 | justin173 | devn: yeah at least I can sense when there's probably some stupidly simple solution to my issue so I can ask here :) |
| 17:25 | Frozenlock | Ok now I'm trying to print the byte-array I have, but instead it only prints "[B@44bcc9bd". Any advices? |
| 17:25 | Frozenlock | I've tried both println and write method for my printstream. |
| 17:33 | aperiodic | huh, that's weird. it seems like its writing out the string representation of the byte array object, rather than its contents |
| 17:34 | antares_ | Frozenlock: (String. ^bytes your-byte-array) creates a string from it |
| 17:35 | antares_ | aperiodic: byte arrays do not have "string representation" beyond what Frozenlock has demonstrated |
| 17:35 | antares_ | character arrays do but not byte arrays |
| 17:35 | antares_ | but you can instantiate a string from a byte array |
| 17:35 | Frozenlock | Wait, I need to convert my byte-array to string? |
| 17:36 | antares_ | if you want to print it as a string |
| 17:36 | antares_ | if you want to treat it as a byte array, use what you have |
| 17:36 | antares_ | but byte arrays do not have string representation that is human readable |
| 17:36 | Frozenlock | Not really, I want to write it as a binary file :s |
| 17:36 | aperiodic | antares_: maybe "string representation" is the wrong word, but i mean the string that says "there's an array of bytes at memory location 44bcc9bd" |
| 17:37 | antares_ | byte buffers kinda do, (java.nio.ByteBufer/wrap …) |
| 17:37 | aperiodic | like what shows up in stacktraces |
| 17:37 | antares_ | aperiodic: [B says "it is an array of bytes" |
| 17:37 | aperiodic | yeah |
| 17:37 | antares_ | that's java.nio.ByteBuffer, of course (double f) |
| 17:41 | brainproxy | Spaceghostc2c: awesome, glad to hear it :) |
| 17:42 | brainproxy | I've been away from IRC for most of the weekend, leaving again now, but I'll be back on later tonight |
| 17:42 | brainproxy | I definitely recommend the O'Reilly book "Clojure Programming" -- good place to start, especially w/ your strong background in ruby |
| 17:43 | Frozenlock | That's odd.. I read a .jar file, zip it using the zipping utility, and I get a file twice as large as the original... |
| 17:43 | Frozenlock | Damn you, file manipulation! |
| 17:44 | aperiodic | Frozenlock: (with-open [w (java.io.FileOutputStream. "foo")] (.write w (byte-array [(byte 33) (byte 35)]))) results in a file with just a shebang for me |
| 17:48 | guns | The destructuring form [& {:keys [a b] :or {a 1 b 2}] seems clunky. Are there downsides to simplifying that to [& {:keys {a 1 b 2}}]? |
| 17:49 | aperiodic | Frozenlock: if you want to do binary output, i think you want a FileOutputStream rather than a PrintStream; PrintStream seems to be designed to print string representations of data, which is probably why you were getting that "[B@..." nonsense in your output (note there's no print(byte[]) method for PrintStream) |
| 17:49 | botter | Can anyone here recommend good Clojure books, that they have actually used? |
| 17:49 | botter | I have Java experience, but no functional programming experience at all. |
| 17:50 | Frozenlock | aperiodic: That makes sense. I mean, NOW that you have said it :P |
| 17:50 | botter | And I'm looking at The Joy Of Clojure, and Clojure Programming by OReilly |
| 17:51 | johnthejohn | As a programmer new to functional programming, what is the recommended way of learning Clojure? |
| 17:53 | guns | botter: Joy of Clojure assumes some familiarity with Lisp |
| 17:53 | botter | guns, do you have any experience with Clojure Programming? |
| 17:53 | mybuddymichael | I'm reading through Clojure Programming right now. It's better for the newbie than JoC. |
| 17:54 | guns | botter: I've heard the book by stu halloway is better if you don't have lisp experience |
| 17:55 | guns | johnthejohn: Doing just the first chapter of SICP (in old MIT Scheme) goes a long way |
| 17:55 | cemerick | guns, botter: FWIW, we didn't assume any prior lisp experience. |
| 17:56 | botter | Ah! The author himself! |
| 17:56 | botter | :D |
| 17:57 | cemerick | :-) |
| 17:57 | cemerick | *co*author |
| 17:57 | cemerick | botter: Also FWIW, to get a sense of what the objectives were: http://clojurebook.com |
| 17:58 | Raynes | cemerick, guns, botter: FWIW, none of the books assume prior Lisp experience. Where people get this stuff in their heads continues to elude me. |
| 17:58 | Frozenlock | aperiodic: It was indeed the PrintStream which was messing things up, thank you very much ^^ |
| 17:58 | botter | Raynes, I assumed they did |
| 17:58 | Raynes | AFAIK, most Clojure programmers didn't come from a Lisp background. |
| 17:58 | botter | But I'm looking at Amazon's preview of Clojure Programming (the OReilly one) and it looks good |
| 17:59 | Frozenlock | Raynes: I come from an Emacs-lisp background :) |
| 17:59 | cemerick | Raynes: Quite; although I haven't bought the 2nd ed of PC. |
| 17:59 | Frozenlock | But Im no programmer so... |
| 17:59 | cemerick | so, I try to not say anything about it. :-) |
| 17:59 | guns | Raynes: maybe you'd agree that JoC is not a very gentle introduction |
| 17:59 | antares_ | hey cemerick, hey Raynes |
| 17:59 | antares_ | cemerick: are the state of clojure results ready yet? |
| 18:00 | Raynes | guns: It wasn't meant to be, but that certainly has nothing to do with requiring prior Lisp experience. |
| 18:00 | antares_ | I am very curious about them :) |
| 18:00 | cemerick | antares_: coming sometime this week. |
| 18:00 | antares_ | cool |
| 18:00 | cemerick | I may not actually read all of the comments this time. *Tonnes* of responses. |
| 18:02 | antares_ | Raynes: I heard from monger today, it says it badly wants to be reviewed by a rad Clojure hacker. Bonus points if he/she is a southerner. |
| 18:03 | antares_ | cemerick: do you know how many people approximately took the survey? |
| 18:04 | cemerick | I do, but don't want to spoil the surprise. :-) |
| 18:04 | antares_ | ok, fair enough :) |
| 18:04 | cemerick | More than 2011, we'll say. ;-) |
| 18:05 | Raynes | antares_: I heard from my knuckles today. It says it really wants to be embedded in someone's face. Bonus points for Swedes. |
| 18:06 | Raynes | In all seriousness, just haven't had a chance yet. I apologize. :( |
| 18:07 | antares_ | it's a good thing I am not a Swede :) |
| 18:21 | jamii | First pass at a datalog compiler: https://gist.github.com/3202150 |
| 18:48 | francis | (((:foo 0) ({:bar :baz} 1))) |
| 18:48 | francis | (eval (((:foo 0) ({:bar :baz} 1)))) |
| 18:50 | francis | sorry, thought that the chatbot would evalute that. Anyway, why does this return a null pointer exception? |
| 18:52 | francis | I realize that its this set doing it, and apparently it's getting evaluated as a funciton. Do sets always do this? do I have to quote everytime I end up with somthing like this? ({:bar :baz} 1) |
| 18:54 | arohner | ,({:bar :baz} 1) |
| 18:54 | clojurebot | nil |
| 18:55 | arohner | your real problem is: |
| 18:55 | arohner | ,(nil nil) |
| 18:55 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0)> |
| 18:55 | arohner | (nil) |
| 18:55 | arohner | ,(nil) |
| 18:55 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0)> |
| 18:56 | francis | I |
| 18:57 | francis | 'm confused (suprise!) why is that nil? |
| 18:57 | presto | ,(#{:meh} : meh) |
| 18:57 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Invalid token: :> |
| 18:57 | francis | The set fn (I'm assuming) would return the val at the passed index |
| 18:57 | presto | ,(#{:meh} :meh) |
| 18:57 | clojurebot | :meh |
| 18:57 | francis | ah |
| 18:57 | presto | ,(#{:meh} :bleh) |
| 18:57 | clojurebot | nil |
| 18:58 | francis | thanks |
| 18:58 | presto | Hash set. :=D |
| 18:58 | francis | nifty stuff |
| 18:59 | presto | ,([:meh] 0) |
| 18:59 | clojurebot | :meh |
| 18:59 | presto | ,([:meh] 1) |
| 18:59 | clojurebot | #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException> |
| 19:00 | muhoo | ,(:meh #{:meh}) ;; also,too |
| 19:00 | clojurebot | :meh |
| 19:01 | francis | Sets have no order to them right? Hence the above functionality |
| 19:01 | presto | Yes. I prefer the other order though, are both clojurey? |
| 19:01 | presto | ^ to muhoo |
| 19:02 | presto | francis, yes, no guaranteed order, as far as I know. |
| 19:02 | muhoo | presto: i use both, depending on the context |
| 19:03 | presto | francis, well, there is sorted-set. |
| 19:03 | presto | ,(sorted-set :meh :bleh) |
| 19:03 | clojurebot | #{:bleh :meh} |
| 19:03 | presto | ,(hash-set :meh :bleh) |
| 19:03 | clojurebot | #{:bleh :meh} |
| 19:05 | presto | ,(hash-set :b :c :a) |
| 19:05 | clojurebot | #{:a :c :b} |
| 19:05 | presto | ,(sorted-set :b :c :a) |
| 19:05 | clojurebot | #{:a :b :c} |
| 19:05 | presto | There we go. o-o |
| 19:25 | rbarraud | Hi arbscht |
| 19:34 | arohner | francis: (:foo {:foo 3}) is faster than ({:foo 3} :foo), in some circumstances |
| 19:34 | arohner | in defrecords primarily |
| 19:34 | arohner | so the usual advice is use (:foo map) everywhere |
| 19:50 | francis | noted. |
| 19:52 | Frozenlock | Raynes: your tests in `fs' require midje. Should it be added in the project dependencies? |
| 20:05 | gert | weavejester: your `secure-eql?` function in your (excellent) csrf ring middleware still leaks information about the length of the expected string (with the .length check at the beginning) |
| 20:06 | gert | it's a bit paranoid to worry about that perhaps, but maybe it's good to be paranoid? |
| 20:06 | devn | anyone know of an existing solr-cell clojure lib? |
| 20:06 | weavejester | gert: Does that matter? I mean, people can look at the source code and find that out, and knowing that there are 60 bytes of random data doesn't really help an attacker much. |
| 20:07 | gert | true, in this case. I'm thinking about a more general string compare function where the length of a string might not be known outside the app |
| 20:08 | gert | but good point - in this case it doesn't matter |
| 20:50 | Raynes | Frozenlock: Midje is a dev dependency. It doesn't need to be a project dependency. |
| 20:51 | Frozenlock | Raynes: yeah just realized that... I wasn't in dev :( |
| 20:55 | Frozenlock | Do you want a new pull request or you'll change it? |
| 21:06 | gfredericks | $findfn - [1 2 3] 1 |
| 21:06 | lazybot | [] |
| 21:06 | gfredericks | $findfn - 1 2 3 1 |
| 21:06 | lazybot | [clojure.core/max-key clojure.core/cond] |
| 21:07 | gfredericks | huh; somehow have not heard of max-key and min-key before. surely clojure.core is endless. |
| 21:42 | Raynes | Frozenlock: You don't have to do another pull request. Just change this one (any changes made in your branch are reflected by the pull request). In fact, just remove the commit entirely and then do a force push to Github. |
| 21:43 | Raynes | Frozenlock: Or, if all that seems complicated, I can just cherry pick around that commit. |
| 21:43 | Raynes | Yeah, I'll just do that. |
| 21:43 | Raynes | Frozenlock: Thanks! :) |
| 21:43 | Frozenlock | Thanks to you, I read 4 times what you said and was like "waaaaaa..." |
| 21:43 | Frozenlock | One day, one day I'll understand git. |
| 21:44 | Frozenlock | BTW you might want to take a look at the make-zip-stream. I use it with Noir to let users download stuff made on-the-fly, with nothing written to disk. Pretty cool :) |
| 21:58 | jcao219 | $help |
| 21:58 | lazybot | You're going to need to tell me what you want help with. |
| 21:58 | jcao219 | $help commands |
| 21:58 | lazybot | Topic: "commands" doesn't exist! |
| 21:59 | gfredericks | lazybot: you're going to need to do a better job indicating what you're capable of helping with |
| 21:59 | xeqi | $help list |
| 21:59 | lazybot | xeqi: Lists the available help topics in the DB. |
| 21:59 | gfredericks | $list |
| 22:00 | lazybot | I know about these topics: |
| 22:00 | gfredericks | those are some nice topics. |
| 22:00 | xeqi | lazybot is smart |
| 22:00 | gfredericks | lazybot: I know about all those topics too |
| 22:23 | estebann | quick question. why does this not work? (let [thesym "funngames"] (eval '(println thesym))) |
| 22:24 | gfredericks | eval doesn't use the local scope |
| 22:25 | estebann | that seems weird to me |
| 22:27 | gfredericks | the only justification I can think of is that the primary purpose for eval is loading code, and if it used the local scope you'd probably get unintentional shadowing for that use case |
| 22:28 | gfredericks | if you want to add some locals to an expression you can wrap it in a let before evaling |
| 22:28 | estebann | yeah, good point |
| 22:30 | presto | ,(let [thesym "funngames"] (eval `(println ~thesym))) |
| 22:30 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 22:30 | presto | Meh. |
| 22:30 | presto | Anyway, what about that? |
| 22:31 | estebann | hmmm... possible, but I want the code that's going to be evaled to be easy to write |
| 22:31 | gfredericks | an eval-with-locals macro wouldn't be hard |
| 22:32 | emezeske | Presto, the second one you pasted should work fine |
| 22:32 | estebann | is there a way to access local bindings? |
| 22:33 | Raynes | emezeske: That's pretty unreasonable. |
| 22:33 | Raynes | emezeske: There are situations where it is perfectly acceptable to do so. |
| 22:33 | gfredericks | well I was thinking explicitly given, but you could do the current local scope as well I think, using the &env variable accessible in a macro |
| 22:33 | Raynes | To fix a pull request that was issued 30 seconds ago is, in my opinion, acceptable. |
| 22:34 | emezeske | Raynes: Nah, it is a bad thing to do, all the time. Once it's public,anyone who has grabbed it gets screwed if you rebase or force push |
| 22:34 | gfredericks | emezeske: +1 |
| 22:34 | emezeske | Raynes: Well, if you know for certain nobody has grabbed, sure |
| 22:34 | emezeske | Raynes: But if you rebase or force a branch that someone else has already pulled, you are giving them grief |
| 22:34 | Raynes | emezeske: The odds that someone had grabbed some random branch of fs and had committed changes based on that tree is pretty ridiculous. |
| 22:35 | emezeske | Raynes: Doesn't matter if they committed, it is still grief to have a branch you're tracking get rebased |
| 22:35 | gfredericks | Raynes: you only need "having grabbed" not committing changes |
| 22:35 | Raynes | Silliness. |
| 22:36 | gfredericks | you'll likely not notice and end up merging every time you pull until you finally commit this parallel history |
| 22:36 | Raynes | I wouldn't have recommended he force pushed if it wasn't some random fork that was pushed minutes before on a project that nobody really cares about. |
| 22:37 | estebann | gfredericks: thnks for the suggestions |
| 22:37 | Raynes | But anyways, if anyone is ever mortally wounded by my actions in the future, please come forward and I will offer reparations in the form of sacrifice. |
| 22:37 | Frozenlock | "... that nobody really cares about" Oh, I see... |
| 22:38 | Raynes | Frozenlock: I was referring to the project, silly, not your contributions. |
| 22:38 | Raynes | Frozenlock: I've been hoping someone would add zip. |
| 22:38 | emezeske | Raynes: Heh, you can do whatever you want on your project. All I did was state my hatred for rewriting history on public branches. :) |
| 22:38 | emezeske | Tis but my opinion. |
| 22:38 | gfredericks | Frozenlock: clearly despite nobody caring about the project everybody loves your contributions to it |
| 22:38 | Frozenlock | lol |
| 22:38 | Frozenlock | Yeah sure :p |
| 22:38 | gfredericks | actually I care about fs and have contributed to it |
| 22:38 | Frozenlock | My first pull request, so I'm proud. |
| 22:39 | Raynes | emezeske: Fair enough. I don't get it in this context, but meh. |
| 22:39 | Raynes | You're still one of my favorite people. You had that paredit.vim repo. |
| 22:39 | Raynes | Made me so happy. |
| 22:39 | emezeske | Raynes: You are one of my favorite people for convincing Tomas to bust out paredit from slimv for real. :) |
| 22:39 | emezeske | <3 |
| 22:40 | Raynes | <3 |
| 22:41 | gfredericks | well I tried to contribute; apparently Raynes just did a big rewrite and obsoleted my contribution |
| 22:41 | Raynes | I did? :o |
| 22:41 | gfredericks | yeah but you did it conciously, because you closed the issue with the commit |
| 22:41 | Frozenlock | Oh in my case I wouldn't mind about that, as long as there's zip capabilities. |
| 22:41 | gfredericks | well I mind. I DID IT FOR THE GLORY. |
| 22:42 | Raynes | Oh, with-dir. |
| 22:42 | gfredericks | not only does nobody care about the library, but Raynes has bigger ideas for it than I do. |
| 22:42 | gfredericks | yeah with-cwd is a more internally consistent name |
| 22:43 | Raynes | gfredericks: Ah yes. It was actually because the fix for another issue was to make it all work differently. |
| 22:43 | gfredericks | I told my mother I was going to be in the commit history for fs. I don't know if I have the strength to tell her what really happened. |
| 22:44 | Raynes | I'm so sorry. |
| 22:45 | Hodapp | ... |
| 22:50 | muhoo | i'm kind of tired of getting clojurescript errors complaining about Could not locate clojure/instant__init.class or clojure/instant.clj on classpath: |
| 22:51 | casion` | I'm an an impasse in understanding |
| 22:52 | casion` | does iterate make a lazy sequence in the same way reduce works imperitively? |
| 22:53 | muhoo | ,(doc iterate) |
| 22:53 | clojurebot | "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects" |
| 22:53 | muhoo | hmm, says it returns a lazy sequence |
| 22:53 | muhoo | and "free of side effects" seems kind of purely functional to me. |
| 22:54 | technomancy | FSVO "must" |
| 22:54 | uvtc | casion`: I don't know what you mean by "way reduce works imperatively". In what way does `reduce` work imperatively? |
| 22:54 | casion` | it evaluates immediately |
| 22:55 | uvtc | casion`: Right. The point of `reduce` is to keep evaluating until it gives you a single result in the end. Which is different from the functions that lazily return a list which you can realize at your liesure. :) |
| 22:56 | uvtc | Gah. *leisure. |
| 22:56 | casion` | uvtc: I'm having difficulty grasping lazy sequecnes in general, but I get the concpet |
| 22:56 | casion` | just the application is bewilderring me, so I'm trying to make connections |
| 22:57 | muhoo | what application? |
| 22:57 | Frozenlock | I always get screwed by lazy sequences. In the REPL they print fine, but in the real world... Oh boy! |
| 22:57 | Raynes | Frozenlock: Pulled your stuff. Excellent work! |
| 22:57 | casion` | muhoo: I'm pretty bad at choosing words heh.. |
| 22:57 | uvtc | casion`: There's a neat example of a creating a lazy sequence in the Clojure Prog (O'reilly) book. Oh, let's see ... where is it ... |
| 22:58 | muhoo | i wish there were a way to suppress evaluation of lazy seqs in the repl, to get a "real world" sense of where there may be dragons |
| 22:58 | casion` | application in the literal sense, not an 'app' |
| 22:58 | Frozenlock | Raynes: Yay! |
| 22:58 | casion` | noun form of apply |
| 22:59 | Raynes | muhoo: The dragons are in the house of the undying. |
| 23:00 | casion` | in the volkmann tutorial for instance, this line confuses me '(def f-seq (map f (iterate inc 0)))' |
| 23:00 | muhoo | Raynes: i wasn't making a game o thrones joke, but ok |
| 23:00 | Frozenlock | Raynes: How does github work in this case? Should I delete my forked repo? |
| 23:00 | Raynes | Frozenlock: You can. You don't have to. |
| 23:00 | uvtc | casion`: Ah, here we are. Page 94. There's a neat example, where, you create a lazy list by writing a function which wraps `lazy-seq` around `cons` of a value and the result of calling the fn again. |
| 23:01 | Raynes | Frozenlock: Your changes are now in my fork. That's how git works. One copy of a repo doesn't rely on stuff from another copy of that repo. |
| 23:01 | casion` | uvtc: that book arrives on tuesday for me |
| 23:02 | uvtc | casion`: That is, you ask it for the next value, and it produces the next one plus "whatever else comes after that which I haven't yet bothered to compute --- I'll compute it when you need it quit bugging me already"> |
| 23:02 | uvtc | :) |
| 23:02 | casion` | I'm mostly relying on the clojure docs and volmann tutorial while browsing other people's code |
| 23:02 | casion` | in the meantime |
| 23:02 | casion` | uvtc: I get that conceptually |
| 23:03 | casion` | but like the line '(def f-seq (map f (iterate inc 0)))' at http://java.ociweb.com/mark/clojure/article.html#Sequences |
| 23:03 | casion` | it's making a lazy sequence of a lazy sequence? or? |
| 23:04 | Raynes | iterate returns a lazy seq and so does map. Nothing happens until you start looking at items in the sequence returned by map. It'll start realizing the sequence from iterate. |
| 23:05 | casion` | what I think is happening is (iterate inc 0) is like a lazy sequence version of (range _), and it's using that as an argument to f, and that's mapped to the lazy sequence f-seq |
| 23:05 | Raynes | I wouldn't overthink it too much. |
| 23:05 | uvtc | casion`: here's the example from the book https://www.refheap.com/paste/3878 |
| 23:05 | casion` | is that close to corrrect? |
| 23:05 | Raynes | range is lazy too. |
| 23:05 | casion` | is it? |
| 23:05 | Raynes | mhm |
| 23:06 | muhoo | well, if it wasn't, then your computer would hang when you do (range) |
| 23:06 | uvtc | The way it works is, if you just go ahead and call the function in the repl, the repl will try and realize the whole thing. So, that's no good. But, |
| 23:06 | casion` | why iterate there instead? |
| 23:06 | casion` | or would range work the same... |
| 23:06 | casion` | may as well trry |
| 23:06 | uvtc | Oh, sorry. I don't mean to cross wires. |
| 23:06 | casion` | uvtc: I'm following you |
| 23:07 | casion` | I can handle 2 conversations ;) |
| 23:07 | uvtc | casion`: Ah. I tend to be one-track minded in that way. :) |
| 23:08 | uvtc | casion`: Anyhow, the way it works is this: if you call that function such that it doesn't need to return all the values at once, |
| 23:09 | uvtc | casion`: it won't. It'll come up with the first rand-int, |
| 23:09 | uvtc | casion`: but then just defer computing the rest until later on. |
| 23:09 | uvtc | casion`: That is, if you only ask for one value from it, it will remain |
| 23:10 | uvtc | casion`: suspended with something like `(cons 42 (random-ints 100))`, and not |
| 23:10 | casion` | so it need not be incremental? |
| 23:10 | uvtc | casion`: make that call to random-ints until you ask for more values. |
| 23:10 | casion` | ok let's see |
| 23:11 | casion` | ahem.. not in the repl I suppose |
| 23:11 | uvtc | casion`: That's the thing; the repl is a people-pleaser. :) |
| 23:11 | uvtc | casion`: It wants to realize lazy lists so it can display them for you. |
| 23:12 | uvtc | casion`: However, |
| 23:12 | casion` | ok, i just dod something wrong |
| 23:12 | casion` | did* |
| 23:12 | uvtc | casion`: Right. Sorry. I was too slow at typing: you shouldn't just call that function, |
| 23:13 | uvtc | casion`: because it will just try to realize the infinite list and take over your repl. Sorry. |
| 23:13 | casion` | too late |
| 23:13 | uvtc | casion`: You can call it like so though, `(take 5 (random-ints 100))`, |
| 23:13 | casion` | and... time to restart emacs |
| 23:13 | uvtc | casion`: and it'll give you just 5 of the infinite list. |
| 23:13 | casion` | brb |
| 23:13 | uvtc | casion`: Oh shoot. Sorry about that. |
| 23:14 | casion | heh |
| 23:14 | casion | well, obviously I didnt understand that well enough to not do that |
| 23:16 | uvtc | casion: Point is, the function returns a lazy infinite list, and so will generate items as you need them, for example, |
| 23:16 | casion | I think where I'm caught is how the sequence is evaluated |
| 23:16 | casion | or stored |
| 23:16 | uvtc | casion: if you have a function that needs some values from it, `random-ints` will supply as many as it needs: |
| 23:16 | casion | orr both |
| 23:17 | uvtc | Ex: `(zipmap [\a \b \c \d] (random-ints 100))` |
| 23:17 | uvtc | There, zipmap wants to create a map for you made out of zipping those keys and values. |
| 23:17 | uvtc | `random-ints` supplies 4 values, because that's all that zipmap needs. |
| 23:18 | casion | ok |
| 23:18 | uvtc | The way that random int list looks as it's being evaluated looks something like this: |
| 23:18 | uvtc | (50 (the rest)) |
| 23:18 | uvtc | Ooof. I mean: |
| 23:18 | uvtc | (cons 50 (the-rest)) |
| 23:19 | uvtc | (50 (cons 39 (the-rest))) |
| 23:20 | uvtc | (50 39 (cons 42 (the-rest))) |
| 23:20 | uvtc | (50 39 42 (cons 28 (the-rest))) |
| 23:20 | uvtc | And it only evaluates that cons when it needs the next one. |
| 23:20 | casion | ahh ok |
| 23:21 | casion | I'm still getting used to the idea of immutable.. everything |
| 23:21 | uvtc | (where, `(the-rest)` is that call to `random-ints`. I probably should've written that instead of "the-rest") |
| 23:21 | casion | no, I got what you were saying |
| 23:22 | uvtc | casion: I'm not sure where the sequence "is stored" ... It's floating there in space waiting to be asked for more of its values. :) |
| 23:23 | uvtc | The values you've asked for are "realized" (computed and made available). |
| 23:23 | casion | I have this need to have at least a basic idea of the implementation |
| 23:23 | casion | or I feel like I don't understand it |
| 23:24 | uvtc | `(source lazy-seq)` ? |
| 23:24 | casion | yeah, i'm going through a few now |
| 23:24 | casion | I just don't know enough clojure yet to grasp some of it |
| 23:24 | casion | this is all a massive brainfuck to me |
| 23:34 | uvtc | casion: In that example you gave above, `(def f-seq (map f (iterate inc 0)))`; both the `iterate` and the `map` are lazy. `iterate` only generates values it's asked for, and same with `map`. So, if you ask for a value from the list --- say, (nth the-list 5), `nth` asks `map` to start walking through values 'til it gets to the 5th one, and it in turn asks `iterate` for values. |
| 23:34 | casion | so iterate just recurisively cons a result of f? |
| 23:35 | uvtc | (sorry -- replace "the-list" with "f-seq") |
| 23:35 | uvtc | `iterate` just gives you f(x), f(f(x)), f(f(f(x))) , ... as you ask for them. |
| 23:35 | casion | doesn't it take the nth result from iterate, then map that? |
| 23:36 | uvtc | No, it has to work up to it. :) |
| 23:36 | casion | doesnt map need a collection though? |
| 23:36 | uvtc | `iterate` hasn't generated a list yet. It generates it as it's asked for values --- no sooner. |
| 23:36 | casion | so iterate would have to returrn first? |
| 23:37 | uvtc | No. `map` just needs something that's promised to look and act like a list. :) |
| 23:37 | casion | hmm |
| 23:37 | uvtc | AFAIU, it's a train of lazy functions. You ask `map` for the next one, and it asks `iterate` for the next one. |
| 23:38 | uvtc | But if you ask here during eastern daylight time working hours, I'm sure the wizards will be able to explain exactly how it works. |
| 23:38 | casion | that doesn't make sense to me at all... I would think iterate needs to be evaluated first? |
| 23:38 | casion | but I'm in no position to disagree heh |
| 23:39 | casion | thank you very much though, you've made a lot more clear for me |
| 23:39 | uvtc | y/w. :) |
| 23:43 | xeqi | &(class (iterate inc 0)) |
| 23:43 | lazybot | ⇒ clojure.lang.Cons |
| 23:53 | ivan | &(take 25 ((fn fibs [] (concat '(1 1) (lazy-seq (map +' (fibs) (drop 1 (fibs)))))))) |
| 23:53 | lazybot | ⇒ (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025) |
| 23:56 | uvtc | ivan, what is +' ? |
| 23:57 | ivan | it's + with arbitrary precision |
| 23:57 | ivan | that is, supports adding a small and large number |
| 23:57 | uvtc | ,(doc +') |
| 23:57 | clojurebot | "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Supports arbitrary precision. See also: +" |
| 23:57 | uvtc | Hm. Didn't know you could use a single-quote mark like that. |
| 23:58 | uvtc | Thanks. |
| 23:59 | uvtc | Ah. You're mapping +' onto 2 collections: one shifted by 1 from the other... |