2009-10-23
| 00:28 | Licenser_ | somnium: I see forward to your driver :P I'm curiose about it |
| 00:29 | somnium | Licenser_: its 90% done, doing the build.xml will likely be the most unpleasant part :) |
| 00:31 | Licenser_ | since you mentioned mongodb earlyer I decided to use it for my next (current) project |
| 00:34 | somnium | I'm very impressed with it, schema-less storage plus ad-hoc queries |
| 00:36 | Licenser_ | even having some relations, it seems not too bad to query with all data stored in teh documents |
| 00:37 | Licenser_ | and the group queries make it nice to even ask the DB about every of the sub elements, with a link to their parents (since at least I usually require then right ahead too) |
| 00:37 | somnium | yes, in some cases you don't even need relations, comments just become an attached array |
| 00:38 | Licenser_ | *nods* I find that kind of sweet |
| 00:41 | somnium | there seems to be some good ruby/python drivers for it too, though I haven't tried them |
| 00:41 | Licenser_ | yea if this works out I might think about using it in ruby too |
| 00:42 | Licenser_ | hmm creating a static map of 1000x1000 fields takes qite some time so :P |
| 00:42 | somnium | ? |
| 00:42 | Licenser_ | for(var x=1; x <= 1000; x++) for(var y=1; y <=1000; y++) db.map.save({x: x, y: y, type: 255}); |
| 00:42 | Licenser_ | that takes some time |
| 00:43 | somnium | you can do mass inserts you know |
| 00:43 | somnium | that's 1000 * 1000 function calls vs. 1 :) |
| 00:44 | Licenser_ | somnium: too easy :P technically I don't need the entire map from the beginnig it's empty anyway |
| 00:44 | Licenser_ | but adding 3 fields and querieing over them is still somewhat fast |
| 00:44 | Licenser_ | then again not having the entire map stored is way better |
| 00:45 | Licenser_ | like only storing the interesting fields |
| 00:48 | Licenser_ | yes not storing them is the better way |
| 00:48 | Licenser_ | way better way |
| 00:48 | Licenser_ | just have to make a few tricks when inserting/updating |
| 00:49 | somnium | it does require a different approach for validating data |
| 00:49 | Licenser_ | and a different idea about storing data too |
| 00:49 | Licenser_ | in a SQL table I'd just create 1000x1000 entries - I mean who cares :P |
| 00:50 | Licenser_ | but if I want to search over an attribute in this data it kind of is slooow here |
| 00:50 | somnium | Licenser indexes! |
| 00:51 | Licenser_ | yes yes, I'm thinking about it but I query over a hashmap not over a value :P |
| 00:52 | Licenser_ | just rebuilding my huge db to see if that thing indexes well over that kind of data |
| 00:52 | somnium | ? indexes go on keys |
| 00:52 | Licenser_ | not sure, I'm finding it out now |
| 00:53 | Licenser_ | my data looks like: {x: 300, y:42, type: 4, owner: {'name' : 'Licenser', id: 42}} |
| 00:53 | Licenser_ | now I want to find 'all owerns' I do that by: db.map.group({key:{owner:true}, cond:{owner: { $exists : true }}, reduce: function(obj,prev) {prev.data.push(obj)}, initial: {data: []}}); |
| 00:53 | Licenser_ | which gives me a listof all owners and their map fields |
| 00:53 | Licenser_ | just taks 400ms on a 1000x1000 map |
| 00:54 | somnium | ah, you're using the shell? |
| 00:54 | Licenser_ | yes |
| 00:54 | Licenser_ | for testing out how to do things best :P |
| 00:54 | Licenser_ | also your lib isn't done yet |
| 00:54 | somnium | not everything in the shell is available in java yet :( |
| 00:54 | somnium | though you can eval javascript in a pinch |
| 00:54 | somnium | its still very much in development |
| 00:54 | somnium | lots of features supposed to be in next release |
| 00:55 | Licenser_ | oh crist, the index isn't what doing what I want :P |
| 00:56 | Licenser_ | it seems you only can have one index which makes it kind of useless for my task |
| 00:56 | Licenser_ | I can't index x,y (for fast queries on the position) |
| 00:57 | Licenser_ | and the owner |
| 00:57 | somnium | compound indices are possible |
| 00:57 | somnium | but only one index used at a time AFAIK |
| 00:57 | somnium | so x, y, x && y I guess |
| 00:57 | somnium | probably improvements coming in that area, its been coming up on the mailing list |
| 00:57 | somnium | btw, if you like mongo I recommend the mailing list, its very active |
| 00:58 | Licenser_ | sounds good |
| 00:59 | Licenser_ | hmm indexing the owner does not help to query about it |
| 01:00 | Licenser_ | that is very odd, I have the owner as index and the query still takes 300ms |
| 01:01 | Licenser_ | well I'll take care of this later on, it's past 7 am so time to sleep |
| 01:01 | somnium | cheers |
| 01:56 | piccolino | Is there some way to create a string as conjing repeatedly onto a stringseq? |
| 02:06 | arsatiki | p: are you trying to build a string from characters or from shorter strings? |
| 02:07 | piccolino | From characters. |
| 02:08 | arsatiki | AFAIK (which is not much, though) what you attempt is not possible |
| 02:08 | arsatiki | the java string is immutable, after all |
| 02:09 | arsatiki | but you can collect the chars into a seq and then (apply str ...) |
| 02:09 | piccolino | Oh, I didn't have a particular attachment to that particular way of doing it. I'm just needing to parse a string character by character into smaller chunks, and thought that it would be best to do it in term of seqs... |
| 02:15 | piccolino | OK, I think I get what I basically wanted by conjing to a vector and then calling str on that. |
| 02:15 | piccolino | Thanks. |
| 02:24 | hoeck1 | ,(apply str (map identity (seq "abc")) |
| 02:24 | clojurebot | EOF while reading |
| 02:24 | hoeck1 | ,(apply str (map identity (seq "abc"))) |
| 02:24 | clojurebot | "abc" |
| 02:24 | hoeck1 | @piccolino ^^ |
| 02:25 | hoeck1 | piccolino: its not overly efficient, I guess, but it takes you at least somewhere before diving into java |
| 02:26 | piccolino | I don't understand, doesn't this just turn the string into seq, return a seq of each character, and then turn that back into a string? |
| 02:33 | slashus2 | hoeck1: Why are you mapping identity to it? |
| 02:33 | hoeck1 | piccolino: yes, its just an example of working with seqs of characters |
| 02:33 | slashus2 | , (apply str (seq "abc")) |
| 02:33 | clojurebot | "abc" |
| 02:33 | hoeck1 | just to show it works |
| 02:34 | piccolino | Oh, I see. |
| 02:35 | hoeck1 | piccolino: sorry if I misunderstood your actual question, I thought it was about building strings out of character seqs |
| 02:36 | piccolino | Oh, it was, I was just trying to do it character by character without having to reverse a list on the way. |
| 02:37 | slashus2 | ,(apply str (reverse "abc")) |
| 02:37 | clojurebot | "cba" |
| 02:47 | piccolino | I have an even dumber question, which is how do I set the value of a variable during a loop? |
| 02:49 | jdz | piccolino: your mind is full of destructive thoughts |
| 02:50 | jdz | piccolino: you are not asking for what you want really. i'm pretty sure setting variables is not what you want. |
| 02:50 | piccolino | Am I gonna have to whip out a transaction for setting a state boolean during a parsing loop? |
| 02:51 | jdz | piccolino: why do you have a _state_ boolean in the first place? |
| 02:52 | hoeck1 | piccolino: no, you use recur to mutate loop invariants |
| 02:52 | piccolino | Because I gotta do different things depending on whether or not I'm in something that's quoted. |
| 02:52 | piccolino | Oh. |
| 02:53 | piccolino | Well that makes me kind of unhappy. |
| 02:54 | slashus2 | piccolino: What exactly is the problem you are trying to solve? |
| 02:54 | piccolino | Parsing a CSV file. |
| 02:54 | hoeck1 | piccolino: in java: for(int i=0, i<100, i++) {body}, in clojure: (loop [i 0] (when (< i 100) body (recur (inc i))) |
| 02:55 | piccolino | Yeah, but I've got to build up the vectors of row cells as I go, and that means every recur (of which there are several in the loop) is going to be like 5 or 6 lines each. |
| 02:55 | hoeck1 | piccolino: you basically use a loop-recur form |
| 02:55 | slashus2 | If you want to get the file-line by line you could use (line-seq on a reader. |
| 02:56 | hoeck1 | and then loop throug each line identifying columns and conjing them onto a vec |
| 02:56 | piccolino | I'm only working with the function that does a single line right now. |
| 02:57 | slashus2 | (line-seq (java.io.BufferedReader. (java.io.FileReader. "test"))) |
| 02:57 | slashus2 | returns a lazy seq of file lines |
| 03:01 | slashus2 | piccolino: Does that help? |
| 03:09 | piccolino | Yeah, I got that working. It looks bad to me, repeating all the state variables in every recur even if they shouldn't change. http://clojure.pastebin.com/m610e527c |
| 03:10 | piccolino | Any style comments? |
| 03:10 | piccolino | Maybe you can make me feel better about that. |
| 03:12 | hoeck1 | piccolino: you can just use a single state var, which uses a keyword describing its state, like :start, :quoting etc |
| 03:12 | slashus2 | I would probably split things into defn functions to make it more readable. |
| 03:14 | piccolino | I don't understand that comment hoeck1... there's only quoting... |
| 03:14 | slashus2 | Have you all ever embed a 3rd party applet into a swing program? |
| 03:15 | hoeck1 | piccolino: ok, you're right, then using keywords makes no sense and a simple flag is appropriate |
| 03:17 | arsatiki | picc: it seems to me you could cut down the amount of code somewhat by using (let [current-char ... remaining-chars] (cond ..)) |
| 03:17 | arsatiki | and perhaps that would allow you to see the bigger picture |
| 03:18 | piccolino | I don't understand... those have to change each time through the loop.. |
| 03:21 | arsatiki | right, there's that one case in the cond |
| 03:21 | arsatiki | missed that |
| 03:34 | piccolino | What's the difference between require and use? |
| 03:48 | hoeck1 | piccolino: require just loads the namespace, use puts all defined symbols of the used namespace in your current namespace |
| 03:48 | piccolino | Ah, OK, thanks. |
| 03:54 | piccolino | I wonder why I can use clojure.contrib.str-utils2, but not clojure.contrib.test-is. |
| 03:55 | liwp | anyone here used fnparse? |
| 03:57 | liwp | how do I define a parser that matches a literal string? Can I just use (lit "foo")? |
| 03:57 | liwp | the token stream is characters, so I thought maybe I can only use character literals and would have to define some sort of composite parser consisting of each literal char separately... |
| 03:58 | Chousuke | I think that's what you need to do. |
| 03:58 | Chousuke | there's lit-seq though, IIRC |
| 03:59 | arsatiki | piccolino: are you perhaps using a cutting edge clojure, where test-is is moved out of contrib and into clojure |
| 03:59 | piccolino | I don't know, that's what doesn't make sense. In Github, test-is is still there, it just loads clojure.test. But that doesn't work. I also can't load clojure.test. So yeah, it's strange. |
| 04:02 | arsatiki | p: This is a pure educated guess, but sounds like you have "old" clojure and "new" contrib |
| 04:02 | liwp | Chousuke: thanks, I'll look into it. I had my first look at fnparse yesterday evening, so I haven't gotten very far yet |
| 04:03 | piccolino | Ah, that is a possibility. I was in here a week or so ago complaining that there is no numbered release of contrib. |
| 04:04 | piccolino | I think that since I am using Slime right now, it might have pulled its own thing. |
| 05:16 | G0SUB | hmm, fuzzy completion works on the SLIME repl but not on Clojure files. any idea how to fix that? |
| 05:17 | AWizzArd | How did you get fuzzy completion to work? :) |
| 05:17 | G0SUB | AWizzArd: well, I did nothing. I am using ESK. |
| 05:18 | G0SUB | AWizzArd: in fact, no completion works on a clojure buffer. only on the repl. |
| 05:34 | liwp | G0SUB: try M-tab for completion |
| 05:34 | liwp | or Esc-tab if alt-tab switches windows |
| 05:35 | liwp | it's bound to (slime-complete-symbol) by default in a slime-enabled clojure buffer |
| 05:43 | G0SUB | liwp: well, it doesn't work. I get this in *Messages* funcall: Synchronous Lisp Evaluation aborted |
| 06:12 | liwp | G0SUB: it definitely works for me. Have you updated slime / swank-clojure recently (I haven't)? |
| 06:12 | liwp | G0SUB: hmm, I didn't try fuzzy completion actually. Give me a minute. |
| 06:13 | G0SUB | liwp: fuzzy completion works fine on the repl. not on open files. there is must be some setting... |
| 06:14 | liwp | G0SUB: yeah, you're right. It's doesn't work in clojure buffers for me either. I don't really use it, so I haven't noticed before. |
| 06:15 | G0SUB | liwp: any idea how it can be fixed? |
| 06:27 | liwp | G0SUB: nope |
| 06:28 | liwp | is the completion function the same in both the repl and the buffer, i.e. is M-tab bound to the same functin? |
| 06:28 | liwp | seems to be: slime-complete-symbol |
| 06:28 | liwp | I don't really know how to fix that... |
| 07:02 | AWizzArd | rhickey: about deftype: the idea to have assoc/dissoc converting to clojure maps is good. Maybe this can be made configurable? Maybe deftype could take an arg that says if conversion can happen or if it will produce an error. |
| 07:02 | AWizzArd | And maybe one could get a warning when conversion happens, and that behaviour could also be turned off in an arg to deftype. Or would that make things too complicated? |
| 07:04 | rhickey | AWizzArd: it's not a conversion. But yes, support will have to be configurable in some way else you couldn't use deftype to define PersistentMap (one of the objectives). So, at least, saying you implement Associative/ILookup etc will disable the automatically generated implementation |
| 07:06 | AWizzArd | Oh, so you plan to make a deep use of deftype? I first thought that it is just for the enduser.. but interesting perspective! |
| 07:07 | cgrand | rhickey: that means you plan to keep most interfaces? For compatibility? interop? perfs? Or am I reading too much in one sentence? |
| 07:07 | rhickey | AWizzArd: yes, I want to be able to write Clojure, and Clojure-like things, in Clojure |
| 07:08 | AWizzArd | i like this direction |
| 07:09 | rhickey | cgrand: I'm still working out the interface/protocol breakdown. I imagine many existing things will become both, mostly to reach to classes that can't implement new interfaces, but also working on making sure there is a good dynamic story |
| 07:13 | rhickey | the trick is to make a smooth spectrum with tradeoffs between dynamics/flexibility and speed, without requiring architectural changes in an app |
| 07:15 | rhickey | but the actual decisions about keeping particular interfaces will come later with cinc, not changing anything like that right now, just building the constructs we need |
| 07:19 | djpowell | rhickey: is there still a plan to rework IFn to support 4x (long, Object, double) parameters? |
| 07:20 | rhickey | djpowell: yes, the idea stands there and stares at me, but must wait :) |
| 07:21 | djpowell | rhickey: cool. just wondered whether it was in the queue, or whether it had been scrapped for some reason. |
| 07:22 | rhickey | for instance, much more important is to get datatypes in play, then can use them (+ macros) to crank out e.g. persistent vectors of primitives (which would otherwise require painful code duplication in Java) |
| 07:26 | djpowell | do datatypes + protocols interact with newnew at all? I haven't been following them |
| 07:29 | djpowell | protocols are a higher level construct that are an alternative to interfaces? |
| 08:19 | snowwhite07 | ping |
| 08:21 | snowwhite07 | Is there any feedparser in clojure? |
| 08:26 | snowwhite07 | cgrand, ? |
| 08:27 | cgrand | snowwhite07: yes? |
| 08:27 | snowwhite07 | cgrand, Is there any feedparser in clojure? |
| 08:28 | cgrand | haven't heard of one -- you should try java stuff I guess |
| 08:28 | snowwhite07 | cgrand, Thanks |
| 08:28 | jdz | snowwhite07: isn't an XML parser enough? |
| 08:29 | snowwhite07 | jdz, how are you suppose to parse feeds using XML parser? |
| 08:29 | jdz | snowwhite07: are you talking about RSS feeds or paper feeds? |
| 08:30 | cgrand | jdz: it depends if you want to handle all formats and all malformed feeds (especially regarding raw html content) out there in the wild |
| 08:30 | snowwhite07 | jdz, RSS feeds |
| 08:41 | patricius_ | Are there something equal to enumerations in Clojure? If I have a function that takes an argument, which can be one of two values, would I use a keyword for those value? Contrived example (defn [lamp-state] (if (= lamp-state :on) (turn-on-lamp) (turn-off-lamp)))? |
| 08:42 | patricius_ | Would I use keywords as enumeration values? |
| 08:43 | AWizzArd | ,((get {:on #(println "Clojure")} :on #(println "lamp is off"))) |
| 08:43 | clojurebot | Clojure |
| 08:43 | AWizzArd | ,((get {:on #(println "Clojure")} :off #(println "lamp is off"))) |
| 08:43 | clojurebot | lamp is off |
| 08:45 | patricius_ | Ok. Seems keywords are used in such scenarios. Thanks. |
| 08:46 | snowwhite07 | jdz, clojure.xml/parse is enough to parse RSS feeds :) |
| 08:46 | jdz | snowwhite07: according to cgrand only some of them |
| 08:46 | jdz | or, put another way, most of them |
| 08:50 | snowwhite07 | jdz, hmm |
| 09:13 | chouser | snowwhite07: you might try using http://commons.apache.org/sandbox/feedparser/ |
| 09:14 | chouser | this kind of event-driven API is annoying but might be worth it if you want to handle faulty feeds. |
| 09:15 | snowwhite07 | chouser, True Thanks |
| 09:29 | G0SUB | I am trying to use c.c.http.agent to download a zip file, but the file saved is always corrupt. wget works fine. any ideas? |
| 09:29 | drewr | G0SUB: code? |
| 09:29 | G0SUB | drewr: just a sec. |
| 09:30 | chouser | G0SUB: are you on Windows? |
| 09:31 | lisppaste8 | G0SUB pasted "HTTP Agent" at http://paste.lisp.org/display/89154 |
| 09:31 | G0SUB | chouser: no. Ubuntu. |
| 09:32 | chouser | is the file size correct? |
| 09:32 | G0SUB | chouser: file size is wrong. (the server doesn't return the size in the response) |
| 09:33 | chouser | the one your code saves out is too small? |
| 09:33 | G0SUB | chouser: it's actually larger than expected. |
| 09:35 | vy | There is a page listing documentations of clojure-contrib packages. What was the URL? |
| 09:35 | G0SUB | vy: http://richhickey.github.com/clojure-contrib/ |
| 09:36 | vy | G0SUB: How do I reach to that URL? I've been searching the web for half an hour. |
| 09:37 | G0SUB | chouser: any idea? is it because the server doesn't return the Length in the response? |
| 09:37 | G0SUB | vy: copy/paste the url on your browser? |
| 09:38 | vy | G0SUB: Huh? |
| 09:38 | G0SUB | vy: The URL is -> http://richhickey.github.com/clojure-contrib/ |
| 09:39 | chouser | G0SUB: I don't know -- you've alrady ruled out the most common issues I've seen. Next I'd check to make sure it's not a character encoding thing, and then I'd try to hunt down some examples or Java help for the apache lib. |
| 09:40 | vy | G0SUB: I just wanted to say that the URL is not mentioned in the clojure.org and hard to find via googling. |
| 09:41 | jdz | G0SUB: reading/writing binary files as character data? ugh... |
| 09:41 | G0SUB | vy: yeah, unfortunate. may be it should be mentioned on the webpage. |
| 09:41 | G0SUB | jdz: suggest a better way please :) |
| 09:42 | chouser | vy: "User contribs" in the top blue box at http://clojure.org/ |
| 09:44 | jdz | G0SUB: just don't use Printers and Writers, use the binary equivalents |
| 09:44 | jdz | (output and input Streams) |
| 09:59 | chouser | we're using google protocol buffer rpc interfaces from C++, Java, and Clojure. We can provide the cleanest usage in Clojure via macro. Next best is C++ (again, macros such as they are). Java has easily the most boilerplate and clumsy interaction. |
| 10:03 | G0SUB | jdz: I am new to Java. can you give me some pointers to reading/writing binary data? |
| 10:04 | jdz | G0SUB: http://java.sun.com/j2se/1.5.0/docs/api/java/io/OutputStream.html |
| 10:04 | liwp | G0SUB: as the main principle writers (and readers) deal with char data and outputsteams (and inputstreams) deal with binary data |
| 10:05 | G0SUB | liwp: anything in c.c that does that already? |
| 10:05 | liwp | dunno, probably something in duck-streams |
| 10:07 | liwp | looks like duck-streams specifically opens BufferedReader and PrintWriters, so it's doing exactly the wrong thing from your point of view |
| 10:07 | G0SUB | eww |
| 10:08 | G0SUB | liwp: I think duck-streams/writer can write to an outputstream |
| 10:09 | liwp | G0SUB: yeah, possibly |
| 10:10 | liwp | have you guys seen the cake on clojure.org - heh |
| 10:11 | Licenser | bah sometimes dynamic IP's from the ISP can be a pain ... |
| 10:15 | AWizzArd | Do we have users of clojure.contrib.sql here? |
| 10:16 | AWizzArd | I would like to know how to specify NULL for a ? placeholder in a prepared statement. |
| 10:16 | AWizzArd | nil doesn't work |
| 10:17 | AWizzArd | Example: (sql/with-connection *db-conn* (sql/with-query-results r ["SELECT ?" nil] (doall r))) |
| 10:19 | djork | AWizzArd: what's the error |
| 10:20 | AWizzArd | "org.postgresql.util.PSQLException: FEHLER: konnte Datentyp von Parameter $1 nicht ermitteln" which means: couldn't find out the datatype of parameter $1 |
| 10:29 | chouser | doesn't SQL have special syntax for null, like "WHERE foo IS NULL" instead of = |
| 10:31 | AWizzArd | yes |
| 10:31 | AWizzArd | just stumbled over this.. because "SELECT NULL" works |
| 10:34 | Licenser | AWizzArd: yes |
| 10:35 | Licenser | but NULL is a constant, rather then a value as chouser said, why would you want to replace it with a ? and not put it directlyß |
| 10:35 | Licenser | ? |
| 10:35 | djork | Licenser: what if you wanted to compare a value in the database to a clojure value that might be nil? |
| 10:37 | Licenser | djork: good question :P but what would be the expected result when you pass null? |
| 10:38 | AWizzArd | That would require two queries, if you expect to have nil values in Clojure. |
| 10:39 | AWizzArd | For non-nils you would compare using WHERE x=? and if you expect you could compare with nils then WHERE x IS NULL. |
| 10:39 | Licenser | or do evil magic things |
| 10:39 | Licenser | I think it would be possible to make =? become IS NULL when something is nil, question is if one wold want that |
| 10:42 | AWizzArd | yes, you can use cl-format which can do this |
| 10:44 | Licenser | (doc cl-format) |
| 10:44 | clojurebot | "clojure.contrib.pprint/cl-format;[[writer format-in & args]]; An implementation of a Common Lisp compatible format function. cl-format formats its arguments to an output stream or string based on the format control string given. It supports sophisticated formatting of structured data. Writer is an instance of java.io.Writer, true to output to *out* or nil to output to a string, format-in is the format control string and |
| 10:45 | Licenser | (+ 1 1) |
| 10:45 | clojurebot | 2 |
| 10:45 | Licenser | wow clojurebot works w/o the , |
| 10:45 | liwp | there's no stopping progress |
| 10:46 | djork | (and now we see if it evaluates every parenthetical mark) |
| 10:46 | djork | neat |
| 10:46 | liwp | pass |
| 10:46 | rhickey | (not) |
| 10:46 | djork | ("Only the ones that evaluate) |
| 10:46 | djork | oops |
| 10:46 | djork | ("Only the ones that evaluate") |
| 10:46 | djork | what's going on here :) |
| 10:46 | liwp | (not true) |
| 10:47 | cgrand | (+ "a") |
| 10:47 | liwp | maybe it was a fluke... |
| 10:47 | liwp | (+ 1 2) |
| 10:47 | clojurebot | 3 |
| 10:47 | Licenser | ('test') |
| 10:47 | djork | (inc 1) |
| 10:47 | cgrand | (str "test") |
| 10:47 | Licenser | (+ 'test' ' case') |
| 10:47 | djork | apparently it's only for + :) |
| 10:48 | Licenser | (+ "test" " case") |
| 10:48 | djork | + numbers |
| 10:48 | Licenser | yap |
| 10:48 | cgrand | (* 4 3) |
| 10:48 | clojurebot | *suffusion of yellow* |
| 10:48 | Licenser | (- 3 4) |
| 10:48 | clojurebot | -1 |
| 10:48 | Licenser | (* 4 3) |
| 10:48 | clojurebot | *suffusion of yellow* |
| 10:48 | Licenser | Someone likes douglas addams |
| 10:48 | Licenser | (* 3 3) |
| 10:48 | clojurebot | *suffusion of yellow* |
| 10:49 | Licenser | hrm |
| 10:49 | Licenser | (+ 4 1) |
| 10:49 | clojurebot | *suffusion of yellow* |
| 10:49 | Licenser | ah nice :) I love it! |
| 10:49 | Licenser | ,(+ 4 1) |
| 10:49 | clojurebot | 5 |
| 10:52 | Licenser | ,(tan 74) |
| 10:52 | clojurebot | java.lang.Exception: Unable to resolve symbol: tan in this context |
| 10:52 | Licenser | (. tan Math 74) |
| 10:52 | Licenser | ,(. tan Math 74) |
| 10:52 | clojurebot | java.lang.Exception: Unable to resolve symbol: tan in this context |
| 10:52 | Licenser | (.tan Math 74) |
| 10:52 | liwp | Licenser: tan is probably a static method |
| 10:52 | liwp | ,(Math/tan 74) |
| 10:52 | clojurebot | -5.737022539278999 |
| 10:53 | Licenser | ah sneakzy! |
| 10:53 | liwp | bless you |
| 10:53 | Licenser | (- 0 100) |
| 10:53 | clojurebot | -100 |
| 10:54 | Licenser | hah I found how to trick the calculator! And again it proves the feather is mighter then the sword, while wracking clojurebot with a sword has a apeal too |
| 10:54 | Licenser | (+ 0 (- 1 100)) |
| 10:55 | hiredman | the specs on the i ching calculator merely state anything above 4 is represented as a suffusion of yellow |
| 10:56 | Licenser | I know hiredman hence why I tried negative numbers :P |
| 10:56 | Licenser | (red) |
| 10:56 | Licenser | (press red) |
| 10:57 | Licenser | not implementet awww |
| 10:57 | Licenser | (red-button) |
| 10:57 | ankou | hi, how do I overwrite the .toString method of a structmap? I tried to overload print-method and it almost works but I get "\"hi\"" instead of just "hi" and I don't know where these quotation marks come from |
| 11:00 | hiredman | ankou: are you using prn-str? |
| 11:00 | ankou | no |
| 11:00 | hiredman | lets see the code |
| 11:01 | ankou | okay, are there any good clojure-supporting pastebins? |
| 11:02 | liwp | ~paste |
| 11:02 | clojurebot | lisppaste8, url |
| 11:02 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 11:02 | hiredman | lisppaste8: url |
| 11:02 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 11:03 | lisppaste8 | ankou pasted "toString" at http://paste.lisp.org/display/89155 |
| 11:04 | ankou | there it is |
| 11:05 | hiredman | uh |
| 11:05 | hiredman | something there doesn't seem right |
| 11:06 | hiredman | first, don't call .toString |
| 11:06 | ankou | then print-method is not what I'm looking for |
| 11:06 | ankou | because I want to pass the struct as an Object to a java class which calls .toString on it |
| 11:09 | hiredman | (.write writer (:name gm)) |
| 11:09 | ankou | is there another way to "overwrite" toString? |
| 11:09 | ankou | ah okay great |
| 11:09 | ankou | thanks |
| 12:11 | mwoelker | rhickey: hi, what are the chances of an externally contributed patch for http://www.assembla.com/spaces/clojure/tickets/64 getting into clojure? |
| 12:24 | mwoelker | rhickey: AFn already is serializable, so that covers a lot of ground, the only thing that seems to be missing (afaict) is Obj |
| 13:33 | cgrand | mwoelker: I don't know if AFn is really serializable despite being marked as such, the commit that added Serializable is dubious on the intent http://github.com/cgrand/clojure/commit/7cd3b285328e7e7e71b23080303d66640e0f21e8#diff-0 (but I'm not a java serialization expert). |
| 13:37 | hiredman | http://en.wikipedia.org/wiki/Serialization#Java |
| 13:42 | mwoelker | cgrand, yeah serializing arbitrary AFn probably won't work, but the thing I (and the original reporter) are after is serialization for standard clojure datatypes (Vectors, Maps, Seq etc) |
| 13:43 | mwoelker | cgrand, I wondered about that commit as well, another option might be to mark the relevant Classes as serializable further up the hierarchy |
| 13:44 | cgrand | do you have an idea why findbugs complained about missing Serializable? |
| 13:44 | mwoelker | cgrand, what is the policy on unit tests for the java code? these might be neat to have to see if the objects are indeed serializable |
| 13:45 | mwoelker | cgrand, I was just about to remove it to find out... |
| 13:47 | cgrand | I don't think there's one yet -- but the clojure tests exercise the java code as well |
| 14:04 | mwoelker | cgrand, okay I checked out the commit preceding the findbugs one and it gives me "Class clojure.lang.PersistentVector defines non-transient non-serializable instance field root" |
| 14:04 | mwoelker | root being final Object[] root; |
| 14:07 | cgrand | mwoelker: thanks for researching that |
| 14:09 | cgrand | mwoelker: btw I agree with you that having a single repo for ccw would be nice |
| 14:11 | mwoelker | cgrand: did you see http://github.com/manuel-woelker/ccw/tree/ccw-project-merge ? |
| 14:12 | mwoelker | cgrand: But I have no clue why FindBugs thinks PersistentVector should be serializable itself... |
| 14:18 | mwoelker | No Serializable or Externalizable in the implemented interfaces, no readObject()/writeObject() method as far as I can see |
| 14:19 | mwoelker | Hmm it would probably be cleaner to move the Serializable tags higher up the hierarchy |
| 14:44 | cemerick | rhickey: I'm turning back to the isa? caching again. (http://clojure-log.n01se.net/date/2009-08-31.html#15:13 was our prior conversation) Are you still amenable to a patch using "a persistent map of hashes to weak refs of class+cached-value thingies"? |
| 14:46 | cemerick | The possible alternative being to memoize isa? entirely, dropping the cache on any hierarchy change. As you said then, it's possible the class unloading issue is a non-issue (or, at least something we don't know the contours of yet). |
| 14:48 | rhickey | cemerick: I'd hold off for now. I'm looking at using some ideas from http://portal.acm.org/citation.cfm?id=1391960 for protocols and they might apply here as well |
| 14:50 | cemerick | rhickey: OK. Until then, I'm just going to bash out isa? with (memoize isa?) :-P |
| 14:51 | rhickey | there you go |
| 14:51 | cemerick | oh, see, I was trying to irk you a little bit :-) |
| 14:51 | rhickey | I'm pretty focused on the unification of reify/structs/types right now |
| 14:52 | hiredman | https://www2897.ssldomain.com/higherlogics/www/Wiki.ashx/Interesting+Language+Research <-- pdf of that paper is also here |
| 14:53 | cemerick | rhickey: Godspeed, and all that. |
| 14:54 | rhickey | thanks, I'll write up the most recent decisions shortly |
| 14:55 | rhickey | basically, structs can implement interfaces and get type tags, fast lookup all around, seamless transition from dynamic to static |
| 14:56 | rhickey | what I have been calling deftype becomes defclass, deftype will be a dynamic version, replacing most uses of structs |
| 14:57 | cgrand | rhickey, AWizzArd: I created ticket #205 (preserving hints on inlined and interop forms) and attached a patch. |
| 14:57 | cgrand | cemerick: with this patch, improved -> and ->> are less brittle: http://github.com/cgrand/clojure/commit/a027636d9ef857ee80cb13190731a2801684fe9c |
| 14:57 | cemerick | rhickey: I'm surprised you're wading into those namings. I don't have a problem with them, but defclass in particular has some baggage from some corners. |
| 14:58 | rhickey | cemerick: baggage from CL? |
| 14:58 | cemerick | that too, but I was thinking of Java classes as well. |
| 14:58 | cemerick | or .NET, or whatever |
| 14:59 | rhickey | cemerick: but that's exactly what this is for, defining Java classes |
| 14:59 | rhickey | or .Net or whatever |
| 14:59 | cemerick | it's a restricted set of interop though, right? |
| 14:59 | rhickey | cemerick: yes please |
| 15:00 | hiredman | so deftype will get me to the metal code generation like new new, and also let me name the class? |
| 15:01 | cemerick | I'm just playing the expectations game ahead a few moves. Fine by me if we need to push back on the completionists, but there will be some mismatch here and there. |
| 15:01 | rhickey | hiredman: defclass will let you name the class, all will do to-the-metal generation (based off reify work) |
| 15:01 | cemerick | Is genclass sticking around for über-interop? |
| 15:01 | cemerick | cgrand: oh, that's nice |
| 15:01 | rhickey | cemerick: for now, I really don't want to get sucked into interop right now. I want decent, high performing polymorphic constructs for Clojure |
| 15:02 | cemerick | That reminds me, I actually just noticed last night that transients aren't yet up to speed w.r.t. meta. |
| 15:02 | rhickey | cgrand: I'll take it, thanks,, could you please create issue/patch |
| 15:02 | rhickey | ? |
| 15:04 | rhickey | reify - anonymous, created right then, direct method impls, deftype - anonymous, type tag, factory fn, direct method impls, fast field lookup, defclass - named, AOT, direct method impls, accessible ctor, fast field lookup *and* .field access |
| 15:05 | cemerick | rhickey: and 'direct method impls' means no redirection to another fn in an ns? |
| 15:05 | rhickey | cemerick: right, Clojure code in method bodies directly |
| 15:06 | rhickey | typed fields all around |
| 15:06 | chouser | how can you do that with named classes? |
| 15:06 | chouser | oh, AOT only for those. |
| 15:07 | hiredman | to the metal named class generation is what I really missed working my reader |
| 15:07 | chouser | hiredman: why did you need named? |
| 15:08 | rhickey | chouser: yes, the beautiful thing is not with reify + defstruct, you can write completely dynamically (but still get interface impls), then any time you want you can 'bake' by switching deftypes to defclass, without changing any code except factory fn |
| 15:08 | hiredman | chouser: so I could use my reader to read in clojure code before core was loaded |
| 15:08 | rhickey | sorry, deftype, not defstruct |
| 15:09 | rhickey | so even though deftypes are anonymous, they use type tags that protocols will look at, and the method bdies are inlne and fast |
| 15:09 | rhickey | so you can fully redef dynamically |
| 15:09 | chouser | 'baking' there would buy you faster jvm-inlinable field access? |
| 15:10 | hiredman | right now my reader is all in one fn (containg a letfn) and when that namespace is compiled it writes the name of the fns class to a properties file, which RT reads at start up to find out the name of the reader's class so it can load the reader |
| 15:10 | rhickey | will be limited to :field lookup, which I intend to make very fast, compiled per type vs. current defstruct lookups |
| 15:10 | rhickey | chouser: baking buys you external name, .field access, direct ctor access |
| 15:10 | rhickey | not much more really |
| 15:11 | rhickey | but when you need it, it's there |
| 15:12 | rhickey | OTOH the dynamic story is substantially improved, much faster methods, interfaces for structs(now types), protocols work with type tags, full live redef w/o restart |
| 15:12 | cgrand | rhickey: ticket #206 created |
| 15:12 | rhickey | protocols will *not* work with hierarchies on type tags |
| 15:12 | rhickey | cgrand: thanks! |
| 15:13 | chouser | rhickey: so that's a key differentiator between protocols and multimethods |
| 15:13 | rhickey | chouser: yeah, I've basically had it with implementation inheritance, it's a bad idea whose time has gone |
| 15:16 | hiredman | interface inheritence + functions? |
| 15:16 | rhickey | I'v ealso been thinking about explicit implemant clauses in the body, allowing for body clauses to be subject to macroexpansion, thus enabling code-sharing macros: |
| 15:16 | rhickey | (deftype Foo [x y #^int z] |
| 15:16 | rhickey | (implement [Iterable] (iterator [] ... x y ... this ... ))) |
| 15:17 | rhickey | then you could write (implement-Foo-given a b c) macros calls in the body |
| 15:17 | chouser | that's an interesting idea that presents itself very quickly even with older plans for new new |
| 15:17 | chouser | henceforth referred to as "old new new" |
| 15:18 | rhickey | reify will survive. Basically these are all flavors of the same thing, the trick is finding the core |
| 15:18 | chouser | if the facility isn't made available directly in deftype and friends, it's just a matter of time before some macro would be created to allow some kind of modular implementation insertion. |
| 15:23 | rhickey | https://www.assembla.com/spaces/clojure/documents/download/deftypes.pdf |
| 15:24 | rhickey | chouser: I want to try to support that from the start, thus the separate clauses and the promise to macroexpand |
| 15:25 | rhickey | the above is my scratch diagram, you can see how closure creates a set of fields, as does explicit listing of fields, from there interface method impl is the same, then there's just more default behavior... |
| 15:26 | rhickey | so I just need to tweak what I've been doing for reify to support at least the 3 latter cases (the first (fn) is already handled, but could be redefined in terms of reify) |
| 15:28 | rhickey | one things that's become apparent is the fact that auto-implementing interfaces will require they have better-distinguished method names, like meta__clj, valAt__clj etc, else potential for name conflict when merged with interface set |
| 15:30 | chouser | so deftype has a type tag, but this would not be used for protocols. protocols would instead use the actualy host interfaces the deftype implements. the type tag could still be used for multimethod heirarchies |
| 15:31 | chouser | rhickey: do you "think" in omnigraffle, or is it part of collecting your raw notes for eventual docs? |
| 15:33 | rhickey | chouser: I "think" in omnigraffle quite a bit |
| 15:34 | rhickey | chouser: no, type tags would be used by protocols, just no tag inheritance |
| 15:34 | rhickey | so you can work with protocols, deftype, type tags and completely ignore more static interfaces + classes |
| 15:35 | rhickey | yet at any time, incrementally: back up a protocol with an interface, implement an interface with a deftype, move a deftype to a defclass, swap .field for :field, without any architectural disturbance |
| 15:38 | rhickey | (deftype ::Foo [a b c]) ... (defprotocol Bar (baz [x])) ... (implement Bar ::Foo (baz [afoo] (:b afoo)), or something |
| 15:38 | rhickey | no Java at all |
| 15:38 | rhickey | all dynamic |
| 15:39 | rhickey | (defprotocol Bar :on IBar (baz [x])) |
| 15:39 | rhickey | (deftype ::Foo [a b c] (implement IBar (baz [] b)) |
| 15:39 | rhickey | etc |
| 15:40 | rhickey | smooth dynamic/performance tradeoff, same architecture |
| 15:42 | rhickey | oops, stick a (definterface IBar (baz [])) in there |
| 15:42 | rhickey | definterface and defclass are AOT |
| 15:43 | chouser | but not needed until you decide to decorate your defprotocol with :on |
| 15:43 | rhickey | right |
| 15:43 | chouser | well, it sounds beautiful to the extent that I understand it so far. :-) |
| 15:44 | rhickey | I intend to make defprotocol + deftype perf very satisfying, so the other is mostly about interop, or ultimate Java perf parity |
| 15:45 | rhickey | but as cemerick noted, this is still not a full interop story, it's just for nice interop |
| 15:45 | rhickey | ugly interop is, well, ugly |
| 15:46 | rhickey | it's quite amazing how much cruft comes in with impl inheritance |
| 15:47 | chouser | yep. and even if interop uses reify internally, there's hardly any value in making its usage look like these native def*s. When you're doing interop with existing Java, you know you're doing interop from the beginning. |
| 15:47 | rhickey | possible inheritance of some declared interfaces |
| 15:47 | rhickey | ctor bodies |
| 15:47 | rhickey | super ctor calls, field inits |
| 15:47 | rhickey | super method access, protected |
| 15:48 | rhickey | well designed Java should use interfaces and thus work well with this |
| 15:49 | rhickey | and, it provides a recipe for specifying how to interact with your app from Java |
| 15:49 | rhickey | static factory methods TBD |
| 15:50 | rhickey | plus you write your code to protocols and never have a question about being able to make it 'reach' anything |
| 15:50 | rhickey | protocols will fastpath the :on interface |
| 15:50 | chouser | I guess that would be the exception then, if you assume it's well designed Java, start using defprotocol, then realize you've got a protected field or something and have to fall back on the (ugly-interop ...) form |
| 15:50 | cemerick | What I'd like to see is the ability to write Java in-line in clojure files, and have that compiled out to standalone classes, etc. That would keep all the gnarly interop out of the designs of the clean interop and clojure-only stuff, and be a boon for optimizing hotspots, too. Sort of like how you can write C in python, or ASM in C, etc. |
| 15:50 | chouser | uh oh. |
| 15:51 | rhickey | cemerick: what I've been calling host-in-parens |
| 15:51 | cemerick | ah, sure |
| 15:51 | drewr | a way to make a perfectly terse clojure fn into 300 lines |
| 15:52 | riddochc | Hi, folks. Anyone else having problems with firefox's rendering of the Clojure API page when trying to scroll to anyplace but the top of the page? It's terribly javascript-heavy, for what it is... |
| 15:52 | rhickey | cemerick: but it won't be necessary for hotspots/optimization - the inline Clojure method bodies will produce the same code as Java, leverage primitive fields etc |
| 15:52 | hircus | speaking of which, where is the defprotocol design doc? |
| 15:52 | chouser | hircus: http://www.assembla.com/wiki/show/clojure/Protocols |
| 15:52 | chouser | more live notes than design doc |
| 15:52 | hircus | chouser: thanks |
| 15:53 | chouser | in fact, it's already out of date. :-) |
| 15:53 | cemerick | rhickey: Definitely, it's going to be an improvement, but surely there will be times when Java still laps clojure. *shrug* |
| 15:53 | rhickey | cemerick: like what? |
| 15:53 | rhickey | when |
| 15:54 | rhickey | ? |
| 15:55 | cemerick | I've no idea off the top of my head. Perhaps I'm just vastly underestimating you. :-) |
| 15:55 | AWizzArd | cemerick: I think we should look at it and see the differences. I already have code waiting for deftype, where I am currently using a struct. I also wrote a pure Java class and so will be able to see the direct comparison. |
| 15:56 | cemerick | The notion of generating the same bytecode as Java using clojure somehow seems too good to be true. |
| 15:56 | rhickey | cemerick: it's not me, just a matter of: inline in a method all primitive stuff is the same, type-hinted method calls are the same, hinted array access is the same, recur is goto |
| 15:56 | rhickey | you have to opt out of safe math etc, but you can already |
| 15:57 | rhickey | as cgrand saw with early reify, the perf was the same as the Java |
| 15:58 | rhickey | the only thing left is boxing across a fn call boundary |
| 15:58 | cemerick | oh, I'm sure it'll be neck-and-neck in many (most?) cases. I'm just assuming that someone will have an algorithm in java that won't be amenable to a comparable clojure impl. |
| 15:59 | rhickey | cemerick: the point of this is to make that not true |
| 15:59 | hiredman | you can do a lot with loop/recu |
| 15:59 | hiredman | r |
| 15:59 | hiredman | algorithmicly speaking |
| 15:59 | AWizzArd | in some very strange cases there may be a need for reflection |
| 16:00 | AWizzArd | but in those cases you would be doing things that won't be possible in Java then |
| 16:00 | hircus | cemerick: Scala does quite well in that regard, I don't see why it's impossible |
| 16:00 | rhickey | cemerick: but to match you will have to have types, primitives, bad math etc |
| 16:00 | AWizzArd | yes |
| 16:01 | rhickey | AWizzArd: you have an example of something you can't type hint the reflection off of? |
| 16:01 | cemerick | hircus: I wasn't trying to say it was impossible. |
| 16:02 | cemerick | I guess I'm just remembering the painful "clojure is/isn't as fast as java" threads from some months ago. |
| 16:02 | hircus | cemerick: fair enough |
| 16:02 | AWizzArd | rhickey: you could at runtime have a (if ...) returning an object on which you will then call a method |
| 16:03 | AWizzArd | (.method (if (pos? x) "10" (File. "/foo.txt"))) |
| 16:03 | hircus | rhickey: sorry if this has been brought up before, but at the cost of mis-alignment with Java interfaces, could we have protocols be "traits" (ala Scala), in that they supply some implementation functions but not all? |
| 16:03 | AWizzArd | only at runtime it becomes clear which .method we want to call |
| 16:03 | hircus | I think at bytecode level what happens is Scala generates both an interface and a singleton class with the methods |
| 16:04 | AWizzArd | or changing the namespace dynamically.. but as I said, this is very strange stuff and only finds its place in esoteric programs |
| 16:05 | AWizzArd | rhickey: one nice side effect of deftyped objects would be their integration in Drools :) |
| 16:06 | rhickey | AWizzArd: ah, yes, Drools, but not for deftype as the actual class might change on re-eval, even though they are POJOs |
| 16:07 | rhickey | hircus: I don't like Scala traits, nor implicits |
| 16:08 | hircus | rhickey: fair enough. because they make the code harder to reason about? |
| 16:08 | rhickey | hircus: yes, totally |
| 16:08 | hircus | I guess I normally only use implicits to work around Scala's lack of macros (i.e. for creating infix ops) |
| 16:08 | rhickey | I wouldn't want to work with a system that used traits extensively |
| 16:10 | cemerick | implicits scared the crap out of me once I used them for a month |
| 16:10 | hircus | I personally find implicits scarier, but traits and mix-ins are.. pretty much common in most OO languages, right? |
| 16:11 | rhickey | and implicits for the expression problem is just auto-adapter pattern, with all the negatives of adapter |
| 16:11 | hircus | granted, Python does its multiple inheritance the other way around -- first definition of a method wins |
| 16:11 | AWizzArd | rhickey: Drools will also work perfectly fine with the data structures that Clojure offers today. Those rules just won't run as efficient. And that may change with deftyped objects. I will see this maybe this year. |
| 16:11 | rhickey | hircus: no, both Java and C# disallow multiple inheritance of implementation |
| 16:12 | hircus | I guess the nice thing about implicits (if any) is precisely that people don't have to reimplement a pattern (and get it wrong). Like how they have the Singleton object |
| 16:12 | hircus | rhickey: ah, I mean all but Java and C#. I see Scala's traits as a reaction to the limitation of an interface-only multiple inheritance, since sometimes it does make sense to share method definitions |
| 16:12 | rhickey | hircus: it's still a bad pattern |
| 16:13 | chouser | every namespace is a singleton :-) |
| 16:14 | Kjellski | Good evening (maybe you´re in my timezone=) |
| 16:14 | rhickey | adapter pattern: requires allocation on wrap, the wrapper isn't-a wrappee, issues with identity, can't reach 2 adaptation targets in a single flow... |
| 16:16 | hircus | chouser: yup, so happily Clojure has that solution too. in fact, if you use Python, a module is a singleton too, really, I don't see why people always try to reimplement the singleton constructor in Python (because they can, I guess) |
| 16:16 | rhickey | hircus: there's a difference between sharing an implementation and creating a derivation relationship to do so. Also mixins have terribly complicated diamond resolution strategies - always |
| 16:17 | hircus | rhickey: good explanation, thanks. |
| 16:20 | rhickey | so, one thing about deftype/defclass is that method bodies are *not* closures |
| 16:21 | chouser | because their fields are explicit instead |
| 16:21 | AWizzArd | Which is the more general of those two? |
| 16:21 | rhickey | (let [a 42] (deftype Foo [x] (implement IBar (baz [] a) <-- error, a not seen in baz |
| 16:22 | rhickey | this one of the compromises |
| 16:22 | cemerick | well, deftypes are generally going to be top-level anyway, right? |
| 16:22 | AWizzArd | Well, I think this is no problem at all. It's just that some defstructs would be replaced by deftype. |
| 16:22 | rhickey | cemerick: I imagine so |
| 16:22 | Kjellski | Is it possible to have more than one "(recur ..." in a loop body? |
| 16:22 | rhickey | AWizzArd: defstructs have no methods now anyway |
| 16:23 | chouser | Kjellski: yes |
| 16:23 | AWizzArd | right |
| 16:23 | Kjellski | ty |
| 16:23 | chouser | (loop [] (if ... (recur ...) (recur ...))) for example. |
| 16:23 | lpetit | Kjellski: as long as they are in tail position, of course |
| 16:23 | AWizzArd | I just didn't know that deftype/defclass can have some. |
| 16:23 | chouser | I've decided "tail position" is a misleading term. sounds like there's only one. |
| 16:24 | Kjellski | chouser : You guessed where this is going to lead... frightening... ^^ |
| 16:24 | chouser | more of a syntax tree "leaf position" |
| 16:24 | chouser | hm, no that's not right either |
| 16:25 | hiredman | but you can only follow one code path through an if at a time |
| 16:25 | chouser | control structure leaf position |
| 16:25 | hiredman | so there is only one tail for any given branch |
| 16:25 | chouser | hiredman: I suppose. so tail position of a function *call*. leaf position of a function definition. |
| 16:26 | hiredman | huh? |
| 16:26 | chouser | if you're looking at a function definition there are multiple tail positions. it's only when you're running the fuction that you have to choose a single one. |
| 16:27 | chouser | s/are/could be/ |
| 16:27 | hiredman | *shrug* |
| 16:27 | hiredman | I'm just going to call them tail calls |
| 16:28 | chouser | I'm just saying it's a somewhat confusing topic to FP newcomers, and using the word "tail" tends to lead people to believe something that's likely to cause more confusion. |
| 16:29 | chouser | I don't expect to get everyone to call it something different of course. |
| 16:30 | hiredman | damn |
| 16:31 | hiredman | chouser made me think about loop/recur which made me think about all the java loops -> loop/recur translation I've been doing, which made me realize there is a bug in my reader |
| 16:32 | chouser | heh. happy to help. :-) |
| 16:35 | rhickey | another open question possibly not eveident from the diagram (is anything evident from the diagram? :) - ther may be just one factory fn for deftypes - I'm thinking (Typename vals [extension-keyvals]) |
| 16:36 | rhickey | so you'd always have to supply all fields. You could of course write other factory fns on top of that |
| 16:38 | cemerick | rhickey: what's the line on expando at the moment? |
| 16:39 | rhickey | whereas currently you have (struct s vals) and (create-struct s inits) |
| 16:39 | cemerick | (wow, that's such a horrible term) |
| 16:39 | rhickey | cemerick: it will be an option, possibly the default, defeated by an impl of Associative |
| 16:40 | cemerick | wonderful |
| 16:40 | rhickey | I'm not yet sure of how to control the various auto-impls, I can see situations where you might want none of them |
| 16:41 | rhickey | they are meta, type, lookup (get), expando (assoc) |
| 16:41 | rhickey | probably more, like Seqable |
| 16:42 | rhickey | also in question, are deftypes j.u.Maps? I'd prefer not |
| 16:42 | rhickey | maps serve dual purposes in Clojure, as small structs and large collections, only the latter use really maps to j.u.Map |
| 16:43 | cemerick | presumably, that's an area where one would want a generic extension point (referring to auto-impls there) |
| 16:44 | chouser | as differentiated by whether they keys to the map show up literally in the code |
| 16:44 | cemerick | IMO, I'm happy to copy into a j.u.Map if I need one from a struct |
| 16:44 | rhickey | chouser: ? |
| 16:44 | rhickey | chouser: got it, nevermind |
| 16:45 | chouser | if a maps keys are in your code literally, it's a struct-like map. if... ok. |
| 16:46 | rhickey | cemerick: generic extension is tricky as you'd need to communicate the field details, and some extensions add fields |
| 16:46 | rhickey | cemerick: but I agree, interesting |
| 16:47 | chouser | does that suggest something more specific than general macroexpansion in the body of a deftype? |
| 16:48 | rhickey | some things are self contained - like meta and type, and already there it's complex - type wants to add a static field |
| 16:49 | rhickey | other things need to process the set of fields, like lookup, and even there, some fields are implementation details |
| 16:49 | rhickey | the full semantics for extension could get pretty involved |
| 16:50 | rhickey | wheras it's easier with macros - a macro could ask you to supply the names of public fields, and the name of a field it could use etc |
| 16:51 | rhickey | whereas |
| 16:54 | cemerick | heh, memoizing isa? gets me another 2x speedup on a particular chunk of fns (rather than memoizing bases and supers separately) |
| 16:55 | rhickey | cemerick: just wait till perfect hashing makes that a direct lookup :) |
| 16:56 | cemerick | perfect hashing? |
| 16:56 | rhickey | you didn't read the paper from before yet? :) |
| 16:56 | cemerick | ha. I'm too busy trying to keep the trains on the tracks at the moment. :-/ |
| 16:57 | rhickey | Perfect Hashing as an Almost Perfect Subtype Test |
| 16:57 | cemerick | compatible with hierarchies, As We Know Them? |
| 16:58 | rhickey | cemerick: I haven't thought much about their application there, but I don't see why not |
| 16:58 | cemerick | well, joy :-D |
| 17:05 | rhickey | actually, for a stable map with keyword keys, where it makes sense, you could define a general (perfect-hash map) -> perfect-hashed-map |
| 17:06 | cemerick | it's funny, I put this in my to-read queue earlier this week: http://research.microsoft.com/en-us/um/people/hoppe/perfecthash.pdf |
| 17:07 | rhickey | neat! |
| 17:17 | cemerick | yeah. of course, I fall down on the math, but I can generally hack my way to vague understanding :-) |
| 17:25 | AWizzArd | the map issue ("deftype is j.u.Map or not?") is not so easy to answer.. in principle *all* collection types like lists, pojos, hashmaps, etc. are mappings |
| 17:25 | rhickey | AWizzArd: but not all POJOs are j.u.Maps |
| 17:25 | AWizzArd | true |
| 17:26 | AWizzArd | What would a disadvantage of deftypes being j.u.Maps? |
| 17:26 | rhickey | obviously I agree with the sentiment there, that's why maps play the various roles they do in Clojure, OTOH, they can do that by implementing ILookup and Associative w/o j.u.Map |
| 17:28 | rhickey | deftypes are more like POJOs in that you'll use them to implement other higher-level things. If you use one to implement a Vector or Set, would you still want it to be a Map? |
| 17:28 | AWizzArd | no |
| 17:28 | rhickey | or, conversely, who would need/use them that way? |
| 17:28 | rhickey | i.e. why put in if not needed? |
| 17:29 | AWizzArd | So, the idea to make them maps just came up, because those are used everywhere in Clojure. |
| 17:30 | AWizzArd | Someone else coming from outside would not have even thought about making deftypes a map? |
| 17:31 | rhickey | AWizzArd: specifically java.util.Map, they will support get and assoc, associative destructuring etc, will print like map variants... |
| 17:31 | rhickey | all I am talking about is the standard Java interface |
| 17:32 | AWizzArd | yes |
| 17:32 | AWizzArd | And that sounds very nice of course, especially for those cases that I have in mind: replacements for defstruct. |
| 17:33 | rhickey | you are passing structs to Java APIs that take j.u.Maps? |
| 17:33 | AWizzArd | no |
| 17:34 | AWizzArd | I use structs as containers for my objects |
| 17:34 | AWizzArd | those objects live in one very big container, a ref |
| 17:34 | AWizzArd | (sometimes refs in refs) |
| 17:35 | AWizzArd | and functions that operate on my struct objetcs will use assoc and get |
| 17:35 | AWizzArd | if I now could basically replace defstruct with deftype then the code would still work |
| 17:36 | rhickey | AWizzArd: yes, that has nothing to do with j.u.Map |
| 17:36 | AWizzArd | oki :) |
| 17:37 | rhickey | j.u.Map doesn't have functional style assoc |
| 17:39 | AWizzArd | My main use of deftype (or defclass?) would be to replace defstruct. Not for implementing big things such as a Vector or Set. |
| 17:42 | AWizzArd | enduser use |
| 17:43 | AWizzArd | but nice surprise that you have plans to make them so generic that you can actually rewrite Clojure types in it |
| 17:43 | hiredman | well, thats what is driving this, right? |
| 17:43 | rhickey | AWizzArd: a big point is to enable writing Clojure's data structures in Clojure |
| 17:44 | AWizzArd | It's good |
| 17:45 | rhickey | so no one's complaining that you can derive only from interfaces |
| 17:52 | uninverted | What's the idiomic way to run external programs in clojure? Something like "system 'foo'" in ruby and perl and whatnot. |
| 17:58 | Chousuke | uninverted: contrib has the shell-out thingy. |
| 18:04 | lpetit | uninverted: shell-out rocked for me. |
| 18:04 | uninverted | Thanks, I'm downloading contrib now |
| 18:06 | lpetit | rhickey: Maybe not anybody (me, for example) has the understanding of what it will imply to restrict types derivation from interfaces. It's too much for me to currently project all these upcoming use cases. |
| 18:07 | lpetit | rhickey: not doing it now (deriving from e.g. protocols) will prevent or really compromise doing it later ? |
| 18:09 | ztellman | has anyone had a problem where some instances of clojure can locate a class, and others can't? |
| 18:10 | ztellman | I'll be working smoothly, close the process, reopen it, and all of a sudden quicktime.sd.QDGraphics is nowhere to be found |
| 18:10 | ztellman | though every other class in that namespace seems available |
| 18:10 | ztellman | I can't figure out any pattern to it, and it's missing a lot more often than not |
| 18:11 | hiredman | ztellman: you aren't using add-classpath are you? |
| 18:11 | ztellman | hiredman: no |
| 18:12 | ztellman | I'm using QTJava, which is native to my OS |
| 18:12 | ztellman | no classpath changes are necessary |
| 18:32 | uninverted | How do you suspend execution for a certain amount of time, like "sleep N" in ruby and perl and whatnot? |
| 18:32 | chouser | (Thread/sleep 1000) ; one second |
| 18:33 | ztellman | so the problem was that I had to initialize quicktime before I could even import certain classes |
| 18:33 | uninverted | Ah, I tried Thread/sleep, though it was in seconds. Thanks. |
| 18:38 | leafw | ,(prn (str "id=\"123\"")) |
| 18:38 | clojurebot | "id=\"123\"" |
| 18:38 | leafw | why the backslashes? I'd appreciate help in avoiding them |
| 18:39 | leafw | (this is a test case of a much larger (prn (str ...)) |
| 18:40 | hiredman | prn prints things in a way that can be reader back in |
| 18:40 | leafw | ,(print (str "id=\"123\"")) |
| 18:40 | clojurebot | id="123" |
| 18:40 | leafw | I see -- thanks hiredman |
| 18:48 | leafw | and is there any way to insert several of lines of text verbatim, the equivalent of """ ... """ in python? |
| 18:48 | leafw | as a String |
| 18:49 | hiredman | nope |
| 18:50 | leafw | would be nice to have. Perhaps a modification of (comment ....) |
| 18:51 | leafw | that returned it content as a STring. |
| 18:51 | hiredman | nope |
| 18:51 | hiredman | the input to macros has already passed through the reader |
| 18:58 | riddochc | I don't suppose it's possible that sort or sort-by can avoid consuming a whole sequence that it's meant to work on? ;) |
| 18:59 | Licenser | hmm hmmm likely not |
| 19:00 | Licenser | I guess you could work with tricky heuristics to sort a sequence good enough but then agian that's very ... strange |
| 19:00 | Licenser | I've read about algorithms for heaps that work on a basis that isn't entire correct but 'good enough' to give correct answers, then again I'm not sure if you could apply the same tricks ehre |
| 19:02 | riddochc | Yeah, I figured... wishful thinking, in my case. |
| 19:03 | Licenser | well if you know the items in a list you could kind of cheat, I mean min and max |
| 19:10 | riddochc | What I need is kind of like this: (if-nth-most predictate sort-predicate sequence) |
| 19:12 | riddochc | If I could avoid having to sort the list before iterating over it to find the first element that my first predicate returns true for, it would be less computationally intense, but I don't think I can really make it truly lazy. |
| 19:15 | riddochc | Hmm. Actually, a better name might be nth-most-such-that, or nth-most-where |
| 19:24 | riddochc | No... that's not quite it, either. max-such-that. That's closer to what I mean. |
| 19:27 | chouser | but you can't know you've found the max until you've gotten to the end. |
| 19:30 | chouser | rhickey: no, no complaints about deriving only from interfaces for native clojure things, especially with a sufficient mix-in-like mechanism (macros or otherwise) |
| 19:36 | riddochc | chouser: you're right, of course. But I wanted magic. Clojure is magical, isn't it? ;) |
| 19:36 | ztellman | so can someone explain this to me: http://github.com/ztellman/looking-glass/blob/master/capture.clj |
| 19:36 | ztellman | I have to execute code before I can import certain classes |
| 19:36 | ztellman | is that a peculiarity of Clojure, Quicktime, or both? |
| 19:37 | ztellman | it doesn't seem like you have to do anything of the sort in the Java examples I've seen |
| 19:43 | chouser | yeah, that's odd. I would guess a quirk of the Quicktime lib, but that doesn't explain why you haven't seen it documented for Java examples. |
| 19:43 | ztellman | is the java import lazier than the clojure import? |
| 19:44 | ztellman | I mean, maybe I'm just misunderstanding the java examples, they were just snippets in much larger pieces of code |
| 19:49 | chouser | hm... actually, that's a good point. I think Java's import does nothing at runtime. |
| 19:49 | chouser | but Clojure's probably does class init stuff, since you name each class individually. |
| 19:49 | ztellman | ok, that makes sense then |
| 19:50 | ztellman | totally unexpected issue, though |
| 19:50 | chouser | things that Java would do when you first mention the class at runtime. perhaps. |
| 19:50 | ztellman | took me forever to figure out |
| 19:50 | chouser | yeah, I can see why |
| 19:50 | ztellman | sometimes I would get into a state at the REPL where things had been properly initialized, and they were working |
| 19:51 | ztellman | anyways, thanks for helping me wrap my head around this |
| 21:13 | toups | I am having some problems with swank-clojure-project. In particular, it hangs polling for the new slime |
| 21:13 | toups | I may not have set up the directory appropriately. |
| 21:14 | toups | Where should I put clojure and should it be the jar, or the directory structure or what? |
| 21:14 | tomoj | all the jars you need should be in lib/ or target/dependency |
| 21:14 | tomoj | including clojure.jar and clojure-contrib.jar |
| 21:15 | toups | Ok |
| 21:15 | toups | So no source code needs to be there |
| 21:16 | toups | Let me try it out |
| 21:17 | toups | tomoj: Thanks, that did it. |
| 21:17 | toups | Do you know of anyone doing numerical modeling in clojure? |
| 21:18 | toups | I am not doing anything super-heavy, and I am hoping with type declarations in the right places, I will be able to get ok speed. |
| 21:18 | tomoj | toups: nope, don't even know what that is |
| 21:24 | toups | I am a neuroscientist |
| 21:24 | toups | So I want to model some very idealized neurons |
| 21:29 | liebke | toups: I use Incanter for numerical modeling in Clojure (http:incanter.org) |
| 21:33 | toups | liebke: Incanter is definitely on my radar |
| 21:36 | liebke | cool, sounds like you're working on something fun :) |
| 23:05 | Drakeson | is it possible to run slime + swank on a multiuser machine securely? |
| 23:18 | tomoj | hmm |
| 23:20 | tomoj | you'd have to use unix sockets, I guess? |
| 23:21 | Drakeson | but, does swank-clojure use unix sockets or is it just a numeric port? |
| 23:21 | tomoj | well, I think it just listens on a port |
| 23:22 | tomoj | and slime-connect asks for host+port |
| 23:22 | tomoj | maybe slime has some way of connecting to a unix socket instead, I dunno |
| 23:22 | Drakeson | tomoj: I see, thanks |
| 23:22 | tomoj | maybe you'd have better luck asking in #emacs |