#clojure logs

2011-04-29

00:00dnolenchoffstein: what I mean is what advantage over an atom?
00:00choffstein...uh, no idea. As I said, I am very new to clojure :)
00:01amalloyi wonder if the popularity of refs, when atoms would do, is related to refs being an older language feature
00:01amalloy(they are, right? i'm not imagining it?)
00:01dnolenchoffstein: dosync is about coordinating changes between data, if you just need to serialize access to something, atoms are fine and much faster.
00:01choffsteinamalloy: I use ref because I come from a SML background -- and ML has refs. Maybe that's it?
00:02choffsteindnolen: ah, I see. atoms may be okay then :)
00:02cemerickamalloy: "I'm using _STM_, baby!" is enough of a thrill for a lot of people to motivate the usage. ;-)
00:02amalloynice
00:03carllercheI'm trying to write a connection pool, would it be better to represent it as an atom -> { "hostname" PersistentQueue } or maybe ref -> { "hostname" ref -> PersistentQueue } and then use dosync, or maybe a ref -> { "hostname PersistentQueue } directly and still use dosync?
00:04amalloyi can't think of a good reason to have a ref of a map of refs
00:06choffsteindnolen: when you say coordinating changes between data, what exactly do you mean? In a concurrent sense -- like a database?
00:06dnolenchoffstein: yes.
00:06dnolenchoffstein: dosync is like a db transaction
00:07choffsteindnolen: well, then it might make sense for my 'sessions' to be refs then, right, since those would be used across website users?
00:07choffsteinwhereas something that is specific to an individual session that will only be touched by a user and is just being used for serialization can be an atom
00:07choffstein?
00:09dnolenchoffstein: dosync if there are not two peices of data involved doesn't make sense, to me at least. dosync is about changing > 1 refs.
00:10choffsteinAnnnnddd that makes a whole lot more sense now.
00:10carllercheamalloy: well, if trying to modify the individual queues becomes highly contended, wouldn't that loosen up the number of transactions that need to be restarted?
00:10choffsteinso if I had a list of refs and I wanted to alter them all, I would wrap it with a dosync?
00:11carllerche(i haven't actually gotten around to using refs yet, so I don't know)
00:11dnolenchoffstein: yes, but you want to control the scope of a transaction, better for a transaction to try to change two rather than ten refs at the same time.
00:11choffsteinhmmm. I think i'll leave transactions alone for a little while :D
00:11choffsteinI think i'm pretty happy with my horrible hacking for this evening.
00:12amalloyyour use of the word "pooling" implies, to me, a fixed-size pool, so you never need to alter the top-level structure. it can just be an immutable map of (somethings) to (refs of connections)
00:12dnolencarllerche: I don't know much about efficient connection pools, I would look at how other people have done it. atoms and and refs have costs. but maybe efficiency is not a big concern in your case.
00:12carllercheamalloy: I'm actually building an HTTP reverse proxy that could have arbitrary end points
00:13carllercheso, basically my goal is to determine the total number of open connections that can be held at once (in the thousands) and build an LRU that can manage that
00:13amalloyokay...
00:14amalloyi'm hearing you say "yes, i have a fixed-size map"
00:14choffsteinalright. time for bed before my brain melts. later all.
00:15carllercheamalloy: well, the keys can't be predetermined... it would be based on usage
00:15carllercheaka, i can't preallocate the connections
00:17carllerchei guess i could try the various options and see what works best
00:18carllerchealthough, i wonder if i could just implement it as commutative operations
00:19carllercheamalloy: so, what you are saying is that a ref to a map of refs is just crazy talk?
00:19amalloyyes. i have violent reactions to overuse of mutable state, so take that with a grain of salt though
00:20amalloyrata convinced me an atom of a map of agents made sense, though, at some point
00:21Apage43do agents have any ordering guarantees?
00:22cemerickcarllerche: I presume that any talk of refs in conjunction with IO stuffs is crazy. Transactions will be retried. IO operations should not be retried. :-)
00:22amalloyApage43: all requests from thread X will be processed in the order X sent them
00:22Apage43k
00:22Apage43i figured that'd be the case, just didn't remember
00:23Apage43cemerick: the commutative part (if using commute) won't be though
00:24carllerchecemerick: right... this is just for some structure that can store / retrieve objects
00:24carllercheno IO operations
00:37carllerchei'm confused about commute, is it possible for the retval of commute to be different from the value the ref gets set to?
01:16Apage43carllerche is gone
01:16Apage43but yes
01:17Apage43or rather
01:18Apage43well, it barely matters.
01:20tomojI'm interested
02:58stirfoodoes this profile macro look correct? http://paste.lisp.org/display/121658
02:59stirfoothe thing that bugs me is a given entry function shows less time than functions called by that entry function
03:01clgvstirfoo: the initial let looks fine. dont forget about lazy evaluation which can cause your functions to return fast since the real evaluation is postponed to the time the entry in the lazy seq is read
03:01stirfooclgv: yes, that's something I haven't gotten a grip on yet, lazyness
03:02clgvyour if-let has a different meaning than you might think
03:02stirfoooh? do tell
03:04clgvthat might work as well: ##(if-let [[a b] [nil nil]] [a b] 'else)
03:04clgvbut it seems that doesnt matter in the remaining code
03:04sexpbot⟹ [nil nil]
03:05clgvsummarizing: the code looks ok
03:08stirfoook, thanks clgv. Is the actual book 'joy of clojure' available yet? I know I can get a pdf. Haven't checked their site in a while.
03:08clgvstirfoo: yes it is
03:09stirfooawesome
03:09clgveven on amazon now ;)
03:10ambrosebsmine just came in the mail
03:10ambrosebslove the guy on the cover
03:11stirfooI read one or two of the freebee chapters a while back. Seemed like a well written book.
03:11ambrosebsI ordered "Learn you a haskell for great good", which has a blue elephant on the front... two fun covers with fun titles :)
03:12stirfooDid Duane draw the elephant? (scheme joke)
03:14ambrosebs*whoosh* :P
03:16ambrosebson the way to work this morning I was thinking if "The Joy of Java" would pop up in some form xD
03:17ambrosebsthe only cover I've seen that advocates java as "fun" is the Pragmatic Programmers' Stripes book
03:17ambrosebssubtitled: "...and Java web development is fun again!"
03:17ambrosebsI laughed
03:17ambrosebsstill, good book, good framework.
03:30amalloytomoj: (commute) sets the ref to some temporary value for within your transaction, and returns that value. when you go to commit your transaction, if anyone else has altered/commuted that ref in the meantime, the stm re-performs the commute function with the new ref value and commits that
03:30amalloyit doesn't have to retry the transaction or tell you about the new value at all, because you told it commuting was okay
03:31amalloyso it is possible for (commute) to return a value that the ref never actually has, outside of your snapshot fantasy-land
04:02clgvIs it possible to combine two different plots with different scales in on Incanter chart? e.g. one scale on the left the other on the right?
04:03clgv*one
04:21pyrhi
04:23pyrI'm facing a weird use case with leiningen. How do I integrate jars which are not in any maven repo ?
04:28pyrI could put them in lib/ but every lein clean flushes them out
04:29clgvpyr: just add ":disable-implicit-clean true" to your project.clj
04:30pyr'k thanks
07:11ordnungswidrig1*print-dup* causes records to be dumped as #=foo.BarRecord/create {:a 1 :b 2 :c 3} how to I dump records so that load-string will read them?
07:43thorwilordnungswidrig: isn't read meant to used for such dumps?
07:44ordnungswidrigthorwil: the reader doesn't support record literals yet
07:44ordnungswidrigthorwil: the need of importing the record class makes is worse
08:09clgvordnungswidrig: you could dump them as normal maps and read those maps and assoc them...
08:09ordnungswidrigclgv: no so easy because you need some reflection to initialize an empty record.
08:09ordnungswidrigclgv: but certainly possible
08:11clgvordnungswidrig: oh ok. I assumed you will know the record type at the time you want to read it
08:13ordnungswidrigclgv: no, but I can flip it into a map, like (defrecord Foo [a b c]) and (Foo. 1 2 3) -> {::type "some-ns/Foo" :a 1 :b 2 :c 3 }
08:14ordnungswidrigclgv: on read time i can transform back
08:14clgvordnungswidrig: I know ;) but it's less code without the reflection part and thus easier ;)
08:16clgvordnungswidrig: humm why not write (Foo. 1 2 3) to file? maybe with namespace associated?
08:30fliebeldnolen: I'm in the train, read the little paper. The syntax is indeed weird. What of this all is most relevant to your plan?
08:30dnolenthe pattern matching paper?
08:30dnolenfliebel: ^
08:32fliebelyea
08:32fliebeluhm, no, well... the one with ml
08:34dnolenfliebel: yeah that's the pattern matching paper. the paper shows you how to do pattern matching efficiently, the implementation allows you to break apart the compilation and analysis/optimization steps.
08:35dnolenwhich makes the implementation a lot simpler/cleaner than previous papers on papers on pattern matching.
08:35david`what's the difference between (case x) and (condp = x)?
08:36dnolendavid`: case does not test possibilities.
08:36fliebeldnolen: Ah, I see. And you want to use Logos to generate the maximum sharing shallow stuff?
08:37david`I see, so the "= x" can be changed to really any test condition
08:38david`like condp some [1 2 3 4]
08:38dnolenfliebel: no I plan on implementing what's described in the pattern matching paper as is. but pattern matching has a problem. It's closed, you can't add stuff later. Also order matters, it's easy to make a mistake and write broken pattern.
08:39dnolenfliebel: keeping things open is unrelated to the logic engine, however automatically reordering clauses is something the logic engine can do.
08:40dnolenfliebel: consider (defm foo [x] :guard (even? x))
08:40dnolenfliebel: then consider that someone else wants to add (defm foo [0]) after the fact.
08:40dnolenfliebel: because the first one was defined first, the second one will never be reached.
08:41dnolenfliebel: we can fix that with a logic engine.
08:41fliebeloh, so you are just implementing these pares really. I thought you want to tell logos the properties of the tree ansd say "go do it"
08:43dnolenfliebel: it will store properties of the tree, but it's there to solve implication issues like the one above.
08:43fliebeloh, okay. Interestng. I need to go now though, my train isn't going where it should.
08:48dnolendavid`: yes.
08:55david`kewl
10:12devndnolen: intensely awesome work
10:12clgv(apply third-party-macro param1 param2 options) does not work. can I work around that somehow?
10:13dnolendevn: heh, at this point we're still in the realm of ideas ;)
10:14devndnolen: even still, the germ of the idea is exciting
10:14devndnolen: is there video anywhere of this LispNYC talk you gave?
10:15apgwozdevn: you have to move to nyc to see it
10:15apgwozsorry, them's the rules
10:15devnapgwoz: how big is your apartment?
10:15apgwozbig enough for my wife, a baby (soon) and myself. not for you
10:15apgwoz:)
10:15devnalls i've got is this here stick and bindle
10:16apgwozedw: chicken scheme can speak to slime now
10:18devnapgwoz: you bring up an important point. i'd like a move sometime soon.
10:18apgwozmadison isn't happening enough for you?
10:18Ramblurrdo most people use the stable clojure release or use the live git version?
10:18apgwozdevn: meetup is hiring, though there's only a tiny tiny tiny bit of clojure code at the moment.
10:18devnI really like Madison, but once my girlfriend is finished with school next semester we're sort of planning on a move East or West
10:19apgwozyeah, i visited madison last september, nice place.
10:20devnthere's going to be a madison ruby conference this year -- excuse for you to make a visit
10:21devnapgwoz: either way, maybe ill come out to NYC for a weekend and see some friends, drop by the LispNYC meetup
10:21devnRamblurr: depends on what you want to do
10:22devnRamblurr: id say most are on stable, though
10:24apgwozdevn: but i don't really like ruby, so that's a reason to avoid madison :)
10:26Ramblurrdevn: ah, hm. I asked because my 1.2.0 jar seems to be missing functions: join, blank?
10:27devnRamblurr: what's your setup?
10:27Ramblurrdevn: oh, i have to "use" the string module heh
10:28clgvhow can I avoid this: (eval `(xy-plot ~x ~first-col ~@options)) ???
10:28clgvxy-plot is a macro unfortunately sothat I can't use apply
10:28Ramblurrdevn: is this error expected when doing (use 'clojure.string) ? WARNING: replace already refers to: #'clojure.core/replace in namespace: user, being replaced by: #'clojure.string/replace
10:29devnRamblurr: yes.
10:29devnRamblurr: are you just getting used to the idea of clojure's namespaces and such?
10:29devnRamblurr: http://blog.8thlight.com/articles/2010/12/6/clojure-libs-and-namespaces-require-use-import-and-ns
10:29pjstadigclgv: write your own wrapper macro?
10:29Ramblurrdevn: yea, this is my first encounter with them
10:30Ramblurrdevn: thanks for the reading
10:30devnRamblurr: not a problem. have fun
10:30clgvpjstadig: errmmm... how?
10:30clgvjust extract the code over there?
10:31pjstadigyeah something like (defmacro xy-plot2 [x first-col & options] `(xy-plot ~x ~first-col ~@options))
10:32pjstadigeval + syntax-quote is essentially macro evaluation anyway
10:35clgv pjstadig: hmm I can't really get around it. I want to write a function but the option-handling forces me to write a macro if I do not use eval + syntay-quote
10:35pjstadigwhere is xy-plot from and why is it a macro?
10:37clgvit's from Incanter
10:37clgvI dont know why it is a macro
10:37clgvit just seems to do some default value handling for options
10:38sritchiehere's the source -- https://github.com/liebke/incanter/blob/8736bc3cae44491172031b381c6e165c0bd1139c/modules/incanter-charts/src/incanter/charts.clj#L984
10:38clgvsritchie: already looking at it ;)
10:39sritchieclgv: just trying to live up to clojurebot's helpfulness :)
10:40Ramblurro_0 I'm getting different results from a function when i call it with dotrace or by itself
10:43chouserRamblurr: is dotrace printing return values of functions or their arguments? or just listing the names of functions being called?
10:44Ramblurrchouser: both
10:44Ramblurrchouser: preparing a snippet, one sec
10:44pjstadigclgv: you could do something icky like (apply xy-plot* x first-col @#'incanter.charts/create-xy-plot options)
10:45chouserRamblurr: if it prints return values or args, it may be forcing lazy sequences that wouldn't otherwise be realized.
10:46Ramblurrchouser: oh, i see
10:46clgvpjstadig: hmmm I guess I'll write the whole thing as macro
10:48Ramblurrchouser: http://pastebin.com/aALcDt1y
10:51Ramblurrchouser: and here is the output different http://pastebin.com/QXvHVige Would you say this is a case of lazy seqs being evaled?
10:59pyrhi, do you any use cases where clojure.contrib.sql's with-query-results could yield an exception because distinct? was called with no arguments
11:15mec(let [[a b c] (if t [1 2 3] [2 3 4])] ...) vs (let [foo (fn [a b c])] (if t (foo 1 2 3) (foo 2 3 4))
11:20semperosis there any reason to use clojure.string/escape over clojure.string/replace?
11:20kzarI'm trying to get my head around Enlive, I've made a snippet to add stylesheet links to my page's layout. For my snippet selector I've used [:link {:rel "stylesheet"}], I've then done used set-attr on [:link] in an attempt to set the href of the stylesheet. I can't get it working though. Also it seems weird that I have to define my template to point to layout.html and then point my css including snippet at the layout
11:20kzar.html template too. I get the feeling I've totally misunderstood something here?
11:20semperosin microbenchmark, clojure.string/replace performed better
11:21semperosother than the need to replace more than one thing in a single swipe
11:26manutterkzar: do you have a gist?
11:26kzarmanutter: http://paste.lisp.org/display/121664
11:27kzarmanutter: The css-include part is what's confusing me although it's likely all backwards
11:42edwIn theory, shouldn't re-factoring conserve the does-it-work? property?
11:54kzarmanutter: I've cracked a couple of problems, just got to figure out how to get it populating the href properly now
12:07kzarah I've cracked it :)
12:14manutterMan, bosses can be so demanding at times :\
12:14manutterGood, I'm glad you got it, I got called away
12:15kzarno worries! I know what that's like heh
12:22TimMcedw: Yeah, and as long as it doesn't affect your API, your automated tests should all still pass.
12:55TimMc(You *are* writing tests, yes? :-P)
12:55semperosanyone know proper spec for clojure.contrib.sql for a DATETIME column? tried :datetime
12:56semperossorry, for the clojure.contrib.sql/create-table fn
13:11ataggartstuarthalloway: free to discuss the bit-ops stuff?
13:12stuarthallowayyep
13:13ataggartread your responses, everything looks as I expected. ONe question: what's the point of having Object overloads if everything gets treated as a long anyway?
13:14stuarthallowayI think you will find that there are code paths where things come in as objects
13:14stuarthallowayyou can try long only and see what happens :-)
13:14ataggartI have: https://github.com/ataggart/clojure/commits/bit-ops
13:14ataggartthe compiler knows how to push numbers to long primitives
13:16ataggartif that commit looks good, I'll make a patch and attach it to 767
13:17stuarthallowaythe core.clj changes in that commit seem related to something else ?
13:17stuarthallowayreviewing the numbers.java changes now
13:18ataggartthe change in core.clj is because where the exception on passing a double to even? went away
13:20stuarthallowayseems like exception is the right behavior
13:20ataggartit used to be thrown via bitAnn on line 1201 in Numbers
13:20stuarthallowaywhat does it mean for a double to be even?
13:21ataggartyep, it's always thrown an exception on non-integer nums
13:21ataggartjust changed the location
13:21stuarthallowaylet's leave that out of the patch
13:22stuarthallowaydo you know if the shiftLeftInt variants are ever used anywhere?
13:22ataggartthey are not
13:23ataggartI'm not clear on what you want left out of the patch. even? is supposed to throw an exception; that exception used to be thrown by bitAnd which used to throw it in bitOps, bit bitOps is gone, so someone needs to throw the exception when even? is called with a non-integer
13:24stuarthallowaywhat happens without the change in core?
13:24ataggarttests failed, don't recall what
13:24ataggartlemme see
13:25stuarthallowaythanks, trying it here as well
13:25stuarthallowaydid you see that #426 (case) finally got in?
13:26ataggartI'm not a religious man, but....
13:26ataggartwhat was the voodoo you used to find those bad numbers?
13:27stuarthallowayataggart: I thought Alan told you
13:28stuarthallowayhttps://github.com/clojure/test.generative
13:28ataggarthe mentioned you had some framework, ah yeah nice
13:28stuarthallowaythe tests are still in there (under examples)
13:28aredingtonAlan was probably avoiding stealing Stu's thunder on dropping that bombshell
13:32ataggartsigh, the compiler is automatically casting from non-integers to long
13:32aredingtonWhat kind of non-integers ?
13:32ataggartratios, doubles
13:33ataggartanythign that's not a long or int
13:34ataggartwhen the param is long, but the arg is neither long nor int, the param gets treated as an object and then automatically cast to the param type
13:35ataggartI can manually deal with all the type checking, but... ugh
13:36stuarthallowaynot sure I am totally following you without seeing it run -- going to build it now
13:36stuarthallowaysorry slow -- I am multitasking several numerics tasks here
13:36ataggartya sry, I can see it since my head has been in the compiler for a few months now
13:37ataggartanyway, it's a problem with bit-ops really, since (bit-and 1.5 1) is coming back 1
13:37ataggartbecause that 1.5 is getting truncated to a long
13:38ataggartby the compiler
13:38ataggartdon't waste your time on it, lemme fix that
13:38stuarthallowayso would the Object/long and long/Object variants fix that?
13:40ataggartthey wouldn't, but for (bit-and double long) the compiler would choose and(Object, long) and we can perform manual type checking, which is what bitOps used to do
13:40ataggartit's a deficiency in the compiler
13:40ataggartimo
13:40stuarthallowayfair enough, but let's get this done
13:40ataggartyup, half way there
13:52dakronestuarthalloway: response to your email, I need a float for a test as such: (is (= "3.14" (json/generate-string (float 3.14)))), but fails with the 1.3 stuff
13:52dakronefor testing a lib that has float methods
13:53stuarthallowaydakrone: where is the float method?
13:54stuarthallowaycalled inside json/generate-string somewhere?
13:54dakroneinside the generater, in a condp looking something like "... Float (.writeNumber jg ^Float obj)"
13:54dakroneyes
13:55stuarthallowayand you need float fidelity, so double promotion would be a bug?
13:56ataggart*cough*445 fixes that*cough*
13:56dakroneyes, otherwise I get the error that it can't find a correct method
13:57stuarthallowaylet me see if I have the general issue right: you have a serialization framework that depends on access to the different Java primitive types in order to drive different semantics
13:58dakronestuarthalloway: http://jackson.codehaus.org/1.7.4/javadoc/org/codehaus/jackson/JsonGenerator.html#writeNumber(int) there are 7 .writeNumber methods, which can be treated differently internally depending on class
13:59dakroneI have no way to guarentee that .writeNumber(double) behaves the same as .writeNumber(float)
13:59stuarthallowaydakrone: so you could get there by calling them directly (with float hinting) but any indirection (e.g. a Clojure fn) makes things doubles
14:00@rhickeydakrone: calling such an overloaded thing requires coercions
14:00@rhickeycoercions are not hints
14:01stuarthallowayrhickey: how does that work when there is a Clojure fn call between the float the Java method to be called
14:01dakronerhickey: If I'm doing condp with dispatch on type though, by that point the compiler's already made it a double
14:01@rhickeystuarthalloway: like what?
14:02@rhickeydakrone: condp doesn't do type dispatch on primitives
14:02semperossorry to re-ask, had to leave an hour ago
14:02@rhickeyif you want a boxed Float make one
14:02semperosdoes anyone know how to use clojure.contrib.sql/create-table with datetime columns?
14:02@rhickey(float x) does not make a Float
14:03dakroneno, understandable, how should I dispatch in a function then on primative, and call it from a test if in the test I use (float 3.14) and by the time it reaches a dispatch it's a double?
14:04stuarthallowaydakrone: (Float. 3.14)
14:04@rhickeystuarthalloway: you can't route floats around, Clojure doesn't have primitive floats
14:04ataggartit *could*...
14:04stuarthallowaydakrone: when you are making a fn call you are using objects anyway
14:04@rhickey(float x) produces a float for immediate consumption by a Java thing that takes a float
14:04stuarthallowayataggart: go finish that patch :-)
14:05ataggartaye sir
14:05dakroneokay, then I will not be able to handle doing json enconding of java methods that *could* return floats
14:05stuarthallowaydakrone: yes, you could, with (Float. )
14:05@rhickeydakrone: I don't see why not
14:05dakrone(json/encode (.methodThatReturnsAPrimativeFloat foo)), at that point it would be a float, how can I dispatch on it?
14:06@rhickeyataggart: no, it won't
14:06ataggartstuarthalloway: https://github.com/ataggart/clojure/commit/496135716ab8687ba4373ca9799db57ed6638060
14:06hiredmanif you call a java method and it returns X, but you aren't sure what type X is, how do you determine the type of X in such a way that avoids boxing X as a different type?
14:06dakroneI can dispatch in encode in a condp with Float, but it's not a Float and I need to dispatch in encode on what type it is
14:07pjstadigright, it's not *inter*op if it only goes one way, if values returned from java are converted to doubles, then there's no way to maintain fidelity of floats to/from java
14:07ataggartrhickey: every fall to a float-taking method is effectively called like Foo.bar((float)(double)myFloat). That causes unexpected changes in value, and can be easily fixed.
14:07@rhickeydakrone: how would you write json/encode in java?
14:09hiredmandakrone: you happen to have it also written up in java, yes?
14:09stuarthallowayataggart: given no plan to support big ints, can we not replace bitOpsCast with a simple cast to long?
14:09@rhickeycall RT.box then
14:10hiredmanrhickey: on which side of the fn call?
14:10ataggartstuarthalloway: the choices are unchecked cast to long, checked cast to long which accepts all numic categories (i.e. RT.longCast(Object)), or the category-specific checked cast I added.
14:11hiredmancalling RT/box inside the fn is too late (conversions have happened) calling it outside means all callers of encode have to call (encode (RT/box x))
14:11dakronerhickey: In java the point would be moot since there would no longer be a wrapper in the middle, you would call the generate method directly and java would route to the right place
14:11kzarDoes anyone else find that sometimes emacs stops displaying function arguments in the mini buffer after a while?
14:11@rhickeyhiredman: was speaking to json/encode
14:12hiredmanuh, I thought I was too?
14:12@rhickeyI'm not particularly attached to floats as Doubles if itsa big problem for people. short/int/long as Long is a bigger deal
14:13semperoskzar: you using slime/swank?
14:13hiredmangiven the lack of floating point weirdness I can't imagine it would be a big deal
14:13kzarsemperos: Yea, it works fine but just sometimes after a while it breaks
14:13@rhickeydakrone: I don't understand
14:14kzarsemperos: It's probably my god-awful code causing it to seppuku heh
14:14no_mindI have serialzed a map and stored in a string to dump in a db. NowI want to deserialize the sw do I do it ? map. Hotring to
14:14semperoskzar: I've had similar happen; sometimes I forget to compile and load ns's
14:14semperossometimes it just needs a classic reboot :)
14:15raekno_mind: are you talking about pr-str and read-string?
14:16dakronerhickey: In java, I'd encode directly and be happy, no special forms or rewriting required. In clojure, I need to dispatch on things like vectors, lists, maps and such to translate them to an encodeable-format before passing them down to the java methods, once I have a list though, I need to dispatch on each element in the list, with could be a Number, so I do a condp and dispatch on Number. I do this recursively, so have a co
14:16dakronedoes that kinda explain it?
14:16no_mindraek: dont know what they are ? I serialized the string with *print-dup*
14:17stuarthallowayrhickey: should (bit-and 1N 1) throw an exception, or coerce to primitive long and proceed?
14:17raek,(let [m {:a "1", :b "2"}] [m (pr-str m) (read-string (pr-str m))])
14:17clojurebot[{:a "1", :b "2"} "{:a \"1\", :b \"2\"}" {:a "1", :b "2"}]
14:18amalloydakrone: fyi your huge-long message was too long for irc and got truncated at "have a co"
14:19pjstadigupcasting bytes, shorts, ints as longs makes sense, because those types are precise and you can just chop off some data to down cast it without any loss
14:19@rhickeystuarthalloway: if bit-and is defined for longs only then that has the same answer as should any long-taking method accept BigInts (i.e. the converson question we talked about this morning)
14:19pjstadigas we've seen upcasting from float to double produces slightly different values
14:19raekno_mind: if a value is built only of strings, keywords, symbols, lists, vectors, maps etc (i.e. only object that are part of the clojure syntax), then you can use pr-str to turn it into a string and use read-string for the reverse
14:19pjstadigfloats are not exactly a subset of doubles
14:20no_mindok
14:20dakronerhickey: http://p.writequit.org/explain.html
14:20dakroneamalloy: thanks for the heads up
14:20stuarthallowayrhickey: what about even?, which (as implementation detail IMO) is implemented with bitops
14:20@rhickeydakrone: that's getting bigger and bigger - make the problem smaller - what would the signature of encode be in Java?
14:22dakronerhickey: that's what I'm saying, there would be no need for encode in java
14:22dakroneIt's entirely possible that I am Doing It Wrong (tm)
14:22dakronewill look and get back to you
14:23@rhickeystuarthalloway: what about it?
14:24@rhickeystuarthalloway: should even? work for bigints? - of course
14:25stuarthallowayrhickey: right on, so the implementation has to change, since bit-and will not work for big ints
14:25@rhickeystuarthalloway: sounds right
14:28stuarthallowaytotally separate issue: running Clojure in IDEA for debugging
14:28scgilardiwould the change be to use BigInteger's "and" method directly? avoiding a division or div/rem operation for even? would be nice.
14:29stuarthallowayI am stuck because the basic compilation doesn't put the version resource in the right place, causing an NPE reading the version string
14:29aredington(= (mod <num> 2) 0) should work transparently across all integer values
14:29stuarthallowayI can think of a dozen workarounds or fixes, any strong opinions? Or does anybody have a workflow (not including ant or maven) for interactive debugging?
14:30hiredmanI have a lein'ized clojure build
14:30fogus`stuarthalloway: sed was my Huckleberry. It sucked
14:31scgilardiaredington: mod is division-y
14:31hiredmanI rember futzing with the version file issue
14:31stuarthallowayfogus` : why is there a backtick in your name?
14:31hiredmandunno how well it would work in IDEA
14:31fogus`stuarthalloway: Some other fogus took my name
14:31aredingtontoo many fogii
14:31stuarthallowayfogus` : poor Optimus had the same problem
14:31aredingtonthat's right you can't outtype me
14:32redingerfogi?
14:32fogus`fogen
14:32optimus`not funny guys
14:33hiredmanhttps://github.com/hiredman/clojure/commit/0a1c064c767991004b94aa796181aed111c98f34
14:34stuarthallowayhiredman: zoinks
14:35hiredmanoh, actually now I remember it doesn't build with a stock lein either
14:35hiredmandamn
14:35hiredmanlein puts ./src on the classpath which breaks for building clojure
14:36bultersalandipert: I was just wondering who would be optimus prime then.
14:36mecanyone know the O of adding to a sorted set?
14:37chousermec: there's a nice chart for that...
14:37stuarthallowayataggart: re http://dev.clojure.org/jira/browse/CLJ-781, you need to put your shorts in the first branch of the if
14:38bultersmec: ordered? then it\s usually a O(log n/log r) op
14:38stuarthallowayataggart: otherwise they fall through and get converted to doubles, then longs.
14:39ataggartstuarthalloway: what are you referring to?
14:39ataggartthe patch on 781?
14:39amalloymec: log2(n)
14:39mecthanks all
14:39stuarthallowayataggart, sorry, wrong link: http://dev.clojure.org/jira/browse/CLJ-782
14:40stuarthallowayshorts used to fall down to the longCast at the bottom
14:40fbru02stuarthalloway: Hey ! Can you please take a look at http://dev.clojure.org/jira/browse/CLJ-730 ?
14:41stuarthallowayfbur02: we'll take a look, but lower priority than bugs
14:42stuarthallowayataggart: if you are working on the bit-ops patch, I can tweak 782 and submit it to Rich
14:43@rhickeyhttps://github.com/clojure/clojure/commit/6fb09f402c5448070a2efc64ebd64285480b263f
14:43ataggartok, just add Short and Byte to the first if
14:44stuarthallowayrhickey: performance tweaking question for you
14:44@rhickeystuarthalloway: ok
14:44stuarthallowayataggart's patch http://dev.clojure.org/jira/browse/CLJ-782 correctly splits out a new path in longCast
14:44hiredmanthe passes are Parser/paser and Expr/(emit|eval)?
14:44hiredmanparse
14:45stuarthallowaybut that split implies the need to also split out short and byte, which used to fall to the bottom
14:45stuarthallowayis it important that those conditionals be away from the top, so the hot path (int and long) at the top doesn't pick up two more checks?
14:45stuarthallowayor does the short/byte case need to be handled further down
14:46@rhickeystuarthalloway: can't read these damn context-less patches
14:46@rhickeystuarthalloway: but yes, prioritize long and int please
14:47fbru02stuarthalloway: thanks :)
14:47stuarthallowayrhickey: apply the patch locally and then view in IDEA :-)
14:47@rhickeystuarthalloway: applying patches in order to see what they do is a huge time suck
14:47ataggartstuarthalloway: posted link to updated bit-ops commit for your review
14:48stuarthallowayataggart: can you move the short/byte check out of the first if, down later in the fn? (see discussion with rhickey above)
14:48ataggartstand by
14:52ataggartand updated cast fix: https://github.com/ataggart/clojure/commit/59bc3b2010ae7b0c8efb77e82939118b2f435045
14:54stuarthallowayataggart: https://github.com/ataggart/clojure/commit/59bc3b2010ae7b0c8efb77e82939118b2f435045 looks good. please put the patch on the ticket and I will screen it
14:55stuarthallowayataggart: still looking at the bit-ops patch and wondering how best to implement even?
14:55aredingtonchecking even let's BigIntegers in the door which are then going to be cast to long for bit-and
14:56ataggartthat shouldn't affect the eveness
14:56ataggartthe LSB is still going to be 1 or 0 irrespective of the truncation
14:57stuarthallowayataggart: so we should need unchecked-long instead of long?
14:57ataggartyup
14:57ataggartstand by
14:57scottjis there a shorter version of &&(reduce #(update-in %1 [%2] (fnil inc 0)) {} [1 2 3 1 2 1])
14:58amalloyscottj: ##, not &&
14:58scottj##(reduce #(update-in %1 [%2] (fnil inc 0)) {} [1 2 3 1 2 1])
14:58sexpbot⟹ {3 1, 2 2, 1 3}
14:58amalloy&(frequencies [1 2 3 1 2 1])
14:58sexpbot⟹ {1 3, 2 2, 3 1}
14:58dakronerhickey: I was able to work around the primative problem, I was indeed doing it not-wrong-but-not-the-best-way
14:58dakronethanks for the help
14:58scottjamalloy: thanks
14:59amalloyunless you're looking for a better way to reimplement frequencies
14:59@rhickeydakrone: I wasn't much help, but glad you are unstuck :)
15:00amalloyscottj: i think your original question is how i solved http://4clojure.com/problem/55
15:09choffsteinHey all! I have a question: I am basically trying to perform a map, but also while using an accumulator. So its sort of like reductions, but I don't want the accumulator recorded. Is this idea possible? I think it can be done using a recursive solution, but I was wondering if it was a built in idiom
15:09opqdonut_:t mapAccumL
15:10opqdonut_oh, sorry, I thought I was in #haskell
15:10opqdonut_no, I don
15:10opqdonut_'t think I've seen a function for that in the standard library
15:10opqdonut_but you might get a nice solution with map + reduce
15:12choffsteinyeah, I didn't think there would be
15:13opqdonut_IMO reducing with a slightly intricate function is better than a custom recursive solution
15:13choffsteinwell, what I need to do is basically keep "track" of a previous label and carry that label through to all nil labels until i hit a new label
15:14opqdonut_that
15:14bultersI have a dependency in a leiningen project (in this case org.clojars.liebke/congomongo "1.0.0") and I try to 'use' it in a slime session I get a compile error (FileNotFoundException)
15:14opqdonut_certainly sounds doable
15:14bultersbut checking the classpath, congomongo-1.0.0 is on it.
15:14opqdonut_(how come I keep hitting my return key by accident all the time?)
15:14stuarthallowayrhickey, ataggart: http://dev.clojure.org/jira/browse/CLJ-782 is screened
15:15amalloychoffstein: so use reductions, with a two-part accumulator: [the-map-value current-label]
15:15bultersany ideas what I'm doing wrong?
15:15amalloythen you can (map first (reductions (fn [[_ label]] (...return a vector of [map-value new-label]...))))
15:16ataggartrhickey has left the channel
15:16amalloysorry, should be (fn [[_ label] current-input] ...)
15:17choffsteinamalloy: that's what I was going to do, I just didn't know if that was idiomatic clojure
15:18amalloychoffstein: i tend to overuse the HOFs for cases when writing a lazy-seq by hand would be clearer and/or easier. this might be such a case
15:19raekbulters: did you check the classpath from within the clojure instance that could not use it?
15:19choffsteinHOFs?
15:19opqdonut_higher order functions
15:19opqdonut_like map, reduce
15:19bultersraek: yup, it clearly lists lib/congomongo-1.0.0.jar
15:20raekwhat namespace are you trying to use?
15:21bultersraek: tried 'everything' congomongo, liebke.congomongo, org.clojars.liebke/congomongo
15:21TimMcclojurebot: HOFs are higher order functions
15:21clojurebotanonymous functions are functions with no names
15:21TimMcbah
15:21TimMcThis bot can't conjugate.
15:22raekbulters: I don't think org.clojars.liebke is the official fork
15:22Ramblurri'm having an issue where the results of dotrace are different than when i println the function's results :\
15:23raekbulters: in the jar, there's a namespace called somnium.congomongo
15:23bultersraek: trying somnium now
15:23Ramblurrunfortunately the dotrace result is the correct one
15:23raekbulters: docs semes to be here: https://github.com/somnium/congomongo
15:25raekbulters: but for some reason, there isn't any stable (non-snapshot) version available
15:25bultersraek: my biggest hurdle I have so far in using clojure ;-)
15:27raekbulters: [congomongo "0.1.4-SNAPSHOT"] should work, but leiningen won't allow you to make a stable version of your project that depends on a snapshot version of a lib
15:27raekthis is probably why liebke pushed a private version
15:29bultersraek: Luckily I'm not releasing anything for the next few years
15:29bulters;-)
15:29bultersthanks, it compiles :D
15:49mechow come some places in core.clj call (drop 1 ...) instead of just next?
15:50rak85hi, guys
15:50rak85a ! in the end of a function name is some kind of convention?
15:51TimMcrak85: Yeah, it usually indicates mutation.
15:51TimMcSpecifically, things that aren't safe to call in a transaction.
15:51bultersTimMc: So stuff that has side effects go to a x! function?
15:52TimMcbulters: I think ! is usually used to make it clear when it wouldn't otherwise be obvious.
15:52bultersok, so store-blah is fairly obvious :P
15:52TimMcbulters: compare assoc vs. assoc! for instance
15:53bulterssame as in ruby, one variant that is non 'destructive' and one that is.
15:53meclooks like its mainly for things that muck with atoms and transients
15:53mecand vars
15:56rak85thanks everyone
15:58dnolenbulters: not quite, assoc! can only be used transients, and even then those can't be bashed in place.
16:01bultersdnolen: I have no idea what transients are... yet; guess it's google time
16:09mattmitchelli have what i think is a byte array: #<byte[] [B@ff22be7>
16:09mattmitchellhow do a pull out the items in that object?
16:09mattmitchellis the duck streams contrib required?
16:09ataggart,(aget (byte-array 1) 0)
16:09clojurebot0
16:10dnolen,(nth (byte-array 1) 0)
16:10clojurebot0
16:10ataggartnth uses a seq though
16:10ataggartiirc
16:11mattmitchellataggart: thanks! trying that out now...
16:12dnolenataggart: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L746
16:12ataggartyeah, so not a seq, but still more involved than aget
16:13dnolenataggart: true
16:14raek,(into-array [1 2 3])
16:14clojurebot#<Integer[] [Ljava.lang.Integer;@e8873a>
16:14raek,(seq (into-array [1 2 3]))
16:14clojurebot(1 2 3)
16:14mattmitchellok, so i could turn the byte array into a seq
16:14dnolenmattmitchell: if you don't care that you lose random access.
16:15raekmattmitchell: function that operate on sequences will call seq on the argument, so in most cases you can ommit seq
16:15raek,(map inc (into-array [1 2 3]))
16:15clojurebot(2 3 4)
16:15mattmitchellraek: ok cool
16:15ataggart(map inc (byte-array 3))
16:15ataggart,map inc (byte-array 3))
16:15clojurebot#<core$map clojure.core$map@b36022>
16:15ataggartbah
16:15ataggart,(map inc (byte-array 3))
16:15clojurebot(1 1 1)
16:16ataggartthis is annying though: ##(type (aget (int-array 1) 0))
16:16sexpbot⟹ java.lang.Integer
16:17ataggartwait what
16:17ataggartah 1.3.0 has that as a Long
16:20kzarThis has a very real danger of being a bad idea, badly executed but can anyone spot what's wrong with this macro? http://paste.lisp.org/display/121675
16:21raekyup. all integer numbers are represented as Longs when they are boxed in 1.3
16:21kzar(I wanted it to just return nil on any exception.)
16:23raekkzar: you need to use gensym'ed symbols to bind values: (catch Throwable e# ...)
16:24raekotherwise it will be resolved, as if it was meant to refer to a global var
16:24raek,`foo
16:24clojurebotsandbox/foo
16:24raek,`foo#
16:24clojurebotfoo__1290__auto__
16:24raekthis is to avoid symbol capture
16:25kzarraek: So with # it's gensymed and then the variable ends up being bound inside the place where it's actually being used. Otherwise it's not gensymed and it ends up being global to the namespace, or at least it tries to be but because it's not present I (ironically) get an exception
16:26ordnungswidrigI'm looking for a way to serialize / dump a clojure value which consists of maps, list etc. but also refs, e.g. {:foo-by-id {1 (ref {:name "foo-1"}) 2 (ref {:name "foo-2"})}
16:27ordnungswidrigprint-dup does not support refs :-(
16:27raekkzar: let (and also catch) simply requires the symbol to not have a namespace part (and refuses compilation if the rule is not followed)
16:28raeksyntax-quote (`) simply adds namespace parts to all symbols (except for those representing special forms)
16:29kzarraek: Ah right I get you now
16:29kzarraek: Thanks :)
16:29raekbut it won't add a namespace part if the symbol ends in #, instead it makes up a new unique symbol to avoid name collisions
16:37amalloyclojurebot: HOFs |are| higher order functions
16:37clojurebotAlles klar
16:37amalloyTimMc: ^
16:39fliebeldnolen: Sorry for leaving so abruptly earlier today. I've only just reached home :P Some crane drove through the catenary of the train I was supposed to take.
16:39dnolenfliebel: np.
16:41fliebeldnolen: That paper, it does not describe the actual pattern matching, does it? Just the underlying tree stuff.
16:42dnolenfliebel: ? what do you mean.
16:43mattmitchellwow i'm confused. i'm using the contrib.sql lib, and when i run a select w/a group_concat, the resulting field is a byte array. how the heck do i grab the actual values out of it? :|
16:44fliebeldnolen: well, they just write _::[] to mean whatever that means. So besides implementing that paper for the efficient dispatch, you also need the actual pattern matcher, right?
16:50mattmitchellok clojure.core/slurp does the trick!
16:55dnolenfliebel: sorry, stepped away for a second, the decision tree is the pattern matcher.
16:59dnolenfliebel: the predicate dispatch paper is all about building a decision tree with user definable predicates, the OCaml paper is about making a really, really efficient decision tree with the hard coded "predicates" that OCaml provides like _::[]. OCaml actually has guards which are like user definable predicates, but these are susceptible to ordering problems as I said before.
17:04fliebeldnolen: I too stepped away :) Umph, I understood little of the paper I guess.
17:04dnolenfliebel: I'm reading it for a 4th time now, it's starting to make sense.
17:05fliebelhehe :) okay, point made.
17:06dnolenfliebel: basically the gist of both papers is the same, the predicate dispatch comes from the perspective of OO and generic methods, the OCaml paper comes from the perspective of ML style pattern matching. But the methodology is very much the same, and the second paper really digs into how to make it very fast.
17:06fliebeldoes the other one also use that math syntax?
17:08dnolenfliebel: predicate dispatch perspective - we want pattern matching, but we want to be able add new patterns whenever we want. But they don't address the fact that new patterns might introduce ordering issues. So I want to the open-ness of predicate dispatch, the efficiency of ML pattern matching, and remove the ordering issue.
17:08dnolenfliebel: no.
17:08fliebelThey seem to be theorizing about tree depth and sharing. Would it make sense to write a pattern JIT? I mean, let the naive one run a few iterations, and optimize 'hot paths'.
17:09fliebelIn real life, some branches are more equal than others.
17:10dnolenfliebel: let the JVM do that for you.
17:11dnolenit's just byte code.
17:13dnolenfliebel: the other advantage with that paper is prior papers on ML pattern matching implementations are complex, while this paper presents a solution that's simpler to implement w/o losing on perf.
17:14fliebeldnolen: What I mean is that while these nice heuristics might figure out a tree that hash not to much decisions for all leaf nodes, there might be nodes that get accessed more frequently than others. So I was thinking you could shape the tree by usage, so that the common cases require few deciisions.
17:15fliebeldnolen: Yea, the mentioned that it is simple and still works for anything but pairs.
17:19mattmitchellwhat's the best way to convert a string "1" into an integer 1 ?
17:19dnolenfliebel: I know. a runtime optimization - so something I'd rather leave to JVM.
17:20amalloy&(read-string "1")
17:20sexpbot⟹ 1
17:22mattmitchellamalloy: perfect thanks
17:30raekmattmitchell: if you only want to allow integers: ##(Integer/parseInt "1")
17:30sexpbot⟹ 1
17:42mreynoldsI'm blanking on how to force a string to not be treated as a sequence. What's the function to dot hat?
17:43mecIs there anything better than (Object.) for a bunch of unique things to use in a map
17:43mecas keys* in a map
17:43mecmreynolds: what are you wanting to do with the string?
17:43mreynoldsmec: Trying to create a sequence of strings, not chars
17:43raekmec: keywords with namespace parts could be an option
17:44mreynoldsmec: Trying to build tests for a simple line parser
17:45mecmreynolds: so you want to split a string into smaller strings?
17:45raekmreynolds: could you show us the code where the problem occurs?
17:46mreynoldsmec: Actually, I have test strings that I want to feed into a function that then splits them. I have the splitting part, but I want to build a test and that requires building up some test strings.
17:46raekmreynolds: there's nothing with strings that keep them from being part of sequences
17:46mreynoldsraek: k, lemme see what I can do
17:49mecraek: I can't know how many ahead of time so I dont think I want to make keywords on the fly
17:51raekmec: then (Object.) sounds like a good fit to me
17:51clojurebotExcuse me?
17:51raekO_ô
17:52amalloymec: (Object.) and (gensym) are the classics
17:52mecah forget about (gensym), I think it would have more overhead tho
17:53dnolengensym is actually quite slow.
17:53mreynoldsraek: I think I'm running into a problem with printing at the console, not with sequences. One sec.
17:55amalloy(Object.) is surely "cheaper"
17:55mecI was just using numbers, but I figured eventually I would run out so I'd rather future proof :x
17:56amalloybut i bet if you want to debug it's easier to read ##(gensym) than ##(Object.)
17:56sexpbot (gensym) ⟹ G__37171
17:56sexpbot (Object.) ⟹ #<Object java.lang.Object@1bc2314>
17:57mechmm, maybe a helper function that switches to (gensym) for debugging
17:58mreynoldsraek: http://pastebin.com/tRb8z2Es
18:03Ramblurris it possible to supress warnings when (use ..) ing?
18:03raekmreynolds: some comments: replace (String. "foo") with "foo" and == with =
18:04mreynoldsraek: Yeah, I did for the affected test (realized the String. was irrelevant), and I had it as "=" before, but I thought == does contents equality?
18:04raekRamblurr: are the warnings caused by your code? if so, you should fix the cause instead... :-)
18:05Ramblurrraek: yea they are, i know usually you would want to fix the cause, but in this case my goal is to make the code as small as possible
18:05raekmreynolds: == is a rare special operations for numbers. = does what you want
18:05Ramblurrraek: so replacing a function is better than using a namespace
18:05raekRamblurr: what var is being replaced?
18:05mreynoldsraek: k, thanks. Also, found my other bug which is pipe being a special char and I didn't comment it. Commenting it returns the right thing. However, if it fails to split, the function treats the original string as a sequence.
18:06Ramblurrraek: im replacing clojure.core/repeat with clojure.contrib.string/repeat
18:06raek,(clojure.string/split "\"a\"|\"b\"|12345|12345678901234567890|\"long string\"|\"\"\n" #"\|")
18:06clojurebot["\"a\"" "\"b\"" "12345" "12345678901234567890" "\"long string\"" "\"\"\n"]
18:06raekmreynolds: I get the string split into its parts
18:06mreynolds,(clojure.string/split "\"a\"|\"b\"|12345|12345678901234567890|\"long string\"|\"\"\n" #"|")
18:06clojurebot["" "\"" "a" "\"" "|" "\"" "b" "\"" "|" "1" ...]
18:07raekRamblurr: and you want to use string's repeat instead?
18:07mreynoldsmreynolds: That's the bug in my code with pipe.
18:07Ramblurrraek: yup
18:07mreynoldsraek: Trying to remember the interaction of pipe as a regex, and if the original string is being returned as a sequence, or...
18:07raekif so, you should have (ns your-ns (:refer-clojure :exclude [repeat]) ...)
18:07raekto make that clear
18:08Ramblurrraek: doing (use '[clojure.contrib.string :only (repeat)]) and then (repeat..) rather than (require ... :as s/repeat) is less code, but i get a warning :\
18:09Ramblurrraek: ah nevermind, the error goes to stderr anyways
18:09Ramblurrnot stdout, so all is good
18:09Ramblurrraek: thanks for that namepsace exclude tip
18:09raekfor the user namespace in the repl, everything in clojure.core is already referred.
18:10raekso it's hard to opt out certains vars in it...
18:11raekRamblurr: :exclude is the correct way to do it. the reason clojure show a warning instead of an error is to not break peoples' projects when new stuff enters clojure.core.
18:12raekmreynolds: | in a regex means alternative, so you have to quote it like \|, as you did in your paste
18:13mreynoldsraek: Gotcha, just trying to figure out why the original string gets treated as a sequence in taht case.
18:13raekmreynolds: but note that the order of the keys of a map is not maintained, so your equality check will probably fail
18:13raek,(clojure.string/split "\"a\"|\"b\"|12345|12345678901234567890|\"long string\"|\"\"\n" #"")
18:13clojurebot["" "\"" "a" "\"" "|" "\"" "b" "\"" "|" "1" ...]
18:14raekmreynolds: it doesn't. you split at "nothing"
18:14mreynoldsraek: Yeah, sorry, building up the test a piece at a time, wanted to jump over the sequence hurdle first
18:14mreynoldsraek: Gotcha. This is my faulty memory of regex handling in java coming back to bite me
18:14raekthe string matches nothing, followed by ", followed by nothing, followed by a, etc
18:14mreynoldsraek: thanks
18:15raekone rule about regex *literals* in clojure is that their syntax is *exactly* as described in http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
18:17mreynoldsraek: Gotcha. I screwed this up when I did java too, so I don't blame clojure for that :)
18:18mecwhen should i use clojure.test/testing vs clojure.test/deftest
18:25dakronemec: use deftest to declare a test, testing to declare sections of a test within a deftest
19:48mreynolds'(contains? (list "a" "b" "c") "a")
19:49mreynolds,(contains? (list "a" "b" "c") "a")
19:49clojurebotfalse
19:49mreynoldsClojuredocs.org has a note on contains? saying they're not sure why that evaluates to false, does anyone here know?
19:50raek,(contains? (list "a" "b" "c") 0)
19:50clojurebotfalse
19:50technomancyclojurebot: contains?
19:50clojurebotcontains? is for checking whether a collection has a value for a given key. If you want to find out whether a value exists in a Collection (in linear time!), use clojure.core/some or the java method .contains
19:50mreynoldsbah
19:50mreynoldsI'll edit the page :)
19:50technomancycontains? is specifically designed to trick newbies into thinking about O(n) characteristics of data structures.
19:50mreynoldsit worked!
19:51technomancythere is no other explanation for why it hasn't been renamed
19:51technomancymreynolds: brilliant. =)
19:54dnolen,(associative? '(a b c))
19:54clojurebotfalse
19:54dnolen,(associative '[a b c])
19:54clojurebotjava.lang.Exception: Unable to resolve symbol: associative in this context
19:55dnolen,(associative? '[a b c])
19:55clojurebottrue
19:55mec,(contains? '(a b c) 1
19:55clojurebotEOF while reading
19:55mec,(contains? '(a b c) 1)
19:55clojurebotfalse
19:55dnolen,(get '(a b c) 0)
19:55clojurebotnil
19:55dnolen,(get '[a b c] 0)
19:55clojurebota
19:56mec(nth '(a b c) 0)
19:56mec,(nth '(a b c) 0)
19:56clojurebota
19:56dnolen,(find '(a b c) 0)
19:56clojurebotjava.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.util.Map
19:56amalloyi like that explanation, technomancy
19:56dnolen,(find '[a b c] 0)
19:56clojurebot[0 a]
19:57amalloy&(doc find)
19:57sexpbot⟹ "([map key]); Returns the map entry for key, or nil if key not present."
19:58amalloyneat. i didn't know about that one
20:01mecuseful if your map's values might be nil
20:01mecwell i guess thats what not-found is for anyway
20:10pdkthat sorta thing
20:10pdkis why i miss multiple-value-bind sometimes
20:18mecis that a language feature or built onto CL?
20:19amalloyi think it must be a language feature. pasting it on with other CL primitives would be gross
20:20mecyou could do it it with with-bindings and 2 macros
20:24amalloyi don't think you could do it in a way that is both transparent to non-mvbind contexts and performant. i implemented mvbind in clojure a couple different ways for fun, and they're not very good; i'd be interested to see the way you do it
20:24mecsure, working on it now
20:27mecwhat are the 2, mutiple-value-bind and values?
20:38mecwhats the difference between binding and with-bindings and how do you use either
20:42mechttps://gist.github.com/949291
20:42mec^^ multiple-value-bind
20:53amalloymec: with-bindings is lower-level. wants vars instead of symbols
20:54mecwell its about 12 times slower than directly using let
20:54amalloymec: i'm not convinced by your solution. it doesn't work to have (values (some-other-mv-function) true), because some-other-mv-function will see the global value of *multi-value*
20:55amalloyie, you only support one multi-valued function globally at a time - they don't nest
20:55mecah hmm
20:55amalloyvery neat prototype though. not a way i'd considered doing it
20:57mecno idea how to fix that
20:58mecother than to wrap ~vals in (binding [*multi-value* false] ~vals)
21:08chrissbxWhat's the best way to fold over a sequence two elements per step? Like for example the vector with the variables+expressions in a let form.
21:09mecany idea why this would throw a null pointer? (when (sequential? x) (= (seq x) (seq this)))
21:09mecchrissbx: (partition 2 coll)
21:10mecso (reduce (fn [[k v]] ...) (partition 2 coll))
21:14chrissbxThanks. Any way to get error checking for (partition 2 '(k1 v1 k2)) ?
21:14chrissbx(Without me doing length calculations around it?)
21:14mec(let [kvs (partition 2 coll)] (if (odd? (count kvs)) (throw ...)))
21:15mecoh
21:16chrissbxwell, whatever. I guess I'm just supposed to do it that way.
21:16mec(reduce (fn [[k v :as t]] (if (= (count t) 1) (throw Exception.) ...) (partition 2 coll))
21:16mecs/partition/partition-all/
21:16sexpbot<mec> (reduce (fn [[k v :as t]] (if (= (count t) 1) (throw Exception.) ...) (partition-all 2 coll))
21:17chrissbxI always prefer solutions that I can use without caring about errors and that then don't just suppress them.
21:17chrissbxBut since clojure even doesn't think (first '()) is an error, then I guess my code will never be fool proof anyway.
21:18chrissbxI suppose I better get over it.
21:19mecits pretty handy that a lot of stuff returns nil instead of exceptions
21:20chrissbxWell, at the cost of missing (early) error checking.
21:21chrissbx(But partition doesn't even return nil, it just returns part of the solution.)
21:22mecya partition truncates, gotta use partition-all if you want partials
21:23amalloymec: actually i think that's a sufficient fix. wrapping values, that is
21:23amalloyclojurebot: partition?
21:23clojurebotpartition is probably not what you want; see partition-all.
21:23meclol
21:24amalloychrissbx: forget about (first ()), clojure is perfectly happy with ##(first (first (rest (first nil))))
21:24sexpbot⟹ nil
21:24chrissbxWell, using partition-all will just sweep the error under the carpet in the subsequent reduce.
21:24amalloy&(doc partition)
21:24sexpbot⟹ "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complet... http://gist.github.com/949317
21:25mecok i changed equiv on this deftype to (equiv [this x]) and it still throws a null pointer when called
21:25amalloychrissbx: pass a "pad" collection that's something like (repeatedly #(throw (Exception. "OMG WUT")))
21:25amalloy&(partition 2 2 (repeatedly #(throw (Exception. "OMG WUT"))) (range 4))
21:25sexpbot⟹ ((0 1) (2 3))
21:25amalloy&(partition 2 2 (repeatedly #(throw (Exception. "OMG WUT"))) (range 5))
21:25sexpbotjava.lang.Exception: OMG WUT
21:26mecwow thats interesting
21:26amalloythat still delays the exception until the first wrong-sized partition, but you can't do any better than that and still be lazy
21:27mecwhy does partition do that instead of just passing the function
21:27amalloymec: ?
21:27mecah nvm
21:33amalloychrissbx: anyway you can (defn die [] (repeatedly #(throw...))), and then use (die) as your pad collection
21:33amalloyto let you fail as fast as is possible
21:33chrissbxwell, (def die (repeatedly ...))
21:34chrissbxBut since I'm used not to bother about edge cases when writing my code, I'll forget about this.
21:34amalloychrissbx: i considered that, i don't think it's a good idea
21:34chrissbxAnd my code will just do unsensible stuff as a consequence.
21:34chrissbxAnd I don't care right now :)
21:35amalloyif you use the same lazy-sequence of exceptions and someone ever catches one of them, that first result gets cached and probably would result in silent failures
21:35chrissbxWhat would be cached isntead of the exception?
21:36chrissbxah the result of the exn handler, you mean?
21:36amalloyi'm not sure, really. it's a weird case
21:36chrissbxheh
21:36mecmine keeps blowing up
21:36chrissbxmec: amalloy means when you use an exception handler that replaces the exn with a value
21:37amalloyyeah, but i was wrong
21:37amalloythere's no way it could get cached
21:37chrissbxIf that's possible in Clojure to have such a handler at all.
21:39amalloyno, it's not
21:39amalloythe stack unwinds up to the first handler it can find, and grows anew from there
21:41chrissbxHow do debuggers work, though, if an exception happens? They'll have to capture it with the stack before unwinding.
21:41amalloythey attach to the process externally
21:41chrissbx(Or have access to the unwound stack after-the fact.)
21:42chrissbx(To the un-unwound, I meant)
21:42amalloyand then the jvm gives them priority execution while the target program is suspended
21:42chrissbxk
21:43chrissbxMaybe that'll be a feature in a future Clojure version (for restarts ...).
21:44chrissbxThen my code will break then :)
21:45chrissbxMy future is already doomed while learning Clojure.
21:45amalloyeh?
21:49chrissbxJust exaggerating.
22:26semperosinformational question: what do folks think would be interesting metrics to "calculate" from scanning all of Clojure's IRC logs for the last three years?
22:34mecsemperos: number of unique visitors could be interesting
22:35semperosmec: thanks
22:35semperosany thoughts on "equivalent" nicks? by default i was thinking "foo" and "foo_" with any number of underscores
22:36mecalso ` and preceding _
22:37semperos` at the end?
22:37semperosI've been brainstorming a few things, esp. around clojurebot/sexpbot use, specific Clojure fn's, folks who talk the most, folks "on" most number of days
22:37semperosthings in that vein
22:48chrissbxsemperos: you might catch most nick duplicates by checking for renames
22:48semperostrue
22:49semperosactually using the logs saved at n01se.net for this, where those aren't captured
22:49chrissbxah
22:49semperosbut a fine thought
22:51semperoshere's what I have so far after a quick brainstorm:
22:51semperos* Total unique visitors
22:51semperos* Total messages
22:51semperos* Total mentions of particular languages (Java, Ruby, Lisp)
22:51semperos* Clojurebot vs Sexpbot use
22:51semperos* For a user, total messages
22:51semperos* For a user, total days "online" (at least one message)
22:51semperos* Top users
22:51semperos* Top days (number of messages)
22:51semperos* Top Clojure fn's mentioned/used
22:51semperoswas hoping that wouldn't make separate messages...
22:52semperosobviously there'll be ambiguity, but this is a start
22:53semperos* For a user, number of messages including Java interop forms
22:59chrissbxAnother fine thought might be to ask for the source files used by n01se.net, esp. since there seems to be a parser for those at https://github.com/Chouser/clojure-irc-log