#clojure logs

2011-04-12

00:41currentBhow to I get the first result of a strsplit
00:41currentBdamn wrong room disregard
01:39dnolenhmm some interesting optimizations are possible with case, https://gist.github.com/914995
01:44dnolenpredicate dispatch could be > 5x faster than multimethods in some cases and much more general...
01:45amalloydnolen: multimethods have to support isa/hierarchies
01:45amalloyand i don't see anything "more general" about hardcoding a big long case statement?
01:46dnolenamalloy: yeah I'm not interested in supporting hierarchies with this at all, only thinking about defrecord/deftype
01:46dnolenamalloy: it would be "hardcoded" each method would modify the dag, and the optimized case statement be emitted.
01:46dnolens/would/wouldn't
01:46sexpbot<dnolen> amalloy: it wouldn't be "hardcoded" each method wouldn't modify the dag, and the optimized case statement be emitted.
01:46amalloyhaha good old sed
01:47amalloydnolen: incidentally, if you're optimizing you might as well turn (case foo true a, false b) into (if foo a b)
01:47amalloyor do you want to specifically catch non-booleans and barf on them?
01:50hiredmancase is faster than (if (= ...) ...)
01:51hiredmanmaybe faster than if period, given that if has to do nil checks, etc
01:52dnolenanyways food for thought, night.
02:12devnwhat /is/ the idiom in clojure for using and requiring? I've seen 100 seemingly different ways. Heavy :requires with :as, lots of :uses with :only, when do you choose which?
02:13amalloyhiredman: he was doing (case (= x y) ...); surely that's not faster than (if (= x y))?
02:13devnNot trolling, just curious at what people see the "standard" being in that instance?
02:13amalloydevn: i do some of both
02:13devnamalloy: what is the motivating factor behind each decision?
02:13amalloycan't easily explain which when
02:13devnDoes it require a survey of the library?
02:14amalloyno, i don't think so. more about how related the library is to the core function of the file i'm in
02:14hiredmanamalloy: if has to do a null check on the value
02:14devnan example?
02:14amalloyhiredman: really?
02:14hiredmanso that is two branches vs. one for case
02:14devn^very interesting
02:14hiredmanamalloy: nil and false are falsy
02:14amalloyoh, of course
02:15amalloydevn: (:use [somnium.congomongo :only [fetch update!]]) (:require [clojure.string :as str])
02:15amalloyin a file that mostly does database stuff with a little string manipulation
02:16hiredmanI mean, I haven't read the part of the compiler that implements it, but it must call RT/booleanCast or similiar, which without inlining must be even slower then branching twice
02:16amalloyarguably it should be the other way around, devn, but this way feels more natural to me
02:16amalloyhiredman: yes, you're quite right
02:17hiredmanI smell 1.3, jira is getting cleared out, the auto promotion of earmuffed vars to dynamic is gone
02:55amalloyhiredman: did someone decide on 1.3 vs 2.0?
05:46matthias__hrm, im trying to install penumbra with leiningen, but i only get a bunch of errors which i dont understand :(
05:50matthias__you guys know a good, up-to-date tutorial on how to set up clojure with emacs on ubuntu?
05:50matthias__the last one i used turned out to be outdated in the middle and im afraid i may have made a mess here
05:51ejacksonmatthias the best and easiest way is to use elpa as detailed in Technomancy's blog
05:52ejacksonhere: http://technomancy.us/126
05:52ejacksonthis looks like the same thing: http://davidhilton.wordpress.com/2009/07/08/clojure-getting-started-in-5-simple-steps/
06:32matthias__thanks, ejackson
06:33ejacksongood luck, it's a bit of a fight the first time.
06:34matthias__looks like the stuff in technomancy's blog is also outdated :|
06:41matthias__what are you using?
06:41clgveclipse with counterclockwise
06:42matthias__gosh, the emacs-starter-kit removes the menu
06:42matthias__oh igot errors
06:47matthias__he says "you really don't need these; trust me" in the init.el
06:47clgvlol hihi, sounds funny
06:47matthias__i can sure do without scrollbars and the toolbar, but i think i might wanna keep the menu. but maybe he's right? hmm
08:12raekmatthias__: if you use emacs-starter-kit, then the readme for swank-clojure explains the rest
08:20markomanhow is internalization, common terms and text translations used to implement in clojure apps?
08:21joodiemarkoman: I use a map of language -> term -> string/function
08:21clojurebotmap and the other sequence functions used to be lazy, but with the advent of chunked sequences, may or may not be lazy, consult your local ouija board
08:22joodie(def strings {:en {:bla "Bla text" :foo (fn [arg] (format...))}})
08:22joodiecombined with a function to extract the translation given a keyword and language
08:23markomansomehow i would need to provide a path to the term because translation is often in some context
08:25joodieyou can make the path part of the key, or nest more maps.
08:26markomantrue, im thinking, if namespace could be part of the key
08:27raek,(ns-name *ns*)
08:27clojurebotsandbox
08:27raekyou can use that to get the name of the current namespace as a symbol
08:28markomanhow about getting name of the function I am in?
08:29joodiegenerally, you can't get the name of the function you're in
08:29joodieand I'm pretty sure you don't want to
08:30clgvmarkoman: you can write a frontend/wrapper to defn which enables you to get the name of the function you are in
08:30markomanin PHP i have __CLASS__ and __FUNCTION__ constants I can use for such tricks
08:30markomanor __FILE__
08:30joodiemarkoman: yeah, but in clojure you can move function definitions around
08:31markomanoh yes, true
08:31raekfunctions are just values, and vars can contain any value
08:33clgvthe defn wrapper would do something like (binding [*function-name* fname] (do ~@body))
08:33markomannamespace could help a little but im afraid i need to be more specific with the path. the reduced problem is {:en {:kuusi "fir" :kuusi "six"}}
08:35markomanso I think if i can pass more precise path / context i can get right term
08:35markomanwithout too much har coding of course, im lazy by nature, lol
08:36Chousukeyou could also do {:en {:kuusi ["fir" "six"]}} if you don't need the extra information about which is which
08:36Chousukethough hm
08:37Chousukelooks like you do :/
08:38markomansure, but its not practical as is not my example. if hard coded its better: {:en {:tree {:kuusi "fir"} :number {:kuusi "six"}}}
08:38ChousukeI suppose you could mark localisable strings with a macro that replaces them with a function call that fetches the correct string at runtime
08:39markoman clgv: i need to play with that idea, binding
08:41markomanmost often translatable terms are inside of hiccup forms...
08:42markomanso one idea would be to get class or id path of the term and use it for translation
10:11sritchiedoes anyone have any suggestions on a cleaner way to write this function ?
10:11sritchiehttps://gist.github.com/915542
10:12sritchieI'm looking to generate identity matrices, where each nested vector represents a row
10:15mduerksensritchie: ##(vec (map #(assoc (vec (repeat 10 0)) % 1) (range 10)))
10:15sexpbot⟹ [[1 0 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0 0] [0 0 1 0 0 0 0 0 0 0] [0 0 0 1 0 0 0 0 0 0] [0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0] [0 0 0 0 0 0 1 0 0 0] [0 0 0 0 0 0 0 1 0 0] [0 0 0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 0 0 1]]
10:17sritchiemduerksen: hey, that looks great, thanks
10:22mduerksenyou're welcome :)
10:24ejacksonmduerksen: slick !
10:24sritchie##(vec (for [row (range 5)] (assoc (vec (repeat 5 0)) row 1)))
10:24sexpbot⟹ [[1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1]]
10:25sritchiecool
11:10hugod_##(take 5 (partition 5 (cycle (concat [1] (repeat 5 0)))))
11:10sexpbot⟹ ((1 0 0 0 0) (0 1 0 0 0) (0 0 1 0 0) (0 0 0 1 0) (0 0 0 0 1))
11:27dnolenfogus`: did you see my snippet idea of DAG -> case for predicate dispatching? I'm curious as to how you approached the problem. I've been reading over Efficient Predicate Dispatching and papers on how they do it in Standard ML.
11:43TimMchugod_: Nice.
12:16amalloyhugod_: ##(cons 1 (repeat 5 0)) seems cleaner than concat
12:16sexpbot⟹ (1 0 0 0 0 0)
12:18hugod_amalloy: indeed
12:47codsIs there a clojure mode for Emacs which is able to correctly indent case? (rather than aligning condition and expressions on the same column)
12:48amalloycods: as far as i can tell that's the "right" way to indent case, bizarre as it seems to me
12:49amalloyif you get the latest version of clojure-mode.el, i've added a variable you can customize that would indent this right: M-x customize-variable clojure-defun-indents, then add case to the list
12:49mechow do you save once you've done that?
12:50amalloymec: save what? the customization?
12:50mecya
12:50codsamalloy: ok, trying it. Sound interesting :)
12:50amalloyC-x C-s works fine, mec
12:50amalloythe customization screen has Set and Save buttons if you prefer those
12:51amalloycods: thanks for bringing it up. i haven't used case since adding that feature, so mine still indents "wrong". nice to have it look more natural
12:51codshmm, actually I meant cond, but case is similar.
12:52amalloycods: if you don't like cond's indentation you're doing it wrong :P
12:52amalloyshould be (cond<RET>a b<RET>c d), which will indent fine
12:53codssure if you don't break line between a and b :)
12:53amalloymmm. that's harder. clojure's cond doesn't group pairs with parens, so emacs won't really be able to indent it (and there's no clearly "right" way)
12:54amalloyi see people put a blank line, or a comma, after b in that case
12:54codsI get lost because I'm used to Common Lisp, where (cond (a b) (c d)) is less confusing
12:54amalloycods: yeah. it's rather more cluttered; it's a compromise
12:55amalloyi proposed at one point making (cond [a b] c d) equivalent to (cond a b c d) for just this reason
12:55amalloysince a literal vector is always truthy, this doesn't seem to break any existing code
12:56mecyou could always (defmacro my-cond [& body] (cons 'cond (apply concat body)))
12:56amalloymec: no good
12:56amalloy(cond a [b] c d)
12:57amalloyor even (cond a (inc b)) - the list goes on
12:57codsmec: that what I was thinking, but I prefer conforming to the language, rather than trying to import my habits from another language
12:58amalloywell, i'll slop up a quick cond* and see if i like it
12:59mecDo i need to change anything else if i upgrade from clojure-mode 1.7.1 to 1.8.1 or just drop-in?
12:59amalloymec: drop-in afaik
12:59amalloyi did that when i was hacking it
13:09amalloycods: https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/core.clj if you're interested
13:11codsamalloy: thanks :)
13:12amalloycods: i've carefully engineered that to depend on my amalloy-utils: if you want to use cond* you have to either depend on my repo or look up lazy-loop and rewrite without it
13:28fogus`dnolen: I have not had time to look at it yet. I will do so ASAP
13:30dnolenfogus`: seems like you get get a near 6X speed increase over multimethods and a with considerable amount of additional generality.
13:31dnolensupporting ad-hoc hierarchies might be tricky, but I'm not a big fan of those these days.
13:32jcromartiewhat general naming convention would you use for functions that return predicates?
13:33jcromartiemake-<predicate>?
13:34jcromartielike (defn make-shorter-than? [n] (fn [x] (<= (count x) n)))
13:39mec_,(#('%))
13:39clojurebotjava.lang.IllegalArgumentException: Wrong number of args (0) passed to: sandbox$eval71$fn
14:06mduerksenis there an elegant way to convert a record into a normal map, e.g. for sending it over wire? instead of (into {} rec)
14:08amalloymduerksen: that's not elegant?
14:08mduerksenwell, not elegant enough ^^ ideally it should work with nested records
14:09mduerksenthanks a lot i'm asking for, i know ;)
14:10mduerksen*thats
14:10amalloymduerksen: (postwalk (partial into {}) nested-records)
14:10amalloywell, that's obviously rubbish
14:10amalloybut you get the idea
14:12amalloyif you want to copy transform-if from my utils library, you could write (postwalk (transform-if #(instance? clojure.lang.IPersistenMap %) (partial into {})) nested-records)
14:12mduerksenpostwalk? that's not clojure.zip, where is that function in?
14:12amalloyclojure.walk
14:13dnolenwarning; postwalk is horrendously slow.
14:13mduerksenah, that's great, thanks. i think i know what transform-if means, i have an own version of that in my source (i called it change-when)
14:14amalloyheh
14:14amalloymine returns a function rather than actually doing the change, which is handy for postwalk
14:15jcromartiehow does "lein run" work? it says "No :main namespace specified in project.clj."
14:15jcromartieI have a key for :main with a symbol for my namespace with a -main fn
14:17mduerksenamalloy, dnolen: thanks. i take it as yet another nudge to look further than clojure.core
14:18amalloydnolen: i'm always surprised by the number of people who want to use records, which seem to be primarily for performance, and then do all kinds of slow things with them
14:19amalloyusing hash-maps all the way i usually wind up happier
14:20mduerksenin my case, i use records to add protocols to them, performance is but a nice side effect. where i don't use protocols, i usually just use hash-maps too
14:22amalloymduerksen: protocols are mostly a high-performance, low-flexibility version of multimethods
14:23technomancyjcromartie: can you paste project.clj?
14:23jcromartiehttps://gist.github.com/d3e77832ace0e60462fa
14:23llahnahi, can partial be used to bind other args than the first one?
14:23jcromartiellahna: you want fnil
14:24amalloyjcromartie: i don't think that's true
14:24technomancyjcromartie: no need to quote symbols in project.clj
14:24jcromartieamalloy: ?
14:24jcromartietechnomancy: ah, ok
14:24amalloyjcromartie: he wants to not pass the arg at all, not substitute something for nil
14:24jcromartietechnomancy: you kids with your tricky macros
14:25amalloyllahna: anyway the answer is no. you can use #(some-fn %1 default-arg %2), for example
14:25clojurebotRoger.
14:25amalloyclojurebot: seriously? knock it off
14:25clojurebotOh, I know the best knock-knock joke! It goes like this... OK, you go first:
14:25technomancyjcromartie: yeah, defproject would be a real pain to work with if you had to quote every symbol
14:25jcromartieSorry I thought I had seen fnil used as a way to bind things other than the first arg
14:25llahnajcromartie: thanks
14:26llahnaamalloy: oh ok
14:26jcromartiellahna: not so fast... amalloy says you want what he suggested
14:26mduerksenamalloy: true. still, a record provides me a type for dispatch. with a plain hashmap, i'd have to put an type identifier inside the map
14:26jcromartietechnomancy: I un-quoted the namespace but still "No :main namespace specified in project.clj."
14:26jcromartieIf I use -m findex.core it works
14:27amalloyllahna: i have a reorder function, which lets you reorder the arguments to a function and get out a new function. if you really wanted to, you could do like (partial (reorder subs) 2) to get a one-arg version of clojure.core/subs that has the second arg auto-filled in instead of the first
14:27jcromartiemaybe I'll just update lein first :)
14:27amalloybut in practice i think that will lead to more confusion than enlightenment
14:27dnolenamalloy: personally I think multimethods are stop gap until we get something much better. the type dispatch function is a ball and chain.
14:28dnolenI mean the dispatch fn.
14:28amalloydnolen: like what?
14:28dnolenamalloy: matching multiple things means constructing a collection, downstream users of the multimethod are ball and chained to your dispatch fn.
14:29technomancyjcromartie: wfm on 1.5
14:29jcromartietechnomancy: I am on 1.5.0
14:29jcromartiederp
14:29jcromartiederp derp derp
14:29jcromartienever mind
14:29jcromartieI had two project.clj in my Emacs
14:29technomancyit happens =)
14:30jcromartienow, next up: where did stdin go?
14:31jcromartieI'm piping the output of find to this program, and in -main I have (println (line-seq (BufferedReader. *in*))) which prints nil
14:32technomancyyeah, that's an ant bug
14:32technomancy
14:32jcromartiehm
14:32technomancythey have no plans to fix it
14:32jcromartieso...?
14:33jcromartieI see
14:33technomancyhave to use java -cp `lein classpath` clojure.main
14:34dnolenamalloy: efficient predicate dispatch and Haskell pattern match + guards - order/exhaustiveness issues are more interested direction than what we currently have.
14:34jcromartiethat works
14:34jcromartieor do I need genclass in that case?
14:35jcromartiesorry, using clojure to actually run standalone programs is new to me
14:35technomancyjcromartie: you can use clojure.main to get a repl or clojure.main -e "(some-form)"
14:35technomancyor if you're on 1.3 you can do clojure.main -m my.ns
14:44duncanmamalloy: is choffstein someone who shows up here in #clojure?
14:44duncanmamalloy: he just wrote a blog post about hacking clojure
14:45amalloyyes
14:46duncanmamalloy: is that his irc nick?
14:46amalloyyep
14:46duncanmahh, i 'll keep an eye out for him then, i want to find more clojure users in the boston area
14:46amalloyduncanm: you can $mail him
14:46amalloy$help mail
14:46sexpbotamalloy: Send somebody a message. Takes a nickname and a message to send. Will alert the person with a notice.
14:47technomancyduncanm: there should be a boston meetup announced soon for the first week of may
14:47technomancyor so I've heard...
14:48duncanmtechnomancy: oh cool, there was a meeting a few months ago that i went to, but it went silent afterward
14:48technomancyyeah, my boss is attempting to revive it
14:48amalloyduncanm: oh cool, i read the first half of that blog post but then got interrupted. neat to see that i'm at the bottom, and it explains why you asked me specifically
14:48duncanmtechnomancy: oh? who's your boss?
14:57duncanmdum de dum
14:57mec_is it better to make a simple macro that makes a bunch of nested ifs, or a more complex one that rips them all into one if
14:58duncanmmagnet:
14:58amalloymec_: better still to use cond?
14:58duncanmmec_: what about cond?
14:58mec_err sorry, not ifs, lets
14:58amalloy*shrug* let is free. do what you find most readable
14:59duncanmthe reason why traditional Lisps have LET vs LET* is a performance trade-off, right?
14:59amalloyduncanm: i don't think so
14:59duncanmactually, space trade off?
14:59duncanmi don't remember anymore, i think we talked about it in my PL class when i was in school
15:00duncanmparallel bindings can be executed in parallel (but I don't know if any LISP systems actually do this)
15:00duncanmparallel bindings create a single new environment (scope) for all the bindings. Sequential bindings create a new nested environment for every single binding. Parallel bindings use less memory and have faster variable lookup.
15:00duncanmso i'm not totally wrong here....
15:00mec_so a big let vs a bunch of nested are more or less equal?
15:00hiredmanif (let [x 1] ..) ~= ((fn [x] ..) 1), then (let [x 1 y x] ...) ~= ((fn [x y] ..) 1 x)
15:01mec_beyond the obvious that is
15:01amalloyduncanm: that's probably only relevant in interpreted code
15:01technomancyit may have to do with clojure's lack of reified environments
15:01amalloycertainly for "faster variable lookup" i can't see that being true in compiled code
15:01matthias__when i start swank with lein swank and then connect to it using M-x slime-connect, it always says "versions differ bla bla"
15:01matthias__is that bad?
15:01amalloymatthias__: nothing you need to worry about
15:02duncanmmec_: this is a good explanation: http://stackoverflow.com/questions/554949/let-versus-let-in-common-lisp/587837#587837
15:02Bronsamatthias__: put this in your .emacs => (setq slime-protocol-version 'ignore)
15:02duncanmbut it's more geared towards Common Lisp
15:02Bronsaand stop worring about it
15:02amalloyi have in my .emacs: (eval-after-load "slime" '(setq slime-protocol-version 'ignore))
15:02mec_duncanm: is this valid for clojure tho?
15:03matthias__hmm, swank just got an exception. "invalid token: swank::"
15:03amalloyit's an artifact of the poor version-control practiced by slime devs, as i understand it
15:03technomancyamalloy: that's correct.
15:03technomancywell, poor release management.
15:03duncanmmec_: Clojure doesn't have LET*, its 'let' has the same semantics as LET* in older Lisps
15:03technomancyabsent release management, rather
15:04duncanmmec_: so unless you really want to signify some difference in scope stylistically, (let [x 1] (let [y 2] ...)) is equivalent to (let [x 1, y 2] ...)
15:04hiredmanwell, clojure does have a let* but let and let* both behave like common lisp's let*
15:04amalloytechnomancy: yes, i was being vague rather than trying to find the exactly-specific-enough term :P
15:04duncanmhiredman: oh really? let* is a synonym of let?
15:05hiredmanno
15:05hiredmanlet* lacks destructuring support
15:05duncanmoh
15:05mec_let* is the builtin compiler function that let uses
15:05matthias__http://pastebin.com/YEVnzDb3 thats the exception i got from swank
15:05matthias__can you help me?
15:05duncanmi didn't know that
15:05hiredmanlet* is the real primitive, let is a macro on top
15:06duncanmoh, well, at least that doesn't quite invalidate what i said
15:06amalloy&(macro-expand '(let [[x :as all] (range)]))
15:06sexpbotjava.lang.Exception: Unable to resolve symbol: macro-expand in this context
15:06amalloy&(macroexpand '(let [[x :as all] (range)]))
15:06sexpbot⟹ (let* [vec__18069 (range) x (clojure.core/nth vec__18069 0 nil) all vec__18069])
15:06Chousukeclojure doesn't officially have let* anyway
15:07Chousukeit's just an implementation thingy
15:07duncanmChousuke: the naming makes it particularly confusing
15:07ChousukeI suppose, if you know CL
15:07hiredmanit's like fn and fn*
15:07duncanmsince LET and LET* have well-defined meaning in CL and Scheme
15:07hiredman~scheme
15:07clojurebotscheme is Scheme is like a ball of snow. You can add any amount of snow to it and it still looks like snow. Moreover, snow is cleaner than mud.
15:08hiredmanhmm
15:08duncanm(i capitalize when i talk about scheme/lisp identifiers)
15:08hiredman~scheme
15:08clojurebotscheme is Scheme is like a ball of snow. You can add any amount of snow to it and it still looks like snow. Moreover, snow is cleaner than mud.
15:08hiredmanbleh
15:08kotarak,map
15:08clojurebot#<core$map clojure.core$map@b36022>
15:08kotarak,MAP
15:08clojurebotjava.lang.Exception: Unable to resolve symbol: MAP in this context
15:08kotarakhmmm
15:08amalloykotarak: clojure doesn't SHOUT like common-lisp
15:08kotarakamalloy: I KNOW.
15:09hiredman~please tell us what the hyperspec says
15:09clojurebothyperspec is not applicable
15:09duncanmi got used to seeing uppercase identifiers, it's kinda nice that it makes them standout more
15:09TimMckotarak: Checking for case sensitivity?
15:09hiredmanclojurebot: why doesn't clojure do like what I read in the hyperspec?
15:09clojurebothyperspec is not applicable
15:10duncanmotherwise, you kinda resort to some quoting convention
15:10kotarakTimMc: not really
15:10amalloyduncanm: blech
15:10amalloyclojure supports unicode symbol names. upcasing them would be a disaster for letters you don't recognize
15:11kotarakamalloy: clojure supports ascii symbols. Everything else is an implementation detail.
15:11technomancyelisp does fine with quoting in docstrings like so: "Pivots down to the `bargle' position."
15:11duncanmi'm not saying it's great, but it's easy to follow that uppercase means it's some bounded identifier
15:11duncanmtechnomancy: that's the elisp convention? `foo' like that?
15:11fibeuI have a quick qeustion: which IDE is best for doing GUI development in clojure?
15:11technomancyduncanm: yeah, erc even knows to highlight it
15:12amalloyduncanm: but it doesn't mean that! even in CL, if something returns the symbol A, you don't know if it's bound
15:12hiredmanhttp://dev.clojure.org/display/design/Library+Coding+Standards
15:12duncanmfibeu: there's not a lot of support for GUI development in clojure - i do quite a bit of it, but i just use emacs, and i don't use any form designer
15:12TimMcfibeu: I don't think GUI dev is going to be much different from ordinary dev.
15:13amalloy&((juxt identity #(Character/toUpperCase %)) \u039b)
15:13sexpbot⟹ [\Λ \Λ]
15:13jweissis there a simpler way to write #(not (nil? %))
15:13amalloy(complement nil?)
15:13amalloylonger, but simpler :)
15:13fibeuSo I guess best approach is using java GUI builder to build classes and just call them from clojure?
15:13kotarakjweiss: % if you know it's not a boolean
15:14amalloykotarak: ##(not (nil? 4))
15:14sexpbot⟹ true
15:14amalloyhe is effectively casting to a boolean, which yours doesn't
15:14hiredman,(if 4 :x :y)
15:14clojurebot:x
15:14TimMc&(Character/toUpperCase \u131)
15:14sexpbotjava.lang.IllegalArgumentException: Invalid unicode character: \u131
15:14kotarak,(if 4 "o.O" "O.o")
15:14clojurebot"o.O"
15:14hiredman,(if (not (nil? 4)) :x :y)
15:14clojurebot:x
15:14jweissi just want to take-while from an infinite seq while it's not nil
15:15TimMc&(Character/toUpperCase \u0131)
15:15sexpbot⟹ \I
15:15jweisswhat pred to use
15:15duncanmfibeu: there's something nice about typing it all by hand, if you organize things
15:15amalloy&((juxt identity #(Character/toUpperCase %)) \u03bb)
15:15sexpbot⟹ [\λ \Λ]
15:15duncanmfibeu: if you organize things just the right way, you can change the app while it's running
15:15hiredmanif does an implicit boolean cast
15:15kotarakjweiss: (take-while identity ...) or (take-while (complement nil?) ...)
15:15kotarakjweiss: the latter is more secure
15:15jweissah identity. that's it :)
15:15kotarakAh
15:15fibeuduncam: yes, in the REPL, I tried some basic stuff with Swing, it is cool
15:15amalloyduncanm: ^ is the example i was looking for about why it would be evil to uppercase symbols
15:16jweissit's iether going to be a string or nil, so i like identity
15:16fibeureminds me of doing things in Smalltalk
15:16TimMc&(= (Character/toLowerCase (Character/toUpperCase \u0131)) \u0131)
15:16sexpbot⟹ false
15:16amalloy&\0131
15:16sexpbotjava.lang.Exception: Unsupported character: \0131
15:16duncanmamalloy: sure
15:16amalloy&\u0131
15:16sexpbot⟹ \ı
15:16TimMc^ This is why we don't do case-folding.
15:16amalloyTimMc: what dang character is that
15:16TimMcamalloy: Turkish dotless i.
15:16duncanmfibeu: yeah, but it takes a lot of care to do it right, often times, i just restart the app
15:16amalloyfun
15:17duncanm(well, kill the frame and start again)
15:17amalloyi guess i knew there were characters that didn't transition nicely, but i never would have found one. thanks
15:17mec_wow apparently there are limits on method length ;p
15:17duncanmfibeu: also, it's easy to accumulate too many dangling references in the REPL, and then you either can clear it out with (System/gc) or you have to restart your slime session (or you figure out some slime way to clean up....)
15:18duncanmmec_: is that a JVM limitation?
15:18amalloymec_: yeah, they're crazy large though. but you can't write your whole app in one big macro :P
15:18mec_I would assume so
15:18amalloyduncanm: yes
15:18TimMcamalloy: http://gizmodo.com/#!382026/a-cellphones-missing-dot-kills-two-people-puts-three-more-in-jail < Interesting case where lack of support for dotless i led to someone being killed. (Sorry for Gizmodo link.)
15:19duncanmdotless i? it's used in turkish or something?
15:19fibeuduncanm: hmm, never tried slime, I use IDEA
15:19mec_looks like the limit is 65536
15:19duncanmfibeu: oh, slime is what you'd use with emacs
15:19duncanmi tried to like IDEA, but it just doesn't look very nice on the machines that I ran it on (mac and windows)
15:20TimMcduncanm: Turkish has both dotted and undotted upper and lowercase Is.
15:20amalloymec_: 65536 of anything in particular? methods can't have more than 64k rubber ducks?
15:20mec_on the plus site nested let vs 1 big let doesnt seem to run any slower
15:20TimMcEnglish has a dotted lower and an undotted upper. Localization hilarity ensues.
15:20hiredmank
15:21mec_i think it's characters but I cant be sure
15:21hiredmanmethod size it bytes is limited to 64k I believe
15:22fibeuI think I will use netbeans to write some GUI classes in java, do the functional part in clojure and glui it together
15:22duncanmmec_: in Scheme, i think (let ((a 1)) (let ((b 2)) ....) is the same as (let* ((a 1) (b 2)) ....)
15:22amalloyTimMc: that's a pretty amazing localization story
15:22duncanmfibeu: i'd be interested to hear how that works out for you
15:23duncanmfibeu: i write java code in NBs, but i neverg got around to using their form designer
15:23duncanmfibeu: i wrote all the layout code by hand ;p
15:23fibeuoh, netbeans GUI designer is great I think
15:23matthias__hmm, according to something i found, my problem might be that i got the wrong version of slime, but i did install it with package.el
15:24duncanmfibeu: i just don't really like having generated code
15:24duncanmbut yeah, i should embrace it, it's a much easier/faster way to work
15:24fibeuIyes, lot"s of boilerplate
15:26amalloyduncanm: write macros *you* understand to generate all the code, instead of letting a tool fill your program with code you don't understand
15:26mec_anyone know where let* is defined? all I can find is a reference in compiler of defining the symbol LET
15:27mec_wow dejavu
15:27amalloymec_: it's in the compiler. the symbol LET is bound to Symbol.intern("let*")
15:27mec_but where from there?
15:27duncanmamalloy: yeah, that's why i want to write a define-action macro for Clojure+Swing
15:27matthias__swank keeps crashign with that unreadable message error :|
15:28amalloyLetExprParser, iirc
15:28amalloyLetExpr.Parser
15:28duncanmamalloy: the idea is to kinda do SAM conversion, by making define-action return an AFn that also implements the given SAM interface
15:28TimMcIt's in the Compiler.java file.
15:28raekmatthias__: which slime version are you using? the one from emacs-starter-kit?
15:29matthias__yes
15:29matthias__how can i check which version i have though?
15:30raekand you connect with M-x slime-connect?
15:30matthias__slime-20100404.1
15:30matthias__yes
15:30matthias__and then swank crashes
15:31raekI'm looking in my .emacs.d/ and I have that version too
15:31matthias__"unreadable message: (:emacs-rex (swank:autodoc (quote ("+" swank::%cursor-marker%)) :print-right-margin 80) "user" :repl-thread 4)"
15:31raekwhich version of swank-clojure?
15:31matthias__i got swank-clojure 1.3.0-SNAPSHOT
15:32raeksame as the one I use too
15:32matthias__:(
15:32raekI'l try to update it
15:33matthias__swank crashed once i type more than a ( into slime
15:33raek...and you don't have any old installation of slime lying around?
15:33matthias__*crashes
15:34matthias__erm
15:34raekok, this is strange...
15:34matthias__i dont know
15:34matthias__i might have made a mess, i tried multiple different clojurei nstallation tutorials :D
15:34matthias__but i removed the .emacs and .emacs.d and then installed the starter ki
15:34matthias__t
15:34raekok
15:34raekthat's good
15:35raekmatthias__: there's a slime package in ubuntu (assuming you are using some GNU/Linux variant). you don't have it installed?
15:36matthias__who knows B) ill look
15:36matthias__i do
15:36matthias__it actually seems to be a newer version
15:36raektry removing it
15:36matthias__on it
15:37raeknewer versions are known to break compability with swank-clojure...
15:37matthias__yeah i heard
15:39matthias__still doesnt work, but its different now
15:39raekdid you install both slime and slime-repl with package.el?
15:39matthias__"exception in read loop
15:39matthias__java.lang.Exception: Error reading swank message
15:39matthias__ at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
15:40matthias__yes
15:40matthias__but who knows what else i had lieing around D:
15:41raekwhat does "java -version" say?
15:41matthias__java version "1.6.0_20"
15:41matthias__OpenJDK Runtime Environment (IcedTea6 1.9.7) (6b20-1.9.7-0ubuntu1)
15:41matthias__OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)
15:42raekmatthias__: could you post the stacktrace somewhere?
15:43matthias__http://pastebin.com/53knb18c
15:45raekyou could try switching the Java implementation to the Sun variant
15:46matthias__huh, i dont even get a repl anymore when i run slime-connect
15:46matthias__is that normal?
15:46matthias__used to see that fancy anymation right away
15:46amalloyno
15:47matthias__can i open one manually?
15:47amalloythat's a broken, there
15:47matthias__i got a *slime-events* buffer
15:47matthias__so is openjdk known to cause issues or was that just a wild guess?
15:48raekI'm not sure, but getting an exception from sun.reflect.NativeConstructorAccessorImpl.newInstance feels suspicious :/
15:49matthias__hasnt crashed this time, but i cant try running code because i dont see a repl
15:49matthias__i uninstalled cl-swank and something else. dont even know why i had cl stuff, never used it
15:50hiredmanraek: that is just a reflective call to a constructor
15:53raekmatthias__: anyway, here's some instructions on how to install the sun jvm: http://www.webupd8.org/2010/09/how-to-install-java-jre-and-java-plugin.html
15:54raekmatthias__: does the problem persist if you use swank-clojure 1.2.1?
15:55matthias__uh
15:56matthias__how i do that?
15:56raekhow do you start swank-clojure currently?
15:56matthias__lein swank
15:56matthias__do i have to uninstall 1.3.0 and install 1.2.1?
15:57raekmatthias__: did you add swank-clojure to you project.clj or did you do a lein plugin install?
15:57raekin the latter case, yes
15:58mec_How could I do this? `(foo ~(rest (bar-macro ~@body))) I want to replace the head of the result from (bar-macro ~@body) with foo
15:58matthias__yeah, the latter
15:58raeklein plugin uninstall swank-clojure "1.3.0-SNAPSHOT" && lein plugin install swank-clojure "1.2.1"
15:59matthias__"Plugin "swank-clojure 1.3.0-SNAPSHOT" doesn't appear to be installed.
15:59matthias__" what the hell :|
15:59raekmec_: you can't, since that subsitution will hapen after the foo macro is done
15:59Chousukemec_: hmmh, that's a bit tricky
16:00raekor can you?
16:00mec_(cons `foo (rest (macroexpand-1 `(bar-macro ~@body)))) works but seems iffy
16:00ChousukeI was about to type something like that
16:01Chousukeit's not that bad :/ the macroexpansion still happens at macroexpansion time so it's not like you're using eval or something :)
16:02tsdhWhy are there no nightly clojure builds since december last year?
16:02amalloydo you control bar-macro? it sounds like it would really rather be a function than a macro
16:02amalloytsdh: sun hasn't gone down yet, in antarctica?
16:02mec_amalloy: ya I was just thinking about pulling bar-macro out into a helper function that is referenced by both
16:02matthias__oh, there's lisp connection closed unexpectedly: connection broken by remote peer in *messages*
16:02matthias__but swank doesnt seem to have crashed
16:03tsdhamalloy: ;-)
16:03Chousukeyou could also use the macro function instead of the macro so you don't need macroexpand-1.
16:03Chousukebut that's maybe overkill :P
16:03mec_do what now?
16:04Chousuke,(@(var defn) 'foo '[args] 'body 'here)
16:04clojurebotjava.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
16:04Chousukehmm
16:04Chousukeoh right macros take the weird extra args too :/
16:04amalloyChousuke: it wants some nils for &env and &body
16:04Chousukenever mind, best not try thtat then :D
16:05matthias__erm, i had something about 1.2.0 in my project.clj :|
16:05amalloy,(#'and nil nil 'a)
16:05clojurebota
16:05matthias__i dont even remember where i got that one
16:05matthias__still not getting a repl in emacs
16:05mec_are &env and &body supposed to be anything besides nil?
16:05matthias__is there really no way to manually start a slime repl?
16:05amalloymec_: the compiler sets them
16:05amalloymatthias__: yes, you manually start it with slime-connect
16:05amalloythat's it
16:06matthias__:(
16:06matthias__how i find out why it doesnt work?
16:06raekmatthias__: so you have put a more recent one in your project.clj and done lein deps?
16:06amalloyit can't start a repl with a swank server it can't connect to
16:06matthias__i didnt do line deps
16:07matthias__got a bunch of artifact missing errors
16:07matthias__it did say it connected
16:07matthias__Connected. Lemonodor-fame is but a hack away!
16:08matthias__perhaps i need to add some kind of repository for lein
16:08matthias__hmm
16:08raekyou have the latest version of lein?
16:09raekyou could remove lib/, add [swank-clojure "1.3.0-SNAPSHOT"] to project.clj and a lein deps again
16:09raekswank-clojure is in clojars, so you shouldn't have to add any repo
16:10raekwhat artifact is missing?
16:10raekalso, do you still have the global swank-clojure install (form lein plugin install)? if so, you don't need any in project.clj
16:11matthias__i cant tell which is missing
16:11matthias__now it worked (after i removed it from project.clj)
16:12matthias__the lein deps that is
16:12raeksounds like a typo
16:13matthias__"[leiningen/lein-swank "1.3.0-SNAPSHOT"]" iswhat is said before
16:13raekooh, that's also old... :)
16:13matthias__slime still wont show me a repl, but is connected
16:13raek"lein swank" is in swank-clojure now
16:13matthias__as i said i tried a bunch of outdated tutorials on how to set up clojure and made a mess :(
16:13raekmatthias__: replace that with [swank-clojure "1.3.0-SNAPSHOT"]
16:14raekthen you should be good to go :-)
16:15matthias__still getting no repl
16:16raekfirst, did the swank server start?
16:16matthias__all i get is some stuff in *Messages* and a *slime-events* buffer
16:16matthias__oh i crashed again
16:16matthias__didnt do that before
16:16raeki.e. do you get the #<ServerSocket ServerSocket[addr=localhost/127.0.0.1,port=0,localport=4005]> line?
16:16matthias__i did, but then it crashed
16:17matthias__same as the last error i put on pastebin
16:17raekwhat does "ls ~/.lein/plugins/" say?
16:18raekand could you paste your project.clj?
16:18matthias__swank-clojure-1.3.0.jar swank-clojure-1.3.0-SNAPSHOT.jar
16:18matthias__http://pastebin.com/3S64NFRW
16:19matthias__thanks a lot for helping me out, btw
16:19matthias__now i'm wondering why i have two swanks
16:19raekok, do a rm ~/.lein/plugins/* ~/.lein/bin/*
16:20raekand then remove lib/ in your project and do a lein deps and lein swank
16:21raek...and before that, change version to "1.3.0" in project.clj
16:21raek(didn't realize that one was released)
16:21raek[swank-clojure "1.3.0"]
16:22matthias__gosh
16:22matthias__can i also do that after? :p
16:22raekyes, just do a lein deps
16:23raekit should remove the old stuff from lib/ too, I was just a bit paranoid before...
16:23matthias__i have a feeling the problem is actually with slime right now. maybe
16:23matthias__i mean it says it connects
16:23matthias__but doesnt give me a repl
16:23matthias__the newer version of slime always did, but then crashed after
16:23raekis there any *slime-repl clojure* buffer anywhere?
16:23matthias__or made swank crash rather
16:24matthias__no
16:24matthias__only *slime-events*
16:25raekso you get "Connecting to Swank on port 4005.."
16:25raekand then "Connected. Take this REPL, brother, and may it serve you well."? (or other random quote)
16:25matthias__yes
16:25matthias__actually is said [2 times] after the connected
16:26raekbut no repl? that's odd..
16:26matthias__and then it says byte-code: beginning of bugger [6 times]
16:26matthias__*buffer
16:26matthias__after the random quote
16:26raekand the "lein swank" terminal hasn't changed?
16:26matthias__nope
16:27matthias__not this time anyways :|
16:28raekthe only thing I can think of now is to remove .emacs.d and replace it with a fresh install of emacs-starter-kit, and then install clojure-mode, slime and slim-repl again
16:28matthias__hmm, i kinda only just installed emacs-starter-kit
16:28raekI'm not sure what happens if you try to install those while you have the system slime package installed
16:28matthias__but i guess i should try that :(
16:28matthias__ah
16:28matthias__maybe
16:29matthias__huh, swank crashed after i closed emacs
16:29raekI get that at my setup too, if I exit emacs while the slime<->swank conenction is running
16:30raekhrm, and then I get the same exception as you did...
16:30matthias__i think this is looking like slime is the problem
16:30raekprobably means that swank-clojure got an EOF while reading or something
16:32matthias__reinstalled the starter kit
16:34matthias__ihuh, slime-repl failed to install
16:34matthias__Error: No setf-method known for slime-connection-output-buffer
16:35raektry installing one at a time, and with slime before slime-repl
16:35matthias__did have slime before slime repl
16:37edwDoes ztellman of aleph fame hang here?
16:37raekmatthias__: and you're not trying to install the "swank-clojure" package, right?
16:37matthias__no, i installed clojure-mode and slime and then tried slime-repl
16:38matthias__i got the exact same error as the commenter on that: http://webcache.googleusercontent.com/search?q=cache:http://blog.clojurls.com/setting-up-clojure-with-emacs-and-leiningen
16:38matthias__i'm too dumb to copy stuff out of emacs :D
16:39raekmatthias__: M-w :-)
16:40matthias__slime-repl.el:122:39:Error: No setf-method known for slime-connection-output-buffer
16:40matthias__haha
16:40matthias__thanks
16:41matthias__seems like slime-repl might actually be installed, but just not byte-compiled
16:41matthias__according to 3. here http://groups.google.com/group/swank-clojure/tree/browse_frm/thread/20141a1e19c60339?_done=%2Fgroup%2Fswank-clojure%2Fbrowse_frm%2Fthread%2F20141a1e19c60339%3F&amp;
16:42matthias__i was actually going to install swank-clojure after slime-repl :>
16:42matthias__i dont even know what it is, but some random part of the internet told me to
16:42raekheh, that package is from the time before lein
16:42matthias__technomancy, you're phil hagelberg, right?
16:42technomancyyeah
16:42technomancywhy slime-repl ever got separated out of slime.el I will never know. bunch of nonsense.
16:42matthias__i dont know how i knew that
16:43raek"When you perform the installation, you will see warnings related to the byte-compilation of the packages. This is normal; the packages will work just fine even if there are problems byte-compiling it upon installation."
16:43matthias__well this was an error, no warning
16:44matthias__huh, got a repl and it seems to work 8)
16:44raekmatthias__: is slime-connect available anyway?
16:44matthias__yeah
16:44matthias__thanks again, raek
16:44matthias__btw, what happens when i run just slime?
16:44raekmatthias__: I can tell you, it's downhill from here ;-)
16:44matthias__better be :D
16:45technomancywhat was the root cause? mostly just confusion due to the apt-get version of emacs?
16:45matthias__oh man
16:45matthias__i didnt quite understand it all. but that was one of the problems
16:45technomancyI'm open for suggestions to make it clearer
16:45matthias__i didnt get a cool animationthis time though
16:46technomancyunfortunately I can't fix blogs with misleading info =\
16:46raeka combo of the slime debian package, [leiningen/lein-swank "1.3.0"] for [swank-clojure "1.3.0"], among other things
16:46matthias__your newest explanation is outdated. perhaps someone should make a tutorial on how to set it all up and actuallt keep is up to date
16:46raek...coming from outdated blogs, I think
16:46technomancymatthias__: which one are you refering to as the newest?
16:46matthias__some random one i found
16:46matthias__:D
16:47raekmatthias__: this one? http://technomancy.us/126
16:48matthias__yeah
16:48matthias__its not one of the problematic ones since its clear that its outdated
16:48technomancythat points to the official readme at least
16:48matthias__the link is also outdated and the official wiki thing explains some stuff about inferior lisp mode
16:48matthias__which sounded wrong to me
16:49raekI should really make a screecast about how to do this...
16:49technomancyit's an alterante approach
16:49technomancynot invalid, just more simplistic
16:49matthias__yeah, but it seems there was no current one about the swank-clojure + slime approach
16:50matthias__that might have made it clearer 8)
16:50raektime to write that mail re. write access to the wiki
17:04duncanmla la la
17:07amalloyedw: i've seen him once or twice in here, but seems very rare
17:08duncanmi can never remember the arguments to the methods for JOptionPane
17:10jcromartieam I completely misunderstanding redis-clojure?
17:11jcromartieor is sadd broken... because doing (redis/sadd "key" "val") and then (redis/smembers "key") returns #{"3"}
17:17jcromartieit appears to be storing the length of the value instead of the value itself... must be a protocol mismatch
17:21edwamalloy: Thanks. I rooted through the source and found the answer to one of my questions.
17:22amalloyedw: i met him a month ago, though. i think there are lamina and/or aleph usergroups that he does follow if you want to get his attention
17:23edwamalloy: Thanks again. I'm curious about what sort of scalability benefits using aleph makes possible, as I've recently worked on a small but non-trivial Node.js project, and it got me getting very sick of the C-like syntax required for this very Lisp-like job.
17:28lucianedw: if you ever have to write JS, give CoffeeScript a try
17:28raektechnomancy: do you think it would be resonable to present slime + swank-clojure as the primary / most common approach at Getting Started with Emacs in confluence?
17:29edwlucian: I feel like I'm at Hacker News right now! ;) I tried it, it's not compressing my code much, it requires too much thinking (do I NEED those parens?!) and it adds complexity to the development process.
17:30technomancyat least you don't have to think "did I get all my return statements in?"
17:30lucianedw: meh. i find the tradeoff worth it
17:30technomancythat's like a 50% bug reduction right there when it comes to the JS I write.
17:30luciani get indentation-syntax, more expressions and nice function literals
17:30edwtechnomancy: Yeah, I hear you. And lucian, I'm not begruding anyone their coffeescript; it's just not for me.
17:31lucianedw: sure, never blamed you of anything
17:31amalloyexplicit return statements are so sad
17:31technomancyraek: yes, but only if it's simple enough. I keep thinking it is, and people keep proving that false.
17:31lucianamalloy: to each his own. i think it's not the best of reasons for disliking JS :)
17:31edwI hate syntax. I love lisp.
17:31raekfair point.
17:32amalloylucian: it's actually a reason for disliking php, for me :P. make a function to be an alias of another, and spend ages debugging to find i forgot the return
17:33lucianamalloy: i suppose that's down to familiarity. as a pythonista, i pretty much never do that
17:33edwAnd aleph, which someone on HN pointed me to, looks like it could let me write async threadless server apps in Clojure.
17:33lucianbut there are plenty of things that are clearly wrong & stupid in both JS and especially PHP
17:34edwlucian: You spend much time in a lisp, where everything's an expression, you quickly forget the `return' ever existed. I stared at some of that Node.js code for ten minutes until I realized I needed a `return' in there.
17:34lucianedw: yeah, i realise that. i get the reverse when i write lisp, but not with returns
17:35lucianedw: btw, there's also ParenScript. it's a bit odd, you might hate it (i do)
17:35edwWith pattern matching (destructuring assignment) and implicit returns and a banishment of assignment, Javascript would be *so* much nicer.
17:36edwAnything that's a prepocessor is going to be a drag.
17:36lucianwell, still has assignments, but they're done right and less necessary
17:36edwlucian: CS has destructuring assignment?
17:36lucianedw: doesn't it? i might be wrong, but i thought it did
17:37luciani treat CS as a compiler
17:37lucianor you can get it to compile in the browser if it's really a problem
17:38lucianedw: yeah, it has destr. assi.
17:38lucianedw: http://jashkenas.github.com/coffee-script/
17:38lucianworks like in python or js1.7
17:39edwlucian: Thanks, I hadn't gotten that far down in the docs yet.
17:39lucianit might depend for your particular case, but i'm willing to jump some hoops to replace JS with CS
17:39lucianit's just that much nicer
17:39edwI'm using Joyent's Node.js Cloud, so the CS would interfere with the git push goodness.
17:40lucianwell, you could run coffee -c -w and commit .coffee files
17:40lucians/.coffee/.js/
17:40sexpbot<lucian> well, you could run.js -c -w and commit .js files
17:41luciansexpbot: bad bot
17:41brehautlucian: if you dont want sexpbot to do that, there is an exclude list
17:41lucianwell, my regex is wrong
17:42lucianbrehaut: i should get my regexen right instead :)
18:45raektechnomancy: what is the difference between the slime, slime-repl and clojure-mode packages when comparing ELPA and Marmalade
18:45raek?
18:46technomancyraek: clojure-mode is newer at marmalade. slime and slime-repl are probably the same.
18:48raekis it mentioned in the swank clojure readme beacuse it gets newer version more quickly?
18:49technomancyraek: elpa has basically stopped accepting new versions in hope that people will migrate to marmalade
18:51raektechnomancy: ah, so maybe it's a good idea to mention it instead of elpa in Getting Started with Emacs? (since the packages mentioned at that page are all in marmalade anyway)
18:51technomancyraek: oh, for sure
18:52raekok, thanks!
18:54TimMcmarmalade... never heard of it
18:55raekjust discovered it myself :-)
18:55technomancyit's spreadable elisp
19:54raekthere. today's work is done: http://dev.clojure.org/display/doc/Getting+Started+with+Emacs
19:54raekgood night.
19:57technomancyraek: thanks!
19:59technomancydoes lein repl actually work for inf-lisp?
19:59clojurebotthe repl is holding onto the head of sequences when printing them.
20:00technomancyclojurebot: nonsense
20:00clojurebotPardon?
20:02znutar_oh nice! I just started with clojure and emacs on saturday and the nebulous state of the documentation on what to actually use was a real drag
20:03technomancywell the old wiki docs were already halfway decent; the problem is more that people don't read them
20:04technomancyand that everyone put lots of google juice into the assembla pages and now they're on confluence
20:06znutar_Yeah, it's a pain figuring out what docs are good out of context. Otoh it's usually a sign that people are actually doing something and not just blogging.
20:07technomancymore like people who don't know what they're doing are the ones doing the blogging
20:10znutar_That's almost always going to be the case, though. If you have everything running smoothly it's rarely interesting enough to warrant telling people about.
20:10technomancyquite true.
20:11technomancy"Hey guys, check out the readme! It tells you how to use it. Shocking, I know." <= lemme go retweet that!
20:11technomancy</rant>
20:24znutar_I wonder if the whole game console-like achievements angle for something like labrepl would do a good job of illustrating the most painless way to get yourself set up in some known state for newbies
21:10sritchiedoes anyone here know how to force stdout to print to the current emacs repl buffer, with SLIME?
21:10sritchiecake currently directs it to .cake/cake.log, but I've seen a few screencasts where stdout shows up directly in emacs
21:59MiggyXHi guys, if you need to write a program that goes through a CSV file to sequentially match rows (i.e. order is important) is there a standard way to maintain this 'state' in clojure ?
22:03amalloysritchie: that's weird. it prints to the repl for me
22:04amalloy(and i use cake)
22:04sritchieamalloy: hmm, odd! I've been running cake swank at the command line, then slime-connect in emacs
22:04dnolensometimes things are so easy in Clojure it seems criminal, https://gist.github.com/916831
22:05sritchiethe solution floating around the web is to put (setq SWANK:*GLOBALLY-REDIRECT-IO* t) in ~/.swank.lisp, but no luck there
22:05amalloysritchie: same. maybe you have an old version of one of those?
22:06sritchieamalloy: I just updated everything off of ELPA, so it's not that --
22:06amalloyerrr, cake isn't in elpa, is it?
22:07sritchiesorry, I meant slime, etc
22:07sritchiecake is maybe a month old
22:07amalloycake --version?
22:08sritchiejust ran cake upgrade, so now it reads cake 0.6.2-20110221.082826-17-g4d002b1 -- let me test it now
22:11brehautMiggyX: without knowing more details you probably want to look at reduce
22:12sritchieamalloy: no dice. normal side effects show up, and the results of function calls, just not anything that's meant to be piped to stdout
22:12sritchiecascalog output, or pallet output, for instance
22:13amalloyoh. piped? i guess i don't understand the problem
22:14amalloybut if i did understand it i still wouldn't have a solution, so probly not worth your effort to clarify
22:14MiggyXbrehaut: Basically processing a huge csv file (30GB+) and matching rows together etc
22:14MiggyXbrehaut: brb
22:16sritchieamalloy: no problem, thanks for taking a look. the clarification's short -- non-repl threads currently print to .cake/cake.log, so I was just looking for a way to get all threads, repl or non-repl, to send output to the repl buffer
22:18brehautMiggyX: a) http://mywiki.wooledge.org/XyProblem b) thats still an extremely general description of a problem
22:21MiggyXbrehaut: Well basically I have a CSV file that contains two feeds of data. We're talking more than 9 million rows combined. From the first feed (let's call it feed A) there should be a matching entry - or at least a similar entry - in feed B. The problem is that there are no global identifiers and so the file needs to be processed sequentially. Basically I want to match the two.
22:23brehautMiggyX: how are they 'matched' ?
22:24MiggyXbrehaut: There is a sequence number and various fields that should match up - it's unlikely that the same combination would appear within a few minutes of each other (though theoretically possible). However trying to load the file and match in one go won't work as you will have great trouble trying to isolate the correct one
22:25brehautMiggyX: is this tallyman / TCRM data?
22:26MiggyXbrehaut: forex price feed / trade
22:26brehautclose then. those formats are always miserable
22:27MiggyXbrehaut: Tell me about it :/
22:27amalloybrehaut: i'm going to have to start prefacing all my questions with "I'm on Gentoo so I know what I'm doing"
22:27brehautamalloy: golden eh :)
22:27brehautvia raganwald's tweeter
22:28MiggyXThing is, I can't see how I can do it without maintaining some sort of state - or sticking most of the code into a single function...
22:28brehautMiggyX: are you fairly new to the functional programming thing?
22:29MiggyXbrehaut: yeah - read a lot about it, but have yet to actual do anything useful with it.
22:30brehautMiggyX: ok. theres a function called reduce (sometimes called 'fold' in other languages) that takes a function, some data and a sequence. The function it takes as an argument is given items from the sequence one at a time along with some data (sometimes called the accumulator/accumulation) and it returns a new accumulation
22:31brehautMiggyX: a simple example would be ##(reduce + 0 [1 2 3])
22:31sexpbot⟹ 6
22:31brehautMiggyX: the ## just tells sexpbot to evaluate it
22:32amalloybtw, you can see what the reduce is doing "under the hood" with ##(reduce (partial list '+) 0 [1 2 3])
22:32sexpbot⟹ (+ (+ (+ 0 1) 2) 3)
22:32brehautamalloy: ah yes good example
22:32MiggyXokay, with you so far :)
22:32brehautMiggyX: so the data passed to reduce is the seed value for the accumulator, if its not present clojure will use the first argument in the sequence
22:33amalloybrehaut: you missed my stroke of genius to explain the difference between apply and reduce: ##((juxt apply reduce) (partial list '+) (range 4))
22:33sexpbot⟹ [(+ 0 1 2 3) (+ (+ (+ 0 1) 2) 3)]
22:33TimMcWe don't have foldl and foldr, do we?
22:33brehautamalloy: nice :)
22:34brehautTimMc: nope
22:34amalloyTimMc: no
22:34brehautMiggyX: so in your case you might have something like (reduce match-csv (match-acc) csv-data)
22:35brehautwhere match-csv is a function that operates record at a time on csv-data and (match-acc) is a function that returns an empty accumulator
22:36MiggyXcan the csv-data see the contents of match-acc ?
22:36brehautno
22:36brehautcsv-data needs to be a sequence of csv records from your csv file
22:37MiggyXif I understand correctly, each row (assuming I set it up that way) will be passed to the match-csv function which will be called uniquely (i.e no side effects) for each row.
22:37brehautalso because im a muppet, it should probably just be empty-match-acc or something; no need for it to be a function call
22:37MiggyXFrom that I'm not sure how I could match saw row one with row ten
22:38brehautMiggyX: match-csv can return anything it likes. whatever it returns is used as the accumulator argument for the next call to match-csv
22:38brehautMiggyX: think of it as simple recursive over a list but without you needing write the recursive logic and tests
22:39MiggyXokay, so match-csv is called with the result of the accumulator and the next row from the file?
22:39brehautthe result _is_ the accumulator
22:40amalloybrehaut: haskell teaches us that everything should be a function call
22:40TimMcOh, that's right... nullary functions for constants.
22:40brehautamalloy: this is indeed what tripped me up
22:40amalloyhaha
22:41amalloyi didn't even know that, TimMc
22:41amalloyi just figure, if brehaut says something crazy, blame haskell
22:41TimMcWell, don't take it as gospel.
22:42brehautamalloy: if you cant have any side effects due to the type system, and the funcall syntax doesnt require parens, then there is no difference between a function of no argumnts and a constant value
22:42TimMcbrehaut: Can you confirm my assertion?
22:42TimMcheh
22:42brehautTimMc: yes. although its probably elided back to just constant values by the compiler
22:43TimMcbrehaut: Also, where do you live? I'm wondering about your use of the word "muppet".
22:43brehautTimMc: New Zealand
22:43TimMcIt's a Brtish thing, yeah?
22:43mecamalloy: do you have an example of using your lazy-recur in a non tail position?
22:43brehautTimMc: probably
22:44dnolenhmm are strings reliable unique identifiers for classes on JVM? I wondering the what's the most stable thing considering redef'ing types/records is common.
22:44amalloymec: https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/core.clj, but pretty much every use of lazy-recur isn't in tail position
22:44amalloydnolen: no
22:45amalloytwo classes with the same package and name can be loaded by different classloaders and not conflict
22:45mecamalloy: err right
22:45TimMcamalloy: "not conflict" is an interesting phrase
22:46TimMcIt can be problematic if you accidentally try to cast one to the other.
22:46amalloyTimMc: feel free to propose more-accurate statement
22:46TimMcnuh-uh
22:46MiggyXstupid question - I don't suppose reduce runs in paralllel :)
22:46brehautMiggyX: nope
22:46TimMcMiggyX: preduce
22:46dnolenamalloy: huh ... how does the JVM differentiate them? If I load some other jar that references one of those classes, which will get instantiated ?
22:46TimMcWait, how would that even work?
22:46MiggyXTimMC: I assume that would screw up the accumulator though
22:47amalloydnolen: suppose class A1 and A2 are loaded by classloader L1 and L2
22:47amalloyif someone in class B refers to class A, they get the class named A which was loaded by the same classloader as B
22:47amalloyiirc
22:49TimMcMiggyX: There's something called preduce, but I think it parallelizes operations on different key-value pairs of maps.
22:49dnolenamalloy: if classes can't cross class loader boundaries then how can using string as an identifier be problem?
22:50brehautMiggyX: thres no such thing as magic parallization; you need to know your domain well enough to device reasonable partitioning, operations on those partitions, and reconstitutions for instance
22:50MiggyXTimMc: I always seem to pick hard tasks :)
22:50amalloydnolen: you can find references to other classloaders, and ask them to load a class for you, or return it if it already exists
22:50brehautMiggyX: and your strong ordering requirement may cause you a lot of grief
22:50amalloyMiggyX: you pick vaguely-defined tasks
22:50amalloyall such tasks are hard :)
22:51amalloyhttp://download.oracle.com/javase/1.4.2/docs/api/java/lang/ClassLoader.html#getSystemClassLoader()
22:51MiggyXbrehaut: If I was doing it in say Python, I would split the file into say 1GB chunks and then start the matching process. any rows that aren't match are passed back, put in an ordered list and then processed as a final job. I think that should work
22:51MiggyXbut I was hoping to have a good excuse to spend a few days doing it in clojure :D
22:51brehautMiggyX: you would do the same in clojure then
22:52phenom_hey, in my code I create a lot of vectors which i pass around to single argument functions which in turn deconstruct the vector ... YourKit is showing me that alot of my space is taken up by clojure.lang.PersistentVectors ... any idea why?
22:52phenom_shouldn't they be garbage collected? I dont hold on to them at all
22:53brehautMiggyX: but you will have a potentially very large post-parallel bottleneck which is going to seriously impede your performance gains
22:53brehautphenom_: the collector runs in its own time
22:53amalloyphenom_: they get gced eventually, but in the meantime you're creating a lot of them. what else can you expect but that they take up space meanwhile?
22:54MiggyXbrehaut: I wouldn't expect it to be that bad. If I slice the CSV file, only a few rows would be affected either side of it... there shouldn't be much left to process after the main chunks I'd have thought
22:54phenom_amalloy, brehaut: but i eventually get an OOM exception :S with -Xmx1G
22:54amalloythen something is wrong; fix it :P
22:55TimMcphenom_: Are you holding onto the head of seq you shouldn't be?