#clojure logs

2010-12-19

00:41GOSUBClinteger: it will seem right.
01:20TakeVDoes anyone here use Penumbra?
06:46bartjwhat would be the best way to remove nil, empty values from a hash-map
06:49bartjmy attempt is this: (map (fn [[k v]] (if (and v (> (count v) 0)) [k v] nil)) x)
06:51mduerksen_bartj: (apply conj {} (filter (comp not nil? val) x))
06:52mduerksen_map wouldn't give you a sequence, not a hash-map
06:52mduerksen_*would*
06:53bartjmduerksen_, oops, I forgot to give a (into {}...) here
06:53mduerksen_ah, you want to remove empty collections as well?
06:54mduerksen_then my solution won't be complete
06:54bartjI'll just use a pos? as well :)
06:54_ato(zipmap (keys m) (filter seq (vals m)))
06:54_atoassuming all the values are collections
06:55bartjI sometimes tend to avoid zipmaps, I don't know why
06:57_ato(into (empty m) (filter #(seq (val %)) m))
06:57mduerksen__ato: seq is a great idea - but the zipmap code won't work because it interleaves the wrong keys with the values that are left
06:58_atomduerksen_: ah of course. Silly me.
07:00mduerksen__ato: hmm, you're empty is nice, by the way. i should start using it since it does work for all kinds of collections
07:02mduerksen__ato, bartj: the most elegant way IMHO would be: (into (empty m) (filter (comp seq val) m)) (i try to avoid the #-notation whenever possible)
07:03bartjok guys, lots of thanks
07:05mduerksen__ato: :D really? why?
07:09_atoA knee jerk reaction to overuse of pointfree style, I guess. I dunno. ;-)
07:12Chousukeavoiding #() is silly.
07:13Chousukepointfree style in clojure becomes unreadable beyond the simplest cases :P
07:19mduerksen_hmm, i have heard the term "pointfree" here and then, but i don't actually know what it means. i find (comp seq val) very readable. just to be clear: i'm not forbidding myself to use #(), but i do think that often enough it's a sign that i haven't written my code very idiomatically
07:24_atothe terminology was probably made popular by Haskell where it's used much more often than Clojure: http://www.haskell.org/haskellwiki/Pointfree
07:26_atoessentialy just means combining functions with things like comp and partial and juxt so as to avoid local bindings
07:29mduerksen_i see, thanks. i for my part like partial, comp, complement etc., but i agree that this can be overdone (as almost everything)
07:47LauJensenmduerksen_: Did you see the slides from cgrands talk at Clojure Conj? If not, you should check them out
07:51mduerksen_LauJensen: no, i haven't. are they on slideshare?
07:51LauJensenmduerksen_: http://lmgtfy.com/?q=cgrand+slides+clojure+conj&l=1
07:54mduerksenLauJensen: sorry, my connection broke. did you write something while i was gone?
07:55LauJensenmduerksen_: http://lmgtfy.com/?q=cgrand+slides+clojure+conj&l=1
07:55LauJensenjust the link
07:55mduerksenthanks
07:55LauJensennp
08:21FireSnakemy Clojure app works perfectly on Jetty at localhost:8080 but I get 500 errors on Google App Engine. Anyone guess why?
08:34Lajlathe stupid part about point free is that it doesn't exist.
08:34Lajlaf x y = whatever in haskell is just sugar for f = \x -> (\y -> whatever)
08:34LajlaAlso point free tada.
08:35LajlaAlternatively, f . g is just sugar for \fuckThisShit -> (f (g FuckThisShit))
08:51pyrtsa...With the difference that when you write "\x", you are expressing the "point" you are operating on.
09:27mduerksenLauJensen: those slides are really insightful. i assume you were referring to my question yesterday?
09:34leif-pHi, where do I report bugs/request enhancements for clojure?
10:42LauJensenmduerksen: yes
11:12ohpauleezRaynes: Can you play with the new clj-github changes and then when you feel solid, push a new drop to clojars?
11:14dsophmm is there a nice way to validate email addresses in clojure? I only find some Java EE stuff to do it
11:19fliebeldsop: You mean just a nice regex?
11:40leif-pIs it just me, or is clojure's 'gensym' a little too liberal about its input?
11:41fliebelleif-p: How do you mean liberal?
11:42leif-pUnlike CL's, which essentially only takes strings, clojure's seems to take any old thing that can be 'str'ed.
11:42fliebel&(gensym :test)
11:42sexpbot⟹ :test27260
11:43stuartsierrasymbol-generating fns are generally liberal in Clojure
11:43fliebel&(type (gensym :test))
11:43sexpbot⟹ clojure.lang.Symbol
11:43stuartsierrawhether or not this is a good thing is a much-debated but never-resolved topic
11:43fliebelA symbol that starts with a colon is weird though.
11:45leif-pIs there a way to print this in a way that could be re-read? Like CL's |:weird + symbol|.
11:45stuartsierraleif-p: not right now, but also debated in the past
11:45stuartsierraThere's ambivalence about whether Clojure symbols should be allowed to contain arbitrary characters.
11:46stuartsierraIn CL it's a leftover from before Lisps had a String type.
11:46fliebelstuartsierra: Any idea what came of the escaping discussion? It was related to the |syntax| I think.
11:46stuartsierraThere was no resolution as fas as I know.
11:48fliebelI liked the idea of r"raw strings" like in Python, or unicode quotes, and in case of emergency(huh?) even arbitrary delimiters.
11:49leif-pfliebel: Maybe this is the wrong room to say you liked a perl feature :)
11:52fliebelleif-p: I ultimately think that if you want wrid shit in your strings, you should read them from a file. And Perl is for emergencies. Like the way Haskell uses Perl to bootstrap Haskell to new platforms by fumbling with the generated assambly.
12:34TakeVIs there a way to save work done in a REPL to the namespace you are working in? The REPL makes it easy to test things, but changes don't stick unless I go back and add the changes to the file manually.
12:44bortrebCan you call an object created by defrecord in clojure using non-java-legal characters with java in some way?
12:44chouserbortreb: probably via reflection
12:44chouserTakeV: when you define a function at a standard repl, the source code isn't saved anywhere, so no.
12:45chouserTakeV: one could make a repl that saved things out to a file as you go along or something, but I think most people end up writing their code in a file and then either sending it from there to the repl,
12:45chouseror saving the file to disk and then reloading it from the repl.
12:46TakeVAh, is there a way to automatically reload a file?
12:46chouserhm, not sure about automatically. Some of the IDEs may have that, and such a thing could be written.
12:47chouserlazytest has a "watch" mode that reruns appropriate unit tests when it sees a file has been written to disk.
12:47chouserI usually just push the up arrow in my repl to recall the (use foo :reload-all) line, and then hit enter.
12:47TakeVI think I'll write an auto-reload thing.
12:51bartjIf a clojure file has a "main" method defined, can't I use the functions defined in it?
12:51KirinDavebartj: Defined inside the main method?
12:51KirinDavebartj: Or just the module containing the -main defn?
12:52bartjKirinDave, the latter
12:52KirinDavebartj: THen the answer is yes, absolutely
12:53bartjI did a ( :use, :only ) with no luck
12:53KirinDavePerhaps a gist.github.com demonstration of you problem is in order, bartj
12:56bartjKirinDave, unfortunately I can't :(
12:57KirinDavebartj: So one of two things is happening here. I'll list them on a probability gradient, high to low:
12:57bartjbut, I think I am doing a recursive "use"
12:57KirinDaverecursive use?
12:57KirinDaveSo two modules sharing required code?
12:58bartjModule A has func1, func2
12:58bartjModule B has func3, func4
12:58KirinDaveDoes it actually give you an error for this?
12:59bartjweird thing is it runs, but doesn't compile
12:59bartjam using "ant"
12:59KirinDaveYeah, so...
12:59KirinDaveThat may not work. :)
13:00KirinDaveBut without a clear example it's reeeeaallly hard to diagnose.
13:00bartjthe function calls are like this: func1 -> func3 -> func2
13:00bartjwith the appropriate use/require in place
13:01KirinDaveWell, first.
13:01bartjso, I think there is something wrong with the code organization
13:01bortrebTakeV: I've already written an automatic reload function if you're interested
13:02bortrebalso, with reagards to my earlier question, I've already taken all the necessary steps to AOT the clojure. i have a class called literally "clojure-object.class" -- note the hyphen. Is there any way to call that from java?
13:05TakeVbortreb: I would be very interested.
13:18bortrebTakeV: I'll put it on github... hold on
13:22bortrebTakeV: https://gist.github.com/747559
13:23bortrebthe idea is you can just call rlm.rlm-commands/re to do a fast reload
13:23TakeVbortreb: Thank you.
13:23bortrebor (rlm.rlm-commands/reload) to do a very trough reload
13:23bortrebthere's also an undef function which does about what you'd thing
13:23bortrebyou're welcome!
13:25bortrebso, anyone know if you can call classes like "clojure-object.class" from java?
13:42shortlordHow can I use partition to create vectors?
13:42shortlordI am using this line:
13:42shortlord(def fields (vec (partition 2 (interleave numbers resources))))
13:49raekshortlord: (def fields (map vector numbers resources))
13:49fliebelshortlord: (map vector (partition 2 seq))
13:49fliebelmaybe
13:49raekno need to interleave them and then split them again
13:49fliebeloh right :)
13:49raek,(map vector [1 2 3] [:a :b :c])
13:49clojurebot([1 :a] [2 :b] [3 :c])
13:50shortlordraek: oh cool, thx :)
14:05dsapalaanyone know anything about the clj-http project?
14:12fliebelthe_shadow_of_dsapala: yes
14:14dsapalaAre any of you folks familiar with clj-http?
14:14fliebelyes
14:15fliebelBut that doesn't mean it's me, and it doesn't means anyone knows the answer to your question, therefore I suggest you just ask your question.
14:17dsapalaHow can I set a timeout for connections or reads using clj-http?
14:33fliebelLauJensen: How are plans for the Reddit clone based on "new" stuff?
14:33LauJensenfliebel: Plans are: As soon as I have an hour or two, I'll write it up :)
14:34fliebelLauJensen: I'm curious :) I have some plans for a project like this as well.
14:35LauJensenI'll make sure to announce it on Twitter :)
14:35bhenryhow do i assoc into a vector but i want it to be an "insert before" rather than a "replace what's there".
14:36fliebelbhenry: I think you'll have to do split-at and concat.
14:37fliebelbhenry: Or do a zipper.
14:39bhenrythanks. i decided it was easier to pass what i want into the function that makes the vector.
15:03currentBwhat's the best way to assoc a new key in a hashmap stored within a vector in a dosync?
15:05AWizzArdcurrentB: what code do you currently use so far?
15:09fliebelcurrentB: Cant you just do (update-in vec [index :key] some-fn)?
15:09fliebel&(update-in [1 2 3] [1] inc)
15:09sexpbot⟹ [1 3 3]
15:10currentBalright cool thanks, checking that out
15:16fliebelWhy can't I do this? (dissoc [1 2 3] 1)
15:18ducki2pfliebel: dissoc requires a map
15:18fliebelIn most other ways, vectors seem to be like maps with integer keys.
15:20fliebel&(vals (dissoc (into (sorted-map) (map-indexed vector [:a :b :c])) 1)) ; evil
15:20sexpbot⟹ (:a :c)
15:21ducki2p&(vec (filter #(not= 1 %) [1 2 3]))
15:21sexpbot⟹ [2 3]
15:21fliebelducki2p: You remove a value, not an index.
15:46tomojhuh, #(not= 1 %) is shorter than (complement #{1})
15:47tomoj#\ is available
15:47tomoj#\{1} ? :)
15:48tomojnah
15:48tomojjust (remove #{1} ..)
15:54amalloytomoj: #(not= 1 %) can't be nested inside another #() function
15:54amalloyplus, i know it makes me a sinner, but i (def ! complement) in most of my code
17:23amalloyis there any particular guarantee about order of evaluation in a form like [(foo) (bar)]? i'm doing some interop and foo affects some state that bar depends on; is the above sufficient, or do i have to make bar a function of foo in order to make sure foo has been computed?
17:23chouserthey'll go in order
17:23chousermaps are not guaranteed, I think.
17:24amalloythanks chouser
17:24amalloya point in favor of clojure that i didn't have to ask this question until i'd written clojure for about five months
17:24Raynes(inc clojure)
17:24sexpbot⟹ 1
17:29chouserheh
17:29nickikwhy did you do that raynes? it had no effect on clojure :)
17:29chouserscheme doesn't even promise function arguments will be evaluated in order
17:30RaynesIt does in my little world.
17:30Raynes(inc clojure)
17:30sexpbot⟹ 2
17:30amalloychouser: neither does C
17:30chouser!!!
17:30amalloyor any of its children (java, etc) as far as i know
17:31chouserwow, I had no idea
17:31brehautnickik: presumably because (send clojure inc) or (swap! clojure inc) is long winded ;)
17:32amalloychouser: if you do much imperative programming, http://en.wikipedia.org/wiki/Sequence_point is good reading for the fiddly details
17:32amalloy(4) under <Sequence points in C and C++> in particular
17:33chouserI've written a lot of C code in my life, and am surprised this hasn't ever bitten me.
17:33amalloychouser: it rarely does. your functions probably don't affect a lot of global state
17:33amalloyand i think gcc does evaluate them in order, to be nice
17:35_mstjava does go left to right, just for what it's worth (http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html)
17:35_mstalthough it recommends you don't rely on it, which is a bit funny...
17:37amalloy_mst: ah, so it does. thanks (15.7.4 for anyone else who's looking)
17:49amalloycan someone load https://gist.github.com/747785 into an editor with paredit mode on? all the parens in my docstring are balanced, and indeed paredit-mode is happy to be enabled, but if i try to do anything interesting (backspace, M-(, etc) in the body of my function, it complains of unbalanced parentheses
17:49amalloyand i'd like to verify it's not something wrong with my config before i file a bug
17:50amalloy(and if i delete the docstring, the problem fixes itself)
17:54_mstamalloy: same deal for me here, yep. I notice if I put a space before your {'s in the docstring it's OK...
17:55amalloy_mst: aha! well spotted. in fact, any character at all before them is fine; it doesn't like them at the start of a line, apparently
17:56_mstit might not be paredit specific... if I do a C-M-a (to go back to the start of the defun) it jumps me to one of those braces
17:56_mstso maybe clojure-mode is mistaking where the defn actually begins...
17:57_mstah! (setq open-paren-in-column-0-is-defun-start nil) seems to fix it for me
17:57_mstdunno what else it breaks though ;)
17:58amalloy_mst: fascinating. thanks
17:59_mstheheh no worries
18:02lpetitamalloy: works ok with paredit.clj :-p
18:02amalloylpetit: is that for ccw?
18:03lpetitamalloy: yeah, pasted your gist into ccw. But don't worry, there are still some corner cases with paredit.clj, your example is just not one of those :-D
18:05lpetitamalloy: I'm currently doing the necessary (albeit boring) port of paredit.clj commands into the new repl client of ccw. Just ported join & split before going to bed
18:08brehautdoes anyone know if there is an atom-pub lib built on top of ring?
18:29qbgHow do you get a namespace qualified symbol from a var?
18:31amalloy&(apply symbol ((juxt (comp str ns-name :ns) (comp str :name)) (meta #'first)))
18:31sexpbot⟹ clojure.core/first
18:32amalloyis kinda disgusting but works
18:32qbg&(symbol (subs (str #'first) 2))
18:32sexpbot⟹ clojure.core/first
18:32qbgThat is worse
18:32amalloylol
18:38shortlordgiven a nested collection that contains a few values, that have to be mutable. Should I place the whole collection in a single ref or rather use separate refs for each value that has to be altered?
18:39Chousukethe fewer mutable things you have, the easier they will be to handle.
18:39Chousukeso prefer a single ref, unless it becomes a bottleneck
18:41shortlordChousuke: the only problem I have is how to change that single ref with alter. Using assoc-in results in ugly code, because I have to alter the value using assoc-in, which means that I need to dereference the ref directly as the first argument of assoc-in
18:41shortlordwhich destroys the point of using alter instead of ref-set, right?
18:44qbgI'm proud of this: https://gist.github.com/747841
18:46qbgSomething like syntax-rules in Clojure!
18:50Chousukeshortlord: hm, no you don't?
18:50amalloyshortlord: i don't understand what you're saying
18:51Chousukeshortlord: (alter somerefref assoc-in [keys here] val)
18:51Chousuke-ref
18:51Chousukeshortlord: update-in is useful too
18:54shortlordChousuke: ah ok! I thought that alter provided the ref as the last argument, not the first one
19:00shortlordwhat would be the best way to increment that value?
19:00shortlordRight now I am using:
19:01shortlord(dosync (alter players (fn [players] (assoc-in players [player resource] (inc ((players player) resource))))))
19:01shortlordbut that does not look very elegant
19:03qbg(dosync (alter players update-in [player resource] inc))
19:06amalloy(inc qbg)
19:06sexpbot⟹ 1
19:06shortlordthx a lot :)
19:39currentBlet's say I have a vector of hash-maps. i will periodically conj a new hash-map to the vector which will just be the "peek" of the vector (ie the first current hash). Occasionally values pairs from this first hash will be chagned or new ones will be added. The lazyness of clojure makes this efficient right? as in a new hash isn't created when each new peek value is conjed to the vector right? or when a new value is assoced in the first
19:40currentB(i need to implement a simple compiler for a class and I'm wondering if I can just create a new hash-map to represent each scope with the values of all "lower" scopes included, or if it's best to just create a new hash map for each scope and search them sequentially
19:47amalloycurrentB: i don't understand what you're talking about with "peek". the peek of a vector is the last element in it; if you conj something to a vector it is the peek by definition
19:48currentBbut if i want to create a new scope, i might want to copy everything in the previous scope to that new scope
19:48currentBso i can alter those old values
19:48currentBand just remove it when the scope is exited
19:49amalloyoh, you mean if you have like a 10KB hash table, and want to create another one just like it but with one additional item?
19:49currentByes
19:49currentBi think
19:49amalloyyou're correct that clojure doesn't copy all 10KB worth of keys, but that's not really related to laziness
19:50currentBok, so that's just the persistence + tricks with pointers?
19:50amalloyright
19:50amalloyneither vectors nor hashes are lazy
19:50mister_roboto1what is the right way to expose a function that you always want call via memoize? that is, if you are writing a library function and the set of return values is always small so rather than cache it yourself you want to leverage memoize?
19:51mister_roboto1just def it ahead of time and make the real function private?
19:51amalloymister_roboto1: do you want to memoize recursive calls as well?
19:52mister_roboto1amalloy: this function is not recursive
19:52amalloy(def myfn (memoize (fn [args] (compute))))
19:52amalloyis a solution that works and doesn't seem too ugly to me
19:52mister_roboto1ahh, internally make it anonymous. i like it
19:53amalloyanother useful trick is (def ^{:arglists '([args])} myfn (memoize...))
19:53amalloyso that (doc myfn) and eldoc will be useful
19:54mister_roboto1amalloy: that second thing is totally new to me. i'll have to read up on that one.
19:55currentBamalloy: ok so if I have a vector x [{:a 1 :b 2}] I can later alter it to (conj x (peek x)), or [{:a 1 :b 2}{:a 1 :b 2}], then later alter just the first hash so it is [{:a 1 :b 2 :c 3}{:a 1 :b 2}], this is better than just structuring things so I have [{:c 3}{:a 1 :b 2}], and then, if I need to find :a, first looking through the first map, then checking the second, etc?
19:55amalloymister_roboto1: ^{key value} is how you attach metadata to a var (or to anything): ##(-> first var meta :arglists)
19:55sexpbot⟹ ([coll])
19:57raekwith defn, you can also put a map after the docstring (or after name if there is no docstring). the metadata will be merged with that map
19:57raek,(doc defn)
19:57clojurebot"([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any do...
19:57amalloycurrentB: i think that depends on the performance characteristics of your application. how big the hashes will be, how often they'll change, and so on
19:58amalloymy inclination is to search maps sequentially because it feels like a better description of how nested scopes behave, and especially if the values in the hashes can change you don't want to have to ripple through to all parent scopes
19:59currentBok sweet, that actually seems really obvious now that you put it that way, thanks a ton!
20:00currentBthis room is the great, it solves all my clojure struggles :)
20:24shortlordis there any way to alter all the leafs in a nested ref structure? I have a hash-map in a ref vector and I need to change the hash map for every entry in the vector
20:25amalloyshortlord: like (ref [{:foo 1} {:bar 2}])?
20:26shortlordamalloy: no, rather like [[:key1 {:foo false}] [:key2 {:foo false}]
20:26shortlordand I want to set every :foo to true without changing the keys :key1 or :key2
20:27shortlordthere is only one entry in the vector supposed to be {:foo true}, so it would also be ok to find this entry and then selectively switch that to false
20:28amalloy&(map #(assoc-in % [2 :foo] true) [[:key1 {:foo false}] [:key2 {:foo false}]])
20:28sexpbot⟹ ([:key1 {:foo false} {:foo true}] [:key2 {:foo false} {:foo true}])
20:28amalloywhoops
20:28amalloy&(map #(assoc-in % [1 :foo] true) [[:key1 {:foo false}] [:key2 {:foo false}]])
20:28sexpbot⟹ ([:key1 {:foo true}] [:key2 {:foo true}])
20:29amalloyshortlord: like so?
20:29shortlordamalloy: that could work, I'll try that
20:29shortlordthx
20:30currentBone more thing, using map on a seq will always process the seq in order right?
20:31amalloycurrentB: yes. as long as the seq has some notion of order; for example, hash-maps don't
20:32currentBk
20:34amalloyeven for non-ordered seqs, you're guaranteed (i think?) that if you iterate over an identical seq N times, it will always be in the same order. but if you, say, add a key or change a value, you may get a completely different order
20:39shortlordamalloy: it still does not work:
20:39shortlord(dosync
20:39shortlord (alter fields map #(assoc-in % [3 :bandit] false))
20:39shortlord (alter fields assoc-in [field 3 :bandit] true)))
20:39shortlordthat's the error: clojure.lang.LazySeq cannot be cast to clojure.lang.Associative (repl-1:582)
20:40amalloyshortlord: well, one issue is that you're passing the arguments to map in the wrong order: it will look like (map @fields #(fn...))
20:41shortlordamalloy: I tried partial and even a custom fn, but it didn't help
20:41amalloythe other is that assoc-ing will only work on maps and vectors; if fields contains lists or seqs, it won't do the right thing
20:43shortlordamalloy: that's strange, because I am operating on a vector
20:43amalloyshortlord: then it's probably the first problem
20:43shortlordamalloy: well, partial is supposed to curry a function, right?
20:44shortlordso I thought this should work: (alter fields (partial map #(assoc-in % [3 :bandit] false)))
20:45amalloyit does seems that way
20:47shortlordamalloy: do you know a good paste service that supports clojure syntax highlighting? I could paste the whole source then
20:47amalloyso fields is a (ref of a) vector of things you want to work with; each things is a vector whose fourth element is a map you want to add :bandit false to?
20:47amalloyshortlord: http://gist.github.com
20:48amalloy&(let [fields (atom [[0 1 2 {:player true}]])] (swap! fields (partial map #(assoc-in % [3 :bandit] false))) @fields)
20:48sexpbot⟹ ([0 1 2 {:bandit false, :player true}])
20:49shortlordamalloy: https://gist.github.com/747927
20:51amalloyshortlord: map is going to return a seq, not a vector
20:51amalloy&(map inc [1 2])
20:51sexpbot⟹ (2 3)
20:51amalloy&(vec (map inc [1 2]))
20:51sexpbot⟹ [2 3]
20:51clojurebotmap is lazy
20:52amalloyso after you map over fields, it's turned into a lazy seq and the next assoc-in fails because it's not a vector
20:52amalloythe easiest fix is to make it back into a vector when you're done: (comp vec (partial map...))
20:53amalloyclojurebot: that was surprisingly on-topic. have a cookie, i guess
20:53clojurebotTitim gan éirí ort.
20:54amalloyshortlord: follow all that?
20:55shortlordamalloy: yeah, that works and makes sense :)
20:55shortlordthx a lot
20:55shortlordthis channel is incredibly helpful :)
21:13tomojif aleph clients are channels, you can only issue one request at a time without causing problems about figuring out which response was to which request, right?
21:55hippiehunteris there some relative of clojure.contrib.monads.maybe-m that throws an exception or logs on what step it failed?
21:56brehauthippiehunter: why not just use exceptions or conditions?
21:57hippiehunterbecause the only failure condition is nil and i'm not good enough with macros to make that a palatable syntax
21:58amalloyhippiehunter: write a monad transformation on top of maybe-m?
22:01hippiehunterIm pretty noobish when it comes to doing anything other than basic consumption of monads. I was just asking to see if there was anything already in existance that my search missed.
22:02brehauthippiehunter: while you could do it with a monad or monad transformer i think it would be overkill. great if you want to learn how they work more but probably not the right solution
22:03brehauthippiehunter: that being said, maybe-m is trivial to write, so you could easily concoct your own version that throws an exception on nil
22:04tomojwas there somewhat recently a change in the way the metadata works?
22:04tomojsomething to make :static easier, I think?
22:06tomojdid "^:foo" no longer mean "{:tag :foo}"? post 1.2
22:09amalloytomoj: i don't think that's the case, but i'm still on 1.2
22:11tomojoh well, :tag is fine
22:13shortlordwhat is the best way to keep indices in "looping" bounds? for example: if the vector has the length 5, the indices 0 to 4 stay the same, 5 becomes 0, -1 becomes 4, etc. In python it's possible to use the modulo, but clojures (rem -1 5) returns -1 instead of 4
22:14amalloy&(mod -1 5)
22:14sexpbot⟹ 4
22:14shortlordoh, mod exists as a separate function? great! :D
22:14amalloyshortlord: yeah, read the doc for mod and rem. they behave differently for negative numbers
22:15shortlordamalloy: ok, thx
22:17amalloybtw shortlord, a fun mod trick: ##((juxt quot rem) 23 4)
22:17sexpbot⟹ [5 3]
22:17cemericktomoj: ^:foo means {:foo true} in 1.3
22:17cemerick^String means {:tag String}
22:17cemericksince 1.2
22:20bortrebwhat's a good way to write and read objects created by clojure with defrecord to and from disk?
22:21tomojcemerick: ah, ok
22:21tomojcemerick: and then you can do "^:foo ^:bar" for "{:foo true :bar true}" ?
22:21tomojthat would be great
22:21cemerickexactly
22:22tomojthat will force me to generate a bunch of stub classes if I keep it this way... :(
22:25joshua__Question for you guys. I'm trying to help my uncle out by building a dll in C++. I want to talk in the C++ channel to ask questions, but it says that the message can't be sent. What am I missing here or is this a glitch?
22:25amalloyjoshua__: you probably need to register your nick
22:25bortrebdo something like /msg nickserv identify <your-password> ?
22:30anthony__(completely new at all things lisp/functional) I'm using doseq to iterate through the elements in a vector, and I need to append each one to a string, which will be the value of my function. What's the best way to do this? Should I be using map instead of doseq?
22:31cemerickanthony__: welcome :-)
22:31cemerick,(map #(str "foo" %) (range 10))
22:31clojurebot("foo0" "foo1" "foo2" "foo3" "foo4" "foo5" "foo6" "foo7" "foo8" "foo9")
22:31amalloyanthony__: you should be using reduce, probably
22:31amalloy&(reduce str ["foo1" "foo2" "foo3"])
22:31sexpbot⟹ "foo1foo2foo3"
22:32anthony__Ah man, that's so elegant.
22:32amalloyanthony__: welcome to lisp! :)
22:32cemerickof course, apply is far more efficient for string concatenation
22:32amalloywell yes
22:32cemerick&(apply str ["foo1" "a" "k"])
22:32sexpbot⟹ "foo1ak"
22:33anthony__Dang it. I used apply in another function. Tried to use it here and couldn't figure it out. Java has ruined me.
22:33anthony__Thanks for the help.
22:34amalloyanthony__: good thing you couldn't figure apply out - now you know about reduce, too!
22:35anthony__haha very true
23:03Lajla(thunk)
23:03LajlaI take that back.
23:03Lajla(thunk-cps Lajla)
23:03LajlaSo, what have you got for me baby
23:04currentBeh, if I'm implementing a recursive descent parser, is it only necessary/ideal to put one dosync before the recursion entry to handle everything? is that bad form?
23:06amalloycurrentB: why do you need mutable state for a parser?
23:06amalloy$google fnparse
23:06sexpbotFirst out of 104 results is: joshua-choi/fnparse - GitHub
23:06sexpbothttps://github.com/joshua-choi/fnparse
23:08currentByeah i found stuff like that but it's for an undergrad class where we could just use whatever language we want, and I figured it'd be cool to use clojure but it's probably best to just go with the method the rest of the class is supposed to use
23:08currentBdefinitely against the current in a few places..
23:09amalloycurrentB: well, parsers are very recursive in nature; it's very convenient to be able to backtrack and have the right state already on the stack without having to restore it manually from a ref
23:12currentBk cool I'll meditate on that a bit :) thanks again
23:54mister_roboto1is there a library function to get the index of some value in a collection? e.g. if i have [:a :b :c] i want to pass :b and get 1 back
23:55mister_roboto1if there is something built in, i can't find it