2009-03-06
| 00:12 | Drakeson | what is elisp's mapconcat or python's join called in clojure? |
| 00:14 | hiredman | ,(doc mapcat) |
| 00:14 | clojurebot | "([f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection." |
| 00:14 | Drakeson | I want (join ", " ["a" "b" "c"]) -> "a, b, c" |
| 00:15 | Drakeson | ,(doc join) |
| 00:15 | clojurebot | java.lang.Exception: Unable to resolve var: join in this context |
| 00:15 | Drakeson | ,(doc string-join) |
| 00:15 | clojurebot | java.lang.Exception: Unable to resolve var: string-join in this context |
| 00:15 | arohner | there's a str-join in c.c.str-utils |
| 00:16 | Drakeson | arohner: oh, thanks. why is it in contrib? :( |
| 00:16 | arohner | ,(doc clojure.contrib.str-utils/str-join) |
| 00:16 | clojurebot | "([separator sequence]); Returns a string of all elements in 'sequence', separated by 'separator'. Like Perl's 'join'." |
| 00:17 | arohner | Drakeson: the simple but snarky answer is that it's there because it isn't in core |
| 00:17 | arohner | clojure is still young |
| 00:19 | Raynes | Is there a certain convention for writing functions like so (defn afunction ([] ..)) |
| 00:20 | Raynes | I tend to do it when the function contains documentation. |
| 00:20 | hiredman | that is for mult-arity functions |
| 00:21 | hiredman | ~def max |
| 00:21 | hiredman | like that |
| 00:21 | hiredman | unless your function multi-arity like that, please don't write your functions that way |
| 00:22 | Raynes | Thanks ^_^ |
| 00:23 | Drakeson | ,(filter 'identity [nil true]) |
| 00:23 | clojurebot | () |
| 00:23 | Drakeson | why?! |
| 00:24 | hiredman | ,(filter identity [nil true]) |
| 00:24 | clojurebot | (true) |
| 00:24 | hiredman | 'identity is a symbol |
| 00:25 | Drakeson | habits ... |
| 00:25 | hiredman | identity is also a symbol that is resolved to a var that points to a function |
| 00:25 | Drakeson | hiredman: I know :) |
| 00:26 | hiredman | symbols can be called like funtions for hash look ups and the like |
| 00:26 | hiredman | ,('identity {'identity 1}) |
| 00:26 | clojurebot | 1 |
| 00:28 | Drakeson | hiredman: thanks, My fingers tend to put a quote in those places to fill the common-lisp void! |
| 00:29 | replaca | Drakeson: I make the same mistake with identity all the time! |
| 00:40 | Raynes | Could someone show me an example using comp? |
| 00:44 | hiredman | ,(map (comp inc first) (replicate 3 (range 3))) |
| 00:44 | clojurebot | (1 1 1) |
| 00:44 | Raynes | Thanks. |
| 00:55 | mrk1 | In my slime repl, (read), (read-line) doesn't repond. is this normal? |
| 01:29 | durka42 | wait, so are streams back under consideration? |
| 01:31 | slashus2 | They look very interesting. |
| 01:32 | slashus2 | durka42: Why did they go out of consideration? |
| 01:32 | durka42 | i was under the impression rich had banged on them for a while, thought they were kind of ugly, and went for full laziness instead |
| 01:33 | slashus2 | Why not have both |
| 01:33 | slashus2 | ? |
| 01:33 | durka42 | well, right |
| 01:33 | durka42 | i guess they came back |
| 01:34 | slashus2 | Looking at the examples, I wonder if some of the core functions will be rewritten with streams? |
| 01:34 | slashus2 | I guess it just shows that they can be. |
| 01:35 | lisppaste8 | Rayne@acidrayne.net pasted "key value text reader" at http://paste.lisp.org/display/76568 |
| 01:35 | hiredman | well, streams and seqs are a different abstraction |
| 01:35 | Raynes | Damn that bots fast. |
| 01:35 | Raynes | It printed that before I even hit enter O_O |
| 01:35 | slashus2 | I guess causality didn't apply? |
| 01:36 | durka42 | it seems really fast because it posts to the channel before serving you the page |
| 01:37 | Raynes | durka42: Yeah, I noticed. O.O |
| 01:38 | durka42 | Raynes: does what you posted work? |
| 01:38 | Raynes | Yes. |
| 01:38 | Raynes | Surprisingly. |
| 01:39 | durka42 | (well, on windows) |
| 01:39 | Raynes | Windows specific at the moment yes. |
| 01:40 | durka42 | oh -- your config lines are specified as "foo = bar" not "foo=bar" |
| 01:41 | Raynes | Yup. |
| 01:41 | Raynes | "foo=bar" was too easy. |
| 01:42 | durka42 | heh |
| 01:43 | durka42 | hmm monads for clojure programmers http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/ |
| 01:43 | durka42 | maybe i'll understand this one |
| 01:43 | Raynes | Oh cool. |
| 01:43 | hiredman | hot |
| 01:43 | hiredman | onclojure, someone has set their sites high |
| 01:43 | Raynes | I need to go to sleep, but I want to read this. |
| 01:43 | Raynes | :| |
| 01:44 | Raynes | Meh, it will only take a minute. |
| 01:49 | Raynes | I only read half of it, too sleepy to comprehend it. Me go sleepy. |
| 01:49 | Raynes | Also durka42: Thanks for not insulting my shitty code :) I know you were thinking it. |
| 02:20 | dcnstrct | is there a way to check your classpath from the REPL ? |
| 02:22 | ayrnieu | ,(System/getProperty "java.class.path") |
| 02:22 | clojurebot | java.security.AccessControlException: access denied (java.util.PropertyPermission java.class.path read) |
| 02:22 | dcnstrct | thnx |
| 03:22 | xristos | i'm trying to setup swank-clojure but nothing seems work here |
| 03:22 | xristos | can anyone post his .el |
| 03:54 | AWizzArd | clojurebot: max people |
| 03:54 | clojurebot | max people is 156 |
| 03:54 | AWizzArd | aha, new record :) |
| 03:57 | hiredman | I was begining to think it wasn't working correctly |
| 04:09 | AWizzArd | seems to work |
| 04:15 | AWizzArd | Moin kotarak |
| 04:15 | kotarak | moin moin |
| 04:16 | AWizzArd | Alles Roger oder was? ;) |
| 04:52 | leafw | I just translated the nice make-a-derivative-fn-from-a-fn example, see http://pacific.mpi-cbg.de/wiki/index.php/Clojure_Scripting#Creating_a_derivative_of_a_function |
| 04:57 | AWizzArd | gut |
| 05:59 | aseeon | Could you recommend be a good editor/ide to write Clojure code in (i am not the vim kind of guy)? |
| 06:01 | kotarak | aseeon: geez. As maintainer of the vim mode, I would have recommended that... ;) There is a mode for emacs, enclojure for netbeans, clojure-dev for eclipse, waterfront (written in Clojure), a plugin for intelliJ ... pick one. :) |
| 06:01 | hoeck | aseeon: emacs :) (sorry, I'm an emacs guy) |
| 06:10 | AWizzArd | aseeon: you can try Enclojure: http://enclojure.org/ |
| 06:10 | AWizzArd | if you are used to modern looking IDEs then this would probably your best bet. |
| 06:10 | aseeon | AWizzArd: looks very promising |
| 06:10 | AWizzArd | absolutely |
| 06:11 | aseeon | yeah i am, Komodo Edit, Netbeans and Eclipse are my tools of the trade :D |
| 06:11 | AWizzArd | then you pretty much will need Enclojure, as this is a plugin for NetBeans. |
| 06:12 | AWizzArd | I myself still use mostly Emacs, because I have a long Lisp background. But I closely look at Enclojure every time it gets updated. Soon it will be there where Emacs is. |
| 06:13 | aseeon | thanks kotarak and AWizzArd for telling me about enclojure, i will give it a spin :) |
| 06:13 | aseeon | and hopefully will be back here ^_^ |
| 07:23 | Hooke | hello |
| 07:24 | AWizzArd | Hi Hooke |
| 07:25 | Hooke | hello, AWizzArd, how are you |
| 07:26 | AWizzArd | fine thx, hope you too |
| 08:38 | jayfields | (doc compare) |
| 08:38 | clojurebot | Comparator. Returns 0 if x equals y, -1 if x is logically 'less than' y, else 1. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable; arglists ([x y]) |
| 09:42 | candera | I'm sure this is a FAQ, but I've been unable to find the answer so far: I'm getting a ClassNotFoundException when trying to compile a lib. It's choking on :extends [javax.swing.JApplet] in my namespace's :genclass clause. |
| 09:43 | shoover | candera: try it without the []? |
| 09:44 | cemerick | candera: yeah, classes can have only one superclass -- can implement multiple interfaces, tho |
| 09:45 | candera | Yep, that worked. Thanks! |
| 09:45 | candera | On to the next problem! :) |
| 09:55 | cgray | hi, I'm having trouble with require... I would like to name my files like foo-bar.clj , but when I do (require 'foo-bar) I get an error that there is no foo_bar.clj |
| 09:56 | Chouser | cgray: I would like to name my files like foo-bar.clj as well, but alas it doesn't work. You need to use foo_bar.clj |
| 09:56 | cgray | is there a good reason for that? |
| 09:56 | Chouser | well, it's a relatively good reason. :-) |
| 09:57 | Chouser | 'require' and 'use' deal in namespaces |
| 09:57 | Cark | i've been bitten by that too |
| 09:57 | cemerick | hrm, where oh where did cond-let go? |
| 09:58 | Cark | common lisp was more forgiving in that respect ! |
| 09:58 | leafw | why do I never get cond right? Somehow, it is not intuitive to me how to lay down the expressions. |
| 09:58 | Chouser | namespace names map to java class names |
| 09:59 | Cark | and the file names must be the same as file names ? |
| 09:59 | Chouser | java doesn't allow - in identifiers because it would mean subtraction in their infix notation. |
| 09:59 | Cark | err class names |
| 09:59 | Chouser | therefore the jvm doesn't allow - either (though this could theoretically change) |
| 09:59 | cgray | Chouser: okay, thanks I see now |
| 09:59 | Cark | in java is it forbidden to have a file name different from the class name it contains ? |
| 10:00 | Cark | i thought this was introduced with aot compilation |
| 10:00 | Chouser | Cark: java uses the filename to find the definition of a given package/class, so it needs to match. |
| 10:00 | cemerick | ah-ha, tricky -- my favorite documentation browser helpfully includes contrib stuff, but I didn't notice the contrib annotation on cond-let |
| 10:00 | Cark | ok i see |
| 10:01 | Chouser | basically it comes down to simply having one rule that - in a clojure name maps to _ in a java name or file is a simple rule that avoids a lot possibly more complicated rules and issues. |
| 10:02 | Chouser | cemerick: ah, I didn't know there was a cond-let anywhere. nice. |
| 10:02 | cemerick | Chouser: Unfortunately, it doesn't seem to work. |
| 10:02 | Chouser | leafw: surely cond is easier to get right than condp, though! |
| 10:02 | leafw | Chouser: the docs are so incomplete on cond. |
| 10:03 | leafw | also, no indication of the "default". What is it, :else ? |
| 10:03 | Chouser | leafw: any true expression will do. :else is the common idiom. |
| 10:03 | leafw | ok. Thanks Chouser |
| 10:05 | Chouser | I thought the trailing ~ was cute |
| 10:05 | Chouser | minor adjustment to the reader, I think... |
| 10:06 | rhickey | major overloading of ~ though |
| 10:07 | Chouser | no more major than, for example, # |
| 10:08 | Holcxjo | ,(find-doc "cond") |
| 10:08 | clojurebot | java.lang.NoClassDefFoundError: clojure/lang/IteratorSeq$State |
| 10:08 | Holcxjo | Is that meant to be the result? |
| 10:08 | Holcxjo | Sandboxing issue? |
| 10:09 | Cark | rhikey : i liked the prepended s in your examples ... looks like 'S'tream and also like a verb |
| 10:09 | rhickey | Chouser: not sure about that, we don't put # on front and back of names |
| 10:09 | Chouser | #'foo means something completely different than foo# |
| 10:09 | Chouser | completely unrelated, even. |
| 10:09 | Cark | meaning : this stream maps the sequence with that function |
| 10:10 | rhickey | what about =map=, =filter=, e.g. the pipe metaphor? |
| 10:10 | Chouser | cemerick: cond-let seems to work for me. What kind of failure are you seeing? |
| 10:10 | rhickey | Cark: that was the intent there, just not sure it will work well for fnctions that normally end in s |
| 10:10 | Cark | just follow the english grammar |
| 10:10 | Cark | what function do you think of ? |
| 10:11 | Chouser | reductionss |
| 10:11 | thickey | there's already pmap, would smap be following that 'convention'? (though, i wish both cases would just use the full word, but i know most would hate that) |
| 10:11 | Cark | abusing special character seems ugly |
| 10:11 | cemerick | Chouser: huh. (cond-let [a 5] (pos? a) (+ a 9) :else 3) => java.lang.Exception: Unable to resolve symbol: a in this context |
| 10:12 | Chouser | cemerick: yeah, is bound to the result of (pos? a) |
| 10:12 | rhickey | another possibility is map-1, filter-1, for the once-only nature of their use |
| 10:12 | Chouser | cemerick: so it's not bound to anything when (pos? a) itself is evaluated. |
| 10:13 | Cark | rhickey : painfull on a belgian keyboard ! |
| 10:13 | leafw | Cark: programming on anything than querty english is painful. |
| 10:13 | rhickey | Cark: how so? |
| 10:13 | Cark | leafw : true |
| 10:14 | gnuvince | french canadian is not bad imo |
| 10:14 | Cark | well the - is already bad, but we have to in lisp (it's right beside backspace), then 1 is using the shift key |
| 10:14 | Chouser | =map= isn't too bad. It feels a bit heavy by itself, but doesn't look to bad with parens around it. |
| 10:14 | Cark | how about map> ? |
| 10:14 | Chouser | would =map, =filter, etc. be acceptible, or is that too much like equality? |
| 10:15 | Chouser | too bad |
| 10:15 | rhickey | <=map, <=filter ? |
| 10:15 | Cark | why does it have to go left ? |
| 10:15 | gnuvince | (|map f xs)? |
| 10:16 | Cark | |map looks like some reader macro |
| 10:17 | rhickey | <-map, <-filter |
| 10:17 | cemerick | Chouser: the docs evade me, but I found an example that Stephen posted on the group. What it does is very surprising to me -- I was very much expecting just a mash of let and cond |
| 10:17 | rhickey | <<map <<filter |
| 10:17 | Chouser | cemerick: you wanted a single extra let around the outside? |
| 10:18 | Cark | any of those would be nice rhikey |
| 10:18 | cemerick | Chouser: yeah. I figured it would produce (let [a 5] (cond (pos? a) ....)) |
| 10:18 | Cark | << being the easiest |
| 10:18 | gnuvince | Has anyone considered putting them in a different namespace and just using stream/map, stream/filter? |
| 10:19 | rhickey | gnuvince: where will you put your stream functions? |
| 10:19 | Holcxjo | Or make it hard for everybody and use non-ASCII �map |
| 10:19 | cemerick | I guess I just turned into one of those people that never read anything :-P |
| 10:19 | Cark | hoclxjo : haha |
| 10:19 | gnuvince | rhickey: ? |
| 10:20 | Chouser | cemerick: well, the behavior it has is the one I have wanted, where I've got a couple different complex test expressions, and have to repeat them inside the return exprs. |
| 10:20 | rhickey | gnuvince: using a namespace only solves the problems for core |
| 10:21 | Chouser | separate namespace doesn't help. then any code that does it a lot ends up using s/filter s/map etc. :-( |
| 10:21 | gnuvince | Chouser: that's better IMO than an arbitrarily selected symbol that means "stream" |
| 10:22 | cemerick | Chouser: yeah, I can definitely see that being useful. When I see 'let', I think of a vector of pairs, though. |
| 10:22 | rhickey | gnuvince: but you can't put your streams functions in the stream namespace, so everyone will have to pick a different prefix namespace |
| 10:22 | thickey | i'm with gnuvince, all these quirky charachters before/after things doesn't mean anything |
| 10:22 | Chouser | cemerick: hm. I think that may be part of why it's not in core. |
| 10:23 | rhickey | gnuvince: a naming convention lets you put both stream and seq versions in same namespace, and everyone will know what to pre/append to get the stream version |
| 10:23 | cemerick | I'll third gnuvince, thickey on this. |
| 10:24 | rhickey | thickey: yeah, they never inherently mean anything, but this is one case where frequently you'll have (map ... (filter ...) and want to make it faster by just adding a character to each call |
| 10:24 | cemerick | why not s-map, s-filter, etc? I just cringe at seeing more line noise (in the aggregate). |
| 10:24 | cemerick | or smap, sfilter as suggested before |
| 10:24 | Chouser | I think <<map is my favorite so far (if map~ is off the table) |
| 10:24 | gnuvince | rhickey: I am thinking of something like Data.ByteStream in Haskell where it is a convention for users of the module to qualify import it (import qualify Data.ByteString as B) because it shares many names with Data.List, Data.Set, Data.Map, etc. |
| 10:24 | rhickey | Chouser: nothings off the table at this point except non-ascii |
| 10:24 | thickey | rhickey: makes sense |
| 10:26 | danlarkin | I'm with gnuvince, I think a separate namespace makes sense |
| 10:26 | rhickey | gnuvince: I don't think you are getting my point about there being many user namespaces with seq and stream versions of a function, you can't have a namespace-based naming convention |
| 10:26 | thickey | then i'm back to smap, sfilter... at least it in line with the decision to make the parallel functions named the way they are |
| 10:27 | rhickey | danlarkin: forcing all namespaces that have stream version to have a sub-namespace with a naming convention? ouch |
| 10:27 | Chouser | I like appending a modifier over prepending, because the algorithmic meaning of the stream ops is the same, it's just the data types involved that are different. |
| 10:27 | rhickey | Chouser: not exactly, due to the once-only use aspect |
| 10:27 | gnuvince | rhickey: that's the thing, why does there need to be a convention? You want to use regular seqs? Use the core functions. You want streams? Require stream (possibly aliasing it to a shorter name for your own convenience) and use that. |
| 10:28 | Chouser | rhickey is talking about user-created functions. |
| 10:28 | Chouser | I think. |
| 10:29 | rhickey | gnuvince: so core has core and core.stream, and you have gnuvince and gnuvince.stream, and a user that wants to use both/all uses what aliases? |
| 10:29 | Chouser | If I write a fancy text-partitioning seq generators called clojure.contrib.regex.re-split, would my stream version have to have another whole namespace? |
| 10:30 | Chouser | clojure.contrib.regex.stream.re-split? |
| 10:30 | rhickey | map$, filter$ |
| 10:30 | Cark | smap ... the smapy version of a regular map |
| 10:31 | cemerick | rhickey: indeed ;-) |
| 10:31 | Chouser | hm, is there some history to $ that I don't know. |
| 10:31 | rhickey | map*, filter* |
| 10:31 | Chouser | cemerick: nice. |
| 10:31 | rhickey | map1 filter1 |
| 10:32 | Cark | i'll vote for the easy smap, sfilter, sreduce |
| 10:32 | rhickey | map-once, filter-once |
| 10:32 | cemerick | is there really a compelling reason to not use smap, etc? |
| 10:32 | rhickey | map-s filter-s |
| 10:32 | Chouser | I don't like the 1 |
| 10:32 | gnuvince | rhickey: I guess I just don't see the problem with having the user explicitly require what he needs. |
| 10:32 | cemerick | using the p-prefix for parallel fns was a much bigger change, IMO |
| 10:32 | gnuvince | In any case, just my opinion, you're the dictator :) |
| 10:33 | cemerick | or, the parallelism of those fns represented a much bigger change in behaviour from the standard fns, I mean |
| 10:33 | rhickey | gnuvince: just answer the question, if I want to use the seq and stream version of clojure's map and the seq and stream version of gnuvince's foo, what will that look like? |
| 10:33 | rhickey | 4 namespaces and 2 aliases? |
| 10:34 | danlarkin | I realize why there are, but I kinda wish there didn't have to be different versions |
| 10:34 | gnuvince | (ns (:require [clojure.stream :as s] [gnuvince :as g] [gnuvince.stream :as gs]) (map f xs) (s/map f xs) (g/map f xs) (gs/map f xs)) |
| 10:34 | thickey | wouldn't "the stream version of gnuvince's foo" just have some other name that gnuvince gave it? |
| 10:35 | cemerick | danlarkin: +1. I know I'm eventually going to have to write something like spmapcat or something. :-( |
| 10:36 | cemerick | at some point, it would be nice to "decorate" the core fns with various characteristics (uses streams, uses parallel goodness, etc) (not that I have any concrete proposals about how to do that "decoration") |
| 10:36 | AWizzArd | could be as easy as providing an argument |
| 10:36 | AWizzArd | (map :stream #(+ 4 %) coll) |
| 10:36 | rhickey | gnuvince: ok, looks tedious, also, as a reader I have no idea what the implications of gs/ and s/ are to the evaluation - they could just as easily be fred/ and ethel/, even in two parts of the same program. The behavioral difference is critical to call out here in a consistent way - you don't want to be aliasing these things |
| 10:36 | cemerick | (map +sp #() coll) |
| 10:36 | Chouser | cemerick: metadata! (#^{:use-stream true, :use-parallel true} mapcat func coll) |
| 10:37 | cemerick | Chouser: you just pegged my verbosity meter! :-P |
| 10:37 | Chouser | AWizzArd: that already means something else |
| 10:37 | Chouser | cemerick: :-) |
| 10:37 | AWizzArd | yes, plus I don't like that idea. |
| 10:37 | rhickey | using args means a lot of partial-ing for HOF use |
| 10:38 | AWizzArd | something like smap, sfilter would be ok I guess |
| 10:38 | RadioApeShot | Hi #clojure - I am looking for a way to launch a clojure function in a separate thread from the REPL. For instance, if I wanted a rendering loop to be running in the background but still have access to the REPL to add, remove, or change things about it via dosync blocks. |
| 10:38 | Cark | forth style : (streaming (map #(+ 4 %) coll)) |
| 10:38 | cemerick | yeah, maybe some more concise metadata representation could be fielded for stuff like this (analogous to #^Classname) |
| 10:38 | rhickey | It is critical to note that while there is an algorithmic similarity, streams have very circumscribed usage compared to persistent seqs, they are one-pass and ephemeral |
| 10:39 | RadioApeShot | I already tried creating a fn and then calling its run method via (. f run) |
| 10:39 | rhickey | I am partial to Chouser's argument for appending, especially as then the two versions will sort together |
| 10:40 | cemerick | rhickey: Definitely. However, if just one more 'axis' of functionality is introduced, then the various combinations of streams, parallelism, and XX will become very difficult to keep straight. |
| 10:40 | Chouser | RadioApeShot: (.run (Thread. #(prn "hi!"))) |
| 10:40 | rhickey | cemerick: you want less functionality? :) |
| 10:40 | RadioApeShot | Chouser: Thanks. |
| 10:40 | Chouser | RadioApeShot: or look into agents or futures, depending on how you intend to use the thread. |
| 10:40 | cemerick | rhickey: surely, no. But I do want a way to compose various features around a core operation (map, filter, etc) |
| 10:41 | rhickey | cemerick: in the ends these aren't 'properties' of the same function - they're different functions with different albeit similar semantics |
| 10:41 | cemerick | ...without having an explosion of variants of those core operations (spmapcat, etc) |
| 10:41 | rhickey | cemerick: that's a theoretical argument |
| 10:41 | Cark | would it make sense to have a parallel stream function anyways ? |
| 10:42 | AWizzArd | I thought streams are serial? |
| 10:42 | gnuvince | rhickey: is there a reason not to have both? Put them in a different namespace and dictate a naming convention to make their behavior explicit to the reader? There are already over 450 symbols in the core namespace; if set operations were put in a different namespace, why not streams? |
| 10:42 | Chouser | = has parallel lines, thus clearly means parallel multithreaded operation. ~ looks like a little river, so clearly means stream. thus mapcat=~ |
| 10:42 | cemerick | lol |
| 10:43 | RadioApeShot | (.run (Thread. f)) still causes my REPL to hang while the thread does its work |
| 10:43 | gnuvince | Chouser: I proposed ~ yesterday, but the reader doesn't like that :-/ |
| 10:43 | cemerick | Chouser was egyptian in a previous life |
| 10:43 | Cark | haha |
| 10:43 | rhickey | = looks like a pipe and ~ a tail, so streaming and lazy :) |
| 10:43 | Chouser | gnuvince: the reader can be fixed. |
| 10:43 | Chouser | rhickey: :-P |
| 10:44 | cemerick | ~ really can't be in the running. One would get dizzy while writing macros. |
| 10:44 | clojurebot | Holy Crap. |
| 10:44 | AWizzArd | What are the contras for a prefix letter, such as "s"? |
| 10:44 | Chouser | gnuvince: but yes, I know you thought of it. It's not my idea, I'm simply defending it. :-) |
| 10:44 | rhickey | cemerick: I agree |
| 10:44 | danlarkin | AWizzArd: doesn't sort together |
| 10:44 | Chouser | AWizzArd: reductionss |
| 10:44 | Chouser | oh, prefix, sorry. |
| 10:44 | cemerick | danlarkin: bah, the p* fns don't sort with their single-threaded counterparts |
| 10:45 | Cark | i don't buy the sorting argument, docs are searchable by other means |
| 10:45 | rhickey | cemerick: where are these many p* fns? |
| 10:45 | Chouser | nah, we already can have `(let [foo# #'foo, bar# ~#{#'baz #'qux}] ...) in a macro |
| 10:46 | rhickey | Chouser: but not ~foo~ |
| 10:46 | Chouser | ooh, pretty! |
| 10:47 | rhickey | that's foo swimming in a sea of confusion |
| 10:47 | Cark | looks like foo is about to drown ... more like a pond than a stream |
| 10:47 | Chouser | heh. ok, fine. |
| 10:48 | gnuvince | rhickey: any thoughts on the namespace+naming convention idea or is it just bad? |
| 10:48 | rhickey | map<<, filter<< |
| 10:48 | Chouser | mapS map$ map= |
| 10:48 | Chouser | was the map$ suggesting entirely a joke? |
| 10:49 | rhickey | gnuvince: I didn't see the naming convention in there |
| 10:49 | gnuvince | [10:43:56] < gnuvince> rhickey: is there a reason not to have both? Put them in a different namespace and dictate a naming convention to make their behavior explicit to the reader? There are already over 450 symbols in the core namespace; if set operations were put in a different namespace, why not streams? |
| 10:49 | rhickey | Chouser: no, but $ is totally unused and could thus be used for something really special down the line |
| 10:49 | AWizzArd | I don't like too many conventions. More than enough people will not stick to it. |
| 10:49 | cemerick | rhickey, danlarkin: sorry, my bad. There's pmap of course, but we have a pfilter here, too. I thought the latter was in core. :-( |
| 10:49 | rhickey | gnuvince: what's the naming convention then? |
| 10:50 | gnuvince | rhickey: well that's to be decided, but would you opposed to putting "conventially-named" functions for streams in a separate namespace? |
| 10:51 | Chouser | map<< is my new favorite |
| 10:51 | rhickey | gnuvince: yes, because all the seq functions will likely be defined in terms of the stream ones, creating a lot of organizational hassle for people |
| 10:51 | gnuvince | ah |
| 10:51 | gnuvince | Didn't know that. |
| 10:52 | rhickey | gnuvince: there might even be a single macro that defines both a stream and seq version in one shot |
| 10:52 | Cark | if smap is rejected i'd go for map<< too |
| 10:52 | gnuvince | So the seq functions are going to lose their nice functional, recursive definition in favor of something more iterative? |
| 10:52 | jayfields | (doc var) |
| 10:52 | clojurebot | No entiendo |
| 10:52 | cemerick | rhickey: looking at clojure.org/streams, your original thought of map*, etc. looks really good. |
| 10:53 | rhickey | (def map #(sequence (map-stream %1 %2))) |
| 10:53 | Chouser | jayfields: var is a special form: http://clojure.org/special_forms#var |
| 10:54 | jayfields | Chouser: thanks. |
| 10:54 | rhickey | map*, map+, map= or map<< ? |
| 10:54 | rhickey | map1 map-1 maps |
| 10:54 | Chouser | map* says nothing, and the * suffix is occasionally used elsewhere |
| 10:54 | gnuvince | Any reason for <<? |
| 10:55 | rhickey | gnuvince: implies piping |
| 10:55 | cemerick | huh, map+ is nice |
| 10:55 | Chouser | map= looks too much like it's related to equality, I'm afraid. |
| 10:55 | gnuvince | rhickey: piping the elements into f? |
| 10:55 | cemerick | isn't +name+ used as some kind of convention in CL? |
| 10:55 | cemerick | (not that that would be a reason to not use map+, etc) |
| 10:55 | rhickey | gnuvince: just being part of a pipeline, that really is the analogy, there is also tap now |
| 10:56 | Chouser | the 1 suffixs I dislike because they might imply taking only the first rather than taking each thing only once. |
| 10:57 | gnuvince | Has any other Lisp (or another language like Forth or Factor) implemented something like this and decided on a convention? |
| 10:57 | Chouser | so of those, I think map+ and map<< rise to the top. |
| 10:57 | rhickey | Chouser: you might read it 'once', works like macroexpand-1 |
| 10:57 | rhickey | people coming from other langs might not see foo<< as one symbol |
| 10:58 | Cark | you don't have to put a warning in the name of your function, that's what docs are for |
| 10:59 | tashafa | how do i make a thread sleep in clojure |
| 10:59 | tashafa | ? |
| 10:59 | cemerick | map+ and map* are my preferences, FWIW |
| 10:59 | tashafa | (java.lang.Thread/sleep n) doesnt seem to work for me |
| 10:59 | thickey | my brain seems to like map* because verbalizing "map-star" at least shares some commonality with "map-stream" so the "oh right, that's the stream version" moment of realization is there |
| 11:00 | Chouser | I wouldn't worry too much about foo<< looking like two symbols. At that level of understanding, they might see it as a separate modifier or something, but you pretty quickly get used to looking for spaces to break up symbols. |
| 11:00 | thickey | not loving map<< |
| 11:00 | rhickey | map<-s, filter<-s |
| 11:00 | rhickey | map-s, filter-s |
| 11:00 | cemerick | tashafa: that's the right function.... |
| 11:01 | rhickey | map*s, filter*s |
| 11:01 | Cark | chouser : yes at that rate someone looking at read-file would think we're doing a substraction |
| 11:01 | cemerick | (* "ugh" 6) |
| 11:02 | Chouser | tashafa: that takes milliseconds, so (Thread/sleep 1000) should be noticable. |
| 11:02 | tashafa | cemrick: hmm, it doesnt throw any errors, but would using it in a doseq change teh behaviour? |
| 11:03 | Chouser | thickey: any particular reason? |
| 11:04 | leafw | rhickey: map<-s or map-s read best to me; map*s does't convey the meaning to my eyes (looks to much like global var, or like the product of something) |
| 11:04 | cemerick | tashafa: like any side-effecting method, if you call Thread/sleep in a lazy context, then you're likely not going to get what you want |
| 11:04 | thickey | Chouser: they share a lot of letters |
| 11:04 | RadioApeShot | So (.run (Thread. th)) - am I wrong in thinking this should run th (a clojure function which loops forever and sometimes sets a value inside a ref) in a new thread and immediately return to the REPL? When I call this my REPL freezes just as if I had called (th) |
| 11:04 | thickey | Chouser: oh, did you mean for not liking << ? |
| 11:05 | Chouser | thickey: yes |
| 11:05 | cemerick | RadioApeShot: you want .start, not .run |
| 11:05 | tashafa | ok my bad...it does work |
| 11:05 | Chouser | ah! my fault, sorry. |
| 11:06 | RadioApeShot | cemerick: Thanks. |
| 11:06 | tashafa | thanks all |
| 11:06 | RadioApeShot | My java is rusty |
| 11:06 | thickey | Chouser: just don't like the way it looks. and i'm in preference of the "s" variants myself, and thought that at least * had some way i could connect the two, as opposed to << which just leaves me wondering |
| 11:06 | leafw | thickey: << is a c++ thinguie, really. |
| 11:07 | leafw | which has meaning around the concept of streams. |
| 11:07 | Cark | great let's plunder c++ ...was good for java, might be good for clojure as well =P |
| 11:07 | cemerick | << is a bit shift to me *shrug* |
| 11:07 | Chouser | but not in clojure |
| 11:07 | leafw | cemerick: that too xD |
| 11:07 | rhickey | doesn't << imply piping to anyone? |
| 11:08 | leafw | rhickey: to me. But map<< reads funny |
| 11:08 | cemerick | rhickey: not really |
| 11:08 | rhickey | ok |
| 11:08 | cemerick | <- perhaps |
| 11:08 | cemerick | but that's bad for other reasons |
| 11:08 | rhickey | <-map, <-filter |
| 11:08 | Chouser | sure, << implies a direction of flow. I like filter<< |
| 11:09 | AWizzArd | smap, sfilter, sreductions |
| 11:09 | cemerick | rhickey: if those are options, why not just use smap, sfilter |
| 11:09 | leafw | how about map$ where $ is for stream. Or is the $ used for something else? |
| 11:09 | leafw | also, it makes it stand out a lot. |
| 11:10 | Chouser | leafw: "< rhickey> Chouser: no, but $ is totally unused and could thus b |
| 11:10 | leafw | map* read like a pointer. map+ reads like "something more than map" |
| 11:10 | Chouser | e used for something really special down the line" |
| 11:10 | AWizzArd | rhickey: every few weeks you come up with a new naming challenge. Why don't you write a small poll (in Clojure) for the website? ;) |
| 11:10 | rhickey | Just as an FYI, whatever it ends up being, you're going to use it a lot as it can be 3-4x as fast |
| 11:10 | Chouser | ew. sorry. |
| 11:10 | Chouser | leafw: pointer!? |
| 11:10 | leafw | Chouser: sorry, started with C long ago. |
| 11:10 | cemerick | heh, I didn't think about the pointer interpretation at all |
| 11:11 | Chouser | leafw: me too, but it's not a syntax I come close to thinking about here. :-) |
| 11:11 | cemerick | fn* is pretty standard for a slightly modified version of fn in various lisps, which makes sense |
| 11:11 | leafw | Chouser: well, just an impression :) |
| 11:11 | Chouser | my main argument against * is that it's used several other places to mean non-stream things. |
| 11:11 | leafw | cemerick: but is map* a modified map in the same way that fn* is a modified fn? Or an altogether different modification? |
| 11:12 | Chouser | altogether different, which is my argument |
| 11:12 | leafw | I agree Chouser |
| 11:12 | AWizzArd | can we already foresea if the stream version will be used more often than the one we currently have? In that case one could maybe even think of having the stream versions named map, reduce and filter, and find a new name for the existing stuff. |
| 11:12 | Chouser | a + suffix is equally unmeaningful, but at least unique within clojure. |
| 11:12 | cemerick | AWizzArd: oh, no, please, no |
| 11:13 | Chouser | AWizzArd: huge breaking change! |
| 11:13 | AWizzArd | of course |
| 11:13 | cemerick | Chouser: in that case, smap and sfilter should be it, sort order be damned. |
| 11:13 | thickey | Chouser: good argument against * |
| 11:13 | AWizzArd | cemerick: yes, I like these prefixes also more |
| 11:13 | leafw | map-s reads most natural, but honestlym it would already break some of my code: I have vars named like that |
| 11:14 | leafw | smap would do it for me too -- reads like "stream map", and it's an unlikely name for a var. |
| 11:30 | achim_p | hmm, what about putting the stream variants in a separate namespace. people could alias it to their liking, even (require '[clojure.streams :as <-]) |
| 11:31 | AWizzArd | that was what gnuvince suggested |
| 11:31 | AWizzArd | scroll up to see rhickeys questions regarding that |
| 11:31 | achim_p | oops, sorry |
| 11:32 | gnuvince | achim_p: it'd be alright if it wasn't for the fact that the core seq functions will be defined in terms of streams |
| 11:35 | Chouser | and that you can only alias one namespace to <- even if you want stream functions from several different libs |
| 11:35 | achim_p | i see |
| 12:24 | hiredman | ~latest |
| 12:24 | clojurebot | latest is 1326 |
| 12:29 | hiredman | hmmm |
| 12:44 | hiredman | r1006 |
| 12:47 | hiredman | ~latest? |
| 12:47 | clojurebot | latest is 1326 |
| 12:48 | rhickey | I'm currently partial to map* and filter*, I don't see the prior usage of blah* as being part of the public interface |
| 12:50 | rhickey | could just as easily be fn-special-op, let-special-op |
| 12:50 | rhickey | no one uses them directly |
| 12:58 | cemerick | rhickey: I actually didn't realize that fn* et al. existed until I started spelunking with macroexpand |
| 12:58 | cemerick | but yeah, changing those forms to something without the trailing asterisk would make sense |
| 12:58 | cemerick | I actually use the * convention for a couple of "alternative" fn implementations already. |
| 13:01 | jayfields | is there a function that lets me verify if an argument is in a seq, e.g. (any? [1 2 3] 1) |
| 13:02 | achim_p | jayfields: (some #{1} '(1 2 3)) |
| 13:02 | jayfields | thanks |
| 13:02 | achim_p | jayfields: contains? is faster for vectors and sets, doesn't work on lists |
| 13:02 | hiredman | ,(.contains '(1 2 3) 1) |
| 13:02 | clojurebot | true |
| 13:02 | cemerick | jayfields: to be clear #{1} creates a set that contains a single member (1) -- and sets are fns of their contents |
| 13:03 | cemerick | ,(#{1 2 3} 3) |
| 13:03 | jayfields | where is contains? defined? |
| 13:03 | clojurebot | 3 |
| 13:03 | hiredman | might be in contrib |
| 13:03 | jayfields | cool. thanks. |
| 13:04 | achim_p | contains? is in core ... |
| 13:04 | hiredman | oh |
| 13:04 | hiredman | ~def contains? |
| 13:04 | hiredman | I guess that is where it is defined |
| 13:04 | achim_p | argh, contains doesn't work for vectors, forgot that |
| 13:05 | danlarkin | achim_p: it does! but not how you thought |
| 13:05 | achim_p | yeah |
| 13:05 | achim_p | contains? is "contains key?" |
| 13:05 | danlarkin | ya |
| 13:06 | hiredman | so clojurebot has brand spanking new svn polling code, and https://twitter.com/clojurebot, so I am just waiting for rhickey to commit something so I can see if it works |
| 13:06 | danlarkin | achim_p: you probably want (some #{k} coll) |
| 13:09 | achim_p | danlarkin: yeah, i was replying to myself replying to jayfields ;) |
| 13:10 | danlarkin | :-o |
| 13:10 | danlarkin | I have a bad habit of not reading my whole irc buffer |
| 13:15 | shoover | cemerick: true, as long as you don't have nil as a value in the set |
| 13:18 | shoover | even then it's true, I suppose, but hard to distinguish |
| 13:18 | shoover | (to mince words with myself) |
| 13:30 | sohail | hey anyone here know how to pass -Xlint:deprecation through maven? |
| 13:49 | cp2 | anyone here have experience with couchdb? im wondering how it is, if you like it, etc |
| 13:50 | eevar__ | ,(use 'clojure.contrib.lazy-seqs) |
| 13:50 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib/lazy_seqs__init.class or clojure/contrib/lazy_seqs.clj on classpath: |
| 13:50 | eevar__ | (doc primes) |
| 13:50 | clojurebot | Excuse me? |
| 13:50 | eevar__ | m(doc primes) |
| 13:50 | eevar__ | ,(doc primes) |
| 13:50 | clojurebot | java.lang.Exception: Unable to resolve var: primes in this context |
| 13:51 | digash`` | cp2: i'v heard from not unbiased developers for mongodb that couchdb is very slow. |
| 13:51 | cp2 | heh |
| 13:52 | cp2 | ok, ill change the question then |
| 13:52 | cp2 | any "clojure-friendly" database api/whatever |
| 13:52 | Chouser | Rich was talking about the state of mongodb recently. |
| 13:53 | cp2 | heh |
| 13:53 | cp2 | thanks |
| 13:53 | digash`` | mongodb guys have couple of different java apis |
| 13:53 | cp2 | i may end up using clojureql in the end |
| 13:53 | cp2 | but im open to other options |
| 13:53 | digash`` | and they are willing to cooperate to make it much more clojure friendly when i've talked to them. |
| 13:56 | eevar__ | how hard is using plain jdbc from clojure? |
| 13:57 | digash` | pretty straight forward, i've wrote number of scripts to "massage" databases. |
| 13:57 | Chouser | not bad, plus there's clojure.contrib.sql for a fairly thin wrapper, or clojureql for a bit more abstraction. |
| 13:58 | cp2 | does contrib.sql / clojueql have support for more than just mysql? (as in sqlite, mysqli, etc) |
| 13:59 | Chouser | I believe contrib.sql will work with whatever, but doesn't hide the differences in SQL syntax. |
| 13:59 | eevar__ | database independence is a pipe dream anyway |
| 13:59 | Chouser | clojureql attempts to hide those differences as well, and supports a couple databases. |
| 14:00 | cp2 | yeah, im not too worried about being database independent |
| 14:00 | cp2 | i just dont want to _have_ to use mysql |
| 14:00 | Chouser | eevar__: 100%, sure, but even independence for 80% of your db interaction can be a big win. |
| 14:00 | cp2 | Chouser: thanks for the info |
| 14:00 | eevar__ | dunno. I'd rather pick one db and marry it ;) |
| 14:00 | Chouser | hm. |
| 14:01 | digash` | i think jdbc does abstract quite a bit compare to libmysql.so |
| 14:02 | eevar__ | should I ever come across somethign postgres can't handle, i'm sure there's plenty of $$ floating around for oracle/db2 porting |
| 14:03 | eevar__ | i do use embedded db's a times, tho |
| 14:04 | eevar__ | but only for small hackish things that are easily ported to pg if neccessary |
| 14:11 | hiredman | ~latest contrib? |
| 14:11 | clojurebot | latest contrib is 334 |
| 14:11 | hiredman | clojurebot: latest contrib is 570 |
| 14:11 | clojurebot | 'Sea, mhuise. |
| 14:23 | dcnstrct | has anyone here had any success using CouchDb4J ? |
| 14:24 | dcnstrct | for some reason I can't get it to execute views although it works fine for CRUD on individual documents |
| 14:27 | dcnstrct | nvm I just found jcouchdb a different library.. and it works |
| 14:36 | tashafa | look into clj-record |
| 14:36 | tashafa | http://github.com/duelinmarkers/clj-record/tree/master |
| 14:52 | cemerick | hrm, using delays in maps makes determining equality a little tricky |
| 14:53 | dcnstrct | clj_record looks badass, maybe I can augment it to add couchdb support |
| 15:04 | danlarkin | dcnstrct: some sort of ORM-ish type thing with couchdb backing is on my (ever growing) todo list |
| 15:05 | danlarkin | maybe you could strike it off for me! |
| 15:06 | dcnstrct | sounds like a plan, but don't hold your breath ;) |
| 15:12 | gnuvince | Was anything decided for streams? |
| 15:16 | gnuvince | ls |
| 15:18 | cemerick | gnuvince: I think map* is in the lead, last I saw |
| 15:22 | gnuvince | ok |
| 15:29 | StartsWithK | i have in one file (gen-class :name net.ksojat.neman.swing.Wrapper ..) (defmethod patch [net.ksojat.neman.swing.Wrapper ..] ...) |
| 15:29 | StartsWithK | but i get a error that net.ksojat.neman.swing.Wrapper dosn't exist |
| 15:30 | kotarak | Did you compile the containing namespace? |
| 15:30 | StartsWithK | what should i do to make it work? |
| 15:30 | StartsWithK | yes |
| 15:30 | hiredman | is it in your classpath? |
| 15:30 | StartsWithK | yes |
| 15:31 | StartsWithK | that part is ok im sure |
| 15:31 | hiredman | lets see the stack trace |
| 15:32 | StartsWithK | it says that when i try to run example from repl, not when i compile the code |
| 15:34 | hiredman | (.printStackTrace e*) |
| 15:34 | hiredman | oe *e |
| 15:34 | hiredman | r |
| 15:34 | hiredman | whatever it's named |
| 15:35 | StartsWithK | http://paste.pocoo.org/show/106759/ |
| 15:36 | hiredman | how do you know the compiled class is in your classpath? |
| 15:37 | StartsWithK | build generates my repl script to reflect any changes i made to classpath |
| 15:37 | hiredman | so your *compile-path* is in your CLASSPATH? |
| 15:37 | StartsWithK | yes |
| 15:37 | hiredman | really? |
| 15:38 | Chouser | you should be able to say net.ksojat.neman.swing.Wrapper at the repl before you 'load' anything |
| 15:38 | StartsWithK | yes |
| 15:38 | hiredman | what does (System/getProperty "java.class.path") say? |
| 15:39 | StartsWithK | Chouser: that fails too |
| 15:39 | Chouser | StartsWithK: then that class is not in your classpath. Either it wasn't generated, or the place where it was generated is not in your classpath. |
| 15:41 | StartsWithK | hiredman: http://paste.pocoo.org/show/106762/ |
| 15:42 | StartsWithK | hmm, but java.class.path says it is, and swing/target/classes has that class |
| 15:45 | hiredman | StartsWithK: was it generate before or after you started your repl? |
| 15:46 | StartsWithK | hiredman: before |
| 15:46 | StartsWithK | and just in case i regenerated repl script |
| 15:47 | hiredman | are all your namespace declarations correct? |
| 15:48 | StartsWithK | yes |
| 15:48 | kotarak | @rhickey: AOT compilation uses metadata of namespaces. |
| 15:48 | kotarak | s/uses/looses |
| 15:49 | StartsWithK | only thing that is not compiled is test file |
| 15:50 | Chouser | (let [p #(.getAbsolutePath (java.io.File. %))] (filter #{(p *compile-path*)} (map p (.split (System/getProperty "java.class.path") ":")))) |
| 15:51 | Chouser | StartsWithK: what does that return? ^^^ |
| 15:51 | kotarak | Stupid question: How do I use *warn-on-reflection*? |
| 15:51 | Chouser | kotarak: not stupid! set it true before you evaluate some (defn ...) forms. |
| 15:52 | StartsWithK | Chouser: from repl? (), but i don't have *compile-path* for repl, only for compile target |
| 15:52 | Chouser | hm, ok. |
| 15:52 | kotarak | So must it be source file or do compiled files also work? (read: (set! ...) (require 'foo.bar) ? |
| 15:53 | Chouser | kotarak: the warnings are generated at compile time, not at runtime |
| 15:53 | Chouser | so in that example, if foo.bar is not compiled, it should work. |
| 15:53 | Chouser | but if foo.bar is loaded from a .class file, you'll get no warnings. |
| 15:54 | kotarak | Ah ok. I need gen-class, though. Can I set the warn flag also when compiling? Some -Dclojure.warn-on-reflection=true magic? |
| 15:55 | Chouser | as far as I know there's no property you can set, but you should be able to use (set! ...) and then compile. |
| 15:57 | kotarak | Chouser: Ok. Simply compiling the gen-class stuff and then using load-file give the warnings. set!-ing and then compiling does not give the warnings, though. Hmm... Ominuous. |
| 15:57 | kotarak | Chouser: thanks. :) |
| 15:58 | Chouser | hmph |
| 15:59 | StartsWithK | this is the file http://paste.pocoo.org/show/106763/ loaded from (ns :load "swing/wrapper"), compiles ok, i see all generated classes, but now i see that even require on swing namespace generates the same erro |
| 16:02 | StartsWithK | ah, and line 24 is line 16 in the paste, didn't include the header.. |
| 16:05 | kotarak | Can I somehow tag the :state part of gen-class? |
| 16:06 | StartsWithK | tag how? |
| 16:07 | StartsWithK | it 'works' now, but i included generated jar in classpath, and not directory with generated .class files |
| 16:07 | StartsWithK | why should that make any difference? |
| 16:11 | kotarak | StartsWithK: I always have a IPersistentMap in there. But all calls to .theMap return something, which I have to tag with IPersistentMap to avoid reflection. :( |
| 16:11 | kotarak | But maybe I just the "usual" functions instead of the methods directly... |
| 16:13 | Chouser | ah, interesting. If you provide an accessor that has a tagged return value, then you should be able to use that accessor everywhere and not have to tag each usage. |
| 16:19 | fanda | hello! |
| 16:19 | fanda | i have a question about "contains?" |
| 16:19 | fanda | how does it work with lists? |
| 16:19 | fanda | ,(contains? '(1 2 3) 1) |
| 16:20 | clojurebot | false |
| 16:20 | fanda | is this a bug? |
| 16:20 | hiredman | ,(doc contains?) |
| 16:20 | clojurebot | "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'." |
| 16:20 | hiredman | "it will not perform a linear search for a value" |
| 16:20 | fanda | oh, I see |
| 16:21 | hiredman | Chouser: could you commit something to contrib? |
| 16:27 | fanda | hiredman: are you testing some functionality? |
| 16:27 | fanda | I could commit something too |
| 16:28 | hiredman | that would be cool |
| 16:28 | hiredman | Yes |
| 16:30 | kotarak | cool. one can also tag %1 in a #() :) |
| 16:31 | fanda | new test for "find" commited |
| 16:31 | hiredman | *tada* |
| 16:31 | Chouser | nice |
| 16:32 | fanda | yes, looks nice |
| 16:37 | Raynes | To iterate is human. To recurse is divine |
| 16:37 | fanda | :-) |
| 16:38 | hiredman | ah, well, the recurse in instant space is divine |
| 16:38 | hiredman | to |
| 16:38 | hiredman | constant |
| 16:38 | hiredman | ugh |
| 16:52 | fanda | :-) |
| 16:53 | hiredman | I think I fail at twitter |
| 16:54 | fanda | why is that? |
| 16:55 | hiredman | fanda: it seems simple, but for some reason clojurebot's tweets are not working correctly |
| 16:56 | hiredman | I blaim that fact that I am shelling out to curl, so I think I'll go find some java code |
| 16:57 | fanda | hiredman: it's always good to have more options :-) |
| 16:59 | fanda | rhickey, Chouser: I believe that Clojure issues 55 and 76 could be solved now. |
| 16:59 | fanda | http://code.google.com/p/clojure/issues/list |
| 16:59 | fanda | They were waiting for Timothy Pratley to sign and send his CA, but that looks done: |
| 16:59 | fanda | http://clojure.org/contributing |
| 17:01 | Chouser | 55 is already fixed, but the issue needs to be marked, I guess. |
| 17:02 | Chouser | ,(repeat 5 9) |
| 17:02 | clojurebot | (9 9 9 9 9) |
| 17:03 | fanda | replicate hasn't been removed, though |
| 17:29 | Drakeson | is there a shortcut for replacing subtrees matching a certain criteria with a function of the subtree? (e.g. DFS). tree=[:a [:b 1] [:b 2 3]] pattern=[:b x] --> [:a (f [:b 1]) [:b 2 3]] |
| 17:30 | Chouser | you might find something useful in clojure.contrib.walk, but I'm not sure. |
| 17:32 | dcnstrct | could anyone give me a suggestion of what I might be doing wrong ? I'm trying to use jcouchdb to create a document, and exactly what like what is showin the first example on this page: http://code.google.com/p/jcouchdb/wiki/Tutorial |
| 17:33 | dcnstrct | (. *db* createDocument {:foo "bar"}) returns this: java.lang.UnsupportedOperationException (NO_SOURCE_FILE:0) |
| 17:33 | dcnstrct | I can't figure out how to trace into this to figure out what the problem is. Do I need to use a java debugger ? |
| 17:34 | dcnstrct | if so what debugger would you recommend (I'm on OSX) |
| 17:34 | Drakeson | Chouser: thanks, that's like what I was looking for. |
| 17:35 | dcnstrct | forget the jcouchdb part of the question... I just want to know the name of a good java debuger (I'm new to java) |
| 17:36 | hiredman | dcnstrct: the db must be trying to mutate the imutable clojure hash |
| 17:36 | dcnstrct | hiredman, ah ha! |
| 17:37 | dcnstrct | hiredman, yes it is.. it's trying to add a couple properties to it |
| 17:37 | hiredman | :( |
| 17:37 | hiredman | how unfortunate |
| 17:37 | dcnstrct | hiredman, is there a way I can turn the clojure hash into something more maleable before I pass it in ? |
| 17:37 | hiredman | sure |
| 17:39 | hiredman | ,(java.util.HashMap. {:a 1}) |
| 17:39 | clojurebot | #<HashMap {:a=1}> |
| 17:40 | dcnstrct | it works!!! thank you you saved the day |
| 17:45 | hiredman | ugh |
| 17:45 | hiredman | silly sun, not including Base64 encode/decode in the jdk |
| 17:47 | Chouser | so now after starting up a plain repl, you can run (add-break-thread!) |
| 17:48 | Chouser | after that, Ctrl-C should break you out of any infinite loop and return you to the repl. |
| 17:48 | Chouser | I don't know what it'll do in slime/swank or any other unusual repl |
| 17:48 | Chouser | and even in a plain repl there may be odd consequences, since it's using Thread.stop() |
| 17:49 | Chouser | ...but it may get you out of a sticky situation. I'd be curious to know if anyone finds it useful, or if it makes bad things happen for anyone. |
| 19:20 | keithb | Is there a way to write a function that returns something that it lazily initializes |
| 19:20 | keithb | ? |
| 19:21 | keithb | I'm finding that I need some objects to be available in various parts of a program. Is it better to use def? |
| 19:23 | mrsolo | hm how come there is not-any? but not any? |
| 19:24 | keithb | mrsolo: some? |
| 19:24 | durka42 | what he said |
| 19:24 | mrsolo | ah |
| 19:24 | hiredman | mrsolo: because there was 'some' and someone wanted 'not-any' and bitched until they got it |
| 19:25 | mrsolo | .. |
| 19:25 | keithb | I withdraw my previous question... |
| 19:25 | hiredman | ~def not-any? |
| 19:26 | Raynes | (doc not-any?) |
| 19:26 | clojurebot | Returns false if (pred x) is logical true for any x in coll, else true.; arglists ([pred coll]) |
| 19:26 | Raynes | (doc some) |
| 19:26 | clojurebot | Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return true if :fred is in the sequence, otherwise nil: (some #{:fred} coll); arglists ([pred coll]) |
| 19:26 | Raynes | Well... |
| 19:26 | hiredman | not-any? is literally the composition of not and some |
| 19:27 | Raynes | Tsk. |
| 19:28 | keithb | I have a def that calls a function with a fn, that is: (def foo (myfunc (fn [] ...))). I refer to a variable in the fn. At the time the def is read by the interpreter, that variable in the fn has not yet been initialized. So will it always refer to nil, even though when it is called the var has a non-nil value? |
| 19:28 | mrsolo | oddity that's all since there are empty and every? |
| 19:28 | hiredman | keithb: pastbin |
| 19:29 | Raynes | paste.pocoo.org or paste.lisp.org O.O |
| 19:29 | durka42 | ~paste |
| 19:29 | clojurebot | lisppaste8, url |
| 19:29 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 19:29 | Raynes | durka42: Thanks for not insulting my code, I know you wanted too :p. |
| 19:30 | durka42 | Raynes: i was just puzzled while i was trying to reverse-engineer your input format from the code :) |
| 19:31 | Raynes | I know the code sucks though anyways :| |
| 19:31 | durka42 | i did find it strange that you had two replace-xxx fns that both took strings, but one was the actual string and the other took a filename |
| 19:32 | Raynes | That was a break-code-up-into-smaller-functions-and-dont-format accident. |
| 19:32 | durka42 | hmm, someone should write a clojure refactoring tool :p |
| 19:32 | lisppaste8 | keithb pasted "Entire Program" at http://paste.lisp.org/display/76599 |
| 19:33 | keithb | That's the whole thing; I'll try to pare it down now... |
| 19:33 | lisppaste8 | Rayne@acidrayne.net pasted "new keyvalue reader" at http://paste.lisp.org/display/76600 |
| 19:34 | Raynes | I also realized that if I cut one of the spaces beside the '=' then I don't need to replace the double spaces with single spaces before splitting :D |
| 19:34 | durka42 | "Hi there, it looks like you're writing iterative, stateful code with loop/recur. Would you like to: -change the loop into tail recursion -transform the loop into an elegant lazy fold -write the goddamn loop in peace" |
| 19:35 | durka42 | keithb: it's clear-action on line 114 you're asking about? |
| 19:38 | keithb | durka42: yes |
| 19:39 | lisppaste8 | keithb annotated #76599 "untitled" at http://paste.lisp.org/display/76599#1 |
| 19:42 | durka42 | keithb: it's true that fahr-text-field isn't bound until you call create-text-fields |
| 19:43 | keithb | durka42: Yes, I know. My question is about the timing of the access to fahr-text-field in the fn. |
| 19:43 | duncanm | i have a list of names (let [name "x" names `(name ~name)] (for [n names] (println n))) --> this prints (nil nil) |
| 19:43 | duncanm | shouldn't it print "name x" |
| 19:43 | duncanm | ? |
| 19:44 | durka42 | keithb: i think it should be okay to globally def fahr-text-field to nil, since the fn you pass to create-action can't be called until the frame is on the screen, which happens after create-text-fields is called |
| 19:44 | keithb | durka42: I thought that it would access fahr-text-field and get its value *when it is called*, but it appears to hold on to the value (nil) it had when the function was *defined*. |
| 19:44 | keithb | durka42: Oh.. |
| 19:45 | durka42 | duncanm: for is lazy. for me it prints: |
| 19:46 | durka42 | Clojure=> (let [name "x" names `(name ~name)] (for [n names] (println n))) |
| 19:46 | durka42 | (clojure.core/name |
| 19:46 | durka42 | x |
| 19:46 | durka42 | nil nil) |
| 19:46 | durka42 | use doseq if you want a more "traditional" for loop |
| 19:46 | durka42 | for is not a "for loop", it is more of a list comprehension |
| 19:46 | duncanm | hmm |
| 19:46 | duncanm | all i'm looking for is something like FOR-EACH in Scheme |
| 19:47 | keithb | durka42: I just tried that. No joy. I now get a NullPointerException. I remember in my Ruby study that a code block retains its bindings from when it was created. I think that's what's happening here. |
| 19:47 | gnuvince_ | duncanm: doseq |
| 19:47 | gnuvince_ | (doseq [element sequence-of-things] (println element)) |
| 19:48 | lisppaste8 | durka42 pasted "keithb" at http://paste.lisp.org/display/76601 |
| 19:50 | keithb | durka42: Thanks. Great job of reducing the problem...so it looks like I have to include an accessor method. |
| 19:50 | keithb | That's why I was wondering before about lazily initializing the thing within that accessor method. Possible? |
| 19:50 | durka42 | i'm not sure what you mean by lazily |
| 19:51 | keithb | durka42: Lazily in that the object would not be created until the function's first time called. Subsequent times it would return the same value. |
| 19:52 | durka42 | oh, i suppose you could do that |
| 19:52 | durka42 | but isn't this an event handler function? |
| 19:52 | durka42 | so you would want the text fields to be created before that |
| 19:52 | keithb | durka42: It doesn't really matter when they're created...they don't rely on any context. |
| 19:54 | durka42 | but you will need them to be created so they can be shown onscreen... |
| 19:56 | lisppaste8 | keithb annotated #76599 "Java lazy initialization method" at http://paste.lisp.org/display/76599#2 |
| 19:56 | keithb | durka42: This is what I would like to do in Clojure. |
| 19:56 | durka42 | that looks doable |
| 19:57 | durka42 | (if fahr-text-field fahr-text-field (create-text-field)) |
| 19:57 | keithb | durka42: I think I just figured it out... def it to nil in the beginning, and then, what you said. ;) |
| 19:57 | durka42 | (or fahr-text-field (create-text-field)) |
| 19:58 | keithb | durka42: ...except you want to hold onto the newly created thing in the variable, so you only ever create one of them. |
| 19:58 | durka42 | well, that's what the (if) or the (or) does |
| 19:59 | keithb | ok, I'll write something up and run it by you. THanks much. |
| 20:01 | AWizzArd | gnuvince_: is there a descision about the streams now? |
| 20:02 | gnuvince_ | AWizzArd: I don't know, I've been away most of the afternoon and evening |
| 20:19 | lisppaste8 | keithb annotated #76599 "untitled" at http://paste.lisp.org/display/76599#3 |
| 20:20 | keithb | Got it... it was an extra set of parens!!!! |
| 20:26 | durka42 | oh, i see |
| 20:26 | durka42 | nice work |
| 20:30 | lisppaste8 | keithb annotated #76599 "untitled" at http://paste.lisp.org/display/76599#4 |
| 20:31 | keithb | Given the repetition in the pastie, and the simplicity of the function, is there a macro somewhere that would do this for me with a simple definition of name and initialization strategy? Where does one look for these things? |
| 20:33 | Chouser | (if foo foo bar) is the same as (or foo bar) |
| 20:33 | Chouser | oh, wait. |
| 20:33 | Chouser | what are you doing? |
| 20:34 | keithb | Chouser: I'm writing accessors that lazily initialize the thing they access. |
| 20:34 | keithb | They're not really self contained; they require a def outside of the function. If there's a better way I'm totally open to it... |
| 20:35 | Chouser | hm, there are a few options... |
| 20:35 | Cark | def inside a function ...that's ugly |
| 20:37 | hiredman | keithb: sounds like you want futures |
| 20:38 | keithb | The use case I'm trying to address is that I want to pass a fn that has access to a var whose value will be initialized in the future. YES! |
| 20:38 | hiredman | (doc future) |
| 20:38 | clojurebot | Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block.; arglists ([& body]) |
| 20:38 | Chouser | delay is probably closer to what you want, unles I'm misunderstanding. |
| 20:40 | hiredman | ~def delay |
| 20:40 | keithb | Chouser: Thanks! I think delay is what I want; an additional thread is overkill. |
| 20:40 | lisppaste8 | Chouser annotated #76599 "close over a delay" at http://paste.lisp.org/display/76599#5 |
| 20:44 | keithb | Chouser: That's great, it works. Now, to be a pain about it...couldn't a macro hide the let and force mechanics from me so that my functions could be even simpler? |
| 20:45 | lisppaste8 | keithb annotated #76599 "untitled" at http://paste.lisp.org/display/76599#6 |
| 20:45 | keithb | ...something like the thing I pasted, which could maybe be expanded to your delay/force code, which would in turn be expanded? |
| 20:45 | keithb | I haven't learned macros yet... |
| 20:45 | Chouser | yep, sure could |
| 20:46 | Chouser | looks like a great one to start with. |
| 20:46 | keithb | :) |
| 20:46 | keithb | Ok, for another day...thanks for all your help. |
| 20:46 | Chouser | I'm not kidding. I'm guessing you haven't bought Halloway's book? |
| 20:46 | Chouser | oh, ok. you're welcome. |
| 20:47 | keithb | Yes, I have...I've been using it. |
| 20:47 | keithb | But only read some chapters so far. |
| 20:48 | keithb | I know you're not kidding...I will try that...but first I want to finish this program...I hope to post an article about it on my blog at http://krbtech.wordpress.com. |
| 20:50 | Chouser | ah, great. The chapter on macros should be just right for this example. |
| 20:50 | keithb | Chouser: So where is the cached value stored? |
| 20:50 | keithb | Metadata? |
| 20:50 | Chouser | nope, it's cached inside the delay object, which is held by x |
| 20:51 | keithb | Ah, it's a Java object? |
| 20:51 | Chouser | x is held inside the function (a.k.a. closure) created by #() |
| 20:51 | Chouser | ,(class (delay)) |
| 20:51 | clojurebot | clojure.lang.Delay |
| 20:51 | hiredman | http://twitter.com/clojurebot/status/1291166090 <-- so this kind of works |
| 20:53 | keithb | Chouser: and a function can hold data because code is data? This is hard for me to wrap my head around, coming from C/C++/Java/Ruby. |
| 20:53 | te | hello all |
| 20:53 | Chouser | keithb: no, it's independent of that. I'm pretty sure Ruby has closures... |
| 20:53 | te | Is it possible to create a function that renames itself? |
| 20:54 | keithb | Chouser: I believe in Ruby any code block, lambda, or proc is a closure. |
| 20:54 | keithb | Oh, I think I get it... |
| 20:54 | te | keithb: im not sure if that's true |
| 20:54 | te | lambda and proc behave differently |
| 20:54 | hiredman | te: that sounds like mutation |
| 20:54 | keithb | te, do tell... |
| 20:54 | Chouser | my ruby is really rusty... |
| 20:55 | te | iif you use lambda inside a block it will not continue past the point in the block that it occurs |
| 20:55 | te | proc will return the value of the block it exists inside |
| 20:57 | hiredman | that is really weird |
| 20:57 | te | i cant remember for sure if its like that or vice versa |
| 20:57 | hiredman | http://samdanielson.com/2007/3/19/proc-new-vs-lambda-in-ruby |
| 20:57 | te | this may h ave changed in 1.9 also |
| 20:59 | keithb | From the pickaxe book, it sounds like both code blocks and Procs are closures: Associated with a block (and hence a Proc object) |
| 20:59 | keithb | is all the context in which the block was defined: the value of self and the methods, |
| 20:59 | keithb | variables, and constants in scope. Part of the magic of Ruby is that the block can still |
| 20:59 | keithb | use all this original scope information even if the environment in which it was defined |
| 20:59 | keithb | would otherwise have disappeared. In other languages, this facility is called a closure. |
| 21:00 | te | oh yeah im sorry |
| 21:00 | te | i forgot that lambdas are basically procs |
| 21:00 | Chouser | f = lambda{ x = 5; lambda { x = x + 1 } }.call |
| 21:00 | te | they literally are procs |
| 21:00 | te | (lambdas are) |
| 21:00 | Chouser | ok, it's a bit like that |
| 21:01 | Chouser | f.call returns the value of x (it also mutates it, but that's not my point) |
| 21:01 | lisppaste8 | slashus2 annotated #76599 "lazy-init" at http://paste.lisp.org/display/76599#7 |
| 21:01 | keithb | ok, I'll leave it at that...my head's exploding... ;) |
| 21:01 | te | if you define f = lambda{ puts "hello" } |
| 21:01 | te | and do f.type |
| 21:01 | te | it's type Proc |
| 21:01 | slashus2 | keithb: Does that work? |
| 21:01 | Chouser | where is the int stored? inside the x that is held by the inner lambda |
| 21:02 | te | Chouser: what that a question and answer |
| 21:02 | te | or a question? |
| 21:02 | keithb | slashus2: You mean the delay strategy? Yes. |
| 21:02 | slashus2 | keithb: That macro? |
| 21:02 | Chouser | keithb: congrats, it's a macro! :-) |
| 21:02 | keithb | slashus2: Sorry, I didn't see your pastie. Tyring it now. Chouser, that wasn't me. ;( |
| 21:02 | Chouser | te: sorry, rhetorical device. yes, question and answer. |
| 21:03 | te | ah cool just checking |
| 21:03 | Chouser | oh |
| 21:03 | Chouser | sorry |
| 21:04 | Chouser | slashus2: you've got a few more args than you need. |
| 21:04 | Chouser | man, irb really hates it when I paste in clojure code |
| 21:04 | te | Can you create a function that renames itself? |
| 21:04 | te | Is that possible? |
| 21:04 | te | Chouser: haha |
| 21:05 | hiredman | te: that sounds like mutation |
| 21:05 | te | hiredman: could you elaborate please:? |
| 21:05 | Chouser | te: functions don't really have external names |
| 21:05 | te | external in reference to what? |
| 21:05 | Chouser | external to itself |
| 21:06 | te | hmmm thats hard to understand |
| 21:06 | te | could you explain what you mean |
| 21:06 | hiredman | te: you would have to mutate the symbol that names the var that resolves to the fn |
| 21:06 | Chouser | you could say that (fn foo [] ...) is called foo inside (where the ... is), but that form returns an anonymous function. |
| 21:06 | hiredman | and symbols are not mutatable |
| 21:06 | keithb | slashus2: Can you tell me how I would call lazy-init? |
| 21:07 | Chouser | you can have multiple Vars or locals pointing to the same function |
| 21:07 | te | could that become dirty if i did it too many times? |
| 21:07 | slashus2 | keithb: exactly how yous specified |
| 21:07 | hiredman | dirty? |
| 21:07 | Chouser | keithb: the opportunity to justifiably write a macro is pretty rare. I'd ignore solutions posted by others and do it yourself. :-) |
| 21:07 | te | hiredman: could it impact performance? |
| 21:08 | keithb | Chouser: I hear you. Thanks, everyone. I'm going to call it a night. Beer and karaoke for me. Woohoo!!! ;) |
| 21:08 | te | hiredman: sorry im just poking around -- i dont mean to ask 10,000 questions |
| 21:08 | hiredman | I dunno about perf, but it would impact "does this program make sense" |
| 21:08 | slashus2 | keithb: You could ignore mine, but mine does (lazy-init create-a-text-field) |
| 21:09 | keithb | slashus2: So: (def fahr-text-field (lazy-init create-a-text-field))? |
| 21:09 | slashus2 | keithb: yeah |
| 21:09 | te | hiredman: im interested in renaming functions according to metadata inside the function |
| 21:09 | keithb | slashus2: Cool. |
| 21:10 | hiredman | te: without hearing and explanation I am going to tell you: that makes no sense |
| 21:10 | hiredman | an |
| 21:10 | hiredman | besides |
| 21:10 | hiredman | functions cannot currently have metadata |
| 21:11 | te | im sorry man maybe im using the complete wrong way to explain this |
| 21:11 | Chouser | but Vars can, and you could make a new Var pointing to the same fn based on the metadata of the old Var. |
| 21:11 | keithb | slashus2: It works. Well done! Chouser, I'll look into reimplementing it myself later when I learn macros. Thanks everyone! |
| 21:11 | Chouser | Not sure why you'd do that, though. |
| 21:12 | Chouser | te: where would the metadata come from? |
| 21:12 | te | It would change based on the input |
| 21:12 | te | for the function |
| 21:12 | hiredman | :( |
| 21:14 | te | i really dont know how to approach this, but basically i want to give the ability to "tag" functions according to whether or not their meta data matches a string the best |
| 21:14 | te | so "Red house dog cat" would match functions whose meta includes house and cat |
| 21:14 | Chouser | maybe you want a hash-map with strings as keys and fns for the values? |
| 21:14 | hiredman | why? |
| 21:15 | te | im interested in toying with evolution of code |
| 21:16 | Raynes | Chouser: hash-map is my newest favorite function. |
| 21:16 | te | the idea is to age tags that satisfy the combination of functions to give a correct answer |
| 21:16 | te | or an interesting one, at least |
| 21:16 | hiredman | te: why would you even name those funtions? |
| 21:16 | hiredman | (name in the sense of symbol->var->fn) |
| 21:17 | te | i suppose it isn't necessary, but it would be nice to glimpse into the pool of possibilities and see what has become of the original pool of fns |
| 21:17 | te | hiredman: consider "design space" |
| 21:17 | Raynes | (apply hash-map ..) <3 |
| 21:18 | te | where design space is this space that contains every single possibility for design |
| 21:18 | hiredman | te: I refuse to consider something so broad |
| 21:18 | te | from a toaster to soil to a ferarri |
| 21:18 | hiredman | and it's dinner time |
| 21:19 | te | hiredman: im just trying to start with a number of possible designs that are necessary to create new designs |
| 21:19 | te | and then evolve them to see what i can come up with |
| 21:25 | slashus2 | Chouser: I don't think that a macro was needed for that lazy-init. I rewrote it as a function, and it works correctly. |
| 21:26 | Chouser | slashus2: it would have to be a macro if you wanted to provide arbitrary expression rather than a fn. |
| 21:27 | Chouser | like his example: (lazy-init (create-a-text-field)) |
| 21:27 | slashus2 | oh, okay |
| 21:28 | slashus2 | ~expr in the place. |
| 21:28 | clojurebot | It's greek to me. |
| 21:28 | slashus2 | woops |
| 21:30 | rlb | Does anyone know if the output of pr (or prn) is likely to be identical for a given data structure (at least the core structures) across clojure releases? |
| 21:30 | slashus2 | Chouser: Thank you, I didn't see the potential for entering an expression. |
| 21:31 | Chouser | slashus2: sure, np. |
| 21:31 | slashus2 | It was actually easier to write that way. |
| 21:35 | rlb | More spefically, I'm wonding what the chance is that you can use pr (or prn) to write a bunch of data to a file and have a sha-1 of that file match the output of the same data by a future version of clojure. |
| 21:36 | rlb | ouch s/spefically/specifically/ s/wonding/wondering/ |
| 21:36 | Chouser | hard to say for sure. you don't need print-dup i hope? |
| 21:37 | rlb | print-dup? |
| 21:38 | Chouser | ,(binding [*print-dup* true] (pr-str [1 2] #{3 4} (sorted-set 5 6)) |
| 21:38 | clojurebot | EOF while reading |
| 21:38 | rlb | Actually, hmm, I should look -- ISTR something about clojure serialization, but the same question would apply there, i.e. is the output likely to be bit-for-bit identical across releases? I just want to know if it's likely that I could depend on that. I would guess not, but I thought I'd ask. |
| 21:39 | Chouser | ,(binding [*print-dup* true] (pr-str [1 2] #{3 4} (sorted-set 5 6))) |
| 21:39 | clojurebot | "[1 2] #{3 4} #=(clojure.lang.PersistentTreeSet/create [5 6])" |
| 21:40 | rlb | Basically I want to be able to reliably write at least simple lists or vectors of at least numbers and strings quickly in a way that always results in a byte-wise identical file. |
| 21:41 | Chouser | that's unlikely to change, I would think, but you'd want some way to recover if strings get escaped slightly differently or something. |
| 21:41 | rlb | And I need to be able to read it back in. Obviously I can write code to do that (i.e. rigid-read rigid-write or whatever, I just wondered if clojure might obviate the need. |
| 21:42 | rlb | Chouser: I suspect I'll just need to do it myself, though I might use clojure's read/write for now (as the implementation), and plan to just switch to custom routines if/when clojure breaks anything. |
| 21:42 | Chouser | that might work. |
| 21:42 | rlb | (where "breaks" means changes output format) |
| 21:42 | Chouser | right |
| 21:42 | rlb | Chouser: anyway, that seems like a fast way to get started -- thanks for the help. |
| 21:43 | rlb | I'll just add "make check" tests to look for variations. |