2011-02-17
| 00:24 | simard | bortreb: hum I only get to 87 ms |
| 00:24 | simard | were you serious about 3 ms ? ;) |
| 00:47 | tomoj | why aren't sorted sets and maps IEditableCollections, I wonder? |
| 00:48 | bortreb | I was doing the coderloop problem, which goes much higher than the euler ones |
| 03:14 | TobiasRaeder | morning |
| 04:48 | iwillig | is there a protocol that I can extend a Java class to take advantage of ISeq ? |
| 05:03 | Dranik | is there a way to save the current clojure application state and load it like in lisp? |
| 05:23 | _2x2l | Dranik: how would you do it in CL? |
| 05:24 | Dranik | _2x2l, I don't know CL so well but I'm sure it is possible to save the current state and restore it after a while |
| 06:28 | zmila | #join compojure |
| 07:17 | bmh | I'm thinking of implementing sampling from the conditional multivariate normal distribution in Incanter and I want to make sure I get my interface right. Anyone involved with Incanter around? |
| 07:27 | zmila_ | aoeu |
| 08:59 | Cozey | Hi! I'm using 'contexts' with cake. Will I be able to set some configuration in a later generated jar? when I do cake jar @context it doesn't seem to place the cake namespace inside the jar |
| 09:14 | _fogus_ | Looks like the documentation for #= has vanished. :-( |
| 09:38 | ejackson | _fogus_: the LHC is rumoured to be emitting particles of antidocumentrons. |
| 09:39 | Fossi | that'd be funny |
| 09:57 | _fogus_ | CURSE YOU LHC! |
| 09:58 | ejackson | its always the French. |
| 10:13 | octe | i've noticed a pattern when i write clojure utils, i'll make a create/init function that returns a state-object that is usually a ref to a map, and a destroy/close function that releases any resources the state contains, and then a bunch of functions that takes the state as an argument and does various things |
| 10:13 | octe | is this a good pattern? |
| 10:16 | Chousuke | hmm |
| 10:17 | Chousuke | if the functions operating on the actual ref is low, then I guess. |
| 10:18 | Chousuke | your main concern should be writing functions that operate on the values of the ref, not functions that operate on the ref :) |
| 10:19 | Chousuke | though I have to say that sounds a lot like you're just emulating object-orientation |
| 10:19 | Chousuke | with a constructor, methods, mutable state, and a destructor :P |
| 10:23 | octe | Chousuke, yeah, that's the feeling i get too. |
| 10:24 | octe | say for example i'm writing an irc client, i'll need to at least keep track of the socket (in the state object then) |
| 10:24 | octe | it feels inevitable |
| 10:25 | octe | 1 |
| 10:29 | Chousuke | octe: you can't avoid state entirely, the point is isolating it from the non-stateful stuff. |
| 10:29 | Chousuke | octe: which includes most processing of data |
| 10:30 | octe | yes |
| 10:30 | Chousuke | if you can tell which functions are stateful and which aren't given arbitrary parameters, you're doing fine I think :P |
| 10:31 | octe | well when there's io involved, they're all stateful i guess |
| 10:31 | Chousuke | in a stereotypical OO program, there's just no reliable way to tell wtf exactly is happening. :) |
| 10:31 | octe | yeah |
| 10:31 | Chousuke | octe: only the IO itself is stateful, processing the stuff you read is not. |
| 10:31 | octe | feels like im falling into that trap with my state-objects |
| 10:32 | octe | ah well |
| 10:38 | dnolen | octe: you could create a small paste gist isolating the particular pattern you find yourself using. it sounds unidiomatic to me. |
| 10:54 | raek | octe: I think one example could be to write (defn parse-line [s] (.split s ",")) (parse-line (read-line rdr)) instead of something like (defn get-and-parse-line [rdr] (.split (read-line rdr) ",")) |
| 10:54 | raek | i.e. to as often as possible to all data processing in pure functions |
| 11:09 | jkdufair | anyone working/worked with appengine-clj? |
| 11:11 | TobiasRaeder | the freiheit one? |
| 11:11 | TobiasRaeder | or appengine-magit |
| 11:12 | TobiasRaeder | *magit |
| 11:12 | TobiasRaeder | but i guess that would be appengine-magic and not -clj ;) |
| 11:12 | TimMc | *magic |
| 11:12 | TobiasRaeder | ty |
| 11:12 | TobiasRaeder | lol |
| 11:12 | TobiasRaeder | but yeah actually i do |
| 11:13 | ev4l | hi there! did anyone here experienced the following error with swank-clojure: "swank-clojure-reset-implementation: Symbol's function definition is void: aput" |
| 11:13 | ev4l | it happens when run 'swank-clojure-project' to change the current project directory |
| 11:14 | ev4l | *it happens when i run* |
| 11:17 | jkdufair | i've been playing with appengine-magic but discovered appengine-clj. there are several forks and i wondered if anyone had experience with any of them. the datastore features in the r0man fork and below look pretty tasty |
| 11:18 | TobiasRaeder | i just know the original (smartrevolution) one which is in kind of a big overhaul right now which is nearly done |
| 11:19 | raek | ev4l: haven't heard of that problem, but I would recommend trying durendal (https://github.com/technomancy/durendal) |
| 11:20 | raek | it lets leiningen take care of starting swank, rather doing that from emacs |
| 11:20 | jkdufair | i've been using durendal and it works nicely |
| 11:21 | raek | I think you could say that it's the successor of swank-clojure.el |
| 11:21 | TobiasRaeder | @jkdufair you need any help with appengine-clj? |
| 11:21 | raek | "Previous versions of Swank Clojure bundled an Elisp library called swank-clojure.el that provided ways to launch your swank server from within your Emacs process. While swank-clojure is still distributed with the project, it's a much more error-prone way of doing things than the method outlined above." |
| 11:21 | raek | "If you have configured your Emacs to use M-x swank-clojure-project then it should still work, but it's not recommended for new users." |
| 11:22 | raek | when I started using durendal, I also had to add a lein symlink in /usr/local |
| 11:23 | jkdufair | TobiasRaeder: not help, per-se. just in choosing a fork. looks pretty self-explanatory otherwise. i'm building a RESTful JSON frontend to appstore entities |
| 11:23 | raek | since it wouldn't use my custom PATH from by .bashrc |
| 11:23 | jkdufair | wrote a bunch of macros and such which look like was done better by appengine-clj |
| 11:24 | TobiasRaeder | @jkdufair okay, well i think the smartrevolution should be really nice specially after the next update (gonna try to force that to be published soon) |
| 11:25 | jkdufair | TobiasRaeder: Are you referring to smartrevolution/clj-gae-datastore? |
| 11:26 | TobiasRaeder | @jkdufair i thought there was an appengine-clj from that user aswell but doesn't seems that way. im kinda confused now :D gonna see if i can find what i mean |
| 11:26 | TobiasRaeder | @jkdufair because i thought there was more then just a datastore api |
| 11:27 | octe | raek, yeah, i try to do that |
| 11:33 | ejackson | Lets say I download some clojure library (say clojure-redis). Is it horrendous just create symlinks from my src/main/clojure/.... ? |
| 11:33 | cemerick | ejackson: yes, just a bit :-) |
| 11:33 | ihodes | ejackson: yes |
| 11:33 | ejackson | I want to keep them separate, but also want to be able to use clojure-redis in my project without building and deploying jars each tim |
| 11:33 | ejackson | so what's the technnique ? |
| 11:33 | ihodes | ejackson: use lein, please |
| 11:34 | cemerick | ejackson: lein, maven, gradle, ant……really, anything other than synlinks. |
| 11:34 | ejackson | lets assume maven |
| 11:34 | ejackson | now what ? (sorry for this stupid question) |
| 11:34 | cemerick | heh |
| 11:35 | ejackson | do I mvn package the clojure-redis |
| 11:35 | ejackson | mvn install it |
| 11:35 | cemerick | ejackson: one would hope it's in a repo somewhere already |
| 11:35 | ejackson | and then use it as a dep in my pom.xml for the main project ? |
| 11:36 | cemerick | ejackson: essentially, yes |
| 11:36 | cemerick | maybe this is what you're after? http://clojars.org/redis-clojure |
| 11:36 | ejackson | this was just a minimal example. Really I have two projects that rely on substantially amounts of my own code |
| 11:37 | ejackson | i've been balking at pulling those shared sections into independent libraries |
| 11:37 | clojurebot | libraries is http://clojure.org/libraries |
| 11:37 | ejackson | symlinks are a cute solution, but felt evil |
| 11:38 | cemerick | They are. It doesn't seem like it in the small and while you're working solo, but as soon as either change, it's a disaster. |
| 11:38 | fliebel | morning |
| 11:38 | ejackson | cemerick: thanks for the tips. I'll buckle down and sort this out... |
| 11:39 | cemerick | ejackson: FWIW, of course. :-) |
| 11:46 | ejackson | cemerick: am I correct in thinking that converting to a multi-module maven project is a reasonable approach ? It would allow me to make a .jar for each module of the current project, deploy em to the binary repo and use elsewher. |
| 11:47 | ejackson | To press my luck on the questions: Would bringing in some existing projects (like redis-clojure) and a module into a big project be a good move ? |
| 11:48 | ejackson | s/and a/as a/ |
| 11:48 | sexpbot | <ejackson> To press my luck on the questions: Would bringing in some existing projects (like redis-clojure) as a module into a big project be a good move ? |
| 12:08 | technomancy | ejackson: FWIW that's what "checkout dependencies" are for in lein |
| 12:08 | ejackson | technomancy: thanks, I'll examine that. |
| 12:09 | technomancy | that way changes in the checkout are available without doing the repackage/restart dance |
| 12:10 | ejackson | yeah, that's what's irritating me right now |
| 12:25 | fliebel | What is a good data structure for storing positions where adjacent positions are nearby and easy to get to? |
| 12:25 | AWizzArd | fliebel: you can think about sorted-set-by |
| 12:25 | AWizzArd | for those and on sorted-map-by's you can do subseq |
| 12:27 | fliebel | AWizzArd: Sorted by what? |
| 12:27 | AWizzArd | ,(subseq (sorted-set-by #(< %2 %1) 1 2 3 4 5) < 3) |
| 12:27 | clojurebot | (5 4) |
| 12:29 | AWizzArd | You can sort by position |
| 12:29 | AWizzArd | ,(sorted-set-by compare (range 10)) |
| 12:29 | clojurebot | #{(0 1 2 3 4 5 6 7 8 9)} |
| 12:29 | fliebel | I never really understood subseq, but it looks nice :) (as deos a hilbert curve, but I'm not sure that's of any use) |
| 12:29 | AWizzArd | ,(apply sorted-set-by compare (range 10)) |
| 12:29 | clojurebot | #{0 1 2 3 4 5 6 7 8 9} |
| 12:30 | AWizzArd | ,(subseq (apply sorted-set-by compare (range 10)) >= 3) |
| 12:30 | clojurebot | (3 4 5 6 7 8 9) |
| 12:30 | AWizzArd | ,(subseq (apply sorted-set-by compare (range 10)) >= 3 < 8) |
| 12:30 | clojurebot | (3 4 5 6 7) |
| 12:30 | AWizzArd | those are >=3 and <8 |
| 12:31 | AWizzArd | or you can have |
| 12:31 | AWizzArd | ,(sorted-set-by #(.compareTo (str %1) (str %2)) :a :b :c :d :e :f :g) |
| 12:31 | clojurebot | #{:a :b :c :d :e :f :g} |
| 12:31 | AWizzArd | and then subseq on it with >= :c and <= :e |
| 12:32 | fliebel | AWizzArd: I am not sure I understand how this is useful, for say a 2D grid. |
| 12:32 | AWizzArd | I don't know if it is useful. It is just an idea to fetch nearby objects. |
| 12:34 | fliebel | okay, i'll think about it |
| 12:40 | ev4l | raek: thx! |
| 12:43 | amalloy | AWizzArd: isn't #(< %2 %1) identical to >= ? |
| 12:43 | raek | *> |
| 12:44 | amalloy | mmf. i guess that's true. i always forget that reversing the order of args isn't the same as negating the operation :P |
| 12:44 | amalloy | &(doc subseq) |
| 12:44 | sexpbot | ⟹ "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true" |
| 12:51 | fliebel | dnolen: ping |
| 13:02 | dnolen | fliebel: pong |
| 13:04 | AWizzArd | amalloy: yes, I just wanted to show how it can be used in principle. |
| 13:05 | fliebel | dnolen: It's diner time for me now, but after the break, I'd like to discuss some issues with the cond-i problem. some examples in the book do not work because of this. |
| 13:05 | fliebel | any-o for example. |
| 13:10 | dnolen | fliebel: yeah, I'm probably not going to address that. it's pretty easy enough to sort out what's going on in those examples anyhow. |
| 13:12 | dnolen | fliebel: Oleg has the version of miniKanren used in the book here, http://kanren.cvs.sourceforge.net/kanren/kanren/mini/mk.scm, copy and paste into Racket. |
| 13:14 | dnolen | LogicBlox use of Datalog seems really interesting: http://www.logicblox.com/research/presentations/arefdatalog20.pdf |
| 13:15 | jweiss | i'm trying to figure out how clojure.zip/branch? is throwing NPE. I can't think of any input that would cause that. http://www.fpaste.org/5J8h/ |
| 13:16 | jweiss | my branch fn is just #(contains? % :links), which i tested calling it with nil, doesn't throw NPE |
| 13:17 | raek | jweiss: the closing paren on line 7 looks suspicious |
| 13:17 | amalloy | raek: a fine point |
| 13:18 | jweiss | raek: amalloy: it did the same thing before i added line 7 |
| 13:18 | raek | also, (if x (f x) nil) can be written as (and x (fx x)) |
| 13:18 | amalloy | raek: damn, beat me to it |
| 13:18 | amalloy | jweiss: you wrote the if on line 7 wrong |
| 13:18 | jweiss | i am kinda grasping at straws |
| 13:18 | raek | jweiss: your defn contains two expressions: (if (nil? z) nil) and (->> ...) |
| 13:18 | amalloy | should be (if (nil? z) nil (->> ...)), not (if (nil? z) nil) (->> ...)) |
| 13:19 | jweiss | amalloy: doesn't matter. removing line 7 has no effect. |
| 13:19 | jweiss | it was broken before i added it |
| 13:20 | raek | jweiss: having that expression there won't affect anything, since you discard the value of the 'if' and eval the ->> anway |
| 13:21 | jweiss | raek: so z may in fact be the 'problem' nil on line 6 |
| 13:21 | raek | look carefully how the parentheses are arranged in amalloy's explanation |
| 13:21 | jweiss | let me fix and retry |
| 13:25 | jweiss | raek: amalloy: http://www.fpaste.org/pAXq/ |
| 13:25 | jweiss | seems to have fixed my bad "if" but still has the same problem |
| 13:25 | jweiss | it's a zipper problem i think since it's thrown from clojure.zip/branch? |
| 13:26 | raek | jweiss: if you reload the file with (reload 'com.redhat.qe.auto.navigate :reload) or (C-c C-k in emacs) you will get line numbers in the stack trace |
| 13:26 | raek | ...for you own functions |
| 13:26 | raek | *(require ...) |
| 13:26 | jweiss | raek: yeah i know, i already know what line # in my own functions it's thrown from |
| 13:27 | raek | which line is it in the paste? |
| 13:27 | jweiss | it's line 7 in the paste |
| 13:27 | amalloy | jweiss: it's a problem with how you're using the zipper, anyway :P. (zip/next nil) will probably throw the same error |
| 13:28 | jweiss | amalloy: hm... maybe it's because my zipper predicate returns nil instead of false? |
| 13:30 | raek | maybe the lazy-seq from iterate will call zip/next one time too much |
| 13:30 | raek | and then it's too late to do the zip/end? test |
| 13:30 | jweiss | raek: i don't think so, since zip/end? returns true on the last one |
| 13:31 | jweiss | oh wait i think i may see what you mean |
| 13:31 | jweiss | the way zipper's docs say it, it should be ok |
| 13:31 | jweiss | in fact, if there was a problem that you describe, my find-node would always fail |
| 13:31 | jweiss | but it doesn't |
| 13:33 | jweiss | the doc here is unclear: "children is a fn that, given a branch node, returns a seq of its |
| 13:33 | jweiss | children." |
| 13:33 | jweiss | so i am supposed to return an empty seq if there are no children? |
| 13:34 | amalloy | jweiss: nill is probably the same as an empty seq |
| 13:34 | raek | maybe the lib will only call that function for nodes where branch? is true |
| 13:34 | amalloy | but don't return a seq containing nil |
| 13:36 | fliebel | dnolen: easy?! :( Oh, well, I think I'll figure it out. What do you mean by "not going to address"? I don't expect you to make cond-i/e work differently in Logos, but maybe you could explain me a bit about the difference, and and why any-o does not work with Logos, as defined in the book. |
| 13:37 | raek | jweiss: have you tried defining a lazy-seq in some way like this: (defn traverse-tree [z] (lazy-seq (when-not (zip/end? z) (cons z (traverse-tree (zip/next z)))))) |
| 13:37 | raek | I don't know if zippers are designed to be used this way |
| 13:38 | raek | (I have barely used tried them) |
| 13:38 | jweiss | raek: you mean using next to create a lazy seq? |
| 13:38 | jweiss | i figure next must be there to create a traversal |
| 13:39 | raek | I was thinking about putting next and end? at the same place |
| 13:39 | raek | to use them both to construct the seq in order to not walk outside the end |
| 13:39 | raek | (assuming that was the problem, which mich not be the case anyway) |
| 13:47 | dnolen | fliebel: sorry got disconnected. |
| 13:48 | dnolen | fliebel: I just don't have much interesting in supporting depth-first search in Logos. It's existence in TRS purely pedagogical, show you can see the benefits of an interleaving search. |
| 13:49 | dnolen | s/show/so |
| 13:49 | sexpbot | <dnolen> fliebel: I just don't have much interesting in supporting depth-first search in Logos. It's existence in TRS purely pedagogical, so you can see the benefits of an interleaving search. |
| 13:50 | fliebel | dnolen: I wasn't asking if you could support it, but rather if there is a way to make things like any-o work with your cond-e. |
| 13:51 | dnolen | fliebel: can you paste the snippet so I can see what your talking about? I don't have my copy of TRS lying around. |
| 13:51 | fliebel | (defn any-o [q] (cond-e (q s#) ((any-o q)))) |
| 13:52 | dnolen | fliebel: and how are you running that? (run 1 [q] (any-o q) ? |
| 13:53 | fliebel | (run 1 [q] (any-o s#) (== true q)) |
| 13:53 | fliebel | no, wait... |
| 13:53 | fliebel | yea, like that |
| 13:55 | fliebel | I can imagine the because of interleaving, it tries q, recurs, and never reaches s#, but.. |
| 13:55 | fliebel | (defn any-o [] (cond-e (s#) ((any-o)))) has the same result. |
| 14:08 | dnolen | fliebel: actually I think you found a legitimate bug :) |
| 14:11 | dnolen | fliebel: I created an issue, the interleaving is not right |
| 14:16 | mprentice | happy thursday folks |
| 14:25 | whr | Hello, i've got a question. Why doesn't this code: (try (map + '(a b)) (catch Exception ex 42)) catch the exception (it throws ClassCastException)? Similiar code, (try (throw (new ClassCastException)) (catch Exception ex 42)) returns 42 |
| 14:28 | mprentice | I need to differentiate between a map and a string. Ideally, (somefun {}) will return true, and (somefun "anystring") will return false. What is the idiomatic clojure way to do this? (I have a vector filled with maps and strings and i need to only do a lookup based on a key in the maps) |
| 14:28 | Chousuke | (doc map?) |
| 14:28 | clojurebot | "([x]); Return true if x implements IPersistentMap" |
| 14:28 | mprentice | ahhhhh, durr, yes, thanks much :) |
| 14:39 | amalloy | whr: map is lazy |
| 14:39 | amalloy | the exception doesn't occur during the call to map, but in the realization of the lazy seq that map returns, which is outside the lexical scope created by try |
| 14:40 | amalloy | &(try (map + '(a b))) |
| 14:40 | sexpbot | java.lang.ClassCastException: Cannot cast clojure.lang.Symbol to java.lang.Number |
| 14:40 | whr | amalloy: I see, thank you! |
| 14:40 | amalloy | &(try (map + '(a b)) (catch Exception _ 10)) |
| 14:40 | sexpbot | java.lang.SecurityException: You tripped the alarm! catch is bad! |
| 14:41 | amalloy | mutter. anyway, you can put a (doall (...)) inside the try, if you want to catch and don't mind realizing the whole seq at once |
| 14:41 | jcromartie | &(take 2 (map inc '(3 9 a b c))) |
| 14:41 | sexpbot | ⟹ (4 10) |
| 14:41 | jcromartie | &(take 3 (map inc '(3 9 a b c))) |
| 14:41 | sexpbot | java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number |
| 14:44 | dnolen | fliebel: should be able to get that fixed later this evening. Looks like I'll be using delay to force interleaving, fun. Thanks for the report. |
| 15:09 | jweiss | so (first (filter pred coll)) isn't lazy... how do i lazily find the first matching item? |
| 15:10 | raek | what do you mean by not lazy? does it force too many elements? |
| 15:10 | raek | jweiss: 'some' is made for that |
| 15:10 | raek | (some #(when (pred %) %) coll) |
| 15:11 | jweiss | raek: sweet, that's it, thakns |
| 15:11 | raek | if the seq is chunked, maybe that won't make any difference |
| 15:16 | monora | Hi, I am experimenting with slime-clojure. But can't remember how to get the value of the last evaluated expression. Was it $1, $2,... |
| 15:17 | jcromartie | *1 |
| 15:17 | jcromartie | *2 |
| 15:17 | monora | Ah! Thanx |
| 15:17 | jcromartie | raek: is "some lazy? |
| 15:25 | clizzin | quick question about records and type hints: i declared (defrecord Foo [a b]) in (ns foo). then, in (ns bar), i have a function (defn bar [#^Foo f] ... ). but i didn't require or use the foo ns in any way. how come the bar function still compiles with the type hint even though the bar ns shouldn't recognise the Foo type? |
| 15:25 | raek | jcromartie: I don't think the term applies to it, since it does not produce a seq. however, I don't think it will force more of the seq than it needs |
| 15:35 | jcromartie | it's kind of strange that (first (filter pred coll)) seems to fully evaluate the seq |
| 15:36 | jcromartie | &(first (filter #(do (println %) %) (range 5))) |
| 15:36 | sexpbot | ⟹ 0 1 2 3 4 0 |
| 15:36 | jcromartie | those 0 1 2 3 4 are printed |
| 15:37 | jcromartie | but filter says it returns a lazy seq |
| 15:39 | Scriptor | jcromartie: print forces evaluation, maybe? |
| 15:39 | jcromartie | that would be strange |
| 15:39 | _fogus_ | &(second (filter identity (iterate #(do (println \.) %) 1))) |
| 15:39 | sexpbot | ⟹ . 1 |
| 15:40 | raek | &(first (filter #(do (println %) %) (range 100))) |
| 15:40 | sexpbot | ⟹ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0 |
| 15:40 | jcromartie | hm |
| 15:40 | raek | ranges come in chunks of 32. |
| 15:40 | jcromartie | it takes 32 eh |
| 15:40 | Scriptor | ohh |
| 15:40 | Scriptor | right, it's an optimization |
| 15:40 | jcromartie | so what's lazy, filter, or range? |
| 15:40 | _fogus_ | raek: beat me to it! :-) |
| 15:40 | jcromartie | what's lazy: filter, or range? |
| 15:41 | Scriptor | both, I think |
| 15:41 | _fogus_ | (inc raek) |
| 15:41 | sexpbot | ⟹ 5 |
| 15:42 | raek | both return lazy sequences, but performing sequence operations of a chunked seq (e.g. one returned by range) happens 32 at a time |
| 15:42 | jcromartie | &(first (filter #(do (println %) %) (vec (range 100)))) |
| 15:42 | sexpbot | ⟹ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0 |
| 15:42 | jcromartie | looks like filter is returning a 32-chunked seq |
| 15:42 | raek | I don't know much more details than this |
| 15:42 | jcromartie | I could just look at the source I guess |
| 15:42 | jcromartie | :P |
| 15:42 | raek | over to you, _fogus_... :-) |
| 15:42 | jcromartie | silly me |
| 15:46 | cemerick | OT: Any chance anyone here is an expert in the minutiae of options? |
| 15:46 | _fogus_ | options? |
| 15:46 | _fogus_ | stock options? |
| 15:46 | cemerick | _fogus_: of the financial sort |
| 15:47 | jcromartie | &(type (range 10)) |
| 15:47 | sexpbot | ⟹ clojure.lang.LazySeq |
| 15:47 | jcromartie | &(type (seq (range 10)) |
| 15:47 | sexpbot | java.lang.Exception: EOF while reading |
| 15:47 | jcromartie | &(type (seq (range 10))) |
| 15:47 | sexpbot | ⟹ clojure.lang.ChunkedCons |
| 15:48 | _fogus_ | cemerick: Sorry... not I |
| 15:48 | cemerick | _fogus_: yeah, it was a longshot. I've had good luck asking longshot OT questions here, though. |
| 15:50 | jcromartie | looks like seq returns chunked seqs |
| 15:50 | jcromartie | for some types |
| 15:51 | raek | it just returns whatever was wrapped in the (lazy-seq ...) form inside the definition of range |
| 15:59 | jweiss | i'm a bit confused about zippers. all my nodes are the name type - a map. each node can have a :links key, whose value is a seq of other nodes (children). |
| 15:59 | jweiss | so isn't my "branch?" function (constantly true)? |
| 16:00 | jweiss | since all my nodes are branches (whether they actually have children or not) |
| 16:00 | amalloy | jweiss: yes. why is that confusing? |
| 16:00 | amalloy | and your children function is just :links |
| 16:01 | jweiss | amalloy: well, it isn't but the zipper doesn't seem to work. each node (if i call zip/node) still has all the children in it. |
| 16:01 | jweiss | i kinda expected not to see them |
| 16:02 | amalloy | what do you mean, still has all the children? zip/node returns the exact data structure that you have it |
| 16:03 | jweiss | amalloy: i am confused about the zipper model. it's calling it a node, when the way it behaves seems like it's returning the entire tree for which that node is a root. |
| 16:03 | amalloy | so if your map is {:name "test" :size 10 :children [{:name "foo"}]} |
| 16:04 | amalloy | then that map is the node |
| 16:04 | jweiss | hm, ok. i was expecting all the nodes to be the same size as i walked from root to leaf. |
| 16:04 | jweiss | but they actually get smaller and smaller. |
| 16:04 | amalloy | it doesn't know how to "take out" the children-related data. how could it? it just knows that this map is a data point, and to get the children of that data point, it calls (:children the-map) |
| 16:05 | jweiss | amalloy: yeah, i understand. it's the nomenclature that had me thinking the wrong way. |
| 16:05 | jweiss | it's not a node, it's a branch. |
| 16:05 | amalloy | only if you want to think of it that way |
| 16:05 | robonobo | Hi guys |
| 16:06 | robonobo | How would i find the index of the greatest element in a seq? |
| 16:07 | amalloy | robonobo: you can do it, but usually messing with indexes is the wrong way to go |
| 16:07 | jweiss | amalloy: what is the point of zip/path then? it returns [entire tree, subset, smaller subset, etc] |
| 16:08 | amalloy | jweiss: it gives you zip nodes, not your data elements |
| 16:08 | jweiss | the data element of the first item in the path is the entire dataset |
| 16:08 | robonobo | amalloy: I know, but it is pertinent in this context |
| 16:08 | amalloy | &(first (apply max-key second (map-indexed identity [4 1 6 8 0]))) |
| 16:08 | sexpbot | java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$identity |
| 16:08 | amalloy | &(first (apply max-key second (map-indexed vector [4 1 6 8 0]))) |
| 16:08 | sexpbot | ⟹ 3 |
| 16:09 | amalloy | &(first (apply max-key second (map-indexed vector [4 1 6 -8 0]))) |
| 16:09 | sexpbot | ⟹ 2 |
| 16:09 | amalloy | robonobo: ^ |
| 16:09 | robonobo | wow, I would have thought that to be simpler |
| 16:11 | amalloy | robonobo: perhaps there is a simpler way, but this is straightforward enough for me. why write a standard-library function to do something you should rarely do? |
| 16:11 | robonobo | amalloy: true |
| 16:12 | amalloy | and it's fairly clear what it's doing. turn a seq of data items into a seq of [idx, data] pairs; find the element with the largest data item; get the index of that element |
| 16:30 | simard | is there a way to do something like this (ie.: the problem seems to lie with the % signs) ? (map #(map #(identity %) %) (partition 5 big-number)) |
| 16:30 | simard | Nested #()s are not allowed |
| 16:30 | simard | hum |
| 16:30 | simard | clear enough |
| 16:31 | fogus_away | simard: You don't need #() around identity |
| 16:31 | brehaut | the use of identity there is just a placeholder right? |
| 16:31 | simard | brehaut: yeah just to make sure this is working |
| 16:32 | brehaut | clojurebot: partition |
| 16:32 | clojurebot | partition is probably not what you want; see partition-all. |
| 16:33 | amalloy | simard: i think fogus_away's point was that "#(foo %)" can be more concisely written as "foo" |
| 16:33 | simard | nah I really want partition :) |
| 16:33 | amalloy | brehaut: that's interesting; i usually want partition |
| 16:34 | amalloy | for things like ##(partition 2 1 (range 6)) to get a seq of pairs |
| 16:34 | sexpbot | ⟹ ((0 1) (1 2) (2 3) (3 4) (4 5)) |
| 16:34 | brehaut | amalloy: however a lot of people who dont realise both exists actually want partition-all |
| 16:34 | brehaut | oh yeah for sure, partition-all is messy there |
| 16:35 | amalloy | i think partition-all would give me (5) as an extra "pair" |
| 16:35 | brehaut | yeah it would |
| 16:37 | ossareh | afternoon all |
| 16:37 | brehaut | ossareh: its always morning in UGT |
| 16:38 | ossareh | UGT? |
| 16:38 | clojurebot | ugt is Universal Greeting Time: http://www.total-knowledge.com/~ilya/mips/ugt.html |
| 16:38 | ossareh | ah :) |
| 16:38 | technomancy | ~botsnack |
| 16:38 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 16:39 | ossareh | In all my years on IRC I've never heard of ugt - awesome! |
| 17:06 | TimMc | I think it has been making the rounds again recently. |
| 17:07 | TimMc | ...unless I first heard about it here, in which case it is not indicative of a trend. :-P |
| 17:12 | simard | is it possible to have a seq be indexed through (nth) without all elements before the nth element to be evaluated ? (it would depend of the seq of course, some are recursively defined, but others are not..) could anyone enlighten me on this ? |
| 17:12 | simard | or give a pointer anyway |
| 17:17 | Cozey | is there some function to updated an element of a list using a predicate to determine which one? (the new value will also be calculated from old value + something else) |
| 17:21 | brehaut | Cozey: asside from (defn map-if [pred f s] (map #(if (pred %) (f %) %) s)) ? |
| 17:23 | Cozey | brehaut: not bad! |
| 17:23 | brehaut | Cozey: it does strike me that a list is the wrong tool for the job though |
| 17:24 | Cozey | brehaut: perhaps - but what if i want to manipulate some ordered collection of data? I'd like to keep the order |
| 17:25 | brehaut | ordered or sorted ? |
| 17:27 | Cozey | ordered |
| 17:29 | Cozey | I have a list of symbols and another equaly long list of classes. I want to create a structure like [ [class1 item1 item2 item3] [class2 item1 item2 item3... ] ... ] with items partitioned for each class. the order of classes should be the same as they 'appear' in list of classes, so if classes are: a c b b a a, it should be: a c b |
| 17:30 | Cozey | (if symbol has the same position as class in it's list, it belongs to that class) |
| 17:35 | jweiss | is there some kind of gotcha in writing a closure like this? http://www.fpaste.org/Zz0y/ - the function it returns is behaving really oddly. seems to work fine when called from the repl directly, but when i call another function that calls it (with the same args), from the same namespace, it does nothing. |
| 17:36 | jweiss | it could be a lot of things, but I suspected closure issues |
| 17:37 | Chousuke | should work fine |
| 17:37 | Chousuke | are you sure there's no laziness involved? |
| 17:37 | Chousuke | or dynamic binding :P |
| 17:38 | Cozey | contains? for vectors? |
| 17:39 | Chousuke | sounds inefficient ;/ |
| 17:39 | Cozey | :-) should i use a map then? |
| 17:42 | brehaut | Cozey: contains? doesnt do what you expect for vectors - it only tells you if the index is contained in the vector |
| 17:43 | Cozey | yes but is there a function to check if vector contains a value? |
| 17:43 | Cozey | or should I do this with some |
| 17:43 | brehaut | i dont think there is |
| 17:43 | brehaut | you could do it with some |
| 17:43 | brehaut | its linear search though |
| 17:43 | Cozey | yes |
| 17:44 | brehaut | im sure chouser has a finger trees solution for you ;) |
| 17:47 | TimMc | Looks like I can't :use namespace A in both B and C and then :use B in C. |
| 17:47 | TimMc | Can someone confirm/deny? |
| 17:47 | brehaut | as long as its not circular i think you should be fine |
| 17:48 | amalloy | TimMc: yeah, that should work |
| 17:49 | amalloy | B won't re-export A's symbols, which would be a problem |
| 17:51 | TimMc | Hah, I forgot to delete what I moved to A from their original home in C. >_< |
| 17:51 | TimMc | Hitting save would help. |
| 17:53 | amalloy | Cozey: if you want to keep an ordered list but also know what's in it at any given time, you can maintain in parallel a hashset of its values |
| 18:00 | Cozey | i think this is what i'll do |
| 18:28 | pdk | hm |
| 18:28 | pdk | would there be anything special to worry about for writing a multimethod with multiple arities |
| 18:30 | amalloy | pdk: no. your dispatch function just needs to handle all the same arities |
| 18:31 | pdk | hm |
| 18:31 | pdk | in this case arity won't affect the dispatch values |
| 18:31 | pdk | so if i were to write the multimethod to take [x & y] |
| 18:31 | pdk | and one of the methods to take ([x] [x y]) i'm hoping it'd still interpret it right |
| 18:32 | amalloy | indeed, or [[x]] |
| 18:32 | amalloy | (instead of [x & y]) |
| 18:32 | pdk | in this case it'll be 1/2 args |
| 18:33 | pdk | actually would there a quick way to inline default values for optional args with the destructuring syntax |
| 18:33 | pdk | or do i just stick (or optional-arg default-value) all over the place |
| 18:39 | amalloy | pdk: it's easy for args that are passed in a map. i don't know how to do it otherwise |
| 18:39 | amalloy | &(let [{a :value b key :or {a 10}} {:key "hello"}] [a b]) |
| 18:39 | sexpbot | ⟹ [10 nil] |
| 18:40 | amalloy | &(let [{a :value b :key :or {a 10}} {:key "hello"}] [a b]) |
| 18:40 | sexpbot | ⟹ [10 "hello"] |
| 18:40 | pdk | it'd be nice if there was a guide that explained destructuring specifically in the context of fn argument lists |
| 18:40 | amalloy | pdk: there's no need to |
| 18:40 | pdk | since i'm doubting everything given with destructuring for let bindings still applies with an arg list but |
| 18:40 | amalloy | it does |
| 18:41 | pdk | \o/ |
| 18:41 | amalloy | ((fn [a & b] 10) => (let [[a & b] [10]]) |
| 18:41 | amalloy | ie, just wrap the formal and actual parameters in a vector, and you're done |
| 18:42 | amalloy | first example should read ((fn [a & b]) 10) |
| 18:45 | TimMc | Do :import and :use etc. have the same parameter structure (modulo quoting) that import and use do? |
| 18:46 | amalloy | TimMc: yes |
| 18:46 | pdk | i've never seen a case where they had to be different |
| 18:46 | pdk | aside from perhaps not needing ' |
| 18:46 | TimMc | OK. |
| 18:46 | amalloy | and you don't need to quote either import or :import, btw |
| 18:46 | TimMc | really? |
| 18:47 | amalloy | &(import java.util.ArrayList) |
| 18:47 | TimMc | Where can I find an explanation of the complete syntax available in import, require, etc? |
| 18:47 | sexpbot | ⟹ java.util.ArrayList |
| 18:47 | pdk | it used to be you needed to quote them in early versions |
| 18:47 | pdk | they're changed to be macros now so you don't anymore |
| 18:47 | TimMc | I see a bunch of examples, but no complete grammar. |
| 18:47 | amalloy | pdk: no |
| 18:47 | amalloy | &(meta #'import) |
| 18:47 | sexpbot | ⟹ {:macro true, :ns #<Namespace clojure.core>, :name import, :file "clojure/core.clj", :line 2617, :arglists ([& import-symbols-or-lists]), :added "1.0", :doc "import-list => (package-symbol class-name-symbols*)\n\n For each name in class-name-symbols, adds a mapping ... http://gist.github.com/832984 |
| 18:47 | amalloy | oh. hm, maybe so, sorry |
| 18:47 | pdk | neener neener |
| 18:48 | amalloy | *hang head in shame* |
| 18:48 | amalloy | &(meta #'use) |
| 18:48 | sexpbot | ⟹ {:ns #<Namespace clojure.core>, :name use, :file "clojure/core.clj", :line 4871, :arglists ([& args]), :added "1.0", :doc "Like 'require, but also refers to each lib's namespace using\n clojure.core/refer. Use :use in the ns macro in preference to calling\n this di... http://gist.github.com/832985 |
| 18:49 | amalloy | i don't get why it would be a macro though. i mean, you can use the classnames without quoting; is it just so that you get a symbol instead of a class object? |
| 18:49 | amalloy | &java.util.regex.Pattern |
| 18:49 | sexpbot | ⟹ java.util.regex.Pattern |
| 19:17 | cdddr | This is probably silly, but is there a magical way of getting a list of common elements on two *sorted* sequences, or am I safe in writing that alone? :) |
| 19:21 | TimMc | Ha, someone (in meatspace) was just talking about being asked that as an interview question. |
| 19:21 | TimMc | (given two unsorted sequences, find the common elements -- the answer involved what you're doing) |
| 19:22 | cdddr | This *is* trivial in any Lisp for sorted seqs, I'm just wondering if there's a neat way I didn't think of. :) |
| 19:23 | Despite | I love catonmat.net's set operations in the unix shell page. intersection is 'comm -12 <(sort set1) <(sort set2) ' |
| 19:24 | Despite | I never realized how often I needed set ops until I read that page |
| 19:24 | TheBusby | cdddr: 10 different ways jump to mind. Are you looking for the fastest, shortest, or most clojuresque way? |
| 19:25 | cdddr | TheBusby: The clojuresque way, seeing as I'm still learning and this isn't time-critical. |
| 19:26 | cdddr | Also - 10? Hah, I could only think of 3 off-hand. ;) |
| 19:26 | TheBusby | are the elements unique in each set? |
| 19:27 | cdddr | Yup. |
| 19:27 | cdddr | Ahhh, I see. |
| 19:27 | TheBusby | "set" being the keyword ;) |
| 19:28 | cdddr | Yeah, I got too focused on the sorted part to notice. :> |
| 19:29 | TheBusby | it hides in 'clojure.set so I forget about it frequently as well |
| 19:41 | simard | what's better, (apply max (range 1 1000)) or (reduce max (range 1 1000)) ? |
| 19:42 | cdddr | I |
| 19:45 | cdddr | Max being explicitly defined with more, I'd go with the former. |
| 19:46 | simard | makes sense.. both take the same amount of time |
| 19:46 | simard | (though) |
| 19:46 | simard | is there a way to measure the memory required ? |
| 19:46 | simard | in the same way you measure (time...) |
| 19:47 | cdddr | Well, I'd guess max is defined in terms of a macro for more arguments - one that's basically equivalent to the reduce. |
| 19:47 | simard | so you'd save one step |
| 19:47 | cdddr | So they're likey to work just the same under the hood. |
| 19:47 | simard | the macro expansion |
| 19:48 | simard | (well, one macro expansion) |
| 19:48 | cdddr | I'm with Knuth on optimization - if it works, stop caring. ;) |
| 19:48 | simard | sure :) |
| 20:07 | Mec_ | ,(isa? #() clojure.lang.IFn) |
| 20:07 | clojurebot | false |
| 20:07 | technomancy | Mec_: you want instance? |
| 20:08 | Mec_ | ,(instance? #() clojure.lang.IFn) |
| 20:08 | clojurebot | java.lang.ClassCastException: sandbox$eval1323$fn__1324 cannot be cast to java.lang.Class |
| 20:08 | Mec_ | ah |
| 20:08 | brehaut | ,(ifn? #()) |
| 20:08 | clojurebot | true |
| 20:08 | technomancy | ,(instance? clojure.lang.IFn #()) ; yay consistency |
| 20:08 | clojurebot | true |
| 20:09 | Mec_ | ah thank you both |
| 20:09 | brehaut | Mec_ most of the standard types have predicates like that too |
| 20:10 | brehaut | ,[(fn? #()) (fn? {}) (ifn? {}) (map? {})] |
| 20:10 | clojurebot | [true false true true] |
| 20:12 | Mec_ | What's the difference between an Fn and an IFn? |
| 20:12 | brehaut | not all iFns are fns |
| 20:12 | brehaut | you can make anything act like afunction, but that doesnt make it a function |
| 20:13 | brehaut | ,(apropos "?") |
| 20:13 | clojurebot | java.lang.Exception: Unable to resolve symbol: apropos in this context |
| 20:13 | brehaut | ##(apropos "?") |
| 20:13 | sexpbot | java.lang.Exception: Unable to resolve symbol: apropos in this context |
| 20:14 | brehaut | ##(use '[clojure.repl :only [apropos]]) |
| 20:14 | sexpbot | ⟹ nil |
| 20:14 | brehaut | ##(apropos "?") |
| 20:14 | sexpbot | ⟹ (superset? subset? alert-time? impl-enabled? enabled? logged-in? has-privs? -?>> .?. seqable? -?> is-blacklisted? is-command? leftmost? auto? rightmost? connection? keyword? chunked-seq? instance? sequential? fn? nil? string? sorted? false? true? odd? symbol? thread-... http://gist.github.com/833071 |
| 20:14 | Mec_ | ##(doc -?>>) |
| 20:14 | sexpbot | java.lang.Exception: Unable to resolve var: -?>> in this context |
| 20:14 | brehaut | -?>> is in clojure.contrib.core |
| 20:15 | brehaut | its like ->> but if any of the forms return nil, the whole expression returns nil |
| 20:15 | Mec_ | thats what i thought |
| 20:15 | Mec_ | I use -> and ->> for everything so I don't have to read inside out, does that mean I'm doing it wrong? :D |
| 20:16 | brehaut | nope |
| 20:16 | brehaut | well, depends what you mean by everything ;) |
| 20:16 | brehaut | sometimes just using a let is clearer ;) |
| 20:16 | Mec_ | just by assigning each step a name? |
| 20:16 | brehaut | yeah |
| 20:17 | Mec_ | makes sense |
| 20:17 | brehaut | if each expression is complex its good, because then youve got cognitifve assistence for determing the what and why of each |
| 20:18 | brehaut | also if you are doing something like (-> mapmapmap :a :b :c) consider (get-in mapmapmap [:a :b :c]) |
| 20:21 | brehaut | Mec_ and of course, if you have something like (defn foo [a] (-> inc inc)) you could do (def foo (comp inc inc)) |
| 20:21 | amalloy | brehaut: meh. get-in doesn't strike me as much clearer really |
| 20:21 | Mec_ | I was just thinking about using comp more, but its still a bit backwards |
| 20:22 | brehaut | exactly why thrush should be in core :P |
| 20:23 | technomancy | you let one bird in and all the others are going to want in as well; soon we'll have kestrels, larks, even doves clamoring for admission. |
| 20:23 | technomancy | err--wait, we already have kestrel. |
| 20:24 | brehaut | hah |
| 20:24 | Mec_ | whats thrush |
| 20:24 | brehaut | ~comp backwards |
| 20:24 | clojurebot | the scala compiler | is | <reply> see: http://harrah.github.com/browse/samples/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala.html#65760 |
| 20:24 | brehaut | wow that isnt something i expected |
| 20:25 | brehaut | Mec_: http://www.angelfire.com/tx4/cus/combinator/birds.html |
| 20:25 | Mec_ | owe my eyes |
| 20:25 | brehaut | http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/ |
| 20:26 | TimMc | Given a unary function, how can I easily iterate (f (f (f (f x)))) a set number of times? |
| 20:26 | brehaut | 'owe my eyes' is using 'OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO' as shorthand for ">=" |
| 20:27 | amalloy | TimMc: try: ##(doc iterate) |
| 20:27 | sexpbot | ⟹ "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects" |
| 20:27 | TimMc | And then use nth? |
| 20:28 | amalloy | yeah |
| 20:28 | TimMc | Ha, OK. |
| 20:28 | amalloy | TimMc: or if you want, ##((apply comp (repeat 10 inc)) 2) |
| 20:28 | sexpbot | ⟹ 12 |
| 20:28 | TimMc | I saw iterate, but passed it by -- I need to get more into functional thinking patterns. |
| 20:29 | TimMc | THat's pretty cute. |
| 20:29 | amalloy | i stole it from technomancy, i think |
| 20:30 | TimMc | comp looks pretty useful. |
| 20:30 | Mec_ | my favorite use of iterate is ##(take 10 (map first (iterate (fn [[a b]] [b (+ a b)]) [1 2]))) |
| 20:30 | sexpbot | ⟹ (1 2 3 5 8 13 21 34 55 89) |
| 20:30 | technomancy | dinc! |
| 20:31 | amalloy | technomancy: yeah, as soon as i hit enter i regretted using 10 instead of 8 |
| 20:32 | technomancy | amalloy: well to be fair yours is 25% more effective than oinc. |
| 20:32 | amalloy | technomancy: moore's law |
| 20:32 | amalloy | it's been a few months |
| 20:33 | technomancy | astounding. |
| 20:37 | jnymo_ | hi |
| 20:38 | Mec_ | I don't really see the benefit of thrush, it's seems like threading but every form has to be a function |
| 20:38 | jnymo_ | I wonder if it'd be possible to do multi-threading with web-workers, for that cojure-js thing. |
| 20:46 | simard | clojurebot: partition |
| 20:46 | clojurebot | partition is probably not what you want; see partition-all. |
| 20:48 | technomancy | ~botsnack |
| 20:48 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 21:53 | simard` | in this example, is def'ining just4 a problem for memory ? (def just4 (repeat 4)) (take 99999 just4) |
| 21:54 | amalloy | yes |
| 21:54 | simard | yes it's a problem ? |
| 21:56 | amalloy | you asked a yes/no question and got a yes answer. what are you looking for by asking me again? |
| 21:57 | simard | just to make sure I didn't miss anything when I left the channel actually.. :P |
| 22:22 | TimMc | How is (repeat 4) memory-intensive? |
| 22:23 | brehaut | TimMc: you are holding onto the head ofthe seq |
| 22:23 | brehaut | (probably) |
| 22:23 | brehaut | eg (let [four (repeat 4)] (take 100000 four)) is memory intensive (take 1000000 four) is not |
| 22:24 | TimMc | (take 1000000 (repeat 4)) you mean? |
| 22:24 | brehaut | yeah i do mean |
| 22:25 | brehaut | make sense? |
| 22:25 | TimMc | I need to learn more about seqs. I thought they were just generators that didn't hold any stuff beyond what they were given. |
| 22:25 | brehaut | sort of |
| 22:25 | brehaut | they are (conceptually at least) immutable though |
| 22:26 | TimMc | Ah, but internally cache stuff? |
| 22:26 | brehaut | nah simplier |
| 22:26 | brehaut | unlike an iterator/generatoe next/rest doesnt modify the seq you have,it returns a new seq |
| 22:26 | brehaut | like a lazy linked list |
| 22:27 | TimMc | Oh! |
| 22:27 | TimMc | So you are preventing the GC from collecting the intermediate nodes? |
| 22:27 | brehaut | bingo |
| 22:27 | TimMc | sneaky |
| 22:28 | brehaut | its teh one gotcha from having really good seqs |
| 22:28 | brehaut | they allow a lot more expressiveness than the traditional iterator |
| 22:28 | TimMc | (rest some-seq) holds a pointer to some-seq, yes? |
| 22:29 | brehaut | no |
| 22:29 | brehaut | seqs are singly linked |
| 22:29 | brehaut | like a cons cell |
| 22:29 | TimMc | I don't understand the object graph then. |
| 22:29 | brehaut | (cons 1 (cons 2 (cons 3))) ; the tail of each cons knows nothing about the cell its contained in |
| 22:30 | TimMc | sure |
| 22:30 | brehaut | rest returns a new thing from a seq |
| 22:30 | brehaut | that new thing is the tail |
| 22:30 | TimMc | But a seq like (repeat ...) is not a concrete linked list. |
| 22:30 | brehaut | no |
| 22:30 | brehaut | its a conceptual one |
| 22:32 | brehaut | as you realise a lazy-seq it becomes concrete though |
| 22:34 | TimMc | OK, so (repeat x) is (lazy-seq (cons x (repeat x))) |
| 22:34 | TimMc | (reading the source) |
| 22:34 | brehaut | yup |
| 22:37 | TimMc | So wait... walking through that seq builds up a cons chain? |
| 22:37 | brehaut | yes |
| 22:37 | TimMc | I'm having a little trouble understanding the mechanics behind realization. |
| 22:37 | brehaut | ok heres the interface for a seq |
| 22:37 | brehaut | https://github.com/clojure/clojure/blob/1.2.x/src/jvm/clojure/lang/ISeq.java |
| 22:38 | brehaut | i have no idea what more does |
| 22:39 | TimMc | lazy-seq just looks like magic to me. |
| 22:39 | brehaut | i tried to make an example with reify but i failed |
| 22:39 | brehaut | it is |
| 22:39 | brehaut | ;) |
| 22:39 | brehaut | basicly it creates a 'thunk' |
| 22:39 | brehaut | a thunk is a promise to compute some value later |
| 22:40 | TimMc | yes |
| 22:40 | brehaut | that is then replaced with that value |
| 22:40 | brehaut | the mechanics of lazy-seq arent actually too important to grok what is going on |
| 22:41 | simard | hum nice job on clojars and leiningen.. it's really easy |
| 22:44 | TimMc | brehaut: Oh! clojure.lang.LazySeq uses internal mutation. |
| 22:45 | TimMc | I'm not confused anymore. |
| 22:45 | brehaut | yeah thats why its conceptually immutable |
| 22:45 | TimMc | ...but can still build up an object graph extending from the head. |
| 22:45 | brehaut | yeah you can do real tricky stuff with it |
| 22:46 | brehaut | in haskell they have a trick they call 'tying the knot' |
| 22:46 | brehaut | where you make the tail of one list its own head |
| 22:47 | TimMc | So... seqs are "immutable" but can still do things that look like mutation, which means you have to treat them like realized lists in some ways. |
| 22:47 | brehaut | dont think ofthem as tricky |
| 22:47 | brehaut | they _dont_ look like mutation |
| 22:47 | brehaut | thats the cool part |
| 22:47 | brehaut | the tail of lazy-seq may contain unrealized values |
| 22:48 | brehaut | as soon as its realized (ie observed for the first time) it has a value, and that value never changes |
| 22:49 | TimMc | So I should think of any seq as "an existing singly-linked list that may be lazily computed." |
| 22:49 | TimMc | THat covers the holding-onto-the-head problem. |
| 22:50 | brehaut | yeah i think thats ok |
| 22:56 | tomoj | I wonder if channels and seqs are dual |
| 22:57 | tomoj | similar to IObservable/IEnumerable but better? |
| 22:59 | brehaut | could be eh |
| 23:12 | simard | how do you guys start your inferior-lisp-process so that the classpath is set properly to that required by your current lein project ? |
| 23:14 | amalloy | cake swank |
| 23:14 | amalloy | or lein swank |
| 23:16 | semperos | or just set inferior-lisp-program to "lein repl", if you don't use slime |
| 23:37 | technomancy | there's also lein classpath |
| 23:37 | talios | and mvn clojure:swank |
| 23:47 | simard | hum running "lein swank" -> "That's not a task." |
| 23:47 | simard | swank-clojure is running though |
| 23:47 | technomancy | swank isn't used with inferior-lisp-process |
| 23:48 | technomancy | you can just do java -cp `lein classpath` clojure.main as your inf-lisp |
| 23:49 | pdk | (doc take) |
| 23:49 | clojurebot | "([n coll]); Returns a lazy sequence of the first n items in coll, or all items if there are fewer than n." |
| 23:49 | simard | oh these backticks will work directly in that var ? |
| 23:49 | simard | nice |
| 23:50 | technomancy | simard: err--actually no |
| 23:50 | simard | oh well I'm connected with slime-connect to swank-clojure right now |
| 23:52 | technomancy | oh sure, if you want to use slime you don't need to set inf-lisp-anything |
| 23:52 | pdk | (doc repeatedly) |
| 23:52 | clojurebot | "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it" |