#clojure logs

2009-10-10

00:17iceyi've been trying to get my emacs configured using http://technomancy.us/126
00:17iceybut i keep getting errors stating swank.clj can't be found when i try to run slime
00:17iceyi've tried on a couple of machines; is there something wonky with the current git versions?
00:47qbgSo it seems like I get NullPointerExceptions after taking a sufficiently large number of elements from an infinite sequence.
03:13LauJensenMorning gents
03:14G0SUBLauJensen: Good Morning Sire!
05:48namorWasn't there an online-clojure compiler somewhere?
06:02ambient,(+ 1 2)
06:02clojurebot3
06:03Chousuke,#=(System/getProperty "java.class.path")
06:03clojurebotSystem
06:03Chousukehm
06:04Chousukethat wasn't what I expected :P
06:14Kyromancer,(repeat 3)
06:14clojurebotEval-in-box threw an exception:java.lang.OutOfMemoryError: Java heap space
06:14Kyromanceroic
08:33Guest92834hmm... I have downloaded a clojure library I would like to use from my project. how do I do that?
08:35fyuryuGuest92834: the same way you would use a java lib in a project. Is this lib a in a .jar?
08:35Guest92834nope... it's a collection of .clj files
08:36fyuryuGuest92834: are they placed in a folder stucrure such as: some/library/file.clj?
08:36serp_fyuryu: yup
08:37fyuryuserp_: then you have to add the folder containing those folders to your classpath
08:38fyuryuserp_: that is, apart from having clojure.jar in you classpath, add "/path/to/folder"
08:39serp_aha let me try
08:39fyuryuserp_: then you'll be able to "use" and "require" those libraries
08:43serp_eh doesn't work... I'll have to read a little
08:43serp_thanks
08:45fyuryuserp_: I don't know how well are you familiar with java (classpath in particular)
08:45fyuryuserp_: how does the commnd with which you run clojure repl/script looks like?
08:46serp_I use vimclojure
08:46serp_and start the server with java -cp penumbra/src/penumbra:clojure.jar:clojure-contrib.jar:vimclojure.jar com.martiansoftware.nailgun.NGServer 127.0.0.1
08:47serp_then, in my file lol.clj I start with this: (ns lol (:require opengl))
08:48serp_there is a file named opengl.clj in penumbra/src/penumbra
08:48ambientperhaps just use java -cp penumbra/src and (ns lol (:require 'penumbra.opengl))
08:48fyuryuserp_: penumbra is the opengl lib, I think it needs some more libs (including native ones)
08:49ambientyes, you need to link the native libs too, eg. -Djava.library.path=c:\path\to\penumbra\lib\windows
08:51serp_ambient: is java.library.path different from classpath?
08:51ambienti dont know
08:51serp_ok
08:51fyuryuserp_: it should be: (ns lol (:require penumbra.opengl))
08:51ambientits just what i
08:51ambientve used
08:51fyuryuwithout the quote
08:53serp_hmm got a little further
08:54serp_#<CompilerException java.lang.ClassNotFoundException: javax.media.opengl.GL2 (core.clj:9)>
08:54serp_now I got that
08:54serp_but I'll have to figure it out later... I've gotta go
08:54serp_thanks for your help guys
08:54fyuryuserp_: np
08:54ambientyou sure you're linking the right binaries? 32 bit or 64 bit
08:54ambientit has to match the jvm
11:30ambientit's pretty cool what F# does how it gets core features of laziness, functionality and immutability included in core .NET
12:05voodoomonkey55i have a noob-like question for anyone willing to listen
12:08voodoomonkey55i need some help with the lazy-cons function
12:18Makoryuvoodoomonkey55: What's your question?
12:19voodoomonkey55am i supposed to import some library to use it or is it in clojure.core
12:19voodoomonkey55?
12:20voodoomonkey55because I've written some code that tries to use it but it won't run, saying that it can't find the symbol "lazy-cons"
12:21Makoryuvoodoomonkey55: It's been replaced by the more general-purpose lazy-seq
12:21voodoomonkey55oh ok
12:22voodoomonkey55could i use cons in place of lazy-cons? and how would i do that?
12:22Makoryuvoodoomonkey55: Inside the body of a lazy-seq macro, just use cons where you would use lazy-cons
12:23voodoomonkey55ok
12:23voodoomonkey55i'll try that
12:23voodoomonkey55thank you
12:24Makoryu,(doc lazy-seq)
12:24clojurebot"([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls."
12:25voodoomonkey55oh cool
12:25voodoomonkey55that helps a lot
12:25voodoomonkey55thanks
13:33MakoryuIs there any reason (apart from "Java doesn't support it already") that the underscore can't be used as intra-token "whitespace" in numeric literals?
13:58ChousukeMakoryu: what do you mean?
13:59MakoryuSome languages (Perl and Ruby, for example) allow 1_000_000 for 1000000
13:59ChousukeI think it'd look weird and complicate parsing a lot :/
14:00MakoryuNah, just stick with the existing "\d starts a numeric literal" rule, and add an "s/_//g" pass (whatever the Java equivalent of that is)
14:00MakoryuSince there's nowhere in numeric literals where underscores are already allowed, and the tokenizer already sees it as one token, it'll be fine
14:05chouserMakoryu: I don't think there's any technical problem -- it's been suggested before, but I think rhickey was uninterested.
14:06Makoryuchouser: Hrm....
14:08kmurph79i'm trying this while learning clojure: (map (fn [a b c] (a + b - c)) [1 2 3] [1 2 3] [1 2 3]) i want it to return (1 2 3) but i get an error when I try it. help?
14:08Makoryu,(1 + 2 - 3)
14:08clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
14:09MakoryuIs that your error?
14:09chouserkmurph79: you need to use prefix notation for + and - too, not infix like you have.
14:09kmurph79yes
14:09rongenreyeah, fix the fn
14:09kmurph79ohhhhhh
14:09rongenre(+ a (- b c))
14:09kmurph79blah
14:09kmurph79haha
14:09Makoryu,(- (+ 1 2) 3)
14:09clojurebot0
14:09kmurph79whoa, clojurebot is cool
14:10hiredman~botsnack
14:10clojurebotthanks; that was delicious. (nom nom nom)
14:10rongenreI end up writing python by mistake too, especially in arithmetic stuff.
14:10rongenreand I've been dabbling in lisp for like 20 years. I think it speaks to its usability.
14:10Chousukehiredman: you need to bind *read-eval* to false in the sandbox-eval function btw
14:11Chousuke,#=(eval (def foo 5))
14:11clojurebot#'sandbox/foo
14:11Chousuke,foo
14:11clojurebot5
14:11rongenre,first
14:11clojurebot#<core$first__4158 clojure.core$first__4158@1a1644b>
14:12Chousukehiredman: also, add alter-var-root and alterRoot to the bad form list :P
14:12Chousuke,hiredman.sandbox/*bad-forms*
14:12clojurebot#{alterRoot intern load-reader load-string clojure.core/addMethod eval alter-var-root def}
14:13chouserMakoryu: http://clojure-log.n01se.net/date/2008-03-30.html
14:13chouserso apparently I'm remembering incorrectly
14:14itistodayThink i've discovered a bug in this documentation: http://clojure.org/functional_programming
14:14Makoryuchouser: Oh, awesome. Better remind him :p
14:14chouserMakoryu: we probably just did.
14:14hiredmanhiredman.sandbox is so crufty
14:14Makoryuchouser: :p
14:14itistodayalthough could my lack of clojure knowledge, but isn't the variable 'x' not used in the make-adder function?
14:15hiredmanitistoday: it is
14:15hiredmanthe value of x is bound to y
14:16itistodayhiredman: ah, gotcha, sorry, i thought that meant something else, thanks!
14:18itistodayis there a reason why let is used? I tried removing let and just having it return (fn [z] (+ x z)) and that worked as well
14:19hiredmanit is an illustration of lexical scoping
14:20itistodayhiredman: i guess i mean to say, isn't removing the let still lexical scoping?
14:20itistodayhiredman: or is there some difference?
14:21hiredmanyes, but there are 3(?) ways to interact with lexical scope, and the exmple illustrates all three of them
14:21kmurph79in the repl, how do I cancel a command?
14:21Chousukekmurph79: you have to kill the repl :p
14:21kmurph79ah ok
14:23hiredmanlexically scoped names can be cated by calling a function and using let, lexicallybound names can be captured by creating a fn
14:23itistodayhiredman: so, just to make sure (as I'm trying to learn clojure by reading these documents), I would not define make-adder that way with the 'let' normally, as that would be redundant?
14:23hiredmansure
14:24itistodayhiredman: thanks, do you happen to know of a document somewhere that goes over these issues? and stuff like gensym? for clojure?
14:24itistodayi know of a great scheme tutorial that has a section dedicated that stuff
14:25itistoday(this is the scheme tut i'm referring to: http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-7.html#node_chap_5)
14:25hiredmanyou're looking at the clojure document
14:25hiredmanclojure.org
14:26itistodayis there a section on it that i've missed?
14:26hiredmanyou are looking at the section on lexical scoping right now
14:27itistodaywell it doesn't explain what it is, it just reference sit
14:27itistoday*references it
14:27itistodayi.e. it assumes the reader already knows about it
14:27hiredman"You can create local names for values inside a function using let. The scope of any local names is lexical, so a function created in the scope of local names will close over their values:"
14:28itistodaylike i said... that doesn't explain anything
14:28itistodayit doesn't define what lexical means
14:28itistodayand it gives an example that you just said was redundant
14:28itistodayyet it doesn't mention that
14:28hiredmaneh?
14:29hiredmanthe example illustrates the text
14:29itistodayso just reading that i would be under the impression to always surround (fn) with (let) to make it lexical
14:29itistoday.....
14:29itistoday*points gun to head*
14:29hiredmanI read that, and I was never under that impression
14:29itistodayit doesn't explain what lexical scoping is, nor does it explain any of the issues with it
14:30hiredman*shrug*
14:30hiredmanI don't see how the clojure docs should be responsible for teaching programming 101
14:31Chousukehttp://java.ociweb.com/mark/clojure/article.html this might have a bit more detail
14:31Chousukethen again, it might not :P
14:31itistodayChousuke: thanks! that was actually next on my reading list
14:31hiredmanif you want to know what lexical scope is, wikipedia has an article on it
14:31itistodayhiredman: i'm not saying the clojure docs should be responsible, i originally asked where i could find a document that addresses these issues (clojure specific)
14:32itistodayhiredman: this scheme tutorial does a great job: http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-7.html#node_chap_5
14:32itistodaybut i was asking because it's scheme-specific
14:32itistodayreferencing functions like fluid-let
14:32itistodaylet*
14:32itistodaygensym
14:32itistodaymacros, etc
14:33itistodayall of that stuff could be different in clojure, hence my questioning
14:33hiredmanChousuke: do you know of any lexical scope issues specific to clojure?
14:33Chousukecan't think of any
14:33hiredman
14:33itistodayheh
14:34Chousukefluid-let is kind of like the binding macro I guess
14:34Chousukewhich is another kind of scoping entirely :P
14:34Makoryu,(doc gensym)
14:34clojurebot"([] [prefix-string]); Returns a new symbol with a unique name. If a prefix string is supplied, the name is prefix# where # is some unique number. If prefix is not supplied, the prefix is 'G__'."
14:35itistodayso clojure doesn't have a fluid-let?
14:35Chousuke(doc binding)
14:35clojurebot"([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before. The new bindings are made in parallel (unlike let); all init-exprs are evaluated before the vars are bound to their new values."
14:36hiredmanitistoday: check the api page
14:36hiredmanor even better
14:36hiredman,fluid-let
14:36clojurebotjava.lang.Exception: Unable to resolve symbol: fluid-let in this context
14:36ChousukeI don't know if binding corresponds directly to fluid-let but it seems similar
14:36itistodayit might be called something different, but yeah, binding seems similar, thanks Chousuke
14:38itistodayand if it doesn't, the tut gives the implementation: http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-10.html#node_sec_8.3
14:38itistodaycrazy macro
14:39itistodaythat's something else i need to get good at, is writing macros. in newLISP they're f-exprs, which are identical to functions except the function arguments are quoted (aren't evaluated)
14:39Chousukethat's what they are in Clojure too? :/
14:39itistodayclojure has f-exprs?
14:39Chousukeexcept the result of the function call is evaluated.
14:40ambientwth are f-exprs?
14:40Chousukeno, but a macro is essentially a function that takes forms as parameters and returns another form
14:40Chousukewhich is then evaluated by the compiler
14:41itistodayChousuke: sorry, i don't understand what you meant by "they are in Clojure too". aren't clojure's macros the same sort as lisp and scheme?
14:41ambientim thinking of writing a lisp that doesnt have macroes, nor even lambda
14:41Chousukeambient: it's not lisp then anymore :P
14:41itistodayambient: they are identical to functions except the function arguments are quoted (aren't evaluated)
14:41ambientwell it is if the language is homoiconic, nested lists
14:42itistodayambient: newLISP "macro": (define-macro (my-macro x y) (println x " " y)) (my-macro x y) => 'x 'y
14:42itistodayambient: vs: (define (my-func x y) (println x " " y)) (my-macro x y) => nil nil
14:43itistodayambient: sorry, that last part should be (my-func x y) => nil nil
14:43itistodayambient: (because x and y weren't defined yet)
14:43Chousukeitistoday: so when is the println call done?
14:44itistodayChousuke: when you call my-macro/my-func?
14:44Chousukethat's not a macro then :/
14:44itistodayyeah i know, it's an f-expr
14:44itistodaynewlisp still calls them macros
14:44itistodayambient was asking what f-exprs were
14:44Chousukeitistoday: anyway, hm, binding is not quite like fluid-let I think
14:45itistodayChousuke: what's the difference?
14:45Chousukebinding dynamically rebinds vars, not locals
14:46Chousukesay you have (def *x* 5), (defn foo [] (println *x*))
14:46Chousukethen (let [*x* 3] (foo)) will print 5, but (binding [*x* 3] (foo)) will print 3
14:47Chousukethe binding is thread-local, and only in effect within the binding form, of course
14:47itistodayChousuke: isn't that the same as the fluid-let example? i don't see the difference
14:48itistodaysure scheme doesn't have vars (and i haven't gotten to reading about them yet), but the example results in the same values as the fluid-let example
14:49Chousukeitistoday: it says that fluid-let talks about lexical variables so I'm not sure
14:50Chousukebinding will as a side-effect shadow any lexicals too, but it's meant to allow dynamic scoping of *global* bindings
14:51Chousukehm, the earlier sentence was a bit unclear :P
14:51itistodayChousuke: yeah i'm still parsing it :P
14:51itistodayit's not a big deal though, i'm sure i'll get to it eventually and figure it out
14:52itistodayi think for now i'll just assume they're "similar" and see where that assumption leads me
14:52ordnungswidrighi
14:53ordnungswidrigdoes anybody know about a validation lib for clojure? sth. I can use for input parameter validation?
14:53Chousukeitistoday: I guess the difference with fluid-let is that it uses the set! thing which works with lexical locals too in scheme
14:54Chousukeitistoday: but in clojure, there is no way to change locals :P
14:55itistodayChousuke: so would it be fine to think of fluid-let as having "all of the functionality of binding, and then some"?
14:55itistodayi.e. it can be used to change locals?
14:56Chousukewell, somehow I doubt the changes are thread-safe like in clojure, but otherwise I guess that's right.
14:56itistodayright, yeah, they're definitely not thread-safe ;-)
15:11poetis whole-numbers a built in sequence?
15:11poetClojure=> (take 10 (whole-numbers))
15:11poet#<CompilerException java.lang.Exception: Unable to resolve symbol: whole-numbers in this context (REPL:5)>
15:12itistodayok, why does conj behave different for lists verse vector? for a list it prepends, and for a vector it appends? wtf?
15:12serp_,(+ 2 3)
15:12clojurebot5
15:12serp_,(whole-numbers)
15:12clojurebotjava.lang.Exception: Unable to resolve symbol: whole-numbers in this context
15:12itistoday,(nth (conj '(1 2 3) 4) 0)
15:12clojurebot4
15:12itistoday,(nth (conj [1 2 3] 4) 0)
15:12clojurebot1
15:13itistodayseems like a silly decision to me
15:15hiredmanitistoday: it's useful, you can build stuff up recursivly using vectors and not have to call reverse when you are done
15:16serp_,(conj [1 2 3] 4)
15:16clojurebot[1 2 3 4]
15:16serp_,(conj '(1 2 3) 4)
15:16clojurebot(4 1 2 3)
15:16serp_,(5 .4)
15:16clojurebotjava.lang.Exception: Unable to resolve symbol: .4 in this context
15:16itistodayhiredman: it's inconsistent, and i don't think that just because you can "do something" in some particular situation is a good reason to introduce this sort of inconsistency
15:17hiredman*shrug*
15:18itistodaydocs for last also says it takes linear time in the api docs, really? even for vectors? and lists could be linear time as well if you kept a pointer to the tail...
15:18hiredmanvectors and lists are different datastructures with different chracteristics
15:18itistoday,(doc last)
15:18clojurebot"([coll]); Return the last item in coll, in linear time"
15:19hiredmancoll there should be changed to sequence
15:20hiredmanthe reason it is linear time is last operates are sequences
15:21itistodayweird...
15:21itistodayis there a way to get the last element in constant time?
15:21itistoday(for lists also?)
15:21hiredmanno
15:21hiredmannot for lists
15:21itistodayi guess it's not too bad considering there are vectors...
15:22hiredman,(let [v [1 2 3]] (v (dec (count v))))
15:22clojurebot3
15:22itistodayyeah
15:22hiredmanhmm
15:22hiredman,(doc peek)
15:22clojurebot"([coll]); For a list or queue, same as first, for a vector, same as, but much more efficient than, last. If the collection is empty, returns nil."
15:22hiredman↑ there we go
15:22itistodaynice! thanks! :-)
15:22hiredman,(peek [1 2 3])
15:22clojurebot3
15:23itistodayso clojure has implicit indexing too?
15:23itistoday,([1 2 3] 0)
15:23clojurebot1
15:23itistoday,([1 2 3] -1)
15:23clojurebotjava.lang.IndexOutOfBoundsException
15:23itistodayeh.. doesn't do that though :-p
15:23itistoday,('(1 2 3) 0)
15:23clojurebotjava.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn
15:23itistodaydoesn't do that either...
15:23itistodaynot very list friendly for a lisp
15:24hiredmanlists are not functions
15:24hiredmanthey are associative
15:24itistodayneither are vectors...
15:24hiredmanyes they are
15:24itistodayvectors are functions?
15:24hiredmansure
15:24itistodaydocs?
15:25itistoday(news to me)
15:25itistoday(hehe, then probably most of what you tell me will be news, as i'm just learning clojure)
15:25hiredmanon clojure.org
15:26hiredmansince vector is a datastructure, I would checkout the datastructure page
15:27hiredmanvectors and maps are functions of their indices and keys
15:27hiredman,([1 2 3] 0)
15:27clojurebot1
15:27hiredman,({0 1 1 2 2 3} 0)
15:27clojurebot1
15:27itistodayhiredman: thanks! "Vectors implement IFn, for invoke() of one argument, which they presume is an index and look up in themselves as if by nth, i.e. vectors are functions of their indices."
15:28itistodayalthough i don't see why implicit indexing couldn't be done for lists as well
15:29hiredmanlists are not indexed
15:29itistodayyeah but it doesn't mean you can't use implicit indexing on them
15:29itistodaynewlisp does it :P
15:30Chousukeyeah, but it's slow :P
15:30hiredmanso?
15:30hiredmanif newlisp jumped off a cliff would you?
15:30Chousukeit's better not to allow it so that people don't do it accidentally.
15:30itistodayhey, you don't have to like it, i just thought it'd be a nifty addition to the language
15:30Chousukeitistoday: but conceptually, it doesn't make sense since lists aren't associative :)
15:31itistodayhiredman: if newlisp jumped off a cliff i would not follow suit, but if it did it would be quite surprising behavior for it ;-)
15:31itistodayChousuke: what do you mean by associative?
15:31hiredmanthey aren't functions
15:32itistodayneither are vectors!
15:32hiredmana map is a function that maps keys to values
15:32Chousukeitistoday: a vector associates a numerical index with a value. similarly, a map associates a key with a value
15:32hiredmanvectors are maps with numerical keys
15:32Chousukeitistoday: lists do neither
15:32itistodayyeah sure, but this is just conceptual jibber jabber
15:32itistodaya list can associate a value to another
15:32itistodayyou define the position in the list as the key
15:32itistodayand what's at that position as a value
15:32itistodayboom
15:33itistodayperfectly mathematically valid
15:33itistoday*how* it's done doesn't matter
15:33hiredmanthat is not a list any more
15:33Chousukeitistoday: mathematically that's equivalent to a vector though :P
15:33hiredmanyou can call it a list, but it isn't one
15:33itistodayChousuke: yes, my point though ;-)
15:33itistodayhiredman: how is it not a list?
15:33Chousukeitistoday: but in a programming language, thinking that a list is a vector is a bad thing.
15:34hiredmanit's no longer just a linear collection of things
15:34itistodayhiredman: really? then what is it?
15:34itistodayhiredman: or rather do you mean to say it *is* a linear collection of things, but can be thought of as more too? in which case it's still a linear collection of things
15:34hiredmanit's a numbered linear collection of things
15:35itistodayyeah, just like a vector is ;-)
15:35Chousukeitistoday: that's the thing. a vector can be thought to be a list with no trouble, but the reverse is not true.
15:35Chousukeitistoday: indexing a list by position is stupid
15:36Chousukesometimes easier than the non-stupid thing, yes, but generally stupid :P
15:36hiredmansince the list doesn't have indexed access, you have to walk it to find the nth thing
15:36itistodayyes, i understand that it's inefficient to get to the middle
15:36itistodayfine, ok, i'll back off since clojure supports implicit indexing for vectors
15:36hiredmanif you want indexed access use a vector
15:36itistodayand it probably uses them a whole lot more often
15:36Chousukeyeah :)
15:37itistoday:-)
15:37hiredmanhaving a plurality of datastructures with different characteristics is a good thing
15:37Chousukethe list function is not very popular :P
15:37Chousukeusing a vector is more idiomatic
15:37itistodaysee, this is news to me, as in newlisp they're almost all you use
15:37hiredmanfunctions * datastructures
15:37itistodayand actually, in newlisp, functions *are* really lists
15:38Chousukefunctions are lists in the original lisp too :/
15:38itistodayyou can actually do this: ((fn () (println "hello")) 0) => "hello"
15:38Chousukewait, what, 0?
15:38ambientehm, you can do that in clojure too
15:39ambient((fn [x] (+ x 1)) 0)
15:39itistoday,((fn [x] (+ x 1)) 0)
15:39clojurebot1
15:39itistodayhmmm
15:39itistodaywhy doesn't this work though:
15:40itistoday,((fn [] "hello") 0)
15:40clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--3883$fn
15:40ambientthat doesn't make any sense
15:40Chousukeitistoday: you're passing an argument to a function that takes none :)
15:40itistodaywhoops
15:40Chousuke,((fn [] (print "this works")))
15:40itistodaysorry, lol
15:40hiredman1 vs. 0
15:40clojurebotthis works
15:40itistodaywait.. i've confused myself and all of you
15:40itistodaylet me fix my newlisp example...
15:41itistoday(nth 0 (fn () (println "hello"))) => ()
15:41ambientclojure doesn't have call/cc though afaik
15:41itistoday(nth 1 (fn () (println "hello"))) => (println "hello")
15:41itistodaythat's what i meant to do
15:41Chousukeitistoday: that's not exactly new.
15:41itistodayChousuke: yeah, i'm not saying it is, was just illustrating that in newlisp functions are lists
15:42hiredmanis newlisp compiled?
15:42itistodayno
15:42itistodaynewlisp is a neat language though, i'm not bashing clojure or saying newlisp is better, just that it's nifty
15:43hiredmanI just can't imagine that having good performance, even in an interpreted lisp
15:43itistodayand that i'm coming to clojure from newlisp, and that's why i was surprised when it supported implicit indexing for vectors but not lists
15:43itistodayhiredman: newlisp is fast as hell
15:43ambientwhat does fast as hell mean?
15:43Chousukehiredman: the interpreter probably stores the original code somewhere and keeps an internal object for the actual function
15:43itistodayit's extremely fast for an interpreted language
15:44itistodaymeaning, it's faster than most other interpreted languages
15:44ambientfor all intents and purposes, clojure seems like interpreted language to me also
15:44itistodayand i've done some rudimentary benchmarks between it and clojure, and they were comparable there, but better benchmarks would be useful
15:44slashus2As fast as a pyroclastic flow rolling down a hillside. hehe
15:44ambienti don't see any significant difference
15:44hiredmanclojure is compiled
15:45hiredmaneverything is turned into jvm bytecode
15:45itistodayyeah, there's a big difference
15:45ambienthiredman but the application development speed and the power inherent to the language is equal or greater than what interpreted languages have
15:46itistodayambient: what?
15:46itistodaynewlisp is fast because it doesn't implement some things that slow clojure and other languages down
15:46ambientit used to be that with interpreted languages it was nice to write code, but they were slow. high performance languages were pita to write code
15:47ambientbut in today's world, i don't see any benefit in interpreting, unless one is just building up a new language
15:47slashus2itistoday: What slows clojure down?
15:47itistodayambient: it's a good point, but actually clojure can't do some things newlisp can because it's compiled
15:47itistodayambient: newlisp is very dynamic because it's interpreted
15:47hiredmanitistoday: if newlisp has comparable to python, then clojure code written with an eye towards peformance should smoke it
15:48ambientitistoday i doubt that it's a lot more dynamic than clojure, very much
15:48clojurebotclojure is like life: you make trade-offs
15:48itistodayhiredman: i would bet that newlisp beats python
15:48slashus2I mean clojure can run a live REPL and allows you to inject new code into a running program. That is very dynamic.
15:48ambientpython isn't exactly the fastest around. compare to lua instead
15:48itistodayslashus2: two things i know of are garbage collection and lexical scope
15:49Chousukenewlisp doesn't do garbage collection?
15:49itistodayslashus2: newlisp has no garbage collection and is dynamically scoped
15:49iceywhat does newlisp interop with? or what does it's library ecosystem look like?
15:49Chousukewhat does it do then? :|
15:49slashus2ahh... well garbage collection algorithms continue to improve, and given the benefits, I don't think that the speed is hit by it as much as you think.
15:49Chousukethe JVM's garbage collector is already awesome
15:49itistodayicey: it can integrate directly with C very easily
15:50itistodayicey: it's standard library is fantastic too
15:50Chousukelack of lexical scoping worries me though.
15:50slashus2The performance argument against garbage collection is not very relevant anymore.
15:50hiredmanI saw some papers by early lispers that said "hey, we have more and more memory, stop the world gc sucks, so lets just not gc"
15:50iceyso you can drop to C for speed like you can in python, or java in clojure... is there any ecosystem outside of the standard library?
15:50ambientSBCL seems to provide the best performance/power ratio, only thing missing is library support :p
15:50kotarakIf it has no GC it not interesting...
15:50iceythat's a big concern for me when i'm writing software; i hate having to rewrite the wheel all the time
15:50itistodayicey: what do you mean "ecosystem" there are libraries written for newlisp, yes
15:51itistodayicey: not as many as clojure though
15:51hiredmanclojure is not targeted at "scripting" either, it is targeted at building large software systems, the same niche as java
15:51itistodayhiredman makes an excellent point
15:51iceyitistoday: like, say on any given day i need an html parser, some way to interop with tokyo cabinet, oauth interop
15:51itistodayicey: right, don't use newlisp
15:52iceyitistoday: gotcha; thanks
15:52itistodaybtw, don't let the dynamic scope and lack of gc put you off newlisp
15:52ambienthiredman although i might just use it for scripting, and thing it could work very well for that. i cant see why not
15:52hiredmanso it's a scripting language with no libraries...
15:52itistodayhiredman: it has libraries, just not as many
15:52iceyitistoday: do you have to deal with gc yourself? how does it free memory?
15:52itistodayicey: no
15:52hiredmanitistoday: it really sounds like newlisp is a throw back to very early lisps
15:52hiredmanwhich is ok, I guess
15:52itistodayjust, hold on
15:52itistodaylet me explain the gc thing
15:52hiredmandynamic scope and lack of gc
15:52itistodayin newlisp it's not like C or C++
15:52itistodaymemory management is not an issue
15:53itistodaynewlisp uses once-only-referencing
15:53itistodayORO
15:53itistodayor, OOR, don't knwo
15:53itistodayheh
15:53itistodayanyway, most of the time data is copied by-value
15:53itistodaydata passed between built-in functions is passed by reference
15:53Chousukehttp://www.newlisp.org/MemoryManagement.html aha.
15:53itistodayyes
15:53iceychousuke: reading it now actually haha
15:53hiredmanearly lisps where typically dynamicly scoped
15:53itistodaydata passed between user-defined functions is copied by value
15:53clojurebotfunctions are maps
15:54itistodayhiredman: yes, newlisp is new though
15:54hiredmanclojurebot: botsnack
15:54clojurebotthanks; that was delicious. (nom nom nom)
15:54Chousukeitistoday: that sounds fairly inefficient :P
15:54itistodayi know
15:54hiredmanitistoday: if all its ideas are old, how can it be new?
15:54Chousukeitistoday: unless it's a functional language.
15:54itistodayjust, trust me on this, it's fast
15:54itistodaythe decisions to not have a GC and use dynamic scope make it fast
15:55itistodayyou can benchmark it yourself
15:55slashus2newLisp appeared in 1991...hmm
15:55itistodaythe author is not an idiot
15:55itistodayhe consciously chose to forego a GC and use dynamic scope
15:55itistoday(and use fexprs instead of macros)
15:55hiredmanI'm not saying he is, I am saying newlisp isn't very new
15:55itistodaythe language is *great* for scripting purposes
15:56itistoday1991 is pretty new for lisp
15:56hiredmanand hardly modern
15:56iceypeople who like newlisp *really* like newlisp. it just seems to have limited usefulness which isa problem for lazy people like me.
15:56itistodaynewlisp has its niche where it shines
15:56itistodayi do not recommend it for making huge backends with lots of fancy libraries and whatnot
15:56hiredmanitistoday: regardless of the creation date, dynamic scope and lack of gc make it sound very similar to the lisps that predated the lisp machines
15:56itistoday(which is why i'm learning clojure)
15:57iceyi'm sure it's earned its fans
15:57itistodayhiredman: that's interesting to know
15:57hiredmanI think scheme was actually the first lisp to popularize lexical scope
15:58hiredmanitistoday: The Evelution of Lisp is a great paper to read, Guy Steele and Some Other Dude
15:58itistodaynewlisp is very useful as a scripting language because of it's built-in library (which has a lot of stuff) and it's extremely small size
15:58itistodaynewlisp is like... about 200k
15:58itistoday*200kb
15:58itistodayit's so small you can actually "link" your script to the binary and send it off to someone
15:59hiredmanambient: I had no idea that scheme was originally built to explore the actor model of computation
15:59hiredman~clojure
15:59clojurebotclojure is a very attractive hammer with a nice heft to it
15:59itistodayhiredman: thanks for the suggestion
15:59hiredman~clojure
15:59clojurebotclojure is not scheme
16:00kotarakRichard Gabriel was the "other guy"
16:00hiredmankotarak: thanks
16:01itistodayjust thought it'd be a recommendation here in case you guys are looking for a lisp scripting language, it's worth checking out i think
16:02itistodayit beats the pants off using bash and the others ;-)
16:02ambientpython is way too good for that for me to consider anything else
16:02itistodayambient: yeah, i like python too, but i already know newlisp and don't have the time to learn python
16:02kotarakitistoday: speaking of scripting: did you try scsh?
16:02itistodaykotarak: no...
16:02iceyyou can literally learn a useful amount of python in a week if you know any other programming language
16:02iceyerm s/week/weekend
16:03itistodaykotarak: is that different from tcsh?
16:03hiredman~python
16:03clojurebotGabh mo leithscéal?
16:03hiredmanbah
16:03itistodayicey: yeah, it's very readable, but it has too much syntax, newlisp is more readable i think ;-)
16:03itistodayicey: i had to teach it to myself for a project due in my AI class
16:03clojurebotfor is not a loop
16:04ambientpython is basically pseudo-code with very little actual syntax imo
16:04itistodayicey: in 3 hours i: 1) learned the language 2) wrote a game in it for the AI class
16:04iceyitistoday: i wasn't talking about newlisp, you said you didn't have time to learn python and I said it would take a weekend to learn a useful amount of it
16:04kotarakitistoday: scsh means scheme shell. http://www.scsh.net/
16:04hiredman~literal [7] clojure
16:04clojurebotfar closer to perfection then python
16:05ambientpython isn't perfect, doesn't try to be, and that's one of its strenghts actually :)
16:05itistodaypython is a nice language, i definitely agree
16:05kotarakitistoday: has nothing to do with tcsh
16:05hiredmanpython has got to be one of the ugliest languages I have ever seen
16:05itistodaykotarak: thanks, that looks interesting i'll have a look
16:05hiredmanI hate it, and I hate that everyone uses it everywhere
16:06itistodayhiredman: lol
16:06ambientthat's not necessarily a very pragmatic approach to things
16:06itistodayi like it for how it's readability and relative lack of syntax compared with the other popular scripting languages like Ruby and whatnot
16:07itistodaybut i love the concept of lisp - virtually no syntax. it's like heaven after years of C/C++ programming
16:37wavisis there a way to get the arity of a function?
16:37wavisexample (if (= 0 (arity the-fn)) (the-fn) the-fn)
16:42ambientthere seems to have been a way (:arglist ^#'myfunc) but that doesn't seem to work anymore because it exposed actual implementation details
16:44slashus2wavis: What are you trying to accomplish?
16:45slashus2wavis: You could overload the function to take multiple number of arguments and "dispatch" from that function to call other functions.
16:46slashus2(fn ([] (print "hi")) ([x] (print x)) ([x y] (print x y)))
16:47wavis,(apply max (map count ((meta #'map) :arglists)))
16:47clojurebot6
16:47wavisi think i just answered my own question :)
16:48wavisi'm trying to build a dumb repo which, when an object is fetched, will call it if it is a function and doesn't accept args
16:49wavisso as to allow some things not to be stored, but still be accessible
16:49hiredmanthat only works for functions created with defn
16:49wavisoh
16:49hiredman#'map is the var that the name symbol map refers to
16:49hiredmanthe metadata is stored on the var
16:51wavisthis is true. actually my solution should be to use metadata anyway. so i can (put-repo (with-meta (fn [] nil) {:call-with ["one-arg" "and another"]}))
16:52slashus2there you go
16:53wavis:)
16:56itistoday,(def x [1 2]) (== x [1 2])
16:56clojurebotDENIED
16:56itistodaywell, it would have said false
16:56itistodaywhy?
16:56slashus2use =
16:56itistodayi don't understand what the doc says
16:57slashus2it does .equals
16:57rongenre,def
16:57clojurebotjava.lang.Exception: Unable to resolve symbol: def in this context
16:57rongenre,(doc def)
16:57clojurebotDENIED
16:57slashus2== is for numbers
16:57rongenre,(doc first)
16:57clojurebot"([coll]); Returns the first item in the collection. Calls seq on its argument. If coll is nil, returns nil."
16:57slashus2, (let [x [1 2]] (= x [1 2]))
16:57clojurebottrue
16:57itistodayslashus2: that's it?
16:58rongenre(let [x [1 2]] ) (== x [1 2]))
16:58rongenreer..
16:58itistoday,(let [x [1 2]] ) (== x [1 2]))
16:58clojurebotnil
16:58rongenre,(let [x [1 2]] ) (== x [1 2]))
16:58clojurebotnil
16:58itistoday== is for numbers?
16:58slashus2,(doc ==)
16:58clojurebot"([x] [x y] [x y & more]); Returns non-nil if nums all have the same value, otherwise false"
16:58slashus2You can use = for numbers too if you want.
16:58itistodayso uh, i'm missing the point of == then
16:59slashus2It is the same as java's ==
16:59itistodaybut doesn't java's =='s compare primitives?
16:59rongenre,(.intValue 3)
16:59clojurebot3
16:59rongenreIs it a weird autoboxing thing?
16:59itistodayand clojure doesn't have primitives right?
17:00itistodayso why would it have ==?
17:00rongenre(== 3 3)
17:00rongenre,(== 3 3)
17:00clojurebottrue
17:00slashus2,(== (.intValue 3) (.intValue 3))
17:00clojurebottrue
17:00ambient,(== (int 3) 3)
17:00clojurebottrue
17:00wavis,(with-meta (fn [] 7) {:stuff true})
17:00clojurebotjava.lang.UnsupportedOperationException
17:00rongenre,(let [x [1 2]] (== x x))
17:00clojurebotfalse
17:00rongenrewhoa
17:00itistodaywow
17:00rongenrethat's surprising
17:00slashus2itistoday: You can cast things to primitives. Just like ambient just did.
17:01rongenreso object identity's a bit weird, huh
17:01rongenre,(new Object)
17:01clojurebot#<Object java.lang.Object@bade60>
17:01slashus2,(let [x [1 2]] (= x x))
17:01clojurebottrue
17:01itistodayslashus2: where did he do that?
17:01rongenre,(let [x (new Object)] (== x x))
17:01clojurebotfalse
17:02itistodayok, i think == needs more than the sentence that's dedicated to it in the docs...
17:02rongenre,(let [x 666] (== x x))
17:02clojurebottrue
17:02rongenreYeah, object identity's confusing me here.
17:03ambient(== [] [])
17:03ambient,(== [] [])
17:03clojurebotfalse
17:03rongenreEven the same object instances don't == to true.
17:03slashus2Just use =.
17:03slashus2=
17:03itistodaylol
17:03rongenreWell yes ;-)
17:03itistodayi'm just wondering wtf this =='s is...
17:04rongenreI'm just curious about =='s looking at. And is there unnecessary scaffolding being constructed
17:04itistodayyou know, google won't even let me search for "=="
17:04slashus2It uses (. clojure.lang.Numbers (equiv x y))
17:05rongenregoogle's getting pretty cuil lately isn't it
17:05slashus2,(clojure.lang.Numbers/equiv 5 5)
17:05clojurebottrue
17:05rongenreslashus2: thanks. So if I wanted to look at pointer equality, ='s the way to go.
17:05slashus2,(clojure.lang.Numbers/equiv [] [])
17:05clojurebotfalse
17:06itistoday,(let [x [1 2]] (= x [1 2]))
17:06clojurebottrue
17:06rongenre,eq
17:06clojurebotjava.lang.Exception: Unable to resolve symbol: eq in this context
17:06rongenre,eq?
17:06clojurebotjava.lang.Exception: Unable to resolve symbol: eq? in this context
17:06slashus2Yes, because this is only checking for numerical equivalence.
17:06itistoday,(let [x (new Object)] (= x (new Object)))
17:06clojurebotfalse
17:06slashus2rongenre: All you need is =
17:07rongenreslashus2: = corresponds to java ==, then? Pointer equality, about as fast as you can get?
17:07itistodayi don't think so?
17:07itistodayi don't think clojure has java's ==?
17:07kotarak(doc identical?)
17:07clojurebot"([x y]); Tests if 2 arguments are the same object"
17:07slashus2It is different because == only checks for number equality in clojure.
17:08rongenre,(let [x (new Object)] (identical? x x])
17:08clojurebotUnmatched delimiter: ]
17:08rongenre,(let [x (new Object)] (identical? x x)
17:08clojurebotEOF while reading
17:08itistodayah, yes, identical? is java's ==
17:08itistoday,(let [x (new Object)] (identical? x x))
17:08clojurebottrue
17:08rongenredone. Cool.
17:09rongenreThere's a certain level of 1992 in wondering if I should be using an emacs irc mode.
17:10itistodaythanks all, i think i get it, and i now know to simply not use ==. think they should remove it in fact to avoid confusion. ;-)
17:10slashus2It is probably faster for number comparison...
17:10itistodayslashus2: ok, that would be a good reason to use it.. if true
17:10slashus2But, looking under the hood, it looks like clojure.lang.Util/equiv just does an k1 == k2 sort of thing.
17:11ambientrongenre no you shouldnt, you should use emacs console, in which you would run screen irssi ;)
17:11ambientor was it M-x term i forget
17:11rongenre,(identical? 3 3)
17:11clojurebottrue
17:12slashus2Because = will eventually call Numbers.equiv(k1,k2) if k1 is an instance of number.
17:12slashus2Probably little advantage.
17:12itistodayhow do you use dotimes?
17:12slashus2to none
17:13slashus2,(dotimes [x 5] (print x))
17:13clojurebot01234
17:13itistodaygotcha, thanks
17:14slashus2chouser: Why does == still hang around? Is it the way the core.clj was implemented?
17:14rongenre, (identical? 3 (/ 6 2))
17:14clojurebottrue
17:15slashus2,(* 1/2 1/3)
17:15clojurebot1/6
17:15itistodayok, found some very interesting results
17:15itistodaycheck this out
17:15itistoday,(time (dotimes [n 100000000] (== 3 3)))
17:15clojurebot"Elapsed time: 190.169 msecs"
17:15itistoday,(time (dotimes [n 100000000] (== 3 3)))
17:15clojurebot"Elapsed time: 10.612 msecs"
17:15itistoday,(time (dotimes [n 100000000] (= 3 3)))
17:15clojurebot"Elapsed time: 449.279 msecs"
17:15itistoday,(time (dotimes [n 100000000] (= 3 3)))
17:15clojurebot"Elapsed time: 361.286 msecs"
17:15itistoday,(time (dotimes [n 100000000] (identical? 3 3)))
17:15clojurebot"Elapsed time: 569.936 msecs"
17:15itistoday,(time (dotimes [n 100000000] (identical? 3 3)))
17:15clojurebot"Elapsed time: 583.892 msecs"
17:15itistodayso.....
17:15itistodayidentical? does not do what we thought
17:15itistodayit's the slowest
17:15itistoday== is the fastest
17:15chouser== is for numbers. = for all other value comparisons
17:16itistodayyeah
17:16itistodaybut check that out
17:16itistodayidentical? is super slow!
17:16itistodaywhy?
17:16itistoday,(doc identical?)
17:16clojurebot"([x y]); Tests if 2 arguments are the same object"
17:16itistodaysee, wouldn't know that from the doc
17:16chouserhm
17:16slashus2chouser: I mean there isn't much advantage of using == over = with number comparisons, correct?
17:16slashus2= is very universal
17:16ambientin theory with copy-on-write immutable structures it shouldn't be that hard to do an equality test
17:16itistodayslashus2: there is, it's faster
17:17hiredmanambient: egal
17:17hiredmanclojurebot: egal?
17:17clojurebotegal is http://home.pipeline.com/~hbaker1/ObjectIdentity.html
17:17itistodaywhy is identical? super slow? anyone know?
17:17chouserI believe == can work directly with primitive number types, while = doesn't.
17:17slashus2micro-benchmarks don't really do it justice with the jit and everything under the hood.
17:18slashus2chouser: Well under the hood = eventually calls Numbers.equiv(k1, k2)
17:18slashus2and Numbers.equiv is overloaded to support primitives.
17:18hiredman1d10
17:18clojurebot5
17:18hiredmansorry
17:18chouseryeah, that's it: = will always box its args. == can take many combinations of primitive numbers directly
17:18chouser(show clojure.lang.Util "equiv") vs (show clojure.lang.Numbers "equiv")
17:19slashus2if(k1 instanceof Number)return Numbers.equiv(k1, k2);
17:19slashus2Is called from clojure.lang.Util/equiv
17:19itistoday,(time (dotimes [n 100000000] (clojure.lang.Util.equiv 3 3)))
17:19clojurebotjava.lang.ClassNotFoundException: clojure.lang.Util.equiv
17:19itistoday,(time (dotimes [n 100000000] (clojure.lang.Util/equiv 3 3)))
17:19clojurebot"Elapsed time: 441.838 msecs"
17:20itistoday,(time (dotimes [n 100000000] (clojure.lang.Util/equiv 3 3)))
17:20clojurebot"Elapsed time: 327.715 msecs"
17:20itistoday,(time (dotimes [n 100000000] (clojure.lang.Numbers/equiv 3 3)))
17:20clojurebot"Elapsed time: 219.285 msecs"
17:20itistoday,(time (dotimes [n 100000000] (clojure.lang.Numbers/equiv 3 3)))
17:20clojurebot"Elapsed time: 11.967 msecs"
17:20itistoday,(time (dotimes [n 100000000] (clojure.lang.Numbers/equiv 3 3)))
17:20clojurebot"Elapsed time: 10.613 msecs"
17:20itistodayyou know what's fucked up? the incredible performance increase of running it twice
17:20itistodayeven though it's doing the same thing 100000000 times
17:20chouseritistoday: that's hotspot for you
17:20hiredmanit's called a JIT
17:20ambientwhy? it got jitted
17:20slashus2That is the jit kicking in
17:21itistodayyeah i know
17:21itistodayi'm saying that you'd think it'd jit it on the first call
17:21slashus2nooo
17:21itistodayoh, right
17:21itistoday"hotspot"
17:21itistodaygotcha
17:21itistodayi get it
17:21itistodaylol
17:21hiredmanmaxine compiles everything :)
17:21hiredmanno interpreter
17:21chouseritistoday: but note you're working with boxed numbers in all those examples.
17:21hiredmanbut I can't get maxine to build
17:22slashus2itistoday: Run this on your computer compared to the other (dotimes [x 3] (time (dotimes [n 100000000] (clojure.lang.Numbers/equiv (int 3) (int 3)))))
17:22itistoday(dotimes [x 3] (time (dotimes [n 100000000] (clojure.lang.Numbers/equiv (int 3) (int 3)))))
17:22itistoday,(dotimes [x 3] (time (dotimes [n 100000000] (clojure.lang.Numbers/equiv (int 3) (int 3)))))
17:22clojurebot"Elapsed time: 81.941 msecs" "Elapsed time: 2.726 msecs" "Elapsed time: 0.043 msecs"
17:22itistoday,(dotimes [x 3] (time (dotimes [n 100000000] (clojure.lang.Numbers/equiv (int 3) (int 3)))))
17:23clojurebot"Elapsed time: 8.832 msecs" "Elapsed time: 2.599 msecs" "Elapsed time: 0.043 msecs"
17:23itistoday,(dotimes [x 3] (time (dotimes [n 100000000] (== (int 3) (int 3)))))
17:23clojurebot"Elapsed time: 9.388 msecs" "Elapsed time: 2.644 msecs" "Elapsed time: 0.046 msecs"
17:23itistodayyeah == is that function
17:23itistoday,(dotimes [x 3] (time (dotimes [n 100000000] (== 3 3))))
17:23chouseritistoday: please consider running that on your own repl and/or pasting to lisppaste
17:23clojurebot"Elapsed time: 192.242 msecs" "Elapsed time: 5.216 msecs" "Elapsed time: 0.045 msecs"
17:23hiredmanyeah
17:23hiredmanplease
17:23itistodaysorry, k
17:23itistodaybut that last result is interesting
17:24itistodayi guess the compiler figured out to not box it or something?
17:24slashus2It is a micro-benchmark, it will vary depending on the current computer load.
17:24itistodaystill, these are consistent numbers
17:24chouserprobably not. there's so much going on in the JVM, your real results are probably getting lost in the noise.
17:25hiredmanclojurebot is not a benchmarking platform
17:25slashus2haha
17:25chousergarbage collection pauses, for example, can make a huge difference.
17:25itistodayyeah, i'm just trying to figure out what the heck is going on here
17:25itistodayand i still haven't found out why identical? is so slow
17:26itistodaywhich means i don't really know what it's doing
17:27slashus2Look at core.clj to figure it out. It gives good insights to how the code works under the hood.
17:27itistodayslashus2: thanks, will do
17:28hiredmanidentical? is in RT.java actually
17:28slashus2Yeah, I just saw that.
17:30itistodayis this it: http://pastie.org/649805
17:30itistodaybecause if it is i'm still at a loss..
17:34slashus2itistoday: You would probably have to ask Rich Hickey about it. I wouldn't worry about it too much. The concurrency constructs make up for any performance loss in little things in the language. Overall it is very fast.
17:35hiredmanI wonder if it just the difference between comparing Objects and primitives
17:35itistodayslashus2: k, thanks for the advice. should I ask him on IRC or send email to devlist?
17:35itistodayhiredman: java's == should be comparing primitives (memory addresses) no?
17:35ambientwhat worries me though that with simple processes in other imperical languages i've been able to get ~90% speedups but by using clojure constructs that seems way lower
17:35ambientin embarassingly parallel problems
17:35hiredmanitistoday: by the time it gest to java's == the ints are boxed
17:36hiredmangets
17:36hiredmanlook at the method signature for invoke
17:36hiredmanequiv ultimately unboxes before doing the comparison
17:36itistodayhiredman: ok, fine, but then why is = still faster?
17:36itistodayboxing still occurs there..
17:37itistodayon my machine it's over twice as fast
17:38itistodaysorry, i'll ask hickey ... if i see him on the channel i guess
17:38hiredmanitistoday: I haven't checked, but I imagine = is distpatching to equiv
17:38hiredmanwhere the numbers are unboxed before being compared
17:39itistodayi can't see how that would speed it up though
17:39itistodayas both box the numbers
17:39itistodayand identical? just compares the pointer values
17:40chouseridentical? is about 10x faster than = for me.
17:40chouseroh. when the answer is false, anyway.
17:41itistodayhmm... i'm using the git checkout from git://github.com/richhickey/clojure.git
17:41itistodayalpha of 1.1.0
17:41hiredmanit's possible the jvm has some kind of scary optimizer for primitive comparisons
17:42hiredmanitistoday: what are you using identical? for?
17:42itistodayor... perhaps it's the other way around, it has some kind of scary inefficiencies in comparing pointers?
17:42itistodayhiredman: i'm just learning
17:42itistodaywas experimenting with: (time (dotimes [n 100000000] (identical? 3 3)))
17:43itistodaywanted to see the various comparison functions in clojure and what the differences were
17:43hiredmanso you aren't actaully doing anything with it
17:44itistodayi'm not "actually doing" anything with clojure yet, but i hope to
17:44itistodayand it seems like identical? could be a very useful function to know about
17:44hiredmannot really
17:44Chousukeit is useful, but it's mostly for optimisation
17:44itistodaywell, comparing things for equivalency is pretty common
17:44hiredmanI don't thing I've ever used it
17:44hiredmanitistoday: that is what = is for
17:45Chousuke,(identical 3 3)
17:45clojurebotjava.lang.Exception: Unable to resolve symbol: identical in this context
17:45Chousuke,(identical? 3 3)
17:45clojurebottrue
17:45Chousuke,(identical? 3 (long 3))
17:45clojurebotfalse
17:45Chousukeyou need to be *very* careful with it.
17:45chouser,(identical? 3 (Integer. "3"))
17:45clojurebotfalse
17:45itistoday,(identical? 3 (int 3))
17:45clojurebottrue
17:45itistodayChousuke: i know
17:45hiredmanclojurebot's source and the checkout of ring I have laying around both don't have any any calls to identical?
17:46hiredmancompojure is also free of calls to identical?
17:46chouserI've sometimes used == instead of = for optimization, but never resorted to 'identical?'
17:46chouserI think I've only ever used 'identical?' for sentinel comparisons.
17:46itistodayi just saw hickey use it in his talk on sequences, so that's where i know of it
17:47Chousukehmm
17:47hiredmanwell, that must be the only place it's used
17:47Chousuke,(identical? :foo (keyword "foo"))
17:47clojurebottrue
17:47itistodaylol
17:47ChousukeI think that's guaranteed :)
17:47Chousukeso identical? should be okay for keyword comparisons at least.
17:48hiredmanbut why?
17:48itistodaythey're singletons?
17:48kotarak= does a == anyway?
17:48itistodaykotarak: no
17:48itistoday== is for numbers, it calls something else
17:48hiredmanitistoday: not why is that true, why bother to use identical? on keywords?
17:48kotarakitistoday: I mean the Java ==
17:48itistodayhiredman: ah
17:48chouser,(let [not-found (Object.)] (if (identical? not-found (get {:a nil :b false :c 1} :d not-found)) "not found" "found it"))
17:48clojurebot"not found"
17:49itistodaykotarak: = calls .equals
17:49itistodaynewbie question: what does (Object.) mean?
17:49hiredmanclojurebot: new
17:49clojurebotnew Class(x) is (Class. x)
17:49itistodayah, shorthand for (new Class)?
17:49Chousukeyeah
17:49itistodayk thanks
17:52kotarakitistoday: The first thing = does in Util/equiv is checking Java ==
17:53mrpikawhat's the difference between symbols and keywords?
17:53mrpikaaren't they pretty much the same thing?
17:53kotarakmrpika: keywords evaluate to themselves
17:53kotarak,:foo
17:53clojurebot:foo
17:53kotarak,foo
17:53Chousukealso you can have multiple instances of the same symbol
17:53clojurebot5
17:53Chousukekotarak: haha, got lucky.
17:53kotarakAnd hence Symbols can carry metadata, while keywords cannot
17:54mrpikawhat's the significance of having multiple instances?
17:54kotarakmrpika: metadata
17:54mrpikaand as for the self-evaluation, why not just get friendly with the quote?
17:54hiredman,(prn 'f)
17:54clojurebotf
17:54hiredman^- how do you read that back in?
17:54Chousukemrpika: it's not as nice if you're using keywords as map keys :)
17:55kotarakmrpika: print a keyword and read it back, you get the same. Read with hiredman does and see the problem with Symbols.
17:55itistodaykotarak: thanks, didn't know that. (though i thought you meant clojure's ==, not java's ==)
17:55Chousukeactually
17:55Chousuke,(read-string "f")
17:55clojurebotf
17:55Chousukeis there a problem? :)
17:55kotarakitistoday: I tried to clarify that...
17:55mrpikaokay
17:55mrpikai see the point
17:56mrpikathanks, been wondering about that for a while
17:56itistodaykotarak: ah, i see that, sorry! :P
17:56mrpikai've never seen a keyword in scheme
17:56Chousukemrpika: I guess keywords are mostly a convenience
17:56kotarakmrpika: there are no keywords in Scheme.
17:57Chousukemrpika: you could do without them, but why should you. they're great for maps
17:57mrpikai know, that's why i wondered about the usage in lisp
17:58hiredmancommon lisp has them, I think
17:58mrpikayeah
18:01itistodayhey i just found something really cool, check this out:
18:01itistoday,(def x =)
18:01clojurebotDENIED
18:01itistodayarg!!
18:01Chousukeheh
18:02Chousuke,#=(def x #=(eval =))
18:02clojurebotEvalReader not allowed when *read-eval* is false.
18:02Chousukeooh, yay
18:02Chousukeit's fixed.
18:03Chousukeitistoday: so what's cool?
18:03itistoday,(x = x)
18:03clojurebotjava.lang.Exception: Unable to resolve symbol: x in this context
18:03itistoday,(def x =)
18:03clojurebotDENIED
18:03itistodayeh
18:03Chousukeheh :P
18:03itistodayyou get the idea ;-)
18:04itistodayor (= x =) ; <-- TIE fighter
18:05mrpika(let [x =] (x = x))
18:05mrpika,(let [x =] (x = x))
18:05clojurebottrue
18:05itistodaythanks :-)
18:05itistodayshoulda seen that
18:05mrpikanp
18:05itistodayChousuke: what did you do there? #=(def x #=(eval =))
18:06itistodaycan't figure it out from here http://clojure.org/reader
18:08itistodayum... what would happen if i typed ,(while true)?
18:08itistodaywould clojurebot die?
18:09itistodayif anyone doesn't want me to type ,(while true) speak now or forever hold your peace
18:09whoppixitistoday, it's most likely secured against that kind of simple attack :)
18:09itistodaylet's see...
18:09itistoday,(while true)
18:09itistoday,(+ 1 1)
18:09mrpikais there an admin that can restart it
18:09clojurebotExecution Timed Out
18:09mrpika?
18:09clojurebot2
18:09itistodayoh nice
18:09mrpikanice
18:10mrpikalong running fuctions prohibited
18:10mrpikafunctions
18:10whoppixitistoday, most eval bots of that kind fork off, cage the process in a chroot/jail/vm, restrict it's filehandle/ptrace it, put an alarm to kill it after a while, something more tricky like that.
18:10itistodaywhoppix: thanks, good to know
18:11whoppixitistoday, have a stab at buubot in #buubot, it evals about 20 different languages (not clojure yet, though)
18:11itistodaywhoppix: it auto-detects the language?
18:12whoppixitistoday, nope, you have to tell it what language you want.
18:12itistodaygotcha
18:12itistodaywill do some other time, gotta get back to reading clojure docs
18:12whoppixHave fun
18:12itistodaywill do
18:14mrpikawould there be any value in having a reader macro for dosync
18:14mrpikaso instead of (dosync alter ...) you could just type %(alter ...)
18:14mrpika?
18:14mrpikaor similar
18:15Chousukemrpika: often dosync contains multiple expressions so a reader macro like that wouldn't be very useful
18:15Chousukeand I don't think dosync is so special that it needs a reader macro :)
18:15mrpikaah
18:33LuytI guess that as easy it is to use java libraries from within clojure, it's also easy to use clojure functions from java?
18:34javajeffLyut - there are some examples of calling clojure from Groovy at http://groovy.codehaus.org/Calling+Clojure+from+Groovy
18:34itistodayhow does class? work?
18:35itistoday,(doc class?)
18:35clojurebot"([x]); Returns true if x is an instance of Class"
18:35itistodaywhat class..?
18:35itistodayclojurebot: class
18:35clojurebotTo use an inner class Foo.Bar, import it with (import 'Foo$Bar), and you can refer to the class as Foo$Bar
18:36faux,(class 123)
18:36clojurebotjava.lang.Integer
18:37itistodaynot class but class?
18:37itistodayheh, that sounds funny if you read it as a question
18:37Luytjavajeff: Thanks for the pointer.
18:38fauxah well that would be a comparison to the class Class
18:41itistodayfaux: ah thanks, how do you do instanceof?
18:42kylesmithdoes anyone know the status of the rdf stuff?
18:43fauxitistoday: look at isa?
18:43itistodayfaux: thanks
18:44itistodaythat looks like it
18:45kotarak(doc instance?)
18:45clojurebot"([c x]); Evaluates x and tests if it is an instance of the class c. Returns true or false"
18:45kotarak,(instance? String "foo")
18:45clojurebottrue
18:45kotarak,(isa? String "foo")
18:45clojurebotfalse
18:46kotarak,(isa? String (type "foo"))
18:46clojurebottrue
18:46itistoday:-), i was just about to say...
18:47fauxmuch better
18:48itistoday,ints
18:48clojurebot#<core$ints__6041 clojure.core$ints__6041@100e398>
18:48itistodayerr
18:48itistoday,(doc ints)
18:48clojurebot"([xs]); Casts to int[]"
18:48itistodayhow do you use that?
18:48Luyt,(doc doc)
18:48clojurebot"([name]); Prints documentation for a var or special form given its name"
18:51kotarak,(ints (to-array [1 2 3]))
18:51clojurebotjava.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [I
18:52kotarak,(ints (into-array Integer [1 2 3]))
18:52clojurebotjava.lang.ClassCastException: [Ljava.lang.Integer; cannot be cast to [I
18:52kotarakhmmm...
18:52kotarak,(ints (into-array Integer/TYPE [1 2 3]))
18:52clojurebot#<int[] [I@1347991>
18:52Luyt,(println (str "codepad" "." "org"))
18:53clojurebotcodepad.org
18:53itistodaykotarak: and then what do you do with the output of ints?
18:54kotarakitistoday: (defn foo [x] (let [x (ints x)] ...)) ... (foo (into-array Integer/TYPE [ 12 3])) might be a use
18:54hiredman~performance
18:54clojurebothttp://clojure.org/java_interop#toc46
18:54kotarakitistoday: ints avoids boxing in tight loops.
18:56itistodayah gotcha
18:56itistodayhiredman: thanks
18:56itistodayso aget is what i was looking for
18:56itistoday,(doc aget)
18:56clojurebot"([array idx] [array idx & idxs]); Returns the value at the index/indices. Works on Java arrays of all types."
18:57itistodaypeace all
22:09iceyso have any of you guys switched over to using clojure as your primary web stack yet?
22:51solussdI'm trying to configure a clojure dev environment in emacs using 'M-x clojure-install'. After it sets everything up and I run "M-x slime" it works, until I restart emacs. Any suggestions?
22:52tomojdid you add the stuff to your .emacs?
22:57solussdwhat is "the stuff"? :)
23:07solussdThe wiki (http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Emacs_.2F_inferior-lisp) doesn't talk about adding anything to my .emacs when using 'clojure-install'.
23:16arbschtsolussd: supposedly, when clojure-install completes, it will give you some instructions on what to add to your emacs init file
23:17solussdI'll run the install again and see if I can catch that.
23:18arbscht"Add a call to \"\(clojure-slime-config\)\"
23:18arbschtto your .emacs so you can use SLIME in future sessions."
23:18arbschtsomething like that
23:23solussdyep. that was it. thanks!
23:24solussdOne more question- I'm still not able to "C-c C-e" to evaluate a line. When I run that I get "Slime Eval:" instead of it running the sexp in the repl
23:24arbschtC-c C-c to evaluate a top level form
23:25arbschtwell, compile and eval
23:25arbschtwell, compile and eval are different
23:25arbschttypically you compile from a buffer and eval in a repl
23:27solussdI'd like to have the behavior rich hickley has set up in emacs- where he evaluates a line in this source file in the repl by hitting a key combination
23:27arbschtC-M-x will eval a top level form
23:29solussdexcellent. thanks again
23:29arbschtC-x C-e will eval the last expression
23:30solussdah, that's what i was looking for