2009-11-17
| 00:00 | jkkramer | i did add this to my emacs config a while back, maybe related? (define-key global-map (kbd "RET") 'newline-and-indent) |
| 00:00 | hiredman | declare just lets you defn functions that reference vars that are not defined yet |
| 00:00 | technomancy | jkkramer: the minibuffer has its own keymap; it shouldn't be affected |
| 00:00 | Draggor | hiredman: Is there any way to get around this? I greatly dislike the idea of having to procedurally define things |
| 00:00 | slyrus | technomancy: what was that we were saying about how awesome these magic download-and-install-package-manager-thingys are? :) |
| 00:01 | jkkramer | the only place i have swank-clojure installed is in ~/Library/clojure/swank-clojure |
| 00:01 | technomancy | slyrus: heh; yeah M-x clojure-install was always an interim solution until I could get elpa working. |
| 00:01 | hiredman | Draggor: I have no idea what "procedurally define things" means |
| 00:03 | arohner_ | Draggor: the var must be declared before it can be referenced when compiling. At runtime, the var must have a value when it is referenced or you get a unbound var exception |
| 00:03 | arohner_ | if you don't want it to have a value, set it to nil |
| 00:04 | jkkramer | even with minor obstacles, clojure-mode made my life a lot easier. none of the other IDE/editor solutions i've tried were as good |
| 00:05 | jkkramer | although, now it's harder to poke fun at emacs users, since i am one now |
| 00:05 | arohner_ | following your earlier example, something is calling (func1 some-arg) before it has a value. that can't work in any sane PL |
| 00:07 | slyrus | jkkramer: i'm so far gone that I have a hard time imagining that folks would consider using anything else (except climacs, of course... :) ) |
| 00:07 | slyrus | I assume most emacs users here use paredit? |
| 00:08 | jkkramer | i still hit ESC whenever i intend to invoke some command |
| 00:10 | technomancy | paredit is bliss. |
| 00:10 | jkkramer | i installed paredit but have no idea how to use it |
| 00:11 | technomancy | jkkramer: http://p.hagelb.org/paredit-outline |
| 00:11 | technomancy | one day that will become a screencast... not sure when. =) |
| 00:11 | jkkramer | ooo |
| 00:12 | jkkramer | that's what i've been looking for. quick-start guide |
| 00:12 | jkkramer | you are awesome |
| 00:12 | lgas | technomancy: re. the clojure wide-finder from your blog, this version gets the time down to about ~2.7 seconds (from ~272) on the same input file I posted to your blog about: http://pastie.org/702158 |
| 00:12 | lgas | it still doesn't really peg my CPUs during that 2.7 seconds though |
| 00:13 | technomancy | lgas: wow! so partitioning inside the pmap makes a pretty big difference? |
| 00:14 | lgas | yeah... otherwise I guess the unit of work that each thread is doing is too small. |
| 00:15 | lgas | I don't have time tonight but I'm going to try to pull down some larger logs and try processing them (and also changing the regex so that it matches more of our URLs). |
| 00:15 | technomancy | yeah, I realized the original regex was more complicated |
| 00:15 | technomancy | also: it's hard to find sample log files! |
| 00:18 | lgas | Yeah. We have some decently sized log files, but I can't give them out unfortunately. The one I've been testing with is 1.1m lines. But out of that 1.1m lines it only produces 48 matching URLs and of those a couple occur 4 times, a couple 3, a couple 2, and most just once, so it may not be the best test. |
| 00:23 | Drakeson | is slime trunk still broken with clojure ? |
| 00:24 | Drakeson | (it broke for me around Oct 30) |
| 00:24 | technomancy | yep |
| 00:24 | slyrus | I'd put it differently. swank-clojure is broken wrt slime HEAD |
| 00:24 | slyrus | the offending commit is: addc5be70a489cdc8ed555a2fed7273040da196e |
| 00:24 | slyrus | before that you should be ok |
| 00:24 | technomancy | is it un-idiomatic to use doto in non-java contexts? |
| 00:25 | slyrus | (not to blame swank-clojure, as this clearly seems to be changes in slime that broke swank-clojure) |
| 00:25 | technomancy | Drakeson: if you must work from git, use the technomancy fork of slime on github; else use elpa |
| 00:25 | technomancy | (I haven't fixed it, I just haven't updated it with the breaking change yet) |
| 00:25 | hiredman | technomancy: I think it must be |
| 00:26 | arohner_ | technomancy: yeah, I'd like to see an example of that |
| 00:26 | slyrus | Drakeson: or, for a second opinion, just make sure you checkout the version right before addc5be70a489cdc8ed555a2fed7273040da196e :) |
| 00:26 | arohner_ | I've never needed to outside of java-interop |
| 00:26 | technomancy | hiredman: I like (doto (str (:root project) "/Manifest.txt") (spit (str "Main-Class: " (:main project)))) much better than the let-using equivalent |
| 00:27 | technomancy | but it reads a little funkily |
| 00:27 | hiredman | I see |
| 00:27 | technomancy | (apart from the fact that it's squashed onto one line) |
| 00:28 | arohner_ | where is let-using? |
| 00:29 | qed | http://clojure.pastebin.com/m1c41118e -- could someone tell me why im getting an error that says recur is missing args? |
| 00:29 | hiredman | arohner_: it would be (let [x (str (:root project) "/Manifest.txt")] (spit x (str "Main-Class: " (:main project))) x) |
| 00:29 | technomancy | arohner_: left as an exercise to the reader =) |
| 00:29 | arohner_ | oh, I thought there was an actual function named 'let-using' |
| 00:30 | hiredman | I have a marvelous example that this terminal is too narrow to contain |
| 00:30 | _ato | qed: you're calling recur with 2 args while your loop has 6 bindings |
| 00:30 | technomancy | hiredman: that trailing x bugs me |
| 00:30 | qed | _ato: hmm i thought i had this loop/recur stuff figured out |
| 00:30 | hiredman | technomancy: I as well |
| 00:30 | Drakeson | slyrus: I have been doing that ever since it broke |
| 00:31 | qed | _ato: do i have to do something to those args in recur? |
| 00:31 | qed | could they just be empty lists? |
| 00:31 | Drakeson | technomancy: well, the rate of changes in slime trunk is fairly high. I would rather stick to a fork of swank-clojure |
| 00:32 | _ato | qed: they could be... then v2 v3 etc are going to be assigned to empty lists? is that what you want? |
| 00:32 | qed | no, i just want to run x2->x6 on every inc of cnt |
| 00:32 | Drakeson | but again, I haven't look into what actually broke between the two, so I don't know if slime is going in the wrong direction (to deserve a fork) or swank-clojure should just keep up with slime's changes. |
| 00:33 | technomancy | Drakeson: I don't mean "fork" in the negative sense, merely the "I've branched and haven't bothered to update" sense |
| 00:34 | Drakeson | oh, I made my "update-clojure" script to use a specific commit for slime since then |
| 00:35 | _ato | qed: ah, move all the v2 v3 v4 etc into a let-binding inside the loop then |
| 00:36 | Drakeson | btw, will it make sense to have swank-clojure be merged into upstream slime (as there is ruby, etc. backends for slime) |
| 00:36 | qed | _ato: before or after the loop's binding? |
| 00:36 | _ato | the bindings on loop should just be the ones you want recur to assign to |
| 00:36 | qed | is the let-binding part of the body of the loop |
| 00:36 | hiredman | http://gist.github.com/236676 <-- with-open? we don't need no stink'n with-open |
| 00:37 | _ato | qed: lets try this again: http://etherpad.com/XIbR7KzRQl |
| 00:38 | arohner_ | hiredman: what about exceptions? |
| 00:39 | hiredman | arohner_: I'm not exceptional |
| 00:51 | qed | :) |
| 00:59 | st3fan | i'm doing a clojure talk here in toronto on thursday |
| 01:01 | st3fan | time for zzz |
| 01:03 | Drakeson | st3fan: where? |
| 01:04 | Drakeson | (assuming you still haven't zzz'ed!) |
| 01:05 | technomancy | folks: it's time to discuss what the collective nouns should be for Clojure terms |
| 01:05 | technomancy | "An alignment of vectors" |
| 01:05 | technomancy | "A lethargy of lazy-seqs" |
| 01:05 | technomancy | "A cartography of maps" (sorry) |
| 01:13 | adityo | "An Agency of Agents" |
| 01:14 | technomancy | yes! that's what I'm talking about. |
| 01:14 | hiredman | (Secret) Agency |
| 01:14 | adityo | :) |
| 01:14 | _ato | A conspiracy of conses? |
| 01:15 | hiredman | (def #^{:private true} a [(agent nil (agent nil)]) |
| 01:17 | technomancy | "𝅘𝅥𝅮 Secret ... Aaaaaagent Man 𝅘𝅥𝅯" |
| 01:18 | adityo | Look up the CAD, Clojure Agent Directory ;) |
| 01:24 | qed | Instead of 007 it's BigO1 |
| 04:21 | ngoc | Hi, how to convert Java's ArrayList to Clojure's array and Java's HashMap to Clojure's map? |
| 04:31 | Chousuke | ngoc: (into [] arrayList) or (into {} hashmap) should work |
| 05:22 | djpowell | I suppose it ought to be possible to automatically generate a method-map from a datatype's fields. Would be quite handy so that I can have 'subclasses' that override the field accessors with more complicated logic, and then I don't need to change client code from (:my-field o) to (my-accessor o) if I decide that simple fields aren't good enough |
| 06:05 | AWizzArd | ~max people |
| 06:05 | clojurebot | max people is 214 |
| 06:05 | AWizzArd | uh la la |
| 06:43 | krumholt | hi, is there a difference between sync and dosync? |
| 06:44 | rhickey | krumholt: dosync is built on sync |
| 06:44 | rhickey | sync has a (currently unused) spot for options, dosync elides that |
| 06:44 | krumholt | rhickey, ok thanks |
| 06:45 | rhickey | prefer dosync for now |
| 06:45 | krumholt | will do thanks |
| 07:21 | djpowell | urgh, macros confuse me. I wanted to autogen a protocol based on a datatype's fields. |
| 07:29 | AWizzArd | and? |
| 07:32 | djpowell | i'm getting confused. as defprotocol is a macro, does that mean I need to write a macro to construct a call to it? |
| 07:39 | rhickey | djpowell: yes |
| 07:40 | rhickey | but what are you going to generate for the fields - accessors? you already get them for free |
| 07:42 | djpowell | well, I want to (in some 'subclasses') override some accessors to do some more complicated stuff, like have fallbacks to other fields. so I don't want to have to change all client code to change from (:field o) to (accessor o) |
| 07:42 | djpowell | so i wanted to have a base method-map that has accessors for the fields, that I can override |
| 07:43 | rhickey | djpowell: there is no equivalent to subclasses with deftype/protocols |
| 07:45 | djpowell | no, but I can have a bunch of deftypes representing some related entities, and have them implement a common protocol, along with a protocol for their type specific operations |
| 07:46 | djpowell | and I can override the method-map from the defaults to type-specific versions where i need something more than getting the field directly |
| 07:46 | rhickey | djpowell: ok, I'm not trying to dissuade you, just don't want you to be disappointed later :) |
| 07:47 | rhickey | so, right now the mechanics of defprotocol are wrapped in a macro. Exposing that as a function might be useful |
| 07:49 | djpowell | i'm just toying around with things at the moment, looking at how these features might help me. cause I have some java right now (as you can probably tell!), that really needs some of the dynamic features that deftypes/protocols seem to offer |
| 07:51 | AWizzArd | btw, rhickey, why is a hierarchy of types bad? You mention something like this on the Protocols wiki page. |
| 07:56 | rhickey | AWizzArd: the long answer would take hours. A short answer is, a) I didn't say that, and b) if you can provide features (protocols/mixins) without requiring derivation/hierarchy, that's better |
| 07:57 | lpetit | rhickey: what would you consider the most interesting "paper" on this subject, that anyone could read to make one's own opinion without making you repeat things over and over again ? |
| 07:57 | AWizzArd | Maybe in your future talks you will leak out more details about it :) |
| 07:58 | djpowell | rhickey: I might be ok with using keyword accessors, and distinct protocol methods for the cases where I need different behaviours. Not sure yet. |
| 07:59 | fogus_ | lpetit: This one is not bad: http://www.scala-lang.org/docu/files/IC_TECH_REPORT_200433.pdf |
| 08:00 | rhickey | it's better because hierarchy creates a world in which some people are saying, "if something is an X, do this that way" while others may say "foo instanceof Y", and still others say "Y isa X" and managing the implications becomes impossible |
| 08:00 | fogus_ | lpetit: Scala-centric of course |
| 08:00 | rhickey | fogus_: I don't think so. traits are a good example of what I'm trying to avoid with protocols |
| 08:02 | fogus_ | rhickey: Interesting. I've always liked the discussion on the expression problem in that paper, but if you have a link more in line with your own thinking, then I would also be interested in reading it |
| 08:05 | fogus_ | rhickey: RE: Traits. You're trying to avoid them because they do not solve the problem that you presented above, no? |
| 08:06 | rhickey | I think Scala implicits shows they don't really address the expression problem in as shown in the paper |
| 08:06 | rhickey | traits are classes, so can have impl they have no pure interface-like spec construct |
| 08:06 | rhickey | protocols are specs only |
| 08:07 | rhickey | trait introduce hierarchy and isa, protocols don't |
| 08:07 | rhickey | you can't imbue a class with a trait other than with implicits, which requires an adapter allocation and introduces identity and other isa problems |
| 08:08 | rhickey | vs extending a protocol to String |
| 08:08 | fogus_ | rhickey: You had to mention implicits... they are the skeleton in Scala's closet. ;) |
| 08:08 | rhickey | and mixing in implementations by method map composition, no hierarchy required |
| 08:09 | rhickey | so, yes, traits/implicits are in the same expression problem space, they are very different from protocols |
| 08:10 | rhickey | protocols - pure specs, no adapters, compositional mixins |
| 08:10 | fogus_ | I see that more clearly now. |
| 08:11 | rhickey | traits/implicits - impure specs, implicit adapters, hierarchical mixins |
| 08:12 | fogus_ | rhickey: I have a lot of experience with Scala and it's M.O. so it's helpful for me to understand the comparison. Thanks |
| 08:14 | djpowell | hmm, juxt seems slightly handy for composing method impls from calls to other methods |
| 08:15 | djpowell | perhaps |
| 08:45 | ohpauleez | when writing something like: (let [x [1 2 3 4 5]] (nth x (rand-int (count x)))) one could do: (let [x [1 2 3 4 5]] (nth x (-> x count rand-int))) ... |
| 08:45 | ohpauleez | but is there something more concise? |
| 08:48 | hoeck | ohpauleez: I have written a little rand-nth function for this case, like (rand-nth [1 2 3 4 5]), couldn't find a more concise way |
| 08:48 | ordnungswidrig | hoeck: a rand-nth function is concise for the user of the rand-nth function |
| 08:49 | ohpauleez | is there a way to man-handle something like %1 when not making anon-functions/lambdas |
| 08:50 | ohpauleez | for example: (-> x count rand-int (nth x %1)) |
| 08:50 | ohpauleez | which I guess isn't more concise, so nvm haha |
| 08:57 | st3fan | what does -> do? |
| 08:58 | chouser | ,(let [x '[a b c d e]] (->> x count rand-int (nth x))) |
| 08:58 | clojurebot | c |
| 08:59 | ohpauleez | it threads the values from one call to the next |
| 08:59 | chouser | st3fan: it rearranges your code |
| 08:59 | fogus_ | st3fan: http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro ;) |
| 08:59 | ohpauleez | thanks chouser! |
| 09:00 | st3fan | interesting :-) |
| 09:02 | ohpauleez | chouser: what's the rationale for quoting the vector |
| 09:02 | chouser | ohpauleez: so I didn't have to quote each of the symbols |
| 09:03 | ohpauleez | ahh right right |
| 09:03 | ohpauleez | thanks |
| 09:03 | chouser | symbols instead of keywords or strings because I can type each with a single keystroke instead of 2 or 3. :-) |
| 09:09 | esj | ->> is related to -> how ? Doesn't seem to be on the reader section of the web-page. |
| 09:09 | ohpauleez | ,(doc ->>) |
| 09:09 | clojurebot | "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc." |
| 09:09 | ohpauleez | it stacks on the last, not the second arg |
| 09:14 | esj | aah, brilliant, thanks. |
| 09:16 | ohpauleez | totally welcome |
| 09:27 | fogus_ | Is it possible to destructure and coerce at the same time using `let`? |
| 09:28 | cemerick | "coerce"? |
| 09:30 | AWizzArd | ,(doc coerce) |
| 09:30 | clojurebot | Excuse me? |
| 09:31 | ordnungswidrig | watching rick's infoq presentation right now. I like the idea of identity beaing a series of values. Is there more information on this topic? I see that patch-theory is related to this, |
| 09:31 | cemerick | fogus_: do you mean hinting in a destructuring form? |
| 09:31 | cemerick | if so, sure |
| 09:31 | fogus_ | I'm ripping out the chars from a string and want to coerce them to int. At the moment I have (let [[a b] "xy"] (println (int a) ", " (int b))) |
| 09:31 | cemerick | sure, you can hint a and b |
| 09:32 | cemerick | you can hint any symbols in a binding-form |
| 09:32 | cemerick | regardless of destructuring, etc |
| 09:32 | chouser | hinting is not coersion |
| 09:32 | fogus_ | cemerick: I don't think hinting gets me what I need. |
| 09:32 | chouser | fogus_: I think you have to use two separate steps |
| 09:32 | fogus_ | chouser: As I suspected |
| 09:33 | chouser | this is not the only case where it feels like it would be useful to call more or less arbitrary functions during destructuring |
| 09:33 | chouser | I think languages with flexible pattern-matching mechanisms can allow that to some extent |
| 09:33 | cemerick | fogus_: oh, you are actually converting, sorry, didn't read the sample carefully enough |
| 09:33 | AWizzArd | fogus_: can you hae your let also be something like (map int "xy")? |
| 09:33 | AWizzArd | hae ==> have |
| 09:34 | rhickey | chouser: do you have any examples in other langs? |
| 09:34 | fogus_ | cemerick: no worries. |
| 09:34 | fogus_ | AWizzard: That's it! |
| 09:34 | AWizzArd | k |
| 09:35 | fogus_ | ,(let [[a b] (map int "xy")] [a b]) |
| 09:35 | clojurebot | [120 121] |
| 09:35 | fogus_ | AWizzard: Thank you |
| 09:36 | chouser | rhickey: not off the top of my head, but I'm pretty sure I've seen somewhere a general mechanism where you can provide both a constructor and a deconstructor. I'll see if I can find it. |
| 09:41 | patrkris | hey, i'm looking for something to do for my masters thesis, and since I like Clojure very much, I thought about maybe doing something about distributed parallelism in Clojure? Along the lines of Erlang. What do you think? |
| 09:42 | ohpauleez | refs, STMs, agents, AND actors? |
| 09:42 | ohpauleez | haha |
| 09:42 | patrkris | that's a stupid idea? :P |
| 09:43 | ohpauleez | no, I personally think it's good |
| 09:43 | ohpauleez | I once wrote a networked namespace for python |
| 09:43 | ohpauleez | to support a distributed testbed |
| 09:43 | patrkris | i don't know if it is even possible or whatever... I'd just like to work with Clojure ;) |
| 09:43 | fogus_ | chouser: Would Scala's unapply mechanism fit your description? It's not an arbitrary function however. |
| 09:44 | rhickey | patrkris: I'd love to see more work done around predicate dispatch. |
| 09:45 | chouser | fogus_: I think that must be it. What I'm thinking of would have to be a feature of either Scala or Haskell, and it feels more like Scala. |
| 09:45 | chouser | but yes, I see that it is controlled by the type of thing being destructured, not arbitrarily specified at the moment of destructuring. :-/ |
| 09:46 | patrkris | rhickey: have you or others done any work in that regard? |
| 09:48 | rhickey | I did some Chambers/Chen style stuff in a prototype for Clojure |
| 09:49 | rhickey | but to move it forward I think you'd want some more sophisticated notions of logical implication, maybe combining it with the datalog stuff |
| 09:50 | rhickey | the implications in Chambers/Chen are derived from the type hierarchy, or possibly hardwired numeric implications, not a general system |
| 09:50 | rhickey | supporting arbitrary logic and good performance is still a research topic, AFAIK |
| 09:52 | ordnungswidrig | rhickey: do you think there a connection points between the idea of "identity being a series of values" and patch theory? |
| 09:54 | rhickey | patch theory as described where? |
| 09:54 | ordnungswidrig | rhickey: as implemented by darcs or git. |
| 09:55 | ordnungswidrig | rhickey: well, git does not really patch theory but a repository is basically a collection of functions applied on a state in distributed manner. Like STM, I think. |
| 09:55 | rhickey | I know darcs has some theory behind it, GIT is definitely a persistent data structure on disk |
| 09:55 | rhickey | but the whole notion of merging complicates things |
| 09:56 | ordnungswidrig | rhickey: STM has the same problem, or not? I two concurrent processes try to execute conflicting changes they'll have to be merged. |
| 09:57 | ordnungswidrig | s/I two/If two/ |
| 09:57 | AWizzArd | ordnungswidrig: I have this same issue with my in-ram db. |
| 09:57 | AWizzArd | Clojure is fortunately already doing a lot of needed work for you. |
| 09:57 | ordnungswidrig | AWizzArd: but the merge problem exists anyway |
| 09:57 | AWizzArd | this is true |
| 09:58 | AWizzArd | if you have a db and two threads snapshot it and calculate a new db each, then the first who wants to check is data in wins. The second thread will have to merge. |
| 09:58 | AWizzArd | Each thread which makes a snapshot will have to create its own replay-log, from which merging is possible. |
| 09:59 | lpetit | AWizzArd: won't the commute function help here ? |
| 09:59 | ordnungswidrig | AWizzArd: using patch theory you can provide a way to merge the conflicting changes. e.g. inc and dec can be commuted without changing the result. |
| 09:59 | AWizzArd | lpetit: not really |
| 09:59 | ordnungswidrig | AWizzArd: what is the underlying data model of your db? |
| 09:59 | AWizzArd | ordnungswidrig: maybe we talk about different things |
| 09:59 | rhickey | ordnungswidrig: STM does no merging other than commute, otherwise there are retries |
| 09:59 | AWizzArd | ordnungswidrig: clojure data structures |
| 10:00 | rhickey | merging and operational state transform etc are all interesting |
| 10:00 | rhickey | they get application-domain specific though |
| 10:00 | AWizzArd | right |
| 10:01 | rhickey | so, merging edits to a text file is an application domain |
| 10:01 | ordnungswidrig | rhickey: I expect the things to come together at some point of time. Yes, the domain specific part is often surprisingly easy. |
| 10:01 | rhickey | well, commute is there |
| 10:01 | rhickey | you write the fn |
| 10:02 | ordnungswidrig | rhickey: merging text is hard because the intention of the change is lost. Talking of key value sture the merge model is easier. |
| 10:02 | ordnungswidrig | Oh, there is a commute fn? |
| 10:02 | ordnungswidrig | I mean a way to specify a domain specific one? |
| 10:02 | rhickey | Clojure's STM has commute |
| 10:02 | ordnungswidrig | rhickey: As I said. The things are coming together :-) |
| 10:02 | patrkris | rhickey: thanks - you mentioned a lot of things that I'll need to look up, but sounds interesting (distributed Clojure that is) |
| 10:02 | AWizzArd | commute allows for more parallelism than alter I think? |
| 10:03 | AWizzArd | ,(doc commute) |
| 10:03 | clojurebot | "([ref fun & args]); Must be called in a transaction. Sets the in-transaction-value of ref to: (apply fun in-transaction-value-of-ref args) and returns the in-transaction-value of ref. At the commit point of the transaction, sets the value of ref to be: (apply fun most-recently-committed-value-of-ref args) Thus fun should be commutative, or, failing that, you must accept last-one-in-wins behavior. commute allows for more |
| 10:03 | fogus_ | ,(doc commute) |
| 10:03 | ordnungswidrig | AWizzArd: a commute function can event be interactive. Like a mergetool in DVCS |
| 10:03 | clojurebot | "([ref fun & args]); Must be called in a transaction. Sets the in-transaction-value of ref to: (apply fun in-transaction-value-of-ref args) and returns the in-transaction-value of ref. At the commit point of the transaction, sets the value of ref to be: (apply fun most-recently-committed-value-of-ref args) Thus fun should be commutative, or, failing that, you must accept last-one-in-wins behavior. commute allows for more |
| 10:03 | fogus_ | Whoops.. |
| 10:03 | rhickey | patrkris: I wasn't suggesting work on distributed Clojure, but on (non-distributed) dispatch |
| 10:04 | ordnungswidrig | AWizzArd: is you db public? |
| 10:04 | AWizzArd | ordnungswidrig: i don't know at which level you want to be aware of changes for merges. I want highlevel merges. One entry in the replay-log resembles a full transaction. |
| 10:04 | AWizzArd | ordnungswidrig: Not yet, I will be working on having it opensourced :) |
| 10:04 | AWizzArd | Clojures snapshots are so cheap, I can have tons of them in ram. |
| 10:05 | patrkris | rhickey: see, I don't know anything... yet :) |
| 10:05 | AWizzArd | So, one can have undo, and other nice things. |
| 10:05 | chouser | fogus_: you were right. unapply. |
| 10:06 | ordnungswidrig | AWizzArd: seems like were working on similiar topics. |
| 10:06 | rhickey | patrkris: http://portal.acm.org/citation.cfm?id=320407 |
| 10:06 | chouser | But it looks like you can do arbitrary work, you just have to stick it in an unapply method of a class. |
| 10:06 | AWizzArd | ordnungswidrig: gut :) |
| 10:06 | chouser | http://www.scala-lang.org/node/112 |
| 10:08 | rhickey | chouser: do you get only one unapply per type? |
| 10:09 | fogus_ | chouser: Arbitrary work yes, but still bound to the case class (or somewhere along its heirarchy) |
| 10:10 | lisppaste8 | Chouser pasted "simplified unapply example" at http://paste.lisp.org/display/90579 |
| 10:10 | patrkris | rhickey: thanks, i'll take a look. If you have any other ideas for a masters thesis subject, I'd be happy to hear them |
| 10:10 | patrkris | rhickey: that is, additional ideas |
| 10:11 | chouser | So there's only one unapply for Twice, but because any number of classes could take an Int as their arg in unapply, and you could specify any of them in a case expression. |
| 10:14 | chouser | so just like [a] means roughly assoc in normal expressions but nth in destructuring forms, I suppose int could mean "convert a to an int" normally but "assign a to an int" in destructuring? |
| 10:15 | chouser | (let [[(int a) (int b)] "xy"] ...) ? |
| 10:15 | rhickey | seems pretty easy (let [(destructure-fn a b c) x] ...), where destructure-fn takes one arg and returns a 3-tuple |
| 10:16 | rhickey | arbitrary functional destructuring |
| 10:17 | fogus_ | So in the original case it would be: (let [(int a b) "xy"] ...) ? |
| 10:17 | rhickey | I doubt int is going to mean that, but some fn |
| 10:17 | rhickey | intify |
| 10:17 | chouser | yes, that does seem simple. That's orthogonal to the naming -- would there be 'int' and 'as-int', or would destructuring somehow call a different fn when it sees int in a destructuring form |
| 10:18 | fogus_ | What would `intify` return? |
| 10:18 | rhickey | I don't think int is that intersting, also might be covered by type hints at some point |
| 10:20 | fogus_ | OK, then would would `destructure-fn` return? A seq? |
| 10:20 | chouser | well, something that 'nth' could be used on, so a seq or vector |
| 10:21 | fogus_ | OK. Got it. |
| 10:22 | chouser | (let [(vec a b c) x] ...) would be the same as (let [[a b c] x] ...), wouldn't it? |
| 10:22 | chouser | that seems -- right. :-) |
| 10:23 | rhickey | chouser: yes |
| 10:23 | rhickey | but would make a temporary vector out of x if it wasn't already |
| 10:24 | rhickey | so, kind of a waste |
| 10:24 | chouser | yes, not a practical example |
| 10:24 | rhickey | in general, (let [(foo a b c) x] ...) would be the same as (let [[a b c] (foo x)] |
| 10:25 | rhickey | so, still not that interesting |
| 10:25 | chouser | more interesting when nested |
| 10:25 | rhickey | except when used in internal pieces |
| 10:25 | chouser | right |
| 10:25 | rhickey | heh |
| 10:25 | chouser | which was fogus_'s original case |
| 10:26 | chouser | had to use map on the expression side to get it, and that only worked because he wanted the same fn applied to all pieces |
| 10:27 | chouser | (let [{:keys [name (int age)]} person] ...) |
| 10:27 | fogus_ | (let [destruct-fn #(vec %) (destruct-fn a b c) x] ... ) still not incredibly interesting, but fun |
| 10:28 | chouser | heh |
| 10:28 | fogus_ | I could go all day like this. |
| 10:31 | chouser | (let [{:keys [name (Integer. age)]} person] ...) |
| 10:32 | chouser | (defn intify [x] [(Integer. age)]) |
| 10:32 | chouser | (let [{:keys [name (intify age)]} person] ...) |
| 10:33 | chouser | it seems a shame to require intify be defined just to stuff a result into a vector. |
| 10:34 | chouser | (let [{:keys [name (#(list (Integer. %)) age)]} person] ...) |
| 10:34 | fogus_ | yeah |
| 10:37 | chouser | but since a destructure-fn doesn't know how many values it's being required to produce, if they can ever support more than one, they all would need to return a collection even for a single item. |
| 10:37 | chouser | that would generally rule out direct use of most existing fns -- new ones would be written to be used in destructuring. |
| 10:38 | fogus_ | Unless you want to create a new special type of function that returns a coll if one isn't already reurned... I doubt anyone wants to go down that road |
| 10:38 | cgrand | or change the syntax to (let [(foo [a b c]) x] ...) |
| 10:39 | chouser | fogus_: yeah, and that runs into issues when you return a coll that's meant to be a single item, so it doesn't get wrapped... bleh |
| 10:39 | fogus_ | chouser: Yep. No way to know for sure |
| 10:44 | chouser | cgrand: so the existance of [] in the args would tell destructuring to expect a seq to unpack instead of a single value |
| 10:44 | lpetit | chouser: cgrand's idea fixes it, no ? |
| 10:44 | lpetit | chouser: or is it the other way around ? (I guess soà |
| 10:44 | lpetit | ) |
| 10:45 | lpetit | chouser: if foo is a function that does no collection wrapping, provide it yourself around the parameters ? |
| 10:47 | cgrand | chouser: (let [(foo x) y] ...) would always be equivalent to (let [x (foo y)] ...) no matter what x is (symbol, map, vector, another destructuring fn...) |
| 10:48 | rhickey | cgrand: and (foo a b c) not meaningful then |
| 10:48 | cgrand | rhickey: sadly yes |
| 10:48 | rhickey | but very strange to have bindings of return of foo appear as args to foo |
| 10:48 | fogus_ | What about: (let [[(destr-fn a b c)] x] ... ) ? This could either mean, optionally wrap the result in a coll or always do so. |
| 10:49 | rhickey | I wouldn't want to explain it |
| 10:49 | rhickey | destructuring confusing enough as is |
| 10:49 | fogus_ | rhickey: True |
| 10:50 | cgrand | what about (let [([a b c] foo) x] ...)? the destructing fn isn't in fn position anymore |
| 10:50 | rhickey | maybe (-> foo a), (-> foo [a b c]) |
| 10:50 | cgrand | or (let [(:as foo [a b c]) x] ...) |
| 10:50 | rhickey | the last position being the bindings |
| 10:51 | cgrand | rhickey: yes |
| 10:51 | rhickey | yes to what? |
| 10:51 | rhickey | -> is nice at it chains, and leaves room for args |
| 10:52 | cgrand | yes to (-> foo a), (-> foo [a b c]) |
| 10:52 | rhickey | (let [(-> foo (bar 5) [a b c]) x] ... |
| 10:52 | rhickey | could do -> and ->> |
| 10:52 | djork | how about this: (let [[a b c]] (let [x (foo a b c)] ...)) |
| 10:53 | djork | and we don't make destructuring more complicated |
| 10:53 | djork | :) |
| 10:53 | rhickey | djork: I don't understand what that says |
| 10:54 | djork | I'm just saying do destructuring in one step and them apply a fn to the destructured args in a separate let |
| 10:54 | fogus_ | rhickey: Would -> and ->> therefore be the only allowed destructure-fns? |
| 10:54 | djork | would there really be special cases for onl ycertain symbols in fn-position of a list |
| 10:55 | rhickey | fogus_: possibly |
| 10:55 | cgrand | rhickey: (let [(-> foo (bar 5) [a b c]) x] ...) would be equivalent to (let [[a b c] (-> x foo (bar 5))] ...), right? |
| 10:55 | rhickey | cgrand: yes |
| 10:56 | rhickey | but with the nesting support |
| 10:56 | cgrand | without nesting support it wouldn't be interesting |
| 10:56 | lpetit | The use of existing operators (-> or ->>) confuses me |
| 10:57 | lpetit | What if I want to use regular -> in the (bar 5) expression ? |
| 10:57 | rhickey | lpetit: really? I think they save it |
| 10:57 | fogus_ | In the original case: Would we therefore have (let [(-> int [a b]) "xy") ? |
| 10:58 | fogus_ | That is (let [(-> int [a b]) "xy"] ... ) |
| 10:58 | lpetit | rhickey : what would (let [(-> foo (-> bar baz) [a b c]) x] ...) mean ? |
| 10:58 | rhickey | lpetit: ordinary code goes anywhere except in the last position, which is treated as a binding construct |
| 10:58 | chouser | I'm afraid it would be (let [[(-> int a) (-> int b)] "xy"] ...) |
| 10:59 | lpetit | rhickey : oh yes, it works |
| 11:00 | fogus_ | chouser: :( |
| 11:00 | rhickey | chouser: or (let [(-> coerces int [a b]) "xy"] ...) |
| 11:02 | cgrand | or (let [(->> (map int) [a b]) "xy"] ...) |
| 11:02 | fogus_ | cgrand: beat me to it |
| 11:02 | rhickey | cgrand: right, use functions to help us |
| 11:03 | fogus_ | I like it |
| 11:11 | chouser | hehe |
| 11:12 | fogus_ | I would be happy to work on it... as long as no one minds it taking until Clojure 3.0 |
| 11:17 | qed | so is -> the thrush combinator? |
| 11:17 | qed | is that rght? |
| 11:17 | qed | right* |
| 11:18 | qed | Txy = yx |
| 11:23 | chouser | -> is a macro |
| 11:24 | chouser | ,(-> [x (range 5)] (for (/ x 2))) |
| 11:24 | clojurebot | (0 1/2 1 3/2 2) |
| 11:31 | AWizzArd | Can deftype take a docstring? When yes: at what position? |
| 11:34 | fogus_ | qed: -> is the Thrush... but because Clojure is not lambda calc it provides different forms to handle different argument positions |
| 11:49 | fogus_ | ,(#(* % %) (->> (range 1 100) (filter even?) (reduce +))) |
| 11:49 | clojurebot | 6002500 |
| 11:49 | sh10151 | Is there an idiomatic way to check for tree equality in zip-filter.xml type code? |
| 11:50 | sh10151 | basically I want to filter based on whether or not some child nodes are equal to a given node |
| 12:02 | qed | (recur b (+ a b) (inc term)) --> What is happening here with the b all by itself? |
| 12:02 | Chousuke | the loop has three parameters and on the next iteration the first one is b? |
| 12:04 | qed | not sure I follow |
| 12:04 | qed | what do you mean the first one? |
| 12:04 | Chousuke | the first parameter to the loop |
| 12:05 | Chousuke | (loop [a 1 b 2 c 3] (recur c b a)) ; infinite loop that shuffles a, b and c :P |
| 12:05 | Chousuke | hm, well, b actually never changes. |
| 12:05 | qed | but you swap a and c around b |
| 12:05 | Chousuke | but a and c keep switching values :) |
| 12:06 | qed | hm, interesting, i didnt know you could control recur's order |
| 12:06 | Chousuke | order? |
| 12:06 | Chousuke | you just specify the values the loop will have on its next iteration |
| 12:06 | ohpauleez | qed: recur is like calling the function name again |
| 12:06 | Chousuke | bound to a, b and c in the order they were declared in the initialisation. |
| 12:07 | ohpauleez | except instead of going down the call stack |
| 12:07 | ohpauleez | it does it in place |
| 12:08 | ohpauleez | additionally, recur can call back to a loop, and not a function call, but the idea stays the same |
| 12:08 | Chousuke | ,(loop [a 1 b 2] (when (< b 5) (print b) (recur b (inc a)))) |
| 12:08 | clojurebot | 223344 |
| 12:09 | qed | oh, so it's like two nested for loops? |
| 12:09 | Chousuke | no, just a single loop with two "variables" |
| 12:10 | ohpauleez | not even, it's conceptually like writing: (defn some-name [a 1 b 2] (when (< b 5) (print b) (some-name b (inc a)))) |
| 12:10 | chouser | huh. I think finished it during a single status meeting. |
| 12:10 | ohpauleez | chouser: finished what? |
| 12:11 | chouser | (let [[a (-> str b) c] [1 2]] (list a b c)) ==> (1 "2" nil) |
| 12:11 | ohpauleez | alright! |
| 12:11 | Chousuke | on the first iteration, the values are a = 1, b = 2, on the second, a = 2 (b), b = 2 ((inc a)), and on the third a = 2, b = 3, etc... |
| 12:11 | AWizzArd | chouser: Can deftype take a docstring? Do you know if it is planned that the printed representation of a deftype can be read/read-string'ed back? |
| 12:11 | drewr | ,(filter identity [1 nil 2 3 nil]) |
| 12:11 | clojurebot | (1 2 3) |
| 12:11 | qed | thank you |
| 12:11 | qed | Chousuke: that makes sense now, thanks man |
| 12:12 | chouser | ah, not quite yet... |
| 12:13 | fogus_ | chouser: Wow, you're much faster than me. Clojure 3.0 is not even close |
| 12:13 | chouser | :-P |
| 12:13 | chouser | it's about 6 lines of code |
| 12:13 | Licenser | good evening everyone, how is the clojure world? Everything functioning fine I hope? |
| 12:14 | fogus_ | chouser: Do you mind sending me a patch? |
| 12:14 | fogus_ | Or a link to a branch |
| 12:15 | chouser | it only nests in some cases, not yet all |
| 12:16 | Chousuke | the -> is not the same as the -> macro is it? |
| 12:16 | lisppaste8 | Chouser pasted "-> destructuring [incomplete]" at http://paste.lisp.org/display/90584 |
| 12:16 | chouser | Chousuke: very nearly |
| 12:18 | fogus_ | chouser: very nice |
| 12:19 | ohpauleez | chouser: cool |
| 12:20 | cgrand | chouser: shouldn't '#{-> ->>} be #{'-> '->> `-> `->>}? |
| 12:21 | chouser | cgrand: yep, thanks. |
| 12:22 | ohpauleez | cgrand: great post in the blog, I really enjoyed it |
| 12:22 | cgrand | ohpauleez: thanks |
| 12:25 | qed | cgrand: just reading now, but while we're on the subject, i love your blog, how do you do your syntax hilighting? |
| 12:25 | lisppaste8 | Chouser annotated #90584 "fixed `-> and recursive final form" at http://paste.lisp.org/display/90584#1 |
| 12:26 | cgrand | qed: pygments |
| 12:26 | chouser | I think that's everything except (let [{:keys [(-> str a) b] {:a 1 :b 2}] a) |
| 12:27 | cgrand | I resurected an old pygment plugin for wordpress http://gist.github.com/213649 |
| 12:27 | AWizzArd | chouser: what should your last example accomplish? |
| 12:27 | chouser | (let [[a (->> (map int) [b c])] [\a "bc"]] (list a b c)) ==> (\a 98 99) |
| 12:27 | qed | cgrand: ah i see -- i tried using pygments with my rails blog but gave up and have just been converting my code with pygments and then pasting in the html |
| 12:28 | qed | cgrand: where'd the theme come from? |
| 12:28 | cgrand | qed: Barecity http://shaheeilyas.com/barecity/ |
| 12:28 | chouser | AWizzArd: in short, the final form in a destructuring -> can now itself be a complex destructuring form |
| 12:29 | qed | cgrand: i meant the pygments coloration |
| 12:29 | qed | my pygments highlighted code doesn't look like yours |
| 12:29 | cgrand | qed: let me check |
| 12:33 | cgrand | qed: style=manni |
| 12:33 | qed | ah-ha, cool, thank you |
| 12:35 | chouser | huh. so (let [{:strs [(-> str a)]} {"a" 1}] a) can only be supported when the a in (-> str a) is a single symbol, not a destructuring coll |
| 12:36 | chouser | it's still worth doing, though, right? |
| 12:36 | rhickey | probably not |
| 12:36 | chouser | ok! then I'm done. |
| 12:37 | rhickey | wow |
| 12:37 | chouser | rhickey: you saw the patch paste? you want it in dev-clojure? |
| 12:38 | rhickey | should get an assembla entry I think |
| 12:38 | rhickey | if you don't mind - thanks |
| 12:38 | replaca_ | rhickey: it looks like clojure.parallel is not compatible with the latest jsr166y stuff since ParallelArray has moved to extra166y.jar |
| 12:38 | chouser | it was easy because requiring -> was brilliant |
| 12:40 | rhickey | replaca_: clojure.parallel is not going to be moved forward, as the ParallelArray is not making it into JDK 7. The new par branch will be the future of that stuff, on top of ForkJoin directly |
| 12:41 | rhickey | replaca_: the other advantage of the new par approach is that it uses the persistent data structures directly, not converting to/from parrays |
| 12:42 | replaca_ | rhickey: OK, so I won't worry about it for the autodoc then :-) |
| 12:43 | rhickey | replaca_: right :) |
| 12:43 | replaca_ | thanks |
| 12:43 | rhickey | thank you - the doc stuff looks great! |
| 12:46 | lisppaste8 | dakrone pasted "why does this script error out?" at http://paste.lisp.org/display/90589 |
| 12:47 | replaca_ | rhickey: thanks. I need to get it working with contrib again and then I'm going to try to get it doing multiple branches, but that's tricky for the core (since I'm using things that depend on a given version of core) |
| 12:47 | dakrone | can someone enlighten me as to what I'm doing wrong with that script? |
| 12:49 | dakrone | since (ioc-file "lipsum.txt") seems to work without any problems |
| 12:53 | cgrand | dakrone: ... clojure.lang.Script ./ioc.clj -- lipsum.txt |
| 12:54 | dakrone | cgrand: if I do that, there's no output at all |
| 12:56 | tomoj | can clojure.test unwind the stack on a failure? |
| 12:57 | cgrand | dakrone: because map is lazy, here you should use doseq instead: (doseq [file *command-line-args*] (ioc-file file)) |
| 12:57 | tomoj | or would I have to throw exceptions on failures and catch them at the top-level? |
| 13:04 | dakrone | cgrand: I changed it to doseq and it still errors out, same error |
| 13:05 | cgrand | dakrone: doseq and -- ? |
| 13:05 | dakrone | cgrand: okay, that did it, didn't realize I needed the -- also |
| 13:06 | lisppaste8 | dakrone annotated #90589 "fixed version" at http://paste.lisp.org/display/90589#1 |
| 13:06 | dakrone | cgrand: thank you very much |
| 13:06 | cgrand | dakrone: yw |
| 13:27 | dnolen | cgrand: great blog post on optimizing Life of Brian. |
| 13:45 | chouser | http://www.assembla.com/spaces/clojure/tickets/211-Support-arbitrary-functional-destructuring |
| 13:49 | technomancy | that was quick. |
| 13:51 | mtm | technomancy: playing with the latest leiningen and getting "Component descriptor cannot be found in the component repository: org.apache.maven.artifact.manager.WagonManager" |
| 13:52 | danlarkin | mtm: gah! I get that sometimes too! |
| 13:52 | stuartsierra | tomoj: clojure.test prints stack traces for exceptions, is that what you mean? |
| 13:53 | tomoj | no, I mean like how rspec stops running a test on the first failure in that test |
| 13:53 | tomoj | certain failures for me mean that the test can't continue |
| 13:54 | stuartsierra | tomoj: It doesn't stop on failure. I debated whether or not to do that. But the other tests will just fail, wont they? |
| 13:54 | tomoj | well they will blow up with exceptions currently |
| 13:54 | stuartsierra | yse |
| 13:54 | stuartsierra | *yes |
| 13:55 | stuartsierra | So no, there's no built-in way to stop the test function prematurely. |
| 13:56 | tomoj | I guess I can just throw a meaningful exception instead of doing a test there |
| 13:56 | stuartsierra | You could write something like (deftest ... (when (is foo) (is bar) ...)) |
| 13:56 | tomoj | ah, yeah, that'll work, thanks |
| 13:56 | stuartsierra | (is...) always returns the result of the assertion expression. |
| 14:00 | the-kenny | lisppaste8: url |
| 14:00 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 14:02 | hiredman | arbitrary functional destructuring <-- wow |
| 14:02 | lisppaste8 | the-kenny pasted "untitled" at http://paste.lisp.org/display/90595 |
| 14:03 | hiredman | binding is dynamic scope |
| 14:03 | KirinDave | Yeah |
| 14:03 | KirinDave | Dynamic scope is not lexical scope. |
| 14:03 | the-kenny | hm.. a bit annoying. |
| 14:03 | KirinDave | Uh, no |
| 14:04 | KirinDave | What you want, sir, is to use a lexical scoping construct. :) |
| 14:04 | hiredman | dynamic scope is resolved at function call time, not function definition time |
| 14:04 | KirinDave | You can visualise it as something that rides along in the call stack. |
| 14:05 | cemerick | chouser: the examples in #211 confuse me, FWIW. |
| 14:05 | the-kenny | hm.. ok. I thought something like this was possible. |
| 14:05 | KirinDave | the-kenny: It is. |
| 14:05 | hiredman | but don't do it |
| 14:06 | the-kenny | heh ok :D |
| 14:06 | hiredman | just pass an argument |
| 14:06 | KirinDave | Or swap bindings for let |
| 14:06 | KirinDave | Which is the lexical scoping construct. Consider what you're doing carefully though. |
| 14:07 | KirinDave | Because you're defining ONE instance at definition time. |
| 14:07 | the-kenny | hiredman: clojure-couchdb is a library |
| 14:07 | hiredman | sure |
| 14:07 | KirinDave | the-kenny: So you'd expect to say (bindings [*server* "server-url"] (foo)) |
| 14:08 | KirinDave | the-kenny: In other words, you tend to set bindings at runtime at the upper level of your call tree. |
| 14:08 | hiredman | the first thing I do with libraries that use dynamic scope is wrap them in functions that take arguments |
| 14:08 | the-kenny | KirinDave: That's what I'm doing now. I was a bit confused about the defn-thing |
| 14:09 | KirinDave | the-kenny: Yeah. Just remember the idea that dynamic scope is a rider in the call stack |
| 14:12 | jasapp | hiredman: did you ever use clsql for common lisp? |
| 14:26 | chouser | cemerick: do you think that particular syntax is confusing, or the whole idea of arbitrary code allowed in destructuring? Or are they just poor examples? |
| 14:27 | KirinDave | Wow, clojure.http.resourcefully is a really nice idea. |
| 14:28 | KirinDave | kotarak: It's just pattern matching. You haven't seen it out of control until you've worked in Prolog. ;) |
| 14:28 | cemerick | chouser: all of the above? |
| 14:29 | cemerick | I'm just not clear what pain is being relieved. |
| 14:29 | cemerick | for the sample examples there, or anything like it, I generally prefer (let [a (foo) a (other-foo a)] a), just to keep things clear. |
| 14:29 | kotarak | cemerick: most likely a shortened let, which I don't particular feel as pain. You get a more unreadable destructuring for return. |
| 14:30 | kotarak | cemerick: exactly |
| 14:31 | cemerick | well, if I remember fogus_'s question from before that prompted this, it wasn't so much trying to destructure in a different way than it was trying to get function application into binding forms for their own sake. |
| 14:31 | cemerick | although, I'm probably not being charitable there. |
| 14:31 | cemerick | ...which brings me back to, when would anyone use this, why, and what is the gain? |
| 14:35 | cemerick | chouser: yeah, looking at those examples again, I'm just not at all clear as to what's going on. i.e. (-> str b) is apparently *binding* b, not applying a fn 'b', which is confusing as hell. |
| 14:42 | rhickey | cemerick: are let of vectors and maps confusing in that they don't create vectors and maps? probably at first |
| 14:44 | rhickey | obviously destructuring is sugar, as we can get at the components using fns |
| 14:48 | stuartsierra | I've only been vaguely following this discussion, but it looks confusing as hell. |
| 14:48 | cemerick | rhickey: [] and {} are known sugar -- start messing around with function application, and I think things go bad quickly. |
| 14:49 | cemerick | It's not even so much a matter of it being confusing, the proposed change means that one needs to *read* binding-forms, whereas they're nicely scannable right now. |
| 14:51 | rhickey | cemerick: I don't see how this affects scanning (let [[a b] c d [e f]]...) 0 there's no automatic balancing op |
| 14:52 | rhickey | must distinguish unfamiliar from confusing |
| 14:52 | cemerick | rhickey: I was saying that the proposal in #211 affects scanning, not existing destructuring forms (which are super-readable/scanable, IMO) |
| 14:52 | rhickey | people argue against Lisp because it is 'confusing' |
| 14:53 | rhickey | cemerick: becasue you have to look at the end of (-> ...) for the bindings? |
| 14:53 | cemerick | rhickey: because you need to interpret the ... in order to have any clue as to what the bound value is |
| 14:53 | rhickey | ny example above just to show it's not clear which are the bindings without some manual grouping |
| 14:54 | rhickey | cemerick: you would also if it was on the right hand side |
| 14:55 | cemerick | rhickey: granted, but I currently don't have to do any reading/interpreting to answer "what are the bindings available in this scope", or "where is foo bound", etc. |
| 14:56 | rhickey | cemerick: that, I think, is a familiarity thing, once you understand (-> ends in bindings) |
| 14:56 | rhickey | I agree at the top level it is superfluous and should be discouraged |
| 14:57 | cemerick | heh, only in binding forms, but (-> foo bar) applies bar to foo everywhere else |
| 14:57 | rhickey | cemerick: but it does apply the destructuring bind of bar to foo |
| 14:57 | rhickey | cemerick: vectors and maps do different things in binding forms than elsewhere also |
| 14:58 | cemerick | oh, my, now I just grokked the third example in #211 |
| 14:59 | cemerick | rhickey: so, when *would* this be used? I still haven't seen any compelling example where this is beneficial. |
| 15:01 | slyrus_ | does stefan kamphausen hang out here? |
| 15:01 | kotarak | cemerick: still the only use case I can think of is cutting down on lets: (let [[a (-> str b) c] x] (list a b c)) vs. (let [[a b c ] x b (str b)] (list a b c)).... |
| 15:02 | cemerick | kotarak: and I'd prefer the latter anyway, for clarity's sake |
| 15:02 | kotarak | cemerick: me too. :) |
| 15:03 | cemerick | I'm no minimalist, but complexity has to carry some commensurate power. |
| 15:07 | kotarak | for is a good example: (for [x abc :let [y (do-something x)] z fgh :when y w asd :while y] ...) packs a lot in the punch. (for [:let [foo bar] ...] ...) just for the sake of saving one surrounding let.... questionable. |
| 15:10 | rhickey | cemerick: I agree, and we'll have to see if it holds muster. My gut says it will have utility in those cases where you might not have direct access to the thing being destructured or the subsequent expansion, i.e. when binding forms flow through macros |
| 15:10 | spuz | cgrand: nice post today. I wonder, why does unrolling a function call get you such large performance gains? What did the original version of the code look like? |
| 15:11 | cemerick | rhickey: any example off the top of your head, what the workarounds were? |
| 15:13 | rhickey | well, for before it had let :) |
| 15:14 | rhickey | the workaround was adding let to for, would we have needed that? |
| 15:14 | rhickey | :let |
| 15:14 | chouser | :let is still a bit clumsy, what with the extra [] in there... |
| 15:15 | rhickey | that :let now seems like a special case workaround for exactly this, serving only one macro |
| 15:17 | rhickey | it's an example of where bindings are flowing along and you haven't access intermediately |
| 15:17 | rhickey | to install another let |
| 15:17 | chouser | 'let' is actually often the least compelling example for any sort of destructuring. for, doseq, and fn better |
| 15:17 | kotarak | rhickey:Well, it is only a problem in for, no? Not in let, fns, .... The only improvement there is (maybe) that you can do (let [[a (-> str b) (-> (foo b) c)] bla] ...). In which way is that better or worse than (let [[a b c] bla b (str b) c (foo c b)] ....) |
| 15:18 | rhickey | kotarak: for and doseq, and anything like them... |
| 15:19 | rhickey | also a very compelling macro target, again, where you don't control the expanded-into scope |
| 15:20 | rhickey | you need to perform a transformation but emit a single clause |
| 15:22 | nathanmarz | hey guys... if i have two lazy seqs, say something like (1 2 3 4 5 ...) and (0 1 2 3 4 ...), is there an easy way to "merge" them and produce something like ([1 0] [2 1] [3 2] [4 3] [5 4]...)? |
| 15:22 | cemerick | rhickey: if this *does* run the gauntlet, perhaps we can avoid -> at the very least. Having its last argument be a binding instead of the last function to be applied is perhaps the most grating issue, IMO. |
| 15:22 | kotarak | nathanmarz: (map vector seq1 seq2) |
| 15:24 | rhickey | cemerick: I disagree strongly, this is a binding form slot, where the fundamental 'function' is destructuring. |
| 15:24 | chouser | (let [(a str) 1] a) ==> "1" is perhaps more consistent, but definitely worse |
| 15:24 | nathanmarz | thank you |
| 15:25 | rhickey | reading (-> foo bar [a b c]) says to me - flow the destructuree through foo and bar before breaking up into a b c |
| 15:26 | rhickey | once we've taught the editors and IDEs to do local var coloring it will become clear :) |
| 15:27 | kotarak | Btw: is let in for really only a short-hand for a vector? (for [x [1 2 3] y [(str x)]] ...) vs (for [x [1 2 3] :let [y (str x)]] ...)? |
| 15:27 | rhickey | cemerick: so you'd just take parens off the table for any syntax? |
| 15:27 | rhickey | one of 3 grouping constructs? |
| 15:28 | rhickey | used here for function application during destructuring? |
| 15:28 | cemerick | rhickey: barring compelling use-cases, yes |
| 15:28 | cemerick | of course, compelling is relative |
| 15:29 | cemerick | IMO, destructuring is *structural*, thus the name. "function application during destructuring" is an oxymoron for me at the moment. |
| 15:29 | rhickey | what about :let in for, a plain workaround, the need for which will come up again? |
| 15:31 | cemerick | never having used :let in for. I tend to just use a nested let. |
| 15:31 | rhickey | you must have never needed the transformed value later in the for header |
| 15:32 | kotarak | rhickey: and even the workaround ([..]) is not impossible if really necessary |
| 15:32 | rhickey | kotarak: that is not a workaround |
| 15:32 | kotarak | rhickey: why not? |
| 15:34 | cemerick | rhickey: yeah, I rarely have more than 4 lines in a for, et al. -- a couple of seqs + a :when or :while. |
| 15:34 | lisppaste8 | Chouser pasted "example of -> destructuring" at http://paste.lisp.org/display/90605 |
| 15:35 | rhickey | kotarak: doesn't do the same job |
| 15:36 | chouser | I appreciate, for example, avoiding the tortured name mime-exts |
| 15:37 | Chousuke | hmm, that looks pretty neat. |
| 15:37 | cemerick | chouser: you mean (let [a (foo) a-str (str a)] ...)? |
| 15:38 | Chousuke | it might be a bit confusing initially though, given that -> and ->> are also macros |
| 15:39 | cemerick | Chousuke: no, don't you see, this will bring the locusts down from up on high!!!! :-P |
| 15:40 | chouser | but these aren't coincidentally named -> and ->> -- they're used outright in the implementation. |
| 15:40 | Chousuke | chouser: yeah, i noticed. clever :P |
| 15:40 | chouser | they mean the same, just a bit different context. |
| 15:41 | rhickey | for's :let is a perfect example of the gut case I made before, and a categoric one - should every construct that flows bindings provide a similar 'gap' to allow executable code to run? |
| 15:41 | Chousuke | cemerick: the way I see it, this just allows you to specify your own destructuring operations |
| 15:41 | rhickey | then think about a macro targeting for |
| 15:41 | rhickey | that needed to emit an inner :let |
| 15:41 | rhickey | aargh |
| 15:42 | Chousuke | splitting the string to mime-exts is just a part of the destructuring |
| 15:42 | lpetit | In the clojure syntax, does/can : (colon) prefix other things than keywords ? |
| 15:42 | rhickey | lpetit: no |
| 15:43 | lpetit | That is, if I want to do syntax coloring right for keywords even if just : (colon) is typed by the user, is it ok to consider it a keyword (or at least the start of a keyword) ? |
| 15:43 | Chousuke | ,(keyword? (symbol ":foo")); I think you can cheat though |
| 15:43 | clojurebot | false |
| 15:43 | Chousuke | but that's not supported :) |
| 15:43 | lpetit | I'm interested in literal keywords, btw :) |
| 15:43 | Chousuke | hmm |
| 15:43 | Chousuke | ,: |
| 15:43 | clojurebot | Invalid token: : |
| 15:44 | cemerick | Chousuke: yeah, I understand the mechanics. I just know that I'm confused looking at these things. Readability and consistency is a big deal for me, and I think this impacts both negatively. |
| 15:44 | lpetit | But how would you like your preferred editor to react :when you have just typed : (colon), do you want it to already apply the syntax coloration for keywords, or do you want it to apply no coloration since it's not yet a valid keyword |
| 15:44 | lpetit | ? |
| 15:45 | cemerick | Clearly, I'm not the intended audience, but I'm not looking forward to reading this in other people's code. |
| 15:45 | rhickey | cemerick: I don't know why it should occur in handwritten code any more often than :let in for |
| 15:45 | rhickey | but given this, we could eliminate :let in for and the need for any similar construct in any similar macro forever |
| 15:46 | lpetit | cemerick: this is a good functionality AFAIC, since it will allow me write a "warning problem marker" in eclipse if people abuse it in simple cases :-p |
| 15:46 | cemerick | lpetit: lol |
| 15:47 | cemerick | rhickey: we'll have to find out, of course. :let in for is a very niche widget, though -- this will be available in every binding-form everywhere. |
| 15:48 | lpetit | Joke apart, I think if the mechanism is totally orthogonal (and it seems to be the case), then it's worth having it |
| 15:48 | lpetit | But he, time will tell :) |
| 15:49 | Chousuke | cemerick: do you have any suggestions for a better syntax? |
| 15:49 | lpetit | So you did not answer my oh so more important question about the special case of handling single : (colon) syntax coloring in clojure editors ? |
| 15:49 | Chousuke | lpetit: can you have a delay in the colouring? |
| 15:50 | cemerick | Chousuke: nope, I'm just lobbing stones. I can definitely see the utility for macro writers, but I think it's simply not appropriate in user-land, so to speak. |
| 15:50 | Chousuke | lpetit: a single : is an error but you shouldn't flag it so immediately |
| 15:50 | lpetit | Chousuke: tell what you have in mind :) |
| 15:50 | Chousuke | lpetit: mostly because it's very likely to be followed soon by other characters that make it legal. |
| 15:50 | lpetit | Chousuke: cute, but no, not such sophistication for the moment (but I like it) |
| 15:51 | lpetit | Chousuke: we may well end up with this later, indeed : a quick syntax coloring, and when the user pauses for a long time, a more in depth syntax coloring, yes. |
| 15:51 | ziga` | write an editor for clojure in clojure or better - an IDE with debugger and all |
| 15:51 | lpetit | Chousuke: so ok you convinced me to do nothing for the moment :) |
| 15:52 | lpetit | ziga`: huh ? |
| 15:52 | ziga` | just kidding |
| 15:52 | Chousuke | for now it's more cost-effective to build upon existing IDEs anyway |
| 15:53 | Chousuke | though there is a Clojure editor I think. Was it called Waterfront or something? |
| 15:53 | lpetit | ziga`: there is room for anybody's contributions anyway, the door is not closed :) |
| 15:57 | cemerick | chouser: I'd suggest that if #211 is going in, we should add arbitrary fn application to map destructuring as well, if it's doable. |
| 15:58 | cemerick | e.g. (let [{ival .intValue} 5.0] ival) or (let [{ival (-> :a .intValue)} {:a 5.0}] ival), etc. |
| 15:58 | chouser | it's there. |
| 15:58 | chouser | er |
| 15:59 | kotarak | (defn p [string] (for [mime-exts (.split string ",") [mime exts] [(.split mime-exts ";")]] [(keyword mime) exts])), still not sure why I need :let in for besides it being sugar. |
| 16:00 | chouser | cemerick: (let [{(-> int ival) :a} {:a 5.0}] ival) ==> 5 |
| 16:02 | cemerick | chouser: ok -- I was trying to wiggle the host invocations in there. I've actually always thought being able to specify .getFoo in map destructuring would be super-useful, especially in :keys. |
| 16:02 | chouser | you can use .intValue in place of int there |
| 16:03 | cemerick | yeah, I'm talking about more straightforward usage like {a .getFoo b .getBar}, etc. |
| 16:07 | spuz | msg lpetit Hey |
| 16:07 | spuz | shit |
| 16:07 | hiredman | hah! |
| 16:07 | hiredman | I knew it! |
| 16:08 | lpetit | msg spuz Ho |
| 16:08 | lpetit | re -shit :-p |
| 16:08 | spuz | hiredman: that I'm retarded? I'm surprised you hadn't realised :p |
| 16:09 | hiredman | clojurebot: I knew it! is <reply>You know nothing! |
| 16:09 | clojurebot | Ack. Ack. |
| 16:44 | michaeljaaka | clojurebot: how are you? |
| 16:44 | clojurebot | with style and grace |
| 16:45 | michaeljaaka | clojurebot: what is the meaning of life? |
| 16:45 | clojurebot | what is wrong with you |
| 16:45 | mabes | it should answer with 42 |
| 16:45 | KirinDave | No |
| 16:46 | KirinDave | mabes: Pretty sure it answered your question correctly. |
| 16:48 | mabes | KirinDave: you mean michaeljaaka's question? |
| 16:48 | KirinDave | Well, yes. |
| 16:48 | hiredman | KirinDave: very philosophic |
| 16:48 | KirinDave | It answered the question correctly. |
| 16:57 | spuz | the meaning of life is what's wrong with me? |
| 17:03 | george | clojurebot: Am i handsome ? |
| 17:03 | clojurebot | It's greek to me. |
| 17:04 | george | clojurebot: what is your name ? |
| 17:04 | clojurebot | What is meta |
| 17:04 | nathanmarz | is there any sort of clojure function that acts like reduce but outputs all the intermediate values? |
| 17:04 | fanatico | If AI has taught us anything, the correct response to "what is the meaning of life?" is "why do you say what is the meaning of life?". |
| 17:05 | nathanmarz | by output i mean returns a lazy seq to the intermediate vals |
| 17:05 | chouser | nathanmarz: clojure.contrib.seq-utils/reductions |
| 17:05 | george | or should answer it with a philosofical meta referrence ... "the meaning is to find a meaning" |
| 17:06 | nathanmarz | chouser: thanks, nice and simple like usual |
| 17:06 | hiredman | clojurebot: why? |
| 17:06 | clojurebot | http://clojure.org/rationale |
| 17:07 | george | anyone knows how is the market for clojure ... i mean , for find a job ... |
| 17:07 | chouser | george: get a Java job. Then sneak Clojure in the back door. |
| 17:08 | chouser | if that doesn't work, get another Java job -- there are plenty to choose from. :-) |
| 17:08 | ohpauleez | In Philadelphia, there are currently two companies actively using clojure that I know of |
| 17:08 | ohpauleez | I'm pushing a third company to adopt it |
| 17:09 | george | chouser: Can i put java code in clojure as i was writing java code ? |
| 17:10 | chouser | george: not (usefully) in the same text file, but things defined in clojure and things defined in java can interact quite easily. |
| 17:11 | ohpauleez | george: and someone has created jsr233 bindings for clojure too |
| 17:11 | george | chouser: so i would have to start learning java ...=/ . It probably would be hard , after having fun with scheme ... |
| 17:12 | lpetit | george: maybe TeachScheme -> Reach Java may help : http://www.teach-scheme.org/ |
| 17:21 | george | lpetit: cool ... how do i get "How to Design Class Hierarchies" |
| 17:23 | Kjellski | What is the algorithm used to coordinate things in a transaction on refs? |
| 17:25 | Chousuke | Kjellski: As far as I know it's multiversion concurrency control but I don't know the details of the algorithm at all :P |
| 17:25 | _ato | Kjellski: http://clojure.org/refs |
| 17:25 | _ato | "The Clojure STM uses multiversion concurrency control with adaptive history queues for snapshot isolation, and provides a distinct commute operation. |
| 17:26 | _ato | that means little to me, but it's enough to google some papers on :) |
| 17:26 | Kjellski | Thanks a lot... and sorry for not digging clojure.org first... |
| 17:33 | hiredman | http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.105.3507&rep=rep1&type=url&i=0 <-- rhickey mentioned this paper on stm a while back |
| 17:34 | hiredman | anyway, http://delicious.com/clojurebot/rhickey |
| 17:34 | Kjellski | hiredman : thanks... I´ll save that one too |
| 18:02 | spuz | are there any articles that describe how Clojure implements lazy sequences? |
| 18:06 | spuz | When debugging a clojure application, it's pretty mind-bending to look at the call tree that is generated |
| 18:07 | Kjellski | ,(doc . |
| 18:07 | clojurebot | EOF while reading |
| 18:07 | Kjellski | ,(doc .) |
| 18:07 | clojurebot | Gabh mo leithscéal? |
| 18:07 | Kjellski | ,(doc .. |
| 18:07 | clojurebot | EOF while reading |
| 18:08 | Kjellski | ,(doc clojure.core/.) |
| 18:08 | clojurebot | Huh? |
| 18:08 | Kjellski | ,(doc clojure.core/..) |
| 18:08 | clojurebot | "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand." |
| 18:08 | hiredman | . is a special form, so there is no var for a docstring to hang on |
| 18:09 | hiredman | the clojure doc stuff has special handling for special forms, clojurebot's doc does not |
| 18:09 | Kjellski | hiredman : Your bot is not recognizing when closing parens aren´t out there... I´ve figured that from the sources... |
| 18:09 | hiredman | Kjellski: what? |
| 18:09 | Kjellski | ,(doc clojure.core/.. |
| 18:09 | clojurebot | EOF while reading |
| 18:09 | Kjellski | ,(doc clojure.core/..) |
| 18:09 | clojurebot | "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand." |
| 18:09 | hiredman | and? |
| 18:09 | Kjellski | ,(doc apply |
| 18:09 | clojurebot | EOF while reading |
| 18:10 | Kjellski | ,(doc apply) |
| 18:10 | clojurebot | "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq." |
| 18:10 | licoresse | jaha? |
| 18:10 | Kjellski | hiredman : huh? Sorry... thought that was somewhat different the last time I´ve tried that ..... |
| 18:17 | Kjellski | hiredman: the clojurebot accepts xxx-lookup? functions without closing parens? But gives EOF while reading? |
| 18:17 | hiredman | what? |
| 18:18 | Kjellski | hiredman : Is the "EOF while reading" from the clojurebot his indication of missing parens? |
| 18:20 | Chousuke | Kjellski: it's Clojure's indication of a missing closing paren :) |
| 18:20 | Chousuke | try (read-string "(+ 1 2") in a repl |
| 18:21 | Kjellski | Chousuke : aha! so, nevermind hiredman ... ^^ |
| 18:23 | Kjellski | Whatever, sleep well... =) cya |
| 18:24 | spuz | how can I tell whether a given function returns a lazy sequence or not? |
| 18:25 | spuz | say, for example, vec |
| 18:25 | hiredman | well |
| 18:25 | hiredman | vec returns a vector |
| 18:25 | hiredman | vectors are not sequences |
| 18:25 | hiredman | so a vector cannot be a lazy sequence |
| 18:25 | spuz | I see your point |
| 18:25 | spuz | what about say, rest |
| 18:26 | spuz | ,(class (range 10)) |
| 18:26 | hiredman | rest returns a sequence |
| 18:26 | clojurebot | clojure.lang.LazySeq |
| 18:26 | spuz | ,(class (rest (range 10))) |
| 18:26 | clojurebot | clojure.lang.ChunkedCons |
| 18:26 | spuz | What is a ChunkedCons...? |
| 18:27 | hiredman | spuz: why does it matter? |
| 18:27 | hiredman | you can call first and rest on it |
| 18:28 | hiredman | what else do you need? |
| 18:28 | spuz | hiredman: I want to know whether a function will evaluate the entire sequence that I pass to it |
| 18:28 | KirinDave1 | technomancy: Hey, is there more detailed docs on how to use leiningen? |
| 18:29 | hiredman | spuz: then read the docs |
| 18:29 | spuz | hiredman: for example, vec will evaluate all the elements of a sequence passed to it, but it doesn't tell me that in the docs |
| 18:29 | KirinDave1 | technomancy: Things like manipulating the classpath, etc. I'd like to use it and your clojure-http-client stuff, but figuring out the right way to go about doing that is kinda opaque to me. |
| 18:30 | hiredman | spuz: it should be obvious |
| 18:30 | hiredman | vectors are not lazy |
| 18:30 | hiredman | vec returns a vector |
| 18:30 | spuz | yes, but in general, is there a way to find out empirically? |
| 18:31 | hiredman | why? |
| 18:31 | technomancy | KirinDave1: docs are slim unfortunately. right now it works best with dependencies that are already published to a public repository, which clojure-http-client is not. |
| 18:31 | KirinDave1 | technomancy: What's the "right way™" to use something like clojure-http-client? |
| 18:31 | KirinDave1 | technomancy: Just roll it into src/ for now? |
| 18:32 | Chousuke | spuz: try the function on a seq that has side-effects. |
| 18:32 | technomancy | KirinDave1: yes, but I hope to have a better solution in a matter of days. |
| 18:32 | technomancy | you just caught me at an awkward time. =) |
| 18:32 | KirinDave1 | technomancy: well I think it's an awesome library |
| 18:32 | technomancy | I know _ato is working on a public repo service that should make this easier too. |
| 18:32 | technomancy | thanks |
| 18:32 | KirinDave1 | technomancy: Too bad github doesn't support it directly. |
| 18:32 | KirinDave1 | technomancy: Is there an easy way to modify the invocation classpath? |
| 18:33 | hiredman | ~latex \text{vec returns a vector}\\\text{vectors are not sequences}\\\text{since vec returns a vector, and vectors are not sequences, than vec cannot return a type (lazy) of sequence}\\QED |
| 18:33 | technomancy | KirinDave1: the clean way to do it would be jar it and put it in lib |
| 18:33 | technomancy | but that involves installing the clojure-pom project too, which is a hassle right now. |
| 18:33 | spuz | Chousuke: ok, but how do I evaluate the function? I can't type it at the repl as printing automatically evaluates a lazy sequence |
| 18:33 | technomancy | unfortunately the centralized maven repos are very slow-moving nad hard to get stuff into. |
| 18:33 | hiredman | undoubtly a misuse of qed |
| 18:34 | KirinDave1 | technomancy: Not to mention that lein seems to disagree with the maven repo about somethign that should be there. |
| 18:34 | technomancy | KirinDave1: how's that? |
| 18:34 | spuz | heh, does anyone use QED correctly? |
| 18:34 | KirinDave1 | technomancy: As lein deps on the sample repo currently fails for me |
| 18:34 | Chousuke | spuz: you can just try (do (f someseq) nil) |
| 18:34 | spuz | Chousuke: ok |
| 18:35 | technomancy | KirinDave1: there was a typo in the maven source repo URL, wipe your ~/.leiningen.jar and do a self-install again |
| 18:35 | Chousuke | spuz: but in general, most functions operating on seqs will be lazy |
| 18:35 | KirinDave1 | technomancy: Ah |
| 18:35 | Chousuke | spuz: vec produces a vector so it can't be lazy. :) |
| 18:35 | spuz | Chousuke: as hiredman has proved :) |
| 18:38 | KirinDave1 | technomancy: Well, okay. So… what's the way that I am to modify the classpath to include your code for tasks such as repl? |
| 18:38 | KirinDave1 | technomancy: If I have a submodule with clojure-http-client? |
| 18:39 | technomancy | KirinDave1: actually hang on; I might have this available in a public repo now that I think about it |
| 18:41 | technomancy | KirinDave1: I set this up a while ago and had forgotten about it: http://p.hagelb.org/project.clj.html |
| 18:41 | technomancy | but it should work |
| 18:42 | KirinDave1 | rad. |
| 18:43 | KirinDave1 | technomancy: That's awesome. |
| 18:43 | KirinDave1 | technomancy: I am curious tho, how you might go about doing things like extending the classpath or other salient environment settings for the default tasks. Seems like it could be important. |
| 18:44 | technomancy | KirinDave1: I'm of the opinion that the less the classpath varies on a per-project basis the better |
| 18:44 | KirinDave1 | technomancy: So, if it's not a public repo somewhere leiningen doesn't make it easy to use it? |
| 18:44 | technomancy | since any changes must be reflected in your build tool as well as Emacs or any other IDE contributors use |
| 18:45 | technomancy | KirinDave1: if it's not a jar, it's going to be more complicated. |
| 18:45 | KirinDave1 | For clj files it doesn't seem like it would be. |
| 18:45 | KirinDave1 | as long as you have the relative directory structures, I suppose. |
| 18:46 | technomancy | you can jar up clj files; that works fine. doesn't have to be AOT-compiled. |
| 18:47 | KirinDave1 | Okay, so let's say it is a jar? |
| 18:47 | technomancy | if it's a jar, you toss it in lib/ |
| 18:47 | KirinDave1 | You'd lob it in deps then? |
| 18:47 | KirinDave1 | Err lib, sorry |
| 18:47 | technomancy | it's a pretty standard convention that all jars in lib get globbed onto the classpath |
| 18:47 | technomancy | so all the IDEs etc. support it. |
| 18:47 | KirinDave1 | I can see that. |
| 18:48 | technomancy | much of this depends on it becoming easier to publish to a public repo in the future |
| 18:48 | technomancy | which I hope to help tackle once lein is somewhat stable and documented. |
| 18:49 | KirinDave1 | It'd be nice if github supported us the way that they do rubygems. :) |
| 18:49 | technomancy | it would... but considering they're moving gems off github it seems unlikely. |
| 18:49 | technomancy | but you know those guys, right? maybe you can talk them into it. =) |
| 18:50 | KirinDave1 | Unlikely. |
| 18:50 | KirinDave1 | But I could mention it. |
| 18:50 | KirinDave1 | I see Tom a lot less because of his jet-setting successful-startup lifestyle. :) |
| 18:50 | _ato | KirinDave1: I'm have a go it: http://clojars.org/ |
| 18:51 | KirinDave1 | _ato: That's awesome. |
| 18:52 | _ato | I'm going to get search working today and then release this afternoon or tomorrow |
| 18:52 | KirinDave1 | Wow, on the cusp! |
| 18:52 | technomancy | _ato: I'll race you to release. =) |
| 18:52 | _ato | bwaha |
| 18:53 | technomancy | wait, this afternoon? never mind. |
| 18:53 | _ato | technomancy: you decided to do a repo as well? |
| 18:53 | technomancy | _ato: that's old stuff from when I was using clojure-pom with maven |
| 18:56 | _ato | technomancy: you don't mind if I say Leiningen is the preferred way of using it right? (ie Leiningen is usable enough already) |
| 18:56 | technomancy | _ato: it's useful today if ill-documented. |
| 18:57 | technomancy | the main bummer is that mvn must be installed to install your project locally since that part still shells out =\ |
| 18:57 | technomancy | but the primary blocker to release is documentation |
| 18:58 | _ato | ah, ok. |
| 18:59 | _ato | I'll probably write up a tutorial for clojars.org that covers the basics of Leiningen as well |
| 18:59 | technomancy | end-user type projects generally won't need to install anyway; it's only an issue for library developers |
| 18:59 | technomancy | _ato: be sure to check with me before you do that; I may have something by then |
| 19:00 | _ato | ok |
| 19:02 | piccolin1 | Are you going to make leiningen eventually not use Maven? |
| 19:04 | technomancy | piccolino: it will not need maven installed, but it will bundle some parts of maven with it internally. but you shouldn't have to worry about that. |
| 19:04 | piccolino | Ah, cool. |
| 19:05 | piccolino | Are you going to keep it in ~/.leiningen.jar? |
| 19:06 | technomancy | piccolino: it'll probably go in ~/.m2/repository... haven't decided about that yet. |
| 19:06 | piccolino | 'k |
| 19:07 | technomancy | if you feel strongly, speak up. =) |
| 19:07 | piccolino | Oh, I don't have strong feelings about where it should be, other than that a hidden jar in the user's home directory feels wrong. |
| 19:07 | _ato | technomancy: oh yeah, that reminds me. how about a per-user config-file for leiningen, which you could add plugins (like swank or whatever) to so that you can use them without have to configure on a per-project basis? |
| 19:07 | technomancy | _ato: it will come with time, I'm sure |
| 19:08 | technomancy | but I'm not going to code it myself until I need it personally. |
| 19:08 | _ato | okay, no worries |
| 19:16 | annealer | hmm |
| 19:17 | annealer | so i just noticed scrollback involving clojars / leiningen |
| 19:17 | annealer | thought i'd throw out that... https://www.javagems.org/ |
| 19:17 | annealer | i'm on a similar endeavour, because maven is infuriating |
| 19:17 | gravity | Is there a standard place that people stick jars for their classpath? |
| 19:17 | annealer | it'd sure be nice if we could all work together on somethin' |
| 19:18 | _ato | annealer: ah interesting |
| 19:18 | gravity | Not having the equivalent of /usr/share/lib is weird to me |
| 19:18 | annealer | gravity: javagems installs to ~/.javagem/java by default |
| 19:18 | piccolino | Dude, I already failed on "READY" |
| 19:18 | annealer | (psa javagem is nowhere near production ready yet which is why i havent really publicised it) |
| 19:19 | gravity | heh, ok thanks :-) |
| 19:21 | annealer | piccolino: i can't tell if that was general smartassery or a slam against ruby or both! |
| 19:21 | notallama | can anyone explain why this doesn't work? (protocols) http://paste.lisp.org/display/90628 |
| 19:21 | piccolino | Well, neither. I tried the READY command, and it gave me an error. |
| 19:21 | piccolino | "could not find gem javagems locally or in a repository" |
| 19:21 | technomancy | annealer: would love to talk, but I can't until I get off work later today. efforts should definitely be coordinated. |
| 19:21 | annealer | piccolino: do you have gemcutter installed? some time tonight, gemcutter will become the official rubygems repo. like, 10pm tonight |
| 19:22 | annealer | technomancy: awesome. my email is gabriel.gironda@gmail.com, i'm gabrielg on github. we should coordinate |
| 19:22 | annealer | piccolino: until then, you need to "gem install gemcutter && gem tumble" |
| 19:22 | piccolino | Ah, no I do not, apparently. |
| 19:22 | piccolino | I've never used gem |
| 19:22 | annealer | i figured i'd leave that part out since.... it's an official change in a few hours anyway |
| 19:23 | piccolino | First I gotta upgrade my gem install, I guess. |
| 19:24 | annealer | _ato: as an example, something like this: http://gist.github.com/237420 works already |
| 19:25 | piccolino | Hey, I'm in Chicago too. |
| 19:25 | annealer | i'll be adding "javagem exec" tonight |
| 19:25 | annealer | piccolino: neat. we should get a beer some time |
| 19:25 | piccolino | Cool. |
| 19:29 | _ato | annealer: custom_require.rb:31:in `gem_original_require': no such file to load -- net/https (LoadError) |
| 19:29 | _ato | am I missing a ruby lib? |
| 19:29 | _ato | or wait.. do I need to run it with jruby? |
| 19:30 | Anniepoo | this is sweet |
| 19:30 | _ato | ah that looks like it |
| 19:32 | _ato | looks like it also doesn't compile clojure |
| 19:32 | _ato | but I get the idae |
| 19:32 | _ato | cool |
| 19:32 | _ato | what I like is that you can use it with C ruby so it has fast startup times |
| 19:35 | _ato | annealer: I thought about using gemcutter, but it seems important to be able to use maven-style repositories so you can use java libs without having to repackage anything |
| 19:35 | _ato | although I guess there's probably an easy way to convert maven stuff to gems |
| 19:52 | timothypratley1 | http://www.wakaleo.com/blog/237-more-groovy-magic-with-maven-pom-files <<< looks promising too :) |
| 20:48 | sh10151 | has anyone done anything to set up the slime repl's classpath from one that maven sets up? |
| 20:49 | danlarkin | sh10151: M-x swank-clojure-project |
| 20:49 | danlarkin | :) |
| 20:50 | sh10151 | hey, thanks |
| 20:50 | sh10151 | seems like something's broken with the prompt though |
| 20:50 | sh10151 | it prompts for a classpath |
| 20:50 | sh10151 | I hit ret to accept the default |
| 20:50 | sh10151 | newline appears in minibuffer |
| 20:50 | danlarkin | no it prompts for a project root |
| 20:51 | sh10151 | yeah, sorry |
| 20:51 | danlarkin | Ah, you have an old version of swank-clojure then |
| 20:51 | danlarkin | combined with not having i-do mode |
| 20:51 | danlarkin | (fixed bug) |
| 20:51 | tomoj | does ido not come with emacs? |
| 20:51 | sh10151 | will enabling ido work around? |
| 20:51 | danlarkin | if you don't want to upgrade the workaround is to call swank-clojure-mode directly: |
| 20:52 | danlarkin | M-x-: (swank-clojure-mode "...") |
| 20:52 | danlarkin | where ... is your project root |
| 20:53 | sh10151 | I'll give that a shot when emacs coms back to life |
| 20:53 | sh10151 | thanks for the pointers |
| 20:53 | danlarkin | it will hang forever |
| 20:53 | sh10151 | yep, I think I have noticed this behavior in other modes too |
| 20:54 | sh10151 | I should probably just upgrade actually |
| 20:54 | danlarkin | i-do has a bug/annoying feature where if you call the ido directory chooser and you don't have ido-mode on then the minibuffer hangs like that |
| 20:57 | sh10151 | hm, the clojure-update automagic seems to be confused by the git output |
| 20:57 | sh10151 | wish I knew the first thing about git |
| 21:11 | sh10151 | oof, blind update hurts ... M-x slime -> "Symbol's value as variable is void: package-activated-list" |
| 21:12 | sh10151 | old clojure-mode I guess |
| 21:18 | sh10151 | nope, still a failure |
| 21:38 | sh10151 | Well, M-x slime is working but M-x swank-clojure-project says clojure/main class not found |
| 21:40 | _ato | sh10151: you've got clojure.jar in yourprojectdir/lib right? |
| 21:42 | sh10151 | was hoping it'd get it from pom |
| 21:42 | sh10151 | but looking at the implementation that appears not to be the case |
| 21:42 | _ato | I don't think swank-clojure reads the pom |
| 21:43 | sh10151 | nope, just makes assumptions based on its existence |
| 21:43 | _ato | I think mvn dependency:copy-dependencies or some such should copy over the libs in the pom |
| 21:45 | sh10151 | yep, it did |
| 21:46 | sh10151 | is clojure/main right for clojure-1.0.0 ? |
| 21:48 | _ato | not sure.. the earliest jar I've got handy is 1.0.1-alpha.. it works in that |
| 21:49 | sh10151 | I think it's probably still ok and I still don't have the right classpath somehow |
| 21:50 | sh10151 | gonna debug swank-clojure-project to see |
| 21:52 | sh10151 | it has target/dependency in its list of directories |
| 21:52 | sh10151 | but it doesn't walk it for jars |
| 21:52 | sh10151 | bug or user error? |
| 21:53 | _ato | could be a bug, not sure I haven't tried it with a maven project |
| 21:53 | _ato | how about just symlinking target/dependency to lib/ |
| 21:54 | sh10151 | will try |
| 21:54 | sh10151 | every time |
| 21:54 | sh10151 | I have to do man ls to look at argument order |
| 21:54 | annealer | _ato: i considered the repackaging thing, and honestly, i think i'm ok with it, as long as we can automate it. which i bet we can |
| 21:54 | annealer | it seems almost trivial to turn a jar into a gem |
| 21:54 | sh10151 | sorry, "man ln" |
| 21:55 | _ato | ln -s target/dependency lib |
| 21:55 | sh10151 | yep |
| 21:55 | sh10151 | that worked, so I'm going to call it an oversight in swank-clojure-project |
| 21:56 | sh10151 | target/dependency is in a list of other dirs containing .class files |
| 21:56 | sh10151 | but it should be treated like lib |
| 21:56 | _ato | yeah, it's likely. I don't think technomancy uses maven for clojure stuff much |
| 21:56 | sh10151 | wish I didn't :-P |
| 21:57 | sh10151 | though really for the crazy long classpaths people are installing at work, it helps a little I guess |
| 21:57 | sh10151 | Mule imports the world basically |
| 21:58 | _ato | sh10151: have you tried leiningen? http://github.com/technomancy/leiningen |
| 21:58 | sh10151 | now that is a witty name |
| 21:59 | sh10151 | haven't tried it, but I will bookmark it in case I convince more people to ditch Groovy for Clojure |
| 21:59 | sh10151 | already have been working over a few people :-D |
| 22:00 | _ato | :D |
| 23:15 | technomancy | oh, did I miss him? dang. |