2009-12-01
| 00:00 | tomoj | if you're using BitSet's destructive operations, clojure can't help you |
| 00:00 | dnolen | technomancy: yes, everything working for me now, btw, any opinion on: lein run? not sure if it's a case you're interested in handling the JNI thing. |
| 00:00 | dnolen | perhaps better server as a plugin? |
| 00:00 | dnolen | server -> served |
| 00:01 | the-kenny | alexyk: If you store immutable bitsets, ref/agent/atom is perfect for the leaves. |
| 00:05 | technomancy | dnolen: I want to add lein run; just not sure how that relates to JNI |
| 00:05 | technomancy | I guess you'd need project.clj to be able to contain a :library-path key or something? |
| 00:06 | dnolen | technomancy: just that downloading JNI dependencies is not enough, they need to be unpacked and you can't use classpath to load them, you need to specify the library path when you run the jar with: java -Djava.library.path=foo/bar -jar my.jar |
| 00:07 | dnolen | in order to make Clojure libs use JNIs portable, lein run could help here. |
| 00:07 | technomancy | oh, so they're stored in the jar, but they need to be extracted first? |
| 00:07 | dnolen | technomancy: unfortunately yes from what I could gather after a whole day of reading people complain about it. |
| 00:07 | technomancy | it kind of sounds like having a run command is only a small part of the picture |
| 00:08 | alexyk | so I figure there's no bitsets in clojure? :( |
| 00:08 | dnolen | alexyk: like setting a bit in a byte? |
| 00:08 | alexyk | dnolen: in a series of bytes of any length |
| 00:09 | alexyk | like java.util.BitSet |
| 00:09 | dnolen | oh, why not just use that from Clojure? |
| 00:09 | alexyk | dnolen: looks like from the above I need immutable one |
| 00:09 | hiredman | you don't |
| 00:10 | hiredman | you just shouldn't use clojure's referece types |
| 00:10 | technomancy | dnolen: i've gotta take off; will continue this discussion on the mailing list |
| 00:11 | dnolen | technomancy: cool, thx much. |
| 00:12 | alexyk | hiredman: but then I won't be able to have them inside parallel stuff? |
| 00:13 | KirinDave | alexyk: So long as you don't mutate them directly, it's fine. |
| 00:13 | alexyk | KirinDave: you set bits on them with (.set myBitSet)... how'd I do it if not directly? |
| 00:14 | alexyk | or perhaps there's a method returning a new bitset there without touching the original |
| 00:15 | hiredman | alexyk: you can lock on the bitset |
| 00:15 | _mst | alexyk: if you want multiple threads hitting the same BitSet you're either going to need locking or avoid the whole issue by pushing access through an agent |
| 00:16 | KirinDave | alexyk: What I mean is, write it in such a way that you copy bitsets and then set them. You don't try and mutate the same one directly. |
| 00:16 | KirinDave | Although the performance characteristics of such are beyond me. |
| 00:16 | alexyk | ok... |
| 00:16 | alexyk | I probably will do them in threads and then merge |
| 00:37 | alexyk | somnium: not much increase with the new, but only one key cut the time down by half or more. I guess my processing dominates. |
| 00:57 | Drakeson | how can I access input args (argv) in a clojure script? |
| 00:57 | Drakeson | defn -main doesn't seem to cut it |
| 01:00 | Drakeson | oh, nevermind |
| 01:18 | qed | how to make a lazy infinite sequence of the sum of [n] natural numbers? |
| 01:19 | tomoj | [n]? |
| 01:19 | qed | 1+2+3+4+5=15 == the 5th triangle number |
| 01:19 | tomoj | I have this in my euler code |
| 01:20 | qed | hints please, not answer |
| 01:20 | tomoj | oh |
| 01:20 | qed | answers* |
| 01:20 | tomoj | well, are you using lazy-seq? |
| 01:20 | qed | I was thinking about something like (lazy-seq (iterate..)) |
| 01:20 | qed | im not sure how to use iterate though |
| 01:21 | tomoj | I did it the ugly way with lazy-seq'd recursion |
| 01:21 | qed | hmmm, like a loop and recur |
| 01:21 | tomoj | (lazy-seq (cons .. ...)) |
| 01:21 | tomoj | no recur with that way since it's not tail position, but lazy-seq keeps you from blowing the stack |
| 01:22 | somnium | qed: have you googled triangle numbers? |
| 01:22 | qed | ([& body]) |
| 01:22 | qed | what is the & there? |
| 01:22 | qed | and what specifically is meant by body |
| 01:22 | tomoj | you can carry around extra state by making the function take more than one argument, and then having a no-arg which supplies default values |
| 01:22 | tomoj | body is bound to all the rest of the arguments |
| 01:24 | cark | qed: you don't need lazy-seq, i think you should only look at c.c.seq-utils/reductions and iterate |
| 01:24 | tomoj | e.g. when looks like ([test & body]), so test is bound to the first argument, and body is bound to a list? all of the remaining arguments |
| 01:24 | tomoj | yeah there's usually a prettier way to do something you're doing with lazy-seq :) |
| 01:25 | cark | i think i have the solution right there |
| 01:25 | tomoj | looks like body actually gets bound to an ArraySeq |
| 01:25 | cark | i so want to give it to you ! |
| 01:25 | tomoj | never even heard of that.. |
| 01:25 | qed | sec cark :) |
| 01:26 | tomoj | but anyway it's a seq that contains all the rest of the arguments (that's what the & does) |
| 01:26 | qed | cark, ah-ha! |
| 01:27 | qed | that reductions stuff is slick! |
| 01:27 | cark | yes =) |
| 01:27 | qed | (reductions + (range 0 10000)) |
| 01:27 | qed | weee |
| 01:27 | tomoj | ?def rec-seq |
| 01:27 | qed | re-seq? |
| 01:27 | qed | ?def re-seq |
| 01:28 | qed | ,doc re-seq |
| 01:28 | clojurebot | java.lang.Exception: Can't take value of a macro: #'clojure.core/doc |
| 01:28 | tomoj | guess c.c.seq-utils uses rec-seq internally? |
| 01:28 | cark | that's not an infinite lazy seq |
| 01:28 | qed | cark, mine? |
| 01:28 | cark | yes |
| 01:28 | qed | cark, im guessing you do something where you iterate over (reductions + (range 0 n)) |
| 01:29 | cark | it's bounded by your range |
| 01:29 | tomoj | ,(take 10 (iterate inc 1)) |
| 01:29 | clojurebot | (1 2 3 4 5 6 7 8 9 10) |
| 01:29 | cark | there you go =) |
| 01:29 | qed | hehe thanks |
| 01:29 | tomoj | that's much prettier than my version |
| 01:30 | tomoj | https://gist.github.com/123b199e06c4cdb00280 |
| 01:30 | cark | i guess yours is more efficient tomoj |
| 01:30 | cp2 | talk more, i am configuring my new irssi theme :) |
| 01:31 | tomoj | ,(require 'clojure.contrib.seq-utils) |
| 01:31 | clojurebot | nil |
| 01:31 | tomoj | ,(doc clojure.contrib.seq-utils/rec-seq) |
| 01:31 | clojurebot | "([binding-name & body]); Similar to lazy-seq but binds the resulting seq to the supplied binding-name, allowing for recursive expressions." |
| 01:32 | qed | (take n (reductions + (iterate inc 1)))? |
| 01:32 | tomoj | I don't understand that at all |
| 01:32 | tomoj | uses an atom for some reason |
| 01:32 | cark | ,(take 10 (reductions + (iterate inc 1)) |
| 01:32 | clojurebot | EOF while reading |
| 01:32 | cark | ,(take 10 (reductions + (iterate inc 1))) |
| 01:32 | clojurebot | (1 3 6 10 15 21 28 36 45 55) |
| 01:33 | qed | yay |
| 01:33 | cark | too bad real world isn't always that nice =/ |
| 01:33 | tomoj | I love it when you can replace a hunk of ugly unreadable code with a simple one-liner |
| 01:34 | qed | now the other thing I need to figure out is how to test this infinite lazy sequence for the number of divisors they have |
| 01:34 | tomoj | guess you're doing euler #12? |
| 01:34 | qed | yeah |
| 01:38 | tomoj | qed: hint: don't prime-factorize |
| 01:38 | tomoj | I tried that and I think it was far too slow |
| 01:38 | qed | lol i was just looking at that |
| 01:38 | qed | so brute force this portion of it? |
| 01:39 | tomoj | maybe if you can quickly prime-factorize it would work |
| 01:40 | qed | i dont know how to do that quicly |
| 01:40 | qed | quickly |
| 01:41 | qed | it seems like the number of the first # of primes is 4, like 2*2*2*2*5 |
| 01:41 | qed | that's just a guess |
| 01:45 | tomoj | hmm |
| 01:45 | tomoj | it seems to be taking quite a long time even with a divisor function I got from, I think, hiredman |
| 01:49 | qed | there we go |
| 01:49 | qed | user.oO (time (first (filter #(> (divs %) 500) triangles))) |
| 01:49 | qed | "Elapsed time: 6931.855 msecs" |
| 01:50 | tomoj | wow |
| 01:51 | tomoj | "Elapsed time: 159806.865765 msecs" |
| 01:51 | tomoj | :) |
| 01:51 | qed | (def triangles (lazy-seq (reductions + (iterate inc 1)))) |
| 01:51 | tomoj | if you pasted your divisor function it would make me very happy |
| 01:52 | qed | (defn divs [n] (* 2 (count (filter #(zero? (rem n %)) (range 1 (Math/sqrt n)))))) |
| 01:52 | qed | (time (first (filter #(> (divs %) 500) triangles))) |
| 01:53 | tomoj | oh it seems your computer is just way faster than mine |
| 01:53 | qed | quad-core 2.66ghz |
| 01:53 | qed | 8gb/ram |
| 01:53 | tomoj | netbook here :) |
| 01:53 | qed | ah |
| 01:54 | tomoj | I think the divisor function I stole from hiredman does the same basic thing, just in a different way |
| 01:54 | tomoj | though your version only took 101s |
| 01:55 | qed | my answer is incorrect |
| 01:55 | tomoj | huh, strange |
| 01:55 | tomoj | I got the same answer using my divisor function as with yours |
| 01:55 | tomoj | what was your incorrect answer? |
| 01:55 | qed | 76576500 |
| 01:55 | tomoj | that's the answer I got too |
| 01:55 | qed | it says incorrect |
| 01:56 | qed | this time it worked |
| 01:56 | qed | i think i maybe had an extra space |
| 01:56 | tomoj | huh, I actually hadn't solved #12 yet apparently |
| 01:57 | tomoj | though I had the code right here to do it in 159s, strange |
| 01:57 | qed | ive been avoiding it |
| 01:57 | qed | cause it seemed boring |
| 01:58 | qed | so does 21 |
| 01:58 | tomoj | cl-format probably makes #17 trivial |
| 01:58 | tomoj | if cl-format does ~r |
| 02:00 | qed | unfortunately thats all the euler ill be doing for tonight |
| 02:00 | qed | im gonna try to wake up early before work and do one |
| 02:00 | qed | i do better work in the AM |
| 02:01 | qed | gnight all |
| 02:02 | tomoj | ah crap |
| 02:02 | tomoj | euler wants british english numbers and cl-format does something else |
| 02:07 | tomoj | I wonder if euler did that on purpose so we couldn't use CL's ~r |
| 02:08 | qed | it inspires debate |
| 02:10 | qed | tomoj: i should qualify that i lifted chouser's #12 divisor function to finish that off |
| 02:20 | tomoj | oh, hmm |
| 02:20 | tomoj | did yours say "totally useless"? |
| 02:20 | tomoj | I thought it was hiredman's but my memory is totally shot |
| 02:21 | tomoj | oh, yours was different, I forgot. see, my memory is _totally_ shot |
| 02:21 | tomoj | don't do drugs, kids |
| 02:26 | hiredman | if I recall, euler just wants a word count |
| 02:27 | hiredman | I think I just did the first letter in each word, then counted those |
| 03:08 | angerman | how do I create an agent with meta-data? |
| 03:09 | angerman | (with-meta (agent nil) {:no 1}) gives me an Agent cannot be cast to IObj Exception |
| 03:10 | hiredman | there are two seperate metadata protocols, bifibricated on mutability |
| 03:11 | _ato | ,(doc reset-meta!) |
| 03:11 | clojurebot | "([iref metadata-map]); Atomically resets the metadata for a namespace/var/ref/agent/atom" |
| 03:11 | hiredman | with-meta is for metadata on immutable things |
| 03:11 | angerman | meh :( using (agent nil :meta ....) |
| 03:11 | angerman | so (with-meta) is immutable |
| 03:12 | hiredman | it is for returning a new immutable thing with metadata attached |
| 03:12 | _ato | yes with-meta is for immutable objects, use alter-meta! or reset-meta! to change metadata on mutable objects (like refs, agents, toms, namespaces etc) |
| 03:13 | angerman | yep, I was just confused, I wanted to setup the agent with metadata upfront, musst have missed the :meta arg |
| 03:14 | angerman | I'm trying to write an agent pool that dequeues on completion. |
| 03:15 | angerman | e.g. I have a list of tasks, and 4 agents. Now I could spread out the tasks to the agents randomly. But as the tasks may vary in computation time. That could end up having one agent work very long while the others are waiting. |
| 03:15 | angerman | I think using watches would be even better. |
| 03:34 | angerman | does the function that the agent executes have any access to the agent? |
| 03:43 | slashus2 | angerman: Are you talking about *agent* ? |
| 03:46 | angerman | slashus2: maybe, let me see |
| 04:45 | angerman | wheee ... |
| 04:45 | angerman | http://gist.github.com/246189 |
| 05:28 | optimizer | is using a c++ ffi even practicel in clojure, or is the jni calls just too expensive? |
| 05:29 | ambient_ | well i'll get back to you, im doing that right now |
| 05:29 | optimizer | my question? |
| 05:29 | ambient_ | rtaudio has no good jni implementation :/ |
| 05:29 | ambient_ | yeah your question |
| 05:30 | optimizer | dude |
| 05:30 | optimizer | i wnat to do audi processing too |
| 05:30 | optimizer | any chance you ca open source your interface? |
| 05:30 | ambient_ | well there's jass-sdk |
| 05:30 | ambient_ | http://people.cs.ubc.ca/~kvdoel/jass/ |
| 05:31 | ambient_ | it seems to be pretty low-latency and includes synth toolkit, but i don't know how current it is |
| 05:57 | fliebel | hiredman: After some reading I finally understand you snippet you gave me yesterday. That empty string and the double %S at the start drove me mad, until I carefully read the doc and tried leaving them out. Thanks, I'm on my way to write something working now! :) |
| 06:12 | angerman | do defn's share any state? |
| 06:13 | ohpauleez | I'm not sure exactly what you mean, but they'll only share some notion of state in a binding form |
| 06:13 | angerman | I'm trying to understand why http://gist.github.com/246232 |
| 06:13 | angerman | throws an IllegalStateException: No transaction running |
| 06:14 | angerman | the function is sent to an agent to process it. |
| 06:16 | ohpauleez | let me take a look |
| 06:17 | Chousuke | you have alters in there |
| 06:17 | ohpauleez | you have alters |
| 06:17 | ohpauleez | and they need to be in a dosync |
| 06:17 | ohpauleez | with atoms |
| 06:17 | ohpauleez | ahhh Chousuke! you beat me to it |
| 06:18 | angerman | thanks, let's see |
| 06:19 | ohpauleez | angerman: because atoms are allowed to be manipulated by multiple threads, you need to put them in a dosync to operate on them with alters http://java.ociweb.com/mark/clojure/article.html#ReferenceTypes |
| 06:20 | ohpauleez | same with refs |
| 06:20 | Chousuke | angerman: probably the man, mix and avg values be strings is not very performant |
| 06:20 | angerman | ok, but the atom is function local, right? |
| 06:20 | Chousuke | angerman: that'll create *lots* of strings if you have many query results :/ |
| 06:20 | ohpauleez | I mean refs, not atoms |
| 06:20 | angerman | Chousuke: it's a database -> libsvm conversion. |
| 06:21 | angerman | so I need the strings and write them out |
| 06:21 | Chousuke | angerman: yeah, but you should accumulate values and create the strings at the end |
| 06:22 | angerman | I get for each row three float values |
| 06:22 | angerman | that need to end up as <i>:<float value> <i+1>:<float value> .... |
| 06:22 | angerman | so I'll create the <i>:<float values> in an accoumulator and run reduce over them? |
| 06:23 | Chousuke | no, just accumulate the float values into a vector and print the contents of the vector (using format) instead of creating temporary strings? :) |
| 06:23 | fliebel | Can someone explain me doseq? I read map is for changing the list, but I just want to call a function with every item. I changed map into doseq, but it does not work. |
| 06:24 | angerman | Chousuke: hmmm.... |
| 06:24 | Chousuke | fliebel: (doseq [item seq] (function item)) |
| 06:24 | Chousuke | fliebel: and map doesn't *change* anything :) |
| 06:24 | Chousuke | well, shouldn't. |
| 06:25 | fliebel | Chousuke: Ok, map is for returning a new sequence with different items, right? |
| 06:25 | Chousuke | yeah. |
| 06:26 | angerman | Chousuke: so basically i conj them onto a vector. |
| 06:26 | fliebel | Chousuke: Why does doseq have this strange syntax? I thought it would work on a sequence and put the items in a anonymous function and use %. |
| 06:26 | angerman | (alter vec conj floatval) |
| 06:27 | angerman | then I have a vector of floatvals, how do I turn that into a string with format? that vector is going to be 44700 items long |
| 06:28 | Chousuke | do you need a single string? :P |
| 06:29 | Chousuke | can't you just print it out an item at a time |
| 06:29 | Chousuke | also, now that I think about it, why do you have refs in that function at all? |
| 06:29 | fliebel | Why doesn't this work? (doseq [tag [:a :span]] (def tag (partial html tag))) Apparently Clojure confuses me quite a lot... |
| 06:29 | angerman | because the values are in a column in the table and I need them as a row in the file |
| 06:30 | Chousuke | fliebel: html is a macro? :) |
| 06:30 | angerman | so I'm iterating over the rows, collecting the data, and writing it out. |
| 06:30 | fliebel | Chousuke: A function at least.... |
| 06:30 | Chousuke | angerman: so don't write newlines? |
| 06:30 | angerman | well the writer-agent adds a newline |
| 06:31 | Chousuke | you'll need to change it. |
| 06:31 | angerman | I have 253 experiments, with each 44700 features with min/avg/max values |
| 06:31 | Chousuke | creating a string of all the 45 thousand float vals is going to waste a huge amount of memory. |
| 06:31 | Chousuke | you don't want to do that. |
| 06:32 | fliebel | Chousuke: html takes a tag, attributes and content, and I want to make a function that will define a few partial functions with the tag already supplied. |
| 06:32 | angerman | assuming I'm going to collec the 44700 values in a vector, I could hand that vector to the writing agent |
| 06:32 | Chousuke | possibly |
| 06:32 | angerman | and let the writing agent work them off in a print loop |
| 06:32 | Chousuke | fliebel: oh right. |
| 06:32 | Chousuke | the def is the problem |
| 06:33 | Chousuke | defs are only for top-level |
| 06:33 | Chousuke | you need a macro :) |
| 06:33 | fliebel | ok… and is it a problem to supply :a instead of a? I'm still not sure what it means to write a :a or "a" |
| 06:34 | fliebel | The final goal is to make it a macro, but I blow everything everytime it try, so I thought I'd start off with a function. |
| 06:34 | Chousuke | ,(let [a 1] (map class [a 'a :a "a"])) |
| 06:34 | clojurebot | (java.lang.Integer clojure.lang.Symbol clojure.lang.Keyword java.lang.String) |
| 06:35 | ohpauleez | fliebel: :a is a keyword |
| 06:36 | Chousuke | I can't stay to help, though. must hurry. |
| 06:36 | ohpauleez | http://java.ociweb.com/mark/clojure/article.html#Collections |
| 06:36 | ohpauleez | I'm here, I'll pick things up |
| 06:36 | fliebel | ohpauleez: thanks :) |
| 06:37 | ohpauleez | fliebel: totally welcome, that's a great resource, you can learn the bulk of Clojure in a day from it |
| 06:37 | ohpauleez | angerman: are you all set? |
| 06:37 | fliebel | I just read half of it yesterday… But in a kind of sleepy and back-and-forth way :P |
| 06:38 | ohpauleez | fliebel: are you coming from Java, Python/Ruby, Common Lisp/Scheme or relatively new to programming? |
| 06:39 | fliebel | I started of with Java, then did PHP for a while, a few months ago I started doing Python and now I'm starting Clojure. But you can see me as a Python guy because it's more recent than Java and I like it better. |
| 06:42 | ohpauleez | So keywords in clojure are cool. http://clojure.org/data_structures#toc8 |
| 06:42 | fliebel | I find it quite hard to learn Clojure… Where in PHP, Javascript and Python I have to think about whether or not to use curly branches or to use count or length or whatever or if I need to make an array, a map or a dict. With Clojure I have to think fundamentally different. |
| 06:43 | ohpauleez | you use them as you would standard keys of a dictionary |
| 06:43 | fliebel | keywords are the : ones? |
| 06:43 | ohpauleez | except, like python, hash-maps (dictionaries), are used for book keeping and tracking a lot of information |
| 06:44 | ohpauleez | fliebel: yep, : ones |
| 06:44 | fliebel | I read they are like strings, but more like a number, every time you type :a or 1 you get the exact same thing. |
| 06:45 | ohpauleez | yes, they evaluate to the themselves |
| 06:45 | fliebel | so what are those ' things chousuke mentioned? |
| 06:45 | ohpauleez | quoting a symbol |
| 06:46 | ohpauleez | have a look at: http://java.ociweb.com/mark/clojure/article.html#Syntax |
| 06:46 | fliebel | ah, just like qupoting a list '(:a 'b c 1) |
| 06:47 | fliebel | I know the quoting syntax… Just that the context was missing. |
| 06:47 | ohpauleez | right, you quote a symbol so the reader doesn't attempt to evaluate it |
| 06:47 | fliebel | so what is the difference between ' and `? Quite confusing if you ask me... |
| 06:47 | ambient_ | optimizer: i got jrtaudio working, just had to edit some .cpp and makefiles. http://code.google.com/p/jrtaudio/ |
| 06:48 | _ato | ,`inc |
| 06:48 | clojurebot | clojure.core/inc |
| 06:48 | _ato | ,'inc |
| 06:48 | clojurebot | inc |
| 06:48 | _ato | difference 1: ` qualifies the symbol with its namespace |
| 06:49 | _ato | ,`(:a ~(+ 1 1)) |
| 06:49 | clojurebot | (:a 2) |
| 06:49 | _ato | ,'(:a ~(+ 1 1)) |
| 06:49 | clojurebot | (:a (clojure.core/unquote (+ 1 1))) |
| 06:49 | _ato | difference 2: ` lets you "unquote" in the middle of a form, so you can selectively evalute stuff |
| 06:49 | _ato | ` is usually used for writing macros |
| 06:50 | ohpauleez | thanks _ato, I was only going to mention #2 |
| 06:50 | fliebel | I noticed that, but in which case would you want to use ' instead? |
| 06:50 | fliebel | .`(:a :b) |
| 06:50 | fliebel | ,`(:a :b) |
| 06:50 | clojurebot | (:a :b) |
| 06:51 | fliebel | ,'(:a :b) |
| 06:51 | clojurebot | (:a :b) |
| 06:51 | ohpauleez | I use ' all the time unless I'm writing a macro and need evalutation via unquoting |
| 06:51 | fliebel | Ok, not for any practical reason or something like that... |
| 06:51 | _ato | ' is faster in certain cases, and sometimes you don't want the symbol qualified |
| 06:51 | fliebel | true... |
| 06:51 | _ato | ,'`(a (b c)) |
| 06:51 | clojurebot | (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/a)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/b)) (clojure.core/list (quote sandbox/c))))))) |
| 06:52 | fliebel | Whoa! what happened? |
| 06:52 | _ato | ~ping |
| 06:52 | clojurebot | PONG! |
| 06:52 | _ato | ` supposorts something called splicing-unquote, which looks like this: ~@ |
| 06:53 | _ato | ,`(a b ~@[:c :d] e f) |
| 06:53 | clojurebot | (sandbox/a sandbox/b :c :d sandbox/e sandbox/f) |
| 06:53 | _ato | to do that splicing it needs to rebuild the list |
| 06:53 | ohpauleez | fliebel: it's like *args in pything |
| 06:53 | ohpauleez | python* |
| 06:53 | _ato | that's where all that stuff comes from if you do '`(something) and is why ' can be faster |
| 06:54 | fliebel | ohpauleez: finally an explanation of that splicing thing.... |
| 06:55 | fliebel | Can I use that splicing thing everywhere, or do I need to use apply or something like that? |
| 06:55 | _ato | you can only use it inside a syntax-quoted ` form. |
| 06:55 | _ato | ,~@foo |
| 06:55 | clojurebot | java.lang.Exception: Unable to resolve symbol: foo in this context |
| 06:56 | _ato | ,~@2 |
| 06:56 | clojurebot | java.lang.IllegalStateException: Var clojure.core/unquote-splicing is unbound. |
| 06:56 | fliebel | I see... |
| 06:56 | fliebel | Can I ask some more things about writing macros? |
| 06:57 | _ato | sure |
| 06:57 | angerman | Chousuke: thatnks, that seems to work way better |
| 06:57 | fliebel | Ah, I forgot: "Don't als to ask" |
| 06:58 | fliebel | Can I turn :a into a? |
| 06:58 | ohpauleez | angerman: glad it's working out |
| 06:59 | _ato | ,(symbol (name :a)) |
| 06:59 | clojurebot | a |
| 06:59 | fliebel | ato: How intuitive :) |
| 06:59 | ohpauleez | ,(doc name) |
| 06:59 | clojurebot | "([x]); Returns the name String of a symbol or keyword." |
| 07:00 | _ato | ,(keyword (name 'a)) |
| 07:00 | clojurebot | :a |
| 07:00 | fliebel | ,(doc symbol) |
| 07:00 | clojurebot | "([name] [ns name]); Returns a Symbol with the given namespace and name." |
| 07:01 | fliebel | I'll try to write my macro now, but I'm sure it will not work the way I planned it. |
| 07:01 | ohpauleez | fliebel: You can use the doc browser on your clj REPL for everything. If you sit in here for a few days and doc everything that people talk about and play with it on your own REPL |
| 07:01 | ohpauleez | you'll be up and running in no time |
| 07:02 | fliebel | Hmmm, good idea. |
| 07:05 | fliebel | (defmacro deftag [tag] |
| 07:05 | fliebel | `(def ~(symbol (name tag)) (partial html ~tag))) |
| 07:05 | fliebel | It works, but now I need to get it working with multiple arguments. |
| 07:06 | fliebel | like… (deftag :a :span :p) |
| 07:10 | fliebel | ato or ohpauleez: How can I make a macro that returns the second line of my code for every argument? You said def is only for the top level, so I can't put it in some sort of loop, can I? |
| 07:15 | rhickey | fliebel: just have the macro emit the defs in a do - the do will disappear at top level |
| 07:16 | fliebel | rhicky: The number of arguments is unknown, I want to use the & argument syntax. Would loop work as well? |
| 07:16 | ohpauleez | fliebel: also, have a look at http://en.wikibooks.org/wiki/Learning_Clojure#Macros |
| 07:16 | ohpauleez | [& args] |
| 07:17 | ohpauleez | [arg-one arg-two & other-args] |
| 07:17 | rhickey | fliebel: see the definition for declare in core.clj |
| 07:19 | fliebel | I got this now, but it fails... |
| 07:19 | fliebel | (defmacro deftag [& tags] `(loop [tags tags] (def ~(symbol (name (first tags))) (partial html ~(first tags))) (recur (rest tags)))) |
| 07:19 | rhickey | http://github.com/richhickey/clojure/blob/master/src/clj/clojure/core.clj#L4283 |
| 07:19 | ohpauleez | There is also a little bit of info on declare here: http://java.ociweb.com/mark/clojure/article.html#DefiningFunctions |
| 07:20 | rhickey | ,(macroexpand-1 '(declare a b c)) |
| 07:20 | clojurebot | DENIED |
| 07:20 | rhickey | aargh |
| 07:20 | rhickey | expands to: (do (def a) (def b) (def c)) |
| 07:21 | fliebel | rhickey: that sounds like what I need… |
| 07:22 | ohpauleez | also, your loop has two args, but you're only recuring one |
| 07:22 | rhickey | fliebel: read the source to declare until you understand it, and remember macros are about taking some code and turning it into other code, not doing things |
| 07:22 | ohpauleez | and it might not make sense for this to be a macro |
| 07:23 | ohpauleez | exactly what rhickey said |
| 07:23 | ohpauleez | you only use a macro when you don't want to eval all the args |
| 07:23 | fliebel | uuuhm, that sound reasonable... |
| 07:23 | ohpauleez | it's for generating other syntax or conditional controls |
| 07:25 | fliebel | I want people to be able to call (a rest) instead of (html :a rest) by defining a as a partial. |
| 07:25 | fliebel | so all i want to do is some easy way to define a few of those partials in one blow. |
| 07:26 | ohpauleez | I would define a with-html macro maybe |
| 07:26 | ohpauleez | I'm not sure what you're building |
| 07:26 | ohpauleez | but (with-html "some-file.html" (my-body-here)) |
| 07:27 | ohpauleez | I assume some html browser or DSL |
| 07:27 | fliebel | DSL... |
| 07:32 | fliebel | But I guess it would be a valid macro to turn a list of keywords to a list of partial statements... |
| 07:37 | fliebel | I have to leave, bye! |
| 07:56 | cemerick | rhickey: what's your snap reaction to the notion of a string interpolation reader macro? e.g. #@"str of some value @here", or somesuch. |
| 07:56 | rhickey | cemerick: ick |
| 07:56 | cemerick | I'm writing (format ...) *way* too much IMO -- am about to go write a userspace macro to do string interpolation, but I thought I'd float the reader macro idea. |
| 07:56 | cemerick | heh, OK |
| 07:58 | rhickey | but I'm not saying never, just the ones I;ve seen were more complex than the problem they were 'solving' |
| 07:58 | cemerick | rhickey: Sure. I think it's somewhat inevitable. Too handy in ruby to not steal. |
| 07:58 | rhickey | (str "str of some value " here) |
| 07:59 | cemerick | well, short stuff is certainly not where the money is |
| 08:00 | cemerick | writing long-ish dialog box msgs with lots of bits of data scattered about, webby content generation stuff that doesn't warrant a real templating engine, etc...that's where the real pain is. |
| 08:01 | _ato | (str "Hello, " user "! You have " (count tasks) " remaining tasks.") |
| 08:01 | _ato | vs ala ruby "Hello, #{user}! You have #{(count tasks)} remaining tasks." |
| 08:01 | chouser | ruby's is pretty simple, isn't it? And could be done with a simple fn (or macro) wrapping a normal string I think. |
| 08:01 | _ato | I don't think your gaining much |
| 08:01 | cemerick | chouser: yeah, I'm half-done with a userland macro |
| 08:01 | cemerick | ruby does allow arbitrary expressions, which is a little nutty |
| 08:02 | cemerick | _ato: the two are *very* different w.r.t. readability IMO |
| 08:02 | chouser | oh, I thought that was the whole point, the arbitrary expressions. |
| 08:02 | chouser | nested even, which can get fun. |
| 08:04 | cemerick | Even simple references to existing bindings would be a win at the moment. |
| 08:04 | cemerick | but even nested arbitrary expressions should be pretty straightforward |
| 08:05 | chouser | only problem there would be double-quote-escaping, I think. |
| 08:06 | cemerick | yeah. Having two string delimiters is super-handy. |
| 08:06 | cemerick | " *and* ', that is |
| 08:07 | chouser | I meant that this is valid ruby, but Clojure won't read it right: "outer #{"this" + " inner #{10 + 20}"}" |
| 08:08 | _ato | it does beat (format "Hello, %s! You have %d remaining tasks." user (count tasks)) |
| 08:08 | cemerick | chouser: oh, I didn't realize that was allowable -- I thought people just used single-quotes for strings in #{} out of necessity (rather than style/readability) |
| 08:10 | ambient | i got (gen-class :methods [[callback [double<>] Integer]]) double<> doesn't seem to work, im trying to say to clojure that the type is double[] |
| 08:11 | ambient | so which is the right way to tell gen-class that the methods input attribute is of type double[]? :/ |
| 08:11 | chouser | ambient: I think for gen-class you still have to use "[D" |
| 08:11 | ambient | oh ok |
| 08:13 | ambient | class not found java/land/[D |
| 08:13 | ambient | *lang |
| 08:14 | chouser | ambient: :-( http://www.assembla.com/spaces/clojure/tickets/162 |
| 08:14 | rhickey | http://groups.google.com/group/clojure/browse_frm/thread/d8445bd527be5542/db8672869184702d |
| 08:15 | ambient | chouser: ok seems i have to update clojure :) |
| 08:15 | ambient | using 1.0.0 currently |
| 08:15 | chouser | ambient: that fix isn't in github anywhere yet |
| 08:15 | ambient | :( |
| 08:15 | ambient | well guess im screwed then |
| 08:16 | chouser | ambient: you could try applying it to your 1.0.0 clojure -- there's a passing chance it might work. |
| 08:16 | ambient | here's the code fwiw: http://paste.pocoo.org/show/154098/ |
| 08:17 | chouser | ambient: or you could go crazy and move right to the "new" branch and use deftype instead. |
| 08:17 | ambient | i'd rather not :D |
| 08:17 | chouser | ambient: very sensible. |
| 08:18 | rhickey | anyone have any luck with latest deftype/reify/protocols? |
| 08:18 | chouser | rhickey: haven't had a chance to do much yet. maybe this afternoon. |
| 08:20 | rhickey | I'm thinking about incorporating chouser 's suggestion to drop the parens on multiple arity in defprotocol, and move to defprotocol style of P1 (m1 ...) (m2 ...) P2 (m3 ...) (m4 ...) in deftype and reify, vs the [P1 P2] (m1 ...) ... (m4 ...) |
| 08:21 | rhickey | the latter makes the simplest case simpler still: |
| 08:21 | rhickey | (reify ActionListener (actionPerformed [this evt] ...)) |
| 08:21 | rhickey | and makes deftype/reify consistent with extend* |
| 08:22 | cemerick | rhickey: willl that still transparently work with overlapping interface sigs? |
| 08:23 | rhickey | cemerick: yeah, just put in either, for now would just turn this into old style under the hood, but moving forward could do more checking with them broken out |
| 08:24 | cemerick | rhickey: This should probably be an error: (reify P1 P2 (m1 ...) (m2 ...) (m1 ...)) |
| 08:24 | rhickey | incorporating pile-o-methods into syntax means marrying pile-o-methods semantics |
| 08:25 | rhickey | cemerick: yes, should be |
| 08:25 | rhickey | haven't coded it yet |
| 08:25 | cemerick | sure |
| 08:25 | rhickey | although sometimes code-generating-code writes things like that |
| 08:25 | cemerick | The pile-o-methods approach seems like a lot less work to me. Probably makes things hell for VM and language implementers, though. |
| 08:26 | rhickey | cemerick: you've never gotten bitten by wanting to derive from 2 classes/interfaces whose methods clash? |
| 08:27 | cemerick | rhickey: I try to make sure I'm building the libraries, not using them. :-) Though that's changing fast... |
| 08:27 | chouser | you can namespace-qualify the method names in reify and deftype now? |
| 08:27 | rhickey | chouser: no |
| 08:27 | chouser | so splitting them by protocol name would help there, right? |
| 08:28 | rhickey | chouser: without being able to generate prefixes, the resulting JAva class is going to mash them together anyway |
| 08:29 | rhickey | but having them split in the syntax means prefixes might be a future possibility |
| 08:29 | chouser | ok |
| 08:29 | rhickey | also, enhanced checking |
| 08:29 | rhickey | and consistency with extend* |
| 08:29 | rhickey | and simpler simplest case |
| 08:31 | rhickey | I have to say, adding all the explicit thises to the few exisitng reify/deftypes was a real, seeming pointless, pain |
| 08:31 | rhickey | started using _ for this |
| 08:31 | rhickey | will be most common case |
| 08:32 | rhickey | :( |
| 08:32 | chouser | that's actually what I was tripping over last night too. Used 'x' instead of 'this' in my defprotocol, and was then confused... |
| 08:32 | rhickey | the first arg will rarely be used |
| 08:33 | chouser | right, because of direct access to fields |
| 08:33 | rhickey | almost made me want to accept with and without '.' |
| 08:34 | chouser | hm, surely not. |
| 08:34 | rhickey | chouser: yeah, the only time you need this is to call another method on yourself or pass this to someone else |
| 08:34 | rhickey | chouser: passing idea :) |
| 08:34 | rhickey | now gone |
| 08:35 | rhickey | chouser: you don't want to use 'this' in the defprotocol anyway, that name is for consumers, who will be calling the protocol fn and passing what they consider a coll or num or something |
| 08:36 | rhickey | this is a name for an implementor |
| 08:36 | chouser | extend takes real fns with a real first arg, and calls pass in a real first arg. in all other cases the body isn't a real fn, right? |
| 08:36 | rhickey | chouser: right |
| 08:37 | rhickey | extend* |
| 08:37 | chouser | for me, that's the consistency pain point. |
| 08:39 | chouser | and the extend macros could hide the 'this' arg as well. hm... |
| 08:39 | rhickey | but how to mitigate? would just make members more cumbersome (foo [this x] ... (:afield this)) |
| 08:39 | rhickey | chouser: they would have to auto-bind 'this' though, since you will need it in extend-* defs |
| 08:40 | rhickey | no implicit fields |
| 08:41 | rhickey | doing implicit this in deftype/reify and extend-* would make everything consistent (don't supply frst arg) *except* pure extend and mixins |
| 08:42 | rhickey | the latter being more power tools |
| 08:42 | chouser | right, the latter is what I was suggesting, not (:afield this) |
| 08:43 | rhickey | I see the vast majority of people using deftype/reify and extend-* |
| 08:43 | chouser | still a slight mismatch with callers, but maybe that's no too bad? |
| 08:43 | rhickey | but it is still a mismatch with defprotocol itself |
| 08:44 | esj | guys: I'm having a 'use' issue - can anybody tell my why (use 'clojure.contrib.lazy-seqs) works, but (use 'clojure.contrib.json.write) returns java.lang.NoClassDefFoundError (NO_SOURCE_FILE:0). I have just pulled Master from git. Sorry to bother you with this. |
| 08:44 | chouser | rhickey: because you want to allow a name other than 'this'? |
| 08:44 | rhickey | chouser: because the arg is there |
| 08:45 | chouser | esj: no need to apologize. :-) |
| 08:45 | rhickey | with deftype/reify of interfaces it's easy since the interface method declaration doesn't include this |
| 08:45 | rhickey | esj: try ant clean on contrib before rebuild |
| 08:46 | esj | rhickey: on it |
| 08:47 | rhickey | so, declare Seqable.seq(); , define seq(){...}, call coll.seq(), all matches (in the parens) |
| 08:48 | rhickey | but (defprotocol Seqble (seq [coll]) ), (deftype Foo Seqble (seq [] ...)), (seq afoo) doesn't match |
| 08:49 | chouser | I still don't see why defprotocol can't have an implicit coll (names 'this' of course) |
| 08:49 | rhickey | could be (defprotocol Seqble (seq []) ), (deftype Foo Seqble (seq [] ...)), (seq afoo) ; protocols presume first arg |
| 08:50 | chouser | named |
| 08:50 | chouser | right |
| 08:50 | chouser | leaving (seq afoo) the odd man out |
| 08:50 | rhickey | I think people get that after: coming from Java, using Clojure and seeing where target goes in (.method target args) |
| 08:51 | rhickey | but not intuitive, and bigger mismatch with extend/mixins |
| 08:51 | chouser | running the kids to school -- brb |
| 08:55 | fliebel | How can I append to a list? conj only prepends things… To me lists are a lot more complicated than the regular Python square bracket syntax. I'm also still at a loss on how I can insert at a specified index. |
| 08:56 | esj | fliebel: I had the same misunderstandings - seqs are totally different from vectors |
| 08:56 | ambient | python lists aren't even lists afaik, they're dynamic arrays |
| 08:57 | esj | fliebel: you _can_ append to seqs, but I think that it, in general, is not a good idea. |
| 08:58 | fliebel | esi: Is there any good documentation on vectors, lists and maps? http://clojure.org/sequences is not very helpful to me. |
| 08:59 | rhickey | fliebel: http://clojure.org/data_structures |
| 08:59 | esj | zakly |
| 09:00 | esj | rhickey: after git pull, ant clean, ant on clojure and clojure-contrib my error is now (use 'clojure.contrib.json.write) |
| 09:00 | esj | java.lang.NoSuchMethodError: clojure.lang.RestFn: method <init>()V not found (NO_SOURCE_FILE:0). Seen it before ? |
| 09:01 | rhickey | that is almost always a mismatched/incomplete build problem |
| 09:01 | leafw_ | fliebel: I'd use vectors wherever you think "list" |
| 09:01 | esj | fliebel: also check out http://blip.tv/file/707974 I found it really useful |
| 09:02 | fliebel | leafw: How about appending a statement to a function? functions are lists in fact, aren't they? |
| 09:02 | esj | rhickey: thanks - I'll hunt it down. |
| 09:05 | fliebel | esi: How can I append to a list? Or are there any other options to append a statement to a function? |
| 09:06 | esj | fliebel: are you working with macros ? |
| 09:06 | fliebel | esi: sort of… just playing around, but for this example that includes using a macro. |
| 09:07 | fliebel | At least the function is in list state, not executed. |
| 09:11 | esj | fliebel: OK, I haven't delved as deep as macros yet - so probably not much help. When I was trying to fight Clojure by appending to a seq I made a function that traversed the list manually, synthesising an append. But it was a silly thing to have done. |
| 09:12 | fliebel | I can imagine… I'll try something else, and continue to do that until I understand Clojure, or at least macros |
| 09:12 | rhickey | fliebel: there is concat |
| 09:13 | Drakeson | can I access the name of the ns that uses my library, in a macro? |
| 09:14 | rhickey | Drakeson: *ns*, at macroexpansion time, will be that ns |
| 09:15 | rfgpfeiffer | reify does not complain when I do not implement all methods in a protocol. Is this the intended beaviour? |
| 09:15 | Drakeson | thanks :) |
| 09:16 | rhickey | rfgpfeiffer: that is intended, but an open question moving forward |
| 09:17 | esj | rickey: totally correct, got it going now, thanks. |
| 09:19 | rfgpfeiffer | rhickey: i'd like it to produce a warning, but not an exception |
| 09:20 | chouser | warnings need a way to be turned off |
| 09:20 | rfgpfeiffer | like in haskell when your patterns do not cover all possbile cases |
| 09:22 | rhickey | rfgpfeiffer: that would be possible, I think we need to see how often that 'feature' is leveraged |
| 09:22 | rfgpfeiffer | at least once :) |
| 09:23 | rhickey | I mean the 'isn't it great I don't have to implement all the methods since I know they won't be called' feature |
| 09:29 | rfgpfeiffer | haskell-like pattern matching with double dispatch on protocols http://gist.github.com/246310 |
| 09:30 | lpetit | rhickey: use case. clojure.core defines some protocol. I create an implementation of this protocol. Later a function is added to the protocol. Nothing warns me I'm then not totally compliant with the new version of the protocl |
| 09:30 | lpetit | oh, and hi, BTW :) |
| 09:31 | rhickey | lpetit: I'm not strenuously arguing against a warning, but one person's warning is another's nuisance |
| 09:31 | lpetit | rhickey: certainly, and that would let room for implementing those needed warnings in IDE :-p |
| 09:32 | rhickey | experience will show what the default should be |
| 09:32 | rfgpfeiffer | what about a variable *warn-on-non-exhaustive-protocol-implementation* |
| 09:32 | rhickey | rfgpfeiffer: something like that but, ... shorter |
| 09:32 | rfgpfeiffer | of course |
| 09:34 | rhickey | any more opinions on implicit this in deftype/reify/extend-type and extend-class? |
| 09:35 | lpetit | "experience will show what the default should be" :-p |
| 09:36 | rhickey | lpetit: for implicit this? not toggleable |
| 09:36 | rhickey | my brief experience was a lot of _s |
| 09:37 | lpetit | rhickey: _s are an interesting information by itself for code readers, aren't they ? |
| 09:38 | hoeck | rhickey: |
| 09:39 | rhickey | lpetit: dunno - seems like noise and tedium to me: http://github.com/richhickey/clojure/commit/a84a4e1ff36b85ec2afa4df41c5affca1a76c78a |
| 09:40 | hoeck | rhickey: I'm on the new branch from nov, 12 and actually like the implicit this in deftype after implementing some clojure interfaces |
| 09:41 | rhickey | hoeck: I agree, when implementing interfaces it is clearly better. we've been discussing how to make it fit better with protocols, which currently declare that first arg |
| 09:41 | hoeck | rhickey: explicit this would clutter the code as in your examples, mostly I'm accessing some fields without using this or call the types ctor |
| 09:41 | hoeck | rhickey: a,h ok |
| 09:41 | rhickey | hoeck: right, 'this is rarely used |
| 09:41 | lpetit | rhickey: feedback from python guys may be interesting (isn't explicit this/self the enforced default in python ?) |
| 09:42 | rhickey | lpetit: I found 'self' annoying in Python |
| 09:42 | chouser | me too |
| 09:42 | fogus | here here |
| 09:42 | chouser | though I was a different programmer then |
| 09:43 | angerman | isn't self only a convetion? |
| 09:43 | lpetit | rhickey: so maybe you have already the answer => implicit this (or toggleable, but wouldn't it be even worse than just acting it's implicit, period ?) |
| 09:43 | rhickey | the crux of the matter is, given (defprotocol P (foo [x] ...)), what will you expect to write in (deftype T [a b c] P (foo ... |
| 09:44 | chouser | I think I'd want it gone from defprotocol too. |
| 09:44 | rhickey | then, as consumer of P, wanting to call (foo ...) , will expect to pass what? |
| 09:45 | fogus | angerman: http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html |
| 09:46 | chouser | (foo a-P named args here) ... right? That is the only remaining mismatch (besides direct use of extend fn). So the question is, is that mismatch acceptable. |
| 09:47 | rfgpfeiffer | i like self in python, but reify is more static than python's class: |
| 09:49 | rhickey | chouser: the doc string for foo could add the param back in |
| 09:50 | chouser | rhickey: that would certainly help. |
| 09:50 | rhickey | foo ([Protocol arg arg]) docs |
| 09:52 | chouser | there is a conceptual tension between these things being functions and being methods. When called, they're *really* like functions. When defined in deftype, *really* like methods. |
| 09:52 | cburroughs | angerman, The name 'self' is a convention, but the argument must be there. |
| 09:53 | chouser | so we're pushing around where to draw the line between method-like defaults and function-like behavior. |
| 09:54 | rhickey | There might also be a problem with adding implicit this in extend-type/class, in that those are *not* methods, won't have access to fields etc, and *will* be closures |
| 09:54 | chouser | having the first arg not show up only in the calls (and arglists metadata) is one extreme. Explicit this all the way down is the other extreme. |
| 09:55 | rhickey | of course, reify methods are not functions but *are* closures |
| 09:56 | rhickey | something about having the target as an arg in extend-type/class makes it clearer these are external extensions |
| 09:56 | chouser | explicit this everywhere does have the benefit of complete uniformity. |
| 09:57 | rhickey | also, implicit this in reify isn't really acceptable, only named this (reify this P ...) because reify likely to be nested/macro-wrapped |
| 10:00 | chouser | [_] vs [] is a bit ugly, but hardly a huge cost. |
| 10:01 | rhickey | one tension is that interface declarations already take a stand that can't be changed |
| 10:01 | rhickey | so when implementing an interface the _ is extra, often forgotten baggage |
| 10:03 | rhickey | a common problem for people with gen-class |
| 10:03 | chouser | but that's interop :-) |
| 10:07 | rhickey | another wrinkle: |
| 10:07 | rhickey | (defprotocol P |
| 10:07 | rhickey | (foo [x])) |
| 10:08 | rhickey | (deftype Foo [a b c] [P] |
| 10:08 | rhickey | (foo [x] (recur 42))) |
| 10:08 | rhickey | java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 0 args, got: 1 |
| 10:08 | octe | (let [agents (map (fn [&args] (agent 0)) (range concurrent))] <- there has to be a better way. |
| 10:09 | chouser | rhickey: :-( |
| 10:09 | rhickey | recur works, but you can't replace this |
| 10:09 | chouser | right |
| 10:10 | chouser | octe: (take 10 (repeatedly #(agent 0))) |
| 10:10 | rhickey | hmm, someone proposed an n arg to repeatedly to match repeat... |
| 10:10 | chouser | octe: (for [_ (range 10)] (agent 0)) |
| 10:11 | octe | thanks. |
| 10:12 | rhickey | (extend-class String P |
| 10:12 | rhickey | (foo [s] (recur))) |
| 10:12 | rhickey | java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 0 |
| 10:14 | rhickey | there will be no way to make the same arglist and recur call work in both deftype and extend-type |
| 10:14 | rhickey | indicates they should have different arglists |
| 10:15 | octe | http://paste.lisp.org/display/91345 <- should that work? |
| 10:15 | octe | it seems to sometimes give errors |
| 10:16 | chouser | rhickey: proxy currently has the same problem. |
| 10:16 | octe | or maybe it's only sometimes if the agent function hasnt run yet.. |
| 10:16 | chouser | octe: that usage of #() is incorrect |
| 10:16 | rhickey | chouser: because proxy's implicit this is a lie |
| 10:17 | chouser | rhickey: right |
| 10:17 | octe | chouser: how? |
| 10:17 | rhickey | not so for deftype/reify |
| 10:17 | rhickey | more tea needed - biab |
| 10:19 | chouser | octe: #(foo) calls foo, so it's like (fn [] (foo)). you're trying to call println but actually calling the return value of (println "hi") which is always nil |
| 10:19 | chouser | ,((println "hi") nil) |
| 10:19 | clojurebot | java.lang.NullPointerException |
| 10:20 | chouser | octe: also, agent action fns must take at least one arg, the current value of the agent. |
| 10:20 | chouser | octe: so try (send a (fn [_] (println "hi") nil)) |
| 10:21 | octe | chouser: i don't understand the #() macro, does it take as many arguments as you actualyl use in the function? |
| 10:21 | chouser | octe: yes |
| 10:21 | chouser | well, as many as the highest you name. |
| 10:21 | djork | would it make sense to use an agent to process a line of input from a socket? |
| 10:22 | chouser | ,(#(println "4th is" %4) :a :b :c :d) |
| 10:22 | clojurebot | 4th is :d |
| 10:22 | djork | like, say the agent's value held the sockets to read/write on |
| 10:22 | chouser | djork: yeah, that will probably work. |
| 10:22 | djork | blocking is not a problem? |
| 10:23 | djork | because it could wait indefinitely |
| 10:23 | djork | right now I'm using refs |
| 10:23 | chouser | djork: blocking is fine as long as you use send-off |
| 10:23 | djork | ah, I see |
| 10:23 | octe | chouser: so, (send a #(println %1)) would work too? |
| 10:23 | octe | for example |
| 10:23 | chouser | octe: yes, but of course will change your agent state to nil |
| 10:24 | octe | yes, what i want to do is a one-off asynchronous task |
| 10:24 | octe | don't know if an agent is correct for that |
| 10:24 | chouser | octe: it might be. You might also like 'future' |
| 10:25 | chouser | hm, actually if it's one-off, agent is probably not right. |
| 10:25 | djork | future sounds perfect |
| 10:25 | djork | although deref'ing the returned future blocks |
| 10:25 | djork | so you'd be responsible for managing the time in-between |
| 10:26 | djork | but that only matters if you care about the result |
| 10:27 | octe | do not care about the result |
| 10:27 | octe | did not know about future, sounds better :) |
| 10:28 | djork | anybody else notice that JLine doesn't handle ^Y (yank or "paste")...? |
| 10:28 | chouser | I use rlwrap |
| 10:29 | djork | hmm |
| 10:29 | octe | i don't get prints from my agents/futures in my *slime-repl clojure* buffer, i seem to remember that there was some setting that fixed that |
| 10:29 | djork | that sounds better |
| 10:29 | octe | sound familiar for anyone? |
| 10:29 | djork | octe: it's probably a slime thing |
| 10:29 | octe | yes |
| 10:29 | chouser | I think they go to an inferior buffer, whatever that means. |
| 10:29 | octe | ah, yesh |
| 10:30 | octe | just need to find the variable.. |
| 10:30 | fliebel | Can I use future on the repl? It just waits until the output is returned because the return value is printed of course. |
| 10:31 | chouser | fliebel: yes. maybe stuff it in a 'def' if you don't want to wait just yet. |
| 10:31 | djork | chouser: thanks for the rlwrap tip, works great |
| 10:32 | octe | M-x slime-redirect-inferior-output |
| 10:32 | octe | if someone else was curious |
| 10:32 | octe | i find the public irc log for this channel a great help when searching for problems :) |
| 10:32 | octe | i mean solutions to problems.. |
| 10:33 | djork | oh wow, rlwrap has parens-matching, that is really killer |
| 10:33 | chouser | octe: you use google on it? |
| 10:33 | chouser | djork: and vi-keybinding support. mmmmm |
| 10:33 | fliebel | chouser: works... |
| 10:33 | djork | nice |
| 10:33 | octe | chouser: yep |
| 10:34 | chouser | octe: good. that's the intended use case. glad it's working for you. :-) |
| 10:35 | lpetit | rhickey: I don't mind having to repeat the explicit "this" in recur either, since I expect the default programming model will be to compose functions into maps , so that "adding external behaviour" might be the standard. (but maybe this <- whole sentence did not make any sense ?) |
| 10:38 | rhickey | lpetit: in deftype and reify it's not a matter of repeating - you have to leave it out |
| 10:39 | rhickey | lpetit: it will be interesting to see how much mixing in there will be - mixins are not an option inside deftype/reify |
| 10:41 | fliebel | (What are these thing? I'm trying to (doc) everything, but this gives: Unable to resolve symbol: deftype in this context) |
| 10:41 | rhickey | could be possible in deftype |
| 10:42 | rhickey | but not reify, as closure-per-method in reify reintroduces the n-object-per-object overhead of proxy |
| 10:42 | chouser | fliebel: these are experimental features in the "new" branch on github |
| 10:43 | Raynes | Incidentally, I just google the questions. If there is something relevant in the IRC logs, it is likely to be at the top of the results. |
| 10:43 | fliebel | chouser: that explains quite a lot... |
| 10:44 | chouser | fliebel: you're watching the Clojure design and implementation process in action. |
| 10:45 | fliebel | chouser: Cool, but I do not yet understand the basics... |
| 10:45 | lpetit | rhickey: I guess I'll have to grok again the current state of the defprotocol / deftype wiki pages. But from where i'm, right now, all this seems a little bit complex to remember. So I would not be against "radical" choices (if possible) that would make the rules clear, the rule list short, and let people macroify things where they are tired of typing too much ... |
| 10:47 | rhickey | lpetit: I understand, but if the simplest rule is, say, explicit this, and everyone hates it and ends up using their own macro, that's a fail |
| 10:49 | octe | is it a good/bad idea to queue up a bunch of functions with send-off to agents? |
| 10:49 | lpetit | rhickey: sure, but if the rules are more specialized for each use, and everyone hates when he/she has to add a protocol or reify something, ... |
| 10:49 | rhickey | lpetit: thus, getting it right is important |
| 10:49 | lpetit | because he has to remember / dig clojure/contrib for examples, ... |
| 10:50 | lpetit | rhickey : I'll try to draw a more comprehensive answer to your question tonight, when time permits to analyse all the cases (if it's not too late) |
| 10:50 | rhickey | there is also an underlying 'truth' that can't be papered over in an attempt to make things simpler, e.g. methods are not first class |
| 10:52 | djork | maybe there should be either a #clojuredev or #learnclojure channel :P |
| 10:52 | djork | My vote would be #learnclojure |
| 10:52 | ambient | that probably wouldn't work very well |
| 10:52 | lpetit | rhickey: out of the top of my head: is the problem related to the fact that protocols and interfaces can be mixed ? |
| 10:53 | octe | djork: yes, i ind rhickey's discussions interesting and don't want to disrupt them |
| 10:53 | octe | find* |
| 10:53 | octe | with my newbie questions |
| 10:54 | djork | I mean there should be experts in both, but our noob ramblings just don't seem to fit sometimes :D |
| 10:54 | ambient | djork: i think it's easier just when people hang around without actively participating in the teaching process. when somebody poses a question, it's easier to just give the answer if there is time/patience. it requires separate effort to log and stay into the teaching channel. and i don't think it is any bother to ask questions in this channel. IMHO FWIW |
| 10:54 | octe | djork: yes |
| 10:55 | djork | that's true |
| 10:55 | rhickey | lpetit: not really, I'm happy to set aside interface considerations. relevant just to protocols are: a) deftype and reify methods are methods, not functions, and this *is* a special (non-)argument to methods, and b) the 'this' argument will rarely be used |
| 10:55 | djork | might as well not fragment the community where it's not absolutely necessary |
| 10:57 | chouser | octe: don't worry about interrupting with newbie questions. They might get scrolled off and forgotten when other conversations are heppening, but nobody will be annoyed or bothered. |
| 10:57 | ambient | if one is a total newbie in clojure, one should read a book and the excellent tutorial by R. Mark Volkmann |
| 10:57 | tmountain | does anybody know if there have been any efforts to create any fun clojure tutorials akin to "casting spels in lisp"? http://www.lisperati.com/casting.html |
| 10:57 | lpetit | djork: and the frequency of some newbie questions is part of questioning rich & others concerning the current state of the doc, the ease of use of some features, the frequency of usage of some features etc. |
| 10:57 | chouser | octe: on the other hand, I'm afraid a newbie channel might be mostly full of newbies misleading each other. :-/ |
| 10:57 | djork | yeah |
| 10:57 | octe | yes.. |
| 10:58 | djork | hmm, yeah, if 10 people ask the same question one day, it might be a signal |
| 10:58 | ambient | heh, newbies misleading other newbies. it happens more often than not |
| 10:58 | chouser | nothing gets a response faster in here than an incorrect answer. |
| 10:58 | octe | after running shutdown-agents, is it possible to resurrect them? |
| 10:59 | djork | tmountain: that looks like fun... I think I have seen it before |
| 10:59 | chouser | the clever newbie might leverage that by logging in under a different nick and giving himself bad answers to provoke responses. |
| 10:59 | octe | chouser: yes, another proven strategy for getting help.. ask the questions in a trolling way :) |
| 10:59 | rhickey | chouser: yikes! |
| 10:59 | chouser | rhickey: :-) |
| 10:59 | tmountain | djork: a few others in the same spirit, http://learnyouahaskell.com/ and http://learnyousomeerlang.com/ |
| 11:00 | ambient | yeah, why bother when plain old trolling works just fine :P |
| 11:00 | octe | http://www.bash.org/?152037 feels relevant |
| 11:00 | djork | hah, yes octe |
| 11:00 | djork | did you see the "kissed a girl" thing from Sun? |
| 11:00 | chouser | foo: is into lazy? not-foo: yes, just like all other binding mappers. |
| 11:00 | octe | djork: yes |
| 11:00 | octe | funny |
| 11:01 | ambient | although i suppose people here are too pragmatic to be so easily trolled |
| 11:01 | octe | http://paste.lisp.org/display/91353 <- is this a good/bad way to do it? |
| 11:02 | chouser | yeah, pure trolling mostly gets ignored, thank goodness. |
| 11:02 | KarlThePagan | ambient: just start a message passing benchmark argument? |
| 11:02 | KarlThePagan | like our functions, trolling is higher-order |
| 11:02 | ambient | but then one would not be a newbie :/ |
| 11:02 | octe | KarlThePagan: was that supposed to be directed to me? |
| 11:03 | djork | octe: It's just a sense I get but I feel like there's too much going on |
| 11:03 | octe | djork: yeah.. |
| 11:03 | djork | octe: you've got refs, agents, and future |
| 11:03 | KarlThePagan | octe: no, i was giving an example of how to troll a functional language chan ;) |
| 11:03 | octe | ah |
| 11:03 | djork | oh wait, they're not refs, you're just calling agents refs because they are derefs |
| 11:04 | octe | djork: yeah |
| 11:04 | fliebel | Hmmm, I think those Head First guys should do a book on Clojure… |
| 11:04 | djork | deref'able... whatever the term is |
| 11:04 | octe | i could name it sum-agents, but it can sum anything that needs to be deref'ed :) |
| 11:04 | djork | I think Wrox should do a book on Clojure |
| 11:04 | octe | i think someone should recruit _why |
| 11:04 | fliebel | Who is Wrox? |
| 11:05 | ambient | djork: heh, good one |
| 11:05 | djork | Wrox is the worst tech publisher ever... "for programmers by programmers" |
| 11:05 | djork | no thanks |
| 11:06 | fogus | djork: Do they publish those big red books? |
| 11:06 | djork | they usually put a picture of the author on the cover which always reinforces the fact that it was written by a "regular programmer" |
| 11:06 | djork | (read: fat and unkempt) |
| 11:06 | octe | djork: beards? |
| 11:06 | djork | http://www.neudesic.com/uploads/david_barkol/webpartsbook.jpg |
| 11:07 | fliebel | How good is the Clojure book listed on Clojure.org? |
| 11:07 | octe | after doing a google image search for wrox books i see very little beards |
| 11:07 | djork | (I'm exaggerating) |
| 11:07 | ambient | fliebel: stuart's book? it's pretty good imo |
| 11:08 | fliebel | ambient: Maybe I'll get that someday… Although nothing beets Head First imo. |
| 11:08 | ambient | it's easier to extract information from the book than the hive brain of internet |
| 11:09 | octe | hmm, rich doesn't seem to have one either.. have i been fooled? i thought you needed one to be an expert |
| 11:09 | micampe | fliebel: I have it, it's good if you are new to lispy/functional languages |
| 11:09 | fliebel | ambient: For Python and PHP I found the web a very good teacher and reference. I learned Java from Head First, but did PHP and Python without any books. |
| 11:10 | ambient | fliebel: clojure requires a bit more effort to grok. both python and php are very traditional |
| 11:10 | ambient | in a sense that they're somewhat derived from algol |
| 11:10 | djork | I think Clojure's docs are a good study in docs that are very helpful if you start at the beginning and read to the end. |
| 11:10 | octe | ambient: yes, languages like those generally just require you to learn the stdlib |
| 11:10 | fliebel | But my impressions with Clojure so far is that the web is not so useful and most language concepts new, which makes them hard to learn on my own. |
| 11:11 | ambient | fliebel: reading through core.clj is also a learning experience |
| 11:11 | djork | starting with "The Reader" feels funny |
| 11:11 | djork | but it's also very good |
| 11:11 | fliebel | That is what I mean… they are all more or less C-like... |
| 11:11 | djork | but coming from curly-braces languages you get this feeling like "OK, cut to the chase..." |
| 11:11 | thehcdreamer | I would like to learn some java to take advantage of clojure java compatibility. Anyone know of a book or reference I can read online to get started? I need to reach a level where I can understand java syntax and being able to call libraries from clojure. |
| 11:12 | djork | thehcdreamer: there's really nothing to Java |
| 11:12 | fliebel | thecdreamer: I'm not sure for online, but for a real book I'd finitely recommend Head First Java :D |
| 11:13 | ambient | thinking in java by bruce eckel was free iirc |
| 11:13 | thehcdreamer | djork: I find it confusing to browse java documentation for libraries I may need in clojure, like Date |
| 11:13 | ambient | http://www.ibiblio.org/pub/docs/books/eckel/ |
| 11:13 | fliebel | djork: what did you mean with that quoted sentence? "OK, cut to the chase..." |
| 11:14 | thehcdreamer | fliebel, ambient thanks |
| 11:14 | angerman | clojures agents makes me want to have many cores... two are ok, but so little |
| 11:14 | fliebel | thecddreamer: Head First Java has some character dedicated to understanding the library. |
| 11:14 | angerman | and more memory |
| 11:15 | djork | fliebel: I mean that it's just an impulse coming from languages where syntax patterns are ingrained, and you just want to know how to translate your previous experience into a new syntax |
| 11:15 | djork | you have internalized things like "code is split into lines" |
| 11:16 | djork | and you want to jump into the library of functions |
| 11:16 | ambient | functional programmin is not a trivial step to process |
| 11:16 | djork | no |
| 11:16 | fliebel | I see... |
| 11:16 | djork | so with Clojure's docs you get a bigger picture by starting with the reader, etc. |
| 11:16 | djork | introducing the repl as a fundamental part of the language |
| 11:17 | djork | whereas with other languages it's like "OK you know how source code works... here's how to make an array" |
| 11:17 | ambient | in clojure you dont tell the computer how to do stuff, you tell it what to do |
| 11:17 | djork | right |
| 11:17 | fliebel | ambient: that is quite confusing.... |
| 11:18 | djork | well, I dunno |
| 11:18 | djork | FP is more declarative than imperative |
| 11:18 | djork | so I'd say it's the opposite |
| 11:18 | octe | does doseq do recur? |
| 11:18 | djork | no |
| 11:19 | fliebel | declarative: "denoting high-level programming languages that can be used to solve problems without requiring the programmer to specify an exact procedure to be followed." |
| 11:19 | djork | you can of course have other forms inside of doseq that serve as a recur point |
| 11:19 | djork | fliebel: well never mind then :P |
| 11:19 | octe | djork: when i add (doseq [agent agents] (println agent)) to a catch-expression i get "Cannot recur from catch/finally" |
| 11:20 | djork | oh I see what you mean |
| 11:20 | djork | can you paste? |
| 11:21 | chouser | octe: yeah, doseq uses recur internally |
| 11:21 | octe | http://paste.lisp.org/display/91357 |
| 11:21 | octe | chouser: ah, ok |
| 11:21 | octe | how would i do that then? |
| 11:21 | chouser | octe: and you can't (currently) use recur in a catch block. |
| 11:21 | djork | doseq does use recur and it is a macro |
| 11:21 | octe | yes, that's what i suspected |
| 11:21 | djork | that's kind of an odd gotcha |
| 11:21 | chouser | just put the body of your catch block in a separate function, and call it from the catch |
| 11:22 | chouser | you can even do that all in-line if you want. |
| 11:22 | octe | i find it kind of odd that you get a regular java.lang.Exception when an agent has errors and you try to deref it |
| 11:22 | octe | would be nicer if it was a specific exception |
| 11:22 | chouser | octe: agent error handling is being redone. |
| 11:22 | fliebel | I am developing the habit to run macroexpand-1 on everything I encounter now... |
| 11:22 | octe | i can't check for errors before i deref it since they may happen between the cehck and deref, right? |
| 11:22 | djork | man, doseq is one hairy macro |
| 11:22 | chouser | djork: not as bad as 'for' :-P |
| 11:23 | chouser | octe: https://www.assembla.com/wiki/history/clojure/Agent_exception_handlers |
| 11:23 | chouser | octe: but that's a ways off. :-/ |
| 11:23 | djork | for looks like it is broken up into three main pieces |
| 11:23 | octe | chouser: nice, i |
| 11:23 | octe | chouser: nice, i'll read it later, heading home now |
| 11:23 | djork | doseq just kind of goes on |
| 11:24 | fliebel | ,(macroexpand-1 '(doseq [a [1 2 3]] (println a))) |
| 11:24 | clojurebot | (clojure.core/loop [seq_8240 (clojure.core/seq [1 2 3]) chunk_8241 nil count_8242 (clojure.core/int 0) i_8243 (clojure.core/int 0)] (if (clojure.core/< i_8243 count_8242) (clojure.core/let [a (.nth chunk_8241 i_8243)] (do (println a)) (recur seq_8240 chunk_8241 count_8242 (clojure.core/unchecked-inc i_8243))) (clojure.core/when-let [seq_8240 (clojure.core/seq seq_8240)] (if (clojure.core/chunked-seq? seq_8240) (clojure.co |
| 11:24 | djork | HOLY GOD |
| 11:24 | djork | I just did exactly the same thing in my repl |
| 11:25 | djork | [1 2 3] and all |
| 11:25 | djork | :P |
| 11:25 | djork | it is bigger than clojurebot wants to print |
| 11:25 | fliebel | strange, in repl it's quite small... |
| 11:25 | chouser | fliebel: might depend on your version of Clojure |
| 11:26 | djork | clojurebot might be running a different version |
| 11:26 | djork | ,*clojure-version* |
| 11:26 | clojurebot | {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"} |
| 11:26 | chouser | chunked seq support requires quite a bit more code |
| 11:27 | fliebel | mine is: {:major 1, :minor 0, :incremental 0, :qualifier ""} |
| 11:27 | djork | there you go |
| 11:27 | djork | you must have grabbed the jar from clojure.org |
| 11:27 | fliebel | what is chunked seq support? |
| 11:27 | fliebel | Indeed... |
| 11:28 | fliebel | Well, at least MacPorts did. |
| 11:28 | chouser | chunked seq support (with docs!) is coming for 1.1.0 |
| 11:29 | fliebel | chouser: I figured that, but what does that mean? |
| 11:29 | fliebel | Or is it half a wiki to explain? |
| 11:30 | chouser | there's a video. some slides. |
| 11:30 | ambient | i think it has something to do with granularity |
| 11:30 | djork | fliebel: I would clone from github |
| 11:31 | chouser | one line summary is they allow you to use exactly the same high-level functions you do today, but they run faster (with a bit less laziness). |
| 11:31 | djork | chunked seqs break up the computation of seqs into bigger pieces so that lazy seqs don't have to kick off a generation function for every element |
| 11:32 | fliebel | cool, so it's just optimization I wont notice? |
| 11:32 | chouser | fliebel: you can take some advantage of it without noticing, yes. |
| 11:34 | fliebel | I have done nothing productive or remotely useful with Clojure yet, but I'm starting to like it. I just did my first concurrent line of code without even noticing! |
| 11:35 | ambient | im doing progressively larger projects |
| 11:35 | ambient | fm synth > genetic image construction > jpeg |
| 11:35 | rhickey | anything else we wanted deprecated in 1.1? add-classpath, ^, parallel.clj |
| 11:36 | fliebel | Lol, commas are whitespace aren't they? I just noticed that Clojure preserves them when printing the representation of a map. |
| 11:36 | chouser | fliebel: yeah, inserts them. |
| 11:37 | chouser | ,{1 2 3 4 5 6 7 8} |
| 11:37 | clojurebot | {1 2, 3 4, 5 6, 7 8} |
| 11:37 | fliebel | cool |
| 11:37 | djork | the printer is nice to us |
| 11:37 | fliebel | ,[1 2, 3 4,,,, 5 6] |
| 11:37 | clojurebot | [1 2 3 4 5 6] |
| 11:38 | fliebel | Indeed :) |
| 11:39 | chouser | rhickey: I guess not for 1.1. Do you have any interest in discussions (now or post-1.1) about character literals or escape sequences in strings? |
| 11:40 | rhickey | chouser: you mean the interpolation stuff? |
| 11:40 | fliebel | How far of is 1.1? |
| 11:40 | chouser | rhickey: no, I just mean \newline and/or "\n" |
| 11:40 | rhickey | chouser: what about them? |
| 11:41 | djork | I like character literals |
| 11:42 | rhickey | chouser: you can just point me to the discussion if I missed it |
| 11:42 | chouser | no, there's been no discussion. except in my head. :-P |
| 11:42 | rhickey | ah, there |
| 11:43 | fliebel | Can someone explain me the use of \newline? |
| 11:43 | fliebel | ,(str \newline "\n") |
| 11:43 | clojurebot | "\n\n" |
| 11:44 | micampe | should I use Java APIs to send data over a socket or is there something useful in clojure? |
| 11:44 | chouser | ,(map class [\newline "\n"]) |
| 11:44 | clojurebot | (java.lang.Character java.lang.String) |
| 11:45 | fliebel | chouser: memory efficiency? |
| 11:45 | noidi | is there a function for transforming (a1 b1 c1 a2 b2 c2 a3 b3 c3 ...) to ((a1 a2 a3 ...) (b1 b2 b3 ...) (c1 c2 c3 ...)) ? |
| 11:45 | micampe | oh, I found examples, great |
| 11:46 | chouser | fliebel: no, just a way of naming a character in clojure source code. C uses '\n' vs "\n" for char vs string. Clojure uses \newline |
| 11:46 | fliebel | ah, that is why \n returns just n... |
| 11:47 | replaca_ | are we deprecating ^ ? |
| 11:47 | chouser | right. \n looks exactly like a newline, but isn't. |
| 11:47 | chouser | replaca_: yes, use (meta ...) instead. |
| 11:47 | fliebel | Fun ingredients for some code obfuscation :D |
| 11:47 | replaca_ | chouser: how come? |
| 11:48 | djork | \n looks like a newline *in other languages* |
| 11:48 | replaca_ | do folks want it for something else? |
| 11:48 | chouser | djork: \n is newline in clojure strings. |
| 11:48 | djork | yes |
| 11:48 | noidi | google ftw |
| 11:48 | noidi | ,(apply map vector (partition 3 (range 12))) |
| 11:48 | clojurebot | ([0 3 6 9] [1 4 7 10] [2 5 8 11]) |
| 11:48 | chouser | replaca_: yes, type hints. (defn add [x^Integer y^Integer] ...) |
| 11:48 | rhickey | replaca_: yes, would like ^ to replace #^ |
| 11:49 | rhickey | maybe what chouser said too |
| 11:49 | rhickey | the latter could happen without deprecation |
| 11:50 | rhickey | I mean x^String could happen just by making ^ ok inside symbols |
| 11:50 | chouser | well, x^{:tag String, :foo :bar} would be nice too |
| 11:50 | replaca_ | rhickey, chouser: I see. Priorities. Need that old APL keyboard so we don't have to make choices :-) |
| 11:50 | rhickey | but #^ seems to really trip people up, brings out the perl remarks |
| 11:51 | replaca_ | I use ^ all over the place (mostly in the autodoc stuff), but I'm not really *that* hung up on it |
| 11:51 | chouser | quote behavior is less surprising with trailing ^ |
| 11:51 | rhickey | chouser: still don't need to deprecate for that |
| 11:51 | fliebel | what is #^? I can't google that characters. |
| 11:51 | Chousuke | read-time metadata |
| 11:52 | rhickey | I think the existing metadata would be cleaned up a lot with ^ vs #^ |
| 11:52 | replaca_ | fliebel: substitute for with-meta at read-time |
| 11:52 | chouser | rhickey: you mean without reordering it? |
| 11:52 | Chousuke | ,(meta #^{:foo 'bar} []) |
| 11:52 | clojurebot | {:foo bar} |
| 11:52 | rhickey | replaca_: No |
| 11:52 | replaca_ | I agree ^ is a lot prettier |
| 11:52 | fliebel | another macro... |
| 11:52 | replaca_ | oops, no? |
| 11:53 | rhickey | #^ != with-meta |
| 11:53 | chouser | #^ attaches metadata to the form being read |
| 11:54 | rhickey | ,(read-string "^x") |
| 11:54 | clojurebot | (clojure.core/meta x) |
| 11:54 | rhickey | ,(read-string "#^String x") |
| 11:54 | clojurebot | x |
| 11:54 | rhickey | ,(meta (read-string "#^String x")) |
| 11:54 | clojurebot | {:tag String} |
| 11:54 | chouser | with-meta attaches metadata to an object at runtime |
| 11:55 | replaca_ | right, that's what I meant. It's like with-meta, but at read time |
| 11:55 | fliebel | ok, thanks |
| 11:56 | replaca_ | but I get what you mean, it's not a straight macro expansion |
| 11:56 | rhickey | replaca_: people think that #^ and ^ are analogues |
| 11:57 | replaca_ | rhickey: Yeah, #^ is a problem for the pretty printer cause you can't read code with it and then prety print it back out and get what you expect. |
| 11:57 | rhickey | so describing the behavior of #^ given that presumption is tricky |
| 11:57 | replaca_ | that's why to do real code reformatting, we'll need a custom reader |
| 11:58 | rhickey | replaca_: you can't? even with *print-meta* ? |
| 11:58 | replaca_ | (that treats both #^ and ; specially) |
| 11:58 | replaca_ | yeah, you can print the meta data on something, but it wasn't necessarily applied with the form you just read |
| 11:59 | replaca_ | (although I don't yet support *print-meta* in the pretty printer and I should) |
| 11:59 | rhickey | replaca_: do you have an example?, I'm confused |
| 11:59 | maravillas | ,(doc read-string) |
| 11:59 | clojurebot | "([s]); Reads one object from the string s" |
| 12:00 | replaca_ | rhickey: hang on a sec and I'll cons one up |
| 12:00 | lisppaste8 | rhickey pasted "explicit elided this" at http://paste.lisp.org/display/91364 |
| 12:01 | rhickey | so, in thinking about implicit this, trying to tease out the 2 aspects - the elision from the arglist, and the implicit name |
| 12:01 | rhickey | the latter is a no go for reify |
| 12:01 | chouser | because of nesting |
| 12:02 | replaca_ | ,(binding [*print-meta* true] (print '(def f #^{:a 7} 'bar))) |
| 12:02 | clojurebot | DENIED |
| 12:02 | rhickey | the above paste proposes unified syntax for deftype/reify/extend-*, where this arg is always eilided, but never implicit |
| 12:02 | rhickey | if you want to refer to this, must supply this-name where indicated, same name applies throughout |
| 12:02 | chouser | optionally implicit? |
| 12:03 | rhickey | chouser: no, never implicit |
| 12:03 | rhickey | always elided |
| 12:03 | replaca_ | rhickey: I don't know why the bot doesn't like that, but that produces "(def f (quote bar))" |
| 12:04 | chouser | replaca_: it just doesn't like the word 'def' |
| 12:05 | replaca_ | chouser: picky, picky |
| 12:05 | chouser | ,(binding [*print-meta* true] (print '(f #^{:a 7} 'bar))) |
| 12:05 | clojurebot | (f (quote bar)) |
| 12:05 | chouser | ,(binding [*print-meta* true] (prn '(f #^{:a 7} 'bar))) |
| 12:05 | clojurebot | (f #^{:a 7} (quote bar)) |
| 12:06 | replaca_ | chouser: yes, but if 'bar had already had metadata you'd get that too |
| 12:07 | rhickey | replaca_: is the metadata even there? |
| 12:07 | rhickey | (-> '(fred f #^{:a 7} 'bar) (nth 2) meta) |
| 12:07 | rhickey | ,(-> '(fred f #^{:a 7} 'bar) (nth 2) meta) |
| 12:07 | clojurebot | {:a 7} |
| 12:07 | replaca_ | rhickey: no, I munged the syntax |
| 12:07 | Chousuke | rhickey: that syntax looks pretty good. |
| 12:08 | replaca_ | rhickey: but check this out: "(binding [*print-meta* true] (prn '(def f #^{:a 7} 'bar)))" |
| 12:08 | replaca_ | clojurebot can't do it, but (when f is deffed in my repl), I get: |
| 12:09 | replaca_ | #^{:line 1} (def f #^{:line 1, :a 7} (quote bar)) |
| 12:09 | lpetit | rhickey: concerning implicit this and methods / functions, I'd say if possible, have implicit this for methods, and then have methods defined with the leading dot, and have explicit this otherwise (and not leading dot for the function) |
| 12:10 | replaca_ | which is not what I typed in |
| 12:10 | Chousuke | replaca_: line metadata is attached to lists at read-time |
| 12:10 | lpetit | replaca_: Would a rewrite of pprint be worth the trouble, as far as possible performance gains are involved ? |
| 12:10 | rhickey | replaca_: because of the line stuff? |
| 12:11 | lpetit | replaca_: I meant, a rewrite using protocols |
| 12:11 | replaca_ | Chousuke: and there are a bunch of other reasons that an object can have metadata besides that |
| 12:11 | rhickey | lpetit: leading dot for protocol method defs too? |
| 12:11 | lpetit | rhickey: yes, "a cat is a cat", sort of |
| 12:12 | chouser | a shame the this-name has to be in a vector, but it's good that its consistent. |
| 12:12 | lpetit | rhickey: and implicit this comes with methods (OO hat), explicit "this" comes with functions (functional hat) |
| 12:12 | rhickey | lpetit: ick, dot is so host-y, I;d hate to have it be part of describing pure protocols + deftype |
| 12:12 | replaca_ | since pprint hacks things up before printing them, the metadata on any object is relevant and since you can't tell if it came from the form you're printing or not |
| 12:12 | chouser | ,(binding [*print-meta* true] (prn (read-string "(def f #^{:a 7} 'bar)"))) |
| 12:12 | clojurebot | (def f #^{:a 7} (quote bar)) |
| 12:12 | replaca_ | you cant really use the *print-meta* mechanism |
| 12:12 | magnet | (OT: "appeler un chat un chat" translates to "to call a spade a spade") |
| 12:13 | chouser | replaca_: the metadata really is on those objects. to not print it would be a lie. |
| 12:13 | chouser | replaca_: you can use read-string as I showed there, or some other mechanism, to get objects that don't have line numbers and such attached. |
| 12:14 | replaca_ | chouser: that's true, if your goal is to do what *print-meta* is trying to do, but not if you're trying to print the expression as read |
| 12:14 | chouser | no, that's how it *is* read. that metadata is there as soon as the thing is read |
| 12:14 | replaca_ | chouser: I think there's potentially more stuff than just line numbers |
| 12:14 | chouser | it may not be what you typed, but it's what was read. |
| 12:15 | lpetit | rhickey: is the fact that protocol method defs are methods an implementation detail or not ? Even if so, is this implementation detail a "leaky abstraction" in terms of what one can or cannot do (closures or not, pure functions or not) ... If yes, then maybe let the abstraction leak in an explicit way ? |
| 12:15 | chouser | similar to how ; comments work. you typed it, but the reader doesn't produce anything for it |
| 12:15 | replaca_ | yes, but an object can have other metadata on it. I haven't thought about this in a long time. I'll have to put together some more precise examples |
| 12:16 | chouser | hm, maybe you're wanting to print source code with type hints but not other metadata? |
| 12:16 | rhickey | lpetit: well, there will have to be some discussion of implicit access to the fields and the non-first-class-nature of 'methods', but not really a tie to Java and interop like dot might imply - for instance, you won't be calling the protocol methods via .method |
| 12:17 | replaca_ | chouser: If I'm trying to reformat source code, I want to be able to reconstruct only those things the user entered |
| 12:17 | rhickey | replaca_: I think the only system-added metadata from read is :line |
| 12:17 | lpetit | rhickey: not be calling them via .method -> sounds right, since the (possible, maybe I'm wrong ?) "leaky abstraction" is more on the def side , isn't it ? |
| 12:17 | chouser | huh. maybe should be :clojure.core/line |
| 12:18 | replaca_ | rhickey: yeah, but in the context of the pretty printer, it's possible for arbitrary user metadata to be attached to something (e.g. a symbol) when I'm trying to print it, I think |
| 12:18 | replaca_ | rhickey: I'll have to reconstruct my original logic on this and make sure I'm right. I thought about it pretty hard back in February or so :-) |
| 12:19 | rhickey | replaca_: but why wouldn't you print it if *print-meta* was true? Either it's what they read or they mucked with it |
| 12:19 | hiredman | I imagine the prettyprinter is a whole 'nother kettle of fish |
| 12:19 | chouser | rhickey: with the "explicit elided this", recur always matches the arg count of the literal arg vector? |
| 12:19 | rhickey | chouser: no |
| 12:19 | replaca_ | rhickey: right, *print-meta* was your suggestion :) |
| 12:19 | replaca_ | rhickey: I was just talking about using the pretty printer to do code reformatting |
| 12:20 | replaca_ | lpetit: I haven't yet thought much about using protocols in the pretty printer |
| 12:21 | rhickey | lpetit: I don't understand your last comment |
| 12:21 | rhickey | chouser: I think recur behavior, while telling, is low priority |
| 12:21 | chouser | ok |
| 12:21 | replaca_ | lpetit: The one problem that comes up is tht the pretty printer is based on extended java writers which are classes and not interfaces :-( |
| 12:21 | lpetit | rhickey: I agreed that from the calling side, not calling via .method seemed ok to me |
| 12:22 | lpetit | replaca_: :-( |
| 12:22 | rhickey | lpetit: it's necessary, since some implementations of protocols will not be methods at all, i.e. protocols are not interfaces |
| 12:23 | rhickey | jekyll and hyde |
| 12:24 | rhickey | chouser: something about (extend-class String [s] ...) where s is implicit first arg seems neat |
| 12:24 | rhickey | and in the frequent case where you don't use this, you just leave it out |
| 12:28 | rhickey | lpetit: my first cut with deftpe/reify implementing protocols had .method and implicit this - .method bothered me the most, a mismatch with protocols |
| 12:30 | lpetit | rhickey: I must leave, but I'll re read the fundamentals of what we're talking about first, in the wiki, and then will come back to this discussion concerning the syntax (if I have ideas, of course :-) ) |
| 12:31 | rhickey | lpetit: ok, thanks |
| 12:32 | rhickey | seems like splitting off implicit from eliding isn't helping anyone |
| 12:39 | lisppaste8 | rhickey annotated #91364 "vs explicit supplied" at http://paste.lisp.org/display/91364#1 |
| 12:41 | lisppaste8 | rhickey annotated #91364 "most extends will supply this" at http://paste.lisp.org/display/91364#2 |
| 13:00 | chouser | rhickey: I don't think I understand your first example there yet |
| 13:01 | chouser | is [this-name] there, or not? if supplied, you don't include it in each method? |
| 13:06 | Chousuke | if it can be omitted, it just reduces to the confusing case in most siutations |
| 13:06 | Chousuke | situations* |
| 13:14 | srader | rhickey: I think I found a bug in deftype |
| 13:14 | rhickey | chouser: [this-name] is only needed if you want to refer to this in any method body, never impacts arglists |
| 13:14 | rhickey | srader: what is it? |
| 13:14 | srader | (deftype Foo [a b c]) (def foo (Foo 1 2 3)) (:a foo) |
| 13:15 | chouser | rhickey: ah, that's what you mean by not-implicit. If not specified, there's no way to refer to it? |
| 13:15 | srader | eval that twice and I get #<Foo$__lookup__a user.Foo$__lookup__a@128594c> |
| 13:15 | srader | instead of 1 |
| 13:16 | rhickey | chouser: right |
| 13:16 | rhickey | srader: ok, will check that out |
| 13:16 | srader | rhickey: thx |
| 13:25 | rhickey | srader: fixed -thanks for the report |
| 13:30 | esj | is there a function of a map that returns a struct-map of that map ? |
| 13:32 | esj | i could map over the map assoc'ing into the struct-map, but that seems a bit roundabout ? |
| 13:33 | rhickey | esj: why do you want the struct-map? |
| 13:33 | esj | to share the keys between all the struct-maps efficiently. |
| 13:34 | rhickey | esj: so the map is a prototype for many more? |
| 13:34 | esj | exactly. |
| 13:35 | esj | i will get many instances of the map over time, and I want to store them. |
| 13:37 | cark | esj: there is create-struct as a starting point for your function |
| 13:37 | rhickey | ,(let [m {:a 1 :b 2 :c 3} s (apply create-struct (keys m))] (apply struct s (vals m))) |
| 13:37 | clojurebot | {:a 1, :b 2, :c 3} |
| 13:38 | esj | great stuff, thanks. |
| 13:39 | esj | i'd come up with this: (reduce (fn [c [a b]] (assoc c a b)) (struct-map struct-reading) reading) is it obviously worse ? |
| 13:39 | esj | where 'reading' is the map in question |
| 15:00 | rongenre | ,clojurebot (< Double/MIN_VALUE 0) |
| 15:00 | clojurebot | java.lang.Exception: Unable to resolve symbol: clojurebot in this context |
| 15:00 | rongenre | ,(< Double/MIN_VALUE 0) |
| 15:00 | clojurebot | false |
| 15:00 | rongenre | Yeah, that's not right |
| 15:01 | Chousuke | hmmh |
| 15:01 | rongenre | I'm assuming it's kind of a silent overflow |
| 15:01 | Hun | ,Double/MIN_VALUE |
| 15:01 | clojurebot | 4.9E-324 |
| 15:01 | Hun | in my book that's still > 0 |
| 15:02 | Hun | that would be least-positive-double-float |
| 15:02 | rongenre | yup. |
| 15:02 | Hun | oh, nevermind. read your line wrong :) |
| 15:03 | rongenre | Oh good. MIN_VALUE for double means.. smallest positive |
| 15:03 | rongenre | great |
| 15:05 | liebke | _ato: are you around? Clojars is throwing a sql exception when I try to add someone to the incanter group. Have you seen this before? |
| 15:07 | kotarak | Is it possible to define a print-method for things implementing a Protocol? |
| 15:10 | stuartsierra | ,(Double/MIN_VALUE) |
| 15:10 | clojurebot | 4.9E-324 |
| 15:10 | stuartsierra | ,(Double/MAX_VALUE) |
| 15:10 | clojurebot | 1.7976931348623157E308 |
| 15:10 | rhickey | kotarak: hopefully printing will be based upon protocols at some point |
| 15:11 | kotarak | rhickey: yes, that's my pain at the moment. I want to print a modified IMapEntry as [k v], but it is not recognised as such. |
| 15:12 | kotarak | Since I use reify, I cannot define a custom print-method. But with deftype, it should be possible in the AOT case, no? |
| 15:13 | rhickey | a protocol isn't a type, so type based dispatch won't cover all participants in a protocol |
| 15:13 | rhickey | but deftype will give you a deterministic result from (type x), AOT or not |
| 15:14 | kotarak | argh. Right. So I should probably go with deftype and the protocol. |
| 15:14 | rhickey | so current printing can be extended with deftype, not protocols |
| 15:15 | technomancy | liebke: _ato is on australian time; probably asleep right now. |
| 15:16 | kotarak | Hmm.. How is printing a IMapEntry handled anyway? I extend IMapEntry so shouldn't it print like a "normal" IMapEntry? |
| 15:16 | Chousuke | rhickey: hm. did redefining a protocol reset it completely? (even if the protocol doesn't change) If not, I guess that would nearly solve the print-method problem that causes trouble if you try to re-eval all of clojure.core during runtime. |
| 15:16 | Chousuke | neatly* :P |
| 15:16 | liebke | technomancy: you never know when a hacker is awake :) |
| 15:17 | alexyk | how do you guys parse the command-line options? |
| 15:17 | technomancy | true =) |
| 15:18 | alexyk | ? |
| 15:18 | kotarak | alexyk: there is c.c.command-line |
| 15:19 | alexyk | ok... and what's the way to declare the "main"?"" |
| 15:20 | The-Kennz | alexyk: (defn -main [] ...)? |
| 15:20 | kotarak | alexyk: http://clojure.org/Compilation |
| 15:20 | The-Kennz | alexyk: http://clojure.org/compilation |
| 15:20 | The-Kennz | heh.. kotarak was faster |
| 15:20 | alexyk | thanks! the URL are case-insensitive, I guess |
| 15:21 | alexyk | is defn- main same as defn -main? |
| 15:21 | Chousuke | no |
| 15:21 | kotarak | defn- is a private defn |
| 15:21 | alexyk | what's -main then? |
| 15:21 | Chousuke | alexyk: the - in -main is a naming convention used when defining java methods. |
| 15:22 | Chousuke | you need gen-class in order to have a "main" in Clojure. |
| 15:23 | kotarak | alexyk: you can add any prefix you like: (gen-class ... :prefix MyCoolPrefix-) (defn MyCoolPrefix-main ...) Nice when defining multiple classes in one namespace. |
| 15:23 | chouser | in order to have a Java main that is |
| 15:23 | alexyk | Chousuke: ok... do you have to define a main in order to run from the command line? Or can I run with clojure <some opts> <myfiles>? |
| 15:24 | alexyk | I'm usually running things after maven makes a jar out of them, since mvn ...run doesn't distinguish stderr and stdout |
| 15:27 | kotarak | with deftype I can still override Object methods, like toString, right? |
| 15:33 | jasapp | is there something similar to common lisp's :print-function for clojure structures? |
| 15:36 | michaeljaaka | hi |
| 15:37 | michaeljaaka | is there any easier way to do that? http://gist.github.com/246622 note that filter-neg is an func defined by user |
| 15:37 | kotarak | rhickey: hmm.. extenders do not contain eg. (deftype Foo [] [Protocol] ..), is this correct? |
| 15:42 | Chousuke | michaeljaaka: (filter identity (map f seq))? |
| 15:42 | Chousuke | hm, I guess not. |
| 15:43 | michaeljaaka | hmm output the same |
| 15:43 | michaeljaaka | is it lazy? |
| 15:44 | Chousuke | yes |
| 15:44 | Chousuke | it maps f over a seq and removes anything nontrue |
| 15:44 | Chousuke | ie. nils and falses |
| 15:44 | chouser | kotarak: yes |
| 15:44 | michaeljaaka | Chousuke: so it is the same |
| 15:45 | michaeljaaka | i exactly wanted to get that effect |
| 15:45 | Chousuke | michaeljaaka: right. I just misread your function a bit : |
| 15:45 | kotarak | chouser: hmm.. And what is the reason, why Foo should not be in extenders? Is it to retrieve "after-design-time" extensions? |
| 15:46 | Chousuke | michaeljaaka: there are remarkably few things you can't do with the standard seq functions. :P |
| 15:46 | chouser | kotarak: sorry, was answering your first question: deftype can overrice toString |
| 15:46 | kotarak | chouser: ah. Ok. Found that out already. :) |
| 15:46 | michaeljaaka | Chousuke: so FP is just for me ;) |
| 15:47 | Chousuke | every time you start constructing an explicit lazy seq you should stop and ponder if you could just find the right combination of map, filter and partition for it :P |
| 15:47 | michaeljaaka | Chousuke: well identity was the key |
| 15:48 | chouser | kotarak: I don't think I understand your second question. |
| 15:49 | rhickey | kotarak: me either |
| 15:50 | kotarak | chouser: I did (deftype LazyMapEntry [k v] [ILazyMapEntry IMapEntry] ...). My code failed because IMapEntry and IPersistentVector are in extenders (added by extend-protocol) but ::LazyMapEntry was not. Hence extends? returned nil. Then I found out, that I really wanted satisfies?. That works also for the deftype. But let me check again. |
| 15:50 | kotarak | user=> (extenders ILazyMapEntry) |
| 15:50 | kotarak | (clojure.lang.IMapEntry clojure.lang.IPersistentVector) |
| 15:52 | rhickey | kotarak: extenders returns only the classes/type for which extend* was called |
| 15:52 | rhickey | as you discovered, satisfies? is the test |
| 15:53 | kotarak | rhickey: ookk? Is there a special reason? I mean I could do (deftype Foo [] [Protocol] ....) and then (extend ::Foo Protocol some-mixin-map) |
| 15:54 | rhickey | kotarak: special reason for what? it answers a specific question. The set of types specifying a protocol is never going to be listed in extenders |
| 15:54 | rhickey | since it is an open set |
| 15:54 | rhickey | all derivees of an interface that extends a protocol for instance |
| 15:55 | rhickey | they won;t all register |
| 15:55 | kotarak | hmm... then I don't get the use of extends?. |
| 15:55 | rhickey | also, there may be at some point a way to ask for the method map of an extender - there isn't one for a deftype that implements directly |
| 15:55 | kotarak | ah. ok. |
| 15:56 | rhickey | there are many ways to participate in a protocol, explicit extends is just one |
| 15:56 | rhickey | extenders/extends? is just about explicit extenders |
| 15:56 | kotarak | rhickey: then (deftype .... (foo [] ..)) is not the same as (deftype ...) (extend ... {:foo ...})? |
| 15:57 | rhickey | kotarak: not at all |
| 15:57 | kotarak | ok |
| 15:57 | rhickey | in the former case the type participates in the protocol by implementing its interface |
| 15:58 | rhickey | and the implementations are methods of the class |
| 15:58 | rhickey | in the latter case it is an explicit registration of a map of ordinary fns |
| 15:58 | chouser | but users of the deftype don't need to know which, as long as it 'satisfies?'? |
| 15:59 | kotarak | so the former is faster, I guess..... No mixins for deftype, then? |
| 15:59 | kotarak | No, of course not. deftype method are not closures. |
| 15:59 | rhickey | kotarak: I've been thinking about that, might be possible - method calls fn |
| 16:00 | rhickey | just working on that today |
| 16:00 | rhickey | kind of a mismatch with the macro aspect of deftype |
| 16:02 | rhickey | there will be a way to ask a protocol for the implementation of a fn for a specific extender |
| 16:02 | rhickey | right now: |
| 16:02 | rhickey | user=> (-> P :impls ::Bar :foo) |
| 16:02 | rhickey | #<user$eval__135$fn__140 user$eval__135$fn__140@68302e67> |
| 16:02 | rhickey | get impl of foo for type Bar |
| 16:03 | rhickey | that can't be supported by non-extenders |
| 16:03 | chouser | because a deftype method is a java method, and therefore not a thing of its own. |
| 16:03 | rhickey | right |
| 16:04 | michaeljaaka | Chousuke: I often use (defn map-apply[f col] (map #(apply f %) col)) is there any fun to give the same effect? |
| 16:04 | rhickey | and not registered, part of the open set of implementors of the protocol interface |
| 16:05 | chouser | michaeljaaka: your col is nested seqs? [[1 2 3] [4 5 6] [7 8 9]] ? |
| 16:05 | michaeljaaka | yes |
| 16:06 | chouser | ,(apply map list [[1 2 3][4 5 6][7 8 9]]) |
| 16:06 | clojurebot | ((1 4 7) (2 5 8) (3 6 9)) |
| 16:06 | chouser | hm, that's the wrong axis |
| 16:07 | chouser | michaeljaaka: I can't think of any better way to do that. |
| 16:07 | michaeljaaka | ok |
| 16:07 | michaeljaaka | thx |
| 16:11 | chouser | rhickey: deftype doesn't adjust the protocol object or functions at all does it. |
| 16:12 | chouser | each protocol fn starts with a case for handling objects that implement the protocols matching interface, and thats how a deftype hooks in? |
| 16:12 | rhickey | chouser: nope |
| 16:12 | rhickey | oops, 2 questions |
| 16:12 | chouser | yep, sorry. |
| 16:13 | rhickey | right, deftype implementing a protocol doesn't alter it |
| 16:13 | rhickey | there are a few layers to the implementation |
| 16:13 | rhickey | each function of the protocol has a fast-path preamble that checks for an instance of the protocol interface, and makes a method call as you saw |
| 16:14 | chouser | ok |
| 16:14 | rhickey | that will be the case whenever a protocol fn is used as a first-class object |
| 16:14 | rhickey | but callsites now know about protocols |
| 16:14 | chouser | ah |
| 16:14 | chouser | whoa |
| 16:15 | rhickey | whenyou compile a function that calls foo, where foo is a protocol fn, the compiler will look at the protocol, find the interface, find the method, and burn in that fastpath preamble right into your function |
| 16:15 | chouser | callsites see that the symbol being called is a protocol fn and not some other local or var, in order to do special things? |
| 16:15 | chouser | whoa |
| 16:15 | chouser | ok |
| 16:15 | rhickey | yep |
| 16:16 | rhickey | and hotspot will inline those calls |
| 16:16 | rhickey | just like you said .foo |
| 16:16 | chouser | but with so much more flexibility |
| 16:16 | rhickey | right, so much more |
| 16:16 | chouser | and no type hints |
| 16:17 | rhickey | and ease of use, vs (defn bar [#^IProtocol x] (foo x)) |
| 16:17 | rhickey | heh |
| 16:17 | kotarak | rhickey: to take karmazilla's words "dude, you are made of awesome :)" |
| 16:17 | chouser | haha |
| 16:18 | rhickey | plus the call sites do additional caching for the non-interface case - they will look up the callee in the extenders map, find the method, and store it right in the caller |
| 16:18 | rhickey | so no lookup as long as same target type |
| 16:19 | rhickey | so calls to extenders (like if you extended String) are also very fast at sites where the target is homogenous |
| 16:19 | chouser | probably about as fast as a direct fn call |
| 16:19 | rhickey | right |
| 16:20 | chouser | hm. to a local fn, not through a var |
| 16:20 | rhickey | no, through a var since it needs to see dynamic updates |
| 16:20 | chouser | oh, ok. |
| 16:21 | rhickey | but the check happens i nthe pipeline - since it has the fn to call cached, the fastpath proceeds to set that call up while the pipeline pulls the var and tests against local for identity |
| 16:21 | rhickey | it is definitely faster than waiting to see what's in the var and using that |
| 16:21 | rhickey | so, say, in between direct and through var |
| 16:21 | chouser | huh. cool. |
| 16:22 | chouser | you're referring to the CPU instruction pipeline here? |
| 16:22 | rhickey | right |
| 16:22 | rhickey | the guard does need to pull the var, and the test is for no change, but the fastpath presume true for that, and has the value already in hand |
| 16:23 | chouser | kotarak: it's entirely possible that quote is backwards, and that awesome is made of rhickey. |
| 16:23 | rhickey | vs, you know nothing, have to wait for the var result to proceed |
| 16:23 | chouser | rhickey: yep, I think I've got it. |
| 16:23 | kotarak | HAHA! |
| 16:24 | rhickey | the coolest thing is that non of this speed requires AOT |
| 16:24 | rhickey | nene |
| 16:24 | rhickey | none |
| 16:25 | leafw_ | rhickey: drunk with happiness |
| 16:25 | kotarak | awesomeness ;) |
| 16:26 | technomancy | chouser: time for a clojure-specific spin-off of http://www.schneierfacts.com/ it sounds like |
| 16:26 | chouser | I once promised a blog about Clojure warts. But the list is small and likely to shrink as work gets done, so I'll just paste it. typos and all |
| 16:26 | rhickey | so, if you know in advance and have control, putting the protocol impl right in deftype/reify is as fast as interface call, but of you don't, no worries, it's still very fast (only the tiniest methods will be dominated by dispatch overhead), and the flexibility is still there |
| 16:26 | lisppaste8 | Chouser pasted "warts" at http://paste.lisp.org/display/91391 |
| 16:27 | leafw_ | chouser: triple quotes would be great, python-like. I find myself with problems on the docs of fn with lits of \" |
| 16:27 | leafw_ | s/lits/lots |
| 16:28 | leafw_ | and use/require is being worked on, IIRC |
| 16:28 | chouser | leafw_: I don't know if I'd advocate triple quotes, but having no way at all to avoid \" is a pain |
| 16:28 | Chousuke | that error messages are frequently completely useless is the biggest wart I can think of. |
| 16:29 | Chousuke | but hopefully that will change as things develop |
| 16:29 | chouser | Chousuke: but that's the implementation, not the language itself. |
| 16:29 | Chousuke | I guess so. |
| 16:29 | leafw_ | Chousuke: I find error messages ok, one I filter out all the non-clj lines. |
| 16:30 | leafw_ | except, perhaps, for macros. |
| 16:30 | leafw_ | s/one/once |
| 16:30 | chouser | Chousuke: I mean, that issue doesn't mess make my source files look worse than if it were fixed. |
| 16:30 | chouser | s/mess// |
| 16:33 | StartsWithK | (macroexpand (.toString Integer 1)) expands to (. (clojure.core/identity Integer) toString 1) in 1.1a, shoudn't that be just (. Integer toString 1)? |
| 16:33 | rhickey | chouser: the newline stuff is very funny |
| 16:35 | chouser | ,(macroexpand-1 '(Integer/toString 1)) |
| 16:35 | clojurebot | (. Integer toString 1) |
| 16:35 | chouser | StartsWithK: so, no. |
| 16:35 | StartsWithK | ,(macroexpan '(.toString Integer 1)) |
| 16:35 | clojurebot | java.lang.Exception: Unable to resolve symbol: macroexpan in this context |
| 16:35 | StartsWithK | ,(macroexpand '(.toString Integer 1)) |
| 16:35 | clojurebot | (. (clojure.core/identity Integer) toString 1) |
| 16:35 | chouser | rhickey: what's funny, clojure or what I said? |
| 16:36 | chouser | StartsWithK: If you want a static method of Integer, use Integer/toString. If you want an instance method, use (.method object args) |
| 16:37 | StartsWithK | chouser: i know that, i was just wondering why in that form there is a extra identity call |
| 16:37 | chouser | StartsWithK: saying (.toString Integer 1) is trying to call an instance method named "toString" on an instance of Class |
| 16:38 | chouser | once upon a time, we had FAQ #1, and we called identity ourselves. |
| 16:38 | StartsWithK | oh i see, that is not a valid call |
| 16:38 | rhickey | chouser: both |
| 16:39 | chouser | rhickey: is most of that inherited from CL or something? |
| 16:39 | rhickey | not really, but if you think about the alternatives... you'd need to reserve \ for excaping and use something else for chars? |
| 16:41 | chouser | I guess '\n' is out. ;-) |
| 16:41 | chouser | Java has no syntax for Character literals? |
| 16:41 | rhickey | right, single quote is taken. CL used #\ for chars, doesn't really change things |
| 16:42 | chouser | oh, Java uses '\n' like C. hmph. |
| 16:42 | chouser | using the same lookup table as strings would allow \n to be a newline for some better consistency, but I guess that would make space be just |
| 16:43 | chouser | space be just \ which is annoying |
| 16:43 | chouser | ...though that works today, just prints as \space |
| 16:43 | rhickey | what would be 'n' ? |
| 16:44 | chouser | I spent more time thinking up the problem than any solutions. |
| 16:44 | rhickey | you have to eat another special char, or #combo |
| 16:45 | chouser | #\newline = \n = (first "\n") ? |
| 16:48 | lpetit | \ca \cb ... for direct ASCII/UTF8 encoding, \uFFFF for unicode code, \xFF for US-ASCII codes ? |
| 16:49 | lpetit | And then \n is not reserved anymore, nor \t ... and all the usual conventions inherited from C |
| 16:49 | rhickey | chouser: what is 'n' ? |
| 16:50 | chouser | Maybe #\n |
| 16:50 | lpetit | but I don't like it very much, having to add c .. How many times do you use lots of literal characters, though ? |
| 16:50 | lpetit | The problem remains that you have \n inside strings, and .... something else for chars |
| 16:50 | chouser | right, "\n" is not to be messed with |
| 16:51 | chouser | so to make things any more consistent, \n would have to mean (first "\n") |
| 16:51 | chouser | which, as rhickey keeps pointing out, leaves the question of (first "n") |
| 16:52 | notallama | what about \\n = (first "\n") ? |
| 16:53 | lpetit | (first "n") could be \cn |
| 16:53 | chouser | since "\156" = "n", \156 should definitly be (first "n"), but that hardly seems sufficient. |
| 16:53 | lpetit | (first "a") could be \ca |
| 16:53 | lpetit | http://www.regular-expressions.info/characters.html |
| 16:53 | notallama | nevermind. \\n woiuld make it rather hard to do a literal \ |
| 16:53 | chouser | notallama: \\\ :-) |
| 16:54 | notallama | chouser: i'm getting bad memories of java regex |
| 16:55 | notallama | java regex literal \ is "\\\\" |
| 16:55 | chouser | I think I like #\n over \cn |
| 16:56 | chouser | notallama: yep. We fixed that in Clojure a while ago. :-) |
| 16:56 | technomancy | notallama: you should see Emacs regexes |
| 16:56 | technomancy | terrifying |
| 16:56 | notallama | yes, i'm aware, and i greatly appreciate it |
| 16:58 | lpetit | chouser: but then, if #\n stands for (first "n"), what would be (first "\n") N |
| 16:58 | lpetit | ? |
| 16:58 | chouser | \n |
| 16:58 | rhickey | ouch |
| 16:58 | notallama | i'm not really a fan of breaking \x = (first "x"). it'd be nice to keep that, at least for everything except one escape character. |
| 16:59 | lpetit | less consistent than \cn \n |
| 16:59 | rhickey | lpetit: putting c before things trashes scanability IMO |
| 16:59 | lpetit | (but still, I don't like \cn very much, just sticking to something that may be a standard in regular expressions, as I found in the above mentioned link) |
| 16:59 | lpetit | rhickey: scanability ? |
| 17:00 | chouser | it's a problem for all string escapes, which include \n, \t, \r, etc. |
| 17:00 | rhickey | anytime you put dummy (but alpha) characters before important characters you make you brain do extra work to remove them |
| 17:01 | rhickey | i.e. how easy is it to tell if they are in alphabetical order? |
| 17:01 | lpetit | We're talking about character literals. How often are they "heavily" used in practice ? |
| 17:02 | rhickey | lpetit: not often, I don't consider the problems chouser has raised as problems at all, for me personally |
| 17:03 | lpetit | rhickey: maybe not, but interestingly I had the exact same bug recently. Wrote \n where I should have written \newline :) |
| 17:03 | chouser | ah, yes. \a \b \r \f \n \t and \v, plus the fancier ones for hex or octal |
| 17:04 | liebke | it doesn't seem like a problem... once you consider the alternative solutions :) |
| 17:04 | lpetit | liebke: so sometimes it helps consider alternatives : |
| 17:04 | lpetit | :) |
| 17:04 | liebke | indeed :) |
| 17:05 | chouser | ,\o156 |
| 17:05 | clojurebot | \n |
| 17:05 | chouser | ,\o12 |
| 17:05 | clojurebot | \newline |
| 17:05 | chouser | "\o12" |
| 17:05 | chouser | ,"\o12" |
| 17:05 | clojurebot | Unsupported escape character: \o |
| 17:06 | chouser | this doesn't just seem broken to you? |
| 17:06 | lpetit | ,"\o12" |
| 17:06 | clojurebot | Unsupported escape character: \o |
| 17:06 | chouser | ,(str \o12) |
| 17:06 | clojurebot | "\n" |
| 17:07 | lpetit | ,"\u12" |
| 17:07 | clojurebot | Invalid character length: 2, should be: 4 |
| 17:07 | lpetit | ,"\u0012" |
| 17:07 | clojurebot | "" |
| 17:07 | lpetit | ,"\u0032" |
| 17:07 | clojurebot | "2" |
| 17:07 | chouser | ,\u0012 |
| 17:07 | clojurebot | \ |
| 17:07 | notallama | does java do octals in strings? |
| 17:07 | chouser | ,\u0032 |
| 17:07 | clojurebot | \2 |
| 17:07 | chouser | notallama: yes |
| 17:08 | lpetit | ok I don't have the ascii table wired in my head :) |
| 17:08 | chouser | notallama: no |
| 17:09 | chouser | notallama: yes. sorry. :-) |
| 17:09 | chouser | notallama: \ followed by digits is octal, even without a leading 0 |
| 17:11 | chouser | so again in Clojure we have \12 and "\o12" are invalid, but \o12 and "\12" are valid and mean almost the same |
| 17:12 | chouser | Clojure string literals are very similar to Java string literals. Maybe identical. Clojure character literals feel like they're from an entirely unrelated language. |
| 17:15 | lpetit | ,"\c" |
| 17:15 | clojurebot | Unsupported escape character: \c |
| 17:15 | notallama | \\n makes the most sense to me. java version would be '\n'. so basically, \x would be the same as 'x' |
| 17:17 | lpetit | Or just make the escaping rules be written the same inside strings and for chars, and for ease of use of writing literal chars, add an additional character. Rich said that using an alpha character is not interesting since it creates mental noise (downgrades scanability), so maybe a different char |
| 17:17 | lpetit | \_a , \_b , ...? |
| 17:17 | hiredman | I would be ignored if clojure's handling of character literals changed in a backwards incompatible manner |
| 17:17 | hiredman | for the record |
| 17:17 | hiredman | er |
| 17:17 | lpetit | maybe too close to _ |
| 17:17 | hiredman | s/ignored/annoyed/ |
| 17:18 | chouser | hiredman: you prefer how it is now? |
| 17:18 | lpetit | \'a, \'b ? |
| 17:18 | lpetit | \'a' \'b' ? |
| 17:19 | Chousuke | noisy |
| 17:19 | chouser | lpetit: and for newline, \'\n or \'\n' ? |
| 17:19 | lpetit | for newline \n |
| 17:19 | hiredman | chouser: I like to be able to revisit old code without have to spend a lot of time to make it work |
| 17:19 | hiredman | and I don't mind it as it is now |
| 17:20 | lpetit | \'<one char of your charset>' , and any other escape mechanism similar to what is done in strings for the rest : \n , \t , \b , \u9882 ... |
| 17:21 | chouser | lpetit: I like that. Even better without the trailing ' |
| 17:21 | lpetit | or just 'a' for chars, like in java ? |
| 17:21 | lpetit | isn't it possible, even if ' is for quoting ? |
| 17:21 | chouser | we already see ' as a prefix thing in Clojure code, so \'n isn't too bad for the unusual bare letter case |
| 17:21 | hiredman | chouser: none of the proposals seen here are nice enough to entice me to want to break working code |
| 17:22 | lpetit | \newline could be kept as a deprecated (or more readable) non-shortcut for \n |
| 17:22 | chouser | ,(str 'n' "hello") |
| 17:22 | clojurebot | "nhello" |
| 17:23 | hiredman | chouser: cute |
| 17:23 | lpetit | but yes, \n , \t, \b would break |
| 17:23 | hiredman | I don't see how \'n is in anyway an improvement |
| 17:24 | chouser | it's just to free up \n to mean the same as (first "\n") |
| 17:24 | lpetit | and also \b, \t, and make them behave the same as in "\n" "\b", etc. |
| 17:24 | chouser | right |
| 17:25 | rhickey | what's ''' ? |
| 17:25 | rhickey | '\'' |
| 17:25 | lpetit | ? |
| 17:25 | chouser | \'' |
| 17:25 | rhickey | \'\'' |
| 17:26 | lpetit | \'' |
| 17:26 | lpetit | \'" |
| 17:26 | LauJensen | Man this is great, just like the J forum :) |
| 17:26 | lpetit | and \'\ for (first "\\") |
| 17:26 | lpetit | \'a' could be accepted as a convenience, also : |
| 17:26 | lpetit | :) |
| 17:27 | lpetit | :-( |
| 17:27 | lpetit | sorry |
| 17:28 | lpetit | ,\" |
| 17:28 | clojurebot | \" |
| 17:28 | chouser | \" and \'" would both be accepted and mean the same |
| 17:29 | lpetit | yes |
| 17:29 | chouser | if we used something new instead of \ then old code could remain compatible |
| 17:29 | lpetit | but isn't this a particularity of a particular host platform (the JDK) |
| 17:30 | lpetit | or a particularity of the dominant language of the host platform ? |
| 17:30 | chouser | #\n for newline, #\'n for n |
| 17:30 | hiredman | :| |
| 17:30 | chouser | or #'n for n |
| 17:31 | hiredman | uh |
| 17:31 | hiredman | ,#'n |
| 17:31 | clojurebot | java.lang.Exception: Unable to resolve var: n in this context |
| 17:31 | chouser | oh |
| 17:31 | hiredman | … |
| 17:31 | chouser | maybe not. :-) |
| 17:31 | lpetit | chouser: rather staying with the current implementation, or breaking existing code, than adding patches and not removing old behaviour |
| 17:32 | chouser | old behaviour could be deprecated but left in place until hiredman comes around in his thinking. |
| 17:32 | hiredman | lpetit: so reader macros by patch? |
| 17:32 | lpetit | I have so bad experiences with the Eclipse API, adding new ways of doing the same thing over old ones, forcing you to "replay" all the history to understand things |
| 17:33 | lpetit | hiredman: didn't understand |
| 17:33 | hiredman | you could, just, you know, leave the character handling as is |
| 17:33 | hiredman | lpetit: one argument against reader macros is it essential shatters the language into sublanguages with different syntaxs |
| 17:33 | chouser | sure. could also leave any number of other broken things broken. |
| 17:33 | lpetit | Yes, I guess better leave it as is, than adding another way to do it, and leaving the old way. |
| 17:34 | hiredman | chouser: is it really broken? |
| 17:34 | lpetit | Or, have the courage to break broken things, but this example may not be worth it. |
| 17:34 | chouser | ,\o12 |
| 17:34 | clojurebot | \newline |
| 17:34 | chouser | ,"\o12" |
| 17:34 | clojurebot | Unsupported escape character: \o |
| 17:34 | chouser | broken. |
| 17:34 | lpetit | ,"\12" |
| 17:34 | clojurebot | "\n" |
| 17:35 | chouser | ,(= \n (first "\n")) |
| 17:35 | clojurebot | false |
| 17:36 | lpetit | hiredman: I'm not sure it's the current main arguments. The same can be said about regular macros. I remember the main argument for Rich was along the lines that it's difficult to keep them "in scope" (but I'm no expert) |
| 17:36 | notallama | maybe \\ as the escape sequence. that way, \x works as is (even when x = \), and you get to type more characters to type your characters! |
| 17:36 | twbray | What's the syntax for an arbitrary Unicode character, e.g. U+4F5B ? |
| 17:36 | notallama | so \\\n = (first "\n") |
| 17:37 | lpetit | in strings "\u4F5B" |
| 17:37 | lpetit | ,"\u4F5B" |
| 17:37 | clojurebot | "佛" |
| 17:37 | chouser | also in literals. yay! |
| 17:37 | chouser | ,\u4F5B |
| 17:37 | twbray | lpetit: Thanks |
| 17:37 | clojurebot | \佛 |
| 17:37 | chouser | not broken! |
| 17:37 | lpetit | not broken :) |
| 17:37 | lpetit | too late for me :) |
| 17:37 | chouser | :-) |
| 17:37 | twbray | chouser: so if you have unicode, screw the rest, make 'em all use that :) |
| 17:37 | chouser | there ya go |
| 17:37 | lpetit | ok, so from now on, everybody is writing literals in unicode esac |
| 17:38 | lpetit | shit you beat me again :) :) |
| 17:38 | chouser | ,"this\u000Ais\u000Anice!" |
| 17:38 | clojurebot | "this\nis\nnice!" |
| 17:39 | hiredman | chouser: \o is not a valid escape, so the reader throws an exception, how is that broken? |
| 17:39 | lpetit | ,(printf "this\u000Ais\u000Anice!") |
| 17:39 | clojurebot | this is nice! |
| 17:39 | chouser | hiredman: \o is valid esacpe outside "" but not inside |
| 17:39 | hiredman | no |
| 17:39 | chouser | hiredman: \u is valid in both |
| 17:39 | hiredman | outisde of "" it is not an escape |
| 17:39 | chouser | ,\o12 |
| 17:39 | clojurebot | \newline |
| 17:40 | chouser | \12 is valid inside "" but not outside |
| 17:40 | twbray | ,"foo\uabar" |
| 17:40 | clojurebot | Invalid digit: r |
| 17:40 | chouser | \n is valid in both, but means different things. |
| 17:40 | lpetit | is \u valid in non-java strings (e.g. C#, ...) ? |
| 17:40 | twbray | "foo\u000abar" |
| 17:41 | twbray | ,"foo\u000abar" |
| 17:41 | clojurebot | "foo\nbar" |
| 17:41 | chouser | lpetit: Clojure mimics Java string literals, but doesn't borrow the implementation, I believe. So Clojure strings literals will mean the same across host platforms. |
| 17:41 | twbray | ,"foo\00000abar" |
| 17:41 | clojurebot | "foo |
| 17:42 | lpetit | chouser: are you sure ? |
| 17:43 | twbray | OK, I think there's a bug there. Unicode characters go up to U+10FFFF |
| 17:43 | twbray | oops typo |
| 17:43 | twbray | ,"foo\u00000abar" |
| 17:43 | clojurebot | "foo |
| 17:43 | chouser | lpetit: pretty sure. LispReader.java has Clojure's rules for reading string and char literals. |
| 17:43 | twbray | ,"foo\u10346bar" |
| 17:43 | clojurebot | "fooဴ6bar" |
| 17:44 | lpetit | chouser: good, so the change would be meaningful for every clojure port |
| 17:44 | twbray | Oh crap those \u thingies are recognizing UTF-16 codepoints not unicode characters. Per Java's big mistake |
| 17:44 | chouser | over my head. |
| 17:45 | twbray | OK... U+10346 is GOTHIC LETTER FAIHU |
| 17:45 | twbray | you probably don't have a font for it. |
| 17:46 | chouser | does that take two UTF-16 words to describe or something? |
| 17:46 | twbray | So you'd have to encode this is "foo\ud800\udf46bar" |
| 17:46 | chouser | ah, ok. |
| 17:46 | twbray | ,"foo\ud800\udf46bar" |
| 17:46 | clojurebot | "foo𐍆bar" |
| 17:46 | rlb | chouser: http://java.sun.com/developer/technicalArticles/Intl/Supplementary/ (I think) |
| 17:46 | rlb | Java can't fit all unicode characters into a char. |
| 17:47 | twbray | They're called "surrogates". You don't want to know if you don't have to. |
| 17:47 | rlb | (just codepoints) |
| 17:47 | rlb | Some unicode characters in utf-16 won't fit in 16-bits. |
| 17:47 | twbray | You could make a case that Clojure should Do The Right Thing and recognize \u10346 |
| 17:47 | rlb | (but java pretended they would -- or just didn't care) |
| 17:48 | rlb | (or the standard changed -- don't know offhand) |
| 17:48 | twbray | rib: When Java was being cooked up, people still believed in UCS2, i.e. that you would be able to fit everything in 16 bits. |
| 17:48 | hiredman | you would then need a seperate \u for char literals |
| 17:48 | Chousuke | twbray: the reader works with java's Characters :/ |
| 17:48 | twbray | hiredman: Maybe \U |
| 17:48 | rhickey | \ae, \bee, \cee, \dee , \ee , \ef , \gee, \newline, \tab ... \zee |
| 17:48 | hiredman | the reader works with ints |
| 17:48 | rlb | twbray: oh, ok, I thought it might also have been historical. |
| 17:49 | hiredman | because .read returns an int |
| 17:49 | rhickey | phonetic character literals! |
| 17:49 | Chousuke | hiredman: well they're cast to chars :P |
| 17:49 | Chousuke | basically. |
| 17:50 | hiredman | sure |
| 17:50 | twbray | There are lots of good things about being on the Java platform, but Unicode isn't one of them. Life would be so much easier if it were UTF-8 end to end. |
| 17:50 | Chousuke | well, UTF-8 is just an encoding for unicode. |
| 17:51 | twbray | Chousuke: Agreed. But one that has many advantages over what Java happened to pick. |
| 17:51 | hiredman | but if you, for example, write a reader in clojure which turns int into Integer and char into Character, and then there is not auto back and forth between the two … |
| 17:51 | chouser | rhickey: perfect! |
| 17:51 | rhickey | obviously I have nothing constructive to add :) |
| 17:51 | lpetit | \one \two ...:) |
| 17:52 | Chousuke | twbray: yeah. I suppose processing UTF-8 is a bit more complicated than UTF-16, but since most character data is ASCII or UTF-8, that advantage suddenly becomes a disadvantage :P |
| 17:52 | rlb | Chousuke: processing utf-16 is basically as hard if you do it right (i.e. neither is a fixed encoding.) |
| 17:53 | rlb | s/fixed/fixed-width/ |
| 17:53 | twbray | I wrote a nice UTF-8 based java.lang.String replacement which uses UTF-8 internally. But it's too late. |
| 17:53 | lpetit | But was it UTF16 or raw UCS16, really ? :-) |
| 17:53 | twbray | rib: +1 |
| 17:53 | hiredman | bitbckt: :( |
| 17:53 | twbray | http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF if anyone cares |
| 17:54 | rlb | It's just that the characters with more than one utf-16 code point are not as common. |
| 17:54 | bitbckt | hiredman: You'll get used to it. :-) |
| 17:54 | hiredman | hangul has too many variations of the o and yo sound that all sound the same to me |
| 17:54 | hiredman | bitbckt: I refuse |
| 17:54 | rlb | (at least in many arenas) |
| 17:54 | bitbckt | hiredman: Noted. Off with your head, then. |
| 17:55 | Chousuke | is hangul capable of expressing all the sounds in the English language? |
| 17:55 | Chousuke | the latin alphabet certainly isn't. :P |
| 17:55 | hiredman | badly |
| 17:55 | hiredman | hangul has no f |
| 17:55 | hiredman | koreans shout "powl" at basketball games |
| 17:56 | bitbckt | And we all *laugh* |
| 17:56 | hiredman | pheonix becomes peenix |
| 17:57 | hiredman | it is very noticable because of the amount of english that gets phonetically written in hangul |
| 17:57 | Chousuke | I wonder if that makes it worse than katakana |
| 17:58 | bitbckt | The generations of people taught English from books, without actually ever *hearing* a native English speaker are also a source of great amusement. |
| 17:58 | hiredman | yes |
| 17:58 | Chousuke | I had to listen to a person keep a presentation in English class today. She had horrible pronunciation. |
| 17:59 | Chousuke | Pronunciation is clearly not given enough attention in schools. |
| 18:00 | bitbckt | See? The Roman alphabet isn't phonetic. Fail. ;-) |
| 18:00 | Chousuke | You basically learn it if you already have some sort of natural aptitude for it, but if you don't... Well, sucks to be you. Or actually, sucks to be anyone who hears you speak English :P |
| 18:00 | Chousuke | Well, the problem is that the Finnish alphabet is almost phonetic. |
| 18:00 | hiredman | accents are nice |
| 18:00 | Chousuke | So many Finns just learn to pronounce English like it was finnish |
| 18:00 | Chousuke | which is *completely* and *utterly* hideous |
| 18:01 | hiredman | I don't know exactly what the problem is in korea, but kids go through years of english classes at school plus after school english study, and still can only string together a few words |
| 18:02 | Chousuke | I remember seeing pictures of a teacher's book in Japanese that just had all the english parts transliterated as katakana |
| 18:02 | Chousuke | so the teacher had no need to actually know how to read English |
| 18:02 | hiredman | my dad is an english teacher there, so he, at times, will go on and on on the subject, and the deficiencies of *other* english teachers |
| 18:02 | twbray | hiredman: we have the same problem in English-speaking countries. Kids study French or whatever for years and can't speak at all. |
| 18:02 | hiredman | twbray: I suppose |
| 18:02 | hiredman | but it seems much less common |
| 18:03 | Chousuke | I at least had an English teacher in high school with a proper British accent :) |
| 18:03 | hiredman | all the kids I know who studied japanese speak it |
| 18:03 | bitbckt | Chousuke: I suppose that's an "improvement." |
| 18:03 | lpetit | So that means everybody agrees on the switch to \'a :-) |
| 18:04 | Chousuke | at least you could hear the proper intonation in her speech |
| 18:04 | hiredman | nope |
| 18:04 | Chousuke | the pronunciation guides in books don't really teach that :/ |
| 18:04 | Chousuke | and since Finnish has next to no intonation, that leads to most people speaking quite monotonously, even if their pronunciation is otherwise good. |
| 18:05 | hiredman | my dad was once accosted by another english teacher, and accused, in a thick cockney accent, of teaching koreas a horrible american accent |
| 18:06 | Chousuke | lpetit: I think that looks hideous, but... :P |
| 18:06 | bitbckt | hiredman: I'm sure that was an amusing conversation. |
| 18:06 | lpetit | was a joke |
| 18:07 | stand1 | General question: Does anyone know of an effort underway to get decent date/time functions into clojure. My searches don't turn up anything. |
| 18:07 | bitbckt | stand1: Use joda? |
| 18:07 | lpetit | ~jodatimes |
| 18:07 | clojurebot | I don't understand. |
| 18:08 | lpetit | ~google jodatimes |
| 18:08 | clojurebot | First, out of 6580 results is: |
| 18:08 | clojurebot | Joda Time - Java date and time API - Home |
| 18:08 | clojurebot | http://joda-time.sourceforge.net/ |
| 18:08 | stand1 | Is that java or clojure? |
| 18:08 | the-kenny | stand1: Java |
| 18:08 | the-kenny | But you can always write a simple wrapper :) |
| 18:08 | hiredman | (what's the difference) |
| 18:08 | lpetit | ~google jodatimes clojure wrapper |
| 18:08 | clojurebot | First, out of 82 results is: |
| 18:08 | clojurebot | gcv's cupboard at master - GitHub |
| 18:08 | clojurebot | http://github.com/gcv/cupboard |
| 18:09 | stand1 | I'm actually interested in doing a wrapper. |
| 18:09 | lpetit | ok sorry |
| 18:10 | lpetit | rhickey: from the protocols wiki page = what does it mean to "implement a protocol on an interface" ? How does it look in practice ? |
| 18:11 | stand1 | how common is it to wrap a third party jar like joda. I was thinking of implementing on top of the jdk to avoid dependencies. |
| 18:11 | hiredman | why wrap? |
| 18:12 | stand1 | mainly to avoid lots of heavy lifting. |
| 18:12 | hiredman | is there a lot of heavy lifting you need to do? |
| 18:12 | stand1 | date arithmatic, formatting, etc. |
| 18:12 | stand1 | time zones |
| 18:12 | hiredman | I am unfamiliar with joda time, but it should do all that |
| 18:13 | bitbckt | It slices! It dices! |
| 18:13 | bitbckt | Call now and we'll *double* your order! |
| 18:13 | stand1 | it make julian calendars! |
| 18:14 | bitbckt | and caesar salad! |
| 18:14 | bitbckt | It's quite complete. I'm not sure there's much anyone needs from a time library that isn't in Joda. |
| 18:14 | bitbckt | Other than salad. |
| 18:16 | hiredman | drives me crazy when "quick start" java guides don't mention what package any of the classes are in |
| 18:16 | stand1 | botbckt: Don't disagree, but I'm thinking of more clojure and less java. i.e. wrappingn |
| 18:16 | hiredman | sorry! |
| 18:16 | bitbckt | botbckt is my bot. :-) |
| 18:17 | bitbckt | stand1: So, using Joda directly via Clojure's Java integration is not what you want..? |
| 18:18 | stand1 | well, for example a now function that returns a date structure {:month :day :year etc} |
| 18:18 | stand1 | A (format-date format-string date) function. things like that |
| 18:18 | hiredman | ,(bean (Date.)) |
| 18:18 | clojurebot | {:seconds 18, :date 1, :class java.util.Date, :minutes 20, :hours 15, :year 109, :timezoneOffset 480, :month 11, :day 2, :time 1259709618423} |
| 18:19 | bitbckt | I think the consensus opinion has been the Joda doesn't really need anything like that. |
| 18:19 | stand1 | hiredman: that's close |
| 18:19 | bitbckt | that* |
| 18:20 | alexyk | is clojure all lazy, as in lazy evaluation like in Haskell, or are just seq's lazy? |
| 18:20 | hiredman | just lazy-seqs |
| 18:21 | alexyk | ah. |
| 18:21 | hiredman | java interop would be *extremely difficult and painful* if it was lazy evaluation |
| 18:29 | stand1 | Wow! Matt Moriarty has done something quite close to what I was thinking http://gist.github.com/49656 I found on a thread on the mail list. |
| 18:41 | hiredman | alexyk: for and doseq are the most "foreach" like constructs |
| 18:41 | hiredman | for is actually a lazy list comprehension |
| 18:41 | hiredman | (not a loop) |
| 18:41 | alexyk | ok! |
| 18:41 | hiredman | doseq is very foreachie |
| 18:42 | hiredman | ,(doseq [i (range 3)] (print i)) |
| 18:42 | clojurebot | 012 |
| 18:53 | djork | oh neat, I didn't know I could do a \uXXXX literal |
| 18:54 | djork | and I was doing "\u000d" when apparently \return exists |
| 18:56 | djork | is there some list of these somewhere? |
| 18:56 | Chousuke | hmm |
| 18:57 | djork | ,(map char (range 1 33)) |
| 18:57 | clojurebot | (\ \ \ \ \ \ \backspace \tab \newline \ \formfeed \return \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \space) |
| 18:57 | djork | looks like all the basics |
| 18:57 | djork | good enough for most console work |
| 18:57 | hiredman | http://github.com/hiredman/clojure/blob/readerII/src/clj/clojure/reader.clj#L516 |
| 18:58 | djork | woo! hiredman with the scoop! |
| 18:58 | djork | but that's CIC, not in use yet, right? |
| 18:58 | hiredman | dunno if my reader ever will be |
| 18:59 | djork | impressive nonetheless |
| 19:00 | hiredman | anyway, it was a more or less one to one transliteration of the java, so those literals there should be reliable at least for another few days (till Chouser changes everything) |
| 19:03 | Chousuke | I have a reader too. haven't worked on it for a while though |
| 19:03 | Chousuke | no time :( |
| 19:03 | hiredman | me neither (lazy :) |
| 19:16 | rhickey | lpetit: (extend-class AnInterface AProtocol (foo [x ]...)) |
| 19:16 | lpetit | rhickey: yes, I've understood it in the mean time |
| 19:19 | lpetit | rhickey: here are my current thoughts concerning "this", problems with recur consistency, etc. : http://paste.lisp.org/display/91400 |
| 19:20 | lpetit | rhickey: I also have a couple of questions that may be interesting to be answered in the wiki ? |
| 19:20 | lpetit | rhickey : a) In deftype, does the redefinition of hasCode/equal work as an atomic thing (redefine neither or both), or not ? |
| 19:21 | lpetit | rhickey : b) In deftype, why doesn't IPersistentMap interface have default implementation such as IObj and ILookup ? |
| 19:22 | lpetit | rhickey: c) What is the reason for using keywordized versions of type name and protocol methods name over symbols in extend ? |
| 19:22 | twbray | Eleven theses on Clojure: http://www.tbray.org/ongoing/When/200x/2009/12/01/Clojure-Theses |
| 19:23 | djork | "1. It’s the Best Lisp Ever · I don’t see how his can be a controversial statement." |
| 19:23 | djork | well duh |
| 19:23 | djork | (typo, BTW) |
| 19:23 | rhickey | lpetit: if you define hashCode or equals, both u pto you, no enforcement you define both |
| 19:24 | twbray | djork: Thanks, fixed |
| 19:25 | rhickey | lpetit: b) IPersistentMap include ILookup, IObj always |
| 19:25 | lpetit | rhickey: d) (and the last one) Would adding extend-interface (even if under the hood it shares everything with extend-class) be interesting to manifest that we're just implementing an interface over a protocol ? |
| 19:25 | rhickey | lpetit: c) symbols are a pain in not self-quoting |
| 19:25 | lpetit | rhickey: hashCode/equals = ok, maybe wiki could state this more explicitly ? |
| 19:25 | rhickey | d) interfaces are classes |
| 19:26 | lpetit | rhickey: d) Yes, but conceptually different |
| 19:26 | djork | twbray: Do you think that infix math is maybe the only thing really tripping people up when it comes to Lisp syntax? |
| 19:27 | djork | if you change the operators to English words it gets a little easier to read, I think |
| 19:27 | djork | Logo was a Lisp and we did that in 3rd grade |
| 19:27 | twbray | Start in 3rd grade and the problem goes away :) |
| 19:27 | djork | heh |
| 19:27 | djork | I guess so |
| 19:28 | rhickey | twbray: thanks for spending some time with Clojure and covering is so well! |
| 19:28 | rhickey | covering it |
| 19:28 | lpetit | rhickey: b) was not clearly expressed. I wanted to ask : " why is there no default implementation for IPersistentMap in deftype. Why having to explicitly add the interface to trigger the default implementation" ? |
| 19:29 | twbray | rhickey: If it weren't for the sucky bytes->string mapping, Clojure would have slam-dunked the wide finder field in terms of the ratio between the lines of code and resulting performance. |
| 19:29 | twbray | (Java's mapping, not clojure's) |
| 19:29 | rhickey | lpetit: I'm still on the fence about these default implementations. deftype is a very general purpose thing, not just for structmap replacement. You should be able to use it to implement PersistentHashMap itself |
| 19:29 | djork | nice writeup though, twbray |
| 19:30 | djork | twbray: are you sure you used the best methods to read bytes into Java strings? |
| 19:30 | djork | there are various ways |
| 19:30 | twbray | djork: Nope. But it's a problem that I'm fairly familiar with. |
| 19:30 | djork | k |
| 19:31 | rhickey | lpetit: so, I really don't want people to treat non-collections as collections, but some of the current interfaces are trapped in hierarchies, that, when protocols, will be more a la carte |
| 19:31 | twbray | Going from UTF-8 to UTF-16 is always going to suck |
| 19:31 | lpetit | rhickey: but why a special case for PersistentHashMap over ILookup and IObj ? Why not the same "treatment" as for hashCode and equals : if not present, default implementation, if one of the methods present, user implementation ? No special cae |
| 19:31 | lpetit | case |
| 19:32 | bitbckt | twbray: As always, I enjoy your coverage of these things... and photography. |
| 19:32 | bitbckt | Thanks. |
| 19:32 | rlb | I need to partition a seq of vectors based on a predicate that depends on the previous element. I can write a function that produces a suitable lazy seq, but I wondered if that's the most reasonable way. |
| 19:32 | lpetit | rhickey: oh, ok for IPersistentHashMap, then |
| 19:33 | rhickey | lpetit: because IPersistentMap carries a lot of semantics people won't necessarily understand nor want. Keyword field lookup and metadata are relatively atomic and primitive |
| 19:33 | lpetit | rhickey: What about my lisppaste ? There's really nothing new, but gives my opinionated opinion on the subject, after having grokked the concepts again from the wiki pages :) |
| 19:34 | rhickey | lpetit: I don't like dots anywhere near protocol fns - they just scream 'host interop' |
| 19:34 | djork | so, twbray, you are at Sun? do you know what Sun-in-general thinks about Clojure? |
| 19:35 | twbray | djork: Sun currently in process of being acquired, no opinions are to be expressed. |
| 19:37 | lpetit | rhickey: oh, for me, they were there to say "not a function". But I understand the case for 'host interop' screaming. It would indeed be indented in italic for such a purpose in ccw, for example. And that would be bad. |
| 19:37 | cubix | is there a nicer way to do this or a function that already exists somewhere? http://paste.lisp.org/+1YIY |
| 19:37 | rhickey | lpetit: the more I stare at explicit this: http://paste.lisp.org/display/91364#1 the less it bothers me |
| 19:38 | lpetit | rhickey: so there's just the recur consistency problem left ? |
| 19:38 | rhickey | lpetit: with that, yes, the least likely to be encountered |
| 19:41 | lpetit | rhickey: why do you say so ? |
| 19:42 | rhickey | lpetit: less likely to be encountered than inconsistencies between deftype/reify/extend etc, not unlikely or never |
| 19:43 | lpetit | ,(doc reify) |
| 19:43 | clojurebot | excusez-moi |
| 19:43 | rhickey | every possible solution has some inconsistencies |
| 19:44 | lpetit | rhickey: what does it mean to place type hints on the explicit "this" in method arg list :-p |
| 19:45 | rhickey | lpetit: nothing |
| 19:46 | lpetit | rhickey: it's amusing, we walked the same road in the opposite direction, you arriving where I started from (and vice versa), and we're happy with our final destination :) |
| 19:46 | rhickey | lpetit: because we are walking in circles? :) |
| 19:47 | lpetit | rhickey: I mean, now that I have really read the last versions of protocols and types wiki pages, I'm not annoyed by your solution of having no "this" at all by default, and declaring an explicit this outside of any methode arglist if necessary. And it would make the recur case consistent. And it would somehow remind that those are not real fns |
| 19:48 | lpetit | (deftype AType [AProtocol AnInterface] :as explicit-this (aProtocol-method [] ...)) |
| 19:49 | lpetit | rhickey: spirals, not circles :) |
| 19:57 | rhickey | lpetit: recur would be inconsistent for extend-type then |
| 19:58 | rhickey | lpetit: oh, you wanted explicit this in extend-type |
| 19:58 | lpetit | rhickey: yes |
| 19:58 | rhickey | then extend-type and deftype are inconsistent (in an understandable way perhaps) |
| 20:00 | lpetit | rhickey: yes, after having reasonably grokked the differences between extend-type and deftype, it makes sense for them to be inconsistent concerning "this" handling (at least it does for me) |
| 20:00 | rhickey | as a practical matter, extend type will need to use 'this much more often |
| 20:01 | rhickey | but the question will be asked - why make us state 'this in every method when you have this nicer solution for deftype/reify |
| 20:02 | lpetit | rhickey: by "reasonably", I mean if one understands why its preferable for performance to inline the implems in deftype (if one owns deftype definition), one understands that deftype does not define real functions. And is happy with implicit this in deftype, and explicit this in extend-* |
| 20:03 | rhickey | lpetit: but now I am having a conversation with someone on this side of the understanding hill |
| 20:03 | lpetit | rhickey: and the answer could be "because a cat is a cat, and you don't have the same performance characteristics" ? |
| 20:04 | rhickey | but a macro is a macro (extend-type) and could have taken away this tedium |
| 20:05 | lpetit | rhickey: sure, so the inconsistency of recur could also be got rid of by the macro, maybe ? |
| 20:05 | lpetit | (ok, certainly *not easy if at all possible*) |
| 20:07 | lpetit | I must leave, see you later ! |
| 20:07 | rhickey | lpetit: bye - thanks for the input! |
| 20:07 | lpetit | my pleasure |
| 20:22 | arohner | rhickey: do you have a reaction to http://groups.google.com/group/clojure-dev/browse_thread/thread/ad5597c4eb89ce40/6125b18ef9542df5?show_docid=6125b18ef9542df5 ? Is the lack of deftype introspection a real problem, or am I doing it wrong? 2) what do you think a good solution to this problem is? |
| 20:23 | defn | How do you use (accessor)? |
| 20:24 | rhickey | I think something like this will be built in - no need to add on later |
| 20:26 | arohner | rhickey: ok, thanks. Are there any workarounds until that happens? |
| 20:29 | rhickey | arohner: if you take IPersistentMap default implementation, you will have (keys x), and IDynamicType has getExtensionMap, keys without the keys of the extension map == the fields |
| 20:31 | arohner | sigh. at one point when I was trying to make deftype implement a protocol to work, I took out my IPersistentMap declaration, then forgot to put it back in. if (keys x) had worked for me, I never would have set off down this path. |
| 20:31 | arohner | thanks |
| 20:32 | arohner | well, the good news is I understand the deftype implementation a lot better! |
| 20:35 | arohner | is it possible to require that members of a protocol also implement an interface, say IPersistentMap? |
| 20:36 | rhickey | arohner: no |
| 20:36 | rhickey | the point of protocols is that such requirements can't be superimposed on all types |
| 20:36 | rhickey | e.g. String |
| 20:37 | arohner | oh right. though after cinc, keys will be part of the Associative protocol, right? |
| 20:37 | rhickey | moving forward, it will be possible to write protocols that require other protocols, but only by convention, not enforcemed |
| 20:38 | rhickey | yes, eventually all Clojure's key interfaces will be protocols |
| 20:49 | johannh | Hi all. Quick question: what's the right way to implement pmapcat? I want something like (pmapcat (fn [chunk] (map some-fun chunk)) (partition-all 1000 (line-seq rdr))), but I worry that (apply concat (pmap ...)) would force the entire sequence. |
| 20:50 | chouser | apply doesn't force seqs |
| 20:51 | johannh | So, apply is smart enough to bundle up the &rest argument into a lazy sequence? |
| 20:52 | johannh | I only ask because memory usage makes it look like the whole file is getting slurped in somewhere. |
| 20:59 | arohner | lisppaste8: url |
| 20:59 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 21:02 | lisppaste8 | arohner pasted "deftype extends explosions" at http://paste.lisp.org/display/91404 |
| 21:03 | arohner | I can't get extend-class to work with existing classes or deftype |
| 21:05 | arohner | ah, extend-class expanded into (extend :winston.db-row/java.lang.Object |
| 21:08 | arohner | I've fixed the extend-class by removing the :: off java.lang.Object. now my protocol method works with normal classes, but not deftypes |
| 21:08 | arohner | is there a way to supply a default implementation for all deftypes? |
| 21:11 | notallama | do you need a different implementation for deftypes than Objects? |
| 21:13 | arohner | notallama: my one extend-class on java.lang.Object is happy with "normal" classes, and not happy with deftypes |
| 21:13 | arohner | so I assume so |
| 21:15 | arohner | I also assume that because extend-class and extend-type both exist, there must be some difference |
| 21:20 | notallama | the method for Object should work for everything that doesn't have its own implementation defined. that's not true for you? can you paste what you're doing? |
| 21:20 | arohner | http://paste.lisp.org/display/91404 |
| 21:21 | arohner | except I removed the :: on extend-class |
| 21:21 | lisppaste8 | arohner annotated #91404 "untitled" at http://paste.lisp.org/display/91404#1 |
| 21:24 | notallama | you're implementing half an interface on object, and the other half in deftype. i'm pretty sure that doesn't work. |
| 21:24 | notallama | er, half a protocol |
| 21:25 | notallama | since you have the protocol in the deftype extend-list, it's trying to use that implementation, but you didn't define a method for insert |
| 21:26 | notallama | you could get the effect you want by splitting it into several protocols. (one for each method, or something) |
| 21:27 | arohner | notallama: ok thanks, I'll try that out |
| 21:29 | arohner | if that's the case, it really should be documented. it was not at all obvious that isn't allowed |
| 21:30 | notallama | arohner: i don't know if you're familiar with java interfaces, but it's pretty much the same idea: you either implement all the methods, or you don't use it. |
| 21:31 | hiredman | well, you don't brag about using it |
| 21:31 | arohner | I thought I was implementing all of the methods, just in two different places |
| 21:32 | arohner | still getting the same error |
| 21:32 | notallama | paste again? |
| 21:33 | lisppaste8 | arohner annotated #91404 "untitled" at http://paste.lisp.org/display/91404#2 |
| 21:37 | notallama | take inserttableRow out of the deftype, and it should work. |
| 21:37 | arohner | oh right, because I'm not providing a new method for that |
| 21:37 | arohner | yeah. it works |
| 21:37 | arohner | thanks. |
| 21:47 | rongenre | I'm using resultset-seq to unpack a jdbc resultset. Is there any way to get the struct which is used to make the records? |
| 21:51 | arohner | rongenre: not really. the struct is created dynamically during the resultset-seq call |
| 21:52 | arohner | ~def resultset-seq |
| 21:52 | arohner | see that line "row-struct (apply create-struct keys)" |
| 21:53 | rongenre | Yeah, i noticed there doesn't seem to be a def accessor on PersistentStructMap |
| 21:54 | rongenre | Should I just rebuild the struct if I want to use accessors to access the fields? [I think there's a performance penalty otherwise] |
| 21:55 | arohner | that's one option |
| 21:55 | arohner | yes, accessors will be faster than normal map derefs |
| 21:55 | arohner | * map lookups |
| 21:55 | rongenre | Is there a better one? |
| 21:56 | rongenre | I suppose I could hack a version of resultset-seq to return the new struct and the sequence |
| 21:57 | arohner | I was just about to suggest that |
| 21:57 | arohner | that's what I would do |
| 21:58 | rongenre | got it. Thanks. |
| 22:36 | churib | ,(doc recur) |
| 22:36 | clojurebot | It's greek to me. |
| 22:36 | churib | ,(+ 1 1) |
| 22:36 | clojurebot | 2 |
| 22:37 | churib | ,(doc +) |
| 22:37 | clojurebot | "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0." |
| 22:37 | churib | ,(source +) |
| 22:37 | clojurebot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 22:47 | solussd | ,(println "does the bot talk?") |
| 22:47 | clojurebot | does the bot talk? |
| 22:51 | alexyk | somnium: in (fetch :collection {) |
| 22:51 | alexyk | } ) |
| 22:52 | alexyk | (fetch :collection :only [:key]) -- is :only a keyword? |
| 22:52 | alexyk | I recall it worked as a bare word, or I'm dreaming? |
| 22:52 | alexyk | sorry about { |
| 22:52 | alexyk | it's my mac brace-matching trinket |
| 23:00 | Drakeson | are there any good webkit bindings in java or clojure? |
| 23:03 | KarlThePagan2 | Drakeson, there's a java.net project for rich browser integration - it's a subproject of JDIC (java desktop integration c????) |
| 23:04 | KarlThePagan2 | however it might only be internet explorer |
| 23:04 | KarlThePagan2 | so that may be no help to you |
| 23:05 | solussd | ,(.parseInt Integer "1") |
| 23:05 | clojurebot | java.lang.IllegalArgumentException: No matching method found: parseInt for class java.lang.Class |
| 23:06 | solussd | ,(. Integer (parseInt "1")) |
| 23:06 | clojurebot | 1 |
| 23:06 | chouser | ,(Integer/parseInt "1") |
| 23:06 | clojurebot | 1 |
| 23:56 | Drakeson | KarlThePagan2: thank. I am not really looking for a "browser" as per se. I want the lean renderer, mainly. |
| 23:57 | Drakeson | thanks |