2011-04-29
| 00:00 | dnolen | choffstein: what I mean is what advantage over an atom? |
| 00:00 | choffstein | ...uh, no idea. As I said, I am very new to clojure :) |
| 00:01 | amalloy | i wonder if the popularity of refs, when atoms would do, is related to refs being an older language feature |
| 00:01 | amalloy | (they are, right? i'm not imagining it?) |
| 00:01 | dnolen | choffstein: dosync is about coordinating changes between data, if you just need to serialize access to something, atoms are fine and much faster. |
| 00:01 | choffstein | amalloy: I use ref because I come from a SML background -- and ML has refs. Maybe that's it? |
| 00:02 | choffstein | dnolen: ah, I see. atoms may be okay then :) |
| 00:02 | cemerick | amalloy: "I'm using _STM_, baby!" is enough of a thrill for a lot of people to motivate the usage. ;-) |
| 00:02 | amalloy | nice |
| 00:03 | carllerche | I'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:04 | amalloy | i can't think of a good reason to have a ref of a map of refs |
| 00:06 | choffstein | dnolen: when you say coordinating changes between data, what exactly do you mean? In a concurrent sense -- like a database? |
| 00:06 | dnolen | choffstein: yes. |
| 00:06 | dnolen | choffstein: dosync is like a db transaction |
| 00:07 | choffstein | dnolen: well, then it might make sense for my 'sessions' to be refs then, right, since those would be used across website users? |
| 00:07 | choffstein | whereas 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:07 | choffstein | ? |
| 00:09 | dnolen | choffstein: 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:10 | choffstein | Annnnddd that makes a whole lot more sense now. |
| 00:10 | carllerche | amalloy: 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:10 | choffstein | so if I had a list of refs and I wanted to alter them all, I would wrap it with a dosync? |
| 00:11 | carllerche | (i haven't actually gotten around to using refs yet, so I don't know) |
| 00:11 | dnolen | choffstein: 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:11 | choffstein | hmmm. I think i'll leave transactions alone for a little while :D |
| 00:11 | choffstein | I think i'm pretty happy with my horrible hacking for this evening. |
| 00:12 | amalloy | your 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:12 | dnolen | carllerche: 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:12 | carllerche | amalloy: I'm actually building an HTTP reverse proxy that could have arbitrary end points |
| 00:13 | carllerche | so, 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:13 | amalloy | okay... |
| 00:14 | amalloy | i'm hearing you say "yes, i have a fixed-size map" |
| 00:14 | choffstein | alright. time for bed before my brain melts. later all. |
| 00:15 | carllerche | amalloy: well, the keys can't be predetermined... it would be based on usage |
| 00:15 | carllerche | aka, i can't preallocate the connections |
| 00:17 | carllerche | i guess i could try the various options and see what works best |
| 00:18 | carllerche | although, i wonder if i could just implement it as commutative operations |
| 00:19 | carllerche | amalloy: so, what you are saying is that a ref to a map of refs is just crazy talk? |
| 00:19 | amalloy | yes. i have violent reactions to overuse of mutable state, so take that with a grain of salt though |
| 00:20 | amalloy | rata convinced me an atom of a map of agents made sense, though, at some point |
| 00:21 | Apage43 | do agents have any ordering guarantees? |
| 00:22 | cemerick | carllerche: 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:22 | amalloy | Apage43: all requests from thread X will be processed in the order X sent them |
| 00:22 | Apage43 | k |
| 00:22 | Apage43 | i figured that'd be the case, just didn't remember |
| 00:23 | Apage43 | cemerick: the commutative part (if using commute) won't be though |
| 00:24 | carllerche | cemerick: right... this is just for some structure that can store / retrieve objects |
| 00:24 | carllerche | no IO operations |
| 00:37 | carllerche | i'm confused about commute, is it possible for the retval of commute to be different from the value the ref gets set to? |
| 01:16 | Apage43 | carllerche is gone |
| 01:16 | Apage43 | but yes |
| 01:17 | Apage43 | or rather |
| 01:18 | Apage43 | well, it barely matters. |
| 01:20 | tomoj | I'm interested |
| 02:58 | stirfoo | does this profile macro look correct? http://paste.lisp.org/display/121658 |
| 02:59 | stirfoo | the thing that bugs me is a given entry function shows less time than functions called by that entry function |
| 03:01 | clgv | stirfoo: 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:01 | stirfoo | clgv: yes, that's something I haven't gotten a grip on yet, lazyness |
| 03:02 | clgv | your if-let has a different meaning than you might think |
| 03:02 | stirfoo | oh? do tell |
| 03:04 | clgv | that might work as well: ##(if-let [[a b] [nil nil]] [a b] 'else) |
| 03:04 | clgv | but it seems that doesnt matter in the remaining code |
| 03:04 | sexpbot | ⟹ [nil nil] |
| 03:05 | clgv | summarizing: the code looks ok |
| 03:08 | stirfoo | ok, 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:08 | clgv | stirfoo: yes it is |
| 03:09 | stirfoo | awesome |
| 03:09 | clgv | even on amazon now ;) |
| 03:10 | ambrosebs | mine just came in the mail |
| 03:10 | ambrosebs | love the guy on the cover |
| 03:11 | stirfoo | I read one or two of the freebee chapters a while back. Seemed like a well written book. |
| 03:11 | ambrosebs | I ordered "Learn you a haskell for great good", which has a blue elephant on the front... two fun covers with fun titles :) |
| 03:12 | stirfoo | Did Duane draw the elephant? (scheme joke) |
| 03:14 | ambrosebs | *whoosh* :P |
| 03:16 | ambrosebs | on the way to work this morning I was thinking if "The Joy of Java" would pop up in some form xD |
| 03:17 | ambrosebs | the only cover I've seen that advocates java as "fun" is the Pragmatic Programmers' Stripes book |
| 03:17 | ambrosebs | subtitled: "...and Java web development is fun again!" |
| 03:17 | ambrosebs | I laughed |
| 03:17 | ambrosebs | still, good book, good framework. |
| 03:30 | amalloy | tomoj: (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:30 | amalloy | it doesn't have to retry the transaction or tell you about the new value at all, because you told it commuting was okay |
| 03:31 | amalloy | so it is possible for (commute) to return a value that the ref never actually has, outside of your snapshot fantasy-land |
| 04:02 | clgv | Is 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:03 | clgv | *one |
| 04:21 | pyr | hi |
| 04:23 | pyr | I'm facing a weird use case with leiningen. How do I integrate jars which are not in any maven repo ? |
| 04:28 | pyr | I could put them in lib/ but every lein clean flushes them out |
| 04:29 | clgv | pyr: just add ":disable-implicit-clean true" to your project.clj |
| 04:30 | pyr | 'k thanks |
| 07:11 | ordnungswidrig1 | *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:43 | thorwil | ordnungswidrig: isn't read meant to used for such dumps? |
| 07:44 | ordnungswidrig | thorwil: the reader doesn't support record literals yet |
| 07:44 | ordnungswidrig | thorwil: the need of importing the record class makes is worse |
| 08:09 | clgv | ordnungswidrig: you could dump them as normal maps and read those maps and assoc them... |
| 08:09 | ordnungswidrig | clgv: no so easy because you need some reflection to initialize an empty record. |
| 08:09 | ordnungswidrig | clgv: but certainly possible |
| 08:11 | clgv | ordnungswidrig: oh ok. I assumed you will know the record type at the time you want to read it |
| 08:13 | ordnungswidrig | clgv: 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:14 | ordnungswidrig | clgv: on read time i can transform back |
| 08:14 | clgv | ordnungswidrig: I know ;) but it's less code without the reflection part and thus easier ;) |
| 08:16 | clgv | ordnungswidrig: humm why not write (Foo. 1 2 3) to file? maybe with namespace associated? |
| 08:30 | fliebel | dnolen: 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:30 | dnolen | the pattern matching paper? |
| 08:30 | dnolen | fliebel: ^ |
| 08:32 | fliebel | yea |
| 08:32 | fliebel | uhm, no, well... the one with ml |
| 08:34 | dnolen | fliebel: 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:35 | dnolen | which makes the implementation a lot simpler/cleaner than previous papers on papers on pattern matching. |
| 08:35 | david` | what's the difference between (case x) and (condp = x)? |
| 08:36 | dnolen | david`: case does not test possibilities. |
| 08:36 | fliebel | dnolen: Ah, I see. And you want to use Logos to generate the maximum sharing shallow stuff? |
| 08:37 | david` | I see, so the "= x" can be changed to really any test condition |
| 08:38 | david` | like condp some [1 2 3 4] |
| 08:38 | dnolen | fliebel: 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:39 | dnolen | fliebel: keeping things open is unrelated to the logic engine, however automatically reordering clauses is something the logic engine can do. |
| 08:40 | dnolen | fliebel: consider (defm foo [x] :guard (even? x)) |
| 08:40 | dnolen | fliebel: then consider that someone else wants to add (defm foo [0]) after the fact. |
| 08:40 | dnolen | fliebel: because the first one was defined first, the second one will never be reached. |
| 08:41 | dnolen | fliebel: we can fix that with a logic engine. |
| 08:41 | fliebel | oh, 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:43 | dnolen | fliebel: it will store properties of the tree, but it's there to solve implication issues like the one above. |
| 08:43 | fliebel | oh, okay. Interestng. I need to go now though, my train isn't going where it should. |
| 08:48 | dnolen | david`: yes. |
| 08:55 | david` | kewl |
| 10:12 | devn | dnolen: intensely awesome work |
| 10:12 | clgv | (apply third-party-macro param1 param2 options) does not work. can I work around that somehow? |
| 10:13 | dnolen | devn: heh, at this point we're still in the realm of ideas ;) |
| 10:14 | devn | dnolen: even still, the germ of the idea is exciting |
| 10:14 | devn | dnolen: is there video anywhere of this LispNYC talk you gave? |
| 10:15 | apgwoz | devn: you have to move to nyc to see it |
| 10:15 | apgwoz | sorry, them's the rules |
| 10:15 | devn | apgwoz: how big is your apartment? |
| 10:15 | apgwoz | big enough for my wife, a baby (soon) and myself. not for you |
| 10:15 | apgwoz | :) |
| 10:15 | devn | alls i've got is this here stick and bindle |
| 10:16 | apgwoz | edw: chicken scheme can speak to slime now |
| 10:18 | devn | apgwoz: you bring up an important point. i'd like a move sometime soon. |
| 10:18 | apgwoz | madison isn't happening enough for you? |
| 10:18 | Ramblurr | do most people use the stable clojure release or use the live git version? |
| 10:18 | apgwoz | devn: meetup is hiring, though there's only a tiny tiny tiny bit of clojure code at the moment. |
| 10:18 | devn | I 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:19 | apgwoz | yeah, i visited madison last september, nice place. |
| 10:20 | devn | there's going to be a madison ruby conference this year -- excuse for you to make a visit |
| 10:21 | devn | apgwoz: either way, maybe ill come out to NYC for a weekend and see some friends, drop by the LispNYC meetup |
| 10:21 | devn | Ramblurr: depends on what you want to do |
| 10:22 | devn | Ramblurr: id say most are on stable, though |
| 10:24 | apgwoz | devn: but i don't really like ruby, so that's a reason to avoid madison :) |
| 10:26 | Ramblurr | devn: ah, hm. I asked because my 1.2.0 jar seems to be missing functions: join, blank? |
| 10:27 | devn | Ramblurr: what's your setup? |
| 10:27 | Ramblurr | devn: oh, i have to "use" the string module heh |
| 10:28 | clgv | how can I avoid this: (eval `(xy-plot ~x ~first-col ~@options)) ??? |
| 10:28 | clgv | xy-plot is a macro unfortunately sothat I can't use apply |
| 10:28 | Ramblurr | devn: 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:29 | devn | Ramblurr: yes. |
| 10:29 | devn | Ramblurr: are you just getting used to the idea of clojure's namespaces and such? |
| 10:29 | devn | Ramblurr: http://blog.8thlight.com/articles/2010/12/6/clojure-libs-and-namespaces-require-use-import-and-ns |
| 10:29 | pjstadig | clgv: write your own wrapper macro? |
| 10:29 | Ramblurr | devn: yea, this is my first encounter with them |
| 10:30 | Ramblurr | devn: thanks for the reading |
| 10:30 | devn | Ramblurr: not a problem. have fun |
| 10:30 | clgv | pjstadig: errmmm... how? |
| 10:30 | clgv | just extract the code over there? |
| 10:31 | pjstadig | yeah something like (defmacro xy-plot2 [x first-col & options] `(xy-plot ~x ~first-col ~@options)) |
| 10:32 | pjstadig | eval + syntax-quote is essentially macro evaluation anyway |
| 10:35 | clgv | 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:35 | pjstadig | where is xy-plot from and why is it a macro? |
| 10:37 | clgv | it's from Incanter |
| 10:37 | clgv | I dont know why it is a macro |
| 10:37 | clgv | it just seems to do some default value handling for options |
| 10:38 | sritchie | here's the source -- https://github.com/liebke/incanter/blob/8736bc3cae44491172031b381c6e165c0bd1139c/modules/incanter-charts/src/incanter/charts.clj#L984 |
| 10:38 | clgv | sritchie: already looking at it ;) |
| 10:39 | sritchie | clgv: just trying to live up to clojurebot's helpfulness :) |
| 10:40 | Ramblurr | o_0 I'm getting different results from a function when i call it with dotrace or by itself |
| 10:43 | chouser | Ramblurr: is dotrace printing return values of functions or their arguments? or just listing the names of functions being called? |
| 10:44 | Ramblurr | chouser: both |
| 10:44 | Ramblurr | chouser: preparing a snippet, one sec |
| 10:44 | pjstadig | clgv: you could do something icky like (apply xy-plot* x first-col @#'incanter.charts/create-xy-plot options) |
| 10:45 | chouser | Ramblurr: if it prints return values or args, it may be forcing lazy sequences that wouldn't otherwise be realized. |
| 10:46 | Ramblurr | chouser: oh, i see |
| 10:46 | clgv | pjstadig: hmmm I guess I'll write the whole thing as macro |
| 10:48 | Ramblurr | chouser: http://pastebin.com/aALcDt1y |
| 10:51 | Ramblurr | chouser: and here is the output different http://pastebin.com/QXvHVige Would you say this is a case of lazy seqs being evaled? |
| 10:59 | pyr | hi, 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:15 | mec | (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:20 | semperos | is there any reason to use clojure.string/escape over clojure.string/replace? |
| 11:20 | kzar | I'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:20 | kzar | .html template too. I get the feeling I've totally misunderstood something here? |
| 11:20 | semperos | in microbenchmark, clojure.string/replace performed better |
| 11:21 | semperos | other than the need to replace more than one thing in a single swipe |
| 11:26 | manutter | kzar: do you have a gist? |
| 11:26 | kzar | manutter: http://paste.lisp.org/display/121664 |
| 11:27 | kzar | manutter: The css-include part is what's confusing me although it's likely all backwards |
| 11:42 | edw | In theory, shouldn't re-factoring conserve the does-it-work? property? |
| 11:54 | kzar | manutter: I've cracked a couple of problems, just got to figure out how to get it populating the href properly now |
| 12:07 | kzar | ah I've cracked it :) |
| 12:14 | manutter | Man, bosses can be so demanding at times :\ |
| 12:14 | manutter | Good, I'm glad you got it, I got called away |
| 12:15 | kzar | no worries! I know what that's like heh |
| 12:22 | TimMc | edw: Yeah, and as long as it doesn't affect your API, your automated tests should all still pass. |
| 12:55 | TimMc | (You *are* writing tests, yes? :-P) |
| 12:55 | semperos | anyone know proper spec for clojure.contrib.sql for a DATETIME column? tried :datetime |
| 12:56 | semperos | sorry, for the clojure.contrib.sql/create-table fn |
| 13:11 | ataggart | stuarthalloway: free to discuss the bit-ops stuff? |
| 13:12 | stuarthalloway | yep |
| 13:13 | ataggart | read 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:14 | stuarthalloway | I think you will find that there are code paths where things come in as objects |
| 13:14 | stuarthalloway | you can try long only and see what happens :-) |
| 13:14 | ataggart | I have: https://github.com/ataggart/clojure/commits/bit-ops |
| 13:14 | ataggart | the compiler knows how to push numbers to long primitives |
| 13:16 | ataggart | if that commit looks good, I'll make a patch and attach it to 767 |
| 13:17 | stuarthalloway | the core.clj changes in that commit seem related to something else ? |
| 13:17 | stuarthalloway | reviewing the numbers.java changes now |
| 13:18 | ataggart | the change in core.clj is because where the exception on passing a double to even? went away |
| 13:20 | stuarthalloway | seems like exception is the right behavior |
| 13:20 | ataggart | it used to be thrown via bitAnn on line 1201 in Numbers |
| 13:20 | stuarthalloway | what does it mean for a double to be even? |
| 13:21 | ataggart | yep, it's always thrown an exception on non-integer nums |
| 13:21 | ataggart | just changed the location |
| 13:21 | stuarthalloway | let's leave that out of the patch |
| 13:22 | stuarthalloway | do you know if the shiftLeftInt variants are ever used anywhere? |
| 13:22 | ataggart | they are not |
| 13:23 | ataggart | I'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:24 | stuarthalloway | what happens without the change in core? |
| 13:24 | ataggart | tests failed, don't recall what |
| 13:24 | ataggart | lemme see |
| 13:25 | stuarthalloway | thanks, trying it here as well |
| 13:25 | stuarthalloway | did you see that #426 (case) finally got in? |
| 13:26 | ataggart | I'm not a religious man, but.... |
| 13:26 | ataggart | what was the voodoo you used to find those bad numbers? |
| 13:27 | stuarthalloway | ataggart: I thought Alan told you |
| 13:28 | stuarthalloway | https://github.com/clojure/test.generative |
| 13:28 | ataggart | he mentioned you had some framework, ah yeah nice |
| 13:28 | stuarthalloway | the tests are still in there (under examples) |
| 13:28 | aredington | Alan was probably avoiding stealing Stu's thunder on dropping that bombshell |
| 13:32 | ataggart | sigh, the compiler is automatically casting from non-integers to long |
| 13:32 | aredington | What kind of non-integers ? |
| 13:32 | ataggart | ratios, doubles |
| 13:33 | ataggart | anythign that's not a long or int |
| 13:34 | ataggart | when 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:35 | ataggart | I can manually deal with all the type checking, but... ugh |
| 13:36 | stuarthalloway | not sure I am totally following you without seeing it run -- going to build it now |
| 13:36 | stuarthalloway | sorry slow -- I am multitasking several numerics tasks here |
| 13:36 | ataggart | ya sry, I can see it since my head has been in the compiler for a few months now |
| 13:37 | ataggart | anyway, it's a problem with bit-ops really, since (bit-and 1.5 1) is coming back 1 |
| 13:37 | ataggart | because that 1.5 is getting truncated to a long |
| 13:38 | ataggart | by the compiler |
| 13:38 | ataggart | don't waste your time on it, lemme fix that |
| 13:38 | stuarthalloway | so would the Object/long and long/Object variants fix that? |
| 13:40 | ataggart | they 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:40 | ataggart | it's a deficiency in the compiler |
| 13:40 | ataggart | imo |
| 13:40 | stuarthalloway | fair enough, but let's get this done |
| 13:40 | ataggart | yup, half way there |
| 13:52 | dakrone | stuarthalloway: 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:52 | dakrone | for testing a lib that has float methods |
| 13:53 | stuarthalloway | dakrone: where is the float method? |
| 13:54 | stuarthalloway | called inside json/generate-string somewhere? |
| 13:54 | dakrone | inside the generater, in a condp looking something like "... Float (.writeNumber jg ^Float obj)" |
| 13:54 | dakrone | yes |
| 13:55 | stuarthalloway | and you need float fidelity, so double promotion would be a bug? |
| 13:56 | ataggart | *cough*445 fixes that*cough* |
| 13:56 | dakrone | yes, otherwise I get the error that it can't find a correct method |
| 13:57 | stuarthalloway | let 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:58 | dakrone | stuarthalloway: 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:59 | dakrone | I have no way to guarentee that .writeNumber(double) behaves the same as .writeNumber(float) |
| 13:59 | stuarthalloway | dakrone: 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 | @rhickey | dakrone: calling such an overloaded thing requires coercions |
| 14:00 | @rhickey | coercions are not hints |
| 14:01 | stuarthalloway | rhickey: how does that work when there is a Clojure fn call between the float the Java method to be called |
| 14:01 | dakrone | rhickey: If I'm doing condp with dispatch on type though, by that point the compiler's already made it a double |
| 14:01 | @rhickey | stuarthalloway: like what? |
| 14:02 | @rhickey | dakrone: condp doesn't do type dispatch on primitives |
| 14:02 | semperos | sorry to re-ask, had to leave an hour ago |
| 14:02 | @rhickey | if you want a boxed Float make one |
| 14:02 | semperos | does anyone know how to use clojure.contrib.sql/create-table with datetime columns? |
| 14:02 | @rhickey | (float x) does not make a Float |
| 14:03 | dakrone | no, 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:04 | stuarthalloway | dakrone: (Float. 3.14) |
| 14:04 | @rhickey | stuarthalloway: you can't route floats around, Clojure doesn't have primitive floats |
| 14:04 | ataggart | it *could*... |
| 14:04 | stuarthalloway | dakrone: 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:04 | stuarthalloway | ataggart: go finish that patch :-) |
| 14:05 | ataggart | aye sir |
| 14:05 | dakrone | okay, then I will not be able to handle doing json enconding of java methods that *could* return floats |
| 14:05 | stuarthalloway | dakrone: yes, you could, with (Float. ) |
| 14:05 | @rhickey | dakrone: I don't see why not |
| 14:05 | dakrone | (json/encode (.methodThatReturnsAPrimativeFloat foo)), at that point it would be a float, how can I dispatch on it? |
| 14:06 | @rhickey | ataggart: no, it won't |
| 14:06 | ataggart | stuarthalloway: https://github.com/ataggart/clojure/commit/496135716ab8687ba4373ca9799db57ed6638060 |
| 14:06 | hiredman | if 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:06 | dakrone | I 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:07 | pjstadig | right, 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:07 | ataggart | rhickey: 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 | @rhickey | dakrone: how would you write json/encode in java? |
| 14:09 | hiredman | dakrone: you happen to have it also written up in java, yes? |
| 14:09 | stuarthalloway | ataggart: given no plan to support big ints, can we not replace bitOpsCast with a simple cast to long? |
| 14:09 | @rhickey | call RT.box then |
| 14:10 | hiredman | rhickey: on which side of the fn call? |
| 14:10 | ataggart | stuarthalloway: 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:11 | hiredman | calling 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:11 | dakrone | rhickey: 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:11 | kzar | Does anyone else find that sometimes emacs stops displaying function arguments in the mini buffer after a while? |
| 14:11 | @rhickey | hiredman: was speaking to json/encode |
| 14:12 | hiredman | uh, I thought I was too? |
| 14:12 | @rhickey | I'm not particularly attached to floats as Doubles if itsa big problem for people. short/int/long as Long is a bigger deal |
| 14:13 | semperos | kzar: you using slime/swank? |
| 14:13 | hiredman | given the lack of floating point weirdness I can't imagine it would be a big deal |
| 14:13 | kzar | semperos: Yea, it works fine but just sometimes after a while it breaks |
| 14:13 | @rhickey | dakrone: I don't understand |
| 14:14 | kzar | semperos: It's probably my god-awful code causing it to seppuku heh |
| 14:14 | no_mind | I 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:14 | semperos | kzar: I've had similar happen; sometimes I forget to compile and load ns's |
| 14:14 | semperos | sometimes it just needs a classic reboot :) |
| 14:15 | raek | no_mind: are you talking about pr-str and read-string? |
| 14:16 | dakrone | rhickey: 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:16 | dakrone | does that kinda explain it? |
| 14:16 | no_mind | raek: dont know what they are ? I serialized the string with *print-dup* |
| 14:17 | stuarthalloway | rhickey: should (bit-and 1N 1) throw an exception, or coerce to primitive long and proceed? |
| 14:17 | raek | ,(let [m {:a "1", :b "2"}] [m (pr-str m) (read-string (pr-str m))]) |
| 14:17 | clojurebot | [{:a "1", :b "2"} "{:a \"1\", :b \"2\"}" {:a "1", :b "2"}] |
| 14:18 | amalloy | dakrone: fyi your huge-long message was too long for irc and got truncated at "have a co" |
| 14:19 | pjstadig | upcasting 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 | @rhickey | stuarthalloway: 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:19 | pjstadig | as we've seen upcasting from float to double produces slightly different values |
| 14:19 | raek | no_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:19 | pjstadig | floats are not exactly a subset of doubles |
| 14:20 | no_mind | ok |
| 14:20 | dakrone | rhickey: http://p.writequit.org/explain.html |
| 14:20 | dakrone | amalloy: thanks for the heads up |
| 14:20 | stuarthalloway | rhickey: what about even?, which (as implementation detail IMO) is implemented with bitops |
| 14:20 | @rhickey | dakrone: that's getting bigger and bigger - make the problem smaller - what would the signature of encode be in Java? |
| 14:22 | dakrone | rhickey: that's what I'm saying, there would be no need for encode in java |
| 14:22 | dakrone | It's entirely possible that I am Doing It Wrong (tm) |
| 14:22 | dakrone | will look and get back to you |
| 14:23 | @rhickey | stuarthalloway: what about it? |
| 14:24 | @rhickey | stuarthalloway: should even? work for bigints? - of course |
| 14:25 | stuarthalloway | rhickey: right on, so the implementation has to change, since bit-and will not work for big ints |
| 14:25 | @rhickey | stuarthalloway: sounds right |
| 14:28 | stuarthalloway | totally separate issue: running Clojure in IDEA for debugging |
| 14:28 | scgilardi | would the change be to use BigInteger's "and" method directly? avoiding a division or div/rem operation for even? would be nice. |
| 14:29 | stuarthalloway | I am stuck because the basic compilation doesn't put the version resource in the right place, causing an NPE reading the version string |
| 14:29 | aredington | (= (mod <num> 2) 0) should work transparently across all integer values |
| 14:29 | stuarthalloway | I 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:30 | hiredman | I have a lein'ized clojure build |
| 14:30 | fogus` | stuarthalloway: sed was my Huckleberry. It sucked |
| 14:31 | scgilardi | aredington: mod is division-y |
| 14:31 | hiredman | I rember futzing with the version file issue |
| 14:31 | stuarthalloway | fogus` : why is there a backtick in your name? |
| 14:31 | hiredman | dunno how well it would work in IDEA |
| 14:31 | fogus` | stuarthalloway: Some other fogus took my name |
| 14:31 | aredington | too many fogii |
| 14:31 | stuarthalloway | fogus` : poor Optimus had the same problem |
| 14:31 | aredington | that's right you can't outtype me |
| 14:32 | redinger | fogi? |
| 14:32 | fogus` | fogen |
| 14:32 | optimus` | not funny guys |
| 14:33 | hiredman | https://github.com/hiredman/clojure/commit/0a1c064c767991004b94aa796181aed111c98f34 |
| 14:34 | stuarthalloway | hiredman: zoinks |
| 14:35 | hiredman | oh, actually now I remember it doesn't build with a stock lein either |
| 14:35 | hiredman | damn |
| 14:35 | hiredman | lein puts ./src on the classpath which breaks for building clojure |
| 14:36 | bulters | alandipert: I was just wondering who would be optimus prime then. |
| 14:36 | mec | anyone know the O of adding to a sorted set? |
| 14:37 | chouser | mec: there's a nice chart for that... |
| 14:37 | stuarthalloway | ataggart: re http://dev.clojure.org/jira/browse/CLJ-781, you need to put your shorts in the first branch of the if |
| 14:38 | bulters | mec: ordered? then it\s usually a O(log n/log r) op |
| 14:38 | stuarthalloway | ataggart: otherwise they fall through and get converted to doubles, then longs. |
| 14:39 | ataggart | stuarthalloway: what are you referring to? |
| 14:39 | ataggart | the patch on 781? |
| 14:39 | amalloy | mec: log2(n) |
| 14:39 | mec | thanks all |
| 14:39 | stuarthalloway | ataggart, sorry, wrong link: http://dev.clojure.org/jira/browse/CLJ-782 |
| 14:40 | stuarthalloway | shorts used to fall down to the longCast at the bottom |
| 14:40 | fbru02 | stuarthalloway: Hey ! Can you please take a look at http://dev.clojure.org/jira/browse/CLJ-730 ? |
| 14:41 | stuarthalloway | fbur02: we'll take a look, but lower priority than bugs |
| 14:42 | stuarthalloway | ataggart: if you are working on the bit-ops patch, I can tweak 782 and submit it to Rich |
| 14:43 | @rhickey | https://github.com/clojure/clojure/commit/6fb09f402c5448070a2efc64ebd64285480b263f |
| 14:43 | ataggart | ok, just add Short and Byte to the first if |
| 14:44 | stuarthalloway | rhickey: performance tweaking question for you |
| 14:44 | @rhickey | stuarthalloway: ok |
| 14:44 | stuarthalloway | ataggart's patch http://dev.clojure.org/jira/browse/CLJ-782 correctly splits out a new path in longCast |
| 14:44 | hiredman | the passes are Parser/paser and Expr/(emit|eval)? |
| 14:44 | hiredman | parse |
| 14:45 | stuarthalloway | but that split implies the need to also split out short and byte, which used to fall to the bottom |
| 14:45 | stuarthalloway | is 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:45 | stuarthalloway | or does the short/byte case need to be handled further down |
| 14:46 | @rhickey | stuarthalloway: can't read these damn context-less patches |
| 14:46 | @rhickey | stuarthalloway: but yes, prioritize long and int please |
| 14:47 | fbru02 | stuarthalloway: thanks :) |
| 14:47 | stuarthalloway | rhickey: apply the patch locally and then view in IDEA :-) |
| 14:47 | @rhickey | stuarthalloway: applying patches in order to see what they do is a huge time suck |
| 14:47 | ataggart | stuarthalloway: posted link to updated bit-ops commit for your review |
| 14:48 | stuarthalloway | ataggart: can you move the short/byte check out of the first if, down later in the fn? (see discussion with rhickey above) |
| 14:48 | ataggart | stand by |
| 14:52 | ataggart | and updated cast fix: https://github.com/ataggart/clojure/commit/59bc3b2010ae7b0c8efb77e82939118b2f435045 |
| 14:54 | stuarthalloway | ataggart: https://github.com/ataggart/clojure/commit/59bc3b2010ae7b0c8efb77e82939118b2f435045 looks good. please put the patch on the ticket and I will screen it |
| 14:55 | stuarthalloway | ataggart: still looking at the bit-ops patch and wondering how best to implement even? |
| 14:55 | aredington | checking even let's BigIntegers in the door which are then going to be cast to long for bit-and |
| 14:56 | ataggart | that shouldn't affect the eveness |
| 14:56 | ataggart | the LSB is still going to be 1 or 0 irrespective of the truncation |
| 14:57 | stuarthalloway | ataggart: so we should need unchecked-long instead of long? |
| 14:57 | ataggart | yup |
| 14:57 | ataggart | stand by |
| 14:57 | scottj | is there a shorter version of &&(reduce #(update-in %1 [%2] (fnil inc 0)) {} [1 2 3 1 2 1]) |
| 14:58 | amalloy | scottj: ##, not && |
| 14:58 | scottj | ##(reduce #(update-in %1 [%2] (fnil inc 0)) {} [1 2 3 1 2 1]) |
| 14:58 | sexpbot | ⟹ {3 1, 2 2, 1 3} |
| 14:58 | amalloy | &(frequencies [1 2 3 1 2 1]) |
| 14:58 | sexpbot | ⟹ {1 3, 2 2, 3 1} |
| 14:58 | dakrone | rhickey: I was able to work around the primative problem, I was indeed doing it not-wrong-but-not-the-best-way |
| 14:58 | dakrone | thanks for the help |
| 14:58 | scottj | amalloy: thanks |
| 14:59 | amalloy | unless you're looking for a better way to reimplement frequencies |
| 14:59 | @rhickey | dakrone: I wasn't much help, but glad you are unstuck :) |
| 15:00 | amalloy | scottj: i think your original question is how i solved http://4clojure.com/problem/55 |
| 15:09 | choffstein | Hey 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:09 | opqdonut_ | :t mapAccumL |
| 15:10 | opqdonut_ | oh, sorry, I thought I was in #haskell |
| 15:10 | opqdonut_ | no, I don |
| 15:10 | opqdonut_ | 't think I've seen a function for that in the standard library |
| 15:10 | opqdonut_ | but you might get a nice solution with map + reduce |
| 15:12 | choffstein | yeah, I didn't think there would be |
| 15:13 | opqdonut_ | IMO reducing with a slightly intricate function is better than a custom recursive solution |
| 15:13 | choffstein | well, 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:14 | opqdonut_ | that |
| 15:14 | bulters | I 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:14 | opqdonut_ | certainly sounds doable |
| 15:14 | bulters | but checking the classpath, congomongo-1.0.0 is on it. |
| 15:14 | opqdonut_ | (how come I keep hitting my return key by accident all the time?) |
| 15:14 | stuarthalloway | rhickey, ataggart: http://dev.clojure.org/jira/browse/CLJ-782 is screened |
| 15:15 | amalloy | choffstein: so use reductions, with a two-part accumulator: [the-map-value current-label] |
| 15:15 | bulters | any ideas what I'm doing wrong? |
| 15:15 | amalloy | then you can (map first (reductions (fn [[_ label]] (...return a vector of [map-value new-label]...)))) |
| 15:16 | ataggart | rhickey has left the channel |
| 15:16 | amalloy | sorry, should be (fn [[_ label] current-input] ...) |
| 15:17 | choffstein | amalloy: that's what I was going to do, I just didn't know if that was idiomatic clojure |
| 15:18 | amalloy | choffstein: 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:19 | raek | bulters: did you check the classpath from within the clojure instance that could not use it? |
| 15:19 | choffstein | HOFs? |
| 15:19 | opqdonut_ | higher order functions |
| 15:19 | opqdonut_ | like map, reduce |
| 15:19 | bulters | raek: yup, it clearly lists lib/congomongo-1.0.0.jar |
| 15:20 | raek | what namespace are you trying to use? |
| 15:21 | bulters | raek: tried 'everything' congomongo, liebke.congomongo, org.clojars.liebke/congomongo |
| 15:21 | TimMc | clojurebot: HOFs are higher order functions |
| 15:21 | clojurebot | anonymous functions are functions with no names |
| 15:21 | TimMc | bah |
| 15:21 | TimMc | This bot can't conjugate. |
| 15:22 | raek | bulters: I don't think org.clojars.liebke is the official fork |
| 15:22 | Ramblurr | i'm having an issue where the results of dotrace are different than when i println the function's results :\ |
| 15:23 | raek | bulters: in the jar, there's a namespace called somnium.congomongo |
| 15:23 | bulters | raek: trying somnium now |
| 15:23 | Ramblurr | unfortunately the dotrace result is the correct one |
| 15:23 | raek | bulters: docs semes to be here: https://github.com/somnium/congomongo |
| 15:25 | raek | bulters: but for some reason, there isn't any stable (non-snapshot) version available |
| 15:25 | bulters | raek: my biggest hurdle I have so far in using clojure ;-) |
| 15:27 | raek | bulters: [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:27 | raek | this is probably why liebke pushed a private version |
| 15:29 | bulters | raek: Luckily I'm not releasing anything for the next few years |
| 15:29 | bulters | ;-) |
| 15:29 | bulters | thanks, it compiles :D |
| 15:49 | mec | how come some places in core.clj call (drop 1 ...) instead of just next? |
| 15:50 | rak85 | hi, guys |
| 15:50 | rak85 | a ! in the end of a function name is some kind of convention? |
| 15:51 | TimMc | rak85: Yeah, it usually indicates mutation. |
| 15:51 | TimMc | Specifically, things that aren't safe to call in a transaction. |
| 15:51 | bulters | TimMc: So stuff that has side effects go to a x! function? |
| 15:52 | TimMc | bulters: I think ! is usually used to make it clear when it wouldn't otherwise be obvious. |
| 15:52 | bulters | ok, so store-blah is fairly obvious :P |
| 15:52 | TimMc | bulters: compare assoc vs. assoc! for instance |
| 15:53 | bulters | same as in ruby, one variant that is non 'destructive' and one that is. |
| 15:53 | mec | looks like its mainly for things that muck with atoms and transients |
| 15:53 | mec | and vars |
| 15:56 | rak85 | thanks everyone |
| 15:58 | dnolen | bulters: not quite, assoc! can only be used transients, and even then those can't be bashed in place. |
| 16:01 | bulters | dnolen: I have no idea what transients are... yet; guess it's google time |
| 16:09 | mattmitchell | i have what i think is a byte array: #<byte[] [B@ff22be7> |
| 16:09 | mattmitchell | how do a pull out the items in that object? |
| 16:09 | mattmitchell | is the duck streams contrib required? |
| 16:09 | ataggart | ,(aget (byte-array 1) 0) |
| 16:09 | clojurebot | 0 |
| 16:10 | dnolen | ,(nth (byte-array 1) 0) |
| 16:10 | clojurebot | 0 |
| 16:10 | ataggart | nth uses a seq though |
| 16:10 | ataggart | iirc |
| 16:11 | mattmitchell | ataggart: thanks! trying that out now... |
| 16:12 | dnolen | ataggart: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L746 |
| 16:12 | ataggart | yeah, so not a seq, but still more involved than aget |
| 16:13 | dnolen | ataggart: true |
| 16:14 | raek | ,(into-array [1 2 3]) |
| 16:14 | clojurebot | #<Integer[] [Ljava.lang.Integer;@e8873a> |
| 16:14 | raek | ,(seq (into-array [1 2 3])) |
| 16:14 | clojurebot | (1 2 3) |
| 16:14 | mattmitchell | ok, so i could turn the byte array into a seq |
| 16:14 | dnolen | mattmitchell: if you don't care that you lose random access. |
| 16:15 | raek | mattmitchell: function that operate on sequences will call seq on the argument, so in most cases you can ommit seq |
| 16:15 | raek | ,(map inc (into-array [1 2 3])) |
| 16:15 | clojurebot | (2 3 4) |
| 16:15 | mattmitchell | raek: ok cool |
| 16:15 | ataggart | (map inc (byte-array 3)) |
| 16:15 | ataggart | ,map inc (byte-array 3)) |
| 16:15 | clojurebot | #<core$map clojure.core$map@b36022> |
| 16:15 | ataggart | bah |
| 16:15 | ataggart | ,(map inc (byte-array 3)) |
| 16:15 | clojurebot | (1 1 1) |
| 16:16 | ataggart | this is annying though: ##(type (aget (int-array 1) 0)) |
| 16:16 | sexpbot | ⟹ java.lang.Integer |
| 16:17 | ataggart | wait what |
| 16:17 | ataggart | ah 1.3.0 has that as a Long |
| 16:20 | kzar | This 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:21 | raek | yup. all integer numbers are represented as Longs when they are boxed in 1.3 |
| 16:21 | kzar | (I wanted it to just return nil on any exception.) |
| 16:23 | raek | kzar: you need to use gensym'ed symbols to bind values: (catch Throwable e# ...) |
| 16:24 | raek | otherwise it will be resolved, as if it was meant to refer to a global var |
| 16:24 | raek | ,`foo |
| 16:24 | clojurebot | sandbox/foo |
| 16:24 | raek | ,`foo# |
| 16:24 | clojurebot | foo__1290__auto__ |
| 16:24 | raek | this is to avoid symbol capture |
| 16:25 | kzar | raek: 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:26 | ordnungswidrig | I'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:27 | ordnungswidrig | print-dup does not support refs :-( |
| 16:27 | raek | kzar: let (and also catch) simply requires the symbol to not have a namespace part (and refuses compilation if the rule is not followed) |
| 16:28 | raek | syntax-quote (`) simply adds namespace parts to all symbols (except for those representing special forms) |
| 16:29 | kzar | raek: Ah right I get you now |
| 16:29 | kzar | raek: Thanks :) |
| 16:29 | raek | but 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:37 | amalloy | clojurebot: HOFs |are| higher order functions |
| 16:37 | clojurebot | Alles klar |
| 16:37 | amalloy | TimMc: ^ |
| 16:39 | fliebel | dnolen: 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:39 | dnolen | fliebel: np. |
| 16:41 | fliebel | dnolen: That paper, it does not describe the actual pattern matching, does it? Just the underlying tree stuff. |
| 16:42 | dnolen | fliebel: ? what do you mean. |
| 16:43 | mattmitchell | wow 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:44 | fliebel | dnolen: 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:50 | mattmitchell | ok clojure.core/slurp does the trick! |
| 16:55 | dnolen | fliebel: sorry, stepped away for a second, the decision tree is the pattern matcher. |
| 16:59 | dnolen | fliebel: 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:04 | fliebel | dnolen: I too stepped away :) Umph, I understood little of the paper I guess. |
| 17:04 | dnolen | fliebel: I'm reading it for a 4th time now, it's starting to make sense. |
| 17:05 | fliebel | hehe :) okay, point made. |
| 17:06 | dnolen | fliebel: 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:06 | fliebel | does the other one also use that math syntax? |
| 17:08 | dnolen | fliebel: 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:08 | dnolen | fliebel: no. |
| 17:08 | fliebel | They 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:09 | fliebel | In real life, some branches are more equal than others. |
| 17:10 | dnolen | fliebel: let the JVM do that for you. |
| 17:11 | dnolen | it's just byte code. |
| 17:13 | dnolen | fliebel: 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:14 | fliebel | dnolen: 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:15 | fliebel | dnolen: Yea, the mentioned that it is simple and still works for anything but pairs. |
| 17:19 | mattmitchell | what's the best way to convert a string "1" into an integer 1 ? |
| 17:19 | dnolen | fliebel: I know. a runtime optimization - so something I'd rather leave to JVM. |
| 17:20 | amalloy | &(read-string "1") |
| 17:20 | sexpbot | ⟹ 1 |
| 17:22 | mattmitchell | amalloy: perfect thanks |
| 17:30 | raek | mattmitchell: if you only want to allow integers: ##(Integer/parseInt "1") |
| 17:30 | sexpbot | ⟹ 1 |
| 17:42 | mreynolds | I'm blanking on how to force a string to not be treated as a sequence. What's the function to dot hat? |
| 17:43 | mec | Is there anything better than (Object.) for a bunch of unique things to use in a map |
| 17:43 | mec | as keys* in a map |
| 17:43 | mec | mreynolds: what are you wanting to do with the string? |
| 17:43 | mreynolds | mec: Trying to create a sequence of strings, not chars |
| 17:43 | raek | mec: keywords with namespace parts could be an option |
| 17:44 | mreynolds | mec: Trying to build tests for a simple line parser |
| 17:45 | mec | mreynolds: so you want to split a string into smaller strings? |
| 17:45 | raek | mreynolds: could you show us the code where the problem occurs? |
| 17:46 | mreynolds | mec: 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:46 | raek | mreynolds: there's nothing with strings that keep them from being part of sequences |
| 17:46 | mreynolds | raek: k, lemme see what I can do |
| 17:49 | mec | raek: I can't know how many ahead of time so I dont think I want to make keywords on the fly |
| 17:51 | raek | mec: then (Object.) sounds like a good fit to me |
| 17:51 | clojurebot | Excuse me? |
| 17:51 | raek | O_ô |
| 17:52 | amalloy | mec: (Object.) and (gensym) are the classics |
| 17:52 | mec | ah forget about (gensym), I think it would have more overhead tho |
| 17:53 | dnolen | gensym is actually quite slow. |
| 17:53 | mreynolds | raek: I think I'm running into a problem with printing at the console, not with sequences. One sec. |
| 17:55 | amalloy | (Object.) is surely "cheaper" |
| 17:55 | mec | I was just using numbers, but I figured eventually I would run out so I'd rather future proof :x |
| 17:56 | amalloy | but i bet if you want to debug it's easier to read ##(gensym) than ##(Object.) |
| 17:56 | sexpbot | (gensym) ⟹ G__37171 |
| 17:56 | sexpbot | (Object.) ⟹ #<Object java.lang.Object@1bc2314> |
| 17:57 | mec | hmm, maybe a helper function that switches to (gensym) for debugging |
| 17:58 | mreynolds | raek: http://pastebin.com/tRb8z2Es |
| 18:03 | Ramblurr | is it possible to supress warnings when (use ..) ing? |
| 18:03 | raek | mreynolds: some comments: replace (String. "foo") with "foo" and == with = |
| 18:04 | mreynolds | raek: 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:04 | raek | Ramblurr: are the warnings caused by your code? if so, you should fix the cause instead... :-) |
| 18:05 | Ramblurr | raek: 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:05 | raek | mreynolds: == is a rare special operations for numbers. = does what you want |
| 18:05 | Ramblurr | raek: so replacing a function is better than using a namespace |
| 18:05 | raek | Ramblurr: what var is being replaced? |
| 18:05 | mreynolds | raek: 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:06 | Ramblurr | raek: im replacing clojure.core/repeat with clojure.contrib.string/repeat |
| 18:06 | raek | ,(clojure.string/split "\"a\"|\"b\"|12345|12345678901234567890|\"long string\"|\"\"\n" #"\|") |
| 18:06 | clojurebot | ["\"a\"" "\"b\"" "12345" "12345678901234567890" "\"long string\"" "\"\"\n"] |
| 18:06 | raek | mreynolds: I get the string split into its parts |
| 18:06 | mreynolds | ,(clojure.string/split "\"a\"|\"b\"|12345|12345678901234567890|\"long string\"|\"\"\n" #"|") |
| 18:06 | clojurebot | ["" "\"" "a" "\"" "|" "\"" "b" "\"" "|" "1" ...] |
| 18:07 | raek | Ramblurr: and you want to use string's repeat instead? |
| 18:07 | mreynolds | mreynolds: That's the bug in my code with pipe. |
| 18:07 | Ramblurr | raek: yup |
| 18:07 | mreynolds | raek: Trying to remember the interaction of pipe as a regex, and if the original string is being returned as a sequence, or... |
| 18:07 | raek | if so, you should have (ns your-ns (:refer-clojure :exclude [repeat]) ...) |
| 18:07 | raek | to make that clear |
| 18:08 | Ramblurr | raek: 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:09 | Ramblurr | raek: ah nevermind, the error goes to stderr anyways |
| 18:09 | Ramblurr | not stdout, so all is good |
| 18:09 | Ramblurr | raek: thanks for that namepsace exclude tip |
| 18:09 | raek | for the user namespace in the repl, everything in clojure.core is already referred. |
| 18:10 | raek | so it's hard to opt out certains vars in it... |
| 18:11 | raek | Ramblurr: :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:12 | raek | mreynolds: | in a regex means alternative, so you have to quote it like \|, as you did in your paste |
| 18:13 | mreynolds | raek: Gotcha, just trying to figure out why the original string gets treated as a sequence in taht case. |
| 18:13 | raek | mreynolds: but note that the order of the keys of a map is not maintained, so your equality check will probably fail |
| 18:13 | raek | ,(clojure.string/split "\"a\"|\"b\"|12345|12345678901234567890|\"long string\"|\"\"\n" #"") |
| 18:13 | clojurebot | ["" "\"" "a" "\"" "|" "\"" "b" "\"" "|" "1" ...] |
| 18:14 | raek | mreynolds: it doesn't. you split at "nothing" |
| 18:14 | mreynolds | raek: Yeah, sorry, building up the test a piece at a time, wanted to jump over the sequence hurdle first |
| 18:14 | mreynolds | raek: Gotcha. This is my faulty memory of regex handling in java coming back to bite me |
| 18:14 | raek | the string matches nothing, followed by ", followed by nothing, followed by a, etc |
| 18:14 | mreynolds | raek: thanks |
| 18:15 | raek | one 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:17 | mreynolds | raek: Gotcha. I screwed this up when I did java too, so I don't blame clojure for that :) |
| 18:18 | mec | when should i use clojure.test/testing vs clojure.test/deftest |
| 18:25 | dakrone | mec: use deftest to declare a test, testing to declare sections of a test within a deftest |
| 19:48 | mreynolds | '(contains? (list "a" "b" "c") "a") |
| 19:49 | mreynolds | ,(contains? (list "a" "b" "c") "a") |
| 19:49 | clojurebot | false |
| 19:49 | mreynolds | Clojuredocs.org has a note on contains? saying they're not sure why that evaluates to false, does anyone here know? |
| 19:50 | raek | ,(contains? (list "a" "b" "c") 0) |
| 19:50 | clojurebot | false |
| 19:50 | technomancy | clojurebot: contains? |
| 19:50 | clojurebot | contains? 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:50 | mreynolds | bah |
| 19:50 | mreynolds | I'll edit the page :) |
| 19:50 | technomancy | contains? is specifically designed to trick newbies into thinking about O(n) characteristics of data structures. |
| 19:50 | mreynolds | it worked! |
| 19:51 | technomancy | there is no other explanation for why it hasn't been renamed |
| 19:51 | technomancy | mreynolds: brilliant. =) |
| 19:54 | dnolen | ,(associative? '(a b c)) |
| 19:54 | clojurebot | false |
| 19:54 | dnolen | ,(associative '[a b c]) |
| 19:54 | clojurebot | java.lang.Exception: Unable to resolve symbol: associative in this context |
| 19:55 | dnolen | ,(associative? '[a b c]) |
| 19:55 | clojurebot | true |
| 19:55 | mec | ,(contains? '(a b c) 1 |
| 19:55 | clojurebot | EOF while reading |
| 19:55 | mec | ,(contains? '(a b c) 1) |
| 19:55 | clojurebot | false |
| 19:55 | dnolen | ,(get '(a b c) 0) |
| 19:55 | clojurebot | nil |
| 19:55 | dnolen | ,(get '[a b c] 0) |
| 19:55 | clojurebot | a |
| 19:56 | mec | (nth '(a b c) 0) |
| 19:56 | mec | ,(nth '(a b c) 0) |
| 19:56 | clojurebot | a |
| 19:56 | dnolen | ,(find '(a b c) 0) |
| 19:56 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.util.Map |
| 19:56 | amalloy | i like that explanation, technomancy |
| 19:56 | dnolen | ,(find '[a b c] 0) |
| 19:56 | clojurebot | [0 a] |
| 19:57 | amalloy | &(doc find) |
| 19:57 | sexpbot | ⟹ "([map key]); Returns the map entry for key, or nil if key not present." |
| 19:58 | amalloy | neat. i didn't know about that one |
| 20:01 | mec | useful if your map's values might be nil |
| 20:01 | mec | well i guess thats what not-found is for anyway |
| 20:10 | pdk | that sorta thing |
| 20:10 | pdk | is why i miss multiple-value-bind sometimes |
| 20:18 | mec | is that a language feature or built onto CL? |
| 20:19 | amalloy | i think it must be a language feature. pasting it on with other CL primitives would be gross |
| 20:20 | mec | you could do it it with with-bindings and 2 macros |
| 20:24 | amalloy | i 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:24 | mec | sure, working on it now |
| 20:27 | mec | what are the 2, mutiple-value-bind and values? |
| 20:38 | mec | whats the difference between binding and with-bindings and how do you use either |
| 20:42 | mec | https://gist.github.com/949291 |
| 20:42 | mec | ^^ multiple-value-bind |
| 20:53 | amalloy | mec: with-bindings is lower-level. wants vars instead of symbols |
| 20:54 | mec | well its about 12 times slower than directly using let |
| 20:54 | amalloy | mec: 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:55 | amalloy | ie, you only support one multi-valued function globally at a time - they don't nest |
| 20:55 | mec | ah hmm |
| 20:55 | amalloy | very neat prototype though. not a way i'd considered doing it |
| 20:57 | mec | no idea how to fix that |
| 20:58 | mec | other than to wrap ~vals in (binding [*multi-value* false] ~vals) |
| 21:08 | chrissbx | What'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:09 | mec | any idea why this would throw a null pointer? (when (sequential? x) (= (seq x) (seq this))) |
| 21:09 | mec | chrissbx: (partition 2 coll) |
| 21:10 | mec | so (reduce (fn [[k v]] ...) (partition 2 coll)) |
| 21:14 | chrissbx | Thanks. Any way to get error checking for (partition 2 '(k1 v1 k2)) ? |
| 21:14 | chrissbx | (Without me doing length calculations around it?) |
| 21:14 | mec | (let [kvs (partition 2 coll)] (if (odd? (count kvs)) (throw ...))) |
| 21:15 | mec | oh |
| 21:16 | chrissbx | well, whatever. I guess I'm just supposed to do it that way. |
| 21:16 | mec | (reduce (fn [[k v :as t]] (if (= (count t) 1) (throw Exception.) ...) (partition 2 coll)) |
| 21:16 | mec | s/partition/partition-all/ |
| 21:16 | sexpbot | <mec> (reduce (fn [[k v :as t]] (if (= (count t) 1) (throw Exception.) ...) (partition-all 2 coll)) |
| 21:17 | chrissbx | I always prefer solutions that I can use without caring about errors and that then don't just suppress them. |
| 21:17 | chrissbx | But since clojure even doesn't think (first '()) is an error, then I guess my code will never be fool proof anyway. |
| 21:18 | chrissbx | I suppose I better get over it. |
| 21:19 | mec | its pretty handy that a lot of stuff returns nil instead of exceptions |
| 21:20 | chrissbx | Well, at the cost of missing (early) error checking. |
| 21:21 | chrissbx | (But partition doesn't even return nil, it just returns part of the solution.) |
| 21:22 | mec | ya partition truncates, gotta use partition-all if you want partials |
| 21:23 | amalloy | mec: actually i think that's a sufficient fix. wrapping values, that is |
| 21:23 | amalloy | clojurebot: partition? |
| 21:23 | clojurebot | partition is probably not what you want; see partition-all. |
| 21:23 | mec | lol |
| 21:24 | amalloy | chrissbx: forget about (first ()), clojure is perfectly happy with ##(first (first (rest (first nil)))) |
| 21:24 | sexpbot | ⟹ nil |
| 21:24 | chrissbx | Well, using partition-all will just sweep the error under the carpet in the subsequent reduce. |
| 21:24 | amalloy | &(doc partition) |
| 21:24 | sexpbot | ⟹ "([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:25 | mec | ok i changed equiv on this deftype to (equiv [this x]) and it still throws a null pointer when called |
| 21:25 | amalloy | chrissbx: pass a "pad" collection that's something like (repeatedly #(throw (Exception. "OMG WUT"))) |
| 21:25 | amalloy | &(partition 2 2 (repeatedly #(throw (Exception. "OMG WUT"))) (range 4)) |
| 21:25 | sexpbot | ⟹ ((0 1) (2 3)) |
| 21:25 | amalloy | &(partition 2 2 (repeatedly #(throw (Exception. "OMG WUT"))) (range 5)) |
| 21:25 | sexpbot | java.lang.Exception: OMG WUT |
| 21:26 | mec | wow thats interesting |
| 21:26 | amalloy | that still delays the exception until the first wrong-sized partition, but you can't do any better than that and still be lazy |
| 21:27 | mec | why does partition do that instead of just passing the function |
| 21:27 | amalloy | mec: ? |
| 21:27 | mec | ah nvm |
| 21:33 | amalloy | chrissbx: anyway you can (defn die [] (repeatedly #(throw...))), and then use (die) as your pad collection |
| 21:33 | amalloy | to let you fail as fast as is possible |
| 21:33 | chrissbx | well, (def die (repeatedly ...)) |
| 21:34 | chrissbx | But since I'm used not to bother about edge cases when writing my code, I'll forget about this. |
| 21:34 | amalloy | chrissbx: i considered that, i don't think it's a good idea |
| 21:34 | chrissbx | And my code will just do unsensible stuff as a consequence. |
| 21:34 | chrissbx | And I don't care right now :) |
| 21:35 | amalloy | if 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:35 | chrissbx | What would be cached isntead of the exception? |
| 21:36 | chrissbx | ah the result of the exn handler, you mean? |
| 21:36 | amalloy | i'm not sure, really. it's a weird case |
| 21:36 | chrissbx | heh |
| 21:36 | mec | mine keeps blowing up |
| 21:36 | chrissbx | mec: amalloy means when you use an exception handler that replaces the exn with a value |
| 21:37 | amalloy | yeah, but i was wrong |
| 21:37 | amalloy | there's no way it could get cached |
| 21:37 | chrissbx | If that's possible in Clojure to have such a handler at all. |
| 21:39 | amalloy | no, it's not |
| 21:39 | amalloy | the stack unwinds up to the first handler it can find, and grows anew from there |
| 21:41 | chrissbx | How do debuggers work, though, if an exception happens? They'll have to capture it with the stack before unwinding. |
| 21:41 | amalloy | they attach to the process externally |
| 21:41 | chrissbx | (Or have access to the unwound stack after-the fact.) |
| 21:42 | chrissbx | (To the un-unwound, I meant) |
| 21:42 | amalloy | and then the jvm gives them priority execution while the target program is suspended |
| 21:42 | chrissbx | k |
| 21:43 | chrissbx | Maybe that'll be a feature in a future Clojure version (for restarts ...). |
| 21:44 | chrissbx | Then my code will break then :) |
| 21:45 | chrissbx | My future is already doomed while learning Clojure. |
| 21:45 | amalloy | eh? |
| 21:49 | chrissbx | Just exaggerating. |
| 22:26 | semperos | informational 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:34 | mec | semperos: number of unique visitors could be interesting |
| 22:35 | semperos | mec: thanks |
| 22:35 | semperos | any thoughts on "equivalent" nicks? by default i was thinking "foo" and "foo_" with any number of underscores |
| 22:36 | mec | also ` and preceding _ |
| 22:37 | semperos | ` at the end? |
| 22:37 | semperos | I'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:37 | semperos | things in that vein |
| 22:48 | chrissbx | semperos: you might catch most nick duplicates by checking for renames |
| 22:48 | semperos | true |
| 22:49 | semperos | actually using the logs saved at n01se.net for this, where those aren't captured |
| 22:49 | chrissbx | ah |
| 22:49 | semperos | but a fine thought |
| 22:51 | semperos | here's what I have so far after a quick brainstorm: |
| 22:51 | semperos | * Total unique visitors |
| 22:51 | semperos | * Total messages |
| 22:51 | semperos | * Total mentions of particular languages (Java, Ruby, Lisp) |
| 22:51 | semperos | * Clojurebot vs Sexpbot use |
| 22:51 | semperos | * For a user, total messages |
| 22:51 | semperos | * For a user, total days "online" (at least one message) |
| 22:51 | semperos | * Top users |
| 22:51 | semperos | * Top days (number of messages) |
| 22:51 | semperos | * Top Clojure fn's mentioned/used |
| 22:51 | semperos | was hoping that wouldn't make separate messages... |
| 22:52 | semperos | obviously there'll be ambiguity, but this is a start |
| 22:53 | semperos | * For a user, number of messages including Java interop forms |
| 22:59 | chrissbx | Another 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 |