#clojure logs

2011-05-11

01:09RaynesAnybody happen to know if http://github.com/daveray hangs out on IRC and if so, what his nick is?
01:24amalloyRaynes: dunno. he tweets as darevay though
03:20desertRoameranyone here familar with jython? i'm not really python literate, but i am looking at some python code that i'd like to convert into clojure via java, ie jython. is it possible to go back and forth between python and clojure, or should i just learn python and not bother.
03:21shachafdesertRoamer: "convert into clojure"? Jython isn't going to turn Python source into Clojure source.
03:21opqdonut_jython was pretty unmaintained when we used it (it was stuck in python 2.2 when cpython was up to 2.6 or so), so we switched to clojure
03:21opqdonut_I've no idea about it's current state
03:24desertRoamerok, thanks. guess i'll just "bite the python bullet"
03:24opqdonut_I still have no idea why you are talking about python in here
03:25opqdonut_clojure and jython are two separate and unrelated languages for the java virtual machine
03:25opqdonut_and jython is actually an implementation of the language called python, which also has other implementations
03:29desertRoamerright, just curious how seemlessly python and java (or clojure) developers might collaborate on a project, i guess is my larger question
03:30desertRoamersorry, seamlessly, i mean
03:31OlegYch|hif you can call jython from java, you should be able to call it from clojure
03:31OlegYch|hjust that build process becomes complicated
04:08rrc7czyesterday I had a bit of a head scratcher around converting some imperative pseudocode and I was hoping for some thoughts on my solution: https://gist.github.com/964996
04:10rrc7czit came about during the conditional mutation of two variables, with the mutation acting as a dependency for the next conditional mutation of another two variables (when seconds == 60, inc minutes and set seconds = 0, then do the same for minutes)
05:35Vinzenti've a macro which takes 4 args, all tests work fine while the macro is public. then i've added ^{:private true} and called it from the other ns with var-quote #' syntax and it threw Wrong number of args (4). wtf?
05:38Vinzentfrom the ns where macro is declared all ok after making it private. from the tests ns it takes 6 args instead of 4 somehow. Can't understand what i'm doing wrong
05:42raekVinzent: you cannot use that trick for macros
05:43raekwhen you do (#'your-marco ... ) there will not be a macro expansion. instead, it will become a call to the underlying macro function
05:44raekthe underlying function of a macro always take 2 extra arguments compared to the macro
05:45raekVinzent: you could try (def ^{:private true, :macro true} your-macro @#'the.ns/your-macro)
05:45raek(but I haven't tested that)
05:46raekok, you don't need ":private true" here
05:49Vinzentraek, thanks, understood. i'll try def
05:56Vinzentyep, it works perfect. Thanks again!
07:20fliebelI remember someone saying defmethods are namespace local? So if I define a multimethod in ns1, and add a method to it in ns2, but use it in a function in ns1, will the new method be visible?
07:25fliebelApparently they do work across namespaces, yay!
07:26fliebellogs?
07:26clojurebotlogs is http://clojure-log.n01se.net/
07:34raekfliebel: yes, they are meant to work across namespaces
07:35raekin contrast to other "def-" macros, the name symbol can be a fully qualified symbol that identifies a var in another ns
07:35fliebel:)
07:35clgvVinzent: making a macro private and calling it from another namespace sound really odd to me.
07:36raekI assumed it was for unit testing
07:36clgvraek: ah ok. that is the only reason that makes sense, I guess
07:45Leonidashi, I am trying to get a hang with clojure stm, so I thought of building a counter that I increment in parallel from a number of threads. once unsynchronized and once using STM.
07:45Leonidasbut I tried atoms and refs and they both seem to work the same
07:46Leonidaswhen do I use atoms?
07:47Leonidas"""Atoms are an efficient way to represent some state that will never need to be coordinated with any other""" hmm, I think I see
07:47clgvLeonidas: you should use atoms when you have atomar behaviour. refs should be used when you have a transactional context where you need to synchronize the access to a couple of refs
07:47Leonidasbut how do I get an "unguarded" integer?
07:47Leonidasso for my task, an atom would be enough
07:47clgvyes
07:48clgvatoms should be faster as well since they have less overhead. you could measure it for your example
07:49Leonidasok, so much for that.
07:49Leonidasand now the example without STM, how to do that?
07:49LeonidasI want to explicitly allow threads to overwrite the counter
07:50clgvatoms are without STM afaik. refs are clojure constructs that incorparate the STM#
07:53raekLeonidas: one way to emulate unrestricted mutation is to modify the counter like this: (reset! a (inc @a))
07:54raek(it's highly unideomatic to write code like that, but I guess you're already aware of that :) )
07:55Leonidasraek: yes, of course. I just want to demonstrate the problem to people and therefor I need an example that does it "wrong"
07:55Leonidas*therefore
07:55Leonidasraek: is there also a version of reset! for refs?
07:56raekthe code intriduces the race condition you are looking for because the read and the write is not done atomically
07:56raekLeonidas: ref-set
07:56raekLeonidas: but that can't go wrong, since you can only change a ref in a transaction
07:57Leonidasraek: exactly, this is what I want to demonstrate. the stm example on the clojure page is a bit hard to grasp for people who don't know lisp
07:57raekand the transaction makes the read and the write atomic again
07:58Leonidasraek: so I can't create that race condition with refs at all?
07:58raekLeonidas: exactly
07:58Leonidasok, so I'll do the race condition example with atoms
07:58raekthere is something called write scew which can happen, but that is not a race condition IIRC
08:00raekLeonidas: one of the videos here have such an example: http://www.pluralsight-training.net/microsoft/OLT/Course/Toc.aspx?n=clojure-concurrency-tutorial
08:01raek(and yes they're evailable in non-silverlight format too)
08:04LeonidasWill look into this
08:10Leonidasheh, I'm unable to build a race condition :|
08:18clgvLeonidas: but you should be able to build an inconsistent execution. e.g. let each thread increment an int or something like that
08:19Leonidasclgv: yeah, I'm trying.
08:24fliebelWhat? You are trying to *make* a race condition?
08:25clgvfliebel: for demonstration purpose he said ;)
08:25fliebelI missed that...
08:32fliebel&(let [a (atom 0) f #(dotimes [_ 1000] (reset! a (+ @a 1)))] (pcalls f f f f f) (Thread/sleep 100) @a)
08:32sexpbot⟹ 1271
08:32fliebelmeh, that is silly
08:32_fogus_Raynes: I added you as a commiter to Marginalia. You no long need to wait around for me to merge. :-)
08:37fliebel_fogus_: I encountered your SO answer again :) I know more of these now than I knew then. http://stackoverflow.com/questions/3958630/what-are-important-languages-to-learn-to-understand-different-approaches-and-conc
08:39edwIn SLIME, where does *out* go? I'm looking at the terminal where I'm running my swank server, the *slime-events* buffer, and the *slime-repl clojure* buffer, and (println "foobar") doesn't produce any discernable output.
08:44raekedw: I get mine in *slime-repl clojure*, except when I do it from another thread than the repl thread. in that case I get the output in the swank-clojure terminal (*lein-swank* with Durendal)
08:45_fogus_fliebel: Great! There are so many more that I wanted to add, but I didn't want to cross over into the realm of absurdity. :-)
08:46edwraek: Thanks. Hmm.
08:47Fossiqi sounds interesting
08:48raekedw: you can use (intern 'clojure.core '*out* *out*) to use the current *out* in all threads
08:48edwraek: Odd, did a ",disconnect" and then reconnected: all is well.
08:48edw(Right before your message...)
08:50edwOh, wait: I did a (spit *out* <LIST OF LIST OF STRINGS>) and my *out* went away...
08:50fliebel_fogus_: Which ones would you add? AM I in for a dive into obscurity, or just more interesting concepts?
08:52raekedw: maybe spit closes the "file" when it's done
08:52raekedw: you can use pr to print any clojure form to *out*
08:53fliebel_fogus_: Erlang, Haskell, Prolog and Io are all in "seven languages in seven weeks"; I did some Forth on my own.
08:55_fogus_I would add a defunct language like T (among others), probably Eiffel, Delphi, Joy...
08:56_fogus_Pure too
08:59fliebel_fogus_: ghehe, okay. I heard about Joy, Eiffel and Delphi before. Can you program all these languages? I'd love to know why you think these are interesting, but that is probably going to take you some time to explain.
09:00clgvfliebel: I dont think Delphi is really interesting if you have done C++ ;)
09:00fliebelWell, I havn't ;)
09:08clgvI learned programming with pascal & delphi ;)
09:09_fogus_Delphi is especially interesting if you know C++. It's much cleaner in any case.
09:09Leonidasfliebel: that looks nice :)
09:09clgv_fogus_: that's true. but there are no really new concepts ;)
09:16edwraek: I was testing SPIT; yeah, probably closes it. That makes me feel better. "It's not a bug, it's a *feature*."
09:16Fossipfft. who needs delphi when you can have pascal for windows? ;)
09:18Fossimy dad's worst ever investment in my coding skills :D
09:18Leonidasfliebel: stack based languages are fun.
09:19Leonidasfliebel: i played with PostScript, Joy and Factor and the #concatenative channel is cool
09:19fliebelLeonidas: But are they useful as well? I keep hearing complaints about leaving the stack n a weird state
09:19Fossilua metaprogramming is funky, but not too far from 7 language's ruby
09:20Fossiforth is so much fun an an olpc
09:20Leonidasfliebel: well, Postscript certainly is. The point is, once you grasp the combinators you don't need to think so much about the stack.
09:20Fossibecause all the drivers are "natively" written in it
09:20Fossiand you can inspect a whole lot of stuff
09:21Leonidasfliebel: just like in lisp, where once you grasp map and fold, you don't need to implement everything recursively but have higher level abstractions.
09:22fliebelRight, I guess I'll hang around in #concatenative for a bit :)
09:22Leonidasfliebel: and i can highly recommend the factor online help. its a bit like wikipedia, where you click though the defintiontions and start learning a lot fancy tricks.
09:22fliebelyay
09:23Leonidastake a look how 'max' is implemented. i would've used if with 2 clauses, but they do cool stuff, the implementation blew my mind
09:23Leonidasalthough I still don't know why they implemented it this way :>
09:28Leonidasfliebel: strange, when exacuting, I don't get any race condition with your code
09:36bhenryhow can i add a list to the end of a list of lists. cons and conj both go to the beginning on lists
09:37chouserbhenry: it is not possible to efficiently add to the tail of an immutable linked list
09:38bhenrychouser: how much overhead is it to vectorize the list of lists as a vector of lists?
09:39chouserbhenry: you can build a lazy sequence that walks one list and then the other using concat, and then build a new list out of that seq if desired
09:39chouserbhenry: pouring a list of anything into a vector is O(n)
09:39chouserbut then adding a single item to the right-hand-side of that vector is essentially constant time
09:40bhenrythanks
09:50mec Is there a way to do short-circuit permutations? for example if I want to (first (filter #(apply > %) (permutations [1 2 3 4 5]))) even tho the first test is wrong it will stell go thru 12354 12435 12453 12534 12543 etc
09:59chousermec: permutations looks like it returns a lazy seq. I'm not quite sure what you're asking for.
10:00meclike know that (> 1 2) is false, rather than running thru 12345, 12354, 12435... you can skip straight to 21345
10:01chouserohhhh. hm.
10:02bhenrymec is your usage bigger or more complicated than that example?
10:03mecno i think thats a fair simplification
10:05fliebelmec: Have a loot at core.logic, I think that'll be able to do it.
10:09dnolenmec: fliebel: you would probably need to use conda, fliebel has a permo, but yeah that might work, not sure about perf in this case if that matters. seems like another good problem for a fast constraint solver...
10:10fliebeldnolen: :) yea, not sure mine works correctly.
10:10cemerickIs there any canonical discussion for the hinting of arg vectors?
10:11chousercemerick: why read a discussion when you can create a new one? :-D
10:12cemerickchouser: I'm about to, but figured I'd poll the channel for references that might help me avoid sounding like an idiot. :-D
10:14mecfliebel: dnolen: I'm not at all sure how to use core.logic, is there a clojure constraint solver or is that something you have to write specifically per problem?
10:15dnolenmec: you can write logic program to generate the search space and cut of those branches that don't matter.
10:22chouserdnolen: will you be presenting at clojure-conj?
10:22chouserme too
10:22dnolenchouser: I need to submit abstracts :D procrastination ...
10:23fogus`dnolen: I am stoked to hear what you have to say
10:23chouserI'd like to submit some abstracts as well, but I'm really fumbling for good topics
10:24chousermonads? DSLs? lazy seqs in javascript?
10:24fogus`chouser: cinc is still in play
10:24pdkan abstract about your journey to find a good abstract topic
10:24cemerickMy problem is I'm just not 133t enough.
10:24chouserpdk: heh. cute, but so dull! :-)
10:24pdkjust embellish a few parts
10:25pdklike the part where the king sent you to slay
10:25pdkum
10:25pdkstroustrup i guess?
10:25chouserdnolen: I'd love to hear from you about logic programming, esp. related to assertions about clojure code at compile time
10:25fogus`(inc chouser)
10:25sexpbot⟹ 6
10:27dnolenchouser: yeah that's what I'm most excited about anyhow. I would love to see core.logic be fast enough to replace more common operations, but that's a whiles a way (if ever). But I think it's useful for compile time stuff now.
10:27dnolenchouser: whichever talk gets accepted I'll talk about it anyhow :)
10:27chouserdnolen: excellent. But that removes logic programming from my list of potentials to talk about. :-)
10:27dnolenchouser: heh.
10:28dnolenchouser: I only have two talk ideas - predicate dispatch and logic programming.
10:29chouserAh, I'd love to hear about either. Well, both actually.
10:29chouserbut either will do
10:29cemerickThe latter would definitely be a crowd-pleaster.
10:29cemerickpleaser*, that is
10:30chouserfogus`: cinc is still interesting to me. But what is there to talk about?
10:31mefestodnolen: those would be awesome topics :)
10:31mefestoso fwiw (inc)
10:33fogus`chouser: not sure.... I was hoping your talk would enlighten me. :-(
10:35chouserheh
10:35edwIs there a "State of Clojure in Clojure" written somewherw?
10:37edwI mean, anything more than the end of the following slide deck? http://www.slideshare.net/fogus/clojure-11-and-beyond
10:39dnolenmec: your question is interesting to me, I'll try to cook up an example today of a solution.
10:39dnolengotta run.
10:40mecdnolen: cool thanks, im trying to implement it directly with a permutation generator :x
10:40fogus`edw: I don't think so. chouser's blog post is still the go to source for me
10:41chouserthat was written back when rhickey talked to us in here
10:49hugodfor the intrepid, swank-clj 0.1.0 is out - https://github.com/hugoduncan/swank-clj - with slime debugger support
10:59zippy314I'm getting an error I don't understand: "Thrown class java.lang.InstantiationException" in the context of macros. Here's a gist that makes it happen: https://gist.github.com/966613 Can anyone tell me what this means?
11:00zippy314The basic macro works fine, i.e. you can use it create objects by passing in a symbol name or a function.
11:01zippy314The problem is when I use the macro within another macro.
11:11cemerickComments welcome, especially if I'm totally missing the boat somewhere: http://groups.google.com/group/clojure/browse_frm/thread/2b72bd8be27f0f72
11:12xianHello. This might come close to a stupid question, but how do I tell slime that I want square-brackets highlighted when typed in the slime-repl (just like regular parentheses)?
11:12xian(They're highlighted perfectly in clojure-mode, just not in the slime-repl.)
11:12meczippy314: (let [k :test] (make-obj (symbol (str (name k))) :foo)) gives the same exception, so the problem is somewhere in make-obj
11:14chouserzippy314: eval in a macro is messy
11:15mecah of course, eval doesnt have the scope
11:15chouserexactly
11:17zippy314Hmm. So then how does one implement the intent there that a parameter is evaluated in some cases but no in others (i.e. if it's a symbol)
11:20whidden__zippy314: i would split the cases for early evaluation into one pile and those for late evaluation into another pile and if it is appropriate combine at a higher level of abstraction.
11:21whidden__zippy314: How's that for a non-answer? :)
11:21zippy314whidden__: heh
11:23jarpiainzippy314: (let [name (if ... `'~n n)] `{(keyword ~name) ...})
11:25zippy314jarpiain: yah, that makes sense. Thanks.
11:27meczippy314: i think you can just do (defmacro make-obj [n & args] `{(keyword ~n) [~@args]})
11:28mechmm maybe not
12:10dnolencemerick: re: type-hints, I kind of fail to see how it would be possible make it work given Clojure's design.
12:10dnolenwith real type-inference maybe, but that's a big ol' project.
12:11cemerickdnolen: which part, my naive ideal?
12:13dnolencemerick: could be completely wrong of course. I'd brought this up before myself with rhickey as I was suprised that it didn't work the way you're describing.
12:13cemerickI didn't *think* I proposed anything difficult or novel.
12:15cemerickPerhaps return hints really do need to be on arg vectors for fn* to do its work, but fn should be able to lift them from the arity-body parens as needed.
12:16cemerickThe unification of :tag metadata and the prim interfaces seems more like grunt-work and maybe some cat-herding to make sure things are aligned as necessary for tooling purposes.
12:16cemericks/parens/lists
12:22dnolencemerick: fn's only return Object. :tag is just a cast. to do what you propose it means the compiler now has to track all the signatures internally to know which cast to apply in a given situation. but perhaps you're right, just grunt work.
12:23dnolenwell fn's only Object or one of the support prims.
12:24gfrlogdoes it sound correct to say that some functions cannot be made point-free without changing their performance characteristics?
12:25cemerickdnolen: it's already tracking signatures; otherwise, it would have to fall back to reflection for calls to different arities that have different return types
12:25TimMcgfrlog: Have an example in mind?
12:25gfrlogTimMc: yes
12:25cemerickor, I should say, it's tracking signatures thanks to the prim IFn interfaces
12:25gfrlog(fn [x y] (if (< x y) (* x x) (* y y)))
12:26gfrlogTimMc: that might be a bad example actually
12:26dnolencemerick: that's what I said.
12:26dnolencemerick: but a non-primitive type-hint is just a cast, something completely different from a real IFn sig.
12:27gfrlogTimMc: I'm more thinking of (if) expressions and the problem of preventing unnecessary evaluation
12:31cemerickdnolen: True, but those different things are already handled well by the compiler.
12:31TimMcgfrlog: Yeah, the compiler specials might be tricky.
12:31TimMcgfrlog: Might be able to circumvent that with lazy seqs...
12:31gfrlogTimMc: I guess the everything-can-be-done-point-free principle applies to possibility but not performance
12:32gfrlogTimMc: I thought of that too. It might work, but it'd feel hacky
12:32TimMc*point-free* feels hacky
12:34dnolencemerick: what different things are handled well by the compiler? it looks like tags are oriented around exprs, there's no notion of an expression having multiple possible tags based on known primitive types in a context.
12:36dnolencemerick: not saying this work shouldn't be done, but I don't see how it doesn't boil down to type-inference. if it means type-inference does that mean type-inference should be limited to the scope you're suggesting.
12:37cemerickdnolen: :tag metadata and fn class interface implementations; in the example where the var is hinted as ^String but a particular arity is hinted as ^double, there's no reflection at all because the compiler appears to disambiguate return types based on arity without difficulty.
12:38dnolencemerick: it does no such thing. that works because there 300+ interfaces.
12:39cemerickAll I was suggesting is that (a) fn/var metadata should be the canonical source of type information and (b) hinting position should be consistent regardless of category of return type
12:40cemerickdnolen: That's where the compiler is getting the non-:tag return types, but it sure looks like it's disambiguating based on arity.
12:41dnolencemerick: correct me if I'm wrong, prior to primitive support, fns could have only ONE tag.
12:41cemerickTrue.
12:41dnolenregardless of arities.
12:42dnolencemerick: so what you're describing simply is not true of the current compiler behavior.
12:43cemerickdnolen: then I'm confused about this result: https://gist.github.com/a2247da58bf5a971d7e7
12:43mecxian: any luck with your slime repl question so far? I've been trying to figure that one out too
12:46cemerickdnolen: Right — so, you're right, it's not as smart as I thought, but now I don't know what to make of it at all: https://gist.github.com/a2247da58bf5a971d7e7
12:47dnolencemerick: there are no smarts in it *at all*.
12:48cemerickdnolen: Just a pinch, given the reflection warning there -- it's checking the implemented prim interfaces, and would seem to be finding a long return for arity 1.
12:48dnolencemerick: I reiterate, what you want is type inference :) now who's gonna work on that?
12:49cemerickIn any case, how does that impact how return information is represented in the metadata and the syntactic placement of hints?
12:50dnolencemerick: I think you misunderstand how it was before. There was never any return information. fn vars were hinted.
12:50raekxian: mec: I think durendal can do it: durendal-enable-slime-repl-font-lock
12:50hiredmanfrom what I've read it sounds like hm has problems with oop type systems (like the jvms)
12:50mecraek: thanks
12:51raekxian: mec: install it with package.el (M-x package-list-packages, install "durendal")or get it from https://github.com/technomancy/durendal
12:52cemerickdnolen: which trickled down to the metadata of fns themselves
12:53hiredmancemerick: what makes you say that?
12:53dnolencemerick: uh not as far I understand
12:53hiredmanthe compiler grabs the tag from the var
12:54hiredmanin the case of vars
12:54cemerickhiredman: true enough
12:54cemerickhiredman, dnolen: https://gist.github.com/5eb24e0d2b3525b04601
12:55hiredmanthe other case is hints on forms, like ^String (foo 1) which are only used in a local context, does
12:56hiredmancemerick: the arg lists are wrong in the second one, are you sure you are looking at the right thing?
12:57cemerickhrm, that does look wonky
12:59dnolencemerick: in my repl, the fn has no tag information at all, only the var.
12:59hiredmanthere are two type hint paths, type hinting on forms, and type hinting on vars, I imagine defn copies the type hint on to the fn form so that recursive calls via the lexical binding of the fn name have access to the type hint that way
12:59hiredmansinge (defn foo [] ...) expands to something like (def foo (fn foo [] ...))
13:02dnolencemerick: https://gist.github.com/966873
13:03cemerickdnolen: yeah, I'm getting that now too -- but redefining the same var leads to odd results: https://gist.github.com/248246a3ac545a20a7b3
13:03cemerickSpeaking of which, I seem to recall a bug along these lines…
13:04hiredmansomething about copying metadata?
13:06cemerickYeah, IIRC there was some tension around whether the var's info should be dropped or merged -- though I don't ever remember seeing fn values taking on prior var's metadata…
13:12hiredmancould also be something sort of racey, like the fn taks the vars metadata, but does it before the new metadata gets added to the var
13:14dnolencemerick: so to unify tags and primitive type-hints, exprs now might have multiple possible tags which need to be selected based on context. This code will need to account for arity *and* types.
13:16cemerickdnolen: That's more ambitious than I'm proposing -- all I'm saying is that primitive returns should be in var metadata too.
13:16dnolencemerick: what good would that do?
13:17cemerick(and get that meta onto the fn's)
13:18cemerickdnolen: make things simpler for tooling or anyone else that cares about return types at runtime
13:19jarpiaincemerick: the compiler does look at the primitives metadata on (:arglists (meta #'foo))
13:19gfrlogTimMc: I take it back. I think you can do efficient point-free ifs without using laziness
13:21dnolencemerick: ah, so you just want extra information to flow through.
13:21cemerickjarpiain: so it does; I had forgotten that Long. also takes a String in https://gist.github.com/a2247da58bf5a971d7e7
13:22cemerickdnolen: Right, a consistent representation of returns. I especially don't think that anyone should ever have to touch the IFn$XXXX interfaces.
13:23cemerickIt's been suggested that those interfaces could be eliminated entirely and generated as needed, anyway.
13:23cemerick(also eliminating the 4-arg limit)
13:24dnolencemerick: who suggested that?
13:24cemerickdnolen: I don't recall.
13:24hiredmananyone can suggest things
13:25dnolencemerick: what I mean was, did rhickey think that could actually work or some random person :)
13:25hiredmanI might suggest that tomorrow we make the sun orbit the earth
13:25hiredmanseems unlikely
13:25cemerickdnolen: I think this was post-rhickey-in-#clojure :-)
13:26dnolencemerick: well I don't see how that could work.
13:31cemerickdnolen: it doesn't seem entirely absurd. Similar to proxy class generation, perhaps.
13:34fliebeldnolen: Do you know about a levenschtein distance in prolog, minikanren or logos?
13:37dnolenfliebel: none of the above :)
13:38fliebeldnolen: do you think it'd be easy, tasty and short, or just stupid?
13:40dnolenfliebel: what benefit do you see over just doing it in pure Clojure?
13:47xianraek: Thanks a lot.
13:50TimMcgfrlog: Try doing recursive fib or fact in point-free, then.
13:54gfrlogTimMc: that is a terribly good example. I don't have anything at the moment, but hopefully soon.
13:56xianraek: Unfortunately it doesn't quite work. M-x durendal apropos didn't list durendal-enable-slime-repl-font-lock at all. I set it to t anyway in my .emacs, but square brackets are still not highlighted.
13:56xianmec: Have you perhaps had more luck with durendal?
13:57mecxian: havn't tried it yet
14:38raekxian: oh, sorry. looks like that function is not an interactive one. also, the version of durendal that is in the marmalade package.el repo is old and does not have it
14:39raekxian: if you have the most recent version installed, I think you enable it with by having (durendal-enable) in your emacs configuration
14:43raekok, this did not apparently work...
14:48manutterDoes durendal work with emacs 23? I had it enabled but started having weird issues, and just panicked and bailed out.
14:49raekI have used the version from the marmalade repo regularly without weird issues
14:49technomancydurendal needs a hero to champion it
14:50manutterthough in fairness to durendal that could also have been the result of my other clueless attempts to "improve" my .emacs file
14:50technomancyanyone in here named roland?
14:50manutterlol
14:50raekok, it worked. just my "method of installation" that was a bit flawed
14:50manutterraek: what's the marmalade repo?
14:50technomancyoh hey, this guy is: https://github.com/rosado
14:50raekmanutter: a package.el repo, like ELPA
14:51manutterAh, I'm coming from elpa
14:51manuttereh, I'll look it up later, don't have time to mess with it now anywho
14:51manuttertks
14:51raekemacs apparently used the byte-compiled version of the old file, so that's why I didn't see the changes
14:51raekmanutter: http://marmalade-repo.org/
14:51raekfor future reference
14:52manuttercool, I should be able to remember that one. Tks again
14:54gfrlog,((ancestors (class [])) clojure.lang.ISeq)
14:54clojurebotnil
14:56gfrlogI can recur from a multimethod and it will hit up the dispatch function again?
15:02raek(macroexpand-1 '(defmethod foo :bar [x y] (+ x y))) --> (. foo clojure.core/addMethod :bar (clojure.core/fn [x y] (+ x y)))
15:02technomancygfrlog: I don't think so
15:02cemerickgfodor: no, recur's target is always the inner-most function head or loop
15:02raekgfrlog: probably not
15:02jolyhave to look it up via get-method?
15:02gfrlogoh dang
15:03gfrlogit's okay, I don't need tail call anyhow
15:03manutterseems like you could use trampoline for something like that...
15:04gfrlogprolly cood
15:04gfrlogcould
15:04gfrlogman that was a weird mispelling
15:04manutterhey, it rhymes with "good" :)
15:05gfrlogyeah but I don't think I've done that the entire time I've been alive
15:05gfrlogstrange to start now
15:06manutterIPD -- Intermittent Phonetic Dyslexia, the occasional substitution of a spelling that would sound the same. (See: LOLCATS)
15:06gfrlogmaybe it'll happen to me once every few decades
15:07gfrlogs/once/wunse
15:07sexpbot<gfrlog> maybe it'll happen to me wunse every few decades
15:07manutterapparently it gets worse over time...
15:08manutter:)
15:09gfrlogdang gray matter
15:09gfrlogwhy does having a brain have to be so unfathomably strange?
15:14raekanyone know where the magic &env and &form macro parameters are documented?
15:17manutter,(find-doc "&env")
15:17clojurebotnil
15:17manuttereh, worth a try
15:20TimMcraek: What's this now?
15:21_fogus_raek: http://blog.jayfields.com/2011/02/clojure-and.html
15:24raekfogus`away: thanks
15:27TimMcI guess it's not an official feature.
15:29raekfound it here: https://github.com/clojure/clojure/blob/1.2.x/changes.txt
15:30raek"Macros now have access to implicit arguments: * &form - the macro form * &env - the local bindings"
15:34raek(defmacro captor [] `(zipmap '~(keys &env) (list ~@(keys &env))))
15:34raek(let [x 1, y 2] (captor)) --> {x 1, y 2}
15:34raekinteresting...
15:37mechow does (list ~@(keys &env)) produce the values from &env
15:38raekmec: the (let [x 1, y 2] (captor)) call expands into (let [x 1, y 2] (zipmap '(x y) (list x y))
15:38raek)
15:39raekso &env is not used to get the values (they don't exist until the code is evaluated)
15:39mecah i did macroexpand and just got (clojure.core/zipmap (quote nil) (clojure.core/list))
15:40mecwhich now makes sense
16:00markomanhow can I get an unique list of this [{:id 1}{:id 2}{:id 1}] -> [{:id 1}{:id 2}]
16:01amalloy&(map first (vals (group-by :id) [{:id 1}{:id 2}{:id 1}]))
16:01sexpbotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$group-by
16:01markomanmaps has other keywords too but i need to filter by id
16:01amalloy&(map first (vals (group-by :id [{:id 1}{:id 2}{:id 1}])))
16:01sexpbot⟹ ({:id 1} {:id 2})
16:02amalloybut if you need to preserve other keys, your question is not fully-defined
16:02raekmarkoman: what should happen when to maps have the same id?
16:03markomanyes, I need to preserve other keys and any of the maps could be picked, rest just thrown away
16:04amalloythen there you go. my snippet should work fine
16:05raek,(let [ms [{:id 1, :x 1} {:id 2, :x 2}{:id 1, :x 3}]] (->> ms (map (juxt :id identity)) (into {}) (vals)))
16:05clojurebot({:id 1, :x 3} {:id 2, :x 2})
16:08amalloyinteresting take on the problem, but isn't your map/juxt/into just group-by?
16:10raekat least, it does something very similar
16:10markomanyeah, both work, they give different map for :id 1 but it doesnt matter
16:19zippy314newbie q: In this code: (defn- write-json-fancy-type [x #^PrintWriter out] (write-json-string (str x) out)) what does the #^ construct mean in the parameter list?
16:19gfrlogtype hint
16:20zippy314oh!
16:20gfrlogby "hint" I believe we mean that it's not strictly necessary, but it may help optimize
16:20zippy314its a hint for out, I assume.
16:20gfrlogyes
16:20zippy314tx!
16:20gfrlognp
16:20amalloyzippy314: #^ is deprecated now, btw; if you write new code just use ^
16:21gfrloganybody know why this blows the stack? https://gist.github.com/967259
16:22amalloygfrlog: haven't looked yet, but i'ma go with "too much recursion"
16:22amalloyspecifically, "loop/recur on a lazy-seq" is very popular
16:22gfrlogis neither
16:22gfrlogno such thing in the code
16:22amalloyman. if i were the compiler i would crash your computer just to get you to go away
16:23gfrlogah that might be what's happening
16:25gfrlogmaybe if I pay it more...
16:27Mladejgfrlog: Eh, are you really sure it can't be rewritten in more readable way?
16:28gfrlogbut I pretty-printed it!
16:28Mladej:)
16:29TimMcraek: Does that example with "captor" imply one could write a macro that expands differently when run vs. macro-expanded?
16:30raekTimMc: it does indeed imply that the context (which local variables are present) can affect the macro
16:31TimMcThat could make testing of $env-using macros tricky.
16:31TimMc&env, rather
16:31sexpbotjava.lang.Exception: Unable to resolve symbol: env in this context
16:38dnolenany opinions on pattern matching as it exists in Scala for those people that have used it?
16:44MladejI've used pattern matching only in F#, so I don't know how it works in Scala. But try to look at http://www.brool.com/index.php/pattern-matching-in-clojure
16:44Mladejis it what you are trying to find?
16:44hiredmanMladej: dnolen is writing pattern matching, not using it
16:45Mladejaha, sorry
16:45dnolenMladej: yeah I'm more interested in a experience report
16:46dnoleneven better would be someone who understands how it works in SML/OCaml/Haskell
16:46TimMcdnolen: type inference next plz k thx :-P
16:46dnolengfrlog: does Erlang support guards on patterns?
16:47gfrlogdnolen: it's been a while but I'd give that a pretty confident 'yes'
16:47dnolenTimMc: heh that's a big project, hopefully we can drum up some community interest.
16:47gfrlogTimMc: my first hack at the factorial function is blowing the stack for no apparent reason
16:48TimMcdnolen: Where community == people who can hammer on clojure itself?
16:49dnolenTimMc: Clojure compiler foo not necessary as far as I can tell, familiarity with logic programming, constraint programming very useful.
16:49dnolens/foo/fu
16:49sexpbot<dnolen> TimMc: Clojure compiler fu not necessary as far as I can tell, familiarity with logic programming, constraint programming very useful.
16:51dnolengfrlog: ah yes, Erlang has pattern guards.
16:53gfrlogdnolen: most of my hesitation was not knowing if "guard" meant something different in the other languages
16:53dnolengfrlog: yeah it's just a test to be run after the pattern match initially succeeds.
16:59gfrlogdoes it make sense for one of my tests to throw a stack overflow error, yet the stack trace shows no user code at all? (not even clojure.test)
17:00pdkstack traces tend to get absurdly long with clojure core calls
17:01gfrlogyes I don't mind that it's long. I mind that I can't tell where it came from.
17:04dnolendamn I'm wondering if I'm wandering down a rats nest here, http://scala-programming-language.1934581.n4.nabble.com/Possible-scala-partial-function-pattern-matching-bug-td3029632.html#none
17:04dnolenone dude works on the Scala pattern matcher, no ones ever tried to help him w/ patches to the pattern matcher.
17:04hiredmanwell, it is scala
17:06dnolenhiredman: possibly, understanding efficient pattern matching is not hard, but it does require reading some esoteric papers to see how it's done. w/o prior context I imagine deciphering a pattern matching code base would be quite difficult.
17:07hiredmandnolen: sure, and the scala language is complex as it is
17:11gfrlogTimMc: nevermind, doesn't work.
17:20markomanhmh.. im pulling data from database by search criterias and I need to filter result. I got help already to get unique items only, but my next problem is to find items, that are available on all sets (and clause)
17:21gfrlogmarkoman: can you give an example of the data you have and what you want to do with it?
17:21raekmarkoman: can't you solve the uniqueness problem in the database query?
17:22markoman[[{:id 1}{:id 2}{:id 3}] [{:id 1}{:id 2}{:id 4}] [{:id 1}{:id 2}{:id 3}]] -> [{:id 1}{:id 2}]
17:23markomanim using google datastore, that doenst allow to bind tables in a way sql does, so this needs to be done programic way
17:24gfrlogmarkoman: you could create sets with those, so you would have [#{1 2 3} #{1 2 4} #{1 2 3}]
17:24gfrlogthen you could take the union of the sets
17:24gfrlog,(reduce clojure.set/union [#{1 2 3} #{1 2 4} #{1 2 3}])
17:24clojurebot#{1 2 3 4}
17:24markomanoh, I still need to preserve the content of maps
17:24gfrlogwait
17:24gfrlogintersection I mean
17:25gfrlogI always get that backwards
17:25gfrlogmarkoman: is the content of one {:id 1} the same as the other {:id 1}?
17:29markomanhmh, let me think a bit
17:33markomanthis is a bit more complicated I guess
17:33gfrlog:)
17:37markomanI need to make a pastebin, hard to explain here on one line
17:43markomanhttp://pastebin.com/hzgiAgQt this could give better idea of the problem
17:45markomanso :id I told earlier is same as :parent
17:47gfrlogmarkoman: these are some kind of java objects?
17:47TimMcgfrlog: No luck on pointless fact?
17:47gfrlogTimMc: funny you say that, I just succeeded a second ago; trying to make a pastie now
17:48gfrlogif I can figure out why (with-out-writer) doesn't exist
17:48gfrlogI just wanna call (pprint) and have it go to a file...
17:49markomanthese are entities from datastore. types I guess
17:49raekgfrlog: use binding: (binding [*out* some-print-writer] ...)
17:50gfrlograek: I just found it in c.c.duck-streams, which is faster than thinking about how to get a print-writer for a file
17:50gfrlogthis is repl code, so I don't need it to be good, just effective :)
17:50raekgfrlog: use clojure.java.io instead.
17:51raek(binding [*out* (PrintWriter. (io/writer ...))] ...)
17:51gfrlograek: next time, next time...
17:51raekmost functions of duck-streams have been transfered to clojure.java.io
17:52markomanbut it simplifies to the next form I think: [[#<Key Form("form5")/SavedForm(130)>, #<Key Form("form5")/SavedForm(131)>] [#<Key Form("form5")/SavedForm(130)>] [#<Key Form("form5")/SavedForm(130)>]] -> [['a 'b] ['a] ['a]] -> ['a]
17:52raeksome even to clojure.core
17:52markomanand if [['a 'b] ['a] ['c]] -> []
17:52gfrlogTimMc: https://gist.github.com/967464
17:53gfrlogI even did it in under 250 lines :)
17:53gfrlogmarkoman: so in the case of the symbols, you can go back to the set intersection idea
17:54gfrlog,(let [xs [['a 'b] ['a] ['a]]] (->> xs (map set) (reduce clojure.set/intersection)))
17:54clojurebot#{a}
17:54gfrlogTimMc: next is to make it a little smaller maybe
17:55TimMcCan you paste your point-ful original as well?
17:55gfrlogyep one sec
17:56markoman,(reduce clojure.set/intersection [#{'a 'b} #{'a} #{'c}])
17:56clojurebot#{}
17:57gfrlogTimMc: I added it as a comment on the gist
17:58markomanhow do you turn result back to list , with (into [] #{'a}) ?
17:58gfrlogmarkoman: that could work, although most of the time a set will work just as well
17:58raekmarkoman: [] means vector, () means sequence or list
17:59gfrlogclojure: I still can't decide if it's confusing or not
17:59TheMoonMastergfrlog: It is
17:59gfrlogah, good to know
17:59raekall clojure's sequence functions (e.g. filter, map, ...) will call (seq ...) on the argument, so pouring the result into another data structure is often not needed
18:00raek...unless you want to use one of its features, like constant time random access for vectors or constant time membership test for sets
18:00gfrlogTimMc: this could be the beginnings of a code obfuscation library
18:01markomanI see. I may have tried to get vectors unnecessarily. and I think problem solved easily at the end, thanks
18:08markomanoh, one more thing, how do you make a set from this: [[{:id 1}{:id 2}{:id 3}] [{:id 1}{:id 2}{:id 4}] [{:id 1}{:id 2}{:id 3}]] ?
18:08markoman-> [#{1 2 3} #{1 2 4} #{1 2 3}]
18:08gfrlogwelp...
18:09gfrlog(for [rec-vector [.....]] (->> rec-vector (map :id) (set)))
18:09gfrlogI think that should work
18:10amalloygfrlog: ##(set [1 2 3])
18:10sexpbot⟹ #{1 2 3}
18:10amalloydang it. okay, you're right
18:10gfrlogamalloy: HA
18:10amalloyi always forget which functions return #{1 2 3} and which return #{[1 2 3]}
18:10gfrlog$findfn 1 2 3 #{1 2 3}
18:10sexpbot[clojure.core/hash-set clojure.core/sorted-set]
18:10gfrlogah that one
18:10amalloyyeah, i know
18:10gfrlogI was about to question if anything did that
18:10gfrlogcause I've never used it
18:11gfrlogbut probably could have
18:11amalloywhich makes it hard to turn something into a sorted-set. you have to go like ##(into (sorted-set) [2 5 7 12 50])
18:11sexpbot⟹ #{2 5 7 12 50}
18:11gfrlogamalloy: do you use sorted sets often?
18:11amalloyno
18:13gfrlogamalloy: I guess that's the advantage to only knowing one of the two versions -- I was sure of what it did :)
18:14markoman,(reduce clojure.set/intersection (for [rec-vector [[{:id 1}{:id 2}{:id 3}] [{:id 1}{:id 2}{:id 4}] [{:id 1}{:id 2}{:id 3}]]] (->> rec-vector (map :id) (set))))
18:14clojurebot#{1 2}
18:15markomanI think it works :) thanks
18:15gfrlogwoohoo
19:14TimMcgfrlog: OK, so you're doing explicit recursion.
19:15TimMc(re: the fact gist comment)
19:42gfrlogTimMc: if that's what you call explicit...
19:42gfrlogI would call that "indirect", but I'm not in charge of words
19:46pdkokay stab in the dark here
19:46pdkbut is anyone here familiar with imap
19:47gfrlogthat is like a normal map function but made by apple?
19:47pdksigh
19:47pdkthe email protocol :p
19:48pdktl;dr trying to figure out if an imap search query i'm trying to write is valid since the server isn't taking it
19:54TimMcgfrlog: "indirect"... yes, that's the word
19:54TimMc"explicit" is ambiguous
19:55gfrlogTimMc: for normal recursion you would say "direct"?
20:13TimMcI suppose so.
20:13TimMcOr just "recursion".
20:22amalloyfor normal recursion i would say "yes please"
21:28technomancyso has anyone used jgit?
21:28technomancyis there a version of it that doesn't return nil for every operation?
21:28technomancybecause that would be super.
21:29alandiperttechnomancy: folks are still catching on to the whole expression vs. statement thing :(
21:30ChristianMarksNoob with paste here: http://paste.lisp.org/+2M3K
21:31technomancyalandipert: heh... if only
21:31technomancythis actually claims that every repository simply has no commits in it.
21:32ChristianMarksI know neither Java nor Clojure, but decided to learn both by translating the abysmal button demo from Java to Clojure, and learn Leiningen while doing it. I suppose the connoisseurs frown on such undertakings.
21:33alandipertChristianMarks: not at all, i admire your tenacity
21:33ChristianMarksIt took me a couple days.
21:34ChristianMarksThe paste at http://paste.lisp.org/+2M3K can be mercilessly criticized.
21:37alandipertChristianMarks: no need for (if (nil? x) ..., can just be (if x .. and then swap your then/else forms
21:37ChristianMarksAh -- evidence of non-functional noobery right there, thanks.
21:39tomojCamelCase is unpopular
21:39tomoje.g. create-image-icon and img-url would be more common
21:39alandipertChristianMarks: which language are you coming from?
21:40TheBusbyHmm, (read-lines "1GB_file.tsv") is initially consuming 2+GB of memory. Is that a big red flag here?
21:40tomojlooks like you're calling the result of the System/err println
21:41ChristianMarksI've toyed with common lisp and Haskell. Mostly python, C, C++ various scripting languages.
21:41ChristianMarksOCaml
21:41tomojSystem/err doesn't have a println anyway, does it?
21:42ChristianMarksDon't know. The point is I don't know Java or Clojure. This is the result.
21:43tomojseems (clojure.contrib.io/with-out-writer System/err (println "foo")) works, but ugh
21:44gfrlogthat is strange isn't it?
21:44gfrlogmaybe they stopped once they got the Hello World bootstrapped
21:44ChristianMarksThere is a System.err.printlin
21:45tomojah, yes
21:45tomojI was trying to use it like the println function
21:45gfrlogmaybe they kept going once they got the Hello World bootstrapped
21:45tomojso the . special form is unpopular as well
21:46tomojprefer (.println System/err "foo") to (. System/err (println "foo"))
21:46ChristianMarksOK, I'll make the requisite changes.
21:46tomojespecially unpopular are lonely parens :D
21:46gfrlog,(println ())
21:46clojurebot()
21:47ChristianMarksThis will elevate my status from low-grade moron to imbecile. Thank you.
21:48tomojimo that you're here means you're probably quite a ways beyond those :)
21:49tomojthis is not really a criticism, but it is common to use _ for a binding when you ignore it, like (fn [_] ..) for event handlers that ignore the event
21:49tomoj(fn [e] ..) is fine too I'd say, though
21:49gfrlog,((fn [_ _] (+ _ _)) 3 4)
21:49clojurebot8
21:49ChristianMarksOK
21:50ChristianMarksThat's a common convention in functional programming
21:51ChristianMarksI think the clojure version is better--warts and all--than the Java original
21:53alandipertgfrlog: that is a bit of a mind bender
21:53tomojinitialize-buttons semantics seems kind of unclojurey, but it's java so..
21:54gfrlogalandipert: the bindings are done in order, so the second overrides the first
21:54tomoj(I don't mean the way its code looks, I mean the way it side-effects on its arguments instead of taking some data and returning buttons)
21:56ChristianMarksYou're right.
21:56ChristianMarksMaybe I should stick with Standard ML
21:56tomojbut the stuff it actually does is so arbitrary that any way you write it its gonna look funny I think
21:57ChristianMarksThat's Java for you: anti-modular and anti-parallel
21:58amalloysomeone commented already on the use of (nil?), but the ((....)) after it looks way wrong
21:58alandipertChristianMarks: stuart sierra has a series of posts on his blog about clojure + swing, and using macros to alleviate pain... have you run into them?
21:59ChristianMarksA few of them.
21:59ChristianMarksThe code shows that they haven't completely penetrated my skull.
21:59amalloyChristianMarks: if-let will make you happy
22:00amalloy(if-let [img-url (...)] (ImageIcon. img-url) (.println System/err ...))
22:00ChristianMarksThat's cool
22:00gfrlogthere's a convenience function for just about everything except checking if an item is in a collection
22:01amalloyi'm not sure what your intent was with the ((. construct, but it's definitely wrong. if you can tell me what you meant it to do, i may have a suggestion
22:01ChristianMarksI can see that if-let is superior
22:01ChristianMarksThe supernumerary parentheses?
22:01amalloyyes
22:02amalloysee also the ##(doc doto) macro, which is CRAZY AWESOME for interop
22:02sexpbot⟹ "Macro ([x & forms]); Evaluates x then calls all of the methods and functions with the value of x supplied at the front of the given arguments. The forms are evaluated in order. Returns x. (doto (new java.util.HashMap) (.put \"a\" 1) (.put \"b\" 2))"
22:02ChristianMarksThey should be removed
22:02amalloy&(macroexpand '(doto b1 (.setText blah) (.setSize bar)))
22:02sexpbot⟹ (let* [G__11708 b1] (.setText G__11708 blah) (.setSize G__11708 bar) G__11708)
22:02ChristianMarksI'm using doto
22:03amalloyoh you are, in -main
22:03amalloyuse it in initialize-buttons too :P
22:03amalloygfrlog: big fan of the passive voice?
22:03TheBusbyI apologize for interupting, but I can't seem to load a 1GB TSV file into a repl with 8GB of heap. Any pointers to blogs/etc for handling data and memory?
22:04amalloyTheBusby: do it lazily? don't try to load it all at once
22:05TheBusbyamalloy: unfortunately I need the entire data set available
22:05amalloythen uh. don't load all the *text* at once. build up a data structure as you parse it?
22:05amalloyif you need all the data at once, and all the data doesn't fit in memory, not a lot you can do
22:05TheBusbyhere is what I'm doing now that doesn't work, http://pastie.org/1891378
22:06TheBusby1GB < 8GB
22:06gfrlogamalloy: who have strunk and white been thought that they are anyhow?
22:07amalloyTheBusby: don't use read-lines
22:07amalloyline-seq
22:07amalloynot that this will really help, probably
22:07TheBusbyI should use line-seq, or avoid read-lines because it uses line-seq?
22:08amalloyuse line-seq
22:08amalloyi forget what the deal is with read-lines but it's deprecated
22:08TheBusbyk, thanks. I checked readlines and it appears to be consuming about 2.2GB of RAM to load the 1GB file.
22:09gfrloggotta have one byte for the char and 8 bytes to point to it
22:09TheBusbyif that was the only consumer if memory I could deal with it, but the parsing or storage is blowing that up quite a bit
22:09amalloyTheBusby: re-split is probably causing your problem
22:10amalloymaybe
22:10TheBusbyk, can check that
22:10amalloyit is probably doubling memory consumption
22:10TheBusbyah, yeah that did it
22:11amalloyi'd also verify that your repl *actually* has 8gb of memory
22:11TheBusbysince it's hard to determine memory used by the JVM
22:11TheBusbyI've been changing the max heap size, and if the process dies due to GC I'm just figuring it is out of mem
22:12TheBusbyEverything works fine with 16GB heap, but dies at less than 8GB
22:12amalloyand put some doalls in front of parse-line and/or map, perhaps, since i can imagine it's keeping everything in memory twice
22:12TheBusbywhat do you mean?
22:13amalloyTheBusby: (zipmap fields (parse-line %)) is going to return a map whose values are all lazy-seqs closing around the original input data
22:14TheBusbyahh
22:14TheBusbygreat catch, thank you for pointing that out
22:15amalloyhow many columns are in each row of the tsv?
22:15TheBusbylooking at 20-30
22:16TheBusbythough I'd like to use this function with up to 200 or so... :)
22:17amalloyi mean, you're storing a shedload of duplicated header data in each item
22:17amalloygotta be like half a kilobyte spent on pointers and trees and stuff to make the map of keywords to data
22:17TheBusbywas wondering about that, was hoping keys resolved to something smaller
22:18amalloyTheBusby: the keywords themselves will be tiny. just a pointer
22:18TheBusbya 64bit pointer is much larger than an 8bit ID though...
22:18amalloybut a pointer is eight bytes, and you have twenty of them, and they have to fit into a tree structure...
22:18TheBusbyso worth making a customer structure then I guess
22:18amalloynot necessarily!
22:19amalloyseems much nicer to return (a) a seq of seqs and (b) a function for looking up some field in a column-seq
22:19TheBusbyI love the fact you can do (map :key data) you see
22:19TheBusbyamalloy: that's what my first thought was
22:20TheBusbyjust use the header to determine the offset in each line
22:20amalloyright
22:20TheBusbywould need to do something like (foo key data) to get at the data, but that's not bad either
22:21amalloyif you wanted you could (let [get-foo (partial lookup-fn :foo)] (get-foo data-item))
22:22amalloyor, perhaps better, have (lookup-fn :foo) return #(nth % 10)
22:22TheBusbyoh, that's a great idea
22:23TheBusbywill give that a try and see what memory consumption looks like. Thank you *very* much!
22:23amalloynothing you can't solve with another level of indirection
22:23TheBusbyEr, I wouldn't say that in regarding memory consumption though. ;) Not unless you're counting JNI
22:24amalloyhey, it worked here. we added a level of indirection to the lookup function, and in return saved a bunch of memory on the data structures
22:24TheBusbyExcellent point
22:29ChristianMarksI believe I have taken all of your suggested revisions (at least those I was able to absorb): http://paste.lisp.org/+2M3K/1
22:29TheBusbyJust FYI, read-lines and (line-seq (reader)) show the same memory usage
22:30amalloyTheBusby: indeed. but line-seq is less broken in other ways
22:31amalloyChristianMarks: lookin' pretty good, there. the tabs under the if-let are a bit weird given you've indented everything else with spaces
22:32ChristianMarksHairy arm principle
22:32TheBusbyamalloy: thanks again for the tip ;)
22:33TheBusbyamalloy: any tips on what I should be looking for to replace re-split?
22:34amalloyTheBusby: not really. there's re-seq, but it will have similar issues
22:35TheBusbyI vaguely remember java having memory problems with other string operations. Is it work falling back to java.lang.String or something else?
22:35ChristianMarksthe add-action-listener functions could be cleaned up with another function to set the booleans in order
22:35ChristianMarksBut it's still imperative code
22:37ChristianMarksI could nest defns I believe, so that I could use the closure provided by the outer defn...
22:37amalloyChristianMarks: you might like some of the changes at https://gist.github.com/967834
22:37amalloyor you might not; sorta a style thing
22:38amalloyerrrr, and the doseq should be OUTside of the let-bindings area. i was improvising a bit
22:38datkadoes aleph work with clojure 1.3?
22:39ChristianMarksamalloy: that's great. Intuitively obvious.
22:39datkaI'm thinking about switching my app over
22:39ChristianMarksSame thing for setting the button booleans
22:39amalloyif you adjust initialize-buttons to take an array of buttons, you can even replace [b1 b2 b3 :as buttons] with just buttons
22:40technomancyso good: http://memegenerator.net/instance/7741684
22:40amalloytechnomancy: haha that kills me
22:41technomancyamalloy: yeah, ztellman's beard is getting pretty distinguished
22:42amalloyi guess i'm glad i don't depend on his libs, then?
22:42tomojdatka: tests fail
22:42tomojappears potemkin is broken
22:43tomoj(at least)
22:44datkaok, then that would explain what I'm seeing
22:44datkaI've never been a big fan of the immegrate-like functionality
22:46tomojI patched it to not fuck up M-. and try to pretend it's not there :/
22:53amalloyChristianMarks: you might (defn enable [b] (.setEnabled b true)) and similarly for disable
22:54ChristianMarksThat's better than (for [[button flag] button-flags (,setEnabled button flag)) ...?
22:54ChristianMarksI meant . not ,
22:54ChristianMarksno macro intended
22:55amalloyup to you
22:55ChristianMarksleft out ] after button-flags too
22:55ChristianMarksEarly onset senility
22:55ChristianMarksI liked the destructuring bind
22:55amalloygo for it
22:55amalloybut save yourself, use doseq instead of for
22:55amalloyfor would make you cry
22:56amalloy&(let [s (range 5)] (for [x s] (println x)) 'done)
22:56sexpbot⟹ done
22:56amalloy&(let [s (range 5)] (doseq [x s] (println x)) 'done)
22:56sexpbot⟹ 0 1 2 3 4 done
22:58ChristianMarksyou can use a destructuring bind within the doseq...
22:58amalloydoseq and for have identical syntax
22:58ChristianMarksOK
22:58amalloybut for is lazy and returns a result, while doseq is eager and returns nil
22:59ChristianMarksI prefer eager functions (lazyness leads to monadification, which tends to make functional programs look imperative)
22:59amalloy&(doseq [[a b] (partition 2 1 (range 5))] (println a b))
22:59sexpbot⟹ 0 1 1 2 2 3 3 4 nil
22:59tomojwhat is monadification?
22:59amalloytomoj: an irrational fear, it sounds like. but we'll give him a little wiggle room; he's new to laziness
22:59dnolenChristianMarks: laziness in Clojure is not like in Haskell. laziness in Clojure means lazy sequences
23:00ChristianMarksOK
23:00tomojamalloy: adrenaline rush when I read it.. :)
23:00amalloyhahaha
23:00dnolen,(map inc [1 2 3 4 5])
23:00clojurebot(2 3 4 5 6)
23:00dnolenChristianMarks: ^ no fearsome monadification going on here ;)
23:01ChristianMarksGood. Robert Harper wrote a post on that on Existential Type
23:01amalloyi <3 (partition 2 1 ...)
23:01dnolenChristianMarks: I like his posts thohis SML fanboyism is quite plain, I like SML a lot too.
23:02dnolenat least Haskell is evolving at a clip, can't say that much about SML.
23:03ChristianMarksI'm buying his fanboyism. He's a good type theorist. Anyone who follows Voevodsky on homotopy type theory can't be completely mistaken...
23:03tomojhmm
23:04dnolenChristianMarks: but he's no Simon Peyton Jones, who is a great hacker. You need both kinds of thinking in this game.
23:06tomojseems (partition 2 1 x) is 2-3x slower than (map .. x (next x))
23:06tomojbut that probably hardly ever matters
23:07ChristianMarksLook, I use xmonad myself. I agree with you, actually. I'd like to see how far Harper's ideas go. He says Haskell's type system is fundamentally broken.
23:08dnolenChristianMarks: type systems are fundamentally broken according to Alan Kay. The truth is probably somewhere between these viewpoints.
23:09amalloytomoj: well, partition is allocating new structures
23:09dnolenChristianMarks: but perhaps you'd like to help a implement a type system / inferencer for Clojure - hint hint nudge nudge
23:09ChristianMarksNot a bad idea
23:10tomojamalloy: I tried + and list in the map
23:10tomoj+ seemed unfair to map but it was probably unfair to partition, yeah
23:10dnolenChristianMarks: I've been thinking about it a lot, there's definitely interest from the core team - a la carte type systems.
23:11amalloyi much prefer the flexibility it gives me, though; destructure the result in a for/doseq instead of creating a new function for use with map, for example
23:11tomojwell, you can destructure (map list c (next c)) the same way, right? but it's definitely uglier
23:12amalloy&(time (dorun (partition 2 1 (range 1e6))))
23:12ChristianMarksI'm in the middle of some NSF grant proposals (completely different area: environmental science) but after I could check in again
23:12sexpbot⟹ "Elapsed time: 3209.967174 msecs" nil
23:12ChristianMarks(took a break to have my novice code exposed)
23:12amalloy&(time (dorun (apply map list ((juxt identity rest) (range 1e6)))))
23:12sexpbot⟹ "Elapsed time: 1123.962417 msecs" nil
23:13amalloyi *also* love (juxt identity foo)
23:13dnolenChristianMarks: cool, I'll be here trying to convince unsuspecting newbies to build type inferencing for Clojure.
23:14amalloy~source partition
23:15tomojI think more interesting questions about partition's performance arise with different values for n and step
23:15arohnercan swank-cdt pause the process and just print the current stack?
23:15ChristianMarksIt's a great idea really, because you could use the type inference engine to perform access control, contain side effects...
23:16tomojthough maybe the tests I remember running weren't actually testing partition's performance, I think I was dorunning the whole thing and each partition, which automatically is at least O(n*(count coll)) with step=1 (?)
23:16amalloytomoj: from the source it looks like partition is already dorunning the partitions
23:17amalloy(= n (count p))
23:18tomojI think that is ok
23:18tomojfor some reason it scared me
23:19dnolenChristianMarks: yes, a lot of cool things could fall out of it. It could also potentially be more powerful and certainly easier to extend / experiment w/ since it's not hard coded into Clojure itself as most type systems are.
23:20ChristianMarksExactly. It's a great idea.
23:22ChristianMarksDo you plan on modifying the reader (whatever correspond to the lisp function...)
23:23amalloyChristianMarks: the clojure reader isn't very extensible, so that wouldn't work well with the plan of experimenting
23:24dnolenChristianMarks: no, the missing bit is a hook to the compiler, would need to start a discussion as to what that hook would be.
23:24ChristianMarksOK -- could lead to horrendous code if it were
23:27ChristianMarksI agree with that approach. I wanted to implement justification logic in clojure -- kind of on hold now.
23:28ChristianMarksI have to split
23:28ChristianMarksThanks for the advice ... invaluable.
23:47sorenmacbethI wonder if anyone might be able to help me with a problem
23:47sorenmacbethI have a seq like so: ("7" "7 elements" "7 elements landing" "7 elements landing page" "add")
23:48sorenmacbethI want to collapse it such that if the first string is contained within the second string, remove it
23:48sorenmacbethand so on down the seq
23:49sorenmacbethso in my example, I'd want to end up with ("7 elements landing page" "add")