#clojure logs

2011-05-06

00:15ymasorywhat's the difference between STM and using H2/Derby in-memory?
00:17amalloywell, the stm won't be hideously slow
00:18amalloyeg specifically, it never locks anything
00:18amalloyso you can get as many cheap snapshots as you want
00:18ymasoryah. any major semantic difference?
00:19amalloythe stm understands clojure constructs in a way that i can't imagine derby ever would
00:20ymasorythanks
00:20amalloyi don't know anything about derby, but writing (alter num-customers inc) must be shorter than their equivalent
00:54codedigestionhey!
00:55codedigestionis there anybody out there?
00:55symboleYes.
00:55codedigestiongreat! just wondering. First time in here. thanks for responding!
00:55codedigestion:)
00:56symboleI am a robot.
00:56TheMoonMasterMe too.
00:56symboleBeep! bop!
00:56codedigestioni eat robots for breakfast... What language are you programed in robot?
00:56codedigestionpython???
00:56clojurebotpython is ugly
00:56codedigestionyou seem pretty sloow....
00:56Belaf:)
00:57symboleI am made with Befunge.
00:57TheMoonMasterPython really is ugly...
01:00codedigestioni would've been impressed if you were made in brainfuck
01:00codedigestionoh well...... can't win all the time...
01:01TheMoonMasterI think ZOMBIE would have been a better choice.
01:04symboleI thought Befunge would be arcane enough.
01:04symboleApparently not.
01:05TheMoonMasterWell, "The language should allow the necromancer to animate dead bodies, summon and control spirits, and solve any computable problem. ", sounds awesome for a bot.
01:06codedigestionZombie is an acceptable alternative to brainfuck. Perhaps, the core component was composed in brainfuck, and the remainder, zombie. This Befunge isn't impressive, though...
01:36no_mindIf I instantiate a defrecord based record.How can I find the type of record ? Using 'type' returns Java.lang.Class
01:37hiredmanyou do (defcord Foo ...) in the namepsace bar.baz then the java type is bar.baz.Foo
01:39amalloyno_mind: Foo is in fact the class. (class Foo) returns Class, just like (class String) does
01:42no_mindamalloy: If I do (defrecord Foo ...) then do (def main (Foo. ...)) . I want to know if I can find main is of type Foo ?
01:43amalloy(instance? Foo main)
01:43hiredman(type main) will tell you
01:43hiredman(the type)
01:44amalloybut i don't think you should want to do that. if you don't know the type of the record object already at compile time you don't usually get much benefit from using a record rather than a hashmap
02:37BelafHi
02:40BelafI'm trying (for curiosity/learning) to quickly get the color component values from an argb integer... I'm really surprised to see that
02:40Belaf(.getRed (java.awt.Color. 0xff909030))
02:41amalloy&(java.awt.Color. 0xff909030)
02:41sexpbotjava.lang.Exception: EvalReader not allowed when *read-eval* is false.
02:41Belafis much faster than
02:41Belaf(bit-and 0xff (bit-shift-right 0xff909030 16))
02:41BelafWhy is it so?
02:41amalloyBelaf: the bitops do runtime type checking to determine what size int they're dealing with, i suspect
02:42BelafI see... I'd have thought that allocating an object would have taken more time...
02:43amalloyclojure is allocating objects all the time
02:44amalloyit's working with java.lang.Long, not primitive long, most of the time
02:45BelafIs there any option to avoid bit-and and bit-shift-right type checking? On the other side trying to use arithmetic operations (+ and *) doesn't get any faster...
02:46amalloy$findfn 0xff 0xf 0x0f
02:46sexpbot[clojure.core/max-key clojure.core/cond clojure.core/dosync clojure.core/sync clojure.core/char-escape-string clojure.core/with-loading-context clojure.core/bit-and clojure.core/*clojure-version* clojure.core/with-precision clojure.core/case clojure.core/min-key cloj... http://gist.github.com/958529
02:46amalloyhmph
02:47amalloyBelaf: there's unchecked-add and friends
02:48Belafoh, I'll look at them. Thanks!
03:07Belafamalloy: no luck, they get no faster. Actually every unchecked_XXX functions seem to allocate a clojure.lang.Numbers instance, so I guess I should stay with the java.awt.Color solution... maybe there's too much C in my memories :)
03:08amalloy~source unchecked-inc
03:09amalloyBelaf: they're not allocating c.l.Numbers. it's a class with several static methods
03:10amalloythe closest you can get in java to a plain, isolated function
03:11killahello
03:12killaguys
03:12killaanyone home?
03:14BelafOps, I misread (or better misunderstood it)... I need to give a better look... the speed didn't improve, though.
03:18no_mindis there a package/library in clojure for Publisher-Subscriber model ?
03:18Belafamalloy: what I'm surprised to see is that "(.getRed (java.awt.Color. 0xff909030))" is faster than "(unchecked-divide 0xff909030 (long 65536))"
03:19amalloy&(time (dotimes [_ 1e7] (/ 0xff909030 65536)))
03:19sexpbotjava.lang.Exception: EvalReader not allowed when *read-eval* is false.
03:19amalloyseriously? i guess sexpbot is broken
03:19amalloy,(time (dotimes [_ 1e7] (/ 0xff909030 65536)))
03:19clojurebotjava.lang.ExceptionInInitializerError
03:20amalloyor maybe not
03:20amalloyBelaf: anyway, i'm going to bed. good luck, i guess
03:20BelafAllright, thanks! Have a good night!
03:21killaI would like to ask some questions to experienced clojure developer
03:21killaif there is one here
03:21killa:)
03:21BelafErm... don't look at me ;-)
03:22no_mindkilla: this is a n00bies channel :P
03:22Fossikilla: never ask to ask
03:23Fossiunless you want payed consultant hours that is ;)
03:23killanah questions are rather basic
03:23killajust trying to figure out if clojure is right yo me
03:23killashouldnt be that hard
03:23killaright?
03:25killaanyway I have rather ambitious project in mind. I want to create very flexible RPG game. Since I am looking for runtime flexibility C++/Java and so on are out of the question (unless mixed with Lua or something).
03:26killasome concepts of lisp make sense to me
03:26killaand so does JVM
03:26killathe problem is this functional programming thing
03:26killaimmutable datatupes seem like bad idea when game state changes 24 times a second
03:27killaso Clojure sounds like bad idea, except that I like syntax (or rather lack thereof) and macros
03:28killaso what do you think people
03:28killa?
03:29seancorfieldkilla: well, clojure has very well controlled mutable state too
03:29seancorfieldatom, ref and other types support software transactional memory
03:29seancorfieldwhich would allow you to manage a mutable game state without worrying about concurrency problems
03:33killahow does that work? I mean compared to classic mutable variables?
03:34killaI never saw someone make real time game in clojure (I saw turn based game but that's it)
03:34killathanks for answering, btw
03:36killasorry but I still just don't see it as viable option
04:33seancorfieldkilla: sorry, got distracted with work... well, try it and see how well it works :) then someone will have made a real time game in clojure
04:33killalol, thank you
04:33seancorfieldif you don't think it's viable, i'm probably not going to persuade you...
04:34killawell, I've been googling a bit and I have found one RPG
04:34killathat seems real time
04:34killabut I guess that the problem I really have with the whole thing is that Clojure HAS some good ideas
04:34fliebelkilla: Writing a game in Clojure?
04:35killaresearching how viable is writting game in Clojure
04:35killaat the moment
04:35killanot writing anything yet
04:35fliebelkilla: 3 or 2D?
04:35Fossithere are lots of functionally written games
04:36killafor now it's 2d, but it's real time
04:36fliebelkilla: https://github.com/pepijndevos/Begame/tree/master/src/examples
04:37Fossiin my little toy thing i just applied the state every frame at the top of the game loop
04:38killabut the point is that I don't like cargo cult programming. And every damn language in the universe seems cargo cult. In python they won't give you optional static typing. In java no dynamic typing. And you NEVER, EVER get macros anywhere. And Clojure has no mutable typing. How about supporting most stuff that's usefull and letting ME decide?
04:38Fossibasically events in, commands out atd then applying them to the state
04:38killasorry for ranting
04:38eevarmutable typing?
04:39killaI mean mutable types
04:39killaI mistyped
04:39Fossiyou really can't have all the features there are
04:39killano need for all
04:39killajust all most common
04:39fliebelWell, in Common Lisp you can :P
04:39Fossibecause some of them are mutully exclusive
04:39clgvkilla: you should check atoms and refs
04:39killawell you can have both dynamic and static typing for example
04:40killasome are mutually exclusive, but most aren't
04:40killait seems it's mostly ego thing: everyone want's to get you to program his way
04:40killabut sorry for ranting
04:40killa:)
04:41fliebelkilla: https://github.com/graydon/rust/wiki/Language-FAQ "I like the language but it really needs $somefeature."
04:42killaFossi: you wrote Begame?
04:43fliebelkilla: I did :)
04:43killaokay
04:44killaso is it realisticaly possible to get decent performance (comparable to, say, Java) for real time game using Clojure?
04:44Fossiusing the jvm i'd say yes
04:44killathanks for comments so far, folks :)
04:45fliebelkilla: I'd say so. I have not written anything big with it, but I had 1000 ducks moving around randomly ina smooth way.
04:45Fossithen again a lot depends on the graphics there ;)
04:46fliebelkilla: I have an optional option for automating transitions between key frames, so sometimes you can get away with doing logic a dozen times per frame and then just drawing.
04:47killaanother thing I worry about is the fact that my game is going to be vey complex and very interconnected. That's kind of the point. I want extremely extensible game with scripting and stuff. (That's why I am seeking best language for the job, instead of settling for, say, Java)
04:47killaI have some game developer experience (mostly smaller flash games) and one unfinished RTS in c++
04:48fliebelkilla: You are likely to run into code organization then. Clojure is a single pass compiler, so you need to avoid circular deps and rometimes resort to forward declarations.
04:48killabut now I am truing to make something much larger (I mean conceptually larger, not fancier graphic)
04:48jamesswifthey all. I'm developing in emacs/slime and when i reload a file/namespace on the repl using (require .... :reload-all) and I get the exception "Unable to resolve symbol: blabla in this context" I see no way to find out on which line the offending symbol occurs. The stack trace is in clojure core code. Is there some way to get this that I'm unaware of?
04:48killaand Java is too damn staic
04:49killaI've heard about Steve Yegge bitching about single pass thing too
04:49killaon mailing list or somewhere
04:50fliebelI need to run now, but you can question me about Begame later today :)
04:50killathanks for trying to help
04:50killabasically the point is that I really need something that helps me write complex code
04:50raekjamesswift: if you press C-c C-k in the source code buffer, the rows with errors will be underlined
04:51killasee ya later, fliebel
04:52raek(C-c C-k is like (require .... :reload), but with slime integration)
04:52ttmrichterkilla: I'm curious here: why not just use Common Lisp?
04:53killattmrichter:I like JVM, and Common Lisp sounds very ancient (unless you are aware of some good implementation)
04:54ttmrichterThere are good commercial implementations. The open stuff tends to suck, though, yeah.
04:54clgvkilla: since clojure and java interop quite nice, you might also divide your development between the two, e.g. high performance graphics and stuff in java and complex rules of the logic game engine in clojure...
04:54jamesswiftraek: thanks a million. perfect.
04:56killaclgv: that's sort of what I have in mind. This assumes that Clojure is good at complex interconected logic. In theory it should be, since it's lisp. But functional-only and single pass compliling scares the me.
04:57clgvkilla: functional-only? there are great language concepts for coordinated mutable state as well
04:57killaclgv: I guess I will have to look a litle more thoroughly, then
04:57clgvkilla: the importance of the limitation to single pass compiling isnt quite obvious to me as well
04:58killaclgv: it creates problems when you have pices of code that are mutually dependent, does it not?
04:59clgvkilla: if you are referring to some kind of circular dependencies then afaik you also should avoid these in java, c# or c++ as well ;)
04:59raekI've heard that clojure actually has two pass compilation. however, the compilation unit is not the namespace, but the top-level form
04:59seancorfieldkilla: you can write mutually recursive functions in clojure just fine
04:59raekthis makes macros possible
05:00killaclgv: I am sorta trying to TRANSCENT java and such :)
05:01clgvto clarify: I didn't refer to mutually recursive functions with the previous comment ;)
05:02killabut yeah folks, I am not quite sure what I really need. This stuff is still rather alien to me.
05:02killacompletely different way of thinking
05:02seancorfieldclgv: i know - but i'm trying to see why killa is concerned about single pass compilation affecting mutually dependent code :)
05:03killabut it does seem more flexible than standard OOP model
05:03killadon't laugh at me, I am still warping my head about stuff
05:03killaaround
05:03clgvkilla: I started with clojur last october. I did only imperative OO languages before that
05:04clgvexcept from some prolog while studying ;)
05:04killaand, in your opinion, is this model more flexible? More expressive?
05:04killafrankly OO is too damn verbose
05:04seancorfieldyou can write OO in clojure if you want... i think java is too verbose
05:05killaand not enough runtime flexibility
05:05killabecause I want to create custom objects at runtime
05:05killayou know about universal design pattern by Steve Yegge
05:06killathere is blog post about that
05:06seancorfieldsteve has lots of interesting rants
05:06killaI know
05:06killaI agree about lot's of stuff
05:06clgvyou get custom objects with hash-maps ;)
05:06killahe recomended clojure
05:06killathat's why I am here
05:06seancorfieldi think you should just try and build something with clojure and see how it goes
05:07clgvif you need common "interfaces" you can define a protocol and implement records for it.
05:07seancorfieldit's very hard to reason about a language until you've used it to build real systems, imo
05:08killaagreed
05:08clgvwell, you get a feeling for it if you read an introductory book
05:08killaclgv: yeah I am also thinking about custom objects with hashmaps. That's very Javascript-like
05:08clgvand try the examples along reading and doing a little project after that
05:09killaclgv: Me and Steve Yegge came to similar conclusions about the same thing independently
05:11killaone moment, brb
05:36killaI am back
05:36killaI guess you are right folks
05:36killaI will have to create something first
05:36killathen rant about stuff.
06:12clgvlol that guy is funny ^^ http://steve-yegge.blogspot.com/2010/07/wikileaks-to-leak-5000-open-source-java.html
06:16killaclgv: yeah he is. Make sure to read his stuff about 'universal design pattern' and 'pinnochio problem'
06:17killaclgv: me and him are on same wavelength there
06:17killaclgv: that will explain to you why I got into clojure in the first place
06:17killaclgv: and it is great read, too
06:18clgv:D
06:18killabasically I am interested in system that are extensible at runtime
06:19killawhere you can swap functions inject new code and stuff
06:20killaliving systems
06:21clgv>>The Wikileaks founder said: "Today the Eclipse Foundation put out a private briefing calling me a 'non-thread-safe AbstractKeywordRemovalInitiatorFactory'"<< :D
06:21killaand I have heared lisp is supremely very expressive. Read some stuff and was impressed. Never really did anything, thought. That's why I got interested into Clojure (that and the fact that Steve recommended it).
06:22killabut I don't really know how good is clojure at any of that
06:22clgvI heard and tried some lisp in a lecture on Aspect-Oriented Programming. in CLOS this worked out of the box ;)
06:23killaclgv: and what about clojure?
06:24clgvI would have to find the old slides and examples to be able to compare that.
06:25killaI don't have problem with creating my own object system, as long as it can be made to work well
06:25clgvI know that project named robert.hooke has some wrapping around functions which was the technical side of aop runtime
06:26clgvso it seems possible to develop a more elaborate AOP framework
06:26killayeah aspec oriented programming is part of what I want
06:26killaaspect
06:26killaI might end up developing it myself
06:26killaI am rather motivated
06:26killaalthought I might not be motivated to do that in Clojure
06:27killadepends on many things
06:27clgvin java you already have aspectj for it ;)
06:27clgvthat was the second part of the before-mentioned lecture ...
06:28killait is quite a pain. Or at least it was last time I checked
06:28clgvI can't tell. Last time I saw it is about 3 years ago ;)
06:29killabasically the point is that Java is quite verbose and too damn static and I don't trust it at all
06:29killaso I am looking for alternative
06:29killabut functional seems a bit too radical
06:30killaalso I love idea of macros
06:30killacreating my own language construct
06:30clgvread that "programming clojure" or one of the others to get you started and build a small project meanwhile or when you are done reading ;)
06:31killayeah, probably
06:31clgvthat should help to decide. I think I read it in 2-3 days
06:33killathanks for having patience with me
06:34clgvnp. it's only about 7 months ago that I started using clojure ;)
06:35killaanothe issue is JVM itself
06:35killanow that Oracle has it
06:36ejacksonkilla: ain't nothing perfect in this world - you just have to work with what is available.
06:36killayeah I guess
06:46killareading Programming Clojure now.
06:46killathanks for advice
07:10cemerickkilla: "Oracle has it"?
07:10cemerickit's GPL'ed
07:17clgvhey cemerick, you know of lisp conferences for the remaining year?
07:18cemerickclgv: http://clojure-conj.org/
07:18cemerickApparently there won't be an ILC in 2011 http://www.international-lisp-conference.org/2011/index :-O
07:19cemerickThat's bizarre.
07:19clgvhm true
07:20killacemerick: I don't know the details but I know there where some court battles over JVM implementations. Google vs Oracle
07:20clgvdo you know of any journals in the lisp and functional programming topic?
07:21cemerickkilla: None of which matters a hoot unless you're an Android developer, or want to build your own "clean-room" JVM impl. Just sayin'
07:22cemerickclgv: There's a couple of FP journals. I don't know them off the top of my head.
07:22killait doesn't matter much to me, I agree. But if someone wants to make program accesible on computers without JVM and distributes it as .exe with JVM bundled in?
07:22cemerickclgv: There's also http://cufp.org
07:22killawhat happens with that?
07:22clgvcemerick: hmok I try to persuade google to tell me ;)
07:23cemerickkilla: Commercial redistribution of an unmodified JVM is still allowed, just as it was under Sun.
07:23killaso only modifying is no no ?
07:23killaI can live with that
07:23cemerickYeah, if you wanted to distribute a modified version, you'd have to use OpenJDK. But then you'd be subject to GPL.
07:24killahow large is JVM, btw ?
07:24killain megabytes
07:24clgvkilla: nothing is decided on that. you will have to wait for the outcome of that court battle ;)
07:31cemerickkilla: FYI: http://www.oracle.com/technetwork/java/javase/readme-142177.html#redistribution
08:37no_mindif defining a new record using defrecord, can I force an attribute of record to be a ref ?
09:13chouserno, but you can of course put a ref in any field you want
10:14mrbombastichow come i have to use seq to use basic operations on my sets, vectors etc? why don't these types implement the seq interface automatically? is there a performance reason?
10:16stuarthallowaymrbombastic: example?
10:16mrbombasticwhy doesn't set implement nth, but (seq set) does
10:16raekmrbombastic: I don't understand. many of the operations work directly on the data strucures (conj, disj, peek, pop, assoc, dissoc), and when you use sequence functions, they will call seq on the data structres automatically
10:17manutter,(doc nth)
10:17clojurebot"([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences."
10:17mrbombastici can't (rand-nth #{1 2}), but i can (rand-nth (seq #{1 2})) - why the need for the seq
10:17mrbombasticyeah, i've read the docs thanks
10:17manutter,(nth #{1 2 3} 2)
10:17clojurebotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentHashSet
10:17manutterno, I was just checking, I couldn't remember the order of the args :)
10:18manutter,(nth (seq #{1 2 3}) 2)
10:18clojurebot3
10:18raekmrbombastic: in this case, it's because hash sets do not have any "native" way of looking up the nth element
10:18mrbombasticbut they do when you wrap them as a seq
10:19mrbombasticwhy not have the code that implements nth for a set inside the definition of set in the first place, since it's possible
10:19raekto find element 3, you need to traverse the three and stop at the fourth observed leaf
10:19bartjmy 2c, there is no ordering required for hash sets
10:19raek*the tree
10:19raekseq is that traversal
10:19mrbombasticand in my case, i'm using rand-nth, so i don't care about ordering
10:19mrbombasticso rand-nth makes sense on a set
10:20manutterwell, I think you want rand-element in general, not rand-nth
10:20mrbombastic,(doc rand-element)
10:20clojurebotCool story bro.
10:20manutterdepends if you make a distinction between "set" and "ordered set"
10:21manuttersorry, that was pseudo code
10:21raekI see you point. one reason that rand-nth requires a sequential collection could perhaps be that there is no convenient api in clojure for fetching a random element of any data structure
10:21manutterI'm talking conceptually
10:21mrbombasticok
10:21mrbombasticbut it does all work, and the code is all there, you just have to wrap it in a seq which is counter-intuitive
10:21manutterI dunno, it seems intuitive to me
10:22manutterrand-nth assumes each element has an index/position, because nth refers to that position to retrieve the element
10:22manutterif sets in general do not index the position of their elements, nth would be meaningless
10:23mrbombasticit's not meanginless if n is random
10:23mrbombasticwhich it is when you use rand-nth
10:23raekmrbombastic: it would be convenient of rand-nth would have called seq on its argument in this case, but that would not have been god for vectors
10:23manutterif you had an ordered set, then the indexes would exist, nth would make sense, and rand-nth would be meaningful
10:23manutterYeah, I'm quibbling I know
10:23raekmrbombastic: with a vector, you have constant time lookup, but for a vector seq, you have linear time lookup
10:24manutterMy point is that rand-nth is 2 steps: (1) pick a random n, (2) give me the element at position n
10:24manutterThat's slightly different from a 1 step give-me-any-element-from-the-set
10:24mattmitchelli have a co worker who is trying to implement an java interface in clojure, which has a method that needs to throw a particular exception class. anyone know of a resource we can look at to find out how to do that?
10:25manuttermattmitchell: you mean just how to throw an arbitrary exception?
10:25raekmattmitchell: you can use the throw special form: (if (some-condition ...) (f ...) (throw (AParticularExceptionClass. ...args...)))
10:26manutteryeah, what he said
10:27mattmitchellok awesome. we'll play with that. thanks!
10:27manutter,(rand-elt #{1 2 3} 2)
10:27clojurebotjava.lang.Exception: Unable to resolve symbol: rand-elt in this context
10:27manutteroh, I see
10:28manutter,(clojure.contrib.seq/rand-elt #{1 2 3} 2)
10:28clojurebotjava.lang.IllegalArgumentException: Wrong number of args (2) passed to: seq$rand-elt
10:28manutterdoh, me stoopid
10:28manutter,(clojure.contrib.seq/rand-elt #{1 2 3})
10:28clojurebotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentHashSet
10:28manutterboo yeah
10:29manutterno wonder it's deprecated :)
10:30manutter,(let [any (fn [s] (rand-nth (seq s)))] (any #{1 2 3}))
10:30clojurebot2
10:30manutterThat's what I'd do: define a function called "any" (or something similar) and then use that instead of rand-nth
10:30manutterit's just syntactic sugar, but it makes me happy :)
10:38raek,(let [v (vec (range 1e6))] (time (nth v (dec 1e6))))
10:38clojurebot"Elapsed time: 0.148 msecs"
10:38raek,(let [v (vec (range 1e6))] (time (nth (seq v) (dec 1e6))))
10:38clojurebot999999
10:38clojurebot"Elapsed time: 71.822 msecs"
10:38clojurebot999999
10:39manutterThat's interesting
10:56manutterhas defstruct been superceded by defrecord, or is there still a use case for it?
11:01manutterI was just reading a cool blog post and noticed he was using defstruct
11:01manutterhttp://inclojurewetrust.blogspot.com/2009/11/tail-recursion-and-function-composition.html
11:03manutterusing comp in a tail-recursion to "instantly" unwind a bunch of stack calls -- how awesome is that?
11:06stuartsierradefrecord replaces defstruct in all cases, I believe
11:07manutterI thought I'd heard that
11:07stuartsierraAnd soon you'll be able to print & read them! http://dev.clojure.org/display/design/defrecord+improvements
11:11manutterCool!
11:15cemerickstuartsierra: now if we can just get the struct-related vars marked as deprecated…
11:16stuartsierracemerick: make a patch
11:16cemerickstuartsierra: ok; I was waved off of doing so a while back
11:16stuartsierraoh?
11:17stuarthallowaycemerick, stuartsierra: there was something about struct that was still needed for e.g. resultset-seq
11:17stuarthallowaybut since that itself will be deprecated....
11:17cemerickstuartsierra: key enumeration in the basis is unique to it, IIRC
11:18stuartsierraah
11:18cemerickstuarthalloway: depends on the relative release timings of jdbc and 1.3, then, I presume?
11:18cemerickdeprecation meta, that is
11:18stuarthallowaycemerick: it will be deprecated, but possibly never removed
11:18stuarthallowayso the meta could happen now
11:19stuartsierraOld code never dies, it just deprecates.
11:19cemerickoh good, so we have our java.util.Date now :-/
11:22stuartsierrait's not quite that bad
11:23timvisherhey all
11:23timvisheris it possible to easily create a seq on an Iterator?
11:23cemerickstuartsierra: don't mind me, I'm just being grumpy :-P
11:24timvisherI'm trying to deal with the javax.imageio.* libraries
11:24stuartsierratimvisher: yes, use `iterator-seq`
11:24timvisherand getting the understood image format requires dealing with an Iterator as far as I can tell
11:24stuartsierraand be careful: iterators are allowed to change
11:25timvisherstuartsierra: j00 rock brother. ;)
11:26stuartsierrathx
11:37timvisherI have a seq with duplicate values in it and I want to remove them.
11:37timvisherI tried simply applying hash-set to the whole seq
11:37timvisherbut it says that there are duplicate keys
11:37timvisheris there a simpler way to do it?
11:38semperos,(doc distinct)
11:38clojurebot"([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"
11:39semperostimvisher: ^^ that what you're looking for?
11:39timvishersemperos: exactly
11:39timvisherthx so much
11:39semperosnp
11:39semperosyou can always do a broad documenation search with "find-doc"
11:40semperos,(find-doc "duplicates")
11:40clojurebot-------------------------
11:40clojurebotclojure.core/distinct
11:40clojurebot([coll])
11:40clojurebot Returns a lazy sequence of the elements of coll with duplicates removed
11:40timvisheryeah
11:40timvisheri had erc open so i got lazy
11:40timvisheri usually do that :)
11:40semperos:) no worries
11:40timvisherbut hey, you guys are so helpful!
11:40manutterplus us lurkers get to add to our clojure knowledge... :)
11:42fliebelkilla: How are the game plans going?
11:45zippy314_Is there a way to do the equivalent of unquote splicing (~@) in regular functions (i.e. not in the context of syntax quoting) for parameters that have been collected into a list with &?
11:47manutterhrm, apply?
11:47manutterwhat do you need to do with them once you've "unquote spliced" them?
11:48ataggart,(apply + [1 2 3])
11:48clojurebot6
11:51no_mindCan I define a new exception in clojure ?
11:53zippy314_actually I just used a macro to do it. I wanted to create a function which just looks like a call to a different function with the first two parameters reversed where there's a variable number of params.
11:53raekno_mind: you need to use genclass to define Java exceptions. for error handling in clojure, consider clojure.contrib.error-kit or clojure.contrib.condition
11:53zippy314_So it was easier just to actually use defmacro and the unquote-splicing.
11:53raek~error-kit
11:53clojureboterror-kit is http://pragprog.com/magazines/2009-07/when-things-go-wrong
11:55dnolenzippy314_: except now you have a macro, macros don't compose w/ functions.
11:56manutterzippy314: a function would also work without too much trouble: (defn foo [a b & others] (apply bar (seq b a others))) should do it, I think
11:57zippy314_ok so say i have (defn a [x y &z]) and I want to create a function b that's the same as a except you call it like (b y x foo bar).
11:58zippy314_my solution was (defmacro b [y x & z] `(a ~y ~x ~@z))
11:58raek(defn flip-first-two-args [f] (fn [x y & args] (apply f y x args)))
11:58zippy314_How do you do this with plain functions
11:59raek(def bar (flip-first-two-args foo))
11:59raekzippy314_: ^^
11:59raek(hrm, to match your example, foo and bar should be swapped)
12:00manuttercool, it does work without the (seq), I wasn't sure it would
12:00raekmanutter: do you mean 'list*' instead of 'seq'?
12:01manutterraek: I said "seq" in my (untested) code example because I didn't think you could just pass an unadorned list of symbols to apply
12:02manutterI thought I needed to wrap it in a (seq a b c etc)
12:02raek(apply f a b c args) is the same as (apply f (list* a b c args)) which in turns is the same as (apply f (cons a (cons b (cons c args))))
12:02raekmanutter: seq only takes one argument
12:02manutterSee, now that's why I hang out in this channel :)
12:03manutterthat's right, I remember now
12:03manutterso, um, yeah, I did mean list*
12:03manutter:D
12:03raekapply calls seq on the last argument to convert it from whatever it is (e.g. a vector) to a seq (if it wasn't one already)
12:04raek(since it's an ordinary function, it cannot know what the code of the expression looks like. all it cares about is that it's seqable)
12:05raekso, nothing magic there... :)
12:06zippy314_So, this means that at the regular function level theres no way to substitute the values from a list as parameters? i.e. because apply assumes you have a function to call as in my example?
12:08raekzippy314_: sorry, I don't follow. what do you mean by "substitute the values from a list as parameters"?
12:09raekwhat I meant was that a function cannot tell if it called like (f 123) or (let [a 123] (f a))
12:10raekin response to what manutter said before: "I didn't think you could just pass an unadorned list of symbols to apply"
12:10zippy314_yah, I know I'm not using the right words. So to my (newbie) understanding, unquote splicing has the effect of substituting the values of the list in, instead of the list itself. I was wondering if there's a way to do that not in the context of a syntax quoting.
12:10raekbut I probably misunderstood that, I see now.
12:11raekzippy314_: yes, that's what apply does. it's analogous to "splats" in python and ruby
12:12zippy314_zippy314 is reading the docs for apply
12:12raekif you have a list of arguments l = [1 2 3], and you want to call the function with those elements as separate arguments like (f 1 2 3), you use apply: (apply f [1 2 3])
12:12raekor (apply f l)
12:13manutter,(let [some-list [1 2 3 4]] (+ some-list)
12:13clojurebotEOF while reading
12:13manutter,(let [some-list [1 2 3 4]] (+ some-list))
12:13clojurebotjava.lang.ClassCastException
12:13raekany arguments to apply that comes between "f" and "l" will be prepended to "l"
12:13manutterthere we go: my code failed because I used a list as the argument to +
12:14raekthis is a convenience feature so that you don't need to append them manually
12:14manutterwhat I want to do is add up the numbers IN the list, like with unquote splicing
12:14manutterfor that I can use "apply"
12:14manutter,(let [some-list [1 2 3 4]] (apply + some-list))
12:14clojurebot10
12:15ataggartstuarthalloway: anything need to be worked on?
12:15manutterso in my code, the apply function "unrolls" my list, and clojure effectively does (+ 1 2 3 4)
12:15zippy314_I get it. Thanks. What's hard for me is that apply always takes a function, and I think about doing this in the middle of a list or elsewhere without a particular function in mind.
12:15stuarthallowayataggart: review of fogus' work on defrecord would be welcome
12:16stuarthallowayhttp://dev.clojure.org/jira/browse/CLJ-374
12:16ataggartk, reviewing
12:16manutterzippy314_: I think if you need to make changes in the middle of the list you can just process the list first, and then pass it to some other function
12:16stuarthallowayataggar: also http://dev.clojure.org/display/design/defrecord+improvements
12:17stuarthallowayplease post comments on the ticket
12:17manutterapply is only necessary when you go to pass your list as arguments to some function
12:17zippy314_Yah, makes sense. It's all part of shifting my thinking to the clojure way. I love it, but it's just been too long since I've been really coding in lisp.
12:18raekhaving functions as values really changes how you think
12:26zippy314_What's the clojure ideomatic way to remove duplicates from a seq, i.e. like ruby;s #uniq ?
12:28manutter,(doc distinct)
12:28clojurebot"([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"
12:29zippy314_thanks. I was searching for at filter, unique, etc.
12:30manuttersomebody was just asking for the same thing earlier today
12:30manutterthat's how I found out about it
12:30manuttersomeone else also did this:
12:30zippy314_:-)
12:30manutter,(find-doc duplicates)
12:30clojurebotjava.lang.Exception: Unable to resolve symbol: duplicates in this context
12:30manutterdoh
12:30manutter,(find-doc 'duplicates)
12:30clojurebotjava.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String
12:31manuttersigh, one more time
12:31manutter,(find-doc "duplicates")
12:31clojurebot-------------------------
12:31clojurebotclojure.core/distinct
12:31clojurebot([coll])
12:31clojurebot Returns a lazy sequence of the elements of coll with duplicates removed
12:31manutterthere, I learn eventually...
12:31clsmith'distinct' does seem a strange name for that function
12:31zippy314_nice. where's the clojurebot docs?
12:32manutterI think they're on Google ;)
12:32manutter^ ^ in other words I don't know
12:33timvisherwow
12:33timvisherthis must be in the water today
12:33no_mindis there a package which implements Observer pattern ?
12:34zippy314_(-D)
12:34fliebelno_mind: What is that again? Let me google...
12:34raekzippy314_: you can also use set, but then the order is not maintained (distinct is lazy and carries a set with previously seen elements with it to skip those)
12:34raek,(set [1 2 3 1 2])
12:34manutterzippy314_: https://github.com/hiredman/clojurebot
12:34clojurebot#{1 2 3}
12:34fliebelmaybe https://github.com/stuartsierra/cljque
12:35zippy314_,(into [] (set [1 2 3 1 2]))
12:35clojurebot[1 2 3]
12:36zippy314_raek: cool. thanks.
12:38raek(also, unless you need constant time random access you can keep it as a set)
12:38RaynesWow. Linode went down for the first time since we got it.
12:38RaynesSomewhere around 150 days of uptime.
12:40dpritchettIs it a linode problem or something to do with your apps?
12:40no_mindclique is unstable...
12:41fliebelno_mind: Whatever that means… The interface is really simple, and works, as far as I know.
12:43Raynesdpritchett: I imagine it was scheduled maintenance. They pretty much never go down unless it's scheduled, and even that is very rare.
12:52no_mindfliebel: this is closest to what I want http://dev.clojure.org/display/design/Asynchronous+Events but cant find any schedule for development
13:13mecHow might I transform ((apply comp fs) x) to use trampoline?
13:13fliebelmec: Just prepend a hash sign.
13:15mecfliebel: to what?
13:16fliebelmec: oh, wait, what is that snippet doing? Looks a lot like iterate to me. I need to run now, sorry.
13:17mec(f1 (f2 (f3 (f4 (f5 ... x)))))
13:17fliebelI;d say (reduce #(%2 %1) x fs)
13:18fliebelmaybe switch the arguments… really need torun now
13:18mecok, thanks
13:20raek,(reduce #(%2 %1) 0 (repeat 1e6 inc))
13:20clojurebot1000000
13:21raek,((apply comp (repeat 1e6 inc)) 0)
13:21clojurebot1000000
13:21raekhrm
13:21mecim surprised that actually didnt blow the stack, so I'm oversimplifying my problem
13:21raek~source comp
13:23raekthe vararg version actually does some trampolining...
13:23raekhttps://github.com/clojure/clojure/blob/f128af9d36dfcb268b6e9ea63676cf254c0f1c40/src/clj/clojure/core.clj#L1957
13:24raek,((reduce comp (repeat 1e6 inc)) 0)
13:24clojurebotExecution Timed Out
13:25raek,((reduce comp (repeat 1e4 inc)) 0)
13:25clojurebotjava.lang.StackOverflowError
13:25raekthere we have it!
13:25raekyou learn something every day :D
13:27manutterso apply is lazy and reduce isn't? Is that what those results mean?
13:28mecyes
13:28stuartsierraapply realizes the entire sequence before invoking the function. reduce only realizes 2 elements at a time
13:29stuartsierra(apply + [1 2 3]) evaluates to (+ 1 2 3) but (reduce + [1 2 3]) evaluates to (+ (+ 1 2) 3)
13:29mecThere was an example I remember of giving an infinite seq to apply
13:29manutterThat's what I'd have expected, but it looks like reduce blows stack and apply doesn't, in raek's examples
13:29mecmanutter: comp is blowing the stack, facilitated by reduce
13:30manutterah, wait, I see, it's ((reduce... not (reduce
13:30manutterso the outer parens are effectively holding onto a head of some kind
13:32manutterI think.... Hmm.
13:32manutterCurse my PHP day job!
13:32manutterI'm burning out my brain clutch shifting gears too much :0
13:33chouserreduce isn't lazy. If fully consumes whatever seq you give it
13:33chouser s/If/It/
13:34chousercomp in this case is given two fns, and comp always returns an object that holds onto its args
13:34manutterYes, that's it!
13:34manutterThanks, it clicks now.
13:34chousergreat! :-)
13:35manutterSo I guess "apply" failed to blow stack because the stack isn't exhausted by an arg list of 1000000 integers, or something?
13:36manutterYeah, it's not stacking, it's just making one big list
13:36manutterwhich is heap not stack
13:36chouserit's not even doing that
13:36manutterI'll get this all some day. :)
13:37chouserapply really is lazy, so it's not making one big list, it's just passing along the lazy sequence to comp
13:37manuttercool, so I started off on the right foot even if I wandered a bit between here and there.
13:38chouser:-)
13:44mec,(rseq (seq "!23"))
13:44clojurebotjava.lang.ClassCastException: clojure.lang.StringSeq cannot be cast to clojure.lang.Reversible
13:44mecyou'd think that would be possible
13:46ataggart,(apply (fn [x & more] x) (repeat 1))
13:46clojurebot1
13:47ataggartapply only resolves the required fixed arity elements. it's very lazy
13:48chouser,(reverse "!123")
13:48clojurebot(\3 \2 \1 \!)
13:48chousermec: oh, I see your point. Yeah, does seem like it could be added.
13:51bartjRaynes, you mean try clojure is down ?
13:51Raynesbartj: It shouldn't be anymore. It would have been for several hours this morning.
13:51timvisheris it possible to use the {:keys ...} destructuring syntax in let statements?
13:52ataggarttimvisher: yes
13:52mectimvisher: of course ##(let [{:keys [a b c]} {:a 1 :b 2 :c 3}] [a b c])
13:52bartjRaynes, it seems down for me
13:52mecomg wheres sexybot
13:52Raynesbartj: I guess so.
13:52mec,(let [{:keys [a b c]} {:a 1 :b 2 :c 3}] [a b c])
13:52clojurebot[1 2 3]
13:53timvishernice
13:53timvisheri was missing where the source would come from
13:53timvishernot sure why
13:53timvisherthx guys
13:53timvisherand gals :\
13:53Raynes$kill
13:53RaynesWow, even sexpbot isn't working properly. Sigh.
13:53mec,(let [{:keys [a b] d :c :as e} {:a 1 :b 2 :c 3}] [a b e f])
13:53clojurebotjava.lang.Exception: Unable to resolve symbol: f in this context
13:54mec,(let [{:keys [a b] d :c :as e} {:a 1 :b 2 :c 3}] [a b d e])
13:54clojurebot[1 2 3 {:a 1, :b 2, :c 3}]
13:55mecchouser: clojure.string/reverse uses stringbuilder.reverse which, while not constant time, maintains combined characters
13:55mecso I guess rseq is no good after all
13:58chouser,(rseq "123")
13:58clojurebotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Reversible
13:59chouser,(rseq (into-array [1 2 3]))
13:59clojurebotjava.lang.ClassCastException: [Ljava.lang.Integer; cannot be cast to clojure.lang.Reversible
13:59chouser,(rseq (seq (into-array [1 2 3])))
13:59clojurebotjava.lang.ClassCastException: clojure.lang.ArraySeq cannot be cast to clojure.lang.Reversible
13:59chouserhm
13:59chouser,(rseq [1 2 3])
13:59clojurebot(3 2 1)
13:59chouser,(rseq (seq [1 2 3]))
13:59clojurebotjava.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.Reversible
14:00raek,(rseq (sorted-set 1 2 3))
14:00clojurebot(3 2 1)
14:06RaynesI didn't start mongodb properly, which is why sexpbot is all stubborn and quiet. I'll have that fixed in a moment.
14:12Raynessexpbot is back in action.
14:12technomancyhttp://p.hagelb.org/try-defn.clj.html <= interesting mystery
14:13DeranderRaynes: does sexpbot use congomongo?
14:14ejackson$botstnack
14:14RaynesDerander: Yup.
14:14ejackson$botsnack
14:14sexpbotejackson: Thanks! Om nom nom!!
14:14ejacksonwelcome back sexp
14:15DeranderRaynes: have you ever run into something like "db message size too big (1958167) max is (1821679)" from the java driver?
14:15DeranderRaynes: those numbers are made up, but the first is always larger than the second. it occurs on trying to fetch a fairly large document
14:16Derander(9991339) max is (8389632) <-- those are the actual numbers. it's an IllegalArgumentException that gets thrown.
14:20S11001001Is this guaranteed? ##(let [[_ & r] '(1)] (nil? r)) for all colls/sequences in place of '(1)
14:20sexpbot⟹ true
14:20chouseryou mean collections of length 1
14:20chouser?
14:21S11001001yeah
14:21chouseryes
14:21S11001001great
14:21S11001001thanks chouser
14:21chouserThe & uses 'next', which promises nil when you reach the end of the collections.
14:30S11001001yeah, I've been seqing those, guess I'll stop
14:43fliebeltechnomancy: Solved the mystery yet?
14:44technomancyfliebel: not in the slightest
14:45fliebeltechnomancy: I've experienced more weird things with try. I wonder how it's implemented.
14:46fliebelFor example, you cannot recur across a try, and locking is also doing weird stuff.
14:48technomancyrecurring across try I can sorta understand
14:48fliebelI can't, what could go wrong?
14:49hiredmantry/catch is dynamic scope
14:49technomancyhttp://dev.clojure.org/jira/browse/CLJ-31
14:49fliebelWhere are special forms defined again?
14:49hiredman(infact binding, actually expands to a try/finally
14:49hiredman)
14:50fliebelhiredman: What does that mean?
14:50hiredmanfliebel: it meeans you end up with odd behaviour when you allow recur (jumps) across dynamic scopes
14:51dnolenfliebel: recur is not a function call, so recur across a try doesn't make sense, there is no scope to protect.
14:52technomancydefn inside try, on the other hand... that one stumps me.
14:52hiredmantechnomancy: huh?
14:53fliebeltechnomancy: Well, if the scope is dynamic, maybe it just thorws it away? I never used dynamic scope enough to understand it well
14:53technomancyhiredman: http://p.hagelb.org/try-defn.clj.html
14:53fliebelhiredman: Would recurring mean that you get the scope of the previous iteration?
14:53manutterAh, that's an interesting idea
14:54technomancythe first line defines user/hi
14:54manuttertechnomancy: does the namespace exist at all outside of the try?
14:54hiredmantechnomancy: you got gilardi scenarioed
14:54technomancymanutter: doesn't seem to matter
14:54hiredmanthe defn is happening in the scope of the namespace you started in, not the scope of the in-ns'ed namespace
14:54manutterNo, I mean: you start with a clean repl, run the code, it's done. Did the namespace disappear when the try ended, or did it persist
14:55technomancyhiredman: oh snap. I thought I tried it multiple times, apparently not.
14:55fliebelhttp://technomancy.us/143
14:55technomancythe do is special-cased by the compiler; of course.
14:55hiredmanfliebel: you would loose the finally that pops the dynamic scope
14:56hiredmanindeed
14:59fliebelCan anyone show me some magic try clause that shows the dynamic scope?
14:59manuttertechnomancy: jark gives some interesting feedback:
14:59manutteruser=> (try (ns foo.bar) (defn hi []))
14:59manutter#'user/hi
15:00hiredmanfliebel: if you do (try .. (recur ...) (catch Exception e ...)) the recur is a jump, so if you jump outside of the try, you jump outside of the exception handling, so if the recur thows an exception, it won't be caught
15:00technomancymanutter: yeah as hiredman mentioned, the problem is the defn is compiled before foo.bar exists as a namespace
15:01technomancysee the technomancy.us link above
15:01manutterI knew I'd seen that phrase before
15:01hiredmana.k.a. The Gilardi Scenario
15:02technomancydevious
15:02manutterindeed
15:02manutterBut shouldn't that make the do fail as well?
15:02manuttero wait, do is a special form
15:02fliebeland a special case
15:02manutteryup yup, I didn't see the relevance of the conversation above, but I do now
15:03manutterI'm kicking myself for not tuning in to this channel sooner, I'm learning tons here.
15:05fliebelaaah! A lot of stuff starts to make more sense now, like binding + threads, and the other recur weirdness.
15:06technomancyrecent blind testing has shown that consumers prefer the taste of Freenode's #clojure channel 4 out of 5 times
15:06cheater_hi
15:06cheater_is what clojure calls m-result the same as what haskell calls "return"? (for monads)
15:06fliebel(try (future (throw))) will also not work of course :)
15:08hiredmanbasically, because of the lack of tco, you need recur as a functional loop construct, but it is a jump, not a proper function call, so to make it act sanely you have to restrict the use
15:09hiredmanit does make me wonder how the tco patches for openjdk deal with exceptions and finally, etc
15:09manuttercheater_: are you talking about m-result as used in clojure.contrib.monads?
15:10manutter,(doc m-result)
15:10clojurebotGabh mo leithscéal?
15:10manutter,(find-doc "m-result")
15:10clojurebot-------------------------
15:10clojurebotclojure.contrib.monads/defmonad
15:10clojurebot([name doc-string operations] [name operations])
15:10clojurebotMacro
15:10clojurebot Define a named monad by defining the monad operations. The definitions
15:10clojurebot are written like bindings to the monad operations m-bind and
15:10clojurebot m-result (required) and m-zero and m-plus (optional).
15:10clojurebot-------------------------
15:10clojurebotclojure.contrib.monads/m-reduce
15:10clojurebotnil
15:10clojurebot Return the reduction of (m-...
15:11RaynesWow.
15:11__name__Why do you not teach this bot to use a pastebin?
15:11__name__It is very bad-mannered.
15:12technomancy~botsmack
15:12clojurebotclojurebot evades successfully!
15:12manutterI'll have to be careful how I use that function from now on.
15:12cheater_manutter: yes
15:12__name__~botsmack
15:12clojurebotclojurebot evades successfully!
15:12__name__What's that do?
15:12cheater_manutter: is that the same as haskell's return?
15:13manuttercheater_: I want to say yes, but I'm a total noob wrt haskell and monads
15:13manutterI'm trying to wrap my brain around it/them, but they elude me still
15:14cheater_have you been able to figure out monads in clojure?
15:14cheater_i have just watched this series of tutorials, it's very good. http://vimeo.com/20717301
15:14manutterI've got a rough handle on at least the maybe monad in clojure
15:15cheater_aha
15:15cheater_but not on defining your own monads?
15:15manutterOh yeah, the brian Marick series, I started that but he hadn't finished it yet
15:15manutterI've been meaning to get back to that.
15:15manutterYeah, defining my own monads is way beyond me atm
15:16cheater_i did it in one go
15:16manutterHey, the weekend is near :)
15:16manutterMaybe by Monday I'll understand it better.
15:24cheater_dude
15:24cheater_it's just an hour and a half
15:24cheater_lol
15:29cheater_watch it during lunch ;-)
15:29cheater_i'm off
15:29cheater_thanks for the help!
15:31thorwilthe following code cannot work, but should shed light on my intention: http://paste.pocoo.org/show/384213/
15:33thorwilthat fn shall play the role of an enlive transformation. en/do-> allows to combine several such transformations into one. unsurprisingly, it does not like a when with a false condition
15:35thorwilthis is for a page navigation "Previous Next", both in <span>s in the template
15:37thorwil4 cases: #1: there is only 1 page, nothing to navigate, no need for a transformation. #2: on the first page, only Next needs to be turned into a link. #3 somewhere in the middle: transform both. #4 on the last page, only transform Previous
15:38thorwilwhat i'm struggling with is that i have zero, 1 or 2 transformations to do, so i may or may not need to use en/do->
15:54thorwilis there something like a `when` that produces nothing if false, instead of a nil?
15:55raekthorwil: what value is nothing?
15:55fliebelEven a comment returns nil :)
15:56thorwilah right, everything does at least that
15:56thorwildumb me, i have to assemble a list by concatenating
15:56fliebel&(cons 1 nil)
15:56sexpbot⟹ (1)
15:57fliebel&(concat [1 2 3] nil [ 4 5 6] nil)
15:57sexpbot⟹ (1 2 3 4 5 6)
16:10ordnungswidrigdoes (alter r identity) ensure a ref?
16:11hiredman,(doc ensure)
16:11ordnungswidrigor does is hurt concurrency?
16:11clojurebot"([ref]); Must be called in a transaction. Protects the ref from modification by other transactions. Returns the in-transaction-value of ref. Allows for more concurrency than (ref-set ref @ref)"
16:13raekordnungswidrig: I don't think it does
16:14bhenryis there a function for (apply list [1 2 3]) or do i have to apply list?
16:14raekordnungswidrig: hrm. ignore that.
16:14raekordnungswidrig: have you seen this? http://java.ociweb.com/mark/stm/article.html#write-skew
16:14stuartsierrabhenry: list*
16:15bhenrystuartsierra: thanks
16:15stuartsierra'welcome
16:16ordnungswidrigraek: ah, I lost that link
16:16ordnungswidrigI remember to have read the article
16:18ordnungswidrighowever, it did not worry about write skew.
16:19ordnungswidrigI have a datastructure like (ref (:users (ref { 1 (ref { :name "alice"}), 2 (ref { :name "bob"})}))), i.e. a nested map of refs of maps and so on. I want to have some values as refs to improve write concurrency
16:19ordnungswidrigI write a function update-in-ref which works like update-in but wich will insert a call to "alter" where necessary.
16:20ordnungswidrigwith the above example you can do (update-in-ref m [:users 1] assoc :name alice) or (update-in-ref [:users 2 :bob :age] inc)
16:20raekif you alter a ref and the transaction succeeds, then the ref will note have been altered by another succeeding transaction in between
16:21ordnungswidrigraek: you mean the changes by the in-between-transaction would have been lost?
16:21raekordnungswidrig: ...or what did you mean by "ensure"?
16:22raekno, simply that they are atomic
16:22raek s/note/not/
16:23ordnungswidrigraek: I meant I'm perfectly aware of write skew and ensure, I think. I was not sure if (ref-set r @r) would hurt concurrency.
16:24ordnungswidrigraek: from the docs I read that (ref-set r@) has the same effect as ensure but at a higher cost
16:24raekok, sorry. I missed the "identity" part.
16:24raekthat is probably true
16:26ordnungswidrigso my proposed function update-in-ref should make sure that only the innermost ref would be altered
16:27raekthat sounds very reasonable, since the outer refs need not be changed at all
16:29ordnungswidrighmm, that will be a lot of conditionals hackery then :-)
16:29raekordnungswidrig: in this case, you could also do (-> x deref :users deref (get 1) (alter assoc :name "eve"))
16:29ataggartunless intermediate maps need to be created, which is the advantage of update-in. otherwise, just deref/get the ref/map you want to modify and alter it
16:30raeki.e. first "get-in" to the ref, and then an ordinary alter
16:34ordnungswidrigraek: not so bad.
16:35ordnungswidrigI wanted to have get-in-ref and update-in-ref which handle references transparently where occuring.
16:35ordnungswidrig(get-in-ref {:users (ref {123 (ref {:name "Al"})})} [:users 123 :name]) -> "Al"
16:46scottjbury-buffer is such a nice function, I can't believe I only recently learned about it
16:46scottjopps, wrong chan :)
16:46Ramblurri'm having issues displaying utf8 chars with enlive and compojure.. i think it is because compojure isnt returning the content-type with the charset as utf8
16:48scottjRamblurr: search compojure mailing list thread "Problems with compojure 0.4 + Enlive and UTF-8"
16:48Ramblurrscottj: yea, i just found that middleware..
16:49Ramblurrscottj: since wrap! is deprecated, what is the proper way to use that with (-> ..) ?
16:49scottjyeah
16:49raekRamblurr: ring (which compojure uses) does not set the charset parameter of the Content-Type header and the servlet spec says that if it is missing, ISO 8859-1 should be filled in
16:49scottj(-> app (wrap-charset ..))
16:50ataggartISO8859-1 is for text/html, utf-8 is for xhtml
16:50ordnungswidrigcu all.
16:50raekRamblurr: (assuming your files are in UTF-8) try setting the following header in the response: "Content-Type" "text/html; charset=UTF-8"
16:51raekservlet containers add "; charset=ISO-8859-1" to all "text/*" types, IIRC
16:51raekwhich is kinda sad
16:52symboleraek: Are you sure?
16:52raekRamblurr: if you use firefox, you can see that header by right clicking and choosing show page info
16:52Ramblurrby default i'm not getting the content-type header at all
16:55raekRamblurr: are you sure? the content-type header should always be present
16:56Ramblurrraek: yup -- http://i.imgur.com/wbC31.png
16:56Ramblurrinterestingly, the content-type is set for the GET requests to .css and .js files, but not the html responses
16:57Ramblurri wonder if i'm doing something incorrect with enlive
16:58raekenlive only affects the response body
16:59raeksymbole: fairly. I'm trying to find a mail list thread...
16:59raekhere's one related: http://groups.google.com/group/compojure/browse_thread/thread/44a25e10c37f3b1b/d4a17cb99f84814f?lnk=gst&amp;q=utf8#d4a17cb99f84814f
17:01raekah, here's the thread where I saw this the first time: http://groups.google.com/group/clojure/browse_thread/thread/a7e74645baede508/7df98e3ceab51a96
17:02raeksymbole: http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.5/docs/servlet-2_5-mr2/javax/servlet/ServletResponse.html#getCharacterEncoding%28%29
17:03raek"If no character encoding has been specified, ISO-8859-1 is returned."
17:06miwillhiteHey, new to clojure…I have an app built with Leiningen, and I want to add a libraray from github…whats the best way to go about that?
17:07miwillhitedo I need to clone the repo into my lib directory and just reference the namespace in the dependencies?
17:07technomancymiwillhite: check clojars.org for it
17:07miwillhiteokay thanks
17:07miwillhiteah cool
17:07technomancyalso read "lein help tutorial" if you haven't
17:07miwillhiteI wasn't aware of this site
17:07hiredmanor any maven repo
17:07miwillhitecool thanks a lot
17:08Ramblurrraek: herm, essentially i am passing the result of enlive/content as the handler for the route
17:08Ramblurrlooking at some examples, it looks i should at least be calling (apply str ..) on it
17:09raekRamblurr: from the handler, try returning {:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body result-from-enlive-here}
17:10raekRamblurr: why? ring accepts seqs of strings as bodies
17:10raekit's all here https://github.com/mmcgrana/ring/blob/master/SPEC
17:10Ramblurrraek: huzzah, that worked
17:11Ramblurri had just assumed the status code and headers were handled automatically..shouldn't there be a middleware for that?
17:12raekthe status code and the content-length header are added automatically by ring
17:13raekRamblurr: and there's also these: http://clojuredocs.org/ring/ring.util.response
17:15raekbut as for the content-type: I think "text/html; charset=utf-8" would be resonable as a default, but you would still need to set that header when serving anything else than html
17:59miwillhitethe lib I want to use is version 1.6 on clojars, but the current version on github is 2.3…is there anyway I can grab the github version and bring it into my app?
18:00TheMoonMastermiwillhite: You could push the new version to clojars, https://github.com/ato/clojars-web/wiki/tutorial
18:02raekmiwillhite: are you saying that none of 2.3, 2.2, 2.1 or 2.0 are on clojars? one option could be to use checkouts if you use leiningen (see the readme)
18:02raekmiwillhite: btw, which library is it?
18:08miwillhiteraek: I'm new to clojars, but I only see the 1.6.1-SNAPSHOT as an option
18:08miwillhiteraek: It is the "store" library
18:08miwillhiteI'm trying to integrate S3
18:08raekmiwillhite: github url?
18:09miwillhitehttps://github.com/getwoven/store
18:09miwillhitebtw, if you know of a better one (with better docs) I'd like to hear it
18:09miwillhiteI'm brand new to clojure
18:09miwillhitethis is the first library I've tried to add besides contrib
18:09technomancysomebody really needs to sit the woven people down and explain how releases work
18:11miwillhiteI was a release off in my versions, its actually 0.1.6 and 0.2.3
18:11miwillhitebut STILL!
18:11raekmiwillhite: those that end in -SNAPSHOT are not releases
18:11raekthey are snapshots
18:11miwillhiteyeah
18:11miwillhiteI know…but thats all I see
18:11raekthe author of the lib should really do a proper release
18:12raeksince he has even stepped up the snapshot versions
18:12raeksnapshots are supposed to go between releases
18:12miwillhiteright…as a sort of "edge" version right?
18:12raekyeah
18:13raekif you have people depending on your lib, then you're not in alpha anymore and 1.0.0 should be available
18:13miwillhitegood point
18:13miwillhiteI just found this one: https://github.com/ndimiduk/s3-edge
18:13miwillhitethey actually have tags and its 1.0
18:14miwillhitenot sure if its what I need though…
18:15miwillhitebasically, I just want to pull down a bunch of files from S3
18:17miwillhitehm, I'm finding more results with the query 'aws', I think I need to dig around a bit more
18:17raekmiwillhite: to try out a new version, you can clone a project from github and run "lein install" in the project directory to build and install that version into you local maven repo. (and if you like it, bug the author about making a release... :) )
18:17miwillhitesounds like the woven stuff isn't in a good place right now
18:18miwillhiteraek, perfect thank you
18:18raekyou should then be able to specify that version in your project.clj
18:18miwillhiteawesome
18:30stevenlawrenhello. i've installed clojure from mac-ports. when i run clj and try to run (use 'clojure.contrib.seq-utils) at the repl it says it can't find it. am i using 'use' wrong, or is there some drama with my classpath? what could it be?
18:31technomancystevenlawren: clojure is pretty different from most languages in that it's not that useful when installed in a package manager.
18:32technomancyyou generally want to use something like Leiningen to get started
18:33stevenlawreneven to run a basic script at the command line?
18:33raekstevenlawren: the usual way to do it, is to use a clojure environment tool like Leiningen or Cake to handle the classpath (as well as dependency resolution and fetching)
18:33technomancyyeah, I strongly suggest not using macports from Clojure
18:34raekstevenlawren: there is no official clojure launched (except for starting with the 'java' command)
18:34raek*launcher
18:35stevenlawrenis clj written by the mac ports people then?
18:35dysingerstevenlawren: y
18:35dysingerstevenlawren: if you just want a taste you can try https://github.com/liebke/cljr#readme
18:35dysingergives you a python idle like gui to mess with
18:36stevenlawreni don't want all the guff of a gui, i just want to get a repl on the screen, and to be able to run a script at the command line
18:37raekcake is probably a better fit for the "script" style of development (which to me does not seem to be what clojure was designed for)
18:38technomancyclojurebot: how about jark?
18:38clojurebotTitim gan éirí ort.
18:38technomancy...
18:39technomancyclojurebot: jark is a clojure daemon for scripting: http://icylisper.in/jark/
18:39clojurebotc'est bon!
18:40dysingerstevenlawren: curl -O https://maven.atlassian.com/content/groups/public/org/clojure/clojure/1.2.1/clojure-1.2.1.jar ; java -jar clojure-1.2.1.jar
18:41raekstevenlawren: if you just want to learn the language, I recommend keeping a clojure repl session open rather than starting clojure each time you want to try something
18:41stevenlawrenthere does seem to be a dislike of scripting, or anything else related to posix from the clojure community. is that fair? is there any literature on why this is
18:41raekstevenlawren: you can still use load-file to "execute a script"
18:42technomancystevenlawren: it's fair. it comes from some fundamental shortcomings of the JVM. we don't like it, but we live with it because zomg the GC and JIT are wow.
18:43dysingerstevenlawren: it's pretty easy
18:43dysingerjava -jar clojure-1.2.1.jar -e "(println 'hello)"
18:43dysinger> "hello"
18:43hsbot "hello"
18:44stevenlawrenalmost all other major programming environments have gc and jit but also work well with scripting
18:45stevenlawrenor do you mean that the java gc and jit are particularly good, which they are
18:45technomancystevenlawren: right; other cross-platform VMs are simply not in the same league when it comes to performance
18:46jlf``technomancy: is there any existing clojure analog of emacsclient, such that you could have a long-lived image and do something like clojureclient -e "(println 'hello)" ?
18:46technomancyjlf``: that's basically what jark is, linked above
18:46technomancyI haven't used it myself
18:47stevenlawrenthat's probably an issue for oracle to fix as well, for all of java
18:47technomancyjlf``: or you could argue the slime/swank duo is kinda like that; that's what I use
18:47jlf``heh, backlog reading fail :)
18:53dysingerso leiningen, cljr, et al are super easy to install - I don't see what the problem is
18:54hiredmanindeed
18:55technomancywell we'd all be thrilled if the JVM had a quick boot time and no classpath issues, but given that it's unlikely to ever be fixed we make ourselves comfortable.
18:56raekare there any fundamental reasons code has to be loaded from the classpath in clojure, btw?
18:57hiredmanwhat we need is a jvm that does images
18:57hiredmanessential preload the jdk classes into ram then dump that disk and reuse it
18:57hiredmanraek: it's how you load code into a jvm
18:58hiredmanwell, classloaders are how you load code, and the jvm starts with a classloader that loads from the classpath
19:00raekcouldn't the language load source files like ordinary files, compile them to byte arrays containing JVM bytecode and then load them with java.lanng.ClassLoader/defineClass?
19:01hiredmanhttp://blog.headius.com/2010/03/jruby-startup-time-tips.html
19:01hiredmanraek: "load like ordinary files"
19:01hiredmanwhat does that mean?
19:01hiredmanhttp://download.oracle.com/javase/1.5.0/docs/guide/vm/class-data-sharing.html neat
19:02dysinger% java -jar clojure-1.2.1.jar -e "(defn hello[] (println 'hello))" -r
19:02dysinger#'user/hello
19:02dysingeruser=> (hello)
19:02hiredman"Dumping a shared archive is not supported on the Server JVM.
19:02hiredman"
19:02hiredman:(
19:07hguydoes clojure have it's own name for zip? i can't find it anywhere. not zip as in that zipper library whatever it is, the standard functional zip function
19:08hiredman,(find-ns 'clojure.zipper)
19:08clojurebotnil
19:08hiredmangrr
19:08hiredman,(find-ns 'clojure.zip)
19:08clojurebot#<Namespace clojure.zip>
19:09hiredmanoh, zipmap? or map?
19:09hiredman,(zipmap (range 10) (range 10))
19:09clojurebot{0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6, 7 7, 8 8, 9 9}
19:09hguyis that really what i want? i want the really basic zip function
19:09hiredman,(map vector (range 10) (range 10))
19:09clojurebot([0 0] [1 1] [2 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9])
19:09hiredmanbasic zip function?
19:10hguythe same zip function that haskell and all other funcitonal languages have
19:10hiredmanwhy don't you just explain what you want?
19:11hguy(zip [1 2 3] [4 5 6]) to [[1 4] [2 5] [3 6]]
19:11hguyany other functional language in the world has that function
19:11hguyeven python does!
19:12hiredmanI jsut showed it to you
19:12ataggarta function to create a list of tuples from lists seems kinda limited
19:12hguyzipmap? it has nothing to do with maps
19:13dnolen,(map vector [1 2 3] [4 5 6])
19:13clojurebot([1 4] [2 5] [3 6])
19:13dnolenhguy: ^
19:13hiredmanhguy: I showed you three things, one of them does exactly what you want
19:13ataggartjust what hiredman showed
19:13hguyi'm starting to think that clojure developers don't really understand functional programming when very basic functions such as zip are missing. if it's not required why does haskell have it
19:13dnolenhguy: contrary to popular belief, Haskell is not in fact the world's first functional programming language.
19:14hguyno but it is the academic and industry standard
19:14ataggartthere are only so many good words, not all of them mean the same thing in every language
19:14dnolenhguy: depends on who you ask, some people prefer SML or OCaml
19:14ataggartanyway, if you want to create a list of tuples, (map vector ...) is your answer
19:15hguyit's a very basic computer science concept - there's even a wikipedia page on it http://en.wikipedia.org/wiki/Convolution_(computer_science)
19:15hiredmanhguy: I'm going to go ahead and ignore you now, but please continue
19:15ataggarthave a nice day
19:17raekone reason for the lack of a zip function could be the lack of a tuple type
19:17dysingerheh that hiredman is rude! :)
19:17technomancyA++ excellent time; would be trolled again.
19:17ataggartyes hiredman is rude, but sometimes it's appropriate
19:17dnolenhguy: if you'd rather have the zip you're familiar with, you can always (def zip (partial map vector))
19:18hguyevery time you ask a question about clojure it's very quickly apparent that the community doesn't really understand computer science at all
19:18dnolenhguy: wow just wow.
19:18hguynever heard of the zip operation, that's wow
19:19ataggartso, waffles or pancakes?
19:19ataggartI prefer waffles
19:19hguywaffles? don't you mean carrots ha ha ha
19:19technomancydefinitely waffles
19:19technomancymy secret is to stick some brown sugar in the batter
19:19ataggartI'm not sure if the need for specialized equipment should count as a pro or a con
19:20dysingerI like dolphins
19:20hiredmantechnomancy makes great german pancakes
19:20hiredmandelicious
19:20ataggartporpoises > dolphins
19:21hiredmanbut I am more of a pancake anyway
19:21dysingerclojurebot: pancakes
19:21clojurebotTitim gan éirí ort.
19:21dysingerthere's work to be done!
19:23ataggart(binding [*print-dup* true] (pr-str 2))
19:43seancorfieldif someone thinks haskell is the be-all and end-all of FP, why do they even bother coming in here criticizing clojure?
19:44technomancyfor amusement?
19:46dysingerI kinda like haskell
19:46dysingerI like dolphins & pancakes too
20:43SergioTapiaHi
20:43SergioTapiaCheck out this wallpaper I made :P
20:43Deranderhttp://cl.ly/2H2w353f2P1J3L0P2a2m <-- is that the normal google look? it looks more pastel.
20:43SergioTapiahttp://i.imgur.com/cZj1N.png
20:43SergioTapiaYeah, it looks weird for me too.
20:43SergioTapiaI think they changed it.
20:44Deranderbizarre
20:44SergioTapiaI don't know, I think it looks better
20:44SergioTapiaeasier to scan the information you need
20:44Deranderit looks completely alien :-)
20:44Deranderthe whitespace between results is appreciated
22:24miwillhiteHi, I'm trying to include the jets3t library. Lein found the dependency with [net.java.dev.jets3t/jets3t "0.8.1"], but I can't figure out how to require it in my clj file…trying this:
22:24miwillhite(:require net.java.dev.jets3t)
22:25miwillhitebut the compile fails
22:25miwillhiteCould not locate ... on classpath:
22:25miwillhite(very much a beginner here)
22:27tomojrequire and use are for clojure namespaces only, for java deps you need to import the classes you want
22:27tomoj..or just refer to them fully-qualified
22:27miwillhiteI'll paste some code, I thought that was what I am doing…
22:28tomoj(:require foo.bar) will only work if foo.bar is a clojure namespace
22:28tomojI don't think net.java.dev.jets3t is
22:29miwillhitehttp://pastebin.com/naLNFuHi
22:29miwillhiteI guess the real question is…how do I know which namespace to include?
22:30semperosmiwillhite: don't use :require
22:30semperosuse :import
22:30semperosso if jets3t is an actual class you want to use
22:30semperosyou can do (:import net.java.dev.jets3t)
22:30semperosif you're importing multiple classes in the same "depth"
22:30semperosyou can do
22:31semperos(:import [net.java.dev jets3t foo bar])
22:31semperosthen you can reference the class with just it's name
22:31miwillhiteokay, that makes sense
22:31tomojyou need to look for the jets3t javadocs or documentation to find which classes you want
22:31miwillhiteright, thats what I'm missing
22:31semperosyep
22:31miwillhiteits starting to come together ;)
22:31miwillhitethanks for your help
22:32tomojyou could poke through the jar and take some guesses.. but..
22:32semperoshttp://jets3t.s3.amazonaws.com/api/index.html
22:32miwillhiteah perfect
22:32miwillhitethank you so much
22:32semperosno problemo
22:32semperosso I'm trying out JGit, writing a Clojure wrapper for it
22:33semperoswhen I do a git clone with the library, it clones the .git folder of the repo, but doesn't actually copy over the files
22:33semperosand I'm not making "bare" repo, it's supposed to be a normal repo
22:33semperosanybody have any experience with JGit, or any thoughts?
22:35dlhI'm not familiar w/ JGit, but you most likely need to manually do a checkout.
22:35semperosit's been a few hours, I'll double-check if that does it
22:35semperosdlh: thanks for the thought
23:21trptcolingcj
23:22technomancy~guards
23:22clojurebotSIEZE HIM!
23:23technomancyusing gcj in a clojure channel... honestly.
23:23technomancytrptcolin: what's gotten into you? =)
23:23trptcolin:) whoopsie
23:24technomancytrptcolin: how did that training program go?
23:24trptcolinwowsa - didn't realize gcj was a java compiler
23:25trptcolinit went great, thanks!
23:25trptcolinpeople seemed to get a lot out of it
23:25technomancyhow many attendees wer there?
23:25trptcolin10ish
23:26technomancymostly local?
23:26trptcolinyeah. a few from out of town, but mostly chicago-area
23:27trptcolinso the other day i was thinking of looking into a way to extend radagast to work w/ other test frameworks - specifically speclj
23:28trptcolinany thoughts? just took a quick look, seems like it wouldn't be too bad
23:28technomancyclojurebot: forget guards |is| <reply>SIEZE HIM!
23:28clojurebotI forgot that guards is <reply>SIEZE HIM!
23:28technomancyclojurebot: guards |is| <reply>SEIZE HIM!
23:28clojurebotOk.
23:28technomancythat's better
23:28technomancyhmmm...
23:28technomancyyeah, I don't think there's much to it.
23:29technomancythe coverage is pretty orthogonal; it just sees if stuff has run at all.
23:30ataggartread is the corollary to print-dup, right?
23:31trptcolinlooks like just 1 line to kick off the runner (applying clojure.test/run-tests over the nses)
23:31technomancyzactly
23:59seancorfieldwhy is print-dup called that?
23:59seancorfieldwe seem to have a lot of print functions...