#clojure logs

2011-05-25

00:07mefesto`is there a function in core that does the equiv of 'call ? https://gist.github.com/990307
00:07amalloymefesto: ((:do-this callbacks))?
00:07mefesto`or contrib for that matter...
00:08mefesto`amalloy: but handles the nil case
00:08offby1In traditional Lisp, it'd be called "apply"
00:08amalloyoffby1: untrue. in CL it'd be called funcall
00:08offby1oh.
00:08amalloyapply, which exists in clojure, unrolls the last argument as a list
00:09Raynes(-?> callbacks :do-this) ; Doesn't that do something similar?
00:09amalloyRaynes: nah
00:09RaynesWell, if you wrap it in an outer layer of parethesuzes.
00:09RaynesI know it does something with nil.
00:09amalloyif my patch to -> had been accepted, then (-?> callbacks :do-this ()) would work
00:10mefesto`working on some gui stuff so the usage would be like: (login-prompt :ok-clicked on-submit :cancel-clicked on-cancel)
00:11amalloymefesto`: you can use .invoke, though
00:11Raynesmefesto`: If you're working on Swing stuff, check out http://github.com/daveray/seesaw
00:11mefesto`amalloy: refering to the invoke-later stuff?
00:11amalloy(-?> callbacks :do-this .invoke) ; using clojure.contrib.core/-?>
00:11RaynesI bet you it's a thousand times better than what you're already doing.
00:13mefesto`cool thanks guys
00:18tomojanyone know how cljque is different from lamina?
00:20amalloyscores way better at scrabble
01:33dnolenerg 1.2.0 / 1.3.0 math differences seem unreconcilable, I guess there's just no way to do a conditional compilation?
01:34dnolenirreconcilable I mean.
04:15markomanwhat is this error: java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.Associative
04:17Chousukemarkoman: looks like you're trying to use a keyword where a map should go
04:17Chousukeperhaps you've accidentally done something like (get :key map)
04:17hiredmanthat actually will not throw any exception
04:18hiredman,(assoc :foo :bar :baz)
04:18clojurebotjava.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.Associative
04:18hiredman,(get :key {})
04:18clojurebotnil
04:18Chousukehmm, yeah
04:18Chousukeforgot about that
04:19markomanim using several assoc and assoc-in functions so they could have the problem?
04:22markomani made a big change on codebase and got some errors, but debugging is pain
04:30danbellhey, is there a function that would give the result of a value passed through a function n times?
04:31danbellas in (stacker f n val)
04:33amalloydanbell: ##(doc iterate)
04:33sexpbot⟹ "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"
04:33danbellah, forgot about iterate
04:34amalloythen you can use nth on that if you want it called specifically n times
04:34__name__iterate is awesome.
04:35danbellit would be less memory-efficient than a loop, though
04:44amalloydanbell: why do you think that?
04:45danbelldoesn't it have to store all index < n results?
04:45danbellwhereas a loop discards them?
04:45amalloyno
04:45amalloyit's lazy; it can immediately throw away the previous result when nth discards it
04:46danbellREALLY
04:46amalloyREALLY
04:46danbellha
04:46danbellthat's my interest
04:46danbellnot sarcasm
04:46amalloy*laugh*
04:46amalloyanyway, yes, it can
04:46amalloy&(nth (iterate inc 0) 1e7)
04:46sexpbot⟹ 10000000
04:47amalloy&(long-array 1e7)
04:47sexpbot⟹ #<long[] [J@4d76db>
04:47amalloywell, apparently sexpbot has enough memory for 10 million longs. but if he didn't, the former would still work
04:47danbellha
04:47danbellwell
04:48danbellI need to go put in the effort to get accustomed to dealing w/laziness then
04:48amalloydanbell: it's hard to get much done in clojure if you're not lazy
04:52Fossithat's, um, so weird
04:54amalloyFossi: laziness jokes abound if you put in the effort to look for them
05:00amalloydanbell: anyway, have fun. i'm off to bed
05:01danbellthanks, sleep well
05:02raekgood morning, #clojure
05:07__name__HEllo, raek
05:07__name__*Hello
05:31clgvmay it cause a problem if I use a macro to generate a body of an fn like: (list 'fn (mymacro param)) within another macro?
05:32clgvsome how I dont get it to work properly
05:33clgvit says "CompilerException java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol" on the line of the macrocall
05:35raekclgv: you probably don't want to run the macro inside the macro. instead generate code that uses it
05:36raekclgv: but in this case `(fn (mymacro ~param)) wouldn't work very well, since the fn special form does not evaluate the first argument in the usual way
05:37raekfor a function of no arguments, this works: (defmacro wrap-in-fn [body] `(fn [] ~@body))
05:39raekclgv: but, you can use ordinary functions in a macro to build the generated expression: `(fn [~param] ~(myfn param))
06:06Jeffrey04erm, i'm going through Labrepl, and found this (boolean (some #(divides? arg %) nums)) in one of the sample code
06:06Jeffrey04may i know where can i get more explanation on the #(function_name arg %) part?
06:08Jeffrey04?
06:09Dranikthis is a lambda-function
06:09Dranik# -- abbreviation to
06:09Dranikfn [] ...
06:10Dranik% -- is the single argument provided to that function
06:12Jeffrey04@Dranik so the equivalent form would be (fn [] (function_name arg)) ?
06:17DranikJeffrey04: no
06:17Dranikmoment...
06:17Jeffrey04@Dranik sorry, i think the equivalent form for #(function_name arg %) should be (fn [foo] (function_name arg foo))
06:17Jeffrey04?
06:17Dranikyep, I think so
06:17clgvthx, raek. I'll try to get the last suggestion running. as far as I can see it should be possible to make it a function
06:18Dranikjust check it out int the repl
06:18Jeffrey04@Dranik thanks
06:21clgvraek: just a comprehension question: shouldnt `(fn ~@(mymacro param)) work?
06:25Chousukeclgv: that depends. What do you expect it to do?
06:26Chousukeclgv: it works, but it might not do what you think it does :P
06:26clgvraek: oh well, I found the real error. the "mymacro" does some evaluation that is needed to generate the code and this evaluation fails since in the above constellation only the symbol is passed
06:27hoeckJeffrey04: reader macro characters are explained (a bit terse) here: http://clojure.org/reader
06:29Jeffrey04@hoeck @.@ thanks
06:52raekclgv: yes. both `(some-macro ...) and (some-macro ...) are valid and does something and you need to understand the difference in how they are evaluated (the evaluation rules are actually pretty simple)
06:52clgvraek: yeah, I totaly forgot to check evaluation time when I tried to find the error
06:59raekjust remember that the body of a macro works like the body of a function. the macro "function" receives the unevaluated code of its attributes and returns new code that the macro form should be replaced with (and then macro expansion happens again for the generated code until no macros are encountered)
07:00clgvraek: I basically understand macros but sometimes when trying to do something new non-trivial I get caught in a "trap" ;)
07:00raek` (syntax-quote) is just a "template engine" for building nested lists (and other data strucutres) and resolving symbols, and can be used outside defmacros too
07:02raekwhen writing a macro that consists of multiple parts, it can be more useful to define helper functions than helper macros
07:04clgvwhat is the easiest way to use the private clojure.core/assert-args?
07:04clgvor is there something similar somewhere?
07:07clgvI want some checking of the macro parameters like in clojure.core/let
07:10raekclgv: since it is private, you can't really assume that it will be there
07:10raekclgv: it's probably safest to copy it to your own project
07:10raeknot very elegant...
07:10clgvyeah thats why I ask
07:10raekat least, that is how this guy did it: https://github.com/Kaali/pour
07:11clgvthe macro seems nice to have in general.
07:12raekagreed :)
07:18clgvhmm it's still private in 1.3.0-alpha7
07:26clgvfinally it works: ((juxt-map :plus + :minus -) 10 5) => {:minus 5, :plus 15}
07:26clgv:D
07:30clgvhmm I wonder if the order of the arguments is idiomatic...
07:32symboleAre there any resources on hacking the clojure compiler?
07:48bprcan someone help me understand recur a bit better? for example in http://paste.lisp.org/display/122247, why does map become (assoc map k v), (ie. it's not rebound to {}) but yet k and v pick up the new head of keys and values?
07:48bprit seems like recur is evaluating [k & keys] keys
07:48bprand [v & values] values
07:49bprbut not [map {}]
07:49bprto me it seems that the map binding is being treated differently from the keys and values binding
07:50bprbindings*
07:53clgvbpr: they use destructuring to get the first element and rebind the remaining ones to the same symbol
07:53bpri know how k and v are updated
07:53clgvbpr: k = (first keys) and keys = (rest keys)
07:53bpryes i know
07:54clgvwell than what question remains?
07:54bprthe question is, if that's getting evaluated again, then why isn't [map {}]
07:54clgvoh the value on the right is only for initialization
07:54bproh!
07:54clgvit's only assigned the first time the loop is entered
07:55bprcool, ty!
07:55clgvit's a bit tricky here because they use the same symbol names
07:55bpryeah i'm working through labrepl, and i wrote that lol
07:56bprnow i see you can use :as when destructuring
07:56clgvyeah that as well. the full power of destructuring ;)
07:57bprthanks for the help
07:57clgvwriting the loop that way kinda reminds of prolog ;)
07:57bpryeah it does lol
07:57bprthat thought struck me too
07:59ejacksonis there a way to do (import com.foo.*) ?
08:01clgvejackson: last time I checked there wasn't.
08:01ejacksonthis really is itchy now
08:01ejacksonbut that's me being lazy i guess
08:01bpraccording to labrepl it's use i think
08:01bprlet me double check
08:02clgvuse is for clojure namespaces - import for java classes
08:02bproh
08:03bpri missed that distinction
08:22timvisherhey all
08:22timvisheri'm trying to use clojure-jack-in
08:22timvisherand i'm confused as to the behavior i'm seeing
08:23timvisheri'm on "GNU Emacs 23.2.1 (i386-apple-darwin10.6.0, NS apple-appkit-1038.35)
08:23timvisher of 2011-02-25 on ssm-macbook.local"
08:23timvisherI have clojure-mode 1.9.1 installed through elpa
08:24timvisherand when I run clojure-jack-in from my project I get a long buffer about bootstrapping slime and then I get that a server was started but I can't connect to it in any way and I don't get a repl.
08:26bprdo you have slime-repl installed?
08:26timvishernope
08:26bprtry installing that
08:26raekslime-repl comes with swank-clojure, if you use the clojure-jack-in approach
08:26raekso you shouldn't need that
08:26bproh
08:26raektimvisher: did you install the snapshot version of swank-clojure?
08:27raeklike in this tutorial: http://technomancy.us/149
08:27symboleMake sure there's one version of swank-clojure inside .leiningen/plugins. I had an issue where two different versions caused it to fail.
08:29timvisherraek: indeed I did not.
08:29timvisheri didn't know about that tutorial
08:29timvisheri'll go follow that before i bother you guys any more. :)
08:34timvisherthanks so much, kids! that fixed it.
08:34timvisheras always you've been a magnanimous group of devs.
09:06markomanhow do I make (unique [31 32 32]) -> [31 32]
09:07markomanit was some trick with set ...
09:08clgvmarkoman: its called distinct ##(distinct [31 32 32])
09:08sexpbot⟹ (31 32)
09:08raekmarkoman: if you don't need to maintain order, use a set instead of a vector to keep the elements
09:09markomancan I use merge to add item to the set?
09:09raekmarkoman: you use conj
09:10raek,(conj #{1 2 3} 3 4 5)
09:10clojurebot#{1 2 3 4 5}
09:10markomanok, thanks for both
09:40lpetitHi there
09:41lpetitSomebody willing to review some macro code I did ?
09:41raeklpetit: sure :)
09:41lpetithttps://gist.github.com/990975
09:42lpetitShould pretty self-explanatory given the examples
09:42lpetitNow I'm not sure the macro impl is safe from pitfalls
09:45raeklpetit: I've been looking for something like this :)
09:47lpetitWhat 'bout the macro impl.?
09:47lpetit(I'm no macro expert)
09:51lpetitraek: do whatever you want with it
09:51raeklpetit: I think the implementation is clear. I have no objections :)
09:51lpetitraek: feww ;)
09:54raekmaybe I would have used (if (empty? bindings) ...) instead of (if-not result ...), but since result will never be nil in any legitimate use case, I guess it doesn't really matter
09:54raeklpetit: this macro would be nice to have in core.
09:54lpetitargh no, there's a problem. I'm trying to cheat with assert-args but it's not handled as expected, I suspect it's not used as a macro but as a fn, in my current impl.
09:55lpetitFor what usage have you been looking for it ?
09:56raekto be able to do error handling, but with the simplicity of -> or let
09:56raeklpetit: ah, yes. you can't use the var quote trick for macros. you end up calling the underlying macro function as a function
09:57raek(def ^{:macro true} assert-args clojure.core/assert-args) is another workaround
09:57lpetitraek: exactly what I've just added :)
09:57lpetittho #'clojure.core/assert-args
09:58raeklpetit: I would call "result" and "call" something like "binding-form" and "expr", I think
09:58lpetitindeed
09:59imadelet's say I have a function last-but-one, which way is more idiomatic to implement it (last (butlast coll)) or (-> coll butlast last) ?
09:59imadeI have many implementations, but I am wondering if I should use -> more often
09:59raeklpetit: I was thinking of a small variation to your let-unless where handler-fn does is passed 'result' instead of the value returned from error-fn
10:00imadepersonally I find (last (butlast coll)) more readable
10:00raekimade: if the collection is a vector, you can do ##(nth (rseq [1 2 3 4]) 1)
10:00sexpbot⟹ 3
10:01lpetitraek: mmm, you're right, it's an artifact of past versions where error-fn was used in client code to re-check the result of the let
10:01raek,(fnext (rseq [1 2 3 4])) ; or even this
10:01clojurebot3
10:01imadeI think nth is dangerous, (nth [] 1) gives IOB
10:02raeklpetit: I think it is more general if you don't need some value to both convey thruthiness and a value
10:02lpetityes, removing that right now
10:04raekthis is why I sometimes miss algebraic data types in Clojure...
10:05imadein what situations would you use -> if at all?
10:05lpetitargh, assert-args causes some pain ... expanding into a call to itself which then expands to clojure.core/assert-args which then fails
10:05clgvimade: I love it for trying stuff in repl incrementally ;)
10:05lpetitwill cheat with it and call it twice ;)
10:06clgvimade in some cases you can avoid using let to improve readability
10:06imadewell, I think -> might also help sometimes to reduce lots of nested parentheses
10:07raekit's funny. this is the second time today that the problem of assert-args being private has been discussed
10:07imadeclgv, how do you use -> to avoid let?
10:08raeklpetit: if wonder if copypasting in this case might be the most convenient solution...
10:08lpetitwell ...
10:09imadeclgv, I guess I misread, I think you meant that avoiding let in general helps to improve readability?
10:10clgvimade: (let [bla (+ x 2), blubb (/ bla 10)] x) => (-> x (+ 2) (/ 10))
10:10imadeclgv, thanks, that's a good example
10:12clgvimade: in a repl scenario you could now easily add another function call on the result at the end easily
10:21lenwHi all
10:21lenwif I have a list and i want to expand it into a map calling a fn for each entry to get the value what is a neat way to do that ?
10:23opqdonutthere really isn't anything "neat", but you can do something like (into {} (for [val list] [val (f val)]))
10:24opqdonutor if you're feeling tricky, (into {} (map (juxt identity f) list))
10:24imademaybe zipmap can help too?
10:24lenwopqdonut: thanks thats a refreshing way to look at it - i was stuck
10:25opqdonutimade: I don't like zipmap
10:25lenwimade: i cant see that zipmap allows a fn for the val ?
10:25opqdonutespecially I don't like (zipmap something (map f something))
10:25opqdonutbut maybe I'm weird
10:26lpetitraek: new version https://gist.github.com/990975
10:26imadeI'm a beginner, but if you want some specific keys for the map you created, then zipmap could be useful?
10:27lenwimade: yes that example from opqdonut would work for that
10:28imadeyes, opqdonut example is neat
10:29opqdonutwhich one?-)
10:29imadethe first one is more readable for me
10:30imadeI mean the (into {} (for [val list] [val (f val)]))
10:30opqdonutyeah
10:30raeklpetit: I just realized that there could be a probel with destructuring
10:30raek*problem
10:30opqdonutI like that one too
10:30lpetitraek: listening
10:30opqdonutone can always abstract that out as a function that takes f and list
10:31raekmaybe it would be better to replace [... ~binding-form ~expr] with [... value# ~expr, ~binding-form value#]
10:31raekand then send value# to handler-fn
10:32raek'cause it probably gets weird if you try to pass the expression {:keys [a b]} to handler-fn...
10:33raekexample: (let-unless nil? error-fn [[_ as bs] (re-find #"(a+)(b+)" s)] (success as bs))
10:34raekin this case, [_ as bs] happens to be valid syntax for both a destructuring form and an expression
10:35lpetitraek: you're totally right
10:36lpetitraek: that's what happens when one tries to be smart #autobashing
10:37lpetitthanks for all these catches !
10:37raekyour welcome :-)
10:37raek're
10:37faust453
10:41lpetitraek: corrected version:https://gist.github.com/990975/6d5f6bde57e3bae9db24ae5c59c6c385afd547ce
10:43raeklpetit: I guess error# is not needed anymore, so the if-let could be changed into a if
10:43lpetitlpetit => going to bed
10:43lpetit;)
10:43lpetitraek: right again
10:45lpetitraek: cleaned up : https://gist.github.com/990975/cc31874d45256ad184c824997ee2a2b9d0679957
10:47raeklpetit: the last do form is redundant, and maybe the examples need to be adapted to the new usage of handler-fn
10:47lpetitraek: will not have the time to work more on this today
10:48raeksomething like etherpad, but with clojure syntax highlighting would be nice
10:48lpetitraek: indeed
10:50lpetitraek: corrected: https://gist.github.com/990975/595209332e2e4583208b5b39bd696cdf911af1c7 (but examples not updated)
10:57aavlpetit: hi!
11:00cemerickaav: I think he had a meeting starting @ the hour. :-)
11:04aavcemerick: yep. he already told me :)
11:25lonsteindamn I want this... http://cgi.ebay.com/ebaymotors/2008-Honda-XR-650L-MANY-UPGRADES-/320696339261
11:25lonsteinww
11:58Jeffrey04sigh, I am still doing labrepl, is currently doing the mini_browser tutorial, and is getting this error
11:58Jeffrey04ompilerException java.lang.Exception: Unable to resolve symbol: code* in this context, compiling:(NO_SOURCE_PATH:557)
11:59Jeffrey04I tried this but it doesn't work (use 'labrepl.util :only (code*))
12:03symboleJeffrey04: I never used labrepl, but is it in your classpath?
12:05Jeffrey04@symbole it should be, i tried this (use 'labrepl.util)
12:05raekJeffrey04: you are missing the vector needed for options: (use '[labrepl.util :only (code*)])
12:05Jeffrey04and get
12:05Jeffrey04IllegalStateException source already refers to: #'clojure.repl/source in namespace: user clojure.lang.Namespace.warnOrFailOnReplace (Namespace.java:88)
12:06raekJeffrey04: i think sertain vars are already referred in the user namespace (like clojure.repl/source). you could try to enter another namespace than user first: (ns user2)
12:06Jeffrey04@raek thanks @.@ i probably need to sleep now (0006 at my place here)
12:07raekin that namespace, only the vars in clojure.core should be referred
12:07raekJeffrey04: ok. good luck or good night then :)
12:09Jeffrey04@raek thanks, i will probably finish up the remaining things first, still have 3 steps to go :)
12:20dnolenOK core.logic compat with 1.2.X and 1.3.X for real now thanks to Clojure/core.
12:24ejacksonimpressive !
12:24ejacksonthe big guns
13:52amalloyimade: i like (comp last butlast)
13:54gfrlogis there a convenience method for the (first (filter p coll)) pattern?
13:54gfrlog$findfn even? [1 2 3 4] 2
13:54sexpbot[]
13:54gfrlog$findfn [1 2 3 4] even? 2
13:54sexpbot[]
13:55gfrlogI guess that's as good an answer as any. :-/
13:55gfrlogsexpbot: thanks
13:57cemerickgfrlog: depending on what your predicate returns, some can work; otherwise, (first (filter …)) is idiomatic
13:58gfrlogcemerick: good point.
14:07amalloydnolen: (if @cache @cache (other stuff)) is easier to write as (or @cache (other stuff)) if that's your actual code
14:07dnolenamalloy: true, lots of little things like that to fix in core.logic.
14:12ataggartdnolen: unchecked-multiply-int is a horrifically named fn
14:13ataggartI put up a suggestion to create a separate namespace for those to shadow the regular fns
14:13hiredmannamespaces? crazy
14:14ataggartdnolen: btw, why did you use the -int versions?
14:14ataggarthiredman: PHP leads by example
14:15S11001001gfrlog: contrib has find-first
14:15S11001001guess how it's implemented
14:16dnolenataggart: because it's faster. idea lifted from gvec implementation.
14:17ataggartwell crap, I guess that's why those fns are in core.
14:18hiredman?
14:19dnolenataggart: last I recall, rhickey wasn't against what you're suggesting.
14:21gfrlogS11001001: I guess I should remove my implementation of find-first (which is exactly what I called it) and just refer to that one.
14:26amalloygfrlog: i try to avoid using contrib at all these days, with the apparent difficulty of moving from 1.2.x w/contrib to 1.3 with a bunch of libraries representing a subset of what exists in contrib
14:32technomancywell "contrib" as a library is straight up deprecated
14:32amalloyindeed
14:32amalloybut on 1.2.x it's hard to use the modular-contrib libraries
14:33amalloyand not all of them have been promoted. eg, my app depends on prxml, which simply doesn't exist in modular contrib afaict, so i'm stuck on 1.2
14:38ataggartamalloy: data.xml is sitting there waiting to be populated
14:41amalloyataggart: yeah, i saw that
14:44fliebelataggart: What does that mean?
14:44ataggartfliebel: what does what mean?
14:45fliebelataggart: that data.xml is sitting around empty.
14:45amalloyfliebel: data.xml is the new-contrib place for prxml, but nobody's put any code there yet
14:45fliebelUhm, so is prxml jst going to be copied there, or is it waiting for someone to come around and make something awesome?
14:46amalloyfliebel: prxml needs at least some minor fixes to work on 1.3
14:46fliebeloh, okay.
14:46amalloyeg, the vars it rebinds need to be marked as ^:dynamic
14:47amalloyhuh. i had to read that several times before pronouncing it right. it just *looks* french with only one G
14:48amalloythe ar-maj-DOM
14:48amalloyand i'm aware that there's only one G in armageddon; there are two Ds. thanks for the correction, google
14:48fliebelamalloy: Wait, you mean it's.. ah
14:54no_mindraek: there ?
14:55amalloytechnomancy: arrrrr, mage-tron! combining pirates, wizards, and technobabble, this movie has something for everyone
14:59edwtechnomancy: You around? Curious how one idiomatically connects to a remote, already-running swank server under the new clojure-mode regime.
15:02technomancyedw: here's what I use: http://p.hagelb.org/remote-slime.html
15:02technomancyorthogonal to the new clojure-mode
15:02technomancyI should package it up though
15:04edwAh. So it obviates the need for the (insecure) '... :host "0.0.0.0"' in your START-REPL form... Nice.
15:06raekno_mind: yeah
15:07raekno_mind: there are a lot of other people in this channel that knows enlive, so you could just ask the question :-)
15:07no_mindraek: ever used enlive to generate html ?
15:07no_mindraek: ohk
15:07edwtechnomancy: I'm getting a "Symbol's value as variable is void: safe-tunnel-process" error.
15:08raekno_mind: by transforming a template document, yes
15:08edwSould I just setq it to nil?
15:09no_mindI need to generate a form dynamically and wrote some code. Was wondering if someone can review it
15:09technomancyedw: yeah, incomplete paste, sorry. also set safe-tunnel-port to a number
15:10edwAh, like 4005, fer example?
15:10technomancyaye
15:11edwWoot. Thanks!
15:11no_mindhere is the code for generating a html input element http://pastebin.com/M3b8jLs3 Someone please review it
15:11technomancyedw: definitely need to get that into durendal or something
15:13edwtechnomancy: Whoa, that's some crazy shit in there.
15:20technomancyedw: what specifically?
15:25edwCrazy-awesome. I'd like font-lock in the REPL. Got a little enthusiastic there.
15:27technomancythere's a way to do that.... I forget how, but it's in durendal.
15:27edwYeah, that's what I mean. Good stuff in there. Durendal, was that the ship's computer's name in Marathon?
15:28technomancyedw: yup!
15:28technomancyactually it was Durandal, Durendal is an archaic spelling used in order to avoid MS trademark violations. =)
15:28edwAh. I spent a lot of freshman or sophmore year being freaked out by that on my Mac IIsi.
15:29technomancyah yes, the halcyon days when making a player read actual text in a video game wasn't frowned upon.
15:30amalloyi spent a lot of my high school and jr-high immersed in a MUD. probably wouldn't have learned to touch-type otherwise
15:30edwI really enjoyed reading Durandal's musings.
15:32technomancyeverything I know about Latin I learned from Marathon.
15:32technomancyalways appreciated the shakespeare references too.
15:33edwMarathon prepared me to be freaked out by Event Horizon.
15:40raekno_mind: another approach is to make a element with a map: {:tag :input, :attrs {:type "...", :id "...", ...}, :content ()}
15:42edwGrr. How do I tell Emacs which SLIME I want a buffer associated with?
15:42technomancyedw: there's no good answer for that
15:42technomancyI keep separate insntances
15:42technomancyyou can only have one active slime connection at a time.
15:42edwOf Emacs?
15:42raekno_mind: (at <tree> <selector for containing node> (append {:tag :input, :attrs {:type "...", :id "...", ...}, :content ()}
15:42technomancyyeah, separate emacs instances
15:42technomancyI'm crazy like that
15:43technomancymultiple slime connections can be open, but you have to manually switch between them
15:43edwI'm typing into Emacs on my linode box for IRC, through Emacs. Then I have my Cocoa Emacs, and an 'emacs -nw' going...
15:44edwtechnomancy: I'm using VNC to type into the Emacs running ERC... I don't like restarting Emacsen.
15:45technomancyhah; dude... emacs -nw inside tmux.
15:49edwThat's how I do my swank servers on my degenerate cluster of one...using screen(1).
15:49technomancyM-x emacs-uptime => 142 days, 1 hour, 18 minutes, 51 seconds
15:49edwNice. How do you clean out your ERC buffers?
15:50technomancythere's an erc-truncate module
15:50amalloytechnomancy: that's like...almost half as long as i've known how to use emacs
15:50technomancyamalloy: hah; awesome.
15:50edw(I'm only at six days with my VNC Linode Emacs ERC connection.)
15:51edwI had Emacs running SLIME48 with my consulting firm's web site running inside it for over a year.
15:52edwUsing screen, of course...
15:52fliebelWhat do Mac people in here use for IRC?
15:52edwEmacs.
15:53cemerickColloquy is pretty common
15:53cemerickI'd love to have a better option, but I don't think I could bring myself to pay for an irc client.
15:53edwColloquy feels like it was made for warez traders.
15:54cemerickhuh
15:54jneirai am learning emacs through typos
15:54technomancylimechat and irissi are also somewhat popular
15:55dakronesome people use adium also
15:55cemerickadium is pretty painful for irc IMO
15:55fliebelI did...
15:55jneiratoday i have learned c-c i
15:55edwBest just to stick with ERC in Emacs.
15:56cemericktechnomancy: Hadn't seen limechat before, thanks.
15:56amalloyhey jneira, nice to meet you in here
15:56fliebelI'm trying it move everything to separate apps, so I can maintain some productivity.
15:56edwfliebel: M-x new-frame is your friend.
15:56jneirahi! a typo has guided me here ;-)
15:57amalloyjneira: what is C-c i? it isn't bound to anything for me
15:57jneira(lambda nil (interactive) (switch-or-start
15:57jneira(lambda nil (rcirc-connect "irc.freenode.net"))
15:57jneira"*irc.freenode.net*"))
15:58jneiraops
16:01fliebel_Hm, talking from a lemon now.
16:02raekI'm using irssi
16:06fliebel_dnolen: my colloquy does weird stuff to growl :(
16:07fliebelraek: Why not?
16:08ordnungswidrighow do I preserve the type of an associative structure?
16:08ordnungswidrig,(update-in [1 2 3] [0] inc)
16:08clojurebot[2 2 3]
16:08raekI really thought that Java and JavaScript had nothing in common except for their names...
16:09amalloyordnungswidrig: looks right to me. what's the problem?
16:09ordnungswidrigraek: but?
16:09raekI'm just astonished
16:09fliebelraek: What did you expect? Lua? Or just nothing at all?
16:10ordnungswidrigamalloy: typical case of rubber ducking :-) The structure I tried to update and which I expected to be a vector after updating was a sequence all the time...
16:10jneiraor groovy
16:10raekdidn't expect the JVM to contain an implementation of another language
16:12ordnungswidrigamalloy: so my question is:
16:12ordnungswidrig,(map inc [1 2 3])
16:12clojurebot(2 3 4)
16:12ordnungswidrig,(apply vector (map inc [1 2 3]))
16:12clojurebot[2 3 4]
16:12imadewhen calculating collection length I guess I would have to use only the long version of anonymous function, I can't do it with the #() macro like so (reduce #(inc %1) 0 coll))
16:13amalloyordnungswidrig: clojure.walk/walk works but isn't very high-performance. converting a vector to a seq and then back to a vector can't be performant anyway
16:13ordnungswidrigamalloy: btw. I don't care about vector but about associativines for get-in / update-in
16:14ordnungswidrigamalloy: which seqs do not have. After all I do some matrix updates.
16:14ordnungswidrig,(update-in [[0 1 2] [1 2 3] [2 3 0]] [1 2] inc)
16:14clojurebot[[0 1 2] [1 2 4] [2 3 0]]
16:14amalloysure
16:15amalloydo you care about performance?
16:15ordnungswidrigyes and no
16:20ordnungswidrigI mean, at some point I think I will
16:21amalloyordnungswidrig: you can't really use map on a vector and get out a vector: map converts its argument to a seq for maximum generality
16:22amalloy(and for laziness)
16:23amalloyif you have a vector, and want out a vector, you can use reduce: ##(let [v [1 2 3]](reduce #(update-in %1 [%2] inc) v (range (count v))))
16:23sexpbot⟹ [2 3 4]
16:25raekif all elements should be updated, then could it be a good idea to simply build a new vector?
16:26hugodI thought this would trap the compile error, but it doesn't … (try (defn x [] (String. 1 2 3 4 5)) (catch IllegalArgumentException _))
16:27amalloyraek: i suspect that update-in*N will be faster than seq+map+vec, because it won't have to reconstruct the tree structure, but i could be wrong
16:28amalloyhugod: the error is being thrown in the compiler, because there's no constructor for String that takes that many args: it can't convert that expression into bytecode
16:28hugodright, which is why it is in a try block
16:28amalloyhugod: the *execution* of that expression is in a try block. the compilation isn't
16:31hugodI thought top level forms were executed at compile time
16:33raekhugod: when a file is loaded, each top-level expression is compiled and then evaluated
16:33raek"compile time" is a bit relative in Clojure
16:33hugodso there is no way of making that work without resort to reflection, mm
16:34raekhugod: the compiler would have emitted code that uses reflection if it could not determine which constructor you wanted to use
16:34raekhugod: but in this case, there are no constructors with that signature
16:35raekso the compiler won't even try to emit reflective code, since it knows it will always fail
16:35hugodright, I need to support two versions of an external dependency, and thought I could do that at compile time
16:36hiredmanmacros
16:37hugodhiredman: I guess so
16:38dnolenhugod: that's what I had to do to deal with supporting core.logic on 1.2 and 1.3, doing a top level thing just won't work. Macro lets you get around the problem.
16:38raekhiredman: something like this? (defmacro foo-constructor [args] (case api-version :old `(OldClass. ~@args) :new `(NewClass. ~@args)))
16:39dnolenhugod: w/ a macro, the compiler never gets a chance to see the wrong thing.
16:39hiredmanraek: something like that
16:40hugodI don't think I have a constant available, so I'll have to use reflection to pick the correct code
16:40dnolenhugod: reflection in a macro isn't such a big deal tho right?, cache the result and all that.
16:40raekhugod: that's okay. macros have the whole Clojure language available to figure out what code to generate :-)
16:45hugodsure, just more work than "eval-when" would have been
16:51manutterheh, I thought I was a bit more advanced than that, until I started doing the 4clojure problems
16:52manutter"Heck, everybody knows how to write a fibonacci series in clojure, right?" Yeah, try it without the book in front of you.
16:56amalloymanutter: ##(take 10 (iterate (fn [[a b]] [b (+ a b)]) [0 1]))
16:56sexpbot⟹ ([0 1] [1 1] [1 2] [2 3] [3 5] [5 8] [8 13] [13 21] [21 34] [34 55])
16:56amalloyer, ##(map first (take 10 (iterate (fn [[a b]] [b (+ a b)]) [0 1])))
16:56sexpbot⟹ (0 1 1 2 3 5 8 13 21 34)
16:56manutterNice
16:57manutterI got a slightly different one, but it passed
16:57manutterIt was still humbling :)
16:58amalloymanutter: i found that one on rosettacode when i was still new enough that it astonished me. added a bunch of comments to the rosettacode entry, which was a tremendous help in understanding and remembering it
16:59manutterMy favorite on 4clojure so far is "Implement reverse from scratch"
17:00manutterI had some big complicated thing in mind with loop/recur, and then all of a sudden I though of using reduce, and it frickin worked
17:00amalloymanutter: wanna see the shortest possible solution?
17:00manuttershortest fib? Sure
17:00amalloyno, for reverse
17:00manutteroh yea
17:00amalloyinto ()
17:00manutterlol
17:00jneirahehe
17:00manutterThat is shorter than mine
17:01dnolenhugod: might be worth searching the IRC logs for rhickey's thoughts on eval-when, I see he mentioned it around the time he devised AOT. I assuming there are other thing that need to be in place for eval-when to happen.
17:03amalloymanutter: i think Reverse Interleave is my favorite, because when i proposed it my implementation was "tricky", and i saw several people tweet a simple, elegant solution
17:05jneirai liked implement triangle-minimal-path
17:08amalloyjneira: i don't really like problems where there's a well-known algorithm for doing it, and the problem boils down to looking up the algorithm and implementing it in clojure
17:09jneirammm is there a well-known algorithm to triangle? :-P
17:12jneirai try to not google the answer or see #4clojure tl ones
17:14jneirawith powerset i had to translate wikipedia algorithm, yours is more idiomatic
17:18amalloyjneira: i'm sure i've seen an algo for triangle path at some point, but i can't find it now
17:20amalloyjneira: hah, here it is in scheme: http://community.schemewiki.org/?max-sum-triangle-path
17:21jneiraamalloy: sure, but if you dont get it by yourself it is not so funny
17:23jneiramy take https://gist.github.com/992016
17:24jneirai love map recursion
18:00danlarkinso it's possible to deliver on a promise that's inside a ref without being in a transaction
18:00danlarkinhow do people feel about this
18:00technomancyyou put anything but a value in a ref and all bets are off
18:00danlarkinor, even worse -- if you're in a transaction and it fails you could've prematurely delivered
18:01offby1then the value needs to be in an incubator for months until it's healthy?
18:01technomancy,(instance? clojure.lang.IDeref (promise))
18:01clojurebottrue
18:03amalloydanlarkin: it's also possible to swap! an atom that's inside a ref when you're not in a transaction. refs only manage one level of mutability for you; promises and atoms are another level
18:03danlarkinindeed
18:03danlarkinok, problem solved -- I'll dispatch to an agent and have THAT deliver to the promise
18:04danlarkinthen it won't happen unless the transaction commits
18:05amalloyyes. if you consider delivering to a promise as i/o, that's pretty normal
18:18stirfools
18:26symuynHey, I'd like to take two vectors and get a pair of sets of indices of shared elements: [[5 3 1 2] [1 6 7 3]] → [#{1 2} #{0 3}]. What's the best way?
18:30amalloysymuyn: fwiw i don't see how your inputs relate to your outputs at all
18:31ataggarttook ema while too. the first set is the indices from the first vector, etc.
18:31symuyn#{1 2} means that the first vector's elements at indices 1 and 2 (i.e. 3 and 1) are also inside the second vector.
18:31symuynVice versa for the second vector.
18:31symuynSorry about the example.
18:32symuyn[['a 'b 'c 'd 'e] ['f 'd 'a 'z 'b]] → [#{0 1 3} #{1 2 4}].
18:34ataggart(filter (into #{} a) b) will give you the intersection
18:34ataggartthen you just need to pull the indices for each coll
18:35amalloyi mean, it's going to be an N^2 operation, and there are usually no one-liner ways to do such ugly stuff
18:35amalloy ataggart: a set won't work if there are any duplicates, no?
18:36ataggartthat depends on what problem he's trying to solve
18:36amalloyi guess
18:36gfrlogI don't imagine there's any way to generate all possible ways of matching a regular expression, is there? (re-seq) is not what I mean.
18:36symuynHmm, yes, it is pretty ugly in of itself
18:36symuynThanks for the help
18:42amalloygfrlog: to match against a given input string? or "tell me all input strings that would match this regex"?
18:42gfrloga given input string; so:
18:43gfrloggiven #"(.*)xx(.*)" and "abxxxbca" I want [_ "ab" "xbca"] and [_ "abx" "bca"]
18:43amalloygfrlog: there is never more than one way, because the regex language has precedence rules built in: you will always get abc bca
18:43amalloyer, abx bca
18:44gfrlogokay. so regular expressions themselves do not like this idea.
18:44amalloyno. it would lead to horrible amount of backtracking
18:44amalloyimagine the re-seq like (a*)* matched against "aaaaaaaaaaaaaa"
18:45gfrlogwell that would be an appropriate amount of backtracking
18:45gfrlogbecause if I'm asking for all ways to match that, clearly I'm asking for a pretty long seq back
18:47gfrlogyou may as well say that the subsets function is worthless because it also does a lot of work when passed "aaaaaaaaaaaaaa"
18:57stirfooyou'd have to make the first kleene star non-greedy on one pass and greedy on the next, but that's only for the case given.
19:02amalloystirfoo: i don't really follow. how would you use that technique to return ["aaaa" "a" "aaa" ...]?
19:03stirfooamalloy: I meant it would only work for gfrlog's given example
19:03stirfoodefinitely not a fix-all
19:04amalloyah
19:10scottjwondering about alternate names for this macro: (if-pred string? cf/parse time) => (if (string? time) (cf/parse time) time)
19:11amalloyscottj: i called it transform-if
19:11amalloyand made it a function rather than a macro
19:12amalloyhttps://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/transform.clj#L4
19:12scottjhow often do you use the f-not arity?
19:13amalloymmmm, less often than the other
19:13amalloyscottj: but making it a HOF is a win imo. i can do stuff like (postwalk-replace (transform-if float? int) some-data-structure)
19:15scottjamalloy: agreed, thanks
19:15amalloyscottj: feel free to just depend on amalloy/utils instead of writing it yourself, if that's more convenient for you
19:39Null-AIs there an emacs/slime feature where I can evaluate let bindings as var bindings
19:40Null-Aso with (let [foo 3] foo), I want to move my cursor to foo, type C-c C-?? and now (def foo 3) is executed
19:43scottjnope
19:44Null-Ait's probably an easy elisp hack, but I don't know elisp very well
19:44amalloyNull-A: i doubt it's easy
19:44technomancyusually let bindings depend upon lexical scope, so that would only work in very limited cases
19:44amalloywhat about (let [[foo] [10]])? what should that do?
19:44technomancybetter to put a swank.core/break in there an inspect it live
19:44Null-Aamalloy: I just want something for the common case
19:45Null-AI would just eval the first 2 s-expressions that the cursor is on
19:45Null-Ain slime
19:45Null-Awrap it with def
19:45Null-A(def "foo 3")
19:45Null-A(def <<foo 3>>)
19:51scottj(defun blah () (interactive) (save-excursion (slime-eval `(swank:eval-and-grab-output ,(concat "(def " (symbol-at-point) (progn (forward-sexp) (symbol-at-point)) ")"))))) figure out how to get symbol-at-point to be string and that might work
19:52Null-AoOo
19:53amalloyscottj: symbol-at-point won't work; it needs to be sexps
19:53Null-Aforward-sexp brings the cursor to the end of the current sexp
19:54Null-Ahttp://www.emacswiki.org/emacs/ThingAtPoint
19:54no_minduraek: could you please example code of generating html element using enlive based on the mapp method you suggested earlier. I am not been able to figure out how to use map to generate element
20:07Null-Ascottj: do you know how to unquote in elisp?
20:07Null-Aits not ~
20:08technomancyNull-A: ,
20:21Null-AI've almost got this working in elisp, but there's something wrong with `(swank:eval-and-grab-output call
20:21Null-Amy function works fine in *scratch* but not in a clojure file
20:22Null-Ahttps://gist.github.com/992291
20:22Null-Ascottj:
20:37Null-Ahow do I change the root binding of a var?
20:37Null-AI think that's the problem I'm having
20:37ataggart,(doc alter-var-root)
20:37clojurebotDENIED
20:38ataggartwell damn
20:38Null-Aheh
20:38jedilol
20:38Null-Agood enough
21:04carllercheI'm trying to tweak clojure-mode indentation for a 'defupstream' form, it works, but if I use a namespace (like foo/defupstream) the indentation tweak doesn't work anymore Is there a way around it? https://gist.github.com/1493b7c155f424b9c93b
21:05amalloycarllerche: clojure-mode includes a customizable var, clojure-defun-indents, as of like 1.8 or so
21:06amalloybut i don't think that will fix the issue of (foo/defupstream)
21:06carllercheamalloy: so it seems it indents def* as a defun right now
21:06amalloy*nod*
21:07carllerchei guess i could use the namespace instead of require :P
21:08amalloycarllerche: i don't think anyone (technomancy?) really knows how the clojure indenter works anymore. i only added a few surface things, and i don't know how hard it would be to make */def* indent right
22:05scottjI added some def* thing to clojure-mode that actually doesn't work, can't remember if it was indenting or highlighting
22:20arohnerI don't suppose anyone has a clever solution for the "lazy-seqs that require side effects, and need to clean up when they're done" problem yet?
22:23amalloyarohner: that's a pretty vague and general problem, isn't it? i don't think a single solution can fit all classes of the issue
22:25arohneramalloy: "all I need" is for some cleanup code to be called when the lazy seq is consumed or GC'd
22:25hiredmanat work have a closeable seq, you just have to consume it inside a with-open
22:27arohnerhiredman: oh, a protocol that extends c.l.LazySeq to have a .close method?
22:27hiredmanyes
22:50arohnerhiredman: is there a clever way to just add a .close method to an instance? I'm seeing several messy ways to do this, and no clean ones
22:52mefestoarohner: would a try/finally work? (try (consume seq) (finally (cleanup)))
22:53arohneralso, it seems like there's room for a clojure fn to override an instance. (inherit inst (foo [x]...) (bar [x]). returns an instance of a new class, that inherits from inst. reflects all method calls to inst, unless overridden.
22:54arohnermefesto: conceptually, I really like the idea of making this integrate with with-open. "all you have to do" is return something that implements c.l.LazySeq, and also has a .close method
22:55mefestoarohner: oic, how is your lazy-seq implemented, just with (lazy-seq ...) ?
22:56arohnermefesto: I'm not sure how to implement it yet :-)
22:56mefestosince you want to use it with 'with-open im guessing it's some sort of io?
22:57arohnernot io, but I do need to clean up when I'm done
22:58mefestonot sure if this helps but there is java.io.Closeable which you might be able to use in combination with proxy, deftype/record ...
22:58mefestoCloseable is an interface with a close method that will be called by with-open
22:59mefestoafaik, with-open doesn't require you to implement that ... just as long as whatever object it binds responds to (.close x)
23:03mefestoarohner: is there something specific you are trying to do or just experimenting with clojure features?
23:03arohnermefesto: I'm using webdriver to scrape some pages. I want to generate a lazy-seq of urls from scraping. I want to close the webdriver instance when the seq is consumed/goes out of scope
23:06mefestoarohner: from what i've seen the lazy-seq is separate from the closeable resource. for example: https://gist.github.com/992465
23:06mefestoarohner: notice how line-seq doesn't handle the opening/closing of the file from which it reads
23:10arohnermefesto: that's annoying. This is an experiment, we'll see how it goes
23:16mefestoarohner: why is that so annoying? :)
23:17mefestohere's a comparison if line-seq was also closeable: https://gist.github.com/992465
23:29tomoj&(->> #(rand-int 2) (repeatedly 5) (fn []) (repeatedly 10))
23:29sexpbot⟹ ((1 0 0 1 0) (0 1 0 1 0) (1 0 0 1 1) (1 0 1 0 1) (1 0 1 1 0) (0 1 0 1 1) (0 0 0 1 0) (1 1 0 0 1) (0 0 0 1 0) (1 0 0 0 0))
23:30tomojwhat's a pretty and non-crazy way to do that?
23:30tomojsuppose you could just partition
23:38arohnertomoj: yeah, I would cycle rand-int and then partition
23:38arohnererr, repeatedly, not cycle
23:38arohnerI always get those confused
23:40arohner&(->> #(rand-int 2) (repeatedly 50) (partition 5))
23:40sexpbot⟹ ((0 1 0 1 0) (0 1 0 1 1) (1 0 1 1 0) (0 0 0 0 1) (0 1 0 1 1) (1 0 0 1 1) (0 1 0 0 0) (0 0 0 0 1) (0 1 0 1 0) (0 0 1 0 0))
23:48tomojmuch better