#clojure logs

2009-03-06

00:12Drakesonwhat is elisp's mapconcat or python's join called in clojure?
00:14hiredman,(doc mapcat)
00:14clojurebot"([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:14DrakesonI want (join ", " ["a" "b" "c"]) -> "a, b, c"
00:15Drakeson,(doc join)
00:15clojurebotjava.lang.Exception: Unable to resolve var: join in this context
00:15Drakeson,(doc string-join)
00:15clojurebotjava.lang.Exception: Unable to resolve var: string-join in this context
00:15arohnerthere's a str-join in c.c.str-utils
00:16Drakesonarohner: oh, thanks. why is it in contrib? :(
00:16arohner,(doc clojure.contrib.str-utils/str-join)
00:16clojurebot"([separator sequence]); Returns a string of all elements in 'sequence', separated by 'separator'. Like Perl's 'join'."
00:17arohnerDrakeson: the simple but snarky answer is that it's there because it isn't in core
00:17arohnerclojure is still young
00:19RaynesIs there a certain convention for writing functions like so (defn afunction ([] ..))
00:20RaynesI tend to do it when the function contains documentation.
00:20hiredmanthat is for mult-arity functions
00:21hiredman~def max
00:21hiredmanlike that
00:21hiredmanunless your function multi-arity like that, please don't write your functions that way
00:22RaynesThanks ^_^
00:23Drakeson,(filter 'identity [nil true])
00:23clojurebot()
00:23Drakesonwhy?!
00:24hiredman,(filter identity [nil true])
00:24clojurebot(true)
00:24hiredman'identity is a symbol
00:25Drakesonhabits ...
00:25hiredmanidentity is also a symbol that is resolved to a var that points to a function
00:25Drakesonhiredman: I know :)
00:26hiredmansymbols can be called like funtions for hash look ups and the like
00:26hiredman,('identity {'identity 1})
00:26clojurebot1
00:28Drakesonhiredman: thanks, My fingers tend to put a quote in those places to fill the common-lisp void!
00:29replacaDrakeson: I make the same mistake with identity all the time!
00:40RaynesCould someone show me an example using comp?
00:44hiredman,(map (comp inc first) (replicate 3 (range 3)))
00:44clojurebot(1 1 1)
00:44RaynesThanks.
00:55mrk1In my slime repl, (read), (read-line) doesn't repond. is this normal?
01:29durka42wait, so are streams back under consideration?
01:31slashus2They look very interesting.
01:32slashus2durka42: Why did they go out of consideration?
01:32durka42i 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:33slashus2Why not have both
01:33slashus2?
01:33durka42well, right
01:33durka42i guess they came back
01:34slashus2Looking at the examples, I wonder if some of the core functions will be rewritten with streams?
01:34slashus2I guess it just shows that they can be.
01:35lisppaste8Rayne@acidrayne.net pasted "key value text reader" at http://paste.lisp.org/display/76568
01:35hiredmanwell, streams and seqs are a different abstraction
01:35RaynesDamn that bots fast.
01:35RaynesIt printed that before I even hit enter O_O
01:35slashus2I guess causality didn't apply?
01:36durka42it seems really fast because it posts to the channel before serving you the page
01:37Raynesdurka42: Yeah, I noticed. O.O
01:38durka42Raynes: does what you posted work?
01:38RaynesYes.
01:38RaynesSurprisingly.
01:39durka42(well, on windows)
01:39RaynesWindows specific at the moment yes.
01:40durka42oh -- your config lines are specified as "foo = bar" not "foo=bar"
01:41RaynesYup.
01:41Raynes"foo=bar" was too easy.
01:42durka42heh
01:43durka42hmm monads for clojure programmers http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/
01:43durka42maybe i'll understand this one
01:43RaynesOh cool.
01:43hiredmanhot
01:43hiredmanonclojure, someone has set their sites high
01:43RaynesI need to go to sleep, but I want to read this.
01:43Raynes:|
01:44RaynesMeh, it will only take a minute.
01:49RaynesI only read half of it, too sleepy to comprehend it. Me go sleepy.
01:49RaynesAlso durka42: Thanks for not insulting my shitty code :) I know you were thinking it.
02:20dcnstrctis there a way to check your classpath from the REPL ?
02:22ayrnieu,(System/getProperty "java.class.path")
02:22clojurebotjava.security.AccessControlException: access denied (java.util.PropertyPermission java.class.path read)
02:22dcnstrctthnx
03:22xristosi'm trying to setup swank-clojure but nothing seems work here
03:22xristoscan anyone post his .el
03:54AWizzArdclojurebot: max people
03:54clojurebotmax people is 156
03:54AWizzArdaha, new record :)
03:57hiredmanI was begining to think it wasn't working correctly
04:09AWizzArdseems to work
04:15AWizzArdMoin kotarak
04:15kotarakmoin moin
04:16AWizzArdAlles Roger oder was? ;)
04:52leafwI 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:57AWizzArdgut
05:59aseeonCould you recommend be a good editor/ide to write Clojure code in (i am not the vim kind of guy)?
06:01kotarakaseeon: 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:01hoeckaseeon: emacs :) (sorry, I'm an emacs guy)
06:10AWizzArdaseeon: you can try Enclojure: http://enclojure.org/
06:10AWizzArdif you are used to modern looking IDEs then this would probably your best bet.
06:10aseeonAWizzArd: looks very promising
06:10AWizzArdabsolutely
06:11aseeonyeah i am, Komodo Edit, Netbeans and Eclipse are my tools of the trade :D
06:11AWizzArdthen you pretty much will need Enclojure, as this is a plugin for NetBeans.
06:12AWizzArdI 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:13aseeonthanks kotarak and AWizzArd for telling me about enclojure, i will give it a spin :)
06:13aseeonand hopefully will be back here ^_^
07:23Hookehello
07:24AWizzArdHi Hooke
07:25Hookehello, AWizzArd, how are you
07:26AWizzArdfine thx, hope you too
08:38jayfields(doc compare)
08:38clojurebotComparator. 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:42canderaI'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:43shoovercandera: try it without the []?
09:44cemerickcandera: yeah, classes can have only one superclass -- can implement multiple interfaces, tho
09:45canderaYep, that worked. Thanks!
09:45canderaOn to the next problem! :)
09:55cgrayhi, 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:56Chousercgray: 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:56cgrayis there a good reason for that?
09:56Chouserwell, it's a relatively good reason. :-)
09:57Chouser'require' and 'use' deal in namespaces
09:57Carki've been bitten by that too
09:57cemerickhrm, where oh where did cond-let go?
09:58Carkcommon lisp was more forgiving in that respect !
09:58leafwwhy do I never get cond right? Somehow, it is not intuitive to me how to lay down the expressions.
09:58Chousernamespace names map to java class names
09:59Carkand the file names must be the same as file names ?
09:59Chouserjava doesn't allow - in identifiers because it would mean subtraction in their infix notation.
09:59Carkerr class names
09:59Chousertherefore the jvm doesn't allow - either (though this could theoretically change)
09:59cgrayChouser: okay, thanks I see now
09:59Carkin java is it forbidden to have a file name different from the class name it contains ?
10:00Carki thought this was introduced with aot compilation
10:00ChouserCark: java uses the filename to find the definition of a given package/class, so it needs to match.
10:00cemerickah-ha, tricky -- my favorite documentation browser helpfully includes contrib stuff, but I didn't notice the contrib annotation on cond-let
10:00Carkok i see
10:01Chouserbasically 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:02Chousercemerick: ah, I didn't know there was a cond-let anywhere. nice.
10:02cemerickChouser: Unfortunately, it doesn't seem to work.
10:02Chouserleafw: surely cond is easier to get right than condp, though!
10:02leafwChouser: the docs are so incomplete on cond.
10:03leafwalso, no indication of the "default". What is it, :else ?
10:03Chouserleafw: any true expression will do. :else is the common idiom.
10:03leafwok. Thanks Chouser
10:05ChouserI thought the trailing ~ was cute
10:05Chouserminor adjustment to the reader, I think...
10:06rhickeymajor overloading of ~ though
10:07Chouserno more major than, for example, #
10:08Holcxjo,(find-doc "cond")
10:08clojurebotjava.lang.NoClassDefFoundError: clojure/lang/IteratorSeq$State
10:08HolcxjoIs that meant to be the result?
10:08HolcxjoSandboxing issue?
10:09Carkrhikey : i liked the prepended s in your examples ... looks like 'S'tream and also like a verb
10:09rhickeyChouser: not sure about that, we don't put # on front and back of names
10:09Chouser#'foo means something completely different than foo#
10:09Chousercompletely unrelated, even.
10:09Carkmeaning : this stream maps the sequence with that function
10:10rhickeywhat about =map=, =filter=, e.g. the pipe metaphor?
10:10Chousercemerick: cond-let seems to work for me. What kind of failure are you seeing?
10:10rhickeyCark: that was the intent there, just not sure it will work well for fnctions that normally end in s
10:10Carkjust follow the english grammar
10:10Carkwhat function do you think of ?
10:11Chouserreductionss
10:11thickeythere'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:11Carkabusing special character seems ugly
10:11cemerickChouser: huh. (cond-let [a 5] (pos? a) (+ a 9) :else 3) => java.lang.Exception: Unable to resolve symbol: a in this context
10:12Chousercemerick: yeah, is bound to the result of (pos? a)
10:12rhickeyanother possibility is map-1, filter-1, for the once-only nature of their use
10:12Chousercemerick: so it's not bound to anything when (pos? a) itself is evaluated.
10:13Carkrhickey : painfull on a belgian keyboard !
10:13leafwCark: programming on anything than querty english is painful.
10:13rhickeyCark: how so?
10:13Carkleafw : true
10:14gnuvincefrench canadian is not bad imo
10:14Carkwell the - is already bad, but we have to in lisp (it's right beside backspace), then 1 is using the shift key
10:14Chouser=map= isn't too bad. It feels a bit heavy by itself, but doesn't look to bad with parens around it.
10:14Carkhow about map> ?
10:14Chouserwould =map, =filter, etc. be acceptible, or is that too much like equality?
10:15Chousertoo bad
10:15rhickey<=map, <=filter ?
10:15Carkwhy does it have to go left ?
10:15gnuvince(|map f xs)?
10:16Cark|map looks like some reader macro
10:17rhickey<-map, <-filter
10:17cemerickChouser: 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:17rhickey<<map <<filter
10:17Chousercemerick: you wanted a single extra let around the outside?
10:18Carkany of those would be nice rhikey
10:18cemerickChouser: yeah. I figured it would produce (let [a 5] (cond (pos? a) ....))
10:18Cark<< being the easiest
10:18gnuvinceHas anyone considered putting them in a different namespace and just using stream/map, stream/filter?
10:19rhickeygnuvince: where will you put your stream functions?
10:19HolcxjoOr make it hard for everybody and use non-ASCII �map
10:19cemerickI guess I just turned into one of those people that never read anything :-P
10:19Carkhoclxjo : haha
10:19gnuvincerhickey: ?
10:20Chousercemerick: 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:20rhickeygnuvince: using a namespace only solves the problems for core
10:21Chouserseparate namespace doesn't help. then any code that does it a lot ends up using s/filter s/map etc. :-(
10:21gnuvinceChouser: that's better IMO than an arbitrarily selected symbol that means "stream"
10:22cemerickChouser: yeah, I can definitely see that being useful. When I see 'let', I think of a vector of pairs, though.
10:22rhickeygnuvince: but you can't put your streams functions in the stream namespace, so everyone will have to pick a different prefix namespace
10:22thickeyi'm with gnuvince, all these quirky charachters before/after things doesn't mean anything
10:22Chousercemerick: hm. I think that may be part of why it's not in core.
10:23rhickeygnuvince: 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:23cemerickI'll third gnuvince, thickey on this.
10:24rhickeythickey: 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:24cemerickwhy not s-map, s-filter, etc? I just cringe at seeing more line noise (in the aggregate).
10:24cemerickor smap, sfilter as suggested before
10:24ChouserI think <<map is my favorite so far (if map~ is off the table)
10:24gnuvincerhickey: 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:24rhickeyChouser: nothings off the table at this point except non-ascii
10:24thickeyrhickey: makes sense
10:26danlarkinI'm with gnuvince, I think a separate namespace makes sense
10:26rhickeygnuvince: 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:26thickeythen 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:27rhickeydanlarkin: forcing all namespaces that have stream version to have a sub-namespace with a naming convention? ouch
10:27ChouserI 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:27rhickeyChouser: not exactly, due to the once-only use aspect
10:27gnuvincerhickey: 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:28Chouserrhickey is talking about user-created functions.
10:28ChouserI think.
10:29rhickeygnuvince: 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:29ChouserIf 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:30Chouserclojure.contrib.regex.stream.re-split?
10:30rhickeymap$, filter$
10:30Carksmap ... the smapy version of a regular map
10:31cemerickrhickey: indeed ;-)
10:31Chouserhm, is there some history to $ that I don't know.
10:31rhickeymap*, filter*
10:31Chousercemerick: nice.
10:31rhickeymap1 filter1
10:32Carki'll vote for the easy smap, sfilter, sreduce
10:32rhickeymap-once, filter-once
10:32cemerickis there really a compelling reason to not use smap, etc?
10:32rhickeymap-s filter-s
10:32ChouserI don't like the 1
10:32gnuvincerhickey: I guess I just don't see the problem with having the user explicitly require what he needs.
10:32cemerickusing the p-prefix for parallel fns was a much bigger change, IMO
10:32gnuvinceIn any case, just my opinion, you're the dictator :)
10:33cemerickor, the parallelism of those fns represented a much bigger change in behaviour from the standard fns, I mean
10:33rhickeygnuvince: 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:33rhickey4 namespaces and 2 aliases?
10:34danlarkinI realize why there are, but I kinda wish there didn't have to be different versions
10:34gnuvince(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:34thickeywouldn't "the stream version of gnuvince's foo" just have some other name that gnuvince gave it?
10:35cemerickdanlarkin: +1. I know I'm eventually going to have to write something like spmapcat or something. :-(
10:36cemerickat 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:36AWizzArdcould be as easy as providing an argument
10:36AWizzArd(map :stream #(+ 4 %) coll)
10:36rhickeygnuvince: 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:36cemerick(map +sp #() coll)
10:36Chousercemerick: metadata! (#^{:use-stream true, :use-parallel true} mapcat func coll)
10:37cemerickChouser: you just pegged my verbosity meter! :-P
10:37ChouserAWizzArd: that already means something else
10:37Chousercemerick: :-)
10:37AWizzArdyes, plus I don't like that idea.
10:37rhickeyusing args means a lot of partial-ing for HOF use
10:38AWizzArdsomething like smap, sfilter would be ok I guess
10:38RadioApeShotHi #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:38Carkforth style : (streaming (map #(+ 4 %) coll))
10:38cemerickyeah, maybe some more concise metadata representation could be fielded for stuff like this (analogous to #^Classname)
10:38rhickeyIt 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:39RadioApeShotI already tried creating a fn and then calling its run method via (. f run)
10:39rhickeyI am partial to Chouser's argument for appending, especially as then the two versions will sort together
10:40cemerickrhickey: 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:40ChouserRadioApeShot: (.run (Thread. #(prn "hi!")))
10:40rhickeycemerick: you want less functionality? :)
10:40RadioApeShotChouser: Thanks.
10:40ChouserRadioApeShot: or look into agents or futures, depending on how you intend to use the thread.
10:40cemerickrhickey: surely, no. But I do want a way to compose various features around a core operation (map, filter, etc)
10:41rhickeycemerick: in the ends these aren't 'properties' of the same function - they're different functions with different albeit similar semantics
10:41cemerick...without having an explosion of variants of those core operations (spmapcat, etc)
10:41rhickeycemerick: that's a theoretical argument
10:41Carkwould it make sense to have a parallel stream function anyways ?
10:42AWizzArdI thought streams are serial?
10:42gnuvincerhickey: 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:42Chouser= has parallel lines, thus clearly means parallel multithreaded operation. ~ looks like a little river, so clearly means stream. thus mapcat=~
10:42cemericklol
10:43RadioApeShot(.run (Thread. f)) still causes my REPL to hang while the thread does its work
10:43gnuvinceChouser: I proposed ~ yesterday, but the reader doesn't like that :-/
10:43cemerickChouser was egyptian in a previous life
10:43Carkhaha
10:43rhickey= looks like a pipe and ~ a tail, so streaming and lazy :)
10:43Chousergnuvince: the reader can be fixed.
10:43Chouserrhickey: :-P
10:44cemerick~ really can't be in the running. One would get dizzy while writing macros.
10:44clojurebotHoly Crap.
10:44AWizzArdWhat are the contras for a prefix letter, such as "s"?
10:44Chousergnuvince: but yes, I know you thought of it. It's not my idea, I'm simply defending it. :-)
10:44rhickeycemerick: I agree
10:44danlarkinAWizzArd: doesn't sort together
10:44ChouserAWizzArd: reductionss
10:44Chouseroh, prefix, sorry.
10:44cemerickdanlarkin: bah, the p* fns don't sort with their single-threaded counterparts
10:45Carki don't buy the sorting argument, docs are searchable by other means
10:45rhickeycemerick: where are these many p* fns?
10:45Chousernah, we already can have `(let [foo# #'foo, bar# ~#{#'baz #'qux}] ...) in a macro
10:46rhickeyChouser: but not ~foo~
10:46Chouserooh, pretty!
10:47rhickeythat's foo swimming in a sea of confusion
10:47Carklooks like foo is about to drown ... more like a pond than a stream
10:47Chouserheh. ok, fine.
10:48gnuvincerhickey: any thoughts on the namespace+naming convention idea or is it just bad?
10:48rhickeymap<<, filter<<
10:48ChousermapS map$ map=
10:48Chouserwas the map$ suggesting entirely a joke?
10:49rhickeygnuvince: I didn't see the naming convention in there
10:49gnuvince[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:49rhickeyChouser: no, but $ is totally unused and could thus be used for something really special down the line
10:49AWizzArdI don't like too many conventions. More than enough people will not stick to it.
10:49cemerickrhickey, danlarkin: sorry, my bad. There's pmap of course, but we have a pfilter here, too. I thought the latter was in core. :-(
10:49rhickeygnuvince: what's the naming convention then?
10:50gnuvincerhickey: well that's to be decided, but would you opposed to putting "conventially-named" functions for streams in a separate namespace?
10:51Chousermap<< is my new favorite
10:51rhickeygnuvince: 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:51gnuvinceah
10:51gnuvinceDidn't know that.
10:52rhickeygnuvince: there might even be a single macro that defines both a stream and seq version in one shot
10:52Carkif smap is rejected i'd go for map<< too
10:52gnuvinceSo the seq functions are going to lose their nice functional, recursive definition in favor of something more iterative?
10:52jayfields(doc var)
10:52clojurebotNo entiendo
10:52cemerickrhickey: looking at clojure.org/streams, your original thought of map*, etc. looks really good.
10:53rhickey(def map #(sequence (map-stream %1 %2)))
10:53Chouserjayfields: var is a special form: http://clojure.org/special_forms#var
10:54jayfieldsChouser: thanks.
10:54rhickeymap*, map+, map= or map<< ?
10:54rhickeymap1 map-1 maps
10:54Chousermap* says nothing, and the * suffix is occasionally used elsewhere
10:54gnuvinceAny reason for <<?
10:55rhickeygnuvince: implies piping
10:55cemerickhuh, map+ is nice
10:55Chousermap= looks too much like it's related to equality, I'm afraid.
10:55gnuvincerhickey: piping the elements into f?
10:55cemerickisn't +name+ used as some kind of convention in CL?
10:55cemerick(not that that would be a reason to not use map+, etc)
10:55rhickeygnuvince: just being part of a pipeline, that really is the analogy, there is also tap now
10:56Chouserthe 1 suffixs I dislike because they might imply taking only the first rather than taking each thing only once.
10:57gnuvinceHas any other Lisp (or another language like Forth or Factor) implemented something like this and decided on a convention?
10:57Chouserso of those, I think map+ and map<< rise to the top.
10:57rhickeyChouser: you might read it 'once', works like macroexpand-1
10:57rhickeypeople coming from other langs might not see foo<< as one symbol
10:58Carkyou don't have to put a warning in the name of your function, that's what docs are for
10:59tashafahow do i make a thread sleep in clojure
10:59tashafa?
10:59cemerickmap+ and map* are my preferences, FWIW
10:59tashafa(java.lang.Thread/sleep n) doesnt seem to work for me
10:59thickeymy 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:00ChouserI 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:00thickeynot loving map<<
11:00rhickeymap<-s, filter<-s
11:00rhickeymap-s, filter-s
11:00cemericktashafa: that's the right function....
11:01rhickeymap*s, filter*s
11:01Carkchouser : yes at that rate someone looking at read-file would think we're doing a substraction
11:01cemerick(* "ugh" 6)
11:02Chousertashafa: that takes milliseconds, so (Thread/sleep 1000) should be noticable.
11:02tashafacemrick: hmm, it doesnt throw any errors, but would using it in a doseq change teh behaviour?
11:03Chouserthickey: any particular reason?
11:04leafwrhickey: 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:04cemericktashafa: 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:04thickeyChouser: they share a lot of letters
11:04RadioApeShotSo (.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:04thickeyChouser: oh, did you mean for not liking << ?
11:05Chouserthickey: yes
11:05cemerickRadioApeShot: you want .start, not .run
11:05tashafaok my bad...it does work
11:05Chouserah! my fault, sorry.
11:06RadioApeShotcemerick: Thanks.
11:06tashafathanks all
11:06RadioApeShotMy java is rusty
11:06thickeyChouser: 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:06leafwthickey: << is a c++ thinguie, really.
11:07leafwwhich has meaning around the concept of streams.
11:07Carkgreat let's plunder c++ ...was good for java, might be good for clojure as well =P
11:07cemerick<< is a bit shift to me *shrug*
11:07Chouserbut not in clojure
11:07leafwcemerick: that too xD
11:07rhickeydoesn't << imply piping to anyone?
11:08leafwrhickey: to me. But map<< reads funny
11:08cemerickrhickey: not really
11:08rhickeyok
11:08cemerick<- perhaps
11:08cemerickbut that's bad for other reasons
11:08rhickey<-map, <-filter
11:08Chousersure, << implies a direction of flow. I like filter<<
11:09AWizzArdsmap, sfilter, sreductions
11:09cemerickrhickey: if those are options, why not just use smap, sfilter
11:09leafwhow about map$ where $ is for stream. Or is the $ used for something else?
11:09leafwalso, it makes it stand out a lot.
11:10Chouserleafw: "< rhickey> Chouser: no, but $ is totally unused and could thus b
11:10leafwmap* read like a pointer. map+ reads like "something more than map"
11:10Chousere used for something really special down the line"
11:10AWizzArdrhickey: 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:10rhickeyJust 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:10Chouserew. sorry.
11:10Chouserleafw: pointer!?
11:10leafwChouser: sorry, started with C long ago.
11:10cemerickheh, I didn't think about the pointer interpretation at all
11:11Chouserleafw: me too, but it's not a syntax I come close to thinking about here. :-)
11:11cemerickfn* is pretty standard for a slightly modified version of fn in various lisps, which makes sense
11:11leafwChouser: well, just an impression :)
11:11Chousermy main argument against * is that it's used several other places to mean non-stream things.
11:11leafwcemerick: but is map* a modified map in the same way that fn* is a modified fn? Or an altogether different modification?
11:12Chouseraltogether different, which is my argument
11:12leafwI agree Chouser
11:12AWizzArdcan 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:12Chousera + suffix is equally unmeaningful, but at least unique within clojure.
11:12cemerickAWizzArd: oh, no, please, no
11:13ChouserAWizzArd: huge breaking change!
11:13AWizzArdof course
11:13cemerickChouser: in that case, smap and sfilter should be it, sort order be damned.
11:13thickeyChouser: good argument against *
11:13AWizzArdcemerick: yes, I like these prefixes also more
11:13leafwmap-s reads most natural, but honestlym it would already break some of my code: I have vars named like that
11:14leafwsmap would do it for me too -- reads like "stream map", and it's an unlikely name for a var.
11:30achim_phmm, what about putting the stream variants in a separate namespace. people could alias it to their liking, even (require '[clojure.streams :as <-])
11:31AWizzArdthat was what gnuvince suggested
11:31AWizzArdscroll up to see rhickeys questions regarding that
11:31achim_poops, sorry
11:32gnuvinceachim_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:35Chouserand that you can only alias one namespace to <- even if you want stream functions from several different libs
11:35achim_pi see
12:24hiredman~latest
12:24clojurebotlatest is 1326
12:29hiredmanhmmm
12:44hiredmanr1006
12:47hiredman~latest?
12:47clojurebotlatest is 1326
12:48rhickeyI'm currently partial to map* and filter*, I don't see the prior usage of blah* as being part of the public interface
12:50rhickeycould just as easily be fn-special-op, let-special-op
12:50rhickeyno one uses them directly
12:58cemerickrhickey: I actually didn't realize that fn* et al. existed until I started spelunking with macroexpand
12:58cemerickbut yeah, changing those forms to something without the trailing asterisk would make sense
12:58cemerickI actually use the * convention for a couple of "alternative" fn implementations already.
13:01jayfieldsis there a function that lets me verify if an argument is in a seq, e.g. (any? [1 2 3] 1)
13:02achim_pjayfields: (some #{1} '(1 2 3))
13:02jayfieldsthanks
13:02achim_pjayfields: contains? is faster for vectors and sets, doesn't work on lists
13:02hiredman,(.contains '(1 2 3) 1)
13:02clojurebottrue
13:02cemerickjayfields: to be clear #{1} creates a set that contains a single member (1) -- and sets are fns of their contents
13:03cemerick,(#{1 2 3} 3)
13:03jayfieldswhere is contains? defined?
13:03clojurebot3
13:03hiredmanmight be in contrib
13:03jayfieldscool. thanks.
13:04achim_pcontains? is in core ...
13:04hiredmanoh
13:04hiredman~def contains?
13:04hiredmanI guess that is where it is defined
13:04achim_pargh, contains doesn't work for vectors, forgot that
13:05danlarkinachim_p: it does! but not how you thought
13:05achim_pyeah
13:05achim_pcontains? is "contains key?"
13:05danlarkinya
13:06hiredmanso 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:06danlarkinachim_p: you probably want (some #{k} coll)
13:09achim_pdanlarkin: yeah, i was replying to myself replying to jayfields ;)
13:10danlarkin:-o
13:10danlarkinI have a bad habit of not reading my whole irc buffer
13:15shoovercemerick: true, as long as you don't have nil as a value in the set
13:18shoovereven then it's true, I suppose, but hard to distinguish
13:18shoover(to mince words with myself)
13:30sohailhey anyone here know how to pass -Xlint:deprecation through maven?
13:49cp2anyone here have experience with couchdb? im wondering how it is, if you like it, etc
13:50eevar__,(use 'clojure.contrib.lazy-seqs)
13:50clojurebotjava.io.FileNotFoundException: Could not locate clojure/contrib/lazy_seqs__init.class or clojure/contrib/lazy_seqs.clj on classpath:
13:50eevar__(doc primes)
13:50clojurebotExcuse me?
13:50eevar__m(doc primes)
13:50eevar__,(doc primes)
13:50clojurebotjava.lang.Exception: Unable to resolve var: primes in this context
13:51digash``cp2: i'v heard from not unbiased developers for mongodb that couchdb is very slow.
13:51cp2heh
13:52cp2ok, ill change the question then
13:52cp2any "clojure-friendly" database api/whatever
13:52ChouserRich was talking about the state of mongodb recently.
13:53cp2heh
13:53cp2thanks
13:53digash``mongodb guys have couple of different java apis
13:53cp2i may end up using clojureql in the end
13:53cp2but im open to other options
13:53digash``and they are willing to cooperate to make it much more clojure friendly when i've talked to them.
13:56eevar__how hard is using plain jdbc from clojure?
13:57digash`pretty straight forward, i've wrote number of scripts to "massage" databases.
13:57Chousernot bad, plus there's clojure.contrib.sql for a fairly thin wrapper, or clojureql for a bit more abstraction.
13:58cp2does contrib.sql / clojueql have support for more than just mysql? (as in sqlite, mysqli, etc)
13:59ChouserI believe contrib.sql will work with whatever, but doesn't hide the differences in SQL syntax.
13:59eevar__database independence is a pipe dream anyway
13:59Chouserclojureql attempts to hide those differences as well, and supports a couple databases.
14:00cp2yeah, im not too worried about being database independent
14:00cp2i just dont want to _have_ to use mysql
14:00Chousereevar__: 100%, sure, but even independence for 80% of your db interaction can be a big win.
14:00cp2Chouser: thanks for the info
14:00eevar__dunno. I'd rather pick one db and marry it ;)
14:00Chouserhm.
14:01digash`i think jdbc does abstract quite a bit compare to libmysql.so
14:02eevar__should I ever come across somethign postgres can't handle, i'm sure there's plenty of $$ floating around for oracle/db2 porting
14:03eevar__i do use embedded db's a times, tho
14:04eevar__but only for small hackish things that are easily ported to pg if neccessary
14:11hiredman~latest contrib?
14:11clojurebotlatest contrib is 334
14:11hiredmanclojurebot: latest contrib is 570
14:11clojurebot'Sea, mhuise.
14:23dcnstrcthas anyone here had any success using CouchDb4J ?
14:24dcnstrctfor some reason I can't get it to execute views although it works fine for CRUD on individual documents
14:27dcnstrctnvm I just found jcouchdb a different library.. and it works
14:36tashafalook into clj-record
14:36tashafahttp://github.com/duelinmarkers/clj-record/tree/master
14:52cemerickhrm, using delays in maps makes determining equality a little tricky
14:53dcnstrctclj_record looks badass, maybe I can augment it to add couchdb support
15:04danlarkindcnstrct: some sort of ORM-ish type thing with couchdb backing is on my (ever growing) todo list
15:05danlarkinmaybe you could strike it off for me!
15:06dcnstrctsounds like a plan, but don't hold your breath ;)
15:12gnuvinceWas anything decided for streams?
15:16gnuvincels
15:18cemerickgnuvince: I think map* is in the lead, last I saw
15:22gnuvinceok
15:29StartsWithKi have in one file (gen-class :name net.ksojat.neman.swing.Wrapper ..) (defmethod patch [net.ksojat.neman.swing.Wrapper ..] ...)
15:29StartsWithKbut i get a error that net.ksojat.neman.swing.Wrapper dosn't exist
15:30kotarakDid you compile the containing namespace?
15:30StartsWithKwhat should i do to make it work?
15:30StartsWithKyes
15:30hiredmanis it in your classpath?
15:30StartsWithKyes
15:31StartsWithKthat part is ok im sure
15:31hiredmanlets see the stack trace
15:32StartsWithKit says that when i try to run example from repl, not when i compile the code
15:34hiredman(.printStackTrace e*)
15:34hiredmanoe *e
15:34hiredmanr
15:34hiredmanwhatever it's named
15:35StartsWithKhttp://paste.pocoo.org/show/106759/
15:36hiredmanhow do you know the compiled class is in your classpath?
15:37StartsWithKbuild generates my repl script to reflect any changes i made to classpath
15:37hiredmanso your *compile-path* is in your CLASSPATH?
15:37StartsWithKyes
15:37hiredmanreally?
15:38Chouseryou should be able to say net.ksojat.neman.swing.Wrapper at the repl before you 'load' anything
15:38StartsWithKyes
15:38hiredmanwhat does (System/getProperty "java.class.path") say?
15:39StartsWithKChouser: that fails too
15:39ChouserStartsWithK: 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:41StartsWithKhiredman: http://paste.pocoo.org/show/106762/
15:42StartsWithKhmm, but java.class.path says it is, and swing/target/classes has that class
15:45hiredmanStartsWithK: was it generate before or after you started your repl?
15:46StartsWithKhiredman: before
15:46StartsWithKand just in case i regenerated repl script
15:47hiredmanare all your namespace declarations correct?
15:48StartsWithKyes
15:48kotarak@rhickey: AOT compilation uses metadata of namespaces.
15:48kotaraks/uses/looses
15:49StartsWithKonly thing that is not compiled is test file
15:50Chouser(let [p #(.getAbsolutePath (java.io.File. %))] (filter #{(p *compile-path*)} (map p (.split (System/getProperty "java.class.path") ":"))))
15:51ChouserStartsWithK: what does that return? ^^^
15:51kotarakStupid question: How do I use *warn-on-reflection*?
15:51Chouserkotarak: not stupid! set it true before you evaluate some (defn ...) forms.
15:52StartsWithKChouser: from repl? (), but i don't have *compile-path* for repl, only for compile target
15:52Chouserhm, ok.
15:52kotarakSo must it be source file or do compiled files also work? (read: (set! ...) (require 'foo.bar) ?
15:53Chouserkotarak: the warnings are generated at compile time, not at runtime
15:53Chouserso in that example, if foo.bar is not compiled, it should work.
15:53Chouserbut if foo.bar is loaded from a .class file, you'll get no warnings.
15:54kotarakAh ok. I need gen-class, though. Can I set the warn flag also when compiling? Some -Dclojure.warn-on-reflection=true magic?
15:55Chouseras far as I know there's no property you can set, but you should be able to use (set! ...) and then compile.
15:57kotarakChouser: 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:57kotarakChouser: thanks. :)
15:58Chouserhmph
15:59StartsWithKthis 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:02StartsWithKah, and line 24 is line 16 in the paste, didn't include the header..
16:05kotarakCan I somehow tag the :state part of gen-class?
16:06StartsWithKtag how?
16:07StartsWithKit 'works' now, but i included generated jar in classpath, and not directory with generated .class files
16:07StartsWithKwhy should that make any difference?
16:11kotarakStartsWithK: 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:11kotarakBut maybe I just the "usual" functions instead of the methods directly...
16:13Chouserah, 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:19fandahello!
16:19fandai have a question about "contains?"
16:19fandahow does it work with lists?
16:19fanda,(contains? '(1 2 3) 1)
16:20clojurebotfalse
16:20fandais this a bug?
16:20hiredman,(doc contains?)
16:20clojurebot"([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:20hiredman"it will not perform a linear search for a value"
16:20fandaoh, I see
16:21hiredmanChouser: could you commit something to contrib?
16:27fandahiredman: are you testing some functionality?
16:27fandaI could commit something too
16:28hiredmanthat would be cool
16:28hiredmanYes
16:30kotarakcool. one can also tag %1 in a #() :)
16:31fandanew test for "find" commited
16:31hiredman*tada*
16:31Chousernice
16:32fandayes, looks nice
16:37RaynesTo iterate is human. To recurse is divine
16:37fanda:-)
16:38hiredmanah, well, the recurse in instant space is divine
16:38hiredmanto
16:38hiredmanconstant
16:38hiredmanugh
16:52fanda:-)
16:53hiredmanI think I fail at twitter
16:54fandawhy is that?
16:55hiredmanfanda: it seems simple, but for some reason clojurebot's tweets are not working correctly
16:56hiredmanI blaim that fact that I am shelling out to curl, so I think I'll go find some java code
16:57fandahiredman: it's always good to have more options :-)
16:59fandarhickey, Chouser: I believe that Clojure issues 55 and 76 could be solved now.
16:59fandahttp://code.google.com/p/clojure/issues/list
16:59fandaThey were waiting for Timothy Pratley to sign and send his CA, but that looks done:
16:59fandahttp://clojure.org/contributing
17:01Chouser55 is already fixed, but the issue needs to be marked, I guess.
17:02Chouser,(repeat 5 9)
17:02clojurebot(9 9 9 9 9)
17:03fandareplicate hasn't been removed, though
17:29Drakesonis 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:30Chouseryou might find something useful in clojure.contrib.walk, but I'm not sure.
17:32dcnstrctcould 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:33dcnstrct (. *db* createDocument {:foo "bar"}) returns this: java.lang.UnsupportedOperationException (NO_SOURCE_FILE:0)
17:33dcnstrctI 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:34dcnstrctif so what debugger would you recommend (I'm on OSX)
17:34DrakesonChouser: thanks, that's like what I was looking for.
17:35dcnstrctforget the jcouchdb part of the question... I just want to know the name of a good java debuger (I'm new to java)
17:36hiredmandcnstrct: the db must be trying to mutate the imutable clojure hash
17:36dcnstrcthiredman, ah ha!
17:37dcnstrcthiredman, yes it is.. it's trying to add a couple properties to it
17:37hiredman:(
17:37hiredmanhow unfortunate
17:37dcnstrcthiredman, is there a way I can turn the clojure hash into something more maleable before I pass it in ?
17:37hiredmansure
17:39hiredman,(java.util.HashMap. {:a 1})
17:39clojurebot#<HashMap {:a=1}>
17:40dcnstrctit works!!! thank you you saved the day
17:45hiredmanugh
17:45hiredmansilly sun, not including Base64 encode/decode in the jdk
17:47Chouserso now after starting up a plain repl, you can run (add-break-thread!)
17:48Chouserafter that, Ctrl-C should break you out of any infinite loop and return you to the repl.
17:48ChouserI don't know what it'll do in slime/swank or any other unusual repl
17:48Chouserand even in a plain repl there may be odd consequences, since it's using Thread.stop()
17:49Chouser...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:20keithbIs there a way to write a function that returns something that it lazily initializes
19:20keithb?
19:21keithbI'm finding that I need some objects to be available in various parts of a program. Is it better to use def?
19:23mrsolohm how come there is not-any? but not any?
19:24keithbmrsolo: some?
19:24durka42what he said
19:24mrsoloah
19:24hiredmanmrsolo: because there was 'some' and someone wanted 'not-any' and bitched until they got it
19:25mrsolo..
19:25keithbI withdraw my previous question...
19:25hiredman~def not-any?
19:26Raynes(doc not-any?)
19:26clojurebotReturns false if (pred x) is logical true for any x in coll, else true.; arglists ([pred coll])
19:26Raynes(doc some)
19:26clojurebotReturns 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:26RaynesWell...
19:26hiredmannot-any? is literally the composition of not and some
19:27RaynesTsk.
19:28keithbI 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:28mrsolooddity that's all since there are empty and every?
19:28hiredmankeithb: pastbin
19:29Raynespaste.pocoo.org or paste.lisp.org O.O
19:29durka42~paste
19:29clojurebotlisppaste8, url
19:29lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
19:29Raynesdurka42: Thanks for not insulting my code, I know you wanted too :p.
19:30durka42Raynes: i was just puzzled while i was trying to reverse-engineer your input format from the code :)
19:31RaynesI know the code sucks though anyways :|
19:31durka42i 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:32RaynesThat was a break-code-up-into-smaller-functions-and-dont-format accident.
19:32durka42hmm, someone should write a clojure refactoring tool :p
19:32lisppaste8keithb pasted "Entire Program" at http://paste.lisp.org/display/76599
19:33keithbThat's the whole thing; I'll try to pare it down now...
19:33lisppaste8Rayne@acidrayne.net pasted "new keyvalue reader" at http://paste.lisp.org/display/76600
19:34RaynesI 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:34durka42"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:35durka42keithb: it's clear-action on line 114 you're asking about?
19:38keithbdurka42: yes
19:39lisppaste8keithb annotated #76599 "untitled" at http://paste.lisp.org/display/76599#1
19:42durka42keithb: it's true that fahr-text-field isn't bound until you call create-text-fields
19:43keithbdurka42: Yes, I know. My question is about the timing of the access to fahr-text-field in the fn.
19:43duncanmi have a list of names (let [name "x" names `(name ~name)] (for [n names] (println n))) --> this prints (nil nil)
19:43duncanmshouldn't it print "name x"
19:43duncanm?
19:44durka42keithb: 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:44keithbdurka42: 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:44keithbdurka42: Oh..
19:45durka42duncanm: for is lazy. for me it prints:
19:46durka42Clojure=> (let [name "x" names `(name ~name)] (for [n names] (println n)))
19:46durka42(clojure.core/name
19:46durka42x
19:46durka42nil nil)
19:46durka42use doseq if you want a more "traditional" for loop
19:46durka42for is not a "for loop", it is more of a list comprehension
19:46duncanmhmm
19:46duncanmall i'm looking for is something like FOR-EACH in Scheme
19:47keithbdurka42: 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:47gnuvince_duncanm: doseq
19:47gnuvince_(doseq [element sequence-of-things] (println element))
19:48lisppaste8durka42 pasted "keithb" at http://paste.lisp.org/display/76601
19:50keithbdurka42: Thanks. Great job of reducing the problem...so it looks like I have to include an accessor method.
19:50keithbThat's why I was wondering before about lazily initializing the thing within that accessor method. Possible?
19:50durka42i'm not sure what you mean by lazily
19:51keithbdurka42: 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:52durka42oh, i suppose you could do that
19:52durka42but isn't this an event handler function?
19:52durka42so you would want the text fields to be created before that
19:52keithbdurka42: It doesn't really matter when they're created...they don't rely on any context.
19:54durka42but you will need them to be created so they can be shown onscreen...
19:56lisppaste8keithb annotated #76599 "Java lazy initialization method" at http://paste.lisp.org/display/76599#2
19:56keithbdurka42: This is what I would like to do in Clojure.
19:56durka42that looks doable
19:57durka42(if fahr-text-field fahr-text-field (create-text-field))
19:57keithbdurka42: I think I just figured it out... def it to nil in the beginning, and then, what you said. ;)
19:57durka42(or fahr-text-field (create-text-field))
19:58keithbdurka42: ...except you want to hold onto the newly created thing in the variable, so you only ever create one of them.
19:58durka42well, that's what the (if) or the (or) does
19:59keithbok, I'll write something up and run it by you. THanks much.
20:01AWizzArdgnuvince_: is there a descision about the streams now?
20:02gnuvince_AWizzArd: I don't know, I've been away most of the afternoon and evening
20:19lisppaste8keithb annotated #76599 "untitled" at http://paste.lisp.org/display/76599#3
20:20keithbGot it... it was an extra set of parens!!!!
20:26durka42oh, i see
20:26durka42nice work
20:30lisppaste8keithb annotated #76599 "untitled" at http://paste.lisp.org/display/76599#4
20:31keithbGiven 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:33Chouser(if foo foo bar) is the same as (or foo bar)
20:33Chouseroh, wait.
20:33Chouserwhat are you doing?
20:34keithbChouser: I'm writing accessors that lazily initialize the thing they access.
20:34keithbThey'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:35Chouserhm, there are a few options...
20:35Carkdef inside a function ...that's ugly
20:37hiredmankeithb: sounds like you want futures
20:38keithbThe 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:38hiredman(doc future)
20:38clojurebotTakes 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:38Chouserdelay is probably closer to what you want, unles I'm misunderstanding.
20:40hiredman~def delay
20:40keithbChouser: Thanks! I think delay is what I want; an additional thread is overkill.
20:40lisppaste8Chouser annotated #76599 "close over a delay" at http://paste.lisp.org/display/76599#5
20:44keithbChouser: 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:45lisppaste8keithb annotated #76599 "untitled" at http://paste.lisp.org/display/76599#6
20:45keithb...something like the thing I pasted, which could maybe be expanded to your delay/force code, which would in turn be expanded?
20:45keithbI haven't learned macros yet...
20:45Chouseryep, sure could
20:46Chouserlooks like a great one to start with.
20:46keithb:)
20:46keithbOk, for another day...thanks for all your help.
20:46ChouserI'm not kidding. I'm guessing you haven't bought Halloway's book?
20:46Chouseroh, ok. you're welcome.
20:47keithbYes, I have...I've been using it.
20:47keithbBut only read some chapters so far.
20:48keithbI 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:50Chouserah, great. The chapter on macros should be just right for this example.
20:50keithbChouser: So where is the cached value stored?
20:50keithbMetadata?
20:50Chousernope, it's cached inside the delay object, which is held by x
20:51keithbAh, it's a Java object?
20:51Chouserx is held inside the function (a.k.a. closure) created by #()
20:51Chouser,(class (delay))
20:51clojurebotclojure.lang.Delay
20:51hiredmanhttp://twitter.com/clojurebot/status/1291166090 <-- so this kind of works
20:53keithbChouser: 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:53tehello all
20:53Chouserkeithb: no, it's independent of that. I'm pretty sure Ruby has closures...
20:53teIs it possible to create a function that renames itself?
20:54keithbChouser: I believe in Ruby any code block, lambda, or proc is a closure.
20:54keithbOh, I think I get it...
20:54tekeithb: im not sure if that's true
20:54telambda and proc behave differently
20:54hiredmante: that sounds like mutation
20:54keithbte, do tell...
20:54Chousermy ruby is really rusty...
20:55teiif you use lambda inside a block it will not continue past the point in the block that it occurs
20:55teproc will return the value of the block it exists inside
20:57hiredmanthat is really weird
20:57tei cant remember for sure if its like that or vice versa
20:57hiredmanhttp://samdanielson.com/2007/3/19/proc-new-vs-lambda-in-ruby
20:57tethis may h ave changed in 1.9 also
20:59keithbFrom the pickaxe book, it sounds like both code blocks and Procs are closures: Associated with a block (and hence a Proc object)
20:59keithbis all the context in which the block was defined: the value of self and the methods,
20:59keithbvariables, and constants in scope. Part of the magic of Ruby is that the block can still
20:59keithbuse all this original scope information even if the environment in which it was defined
20:59keithbwould otherwise have disappeared. In other languages, this facility is called a closure.
21:00teoh yeah im sorry
21:00tei forgot that lambdas are basically procs
21:00Chouserf = lambda{ x = 5; lambda { x = x + 1 } }.call
21:00tethey literally are procs
21:00te(lambdas are)
21:00Chouserok, it's a bit like that
21:01Chouserf.call returns the value of x (it also mutates it, but that's not my point)
21:01lisppaste8slashus2 annotated #76599 "lazy-init" at http://paste.lisp.org/display/76599#7
21:01keithbok, I'll leave it at that...my head's exploding... ;)
21:01teif you define f = lambda{ puts "hello" }
21:01teand do f.type
21:01teit's type Proc
21:01slashus2keithb: Does that work?
21:01Chouserwhere is the int stored? inside the x that is held by the inner lambda
21:02teChouser: what that a question and answer
21:02teor a question?
21:02keithbslashus2: You mean the delay strategy? Yes.
21:02slashus2keithb: That macro?
21:02Chouserkeithb: congrats, it's a macro! :-)
21:02keithbslashus2: Sorry, I didn't see your pastie. Tyring it now. Chouser, that wasn't me. ;(
21:02Chouserte: sorry, rhetorical device. yes, question and answer.
21:03teah cool just checking
21:03Chouseroh
21:03Chousersorry
21:04Chouserslashus2: you've got a few more args than you need.
21:04Chouserman, irb really hates it when I paste in clojure code
21:04teCan you create a function that renames itself?
21:04teIs that possible?
21:04teChouser: haha
21:05hiredmante: that sounds like mutation
21:05tehiredman: could you elaborate please:?
21:05Chouserte: functions don't really have external names
21:05teexternal in reference to what?
21:05Chouserexternal to itself
21:06tehmmm thats hard to understand
21:06tecould you explain what you mean
21:06hiredmante: you would have to mutate the symbol that names the var that resolves to the fn
21:06Chouseryou could say that (fn foo [] ...) is called foo inside (where the ... is), but that form returns an anonymous function.
21:06hiredmanand symbols are not mutatable
21:06keithbslashus2: Can you tell me how I would call lazy-init?
21:07Chouseryou can have multiple Vars or locals pointing to the same function
21:07tecould that become dirty if i did it too many times?
21:07slashus2keithb: exactly how yous specified
21:07hiredmandirty?
21:07Chouserkeithb: the opportunity to justifiably write a macro is pretty rare. I'd ignore solutions posted by others and do it yourself. :-)
21:07tehiredman: could it impact performance?
21:08keithbChouser: I hear you. Thanks, everyone. I'm going to call it a night. Beer and karaoke for me. Woohoo!!! ;)
21:08tehiredman: sorry im just poking around -- i dont mean to ask 10,000 questions
21:08hiredmanI dunno about perf, but it would impact "does this program make sense"
21:08slashus2keithb: You could ignore mine, but mine does (lazy-init create-a-text-field)
21:09keithbslashus2: So: (def fahr-text-field (lazy-init create-a-text-field))?
21:09slashus2keithb: yeah
21:09tehiredman: im interested in renaming functions according to metadata inside the function
21:09keithbslashus2: Cool.
21:10hiredmante: without hearing and explanation I am going to tell you: that makes no sense
21:10hiredmanan
21:10hiredmanbesides
21:10hiredmanfunctions cannot currently have metadata
21:11teim sorry man maybe im using the complete wrong way to explain this
21:11Chouserbut Vars can, and you could make a new Var pointing to the same fn based on the metadata of the old Var.
21:11keithbslashus2: It works. Well done! Chouser, I'll look into reimplementing it myself later when I learn macros. Thanks everyone!
21:11ChouserNot sure why you'd do that, though.
21:12Chouserte: where would the metadata come from?
21:12teIt would change based on the input
21:12tefor the function
21:12hiredman:(
21:14tei 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:14teso "Red house dog cat" would match functions whose meta includes house and cat
21:14Chousermaybe you want a hash-map with strings as keys and fns for the values?
21:14hiredmanwhy?
21:15teim interested in toying with evolution of code
21:16RaynesChouser: hash-map is my newest favorite function.
21:16tethe idea is to age tags that satisfy the combination of functions to give a correct answer
21:16teor an interesting one, at least
21:16hiredmante: why would you even name those funtions?
21:16hiredman(name in the sense of symbol->var->fn)
21:17tei 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:17tehiredman: consider "design space"
21:17Raynes(apply hash-map ..) <3
21:18tewhere design space is this space that contains every single possibility for design
21:18hiredmante: I refuse to consider something so broad
21:18tefrom a toaster to soil to a ferarri
21:18hiredmanand it's dinner time
21:19tehiredman: im just trying to start with a number of possible designs that are necessary to create new designs
21:19teand then evolve them to see what i can come up with
21:25slashus2Chouser: I don't think that a macro was needed for that lazy-init. I rewrote it as a function, and it works correctly.
21:26Chouserslashus2: it would have to be a macro if you wanted to provide arbitrary expression rather than a fn.
21:27Chouserlike his example: (lazy-init (create-a-text-field))
21:27slashus2oh, okay
21:28slashus2~expr in the place.
21:28clojurebotIt's greek to me.
21:28slashus2woops
21:30rlbDoes 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:30slashus2Chouser: Thank you, I didn't see the potential for entering an expression.
21:31Chouserslashus2: sure, np.
21:31slashus2It was actually easier to write that way.
21:35rlbMore 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:36rlbouch s/spefically/specifically/ s/wonding/wondering/
21:36Chouserhard to say for sure. you don't need print-dup i hope?
21:37rlbprint-dup?
21:38Chouser,(binding [*print-dup* true] (pr-str [1 2] #{3 4} (sorted-set 5 6))
21:38clojurebotEOF while reading
21:38rlbActually, 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:39Chouser,(binding [*print-dup* true] (pr-str [1 2] #{3 4} (sorted-set 5 6)))
21:39clojurebot"[1 2] #{3 4} #=(clojure.lang.PersistentTreeSet/create [5 6])"
21:40rlbBasically 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:41Chouserthat's unlikely to change, I would think, but you'd want some way to recover if strings get escaped slightly differently or something.
21:41rlbAnd 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:42rlbChouser: 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:42Chouserthat might work.
21:42rlb(where "breaks" means changes output format)
21:42Chouserright
21:42rlbChouser: anyway, that seems like a fast way to get started -- thanks for the help.
21:43rlbI'll just add "make check" tests to look for variations.