#clojure logs

2009-12-01

00:00tomojif you're using BitSet's destructive operations, clojure can't help you
00:00dnolentechnomancy: 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:00dnolenperhaps better server as a plugin?
00:00dnolenserver -> served
00:01the-kennyalexyk: If you store immutable bitsets, ref/agent/atom is perfect for the leaves.
00:05technomancydnolen: I want to add lein run; just not sure how that relates to JNI
00:05technomancyI guess you'd need project.clj to be able to contain a :library-path key or something?
00:06dnolentechnomancy: 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:07dnolenin order to make Clojure libs use JNIs portable, lein run could help here.
00:07technomancyoh, so they're stored in the jar, but they need to be extracted first?
00:07dnolentechnomancy: unfortunately yes from what I could gather after a whole day of reading people complain about it.
00:07technomancyit kind of sounds like having a run command is only a small part of the picture
00:08alexykso I figure there's no bitsets in clojure? :(
00:08dnolenalexyk: like setting a bit in a byte?
00:08alexykdnolen: in a series of bytes of any length
00:09alexyklike java.util.BitSet
00:09dnolenoh, why not just use that from Clojure?
00:09alexykdnolen: looks like from the above I need immutable one
00:09hiredmanyou don't
00:10hiredmanyou just shouldn't use clojure's referece types
00:10technomancydnolen: i've gotta take off; will continue this discussion on the mailing list
00:11dnolentechnomancy: cool, thx much.
00:12alexykhiredman: but then I won't be able to have them inside parallel stuff?
00:13KirinDavealexyk: So long as you don't mutate them directly, it's fine.
00:13alexykKirinDave: you set bits on them with (.set myBitSet)... how'd I do it if not directly?
00:14alexykor perhaps there's a method returning a new bitset there without touching the original
00:15hiredmanalexyk: you can lock on the bitset
00:15_mstalexyk: 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:16KirinDavealexyk: 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:16KirinDaveAlthough the performance characteristics of such are beyond me.
00:16alexykok...
00:16alexykI probably will do them in threads and then merge
00:37alexyksomnium: not much increase with the new, but only one key cut the time down by half or more. I guess my processing dominates.
00:57Drakesonhow can I access input args (argv) in a clojure script?
00:57Drakesondefn -main doesn't seem to cut it
01:00Drakesonoh, nevermind
01:18qedhow to make a lazy infinite sequence of the sum of [n] natural numbers?
01:19tomoj[n]?
01:19qed1+2+3+4+5=15 == the 5th triangle number
01:19tomojI have this in my euler code
01:20qedhints please, not answer
01:20tomojoh
01:20qedanswers*
01:20tomojwell, are you using lazy-seq?
01:20qedI was thinking about something like (lazy-seq (iterate..))
01:20qedim not sure how to use iterate though
01:21tomojI did it the ugly way with lazy-seq'd recursion
01:21qedhmmm, like a loop and recur
01:21tomoj(lazy-seq (cons .. ...))
01:21tomojno recur with that way since it's not tail position, but lazy-seq keeps you from blowing the stack
01:22somniumqed: have you googled triangle numbers?
01:22qed([& body])
01:22qedwhat is the & there?
01:22qedand what specifically is meant by body
01:22tomojyou 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:22tomojbody is bound to all the rest of the arguments
01:24carkqed: you don't need lazy-seq, i think you should only look at c.c.seq-utils/reductions and iterate
01:24tomoje.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:24tomojyeah there's usually a prettier way to do something you're doing with lazy-seq :)
01:25carki think i have the solution right there
01:25tomojlooks like body actually gets bound to an ArraySeq
01:25carki so want to give it to you !
01:25tomojnever even heard of that..
01:25qedsec cark :)
01:26tomojbut anyway it's a seq that contains all the rest of the arguments (that's what the & does)
01:26qedcark, ah-ha!
01:27qedthat reductions stuff is slick!
01:27carkyes =)
01:27qed(reductions + (range 0 10000))
01:27qedweee
01:27tomoj?def rec-seq
01:27qedre-seq?
01:27qed?def re-seq
01:28qed,doc re-seq
01:28clojurebotjava.lang.Exception: Can't take value of a macro: #'clojure.core/doc
01:28tomojguess c.c.seq-utils uses rec-seq internally?
01:28carkthat's not an infinite lazy seq
01:28qedcark, mine?
01:28carkyes
01:28qedcark, im guessing you do something where you iterate over (reductions + (range 0 n))
01:29carkit's bounded by your range
01:29tomoj,(take 10 (iterate inc 1))
01:29clojurebot(1 2 3 4 5 6 7 8 9 10)
01:29carkthere you go =)
01:29qedhehe thanks
01:29tomojthat's much prettier than my version
01:30tomojhttps://gist.github.com/123b199e06c4cdb00280
01:30carki guess yours is more efficient tomoj
01:30cp2talk more, i am configuring my new irssi theme :)
01:31tomoj,(require 'clojure.contrib.seq-utils)
01:31clojurebotnil
01:31tomoj,(doc clojure.contrib.seq-utils/rec-seq)
01:31clojurebot"([binding-name & body]); Similar to lazy-seq but binds the resulting seq to the supplied binding-name, allowing for recursive expressions."
01:32qed(take n (reductions + (iterate inc 1)))?
01:32tomojI don't understand that at all
01:32tomojuses an atom for some reason
01:32cark,(take 10 (reductions + (iterate inc 1))
01:32clojurebotEOF while reading
01:32cark,(take 10 (reductions + (iterate inc 1)))
01:32clojurebot(1 3 6 10 15 21 28 36 45 55)
01:33qedyay
01:33carktoo bad real world isn't always that nice =/
01:33tomojI love it when you can replace a hunk of ugly unreadable code with a simple one-liner
01:34qednow the other thing I need to figure out is how to test this infinite lazy sequence for the number of divisors they have
01:34tomojguess you're doing euler #12?
01:34qedyeah
01:38tomojqed: hint: don't prime-factorize
01:38tomojI tried that and I think it was far too slow
01:38qedlol i was just looking at that
01:38qedso brute force this portion of it?
01:39tomojmaybe if you can quickly prime-factorize it would work
01:40qedi dont know how to do that quicly
01:40qedquickly
01:41qedit seems like the number of the first # of primes is 4, like 2*2*2*2*5
01:41qedthat's just a guess
01:45tomojhmm
01:45tomojit seems to be taking quite a long time even with a divisor function I got from, I think, hiredman
01:49qedthere we go
01:49qeduser.oO (time (first (filter #(> (divs %) 500) triangles)))
01:49qed"Elapsed time: 6931.855 msecs"
01:50tomojwow
01:51tomoj"Elapsed time: 159806.865765 msecs"
01:51tomoj:)
01:51qed(def triangles (lazy-seq (reductions + (iterate inc 1))))
01:51tomojif you pasted your divisor function it would make me very happy
01:52qed(defn divs [n] (* 2 (count (filter #(zero? (rem n %)) (range 1 (Math/sqrt n))))))
01:52qed(time (first (filter #(> (divs %) 500) triangles)))
01:53tomojoh it seems your computer is just way faster than mine
01:53qedquad-core 2.66ghz
01:53qed8gb/ram
01:53tomojnetbook here :)
01:53qedah
01:54tomojI think the divisor function I stole from hiredman does the same basic thing, just in a different way
01:54tomojthough your version only took 101s
01:55qedmy answer is incorrect
01:55tomojhuh, strange
01:55tomojI got the same answer using my divisor function as with yours
01:55tomojwhat was your incorrect answer?
01:55qed76576500
01:55tomojthat's the answer I got too
01:55qedit says incorrect
01:56qedthis time it worked
01:56qedi think i maybe had an extra space
01:56tomojhuh, I actually hadn't solved #12 yet apparently
01:57tomojthough I had the code right here to do it in 159s, strange
01:57qedive been avoiding it
01:57qedcause it seemed boring
01:58qedso does 21
01:58tomojcl-format probably makes #17 trivial
01:58tomojif cl-format does ~r
02:00qedunfortunately thats all the euler ill be doing for tonight
02:00qedim gonna try to wake up early before work and do one
02:00qedi do better work in the AM
02:01qedgnight all
02:02tomojah crap
02:02tomojeuler wants british english numbers and cl-format does something else
02:07tomojI wonder if euler did that on purpose so we couldn't use CL's ~r
02:08qedit inspires debate
02:10qedtomoj: i should qualify that i lifted chouser's #12 divisor function to finish that off
02:20tomojoh, hmm
02:20tomojdid yours say "totally useless"?
02:20tomojI thought it was hiredman's but my memory is totally shot
02:21tomojoh, yours was different, I forgot. see, my memory is _totally_ shot
02:21tomojdon't do drugs, kids
02:26hiredmanif I recall, euler just wants a word count
02:27hiredmanI think I just did the first letter in each word, then counted those
03:08angermanhow do I create an agent with meta-data?
03:09angerman(with-meta (agent nil) {:no 1}) gives me an Agent cannot be cast to IObj Exception
03:10hiredmanthere are two seperate metadata protocols, bifibricated on mutability
03:11_ato,(doc reset-meta!)
03:11clojurebot"([iref metadata-map]); Atomically resets the metadata for a namespace/var/ref/agent/atom"
03:11hiredmanwith-meta is for metadata on immutable things
03:11angermanmeh :( using (agent nil :meta ....)
03:11angermanso (with-meta) is immutable
03:12hiredmanit is for returning a new immutable thing with metadata attached
03:12_atoyes 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:13angermanyep, I was just confused, I wanted to setup the agent with metadata upfront, musst have missed the :meta arg
03:14angermanI'm trying to write an agent pool that dequeues on completion.
03:15angermane.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:15angermanI think using watches would be even better.
03:34angermandoes the function that the agent executes have any access to the agent?
03:43slashus2angerman: Are you talking about *agent* ?
03:46angermanslashus2: maybe, let me see
04:45angermanwheee ...
04:45angermanhttp://gist.github.com/246189
05:28optimizeris using a c++ ffi even practicel in clojure, or is the jni calls just too expensive?
05:29ambient_well i'll get back to you, im doing that right now
05:29optimizermy question?
05:29ambient_rtaudio has no good jni implementation :/
05:29ambient_yeah your question
05:30optimizerdude
05:30optimizeri wnat to do audi processing too
05:30optimizerany chance you ca open source your interface?
05:30ambient_well there's jass-sdk
05:30ambient_http://people.cs.ubc.ca/~kvdoel/jass/
05:31ambient_it seems to be pretty low-latency and includes synth toolkit, but i don't know how current it is
05:57fliebelhiredman: 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:12angermando defn's share any state?
06:13ohpauleezI'm not sure exactly what you mean, but they'll only share some notion of state in a binding form
06:13angermanI'm trying to understand why http://gist.github.com/246232
06:13angermanthrows an IllegalStateException: No transaction running
06:14angermanthe function is sent to an agent to process it.
06:16ohpauleezlet me take a look
06:17Chousukeyou have alters in there
06:17ohpauleezyou have alters
06:17ohpauleezand they need to be in a dosync
06:17ohpauleezwith atoms
06:17ohpauleezahhh Chousuke! you beat me to it
06:18angermanthanks, let's see
06:19ohpauleezangerman: 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:20ohpauleezsame with refs
06:20Chousukeangerman: probably the man, mix and avg values be strings is not very performant
06:20angermanok, but the atom is function local, right?
06:20Chousukeangerman: that'll create *lots* of strings if you have many query results :/
06:20ohpauleezI mean refs, not atoms
06:20angermanChousuke: it's a database -> libsvm conversion.
06:21angermanso I need the strings and write them out
06:21Chousukeangerman: yeah, but you should accumulate values and create the strings at the end
06:22angermanI get for each row three float values
06:22angermanthat need to end up as <i>:<float value> <i+1>:<float value> ....
06:22angermanso I'll create the <i>:<float values> in an accoumulator and run reduce over them?
06:23Chousukeno, just accumulate the float values into a vector and print the contents of the vector (using format) instead of creating temporary strings? :)
06:23fliebelCan 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:24angermanChousuke: hmmm....
06:24Chousukefliebel: (doseq [item seq] (function item))
06:24Chousukefliebel: and map doesn't *change* anything :)
06:24Chousukewell, shouldn't.
06:25fliebelChousuke: Ok, map is for returning a new sequence with different items, right?
06:25Chousukeyeah.
06:26angermanChousuke: so basically i conj them onto a vector.
06:26fliebelChousuke: 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:26angerman(alter vec conj floatval)
06:27angermanthen 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:28Chousukedo you need a single string? :P
06:29Chousukecan't you just print it out an item at a time
06:29Chousukealso, now that I think about it, why do you have refs in that function at all?
06:29fliebelWhy doesn't this work? (doseq [tag [:a :span]] (def tag (partial html tag))) Apparently Clojure confuses me quite a lot...
06:29angermanbecause the values are in a column in the table and I need them as a row in the file
06:30Chousukefliebel: html is a macro? :)
06:30angermanso I'm iterating over the rows, collecting the data, and writing it out.
06:30fliebelChousuke: A function at least....
06:30Chousukeangerman: so don't write newlines?
06:30angermanwell the writer-agent adds a newline
06:31Chousukeyou'll need to change it.
06:31angermanI have 253 experiments, with each 44700 features with min/avg/max values
06:31Chousukecreating a string of all the 45 thousand float vals is going to waste a huge amount of memory.
06:31Chousukeyou don't want to do that.
06:32fliebelChousuke: 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:32angermanassuming I'm going to collec the 44700 values in a vector, I could hand that vector to the writing agent
06:32Chousukepossibly
06:32angermanand let the writing agent work them off in a print loop
06:32Chousukefliebel: oh right.
06:32Chousukethe def is the problem
06:33Chousukedefs are only for top-level
06:33Chousukeyou need a macro :)
06:33fliebelok… 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:34fliebelThe 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:34Chousuke,(let [a 1] (map class [a 'a :a "a"]))
06:34clojurebot(java.lang.Integer clojure.lang.Symbol clojure.lang.Keyword java.lang.String)
06:35ohpauleezfliebel: :a is a keyword
06:36ChousukeI can't stay to help, though. must hurry.
06:36ohpauleezhttp://java.ociweb.com/mark/clojure/article.html#Collections
06:36ohpauleezI'm here, I'll pick things up
06:36fliebelohpauleez: thanks :)
06:37ohpauleezfliebel: totally welcome, that's a great resource, you can learn the bulk of Clojure in a day from it
06:37ohpauleezangerman: are you all set?
06:37fliebelI just read half of it yesterday… But in a kind of sleepy and back-and-forth way :P
06:38ohpauleezfliebel: are you coming from Java, Python/Ruby, Common Lisp/Scheme or relatively new to programming?
06:39fliebelI 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:42ohpauleezSo keywords in clojure are cool. http://clojure.org/data_structures#toc8
06:42fliebelI 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:43ohpauleezyou use them as you would standard keys of a dictionary
06:43fliebelkeywords are the : ones?
06:43ohpauleezexcept, like python, hash-maps (dictionaries), are used for book keeping and tracking a lot of information
06:44ohpauleezfliebel: yep, : ones
06:44fliebelI read they are like strings, but more like a number, every time you type :a or 1 you get the exact same thing.
06:45ohpauleezyes, they evaluate to the themselves
06:45fliebelso what are those ' things chousuke mentioned?
06:45ohpauleezquoting a symbol
06:46ohpauleezhave a look at: http://java.ociweb.com/mark/clojure/article.html#Syntax
06:46fliebelah, just like qupoting a list '(:a 'b c 1)
06:47fliebelI know the quoting syntax… Just that the context was missing.
06:47ohpauleezright, you quote a symbol so the reader doesn't attempt to evaluate it
06:47fliebelso what is the difference between ' and `? Quite confusing if you ask me...
06:47ambient_optimizer: i got jrtaudio working, just had to edit some .cpp and makefiles. http://code.google.com/p/jrtaudio/
06:48_ato,`inc
06:48clojurebotclojure.core/inc
06:48_ato,'inc
06:48clojurebotinc
06:48_atodifference 1: ` qualifies the symbol with its namespace
06:49_ato,`(:a ~(+ 1 1))
06:49clojurebot(:a 2)
06:49_ato,'(:a ~(+ 1 1))
06:49clojurebot(:a (clojure.core/unquote (+ 1 1)))
06:49_atodifference 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:50ohpauleezthanks _ato, I was only going to mention #2
06:50fliebelI noticed that, but in which case would you want to use ' instead?
06:50fliebel.`(:a :b)
06:50fliebel,`(:a :b)
06:50clojurebot(:a :b)
06:51fliebel,'(:a :b)
06:51clojurebot(:a :b)
06:51ohpauleezI use ' all the time unless I'm writing a macro and need evalutation via unquoting
06:51fliebelOk, 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:51fliebeltrue...
06:51_ato,'`(a (b c))
06:51clojurebot(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:52fliebelWhoa! what happened?
06:52_ato~ping
06:52clojurebotPONG!
06:52_ato` supposorts something called splicing-unquote, which looks like this: ~@
06:53_ato,`(a b ~@[:c :d] e f)
06:53clojurebot(sandbox/a sandbox/b :c :d sandbox/e sandbox/f)
06:53_atoto do that splicing it needs to rebuild the list
06:53ohpauleezfliebel: it's like *args in pything
06:53ohpauleezpython*
06:53_atothat's where all that stuff comes from if you do '`(something) and is why ' can be faster
06:54fliebelohpauleez: finally an explanation of that splicing thing....
06:55fliebelCan I use that splicing thing everywhere, or do I need to use apply or something like that?
06:55_atoyou can only use it inside a syntax-quoted ` form.
06:55_ato,~@foo
06:55clojurebotjava.lang.Exception: Unable to resolve symbol: foo in this context
06:56_ato,~@2
06:56clojurebotjava.lang.IllegalStateException: Var clojure.core/unquote-splicing is unbound.
06:56fliebelI see...
06:56fliebelCan I ask some more things about writing macros?
06:57_atosure
06:57angermanChousuke: thatnks, that seems to work way better
06:57fliebelAh, I forgot: "Don't als to ask"
06:58fliebelCan I turn :a into a?
06:58ohpauleezangerman: glad it's working out
06:59_ato,(symbol (name :a))
06:59clojurebota
06:59fliebelato: How intuitive :)
06:59ohpauleez,(doc name)
06:59clojurebot"([x]); Returns the name String of a symbol or keyword."
07:00_ato,(keyword (name 'a))
07:00clojurebot:a
07:00fliebel,(doc symbol)
07:00clojurebot"([name] [ns name]); Returns a Symbol with the given namespace and name."
07:01fliebelI'll try to write my macro now, but I'm sure it will not work the way I planned it.
07:01ohpauleezfliebel: 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:01ohpauleezyou'll be up and running in no time
07:02fliebelHmmm, good idea.
07:05fliebel(defmacro deftag [tag]
07:05fliebel `(def ~(symbol (name tag)) (partial html ~tag)))
07:05fliebelIt works, but now I need to get it working with multiple arguments.
07:06fliebellike… (deftag :a :span :p)
07:10fliebelato 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:15rhickeyfliebel: just have the macro emit the defs in a do - the do will disappear at top level
07:16fliebelrhicky: The number of arguments is unknown, I want to use the & argument syntax. Would loop work as well?
07:16ohpauleezfliebel: also, have a look at http://en.wikibooks.org/wiki/Learning_Clojure#Macros
07:16ohpauleez[& args]
07:17ohpauleez[arg-one arg-two & other-args]
07:17rhickeyfliebel: see the definition for declare in core.clj
07:19fliebelI got this now, but it fails...
07:19fliebel(defmacro deftag [& tags] `(loop [tags tags] (def ~(symbol (name (first tags))) (partial html ~(first tags))) (recur (rest tags))))
07:19rhickeyhttp://github.com/richhickey/clojure/blob/master/src/clj/clojure/core.clj#L4283
07:19ohpauleezThere is also a little bit of info on declare here: http://java.ociweb.com/mark/clojure/article.html#DefiningFunctions
07:20rhickey,(macroexpand-1 '(declare a b c))
07:20clojurebotDENIED
07:20rhickeyaargh
07:20rhickeyexpands to: (do (def a) (def b) (def c))
07:21fliebelrhickey: that sounds like what I need…
07:22ohpauleezalso, your loop has two args, but you're only recuring one
07:22rhickeyfliebel: 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:22ohpauleezand it might not make sense for this to be a macro
07:23ohpauleezexactly what rhickey said
07:23ohpauleezyou only use a macro when you don't want to eval all the args
07:23fliebeluuuhm, that sound reasonable...
07:23ohpauleezit's for generating other syntax or conditional controls
07:25fliebelI want people to be able to call (a rest) instead of (html :a rest) by defining a as a partial.
07:25fliebelso all i want to do is some easy way to define a few of those partials in one blow.
07:26ohpauleezI would define a with-html macro maybe
07:26ohpauleezI'm not sure what you're building
07:26ohpauleezbut (with-html "some-file.html" (my-body-here))
07:27ohpauleezI assume some html browser or DSL
07:27fliebelDSL...
07:32fliebelBut I guess it would be a valid macro to turn a list of keywords to a list of partial statements...
07:37fliebelI have to leave, bye!
07:56cemerickrhickey: what's your snap reaction to the notion of a string interpolation reader macro? e.g. #@"str of some value @here", or somesuch.
07:56rhickeycemerick: ick
07:56cemerickI'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:56cemerickheh, OK
07:58rhickeybut I'm not saying never, just the ones I;ve seen were more complex than the problem they were 'solving'
07:58cemerickrhickey: Sure. I think it's somewhat inevitable. Too handy in ruby to not steal.
07:58rhickey(str "str of some value " here)
07:59cemerickwell, short stuff is certainly not where the money is
08:00cemerickwriting 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_atovs ala ruby "Hello, #{user}! You have #{(count tasks)} remaining tasks."
08:01chouserruby'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_atoI don't think your gaining much
08:01cemerickchouser: yeah, I'm half-done with a userland macro
08:01cemerickruby does allow arbitrary expressions, which is a little nutty
08:02cemerick_ato: the two are *very* different w.r.t. readability IMO
08:02chouseroh, I thought that was the whole point, the arbitrary expressions.
08:02chousernested even, which can get fun.
08:04cemerickEven simple references to existing bindings would be a win at the moment.
08:04cemerickbut even nested arbitrary expressions should be pretty straightforward
08:05chouseronly problem there would be double-quote-escaping, I think.
08:06cemerickyeah. Having two string delimiters is super-handy.
08:06cemerick" *and* ', that is
08:07chouserI meant that this is valid ruby, but Clojure won't read it right: "outer #{"this" + " inner #{10 + 20}"}"
08:08_atoit does beat (format "Hello, %s! You have %d remaining tasks." user (count tasks))
08:08cemerickchouser: 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:10ambienti 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:11ambientso which is the right way to tell gen-class that the methods input attribute is of type double[]? :/
08:11chouserambient: I think for gen-class you still have to use "[D"
08:11ambientoh ok
08:13ambientclass not found java/land/[D
08:13ambient*lang
08:14chouserambient: :-( http://www.assembla.com/spaces/clojure/tickets/162
08:14rhickeyhttp://groups.google.com/group/clojure/browse_frm/thread/d8445bd527be5542/db8672869184702d
08:15ambientchouser: ok seems i have to update clojure :)
08:15ambientusing 1.0.0 currently
08:15chouserambient: that fix isn't in github anywhere yet
08:15ambient:(
08:15ambientwell guess im screwed then
08:16chouserambient: you could try applying it to your 1.0.0 clojure -- there's a passing chance it might work.
08:16ambienthere's the code fwiw: http://paste.pocoo.org/show/154098/
08:17chouserambient: or you could go crazy and move right to the "new" branch and use deftype instead.
08:17ambienti'd rather not :D
08:17chouserambient: very sensible.
08:18rhickeyanyone have any luck with latest deftype/reify/protocols?
08:18chouserrhickey: haven't had a chance to do much yet. maybe this afternoon.
08:20rhickeyI'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:21rhickeythe latter makes the simplest case simpler still:
08:21rhickey(reify ActionListener (actionPerformed [this evt] ...))
08:21rhickeyand makes deftype/reify consistent with extend*
08:22cemerickrhickey: willl that still transparently work with overlapping interface sigs?
08:23rhickeycemerick: 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:24cemerickrhickey: This should probably be an error: (reify P1 P2 (m1 ...) (m2 ...) (m1 ...))
08:24rhickeyincorporating pile-o-methods into syntax means marrying pile-o-methods semantics
08:25rhickeycemerick: yes, should be
08:25rhickeyhaven't coded it yet
08:25cemericksure
08:25rhickeyalthough sometimes code-generating-code writes things like that
08:25cemerickThe pile-o-methods approach seems like a lot less work to me. Probably makes things hell for VM and language implementers, though.
08:26rhickeycemerick: you've never gotten bitten by wanting to derive from 2 classes/interfaces whose methods clash?
08:27cemerickrhickey: I try to make sure I'm building the libraries, not using them. :-) Though that's changing fast...
08:27chouseryou can namespace-qualify the method names in reify and deftype now?
08:27rhickeychouser: no
08:27chouserso splitting them by protocol name would help there, right?
08:28rhickeychouser: without being able to generate prefixes, the resulting JAva class is going to mash them together anyway
08:29rhickeybut having them split in the syntax means prefixes might be a future possibility
08:29chouserok
08:29rhickeyalso, enhanced checking
08:29rhickeyand consistency with extend*
08:29rhickeyand simpler simplest case
08:31rhickeyI have to say, adding all the explicit thises to the few exisitng reify/deftypes was a real, seeming pointless, pain
08:31rhickeystarted using _ for this
08:31rhickeywill be most common case
08:32rhickey:(
08:32chouserthat's actually what I was tripping over last night too. Used 'x' instead of 'this' in my defprotocol, and was then confused...
08:32rhickeythe first arg will rarely be used
08:33chouserright, because of direct access to fields
08:33rhickeyalmost made me want to accept with and without '.'
08:34chouserhm, surely not.
08:34rhickeychouser: yeah, the only time you need this is to call another method on yourself or pass this to someone else
08:34rhickeychouser: passing idea :)
08:34rhickeynow gone
08:35rhickeychouser: 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:36rhickeythis is a name for an implementor
08:36chouserextend 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:36rhickeychouser: right
08:37rhickeyextend*
08:37chouserfor me, that's the consistency pain point.
08:39chouserand the extend macros could hide the 'this' arg as well. hm...
08:39rhickeybut how to mitigate? would just make members more cumbersome (foo [this x] ... (:afield this))
08:39rhickeychouser: they would have to auto-bind 'this' though, since you will need it in extend-* defs
08:40rhickeyno implicit fields
08:41rhickeydoing implicit this in deftype/reify and extend-* would make everything consistent (don't supply frst arg) *except* pure extend and mixins
08:42rhickeythe latter being more power tools
08:42chouserright, the latter is what I was suggesting, not (:afield this)
08:43rhickeyI see the vast majority of people using deftype/reify and extend-*
08:43chouserstill a slight mismatch with callers, but maybe that's no too bad?
08:43rhickeybut it is still a mismatch with defprotocol itself
08:44esjguys: 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:44chouserrhickey: because you want to allow a name other than 'this'?
08:44rhickeychouser: because the arg is there
08:45chouseresj: no need to apologize. :-)
08:45rhickeywith deftype/reify of interfaces it's easy since the interface method declaration doesn't include this
08:45rhickeyesj: try ant clean on contrib before rebuild
08:46esjrhickey: on it
08:47rhickeyso, declare Seqable.seq(); , define seq(){...}, call coll.seq(), all matches (in the parens)
08:48rhickeybut (defprotocol Seqble (seq [coll]) ), (deftype Foo Seqble (seq [] ...)), (seq afoo) doesn't match
08:49chouserI still don't see why defprotocol can't have an implicit coll (names 'this' of course)
08:49rhickeycould be (defprotocol Seqble (seq []) ), (deftype Foo Seqble (seq [] ...)), (seq afoo) ; protocols presume first arg
08:50chousernamed
08:50chouserright
08:50chouserleaving (seq afoo) the odd man out
08:50rhickeyI think people get that after: coming from Java, using Clojure and seeing where target goes in (.method target args)
08:51rhickeybut not intuitive, and bigger mismatch with extend/mixins
08:51chouserrunning the kids to school -- brb
08:55fliebelHow 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:56esjfliebel: I had the same misunderstandings - seqs are totally different from vectors
08:56ambientpython lists aren't even lists afaik, they're dynamic arrays
08:57esjfliebel: you _can_ append to seqs, but I think that it, in general, is not a good idea.
08:58fliebelesi: Is there any good documentation on vectors, lists and maps? http://clojure.org/sequences is not very helpful to me.
08:59rhickeyfliebel: http://clojure.org/data_structures
08:59esjzakly
09:00esjrhickey: after git pull, ant clean, ant on clojure and clojure-contrib my error is now (use 'clojure.contrib.json.write)
09:00esjjava.lang.NoSuchMethodError: clojure.lang.RestFn: method <init>()V not found (NO_SOURCE_FILE:0). Seen it before ?
09:01rhickeythat is almost always a mismatched/incomplete build problem
09:01leafw_fliebel: I'd use vectors wherever you think "list"
09:01esjfliebel: also check out http://blip.tv/file/707974 I found it really useful
09:02fliebelleafw: How about appending a statement to a function? functions are lists in fact, aren't they?
09:02esjrhickey: thanks - I'll hunt it down.
09:05fliebelesi: How can I append to a list? Or are there any other options to append a statement to a function?
09:06esjfliebel: are you working with macros ?
09:06fliebelesi: sort of… just playing around, but for this example that includes using a macro.
09:07fliebelAt least the function is in list state, not executed.
09:11esjfliebel: 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:12fliebelI can imagine… I'll try something else, and continue to do that until I understand Clojure, or at least macros
09:12rhickeyfliebel: there is concat
09:13Drakesoncan I access the name of the ns that uses my library, in a macro?
09:14rhickeyDrakeson: *ns*, at macroexpansion time, will be that ns
09:15rfgpfeifferreify does not complain when I do not implement all methods in a protocol. Is this the intended beaviour?
09:15Drakesonthanks :)
09:16rhickeyrfgpfeiffer: that is intended, but an open question moving forward
09:17esjrickey: totally correct, got it going now, thanks.
09:19rfgpfeifferrhickey: i'd like it to produce a warning, but not an exception
09:20chouserwarnings need a way to be turned off
09:20rfgpfeifferlike in haskell when your patterns do not cover all possbile cases
09:22rhickeyrfgpfeiffer: that would be possible, I think we need to see how often that 'feature' is leveraged
09:22rfgpfeifferat least once :)
09:23rhickeyI 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:29rfgpfeifferhaskell-like pattern matching with double dispatch on protocols http://gist.github.com/246310
09:30lpetitrhickey: 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:30lpetitoh, and hi, BTW :)
09:31rhickeylpetit: I'm not strenuously arguing against a warning, but one person's warning is another's nuisance
09:31lpetitrhickey: certainly, and that would let room for implementing those needed warnings in IDE :-p
09:32rhickeyexperience will show what the default should be
09:32rfgpfeifferwhat about a variable *warn-on-non-exhaustive-protocol-implementation*
09:32rhickeyrfgpfeiffer: something like that but, ... shorter
09:32rfgpfeifferof course
09:34rhickeyany more opinions on implicit this in deftype/reify/extend-type and extend-class?
09:35lpetit"experience will show what the default should be" :-p
09:36rhickeylpetit: for implicit this? not toggleable
09:36rhickeymy brief experience was a lot of _s
09:37lpetitrhickey: _s are an interesting information by itself for code readers, aren't they ?
09:38hoeckrhickey:
09:39rhickeylpetit: dunno - seems like noise and tedium to me: http://github.com/richhickey/clojure/commit/a84a4e1ff36b85ec2afa4df41c5affca1a76c78a
09:40hoeckrhickey: I'm on the new branch from nov, 12 and actually like the implicit this in deftype after implementing some clojure interfaces
09:41rhickeyhoeck: 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:41hoeckrhickey: 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:41hoeckrhickey: a,h ok
09:41rhickeyhoeck: right, 'this is rarely used
09:41lpetitrhickey: feedback from python guys may be interesting (isn't explicit this/self the enforced default in python ?)
09:42rhickeylpetit: I found 'self' annoying in Python
09:42chouserme too
09:42fogushere here
09:42chouserthough I was a different programmer then
09:43angermanisn't self only a convetion?
09:43lpetitrhickey: 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:43rhickeythe 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:44chouserI think I'd want it gone from defprotocol too.
09:44rhickeythen, as consumer of P, wanting to call (foo ...) , will expect to pass what?
09:45fogusangerman: http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html
09:46chouser(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:47rfgpfeifferi like self in python, but reify is more static than python's class:
09:49rhickeychouser: the doc string for foo could add the param back in
09:50chouserrhickey: that would certainly help.
09:50rhickeyfoo ([Protocol arg arg]) docs
09:52chouserthere 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:52cburroughsangerman, The name 'self' is a convention, but the argument must be there.
09:53chouserso we're pushing around where to draw the line between method-like defaults and function-like behavior.
09:54rhickeyThere 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:54chouserhaving 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:55rhickeyof course, reify methods are not functions but *are* closures
09:56rhickeysomething about having the target as an arg in extend-type/class makes it clearer these are external extensions
09:56chouserexplicit this everywhere does have the benefit of complete uniformity.
09:57rhickeyalso, implicit this in reify isn't really acceptable, only named this (reify this P ...) because reify likely to be nested/macro-wrapped
10:00chouser[_] vs [] is a bit ugly, but hardly a huge cost.
10:01rhickeyone tension is that interface declarations already take a stand that can't be changed
10:01rhickeyso when implementing an interface the _ is extra, often forgotten baggage
10:03rhickeya common problem for people with gen-class
10:03chouserbut that's interop :-)
10:07rhickeyanother wrinkle:
10:07rhickey(defprotocol P
10:07rhickey (foo [x]))
10:08rhickey(deftype Foo [a b c] [P]
10:08rhickey (foo [x] (recur 42)))
10:08rhickeyjava.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 0 args, got: 1
10:08octe(let [agents (map (fn [&args] (agent 0)) (range concurrent))] <- there has to be a better way.
10:09chouserrhickey: :-(
10:09rhickeyrecur works, but you can't replace this
10:09chouserright
10:10chouserocte: (take 10 (repeatedly #(agent 0)))
10:10rhickeyhmm, someone proposed an n arg to repeatedly to match repeat...
10:10chouserocte: (for [_ (range 10)] (agent 0))
10:11octethanks.
10:12rhickey(extend-class String P
10:12rhickey (foo [s] (recur)))
10:12rhickeyjava.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 0
10:14rhickeythere will be no way to make the same arglist and recur call work in both deftype and extend-type
10:14rhickeyindicates they should have different arglists
10:15octehttp://paste.lisp.org/display/91345 <- should that work?
10:15octeit seems to sometimes give errors
10:16chouserrhickey: proxy currently has the same problem.
10:16octeor maybe it's only sometimes if the agent function hasnt run yet..
10:16chouserocte: that usage of #() is incorrect
10:16rhickeychouser: because proxy's implicit this is a lie
10:17chouserrhickey: right
10:17octechouser: how?
10:17rhickeynot so for deftype/reify
10:17rhickeymore tea needed - biab
10:19chouserocte: #(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:19chouser,((println "hi") nil)
10:19clojurebotjava.lang.NullPointerException
10:20chouserocte: also, agent action fns must take at least one arg, the current value of the agent.
10:20chouserocte: so try (send a (fn [_] (println "hi") nil))
10:21octechouser: i don't understand the #() macro, does it take as many arguments as you actualyl use in the function?
10:21chouserocte: yes
10:21chouserwell, as many as the highest you name.
10:21djorkwould it make sense to use an agent to process a line of input from a socket?
10:22chouser,(#(println "4th is" %4) :a :b :c :d)
10:22clojurebot4th is :d
10:22djorklike, say the agent's value held the sockets to read/write on
10:22chouserdjork: yeah, that will probably work.
10:22djorkblocking is not a problem?
10:23djorkbecause it could wait indefinitely
10:23djorkright now I'm using refs
10:23chouserdjork: blocking is fine as long as you use send-off
10:23djorkah, I see
10:23octechouser: so, (send a #(println %1)) would work too?
10:23octefor example
10:23chouserocte: yes, but of course will change your agent state to nil
10:24octeyes, what i want to do is a one-off asynchronous task
10:24octedon't know if an agent is correct for that
10:24chouserocte: it might be. You might also like 'future'
10:25chouserhm, actually if it's one-off, agent is probably not right.
10:25djorkfuture sounds perfect
10:25djorkalthough deref'ing the returned future blocks
10:25djorkso you'd be responsible for managing the time in-between
10:26djorkbut that only matters if you care about the result
10:27octedo not care about the result
10:27octedid not know about future, sounds better :)
10:28djorkanybody else notice that JLine doesn't handle ^Y (yank or "paste")...?
10:28chouserI use rlwrap
10:29djorkhmm
10:29octei 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:29djorkthat sounds better
10:29octesound familiar for anyone?
10:29djorkocte: it's probably a slime thing
10:29octeyes
10:29chouserI think they go to an inferior buffer, whatever that means.
10:29octeah, yesh
10:30octejust need to find the variable..
10:30fliebelCan I use future on the repl? It just waits until the output is returned because the return value is printed of course.
10:31chouserfliebel: yes. maybe stuff it in a 'def' if you don't want to wait just yet.
10:31djorkchouser: thanks for the rlwrap tip, works great
10:32octeM-x slime-redirect-inferior-output
10:32octeif someone else was curious
10:32octei find the public irc log for this channel a great help when searching for problems :)
10:32octei mean solutions to problems..
10:33djorkoh wow, rlwrap has parens-matching, that is really killer
10:33chouserocte: you use google on it?
10:33chouserdjork: and vi-keybinding support. mmmmm
10:33fliebelchouser: works...
10:33djorknice
10:33octechouser: yep
10:34chouserocte: good. that's the intended use case. glad it's working for you. :-)
10:35lpetitrhickey: 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:38rhickeylpetit: in deftype and reify it's not a matter of repeating - you have to leave it out
10:39rhickeylpetit: it will be interesting to see how much mixing in there will be - mixins are not an option inside deftype/reify
10:41fliebel(What are these thing? I'm trying to (doc) everything, but this gives: Unable to resolve symbol: deftype in this context)
10:41rhickeycould be possible in deftype
10:42rhickeybut not reify, as closure-per-method in reify reintroduces the n-object-per-object overhead of proxy
10:42chouserfliebel: these are experimental features in the "new" branch on github
10:43RaynesIncidentally, 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:43fliebelchouser: that explains quite a lot...
10:44chouserfliebel: you're watching the Clojure design and implementation process in action.
10:45fliebelchouser: Cool, but I do not yet understand the basics...
10:45lpetitrhickey: 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:47rhickeylpetit: 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:49octeis it a good/bad idea to queue up a bunch of functions with send-off to agents?
10:49lpetitrhickey: 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:49rhickeylpetit: thus, getting it right is important
10:49lpetitbecause he has to remember / dig clojure/contrib for examples, ...
10:50lpetitrhickey : 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:50rhickeythere 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:52djorkmaybe there should be either a #clojuredev or #learnclojure channel :P
10:52djorkMy vote would be #learnclojure
10:52ambientthat probably wouldn't work very well
10:52lpetitrhickey: out of the top of my head: is the problem related to the fact that protocols and interfaces can be mixed ?
10:53octedjork: yes, i ind rhickey's discussions interesting and don't want to disrupt them
10:53octefind*
10:53octewith my newbie questions
10:54djorkI mean there should be experts in both, but our noob ramblings just don't seem to fit sometimes :D
10:54ambientdjork: 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:54octedjork: yes
10:55djorkthat's true
10:55rhickeylpetit: 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:55djorkmight as well not fragment the community where it's not absolutely necessary
10:57chouserocte: 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:57ambientif one is a total newbie in clojure, one should read a book and the excellent tutorial by R. Mark Volkmann
10:57tmountaindoes 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:57lpetitdjork: 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:57chouserocte: on the other hand, I'm afraid a newbie channel might be mostly full of newbies misleading each other. :-/
10:57djorkyeah
10:57octeyes..
10:58djorkhmm, yeah, if 10 people ask the same question one day, it might be a signal
10:58ambientheh, newbies misleading other newbies. it happens more often than not
10:58chousernothing gets a response faster in here than an incorrect answer.
10:58octeafter running shutdown-agents, is it possible to resurrect them?
10:59djorktmountain: that looks like fun... I think I have seen it before
10:59chouserthe clever newbie might leverage that by logging in under a different nick and giving himself bad answers to provoke responses.
10:59octechouser: yes, another proven strategy for getting help.. ask the questions in a trolling way :)
10:59rhickeychouser: yikes!
10:59chouserrhickey: :-)
10:59tmountaindjork: a few others in the same spirit, http://learnyouahaskell.com/ and http://learnyousomeerlang.com/
11:00ambientyeah, why bother when plain old trolling works just fine :P
11:00octehttp://www.bash.org/?152037 feels relevant
11:00djorkhah, yes octe
11:00djorkdid you see the "kissed a girl" thing from Sun?
11:00chouserfoo: is into lazy? not-foo: yes, just like all other binding mappers.
11:00octedjork: yes
11:00octefunny
11:01ambientalthough i suppose people here are too pragmatic to be so easily trolled
11:01octehttp://paste.lisp.org/display/91353 <- is this a good/bad way to do it?
11:02chouseryeah, pure trolling mostly gets ignored, thank goodness.
11:02KarlThePaganambient: just start a message passing benchmark argument?
11:02KarlThePaganlike our functions, trolling is higher-order
11:02ambientbut then one would not be a newbie :/
11:02octeKarlThePagan: was that supposed to be directed to me?
11:03djorkocte: It's just a sense I get but I feel like there's too much going on
11:03octedjork: yeah..
11:03djorkocte: you've got refs, agents, and future
11:03KarlThePaganocte: no, i was giving an example of how to troll a functional language chan ;)
11:03octeah
11:03djorkoh wait, they're not refs, you're just calling agents refs because they are derefs
11:04octedjork: yeah
11:04fliebelHmmm, I think those Head First guys should do a book on Clojure…
11:04djorkderef'able... whatever the term is
11:04octei could name it sum-agents, but it can sum anything that needs to be deref'ed :)
11:04djorkI think Wrox should do a book on Clojure
11:04octei think someone should recruit _why
11:04fliebelWho is Wrox?
11:05ambientdjork: heh, good one
11:05djorkWrox is the worst tech publisher ever... "for programmers by programmers"
11:05djorkno thanks
11:06fogusdjork: Do they publish those big red books?
11:06djorkthey usually put a picture of the author on the cover which always reinforces the fact that it was written by a "regular programmer"
11:06djork(read: fat and unkempt)
11:06octedjork: beards?
11:06djorkhttp://www.neudesic.com/uploads/david_barkol/webpartsbook.jpg
11:07fliebelHow good is the Clojure book listed on Clojure.org?
11:07octeafter doing a google image search for wrox books i see very little beards
11:07djork(I'm exaggerating)
11:07ambientfliebel: stuart's book? it's pretty good imo
11:08fliebelambient: Maybe I'll get that someday… Although nothing beets Head First imo.
11:08ambientit's easier to extract information from the book than the hive brain of internet
11:09octehmm, rich doesn't seem to have one either.. have i been fooled? i thought you needed one to be an expert
11:09micampefliebel: I have it, it's good if you are new to lispy/functional languages
11:09fliebelambient: 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:10ambientfliebel: clojure requires a bit more effort to grok. both python and php are very traditional
11:10ambientin a sense that they're somewhat derived from algol
11:10djorkI 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:10octeambient: yes, languages like those generally just require you to learn the stdlib
11:10fliebelBut 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:11ambientfliebel: reading through core.clj is also a learning experience
11:11djorkstarting with "The Reader" feels funny
11:11djorkbut it's also very good
11:11fliebelThat is what I mean… they are all more or less C-like...
11:11djorkbut coming from curly-braces languages you get this feeling like "OK, cut to the chase..."
11:11thehcdreamerI 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:12djorkthehcdreamer: there's really nothing to Java
11:12fliebelthecdreamer: I'm not sure for online, but for a real book I'd finitely recommend Head First Java :D
11:13ambientthinking in java by bruce eckel was free iirc
11:13thehcdreamerdjork: I find it confusing to browse java documentation for libraries I may need in clojure, like Date
11:13ambienthttp://www.ibiblio.org/pub/docs/books/eckel/
11:13fliebeldjork: what did you mean with that quoted sentence? "OK, cut to the chase..."
11:14thehcdreamerfliebel, ambient thanks
11:14angermanclojures agents makes me want to have many cores... two are ok, but so little
11:14fliebelthecddreamer: Head First Java has some character dedicated to understanding the library.
11:14angermanand more memory
11:15djorkfliebel: 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:15djorkyou have internalized things like "code is split into lines"
11:16djorkand you want to jump into the library of functions
11:16ambientfunctional programmin is not a trivial step to process
11:16djorkno
11:16fliebelI see...
11:16djorkso with Clojure's docs you get a bigger picture by starting with the reader, etc.
11:16djorkintroducing the repl as a fundamental part of the language
11:17djorkwhereas with other languages it's like "OK you know how source code works... here's how to make an array"
11:17ambientin clojure you dont tell the computer how to do stuff, you tell it what to do
11:17djorkright
11:17fliebelambient: that is quite confusing....
11:18djorkwell, I dunno
11:18djorkFP is more declarative than imperative
11:18djorkso I'd say it's the opposite
11:18octedoes doseq do recur?
11:18djorkno
11:19fliebeldeclarative: "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:19djorkyou can of course have other forms inside of doseq that serve as a recur point
11:19djorkfliebel: well never mind then :P
11:19octedjork: when i add (doseq [agent agents] (println agent)) to a catch-expression i get "Cannot recur from catch/finally"
11:20djorkoh I see what you mean
11:20djorkcan you paste?
11:21chouserocte: yeah, doseq uses recur internally
11:21octehttp://paste.lisp.org/display/91357
11:21octechouser: ah, ok
11:21octehow would i do that then?
11:21chouserocte: and you can't (currently) use recur in a catch block.
11:21djorkdoseq does use recur and it is a macro
11:21octeyes, that's what i suspected
11:21djorkthat's kind of an odd gotcha
11:21chouserjust put the body of your catch block in a separate function, and call it from the catch
11:22chouseryou can even do that all in-line if you want.
11:22octei 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:22octewould be nicer if it was a specific exception
11:22chouserocte: agent error handling is being redone.
11:22fliebelI am developing the habit to run macroexpand-1 on everything I encounter now...
11:22octei can't check for errors before i deref it since they may happen between the cehck and deref, right?
11:22djorkman, doseq is one hairy macro
11:22chouserdjork: not as bad as 'for' :-P
11:23chouserocte: https://www.assembla.com/wiki/history/clojure/Agent_exception_handlers
11:23chouserocte: but that's a ways off. :-/
11:23djorkfor looks like it is broken up into three main pieces
11:23octechouser: nice, i
11:23octechouser: nice, i'll read it later, heading home now
11:23djorkdoseq just kind of goes on
11:24fliebel,(macroexpand-1 '(doseq [a [1 2 3]] (println a)))
11:24clojurebot(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:24djorkHOLY GOD
11:24djorkI just did exactly the same thing in my repl
11:25djork[1 2 3] and all
11:25djork:P
11:25djorkit is bigger than clojurebot wants to print
11:25fliebelstrange, in repl it's quite small...
11:25chouserfliebel: might depend on your version of Clojure
11:26djorkclojurebot might be running a different version
11:26djork,*clojure-version*
11:26clojurebot{:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}
11:26chouserchunked seq support requires quite a bit more code
11:27fliebelmine is: {:major 1, :minor 0, :incremental 0, :qualifier ""}
11:27djorkthere you go
11:27djorkyou must have grabbed the jar from clojure.org
11:27fliebelwhat is chunked seq support?
11:27fliebelIndeed...
11:28fliebelWell, at least MacPorts did.
11:28chouserchunked seq support (with docs!) is coming for 1.1.0
11:29fliebelchouser: I figured that, but what does that mean?
11:29fliebelOr is it half a wiki to explain?
11:30chouserthere's a video. some slides.
11:30ambienti think it has something to do with granularity
11:30djorkfliebel: I would clone from github
11:31chouserone 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:31djorkchunked 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:32fliebelcool, so it's just optimization I wont notice?
11:32chouserfliebel: you can take some advantage of it without noticing, yes.
11:34fliebelI 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:35ambientim doing progressively larger projects
11:35ambientfm synth > genetic image construction > jpeg
11:35rhickeyanything else we wanted deprecated in 1.1? add-classpath, ^, parallel.clj
11:36fliebelLol, commas are whitespace aren't they? I just noticed that Clojure preserves them when printing the representation of a map.
11:36chouserfliebel: yeah, inserts them.
11:37chouser,{1 2 3 4 5 6 7 8}
11:37clojurebot{1 2, 3 4, 5 6, 7 8}
11:37fliebelcool
11:37djorkthe printer is nice to us
11:37fliebel,[1 2, 3 4,,,, 5 6]
11:37clojurebot[1 2 3 4 5 6]
11:38fliebelIndeed :)
11:39chouserrhickey: 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:40rhickeychouser: you mean the interpolation stuff?
11:40fliebelHow far of is 1.1?
11:40chouserrhickey: no, I just mean \newline and/or "\n"
11:40rhickeychouser: what about them?
11:41djorkI like character literals
11:42rhickeychouser: you can just point me to the discussion if I missed it
11:42chouserno, there's been no discussion. except in my head. :-P
11:42rhickeyah, there
11:43fliebelCan someone explain me the use of \newline?
11:43fliebel,(str \newline "\n")
11:43clojurebot"\n\n"
11:44micampeshould I use Java APIs to send data over a socket or is there something useful in clojure?
11:44chouser,(map class [\newline "\n"])
11:44clojurebot(java.lang.Character java.lang.String)
11:45fliebelchouser: memory efficiency?
11:45noidiis 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:45micampeoh, I found examples, great
11:46chouserfliebel: 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:46fliebelah, that is why \n returns just n...
11:47replaca_are we deprecating ^ ?
11:47chouserright. \n looks exactly like a newline, but isn't.
11:47chouserreplaca_: yes, use (meta ...) instead.
11:47fliebelFun ingredients for some code obfuscation :D
11:47replaca_chouser: how come?
11:48djork\n looks like a newline *in other languages*
11:48replaca_do folks want it for something else?
11:48chouserdjork: \n is newline in clojure strings.
11:48djorkyes
11:48noidigoogle ftw
11:48noidi,(apply map vector (partition 3 (range 12)))
11:48clojurebot([0 3 6 9] [1 4 7 10] [2 5 8 11])
11:48chouserreplaca_: yes, type hints. (defn add [x^Integer y^Integer] ...)
11:48rhickeyreplaca_: yes, would like ^ to replace #^
11:49rhickeymaybe what chouser said too
11:49rhickeythe latter could happen without deprecation
11:50rhickeyI mean x^String could happen just by making ^ ok inside symbols
11:50chouserwell, x^{:tag String, :foo :bar} would be nice too
11:50replaca_rhickey, chouser: I see. Priorities. Need that old APL keyboard so we don't have to make choices :-)
11:50rhickeybut #^ seems to really trip people up, brings out the perl remarks
11:51replaca_I use ^ all over the place (mostly in the autodoc stuff), but I'm not really *that* hung up on it
11:51chouserquote behavior is less surprising with trailing ^
11:51rhickeychouser: still don't need to deprecate for that
11:51fliebelwhat is #^? I can't google that characters.
11:51Chousukeread-time metadata
11:52rhickeyI think the existing metadata would be cleaned up a lot with ^ vs #^
11:52replaca_fliebel: substitute for with-meta at read-time
11:52chouserrhickey: you mean without reordering it?
11:52Chousuke,(meta #^{:foo 'bar} [])
11:52clojurebot{:foo bar}
11:52rhickeyreplaca_: No
11:52replaca_I agree ^ is a lot prettier
11:52fliebelanother macro...
11:52replaca_oops, no?
11:53rhickey#^ != with-meta
11:53chouser#^ attaches metadata to the form being read
11:54rhickey,(read-string "^x")
11:54clojurebot(clojure.core/meta x)
11:54rhickey,(read-string "#^String x")
11:54clojurebotx
11:54rhickey,(meta (read-string "#^String x"))
11:54clojurebot{:tag String}
11:54chouserwith-meta attaches metadata to an object at runtime
11:55replaca_right, that's what I meant. It's like with-meta, but at read time
11:55fliebelok, thanks
11:56replaca_but I get what you mean, it's not a straight macro expansion
11:56rhickeyreplaca_: people think that #^ and ^ are analogues
11:57replaca_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:57rhickeyso describing the behavior of #^ given that presumption is tricky
11:57replaca_that's why to do real code reformatting, we'll need a custom reader
11:58rhickeyreplaca_: you can't? even with *print-meta* ?
11:58replaca_(that treats both #^ and ; specially)
11:58replaca_yeah, you can print the meta data on something, but it wasn't necessarily applied with the form you just read
11:59replaca_(although I don't yet support *print-meta* in the pretty printer and I should)
11:59rhickeyreplaca_: do you have an example?, I'm confused
11:59maravillas,(doc read-string)
11:59clojurebot"([s]); Reads one object from the string s"
12:00replaca_rhickey: hang on a sec and I'll cons one up
12:00lisppaste8rhickey pasted "explicit elided this" at http://paste.lisp.org/display/91364
12:01rhickeyso, in thinking about implicit this, trying to tease out the 2 aspects - the elision from the arglist, and the implicit name
12:01rhickeythe latter is a no go for reify
12:01chouserbecause of nesting
12:02replaca_,(binding [*print-meta* true] (print '(def f #^{:a 7} 'bar)))
12:02clojurebotDENIED
12:02rhickeythe above paste proposes unified syntax for deftype/reify/extend-*, where this arg is always eilided, but never implicit
12:02rhickeyif you want to refer to this, must supply this-name where indicated, same name applies throughout
12:02chouseroptionally implicit?
12:03rhickeychouser: no, never implicit
12:03rhickeyalways elided
12:03replaca_rhickey: I don't know why the bot doesn't like that, but that produces "(def f (quote bar))"
12:04chouserreplaca_: it just doesn't like the word 'def'
12:05replaca_chouser: picky, picky
12:05chouser,(binding [*print-meta* true] (print '(f #^{:a 7} 'bar)))
12:05clojurebot(f (quote bar))
12:05chouser,(binding [*print-meta* true] (prn '(f #^{:a 7} 'bar)))
12:05clojurebot(f #^{:a 7} (quote bar))
12:06replaca_chouser: yes, but if 'bar had already had metadata you'd get that too
12:07rhickeyreplaca_: is the metadata even there?
12:07rhickey(-> '(fred f #^{:a 7} 'bar) (nth 2) meta)
12:07rhickey,(-> '(fred f #^{:a 7} 'bar) (nth 2) meta)
12:07clojurebot{:a 7}
12:07replaca_rhickey: no, I munged the syntax
12:07Chousukerhickey: that syntax looks pretty good.
12:08replaca_rhickey: but check this out: "(binding [*print-meta* true] (prn '(def f #^{:a 7} 'bar)))"
12:08replaca_clojurebot can't do it, but (when f is deffed in my repl), I get:
12:09replaca_#^{:line 1} (def f #^{:line 1, :a 7} (quote bar))
12:09lpetitrhickey: 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:10replaca_which is not what I typed in
12:10Chousukereplaca_: line metadata is attached to lists at read-time
12:10lpetitreplaca_: Would a rewrite of pprint be worth the trouble, as far as possible performance gains are involved ?
12:10rhickeyreplaca_: because of the line stuff?
12:11lpetitreplaca_: I meant, a rewrite using protocols
12:11replaca_Chousuke: and there are a bunch of other reasons that an object can have metadata besides that
12:11rhickeylpetit: leading dot for protocol method defs too?
12:11lpetitrhickey: yes, "a cat is a cat", sort of
12:12chousera shame the this-name has to be in a vector, but it's good that its consistent.
12:12lpetitrhickey: and implicit this comes with methods (OO hat), explicit "this" comes with functions (functional hat)
12:12rhickeylpetit: ick, dot is so host-y, I;d hate to have it be part of describing pure protocols + deftype
12:12replaca_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:12chouser,(binding [*print-meta* true] (prn (read-string "(def f #^{:a 7} 'bar)")))
12:12clojurebot(def f #^{:a 7} (quote bar))
12:12replaca_you cant really use the *print-meta* mechanism
12:12magnet(OT: "appeler un chat un chat" translates to "to call a spade a spade")
12:13chouserreplaca_: the metadata really is on those objects. to not print it would be a lie.
12:13chouserreplaca_: 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:14replaca_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:14chouserno, that's how it *is* read. that metadata is there as soon as the thing is read
12:14replaca_chouser: I think there's potentially more stuff than just line numbers
12:14chouserit may not be what you typed, but it's what was read.
12:15lpetitrhickey: 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:15chousersimilar to how ; comments work. you typed it, but the reader doesn't produce anything for it
12:15replaca_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:16chouserhm, maybe you're wanting to print source code with type hints but not other metadata?
12:16rhickeylpetit: 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:17replaca_chouser: If I'm trying to reformat source code, I want to be able to reconstruct only those things the user entered
12:17rhickeyreplaca_: I think the only system-added metadata from read is :line
12:17lpetitrhickey: 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:17chouserhuh. maybe should be :clojure.core/line
12:18replaca_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:18replaca_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:19rhickeyreplaca_: but why wouldn't you print it if *print-meta* was true? Either it's what they read or they mucked with it
12:19hiredmanI imagine the prettyprinter is a whole 'nother kettle of fish
12:19chouserrhickey: with the "explicit elided this", recur always matches the arg count of the literal arg vector?
12:19rhickeychouser: no
12:19replaca_rhickey: right, *print-meta* was your suggestion :)
12:19replaca_rhickey: I was just talking about using the pretty printer to do code reformatting
12:20replaca_lpetit: I haven't yet thought much about using protocols in the pretty printer
12:21rhickeylpetit: I don't understand your last comment
12:21rhickeychouser: I think recur behavior, while telling, is low priority
12:21chouserok
12:21replaca_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:21lpetitrhickey: I agreed that from the calling side, not calling via .method seemed ok to me
12:22lpetitreplaca_: :-(
12:22rhickeylpetit: it's necessary, since some implementations of protocols will not be methods at all, i.e. protocols are not interfaces
12:23rhickeyjekyll and hyde
12:24rhickeychouser: something about (extend-class String [s] ...) where s is implicit first arg seems neat
12:24rhickeyand in the frequent case where you don't use this, you just leave it out
12:28rhickeylpetit: my first cut with deftpe/reify implementing protocols had .method and implicit this - .method bothered me the most, a mismatch with protocols
12:30lpetitrhickey: 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:31rhickeylpetit: ok, thanks
12:32rhickeyseems like splitting off implicit from eliding isn't helping anyone
12:39lisppaste8rhickey annotated #91364 "vs explicit supplied" at http://paste.lisp.org/display/91364#1
12:41lisppaste8rhickey annotated #91364 "most extends will supply this" at http://paste.lisp.org/display/91364#2
13:00chouserrhickey: I don't think I understand your first example there yet
13:01chouseris [this-name] there, or not? if supplied, you don't include it in each method?
13:06Chousukeif it can be omitted, it just reduces to the confusing case in most siutations
13:06Chousukesituations*
13:14sraderrhickey: I think I found a bug in deftype
13:14rhickeychouser: [this-name] is only needed if you want to refer to this in any method body, never impacts arglists
13:14rhickeysrader: what is it?
13:14srader(deftype Foo [a b c]) (def foo (Foo 1 2 3)) (:a foo)
13:15chouserrhickey: ah, that's what you mean by not-implicit. If not specified, there's no way to refer to it?
13:15sradereval that twice and I get #<Foo$__lookup__a user.Foo$__lookup__a@128594c>
13:15sraderinstead of 1
13:16rhickeychouser: right
13:16rhickeysrader: ok, will check that out
13:16sraderrhickey: thx
13:25rhickeysrader: fixed -thanks for the report
13:30esjis there a function of a map that returns a struct-map of that map ?
13:32esji could map over the map assoc'ing into the struct-map, but that seems a bit roundabout ?
13:33rhickeyesj: why do you want the struct-map?
13:33esjto share the keys between all the struct-maps efficiently.
13:34rhickeyesj: so the map is a prototype for many more?
13:34esjexactly.
13:35esji will get many instances of the map over time, and I want to store them.
13:37carkesj: there is create-struct as a starting point for your function
13:37rhickey,(let [m {:a 1 :b 2 :c 3} s (apply create-struct (keys m))] (apply struct s (vals m)))
13:37clojurebot{:a 1, :b 2, :c 3}
13:38esjgreat stuff, thanks.
13:39esji'd come up with this: (reduce (fn [c [a b]] (assoc c a b)) (struct-map struct-reading) reading) is it obviously worse ?
13:39esjwhere 'reading' is the map in question
15:00rongenre,clojurebot (< Double/MIN_VALUE 0)
15:00clojurebotjava.lang.Exception: Unable to resolve symbol: clojurebot in this context
15:00rongenre,(< Double/MIN_VALUE 0)
15:00clojurebotfalse
15:00rongenreYeah, that's not right
15:01Chousukehmmh
15:01rongenreI'm assuming it's kind of a silent overflow
15:01Hun,Double/MIN_VALUE
15:01clojurebot4.9E-324
15:01Hunin my book that's still > 0
15:02Hunthat would be least-positive-double-float
15:02rongenreyup.
15:02Hunoh, nevermind. read your line wrong :)
15:03rongenreOh good. MIN_VALUE for double means.. smallest positive
15:03rongenregreat
15:05liebke_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:07kotarakIs it possible to define a print-method for things implementing a Protocol?
15:10stuartsierra,(Double/MIN_VALUE)
15:10clojurebot4.9E-324
15:10stuartsierra,(Double/MAX_VALUE)
15:10clojurebot1.7976931348623157E308
15:10rhickeykotarak: hopefully printing will be based upon protocols at some point
15:11kotarakrhickey: 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:12kotarakSince I use reify, I cannot define a custom print-method. But with deftype, it should be possible in the AOT case, no?
15:13rhickeya protocol isn't a type, so type based dispatch won't cover all participants in a protocol
15:13rhickeybut deftype will give you a deterministic result from (type x), AOT or not
15:14kotarakargh. Right. So I should probably go with deftype and the protocol.
15:14rhickeyso current printing can be extended with deftype, not protocols
15:15technomancyliebke: _ato is on australian time; probably asleep right now.
15:16kotarakHmm.. How is printing a IMapEntry handled anyway? I extend IMapEntry so shouldn't it print like a "normal" IMapEntry?
15:16Chousukerhickey: 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:16Chousukeneatly* :P
15:16liebketechnomancy: you never know when a hacker is awake :)
15:17alexykhow do you guys parse the command-line options?
15:17technomancytrue =)
15:18alexyk?
15:18kotarakalexyk: there is c.c.command-line
15:19alexykok... and what's the way to declare the "main"?""
15:20The-Kennzalexyk: (defn -main [] ...)?
15:20kotarakalexyk: http://clojure.org/Compilation
15:20The-Kennzalexyk: http://clojure.org/compilation
15:20The-Kennzheh.. kotarak was faster
15:20alexykthanks! the URL are case-insensitive, I guess
15:21alexykis defn- main same as defn -main?
15:21Chousukeno
15:21kotarakdefn- is a private defn
15:21alexykwhat's -main then?
15:21Chousukealexyk: the - in -main is a naming convention used when defining java methods.
15:22Chousukeyou need gen-class in order to have a "main" in Clojure.
15:23kotarakalexyk: you can add any prefix you like: (gen-class ... :prefix MyCoolPrefix-) (defn MyCoolPrefix-main ...) Nice when defining multiple classes in one namespace.
15:23chouserin order to have a Java main that is
15:23alexykChousuke: 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:24alexykI'm usually running things after maven makes a jar out of them, since mvn ...run doesn't distinguish stderr and stdout
15:27kotarakwith deftype I can still override Object methods, like toString, right?
15:33jasappis there something similar to common lisp's :print-function for clojure structures?
15:36michaeljaakahi
15:37michaeljaakais there any easier way to do that? http://gist.github.com/246622 note that filter-neg is an func defined by user
15:37kotarakrhickey: hmm.. extenders do not contain eg. (deftype Foo [] [Protocol] ..), is this correct?
15:42Chousukemichaeljaaka: (filter identity (map f seq))?
15:42Chousukehm, I guess not.
15:43michaeljaakahmm output the same
15:43michaeljaakais it lazy?
15:44Chousukeyes
15:44Chousukeit maps f over a seq and removes anything nontrue
15:44Chousukeie. nils and falses
15:44chouserkotarak: yes
15:44michaeljaakaChousuke: so it is the same
15:45michaeljaakai exactly wanted to get that effect
15:45Chousukemichaeljaaka: right. I just misread your function a bit :
15:45kotarakchouser: hmm.. And what is the reason, why Foo should not be in extenders? Is it to retrieve "after-design-time" extensions?
15:46Chousukemichaeljaaka: there are remarkably few things you can't do with the standard seq functions. :P
15:46chouserkotarak: sorry, was answering your first question: deftype can overrice toString
15:46kotarakchouser: ah. Ok. Found that out already. :)
15:46michaeljaakaChousuke: so FP is just for me ;)
15:47Chousukeevery 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:47michaeljaakaChousuke: well identity was the key
15:48chouserkotarak: I don't think I understand your second question.
15:49rhickeykotarak: me either
15:50kotarakchouser: 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:50kotarakuser=> (extenders ILazyMapEntry)
15:50kotarak(clojure.lang.IMapEntry clojure.lang.IPersistentVector)
15:52rhickeykotarak: extenders returns only the classes/type for which extend* was called
15:52rhickeyas you discovered, satisfies? is the test
15:53kotarakrhickey: ookk? Is there a special reason? I mean I could do (deftype Foo [] [Protocol] ....) and then (extend ::Foo Protocol some-mixin-map)
15:54rhickeykotarak: 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:54rhickeysince it is an open set
15:54rhickeyall derivees of an interface that extends a protocol for instance
15:55rhickeythey won;t all register
15:55kotarakhmm... then I don't get the use of extends?.
15:55rhickeyalso, 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:55kotarakah. ok.
15:56rhickeythere are many ways to participate in a protocol, explicit extends is just one
15:56rhickeyextenders/extends? is just about explicit extenders
15:56kotarakrhickey: then (deftype .... (foo [] ..)) is not the same as (deftype ...) (extend ... {:foo ...})?
15:57rhickeykotarak: not at all
15:57kotarakok
15:57rhickeyin the former case the type participates in the protocol by implementing its interface
15:58rhickeyand the implementations are methods of the class
15:58rhickeyin the latter case it is an explicit registration of a map of ordinary fns
15:58chouserbut users of the deftype don't need to know which, as long as it 'satisfies?'?
15:59kotarakso the former is faster, I guess..... No mixins for deftype, then?
15:59kotarakNo, of course not. deftype method are not closures.
15:59rhickeykotarak: I've been thinking about that, might be possible - method calls fn
16:00rhickeyjust working on that today
16:00rhickeykind of a mismatch with the macro aspect of deftype
16:02rhickeythere will be a way to ask a protocol for the implementation of a fn for a specific extender
16:02rhickeyright now:
16:02rhickeyuser=> (-> P :impls ::Bar :foo)
16:02rhickey#<user$eval__135$fn__140 user$eval__135$fn__140@68302e67>
16:02rhickeyget impl of foo for type Bar
16:03rhickeythat can't be supported by non-extenders
16:03chouserbecause a deftype method is a java method, and therefore not a thing of its own.
16:03rhickeyright
16:04michaeljaakaChousuke: I often use (defn map-apply[f col] (map #(apply f %) col)) is there any fun to give the same effect?
16:04rhickeyand not registered, part of the open set of implementors of the protocol interface
16:05chousermichaeljaaka: your col is nested seqs? [[1 2 3] [4 5 6] [7 8 9]] ?
16:05michaeljaakayes
16:06chouser,(apply map list [[1 2 3][4 5 6][7 8 9]])
16:06clojurebot((1 4 7) (2 5 8) (3 6 9))
16:06chouserhm, that's the wrong axis
16:07chousermichaeljaaka: I can't think of any better way to do that.
16:07michaeljaakaok
16:07michaeljaakathx
16:11chouserrhickey: deftype doesn't adjust the protocol object or functions at all does it.
16:12chousereach protocol fn starts with a case for handling objects that implement the protocols matching interface, and thats how a deftype hooks in?
16:12rhickeychouser: nope
16:12rhickeyoops, 2 questions
16:12chouseryep, sorry.
16:13rhickeyright, deftype implementing a protocol doesn't alter it
16:13rhickeythere are a few layers to the implementation
16:13rhickeyeach 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:14chouserok
16:14rhickeythat will be the case whenever a protocol fn is used as a first-class object
16:14rhickeybut callsites now know about protocols
16:14chouserah
16:14chouserwhoa
16:15rhickeywhenyou 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:15chousercallsites see that the symbol being called is a protocol fn and not some other local or var, in order to do special things?
16:15chouserwhoa
16:15chouserok
16:15rhickeyyep
16:16rhickeyand hotspot will inline those calls
16:16rhickeyjust like you said .foo
16:16chouserbut with so much more flexibility
16:16rhickeyright, so much more
16:16chouserand no type hints
16:17rhickeyand ease of use, vs (defn bar [#^IProtocol x] (foo x))
16:17rhickeyheh
16:17kotarakrhickey: to take karmazilla's words "dude, you are made of awesome :)"
16:17chouserhaha
16:18rhickeyplus 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:18rhickeyso no lookup as long as same target type
16:19rhickeyso calls to extenders (like if you extended String) are also very fast at sites where the target is homogenous
16:19chouserprobably about as fast as a direct fn call
16:19rhickeyright
16:20chouserhm. to a local fn, not through a var
16:20rhickeyno, through a var since it needs to see dynamic updates
16:20chouseroh, ok.
16:21rhickeybut 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:21rhickeyit is definitely faster than waiting to see what's in the var and using that
16:21rhickeyso, say, in between direct and through var
16:21chouserhuh. cool.
16:22chouseryou're referring to the CPU instruction pipeline here?
16:22rhickeyright
16:22rhickeythe 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:23chouserkotarak: it's entirely possible that quote is backwards, and that awesome is made of rhickey.
16:23rhickeyvs, you know nothing, have to wait for the var result to proceed
16:23chouserrhickey: yep, I think I've got it.
16:23kotarakHAHA!
16:24rhickeythe coolest thing is that non of this speed requires AOT
16:24rhickeynene
16:24rhickeynone
16:25leafw_rhickey: drunk with happiness
16:25kotarakawesomeness ;)
16:26technomancychouser: time for a clojure-specific spin-off of http://www.schneierfacts.com/ it sounds like
16:26chouserI 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:26rhickeyso, 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:26lisppaste8Chouser pasted "warts" at http://paste.lisp.org/display/91391
16:27leafw_chouser: triple quotes would be great, python-like. I find myself with problems on the docs of fn with lits of \"
16:27leafw_s/lits/lots
16:28leafw_and use/require is being worked on, IIRC
16:28chouserleafw_: I don't know if I'd advocate triple quotes, but having no way at all to avoid \" is a pain
16:28Chousukethat error messages are frequently completely useless is the biggest wart I can think of.
16:29Chousukebut hopefully that will change as things develop
16:29chouserChousuke: but that's the implementation, not the language itself.
16:29ChousukeI guess so.
16:29leafw_Chousuke: I find error messages ok, one I filter out all the non-clj lines.
16:30leafw_except, perhaps, for macros.
16:30leafw_s/one/once
16:30chouserChousuke: I mean, that issue doesn't mess make my source files look worse than if it were fixed.
16:30chousers/mess//
16:33StartsWithK(macroexpand (.toString Integer 1)) expands to (. (clojure.core/identity Integer) toString 1) in 1.1a, shoudn't that be just (. Integer toString 1)?
16:33rhickeychouser: the newline stuff is very funny
16:35chouser,(macroexpand-1 '(Integer/toString 1))
16:35clojurebot(. Integer toString 1)
16:35chouserStartsWithK: so, no.
16:35StartsWithK,(macroexpan '(.toString Integer 1))
16:35clojurebotjava.lang.Exception: Unable to resolve symbol: macroexpan in this context
16:35StartsWithK,(macroexpand '(.toString Integer 1))
16:35clojurebot(. (clojure.core/identity Integer) toString 1)
16:35chouserrhickey: what's funny, clojure or what I said?
16:36chouserStartsWithK: If you want a static method of Integer, use Integer/toString. If you want an instance method, use (.method object args)
16:37StartsWithKchouser: i know that, i was just wondering why in that form there is a extra identity call
16:37chouserStartsWithK: saying (.toString Integer 1) is trying to call an instance method named "toString" on an instance of Class
16:38chouseronce upon a time, we had FAQ #1, and we called identity ourselves.
16:38StartsWithKoh i see, that is not a valid call
16:38rhickeychouser: both
16:39chouserrhickey: is most of that inherited from CL or something?
16:39rhickeynot really, but if you think about the alternatives... you'd need to reserve \ for excaping and use something else for chars?
16:41chouserI guess '\n' is out. ;-)
16:41chouserJava has no syntax for Character literals?
16:41rhickeyright, single quote is taken. CL used #\ for chars, doesn't really change things
16:42chouseroh, Java uses '\n' like C. hmph.
16:42chouserusing 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:43chouserspace be just \ which is annoying
16:43chouser...though that works today, just prints as \space
16:43rhickeywhat would be 'n' ?
16:44chouserI spent more time thinking up the problem than any solutions.
16:44rhickeyyou have to eat another special char, or #combo
16:45chouser#\newline = \n = (first "\n") ?
16:48lpetit\ca \cb ... for direct ASCII/UTF8 encoding, \uFFFF for unicode code, \xFF for US-ASCII codes ?
16:49lpetitAnd then \n is not reserved anymore, nor \t ... and all the usual conventions inherited from C
16:49rhickeychouser: what is 'n' ?
16:50chouserMaybe #\n
16:50lpetitbut I don't like it very much, having to add c .. How many times do you use lots of literal characters, though ?
16:50lpetitThe problem remains that you have \n inside strings, and .... something else for chars
16:50chouserright, "\n" is not to be messed with
16:51chouserso to make things any more consistent, \n would have to mean (first "\n")
16:51chouserwhich, as rhickey keeps pointing out, leaves the question of (first "n")
16:52notallamawhat about \\n = (first "\n") ?
16:53lpetit(first "n") could be \cn
16:53chousersince "\156" = "n", \156 should definitly be (first "n"), but that hardly seems sufficient.
16:53lpetit(first "a") could be \ca
16:53lpetithttp://www.regular-expressions.info/characters.html
16:53notallamanevermind. \\n woiuld make it rather hard to do a literal \
16:53chousernotallama: \\\ :-)
16:54notallamachouser: i'm getting bad memories of java regex
16:55notallamajava regex literal \ is "\\\\"
16:55chouserI think I like #\n over \cn
16:56chousernotallama: yep. We fixed that in Clojure a while ago. :-)
16:56technomancynotallama: you should see Emacs regexes
16:56technomancyterrifying
16:56notallamayes, i'm aware, and i greatly appreciate it
16:58lpetitchouser: but then, if #\n stands for (first "n"), what would be (first "\n") N
16:58lpetit?
16:58chouser\n
16:58rhickeyouch
16:58notallamai'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:59lpetitless consistent than \cn \n
16:59rhickeylpetit: putting c before things trashes scanability IMO
16:59lpetit(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:59lpetitrhickey: scanability ?
17:00chouserit's a problem for all string escapes, which include \n, \t, \r, etc.
17:00rhickeyanytime you put dummy (but alpha) characters before important characters you make you brain do extra work to remove them
17:01rhickeyi.e. how easy is it to tell if they are in alphabetical order?
17:01lpetitWe're talking about character literals. How often are they "heavily" used in practice ?
17:02rhickeylpetit: not often, I don't consider the problems chouser has raised as problems at all, for me personally
17:03lpetitrhickey: maybe not, but interestingly I had the exact same bug recently. Wrote \n where I should have written \newline :)
17:03chouserah, yes. \a \b \r \f \n \t and \v, plus the fancier ones for hex or octal
17:04liebkeit doesn't seem like a problem... once you consider the alternative solutions :)
17:04lpetitliebke: so sometimes it helps consider alternatives :
17:04lpetit:)
17:04liebkeindeed :)
17:05chouser,\o156
17:05clojurebot\n
17:05chouser,\o12
17:05clojurebot\newline
17:05chouser"\o12"
17:05chouser,"\o12"
17:05clojurebotUnsupported escape character: \o
17:06chouserthis doesn't just seem broken to you?
17:06lpetit,"\o12"
17:06clojurebotUnsupported escape character: \o
17:06chouser,(str \o12)
17:06clojurebot"\n"
17:07lpetit,"\u12"
17:07clojurebotInvalid character length: 2, should be: 4
17:07lpetit,"\u0012"
17:07clojurebot""
17:07lpetit,"\u0032"
17:07clojurebot"2"
17:07chouser,\u0012
17:07clojurebot\
17:07notallamadoes java do octals in strings?
17:07chouser,\u0032
17:07clojurebot\2
17:07chousernotallama: yes
17:08lpetitok I don't have the ascii table wired in my head :)
17:08chousernotallama: no
17:09chousernotallama: yes. sorry. :-)
17:09chousernotallama: \ followed by digits is octal, even without a leading 0
17:11chouserso again in Clojure we have \12 and "\o12" are invalid, but \o12 and "\12" are valid and mean almost the same
17:12chouserClojure string literals are very similar to Java string literals. Maybe identical. Clojure character literals feel like they're from an entirely unrelated language.
17:15lpetit,"\c"
17:15clojurebotUnsupported escape character: \c
17:15notallama\\n makes the most sense to me. java version would be '\n'. so basically, \x would be the same as 'x'
17:17lpetitOr 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:17lpetit\_a , \_b , ...?
17:17hiredmanI would be ignored if clojure's handling of character literals changed in a backwards incompatible manner
17:17hiredmanfor the record
17:17hiredmaner
17:17lpetitmaybe too close to _
17:17hiredmans/ignored/annoyed/
17:18chouserhiredman: you prefer how it is now?
17:18lpetit\'a, \'b ?
17:18lpetit\'a' \'b' ?
17:19Chousukenoisy
17:19chouserlpetit: and for newline, \'\n or \'\n' ?
17:19lpetitfor newline \n
17:19hiredmanchouser: I like to be able to revisit old code without have to spend a lot of time to make it work
17:19hiredmanand I don't mind it as it is now
17:20lpetit\'<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:21chouserlpetit: I like that. Even better without the trailing '
17:21lpetitor just 'a' for chars, like in java ?
17:21lpetitisn't it possible, even if ' is for quoting ?
17:21chouserwe already see ' as a prefix thing in Clojure code, so \'n isn't too bad for the unusual bare letter case
17:21hiredmanchouser: none of the proposals seen here are nice enough to entice me to want to break working code
17:22lpetit\newline could be kept as a deprecated (or more readable) non-shortcut for \n
17:22chouser,(str 'n' "hello")
17:22clojurebot"nhello"
17:23hiredmanchouser: cute
17:23lpetitbut yes, \n , \t, \b would break
17:23hiredmanI don't see how \'n is in anyway an improvement
17:24chouserit's just to free up \n to mean the same as (first "\n")
17:24lpetitand also \b, \t, and make them behave the same as in "\n" "\b", etc.
17:24chouserright
17:25rhickeywhat's ''' ?
17:25rhickey'\''
17:25lpetit?
17:25chouser\''
17:25rhickey\'\''
17:26lpetit \''
17:26lpetit\'"
17:26LauJensenMan this is great, just like the J forum :)
17:26lpetitand \'\ for (first "\\")
17:26lpetit\'a' could be accepted as a convenience, also :
17:26lpetit:)
17:27lpetit:-(
17:27lpetitsorry
17:28lpetit,\"
17:28clojurebot\"
17:28chouser\" and \'" would both be accepted and mean the same
17:29lpetityes
17:29chouserif we used something new instead of \ then old code could remain compatible
17:29lpetitbut isn't this a particularity of a particular host platform (the JDK)
17:30lpetitor a particularity of the dominant language of the host platform ?
17:30chouser#\n for newline, #\'n for n
17:30hiredman:|
17:30chouseror #'n for n
17:31hiredmanuh
17:31hiredman,#'n
17:31clojurebotjava.lang.Exception: Unable to resolve var: n in this context
17:31chouseroh
17:31hiredman
17:31chousermaybe not. :-)
17:31lpetitchouser: rather staying with the current implementation, or breaking existing code, than adding patches and not removing old behaviour
17:32chouserold behaviour could be deprecated but left in place until hiredman comes around in his thinking.
17:32hiredmanlpetit: so reader macros by patch?
17:32lpetitI 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:33lpetithiredman: didn't understand
17:33hiredmanyou could, just, you know, leave the character handling as is
17:33hiredmanlpetit: one argument against reader macros is it essential shatters the language into sublanguages with different syntaxs
17:33chousersure. could also leave any number of other broken things broken.
17:33lpetitYes, I guess better leave it as is, than adding another way to do it, and leaving the old way.
17:34hiredmanchouser: is it really broken?
17:34lpetitOr, have the courage to break broken things, but this example may not be worth it.
17:34chouser,\o12
17:34clojurebot\newline
17:34chouser,"\o12"
17:34clojurebotUnsupported escape character: \o
17:34chouserbroken.
17:34lpetit,"\12"
17:34clojurebot"\n"
17:35chouser,(= \n (first "\n"))
17:35clojurebotfalse
17:36lpetithiredman: 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:36notallamamaybe \\ 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:36twbrayWhat's the syntax for an arbitrary Unicode character, e.g. U+4F5B ?
17:36notallamaso \\\n = (first "\n")
17:37lpetitin strings "\u4F5B"
17:37lpetit,"\u4F5B"
17:37clojurebot"佛"
17:37chouseralso in literals. yay!
17:37chouser,\u4F5B
17:37twbraylpetit: Thanks
17:37clojurebot\佛
17:37chousernot broken!
17:37lpetitnot broken :)
17:37lpetittoo late for me :)
17:37chouser:-)
17:37twbraychouser: so if you have unicode, screw the rest, make 'em all use that :)
17:37chouserthere ya go
17:37lpetitok, so from now on, everybody is writing literals in unicode esac
17:38lpetitshit you beat me again :) :)
17:38chouser,"this\u000Ais\u000Anice!"
17:38clojurebot"this\nis\nnice!"
17:39hiredmanchouser: \o is not a valid escape, so the reader throws an exception, how is that broken?
17:39lpetit,(printf "this\u000Ais\u000Anice!")
17:39clojurebotthis is nice!
17:39chouserhiredman: \o is valid esacpe outside "" but not inside
17:39hiredmanno
17:39chouserhiredman: \u is valid in both
17:39hiredmanoutisde of "" it is not an escape
17:39chouser,\o12
17:39clojurebot\newline
17:40chouser\12 is valid inside "" but not outside
17:40twbray,"foo\uabar"
17:40clojurebotInvalid digit: r
17:40chouser\n is valid in both, but means different things.
17:40lpetitis \u valid in non-java strings (e.g. C#, ...) ?
17:40twbray"foo\u000abar"
17:41twbray,"foo\u000abar"
17:41clojurebot"foo\nbar"
17:41chouserlpetit: 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:41twbray,"foo\00000abar"
17:41clojurebot"foo
17:42lpetitchouser: are you sure ?
17:43twbrayOK, I think there's a bug there. Unicode characters go up to U+10FFFF
17:43twbrayoops typo
17:43twbray,"foo\u00000abar"
17:43clojurebot"foo
17:43chouserlpetit: pretty sure. LispReader.java has Clojure's rules for reading string and char literals.
17:43twbray,"foo\u10346bar"
17:43clojurebot"fooဴ6bar"
17:44lpetitchouser: good, so the change would be meaningful for every clojure port
17:44twbrayOh crap those \u thingies are recognizing UTF-16 codepoints not unicode characters. Per Java's big mistake
17:44chouserover my head.
17:45twbrayOK... U+10346 is GOTHIC LETTER FAIHU
17:45twbrayyou probably don't have a font for it.
17:46chouserdoes that take two UTF-16 words to describe or something?
17:46twbraySo you'd have to encode this is "foo\ud800\udf46bar"
17:46chouserah, ok.
17:46twbray,"foo\ud800\udf46bar"
17:46clojurebot"foo𐍆bar"
17:46rlbchouser: http://java.sun.com/developer/technicalArticles/Intl/Supplementary/ (I think)
17:46rlbJava can't fit all unicode characters into a char.
17:47twbrayThey're called "surrogates". You don't want to know if you don't have to.
17:47rlb(just codepoints)
17:47rlbSome unicode characters in utf-16 won't fit in 16-bits.
17:47twbrayYou could make a case that Clojure should Do The Right Thing and recognize \u10346
17:47rlb(but java pretended they would -- or just didn't care)
17:48rlb(or the standard changed -- don't know offhand)
17:48twbrayrib: 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:48hiredmanyou would then need a seperate \u for char literals
17:48Chousuketwbray: the reader works with java's Characters :/
17:48twbrayhiredman: Maybe \U
17:48rhickey\ae, \bee, \cee, \dee , \ee , \ef , \gee, \newline, \tab ... \zee
17:48hiredmanthe reader works with ints
17:48rlbtwbray: oh, ok, I thought it might also have been historical.
17:49hiredmanbecause .read returns an int
17:49rhickeyphonetic character literals!
17:49Chousukehiredman: well they're cast to chars :P
17:49Chousukebasically.
17:50hiredmansure
17:50twbrayThere 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:50Chousukewell, UTF-8 is just an encoding for unicode.
17:51twbrayChousuke: Agreed. But one that has many advantages over what Java happened to pick.
17:51hiredmanbut 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:51chouserrhickey: perfect!
17:51rhickeyobviously I have nothing constructive to add :)
17:51lpetit\one \two ...:)
17:52Chousuketwbray: 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:52rlbChousuke: processing utf-16 is basically as hard if you do it right (i.e. neither is a fixed encoding.)
17:53rlbs/fixed/fixed-width/
17:53twbrayI wrote a nice UTF-8 based java.lang.String replacement which uses UTF-8 internally. But it's too late.
17:53lpetitBut was it UTF16 or raw UCS16, really ? :-)
17:53twbrayrib: +1
17:53hiredmanbitbckt: :(
17:53twbrayhttp://www.tbray.org/ongoing/When/200x/2003/04/26/UTF if anyone cares
17:54rlbIt's just that the characters with more than one utf-16 code point are not as common.
17:54bitbckthiredman: You'll get used to it. :-)
17:54hiredmanhangul has too many variations of the o and yo sound that all sound the same to me
17:54hiredmanbitbckt: I refuse
17:54rlb(at least in many arenas)
17:54bitbckthiredman: Noted. Off with your head, then.
17:55Chousukeis hangul capable of expressing all the sounds in the English language?
17:55Chousukethe latin alphabet certainly isn't. :P
17:55hiredmanbadly
17:55hiredmanhangul has no f
17:55hiredmankoreans shout "powl" at basketball games
17:56bitbcktAnd we all *laugh*
17:56hiredmanpheonix becomes peenix
17:57hiredmanit is very noticable because of the amount of english that gets phonetically written in hangul
17:57ChousukeI wonder if that makes it worse than katakana
17:58bitbcktThe generations of people taught English from books, without actually ever *hearing* a native English speaker are also a source of great amusement.
17:58hiredmanyes
17:58ChousukeI had to listen to a person keep a presentation in English class today. She had horrible pronunciation.
17:59ChousukePronunciation is clearly not given enough attention in schools.
18:00bitbcktSee? The Roman alphabet isn't phonetic. Fail. ;-)
18:00ChousukeYou 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:00ChousukeWell, the problem is that the Finnish alphabet is almost phonetic.
18:00hiredmanaccents are nice
18:00ChousukeSo many Finns just learn to pronounce English like it was finnish
18:00Chousukewhich is *completely* and *utterly* hideous
18:01hiredmanI 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:02ChousukeI remember seeing pictures of a teacher's book in Japanese that just had all the english parts transliterated as katakana
18:02Chousukeso the teacher had no need to actually know how to read English
18:02hiredmanmy 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:02twbrayhiredman: we have the same problem in English-speaking countries. Kids study French or whatever for years and can't speak at all.
18:02hiredmantwbray: I suppose
18:02hiredmanbut it seems much less common
18:03ChousukeI at least had an English teacher in high school with a proper British accent :)
18:03hiredmanall the kids I know who studied japanese speak it
18:03bitbcktChousuke: I suppose that's an "improvement."
18:03lpetitSo that means everybody agrees on the switch to \'a :-)
18:04Chousukeat least you could hear the proper intonation in her speech
18:04hiredmannope
18:04Chousukethe pronunciation guides in books don't really teach that :/
18:04Chousukeand since Finnish has next to no intonation, that leads to most people speaking quite monotonously, even if their pronunciation is otherwise good.
18:05hiredmanmy dad was once accosted by another english teacher, and accused, in a thick cockney accent, of teaching koreas a horrible american accent
18:06Chousukelpetit: I think that looks hideous, but... :P
18:06bitbckthiredman: I'm sure that was an amusing conversation.
18:06lpetitwas a joke
18:07stand1General question: Does anyone know of an effort underway to get decent date/time functions into clojure. My searches don't turn up anything.
18:07bitbcktstand1: Use joda?
18:07lpetit~jodatimes
18:07clojurebotI don't understand.
18:08lpetit~google jodatimes
18:08clojurebotFirst, out of 6580 results is:
18:08clojurebotJoda Time - Java date and time API - Home
18:08clojurebothttp://joda-time.sourceforge.net/
18:08stand1Is that java or clojure?
18:08the-kennystand1: Java
18:08the-kennyBut you can always write a simple wrapper :)
18:08hiredman(what's the difference)
18:08lpetit~google jodatimes clojure wrapper
18:08clojurebotFirst, out of 82 results is:
18:08clojurebotgcv&#39;s cupboard at master - GitHub
18:08clojurebothttp://github.com/gcv/cupboard
18:09stand1I'm actually interested in doing a wrapper.
18:09lpetitok sorry
18:10lpetitrhickey: from the protocols wiki page = what does it mean to "implement a protocol on an interface" ? How does it look in practice ?
18:11stand1how 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:11hiredmanwhy wrap?
18:12stand1mainly to avoid lots of heavy lifting.
18:12hiredmanis there a lot of heavy lifting you need to do?
18:12stand1date arithmatic, formatting, etc.
18:12stand1time zones
18:12hiredmanI am unfamiliar with joda time, but it should do all that
18:13bitbcktIt slices! It dices!
18:13bitbcktCall now and we'll *double* your order!
18:13stand1it make julian calendars!
18:14bitbcktand caesar salad!
18:14bitbcktIt's quite complete. I'm not sure there's much anyone needs from a time library that isn't in Joda.
18:14bitbcktOther than salad.
18:16hiredmandrives me crazy when "quick start" java guides don't mention what package any of the classes are in
18:16stand1botbckt: Don't disagree, but I'm thinking of more clojure and less java. i.e. wrappingn
18:16hiredmansorry!
18:16bitbcktbotbckt is my bot. :-)
18:17bitbcktstand1: So, using Joda directly via Clojure's Java integration is not what you want..?
18:18stand1well, for example a now function that returns a date structure {:month :day :year etc}
18:18stand1A (format-date format-string date) function. things like that
18:18hiredman,(bean (Date.))
18:18clojurebot{:seconds 18, :date 1, :class java.util.Date, :minutes 20, :hours 15, :year 109, :timezoneOffset 480, :month 11, :day 2, :time 1259709618423}
18:19bitbcktI think the consensus opinion has been the Joda doesn't really need anything like that.
18:19stand1hiredman: that's close
18:19bitbcktthat*
18:20alexykis clojure all lazy, as in lazy evaluation like in Haskell, or are just seq's lazy?
18:20hiredmanjust lazy-seqs
18:21alexykah.
18:21hiredmanjava interop would be *extremely difficult and painful* if it was lazy evaluation
18:29stand1Wow! 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:41hiredmanalexyk: for and doseq are the most "foreach" like constructs
18:41hiredmanfor is actually a lazy list comprehension
18:41hiredman(not a loop)
18:41alexykok!
18:41hiredmandoseq is very foreachie
18:42hiredman,(doseq [i (range 3)] (print i))
18:42clojurebot012
18:53djorkoh neat, I didn't know I could do a \uXXXX literal
18:54djorkand I was doing "\u000d" when apparently \return exists
18:56djorkis there some list of these somewhere?
18:56Chousukehmm
18:57djork,(map char (range 1 33))
18:57clojurebot(\ \ \ \ \ \ \backspace \tab \newline \ \formfeed \return \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \space)
18:57djorklooks like all the basics
18:57djorkgood enough for most console work
18:57hiredmanhttp://github.com/hiredman/clojure/blob/readerII/src/clj/clojure/reader.clj#L516
18:58djorkwoo! hiredman with the scoop!
18:58djorkbut that's CIC, not in use yet, right?
18:58hiredmandunno if my reader ever will be
18:59djorkimpressive nonetheless
19:00hiredmananyway, 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:03ChousukeI have a reader too. haven't worked on it for a while though
19:03Chousukeno time :(
19:03hiredmanme neither (lazy :)
19:16rhickeylpetit: (extend-class AnInterface AProtocol (foo [x ]...))
19:16lpetitrhickey: yes, I've understood it in the mean time
19:19lpetitrhickey: here are my current thoughts concerning "this", problems with recur consistency, etc. : http://paste.lisp.org/display/91400
19:20lpetitrhickey: I also have a couple of questions that may be interesting to be answered in the wiki ?
19:20lpetitrhickey : a) In deftype, does the redefinition of hasCode/equal work as an atomic thing (redefine neither or both), or not ?
19:21lpetitrhickey : b) In deftype, why doesn't IPersistentMap interface have default implementation such as IObj and ILookup ?
19:22lpetitrhickey: c) What is the reason for using keywordized versions of type name and protocol methods name over symbols in extend ?
19:22twbrayEleven theses on Clojure: http://www.tbray.org/ongoing/When/200x/2009/12/01/Clojure-Theses
19:23djork"1. It’s the Best Lisp Ever · I don’t see how his can be a controversial statement."
19:23djorkwell duh
19:23djork(typo, BTW)
19:23rhickeylpetit: if you define hashCode or equals, both u pto you, no enforcement you define both
19:24twbraydjork: Thanks, fixed
19:25rhickeylpetit: b) IPersistentMap include ILookup, IObj always
19:25lpetitrhickey: 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:25rhickeylpetit: c) symbols are a pain in not self-quoting
19:25lpetitrhickey: hashCode/equals = ok, maybe wiki could state this more explicitly ?
19:25rhickeyd) interfaces are classes
19:26lpetitrhickey: d) Yes, but conceptually different
19:26djorktwbray: Do you think that infix math is maybe the only thing really tripping people up when it comes to Lisp syntax?
19:27djorkif you change the operators to English words it gets a little easier to read, I think
19:27djorkLogo was a Lisp and we did that in 3rd grade
19:27twbrayStart in 3rd grade and the problem goes away :)
19:27djorkheh
19:27djorkI guess so
19:28rhickeytwbray: thanks for spending some time with Clojure and covering is so well!
19:28rhickeycovering it
19:28lpetitrhickey: 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:29twbrayrhickey: 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:29twbray(Java's mapping, not clojure's)
19:29rhickeylpetit: 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:29djorknice writeup though, twbray
19:30djorktwbray: are you sure you used the best methods to read bytes into Java strings?
19:30djorkthere are various ways
19:30twbraydjork: Nope. But it's a problem that I'm fairly familiar with.
19:30djorkk
19:31rhickeylpetit: 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:31twbrayGoing from UTF-8 to UTF-16 is always going to suck
19:31lpetitrhickey: 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:31lpetitcase
19:32bitbckttwbray: As always, I enjoy your coverage of these things... and photography.
19:32bitbcktThanks.
19:32rlbI 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:32lpetitrhickey: oh, ok for IPersistentHashMap, then
19:33rhickeylpetit: 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:33lpetitrhickey: 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:34rhickeylpetit: I don't like dots anywhere near protocol fns - they just scream 'host interop'
19:34djorkso, twbray, you are at Sun? do you know what Sun-in-general thinks about Clojure?
19:35twbraydjork: Sun currently in process of being acquired, no opinions are to be expressed.
19:37lpetitrhickey: 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:37cubixis there a nicer way to do this or a function that already exists somewhere? http://paste.lisp.org/+1YIY
19:37rhickeylpetit: the more I stare at explicit this: http://paste.lisp.org/display/91364#1 the less it bothers me
19:38lpetitrhickey: so there's just the recur consistency problem left ?
19:38rhickeylpetit: with that, yes, the least likely to be encountered
19:41lpetitrhickey: why do you say so ?
19:42rhickeylpetit: less likely to be encountered than inconsistencies between deftype/reify/extend etc, not unlikely or never
19:43lpetit,(doc reify)
19:43clojurebotexcusez-moi
19:43rhickeyevery possible solution has some inconsistencies
19:44lpetitrhickey: what does it mean to place type hints on the explicit "this" in method arg list :-p
19:45rhickeylpetit: nothing
19:46lpetitrhickey: 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:46rhickeylpetit: because we are walking in circles? :)
19:47lpetitrhickey: 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:48lpetit(deftype AType [AProtocol AnInterface] :as explicit-this (aProtocol-method [] ...))
19:49lpetitrhickey: spirals, not circles :)
19:57rhickeylpetit: recur would be inconsistent for extend-type then
19:58rhickeylpetit: oh, you wanted explicit this in extend-type
19:58lpetitrhickey: yes
19:58rhickeythen extend-type and deftype are inconsistent (in an understandable way perhaps)
20:00lpetitrhickey: 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:00rhickeyas a practical matter, extend type will need to use 'this much more often
20:01rhickeybut the question will be asked - why make us state 'this in every method when you have this nicer solution for deftype/reify
20:02lpetitrhickey: 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:03rhickeylpetit: but now I am having a conversation with someone on this side of the understanding hill
20:03lpetitrhickey: and the answer could be "because a cat is a cat, and you don't have the same performance characteristics" ?
20:04rhickeybut a macro is a macro (extend-type) and could have taken away this tedium
20:05lpetitrhickey: sure, so the inconsistency of recur could also be got rid of by the macro, maybe ?
20:05lpetit(ok, certainly *not easy if at all possible*)
20:07lpetitI must leave, see you later !
20:07rhickeylpetit: bye - thanks for the input!
20:07lpetitmy pleasure
20:22arohnerrhickey: 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:23defnHow do you use (accessor)?
20:24rhickeyI think something like this will be built in - no need to add on later
20:26arohnerrhickey: ok, thanks. Are there any workarounds until that happens?
20:29rhickeyarohner: 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:31arohnersigh. 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:31arohnerthanks
20:32arohnerwell, the good news is I understand the deftype implementation a lot better!
20:35arohneris it possible to require that members of a protocol also implement an interface, say IPersistentMap?
20:36rhickeyarohner: no
20:36rhickeythe point of protocols is that such requirements can't be superimposed on all types
20:36rhickeye.g. String
20:37arohneroh right. though after cinc, keys will be part of the Associative protocol, right?
20:37rhickeymoving forward, it will be possible to write protocols that require other protocols, but only by convention, not enforcemed
20:38rhickeyyes, eventually all Clojure's key interfaces will be protocols
20:49johannhHi 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:50chouserapply doesn't force seqs
20:51johannhSo, apply is smart enough to bundle up the &rest argument into a lazy sequence?
20:52johannhI only ask because memory usage makes it look like the whole file is getting slurped in somewhere.
20:59arohnerlisppaste8: url
20:59lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
21:02lisppaste8arohner pasted "deftype extends explosions" at http://paste.lisp.org/display/91404
21:03arohnerI can't get extend-class to work with existing classes or deftype
21:05arohnerah, extend-class expanded into (extend :winston.db-row/java.lang.Object
21:08arohnerI've fixed the extend-class by removing the :: off java.lang.Object. now my protocol method works with normal classes, but not deftypes
21:08arohneris there a way to supply a default implementation for all deftypes?
21:11notallamado you need a different implementation for deftypes than Objects?
21:13arohnernotallama: my one extend-class on java.lang.Object is happy with "normal" classes, and not happy with deftypes
21:13arohnerso I assume so
21:15arohnerI also assume that because extend-class and extend-type both exist, there must be some difference
21:20notallamathe 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:20arohnerhttp://paste.lisp.org/display/91404
21:21arohnerexcept I removed the :: on extend-class
21:21lisppaste8arohner annotated #91404 "untitled" at http://paste.lisp.org/display/91404#1
21:24notallamayou're implementing half an interface on object, and the other half in deftype. i'm pretty sure that doesn't work.
21:24notallamaer, half a protocol
21:25notallamasince 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:26notallamayou could get the effect you want by splitting it into several protocols. (one for each method, or something)
21:27arohnernotallama: ok thanks, I'll try that out
21:29arohnerif that's the case, it really should be documented. it was not at all obvious that isn't allowed
21:30notallamaarohner: 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:31hiredmanwell, you don't brag about using it
21:31arohnerI thought I was implementing all of the methods, just in two different places
21:32arohnerstill getting the same error
21:32notallamapaste again?
21:33lisppaste8arohner annotated #91404 "untitled" at http://paste.lisp.org/display/91404#2
21:37notallamatake inserttableRow out of the deftype, and it should work.
21:37arohneroh right, because I'm not providing a new method for that
21:37arohneryeah. it works
21:37arohnerthanks.
21:47rongenreI'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:51arohnerrongenre: not really. the struct is created dynamically during the resultset-seq call
21:52arohner~def resultset-seq
21:52arohnersee that line "row-struct (apply create-struct keys)"
21:53rongenreYeah, i noticed there doesn't seem to be a def accessor on PersistentStructMap
21:54rongenreShould I just rebuild the struct if I want to use accessors to access the fields? [I think there's a performance penalty otherwise]
21:55arohnerthat's one option
21:55arohneryes, accessors will be faster than normal map derefs
21:55arohner* map lookups
21:55rongenreIs there a better one?
21:56rongenreI suppose I could hack a version of resultset-seq to return the new struct and the sequence
21:57arohnerI was just about to suggest that
21:57arohnerthat's what I would do
21:58rongenregot it. Thanks.
22:36churib,(doc recur)
22:36clojurebotIt's greek to me.
22:36churib,(+ 1 1)
22:36clojurebot2
22:37churib,(doc +)
22:37clojurebot"([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0."
22:37churib,(source +)
22:37clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
22:47solussd,(println "does the bot talk?")
22:47clojurebotdoes the bot talk?
22:51alexyksomnium: in (fetch :collection {)
22:51alexyk} )
22:52alexyk(fetch :collection :only [:key]) -- is :only a keyword?
22:52alexykI recall it worked as a bare word, or I'm dreaming?
22:52alexyksorry about {
22:52alexykit's my mac brace-matching trinket
23:00Drakesonare there any good webkit bindings in java or clojure?
23:03KarlThePagan2Drakeson, there's a java.net project for rich browser integration - it's a subproject of JDIC (java desktop integration c????)
23:04KarlThePagan2however it might only be internet explorer
23:04KarlThePagan2so that may be no help to you
23:05solussd,(.parseInt Integer "1")
23:05clojurebotjava.lang.IllegalArgumentException: No matching method found: parseInt for class java.lang.Class
23:06solussd,(. Integer (parseInt "1"))
23:06clojurebot1
23:06chouser,(Integer/parseInt "1")
23:06clojurebot1
23:56DrakesonKarlThePagan2: thank. I am not really looking for a "browser" as per se. I want the lean renderer, mainly.
23:57Drakesonthanks