2009-04-22
| 00:04 | brennanc | is there anything like find-doc but that has just the function names. It's really hard to read it when it outputs 20 pages |
| 00:09 | Jedi_Stannis | brennanc: not that I know of, shouldn't be too hard to write one |
| 01:27 | joha1 | I'd like to use a syntax quote which doesn't try to resolve symbols. Is there any easy way of achieving this? |
| 01:30 | hiredman | uh, quote? |
| 01:30 | hiredman | ,'(a b @(c d)) |
| 01:30 | clojurebot | (a b (clojure.core/deref (c d))) |
| 01:30 | hiredman | or not |
| 01:31 | hiredman | why do you want syntax quote? |
| 01:33 | joha1 | building a function that generates code from a template, and I want to insert some values deep inside the vector. Perhaps there is a better way |
| 01:35 | hiredman | zippers |
| 01:36 | joha1 | what i'm looking for is something like `(xxx (yyy ~zzz))) -> (xxx (yyy 3)), but without symbol resolution (assuming zzz = 3) |
| 01:36 | joha1 | zippers, eh? I'll see what I can find |
| 01:36 | hiredman | clojure.zip |
| 01:37 | hiredman | ,(require '[clojure.zip :as zip]) |
| 01:37 | clojurebot | nil |
| 01:37 | hiredman | ,(zip/zip-vec '[a b c]) |
| 01:37 | clojurebot | java.lang.Exception: No such var: zip/zip-vec |
| 01:37 | joha1 | yes of course, that should work. I looked into zip just a few hours ago. thanks for the hint |
| 01:37 | hiredman | ,(-> '[a b c] zip/vec-zip zip/root) |
| 01:37 | clojurebot | java.lang.Exception: No such var: zip/vec-zip |
| 01:38 | hiredman | bah |
| 01:39 | hiredman | ,(ns-interns (find-ns 'zip)) |
| 01:39 | clojurebot | java.lang.NullPointerException |
| 01:40 | hiredman | ,(find-ns 'zip) |
| 01:40 | clojurebot | nil |
| 01:40 | hiredman | ,(ns-interns (find-ns 'clojure.zip)) |
| 01:40 | clojurebot | {lefts #'clojure.zip/lefts, down #'clojure.zip/down, insert-left #'clojure.zip/insert-left, up #'clojure.zip/up, next #'clojure.zip/next, path #'clojure.zip/path, children #'clojure.zip/children, vector-zip #'clojure.zip/vector-zip, append-child #'clojure.zip/append-child, zipper #'clojure.zip/zipper, branch? #'clojure.zip/branch?, end? #'clojure.zip/end?, leftmost #'clojure.zip/leftmost, edit #'clojure.zip/edit, replace |
| 01:40 | hiredman | ,(-> '[a b c] zip/vector-zip zip/root) |
| 01:40 | clojurebot | [a b c] |
| 01:40 | hiredman | ,(-> '[a b c] zip/vector-zip zip/left zip/left zip/root) |
| 01:40 | clojurebot | java.lang.NullPointerException |
| 01:41 | hiredman | ,(-> '[a b c] zip/vector-zip zip/down zip/right zip/right (zip/replace 'z) zip/root) |
| 01:41 | clojurebot | [a b z] |
| 02:06 | hiredman | hmmm |
| 02:06 | hiredman | that is three commits of autodocs for rev 687 |
| 02:08 | replaca | yeah, cause I'm doing more work on the robot than people are doing work on contrib |
| 02:08 | replaca | and google's lame-ass wiki doesn't have an offline preview tool |
| 02:09 | replaca | I can do some stuff editing in the text box and hitting preview, but only so much |
| 02:09 | hiredman | I see |
| 02:09 | replaca | if you want too see the current product, go to http://code.google.com/p/clojure-contrib/wiki/OverviewOfContrib |
| 02:10 | replaca | but it still has a long way to go |
| 02:10 | Cark | wah nice stuff you're doing there |
| 02:11 | hiredman | nice |
| 02:11 | replaca | thx |
| 02:11 | replaca | dealing with the google wiki is kind of a bear |
| 02:11 | replaca | all sorts of limitations I wouldn't have in HTML :-( |
| 02:15 | Cark | ah funny, so many functions in there i implemented on my own |
| 02:15 | replaca | the problem has been that contrib is so opaque! I'm trying to fix that |
| 02:16 | noidi | that's great! |
| 02:16 | noidi | the fixing, not the opaqueness ;) |
| 02:16 | replaca | :-) |
| 02:16 | noidi | grepping the sources gets old fast |
| 02:18 | replaca | know whatchya mean |
| 02:26 | cp2 | bah, i lost my uptime |
| 06:49 | emacsen | hey pjb3 |
| 08:50 | kadaver | what are hashmaps internally? red-black-trees? |
| 08:52 | cemerick | kadaver: they're hash array mapped tries |
| 08:52 | cemerick | the sorted hash maps are red-black trees, I think. |
| 09:12 | rhickey_ | cemerick: right, sorted sets/maps are rb trees |
| 09:22 | cemerick | I haven't had a good brainfuck in a while, but implementing conses, lists, and map/reduce in terms of constraint propagation certainly qualifies... |
| 10:49 | postit | hi. i need a litte advice on which order to read some books |
| 10:50 | postit | ["On Lisp","Practical Common Lisp","The Clojure book"] |
| 10:51 | Chouser | if you've already decided to learn Clojure, I think I'd start with the Clojure book |
| 10:51 | postit | i know the basics of lisp and functional programming |
| 10:51 | Chouser | I've never read PCL, so someone that has may have a different opinion |
| 10:51 | gnuvince | PCL is nothing really special and it's really tailored for Common Lisp |
| 10:51 | postit | do you know, does the clojure book just deal with syntax compared to other lisps? |
| 10:52 | gnuvince | I'd start with the Clojure book as well and if you need to, On Lisp. |
| 10:52 | gnuvince | postit: there's more to the Clojure book than just explanation of the syntax. |
| 10:53 | postit | ive decided on clojure, but i wanted to get a good understanding of the "lispy" way to design things too |
| 10:53 | arohner | postit: I would look at SICP then as well |
| 10:53 | gnuvince | postit: learn Clojure and read code by others |
| 10:53 | gnuvince | You'll pick it up. |
| 10:54 | arohner | but yeah, gnuvince is right. The clojure way of doing things is not exactly the same as CL or Scheme |
| 10:54 | Chouser | The Clojure Book is aims at both Lispers and Java'ers, so it explains how and why to do idiomatic Clojure |
| 10:54 | postit | i was wondering that to. if i could learn enough clojure from the "clojure book" to port other stuff as i read |
| 10:55 | Raynes | The Clojure book teaches Clojure very well. I learned out of it. |
| 10:55 | Chouser | yes, I think if you grok the clojure book material, "on lisp" will then still be useful and interesting. |
| 10:55 | postit | great, thanks guys! |
| 11:04 | dliebke | postit: the author of Programming Clojure, Stuart Halloway, also wrote some articles on porting examples from PCL to Clojure. http://blog.thinkrelevance.com/2008/9/16/pcl-clojure |
| 11:04 | rapido | ,(count [1 2 3]) |
| 11:04 | clojurebot | 3 |
| 11:05 | rapido | ~confluently persistent |
| 11:05 | clojurebot | It's greek to me. |
| 11:18 | postit | is emacs/slime the preferred dev environment (at least if you use emacs) |
| 11:21 | djpowell | it is pretty good. i just use emacs + clojure-mode + the built-in M-x inferior-lisp |
| 11:22 | djpowell | clojuredev seems quite nice tho - i like the rainbow paren highlighting - anyway of doing that in emacs? |
| 11:22 | djpowell | clojure-dev for eclipse i mean |
| 11:25 | arohner | postit: if you're already an emacs user, then yes it's the best environment |
| 11:25 | arohner | I use emacs + slime, though inferior lisp works pretty well |
| 11:26 | arohner | what does rainbow paren highlighting do? |
| 11:27 | Chousuke | different colour for each paren pair. |
| 11:27 | arohner | on my emacs, if you put your cursor on a paren, bracket or brace, it highlights the matching one |
| 11:27 | arohner | but only when the cursor is on a paren |
| 11:27 | arohner | and it highlights in a different color when there is no match |
| 11:28 | djpowell | the rainbow paren thing in clojure-dev just syntax colors parens different colors depending on the nesting level - not only when the cursor is near them |
| 11:31 | Chousuke | anyway, it's pointless to ask if emacs can do something. you need to ask "where's the plugin?" |
| 11:33 | Chouser | and then, "why does it only work with xemacs"? |
| 11:33 | arohner | emacswiki.org has a section on paren modes: http://www.emacswiki.org/emacs/CategoryParentheses |
| 12:42 | gnuvince | Can anyone answer a Java question? |
| 12:43 | danlarkin | waste of a question :) |
| 12:43 | gnuvince | Well, whatever |
| 12:43 | gnuvince | I compiled a bunch of Java files. |
| 12:43 | gnuvince | That worked |
| 12:44 | gnuvince | when I do: java ClassName, I get an error telling my that package/ClassName is a "wrong name" |
| 12:45 | gnuvince | Exact message: $ java BinRepParser |
| 12:45 | gnuvince | Exception in thread "main" java.lang.NoClassDefFoundError: BinRepParser (wrong name: hu/belicza/andras/bwhf/control/BinRepParser) |
| 12:50 | hiredman | gnuvince: what package is the class in? |
| 12:51 | gnuvince | hu.belicza.andras.bwhf.control |
| 12:51 | hiredman | you need to include the package |
| 12:51 | hiredman | java hu.belicza.andras.bwhf.control.BinRepParser |
| 12:51 | gnuvince | ah< |
| 12:52 | gnuvince | thanks |
| 12:52 | brianh2 | gnuvince: yeah. look @ this http://www.jarticles.com/package/package_eng.html |
| 13:03 | replaca | For those using emacs and slime, I strongly recommend paredit: http://mumble.net/~campbell/emacs/paredit.html, it's made for a huge leap in my programming happiness |
| 13:03 | replaca | (actually this is true even if you're not using slime) |
| 13:14 | gnuvince | AAAAAAAAAAAAAAAAAAH! |
| 13:17 | Lau_of_DK | Evening gents |
| 13:21 | technomancy | paredit is amazing. |
| 13:22 | technomancy | it makes me hate editing non-lisp code. |
| 13:23 | gnuvince | technomancy: it's neat, but I could not get used to it. |
| 13:23 | gnuvince | I'd need to spend more time using it |
| 13:29 | technomancy | gnuvince: only in the long run |
| 13:29 | stuhood | gnuvince: it waits longer to optimize, and can use more memory on optimizations |
| 13:29 | danlarkin | -server will use hotspot |
| 13:29 | gnuvince | technomancy: the largest bottleneck (20%) was FileInputStream.read; removing -server fixed the problem. |
| 13:30 | p_l | JVM 1.7 is supposed to always use the same optimization model as -server |
| 13:31 | technomancy | gnuvince: are you talking about my extract-jar function? |
| 13:33 | gnuvince | technomancy: no, my Starcraft parser. |
| 13:34 | technomancy | gnuvince: that was really weird, because I almost sent an email to the mailing list last night asking why a function that used FileInputStream.read was slow. |
| 13:34 | technomancy | I thought you were reading my mind. |
| 13:34 | dnolen | gnuvince is your project a one time run thing? |
| 13:34 | gnuvince | technomancy: I thought that I was nearly 20x slower than Java; turns out my Java was faulty and I wasn't analyzing any file. The number is now ~2.5-3x slower. And when I profiled both programs, -server was about twice as slow as -client |
| 13:34 | technomancy | nice |
| 13:35 | gnuvince | dnolen: currently, yes; give a bunch of files on the command line and it parses them. |
| 13:36 | dnolen | gnuvince: client speeds up startup time, server does really aggressive on the fly optimization. for long running processes server is usually better from what I understand. |
| 13:36 | technomancy | anyway, FileInputStream.read takes an array of bytes, but it won't accept a (make-array Byte 1000); it needs a (make-array Byte/TYPE 1000), but I have no idea what the difference is; I just copied it blindly. =) |
| 13:37 | gnuvince | technomancy: reference type vs value type. The first is a Byte[], the second a byte[] and apparently Java treats them differently. |
| 13:38 | technomancy | static typing saves the day again |
| 13:39 | technomancy | who knows what horrors would occur if I sent it bytes when it wanted Bytes. |
| 13:39 | technomancy | or vice versa |
| 13:39 | gnuvince | That's more of a "let's have primitives and objects" problem. |
| 13:39 | danlarkin | technomancy: this has nothing to do with static typing |
| 13:39 | danlarkin | it's strong typing vs weak typing, which is orthogonal to static vs dynamic |
| 13:43 | technomancy | oh, bytes are primitive, right. |
| 13:46 | Chousuke | having the primitive types is a nasty JVM wart, but I guess there at least used to be a reason to have them :/ |
| 13:46 | gnuvince | I figure performance |
| 13:47 | gnuvince | Although it seems like the kind of thing the compiler should take care of. |
| 13:48 | Cark | well it really makes sense ti have a buffer made of real contiguous bytes |
| 13:48 | Cark | rather than byte objects or whatever |
| 13:49 | danlarkin | right, well it's an array of data structures rather than an array of pointers to classes with overhead etc |
| 13:50 | danlarkin | I agree it's a wart, but I /suppose/ I can see the rationale for having it |
| 13:51 | Cark | .net has the same thing m |
| 13:51 | Cark | more or less |
| 13:51 | Cark | so i guess that's pretty much the way to go |
| 13:56 | gnuvince | instance? seems like a pretty quick operation, am I right? |
| 13:56 | dnolen | what kind of machine does clojurebot run on? |
| 14:00 | Cark | clojurebot has been on strike these days |
| 14:00 | Cark | clojurebot: are you there ? |
| 14:00 | clojurebot | Huh? |
| 14:02 | cemerick | gnuvince: as quick as Class.isInstance :-) |
| 14:03 | gnuvince | cemerick: that's what I wanted to know, that seems to be pretty fast, right? |
| 14:03 | cemerick | for the job, it's all there is... |
| 14:04 | cemerick | the speed of instance? is never going to be your bottleneck, if that's your question |
| 14:04 | gnuvince | cemerick: think again :) |
| 14:04 | gnuvince | rank self accum count trace method 1 37.54% 37.54% 3532 300290 java.lang.Class.isInstance 2 20.12% 57.66% 1893 300285 java.lang.Class.isInstance |
| 14:04 | gnuvince | 3 17.94% 75.60% 1688 300292 java.lang.Class.isInstance |
| 14:04 | gnuvince | 4 2.44% 78.04% 230 300308 java.io.FileInputStream.readBytes |
| 14:04 | gnuvince | well, the output didn't come out too nicely :-/ |
| 14:05 | cemerick | can you paste the code that produces that mix? |
| 14:05 | gnuvince | http://bitbucket.org/gnuvince/clj-starcraft/src |
| 14:05 | gnuvince | check starcraft/replay/parse.clj |
| 14:07 | cemerick | where's the source of the instance? calls? |
| 14:07 | Cark | did you set the *wern-on-reflection* variable ? |
| 14:07 | Cark | warn |
| 14:08 | gnuvince | Cark: yes, there's none. |
| 14:08 | gnuvince | cemerick: most likely the call to vector? in read-field |
| 14:11 | cemerick | what's the overall runtime of the code that you profiled? I'm thinking if the overall runtime was very short, then instance? calls would likely still be reflective, and they could easily be a significant amount of runtime compared to a small disk read. |
| 14:12 | Cark | and the file must be in the cache too, so even faster to read |
| 14:14 | gnuvince | cemerick: ~110 seconds. |
| 14:14 | gnuvince | cemerick: it processed over a thousand files in that time frame. |
| 14:16 | Cark | what's the troughput ? how many megabytes in this time frame ? |
| 14:17 | gnuvince | Not a lot |
| 14:17 | gnuvince | 151 MB |
| 14:18 | gnuvince | Each file is about 150 KB |
| 14:18 | Cark | i remember seeing somewhere a way to read several buffers in one go |
| 14:18 | Cark | an array of buffers with different types |
| 14:19 | gnuvince | Cark: my hands are tied by the Java lib I use. |
| 14:19 | gnuvince | I don't do the IO |
| 14:19 | gnuvince | I take the file |
| 14:19 | gnuvince | pass it off to a Java method |
| 14:19 | gnuvince | grab the ByteBuffer it returned |
| 14:19 | gnuvince | and work with that. |
| 14:24 | replaca | I will attest to isInstance? being a bottleneck, it's also the slowest thing in the pretty printer (although I do do it a lot). |
| 14:24 | Cark | ah too bad ...because with a FileChannel you have this method : read(ByteBuffer[] dsts) |
| 14:24 | gnuvince | replaca: I do a lot of vector? calls too. |
| 14:24 | Cark | you could then prepare wrapped buffers on top of that for each record type |
| 14:25 | Cark | for each field type i mean |
| 14:25 | gnuvince | I was thinking of changing my API slightly, but it seems that a comparaison of length or using try/catch are the same speed. |
| 14:25 | Cark | does your library do memory mapped files ? |
| 14:26 | gnuvince | Cark: not that I know of. |
| 14:26 | gnuvince | as far as I can tell (not really a Java programmer), the guy just opens a FileInputStream, reads, and returns a ByteBuffer. |
| 14:26 | Cark | anyways that's not your problem ...you need to do less at run time |
| 14:27 | gnuvince | yeah |
| 14:27 | gnuvince | I define a field in a record like this: |
| 14:27 | replaca | gnuvince: obviously the pretty printer needs to think about types a lot, cause it's making dynamic decisions based on type. BUt it does more work than it needs to. I'll need to deal with that when I revisit dispatch. |
| 14:28 | gnuvince | [:name 1 Byte] or [:name2 [1 Byte] Integer]. The vector? calls is to read the [1 Byte] and use the value as the number of Integers to read. |
| 14:30 | gnuvince | ,(let [xs (repeat 1000000 [[1] [2 3]])] (time (doseq [x xs] (if (= (count x) 1) 1 2)))) |
| 14:30 | clojurebot | "Elapsed time: 3834.042 msecs" |
| 14:30 | gnuvince | ,(let [xs (repeat 1000000 [1 [2 3]])] (time (doseq [x xs] (if (vector? x) 2 1)))) |
| 14:30 | clojurebot | "Elapsed time: 2458.336 msecs" |
| 14:30 | Cark | I would prepare that parsing before hand |
| 14:31 | Cark | you know build a lambda |
| 14:31 | Cark | there you're "parsing" the field spec during the actual processing |
| 14:32 | gnuvince | So turn these into lambdas instead of structs? http://bitbucket.org/gnuvince/clj-starcraft/src/tip/src/starcraft/replay/actions.clj |
| 14:33 | Cark | that's nice and clean as it is |
| 14:33 | Cark | but you could process this "DSL" before hand into lambdas to make it quicker to parse |
| 14:36 | gnuvince | To make sure I'm following, something like (compile-record [:name 1 Byte] [:name2 [1 Byte] Integer]) and that would return a fn that takes a ByteBuffer as its input? |
| 14:37 | Cark | right |
| 14:38 | gnuvince | Should that be a macro or a function? |
| 14:38 | cipher | hey gnuvince what are you writing there--quick description |
| 14:39 | gnuvince | cipher: it's a library that reads a Starcraft replay file and returns information about the game (players, races, map, etc.) as well as all the actions done by the players. Players use those kinds of programs to analyse their games. |
| 14:40 | cipher | neat. |
| 14:49 | gnuvince | Cark: do you think compile-field should be a function or a macro? I'd prefer a function, but I'm not sure if I can do it... |
| 14:50 | cipher | gnuvince: did you see my PM? |
| 14:50 | gnuvince | Oh, yes. |
| 14:50 | gnuvince | Thanks |
| 14:51 | cipher | Ok. |
| 14:52 | gnuvince | Did you guys to bnetd? |
| 14:52 | cipher | we have some involvement |
| 14:52 | cipher | had* |
| 14:53 | gnuvince | OK |
| 14:53 | gnuvince | Shame Vivendi pulled the plug on that project :( |
| 14:53 | technomancy | if I can't delete a file, should I raise an instance of Exception, or is there a more specific class I should use? |
| 14:53 | gnuvince | technomancy: IOException? |
| 14:54 | technomancy | gnuvince: thanks; that sounds better |
| 14:55 | technomancy | what do you think: does a delete-file-recursively function belong in contrib? |
| 14:56 | technomancy | http://p.hagelb.org/delete-file-recursively.html |
| 15:03 | gnuvince | Java doesn't already have a method for that? |
| 15:03 | technomancy | gnuvince: yeah, I was surprised, but I couldn't find one. |
| 15:03 | technomancy | maybe they just hid it really well? |
| 15:05 | gnuvince | Python's shutil.rmtree ftw! |
| 15:05 | technomancy | FileUtils.rm_rcf |
| 15:05 | technomancy | *rm_rf |
| 15:05 | Chouser | that's the kind of thing apache commons provides |
| 15:05 | leafw | technomancy, gnuvince: no, java does not have a recursive file deletion command. I guess it meant too much potential for damage. |
| 15:06 | technomancy | Chouser: yeah, but needing a 3rd-party dependency for something that basic is unfortunate. |
| 15:06 | leafw | at least it has File.mkdirs() |
| 15:06 | Chouser | technomancy: yeah |
| 15:06 | technomancy | this functionality is pretty important for unit testing |
| 15:06 | technomancy | since you need to clean up after yourself |
| 15:13 | technomancy | posted it to the mailing list |
| 15:13 | technomancy | can create an issue/patch |
| 15:13 | cemerick | contrib *is* a 3rd party dependency (or dependencies). Much more pleasant API than 99% of the stuff out there, but it's a dependency nonetheless. |
| 15:15 | technomancy | every project I've worked with uses contrib already |
| 15:15 | technomancy | so it's not an additional dependency for most |
| 15:15 | technomancy | and it's not exactly 3rd-party |
| 15:16 | Chousuke | Chouser: what's the plan with your clojure-compiler? I see you haven't worked on it in a while |
| 15:17 | cemerick | my real point is that I think it'd be bad if stuff as generic (and as redundant w.r.t. existing libraries) as common IO operations starts leaking into contrib |
| 15:20 | Chouser | Chousuke: I've got a new job and a lot less time to work on Clojure stuff |
| 15:20 | Chouser | so the plans the same, the pace is just way down |
| 15:26 | Chousuke | the code you have right now looks quite scary. |
| 15:26 | Chouser | hm. yeah, it's not gotten to the "clean up" phase yet. ;-) |
| 15:43 | jayfields | how can I return the first item from a collection that matches a predicate? |
| 15:43 | jayfields | other than (first (filter pred coll)) |
| 15:43 | kotarak | (seq-utils/find-first pred coll) |
| 15:43 | jayfields | cool. thanks. |
| 15:44 | jayfields | I take it that's in contrib? |
| 15:44 | kotarak | Yup. |
| 15:45 | cemerick | Chouser: hey, congrats! Is it hush-hush, or do we get to leer at your new employer's wares? |
| 15:45 | Chouser | http://sentryds.com/ |
| 15:59 | drewr | Chouser: Congrats! |
| 16:00 | drewr | Are you relocating to FL or working from IL/IN/wherever you are now? |
| 16:01 | Chouser | telecommuting full time now. We'll see how that goes. :-) |
| 16:02 | drewr | It's definitely bittersweet. |
| 16:03 | drewr | I love it today because it's 65 and I'm on my porch. |
| 16:03 | Chouser | ah, nice |
| 16:09 | triddell | functions are supposed to return early, right? I have a function that checks user security against authorized access roles. How should I return true after the first authorized match from a for list comphrehension? |
| 16:10 | triddell | are not supposed to return early that is |
| 16:10 | hiredman | (first (for ...)) |
| 16:11 | arohner | triddell: for returns a lazy list that is realized as necessary |
| 16:12 | arohner | first "blocks" until the first element is returned from the lazy list |
| 16:12 | technomancy | cemerick: I don't follow. |
| 16:12 | technomancy | what's wrong with that? |
| 16:13 | hiredman | ~literal [3] clojure |
| 16:13 | clojurebot | a very attractive hammer with a nice heft to it |
| 16:13 | hiredman | ^- now using fnparse |
| 16:14 | cemerick | technomancy: there's a lot of java libraries that do a lot of things. Reimplementing capabilities (especially inherently-stateful stuff like IO) in clojure is counterproductive overall, IMO. Not having to do that sort of thing is why having fantastic java interop is a Good Thing. |
| 16:14 | AWizzArd | ~ max people |
| 16:14 | clojurebot | max people is 164 |
| 16:15 | triddell | arohner & hiredman: thanks |
| 16:15 | cemerick | been that way for a long time now |
| 16:15 | cemerick | maybe clojurebot should track the date that the last max was reached |
| 16:16 | technomancy | cemerick: everyone's just going to re-implement it on their own anyway |
| 16:16 | AWizzArd | Well, it first was 164. Then Clojurebot forgot that number. After a few days it maxed out freshly on 162. But then I resetted it to 164 again. This is now a while ago. |
| 16:16 | technomancy | contrib is useful *because* it provides common I/O operations |
| 16:17 | AWizzArd | Until that max number of users there was a funny correlation between the numbers of the GG and the number of users in here. That correlation was: for each 10 new users in the GG we got one more user here. |
| 16:17 | cemerick | technomancy: really? At what point is pulling in well-tested libraries worthwhile, then? |
| 16:17 | technomancy | cemerick: rm -rf ain't exactly rocket science |
| 16:17 | AWizzArd | For some reason then the number of users here settled at +/- 125, while the GG got more users. |
| 16:17 | technomancy | you'd pull in 3rd-party libs for tricky things like joda for date parsing |
| 16:18 | cemerick | I'm sure someone will reimplement date parsing in clojure, too. I'm just wondering where the line gets drawn. |
| 16:19 | technomancy | cemerick: I did. but I realized it's a bad idea because it's impossible to get right. |
| 16:19 | technomancy | so it didn't go in contrib. |
| 16:19 | technomancy | but this is very, very different. |
| 16:22 | cemerick | To each his own, I guess. Reinventing any otherwise well-tested wheel without getting a significant return on that work just seems like a waste to me. *shrug* |
| 16:23 | technomancy | everybody who writes tests for code that writes to disk needs to delete whole directories. having to pull in an apache dependency to do this is... sad. |
| 16:23 | cemerick | not really -- we use ant to clean such temp spaces up. |
| 16:24 | technomancy | it's fewer lines of code to just implement the function than actual lines of XML necessary to express the dependency on apache commons io. |
| 16:24 | technomancy | what about people who want to run tests from the REPL or from slime? |
| 16:26 | cemerick | that largely doesn't make sense to me either :-) |
| 16:27 | technomancy | if you have to launch a new instance every time you want to run the tests, it totally kills your rhythm since you've got to wait a few seconds for the JVM to boot. |
| 16:28 | technomancy | which is OK for integration tests, but totally unacceptable for unit tests where you need instant feedback |
| 16:29 | technomancy | see http://p.hagelb.org/06-clojure-test-mode.ogv |
| 16:30 | cemerick | like I said, to each his own. IMO, the REPL is phenomenal for interactive development, but any results from tests run in it aren't to be trusted -- too much opportunity for environment pollution that can skew them one way or another. |
| 16:31 | technomancy | yeah, it can't be your only method of testing; that's for sure. |
| 16:31 | technomancy | but to avoid testing with it is to give up a valuable tool. |
| 16:33 | cemerick | I don't avoid it...but then, I can't think of a single REPL-friendly test we have that uses any temp files. |
| 16:37 | technomancy | maybe that's because you don't have an rm -rf that works from the repl. =) |
| 16:37 | cemerick | heh |
| 16:38 | cemerick | nah, we just don't generate files *shrug* |
| 16:38 | cemerick | if we did, I'd probably have to know my way around a shell way better than I do |
| 16:41 | cemerick | everything we do is in-memory. GC cleans up after us :-) |
| 16:42 | technomancy | that's awesome if you can get away with it. =) |
| 16:42 | cemerick | I know :-D |
| 16:58 | emacsen | Can someone explain why I get an error that v doesn't resolve in the context: http://paste.lisp.org/display/79032 |
| 16:58 | emacsen | (that's not the final code, but it's the simplest version I have right now) |
| 16:59 | cemerick | emacsen: each arity must be wrapped in parens.... |
| 16:59 | emacsen | cemerick, ah :) |
| 17:00 | cemerick | emacsen: http://paste.lisp.org/display/79032 |
| 17:00 | kotarak | emacsen: and the (if (empty? ..) true) ( ... looks ominous. The if is basically useless. |
| 17:00 | emacsen | kotarak, the first one? you're probably right |
| 17:01 | emacsen | otherwise, well you need it to return true sometime right? |
| 17:01 | emacsen | cemerick, thx |
| 17:01 | kotarak | And (cond ... :else false) can also be left out. cond will return nil of no clause matched, so it will count as false. |
| 17:02 | emacsen | This also isn't the final code. It's going to do more than this, and will be lazy, but this is my first shot |
| 17:02 | emacsen | kotarak, for this version, true. Later versions, no, but you're right in what you see |
| 17:02 | emacsen | (because nil won't print as false in print I believe |
| 17:05 | hiredman | ~ticker JAVA |
| 17:05 | clojurebot | JAVA; -0.06 |
| 17:12 | durka42 | ~ticker ORCL |
| 17:12 | clojurebot | ORCL; -0.18 |
| 17:13 | danlarkin | ~ticker CHINA |
| 17:13 | clojurebot | CHINA; +0.07 |
| 17:13 | danlarkin | tada! |
| 17:14 | durka42 | china? |
| 17:14 | p_l | ? |
| 17:15 | kotarak | ~ticker CON.F |
| 17:15 | clojurebot | java.io.IOException: Server returned HTTP response code: 400 for URL: http://www.google.com/finance/info?q=CON.F |
| 17:15 | durka42 | CDC Corporation |
| 17:15 | durka42 | (Public, NASDAQ:CHINA) |
| 19:19 | cads | hey, how do I use a namespace like clojure.set ? Neither (use clojure.set) or (use clojure/set) seem to work. |
| 19:22 | technomancy | (use 'clojure.set) |
| 19:22 | Raynes | use 'clojure.set |
| 19:22 | Raynes | technomancy: You win this time. :( |
| 19:22 | technomancy | or even better put (:use [clojure.set]) in your ns directive |
| 19:26 | lisppaste8 | Rayne pasted "imports and uses in namespace example for cads" at http://paste.lisp.org/display/79041 |
| 19:28 | cads | why do we quote it? |
| 19:28 | cads | wow, thanks for the example rayne |
| 19:29 | Raynes | cads: No problem. |
| 19:29 | technomancy | cads: because clojure.set is not bound to a value |
| 19:29 | Raynes | Quoting it keeps Clojure from trying to evaluate it. |
| 19:29 | technomancy | try just entering clojure.set into a repl; it doesn't mean anything |
| 19:29 | Raynes | ^ what he said. |
| 19:29 | cads | ah |
| 19:30 | technomancy | it's a symbol that is used to look up a namespace |
| 19:30 | technomancy | which is different from a var that's used to look up a value |
| 19:30 | cads | I thought it would just pass the symbol in that case, but I remember the eval rules now |
| 19:30 | technomancy | cads: if use were a macro, it could do that |
| 19:31 | technomancy | but use is a function |
| 19:31 | technomancy | ns is a macro, which is why the evaluation rules are different there |
| 19:37 | cgrand | technomancy: hi! just noticed (while grepping irc logs) that you talked to cgrand-rec 2 days ago. cgrand-rec isn't me, it's a disconnected irssi logging the channel |
| 19:37 | technomancy | cgrand: ah; good to know. =) |
| 19:38 | technomancy | I forgot what I said though. |
| 19:38 | cgrand | that you were trying the new enlive |
| 19:39 | technomancy | oh, I was "use"ing enlive and was wondering if it might be better not to export any vars that conflicted with clojure core. |
| 19:39 | unlink | What's the idiom for function definitions visible only inside another function? |
| 19:39 | technomancy | I've since decided to stick with "use :only" unless I have a reason not to |
| 19:39 | technomancy | unlink: define them in let bindings |
| 19:40 | lisppaste8 | technomancy pasted "let-binding a function for internal use; see target-file" at http://paste.lisp.org/display/79044 |
| 19:40 | technomancy | unlink: ^^ |
| 19:41 | unlink | boom |
| 19:41 | stuhood | you overwhelmed lisp.org with your awesome code, and it is throwing 500's... |
| 19:41 | technomancy | amazing |
| 19:42 | technomancy | if you want something done right, you have to do it yourself: http://p.hagelb.org/extract-jar.html |
| 19:42 | dreish | Or http://gist.github.com/ |
| 19:42 | technomancy | witness the power of Static Files |
| 19:42 | technomancy | does gist do clojure highlighting? |
| 19:42 | dreish | Yes. |
| 19:42 | stuhood | yea |
| 19:42 | technomancy | cool |
| 19:43 | technomancy | but I prefer static files. =) |
| 19:43 | dreish | They do Genshi highlighting. |
| 19:43 | stuhood | speaking of which, has anyone tried to get Clojure highlighting for Trac? |
| 19:44 | dreish | Maybe Genshi's not so obscure. (I'd never heard of it.) But anyway they cover something like 80 languages. |
| 19:44 | cgrand | technomancy: it bothers me to clash with clojure.core (eg CSS :not is 'but), I should rename 'complement back to 'complement-state (or 'negate or something else) and find another name for 'empty |
| 19:45 | technomancy | cgrand: clashing in private defns is not as big of a deal |
| 19:45 | unlink | So def always (re)binds in the global namespace, regardless of the scope? |
| 19:46 | technomancy | yeah. you shouldn't use it at outside toplevel scope unless you have a really good reason to do it though. |
| 19:46 | unlink | I guess I'm just used to scheme's scoping |
| 19:46 | unlink | which is different |
| 19:47 | technomancy | in fact, you shouldn't do it after your application has loaded at all |
| 19:47 | cgrand | technomancy: I want to keep them (complement and empty) public |
| 19:47 | technomancy | or at least be aware that you're stepping outside the Golden Path |
| 19:47 | unlink | right |
| 19:48 | unlink | I think (def a [x] (def b [x] (+ x 1)) (b x)) is nicer syntax than (def a [x] (let [b (fn [x] (+ x 1))] (b x))) though |
| 19:48 | unlink | s/\<def\>/&n |
| 19:49 | chessguy | so i'm thinking about an interesting little project, but i'd really need a freaking good REPL to play with it. anybody got any good suggestions? is SLIME as good as it gets? |
| 19:49 | dreish | letfn would be handy. |
| 19:49 | technomancy | chessguy: slime is rockin' |
| 19:49 | unlink | see: factorial with recur |
| 19:49 | technomancy | be sure you use M-x clojure-install to set it up though. |
| 19:50 | chessguy | hmm. i don't remember if that's how i installed it or not |
| 19:50 | chessguy | how would i tell? |
| 19:50 | technomancy | chessguy: if you used it, you should have a call to clojure-slime-config somewhere in your personal .emacs setup. |
| 19:51 | chessguy | doesn't look like it |
| 19:51 | chessguy | just (slime-setup) |
| 19:51 | technomancy | if you've already got it working you should be ok |
| 19:51 | chessguy | and slime-setup '(slime-repl) |
| 19:51 | technomancy | I was just thinking if you were going to install from scratch |
| 19:51 | unlink | Am I writing this idiomatically? http://gist.github.com/100173 |
| 19:52 | dreish | unlink: Maybe (letfn [inner [n m] ...] (inner n 1)) ? |
| 19:52 | unlink | Oh, there exists a letfn? |
| 19:52 | dreish | Since January, yes. |
| 19:52 | chessguy | i don't get it, when i M-x slime, it says something about connecting to a server? what is it connecting to |
| 19:52 | unlink | oh |
| 19:52 | unlink | hot |
| 19:53 | technomancy | chessguy: a clojure instance is started that "serves" the Emacs instance over slime |
| 19:53 | technomancy | there's a socket connection between the two |
| 19:53 | chessguy | oh, a JVM environment? |
| 19:54 | Raynes | technomancy: Stop being smarter than me. It's not nice. :| |
| 19:54 | technomancy | heh |
| 19:54 | technomancy | chessguy: yeah, it's launched as a subprocess. |
| 19:54 | chessguy | cool |
| 19:54 | dreish | unlink: Or just ((fn inner [n m] ...) n 1), but the double open parens can cause crossed eyes. |
| 19:56 | chessguy | does slime store the result of the last evaluation anywhere that you can get at it? |
| 19:56 | chessguy | e.g., for haskell, in ghci, if i do > 2 + 3, followed by > it == 5, i'd get true |
| 19:56 | technomancy | chessguy: probably, but I couldn't tell you off the top of my head. the slime manual is really good though. |
| 19:56 | chessguy | oh ok, i'll take a look |
| 19:57 | chessguy | thanks |
| 20:15 | dysinger | why does this work (straight java) |
| 20:15 | dysinger | sonian.archive.aws=> (String/format "%s ran %d miles today" (to-array ["Stu" 8])) |
| 20:16 | dysinger | "Stu ran 8 miles today" |
| 20:16 | dysinger | sonian.archive.aws=> |
| 20:16 | dysinger | and this one doesn't |
| 20:16 | dysinger | sonian.archive.aws=> (format "%s ran %d miles today" ["Stu" 8]) |
| 20:16 | dysinger | java.util.MissingFormatArgumentException: Format specifier 'd' (NO_SOURCE_FILE:0) |
| 20:16 | dysinger | sonian.archive.aws=> |
| 20:16 | dreish | Remove the [] |
| 20:16 | dysinger | I know that works |
| 20:17 | dysinger | I am saying the internal code for (format converts to a java array and passes it to java like the 1st call |
| 20:17 | dreish | The & turns the remaining args into a sequence. |
| 20:18 | dysinger | ~(format "%s ran %d miles today" (seq ["Stu" 8])) |
| 20:18 | clojurebot | format is http://github.com/tomfaulhaber/cl-format/tree/master |
| 20:18 | dysinger | oops |
| 20:18 | hiredman | dysinger: it works that way because [] does not make an array |
| 20:18 | dysinger | ,(format "%s ran %d miles today" (seq ["Stu" 8])) |
| 20:18 | clojurebot | java.util.MissingFormatArgumentException: Format specifier 'd' |
| 20:19 | dreish | dysinger: Why would you expect that to work? |
| 20:19 | hiredman | [] makes a persistent vector, which java's format doesn't know anything about |
| 20:19 | dreish | args now contains (("Stu" 8)) -- a seq with only one thing in it. |
| 20:19 | dysinger | right |
| 20:19 | dreish | That thing happens to be another seq, but it needs _two_ things. |
| 20:19 | dreish | Not _one_ seq. |
| 20:20 | dysinger | so the only way to format with a seq / vector / set is to use apply |
| 20:20 | dreish | Sure, or you could do String/format yourself I guess. |
| 20:21 | dysinger | y |
| 20:21 | dreish | If you do it a lot, maybe write a formatseq? |
| 20:21 | dysinger | true |
| 20:21 | dreish | I'd probably apply. It seems cleaner somehow. |
| 20:21 | dysinger | y it works fine |
| 20:21 | dysinger | just curious |
| 20:22 | dysinger | the & args turning into a seq explains the magic |
| 20:22 | dreish | k |
| 20:23 | dysinger | sorry for the bone-headed questions - I've been seriously programming clojure for 3 weeks. |
| 20:23 | dysinger | :) |
| 20:23 | dreish | np |
| 20:24 | dreish | For some reason I thought you'd been around for months, actually. |
| 20:24 | dysinger | I learn quick - but sometimes ask dumb questions |
| 20:24 | dysinger | and I did Java for 10 years and some lisp already :) |
| 20:25 | dysinger | am totally loving it though |
| 20:25 | dysinger | I rewrote some java today and shrank it 10:1 |
| 20:25 | dreish | It is nice. |
| 20:27 | Raynes | dysinger: Good evening. |
| 20:27 | dreish | Whenever I have to make a change to the existing Java part of my pet project, it's painful to have to deal with that language. |
| 20:27 | dysinger | heya Raynes |
| 20:38 | chessguy | hmm, i don't get how to use slime presentations to copy the previous results to the prompt |
| 20:42 | gnuvince_ | Sometimes I hate dynamic typing... |
| 20:50 | chessguy | i'm reading http://common-lisp.net/project/slime/doc/html/Presentations.html and it says "Using standard Emacs commands, the presentation can be copied to a new input in the REPL", but it doesn't say WHAT standard Emacs commands |
| 20:53 | technomancy | chessguy_: M-p |
| 20:53 | slashus2 | try them all |
| 20:54 | chessguy | M-p takes me to the last one that matches what i've typed so far |
| 20:55 | technomancy | C-h m will show you what bindings are active for the current mode |
| 20:59 | chessguy | none of those seem to do what i want |
| 21:03 | chessguy | *sigh* |
| 21:16 | unlink | How do I pattern match based on whether the argument to a function was a vector or a scalar? |
| 21:16 | durka42 | you could do something with multimethods |
| 21:17 | durka42 | or you could just put an if statement at the top of the function |
| 21:17 | dreish | Destructuring isn't the same as pattern matching, in that it can't really do what you're asking for. |
| 21:18 | unlink | oh |
| 21:18 | hiredman | well |
| 21:18 | hiredman | it can |
| 21:18 | unlink | That was basically the #1 use case of pattern matching for me |
| 21:19 | hiredman | (defmulti f vector?) |
| 21:19 | hiredman | (defmethod f true [arg] do vector stuff) |
| 21:19 | hiredman | (defmethod f false [arg] do scalar stuff) |
| 21:19 | dreish | hiredman: That's a multimethod, as durka42 suggested. |
| 21:20 | unlink | e.g. fun g(a, b, c) = case a of [] => (round c) = 1 | 1::xs => not (null xs) | _ => b |
| 21:22 | dreish | I'm surprised no one has written a defpattern macro for contrib yet. |
| 21:23 | unlink | Obviously (fn ([[a b & c]] ...) ([_] ...)) doesn't work. |
| 21:28 | Jedi_Stannis | what are you trying to do? |
| 21:31 | technomancy | chessguy: it might be a clojure repl feature rather than a slime feature |
| 21:50 | chessguy | Jedi_Stannis, a simple example: if i've done user> (+ 2 3) |
| 21:50 | chessguy | and gotten back 5 |
| 21:51 | chessguy | i want to be able to do user> (+ 5 |
| 21:51 | chessguy | and then hit some combo |
| 21:51 | chessguy | to put the 5 from the previous evaluation into what i'm currently typing |
| 21:51 | Jedi_Stannis | *1 |
| 21:51 | Jedi_Stannis | ? |
| 21:52 | Jedi_Stannis | ,(doc *1) |
| 21:52 | clojurebot | "; bound in a repl thread to the most recent value printed" |
| 21:52 | chessguy | oh cool! |
| 21:52 | Jedi_Stannis | ,(doc *2) |
| 21:52 | clojurebot | "; bound in a repl thread to the second most recent value printed" |
| 21:53 | Jedi_Stannis | ,(doc *3) |
| 21:53 | clojurebot | "; bound in a repl thread to the third most recent value printed" |
| 21:53 | chessguy | ,(doc *42) |
| 21:53 | clojurebot | java.lang.Exception: Unable to resolve var: *42 in this context |
| 21:53 | Jedi_Stannis | lol |
| 21:53 | Jedi_Stannis | only 1 - 3 |
| 21:53 | chessguy | just checking :) |
| 21:53 | chessguy | ,(doc *4) |
| 21:53 | clojurebot | java.lang.Exception: Unable to resolve var: *4 in this context |
| 21:53 | chessguy | boo |
| 21:53 | chessguy | ok, better than nothing |
| 21:53 | chessguy | thanks! |
| 21:54 | Jedi_Stannis | no problem |
| 22:00 | cipher | can someone explain how to use the -> form |
| 22:01 | unlink | I guess one simple example of what I'm trying to do would be a basic implementation of map, where it accepts two parameters, a function and a list. I would like to pattern match on whether the list is empty or not; in the former case, map returns (); in the latter case, it retuns (cons (f x) (map f xs)) |
| 22:01 | Jedi_Stannis | ,(macroexpand '(-> 1 (+ 2) (* 3)) |
| 22:01 | clojurebot | EOF while reading |
| 22:01 | Jedi_Stannis | ,(macroexpand '(-> 1 (+ 2) (* 3))) |
| 22:01 | clojurebot | (* (clojure.core/-> 1 (+ 2)) 3) |
| 22:02 | Jedi_Stannis | bleh, doesn't expand all the way:( * (+ 1 2) 3) |
| 22:03 | Jedi_Stannis | unlink: you can't really pattern match in clojure like you can in haskell or other functional languages.... need to write a conditional or write some sort of pattern matching macro |
| 22:03 | unlink | oh. |
| 22:04 | unlink | Good excuse to learn reader macros, I suppose. |
| 22:04 | Jedi_Stannis | cipher: so if you want an imperative style, you can start with your data structure and list the functions you want applied to it |
| 22:04 | Jedi_Stannis | unlink: umm, clojure also doesn't have reader macros |
| 22:05 | Jedi_Stannis | ,(-> {} (assoc :a 1) (assoc :b 2) (assoc :c 3)) |
| 22:05 | clojurebot | {:c 3, :b 2, :a 1} |
| 22:05 | Cark | hey how is it imperative to start with data structures ? |
| 22:05 | unlink | I guess regular macros might be powerful enough? |
| 22:05 | Jedi_Stannis | yeah, it just will change the way you write it |
| 22:09 | cipher | so I can almost think of it like doto? |
| 22:09 | unlink | Thanks, Jedi_Stannis. |
| 22:12 | Jedi_Stannis | cipher: similar to doto, except instead of it applying methods to an object for side effects, it passes the result from one function call to the next, building up the result |
| 22:13 | cipher | got it. alright thanks. |
| 22:13 | Jedi_Stannis | cark: its not really imperative, just lets you write things in the order they happen, instead of reverse order by having to nest all the calls |
| 22:15 | Jedi_Stannis | your welcome |
| 22:17 | emacsen | I've just learned the comparison operators < and > don't work on strings |
| 22:17 | emacsen | Is there a deep reason for this? |
| 22:17 | Cark | i'll take the bait : what do you expect from the < operator on strings ? |
| 22:17 | Chouser | I think performance of numeric operations are generally cited. |
| 22:18 | Cark | byte by byte comparison ? character wise comparison ? what collating order then ? |
| 22:18 | emacsen | Chouser, right but shouldn't < be defmulti-ed |
| 22:18 | durka42 | emacsen: exactly. that would be slow(er) |
| 22:18 | emacsen | okay, so is there a generic function for this? |
| 22:18 | gnuvince_ | Cark: by the way, thanks for the suggestion of "compiling" my records this afternoon. I'm doing some rough tests here, but performance went from 115 seconds on my home PC for 1000+ files to ~90 |
| 22:19 | gnuvince_ | lambda++ |
| 22:19 | Cark | that's not as good as i imagined gnuvince ='( |
| 22:19 | gnuvince_ | Cark: well it is the first time I've done something like this, so I may have not been as efficient as I could. |
| 22:19 | emacsen | in other languages you can compare numbers, or dates, or strings and they use some inferior operator overloading. Is there a function I can use generically? |
| 22:19 | gnuvince_ | Cark: I'll push the code in a little while if you want to see the code. |
| 22:20 | Cark | gnuvince : i'd love to |
| 22:20 | Cark | emacsen : to me it does not make sense to use the same operator for strings and for numbers |
| 22:21 | Cark | is some kenji symbol smaller or bigger than the letter B ? |
| 22:21 | unlink | Is there a shorthand for (let [x (cond ...)] (if (nil? x) (...) x)) |
| 22:21 | unlink | Or maybe something more robust which lets me return nil from cond and still not evaluate the second (...) |
| 22:22 | emacsen | Cark, Maybe. But then I guess I have to figure out the right function |
| 22:22 | emacsen | and I won't know that ahead of time |
| 22:22 | Cark | emacsen : you have the full java stack at your fingertips |
| 22:22 | Cark | and pretty good docs too =) |
| 22:22 | emacsen | Cark, that's like saying "You have as much mud as you want to build the house of your dreams!" |
| 22:23 | durka42 | :) |
| 22:23 | Cark | maybe but that's efficient mud you dobn't need to recreate ! |
| 22:23 | durka42 | unlink: if-let maybe? |
| 22:24 | unlink | I guess like cond-else in scheme |
| 22:25 | Cark | ,you want some kind of when-not-let ? |
| 22:25 | clojurebot | java.lang.Exception: Unable to resolve symbol: you in this context |
| 22:28 | unlink | After some googling it appears that (cond) excepts :else in place of a condition. |
| 22:29 | gnuvince_ | Cark: http://bitbucket.org/gnuvince/clj-starcraft/src/tip/src/starcraft/replay/parse.clj#cl-41 |
| 22:29 | emacsen | okay, one last very dumb question. Why, if we have namespaces, can't I reuse names from the core? |
| 22:29 | Cark | gnuvince : checking it now |
| 22:29 | emacsen | eg I can't use "val" in my functions as an argument because it's already used in the core |
| 22:30 | Chouser | emacsen: you can, but you have to explicitly exclude those core names from being referred into your new namespace |
| 22:30 | Cark | emacsen : you can but you have to specifically import core |
| 22:30 | hiredman | ,((fn [val] val) 1) |
| 22:30 | clojurebot | 1 |
| 22:30 | emacsen | Wow both those options suck ;) |
| 22:31 | Cark | that's the same option =P |
| 22:31 | emacsen | Then it sucks twice as hard ;) |
| 22:31 | unlink | How is recur not 100% equivalent to using the name of the function in a tail position recursive call? |
| 22:31 | Cark | that's CLish |
| 22:32 | unlink | emacsen: I agree, the semantics are very surprising. |
| 22:32 | hiredman | unlink: cond does not take :else, :else is just convient because it evals to not nil (true) all the time so if it is reached it's clause will run |
| 22:32 | unlink | hiredman: oh, of course. |
| 22:32 | Cark | gnuvince : you still have the lookup in read-field |
| 22:32 | hiredman | ,(cond (= 1 0) :foo 1 :bar) |
| 22:32 | clojurebot | :bar |
| 22:32 | emacsen | unlink, well it's just I have been writing code lately and finding out quickly that I need to change a lot variable names because they're already in the core |
| 22:33 | emacsen | "val" has always been my default single value argument name |
| 22:33 | unlink | emacsen: I ran into the gotcha a few times today as well. |
| 22:33 | emacsen | and "seq" seemed like a good name for an argument which was a sequence passed in :) |
| 22:33 | unlink | I think the idiom is "coll" for that. |
| 22:33 | emacsen | fair nuff |
| 22:33 | gnuvince_ | Cark: the lookup to select the getting function? |
| 22:33 | Cark | right |
| 22:34 | unlink | Ok, I guess except for the use of recur with loop. |
| 22:34 | Cark | gnuvince : you could have a make-read-field function, then in compile record you prepare that function, and just use it in the returned lambda |
| 22:35 | Cark | i usually name these lamba compiling functions like this : make-frobnicator-fn |
| 22:35 | Cark | as this is not really compiling |
| 22:35 | gnuvince_ | ok |
| 22:36 | Cark | so that's one less lookup for you right there ...though i beleive this should not make a huge difference |
| 22:36 | gnuvince_ | As for a make-read-field function, won't I need to lookup the type anyway to select the right one? |
| 22:37 | Cark | well the type is already given in the field-specs right ? |
| 22:37 | gnuvince_ | Yes |
| 22:37 | Cark | mhh let me make a paste with some untested code |
| 22:37 | Cark | lisppaste8: url? |
| 22:37 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 22:40 | lisppaste8 | cark pasted "untitled" at http://paste.lisp.org/display/79053 |
| 22:40 | Cark | that's only to give the idea |
| 22:40 | Cark | and is actually completely wrong =/ |
| 22:41 | Cark | you want to prepare a list of functions |
| 22:41 | gnuvince_ | I'll give it a whirl |
| 22:41 | Cark | very wrong i put it in the returned lambda =P |
| 22:41 | cipher | ,(make-array (. Byte TYPE) [1 2 3]) |
| 22:41 | clojurebot | java.lang.ClassCastException: clojure.lang.LazilyPersistentVector cannot be cast to java.lang.Character |
| 22:41 | Cark | let me anotate again |
| 22:42 | cipher | What's the right way to do that? |
| 22:43 | Chouser | ,(into-array Byte/TYPE (map byte [1 2 3])) |
| 22:43 | clojurebot | #<byte[] [B@1eab16b> |
| 22:44 | lisppaste8 | cark annotated #79053 "untitled" at http://paste.lisp.org/display/79053#1 |
| 22:44 | Cark | that's more like it |
| 22:45 | lisppaste8 | cark annotated #79053 "untitled" at http://paste.lisp.org/display/79053#2 |
| 22:46 | Cark | gnih |
| 22:46 | gnuvince_ | All right |
| 22:46 | gnuvince_ | I'll test it out tomorrow at work when I need to pretend like I'm working |
| 22:47 | Cark | disregard the last one, i need to edit in emacs instead of firefox =P |
| 22:47 | unlink | Am I missing some clojure programming construct which allows me to avoid writing a cond like this? http://gist.github.com/100253 |
| 22:47 | gnuvince_ | hehe ;) |
| 22:48 | gnuvince_ | ,(map even? [1 2 3 4 5 6]) |
| 22:48 | clojurebot | (false true false true false true) |
| 22:48 | gnuvince_ | ,(mapgilter even? [1 2 3 4 5 6]) |
| 22:48 | clojurebot | java.lang.Exception: Unable to resolve symbol: mapgilter in this context |
| 22:48 | gnuvince_ | ,(filter even? [1 2 3 4 5 6]) |
| 22:48 | clojurebot | (2 4 6) |
| 22:49 | unlink | Ok, yes, I know it is a bit contrived. |
| 22:49 | gnuvince_ | unlink: the seq functions are prefered. |
| 22:50 | unlink | But the point of the function is not to return the even elements in the list, but rather the elements in even positions. |
| 22:50 | lisppaste8 | cark annotated #79053 "untitled" at http://paste.lisp.org/display/79053#3 |
| 22:50 | Cark | gnuvince : notice on how the vector? call is now out of the loop |
| 22:51 | Cark | err though the first bracnh of the size if is wrong, you get the idea |
| 22:52 | gnuvince_ | Yeah |
| 22:52 | gnuvince_ | I've bookmarked the page |
| 22:52 | Cark | pretty hard to give a solution without rewriting a whole bunch of it |
| 22:52 | gnuvince_ | One thing I've had to do to get more performance is to close over data instead of using vars. |
| 22:52 | unlink | In Haskell, you would do: evens [] = []; evens x = []; evens (x:y:xs) = y:evens xs |
| 22:52 | Cark | well, the var there is only called once |
| 22:53 | Cark | not inside the loop |
| 22:53 | gnuvince_ | Won't it be called every time I call make-read-field-fn? |
| 22:54 | Cark | yes, but you could do this a single time at compile time |
| 22:54 | Cark | or once a file |
| 22:54 | gnuvince_ | unlink: you want only the even indexed elements? |
| 22:54 | Cark | once for every field in every record type |
| 22:54 | unlink | gnuvince: Yes. |
| 22:54 | unlink | gnuvince: starting at 1 |
| 22:55 | gnuvince_ | ,(take-nth 2 [1 2 3 4 5 6]) |
| 22:55 | clojurebot | (1 3 5) |
| 22:55 | gnuvince_ | This starts at zero however. |
| 22:55 | gnuvince_ | ,(take-nth 2 (cons nil [1 2 3 4 5 6])) |
| 22:55 | clojurebot | (nil 2 4 6) |
| 22:55 | gnuvince_ | meh |
| 22:56 | unlink | I'm actually looking for a way to mimic the Haskell construction. |
| 22:56 | gnuvince_ | Cark: is there any good literature on using lambdas like that to optimize code and "compile" code? |
| 22:56 | gnuvince_ | unlink: Clojure doesn't have pattern matching, so you're pretty much out of luck there. |
| 22:57 | gnuvince_ | Go with the length |
| 22:57 | unlink | So (cond (nil? ...)) is the right construction? |
| 22:57 | Cark | i don't know, i learned this reading the source code of cl-pcre (the common lisp regex compiler made by edi weitz which is faster than perl) |
| 22:57 | unlink | @gnuvince_ |
| 22:58 | gnuvince_ | Cark: ok. |
| 22:59 | Cark | gnuvince : too bad you don't have some test files in there, i would give it a go =) |
| 22:59 | lisppaste8 | gnuvince pasted "evens" at http://paste.lisp.org/display/79054 |
| 22:59 | gnuvince_ | Cark: I have a script to get a bunch of them |
| 23:00 | lisppaste8 | gnuvince pasted "Download Starcraft replay files" at http://paste.lisp.org/display/79055 |
| 23:00 | unlink | gnuvince_: That doesn't lazily iterate the list, though. |
| 23:01 | unlink | s/list/collection |
| 23:01 | gnuvince_ | Cark: this is screen scrapping, so hopefully they didn't change their entire site. |
| 23:01 | gnuvince_ | unlink: it's not too hard to change that |
| 23:01 | Cark | is this python ? |
| 23:02 | unlink | gnuvince_: you mean and still not check whether car and cadr are nil? |
| 23:04 | gnuvince_ | Cark: yes. |
| 23:04 | Cark | i think i'll just download a couple files manually =P |
| 23:06 | gnuvince_ | Cark: wait |
| 23:06 | gnuvince_ | I'll put up an archive on a webserver |
| 23:07 | lisppaste8 | gnuvince annotated #79054 "lazy evens" at http://paste.lisp.org/display/79054#1 |
| 23:07 | unlink | ok, thanks, I have to run |
| 23:10 | gnuvince_ | Cark http://www.studio-cdd.com/replays.tar.gz |
| 23:10 | gnuvince_ | about 1050 files |
| 23:10 | Cark | quite a big file =) |
| 23:11 | gnuvince_ | yeah |
| 23:21 | replaca | good evening, clojurians |
| 23:21 | Cark | hello replaca |
| 23:51 | Cark | are you still there gnuvince ? |
| 23:54 | replaca | this is the time of night when tumbleweeds begin to roll through #clojure |
| 23:55 | Cark | hehe |