2010-06-18
| 00:02 | hiredman | actually, it works for me |
| 00:02 | hiredman | are you using a recent snapshot? |
| 00:16 | ceptorial | does anyone recommend a way to decide whether to use (:key map) or (map :key)? |
| 00:35 | rdsr | Hi all, on creating a table with a text data type I receive a sqlsyntaxexception |
| 00:35 | rdsr | here's the gits http://gist.github.com/443235 |
| 00:35 | rdsr | *gist |
| 00:35 | rdsr | I'm using the c.c.sql lib |
| 00:36 | rdsr | The error mesg received is Syntax error: Encountered "" at line 1, column 91. |
| 00:37 | cemerick | hiredman: yeah, it works fine for me everywhere else too. I only created the gist because it sounded like you didn't think finally was supposed to work in conjunction with a recur in the try block. |
| 00:42 | hiredman | I can't say I am surprised though |
| 00:43 | rdsr | I'm using Derby as my DB |
| 00:43 | rdsr | is text datatype not supported in that? |
| 00:44 | hiredman | try/catch/finally is a linked set of gotos and recur is a goto, so mixing them is bound to be interesting |
| 00:44 | hiredman | rdsr: I'd check the derby docs |
| 00:44 | hiredman | http://db.apache.org/derby/manuals/reference/sqlj123.html |
| 00:45 | rdsr | thks hiredman, doing that right now |
| 00:46 | hiredman | man, tail calls will be so much fun |
| 00:47 | rdsr | thks hiredman, I'm using CLOB instead now and it seems to work |
| 01:27 | zakwilson | clojure.xml/parse can't seem to handle the character \# in a filename. |
| 02:20 | daaku | i have this odd issue where `rlwrap clj` gives me reverse-i-search (Ctrl-r) correctly, but it doesn't work (nothing get's triggered) with `rlwrap lein repl` (i'm on a mac, with clojure 1.1) -- anyone have any ideas on why this might be? |
| 02:21 | daaku | hmm.. it seems like `lein repl` actually has it's own readline equivalent |
| 02:26 | daaku | oh, lein 1.2-snapshot has this fixed. cool |
| 03:11 | daaku | is there anything that offers real tab completion (live, not precomputed) in the command line repl? |
| 03:13 | raek | slime in emacs autocompletes vars in the current namespace |
| 03:15 | daaku | raek: i'm not invested enough yet to use/setup/learn emacs :( |
| 03:15 | wwmorgan | daaku: enclojure has decent autocompletion |
| 03:16 | daaku | wwmorgan: is that netbeans only? |
| 03:16 | wwmorgan | daaku: yes |
| 03:17 | daaku | i'm a vim user, i guess ideally i'd like to keep the repl separate and keep using my vim/screen setup |
| 03:17 | raek | was it enclojure that hade something similar to paredit? |
| 03:23 | daaku | interesting.. enclojure has support for a "standalone repl" mode |
| 05:34 | cad_from_austin | test |
| 05:36 | cad_from_austin | I was hoping for insight into an elusive clojure.contrib.sql problem. I have a read function that works when I load the code into a repl within the defining namespace, but that throws and error when the code is executed from another namespace with (:use defining.namespace). I actually get a jdbc error - check syntax |
| 05:47 | Fossi | test |
| 05:47 | DarthShrine | Test failed. |
| 05:58 | gerryxiao | ,(clojure-version) |
| 05:58 | clojurebot | "1.2.0-master-SNAPSHOT" |
| 05:58 | gerryxiao | hello |
| 05:59 | cad_from_austin | I'd appreciate any help on the above, even "you don't understand namespaces" |
| 05:59 | gerryxiao | how to know whether the number is boxed? |
| 05:59 | gerryxiao | ,(let [a 3] (class a)) |
| 05:59 | clojurebot | java.lang.Integer |
| 05:59 | gerryxiao | ,(let [a (long 3)] (class a)) |
| 05:59 | clojurebot | java.lang.Long |
| 06:02 | gerryxiao | (defn ^:static fib ^long [^long n] nil) |
| 06:03 | gerryxiao | ,(defn ^:static fib ^long [^long n] nil) |
| 06:03 | clojurebot | DENIED |
| 06:15 | mikem | I see some symbols used inside macros which end with a # -- what does that signify? |
| 06:16 | LauJensen | mikem: thats gensym, gives it a unique name in the expansion |
| 06:16 | mikem | LauJensen: ok, that makes sense. thank you! |
| 06:17 | hoeck | cad_from_austin: please paste your code somewhere (and maybe the exception you get) |
| 06:18 | cad_from_austin | Mikem: I've actually just now resolved the problem, but have another question |
| 06:18 | cad_from_austin | I wound up just restarting swank. Is there something I should know about copy and pasting files from my source to the repl? |
| 06:20 | mikem | cad_from_austin: I think you meant hoeck :) |
| 06:20 | hoeck | cad_from_austin: basicall not, if the namespace has been previously loaded into the repl |
| 06:20 | hoeck | *basically |
| 06:22 | hoeck | cad_from_austin: do you copy whole files literally into the repl? |
| 06:22 | hoeck | cad_from_austin: (require 'the.namespace :reload) should be more convenient |
| 06:22 | cad_from_austin | Pretty often, yes. |
| 06:24 | LauJensen | hoeck: or :reload-all |
| 06:36 | cad_from_austin | Where should I put the reload-all? |
| 06:38 | cad_from_austin | Christ, nevermind. I got it. |
| 06:39 | LauJensen | cad_from_austin: Sorry - I had that line on my screen the whole time, but because there was no highlighting, my mind seemed to have filtered it out ... scary :) |
| 06:40 | Raynes | Likewise, actually. :| |
| 06:40 | Raynes | I was playing tetris. :) |
| 06:46 | LauJensen | Raynes: The penumbra version? :) |
| 06:46 | Raynes | Not a Clojure tetris. |
| 06:46 | Raynes | I suck at graphics programming. |
| 06:46 | cad_from_austin | LauJenson: Which line? |
| 06:47 | Raynes | cad_from_austin: The line where you asked where to put reload-all |
| 06:47 | cad_from_austin | Ah. |
| 06:51 | cad_from_austin | Holy crap this is useful. Thanks guys. |
| 06:51 | Raynes | Reload is a gift from the great brackety gods. |
| 08:01 | eevar2 | icfp starting now-ish |
| 08:14 | LauJensen | Raynes: Doesnt matter if you suck. Tetris is in one of the demos that come with Penumbra :) |
| 08:16 | Raynes | LauJensen: Oh. |
| 08:36 | Licenser | hmm reading the page about statics it looks impresive! |
| 08:36 | LauJensen | Licenser: When will you learn, its just a prank, clojure will never be statically typed |
| 08:37 | Licenser | LauJensen: I'm vaxinated against learning, it was a long and painfull process, including torture, brainwashing and humiliation - I think they called it school |
| 08:38 | LauJensen | Ouch - Just say no |
| 08:38 | LauJensen | Anyway, Im kidding of course, statics are cool |
| 08:38 | Licenser | :P |
| 08:58 | Licenser | I start to dislike all that meta annotation stuff :( it gets to look more complicated then useful |
| 08:59 | LauJensen | Because they changed #^ to ^ ? |
| 08:59 | Licenser | No but reading the code in the example it starts to look odd |
| 09:00 | Licenser | too much of ^ in there |
| 09:00 | LauJensen | But you so rarely need it, its not a general thing |
| 09:00 | Licenser | yes but it'd look cooler if it were a macro/special form/function |
| 09:00 | Twey | Isn't it deprecated for (meta …) anyway? |
| 09:00 | Licenser | like (static ...) |
| 09:00 | Twey | Oh, right, I see. |
| 09:01 | LauJensen | I disagree |
| 09:01 | Licenser | what I mean is we start to have many many many special character combinations |
| 09:01 | Twey | (with-meta …)? |
| 09:02 | Licenser | reader macros are kind of cool on the one hand but if we end up with perlish charcter chaos it gets ugly |
| 09:03 | Licenser | also the whole macro syntax can be quite cryptic |
| 09:03 | Licenser | with @,~,` and ' |
| 09:03 | Licenser | now we also got $, and always had #(whatever behind it) |
| 09:04 | Licenser | does it make any sense what I mean, i talk about readability here, it is code lengthy effective but can get cryptic quite quick sadly |
| 09:16 | raek | http://github.com/richhickey/clojure/blob/8c9b0574a83f6c77576325b724c837cf4143eb33/src/clj/clojure/java/io.clj#L263 |
| 09:16 | raek | shouldn't this be "make-output-stream"? |
| 09:17 | Licenser | one think I don't understand about the static stuff, will the static branch break the fact that numbers 'just work'? |
| 09:20 | raek | (output-stream (Socket. "clojure.org" 80)) throws "Cannot open <#<Socket Socket[addr=clojure.org/75.126.104.177,port=80,localport=52729]>> as an OutputStream." for me... |
| 09:20 | raek | but (input-stream ...) works fine... |
| 09:21 | raek | Socket does not seem to be extended to IOFactory correctly |
| 09:24 | Licenser | raek: an output stream is a stream you can write to |
| 09:25 | Licenser | and I might be mistaken but I don't think you can write to clojure.org's webserver |
| 09:26 | raek | that was just an example of something that yields a working socket |
| 09:26 | raek | I'm aware of how HTTP works |
| 09:26 | Licenser | well but it is a read socket I think |
| 09:26 | Licenser | not a write socket, at least I think |
| 09:26 | Licenser | or wait no you should be able to write to it |
| 09:26 | raek | you need to send the request... |
| 09:27 | Licenser | oh details :P |
| 09:27 | Licenser | but perhaps you need to wrap it in something before that? |
| 09:27 | Licenser | I am confused but you may be right |
| 09:27 | raek | I think I can make a fix for this myself |
| 09:28 | raek | but I haven't signed the CA yet |
| 09:28 | cemerick | rhickey: I tripped all over recur last night. Two problem cases: https://gist.github.com/e9bb4c44adf8d9a195dd |
| 09:29 | cemerick | If I had a magic wand, recur from within the try block, regardless of target, would run the finally block. That may be too complicated to implement though. |
| 09:30 | raek | Sockets have two methods called getInputStream and getOutputStream |
| 09:30 | cemerick | In that case, recur out of a try should be disallowed. |
| 09:30 | cemerick | However, it seems like recur whose target doesn't leave the try/catch/finally should be allowable. |
| 09:30 | raek | Socket is extended to clojure.java.io/IOFactory |
| 09:31 | raek | but only half of the protocol is implemented |
| 09:32 | Licenser | heh |
| 09:32 | rhickey | cemerick: yes, recur + try needs work |
| 09:34 | cemerick | rhickey: Shall I open a ticket or is this a 10 minute quickie? |
| 09:34 | Licenser | hmm when I understand the mailing list correctly the new branches will remove automatic overflow to bigint? I find that a huge step backwards even for the sake of performance, I personally would not trade a easyer syntax / working for performance for the 'it just works' effect |
| 09:34 | rhickey | cemerick: it's a huge job and there are already tickets I think |
| 09:35 | cemerick | ok, I'll double check |
| 09:35 | tcrayford | cemerick: I keep on wanting to work on adding your "ideal clojure ide" features to intellij, but getting it build really sucks, and the guy who runs it is not good for help :( |
| 09:36 | tcrayford | I'm pretty sure I can implement most of them pretty quickly, just doing so outside of emacs looks like a right pain |
| 09:36 | cemerick | rhickey: If it's any easier, a temporary change to disallow recur from try entirely would be preferable to the silent dropping of the finally IMO. |
| 09:37 | rhickey | cemerick: you are talking about case #2, yeah, I don't know why that's not caught |
| 09:37 | cemerick | rhickey: right, that's really painful |
| 09:37 | rhickey | currently it's mostly draconian about it |
| 09:37 | rhickey | cemerick: you really wrote something like #2? |
| 09:39 | cemerick | rhickey: yes, I had a recur in the try, with a loop target outside the try, and a finally block that was deleting the temp files that were being looped through after they were processed in the try. I kept running out of disk. :-) |
| 09:39 | cemerick | whoa, I botched that sentence :-O |
| 09:40 | mikem | what's the easiest way to launch a clojure script from the command line without compiling it first? |
| 09:40 | cemerick | similar to (loop [[file & files] files] (when file (try (process-file file) (recur files) (finally (.delete file))))), but with a lot more stuff going on :-) |
| 09:42 | tcrayford | mikem: there's a bash script included in contrib |
| 09:42 | tcrayford | http://github.com/richhickey/clojure-contrib/blob/master/launchers/bash/clj-env-dir |
| 09:43 | mikem | tcrayford: ok, looking at it now |
| 09:43 | cemerick | tcrayford: hrm, yeah, I've heard similar things. :-( I had high hopes when IDEA open-sourced the base, but there doesn't seem to have been a lot of traction on any IntelliJ open-source projects that I've heard of. |
| 09:43 | tcrayford | cemerick: I emailed the author about it in april, and still haven't got a response |
| 09:44 | tcrayford | I already know how to write most of the stuff you've requested, might just go and do it in emacs and then ask the people who write the IDEs to steal it |
| 09:46 | cemerick | tcrayford: I don't think there's a lot of stuff there that's truly difficult, the tough part is getting it in one place and making it accessible to a broad audience. |
| 09:46 | danlucraft | tcrayford: I would steal anything you wrote for Redcar if you OKed it |
| 09:47 | tcrayford | danlucraft: if I do this, the first thing in the readme is going to be a note for IDE writers to steal everything and anything they want |
| 09:47 | danlucraft | brill |
| 09:49 | tcrayford | though note that most of my stuff requires access to a running repl which has all of the source code loaded into it |
| 09:49 | tcrayford | (for whatever project is being worked on) |
| 09:50 | cemerick | danlucraft: what's the UI toolkit you're using? |
| 09:50 | danlucraft | swt |
| 09:51 | cemerick | it is written in jruby then? |
| 09:51 | danlucraft | cemerick: yep. almost entirely |
| 09:51 | cemerick | ah, ok |
| 09:51 | cemerick | you should change your FAQ :-) |
| 09:52 | danlucraft | hmm |
| 09:52 | danlucraft | cemerick: to say it's written in JRuby? |
| 09:52 | danlucraft | done! |
| 09:53 | danlucraft | cemerick: I read your posts on ideal clojure env |
| 09:53 | danlucraft | made some notes |
| 09:53 | danlucraft | I saw you said "Textmate (!)" :) |
| 09:53 | cemerick | I think I only made one, but sure. :-) |
| 09:53 | cemerick | Yeah, TM is an oddball choice for sure. |
| 09:53 | danlucraft | what's the ! for? |
| 09:53 | tcrayford | danlucraft: the problem for him is that redcar won't have amazing java support like the other ides |
| 09:53 | cemerick | IMO, anyway |
| 09:54 | danlucraft | cemerick: I mean, I think I get it, but why would you say ™ is no good for clojure? |
| 09:55 | cemerick | danlucraft: Well, there's not much to the bundle, and TM is a bit of a dead-end until someone writes a replacement. ;-) |
| 09:55 | tcrayford | cemerick: a bunch of the stuff you have in there is already in swank (find usages, go to declaration), and the IDE people could definitely yoink that |
| 09:57 | cemerick | tcrayford: Yeah, but actually implementing the functionality isn't the hard part. |
| 09:57 | cemerick | integrating it into the IDE is. |
| 09:57 | tcrayford | very true |
| 09:57 | cemerick | e.g. getting discovered namespaces recognized as "types" is a good example |
| 09:58 | danlucraft | what's a discovered namespace? |
| 09:59 | danlucraft | as opposed to a regular namespace? |
| 09:59 | mikem | tcrayford: ok, I got the clj-env-dir script working, however it seems my .clj file needs an explicit call to (main) in order to run. is it possible to invoke main from the command line somehow? |
| 09:59 | tcrayford | mikem: I don't know, I just use lein for everything :/ |
| 09:59 | cemerick | danlucraft: one that your editor or build tool has recognized as a namespace to support navigating to it or compiling it. |
| 10:00 | mikem | tcrayford: hehe ok, no worries :) |
| 10:00 | mikem | thanks for the help |
| 10:03 | danlucraft | cemerick: ok |
| 10:07 | rhickey | cemerick: you haven't weighed in yet on the ggroup re: enhanced primitives. More naysayers right now. |
| 10:08 | djpowell | hmm, would it be good for clojure.main to support running the (-main) function somehow? |
| 10:09 | cemerick | djpowell: there's a ticket for that, I think technomancy opened it |
| 10:09 | cemerick | rhickey: I'll dig in a little later -- but, I'm on very shaky ground there. I fail forward when it comes to mathy stuff. :-( |
| 10:16 | cemerick | rhickey: looks like 4:1 against, if I can summarize so callously. And here I was focusing on equality semantics. |
| 10:16 | mmarczyk | incidentally, I wonder if the introduction of the num/prim/equal branches means that 1.2 is settled and basically in testing? |
| 10:17 | mmarczyk | (surely this stuff isn't meant for inclusion at this stage) |
| 10:18 | mmarczyk | cemerick: thanks for prodding me along re: the ca, by the way, should arrive sometime soon (today? Monday?) :-) |
| 10:18 | cemerick | mmarczyk: excellent :-) I'm already using the multi-comparator :-) |
| 10:18 | mmarczyk | cemerick: oh cool, happy to hear that :-) |
| 10:19 | cemerick | mmarczyk: apparently it is intended for 1.2 |
| 10:20 | Licenser | so I might hold a short presentation of clojure on a ruby meeting, I know some of you already did some presentations, are there any advice what are good points to tacke? |
| 10:21 | mmarczyk | am I correct in estimating that this would make 1.1 -> 1.2 a bigger deal than Python 2.6 -> 3.1 ? :-) |
| 10:22 | cemerick | yeah, it's already a pretty huge release compared to 1.1 |
| 10:23 | mmarczyk | I would have thought that the new numeric stuff would require a pretty significant testing effort before release, while the other stuff is probably pretty well tested already |
| 10:23 | cemerick | well, there's a fairly large body of automated tests |
| 10:24 | cemerick | but yeah, I think adding the prim, static, etc stuff will extend the stewing period |
| 10:24 | cemerick | note there's not been a beta release yet *shrug* |
| 10:24 | mmarczyk | true |
| 10:24 | cemerick | hanging out in #clojure makes one think everything's just around the corner |
| 10:24 | Licenser | heh |
| 10:25 | Licenser | tcrayford: you can start c-in-c already :P |
| 10:25 | tcrayford | hah :P |
| 10:25 | mmarczyk | ;-) |
| 10:25 | Licenser | I mean many of use are already using 1.2 I guess |
| 10:25 | mmarczyk | I know I do |
| 10:26 | mmarczyk | protocols / records are really pretty helpful |
| 10:26 | Licenser | yap |
| 10:26 | tcrayford | man this is sorta confusing |
| 10:26 | Licenser | tcrayford: what is? |
| 10:26 | tcrayford | ,(= '() (map identity '())) |
| 10:26 | clojurebot | true |
| 10:26 | _fogus_ | Someone started a 1.1 REPL and I felt physically ill. I wondered how they got along without types/protos/records |
| 10:26 | tcrayford | that |
| 10:27 | mmarczyk | tcrayford: huh? |
| 10:27 | tcrayford | (= empty-seq empty-list) |
| 10:27 | mmarczyk | _fogus_: so, prudence (staying on the stable boat &c.) has adverse effects on your health? ;-) |
| 10:28 | mmarczyk | not to say I wouldn't feel similar, though I'm afraid I have a sillier reason (how could we live with #^ in place of ^!?) :-) |
| 10:29 | silveen | Does anyone know of a bb2html'ish PHP script that handles code syntax highlight for different languages? |
| 10:29 | tcrayford | I can sorta understand why the empty seq is equal to the empty list (they print the same), but its still somewhat weird |
| 10:31 | djpowell | ,(= '() (sequence nil)) |
| 10:31 | clojurebot | true |
| 10:31 | mmarczyk | ,(= [] ()) |
| 10:31 | clojurebot | true |
| 10:31 | tcrayford | ah |
| 10:32 | tcrayford | that makes sense |
| 10:32 | _fogus_ | equality partitions ftw |
| 10:32 | rhickey | _fogus_: got slides? |
| 10:33 | _fogus_ | for the talk last night? |
| 10:33 | rhickey | yes |
| 10:33 | _fogus_ | I will have them up today |
| 10:35 | _fogus_ | it was a fun talk. but I think I talked too fast :( |
| 10:36 | tcrayford | practice gets you better |
| 10:36 | liebke | _fogus_: You did a great job, I enjoyed it a lot! |
| 10:37 | _fogus_ | liebke: Thanks! I thought the Q&A was pretty thoughtful |
| 10:37 | liebke | I agree |
| 10:37 | _fogus_ | People seemed genuinely excited about Clojure/core also |
| 10:38 | rhickey | liebke: want to clean up the incanter test failures on equal branch? mostly things of the (= 113.0 113) variety. Would need to become (= 113.0 113.0) or (== 113.0 113) Any such fixes would be backward compatible |
| 10:39 | liebke | I think they were more excited about trying to improve Clojure's out-of-box experience :-) |
| 10:39 | rhickey | liebke: it's breaking my argos tests |
| 10:39 | liebke | rhickey: will do |
| 10:39 | rhickey | liebke: thanks |
| 10:39 | liebke | I told them about how I kept breaking your argos tests :) |
| 10:40 | rhickey | heh |
| 10:40 | rhickey | I love having argos |
| 10:40 | liebke | I love you having argos |
| 10:40 | _fogus_ | love fest |
| 10:42 | technomancy | group hug! |
| 10:43 | liebke | technomancy: we also talked about your keyboard pants, and the future of wearable computers :) |
| 10:45 | technomancy | sweet. |
| 10:45 | liebke | I'm considering making mouse-shoes |
| 10:45 | technomancy | clojurians have a nose for futurism |
| 10:46 | technomancy | liebke: I am actually considering a foot pedal for mic mute to assist with voip pairing |
| 10:46 | technomancy | would make it easier to work in noisy coffee shops with bean grinders going off in the background |
| 10:46 | liebke | you are the future :) |
| 10:46 | _fogus_ | treat him well |
| 10:46 | liebke | ah, you're pairing at coffee shops, that's cool |
| 10:47 | technomancy | hehe |
| 10:49 | rhickey | so, only inc, dec, +, -, * have overflow issues. If you are in favor of the default being throw on overflow, what suffix would you suggest for the promoting versions, and vice versa, if the default was promote, what suffix for the throwing versions? |
| 10:51 | Licenser | static-inc static-dec static-+ static-- (looks ugly) static-* (or stat- or just s-) |
| 10:51 | rhickey | e.g. things like +n for generic [n]umeric addition, or +o for addition with [o]verflow or [o]ptimized |
| 10:51 | Licenser | or inc! +! -! *! |
| 10:52 | vu3rdd | _fogus_: is your capclug presentation available somewhere for download? |
| 10:52 | rhickey | Licenser: ! for 'hurry up!' ? |
| 10:52 | Licenser | ! for hurry up! for watch out! for might throw! |
| 10:52 | Licenser | generaly for need to look at this! |
| 10:52 | mmarczyk | I'd go with prim-add / fast-add or something for fast math |
| 10:53 | Licenser | and it'd be consistant with the transistant things ! functions are faster but need special care |
| 10:53 | mmarczyk | but Licenser's idea is pretty cool :-) |
| 10:53 | mmarczyk | oh, that's true (the parallel to transients) |
| 10:53 | Licenser | and it also says 'I freaking know what I'm doing!!!!' |
| 10:54 | _fogus_ | how about +slow -slow *slow :p |
| 10:54 | Licenser | heh |
| 10:54 | vu3rdd | _fogus_: sorry, didn't read the conversation above. Looking forward to go thru it |
| 10:54 | mmarczyk | Licenser: yeah! |
| 10:54 | mmarczyk | (inc Licenser) |
| 10:55 | _fogus_ | vu3rdd: It should be (back) up later today. I took it down to move it but had to run |
| 10:56 | Licenser | we could also make it +§ |
| 10:57 | Licenser | which reminds me, clojure is the perfect language for lawyers you can call variables §3 |
| 10:59 | Chousuke | I'd rather have + and - etc. be the fast ones |
| 10:59 | mmarczyk | just out of curiosity -- why? |
| 10:59 | Chousuke | If you anticipate that overflows will be a problem, you can prepare for it |
| 11:00 | mmarczyk | if you anticipate anything of the sort, you know what you're doing |
| 11:00 | Chousuke | meanwhile, anyone else writing regular maths code will get speed. |
| 11:00 | Licenser | Chousuke: but that is an expert decision and the default one should be what is surely good for non experts too |
| 11:00 | Chousuke | well, of course. Programmers can be expected to know what they're doing. |
| 11:00 | Licenser | Chousuke: In what world do you live?!? :P |
| 11:01 | Licenser | just think bout it, when people start to write stuff and start with simple things as fact and boom things go down and they wonder why and have to figure out how to typehint and and and |
| 11:01 | AWizzArd | Hehe, can one translate it that directly from german to english? |
| 11:01 | Licenser | that isn't nice |
| 11:01 | mmarczyk | Chousuke: ah, that's just not true |
| 11:01 | Chousuke | Licenser: Except they won't need to typehint anything |
| 11:02 | mmarczyk | Chousuke: people should be expected to know enough about what they're doing |
| 11:02 | Chousuke | Licenser: they'll just need to use bigint literals. |
| 11:02 | Licenser | but finding out that there are two versions of + |
| 11:02 | mmarczyk | the smaller "enough" is, the better |
| 11:02 | Licenser | even worst o.O |
| 11:02 | mmarczyk | for the parts of the spectrum everyone touches upon |
| 11:02 | mmarczyk | high performance math is not really something everyone touches upon |
| 11:02 | Licenser | I guess very little people do |
| 11:02 | mmarczyk | in particular, cemerick's State of Clojure has 53% of Clojurians do web apps |
| 11:03 | mmarczyk | in which way is having fast math relevant to building a web app? |
| 11:03 | Licenser | and just to make sure people don't get it wrong, I do need fast math but I'd rather go the extra length to write +! where I know I can do it then having to write +n or whatever when I'm in doubt |
| 11:03 | mmarczyk | now not having exceptions because of maliciously formed numerals or whatever |
| 11:03 | mmarczyk | might actually be relevant I guess |
| 11:03 | mmarczyk | Licenser: an (inc) to that too |
| 11:04 | cemerick | mmarczyk: FWIW, maths are #2 in that list :-) |
| 11:04 | Chousuke | I'm not convinced that this would be a problem. |
| 11:04 | Licenser | yes #2 :P |
| 11:04 | mmarczyk | cemerick: yup, I remember :-) |
| 11:04 | Licenser | there is nothing worth more then 'it just works' |
| 11:04 | mmarczyk | cemerick: with what, around 1/3 of the community declaring an interest? |
| 11:04 | cemerick | 39% |
| 11:04 | mmarczyk | some of those guys might be Konrad Hinsen-types :-) |
| 11:04 | mmarczyk | I mean, they want it slower :-P |
| 11:05 | mmarczyk | see clojure.contrib.generic |
| 11:05 | Licenser | iPods are the most sold music players, Ruby went hugely up in the last years, apple computers in general did. And all of them because 'they just work' |
| 11:05 | Chousuke | Licenser: except when it doesn't, and you end up getting weird behaviour because some of your numbers are bigints and some aren't :P |
| 11:05 | cemerick | Licenser: all of which have nothing to do with a design decision in a programming language |
| 11:06 | Licenser | of cause |
| 11:06 | mmarczyk | the present state of arithmetic in Clojure does mostly "just work" though |
| 11:06 | mmarczyk | |
| 11:06 | Chousuke | Licenser: Ruby still had broken strings in 1.8; how does that count as "just working" ;P |
| 11:06 | Licenser | at least ruby, last time I checked was a programming language, but let me fire up IRB and see if it starts to play songs but I think it will still be a programming language |
| 11:07 | Licenser | Chousuke: it was ruby's goal and in a lot of cases it did, now we, when going for performance over promotion, are moving knowingly and willingly away from a it just works |
| 11:07 | Licenser | cemerick: nope not playing songs, still a programming language |
| 11:08 | Licenser | but that aside, yes all of them are totally relevant. In the end if a programming language 'does not sell' it is not worth squat |
| 11:08 | Chousuke | Licenser: Except it'll still just work in the vast majority of use cases :/ |
| 11:09 | Licenser | well I think we won't know in how many cases it will not just work. |
| 11:10 | Licenser | point is, when people get a odd exception (and sadly clojures are not very expressive) they'll be confused like hell |
| 11:10 | technomancy | that was 39% of "data analysis / math" |
| 11:10 | Chousuke | Licenser: an Integer Overflow exception is not very odd |
| 11:10 | Licenser | Chousuke: when you don't delcare types it is :P |
| 11:11 | Licenser | if it is statically typed it would be obviouse |
| 11:14 | Chousuke | for the record, I think ! would be a horrible suffix for the faster functions :P |
| 11:14 | Chousuke | it's as if you were mutating the numbers |
| 11:15 | Licenser | well that depends on how you definate ! |
| 11:15 | mmarczyk | for the record, I'd still be fine with prim-add despite liking +! just fine ;-) |
| 11:16 | Licenser | Let me tell you a tale |
| 11:16 | Chousuke | I don't think prim-add is that good either. It works with bigints too doesn't it? |
| 11:16 | Licenser | back when I was at the university I decided to learn some programming languaegs - odd enoguh I know |
| 11:16 | mmarczyk | Chousuke: ah, fast-add than |
| 11:16 | mmarczyk | something modelled on unchecked-add anyway |
| 11:16 | Licenser | the first and most important one I learned well started, was Smaltalk - a I think utterly dead and not used language |
| 11:17 | Chousuke | I don't think Smalltalk is dead, it's just hiding well :P |
| 11:17 | Chousuke | kinda like common lisp |
| 11:17 | Licenser | Not because I liked the concept, or the syntax or the ideas, back then I didn't cared. But because it had nice easy arithmetics. I could just implement RAS without importing classes for BigInt, BigNum or any other library specially for big numbers |
| 11:18 | Licenser | now I did not learn Java, even so I could have done the same, or other languages, I found Smaltalk did that and weeeh I was happy |
| 11:18 | Licenser | and I kind of want people to have the same happy feeling when they start clojure, that things just work when they write simple code and let experts worry for performance if it matters |
| 11:18 | rhickey | there are also people forced out of using languages they love because they aren't fast enough, and end up using C/Java |
| 11:19 | Licenser | but seriousely we need the fresh blood and everything that icks them is a bad move in my eyes, they should be given cookies, petted on the head and cared for, not scared off with people prim-add |
| 11:19 | Chousuke | so if we went with non-fast math by default, then what exactly would it require to be fast? |
| 11:19 | mmarczyk | rhickey: if there is an actual possibility of having a set of fast-add etc. operators, this shouldn't be the case here even without + defaulting to the new math behaviour, right...? |
| 11:20 | Licenser | rhickey: don't get me wrong, I don't say lets be slow but as I understand the tradeoff is 'it just works' vs 'it is just fast' right? In both cases everything is possible if 'it just works' we still can make things exactly as fast as 'it is just fast' just with extra effort for that code, and if we go for 'it is just fast' we still can write the tings that not just work any more just again with extra effort on that code right? |
| 11:21 | mmarczyk | anyway, I guess if + does default to fast, but there is a very clear path to safe, I'd just use the latter when unsure and be perfectly happy... |
| 11:21 | clojurebot | add-classpath is Fraught with Peril! |
| 11:21 | rhickey | mmarczyk: well, it's a case of how much work is it to be fast. If it is too much work, or too difficult to get right enough to be actually fast, then it won't be perceived as fast |
| 11:21 | Licenser | As I understand the question is not simple or fast but what should be the 'default' behaviour |
| 11:22 | Licenser | what about a (fast) macro |
| 11:22 | rhickey | Licenser: there are many many programs that will 'just work' without ever creating a BigInteger |
| 11:22 | mmarczyk | rhickey: but if it is too much work or too difficult to avoid funky exceptions, than I have a feeling it won't be perceived as "safe", even if it technically is |
| 11:22 | Licenser | it is crazy but you could write (fast (defn bla [x y] (+ a b)) |
| 11:22 | cemerick | yeouch |
| 11:22 | Licenser | rhickey: I know many many will but some will not, and 'just works' is a thing that either is or not 'it just works somethimes' is not 'it just works' |
| 11:23 | rhickey | mmarczyk: yes far less safe things, like Java will be used instead |
| 11:23 | cemerick | Licenser: for some, being fast is their version of "just works" |
| 11:23 | lpetit | I was wrong in my ml post. Having clojure throw an exception when there is an overflow will still preserve my data. So I'm OK with the suggestions. Java, in the other hand, will silently corrupt my data, giving me a false sense of security ( System.out.println(2 * Integer.MAX_VALUE) returns -2, for the record ) |
| 11:23 | rhickey | cemerick: true also, performance as part of the acceptance criteria |
| 11:23 | Licenser | so what is about the deal with a fast macro - that would just work in both cases |
| 11:24 | Chousuke | and with the fast functions, you'd still be able to have "just works" math by using biginteger literals, right? |
| 11:24 | Chousuke | so (+ n 10N) will "just work"? |
| 11:24 | rhickey | fast macro etc definitely not going to happen |
| 11:24 | Chousuke | no matter what n is |
| 11:24 | Licenser | okay was just an idea |
| 11:24 | mmarczyk | rhickey: actually that's possible (though ridiculous), another possibility is, say, Ruby |
| 11:24 | Chousuke | and functions that do (+ n m) will just work as long as either n or m is a bigint |
| 11:25 | mmarczyk | not trying to sound like I understand the implications of all this better than I actually do, by the way, just trying to share what I'm worried about |
| 11:25 | qbg | With regards to the bigint issue, why not have a piece of metadata that you can put on a function definition that will enable aggressive use of primitives? |
| 11:25 | Licenser | qbg: I think that is the same as the fast macro |
| 11:26 | mmarczyk | I'll be happy to be put at my ease by an excellent story (a new one or possibly the current one at a new level of my comprehension) |
| 11:26 | Licenser | mmarczyk: one upon a time there was a cookie, this cookie was laying and the desc and then, oh horror a human came and eat it untill it was eaten. |
| 11:27 | Chousuke | :P |
| 11:27 | lpetit | Licenser: ^^^^ (that is, it works in both cases, if you consider the goal of data integrity) |
| 11:27 | mmarczyk | Licenser: I love the style, though I honestly can't figure out what you mean by that ;-) |
| 11:27 | Licenser | mmarczyk: I'm hungry |
| 11:29 | Licenser | hmm rhickey don't get me wrong I'm all for fast, but I think it might annoy people who are new if they have to learn an extra layer of functions if they want to make things always work. |
| 11:30 | AWizzArd | Let's say I have a (defrecord Foo [a b c]). Now I have the Symbol 'Foo and the vec [10 20 30]. I would like to create a Foo instance out of those two objects. What is the right approach to do so without using eval? (apply (reolve 'Foo) [10 20 30]) won't work. |
| 11:30 | AWizzArd | reolve ==> resolve |
| 11:30 | mmarczyk | do I understand correctly that (fn fact [n] (if (zero? n) 1 (* n (fact (dec n))))) is broken in prim/num ? |
| 11:31 | qbg | For definitions of "broken" |
| 11:31 | mmarczyk | if so, how does one write a function which computes the n! where the status of n as a primitive is left up to the caller to decide? |
| 11:31 | qbg | The writer coerces n to a bigint? |
| 11:31 | mmarczyk | (trying to understand exactly what is happening...) |
| 11:32 | rhickey | mmarczyk: with that definition: |
| 11:32 | rhickey | user=> (fact 20) |
| 11:32 | rhickey | 2432902008176640000 |
| 11:32 | rhickey | user=> (fact 42) |
| 11:32 | rhickey | java.lang.ArithmeticException: integer overflow (NO_SOURCE_FILE:73) |
| 11:32 | rhickey | user=> (fact 42N) |
| 11:32 | rhickey | 1405006117752879898543142606244511569936384000000000N |
| 11:32 | rhickey | user=> (fact 42.0) |
| 11:32 | rhickey | 1.4050061177528798E51 |
| 11:32 | mmarczyk | hm, I see |
| 11:32 | Licenser | rhickey: so how if I make a clculater that gets a number from a input field |
| 11:33 | Licenser | do the user has to type 42N in there or how do I handle it? |
| 11:33 | lpetit | AWizzArd: I guess you'll have to use reflection, but also to have the fully qualified named of the class ('Foo just gives you the class name, not the package) |
| 11:33 | rhickey | (bigint x) |
| 11:34 | Licenser | but then I'm back at where we started or even worst since it always is a bignum |
| 11:34 | Licenser | so I lost speed, and added complexity which is in my eyes a loose loose situation |
| 11:34 | AWizzArd | apply does not work on new |
| 11:34 | qbg | new is a special form |
| 11:34 | AWizzArd | yes |
| 11:34 | rhickey | Licenser: everyone else lost speed to make you happy in the first place |
| 11:35 | lpetit | AWizzArd: of course. You have to use java API reflection. Maybe there's something in contrib masking it, hmm |
| 11:35 | Chousuke | AWizzArd: Use .newInstance on the class object to create objects dynamically |
| 11:35 | AWizzArd | Licenser: for a calculator bignums are the right objects, better not static longs. |
| 11:36 | hugod | do rationals work with primitives? |
| 11:36 | Licenser | rhickey: my point was there, if the inputs are not entirely controlable chances are good we will resort to casting everything to bignum in the first place - just to be sure |
| 11:36 | AWizzArd | .newInstance sounds good.. (apply #(.newInstance (resolve 'Foo) %&) [10 20 30]) ? |
| 11:36 | Licenser | that is whenever user input happens |
| 11:36 | rhickey | Licenser: and yet another trumped up theoretical example. Your calculator will be whole numbers only? If not, you were out of the integer space already |
| 11:37 | Chousuke | AWizzArd: I think it takes an array of objects as the constructor argument though. |
| 11:37 | Chousuke | AWizzArd: check the docs |
| 11:38 | Licenser | rhickey: it was an example to demonstrate a problem I see, I know it is not the perfect solution but working with inputed (may it be read from a file, database, or whatever) integers and then there will be the question |
| 11:38 | lpetit | ,(#(.newInstance (resolve 'String) %&) ["hello"]) |
| 11:38 | clojurebot | java.lang.IllegalArgumentException: No matching method found: newInstance for class java.lang.Class |
| 11:38 | Chousuke | I suppose a calculator would use BigDecimal |
| 11:39 | Chousuke | lpetit: an array, not a vector |
| 11:39 | Licenser | okay another question how, when we don't force primitives would we have to adjust fact up there to make it use promitevs? |
| 11:39 | Chousuke | lpetit: annnoying, isn't it :( |
| 11:39 | Licenser | (fn ^:static fact ^long [^long n] (if (zero? n) (long 1) (* n (fact (dec n))))) like that? |
| 11:41 | qbg | What about boxing a long as a FastBigint (or something similar) when passing a primitive long to an IFn? |
| 11:43 | mmarczyk | rhickey: tbh, asking for elaborate examples of code which breaks/benefits significantly is a bit much at this stage... |
| 11:43 | AWizzArd | Seems that .newInstances takes no args at all. |
| 11:43 | lpetit | Chousuke: more annoying is that you must first get the list of constructors and find the good one, also ... |
| 11:45 | cemerick | rhickey: there's that island dynamic playing out in real time http://www.haskell.org/pipermail/haskell-cafe/2010-June/079044.html |
| 11:45 | AWizzArd | rhickey: would it make sense to teach apply to do (apply SomeClass [10 20 30]) ==> (SomeClass. 10 20 30) ? |
| 11:46 | mmarczyk | cemerick: amazing link |
| 11:46 | lpetit | AWizzArd: clojure.lang.Reflector to the rescue: ,(clojure.lang.Reflector/invokeConstructor (resolve 'String) (to-array ["lolo"])) |
| 11:46 | lpetit | ,(clojure.lang.Reflector/invokeConstructor (resolve 'String) (to-array ["lolo"])) |
| 11:46 | clojurebot | "lolo" |
| 11:46 | mmarczyk | http://www.xent.com/pipermail/fork/Week-of-Mon-20070219/044101.html |
| 11:46 | mmarczyk | ^ reminds me of this one |
| 11:48 | cemerick | mmarczyk: yours is a helluva lot stranger in the first 4 lines! :-P |
| 11:48 | AWizzArd | That works, but it is very inefficient. |
| 11:50 | mmarczyk | cemerick: yeah, it's fantastic :-) |
| 11:50 | rhickey | seriously though, I'm looking for appendable suffixes for either promoting or throwing ops |
| 11:51 | mmarczyk | maybe a sigil of some sort? +&, +: ? |
| 11:51 | qbg | What about %? |
| 11:51 | qbg | (For throwing ops) |
| 11:52 | mmarczyk | +_ for add which stays on the level it starts at... |
| 11:52 | qbg | (probably best as a prefix?) |
| 11:53 | Licenser | I think pre/suffixing both would be the worst to do, leave one as the default and the other as a suffix |
| 11:53 | mmarczyk | incidentally, what happens when the call goes through the Var? |
| 11:53 | rhickey | mmarczyk: which call? |
| 11:54 | mmarczyk | #'+ could be an unpleasant way of saying "slow down, mate" |
| 11:54 | mmarczyk | rhickey: (#'+ 1 2) |
| 11:54 | rhickey | no, same semantics |
| 11:54 | mmarczyk | ah, I see |
| 11:54 | rhickey | not fast, but same operation, will throw on overflow or promote whatever wins as the default |
| 11:55 | Licenser | again what would be the extra effort to make things fast if we'd stay with promoting by default, I'm not entirely sure how the syntax had to look for that :( |
| 11:55 | mmarczyk | hm, I'm reading into the proposal more and more and sort of beginning to see the wisdom of the 'fast' side... not totally sold on it yet, but this goes to show the amount of trust Clojure's design has accumulated with me thus far -- I actually expect to be wrong when feeling uneasy :-) |
| 11:56 | Licenser | and at what level is it decided, argument level function level or return value level? or all of them |
| 11:57 | qbg | mmarczyk: Same here; I like the idea of the num branch, it just feels like I'm losing an old friend... |
| 11:57 | mmarczyk | qbg: fortunately the friend is a phoenix and his new plumage might be even more splendid :-) |
| 11:57 | Licenser | even I do like it I'm just not sure if it's worth it entirely and if there isn't a better way |
| 11:58 | mmarczyk | p+ / +p for "promoting +" ? |
| 11:58 | arkh | java interop question - this works '(.. (Thread. fnname) start)' but how do I do the equivalent of this (.. (Thread. fnname arg1) start) ? |
| 11:58 | Licenser | +^ ? |
| 11:59 | mmarczyk | ,(read-string "+^") |
| 11:59 | clojurebot | + |
| 11:59 | mmarczyk | Licenser: so no go... |
| 11:59 | Licenser | yuck why that? |
| 11:59 | cemerick | arkh: not entirely sure what you're trying to do, but perhaps (Thread. (partial fnname arg1)) will do. |
| 11:59 | mmarczyk | I guess the symbol ends before ^, which is not a symbol char |
| 11:59 | cemerick | arkh: you really want to be using a future or agent though...creating threads is usually unnecessary. |
| 12:00 | mmarczyk | arkh: (-> arg1 fnname Thread. .start) or sth? |
| 12:00 | Licenser | but I'd still like to see what the verbosity trade of of making a function fast would be when using promoting by default |
| 12:00 | mmarczyk | Licenser: me too, absolutely |
| 12:01 | arkh | cemerick: I was scolded for using agents and futures in ways they weren't meant to be used ; ) I have a function I want to kick off in another thread but don't care about it's return value |
| 12:01 | mmarczyk | ,(macroexpand '(-> arg1 fname Thread. .start)) |
| 12:01 | clojurebot | (. (clojure.core/-> (clojure.core/-> arg1 fname) Thread.) start) |
| 12:02 | cemerick | arkh: I abuse futures for that :-) |
| 12:02 | mmarczyk | ah, won't work of course... try it with macroexpand-all (from contrib) maybe at your repl |
| 12:02 | Licenser | (doc send-off) |
| 12:02 | clojurebot | "([a f & args]); Dispatch a potentially blocking action to an agent. Returns the agent immediately. Subsequently, in a separate thread, the state of the agent will be set to the value of: (apply action-fn state-of-agent args)" |
| 12:02 | hoeck | arkh: (.start (Thread. #(fnname arg1 ... argn))) |
| 12:02 | rhickey | what about +' dec' *' ? |
| 12:02 | arkh | mmarczyk: looking into that ... otherwise I'll abuse futures |
| 12:03 | AWizzArd | Sounds like Ocaml... |
| 12:03 | Licenser | rhickey: that doesn't look bad |
| 12:03 | arkh | hoeck: I had tried that but thought it didn't work ... maybe it was my code : ( |
| 12:03 | rhickey | AWizzArd: what does? |
| 12:03 | qbg | rhickey: That looks good |
| 12:03 | mmarczyk | rhickey: +' looks good to me |
| 12:03 | AWizzArd | Different operators that basically do the same thing on diferent types. |
| 12:03 | mmarczyk | rhickey: which variant would you use it for? |
| 12:04 | AWizzArd | But that seems to be the price for very fast execution. |
| 12:04 | Licenser | AWizzArd: it is not about doing different things but using some different logic for the same types |
| 12:04 | rhickey | cemerick: where's the syntax expansion? |
| 12:04 | hoeck | rhickey: please not, how should this be distinguished from a plus and a real quote? |
| 12:05 | cemerick | rhickey: ok, right, just another idiom |
| 12:05 | mmarczyk | rhickey: btw, there's no possibility of doing the equivalent of Haskell's (Num a) => a -> ..., is there...? |
| 12:05 | Licenser | a missing space? |
| 12:05 | rhickey | hoeck: no spaces |
| 12:05 | rhickey | ' would be allowed as a constituent character |
| 12:05 | AWizzArd | maybe add/plus/mul/multiply |
| 12:05 | mmarczyk | hm, wait, that definitely needs rephrasing :-P |
| 12:06 | rhickey | 'fred's => fred's , on my machine |
| 12:06 | cemerick | Still, more otherwise-meaningless chars for core functionality. |
| 12:06 | Licenser | ,(type 'fred's) |
| 12:06 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: core$type |
| 12:06 | rhickey | cemerick: it's not anything more than allowing those chars in names, not special, you can use it yourself |
| 12:06 | AWizzArd | ['fred's] |
| 12:07 | Licenser | wow is clojurebot slow today? |
| 12:07 | Licenser | $eval 'fred's |
| 12:07 | sexpbot | => fred |
| 12:07 | AWizzArd | ,['fred's] |
| 12:07 | clojurebot | [fred s] |
| 12:07 | Licenser | or is it me that is slow |
| 12:07 | cemerick | rhickey: I get it. I guess I'd just rather have the language have a settled default than trying to satisfy all constituencies maximally. |
| 12:08 | mmarczyk | I'm used to ' -- "prime" -- signifying alternative semantics when used at top level... |
| 12:08 | rhickey | cemerick: there will be a default. These functions will still need to exist, and have names, and be easy to change code written in terms of the default into these names |
| 12:08 | Licenser | I think allowing ' is cool since you can do nice mathematical notation with that f f' f'' ... |
| 12:09 | hoeck | ' is such a ubiquitious character in lisp code |
| 12:09 | rhickey | mmarczyk: alternate semantics at top level in which lang? |
| 12:09 | mmarczyk | rhickey: Haskell, e.g. foldl' |
| 12:09 | rhickey | hoeck: not in non-macro clojure code |
| 12:09 | mmarczyk | which is strict, vs. the lazy foldl |
| 12:09 | AWizzArd | +2 *2 |
| 12:10 | qbg | If +' was for throwing +, then + -> +' would be like assoc -> assoc! for transients |
| 12:11 | mmarczyk | ...which sort of brings us back to +!, which is a no-go only if ! is to be reserved for mutation |
| 12:11 | rhickey | cemerick: else, e.g. people will be catching the exception from + as part of normal program flow of control, or coercing to bigint possibly needlessly |
| 12:11 | hugod | is putting the alternate semantics in different namespaces a non-starter? |
| 12:12 | mmarczyk | the idea with suffixed names for one class of arithmetic ops leaves open the possibility of reversing the choice -- as with #^ vs. ^ -- possibly with an intermediate stage with a third set of names... |
| 12:12 | rhickey | hugod: I think so - what does this code do? (+ x y) ... change ns declaration ... and this: (+ x y) ? |
| 12:12 | mmarczyk | might be useful if "most frequent usage" turns out to be something different to whatever 1.2 will bet on |
| 12:12 | cemerick | rhickey: I'm butting out for now, I don't grok all the issues yet. The presence of multiple mathematical fns seems mildly frustrating on spec though, and "mere mortals" will absolutely flip. |
| 12:12 | Licenser | we could do a (promoting ) macro :P |
| 12:13 | Licenser | cemerick: ylou ment you promoted yourself above mere mortals? |
| 12:13 | cemerick | same thing? |
| 12:13 | qbg | Why wouldn't a fast macro work, rhickey? |
| 12:13 | mmarczyk | cemerick: that might be a reason to have suffixed functions for the elevated numeric crowd and not for those who aren't concerned :-) |
| 12:14 | rhickey | qbg: no |
| 12:14 | arkh | cemerick: I'm a mere mortal. You can use me as a litmus test ; ) |
| 12:14 | rhickey | qbg: oh, why |
| 12:14 | liebke | rhickey: I cleaned up the numeric types in Incanter's tests, and argos with the prim branch seems happy (although the latest version of clojure.contrib.jmx seems to have a bad test). Let me know if you need me to fix anything else. |
| 12:14 | cemerick | arkh: *no one* in #clojure is a mere mortal, by definition |
| 12:14 | rhickey | qbg: because it is too contexty, and what does it mean? |
| 12:14 | rhickey | liebke: what bad test, did you pull contrib? |
| 12:14 | arkh | cemerick: if that were only true! I won't delude myself :D |
| 12:15 | cemerick | The guy who needs to calculate interest and shove it back into a DB via hibernate is the one I'm thinking of. |
| 12:15 | Licenser | cemerick: depends on what * function you used the promoting one or the non promoting one, if you used the non promoting one you might get a Human Overflow Exception |
| 12:15 | rhickey | qbg: I don't want the compiler to have math modes, these are just ordinary function calls |
| 12:15 | hugod | rhickey: I think if you are writing code that you want to rely on one behaviour or the other, then being able to decide that at the namespace level, rather than checking every use of every operator, is a win |
| 12:15 | liebke | I did pull contrib. the test for jmx/guess-attribute-typename is calling (Long/valueOf 10) instead of (Long/valueOf "10") |
| 12:17 | Licenser | hugod: I'd say on function or expression level not on namespace level otherwise this will mean you'll get often 2 namespaces |
| 12:17 | rhickey | liebke: should be (Long/valueOf (long 10)), my bad |
| 12:17 | rhickey | liebke: only tested with num |
| 12:17 | liebke | rhickey: ah cool |
| 12:17 | rhickey | where that works |
| 12:17 | Licenser | http://gist.github.com/442044 <- the second version, would that be what it would take to make a function fast in a otherwise promoting environment? |
| 12:18 | hugod | Licenser: get 2 namespaces? |
| 12:18 | qbg | rhickey: In my idea of a fast macro, code inside its lexical scope would have contagious primitive math, but fair enough |
| 12:18 | Licenser | hugod: yes one for functions that require promoting and one for functions that do not |
| 12:19 | dnolen | If people leave over lacking autopromotion of BigInt they weren't that invested anyway. |
| 12:19 | cemerick | dnolen: that's my intuition as well |
| 12:19 | mmarczyk | dnolen: you could turn that around, you know |
| 12:20 | mmarczyk | "if people leave over having to write a lil' macro to add hints" etc. |
| 12:20 | rhickey | liebke: fixed |
| 12:20 | dnolen | mmarcyzk: not true, we're meeting in the middle |
| 12:20 | mmarczyk | dnolen: hopefully |
| 12:20 | dnolen | marczyk: BigInt folk are conceding a tiny amount of ground. |
| 12:20 | liebke | rhickey: great, I'm re-testing |
| 12:20 | mmarczyk | dnolen: the present discussion would be about where the middle is and how useful it is |
| 12:20 | hugod | Licenser: so you are worried about my-lib-promoting/some-fn vs my-lib-nonpromoting/some-fn? |
| 12:20 | Licenser | hugod: yap |
| 12:21 | dnolen | mmarczyk: while bring fast math people to the party. |
| 12:21 | Licenser | I would understand if you have a promoting-fn and a nonpromoting-fn |
| 12:21 | mmarczyk | dnolen: I wonder if that is the case. |
| 12:21 | Licenser | perhaps with a idomatic syntax |
| 12:21 | Licenser | the same that +, -, * ... shoud use |
| 12:22 | dnolen | mmarczyk: I'm not going anywhere if this stuff doesn't make it in, but it does seem to me future work in pure Clojure suffers. |
| 12:23 | Licenser | dnolen: I think noone wants fast math to not be implemented, I think the discussion going on is which mode should be default and which one explict |
| 12:23 | dnolen | Licenser: no modes |
| 12:24 | mmarczyk | dnolen: so you'd rather there were no auto-promoting ops at all? whoever might conceivably bump into bigint space should stay on that side all the time? |
| 12:24 | Licenser | dnolen: with default mode I mean, what will happen without extra effort and what will happen only with extra effort |
| 12:24 | qbg | If one really wants to, they could in theory write a (promoting ...) macro if bigints all the time don't work for thme. |
| 12:24 | qbg | *them |
| 12:25 | hugod | Licenser: I wouldn't expect too many cases where a lib would provide promoting and non-promoting versions - and you could still qualify the symbols to provide promoting-fn and non-promoting-fn |
| 12:25 | Licenser | hugod: no but I can see many cases where some functions are promoting and others are not |
| 12:25 | dnolen | Licenser: the current system creates a lot of incidental complexity. modes just move it somewhere else. |
| 12:26 | dnolen | mmarczyk: people working with BigInts are working with BigInts. people working with primitive math, working with primitive math. num works seems to address that just fine. |
| 12:26 | rhickey | +#, -#, dec# ? the # seems to dominate the op a bit |
| 12:26 | Licenser | dnolen: again you missunderstood me, with modes I mean, what is the behaviour you get 'for free' and what is the behavior you have to add some extra code |
| 12:26 | Licenser | I don't mean modes as in switching |
| 12:26 | mmarczyk | dnolen: they (modes) might also make it smaller if instead of adding a pile of hints all over the place you can just pick your operators wisely |
| 12:26 | Licenser | rhickey: dominating isn't bad if the thing is important to notice and to know about |
| 12:26 | rhickey | Licenser: it is if you can;t see the algorithm through the #s |
| 12:27 | mmarczyk | rhickey: might conflict with # = autogensym |
| 12:27 | qbg | If integer literals could be either longs or bigints based on what is the right thing at the time (no suffixes needed), then the current approach in num could be nice |
| 12:27 | Licenser | rhickey: true |
| 12:27 | mmarczyk | though "no autogensyms for +" is of course an option |
| 12:27 | mmarczyk | rhickey: agreed |
| 12:27 | rhickey | mmarczyk: yes, would have to work that out |
| 12:27 | rhickey | mmarczyk: without special rules like that :) |
| 12:28 | mmarczyk | :-) |
| 12:28 | Chousuke | people'll look at ' and think it's a quote though |
| 12:28 | Licenser | I don't think if it s in the end |
| 12:29 | rhickey | Chousuke: really? - (+' (fib (dec' n)) (fib (-' n 2))) |
| 12:29 | Chousuke | I suppose it's just me. |
| 12:29 | Licenser | (+! (fib (dec! n)) (fib (-! n 2))) |
| 12:29 | Chousuke | and allowing ' in symbols would be nice anyway. |
| 12:30 | mmarczyk | (+_ (fib (dec_ n)) (fib (-_ n 2))) <- just testing... is this too ugly? |
| 12:30 | mmarczyk | but +' is nice |
| 12:30 | qbg | (%+ (fib (%dec n)) (fib (%- n 2))) |
| 12:30 | rhickey | or +`, -`, dec` etc |
| 12:30 | Licenser | % is guly it looks too much like # |
| 12:30 | mmarczyk | fits in with math practice etc. |
| 12:30 | Licenser | nah ` is to hard to type |
| 12:30 | Licenser | it makes horrible things in german keyboards :( |
| 12:30 | rhickey | Licenser: ah |
| 12:31 | mmarczyk | %+ isn't bad to my eye |
| 12:31 | Licenser | it wants to do something to the next character |
| 12:31 | mmarczyk | I've wanted to write a -%> macro a couple of times, would be nice to see this work |
| 12:31 | Licenser | I wanted to write @-->--- functions |
| 12:31 | qbg | I'm just use to %primitive-function style from CL |
| 12:32 | mmarczyk | Licenser: ah, but you can do that already ;-) |
| 12:32 | Licenser | I know |
| 12:32 | Licenser | I also wrote a <3 function |
| 12:42 | Licenser | so where are we at |
| 12:45 | qbg | Long literals have been ruled out? |
| 12:46 | rhickey | stay tuned |
| 12:47 | qbg | num branch + long literals + fast bigints by default would be more than sufficient for me |
| 13:43 | mmarczyk | http://disclojure.org/ has some rather amusing entries this time round :-) |
| 13:43 | mmarczyk | "Every time you mention Scala and Haskell in the same sentence, a Java developer thumbs through a Clojure book at Borders." |
| 13:58 | nickik | Whats the best way to go from here {:a 1 :b 2} to here {:a 1 :b 3}. Cant find the right function. |
| 13:59 | hoeck | ,(update-in {:a 1 :b 2} [:b] inc) |
| 13:59 | clojurebot | {:a 1, :b 3} |
| 14:40 | raek | I have made a patch that fixes the broken clojure.java.io/output-stream implementation for java.net.Socket... |
| 14:40 | raek | http://github.com/raek/clojure/commit/797d2ff22cd8a52707d52efb6a680d5ee0a788f1 |
| 14:41 | raek | the bug was probably just a typo or something |
| 14:41 | raek | what can I do with this now? |
| 14:44 | TeXnomancy | raek: you need to sign a contributor's agreement; see http://clojure.org/contributing |
| 14:46 | raek | done that today :) |
| 14:46 | raek | but the mail takes some time |
| 14:46 | TeXnomancy | gotta wait then. =\ |
| 14:47 | MrHus | MrHus: reak: http://github.com/guides/pull-requests you could try this. |
| 14:47 | TeXnomancy | you can create a ticket, but patches won't get applied till it's in. |
| 14:47 | TeXnomancy | MrHus: rich doesn't like pull requests. |
| 14:48 | MrHus | I can imagine when getting about a 1000 a day. |
| 16:25 | rhickey | http://github.com/richhickey/clojure/commit/c79d28775e06b196ae1426f6c1446d00b621d2e1 |
| 16:45 | Licenser | rhickey: nice :) |
| 16:48 | Licenser | I like the ' syntax |
| 16:48 | rhickey | Updated: https://www.assembla.com/wiki/show/b4-TTcvBSr3RAZeJe5aVNr/Enhanced_Primitive_Support |
| 16:53 | Licenser | rhickey: is there a branch that combines the changes described in the link? |
| 16:53 | rhickey | http://github.com/richhickey/clojure/commit/c79d28775e06b196ae1426f6c1446d00b621d2e1 |
| 16:53 | Licenser | ah okay that one combines things :) |
| 16:54 | hoeck | Licenser_: now we can use v, v' and v'' in our big physics simulations :P |
| 16:54 | islon | is there a simplified sintatic sugar to (def #^{:private true} x 1} in clojure 1.2? |
| 16:55 | hoeck | and that trailing ' is not that bad |
| 16:55 | Licenser | hoeck: yay! |
| 16:56 | hoeck | islon: (def ^:private x 1) |
| 16:56 | dnolen | rhickey: nice! even looks like there a perf boost for primitive long arithmetic with those changes? |
| 16:56 | hoeck | islon: at least in that branch that rhickey just posted |
| 16:56 | rhickey | dnolen: everything is better |
| 16:57 | dnolen | rhickey: good stuff. |
| 16:57 | islon | thanks, i'll try |
| 16:58 | rhickey | dnolen: and if escape analysis ever arrives, it could get better still |
| 16:58 | rhickey | for the casual cases |
| 17:08 | Licenser | okay I feel stupid I fail to clone http://github.com/richhickey/clojure/commit/c79d28775e06b196ae1426f6c1446d00b621d2e1 :( |
| 17:09 | Licenser | dnolen: silly question since you seem to have managed, how did you fetch the right version of clojure? :( |
| 17:09 | hoeck | Licenser: its in the equal branch |
| 17:10 | Licenser | :D |
| 17:10 | Licenser | hoeck: you are my hero! |
| 17:11 | hoeck | :/ |
| 17:11 | Licenser | yuck |
| 17:32 | mmarczyk | rhickey: the new equal looks fantastic, hurray! :-) |
| 17:45 | mmarczyk | I'll be doing the same in a minute :-) |
| 17:45 | Licenser | I think there is a regression in the commit: |
| 17:45 | Licenser | user=> ((fn [x] (*' x x)) 2) |
| 17:45 | Licenser | java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number (NO_SOURCE_FILE:0) |
| 17:46 | mmarczyk | ouch, this would mean that *' x is read as * 'x |
| 17:46 | mmarczyk | as it used to be |
| 17:46 | Licenser | yap it is |
| 17:46 | Licenser | that is badish |
| 17:47 | Licenser | user=> (macroexpand '(*' 1 1)) |
| 17:47 | Licenser | (* (quote 1) 1) |
| 17:47 | rhickey | Licenser: seems like you have a bad build, that's 4 here |
| 17:47 | Licenser | hmm |
| 17:48 | rhickey | Licenser: you building with ant? |
| 17:48 | Licenser | rhickey: yap I suck :P sorry |
| 17:48 | Licenser | I forgot to checkout equal as branch |
| 17:49 | serp_ | are there any working guides for how to use emacs with slime, swank and clojure? |
| 17:52 | tcrayford | I think there's a guide around for lein |
| 17:52 | tcrayford | which is what you should be using anyway |
| 17:52 | dnolen | serp_: some tips on assembla |
| 17:53 | lancepantz | serp_: yeah, assembla has a guide i believe |
| 17:53 | Licenser | ah now it works nice! |
| 17:53 | tcrayford | assembla's guide doesn't cover slime iirc |
| 17:54 | dnolen | tcrayford: it does |
| 17:54 | tcrayford | my bad then |
| 17:54 | serp_ | http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Emacs <- this one? |
| 17:55 | alpheus | This worked for me: http://github.com/jochu/swank-clojure |
| 17:55 | dnolen | serp_: yup |
| 17:56 | serp_ | I'll give it a try, thanks |
| 18:01 | mmarczyk | argh... anybody else having swank woes after moving to equal? |
| 18:03 | dnolen | mmarczyk: swank has a bug that prim triggers |
| 18:03 | mmarczyk | dnolen: oh bother :-( |
| 18:03 | dnolen | mmarczyk: swank-clojure HEAD is patched |
| 18:03 | dnolen | mmarczyk: do you use lein? |
| 18:03 | mmarczyk | dnolen: I see, thanks, will pull now |
| 18:03 | mmarczyk | not for setting up repls |
| 18:04 | mmarczyk | but I normally use HEAD of swank, just haven't bothered pulling in a while now |
| 18:07 | mmarczyk | also, (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec n) (* r n))))) throws on (fact 40) -- that's with *, not *' |
| 18:07 | KirinDave | [n n ? |
| 18:07 | mmarczyk | KirinDave: ? |
| 18:08 | Licenser | mmarczyk: not for me |
| 18:08 | Licenser | I just tested that |
| 18:08 | Licenser | could do (fact 42) |
| 18:08 | mmarczyk | Licenser: really? let me check again |
| 18:08 | KirinDave | mmarczyk: Why two n's? |
| 18:08 | Licenser | wait not exactly for that code |
| 18:09 | dnolen | KirinDave: he's playing around with the new numerics stuff |
| 18:09 | mmarczyk | KirinDave: left one is the local name, right one is the initial value (taken from the parameter to fact called n) |
| 18:09 | KirinDave | Ah |
| 18:09 | Licenser | you're right it trhows here too - very dod |
| 18:10 | Licenser | mmarczyk: but I can't find where it comes from |
| 18:10 | mmarczyk | Licenser: I wonder if loop/recur needs to know ahead-of-time whether it's going to be dealing with primitives or objects |
| 18:10 | Licenser | hmmm |
| 18:10 | mmarczyk | that would be the case with a local variable in Java, right? |
| 18:11 | Licenser | mmarczyk: but oddly enoguh for the simple version of fact it works |
| 18:11 | SirNick | what's the best way to set the character encoding with Ring or Compojure? |
| 18:11 | mmarczyk | incidentally, (fact 40N) doesn't work here either |
| 18:11 | mmarczyk | Licenser: well the simple version has the function call boundary |
| 18:11 | mmarczyk | which might present an opportunity for boxing |
| 18:11 | rhickey | mmarczyk: that's a broken definition, always returns one |
| 18:12 | Licenser | $((fn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec n) (* r n))))) 42) |
| 18:12 | mmarczyk | rhickey: ah, the middle 1 should be r |
| 18:12 | Licenser | ,((fn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec n) (* r n))))) 42) |
| 18:12 | clojurebot | 1 |
| 18:12 | rhickey | the throw is because you have a primitive accumulator r |
| 18:12 | Licenser | yuck |
| 18:12 | Licenser | that's bad |
| 18:12 | mmarczyk | rhickey: the 'old' arithmetic had no problem with it, but I suppose the r would have been a big-I Integer initially, right? |
| 18:13 | rhickey | mmarczyk: no, was boxed, now primitive |
| 18:13 | rhickey | turn on *warn-on-reflection* |
| 18:13 | mmarczyk | that's what I meant, I think |
| 18:13 | rhickey | "recur arg for primitive local: r must be matching primitive, had: java.lang.Number, needed: long" |
| 18:13 | mmarczyk | boxed on master, primitive on equal |
| 18:14 | mmarczyk | right |
| 18:14 | rhickey | you can get boxed accumulator by doing (num 1) |
| 18:14 | mmarczyk | just tried hinting with ^Object which doesn't work... |
| 18:14 | briancarper | SirNick: On responses? Add a header to the response, {:headers {"Content-Type" "text/html;charset=UTF-8"}} |
| 18:14 | Licenser | hmm hmm is there a way to make it just work? |
| 18:15 | rhickey | (defn fact [n] (loop [n n r (num 1)] (if (zero? n) r (recur (dec n) (* r n))))) |
| 18:15 | SirNick | briancarper: Can I set that up to be default? |
| 18:15 | mmarczyk | rhickey: ah, great, thanks! |
| 18:15 | Licenser | I wonder why * does not work correctly BigInt * int should become a bigint shouldn't it? |
| 18:16 | briancarper | SirNick: Yeah, wrap all of your routes with middleware that adds the headers. I think that's the standard way to do it. |
| 18:16 | mmarczyk | not sure if I prefer primitive as default, but I can see myself being perfectly happy with (num ...) |
| 18:17 | Licenser | Do I have to go back to my rant about how confusing this will be to newcomers? |
| 18:17 | SirNick | briancarper: Alright, so how do I handle requests? Or will that work by default by setting the response encoding? |
| 18:17 | Licenser | I mean even mmarczyk was confused |
| 18:18 | Licenser | and why does (* 1 1000000000000000000N) work but not in the loop? |
| 18:18 | Licenser | ah because r grows too big? |
| 18:18 | mmarczyk | yeah |
| 18:19 | mmarczyk | thanks for your highly flattering use of 'even' |
| 18:19 | Licenser | the problem is not that * overflows but that the loop call gets confused with gettinga BigInteger Number |
| 18:19 | Licenser | mmarczyk: don't take it personal I was about to write even I was confused but I figured that my usual arrogance won't help my case to get this changed :P |
| 18:20 | Licenser | ;) |
| 18:20 | mmarczyk | :-) |
| 18:20 | briancarper | SirNick: Honestly not sure how it's handled in requests. I've never done anything special to set anything up. |
| 18:21 | mmarczyk | briancarper: I've been meaning to ask -- how's your RPG project coming along? |
| 18:21 | Licenser | is there any way in the world that the compiler can 'know' what we mean? |
| 18:21 | Licenser | I mean the 1 part, when we mean a primitive and when we mean no primitive? |
| 18:21 | mmarczyk | Licenser: we can tell it :-) |
| 18:21 | briancarper | SirNick: One other potential place to set enoding is in the JVM opts, -Dfile.encoding=UTF8 |
| 18:22 | Licenser | mmarczyk: yes but I opt again for 'it just works' as opposed to 'it works fasts if it does and throws odd and totally confusing exceptions if it does not' |
| 18:22 | mmarczyk | Licenser: apparently Rich has reversed the current situation with loop/recur... you need to hint to get boxing |
| 18:22 | Licenser | ava.lang.IllegalArgumentException: Value out of range for long: 158905670470170624000 does not exactly tell you 'you were using primitves you ape' but rather 'OMFG YOU'RE GOING TO DIE' |
| 18:23 | Licenser | this is kind of a chrossorad and we need to decide which path to follow and I really hope we concider this very very carefully |
| 18:24 | briancarper | mmarczyk: My RPG has been on hold until Clojure 1.2 is released, I was too distracted porting a bunch of other code. But I plan to pick it up again very soon. |
| 18:24 | mmarczyk | briancarper: cool, I really enjoyed that post and the pixel art is cute :-) |
| 18:24 | Licenser | mmarczyk: for all bindings it seems |
| 18:24 | Licenser | let does the same |
| 18:25 | Licenser | okay now a very crazy suggestion how about adding let' and loop'? |
| 18:25 | Licenser | I know I get shot for this sugestion but it would be, as crazy as it is, a logical way to go |
| 18:25 | Chousuke | nooooooooo |
| 18:25 | Licenser | whenever we have non NumberStack behavior we have a ' at the end |
| 18:25 | tomoj | bang |
| 18:26 | briancarper | mmarczyk: Thanks :) |
| 18:26 | Licenser | how about '' a quote that does primitves? |
| 18:26 | Licenser | but seriousely this is evil, it will confuse the hell out of everyone but 5 people |
| 18:27 | Licenser | well 7 since rhickey just told mmarczyk and me |
| 18:27 | Licenser | we could make loop create overloaded jump points for different kinds of objects? longs and Numbers? |
| 18:28 | Licenser | not sure if that is technically possible |
| 18:28 | mmarczyk | Licenser: ...3 of whom are the three-headed dragon who is a thousand years old and lately amuses him/herself by writing Clojure instead of casting spells |
| 18:28 | Licenser | well wizard spells get boring after you memorized all 9th level ones you know? |
| 18:28 | mmarczyk | Licenser: exactly! :-) |
| 18:28 | Licenser | and the other two are rhickey and his shadow I guess |
| 18:29 | mmarczyk | (whew, safer waters again ;-)) |
| 18:29 | defn | hey all |
| 18:32 | Licenser | hi defn |
| 18:32 | Licenser | join the fun of talking about clojure math |
| 18:33 | dnolen | mmm, colocated Mac Mini 4gb RAM running 1.2 equals branch makes a sweet 2010 64bit Lisp Machine |
| 18:34 | mmarczyk | Licenser: rhickey: took the liberty of posting about the primitive-by-default loop locals to the ggroup thread |
| 18:34 | mmarczyk | defn: hi :-) |
| 18:35 | Licenser | mmarczyk: oi, as I did |
| 18:35 | Licenser | but I added 5 lines speach to it :P |
| 18:35 | mmarczyk | Licenser: aye, just noticed :-) |
| 18:35 | Licenser | but you were a minute faster :P |
| 18:35 | Licenser | I think rhickey wil hate us soon |
| 18:36 | SirNick | briancarper: Alright I'll see how that goes, thanks for the help |
| 18:43 | AWizzArd | rhickey: would it be possible to add some more branches to build.clojure.org? |
| 19:06 | mmarczyk | http://gist.github.com/444341 |
| 19:07 | mmarczyk | ^ how come the first (non-static, non-hinted) version seems to be faster than the second (static, hinted) version? |
| 19:09 | Licenser | mmarczyk: found another problem, floats |
| 19:10 | mmarczyk | Licenser: oh? how come? |
| 19:10 | Licenser | http://gist.github.com/444344 |
| 19:10 | Licenser | primitives don't change from one type to another :P |
| 19:12 | mmarczyk | oh, that looks buggish |
| 19:13 | Licenser | mmarczyk: it makes sense in the way it is implemented but it is horrible |
| 19:13 | mmarczyk | yeah, I guess I mean bug-inducing (or sth close) |
| 19:14 | Licenser | *nods* |
| 19:15 | mmarczyk | actually in this case the compiler could conceivably discover that the primitive participates in an arithmetic op with a floating-point literal as the other argument |
| 19:15 | mmarczyk | although if the flonum came from another parameter to the function or a closed-over Var, that wouldn't help |
| 19:17 | mmarczyk | rhickey: any chance of having a (num ...) hint, a (prim ...) hint (boxed vs. unboxed) and defaulting to prim in loop when the compiler can prove that that's alright (because of type hints on the enclosing function's parameters etc., say) and boxed otherwise? |
| 19:19 | mmarczyk | (the etc. encompasses hints on the return type, :tag metadata on Vars participating in arithmetic ops inside the loop's body and whatever else I didn't think of) |
| 19:25 | riddochc | I'm curious, what's an appropriate use for the 'reductions' function? I'm sure it *is* useful, but aside from debugging the use of 'reduce', I'm not sure what sorts of problems I'd apply it to. |
| 19:26 | tcrayford | "ls ~/Projects/clojure | wc -l" => 24 |
| 19:27 | riddochc | tcrayford: It's in the ballpark of my count, too... are you any better at finishing yours than I am? (wouldn't be too hard) |
| 19:29 | mmarczyk | riddochc: for one thing, reductions is lazy |
| 19:30 | mmarczyk | (take 5 (reductions + (range))) |
| 19:30 | tcrayford | riddochc: I don't think *any* of those are anything like finished |
| 19:31 | riddochc | mmarczyk: I suppose reduce can't be lazy, by definition. |
| 19:32 | tcrayford | man lazytest is hella cool |
| 19:32 | mmarczyk | riddochc: Clojure's reduce is a left fold, so it can't be usefully lazy |
| 19:32 | mmarczyk | riddochc: a right fold can be lazy in a lazier language (see Haskell) -- then it can work with infinite sequences |
| 19:33 | Raynes | Right folding in Haskell is insane. |
| 19:33 | Raynes | Insane, I say. Insane. |
| 19:34 | mmarczyk | actually I suppose Clojure might be lazy enough to do some of the lazy foldr stuff, with a little extra effort expended here and there perhaps |
| 19:34 | mmarczyk | Raynes: :-) |
| 19:34 | tcrayford | its funny how many core functions in haskell can be described usefully using fold and foldr |
| 19:35 | Raynes | I've done so much with foldr that I looked for it for a day straight in Clojure until I realized that reduce was the closest thing I could get. |
| 19:35 | AWizzArd | tcrayford: why do you find it funny/surprising? |
| 19:35 | mmarczyk | Raynes: got a good example of an interesting function using scanl? I can't think of one and I know I've seen some... would answer the question about reductions |
| 19:35 | Raynes | That was ages ago. |
| 19:35 | AWizzArd | reduce = fold |
| 19:35 | Raynes | I've never used scanl. I don't even know what it is. |
| 19:35 | Raynes | AWizzArd: I know. |
| 19:35 | mmarczyk | AWizzArd: reduce = left fold |
| 19:35 | tcrayford | AWizzard: just a nice example of how powerful reduce is |
| 19:35 | Raynes | But not a right fold. |
| 19:35 | Licenser | well night people |
| 19:35 | AWizzArd | And reduce is the most basic looping construct. |
| 19:36 | AWizzArd | map and filter are special cases |
| 19:36 | Licenser | mmarczyk: keep the fight up! ;) |
| 19:36 | mmarczyk | Licenser: good night |
| 19:36 | mmarczyk | Licenser: heh :-) |
| 19:36 | AWizzArd | it would be as saying that you find it funny that for-loops are of such big use in C programs |
| 19:36 | Raynes | Night Heinzy. |
| 19:36 | Licenser | Night Raynes |
| 19:36 | tcrayford | I find reduce somewhat annoying to figure out still |
| 19:36 | mmarczyk | Licenser: I know you'll be back here with a flaming sword soon enough :-) |
| 19:36 | AWizzArd | tcrayford: what about for-loops in Java? |
| 19:37 | Licenser | mmarczyk: I'm not here tomorrow so you'll have to take the lead for the day |
| 19:37 | tcrayford | for loops in java are painful as well :( |
| 19:37 | tcrayford | too verbose |
| 19:37 | AWizzArd | ah ok |
| 19:37 | mmarczyk | Licenser: I'm no replacement for you, but I'll stay vigilant ;-) |
| 19:37 | Licenser | we should stop looping of every kind and just write iteratively |
| 19:37 | AWizzArd | Well, just think of reduce (or fold) as a very general looping construct |
| 19:37 | Licenser | heh |
| 19:37 | Licenser | yea few people can be as annoing as I am :P |
| 19:38 | mmarczyk | tcrayford: www.cs.nott.ac.uk/~gmh/fold.ps |
| 19:38 | tcrayford | mmarczyk: already read, and translated into clojure |
| 19:39 | mmarczyk | Licenser: 'passionate' is not really 'annoying' :-) |
| 19:39 | AWizzArd | foldr you can get from (reduce f (rseq coll)) |
| 19:40 | mmarczyk | tcrayford: well I guess that's mostly on foldr... foldl is equivalent for associative ops though |
| 19:40 | tcrayford | yeah, its interesting stuff |
| 19:40 | mmarczyk | AWizzArd: not really, that wouldn't work with infinite seqs, say |
| 19:40 | AWizzArd | what is the "right side" or last element of an infinite seq? |
| 19:41 | mmarczyk | AWizzArd: that's irrelevant to foldr |
| 19:41 | mmarczyk | AWizzArd: the definition is |
| 19:41 | mmarczyk | foldr f v xs = f (head xs) (foldr f v (rest xs)) |
| 19:42 | mmarczyk | foldr f v [] = v, of course |
| 19:42 | mmarczyk | so if f can return something useful based on (head xs) alone without caring too much about (foldr f v (rest xs)) |
| 19:42 | AWizzArd | Do you have a practical example for such a case? |
| 19:42 | mmarczyk | you've got a result, even though xs might be an infinite sequence (in Haskell, most likely a list) |
| 19:43 | mmarczyk | map ? |
| 19:44 | AWizzArd | maybe I am confused, but why does this definition of foldr take (head xs)? |
| 19:44 | AWizzArd | should it not be (last xs)? |
| 19:44 | mmarczyk | AWizzArd: nope |
| 19:45 | AWizzArd | so, what does the r then mean? |
| 19:45 | riddochc | It's about the order of function application. |
| 19:45 | AWizzArd | when it goes from the left side through xs’s right side? |
| 19:45 | mmarczyk | AWizzArd: if you expand this for an example list of xs, the parens will be in all the right places |
| 19:45 | mmarczyk | AWizzArd: (f x1 (f x2 (f x3 v))) |
| 19:46 | AWizzArd | vs? |
| 19:46 | clojurebot | use vs require is (:use [lib :only [a b c]) or (:require [lib :as alias]) -- (:use lib) is only for playing around |
| 19:46 | mmarczyk | AWizzArd: as opposed to (f (f (f v x1) x2) x3) for a left fold |
| 19:47 | AWizzArd | ah ok |
| 19:48 | riddochc | So, I think I had some scheme... (defun foldr (step zero x) (if (null x) zero (step (car x) (foldr step zero (cdr x))) |
| 19:48 | riddochc | Er, define. Sorry. |
| 19:49 | riddochc | And (define foldl (step zero x) (if (null x) zero (foldl step (step zero (car x)) (cdr x)))) |
| 19:49 | rbarraud | , |
| 19:49 | clojurebot | EOF while reading |
| 19:51 | riddochc | Oh, now this is interesting. I hadn't run across it before: http://hyperpolyglot.wikidot.com/lisp |
| 19:51 | mmarczyk | AWizzArd: as for the map via foldr, map f xs = foldr (\x v -> (f x):v) [] xs |
| 19:51 | AWizzArd | yes |
| 19:54 | mmarczyk | riddochc: keywords are a PLT Scheme thing, though, r5rs doesn't have them |
| 19:55 | mmarczyk | riddochc: plus this doesn't make clear the difference between the various vector literals |
| 19:55 | mmarczyk | a nice list nonetheless, thanks for the link |
| 19:55 | briancarper | That site seems to have a lot of inaccuracies in the Clojure column. Defines "atom" as (not (list? x)) |
| 19:56 | mmarczyk | briancarper: hm, indeed |
| 19:56 | mmarczyk | actually, I'd be hard pressed to come up with a useful definition of atom in Clojure |
| 19:56 | riddochc | Yeah, I was noticing their "not possible" thing for "making a standalone executable" in clojure. |
| 19:57 | mmarczyk | I think there's "seqable?" is contrib |
| 19:57 | mmarczyk | ^in... I wonder if it covers all the cases |
| 19:59 | riddochc | I thought there was some JIT stuff for java that'll actually make a standalone executable, unless I'm mistaken. I've never used it. |
| 19:59 | briancarper | mmarczyk: It couldn't cover all cases, could it? You can define your own seqable things by implementing the right interfaces. |
| 19:59 | mmarczyk | briancarper: there's instance? for that |
| 19:59 | briancarper | Ah, right. |
| 19:59 | briancarper | Yeah, I just looked at the implementation of seqable?, it's not pretty. |
| 20:00 | mmarczyk | but then you have to decide if Enumerations and Iterators are seqable? |
| 20:00 | mmarczyk | I guess enumeration-seq and iterator-seq don't count |
| 20:00 | mmarczyk | so probably they're not |
| 20:00 | mmarczyk | then again, because of e.-seq and i.-seq, they're not "atomic" in the traditional sense... |
| 20:01 | riddochc | I can't remember wanting to test for "atomness". |
| 20:01 | briancarper | Me neither, I'm happy to leave it undefined. |
| 20:02 | mmarczyk | me neither, and in fact the only way I might lose sleep over this is due to a purely academic desire to come up with an appropriate test :-P |
| 20:02 | mmarczyk | go away!, go away! (the purely academic desire, I mean) |
| 20:14 | navandres | hi |
| 20:15 | navandres | I'm a dummy and I have a question for you |
| 20:15 | navandres | can I ask? |
| 20:17 | DarthShrine | navandres: Go ahead |
| 20:17 | navandres | I'm trying to make a simple recursive function |
| 20:17 | navandres | and something is wrong |
| 20:17 | navandres | (defn sumatory [n] (+ (sumatory (dec n)) n) ) |
| 20:18 | mmarczyk | navandres: you need a terminating condition |
| 20:18 | navandres | It suppose to sum from n to 0 |
| 20:18 | navandres | yes |
| 20:18 | navandres | I try this also |
| 20:18 | navandres | without luck |
| 20:19 | navandres | let me check that again |
| 20:19 | mmarczyk | navandres: a terminating condition as in (if (zero? n) (return-something) (+ ...recursive call happens here...)) |
| 20:20 | navandres | mmm |
| 20:20 | mmarczyk | or use (defn s [n] (/ (* n (inc n)) 2)) :-) |
| 20:20 | navandres | I was trying that |
| 20:20 | navandres | (defn sumatory [n] (if (== n 0) 0) (+ (sumatory (dec n)) n) ) |
| 20:20 | navandres | that is wrong? |
| 20:20 | mmarczyk | wrong paren placement |
| 20:21 | mmarczyk | (if (zero? n) 0 ...no paren here... (+ ...)...) |
| 20:21 | mmarczyk | where the final ...) means "close all parens" |
| 20:21 | navandres | ok |
| 20:22 | navandres | I'm a little confuse |
| 20:22 | navandres | but I will try that |
| 20:22 | navandres | thanks |
| 20:22 | mmarczyk | np |
| 20:27 | tomoj | recursion :( |
| 20:28 | navandres | have no luck |
| 20:29 | navandres | (defn s [n] (/ (* n (inc n)) 2)) |
| 20:30 | navandres | with this function |
| 20:30 | navandres | s 5 |
| 20:30 | navandres | What should I expect ? |
| 20:30 | tomoj | ,(+ 1 2 3 4 5) |
| 20:30 | clojurebot | 15 |
| 20:31 | mmarczyk | ,((fn [n] (/ (* n (inc n)) 2)) 5) |
| 20:31 | clojurebot | 15 |
| 20:31 | navandres | mmm |
| 20:31 | navandres | I'm getting this |
| 20:31 | navandres | #<user$s__4 user$s__4@739e8329> |
| 20:31 | navandres | 5 |
| 20:31 | tomoj | are you actually typing "s 5" to call it? |
| 20:31 | mmarczyk | ((fn sum-down-to-zero [n] (if (zero? n) 0 (+ n (sum-down-to-zero (dec n))))) 5) |
| 20:32 | navandres | yes |
| 20:32 | mmarczyk | ,((fn sum-down-to-zero [n] (if (zero? n) 0 (+ n (sum-down-to-zero (dec n))))) 5) |
| 20:32 | clojurebot | 15 |
| 20:32 | navandres | :( |
| 20:32 | tomoj | type (s 5) instead |
| 20:32 | mmarczyk | incidentally, the latter idea is not efficient at all |
| 20:32 | navandres | ohhhh |
| 20:32 | navandres | I'm soooooo silly |
| 20:32 | mmarczyk | loop/recur would be ok... but that's besides the point, I guess |
| 20:33 | navandres | thanks |
| 20:33 | navandres | (s 5) |
| 20:33 | navandres | works |
| 20:35 | mmarczyk | ^beside :-/ |
| 20:35 | navandres | all those definitions works now |
| 20:35 | navandres | thanks |
| 20:36 | navandres | is there a way of executing clojure that can load a file also |
| 20:37 | navandres | because I'm have to do the load-file every time |
| 20:44 | vIkSiT | hmm, what would be the best way of reading a file till EOF in some code like this : http://paste.lisp.org/display/111521 ? |
| 20:47 | mmarczyk | vIkSiT: http://stackoverflow.com/questions/2961493/treating-a-file-of-java-floats-as-a-lazy-clojure-sequence/2963984#2963984 |
| 20:47 | mmarczyk | (some code by cgrand which does what you want, I think) |
| 20:47 | vIkSiT | mmarczyk, ooh good pointer, thanks |
| 20:48 | mmarczyk | navandres: using load-file is very unusual |
| 20:48 | mmarczyk | navandres: maybe have a look at http://www.assembla.com/wiki/show/clojure/Getting_Started |
| 20:49 | navandres | hehe |
| 20:49 | navandres | yes |
| 20:49 | navandres | I know |
| 20:49 | navandres | thank you |
| 20:50 | navandres | I have to install the eclipse plugin |
| 21:37 | rhickey | http://groups.google.com/group/clojure/browse_frm/thread/c8c850595c91cc11 |
| 21:56 | qbg | If you have to ask for bigints, asking for a non-primitive in recur fits |
| 21:56 | rhickey | qbg: right, that mismatch was a remnant, it will match the default |
| 21:59 | AWizzArd | in my Clojure version when I have a (loop [x (long 1)] (recur (* x 0.5))) I get ==> java.lang.IllegalArgumentException: recur arg for primitive local: x must be matching primitive |
| 22:00 | AWizzArd | That's a good solution too. |
| 22:01 | vIkSiT | hmm, whats a good way to serialize a protocol? |
| 22:02 | rhickey | AWizzArd: it isn't because there are plenty of times where the recur args is an object that could init the loop local just fine (loop [x 1] ... (recur (:foo bar)) - if (:foo bar) is an integer (even in a box) that will be fast and correct |
| 22:02 | qbg | vIkSiT: Why do you want to serialize a protocol? |
| 22:02 | vIkSiT | erk. I meant a *record* |
| 22:02 | vIkSiT | ok stepping back a bit. |
| 22:03 | vIkSiT | I've got a record that contains a list/vector/map of other records. |
| 22:03 | AWizzArd | rhickey: if the compiler can not prove that (:foo bar) returns a long it could warn, and so one could (recur (long (:foo bar)) |
| 22:03 | vIkSiT | And I'd like to be able to serialize and store it on disk |
| 22:03 | vIkSiT | qbg, ^ .. |
| 22:03 | AWizzArd | but another solution could be that x in [x 1] is a number |
| 22:04 | AWizzArd | a general one, bigint |
| 22:04 | AWizzArd | (num 1) |
| 22:04 | AWizzArd | it would be confusing if (+ 1 0.1) ==> 1.1 but inside a loop then ==> 1 |
| 22:07 | rhickey | AWizzArd: anf then you learn that loop locals take on the type of their initializer, and you are doing floating point so use a floating point init |
| 22:08 | AWizzArd | This may not be discovered always, people forget it, don't write test, don't use Coverage tools, etc. |
| 22:09 | rhickey | AWizzArd: And I should orient Clojure for those people? |
| 22:09 | AWizzArd | In my opinion the two best solutions would be: 1) using fast primitives but then also static type checking which will emit warnings or erros during compilation when type correctness can't be proven, or 2) having the boxed numbers as default where no errors could sneak in |
| 22:10 | rhickey | AWizzArd: static type checking is not going to happen any time soon |
| 22:10 | AWizzArd | Well, it is just more complex rule, if (+ 1 0.1) ==> 1.1 outside of loops, but inside loops just 1. |
| 22:10 | remleduff | My problem with making the loop initializer so magical is java interop. You basically would never feel save initializing a loop variable with an interop form unless you make sure to double-check every time what type the java code returns. |
| 22:11 | rhickey | but it could go back to being an error, causing more work for some correct code |
| 22:11 | AWizzArd | an error or at least warning would be nice imo |
| 22:11 | AWizzArd | (recur (+ x 0.1)) ==> warning |
| 22:12 | AWizzArd | (recur (my-static-add-that-returns-longs x 0.1)) ==> fine |
| 22:12 | AWizzArd | I don't know if + is the version that returns long or +' |
| 22:13 | rhickey | AWizzArd: It's the same rule: |
| 22:13 | rhickey | (defrecord Foo [^long x]) |
| 22:13 | rhickey | (:x (Foo. 4.2)) => 4 |
| 22:13 | AWizzArd | When I explicitly specified long I expect that. |
| 22:13 | rhickey | AWizzArd: it prints warning right now on any mismatch |
| 22:14 | AWizzArd | warnings/errors are fine, I will be informed as early as possible, which is a good thing |
| 22:14 | rhickey | user=> (defn foo [] (loop [x 42] (recur 4.2))) |
| 22:14 | rhickey | NO_SOURCE_FILE:2 recur arg for primitive local: x is not matching primitive, had: double, needed: long |
| 22:14 | rhickey | #'user/foo |
| 22:15 | AWizzArd | yes, this is good behaviour |
| 22:16 | AWizzArd | I just remember that in the equal branch that Licenser tested some hours ago we discovered that for (defn foo [n] (loop [n n r 1] (if (zero? n) r (recur (dec n) (* r 0.2))))) (foo 3) ==> 0 without that warning |
| 22:17 | AWizzArd | in my (1+ month old) Clojure it returns 0.008 |
| 22:18 | AWizzArd | but when I specified r (long 1) then I got this useful warning |
| 22:41 | rhickey | AWizzArd: yes, the warnings used to go on with *warn-on-reflection*, now always on |
| 22:44 | remleduff | Is it a technical limitation that makes statics unable to be closures? |
| 22:45 | rhickey | remleduff: where would their closed-overs go? |
| 22:49 | remleduff | Oh, I was picturing them sitting there in the same generated Fn class and using the same closed-overs, but they wouldn't be accessible to static method. :) |
| 22:53 | remleduff | I was wondering why all functions couldn't be implemented in terms of a var wrapping a static method call and then use VirtualMachine.html#redefineClasses to allow dynamicism. |