#clojure logs

2010-03-23

00:02danlarkintechnomancy: it does not
00:02technomancydanlarkin: even with clean+deps?
00:06danlarkinany particular task after which it's supposed to hang?
00:07technomancyhrm... try deps in the sample project
00:07technomancyor test in lein itself
00:08danlarkinworks just fine
00:08technomancyintelesting.
00:08technomancythanks for checking.
00:09danlarkinheh I was just about to say I must have pulled wrong, github says the last commit was 11 minutes ago but git log says the last one was yesterday... but then I realized it's 8 after midnight :-o
00:10technomancy...
00:10technomancyjust set your clock to PST and be done with it man... =)
00:10technomancyor PDT I guess... /me grumbles
00:10TheBusbyor set everything to GMT and leave time zones for the farmers
00:12technomancyyes
00:12danlarkin*ahem* I think you mean UTC :-D
00:12technomancyI want to set my time zone to Pitcairn island time since it's like PST but it stays year round without any shenanigants
00:13technomancyhttp://en.wikipedia.org/wiki/Pitcairn_Islands
00:13TheBusbycouldn't you just set it to PST (disabled auto DS if required)?
00:14technomancyTheBusby: I don't know if you can disable DST in most systems
00:15TheBusbyI've done it a a fair amount in *NIX
00:15TheBusbydon't know about Oracle or Windows though
00:17technomancyphones might be an issue too
00:17radsgetting a weird error when trying to use some of my project's files in a local leiningen task: Exception in thread "main" java.lang.VerifyError: class clojure.contrib.string$loading__4789__auto____3 overrides final method meta.()Lclojure/lang/IPersistentMap;
00:17radsthere is a (:require [clojure.contrib.string :as s]) in there, but I'm not sure why it's causing an error
00:18TheBusbyer, phones, cellphones in particular use your carriers time usually. Yeah that would likely be a problem
00:19TheBusbyif you're going to go off of whatever your local time is though, might as well go whole hog and use UTC ;)
00:19hiredmanrads: your contrib and clojure jars are out of sync
00:21radsoh
00:22radsleiningen is probably using clojure 1.1.0 when I have 1.2.0 in my project.clj
00:23hiredmanshould be using what is in your project.clj
00:23hiredmanfor 1.2.0 you should be using a snapshot contrib too
00:24radsyeah
00:24radsit works fine for lein swank, but for my user-defined task I get this: {:major 1, :minor 1, :incremental 0, :qualifier }
00:25radssame thing for lein repl
00:25hiredmanwhat version of lein?
00:25hiredmanI know the repl task used the wrong version in .5, it might still
00:25radslatest version
00:26radsfrom github
00:29radswhen I use DEBUG=1, it seems that the clojure jar from my leiningen checkout is in front of my project's clojure.jar in the classpath
00:37rads_any idea how to get lein to use the correct version?
01:30headiushey, someone confirm that I understand the example here: http://clojure.org/runtime_polymorphism
01:30headiusdefmulti defines an aggregate method given a selector function
01:31headiusin this case, that function takes the two incoming arguments and pulls the species from each, returning that tuple
01:31headiusthe tuple is then used to do a search of some table in the multimethod build up by subsequent defmethods
01:33headiuslooking at defmulti impl now
01:34headiuslooks like clojure.lang.MultiFn does the actual aggregation
01:37headiusquiet in here at night
01:40psykoticheadius: yeah, you got it right
01:40headiusgood
01:40headiusMultiFn looks similar to various dyncall caching structures in JRuby (and other dynlangs
01:41headiusis it also fair to say that normal function dispatch isn't really dynamic?
01:41headiusif I understand it right, clojure can statically see the set of functions available at any point
01:41psykoticthere's a level of indirection
01:41psykoticwhen you call a function defined at the top level of a namespace, it actually dereferences a variable at each call site
01:42psykoticbut yes, it has to see at least the symbol entry in the relevant namespace, if not its value
01:43psykoticthat's why you need to use a dummy def (or the shorthand declare macro) if you want to have mutually recursive function definitions
01:43headiusso the complexity of locating a function is always constant
01:44headiusin the normal non-multi case
01:44psykoticright, it does the "hash" lookup at compile time, but the deref at run time
01:44headiusI'm doing a talk tomorrow on invokedynamic, wanted to talk about where in various languages dynamic comes into play
01:44psykoticso it doesn't statically resolve the actual call
01:44headiusso the deref could initially be slow but then it never changes?
01:45headiusit's like a "once" dynamic lookup?
01:45psykoticwell, you should think of the phase distinction like this:
01:45psykoticat compile time, symbols are resolved to vars (which are first-class objects that have a root binding and can be further rebound on a per-thread local basis)
01:46psykoticwhen a variable is evaluated at run time, it is dereferenced. so it's like a cheap thread local storage deref kind of operation, although there is a branch-taken-expected fast path when there is only a root binding and no thread-local rebindings
01:47psykoticthe net effect of this is that you can reload function and variable definitions at runtime and existing referrers will pick up the difference
01:47psykoticso it's still perfectly dynamic in that sense
01:48headiusso a function within a function is stuffed into that outer function's binding
01:49psykoticnot quite
01:49psykoticinner functions just generate new subclasses of AFn that are then newed (passing the closed-over values from the scope) by the outer function referencing it
01:50psykoticthat doesn't really figure out into the namespace binding at all
01:50psykotic*figure into
01:50headiushow do calls to the inner function get resolved compared to calls to top-level functions?
01:51psykoticwell, the inner function is statically known, right? you don't need any indirection like for top-level functions.
01:52headiusso only top-level functions have to be dynamically resolved because new files can be loaded in that aren't available at initial compile time?
01:52psykoticwell, more to the point, old files can be reloaded
01:52headiuswhereas a function is bound to a single file and can be statically mapped out for calls within that context
01:52headiusok
01:53psykoticCompiler.java is actually really readable (even if it isn't very orthodox Java style)
01:53headiusnone of clojure's java is orthodox java style :)
01:53psykoticright :)
01:53headiusit's almost like it was written by someone who likes lisp
01:53psykoticyeah, crazy that
01:53headiusthanks, I think I get it all now
01:53psykoticthe whole symbol/var distinction is something that's quite different about clojure from scheme or common lisp
01:54psykoticso it's a little confusing at first
01:54joshua-choiI for one am very glad for it
01:54headiusI'm more interested in the plumbing than the language anyway
01:54psykoticright
01:54psykoticbut if you try to map it to what you know, you might be confused, that was my point
01:55headiusa part of me is jealous of the simplicity compared to what we have to do in jruby, where everythign is dynamic all the time
01:55headiusbut that's part of the fun
01:55psykotici don't know much ruby, but i know python and i guess resolution of variables is quite similar?
01:55psykotici.e. hash tables, all the time :)
01:56psykoticwith that kind of approach, when you redefine a variable, you actually update the hash table
01:56psykoticin clojure, you don't touch the hash table, you only update the var which the hash table points to
01:56psykoticthe first time you try to something something, it creates the var, etc
01:57psykoticerr, you try to def something
01:57headiuslocal variables are statically determined
01:57headiusinstance variables are hash-like, but jruby call-site caches both methods and ivar locations
01:57psykoticright but what about modules?
01:57headiusour ivar logic is probably similar to how clojure handles vars
01:58headiuswhat about modules?
01:58psykoticone thing i dislike about python, re: dynamic development, is that when you import things directly (i.e. from foo import x, y, z), you actually get the values directly at the time of import
01:58psykoticwhich means that if you reload foo and update x, y, z, you need to reload this client module as well
01:58psykoticif you only import foo and reference x, y, z as foo.x, foo.y, foo.z, then you don't have to reload
01:59psykoticit's an annoying difference
01:59headiusahh
01:59headiuswell python is pseudo-OO to me
01:59psykoticwell, i thought ruby worked the same
01:59headiuscompare to ruby where importing will define classes, but those classes are still mutable
01:59psykoticif i import all symbols directly from another module, do i get the values imported into my namespace?
01:59headiusno
02:00headiusthey go into constant tables, but "constant" lookup is dynamic
02:00headiusclass Foo; end is equivalent to Foo = Class.new { }
02:00headiusFoo becomes an entry in some lexical/hierarchical constant table
02:01headiusso if you're talking about including a module into a class, to get its set of functions...
02:01psykoticright
02:02headiusthe functions aren't copied in; a stub is inserted into the class hierarchy with a reference to the module
02:02headiusso the module can continue to be mutated
02:02psykoticpython's problem here isn't really about OOness. it's that it "flattens" imports. if i do from foo import x, my module gets a 'x' : foo.x (where foo.x is resolved to a value at import time). after this, it doesn't know that x came from x, it's been resolved away.
02:02headiusmm sure
02:02psykoticso, really, even if i'm just trying to get a shorthand for foo.x as x, it subtly changes the semantics
02:03headiusyeah, there's nothing like that, really
02:03headiusa bare x would either be a variable or a call, depending on context
02:03psykoticokay, that's good
02:03headiusif it's a variable, it's statically determined to be a variable always
02:03headiusif it's a call, it's dynamically looked up, always
02:03psykoticwell, what if the variable says x = 42 originally, but it's later redefined?
02:03psykoticthat's what i'm talking about
02:03headiuscan't be
02:04headiusonce there's an x = whatever in a given context, x is treated as a variable for the rest of that context
02:06psykoticbtw, you mentioned call-site caching, i guess you can't do it inline due to the direct and indirect cost of regenerating bytecode? in machine code, you can update the direct target address of a call by just mutating that part of the call instruction the same way you mutate any var.
02:07headiusit's pretty close to inline
02:07LeNsTRhi all
02:07headiusthere's a trampoline
02:07headiusa dynamic call is normally a call to CachingCallSite.call, with an instance of CachingCallSite constructed per call site in code
02:07headiuseach site gets its own monomorphic cache
02:08headiuswe also have in-hierarchy caching for fail cases, so it should eventually be 1 hash hit at worst and one object comparison at best
02:08headiuscomparison as in identity
02:08headiusthere's flags to remove the trampoline and pull the method object all the way back to the actual Java call site, so it can be inlined
02:08psykoticbtw there's a fairly recent concept in clojure called protocols, which is an interesting compromise between multimethods and more traditional java style OO
02:08headiusbut they slow down JVM without tweaking inlining thresholds
02:09headiusI heard something about protocols a few months back
02:09headiushave not looked into it
02:09psykoticthey have the post-hoc open extensability of multimethods, and they also interop with interfaces nicely where possible
02:09headiusfor all the pain it causes, ruby's all-dynamic-all-the-time is the least of our problems...jruby's dynamic dispatch is comparable to interface dispatch in java, overhead-wise (assuming a successful cache)
02:10psykoticbut they're dispatched only on the type (in an extended sense--not just jvm types but also clojure's own dynamic "type tag hierarchy",) of the first argument
02:10headiuseven ruby to java dispatch is generally no worse than a single hash hit
02:10psykoticthat's nice
02:10psykoticso if that's the least of your problems, what's the biggest?
02:10headiusI want to add clojure's cheat of specifying a signature
02:11psykotictype hints?
02:11headiusahh, the biggest problems are fixnums (value types, etc...clojure has the same problem), and what I call "out of band data" from call to call, which forces us to stand up heap structures
02:11headiusin the grand scheme of things, value types would probably be the biggest boost
02:11headiuspsykotic: yes, type hints
02:11psykoticor the 'cheap-ass escape detection' that cliff mentioned in the 2008 jvm talk
02:12headiusyeah, that never has worked well enough
02:12psykoticwhich should have much the same net effect as value types, if it works
02:12headiusand it depends so heavily on inlining
02:12headiusno inlining, and it's worthless
02:12psykoticwell, i think he was proposing a special case of escape analysis, not the current thing which never works :)
02:12headiussure
02:12psykoticand yeah, you need inlining in general to get visibility
02:12headiusI can get dyncalls to inline all over the place, but escape analysis doesn't eliminate anything in its current incarnation
02:12psykoticare value types on the table potentially?
02:13headiusthey're probably the next highest item not being worked on
02:13psykoticfor the jvm i mean
02:13headiuseveryone needs them, really
02:13headiuseven java
02:13headiusdynlangs need them worse though
02:14psykoticso, the typical kind of case where there is a lot of "short range" heap allocing is when you run a list in lieu of multiple return values
02:14psykoticerr, return a list
02:14psykotici assume that's what you mean by out of band data?
02:14headiussomewhat...ruby has some implicit "out" values for certain calls, and the current design of JRuby's call protocol doesn't provide a channel through which to pass them
02:15headiusso we have to allocate a heap structure, stuff it into a thread-local stack
02:15headiusthe unfortunate part is that we don't always know when that data is really needed, since we only have the names of methods to go on
02:15psykotichave you thought of doing your own object pooling?
02:15headiusso we use those known method names as a trigger that says "I might need OOB data"
02:16psykoticright
02:16headiusyes, and we do reuse some fixed-size structures
02:16headiuson the worst end, there's eval and friends, which we full deopt for
02:18psykoticyou might know a good answer to this--
02:18psykotici've been talking to some people about profiling clojure code, and i keep hearing (i'm new to the jvm) that profilers and hotspot interfere so much that you can't really trust the profile data
02:18headiusI don't think that's generally true
02:19psykoticokay, that's a relief
02:19headiusthe problem with clojure is that profiling method performance is not going to produce great results, since as I understand it clojure usually suffers more from allocation costs
02:19headiuswhich don't really show up in normal method timing profiles
02:19psykoticotherwise i'm not really sure how useful profiling would be, assuming you aren't bound by io or whatever
02:19psykoticright
02:19headiusfor example, if I profile numric algorithms in JRuby, the results are not really helpful
02:19psykoticand the cost of GC churn is usually very indirect
02:19psykotice.g. cache streaming
02:19headiusbecause the cost is the fixnum allocation
02:19headiusright
02:20headiusand actually, it's probably not even GC
02:20headiusit's just the allocations
02:20psykoticshouldn't that just be a pointer increment for gen 0?
02:20headiuswe had someone run numbers on how much allocation we were doing, and even though GC took almost no time at all we were requesting chunks of heap at a rate that saturated the memory pipeline
02:20headiusit was all young data, so nearly free to collect
02:20headiusbut there's a cost to getting it in the first place
02:21psykoticright, that's what i meant about cache streaming
02:21headiusyeah
02:21headiusGC times were less than 1% of execution
02:21headiusit was all spent waiting to get the objects
02:21psykoticvalue types would definitely be a huge win here
02:21headiusright
02:22psykoticsince they're on the stack, so you just keep hitting the same lines
02:22headiuswe can almost compete with implementations that have true fixnums, which is mind-boggling
02:22headiusif we had value types, we'd smoke them
02:23psykotichow many people are using jruby for fixnum heavy apps though?
02:24headiusnone...and anyone using any ruby impl for numerics is probably kidding themselves
02:24psykotici was working with lau the last few days on some stuff that's super float heavy, and we would definitely benefit there
02:24headiuswe provide easy ways to call out to java or duby and that should be enough for anyone
02:24psykoticheh
02:24headiusno amount of value type or fixnum magic is going to compare to actual primitive math
02:24psykotici actually have this DSL-like thing i wrote around objectweb.asm that's basically sexpression java, but with macros
02:25headiusheh, have you seen bitescript?
02:25psykoticno?
02:25headiushttp://github.com/headius/bitescript/tree/master/examples/
02:25headiusit's my ruby DSL for ASM bytecode
02:26psykoticnice
02:26headiuser I mean org.objectweb.asm
02:26headiusbut yeah
02:26psykotici call mine demiurge but it still isn't ready for public viewing :)
02:26headiusit's the backend for duby as well
02:27headiusthere's a primitive macro system, but I haven't used it for much
02:27psykoticthe nice thing is that i just hook into clojure's macros
02:27psykoticah, mine is slightly higher level
02:28headiusI just use ruby's blocks, mostly
02:28psykoticfor example, you don't need aload/lload if you've specified types, you can just use plain load
02:28headiusmacro :blah do |args| ... do some bytecode whatever here; end
02:28headiusthen blah foo, bar just calls it
02:29psykoticit started out as a pretty straight sexpression transcription of objectweb asm but as i started to add convenience features like that, i realized i eventually had sexpression java
02:29headiusmmm
02:29psykotic(i still don't handle generics at all though)
02:29headiusinteresting
02:29headiusduby's a similar sort of thing
02:29headiusruby syntax for java
02:29headiushttp://github.com/headius/duby/tree/master/examples/
02:30headiusit's a full type-inferred language though
02:30psykoticyeah, mine is still intended for embedding, rather than standalone use
02:30psykoticlike you might have a tight inner loop
02:30psykoticyou can define it right there inline with demiurge
02:31psykoticit will even capture lexical scope and pass it in to the generated java class
02:31headiusmmm sure
02:31headiusI want to do something similar with duby
02:31headiusyou can define duby methods in a ruby class, but that's not exactly inline
02:31psykotic(clojure has a neat &env magic argument for anonymous functions that gives you access to the lexical bindings in the context, which i use for this)
02:32psykoticor i should say, it reifies the context
02:33psykoticbut yeah, my main goal is to minimize the discontinuity between clojure and demiurge for this kind of 'inline' use
02:33psykoticwith the jvm it's obviously a lot better than the typical ffi thing in the c world
02:33psykoticbut it could still be improved with this kind of thing, imo
02:34psykoticduby looks neat, btw
02:35psykoticis it a proper subset of ruby?
02:35headiusno
02:35headiusit's not ruby at all
02:35headiusjust ruby syntax
02:35headiusI'm trying to map as much of ruby's syntax as I can to "java" without introducing any runtime library
02:35headius.duby file goes in, .class or .java file comes out, and that's it
02:36headiusas a result, you can use duby for anything you can use java for
02:36psykoticbtw i'm curious what the binding time is for jruby for jvm interop
02:36headiusgwt, android, java ME
02:36headiusfor java calls, binding time is the same as ruby calls
02:36psykoticso every time you reference a jvm method it does full from scratch reflection?
02:37headiusno
02:37headiusthe method object cached aggregates all signatures for a given name
02:37headiusgrouped by arity
02:37psykotichmm
02:37psykotici wonder if clojure would benefit from call-site caching from statically unresolvable jvm calls
02:38headiusa second level of caching uses an aggregate of the incoming object's classes' hashcodes
02:38headiusso once you've called a given named method on a java object with all the types you're going to use, it should be a single hash hit
02:38psykoticin most cases where performance matters, people tend to add type hints until the compiler stops complaining when *warn-on-reflection* is set
02:38psykoticgotcha
02:38headiusyeah
02:39headiuswe still use reflection, but ruby-to-java calls are nearly as fast as java.lang.Method invocation can be
02:39headiusI also have some code to generate non-reflected stubs
02:39psykoticright, so you can say "generate stubs for this class"?
02:39psykoticand then call through them?
02:39headiusyes
02:40headiusI'll be using them for jruby on android, where reflection costs a lot more
02:40psykoticbtw one thing i've been wanting to play with is something like that combined with a 'type mapping' facility
02:40headiuselaborate?
02:40psykoticfor example, right now clojure has a "be generous in what you accept, strict in what you hand out" with respect to the jvm
02:41psykoticfor example, there's a special case code for adapting jvm strings, etc, to clojure sequences
02:41psykoticbut of course you can't pass a lazy character sequence (for example) to some jvm method expecting a java string
02:41psykoticso i've been thinking of writing code that generates stubs for classes while passing certain arguments through some kind of user-specifiable type mapping
02:42psykoticas long as you adhere to this policy i mentioned, you only need to do it for arguments, not return values
02:42psykoticit would be a nice way of making some java apis more "clojure-friendly" without manual work
02:43psykotici'm not sure what you do in jruby
02:44headiusahhh
02:44headiusjruby is moving toward user-definable object marshalling for java dispatch
02:45headiuscurrently it calls toJava on each object, and some objects know how to convert (like Strings, Arrays, Fixnums, etc)
02:45headiusa future version will also dispatch to ruby-land "to_java" on the object if it's present
02:45psykoticmy thinking was that you sometimes want this to be done per api rather than globally
02:45headiusso you can add your own java coercion protocols
02:45headiushmmm
02:46headiusyes, I suppose I could see that
02:46headiuscall_with_coercer
02:46headiusor be able to decorate a given call with a specific coercion protocol
02:46psykoticfor example, if you're clojurifying some c-like api like opengl where there are int parameters that are bit flags of things, you might have a special adapter that takes a list of keywords (corresponding to the different flags), maps the keywords to the right powers of two and ORs them together
02:46headiusgiven method, rather
02:46headiussure
02:46headiusin jruby you can just add those things to the class though
02:47headiusreopen the java class, alias methods, add methods, whatever
02:47headiusthe protocols could be added that way
02:47psykoticah, clojure is pretty strict about separating the jvm and clojure worlds
02:47psykoticyou would have to create stubs to do something like this
02:47headiusclass java::lang::System; def self.[](name); getProperty(name); end; end
02:47headiuspretty straightforward
02:48psykoticnice
02:48headiusyeah, I'm sure clojure doesn't maintain its own method tables for java classes like we do
02:48psykoticthis makes me think that there might be a way of extending the current protocol design to accommodate something like that
02:48headiusonce you maintain your own metaclass/method tables, you can add things
02:48psykoticalthough it would require a redesign of the interop system for sure
02:49headiusa little bit goes a long way
02:49psykoticheh
02:49headiusyou don't need to go crazy like groovy
02:49headiushmm, 4 minutes on my battery
02:50headiusI hope my 1-hr flight tomorrow is enough to finish a completely new hour presentation on invokedynamic
02:50headiussigh
02:50psykoticanyway, nice talking to you, i hope some of the info about clojure's vars and namespaces was helpful
02:50headiuswhy do I put these things off
02:50headiuspsykotic: yes, it was very helpful, thank you
02:51headiusbtw
02:51headiusit might be possible to repurpose duby's backend with different syntaxes
02:51headiusI've been toying with the idea
02:51headiusanything that could produce a duby AST would just work
02:51headiusleverage the same type inference, .java and .class backend
02:51headius(and there's a C# backend out there somewhere)
02:52headiusanyway, I have to go
02:52headiusnite
02:52psykoticbye
03:24LauJensenMorning team
03:25hoeckgood morning Lau
03:33psykoticit seems like #=/EvalReader isn't really EvalReader as much as ApplyReader :)
03:34psykotic,#=(symbol "foo")
03:34clojurebotEvalReader not allowed when *read-eval* is false.
03:35psykoticanyway, it will allow things like (symbol "foo") where you have a single function application with already evaluated arguments, but you can't do something like (symbol (str "foo "bar")) because the (str "foo" bar") is just passed to symbol unevaluated as a persistentlist
03:38psykoticaha, you can just use #= recursively: #=(symbol #=(str "foo" "bar")) will work
03:41LauJensenpsykotic: What docs were you reading RE #= ?
03:41psykoticsource code
03:41psykoticEvalReader in LispReader.java
03:42psykoticit's intended for read time evaluation, so you can do things like #'#=(symbol "myvar")
03:42psykotic(yes, i know about resolve)
03:43LauJensenok - Just wanted to make sure there wasn't an unclear doc floating
03:44psykoticdid anyone see this? http://ketain.blogspot.com/2010/03/clojure.html
03:44psykoticit's... interesting code. heh.
03:45LauJensenFun experiment
03:46psykoticit's a not a bad idea for a project but the code is awful
03:47psykoticjust the parser is an insane mix of regular expressions, ad hoc "let's count the parentheses separately to see if they are balanced" like things, exception-wrapped Integer/parseInt calls, etc
03:52psykoticbtw what's the convention in clojure when you have a cond where you want to put the test and result parts of a clause on separate lines? do you indent the result so it stands out from the test?
03:54LauJensencgrand: does, if possible I keep each condition and body on the same line
03:54psykoticme too
03:54psykotici'm asking about cases where that would be harder to read than splitting
03:55LauJensenAnd also, if its the same predicate being used over and over, condp is preferred
03:55psykoticyes
03:56psykoticincidentally, i really wish condp took an actual predicate as argument rather than a binary relation. the binary relation case would be subsumable as (condp #(= foo %) x ... y ... z ...)
03:56LauJensenThat would be more intuitive
03:57cgrandLauJensen: what are you talking about?
03:57psykoticcgrand: he meant to tell me
03:58LauJensencgrand: yea sorry about that - I was just commenting on your style of identation in cond-statements
03:58cgrandha ok, I can go back to my accounting then :-/
03:58psykoticcgrand: sounds like fun!
04:00LauJensenpsykotic: I think there's still an entire cond module in contrib though
04:00psykoticyeah, there's a predicate (rather than binary relation) version called something i can't remember
04:00LauJensencondb ?
04:03psykoticclojure.contrib.cond only has cond-let
04:03psykotici can't remember the name but i believe i saw it
04:03LauJensenoh
04:03psykoticcontrib is a really strange mix :)
04:03LauJensenMaybe I'll write (switch ...)
04:04psykoticthe closest thing to c's switch is case, so that might be confusing
04:04LauJensenNaah
04:06psykoticmaybe call this thing pcase :)
04:06psykoticthere's already (deprecated) fcase is like condp (takes a binary relation, etc)
04:07zmilai use the same identation pattern for cond as in the given blog. if not fit in one line, then the second part - on new line and indented
04:07psykoticzmila: yeah, that's what i'm doing too
04:08psykoticmost other lisps group each clause with ( and ), so you don't need it in those for readability
04:10zmilabut i think this very long cond is the subject to use some way to defmethod
04:11psykoticoh, i don't mean his code
04:11psykotici have a simple three-clause cond but one of the tests is long enough that it looks better with the result broken into its own line
04:14psykoticscrew it, two nested ifs look better here
04:56licoresseIn emacs clojure-mode, I absolutely loathe the way indentation works. How can this be set to, say 3 spaces, and always stick to this?
04:57licoresseJust reading http://ketain.blogspot.com/2010/03/clojure.html, and I want to have indentation like it...
04:58licoressewell, I see it is not really what I want after all... :(
05:00Chousukelicoresse: 2 spaces is the lisp standard. everyone's going to think you're weird if you deviate from that :P
05:00licoresseyeah, 2 spaces is fine, just as long as M-C-q works
05:01licoresseworking with proxy defintions, the indentation gets all messed up
05:02Chousukeparameters are usually aligned, but special forms and macros get special indentation.
05:03licoresseAm I weird if I don't like special forms having special treatment?
05:03Chousukethey would indent way too much if they didn't
05:03Chousukewould you like defn to indent so that the code aligns with the parameter list? :/
05:04licoresseno
05:04licoresseI would like each indent to be 2 (or whatever) spaces, thats it!
05:04Chousukethe indentation on that page doesn't look very special to me
05:05licoresseChousuke: my fault, I was skimming to fast
05:06ChousukeI think clojure-mode has a setting for context-sensitive indentation
05:06Chousukebut I don't even know what effect it has, if any
05:07licoresselooking at clojure-indent-function
05:07psykoticLicenser: what about function calls with multiple parameters broken across lines?
05:07psykoticyou want those be indented by only 2 spaces
05:07psykotic?
05:08Chousuke'clojure-mode-use-backtracking-indent it seems
05:08psykotics/Licenser/licoresse/, damn autocomplete
05:08licoresse:)
05:08ChousukeI have it disabled it seems
05:08licoressepsykotic: Everything should be 2 spaces, no special rules
05:08psykotica foolish consistency is the hobgoblin of small minds :)
05:09licoresseThen I have a small mind, thats ok
05:09licoressebacktracking indent, hmm
05:10Chousukefunction calls would be difficult to read with nonaligned parameters :/
05:10psykoticbacktracking indent, is that like haskell-mode's tab cycling?
05:10psykoticineed
05:10licoresseI'll have a try
05:11ChousukeI have no idea what that is :P
05:11licoresseSoon we will
05:21Licensergreetings my lispy friends
05:21licoressegood morning
05:21sparievmorning
05:23LauJensenMorning Licenser
05:29_invisguys Why this is always () ???
05:29_invis(def Alpha1
05:29_invis (map #((if (not (= 100 %1)) (atan (/ %2 (- L4 %1))))
05:29_invis (if (> %2 0) (/ Math/PI 2))
05:29_invis (if (< %2 0) (/ (* 3 Math/PI) 2))
05:29_invis (if (= %2 0) 0)) (range 0 61 20) (range 61 0 20)))
05:29_invis,(def Alpha1
05:29_invis (map #((if (not (= 100 %1)) (atan (/ %2 (- L4 %1))))
05:29_invis (if (> %2 0) (/ Math/PI 2))
05:29_invis (if (< %2 0) (/ (* 3 Math/PI) 2))
05:29_invis (if (= %2 0) 0)) (range 0 61 20) (range 61 0 20)))
05:29clojurebotEOF while reading
05:30_invis,(println (def Alpha1
05:30_invis (map #((if (not (= 100 %1)) (atan (/ %2 (- L4 %1))))
05:30clojurebotEOF while reading
05:30_invis (if (> %2 0) (/ Math/PI 2))
05:30_invis (if (< %2 0) (/ (* 3 Math/PI) 2))
05:30_invis (if (= %2 0) 0)) (range 0 61 20) (range 61 0 20))))
05:30licoresseeverything on one line, and no def
05:30_invisno def ?
05:30licoresse,(def jalla 123)
05:30clojurebotDENIED
05:30_invisdef Alpha1 :)
05:30_invismy clojure compile it
05:30licoresseclojurebot does not accept def
05:30_invisbut println zero
05:31_invis*nil
05:31_invis()
05:31_inviswhy this function doesnt work :(
05:32tomoj_invis: please don't do that
05:32hircuswhich function?
05:32Chousuke_invis: use a pastebin
05:32Chousukeno lisppaste here though
05:32Chousukehm
05:32Chousuke~paster
05:32Chousuke~paste
05:32clojurebotPardon?
05:32clojurebotlisppaste8, url
05:32Chousukeduh
05:33_invisemm
05:33tomojI think bots should be more self-documenting
05:33Chousukehttp://gist.github.com ... remember to pick Clojure as the language
05:33Chousukealso, really, you should use a proper function instead of the shortcut form
05:33hoeck_invis: a few things, your second range returns (), and map only maps over the smallest sequence when given multiple sequences
05:34hoeck_invis: I guess you wanted (range 61 0 -20)
05:35_invisactually I wanted Xa - coll, but here for example I paste (range ...)
05:35Chousukealso keep in mind that identifiers containing uppercase characters are not particularly idiomatic
05:36_invisok
05:37hoeck_invis: http://gist.github.com/340990
05:37_invisnow here is exception :)
05:38hoeck_invis: right, cause your first "if" returns nil and calling nil throws an NullPointerException
05:38_invisno
05:39_invisit was Double to IFN exception
05:39_invisjava.lang.ClassCastException: java.lang.Double cannot be cast to clojure.lang.IFn
05:39hoecko right, it returns a number
05:39_invishoeck: its work. ty
05:39Chousukeyes, that was because you had #((if ...))
05:40Chousukethe if expression returned a double and it tried to run that as a function
05:40Chousukebut I would still avoid using the anonymous function in that case
05:40Chousukemake it a proper one and give it a name
05:41_invisbut I use it just here, for one time
05:42licoresse_invis: it's hard to read and understand, especially when you're tired
05:42Chousukeyou can use let or letfn
05:42Chousukeor at least make the #() into (fn ...) with named parameters
05:43ChousukeIn my opinion a #() expression that has to be split on multiple lines is usually too long.
05:43_inviswhy this isnt work too http://gist.github.com/340994
05:44Chousukeyou have an extra pair of parens around the second if
05:44_invisthis if for ELSE for first if
05:44Chousukebut honestly, I can't figure out what that even does :/
05:44_invis:)
05:45Chousukethe extra pair of parens is still redundant
05:45Chousukeyou don't wrap the else expression of an if in parentheses. you just write it as you want it
05:45Chousuke(if a x (if b y :nothing))
05:46Chousukebut that's bad style by itself. (cond a x b y :else nothing) is better
05:47_inviswhat it should do http://slil.ru/28839037
05:49Chousukealso, it looks like you're doing the ifs like (if foo (something)) (if bar (something else))
05:49Chousukethat won't work, because even if the first if returns something, the second if still gets executed and the first one's return value is simply ignored
05:50sparievis it right syntax for typehinting typed array - (aget #^"[Lcom.browseengine.bobo.api.BrowseHit;" hits %) ? compiles still reports Reflection warning - call to aget can't be resolved
05:51spariev*compiler
05:51Chousukespariev: remember to hint the index as well
05:51Chousukespariev: and I think hinting arrays as #^objects works just as well.
05:51_invisChousuke: thank you
05:52_invisSo I cant write like this: (if (expr ) (do something if true) (another if if else)) ?
05:53hircusno, unless your expr is actually a thunk (a function that takes 0 argument)
05:53Chousuke_invis: you can, but you seemed to be writing (if expr do-something) <- note closing paren (if expr2 ...)
05:54sparievChousuke: thanks, hint on index did the trick
05:55Chousuke_invis: whereas the syntax for if is (if condition then-expr else-expr) ... and in the case of nested ifs, the else-expr is just another if. that's all there is to it
05:56_invishmm :)
05:56Chousuke_invis: but again, using cond is better. it leads to less nesting
05:56_invisok I will use cond, but just wanted to understand what was wrong
05:57Chousuke_invis: keep in mind that ifs in Clojure are not statements like in other languages. they're just expressions
05:57Chousuke_invis: you can do things like (+ 1 (if *some-global* 2 4))
05:58_invisI understand that
05:58hoeck_invis: with nested ifs: http://gist.github.com/341008
05:58_invisohh
05:59_invisThank you man :)
05:59_invisthat was I try so much to understand
05:59licoressea little reformatting can work wonders
06:00_inviswill it work with X and Y ?
06:00_inviswhy not %1 ? just for view nice ?
06:00Chousukeheh, it won't actually.
06:01licoresse_invis: it is a hint for you to not use anon func
06:01ChousukeI suppose he intended to transform the #(....) to (fn [x y] (...))
06:02LicenserI often find it nicer to use not #() but actual (fn [] ) since you can name the parameters
06:03ChousukeI tend to use #() only for very short and obvious things nowadays
06:03Chousukelike #(= 100 %) or whatever
06:03LicenserChousuke: I like (partial = 100) there :P
06:03Licenserdon
06:03Licenser't know why but it makes me feel so lispy
06:03Chousukethat's longer :P
06:04Licenserso what?
06:04_invisthanks a lot
06:04Licenserit looks cooler and people who read that can say 'woooh Licenser understood how partial functions work!!!'
06:04licoresse:)
06:04Licenser;)
06:07sparievLicenser: I use ->> for the same reason :) looks way cooler
06:08Licenserspariev: see, I don't know exactly what ->> does :P
06:08spariev,(doc ->>)
06:08clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."
06:09hoeckLicenser: do you know -> ?
06:09Licenserhoeck: no, never got the whole arrows, after the knee OP I am scared of them o.o
06:09licoressefinally!! an interview with Rich on seradio
06:09hoeckcool!
06:10Licenser(doc ->)
06:10clojurebot"([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."
06:11Licenser,(->> 1 (+ 2) (+ 3))
06:11clojurebot6
06:11Licenser,(macroexpand '(->> 1 (+ 2) (+ 3)))
06:11clojurebot(+ 3 (clojure.core/->> 1 (+ 2)))
06:12Licenser,(macroexpand1 '(->> 1 (+ 2) (+ 3)))
06:12clojurebotjava.lang.Exception: Unable to resolve symbol: macroexpand1 in this context
06:12Licenser,(macroexpand- '(->> 1 (+ 2) (+ 3)))
06:12clojurebotjava.lang.Exception: Unable to resolve symbol: macroexpand- in this context
06:12Licenser,(macroexpand-1 '(->> 1 (+ 2) (+ 3)))
06:12clojurebot(clojure.core/->> (clojure.core/->> 1 (+ 2)) (+ 3))
06:12Chousuke:P
06:12Licenserwhy is macro expand stopping at the middle?
06:12Chousukeit doesn't macroexpand inner expressions
06:12Licenser,(macroexpand '(-> 1 (+ 2) (+ 3)))
06:12clojurebot(+ (clojure.core/-> 1 (+ 2)) 3)
06:13Licenserah okay -> puts it in the first ->> puts it in the end :)
06:13hoeckcongratulations!
06:14sparievLicenser: also check out this screencast by Sean Devlin on -> & ->> http://vimeo.com/8474188
06:14hoeckthe doc for -> and ->> is nearly uncomprehensable
06:14Licenserhoeck: I agree it is horrible to read
06:14hoeckor uncomprehensible
06:14Licenserthen again, risking that I get stoned, most of the clojure docs are horrible
06:15hoeckwell, except for the function docs
06:15licoresseWould love if someone initiated a project to insert examples in all the doc-strings
06:18licoressesomething like this: http://wiki.squeak.org/squeak/5699
06:50jwr7Any hints as to why "lein swank" doesn't set up the classpath? I only get clojure, clojure-contrib and swank...
06:52leafwkotarak ?
06:53esjjwr7: this used to be a problem, but I think its sorted now. It is for me.
06:53leafwanybody iusing vimclojure, I'd appreciate help. I can never get it to install i na new machine.
06:53jwr7esj: Hmm. I just installed leiningen 1.1.0 and no cigar. Googling around, but can't find anything...
06:54jwr7Leiningen 1.1.0 on Java 1.6.0_17 Java HotSpot(TM) 64-Bit Server VM -- on Mac OS X.
06:54esjyou're not using emacs by any chance ?
06:55jwr7I am — using slime-connect to connect to the swank started by lein swank
06:55MecIf i have a string representation of a data structure do i just use eval to realize it?
06:56zmila,(doc read-line)
06:56clojurebot"([]); Reads the next line from stream that is the current value of *in* ."
06:57esjjwr7: one work around which I used to use was M-x swank-clojure-project, which got around this
06:57zmila,(type (read-line "123"))
06:57clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$read-line
06:57zmila,(type (read-string "123"))
06:57clojurebotjava.lang.Integer
06:57esjjwr7: but I just checked, both my stable and -dev version of leiningen, on a setup pretty much like yours do work
06:58zmilaMec - you can use (read-str "aoeu")
06:58Mecthanks, i didnt know about read-string
06:58jwr7esj: that's strange... perhaps I'm doing something wrong, then. Do I need anything else apart from adding lein-swank to :dev-dependencies?
06:59esjnope
06:59jwr7esj: or could it be that swank-clojure is lying about namespaces? Hmm.
06:59esjtry (use ) something
07:00jwr7esj: nope. And ,change-package completions show user, clojure, clojure.contrib and swank. That's it.
07:01jwr7jwr7: btw, my slime and swank-clojure.el are from ELPA.
07:01esjmine too
07:02esjdunno man, sorry. If you're developing and running on the same machine I'd suggest M-x swank-clojure-project as a good workaround.
07:02leafwvimclojure cannot even be built using the README.txt instructions.
07:02leafw"no build.xml file!", compains ant
07:02leafws/compains/complains/
07:02jwr7esj: yes, I guess I'll revert to that, or my old ways of hacking with a lib directory full of symlinks... But leiningen was supposed to change that...
07:02jwr7esj: thanks anyway.
07:03esjsorry dude.
07:03esjjwr7: hold on
07:04esjyour :dependencies in project.clj is setup right ?
07:04jwr7esj: Yes. And lein deps downloaded a ton of stuff into lib/
07:04esjdoes lein repl work ?
07:04jwr7also, would anybody happen to know why C-c C-c in SLIME gives me NullPointerExceptions ( 0: clojure.lang.Compiler$FnMethod.parse(Compiler.java:3739)), while C-x C-e works just fine?
07:06esjjwr7: again, I dunno, mine compiles.
07:07jwr7People should pay me for testing software — I *always* hit all the quirks that nobody has ever hit before. In every piece of software I touch :-)
07:12licoressein emacs: swank-clojure-project
07:59licoressein a vector [:a :b :c :d] is there a contains?-like function that allows me to do (contains? [:a :b :c :d] :b) ?
08:00noidi,(some #{:b} [:a :b :c])
08:00clojurebot:b
08:00noidi,(some #{:d} [:a :b :c])
08:00clojurebotnil
08:00rhickeylicoresse: why not use a set?
08:01licoresseyeah, why not... :)
08:01licoressegotta think a little
08:03licoresseyes, (#{:a :b :c :d} :d) is much better!
08:03psykoticthen you can just do...
08:03licoresseright
08:03psykotic,(#{:a :b :c :d} :b)
08:03clojurebot:b
08:03licoresse:c
08:04psykotic,(#{:a :b :c :d} :e)
08:04clojurebotnil
08:04licoressecool
08:09noidione case in which the "some" trick is handy is when you have a function that takes a variable number of optional arguments
08:09noidi(if (some #{:fire-the-missiles} options) ...)
08:09licoresseI see
08:10licoresse,(doc some)
08:10clojurebot"([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"
08:10spariev,(clojure.contib.seq-utils/includes? [1 2 3 4] 4)
08:10clojurebotjava.lang.ClassNotFoundException: clojure.contib.seq-utils
08:10spariev,(clojure.contrib.seq-utils/includes? [1 2 3 4] 4)
08:10clojurebottrue
08:11licoressesets serves my purpose well
08:11licoressebut thanks
08:11noidithe reason I prefer "some" over "includes?" in those cases is that sometimes options may imply other options
08:11sparievincludes? will do if you need to deal with vectors
08:11noidia dumb example: (if (some #{:-f :--overwrite-files) options) overwrite-files)
08:51Licenserping
08:51zmila,ping
08:51clojurebotjava.lang.Exception: Unable to resolve symbol: ping in this context
08:51zmila,(ping)
08:51clojurebotjava.lang.Exception: Unable to resolve symbol: ping in this context
08:52djpowellhttp://blogs.tedneward.com/2010/03/23/How+To+And+Not+To+Give+A+Talk+On+F.aspx is some good advice for Clojure evangelists
08:52Licenser(let [ping "pong"] ping)
08:52Licenser,(let [ping "pong"] ping)
08:52clojurebot"pong"
08:53djpowellit always seems that the 'classic' example program for any given technology, is always the most stupid and inappropriate
08:54djpowelleg every SOAP example is a 'stock ticker', which would be better done with http. i'm sure AOP can do more than add log statements. and computing fibonacci numbers, badly, using explicit recursion isn't a great example for functional programming
08:55zmiladjpowell - tĥx, good article to be read on the way home :)
08:56esjdjpowell: I'm not sure if I agree with the article
08:57esjdjpowell: we can't pretend that these languages are like the C#s etc
08:57esjand shouldn't want to
08:57fogusSome applies to Clojure talks, but others very not
08:57sparievnot sure about REPL, I think it's a fantastic tool esp for people stuck with Java
08:58chouserThat's a good article.
08:58fogusI agree with the math stuff
08:58cemerickMore generally, "know thy audience", but yeah.
08:58esji agree that it should not be made to seem other-worldly, but the big win from a pragmatic functional language lies with it being functional
08:58chouserI think the underlying theme may be: tell them things that can be meaningful to them where they are, not things that we all have come to realize are amazing after some amount of time.
08:59chousercemerick: right
08:59djpowellyeah - tho I never really use the repl directly - I use inferior lisp mode together with a real edited file. I think if I had to use a repl directly, I wouldn't so often. Eg, I've never done very much python, but I can't imagine I'd spend much time in the repl. The same probably applies to F# - don't know...
08:59chouserlike the REPL -- if a 3-minute example of how to use it doesn't grab a person, another 25 minutes of repeating the fact isn't going to convince them.
08:59LicenserI use the repl a lot
09:00LicenserI am not sure, didn't read the entire article but some things do not fit me
09:00fogusI doubt something like the REPl would even need to be addressed directly
09:00Chousukeit's good to mention though
09:00cemerickMy general rule is, don't show (much) code, don't show (much) programming. Broadly writ, people care about apps and end-user functionality (i.e. "why the hell should I care about XXX"), not the gritty bits (which don't present well in a talk anyway).
09:00esjabsolutely, its a big, big win
09:00chouserI'm afraid macros are in roughly the same category.
09:01djpowellI think using a resultset-seq as your example data is going to grab people more than using a vector of ints or something when you are showing off map/filter/reduce
09:01chouserdjpowell: I was just thinking that.
09:01Chousukecemerick: I think Rich does an excellent job explaining why people should care about Clojure's state model, at least :)
09:01chousermost developers are keenly aware of the clumsiness of dealing with resultset-seqs
09:01chouserwell, result sets
09:01esjhehe
09:02cemerickChousuke: For sure, but we aren't Rich, and our audiences are rarely Rich's audiences :-)
09:02chousershhh, he's here.
09:02LicenserDO stress that F# can do everything C# or Visual Basic can do. // <- I'm not sure 'can do what Visual Baisc can' is something to be proud of
09:02rhickeyanyone want:
09:02Chousukeheh
09:02rhickey(letfn [(foo [& {a :a b :b}] [a b])] (foo :a 1 :b 2)) => [1 2]
09:02djpowellresultset-seqs are ace. i'm wondering whether I might be able to have something like a resultset-seq that makes datatypes so that i can implement protocols over the data in 2.2
09:02djpowellnot sure how well that will work
09:03chouserrhickey: mmm!
09:03esjthats slick
09:03Licenserit looks nice but it isn't really intitive is it?
09:04Licenserafter & I exect that I can pass as many arguments as i like and then get a list
09:04cemerickI can't say I've ever used letfn. :-/
09:04fogusIt took me a second to realize what I was looking at, but I like it
09:04djpowellno me neither yet. i guess lispers are more familiar with it
09:04rhickeyall associative destructuring options in play, not a special case
09:04ChousukeLicenser: it's not much different from (fn [& [foo bar]] though
09:04chouserthe point is destructuring a seq of alternating key/values into map keywords
09:04rhickeycemerick: letfn is not important here
09:04LicenserChousuke: you can do that?
09:05cemerickrhickey: yeah, that's just me adding noise
09:05cemerickrhickey: so :keys and :or are also available?
09:05Licenser,(letfn [(foo [& [a b]] [a b]) (foo 1 2))
09:05rhickeychouser: right, and implemented exactly like that - if a seq? arg to associative destructuring, hash-map it first
09:05clojurebotUnmatched delimiter: )
09:05Licenser,(letfn [(foo [& [a b]] [a b])] (foo 1 2))
09:05clojurebot[1 2]
09:05Licenser,(letfn [(foo [& [a b]] [a b])] (foo 1 2 3))
09:05clojurebot[1 2]
09:05Licenserhmm I see how it works
09:05djpowellah, that does look pretty cool
09:06rhickeycemerick: yes, everything is available
09:06Licensercould you use :as there too?
09:06rhickeyLicenser: really, everything
09:06cemerickrhickey: Good. There goes the "fns should not require users to pass map literals" preference :-)
09:06Licensercool then you have my vote in favour
09:06Licensernot that it matters
09:07chousersometimes when I do keyword arg parsing manually, I transition to keyword args when I find the first keyword in the input, not a fixed arg count.
09:07rhickeyso, the one icky bit is that (let [{a :a b :b} [:a 1 :b 2]] [a b]) and (let [{a :a b :b} (seq [:a 1 :b 2])] [a b]) are different
09:07cemerickchouser: asking for trouble, no?
09:07Licensersomething like: massing areguments in order or as a key would be incredible
09:08chousercemerick: depends on the arg type I suppose. I don't remember being worried.
09:08rhickeydoes anyone use associative destructuring on vectors?
09:09chouserrhickey: the first is [nil nil]?
09:09rhickeychouser: yes
09:10rhickeyI think the problem is less that there will be a desire to get associative destructuring of vector than that this will be one of very few cases where a vector can't be used where a seq can
09:10chouser,(let [{a 0 b 3} [4 5 6 7]] [x y])
09:10clojurebotjava.lang.Exception: Unable to resolve symbol: y in this context
09:10chouser,(let [{a 0 b 3} [4 5 6 7]] [a b])
09:10clojurebot[4 7]
09:10rhickeyor at least, the behavior will be different
09:10chouserno, I don't think I've ever done that.
09:11fogusHmmm, I didn't even realize that you could do that :(
09:11cemerickIt's surely more of a curiosity than actual practice.
09:12rhickeyso, if no one has become curious, it could be changed to map destructuring and vecs/seqs get same treatment
09:12cemerickrhickey: what would the key interface be?
09:13ChousukeI don't think I've ever seen associative destructuring on vectors
09:13rhickeycemerick: j.u.Map
09:13rhickeybut much less nice than associative
09:14chouserit's not obvious to me which behavior would be better for vectors
09:14rhickeybecause associative also works for sets: (let [{:keys [a b c]} #{:a :c}] [a b c]) => [:a nil :c]
09:15rhickeynot that that anyone knows that either
09:15rhickey:)
09:15chouser:-)
09:15cemerickI actually use that :-/
09:15rhickeycemerick: congrats!
09:16cemerickeh, it's in one hacky spot where I can get a set or map, and that ended up working out.
09:16rhickeyI'm ok with the seq? test, as the overwhelming case is for & args
09:16chouseryeah
09:17ChousukeI think most people would expect map destructuring not to work on vectors.
09:17Chousukein the associative way, that is. so I'm in agreement
09:17cemerickThe current consistency is too perfect tho.
09:17rhickey"Map binding-forms allow you to bind names to parts of associative things (not just maps), like maps, vectors, string and arrays (the latter three have integer keys)."
09:18chouserChousuke: but if that's the case, they might expect vectors to destructure like seqs
09:18rhickeyfirst sentence of map binding docs ^^
09:18cemerickI think a seq test is perfectly reasonable.
09:18cemerick...and puts the burden on the new feature, at least for now.
09:19chouserThis class name is probably a hint that I'm going about things the wrong way: java.lang.ClassNotFoundException: clojure.core$eval__56$mmap_factory$reify$reify__64$eval__66$mmap_factory__67
09:20Chousukeuh
09:20cemerickheh
09:21Chousukeis that a closure of mmap-factory that reifies something and evals a call to itself recursively? :/
09:21fogusrhickey: I remember that example from the docs, but I suppose the implications were lost on me
09:21chouseryes
09:21rhickeyheh, so keyword args was just a one-liner away all this time
09:21rhickeyhave fun! http://github.com/richhickey/clojure/commit/29389970bcd41998359681d9a4a20ee391a1e07c
09:22cemerickrhickey: wait for the griping about the braces :-P
09:22rhickeycemerick: there's no possible argument against them
09:22rhickeygiven [a & [b c]] already
09:23cemerickrhickey: I know. That won't be a deterrent, tho. :-)
09:23chousergriping will more likely be around the extra word and nesting of {:keys [b c]}, I'd think
09:23rhickeycemerick: you just can't please some people
09:23cemericktell me about it.
09:24Chousukechouser: that would be like complaining "we want the language to be inconsistent!
09:24dnolenrhickey: huh, so [a & [b c & rest]] is allowed as well?
09:24rhickeywell, it's a completely clean extension and now works everywhere
09:24rhickeydnolen: sure
09:24fogusChousuke: You've seen programming languages right?
09:24dnolenI sense a hidden feature of Clojure.
09:24chouserpeople often think they inconsistency is at times convenient.
09:25rhickeydnolen: it's not hidden, it just falls out of the nestability of binding forms
09:26dnolenrhickey: no I know :) reference to Stack Overflow question. but I guess defining mutiple arity fns is preferred over this right?
09:27cemerickdnolen: depends on what you're doing
09:28Chousukethe destructure function in clojure.core is pretty scary
09:28dnolencemerick: a simple example where [a & [b c]] would be preferred over multiple arity?
09:28chouserooh, let's count the mini-languages!
09:28fogus1. destructuring
09:28Chousukechouser: count the number of macros!
09:28chouser2. list comprehension
09:28chouser3. regex
09:29noidiexception handling? :)
09:29fogus4. #()
09:29chouserChousuke: hm, I guess -- somehow what 'for' provides seems more like a language than 'defn'
09:29rhickeyregex is not mini
09:29chouser5. syntax-quote
09:29Chousukechouser: defn provides a mini-language for defining functions :)
09:30chouserChousuke: ultra-mini
09:30Chousukeor I suppose that's fn
09:31Chousukechouser: well, it has pre/post, metadata, arglists (with "special" destructuring) and doc strings
09:31ordnungswidrigns macro
09:31fogus6. pre- post-
09:31chouserbut those mostly just feel like keyword args
09:31chouserbut defn's mini language mostly just feels like keyword args
09:32fogus7. (some #{...} ...) ???
09:33chousernah
09:33ChousukeThere's nothing wrong with having mini languages though. if anything, it makes things consistent. If the language provides access to the mechanisms used to create those mini languages, you can design your own APIs to be more consistent with the core language :)
09:33fogusI suppose that's just an idiom
09:33fogus7. -> ->>
09:35chouser ns
09:36fogusI missed numbering that earlier
09:36cemerickdnolen: if it's a simple matter of optional positional args, then [a b & [opta optb optc]] is *always* easier than having mulitple arities. I just saved three overloads right there.
09:36chouseroh, right, I missed it entirely
09:37rhickeyheh, (let [[& {:keys [a b]}] [:a 1 :b 2]] [a b]) => [1 2]
09:37rhickeyconsistency rocks
09:37lpetitgen-class
09:38fogusrhickey: So would you say that it's safe for me to change the section on named args in the book?
09:38rhickeyfogus: I haven't gotten to that yet, but probably
09:38foguslpetit: ooooo, a sub-mini-language
09:38cemerick8. literal numerics i.e. 1e7, 11r02
09:39cemerick9. #^ints, #^bytes, etc
09:40fogusrhickey: great thanks
09:42chouserhm... so a macro that expands something like `(~(fn ...) ~arg) usually works (as long as fn is not a closure), but apparently sometimes gives me ClassNotFoundException
09:43rhickeyI actually quite prefer this to defnk or whatever, in spite of being more verbose, as it just reuses existing knowledge of {} binding, and gives the same caller experience, which is what matters
09:45sparievsolussd, are keywords via destructuring (defn foo [a b & [:kw kw :kw2 kw] are preferred over ruby-like options hash, as in first example here - http://stuartsierra.com/2010/01/15/keyword-arguments-in-clojure
09:45sparievso*
09:46Chousukechouser: you could work around that with `((fn ~@[...]) ~args)
09:47chouserwell, that was simplification. the fn is actually cached in a map, and I was trying to get away with a single lookup at compile time instead of a lookup once per call at runtime.
09:47chouserand it mostly works -- not sure why it sometimes doesn't.
09:48raekcould there be another &, say &&, that turns the seq into a hashmap?
09:49solussdhehe. autocomplete spariev?
09:49sparievsolussd: yep, sorry :)
09:49raek(let [[x y && {:keys [a b]}] [1 2 :a 3 :b 4]] [a b]) => [3 4]
09:51raekI have no idea how descructuring actually is implemented in clojure, so take this with a metric ton of salt
10:11dnolenraek: with rhickey's latest changes your example just works. no need for &&
10:13rhickeywell, you do need one &
10:17dnolenraek: also ** could defined as (defn ** [x] (flatten (seq x)), then (apply somefn 1 2 (** options)) just works.
10:20Licenserhmm IU've a function that is suposed to extact code from free text: http://gist.github.com/341213 any thoughts to that?
10:41rhickeydoes lein have a self update?
10:43ohpauleezrhickey: I believe 1.1 and onward does
10:43rhickeyand to get to 1.1 from 1.0.1?
10:44ohpauleezyou just install over top I believe
10:49technomancyrhickey: yeah, self-update is new; to upgrade to 1.1 you just replace the bin script manually and then self-install
10:50rhickeytechnomancy: ok, thanks
10:51rhickeyany way to get compojure to use something other than current working directory as the root?
10:57licoressehow can I represent the string of :a => "a"
10:57dnolen,(str :a)
10:57clojurebot":a"
10:57chouser,(name :a)
10:57clojurebot"a"
10:58dnolenoops :)
10:58licoressename, yess
10:58licoressethanks
10:58cemerickrhickey: you mean for hosting static stuff?
11:00Licenseranother interesting application for this: http://gist.github.com/341257
11:00Licensera very simple template engine
11:05rhickeycemerick: yeah
11:05cemerickrhickey: see serve-file. You can root things whereever you like.
11:06G0SUBrhickey: (letfn [(foo [& {a :a b :b}] [a b])] (foo :a 1 :b 2)) is returning [nil nil] for me. (I tried the latest master with 29389970bcd41)
11:07rhickeycemerick: right, I have existing code I don't want to change that already calls serve file
11:07cemerickrhickey: Unless you're just playing around, I'd take the 10 minutes to get set up with proper war packaging, which would give you a lot of options. Then you can just let jetty serve the static stuff on its own.
11:07cemerickrhickey: ah. In that case, I think rebinding serve-file is your only option.
11:08rhickeycemerick: not my project
11:09hircuswe should try plugging Clojure to this guy -- he has quite a large readership and is contemplating a Lisp to learn: http://reprog.wordpress.com/2010/03/23/the-long-overdue-serious-attempt-at-lisp-part-1-which-lisp/
11:10cemerickhircus: he says explicitly no Clojure *shrug*
11:10hircushe perhaps does not realize how Lispy it is
11:11drewrdoes he *really* want to use LISP as it was in 1958?
11:11drewrI don't even think that's possible on modern hardware
11:11hircusbut well. funny, considering he just claimed he looks forward more than back. sounds like a tailor made match for Clojure if his claim is true
11:11fogus"I want to start with foundations, and that means the language from 1958" That rules out Scheme
11:11hircusdrewr: I'm sure you can emulate a 1958 machine :p
11:11hircusyeah. not very consistent
11:12fogusLisp as it was in 1958. Have fun. http://github.com/fogus/lithp
11:12drewrhircus: which would be much more cumbersome than learning haskell or clojure ;-)
11:12rsynnottfogus: that also rules out Emacs Lisp and Common Lisp
11:12cemerickEh, he calls out a couple of langs explicitly as not interesting to him right now.
11:12rsynnottthough Emacs Lisp is probably closest
11:12Licenserfogus: byte code asm :P
11:12hircusI sympathize with anyone who has to work on ELisp for a living
11:13rsynnotthircus: there's a Google employee with a blog whose job used to involve maintaining Amazon's customer support system, which was an elisp app
11:13cemerickClojure and any good scheme are (almost, sorta) equivalent anyway (excepting the concurrency stuff). External considerations drive a choice between the two, so any advocacy will likely fall on deaf ears.
11:14rsynnott(can't find the article now, but it sounded pretty terrible, all right)
11:14rhickeycemerick: um, what?
11:14cemerickrhickey: for someone new to lisps in general?
11:14cypher23rsynnott, that employee wouldn't happen to be Steve Yegge?
11:14rsynnottcypher23: ah, yep, that's him
11:15hircusrsynnott: worst abuse of ELisp I could think of. I know some sites use Common Lisp but that actually makes sense
11:15drewrhircus: elisp is a great choice if emacs is your env
11:15hircusif that's Yegge that experience did not seem to cause lasting harm :)
11:15hircusdrewr: yes, it makes sense, but Amazon ran their customer support system from within Emacs ?!
11:15rsynnotthircus: well, he's implementing javascript as an elisp competitor
11:16rsynnottthat surely indicates it left some scars? :)
11:16rsynnotthircus: allegedly
11:16cemerickrhickey: but PDSs surely aren't necessary in a first lisp.
11:16G0SUBrsynnott: not any more. last time I checked, he has abandoned the project.
11:16hircusvery true. odd choice. granted, Javascript was *meant* to be a Lisp...
11:17esjHey at least we're 'fashionable arrivestes'. I can't recall having been one of them before.
11:17drewrhircus: maybe that's all they needed to take info from a customer and persist it to disk
11:17drewremacs is a lisp machine that runs everywhere, even over a terminal
11:17rhickeycemerick: so you meant "Clojure and any good scheme are (almost, sorta) equivalent anyway" only in that context?
11:17hircusI guess this must be in the early days when a single thread can do the job in real time
11:17cemerickrhickey: right, related to this fellow who wants to learn some lisp, linked somewhere above
11:21rhickeyhmph
11:21cemerickrhickey: You should post exactly that as a comment there. :-)
11:22cemerickor, I should say, ;-)
11:22powr-tocIs it possible to use enlive as a DSL for generating HTML,
11:22powr-tocwithout using any HTML?
11:24RaynesLicenser__: ping
11:26powr-tocI realise Enlive uses selectors to insert HTML into the HTML
11:26powr-toctemplate... but can it be used standalone to generate HTML, without a HTML file?
11:27cemerickpowr-toc: yeah, that's doable. Not pleasant, perhaps, but doable.
11:27powr-toccemerick: not pleasant in what sense?
11:27cemerickSorta defeats the point, at least a little.
11:27powr-toccemerick: sure... It's just right now, I don't have a
11:27powr-tocdesigner... I just want to knock up a small amount of HTML inside clojure
11:28cemerickpowr-toc: Insofar as one chooses enlive to populate pages with data, maintaining a clean separation between design and "templating".
11:28powr-toclater on, when maybe there is a designer it'd be good to use the
11:28powr-tocseparation aproach
11:28cemerickpowr-toc: I don't have a designer, either :-) You'll still be better off having your pages on disk, and populating them later.
11:29cemerickKeep separate concerns separate, even if you're wearing both hats.
11:30powr-toccemerick: I agree, but that doesn't mean I need the complexity of
11:30powr-tochaving extra files when I'm probably talking about a handful of
11:30powr-tocforms... I can seperate the logic from the template in a single file
11:30powr-tocof pure clojure
11:31cemerickpowr-toc: yikes. "extra files" isn't complex compared to balling up all your presentation into one ball of mud IMO.
11:33powr-toccemerick: it is while you're talking about just two or three
11:33powr-tocsimple HTML forms. I'd break it out when it got any bigger.
11:34hircuspowr-toc: if you really want to do all your work from a single language, you might want to check this out -- http://twitter.com/Tordf/status/10794263684
11:34cemerickHTML is really, really good at representing HTML. :-P But anyway, *peace man*. :-)
11:35hircuspowr-toc: I guess you can always write a simple Clojure map/vector => HTML converter. My previous university generated its pages from Scheme
11:36hiredmanor just use one that already exists
11:36hircuspowr-toc: but you'd end up only with a slightly more concise representation (no duplicate close tags) and if/when you get a designer that person will get confused
11:36hiredmanhttp://github.com/mmcgrana/clj-html for example
11:36powr-tochiredman: yeah, I know there's hiccup too... but I quite like
11:36powr-tocenlive's approach
11:37powr-tochircus: they wouldn't because I'd have converted them back to
11:37powr-tocHTML for them
11:37chouserI think that enlive consumes the structures produced by clojure.xml/parse
11:37powr-toc(that is I like enlives approach for when you have a designer)
11:37chouserso you'd only need to convert from [:a {:href "foo"} "text"] to {:tag :a :attrs {:href "foo"} :content ["text"]} ...
11:39powr-tocchouser: hmm interesting
11:40hiredman,(let [[tag attrs & content] [:a {:href "foo"} "text"]] {:tag tag :attrs attrs :content (vec content)})
11:40clojurebot{:tag :a, :attrs {:href "foo"}, :content ["text"]}
11:40chouserright, but the vec needs to be recursive, you probably want to allow for missing attr maps, etc.
11:41hiredmanchouser: :(
11:41chouserI feel like I've written such code before...
11:43lpetitcemerick: Assembler is really, really good at representing Assembler. :p :p . Hopefully we have compilers to write assemblers from higher-order languages nowadays. Same for abstracting html away (if there is a viable option) IMHO.
11:43cemerickall for want of an html file or three :-/
11:44powr-toccemerick: It looks like hiccup or a clj-html are all I need
11:44powr-tocnow... I was just wondering if enlive supported a similar usecase
11:44cemericklpetit: Cute, but there's essentially no connection between HTML and assembler. HTML is *the* delivery mechanism that generally doesn't have any incidental complexity, so abstracting away from it is a little silly.
11:45cemericks/that/and
11:45Fossithose rock
11:45Fossithe right thing to do is abstracting you data retrieval layer from the frontend
11:45powr-toccemerick: except that clojure's syntax is easier, less verbose & paredit ensures
11:45powr-toctags are closed...
11:46foguslpetit: I think Erran Gat mentions using Lisp as an assembly "DSL" in this article: http://www.flownet.com/gat/jpl-lisp.html
11:46Fossithen add some compojure, clj-html etc into the mix and it's (much) greater than php
11:46lpetitcemerick: in your dreams :-). More seriously, I mean HTML is *theoretically* abstract, but I guess at least browers differences in implementation make this dream not become true.
11:47lpetitThat's certainly why GWT has a lot of traction those days
11:47cemericklpetit: assuming you're using HTML and CSS for what they're respectively designed for, then I'm not sure what could be gained by driving presentation bits into code.
11:47cemerickGWT and the apps it produces have zero connection with a simple set of forms (which is what powr-toc was aiming for).
11:48lpetitcemerick: Wait ! I'm talking about some real abstraction layer over html. Not one of those who just allows you to write [:p] instead of <p> of course.
11:48lpetitcemerick: my bad for jumping into a conversation without having read it from the beginning. Sorry guys.
11:49cemericklpetit: well, that's fine enough then. :-) But the latter is exactly what's going on at the moment, sadly enough.
11:49hiredmana real abstraction layer is what? swing -> html?
11:49powr-toccemerick: I'm not even needing CSS though... I really just
11:49powr-tocrequire plain old HTML just now. There isn't any real presentation... just a very small structured document.
11:50cemerickhiredman: apparently, [:p :content "hello"] or whatever is better than <p>hello</p> 9.9
11:50lpetithiredman: alas, I guess this one has still to be invented. But at least an additional layer that fills the gap between theoretical html+css code (which should work 'as is' on any browser on any OS), and the reality :-)
11:50cemerickpowr-toc: But, of course, you will. Why pay now, and then pay later?
11:51zaphar_psI'll take enlive over any abstraction layer any day
11:53lpetitfogus: doing GWT right now ? I will start my first GWT app in a few hours/days. Any advice for a beginner ? :-)
11:53foguslpetit: Don't use anything lower than version 2.0
11:53powr-toccemerick: yagni might be one reason
11:54lpetitfogus: I like this quotation from the article you cited : "Apparently they got this idea that because I worked at Google for a year that I was now a search engine expert" :)
11:54lpetitfogus: yeah, the "Programmation GWT 2" by Sami Jaber is on my desktop :-)
11:54zaphar_pslpetit: I run into that sometimes google does a lot more than just search
11:54foguslpetit: Who hasn't had that experience? Being the default-expert that is.
11:55cemerickpowr-toc: Insofar as HTML is viewed by humans, it requires CSS for reasonable presentation. *shrug*
11:55lpetitfogus: yes, so true :)
11:57powr-toccemerick: I don't require reasonable presentation... the form
11:57powr-tocwill just be used by me
12:06lpetitzmila: so bad
12:07zmilai'd like to learn gwt 2.0, it has more interesting traits
12:13cemerickIs there any hope of being able to use non-Java languages for GWT sometime in the future? I presume not, but hope abounds.
12:14chousermaybe if there was a clojure compiler backend that emitted java source? :-/
12:14cemerickha
12:14cemerickI'm sure there is still, in the murky depths of rhickey's hard drive.
12:29lpetit*that emitted java source restricted to only the part of the JDK which is ported to JS :-/
12:49foguscemerick: I heard a rumor about a Scala GWT being planned
12:49cemerickbe still my heart :-P
12:49fogusI knew you'd like that. ;-)
12:49chouseryou did say "non-Java languages" :-)
12:50cemerickchouser: I'm an impossible bastard. :-D
12:50cemerickstill, if scala is in the works, then adding support for a third option will be that much easier.
12:51fogusScala is only like Java for the first 6-months
12:51cemerickthat long? ;-)
12:51fogusI'm slow
12:52cemerickrubbish
12:52cemerickchouser: Make sure you put fogus' last comment on the front of the book.
12:53fogusIt can be the subtitle
12:53chouserheh
12:53shalesIs there a way to cast a number to a number that uses less bits and simply truncate the value? For example, something like if (byte 255) returned the byte -1
12:53chouser,(.byteValue 255)
12:53clojurebot-1
12:53lpetitshales: sure, use clj-native
12:54lpetit:)
12:54shalesah of course, thanks chouser
12:54cemerickshales: of course, keep in mind that...
12:54cemerick,(-> 255 .byteValue class)
12:54clojurebotjava.lang.Byte
12:54peregrine81,(+ 2 2)
12:54clojurebot4
12:54peregrine81sweet
12:54cemerick^^ that's no primitive (reacting here to the "uses less bits" part)
12:55chouserwell, it's trute that's not a primitive, but that test didn't prove it.
12:55chouser,(-> 5 byte class)
12:55clojurebotjava.lang.Byte
12:56chouserthere was a primitive byte in there for a moment, before it got boxed to send to 'class'
12:58fogus,(-> 5 .byteValue Byte/toString)
12:58clojurebot"5"
13:01peregrine81How lispy is clojure if it doesn't contain TCO? Therefore removing opportunity for recursion..
13:02chouserlispy enough
13:02peregrine81lol good answer
13:02peregrine81I was pondering it while reading little schemer
13:03cemerickperegrine81: see the recur form, which provides a better option (IMO) for 98% of the use cases for TCO.
13:04peregrine81cemerick: I've barely used recur yet so I don't know all of the possibilities, thinking about sort of porting scheme to clojure
13:05chouserperegrine81: I'm not sure that will go very well. The Java runtime (and therefore the Clojure runtime) are not best at doing the kinds of things scheme wants to do. They have other strengths.
13:05peregrine81chouser: okay
13:06chouserIn Clojure, however, it's a rare algorithm that needs TCO, and trampoline handles 95% of those.
13:06cemerickperegrine81: you'd have to figure out what you actually want to port.
13:06cemerickDifferent macro systems might be interesting, though I've always taken more naturally to clojure-style (née CL-style) macros.
13:07peregrine81good point
13:08peregrine81I'm no pro at clojure or lisps in general but I want to learn
13:08cemerickchouser: 'course, if what you thought you needed TCO for just gets "unrolled" into a loop with recur, why not call that TCO?
13:08cemerickor, über-TCO, or mutual-TCO, etc.
13:09cemerickMeaning, call the other 5% those latter names.
13:14Licenser_hmm the compujure readly is quite wrong :(
13:23arohnerrhickey: how do you feel about a patch that replaces several calls to SOURCE with SOURCE_PATH, in exception messages in the compiler?
13:27Licenser_*sigh*
14:56chouserunreadably printed objects are a pain
15:02arohnerMan, I really want an emacs mode that allows me to visit old git trees using find-file
15:02arohnerlike find-file ~/my-project/.git/sha-1/old-file
15:06LauJensenfogus: Thanks for that link :)
15:18technomancyarohner: C-x v ~ maybe?
15:18technomancy(for a single file)
15:22rrc7cz-hmI've switched from Clojure Box to Emacs+Slime+Lein-Swank, and I'm having one bit of trouble: C-c C-k is undefined. The REPL is working fine (with classpath configured, etc), but I can't seem to compile
15:26fogusrhickey: Thanks for the shout out!
15:27arohneris (symbol (name :foo)) really the best way to convert a keyword to a symbol?
15:27arohneroh, there's (.sym :foo)
15:28kotarak,(symbol :foo)
15:28clojurebotjava.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String
15:28kotaraka pity
15:33arohner(symbol :foo) should work IMO
15:44ipostelnikrrc7cz-hm, I usually run M-x swank-clojure-project to init my projects in emacs
15:48jwr7fogus: thanks, didn'tknow about that one yet. Will serve as listening material for the dog walk tonight :-)
15:49rrc7cz-hmipostelnik: Is that only for creating a new project? In this case I have an existing project, and I run "lein swank" to start up a local server. Then I do a slime-connect to that server
15:49ipostelnikrrc7cz-hm, for existing project
15:50ipostelnikrrc7cz-hm, you need to provide location of project.clj (emacs will prompt) and then clojure-swank will run "lein swank" for you
15:52rrc7cz-hmipostelnik: that's working beautifully
15:53rrc7cz-hmipostelnik: perhaps I spoke too soon. it does run lein swank and connect automatically, with a working reply, but compilation doesn't look right
15:56ipostelnikrrc7cz-hm, you can see what it's doing in *slime-events* buffer
15:57rrc7cz-hmipostelnik: it is compiling okay, but it's a bit different than I'm used to with clojure-box. When I compile a script that depends on other scripts, it just failed out with ClassDefNotFound instead of recursively compiling the dep script
15:58rrc7cz-hmfor example, I have a top-level, gen-class -main script which uses some other script. I'd expect if I compile this top-level script, instead of failing with ClassDefNotFound, it would simply compile the dep script.
16:01chouseroh, is that what we're doing?
16:01rhickeychouser: should be harmless
16:01chouserbut ... you can't be, you're busy giving an interview.
16:02ipostelnikrrc7cz-hm, that's odd, it resolves dependencies in the project just fine
16:03rhickeyactually I was making the labrepl work with Enclojure - works quite well now
16:06naeuis there a recognised way of creating a command line clojure script that accepts params etc.?
16:06chouserI'm just listening to the software engineering radio interview fogus linked to earlier.
16:07chousernaeu: there's a weak, poorly-documented think in contrib you can at least start with. command-line
16:07naeuchouser: thanks
16:07programblenaeu: i also think *command-line-args* gets populated
16:08programble,(doc *command-line-args*)
16:08clojurebot"; A sequence of the supplied command line arguments, or nil if none were supplied"
16:08naeumy problem is that I'm new to using the JVM for real programming (dabbled with it at uni etc.) and I'm very used to writing simple scripts in Ruby to do useful things
16:08naeuI was wondering to what extent I could start using clojure for those kinds of tasks
16:08kotarak,(let [[hd & tl] (map #(doto % prn) (iterate inc 1))] hd)
16:08clojurebot1
16:08clojurebot1 2
16:09chousernaeu: yes, and you can do this with *command-line-args* and clojure.contrib.command-line, but unfortunately the JVM startup time reduces the set of problems for which this kind of thing is a good solution.
16:09naeuchouser: sure, but these are things for which I don't mind waiting for 10 seconds or so :-)
16:10chousernaeu: ah, good. you'll be set.
16:12naeucool, thanks
16:14slyphonso, if i want to in effect alias a method from namespace X to another namespace Y, such that it would be public in Y, uh, how do you do that?
16:15chouseryou just want to use the function in Y, or make it available to users of Y?
16:15slyphonmake it available to users of Y
16:16chouseryeah, that's not recommend. :-)
16:16slyphonoh, ok :)
16:16slyphoni'll do something different then
16:17Drakesonlook at clojure.contrib.ns-utils/immigrate :D
16:17slyphonah, that's the one i was thinking of, but i think i can just do something more straightforward
16:18chouserimmigrate has been generally disavowed, I think even by its creator
16:18slyphonyou can have foo/bar/baz.clj and foo/bar/baz/spam.clj right?
16:19chouseryes
16:19slyphonok, just making sure
16:19DrakesonIMHO, it only makes sense when the library was poorly designed, e.g. with too many unnecessary sub-namespaces
16:20Drakeson(using immigrate, I mean)
16:32kotarak,#"\\" "/"
16:32clojurebot#"\\"
16:36Drakesonis leiningen (git) after 2010-03-15 is also [partially] broken for you, too? lein deps copies the library to lib/ and then stays there forever. It does not terminate.
16:38technomancyDrakeson: I've noticed that, but it doesn't seem to be consistent on all systems. just use ctrl+c for now; I'll be looking into it later.
16:39Drakesontechnomancy: so it is harmless?
16:39technomancyyeah
16:39technomancyjust a weird artifact of the ant APIs we're using, I'm guessing
16:39Drakesonthanks
16:43naeuI must say, I find the whole JVM classpath thing a real royal pain
16:45naeuI've just pulled and built the latest edge clojure and clojure contrib jars, placed them into their own special directory, written a zsh script that sets the class path (to point to those jars) and to start up a repl, and I can't seem to reference clojure.contrib.command-line
16:45programbleew, zsh
16:45naeujava.io.FileNotFoundException: Could not locate clojure/contrib/command_line__init.class or clojure/contrib/command_line.clj on classpath
16:45naeuew that rather than ew zsh
16:45naeuzsh isn't that bad
16:45naeu:-)
16:45chouserok, so I've got an IPersistentMap implementation via reify, but I need it to work as a key in another map, matching an array-map.
16:46slyphonwow, i have macro bug that's causing the clojure compiler to throw a StackOverflowError
16:46slyphonwhat do i win?
16:46slyphon:D
16:46Chousukehmm
16:46chouserI've got = working properly now, so (= my-reify-map my-array-map) and vice-versa
16:46slyphonoh, nothing, i'm just a retard
16:46hoeckslyphon: thats easy, just write a recursive macro which never terminates
16:46naeuslyphon: are you sure your macro isn't referencing itself or something like that?
16:46slyphonnaeu: yeah, it is
16:47naeuslyphon: at least you got your classpath set up
16:47slyphoni had a defn blah*/defmacro blah combo
16:47chouser...but ({my-array-map :val} my-reify-map) is still nil because the hash codes are different
16:47scottjhttp://paste.lisp.org/display/96803 I can't figure out why this macro works fine when called directly but doesn't work when called inside a function. I think it has to do with the function having the same variable names but I'm not how to use gensyms to fix it. Ideas?
16:47hoecknaeu: maybe post your script?
16:47slyphonnaeu: leiningen takes care of that for me
16:47chouserwhat's the Right Way to get the correct hash code. The implementation appears to be locked up inside APersistentMap where reify can't get to it?
16:47hoecknaeu: should be as short as java -cp clojure.jar:clojure-contrib.jar clojure.main
16:48naeuhoeck: I don't even have a script yet, I'm just trying to reference command_line without it dying
16:48miltondsilvaHow do I add a doc to a def? I've seen this done but I keep forgeting how to do it :S
16:48Chousuke(def #^{:doc "blah"} foo ..)
16:48miltondsilvathanks :)
16:49kotarakscottj: the macro sees name the symbol not name the local.
16:49naeuhoeck: can i use relative paths in the classpath?
16:50kotaraknaeu: sure
16:50scottjkotarak: how come that's different when called directly vs called in the function?
16:51kotarakscottj: because direct call sees "op" the string
16:51chouserput another way, is there a good way to call an instance method of an abstract class on an object that doesn't extend it?
16:51chouserheh, I suppose not. Any way at all?
16:51naeuhmm, I still can't seem to reference command_line
16:51Chousukejust look at the APersistentMap implementation and translate it :P
16:52naeuwhat's the most basic test to see whether I have built and classpathed contrib correctly?
16:52Chousukestart a repl and try to use it :)
16:53ChousukeI think mvn clojure:repl should set up everything for you thoug
16:53Chousukeh
16:53naeuChousuke: that's what i'm doing
16:53Chousukebut then you can only run that in the contrib dir :(
16:58chouserChousuke: yeah, that was much better
16:58chouser(apply + (map (fn [[k v]] (bit-xor (hash k) (hash v))) my-map))
16:59scottjkotarak: how would I fix it?
16:59chouserAPersistentMap/hashCode changes, anyway
16:59kotarakscottj: you can't. This is an intrinsic limitation of macros. Rewrite your macro as function.
17:02Chousukescottj: the string that eventually becomes bound to 'name does not even exist when the macro is executed
17:02Chousukescottj: do you see the problem? :)
17:04scottjChousuke: nope, when is the macro executed, when the function that calls it is defined or called?
17:04Chousukescottj: just before the function is compiled
17:05Chousukeand never again! ;P
17:06lpetithello
17:07lpetitdoes enclojure integrate with lein ?
17:07slyphonlein is *for* clojure
17:07slyphonno?
17:07naeuhere's my failed attempt to reference contrib.command-line: http://gist.github.com/341655
17:07dnolenlpetit: stuart halloway has submitted a patch to lein to make it possible for enclojure to open lein projects.
17:07naeuif anyone can see what I'm not quite doing correctly, I'd love to hear!
17:08slyphonoh, i'm sorry
17:08lpetitdnolen: do you know the details ? I don't understand (yet) what has been done ? And why it is on the lein side ??
17:08kotaraknaeu: no ~ in classpath
17:08kotaraknaeu: tilde is shell, use qualified names
17:08naeukotarak: so how is it pulling in clojure.jar?
17:09lpetitdnolen: I'm interesting in the part where enclojure can (automagically ?) download all the needed dependencies from the lein project description ! ? !
17:09kotaraknaeu: the first ~ works because of the shell
17:09naeuahhh...
17:09kotaraknaeu: subsequent tildes are hidden from the shell => no expansion
17:09dnolenlpetit: not sure on all the details, but it sounds really promising.
17:09naeuyep, that makes sense
17:09naeukotarak: thanks so much :-)
17:09lpetitdnolen: sure. I would like to provide this kind of interop for ccw too
17:09technomancylpetit: "lein pom", then "create project from maven pom" or some such, I believe
17:10technomancyneed the latest lein from git
17:10dnolenlpetit: http://github.com/technomancy/leiningen/commit/1bbcf902f040d5b823647961cb8d35181b65716d is the commit I think
17:10lpetittechnomancy: oh, so if this is it, then I could also achieve the same by adding additional eclipse maven plugin installation
17:10dnolenoh, sorry the man himself speaks :)
17:11lpetittechnomancy, dnolen: so it is a little bit vaporware (yet) to say "no lein, no pom" in the installation instructions for netbeans in the labprepl README ...
17:11technomancywell I haven't used it; just repeating what Stuart told me.
17:11lpetitok
17:13KirinDaveDamn
17:13KirinDavebeing grilled
17:14kotarakoh my... labrepl sucks in the world...
17:14lpetitkotarak: he ?
17:15kotaraklpetit: well, I said: lein deps. Now I get the world downloaded it seems.
17:16lpetitYes, I had the same experience an hour a go. But it's taking some time, so go ahead by another disk ;-)
17:16lpetits/by/buy
17:16kotarak-.- geez
17:17RaynesThe fact that Ioke ints !- Java ints and Ioke strings != Java strings are annoying.
17:17Rayness/are/is/
17:22lpetitI'm *really* impressed by the quality of the material in labrepl. Really a great work. Both from the technical side and the pedagogic side.
17:23KirinDaveHoly crap these folks are picking me dry
17:23KirinDaveThis is crazy detail they want
17:23KirinDaveI'm naming line numbers.
17:24KirinDaveDoh
17:24KirinDaveMan wrong room over and over.
17:27lpetitok, maven 2 plugin for eclipse seems to work like a charm, labrepl will get detailed instructions on how to work from scratch with eclipse+ccw within minutes
17:28lpetitWith the advent of the Egit (Eclipse Git) plugin, there will be no need at all to touch the command line, even for the "clone labrepl" part ;-)
17:32slyphononce you've defonce-d something, is it possible to undef it? (for REPL experimentation purposes)
17:33drewrlpetit: you say that like it's a good thing ;-)
17:34kotarak(doc ns-unmap)
17:34clojurebot"([ns sym]); Removes the mappings for the symbol from the namespace."
17:34nossare there any problems with running clojure code in webstart?
17:34slyphonkotarak: ok, cool
17:35kotaraknoss: http://groups.google.com/group/clojure/browse_frm/thread/2d79e297431e2d29#
17:35technomancyslyphon: actually just "def" will do it
17:37nosskotarak, thanks, *reading*
17:37slyphontechnomancy: oh, mm'kay
17:37slyphontechnomancy: wait, so (def *my-defonced* nil)?
17:39technomancyslyphon: sure. defonce is the only piece enforcing the "oncedness"
17:39kotarakslyphon: with def the Var will survive (*my-defonced* is still available), with ns-unmap it will be completely gone.
17:39slyphontechnomancy: ah! of course
17:40slyphonkotarak: ok, i understand
17:40slyphonthanks
17:41lpetitdrewr: one should never listen to what I'm saying :-)
18:00naeuok, so now i'm running with a classpath, I'm trying to work through this: http://stackoverflow.com/questions/1341154/building-a-clojure-app-with-a-command-line-interface
18:00naeualthough i'm failing at the compilation stage
18:11hoecknaeu: you don't have to compile just to run your script
18:12hoeckrun your script with: java -cp <your classpath> clojure.main <your-script.clj>
18:13naeuhoeck: oh, interesting, so clojure.main takes a src file to interpret as a param?
18:13naeudoes that src file need to be on the classpath too?
18:13RaynesYes.
18:14naeuI'm totally going to write some scripts to get around this mess
18:14hoeckno, I don't think so
18:14hoeckthe clj, can be anywhere
18:14RaynesMost people don't bother compiling unless they need compilation specific features, or some of the other benefits of compilation.
18:14Rayneshoeck: Really?
18:14hoeckbut all scripts you refer to (via use or require) must be on the classpath
18:15hoeckRaynes: well, just tried it with a simple example and it works
18:15naeuRaynes: does compiling improve execution performance? Or just startup time?
18:15hoecknaeu: no, only writes the already compiled stuff to disk
18:15hoeckevery clojure function is always compiled, there is no intepretation
18:15lpetithoeck: startup time
18:16lpetitnaeu: startup time
18:16Raynesnaeu: startup time.
18:16naeu:-)
18:16lpetit:)
18:16hoecklpetit: right, and java-interop
18:16lpetitsure
18:16lpetitusing it everyday on ccw hacking ! :)
18:26kylesmithI would like to suggest an improvement to the docstring of dorun.
18:27kylesmithWhen you have a lazy-seq whose elements are themselves lazy-seqs, it seems dorun will not actually force them.
18:28kylesmithHas anyone else encountered this pitfall before?
18:30hoeckno, but I never had to force a lazy seq of lazy seqs via dorun :)
18:31kylesmithwell, the outer lazy-seq of from iterate, so I can't use doall
18:32kotarakkylesmith: oeh, you can't use dorun also, no?
18:32kotarakdorun won't return
18:32kylesmithI can now (I had to add a doall to the inner lazy-seqs, which obviously don't need to be lazy for my purposes)
18:33kotarakkylesmith: I don't get, how this solves the infinite outer iterate....
18:34arnihermannI vaguely remember there being a problem with macros and symbols being resolved -- can anyone recall something about that?
18:34arnihermannwhen in fact, they were not supposed to be
18:34kylesmithwell the outermost iterate is still lazy. The problem is dorun wasn't forcing each element of the iterate call, so it just returned immediately.
18:35kotarakarnihermann: that is a feature => hygienic macros. If you don't want to resolve symbols use ~'unresolved-symbol
18:36arnihermannah
18:36kylesmith,(time (dorun 4 (iterate #(do (Thread/sleep 1000) (map inc %)) [0 0 0])))
18:36clojurebot"Elapsed time: 4004.01 msecs"
18:37licoresseHow can I reset a ref that is defined like this: (def selection (ref (sorted-map))) ? I tried (dosync (alter selection {})) but obviously this is not correct
18:37kylesmithack, bad demo.
18:37kotarakOha. dorun takes a also an optional count.
18:38kotaraklicoresse: ref-set
18:38licoresse,(doc ref-set)
18:38clojurebot"([ref val]); Must be called in a transaction. Sets the value of ref. Returns val."
18:38licoresse:) thanks
18:39arnihermannkotarak: what if I'm doing some work outside the syntax quote? and preparing that symbol there?
18:39kotarakkylesmith: (dorun 4 (map dorun (iterate stuff here)))
18:40kylesmith,(time (dorun 4 (iterate #(map (fn [x] (Thread/sleep 1000)) %) [0 0 0])))
18:40clojurebot"Elapsed time: 0.679 msecs"
18:40kylesmithkotarak: yes, that will work, but my point is that how is anyone ever supposed to know to do that?
18:41kotarakarnihermann: (let [good (gensym) bad (symbol (str "abc" "xyz"))] `(vector ~good ~bad))
18:41kotarakkylesmith: I never expected dorun to do what you want. It is nowhere stated. And how do you get a non-recursive dorun?
18:42kylesmithI'm not expecting dorun to recursively force seqs either, but I think it would be nice to mention this 'problem' in the docstring.
18:43kotarak,(time (dorun 4 (map dorun (iterate #(map (fn [x] (Thread/sleep 1000) x) %) [0 0 0]))))
18:43clojurebotExecution Timed Out
18:43nossis there any form of dependency injection implemented in clojure?
18:43arnihermannkotarak: I'm doing (symbol (str "'" param))) where param is a parameter passed to the macro (sort of) and I need to be that exact value
18:43kotaraknoss: dependency injection is handled via functions/closure.
18:44arnihermannkotarak: but otherwise, that would work just fine
18:44kotarakarnihermann: the ' is not part of the symbol.
18:44arnihermannah
18:44nosskotarak, no reflection on type annotation and automatic resolving of what actual implementation to pass in?
18:44arnihermannright
18:44kotarak,(let [x (symbol "abc")] `(~x))
18:44clojurebot(abc)
18:45nossi got the book by stuart and started reading it the last days, so i dont know how used this #^notation is used.
18:46kotarak,(macroexpand-1 ''foo)
18:46clojurebot(quote foo)
18:47kotarakarnihermann: 'foo is equivalent to (quote foo)
18:47arnihermannkotarak: thanks
18:47kotaraknoss: #^{:foo :bar} x is similar (but not equivalent) to (with-meta x {:foo :bar})
18:48kotaraknoss: #^String x ~~> (with-meta x {:tag String})
18:49nosskotarak, can i reflect on those meta after code has been compiled?
18:49kotaraknoss: sure
18:49kotarak,(meta #'map)
18:49clojurebot{:ns #<Namespace clojure.core>, :name map, :file "clojure/core.clj", :line 1764, :arglists ([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]), :doc "Returns a lazy sequence consisting of the result of applying f to the\n set of first items of each coll, followed by applying f to the set\n of second items in each coll, until any one of the colls is\n exhausted. Any remaining items in other colls are ignored. Function\n
18:49nosskotarak, cool, then at least there is a good chance someone will get something like google guice implemented if it has not already been done for clojure.
18:49kotarak,(meta (with-meta [] {:foo :bar}))
18:49clojurebot{:foo :bar}
18:50Chousuke#^Foo attaches the metadata to the symbol, at read-time; with-meta attaches it to the value, at runtime
18:51arnihermannkotarak: thanks, i was confusing quote with ' being a part of the name of the symbol
18:51arnihermannkotarak: thanks alot!
18:51kotarakChousuke: that's why I said "is similar (but not equivalent) to" (shame-less self promotion: http://kotka.de/blog/2009/12/with-meta_and_the_reader.html)
18:52arnihermannkotarak: btw, awesome blog, love it
18:52kotarakarnihermann: thanks :)
18:53lpetitany enclojure developer here ?
18:56lpetitI'm writing a "mini-dsl" :-) where a text editor state is (minimally) currently represented as a map : {:text "the text" :offset 3 :length 0}, and in the "human friendly" form, it is just represented as "the| text". The pipe denotes the cursor position.
18:58lpetitNow I want to extend it to really represent selections in the text editor, e.g. {:text "the text" :offset 3 :length 2}. I don't know if the "human friendly" from can just be as "the| t|ext" with two pipes, or as "the< t>ext" with a start and a stop delimiter.
18:58RaynesLicenser_: You around?
18:58Licenser_Me?
18:58Licenser_Noooo!
18:58Raynes;P
18:58RaynesLicenser_: Adding doc to the whitelist doesn't seem to do anything.
18:58Licenser_hmm
18:58lpetitDoes anybody know whether some editors *really* have different behaviors if the selection has been made left to right or right to left ?
18:59Licenser_,(macroexpand '(doc doc))
18:59lpetitThat is, if :selection can be a negative integer ?
18:59Licenser_(clojure.core/print-doc (var doc))
18:59Licenser_you've to allow this
19:01lpetitrofl: I already implemented it with the two pipes version when I first wrote it, will stay with this for now on
19:03RaynesLicenser_: "(doseq [x \"Hello, World!\"] x)" -> SecurityException.
19:03Licenser_did you allow doseq?
19:03RaynesIt's already allowed in the default sandbox.
19:03Licenser_yap it is
19:03RaynesBut even if I allow it manually, it does that.
19:04Licenser_okay let me investigate :)
19:04RaynesHeinz - Private Sandbox Investigator. :P
19:04Licenser_yuck good greif
19:04Licenser_did you ever macroexand that
19:05Licenser_and haha, nice title
19:05RaynesNosir. Never macroexpanded that.
19:05Licenser_it is 4 lines long on my screen
19:06Licenser_(loop* #'clojure.core/seq #'clojure.core/int #'clojure.core/int #'clojure.core/< let* . #'clojure.core/nth recur #'clojure.core/unchecked-inc let* #'clojure.core/seq let* #'clojure.core/chunked-seq? let* #'clojure.core/chunk-first recur #'clojure.core/chunk-rest #'clojure.core/int #'clojure.core/count #'clojure.core/int let* #'clojure.core/first recur #'clojure.core/next #'clojure.core/int #'clojure.core/int) <- functions included
19:06Raynes:o!
19:06Licenser_so I guess the problem is that I don't have half of that in the lists :P
19:07RaynesHehe. There is a lot you don't have in the list.
19:07Licenser_yap
19:07RaynesWould you mind if I added some obviously safe functions to the list myself? I have some in mind.
19:10Licenser_Raynes: please you're as good as me when it comes to it :P
19:10RaynesHehe.
19:12RaynesLicenser_: When you get that fixed, could you push 0.2.5 for me? I have to take off (once again :|) for a while.
19:12Licenser_of cause
19:12Licenser_have fun Raynes
19:12RaynesThanks buddy. <3
19:16Crowb4rAnyone here use Scala all that much?
19:18defnI haven't touched scala yet. Clojure has been my only foray into FP beyond Haskell thus far
19:19Licenser_greetings defn by the way :)
19:20miltondsilvascala is to java as java is to c++ ... it's an improvement but one limited by what the mainstream accepts
19:22miltondsilva(at least that's how I felt when I wrote some small programs in it... but I may be totally wrong)
19:30defnHiya Licenser_
19:30Licenser_I toyed a bit with your walton, I hlope you don't mind
19:30defnBy all means!
19:30polypus~ping
19:30clojurebotPONG!
19:30defnIt's WTFPL for a reason. ;)
19:31Licenser_^^
19:31Licenser_but you'll like the stuff I think, results are now really good
19:32underdevmiltondsilva: i'm totally stealing that line
19:36defnLicenser_: I'm really excited to see the progress
19:36defnhave you submitted a pull req.?
19:36miltondsilvaunderdev: ;)
19:36Licenser_not sure if I did for the latest changes, let me see
19:37defnLicenser_: Perhaps it would be interesting to create a site now which contains core fn examples. That was always my hope with an earlier project, but no one submitted any examples.
19:38Licenser_http://playground.licenser.net:3000/walton.html
19:38Licenser_ ;)
19:38defnyou little!
19:38defnhaha
19:38defnoh cool! you actually show it's output now!
19:38Licenser_yap
19:38defnwe need to do syntax hilighting, and maybe make some ajaxy drop downs or something to see output
19:39Licenser_defn: I was coding remotely, putting the webside online was the simplest thing
19:39defn*nod*
19:39defnvery cool Licenser_ -- This is fantastic.
19:39Licenser_defn, it's your work, I just tossed in a bit sandbox
19:40defnLicenser_: it's a collaborative effort :)
19:40Licenser_:)
19:41defnwhoa. I didn't know github let you apply merges automagically from their web interface
19:42Licenser_:)
19:42Licenser_they do?
19:43defnI clicked something that said "Fork Queue" -- which sounds funny if you say it out loud
19:43Licenser_heh
19:43defnbut i digress, I selected your commits and hit "apply"
19:43defnlooks like it's applying them right now without the fetch/merge/push
19:44defnIt is "processing" them right now -- no telling how long this will take...
19:44Licenser_heh
19:45Licenser_bad news is, it got slower :P
19:46defnthe functionality is what is important
19:46defnas long as the utility isn't sacrified i dont see speed as a big factor
19:46defnit's really just about getting a nice example in your REPL for how to use a function
19:53Licenser_*nods*
19:53Licenser_when things are 'longer running' you can save stuff and speed things up
19:55Licenser_hrm lein is hating me :(
20:07Licenser_it really does grrr
20:10Licenser_lein just tells me: All :namespaces already compiled.
20:10Licenser_ but there isn't anything compled :(
20:15defnLicenser_: what does your :namespaces line look like in project.clj?
20:16Licenser_nothing, I don't have that
20:16Licenser_worked fine untill now
20:16defnmine looks like :namespaces [walton.core, walton.blah]
20:16defnyou need to explicitly say which namespaces to compile nowadays
20:16defnyou may also need a (:gen-class)
20:16defndepending on if it has a main
20:17zaphar_laptopdoes clojure occasionally have problems when calling a java constructor when the arguments are a super class of the constructors expected argument types?
20:18zaphar_laptopI'm getting a class cast exception that seems to be doing that
20:18Licenser_:(
20:18Licenser_narf
20:18defnnARF!
20:18Licenser_exactly
20:18Licenser_I want to run clicky on my server!
20:21_mstyou can also do ':namespaces :all' to have it sniff them all out for you
20:21technomancydon't do that though.
20:21technomancyunless you have a good reason
20:22_mstis laziness a good reason? :)
20:22technomancyit just breaks compatibility across clj versions
20:24defnLicenser_: I pulled your changes in
20:24defnwe should be up to date now
20:24Licenser_defn: cool!
20:24Licenser_^^
20:30kylesmithI'm experiencing an index out of bounds exception, but A. it doesn't give me the index, and B. the stack trace is all in clojure code, not my code. How can I debug this?
20:30defnLicenser_: one thing I've been thinking about is... It might be neat to weight users who are contributors to Clojure
20:30defnAnd also order them by most to least recent
20:31zaphar_laptopstupid ClassCastException!!!
20:32defnIt would introduce another layer of parsing, but this could be done on a daily basis. In other words, the logfile's name would tell us how recent something was
20:33kylesmithOther than nth, what clojure functions can throw index out of bounds exceptions (if any)?
20:34technomancyLicenser_: the next version will tell you *why* no namespaces were compiled instead of that unhelpful message
20:34defntechnomancy: that will be very nice
20:34defntechnomancy: i saw you mentioned something in a tweet about upcoming swank-clojure goodness -- what were you referring to if you dont mind me asking...
20:35Licenserdefn: hmm not sure, examples can come from everyone and especially code few new users give easy examples
20:35Licensertechnomancy: that'd be great :)
20:35defnLicenser: yeah I don't know if it makes sense to weight on users, but for new things like cell, it could be handy
20:35Licensertrue
20:36defnthere has been a lot of pseudocode bandied about for cells
20:36defnhowever, if it runs in the sandbox, who is to say it is incorrect
20:36Licenserheh
20:38defnLicenser: now we need to get some fancy syntax hilighting here
20:38Licenserheh
20:41defnLicenser: how long does it take for you to run (walton "zipmap") at a REPL?
20:41Licenseroh you ask questions
20:42LicenserI run it on a slow system for testing, the combine stuff took 1.2 minutes or so
20:42LicenserI got a new toy for you all http://82.210.31.97:8080/
20:43defnany what is this? :)
20:43defnand*
20:44LicenserThis is clicki! A clojure code wiki
20:44Licenseryou can just add a 'path' and write code, result of this code will be shown
20:44Licenseryou can define functions and call functions from other pages
20:44dnolenLicenser: I don't see anything at that url
20:44RaynesNor do I.
20:44Licenserdnolen: a Hello World text right?
20:45dnolenno, nothing
20:45Licenseroh I should have restarted the server after stopping it :P
20:45zaphar_laptophrmmm how does clojure handle interfaces in a constructor signature?
20:45zaphar_laptopanyone know?
20:46RaynesLicenser: If you get the clj-sandbox stuff figured out tonight, query me, or email me if I'm not online.
20:46Licenserhttp://82.210.31.97:8080/info
20:47LicenserRaynes: I'll work on this tomorrow, I looked into it and it is something more seriouse/complicated :(
20:47RaynesLicenser: Okay. I'll be around for testing tomorrow anyways, so it works better for us both. :p
20:47Licensercool
20:48RaynesLicenser: java.lang.SecurityException: Code did not pass sandbox guidelines: clojure.lang.LazySeq@0 <-- You aren't kidding about complicated! I just executed (println "HAI") on the page you linked. :p
20:49Licenserprintln is forbidden :P
20:49RaynesOh yeah. I forgot that I had whitelisted it for my bot.
20:49RaynesIt seems harmless enough.
20:49Raynes,(println "Hai thar, I'm clojurebawt!")
20:49clojurebotHai thar, I'm clojurebawt!
20:50Licenser:)
20:50Raynes:)
20:51Licenserhrm there seems to be a seriouse issue in the sandbox
20:52defnLicenser: how do you edit text on clicki
20:52defnoh i see, page/edit
20:52zaphar_laptopso apparently clojure doesn't handle method signatures that specify interfaces very well that is somewhat prohibitive
20:52Licenserno just /page
20:53Licenseror /page?edit=
20:53defnif the page already exists it is /page/edit, though right?
20:53defnoh okay
20:53defn/page/edit works
20:53Licenserbut you can do /page/subpage/sub/sub/page ...
20:53Licenserhrm
20:55technomancydefn: it's locals-inspecting at breakpoints and debug-repl integration (in swank)
20:55technomancyhugod is the man behind that
20:55defnooo!
20:55defndebug-repl!
20:55technomancythe one, the only, the legendary debug-repl
20:56technomancyyou can use it in the swank-break branch already, but it's still got a couple issues
20:56defnoften imitated, but never duplicated
20:56defnetc. etc.
21:01zaphar_pshello can you guys hear me in here?
21:01dnolenzaphar_ps: yeah. no luck on searching for that issue on the ML? what are you trying to do exactly?
21:02zaphar_pssorry I thought I was having trouble with chat client there
21:02zaphar_psfor a while it looked like I had been banned or something was getting weird messages
21:03zaphar_psdnolen: I have a class whose constructor takes arguments of a certain interface but I get classCastExceptions when I try to code it
21:04zaphar_psPlain java it works fine
21:04dnolenhave you posted your code somehwere?
21:04zaphar_psin clojure it doesn't
21:04zaphar_psgetting ready to
21:04zaphar_pstrying to find links to related javadocs as well
21:11zaphar_pshttp://gist.github.com/341873
21:12zaphar_psthere code that dies and an accompanying link to example java code
21:12zaphar_psit seems like this should work but it doesn't
21:12zaphar_pswhich leaves me somewhat stranded for setting up an appengine test datastore environment
21:12zaphar_pswell I can probably dig in a little and use lower level api's but it's annoying still
21:14dnolenwhat happens when you try to print helper-conf#
21:14dnolen?
21:14dnolenzaphar_ps: ^
21:15zaphar_psdnolen: #<LocalDatastoreServiceTestConfig com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig@78361e>
21:16zaphar_psin the repl instance? shows that it is an instance of the correct interface LocalServiceTestConfig
21:17zaphar_psI did manage to boil the crash down to two lines of code in the repl that crash the same way as clojure.lang.Reflector.boxArg is doing
21:18zaphar_ps(.cast (class LocalServiceTestConfig) helper_conf#) crashes with the same exception
21:18zaphar_psI'm guessing because java interfaces can't cast their implementors?
21:19zaphar_pswhich is how clojure boxes it's args
21:21zaphar_psdnolen: any thoughts?
21:22dnolenzaphar_ps: sadly I know too little about Java interop. Though I'm assuming what you want can be done. This pattern is similar to event listeners right?
21:22zaphar_psI'm not sure if it is or not
21:23defni wonder how hard is it to call elisp from clojure
21:23defnit is*
21:24dnolenzapahr_ps: have you looked at proxy?
21:24dnolenzaphar_ps: ^
21:24slyphonargh
21:24zaphar_psdnolen: I don't think it will help since both the class and the argument are java
21:25slyphonclojure.contrib.sql is gonna make it hard to use two db connections simultaneously
21:25zaphar_psslyphon: bummer, but maybe you have some idea what I'm missing?
21:25zaphar_pshttp://gist.github.com/341873
21:26zaphar_psthe crash actually occurs on line 364 of this file in the clojure source code: http://github.com/richhickey/clojure/blob/master/src/jvm/clojure/lang/Reflector.java
21:26slyphonhrm
21:27zaphar_psclassCastExceptions are ruining my project
21:27slyphonuh, maybe it'd be easier to do that stuff in a function which your macro calls?
21:27dnolenzaphar_ps: why wouldn't proxy work? you can create an instance of class and define interfaces it implements? I'm guess here tho.
21:27dnolenguess -> guessing
21:28slyphoni find that pattern sometimes helps to clarify things
21:28slyphonthough, i'm really not sure
21:29zaphar_psslyphon: I could try but it's not a syntax error and I can reproduce the crash in a repl without functions or macros
21:29slyphonoh, then i have no idea
21:29zaphar_psdnolen: I don't want to reimplement my own datastore config I want to use the one Google already thoughtfully provided
21:30dnolenzaphar you don't have reimpliment.
21:30dnolenzaphar_ps: ^
21:30zaphar_psdnolen: I'm not following
21:31dnolenI have a hunch. try using proxy that is all :) if it doesn't work it doesn't work. But I'm sure someone has butted up against this very problem before, take it to the Mailing List.
21:32alexyk,(letfn [(endpoints [n m] (let [chunk (int (/ n m))] (loop [r [] prev 0 curr chunk] (if (> curr n) (conj r n) (recur (conj r prev) curr (+ curr chunk))))))] (endpoints 100 3))
21:32clojurebot[0 33 66 100]
21:32alexykis there an FP-ier way?
21:32defnis there something similar to osascript for linux?
21:33alexykendpoints breaks 0..n into m chunks and shows the starting points of each chunk, trailed by n
21:33zaphar_psdnolen: I'll trye but I'm not sure how to use proxy without implementing the required methods
21:33dnolenbut you're extending a class which already implemented that Interface right? why do you need to implement them?
21:34dnolenzaphar_ps: or there something going on in the Java code which I don't grok. Is it creating an Interface object or something?
21:37zaphar_psno it creates an instance of a class that implements an interface
21:38dnolenI'll humor you and try to recreate :) which jar do I need in my path. I have the latest appengine.
21:38dnolenzaphar_ps: ^
21:39zaphar_psappengine-testing-1.3.1.jar
21:39zaphar_psdnolen: ^
21:39dnolenwhere is that in the appengine folder?
21:40dnoleni see appengine/lib/testing/appengine-testing.jar
21:42defnIs there a java property which states the current OS the JVM is running on
21:42somnium,(let [f (fn [n m] (conj (->> n range (partition (int (/ n m))) (map first) vec) n))] (f 100 3))
21:42clojurebot[0 33 66 100]
21:43defnnvm, found it
21:43defn(System/getProperty "os.name")
21:43defn,(System/getProperty "os.name")
21:43clojurebotjava.security.AccessControlException: access denied (java.util.PropertyPermission os.name read)
21:44alexykso I have a BDB with a database of N keys. I can split 0..N into ranges and have one read cursor open for each range, thread-safe. Which concurrency primitive is suitable for scanning all cursors in parallel, where each returns a vector of pairs, to conj them all together or suck into a map?
21:44zaphar_psdnolen: hrmmm the interface isn't that complicated so creating a proxy that wraps the actual object might be doable is that what you meant?
21:44somnium,(let [f (fn [n m] (conj (->> n range (take-nth (int (/ n m))) vec) n))] (f 100 3))
21:44clojurebot[0 33 66 99 100]
21:44dnolenzaphar_ps: yes
21:44alexyksomnium: interesting
21:44zaphar_psdnolen: trying now (thanks for the suggestion I only just now understood)
21:45defnAnyone on OS X? What is the output of (System/getProperty "os.name") on OSX?
21:46alexykdefn: "Mac OS X"
21:46defnty
21:46alexyknp
21:54zaphar_psdnolen: proxy exhibits same issue :-(
21:55zaphar_pslooks like it's mailing list time
21:55dnolenzaphar_ps: what happened?
21:55zaphar_pssame classCastException
21:56dnolencan you gist your proxy code?
21:56zaphar_psdnolen: sure
21:56zaphar_psone sec
21:57zaphar_pshttp://gist.github.com/341873
21:57zaphar_pssame gist
21:58dnolenI think the proxy should specify [class-to-instantiate interface]
21:58zaphar_psdnolen: how so?
21:58dnolen(proxy [LocalDatastoreServiceTestConfig LocalServiceTestConfig] [])
21:58zaphar_psdnolen: I'll give that a try
22:00zaphar_psdnolen: ahh no go the datastore config class is final can't inherit from it
22:00zaphar_pswon't even compile
22:00dnolenzaphar_ps: k out of ideas :)
22:11underdevanyone get labrepl working under emacs?
22:26lancepantzanyone mind taking a look at http://www.pastie.org/884058 for me?
22:26lancepantzvery basic, filter and contains? aren't behaving as i understand them
22:28Rayneshttp://github.com/richhickey/clojure/commit/29389970bcd41998359681d9a4a20ee391a1e07c
22:28RaynesLife is good.
22:28arohnerlancepantz: contains works on sets and maps
22:29arohnerlancepantz: read it as 'has-key?' rather than contains
22:29lancepantzah
22:30arohnerlancepantz: make ignore-keys a set rather than a list, and it should work
22:33lancepantzgot it, thanks arohner
22:33arohnerlancepantz: np
22:39slyphonoof
22:40slyphonNo matching method found: println for class swank.util.io.proxy$java.io.StringWriter$0
22:40slyphonuhh, wtf?
22:43slyphonoh, duh
22:56defnhmmm, how to do the following:
22:57alexykRaynes: care to give an example for that commit usage?
22:57defndepending on the os I'd like to use function a, or function b -- I have a fn which has a (cond) statement. Should I define both functions inside this cond function?
22:57Raynesalexyk: Ask psykotic.
22:57alexykpsykotic: ^^ ?
22:57RaynesWe were discussing this over in #clojure-casual
22:58psykoticalexyk: i just sent an email about it (with some suggestions for extending the current :keys binder), with a few usage examples
22:58psykoticto the list, i mean
22:58alexykkk
22:58alexykcool
22:58defn(defn which-os? [] (let [this-os (System/getProperty "os.name")] (cond (= this-os "Linux") (return a fn here?) (= this-os "Mac OS X") (same here??))))
22:59slyphonyou can use recur without loop, right?
23:03psykoticslyphon: yes
23:03zaphar_psdefn: that seems acceptable
23:03slyphonok, thought so
23:03defnzaphar_ps: thanks for the feedback
23:04zaphar_psdefn: I might name which-os? differenly though
23:04defnzaphar_ps: yeah i found a way to make it make more sense
23:05defn(defn- open-in-browser-mac []) (defn- open-in-browser-linux []) (defn open-in-browser [] (cond...))
23:13defnhmmm. am i adding this namespace wrong?
23:13defni have src/project/core.clj, and src/project/other.clj -- I would just do (ns project.core (:use project.other)) right?
23:21maxhodakwhat happens when you export a method using gen-class with a dash in the name?
23:21maxhodakdoes it become an underscore?
23:26technomancyis #"^\s*(;.*)?$" a good regex for matching lines of Clojure that don't contain code?
23:38Raynestechnomancy: That's a good regex for making your eyes bleed late at night.
23:39mabesI'm trying to use use defprotocol and deftype.. For some reason I am getting "Can't define method not in interfaces: function_name" for the second function/method I add. It worked fine for the first one I added...
23:39mabesDoes that error message sound familiar to anyone?
23:39mabesMy code and backtrace are here: http://gist.github.com/341958
23:41tomojmabes: it sounds like the method you are trying to define is not in the interface you are implementing
23:41RaynesIt is.
23:41tomojhmm, but I see it there in the protol
23:41tomojer, protocol
23:42RaynesI'm stumped.
23:42tomojis this a toy? sounds interesting :)
23:42RaynesI wrote something similar a while back.
23:42mabesYeah, the name of the project says it all :) I'm trying to implement a paper I read on it
23:44mabes(this is the paper: http://bit.ly/bbxMRD)
23:47tomojweird, I just played klondike for the first time about an hour ago
23:47mabesheh, I actually learned it recently for this since playing it before never appealed to me
23:48Raynestomoj: For the first time?
23:48tomojoh, wait..
23:48RaynesIf I ever hear you call me a youngster...
23:48tomojno, I had played it before
23:48tomojmuch earlier, of course, naturally
23:49tomojmy mistake came from having just installed ubuntu, and while waiting for the install to finish I played the solitaire included on the livecd (called "klondike"), and the default settings were different than actual klondike rules
23:49tomojI could turn one card at a time into waste but only had a limited number of redeals
23:49tomojso I thought "klondike" was some easier variant
23:49RaynesAh.
23:49tomojwhich would, I think, be more amenable to mathematical inquiry, actually
23:52mabesthere are a ton of variants.. what I found that was interesting is that for klondike you are actually allowed to see all the cards in the main deck. I always thought you could only see the top one or the top three at most.
23:53RaynesYou guys suck. Tetris is the only game that is reasonable to play while you're waiting on something to finish.
23:54mabesheh, I would probably agree
23:55ttmrichterI thought drinking games were best while waiting for compiles.
23:58technomancytetris you can play without leaving Emacs, so it has my vote
23:59psykoticRaynes: you suck. it's all about torus trooper.
23:59Raynes:O!