2010-10-15
| 00:10 | hiredman | clojurebot: scala is <reply>see: http://harrah.github.com/browse/samples/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala.html#65760 |
| 00:10 | hiredman | ping? |
| 00:10 | clojurebot | PONG! |
| 00:15 | _rata_ | how can I have multiple mutually-referencing objects in one atom? |
| 00:29 | LauJensen | Good morning all |
| 00:36 | kmc | hi LauJensen :) |
| 00:37 | notsonerdysunny | Good morning LauJensen |
| 00:37 | notsonerdysunny | does any of you have trouble with logging into clojuredocs.org? |
| 00:38 | notsonerdysunny | if I try to login with my google-openid it very often hangs.. I would be lucky if I get in.. |
| 00:41 | LauJensen | Never even heard of clojuredocs until now :) |
| 00:42 | notsonerdysunny | I think it would be a nice place to contribute while we learn to use the stuff ourselves |
| 00:42 | notsonerdysunny | It has been around for a while now |
| 00:43 | notsonerdysunny | we can add the things which we try out as examples for others to see and learn |
| 00:43 | notsonerdysunny | very nice model I think |
| 00:44 | LauJensen | Just signed in without any problems |
| 00:45 | LauJensen | Interesting project |
| 00:45 | notsonerdysunny | :) thats nice .. |
| 00:45 | notsonerdysunny | but I have trouble |
| 00:45 | notsonerdysunny | did you use your google openid? |
| 00:47 | LauJensen | I dont think I got it from google, just openid.com |
| 00:49 | ohpauleez | ,(isa? #{1} #{}) |
| 00:49 | clojurebot | false |
| 00:49 | ohpauleez | ,(isa? #{} clojure.lang.PersistentHashSet) |
| 00:49 | clojurebot | false |
| 00:49 | ohpauleez | According to the doc, this only works if they are = |
| 00:49 | notsonerdysunny | ,(supers (class #{})) |
| 00:49 | clojurebot | notsonerdysunny: Gabh mo leithscéal? |
| 00:49 | notsonerdysunny | ->(supers (class #{})) |
| 00:49 | sexpbot | ⟹ #{clojure.lang.IObj clojure.lang.IFn clojure.lang.Seqable java.util.Set clojure.lang.IPersistentCollection java.lang.Runnable clojure.lang.Counted java.lang.Object clojure.lang.IEditableCollection clojure.lang.APersistentSet clojure.lang.IMeta clojure.lang.AFn java.io.Serializable clojure.lang.IPers... http://gist.github.com/627632 |
| 00:52 | ohpauleez | So how do you see if a child is the same type/subtype? |
| 00:52 | ohpauleez | Do I just do = on type()? That seems too verbose |
| 00:56 | amalloy | morning all |
| 01:02 | LauJensen | morning amalloy |
| 01:16 | kmc | hi amalloy |
| 01:16 | ohpauleez | good morning amalloy |
| 01:24 | kmc | a friendly bunch here |
| 01:24 | kmc | more greetings than other channels :) |
| 01:24 | amalloy | i know! it's almost like i'm living the dream of my youth: have friends |
| 01:25 | kmc | haha |
| 01:26 | ubii | anyone going to clojure-conj? |
| 01:32 | amalloy | apparently it's going to be more like an identity than a conj... |
| 01:39 | ubii | just curious how many attendees they planned for |
| 01:39 | ubii | looks like they still have some tickets left |
| 01:39 | amalloy | i suspect a lot of the people who are going are in bed |
| 01:40 | amalloy | since it's late at the conj site |
| 01:40 | ubii | yep, figured |
| 01:40 | ubii | will ask again in the morning |
| 01:44 | kmc | north carolina eh |
| 01:45 | kmc | $350 eh |
| 01:45 | kmc | err $250 |
| 01:45 | amalloy | kmc: you're on the east coast. you could practically walk there |
| 01:46 | kmc | Walking directions to Durham, NC: VA-49 S. 697 mi. 9 days 4 hours |
| 01:46 | amalloy | and the conj starts...in about 10 or 11 days? |
| 01:46 | hiredman | 8 |
| 01:47 | amalloy | kmc: better get walking |
| 01:47 | replaca | ubii: yeah. I'm going. why? |
| 01:48 | ubii | was just curious how big of a crowd they were expecting, as I am thinking of going |
| 01:48 | replaca | I think it's going to be about 200. |
| 01:48 | ubii | wow, bigger than what I thought |
| 01:48 | replaca | That should be a really nice size gorup |
| 01:49 | replaca | Lots of interaction between folks |
| 01:49 | replaca | I think it's going to be a lot of fun. (Assuming you're a geek like the rest of us ;)) |
| 01:51 | ubii | 20+ years in IT, guess that makes me geek enough :) |
| 01:51 | ubii | just wish that I would have found out about the conference sooner, so I could have made arrangement to go |
| 01:52 | ubii | s/arrangement/arrangements |
| 01:53 | replaca | well, we'll miss you. |
| 01:53 | replaca | I know they did everything they could think of to make sure interested floks would know about it |
| 01:54 | replaca | *folks - wow I'm tired tonight :) |
| 01:55 | ubii | well, I have have been so busy with work the last 9 months or so that I haven't been able to do much with clojure lately, hence the reason I just found out about the conference |
| 01:56 | replaca | yeah, I've hd that sort of thing happen to me as well |
| 01:56 | replaca | luckily not this time |
| 01:57 | ubii | been stuck doing mostly ruby, html, css, and javascript, when I would prefer to have been working with clojure :( |
| 01:57 | replaca | still only a few clojure jobs out there, but there are beginning to be more and more |
| 01:58 | _ato | heheh, you can do much worse than having to work in Ruby :-) |
| 01:58 | replaca | ain't that the truth |
| 01:58 | ubii | just started to force myself to spend what little extra time I have to continue to learn clojure and hopefully start using it in the work that I do |
| 02:00 | ubii | true, I could be stuck doing .Net development |
| 02:00 | ubii | or COBOL, like what my wife does :) |
| 02:00 | Crowbar7 | ohh christ COBAL\ |
| 02:01 | ubii | hmm, I wonder which would be more painful, visual basic or COBOL? |
| 02:01 | Scriptor | I don't think vb is that bad at all nowadays |
| 02:01 | amalloy | perl-compatible basic cobol-script |
| 02:02 | ubii | what little vb experience I have was from the pre .Net days |
| 02:03 | ubii | have had to work with C# and ASP.NET a bit and really did not like it |
| 02:03 | Crowbar7 | the .net is better the nthe PHP I have to use |
| 02:04 | Crowbar7 | wtf PHP calling classes starts with the same sign as a variable |
| 02:04 | Scriptor | calling classes? |
| 02:04 | Crowbar7 | $class->function |
| 02:04 | Scriptor | so you mean method calls? |
| 02:04 | Crowbar7 | yeah |
| 02:04 | Crowbar7 | sorrt |
| 02:04 | Scriptor | or class::function() |
| 02:04 | amalloy | Crowbar7: you mean $object->function? class::function() |
| 02:04 | Crowbar7 | more or less yeah |
| 02:05 | Scriptor | well, that makes sense |
| 02:05 | amalloy | yeah |
| 02:05 | Scriptor | an object is a variable, and you're calling a method on that object |
| 02:05 | amalloy | not standing up for php's $ syntax here, but it's totally consistent |
| 02:05 | Scriptor | one of the few times it *is* consistent, mind you |
| 02:06 | Crowbar7 | what is not consistant is it's function naming scheme for core functins |
| 02:06 | Crowbar7 | functions |
| 02:06 | ubii | have to say that I would take Perl over PHP |
| 02:06 | Crowbar7 | ^^ |
| 02:06 | Scriptor | I'd definitely take Perl 6 |
| 02:06 | Crowbar7 | I would take JAVA even over PHP |
| 02:07 | Scriptor | eh, I think I'd prefer dynamic languages for web dev |
| 02:07 | Crowbar7 | I hate it so much, but maybe working with it 80% of the time does not help. |
| 02:07 | LauJensen | Did you guys try #clojure-casual ? :) |
| 02:07 | Crowbar7 | :0 |
| 02:07 | Crowbar7 | p |
| 02:07 | Crowbar7 | :p |
| 02:08 | Crowbar7 | I'm going to try writing an asterisk lib in clojure just for fun to be honest. |
| 02:08 | Crowbar7 | if it actually works I might put it in clojars |
| 02:10 | ubii | LauJensen: sorry, we will stop yacking about these other inferior languages :) |
| 02:14 | ubii | I wonder if there are any plans to record the presentations and make them available online, for folks who are not able to attend the conference |
| 02:15 | LauJensen | np |
| 02:15 | amalloy | ubii: i heard someone say yes, or slides at least, but that is a non-authoritative answer |
| 02:15 | LauJensen | ubii: It has been requested by several Europeans, but I dont know if the host can make it happen yet |
| 02:19 | ubii | it would be cool, if they could, as I am not sure that I will be able to make it to the conference |
| 02:19 | Bahman | Hi all! |
| 02:19 | amalloy | hey, this is a nice feature. i can attach :arglists metadata even to vars that aren't explicitly functions |
| 02:20 | LauJensen | Bahman: Hey |
| 02:21 | Bahman | LauJensen: Hey. |
| 02:23 | ubii | hmm, the conference is an 18 hour drive from where I live and if I drive 120mph, than that is only a mere 9 hours :) |
| 02:25 | ubii | actually, I would fly, but I am sure that with it only a week away, that the flights will be pricey |
| 02:26 | amalloy | hrm. i found some of my old code which is doing (apply concat (for ...)). can anyone think of a reason not to use mapcat there? |
| 02:33 | Derander | I'm coming from ruby. I see the analogues of most of the sequence manipulation stuff I'm used to. Map, reduce, some, all good stuff. I cannot for the life of me find "each" though |
| 02:33 | replaca | ubii: you might be right, but why not check anyway. You might be surprised |
| 02:33 | Derander | How can I call a function on each element of a list? |
| 02:34 | replaca | ubii: especially if you stay over sat. night |
| 02:34 | amalloy | Derander: that's the same as map, in a functional language |
| 02:34 | ubii | replaca: not too worried about the cost of the flight, the biggest concern is the lack of available rooms at the Hilton |
| 02:34 | ubii | looks like they are completely booked on the 21st and 22nd |
| 02:34 | amalloy | ie, if the function you want to call doesn't have side effects |
| 02:34 | Derander | amalloy: even if I don't care what the return values are? |
| 02:35 | amalloy | Derander: the idiomatic way then would be doseq |
| 02:35 | replaca | ubii: yeah, probably means you'd want to look around for a cheap car, unless there's another hotel right next door |
| 02:35 | Derander | amalloy: aaahaaaaaa. |
| 02:35 | amalloy | ,(doseq [x (range 3)] (print x)) |
| 02:35 | clojurebot | 012 |
| 02:35 | replaca | I don't know the area, but you might want to check that out |
| 02:35 | Derander | amalloy: thanks, I didn't look under "force evaluation of sequence" in the clojure api |
| 02:35 | Derander | that's exactly what I want |
| 02:36 | ubii | replaca: I will look into my options in the morning |
| 02:36 | amalloy | Derander: the other possible solutions are dotimes, doall, and dorun, depending on what data structure you already have |
| 02:36 | amalloy | (anything with side effects either starts with do, or ends with !, as a general rule) |
| 02:36 | clojurebot | () invokes the form inside, but there is an implied str call. The semantics are different inside the interpolated string, necessarily so. |
| 02:36 | Derander | good to know |
| 02:36 | amalloy | clojurebot: wtf? |
| 02:36 | clojurebot | I don't understand. |
| 02:37 | Derander | I am writing a queueing doodad. It pulls a list of changed files and dispatches them to callbacks |
| 02:37 | Derander | and I was just trying to figure out a way to actually call the goddamn function |
| 02:37 | Derander | s |
| 02:37 | amalloy | hahaha |
| 02:37 | amalloy | ,(doc dorun) |
| 02:37 | zkim | ola |
| 02:37 | clojurebot | "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil." |
| 02:38 | amalloy | is probably better than doseq for your case |
| 02:39 | Derander | amalloy: I have a list of files that have changed that I want to pass off to another handling function |
| 02:39 | amalloy | ,(let [x (map println (range 4))] true) |
| 02:39 | clojurebot | true |
| 02:39 | LauJensen | Worth a read: http://stackoverflow.com/questions/3906276/whats-the-difference-between-cake-and-leiningen#3939930 |
| 02:39 | amalloy | ,(let [x (map println (range 4))] (dorun x) true) |
| 02:39 | clojurebot | true |
| 02:39 | clojurebot | 0 1 2 3 |
| 02:39 | Derander | from my brief reading, isn't dorun more for force-generating a lazy sequence? |
| 02:39 | Derander | yeah, my list isn't lazy |
| 02:39 | amalloy | if your list isn't lazy, then what's the problem? |
| 02:40 | Derander | well, I'm not sure how to call a function on each element of a list in clojure |
| 02:40 | Derander | in ruby I'd say [1,2,3].each {|e| puts e} |
| 02:40 | amalloy | sure |
| 02:40 | amalloy | in clojure it would usually be map, but map is lazy |
| 02:40 | Derander | oooooooooh |
| 02:40 | amalloy | or, you could use doseq to construct the map and consume it all at once |
| 02:41 | amalloy | or, use map to make it, and dorun to force it |
| 02:41 | Derander | okay. I was missing that part |
| 02:41 | Derander | in ruby I'd only use map if I wanted to transmute a seq |
| 02:41 | LauJensen | amalloy: doseq to construct the map ? |
| 02:41 | amalloy | LauJensen: to uh...construct the seq |
| 02:42 | amalloy | oh |
| 02:42 | LauJensen | with doseq which is intended for side effects? |
| 02:43 | amalloy | ,(doseq [x (range 4)] (print x)) |
| 02:43 | amalloy | ,(dorun (map print (range 4))) |
| 02:43 | clojurebot | 0123 |
| 02:43 | clojurebot | 0123 |
| 02:43 | amalloy | are the two things i'm suggesting |
| 02:43 | Derander | all is well now |
| 02:43 | amalloy | yeah, but now LauJensen is telling me i'm wrong |
| 02:43 | Derander | superfically doseq does what I want it to without any extra code |
| 02:44 | amalloy | yeah, i think doseq is a drop-in replacement for each |
| 02:44 | LauJensen | amalloy: Im just saying, doseq is for side-effects, so if you actually want to generate a return, use 'for'. Otherwise you're back in imperative land |
| 02:44 | LauJensen | its the word 'generate' that doesnt fit |
| 02:44 | LauJensen | ,(doseq [x (range 5)] x) |
| 02:44 | amalloy | LauJensen: which is why i said generate *and consume* |
| 02:44 | clojurebot | nil |
| 02:44 | LauJensen | ,(for [x (range 5)] x) |
| 02:44 | clojurebot | (0 1 2 3 4) |
| 02:44 | kmc | you could use dorun with map, right? |
| 02:44 | LauJensen | kmc: sure |
| 02:44 | amalloy | kmc: yeah, i suggested that |
| 02:44 | kmc | ,(dorun (map print [1 2 3])) |
| 02:45 | Derander | (doseq [file (filter #(>= 0 (.compareTo last-check (Date. (last-modified %)))) (list-desktop-files))] (process file)) is the code that I'm running |
| 02:45 | clojurebot | 123 |
| 02:45 | kmc | ah, i missed it |
| 02:45 | LauJensen | amalloy: nothing is generated, its a naive loop |
| 02:45 | kmc | ,(defn mapM_ [f & xs] (doseq (apply map f xs))) ;) |
| 02:45 | clojurebot | DENIED |
| 02:45 | amalloy | ,(doc pos?) ; Derander might want this instead of >= 0 |
| 02:45 | clojurebot | "([x]); Returns true if num is greater than zero, else false" |
| 02:46 | Derander | amalloy: unless the doc lies, that doesn't include zero |
| 02:46 | Derander | yeah, I need it |
| 02:46 | amalloy | oh right |
| 02:46 | Derander | it'd be a sweet replacement otherwise |
| 02:47 | Derander | sweeet. now all I have to do is write my callbacks |
| 02:48 | amalloy | LauJensen: how is that semantically different from a lazy seq, which never realizes more than one element at a time? |
| 02:48 | amalloy | Derander: the plumbing is done, now all i have to do is build a house? |
| 02:49 | Derander | exactly |
| 02:49 | Derander | the fun part |
| 02:49 | amalloy | true that |
| 02:49 | Derander | first clojure project: engage |
| 02:51 | amalloy | Derander: hosting it on github? |
| 02:51 | Derander | if I ever finish anything |
| 02:51 | Derander | right now it's all over 10 lines of code |
| 02:51 | Derander | all of |
| 02:52 | amalloy | heh, i shared a repo that was only 8 lines the other day |
| 02:52 | Derander | :P |
| 02:53 | amalloy | i like to get version control as soon as there's a single line, because i tend to mess stuff up and then forget how to fix it |
| 02:53 | LauJensen | amalloy: How is what different? |
| 02:53 | Chousuke | you should at least make a local git repo :P |
| 02:53 | amalloy | LauJensen: a simple loop/recur |
| 02:53 | Chousuke | it's easy to push to github later |
| 02:54 | LauJensen | amalloy: loop/recur vs doseq are similar in that you can have local changes, ie side-effects. Its not what I would call idiomatic to functional programming however (though can still be pure) |
| 02:55 | amalloy | LauJensen: oh for sure, avoid them if at all possible |
| 02:56 | LauJensen | amalloy: Yea, and rarely is it not possible. Most loop/recur cans be replaced by reduce, unless you need short-circuiting of some kind. doseq shouldnt be used for any kind of generation, only side-effects |
| 02:56 | Derander | okay, I'm sorry |
| 02:57 | amalloy | haha |
| 02:57 | Derander | if I have a list of conditions that I want to check against, how should I iterate through them idiomatically? |
| 02:57 | Derander | (filter #(and (not (= ".DS_Store" %)) (not (= ".localized" %))) (seq files))) is the current line |
| 02:57 | Derander | gargh. it's so mind bending |
| 02:57 | LauJensen | looks good |
| 02:57 | amalloy | do you want the first true one, or all of them or what? |
| 02:58 | Derander | I want it to do that, but I want to have a lot more files that I'm blacklisting |
| 02:58 | Derander | basically I want to be able to pull from a list, (".DS_Store" ".localized" "screw_this_file") |
| 02:58 | Derander | can I do something like (not (in bad-word-list file))? |
| 02:58 | amalloy | ,(not-any? #{'a 'q 7} [4 6 8 0]) |
| 02:58 | clojurebot | true |
| 02:58 | amalloy | ,(not-any? #{'a 'q 7} [4 6 'q 0]) |
| 02:58 | clojurebot | false |
| 02:58 | Derander | oh. |
| 02:58 | Derander | gah. |
| 02:58 | Derander | sorry to waste your time |
| 02:59 | amalloy | haha no |
| 02:59 | amalloy | it's fun |
| 02:59 | LauJensen | Derander: you can put your criteria in another function (filter meets-requirements? seq) |
| 02:59 | amalloy | plz ask moarrrr |
| 02:59 | LauJensen | afk |
| 02:59 | amalloy | Derander: my not-any? is using a set #{1 5 6} as a function |
| 02:59 | Derander | amalloy: yeah |
| 02:59 | amalloy | when called as a function, sets check whether they contain the argument passed |
| 03:00 | amalloy | k |
| 03:01 | Derander | okay, trying to write my own version |
| 03:01 | amalloy | all righty. don't hesitate to ask for as much or as little advice as you want |
| 03:02 | Derander | well, I've got another question |
| 03:02 | Derander | when should I use a set vs a list? |
| 03:02 | Derander | the docs don't state the performance characteristics |
| 03:02 | Derander | lists are just linked lists, aren't they? |
| 03:02 | amalloy | lists are just linked lists, yes |
| 03:02 | Derander | are sets faster for lookup? |
| 03:02 | amalloy | sets are arrays when they're small, and trees when they're big |
| 03:03 | Derander | oooh, they're sneaky. |
| 03:03 | Derander | basically I'm wondering if I shouldn't make my list of bad files a set |
| 03:03 | Derander | because then I get the nifty syntax which you used in your example above |
| 03:03 | amalloy | you should, 100%, because of the way sets act as predicates |
| 03:03 | Derander | alright then |
| 03:04 | Derander | seems to work |
| 03:04 | Derander | sweet. |
| 03:04 | amalloy | the other thing you should consider (though not for this usage) is vectors, which are often better at being lists than lists are |
| 03:05 | Derander | I have noticed an abundance of vectors in clojure code that I read |
| 03:05 | Derander | I never use them because I'm used to elisp |
| 03:05 | amalloy | you want a summary of the difference between vecs and lists? |
| 03:05 | tobiasraeder | Morning everybody :) |
| 03:05 | Derander | amalloy: if you write it I'll read it |
| 03:05 | amalloy | heh |
| 03:07 | amalloy | lists have fast insert/delete at the front, O(n) random-access, and slow-but-not-awful insertion/deletion from the middle |
| 03:07 | Derander | okay |
| 03:07 | amalloy | vectors have fast insert/delete at the back, O(1) random access, and awful insert/delete from anywhere else |
| 03:08 | Derander | so basically linked list vs array |
| 03:08 | amalloy | not quite, because arrays don't have fast appends |
| 03:08 | Derander | oh, right. |
| 03:08 | amalloy | and clojure lists don't have fast appends, unlike linked lists |
| 03:09 | Derander | alright, thank you. that helps |
| 03:09 | amalloy | because the list is immutable, it can't just tack something onto the end of the list; it has to copy every object in the chain to give it a new next pointer |
| 03:09 | Derander | oooooooooooooh. I was wondering why. |
| 03:09 | amalloy | tricky, isn't it |
| 03:10 | Derander | I am very unused to immutable data structures |
| 03:10 | amalloy | so was i, three months ago :P |
| 03:10 | amalloy | but having vectors&lists is nice. for something that in elisp/CL you would have to build in backwards order and then reverse at the end, in clojure you can just build with a vector instead of a list |
| 03:11 | Derander | makes sense |
| 03:11 | amalloy | rich's immutable datastructures are the masterworks that make clojure possible |
| 03:12 | kmc | you can fast-append to the beginning, but not the end, of a persistent singly-linked list |
| 03:12 | kmc | i'm not sure whether Clojure's lists have this property |
| 03:12 | kmc | amalloy, indeed, i was so excited when i first heard about hash tries |
| 03:13 | amalloy | kmc: they do have this property |
| 03:13 | Derander | thank you for the information. I need to go to sleep now or I'll be worthless for programming tomorrow |
| 03:13 | kmc | has anyone here read Okasaki's book _Purely Functional Data Structures_? |
| 03:13 | Derander | Adiós |
| 03:13 | amalloy | buenas noches |
| 03:14 | amalloy | holy cow, the source for doseq is monstrous |
| 03:15 | amalloy | and for is even worse |
| 03:26 | amalloy | ,(let [times (atom 0)] (dorun (pmap (memoize #(do (swap! times inc) (Thread/sleep 2000) %)) (repeat 10 1))) @times) |
| 03:26 | clojurebot | java.lang.Exception: No such namespace: Thread |
| 03:27 | amalloy | ,(let [times (atom 0)] (dorun (pmap (memoize #(do (swap! times inc) (. java.lang.Thread sleep 2000) %)) (repeat 10 1))) @times) |
| 03:27 | clojurebot | 4 |
| 03:28 | amalloy | does anyone know a way to make pmap/memoize smarter? it's wasting cpu resources computing the same function four times in an attempt to memoize it |
| 03:30 | Chousuke | I suppose you could add a lock or something, so it blocks if the cache is being updated |
| 03:30 | raek | ,(let [times (atom 0), f (memoize #(do (swap! times inc) (. java.lang.Thread sleep 2000) %)), _ (f 1)] (dorun (pmap f (repeat 10 1))) @times) |
| 03:30 | clojurebot | 1 |
| 03:31 | Chousuke | btw, (. java.lang.Thread sleep 2000) is better written as (Thread/sleep 2000) |
| 03:31 | amalloy | Chousuke: see above. i tried that but clojurebot doesn't like it |
| 03:32 | Chousuke | ah, right. |
| 03:33 | amalloy | wasn't sure whether he was annoyed by the / or the lack of java.lang so i just switched both |
| 03:33 | amalloy | ,Boolean/TRUE |
| 03:33 | clojurebot | true |
| 03:33 | amalloy | ,(Boolean/valueOf "true") |
| 03:33 | clojurebot | true |
| 03:34 | amalloy | man wth clojurebot? why not Thread/sleep? |
| 03:34 | Chousuke | It might just be doing some security checks. |
| 03:34 | Chousuke | and failing :p |
| 03:34 | amalloy | heh |
| 03:34 | raek | ,Thread |
| 03:34 | clojurebot | #<clojurebot$eval4127$fn__4128 hiredman.clojurebot$eval4127$fn__4128@7c31af> |
| 03:34 | amalloy | ,(java.lang.Thread.) |
| 03:34 | clojurebot | #<Thread Thread[Thread-1856,5,main]> |
| 03:35 | Chousuke | huh, why does Thread return a function |
| 03:35 | amalloy | ,(meta (var Thread)) |
| 03:35 | clojurebot | {:ns #<Namespace sandbox>, :name Thread} |
| 03:36 | Chousuke | ,(Thread) |
| 03:36 | clojurebot | java.lang.Exception: DENIED |
| 03:36 | amalloy | heh |
| 03:36 | Chousuke | I suppose Clojurebot is using the interpreter. |
| 03:36 | raek | -> (Thread/sleep 1000) |
| 03:36 | sexpbot | java.lang.SecurityException: Code did not pass sandbox guidelines: () |
| 03:37 | amalloy | ->(. Thread sleep 1000) |
| 03:37 | sexpbot | java.lang.SecurityException: Code did not pass sandbox guidelines: () |
| 03:38 | amalloy | exciting. can we inject code to clojurebot by instantiating a Thread with some unsafe Runnable object? |
| 03:38 | raek | ,(def x 5) |
| 03:38 | clojurebot | DENIED |
| 03:39 | raek | ,(java.lang.Thread. (fn [] (def x 5))) |
| 03:39 | clojurebot | DENIED |
| 03:40 | raek | ,(-> x def) |
| 03:40 | clojurebot | DENIED |
| 03:41 | raek | ,((resolve (symbol "eval")) '(+ 1 2)) |
| 03:41 | clojurebot | 3 |
| 03:41 | amalloy | raek: slick |
| 03:42 | amalloy | but i think it maps eval to a safer eval |
| 03:43 | raek | ,((resolve (symbol "eval")) (read-string "(def x 5)")) |
| 03:43 | clojurebot | #'sandbox/x |
| 03:43 | raek | ,((resolve (symbol "eval")) (read-string "(ns-unmap 'sandbox 'Thread)")) |
| 03:43 | clojurebot | nil |
| 03:43 | raek | ,(Thread/sleep 1000) |
| 03:43 | clojurebot | java.lang.Exception: No such namespace: Thread |
| 03:43 | amalloy | ,Thread |
| 03:43 | clojurebot | java.lang.Exception: Unable to resolve symbol: Thread in this context |
| 03:44 | amalloy | ,(. Thread sleep 1000) |
| 03:44 | clojurebot | java.lang.Exception: Unable to resolve symbol: Thread in this context |
| 03:45 | raek | ,((resolve (symbol "eval")) (read-string "(import 'java.lang.Thread)")) |
| 03:45 | clojurebot | java.lang.Thread |
| 03:45 | amalloy | ,(proxy [java.lang.Thread] []) |
| 03:45 | clojurebot | java.lang.IllegalStateException: Var null/null is unbound. |
| 03:47 | amalloy | ,(. java.lang.Thread sleep 100) |
| 03:47 | clojurebot | nil |
| 03:49 | amalloy | ,(.join (. java.lang.Thread (currentThread)) 100) |
| 03:49 | clojurebot | nil |
| 03:49 | amalloy | ,(.join (. java.lang.Thread (currentThread)) 30000) |
| 03:49 | clojurebot | Execution Timed Out |
| 03:53 | amalloy | ,(let [threads (make-array java.lang.Thread 20)] (. java.lang.Thread enumerate threads) (dorun (map print threads))) |
| 03:53 | clojurebot | #<Thread Thread[main,5,main]>#<Thread Thread[pool-1-thread-1,5,main]>#< Thread[Smack Packet Writer (0),5,main]>#< Thread[Smack Packet Reader (0),5,main]>#<Thread Thread[Smack Keep Alive (0),5,main]>#<Thread Thread[Smack Listener Processor (0),5,main]>#<OutputThread Thread[class org.jibble.pircbot.OutputThread-Thread,5,main]>#<Thread Thread[pool-2-thread-1,5,main]>#<Thread Thread[pool-1-thread-2,5,main]>#<TimerThread Thread |
| 03:54 | amalloy | aha. and we could call .destroy on all of those |
| 03:57 | amalloy | ,(reify Runnable) |
| 03:57 | clojurebot | #<sandbox$eval11118$reify__11119 sandbox$eval11118$reify__11119@121bcf2> |
| 04:01 | amalloy | ,eval |
| 04:01 | clojurebot | #<core$eval clojure.core$eval@1415815> |
| 04:02 | amalloy | ,(.run (reify Runnable (run [this] (eval "(def q 1)")))) |
| 04:02 | clojurebot | DENIED |
| 04:02 | AWizzArd | http://xkcd.com/722/ |
| 04:03 | amalloy | ,(.start (java.lang.Thread. (reify Runnable (run [this] (eval "(def q 1)"))))) |
| 04:03 | clojurebot | DENIED |
| 04:03 | amalloy | meh |
| 04:04 | yangsx | hi, in my project.clj, I specifies ':resources "data"' to include the data subdirectory into the jar file, but all the files are put directly into jar without the path, can I specify the path in the resulting jar? |
| 04:04 | amalloy | yangsx: just put them in subdirectories under data |
| 04:05 | amalloy | eg data/foo/bar/baz.jpg should be in the jar under foo/bar/baz.jpg |
| 04:11 | yangsx | amalloy: Maybe I'm doing it wrong. I read the data in a let form in code. That is, for my code it's data/foo, in the jar file it's foo. Maybe I should use a ref to read the data. |
| 04:12 | amalloy | i guess i don't understand. and sorry, gotta head out |
| 04:18 | svdberg | any users of vimclojure here? |
| 04:19 | kryft | No, but I will become one once I actually start writing clojure. :) |
| 04:20 | raek | yangsx: one way of doing it is to put the data/ dir in resources/ |
| 04:23 | xkb | I'm trying to run the repl from inside vim, using the ns i'm editting |
| 04:23 | xkb | but that doesnt really work |
| 04:23 | xkb | classpath only shows clojure jars |
| 04:23 | raek | i'm not aware of any way of adding a prefix to the resulting path in thst case |
| 05:39 | tobiasraeder | is it possible to read the contents of a symbol into a vector inside a macro? |
| 05:39 | tobiasraeder | as in being able to (map #(dostuff) contents-of-the-symbol) |
| 05:40 | carkh | if i understood you question well, i'd say no |
| 05:41 | carkh | your* |
| 05:41 | carkh | do you have an example ? |
| 05:43 | tobiasraeder | yes, one second |
| 05:43 | AWizzArd | What are the "contents of a symbol"? |
| 05:44 | carkh | if your macro call looks something liek this : (my-macro some-symbol) then some-symbol is totally opaque at macroexapansion time |
| 05:45 | tobiasraeder | http://gist.github.com/627922 |
| 05:45 | tobiasraeder | like that |
| 05:45 | tobiasraeder | contents of a symbol as in my case a vector that is bound to the symbol |
| 05:45 | carkh | well your macro can see the value of fields at macroexpansion time and use it |
| 05:46 | tobiasraeder | and how do i do that exactly? |
| 05:46 | carkh | just put ~fields in place of <content-of-fields> |
| 05:47 | xkb | what does ~fields do? |
| 05:47 | carkh | let me test that though =/ |
| 05:47 | notsonerdysunny | is there a way to search backwards through the history from the slime repl like we would do at a readline enabled terminal using control-r |
| 05:48 | tobiasraeder | @carkh seems like thats exactly what i was looking for and just beeing blind. i'll try if i can get it to work, thank you |
| 05:48 | tobiasraeder | @notsonderdysuny no idea :/ |
| 05:49 | tobiasraeder | @carkh ah dread, i forgott one thing let me change the gist quick |
| 05:49 | carkh | notsonerdysunny: try alt-p |
| 05:49 | tobiasraeder | @carkh i edited the gist if you dont mind checking it again |
| 05:50 | carkh | tobiasraeder: mhh you know i don't like that macro at all |
| 05:51 | carkh | it could be a function |
| 05:51 | carkh | i think that's not exactly what you want let me come back to you in a few |
| 05:51 | tobiasraeder | @carkh the actual case is a bit more complex and deals with alot of java interop class/interface generation |
| 05:51 | tobiasraeder | okay, thanks |
| 06:02 | carkh | tobiasraeder: how about something like this http://gist.github.com/627945 |
| 06:03 | carkh | but i really don't like it |
| 06:04 | tobiasraeder | yeah that might work |
| 06:04 | carkh | does this really needs to be done at compilation time ? |
| 06:04 | tobiasraeder | ill try to rework the class-name "-fields" into a map and just store the fields their |
| 06:05 | tobiasraeder | yeah its part of some really huge java interop stuff |
| 06:05 | tobiasraeder | i gotta grab some food, thank you for the input. if you care i'll let you know what i come up with in the end |
| 06:09 | carkh | http://gist.github.com/627945 |
| 06:09 | carkh | sur i'd love to |
| 06:09 | carkh | sure* |
| 06:41 | xkb | any tips to improve this code: http://github.com/svdberg/clojurelisa/blob/master/src/clojurelisa/core.clj? |
| 06:41 | xkb | I'm planning to use it in a presentation on Clojure |
| 06:42 | xkb | its a fork from a blog-post, and I'm trying to make it more idiomatic |
| 06:44 | edbond | ,(doc remove) |
| 06:44 | clojurebot | "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns false. pred must be free of side-effects." |
| 06:44 | edbond | ,(doc replace) |
| 06:44 | clojurebot | "([smap coll]); Given a map of replacement pairs and a vector/collection, returns a vector/seq with any elements = a key in smap replaced with the corresponding val in smap" |
| 06:45 | edbond | xkb: why not use remove and replace ^^ in remove-item and replace-item? |
| 06:46 | xkb | good tip |
| 06:46 | xkb | thanks |
| 06:46 | xkb | hmm.. only the predicate is a bit harder |
| 06:47 | xkb | as I need the nth item in a seq |
| 06:52 | edbond | then remove-item is ok |
| 06:55 | edbond | xkb: closing brackets don't need a new line |
| 06:57 | xkb | ok removed the two or three I found :) |
| 07:39 | jjido | What is the license of clojure.jar? Can I just package it in my project along with the readme.txt? |
| 07:40 | carkh | xkb: (def gen-pixels (grab-pixels gen-image)) inside a function, that's very bad style |
| 07:40 | cemerick | jjido: Clojure uses the EPL license. |
| 07:41 | cemerick | Whether that's compatible with your project depends upon your project's license. |
| 07:41 | jjido | Eclipse, I read that. I use LGPL |
| 07:41 | carkh | xkb: same for defn inside functions |
| 07:42 | cemerick | I know the GPL and EPL don't play nice together. Not sure about LGPL. |
| 07:47 | hiredman | http://gist.github.com/628066 |
| 07:48 | notsonerdysunny | what are symbol macros? |
| 07:57 | xkb | carkh: was afk for a while, and just read your remark |
| 07:58 | xkb | I thought I removed all defn within functions :? |
| 07:58 | xkb | oh within the multimethod? |
| 07:58 | carkh | yes |
| 07:59 | xkb | should I use letfn? |
| 07:59 | carkh | and there are many defs in other functions too |
| 07:59 | xkb | or just factor them out? |
| 07:59 | carkh | well that's for you to decide =P |
| 07:59 | xkb | :) |
| 08:00 | xkb | what's the tradeoff anyway, between a let and a def within a function scope? |
| 08:00 | xkb | I usually use let bindings |
| 08:00 | carkh | a def will modify the toplevel var |
| 08:00 | carkh | same for a defn |
| 08:00 | xkb | but the guy who originally wrote this uses def all the time |
| 08:00 | xkb | ah |
| 08:00 | carkh | that's like introducing global variables |
| 08:00 | xkb | so even within a function scope it introduces a top-level binding? |
| 08:00 | xkb | nasty |
| 08:01 | carkh | iirc it all started with recompiling stuff on the fly (which i dislike a lot too) |
| 08:01 | carkh | yes it does |
| 08:01 | carkh | you can use binding if you want to redef stuff with a dynamic extent |
| 08:02 | carkh | or let for lexical scope |
| 08:02 | xkb | and stuff like in source-image? the file-chooser is within the do scope |
| 08:03 | carkh | you need to use let for the fileshooser |
| 08:04 | xkb | I somehow got something in my head not to use let with doto |
| 08:04 | carkh | also that's nitpicking but ... your closing parenthesis should not be on a line by themselves |
| 08:04 | xkb | that's wrong app/. :) |
| 08:04 | xkb | carkh: hey, I like nitpicking :) |
| 08:04 | carkh | =) |
| 08:05 | carkh | i think we need to call hiredman to the rescue then ! |
| 08:47 | solussd_ | why isnt a record a function of its keys? |
| 08:49 | solussd_ | or field names i guess |
| 08:55 | tobiasraeder | it should be |
| 08:55 | tobiasraeder | iirc it implements ilookup so that should work |
| 08:56 | tobiasraeder | ,(defrecord myrecord [name]) |
| 08:56 | clojurebot | DENIED |
| 08:56 | tobiasraeder | anyway if you (:name (myrecord. "testname")) it returns "testname" |
| 08:57 | tobiasraeder | or did i get wrong what you were looking for? |
| 08:57 | AWizzArd | He wanted ((HisRecord. "x") :name) |
| 08:57 | solussd_ | i'm looking for ((myrecord. "testname") :name) |
| 08:58 | solussd_ | e.g. maps are functions of their keys |
| 08:58 | solussd_ | ,({:name "Joe"} :name) |
| 08:58 | clojurebot | "Joe" |
| 08:58 | tobiasraeder | yeah, got that wrong i guess |
| 08:58 | solussd_ | so, while that works fine with a struct created w/ defstruct, it's a no-go w/ a record. :/ |
| 08:59 | solussd_ | *defined w/ defstruct |
| 09:01 | solussd_ | guess I'm just wondering why |
| 09:02 | G0SUB | solussd_: because it doesn't make any semantic sense |
| 09:02 | G0SUB | solussd_: records are not functions of their keys. they are just a bunch of fields. |
| 09:03 | G0SUB | solussd_: if you need IFn like behavior, go ahead and implement that protocol for your custom type. |
| 09:05 | AWizzArd | solussd_: also records don't eval to themselves |
| 09:05 | AWizzArd | When you eval a record, for example in a macro, it becomes a map. |
| 09:05 | solussd_ | ok |
| 09:06 | dnolen | solussd_: maybe it's just me but the lack of IFn seems to me like an oversite |
| 09:06 | dnolen | solussd_: http://gist.github.com/628148 |
| 09:06 | solussd_ | dnolen: that's what it feels like to me. Doesn't feel very idiomatic- feels more 'java-interopish' |
| 09:06 | stuartsierra | It is deliberate, but debatable. |
| 09:10 | _fogus_ | You can say that again. |
| 09:29 | fhd | Hi. Can I somehow create anonymous types with instance variables? |
| 09:29 | stuartsierra | fhd: yes, with reify |
| 09:29 | fhd | I can create top level types with deftype, but I'd rather have them anonymous. proxy doesn't seem to support that |
| 09:29 | fhd | stuartsierra: Okay, I'll take a look! |
| 09:30 | stuartsierra | reify doesn't have instance variables per se, but it creates closures over locals |
| 09:30 | AWizzArd | And proxy not? |
| 09:30 | stuartsierra | I forget |
| 09:30 | AWizzArd | k |
| 09:30 | fhd | stuartsierra: I do explicitly need instance variables, sadly. An API requires that. |
| 09:31 | stuartsierra | oh then you need deftype |
| 09:31 | stuartsierra | but it can't extend concrete classes |
| 09:31 | fhd | stuartsierra: Yeah, and it works. But the types aren't anonymous, this bothers me a bit. |
| 09:31 | stuartsierra | you could gensym the names :) |
| 09:31 | AWizzArd | Interesting it would be if I want to make a deftype for a new stream. As java.io.OutputStream is not an Interface I can't inherit from it in a deftype. |
| 09:33 | fhd | So anonymous classes with instance variables are not possible in Clojure? |
| 09:33 | jave | hello |
| 09:33 | stuartsierra | an anonymous class really just has a generated name, even in Java source |
| 09:34 | fhd | stuartsierra: Yeah, but I can create as many as I want at runtime, because it appends a number. |
| 09:34 | fhd | stuartsierra: Um, not at runtime I guess... |
| 09:34 | stuartsierra | exactly |
| 09:34 | stuartsierra | Java doesn't create classes at runtime |
| 09:35 | fhd | stuartsierra: Then I should find a way to work around this. Thanks :) Such a weird API, I'll rewrite that in Clojure one day :) |
| 09:35 | stuartsierra | yeah, sounds weird. who uses public instance variables anyway? |
| 09:36 | fhd | stuartsierra: This project: http://github.com/spullara/mustache.java |
| 09:36 | stuartsierra | I think that's been ported to Clojure already |
| 09:37 | fhd | stuartsierra: You think? That would really make my day |
| 09:37 | fhd | It's so weird, I'm really one step from rewriting it myself... |
| 09:37 | fhd | Plus it's not on Maven Central... |
| 09:38 | stuartsierra | http://github.com/cgrand/moustache |
| 09:38 | jave | I'm doing some xml stuff with enlive but its a little bit awkward |
| 09:38 | fhd | stuartsierra: Isn't that something completely different? I stumbled across that too, but it doesn't seem to have anything to do with the Mustache template language. |
| 09:38 | jave | I have to do some workaroudns like adding xml headers and namespaces, is there some existing xml frontend to enlive? |
| 09:38 | stuartsierra | dunno, never used any facial hair libraries |
| 09:38 | fhd | stuartsierra: :) |
| 09:39 | stuartsierra | I like my frameworks clean-shaven. |
| 09:39 | fhd | stuartsierra: I haven't shaved in days, and I partly blame this library :) |
| 09:39 | stuartsierra | Maybe you're a budding Longbeard. |
| 09:40 | fhd | stuartsierra: Not yet :) |
| 09:40 | cemerick | stuartsierra: hah! :-D (re: clean-shaven) |
| 09:40 | cemerick | Does anyone know of a free geocoding web service that doesn't have TOS restrictions like Google's? |
| 09:41 | jave | openstreetmap? |
| 09:43 | fhd | By the way, is unit testing common in Clojure? I know there are quite strong opinions on TDD, so I'm wondering. |
| 09:43 | cemerick | jave: it's certainly a map, but I dont' see an API? |
| 09:43 | jave | oh it has apis |
| 09:43 | cemerick | (not= unit-testing TDD) |
| 09:44 | stuartsierra | TDD isn't necessary in Clojure because Clojure code always works. :) |
| 09:44 | fhd | cemerick: Hence my question |
| 09:44 | fhd | stuartsierra: How about unit testing then? :) |
| 09:45 | jave | cemerick: I havent actualy coded anything m yself, but maybe you can have a look at the java client, its open source |
| 09:45 | cemerick | fhd: clojure.test is all about unit tests. |
| 09:45 | fhd | cemerick: Yup. And because clojure.test is pretty good, I thought unit testing might be real popular |
| 09:45 | stuartsierra | You can do TDD in Clojure with clojure.test or Lazytest or ClojureCheck or ... |
| 09:45 | cemerick | jave: its API seems to be defined by the HTML export from the map. Ick. |
| 09:46 | jave | well there are all sorts of apis to the data |
| 09:46 | cemerick | I'd like to match the awesomeness of e.g. (-> "http://maps.googleapis.com/maps/api/geocode/json?address=Holyoke,%20MA&sensor=false" slurp clojure.contrib.json/read-json) |
| 09:46 | jave | maybe have a look at the josm client |
| 09:47 | jave | well, I dont think openstreetmap is so much about api awesomeness. its about making user contributed maps |
| 09:47 | jave | and thats how I use it |
| 09:48 | cemerick | OK. I was looking for a geocoding API. Anyway, thanks. |
| 09:48 | cemerick | fhd: I use clojure.test extensively in every one of my projects, and it seems to be very widely used in general. |
| 09:49 | fhd | cemerick: Hm, I see. Do you use it test-first or test-later style? |
| 09:49 | cemerick | I probably tend towards a 20/80 mix, respectively. |
| 09:50 | cemerick | fhd: tangential Q: do you have much of a ruby background? |
| 09:51 | fhd | cemerick: I found that the REPL fulfils most of my TDD needs, so I didn't miss it so far |
| 09:51 | fhd | cemerick: No, I'm mostly Java/C++ |
| 09:52 | cemerick | bummer; there goes my TDD stereotype ;-) |
| 09:53 | fhd | cemerick: Sorry :) I'm not a TDD expert though, just discovered it a while ago |
| 09:53 | fhd | cemerick: I've done a bit of Emacs Lisp before, and I couldn't imagine doing TDD with it at all, so I didn't really try it with Clojure |
| 09:54 | cemerick | Never got into it myself. Seems to me that testing simple stuff should be...simpler than TDD. And testing complicated stuff often ends up being...more complicated than TDD can support. |
| 09:55 | stuartsierra | That's what I'm trying to fix with Lazytest, don't think I've succeeded yet |
| 09:55 | _fogus_ | I have a nice little segment in my talk about TDD :-) |
| 09:55 | fhd | cemerick: TDD is really nice for static languages, where you can't quickly test a function. Also leads to real nice object oriented design IMO |
| 09:56 | fhd | cemerick: But in Clojure, there's the REPL, so it's super easy to test specific functions. And it's functional, so creating object-oriented design is a bit weird |
| 09:56 | cemerick | _fogus_: looking forward to it |
| 09:56 | fhd | cemerick: I did get interested and ask some questions regarding how I could do specific things, and it seems to work technically. But I don't find it very nice |
| 09:57 | cemerick | stuartsierra: I'm afraid I've not looked at lazytest one bit. :-( |
| 09:57 | _fogus_ | REPLs do not help much with regressions |
| 09:57 | stuartsierra | cemerick: no worries |
| 09:57 | stuartsierra | It's still evolving somewhat |
| 09:57 | fhd | _fogus_: That's true, the confidence from TDD is definately mising |
| 09:57 | cemerick | I'm a little behind on the cutting-edge clojure hackery from the past few months. |
| 09:57 | fhd | _fogus_: Then again, I haven't refactored my Clojure code much, so I don't really care |
| 09:58 | _fogus_ | fhd: I'm confused. :-( |
| 09:58 | fhd | _fogus_: About what? :) |
| 09:59 | _fogus_ | fhd: TDD, unit testing, refactoring... I'm not sure what we're talking about anymore. :( |
| 10:00 | stuartsierra | _fogus_: buzzword compliance |
| 10:00 | fhd | _fogus_: Well, TDD is basically unit testing + refactoring IMO |
| 10:00 | fhd | _fogus_: Kent Beck says, in a nutshell, that it helps create good designs because it encourages refactoring by providing confidence through loads of test cases |
| 10:01 | _fogus_ | fhd: Oh I see. I doo TDD, but without the Ds |
| 10:02 | fhd | _fogus_: :) |
| 10:02 | cemerick | "Good design" does not come from a random walk through test failure. |
| 10:03 | fhd | cemerick: Well, the nice thing about TDD is that you use test cases to write "how" you want to use an API, and then you start writing the API. |
| 10:03 | fhd | cemerick: The weird thing about TDD is that you basically start writing crap, hard coding everything, only slowly moving towards an actual solution |
| 10:03 | fhd | cemerick: And then refactoring the hell out of that until you like it. |
| 10:03 | cemerick | Yeah, I understand the idea, and I've done that to some extent, but that's not helping with design, it's simply codifying it ahead of its implementation. |
| 10:04 | fhd | cemerick: True. I actually do that most of the time, TDD or not. |
| 10:04 | _fogus_ | I like to write apps with the API that I am going to design. |
| 10:05 | lpetit | It has almost seemed to me (after having done that myself too, not denying my past errances :-) ), that doing TDD is easier when you already know the "field", the application domain of your problem. |
| 10:05 | fhd | All in all, I'm not really convinced by TDD. It does have some good points, and the designs created by it are often actually quite nice. But I don't think it works well in all languages, as Beck claims |
| 10:05 | lpetit | And hard to do in unknown fields/territories. |
| 10:05 | fhd | lpetit: Definitely. |
| 10:06 | lpetit | With clojure, once you know your "field/domain" well, you have the tools to go very high in abstractions, removing all the bits of code redudancy you find. Including your test suite. |
| 10:07 | lpetit | And once you know your application domain well, it makes less sense to "rewrite in TDD style" from scratch a new application. |
| 10:07 | fhd | lpetit: Yeah, I read somebody making this point: In functional programming, you write "what" you want, not "how" that should be achieved. Such code doesn't require tests. |
| 10:08 | stuartsierra | Great, so I've been wasting my time on test frameworks when I could have been writing real code. |
| 10:08 | fhd | Although confusing at first, I found it pretty nice that I don't have to bother with object-oriented design in Clojure. Makes things so much easier |
| 10:08 | lpetit | no, you will need tests. REPLs "on the fly" tests are volatile |
| 10:09 | lpetit | stuarsierra: of course you're just kidding, but I didn't see this smiley of you saying so at the end of your sentence ;-) |
| 10:10 | stuartsierra | :) |
| 10:10 | _fogus_ | stuartsierra's world is crashing down around him |
| 10:10 | stuartsierra | typical |
| 10:10 | fhd | Sorry for starting this :) |
| 10:10 | fhd | I'm still trying to make my mind up on these issues, being pretty new to FP. |
| 10:11 | fhd | I've never done testing _without_ TDD, actually, so I wouldn't really know how to approach that :) |
| 10:11 | lpetit | fhd: it's the nice effect of using a language with less accidental complexity. But when you will be facing problems with more essential complexity, the need for designing things will come, again (but then, you'll add software complexity as you add problem domain essential complexity, and that's a big win) |
| 10:11 | jave | arent macro arguments supposed to not be evaluated? |
| 10:11 | stuartsierra | jave: not in the macro itself |
| 10:12 | stuartsierra | they usually get evaluated eventually |
| 10:12 | fhd | lpetit: Well, I find Clojure design _much_ _much_ easier than OO design for the simple problems I'm tackling. |
| 10:12 | lpetit | jave: you can see macros as functions "eating" source code |
| 10:13 | jave | its odd, because I'm using some macros from Enlive. but I need to clone and modify one of the macros |
| 10:13 | lpetit | jave: ... digesting source code, and returning source code :-) |
| 10:13 | jave | and it doesnt behave the same way |
| 10:13 | fhd | lpetit: Object responsibilities, tell-don't-ask, design patterns... that's really a load of accidental complexity :) |
| 10:13 | lpetit | fhd: normal, functions are simpler building blocks than classes. |
| 10:13 | AWizzArd | Does gen-class support mutable fields as deftype does? |
| 10:14 | lpetit | fhd: tell don't ask is interesting, but probably for *true* asynchronous message-passing systems, a la Erlang. |
| 10:14 | _fogus_ | Erlang is the *only* OO language! |
| 10:14 | lpetit | AWizzArd: you can specify a "state", and generally you'll place a ref or an atom there |
| 10:14 | fhd | OMG |
| 10:14 | jave | oh noes, language wars... |
| 10:15 | _fogus_ | :p |
| 10:15 | fhd | jave: Should be quick. This is the clojure channel :) |
| 10:15 | jave | :) |
| 10:16 | AWizzArd | lpetit: So gen-class won't have an as efficient field access as deftypes. |
| 10:16 | jave | I'm happy so long as I dont have to code in a language thats physically harmfull |
| 10:16 | clojurebot | make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive |
| 10:16 | AWizzArd | But deftypes can't inherit from other classes. |
| 10:16 | fhd | But I'm really impressed by Clojure so far. I just wanted to do a few quick experiments, but I ended up using it for a larger project. |
| 10:16 | fhd | Plus I'm giving a talk about it next week :P |
| 10:16 | AWizzArd | fhd: in Köln? |
| 10:16 | lpetit | AWizzArd: indeed |
| 10:17 | fhd | AWizzArd: Ja, aber in meiner Firma |
| 10:17 | AWizzArd | k |
| 10:18 | stuartsierra | By the way, anybody noticed that swank-clojure doesn't display errors in Clojure 1.3 ? |
| 10:18 | lpetit | fhd: interestingly enough, the set of reasons I came to clojure isn't equal to the set of reasons I'm staying with clojure. I discovered a lot *beyond* what attracted me first. |
| 10:18 | AWizzArd | stuartsierra: right |
| 10:18 | jave | clojure repl errors sometimes arent very helpful |
| 10:18 | AWizzArd | I end up typing *e all the time :) |
| 10:18 | lpetit | stuarsierra: no |
| 10:24 | edbond | does structs deprecated in 1.2 ? |
| 10:24 | xkb | Another question regarding my code at http://github.com/svdberg/clojurelisa/blob/master/src/clojurelisa/core.clj |
| 10:24 | xkb | I think the use of the multimethod mutate is not very benificial here.. |
| 10:24 | xkb | do you agree? |
| 10:30 | @rhickey | bindings now get automatically conveyed to future calls and agent sends |
| 10:30 | @rhickey | http://github.com/clojure/clojure/commit/b1bed1b1c936855801e6d6dd40e649fddb6c039d |
| 10:30 | stuartsierra | holy cow! |
| 10:32 | AWizzArd | Hmm, I am trying to grasp what this means. |
| 10:32 | stuartsierra | I don't know if I like that or not. I was getting used to saying "don't use binding" |
| 10:33 | stuartsierra | Don't get me wrong, I'm impressed. |
| 10:34 | stuartsierra | But how far down the chain does it go? |
| 10:34 | AWizzArd | stuartsierra: what does this update do with bindings under the hood? |
| 10:34 | jjido | is there a limit to the level of continuations in a CPS program? I am at hundreds and only getting started... |
| 10:34 | stuartsierra | If I do (binding [...] (send ... A)) and the action A sends another action, does it inherit the same bindings as A? |
| 10:34 | @rhickey | some notes here: http://dev.clojure.org/display/design/Improve+Binding |
| 10:35 | AWizzArd | Oho, looks like the Confluence Wiki :) |
| 10:35 | @rhickey | stuartsierra: all sends inherit the bindings at the point of send |
| 10:35 | stuartsierra | ok |
| 10:36 | AWizzArd | Oh very interesting indeed. |
| 10:41 | stuartsierra | Is this leading us down the road of first-class environments? |
| 10:41 | @rhickey | no |
| 10:41 | stuartsierra | ok |
| 10:42 | stuartsierra | good |
| 10:42 | @rhickey | e.g., no locals in this environment |
| 10:42 | stuartsierra | ah, yes |
| 10:44 | stuartsierra | Why do you always change the language while I'm trying to write a presentation? :) |
| 10:44 | @rhickey | these benefits convey to pmap, which uses future calls |
| 10:46 | @rhickey | AWizzArd: userland use of bindings should be unaffected by this, but this is much more efficient than manual rebinding a la bound-fn |
| 10:47 | AWizzArd | Sounds good, I will download that version tonight. |
| 10:48 | @rhickey | stuartsierra: I'll go back to sitting on my hands :) |
| 10:48 | stuartsierra | heh |
| 10:48 | lpetit | rhickey: good news ! |
| 10:48 | stuartsierra | Just restrain yourself from making any earth-shattering changes for the next week, if you can, ... |
| 10:48 | lpetit | erm, not you sitting on your hands, of course :-) |
| 10:49 | xkb | stuartsierra: are you working on a presenation for clojure-conf? ;) |
| 10:49 | stuartsierra | you betcha |
| 10:49 | xkb | nice :) |
| 10:50 | edbond | http://faustus.webatu.com/clj-quick-ref.html#struct says structs deprecated in 1.2. Is this correct? |
| 10:50 | lpetit | rhickey: still didn't write a macro to automate the unrolling of first args ;-) |
| 10:52 | @rhickey | lpetit: they all end up being slightly different - I haven't spent the time to see what really could be generalized |
| 10:53 | lpetit | rhickey: oh |
| 10:53 | lpetit | ok |
| 10:53 | stuartsierra | edbond: structs are replaced by deftype / defrecord |
| 10:54 | @rhickey | lpetit: we're still in the process of getting it all configured, confluence jira etc |
| 10:55 | lpetit | rhickey: ok. but let apart the configuraiton, the titles of the other wiki pages seem interesting (though I will not have time to dig into them right now) |
| 10:57 | lpetit | stuartsierra: page on Modularity could be updated for ccw : it's now using the clojure.osgi project, and doesn't use the "eclipse buddies" mechanism anymore (but note that *currently*, clojure.osgi is still dependent on some Equinox aspect, though it's an implementation detail that could be gotten rid of when I or aav has the time to work on it) |
| 10:57 | lpetit | clojure.osgi v1.2.10 to be precise. (1.2 means "compatibility with clojure 1.2", 10 is just a classical version counter) |
| 10:57 | fhd | Gotta go, bye |
| 11:05 | stuartsierra | lpetit: thanks, updated |
| 11:06 | lpetit | stuartsierra: that was quick ! |
| 11:06 | stuartsierra | anything to avoid writing this presentation :) |
| 11:14 | lpetit | stuartsierra: modularity page again. What does it mean to "work fine in Glassfish" ? In which scenario ? One clojure jar per webapp's WEB-INF/lib/ I guess ? Maybe being more explicit on this could help ... |
| 11:18 | lpetit | even git-revert is simpler than reverting with svn ! |
| 11:21 | tobiasraeder | is there a way to put quotes into doc strings? |
| 11:22 | wooby | tobiasraeder: you can escape them like \" |
| 11:23 | tobiasraeder | ah okay, i guess emacs just screwed me over then :D |
| 11:25 | lpetit | tibiasraeder: install paredit.el, and you'll just be able to type " again inside a literal string to automatically get the \ for free (though not at the end of the string => then you'll have to escape paredit and type \ manually) |
| 11:25 | lpetit | Is it me that just gave an advice for emacs ? Wow, must be sick .. :-) |
| 11:27 | lpetit | Nooo, that's just a false sign of peace before the conj .... Embrace and Extend, gnarl gnarl gnarl ... :-E |
| 11:29 | dpritchett | I'm messing around in vimclojure and I notice that Meikel has bound <C-Up> to "UpHistory" but not <C-K> |
| 11:29 | dpritchett | any reason I shouldn't rebind C-K as well? I try not to use the arrow keys |
| 11:32 | tobiasraeder | @lpetit thanks a ton, using paredit but wasnt aware of that |
| 11:57 | ohpauleez | Does anyone know if there are videos of StrangeLoop? |
| 11:59 | defn | ohpauleez: they are filming a lot of it |
| 11:59 | defn | but not /all/ of it -- which talk were you hoping to see? |
| 12:00 | ohpauleez | ah awesome, thanks defn. No one in particular, just wanted to thumb through them and watch the ones that seem interesting |
| 12:00 | lypanov | anyone know how to get vimclojure to print out output from commands executed on the cmdline on the go rather than buffering it all? |
| 12:00 | defn | yeah fortunately/unfortunately they cost of the ticket didn't permit a lot of the perks some confs have |
| 12:00 | ohpauleez | I skipped StrangeLoop for conj, and had to cancel the conj trip because of work |
| 12:00 | defn | oh no! |
| 12:00 | defn | i met chouser yesterday which was cool |
| 12:01 | ohpauleez | Awesome! |
| 12:01 | cemerick | rhickey: that's a helluva change! |
| 12:01 | defn | i drove to strangeloop so i could handle the cost of flying down to conj |
| 12:01 | cemerick | Get them all out of the way now, plz. ;-) (sorry, chouser, _fogus_ ) |
| 12:02 | ohpauleez | cemerick: Don't be sorry, they get a free second edition now :) |
| 12:02 | ohpauleez | lypanov: You want to pipe the output to another shell/console? |
| 12:02 | @rhickey | cemerick: well, it's been a known wart for a while, must be removed to make way for easier parallelism |
| 12:02 | ohpauleez | instead of the designated buffer? |
| 12:02 | lypanov | ohpauleez: just into the buffer at the time its happening rather than queuing it up. |
| 12:03 | lypanov | ohpauleez: (when using "send top level") |
| 12:03 | cemerick | rhickey: for sure, it's a welcome change. I can't think of any immediate downsides -- do you know of any? |
| 12:03 | _fogus_ | cemerick: I don't follow |
| 12:03 | ohpauleez | Ahh, Yeah, I don't know how to do that. I think it's based on the semantics (Looks for the exit code of the process) |
| 12:03 | @rhickey | so, who's ready for a bifurcation of vars into dynamically rebindable and not? |
| 12:04 | jjido | does Clojure have a function to compare two Comparables? < does not work |
| 12:04 | lpetit | rhickey: would affect REPL user xperience ? |
| 12:04 | @rhickey | cemerick: no downsides, as the perf is nearly ideal, one thread local reference, no copies, no cost dependent on number of vars |
| 12:05 | ohpauleez | _fogus_: He wants all the changes out of the way for writing the book. |
| 12:05 | @rhickey | lpetit: in what way? |
| 12:05 | lpetit | rhickey: *you* tell me :-) |
| 12:05 | lpetit | rhickey: redefinition, I mean |
| 12:05 | jjido | rhickey: sounds interesting |
| 12:05 | cemerick | rhickey: perhaps a bifurcation would mean that this non-dynamically-rebindable thing won't be called a var...? |
| 12:05 | notsonerdysunny | ->(when-first [[x y z] [1 2 3 4 5]] (+ x y z)) |
| 12:05 | sexpbot | java.lang.UnsupportedOperationException: nth not supported on this type: Integer |
| 12:05 | lpetit | rhickey: and potentially need for reevaluation of all dependent code ? |
| 12:05 | notsonerdysunny | ,(when-first [[x y z] [1 2 3 4 5]] (+ x y z)) |
| 12:05 | clojurebot | notsonerdysunny: Pardon? |
| 12:06 | notsonerdysunny | ->(when-first [[x y z] [1 2 3 4 5]] (+ x y z)) |
| 12:06 | sexpbot | java.lang.UnsupportedOperationException: nth not supported on this type: Integer |
| 12:06 | cemerick | _fogus_: just (foolishly) joshing the other authors :-P |
| 12:06 | notsonerdysunny | the above expression is return nil on my computer |
| 12:06 | notsonerdysunny | I was expecting it to return 6 |
| 12:06 | _fogus_ | cemerick: Thankfully, we can still squeeze in edits. ;-) |
| 12:06 | @rhickey | I have new ideas about how to make the non-dynamically rebindable vars still 'update-able', for the only viable usage - redefinition of fixed/enhanced functions |
| 12:06 | notsonerdysunny | can somebody clarify what is happening here.. |
| 12:06 | lpetit | rhickey: maybe I should have first aksed: I don't see the use cases |
| 12:06 | @rhickey | so no re-eval required |
| 12:07 | lpetit | ok |
| 12:07 | @rhickey | but the perf benefits of direct/static binding |
| 12:07 | lpetit | seems like everybody is *working hard* not to produce conf slides ... :)- |
| 12:08 | @rhickey | cemerick: naming-wise, I'm thinking var and dynamic-var |
| 12:08 | @rhickey | cemerick: dynamic being something you ask for explicitly |
| 12:08 | lpetit | "consts" could be misleading ? |
| 12:08 | @rhickey | defdynamic |
| 12:09 | arkh | how do I import multiple classes from the same packege in a ns declaration? (e.g. something like this (ns my-namespace :import [java.util Date Timer]) |
| 12:09 | _fogus_ | lpetit: Done mine. :-) |
| 12:09 | cemerick | holy breakage, batman :-P |
| 12:09 | @rhickey | lpetit: const might be something else altogether |
| 12:09 | replaca | lpetit: I'm writing mine! But I'm way behind my ambitions as well :) |
| 12:09 | @rhickey | cemerick: no breakage except for dynamic rebinding of fns |
| 12:09 | cemerick | rhickey: right |
| 12:09 | cemerick | Not that I'm arguing against the breakage. |
| 12:09 | @rhickey | so, I'm here to listen to the moaning around that loss |
| 12:10 | ohpauleez | arkh: (:import (java.util Date Timer)) should work |
| 12:10 | @rhickey | arguably, mocking frameworks should be doing root rebinding |
| 12:10 | lpetit | _fogus_, replaca: good for *you* :-) |
| 12:11 | ohpauleez | (ns my-ns (:import (java.util Date Timer))) (arkh) |
| 12:11 | @rhickey | dynamic fns used for e.g. error handling could still be created, explicitly |
| 12:11 | @rhickey | dynamic binding for monkey-patching will die a deserved death |
| 12:11 | arkh | ohpauleez: I receive the following with that: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword |
| 12:12 | lpetit | rhickey: and clojure.osgi which currently dynamically rebinds clojure.core/load ... :- |
| 12:12 | cemerick | ,(binding [+ -] (+ 10 10)) ; But this is fun! :-P |
| 12:12 | clojurebot | 20 |
| 12:12 | lpetit | :-/ |
| 12:12 | cemerick | oh, right, core is static these days |
| 12:12 | hiredman | dynamic binding is also used a lot for stubbing out functions for testing |
| 12:12 | @rhickey | lpetit: that's monkey patching IMO |
| 12:12 | hiredman | + is inlined |
| 12:13 | lpetit | rhickey: for sure :-) |
| 12:13 | @rhickey | hiredman: see above, root rebinding more suitable, no? |
| 12:13 | cemerick | ,(binding [+ -] (apply + [10 10])) |
| 12:13 | clojurebot | 0 |
| 12:13 | cemerick | true enough |
| 12:13 | ohpauleez | arkh: take a look at: http://gist.github.com/628461 |
| 12:14 | ohpauleez | Is your :import in a s-expr? |
| 12:14 | hiredman | rhickey: yes, well, our tests have started moving down the road of using this with-var-root macro that alter-var-roots and then restores |
| 12:14 | arkh | ohpauleez: no - that was the problem, then : ( - Thank you |
| 12:14 | ohpauleez | arkh: happy to help |
| 12:14 | @rhickey | hiredman: exactly |
| 12:15 | hiredman | I am not sure which I dislike more, alter-var-root or binding |
| 12:15 | lpetit | rhickey: I see root-rebinding as even more "monkey patching" than "call-stack bound rebinding", non ? |
| 12:15 | lpetit | s/non/no/ |
| 12:15 | sexpbot | <lpetit> rhickey: I see root-rebinding as even more "monkey patching" than "call-stack bound rebinding", no ? |
| 12:15 | @rhickey | lpetit: root rebinding is not something you would leave in place, just for testing |
| 12:19 | @rhickey | root rebinding will be possible, but it will be expensive as it will force all var caches to reload on next use |
| 12:19 | @rhickey | so, doing that on code reloads/evals is fine, doing that in tight loop is not |
| 12:19 | replaca | alter-var-root is great for setting up the program environment (processing command line args, reading param files and setting global parameters, etc.) |
| 12:20 | replaca | Purism is situational :) |
| 12:21 | @rhickey | I'm trying to find the middle ground between bind-once of ML and the high-cost of anything could change at any time, the latter being not very functional |
| 12:21 | @rhickey | in this model non-dynamic vars would be presumed constant throughout a fn body |
| 12:21 | _fogus_ | rhickey: I needed it to simulate record invariants. No tight loops involved |
| 12:22 | hiredman | huh |
| 12:22 | @rhickey | this facilitates caching var contents |
| 12:22 | @rhickey | thread binding is reserved for explicit dynamic vars |
| 12:22 | lpetit | indeed, when anything can be rebound, it's hard to agree with blog posts which say that clojure-only functions only rely on the input arguments ! |
| 12:22 | hiredman | the binding propagation will make my scope implementation that uses binding work across threads |
| 12:22 | @rhickey | on fn entry, a guard is tested that checks for _any_ var root alteration, reloads cache if needed |
| 12:23 | @rhickey | this way, you can reload without re-evaluating downstream consumers |
| 12:23 | ohpauleez | this change sounds pretty god to me |
| 12:23 | ohpauleez | good |
| 12:23 | @rhickey | but most of the overhead of dynamism is removed |
| 12:23 | ohpauleez | I appreciated the walkthrough rhickey |
| 12:24 | @rhickey | hiredman: supporting resource scopes was one of the goals for the thread binding improvements |
| 12:25 | @rhickey | but right now we all pay a high price for ever-possible dynamism |
| 12:25 | jjido | rhickey: is "at function entry" the right place? |
| 12:25 | @rhickey | I'm quite stoked, as this new model will avoid much of the brittleness of direct linking and static |
| 12:26 | @rhickey | jjido: where else? |
| 12:27 | @rhickey | jjido: there is talk of providing access to safepoints for alternative langs, might be a few releases of JDK away... |
| 12:27 | jjido | rhickey: it could be user-specified |
| 12:27 | lpetit | sounds reasonable. and the semantics make sense, don't they ? (def not-rebindable) (defdynamic *rebindable*) . Now really no more arguing on adding or not CL-like ++ earmuffs around not-rebindable ... |
| 12:27 | @rhickey | jjido: what would the choices be? |
| 12:28 | jjido | rhickey: nondynamic function, dynamic |
| 12:28 | cemerick | lpetit: I think I may be one of just a handful that ever used ++ anyway. |
| 12:28 | lpetit | heh |
| 12:28 | @rhickey | +ick+ |
| 12:29 | @rhickey | jjido: to what purpose? |
| 12:29 | jjido | not sure ;) |
| 12:29 | lpetit | will read the rest on the logs, must drive home. cu buddies |
| 12:29 | @rhickey | jjido: non-dynamic == can't call fixed functions |
| 12:30 | jjido | rhickey: I didn't understand that |
| 12:30 | hiredman | done? for promises as has been a sore point |
| 12:30 | @rhickey | jjido: if you don't really have a use case, nevermind |
| 12:31 | hiredman | or actually await-for for promises |
| 12:31 | @rhickey | hiredman: ? |
| 12:31 | jjido | rhickey: ok. |
| 12:32 | hiredman | rhickey: a way in core to await on the delivery of a promise with a timeout would be nice |
| 12:32 | @rhickey | hiredman: yes, it's on the agenda awaiting a good design |
| 12:33 | hiredman | right, I am running through the new (to me) wiki |
| 12:33 | @rhickey | ah |
| 12:33 | hiredman | lots of excellent stuff |
| 12:33 | hiredman | (as per the usual) |
| 12:34 | hiredman | a compiler that explicitly passes state, sounds like a job for clojure.contrib.monads |
| 12:34 | @rhickey | hiredman: that blocking calls page is not ok by me yet |
| 12:35 | hiredman | ah |
| 12:35 | fliebel | Any Overtone hackers in here? |
| 12:38 | @rhickey | hiredman: the idea has support, that design, not |
| 12:38 | carkh | Lazy seqs + bindings : would it be possible to somehow attach bindings to closures ? |
| 12:38 | carkh | or would that make these lexical instead |
| 12:39 | @rhickey | carkh: you could, but the cost of establishing per seq step might be too high |
| 12:39 | carkh | attaching at closure instanciation time (tho i don't know know what's under the hood) |
| 12:40 | carkh | right |
| 12:40 | @rhickey | so, I'm still thinking about that but have delivered the first half (thread pool support) |
| 12:41 | carkh | to me the lazy seqs part is most important, but i can live with it as it is right now |
| 12:41 | kumarshantanu | hi, is there any clojure.contrib for dealing with conversion of keyword to/from camelCase strings? |
| 12:41 | kumarshantanu | or any project for that matter |
| 12:41 | carkh | kumarshantanu: i'd love to see that, and also for SQL type naming |
| 12:43 | @rhickey | so, no strong objections to defns becoming not-dynamically (thread-locally) rebindable? |
| 12:43 | kumarshantanu | carkh: SQL type naming as in database-agnostic types? :string {:limit 30} --> VARCHAR(30) |
| 12:44 | carkh | rhickey: to me rebinding these is bad style anyways |
| 12:44 | fliebel | rhickey: I missed most of this, but just defns, or any def? |
| 12:44 | cemerick | rhickey: a msg to clojure-dev pointing at the transcript might flush out a principled objection *shrug* |
| 12:44 | @rhickey | any def, there will be a defdynamic |
| 12:44 | fliebel | sounds good to me :) |
| 12:45 | carkh | kumarshantanu: nope just :hello-world becoming "hello_world" it's all easy, but it would be nice to have this kind of convertions all in the same place |
| 12:45 | carkh | rhickey: but you mean not even with the binding macro ? |
| 12:46 | @rhickey | carkh: the binding macro would only work with defdynamic vars |
| 12:46 | carkh | wew that's pretty destructive for old code |
| 12:48 | @rhickey | carkh: really? |
| 12:48 | @rhickey | presume we can easily make defs of *foo* dynamic |
| 12:48 | hiredman | well, using *foo* and binding all over the place is pretty horrible, so destroying it is good |
| 12:48 | carkh | hiredman: it is, but sometimes that's the best tool |
| 12:49 | technomancy | that is going to hurt testability badly. right now one of the things that makes clojure code easy to unit test is that you can rebind some of the functions it relies on. |
| 12:49 | kumarshantanu | carkh: I am writing some code and need camelCase to/from keyword conversions -- might as well write something and factor it out |
| 12:49 | hiredman | carkh: rarely |
| 12:49 | @rhickey | dynamic is only being removed as the default, not as an option |
| 12:49 | technomancy | if you have to indicate what can be rebound, you will start to need things like dependency injection |
| 12:49 | kumarshantanu | rhickey: technomancy: that's spot-on -- mocking dependencies is the biggest use case |
| 12:49 | @rhickey | technomancy: how so? |
| 12:49 | hiredman | technomancy: well there will be root rebinding apparently |
| 12:49 | hiredman | e.g. with-var-root or something |
| 12:50 | technomancy | ok, maybe I don't have enough context; I should wait till I hear more. |
| 12:50 | @rhickey | truly mocking/stubbing/injecting something requires more power than binding anyway, as that only affects one branch |
| 12:51 | @rhickey | everyone needs to be clear we are only talking about rebinding, not redefing |
| 12:53 | @rhickey | an aPI option is to trigger dynamics from the earmuffs (def *dynamic-foo*) == dynamic |
| 12:53 | carkh | hiredman: i have this now becoming rather large web application, i use binding at the top of the url matching tree as soon as i know the customer in order to "binding" the currency he uses, i can't imagine passing such a value trough all function calls without passing a state mage-object which in the end is not any better than rebinding vars |
| 12:53 | AWizzArd | So, in principle this only shadows older bindings, and releases them when the body closes. |
| 12:53 | carkh | mage->mega |
| 12:53 | @rhickey | that will minimize breakage for anyone using the convention |
| 12:54 | cemerick | please no sniffing of var names to hint semantics |
| 12:54 | @rhickey | let's not argue about dynamic vars, they have obvious utility and are used by Clojure itself, and are not going away under this proposal |
| 12:55 | @rhickey | cemerick: significantly reduces the breakage, and ensures the naming convention |
| 12:55 | jkkramer | could a warning be issued? |
| 12:55 | carkh | rhickey: huh the earmuff thing seems a bit too magical |
| 12:57 | @rhickey | (defdynamic no-earmuffs) will be considered bad karma though |
| 12:57 | defn | 11:55 < jkkramer> could a warning be issued? |
| 12:57 | carkh | wouldn't it make sense to take the reverse option of going defstatic or def for dynamic as it is now ? |
| 12:57 | @rhickey | watning about what? |
| 12:57 | @rhickey | warning |
| 12:57 | cemerick | rhickey: Granted, but it's still bad. Not as bad as the -void-methodName black magic, but still bad. |
| 12:58 | @rhickey | cemerick: alternatives for breakage reduction welcome |
| 12:58 | jkkramer | "i'm making *your-def* dynamic but you should really use defdynamic" |
| 12:59 | danlarkin | my vote is against the name of a var influencing its behavior |
| 12:59 | carkh | and give us an error when trying to binding a static var |
| 12:59 | @rhickey | jkkramer: yes, more likely if we intend to deprecate the earmuffs==dynamic as a transition feature only |
| 12:59 | jkkramer | right |
| 12:59 | @rhickey | carkh: tat is certain |
| 12:59 | @rhickey | that |
| 13:00 | carkh | so why not defstatic+def instead of defdynamic+def ? |
| 13:00 | hiredman | def would not be the same as static |
| 13:00 | carkh | just like you need to specify that function is static and get dynamic by default |
| 13:00 | hiredman | in the case of defdynamic+def |
| 13:01 | @rhickey | carkh: because it's not static, there is a lot of code that presumes namespaces contain vars, dynamic vars will be Vars by inheritance if not by mode |
| 13:01 | jjido | Could we define an auto-dynamic variable pattern? |
| 13:01 | hiredman | it would just not be bindable, which is not the same thing |
| 13:01 | cemerick | rhickey: I don't have any alternative breakage mitigation suggestions at the moment. Adding and then taking away magical var names seems even worse than adding them at all, though. |
| 13:01 | jjido | using a regex |
| 13:01 | @rhickey | cemerick: even if it never makes a release? |
| 13:02 | jjido | That way you can use the earmuffs, dyn-something or whatever pattern you like |
| 13:02 | cemerick | rhickey: that changes the calculus significantly |
| 13:04 | amalloy | i don't understand the objection to carkh's proposal. leave def the way it is, and introduce a defstatic; that gives you access to the new language "feature", while not breaking old code that assumes it can rebind something |
| 13:05 | cemerick | amalloy: people wanting speed is more common then people wanting dynamic rebinding |
| 13:06 | ohpauleez | cemerick: I totally agree, but I kind of like the suggestion myself |
| 13:07 | ohpauleez | as far as migration is concerned. That said I really only use dynamic binding in the cases already mentioned and am fine working around them |
| 13:09 | hiredman | amalloy: that proposal rests on a faulty understanding of the choices and tradeoffs involved |
| 13:09 | cemerick | The same dynamic applied to the prim stuff: people care way more about perf in common cases than the generality of arbitrary precision. |
| 13:09 | carkh | tss ok static might not be the best word |
| 13:09 | carkh | but you get the idea |
| 13:10 | ohpauleez | cemerick: I actually thought of that as the counter example. People don't care about auto-promotion most of them time (in fact, I'm sure they rarely expect it), but when they want it, it's there |
| 13:11 | cemerick | ohpauleez: the same applies here -- rebinding is rarely used, but defdynamic is there when you need it |
| 13:11 | jjido | I like that Clojure can calculate factorial of 10000. |
| 13:12 | ohpauleez | I completely agree. I only use rebinding in the situations listed already, and I'm fine being explicit about them |
| 13:12 | ohpauleez | I retracted my statement from before |
| 13:13 | carkh | you might not have a big code base to take into account maybe .. *cries* |
| 13:13 | ohpauleez | You can't please everyone :) |
| 13:13 | jjido | carkh: but you can use refactoring tools on your code can't you? |
| 13:13 | carkh | what tools ? |
| 13:14 | ohpauleez | or a macro! |
| 13:14 | carkh | all i have is good old emacs |
| 13:14 | ohpauleez | I thought emacs had everything? |
| 13:14 | ohpauleez | :) |
| 13:14 | jjido | ohpauleez: exactly! |
| 13:15 | ohpauleez | carkh: sed will fix it for you |
| 13:16 | ohpauleez | all of this aside, do we really need the special *binding-name-that-is-now-dynamic* trick? |
| 13:16 | ohpauleez | I understand this change will break some projects, but those projects depend on an earlier version on clojure |
| 13:17 | _fogus_ | This appears to break only one example in JoC, so I say it's a win. :-) |
| 13:17 | ohpauleez | Awesome! |
| 13:21 | amalloy | i agree it seems wrong to treat *vars* specially, but as indicated above i don't really understand the issues, so feel free apply a grain of salt |
| 13:29 | fhd | Hi. I'm about to do some string conversion in Clojure. I'd usually just read the string line by line and then add the modified lines to a StringBuilder. |
| 13:29 | fhd | However, that's quite imperative. Any hints on how to do this more elegantly in Clojure? |
| 13:30 | fhd | Specifically, I'm parsing a file and replacing some magics in it by the respective entries in a map. |
| 13:32 | kumarshantanu | fhd: Google's Guava is a nice library -- but it's Java |
| 13:32 | rlb | may need more details, i.e. can the pattern you're looking for span lines? Are you dealing with a *lot* of data overall? per-doc?, etc. |
| 13:33 | fhd | rlb: I'm not really worried about efficiency ATM. It's rather small files, a few hundred bytes. |
| 13:33 | fhd | rlb: The patterns cannot span lines. |
| 13:33 | rlb | fhd: slurp, replace the pattern, then dump? |
| 13:33 | fhd | rlb: Well, it's several patterns. There are tags in the file, like '{{SOMETHING}}' |
| 13:34 | rlb | fhd: or if you don't want to hold the whole doc in memory, use a line-seq, etc. |
| 13:34 | fhd | Then I want to replace each of these with the map value for the key :SOMETHING |
| 13:34 | fhd | rlb: I thought about just doing a few replaces, but that would be ~10 string replacements on each complete file. Don't find that too elegant. |
| 13:35 | rlb | how many items in the SOMETHING domain? |
| 13:35 | rlb | (max) |
| 13:35 | fhd | kumarshantanu: Does Guava have functionality for that? I'm actually trying to do it as Clojure-style as possible, but if there's something I can reuse... |
| 13:35 | fhd | rlb: Hm, I'd guess each item will usually pop up once or twice. And there should be up to 10 different items |
| 13:36 | kumarshantanu | fhd: Guava lets you read from a file line by line -- nice API |
| 13:36 | rlb | you could use a map (or doseq if you only want one line in memory at a time), and a function that just replaces all the patterns in that line before passing it on (via return or write) |
| 13:36 | @rhickey | _fogus_: what breaks in JoC? |
| 13:36 | fhd | rlb: Yeah, that's pretty much how I'd do it in Java. But I thought this was kinda weird in Clojure |
| 13:37 | rlb | (doseq [line (line-seq file)] (write-line ...)) |
| 13:37 | kumarshantanu | fhd: see this example -- http://www.copperykeenclaws.com/googles-guava-java-the-easy-parts/ (Files.readLines...) |
| 13:37 | amalloy | fhd: i'm in favor of rlb's proposal. just define a write-line function that does the necessary replacements |
| 13:38 | fhd | amalloy: Hm, OK I guess. |
| 13:38 | fhd | I somehow thought there was some funky function for this in Clojure :) |
| 13:38 | amalloy | write-line can use reduce on a list of replacements to avoid writing .replace more than once |
| 13:38 | fhd | I'll just use StringBuilder then |
| 13:39 | fhd | amalloy: Hm, I'll look at that |
| 13:40 | nishant | Can I do a require :as from the REPL? |
| 13:41 | fhd | rlb: Why would I use doseq here? Isn't map fine too? |
| 13:42 | rlb | fhd: map should be fine as long as you don't hold on to the head of the result |
| 13:42 | amalloy | ,(let [replacements [["a" "A"] ["b" "B"]]] (reduce (fn [str [from to]] (.replaceAll str from to)) "at bat")) |
| 13:42 | clojurebot | java.lang.UnsupportedOperationException: nth not supported on this type: Character |
| 13:42 | rlb | (or as long as you don't care if each doc's completely in RAM at some point) |
| 13:43 | rlb | and it's more flexible if you ever need that |
| 13:43 | fhd | rlb: I didn't really understand any of that, but I guess I'll just use doseq :) |
| 13:43 | amalloy | ,(let [replacements [["a" "A"] ["b" "B"]]] (reduce (fn [str [from to]] (.replaceAll str from to)) "at bat" replacements)) |
| 13:43 | clojurebot | "At BAt" |
| 13:43 | rlb | fhd: map returns a sequence containing the result |
| 13:43 | rlb | i.e. (line-1 line-2 line-3) |
| 13:43 | fhd | rlb: Ah, I see |
| 13:44 | amalloy | fhd: see above for a reduce/replace recipe |
| 13:44 | fhd | rlb: And doseq returns nothing and just does stuff? |
| 13:44 | rlb | doseq doesn't -- it's not a functional op |
| 13:44 | rlb | it's just for side-effects |
| 13:44 | fhd | amalloy: Thanks, pretty nice |
| 13:45 | rlb | fhd: but since map is lazy, and line-seq is lazy, then map won't keep everything in ram either, as long as no one holds on to the head of the result. |
| 13:46 | fhd | rlb: I don't really get the "holding onto the head" thing |
| 13:46 | rlb | i.e. (doseq [line (map ...)] (print line)) |
| 13:46 | amalloy | ,(nth (range) 100000000) |
| 13:47 | clojurebot | Execution Timed Out |
| 13:47 | amalloy | ,(let [x (range)] (nth x 100000000)) |
| 13:47 | clojurebot | Execution Timed Out |
| 13:47 | amalloy | fhd: the first of those examples will work, eventually, in a real repl |
| 13:47 | rlb | fhd: with a lazy seqence, the items of the sequence aren't computed until they're needed, so you can traverse an infinite list in finite memory as long as you don't hold on to the head of the list. |
| 13:47 | amalloy | because as soon as it's done with an element it can be GCed |
| 13:48 | fhd | rlb: So by holding onto, you mean keeping a reference to the element? |
| 13:48 | amalloy | the second one won't, because x is still referring indirectly to every element in range |
| 13:48 | rlb | fhd, right |
| 13:48 | rlb | i.e. (def ints (all-integers)) is *bad*, even if all-integers is lazy |
| 13:48 | fhd | rlb: Ah, I see. If I would hold references, all memory would eventually be consumed. |
| 13:48 | rlb | but (doseq [i (all-integers)] (prn i)) is fine |
| 13:49 | rlb | well, for some definition of "fine" |
| 13:49 | _fogus_ | rhickey: rebinding an exception handler defn (and example in the final chapter) |
| 13:49 | rlb | it won't run out of ram at least |
| 13:49 | amalloy | rlb: well, fine except you're printing an infinite sequence :) |
| 13:49 | _fogus_ | s/and/an |
| 13:49 | stuartsierra | eventually you'll run out of paper |
| 13:49 | rlb | nah, just electrons |
| 13:50 | @rhickey | _fogus_: so, exception handlers are still valid uses of dynamic fn vars (and the original motivation for allowing dynamic fns), but will have to be explicit about the dynamism |
| 13:51 | _fogus_ | rhickey: It's the only use case that we mention. :-) |
| 13:51 | @rhickey | I'm considering retaining support for the :dynamic true metadata for this purpose, as a second set of dynamic def variants seems like a waste |
| 13:52 | @rhickey | _fogus_: you can slap :dynamic true on that now (harmlessly) and it might still work |
| 13:52 | rlb | fhd: easy way to play around with infinite lists in clojure is via cycle, repeat, or repeatedly. |
| 13:52 | _fogus_ | rhickey: A footnote might be in order... we do not have enough of those. |
| 13:53 | _fogus_ | ;-) |
| 13:53 | _fogus_ | !!! http://twitter.com/amitrathore/status/27464468779 |
| 13:54 | @rhickey | nice! |
| 13:55 | kryft | Told where? |
| 13:55 | rlb | fhd: another thing to keep in mind is that if you're not used to laziness, execution may not happen when you expect it to. i.e. it happens when each element of the list is *consumed*. If the list is never consumed; no execution... |
| 13:55 | amalloy | kryft: at strangeloop |
| 13:56 | fhd | rlb: I guess I'll take the chance :) |
| 14:03 | _fogus_ | Hmmm, just realized that the wording in the Var section might need to be adjusted also. |
| 14:06 | fhd | Are private functions in Clojure mostly a way to make people coming from Java happy or is their use encouraged? |
| 14:07 | rlb | fhd: it's not a problem, just the way laziness works, but I imagine it can be surprising |
| 14:07 | amalloy | fhd: i think they're encouraged. don't clutter namespaces with functions nobody will want |
| 14:08 | amalloy | if someone (use)s your library, they don't want tab-completion for your process-portion-of-file function |
| 14:08 | fhd | amalloy: Probably. I was mostly wondering because I don't think there's such a mechanism in other Lisps, so I thought it might not be Lisp-y |
| 14:09 | carkh | it is also encouraged to only use the symbols you need |
| 14:09 | rbanffy | Hi folks. Total newbie installed Clojure from ELPA. I would like to use 1.2 instead of 1.1. What can I do? |
| 14:09 | carkh | (:use [mynamespace :only [frobnicate]) |
| 14:10 | technomancy | rbanffy: try the swank-clojure readme; sounds like you found some out-of-date docs |
| 14:11 | rbanffy | technomancy: Where can a *total* newbie find it? |
| 14:12 | fhd | carkh: Hm, I always use evertything. |
| 14:13 | amalloy | fhd: i do too, but it's a filthy habit, just like it is in java |
| 14:13 | amalloy | i just can never remember the syntax for using selectively |
| 14:13 | qed | I thought proxy was deprecated for some reason. |
| 14:14 | qed | Guy Steele just said to learn clojure. |
| 14:15 | amalloy | qed: your thunder has been stolen already |
| 14:15 | fhd | amalloy: Well, I kind of like .* in Java :P Hardly ever had any problems with that, and it's IMO worth removing ~100 files from each file. |
| 14:16 | qed | amalloy: I think that was me actually. |
| 14:16 | qed | I'm defn. |
| 14:16 | amalloy | qed: are you fogus too? :P |
| 14:16 | qed | Haha. :F |
| 14:16 | amalloy | fhd: .* is convenient if you're not using a decent IDE, but it means (for example) if you see a strange class like MagicDoStuff in the code, you don't know what package it's from |
| 14:17 | amalloy | but eg Eclipse will manage all the imports for you so that anyone readong your code knows exactly what classes come from where |
| 14:18 | fhd | amalloy: Yeah, but I'm usually on Emacs. Someone using Eclipse can actually see where the file is from by holding the cursor over it :) Well it's probably a matter of taste in the end. |
| 14:21 | amalloy | fhd: search google for "java style guide import .*", the first N hits say DONT DO IT |
| 14:23 | jjido | amalloy: because of name clashes? |
| 14:24 | rbanffy | technomancy: I see slime-lisp-options points to 1.1 Is there an easy way to change that? |
| 14:24 | amalloy | jjido: meh. that's only really a problem for java.util.Date :P. it just makes the code harder to read if you're seeing it for the first time |
| 14:26 | amalloy | i mean yes, it's obviously a style issue since the compiler doesn't care, but so are newlines |
| 14:26 | fhd | amalloy: There's reasons for both approaches, that's why I called it a matter of taste. The topic is quite controversial on the web apparently. |
| 14:27 | technomancy | rbanffy: yeah, you don't need swank-clojure.el, just clojure-mode and slime-repl |
| 14:28 | rbanffy | technomancy: That's confusing. All I wanted was to make M-x slime give me 1.2... |
| 14:31 | fhd | Hm, but there's one problem. When I make functions private, I cannot call them from the REPL for testing purposes anymore. |
| 14:31 | opqdonut | fhd: you can say (in-ns 'foo) |
| 14:31 | opqdonut | then they should be visible |
| 14:31 | fhd | opqdonut: Great, thanks |
| 14:32 | amalloy | or just (ns foo), which expands to the same thing |
| 14:32 | opqdonut | mmm yeah |
| 14:32 | fhd | amalloy: Isn't (ns) already included in (use)? |
| 14:32 | amalloy | fhd: no. use is a combined require/refer |
| 14:33 | opqdonut | yep |
| 14:33 | opqdonut | use imports the given ns into the current ns |
| 14:33 | opqdonut | ns or in-ns changes which ns you are in |
| 14:33 | fhd | opqdonut: Ah, okay |
| 14:33 | opqdonut | this affects the visibility of private stuff and also where defs go |
| 14:43 | duncanm | if i have a map {:a 1 :b 2} and i just want to keep the same map but increment all the vals by one, how should i write that? |
| 14:43 | fhd | Can I turn a keyword into a string? |
| 14:44 | fhd | e.g. :name -> "name" |
| 14:44 | duncanm | ,(str :foo) |
| 14:44 | clojurebot | ":foo" |
| 14:44 | fhd | wow |
| 14:44 | jkkramer | ,(name :foo) |
| 14:44 | clojurebot | "foo" |
| 14:44 | duncanm | even nicer |
| 14:44 | fhd | Thanks :) |
| 14:45 | mrBliss | ,(into {} (for [[k v] {:a 1, :b 2}] [k (inc v)])) |
| 14:45 | clojurebot | {:a 2, :b 3} |
| 14:45 | duncanm | mrBliss: that's kinda messy... |
| 14:45 | mrBliss | duncanm: indeed |
| 14:46 | duncanm | mrBliss: in my mind, what i want to do is to 'map' over the vals of a map and get back a map (and not a list of vals) |
| 14:47 | mrBliss | duncanm: unfortunately, that's not how seqs work :-( I've needed this too |
| 14:48 | amalloy | ,(let [m {:a 1 :b 2}] (zipmap (keys m) (map inc (vals m)))) |
| 14:48 | clojurebot | {:b 3, :a 2} |
| 14:50 | mrBliss | amalloy's version is faster on my machine |
| 14:50 | amalloy | really? i wonder why |
| 14:51 | amalloy | anyway you could easily write a generic map-over-vals function and then use that all over |
| 14:51 | mrBliss | zipmap is loop and recur and for is a bit messier. Also I create a new vector for every element in the map |
| 14:54 | hiredman | ,(doc fmap) |
| 14:54 | clojurebot | "clojure.contrib.generic.functor/fmap;[[f s]]; Applies function f to each item in the data structure s and returns a structure of the same kind." |
| 14:56 | amalloy | aha, nice |
| 14:59 | fhd | amalloy: Remember your replaceAll code from earlier? It works fine, but I don't really understand it. What does (fn [str [from to]] do? |
| 15:00 | fhd | amalloy: I presume it are the two values passed in from resume, but I don't really know that syntax |
| 15:02 | amalloy | fhd: do you understand destructuring yet? |
| 15:03 | fhd | amalloy: Haven't heard it in the context of Clojure yet, so I guess no |
| 15:03 | amalloy | k |
| 15:03 | amalloy | in binding forms like let and fn args, instead of just plain variable names you can give sequences |
| 15:03 | amalloy | that says "the thing that you will bind to this is a sequence; break it down and assign its elements to the variables i name" |
| 15:04 | fhd | amalloy: Ah, so the second argument is a vector? |
| 15:04 | amalloy | ,(let [[a b c] (range)] b) |
| 15:04 | clojurebot | 1 |
| 15:04 | fhd | I see, cool. |
| 15:05 | amalloy | since reduce is iterating over a seq of [from to] vectors, and tracking a single string as the result, the signature of the reduction function is [str [from to]] |
| 15:05 | fhd | Because reduce always passes two strings in, I see |
| 15:05 | fhd | Pretty clever |
| 15:05 | amalloy | indeed, destructuring is amazing |
| 15:06 | fhd | But most of the time I look at Clojure code, I feel like it's far too clever for me |
| 15:06 | fhd | And when I happen to write clever stuff myself, I feel like an evil genious. Well, at least evil. |
| 15:06 | fhd | Does that change with time? :) |
| 15:06 | amalloy | haha not yet |
| 15:07 | amalloy | check out http://rosettacode.org/wiki/Fibonacci_sequence#Clojure for the thing that most recently made my jaw drop (i wrote the description at the bottom to help me understand it) |
| 15:09 | fhd | OMG |
| 15:09 | fhd | I wonder if I'd be better at understanding this stuff if I had studied maths instead of CS :) |
| 15:10 | amalloy | probably not. you just have to get used to functional programming |
| 15:11 | fhd | amalloy: I really like it so far, but I realised just recently that functional programming wasn't OOP with closures :P |
| 15:11 | Adamant | amalloy: laziness is awesome, huh? :) |
| 15:11 | amalloy | heh |
| 15:11 | amalloy | Adamant: it's not the laziness so much as the clever way of maintaining metadata that you throw away before giving out the result |
| 15:12 | Adamant | not holding onto the head and intermediate results? yeah |
| 15:12 | amalloy | i feel like i've fully grokked it now that i've written some code that comverts to/from base N that uses the same idiom |
| 15:13 | rlb | fhd: destructuring can also be useful when defining multiple function bodies, i.e. (defn foo ([x] x) ([x [y z]] (+x y z))) |
| 15:13 | fhd | rlb: Basically overloading, huh? |
| 15:13 | rlb | it allows more sophisticated argument matching |
| 15:13 | fhd | rlb: Yeah, I imagine it can make for real beautiful signatures |
| 15:14 | amalloy | fhd: depends on your notion of beauty. if you nest too deeply it starts to become unreadable |
| 15:15 | amalloy | and there are more advanced features for destructuring. for example: |
| 15:15 | amalloy | ,(let [f (fn [{a :name, b :age}] ) (str a b))] (f {:age 9})) |
| 15:15 | clojurebot | Unmatched delimiter: ) |
| 15:16 | fhd | amalloy: True. But I find it more explicit than passing an array or a collection that contains two elements |
| 15:16 | amalloy | ,(let [f (fn [{a :name, b :age}] (str a b))] (f {:age 9})) |
| 15:16 | clojurebot | "9" |
| 15:16 | fhd | I need Clojure highlighting for irssi |
| 15:17 | fhd | Hm, that's essentially named parameters |
| 15:18 | amalloy | fhd: well, named parameters are a special case of map destructuring |
| 15:18 | mrBliss | fhd: Emacs comes with ERC |
| 15:18 | fhd | mrBliss: Haha :) Although an Emacs user, I was never a big fan of using it as an OS :P |
| 15:19 | amalloy | you can do map destructuring in more complicated ways, for example pull apart a map that's inside a vector |
| 15:19 | fhd | amalloy: Is that whole destructuring thing Clojure-only or general Lisp? I never did advanced stuff in Emacs Lisp, so I wouldn't know |
| 15:20 | amalloy | i believe CL has it but it's way less pretty/convenient |
| 15:20 | mrBliss | ,(let [{:keys [a b c]} {:a 1 :b 2 :c 3}] [a b c]) |
| 15:20 | clojurebot | [1 2 3] |
| 15:20 | fhd | I believe the variable parameter lists in Emacs use something similar |
| 15:20 | amalloy | lisp has &rest and &keys |
| 15:21 | fhd | Yeah, that's it. Then it's not destructuring |
| 15:21 | amalloy | and i think a destructuring-bind function that does stuff like clojure, but it's just harder to get at (like most lisp things) |
| 15:21 | Adamant | CL, please |
| 15:21 | amalloy | argh, i said CL last time |
| 15:21 | Adamant | I don't like the conflation of 'Lisp' with CL |
| 15:22 | amalloy | Adamant: it's a pretty...Common...mistake :) |
| 15:22 | Adamant | not that I don't like CL, but unless they plan to create another standard, formal or informal, it's a dead language |
| 15:22 | ohpauleez | amalloy: haha that was a good one |
| 15:22 | Adamant | oh yeah |
| 15:22 | Adamant | so good it's good while still being bad :P |
| 15:22 | Adamant | also, you must now put on the sunglasses while background music plays "YEeeoowww!!!!!" |
| 15:23 | amalloy | i prefer the drum sting while the audience groans |
| 15:23 | Adamant | hey, that works :P |
| 15:24 | fhd | When using line-seq, can I somehow preserve (to re-add) the EOL characters? |
| 15:25 | mrBliss | ,(interleave [1 2 3] (repeat "\n")) |
| 15:25 | clojurebot | (1 "\n" 2 "\n" 3 "\n") |
| 15:25 | mrBliss | replace [1 2 3] with your (line-seq ..) |
| 15:26 | fhd | mrBliss: Well, I would like to preserve the EOL chars exactly as they appear, if possible |
| 15:26 | fhd | mrBliss: i.e. whatever stile the file uses, plus add one to the end or not |
| 15:26 | mrBliss | yeah I just saw it too |
| 15:26 | fhd | s/stile/style/ |
| 15:26 | sexpbot | <fhd> mrBliss: i.e. whatever style the file uses, plus add one to the end or not |
| 15:26 | fhd | now that's neat |
| 15:27 | mrBliss | do you mean keeping \r\n or \n? |
| 15:27 | fhd | mrBliss: Yeah. If they're mixed, I'd like to keep them mixed. Don't want to play cop here. |
| 15:31 | technomancy | rbanffy: if you're still around, the short version is that it's very awkward to launch clojure processes from elisp because of the fact that the classpath must be known up front. so it's best to launch it with lein/cljr/etc and connect from Emacs |
| 15:35 | hsuh | why (= 1M 1.0M) is false? |
| 15:36 | amalloy | ,(map class [1M 1.0M]) |
| 15:36 | clojurebot | (java.math.BigDecimal java.math.BigDecimal) |
| 15:36 | amalloy | hm. dunno hsuh |
| 15:36 | ohpauleez | yeah, that's what I thought too |
| 15:37 | amalloy | it may be that bigdecimal keeps track of how much precision it's recording |
| 15:37 | amalloy | eg, for scientists 1 != 1.00 |
| 15:38 | amalloy | ,(map #(.precision %) [1M 1.0M]) |
| 15:38 | clojurebot | (1 2) |
| 15:39 | amalloy | hsuh, ohpauleez: ^^ |
| 15:39 | ohpauleez | ahh, for sure |
| 15:40 | hsuh | ok, but there should be some way of testing something like this without knowing the precision,no? (ok i see that zero? works for 0.00000M but anyway...) |
| 15:40 | _rata_ | hi |
| 15:42 | raek | if you convert them to the same type, you can always compare them |
| 15:43 | hsuh | ,(= (bigdec 300M) (bigdec 300.000M)) |
| 15:43 | clojurebot | false |
| 15:43 | lrenn | ,(= 0 (.compareTo 1M 1.0M)) |
| 15:43 | clojurebot | true |
| 15:45 | hsuh | ,(zero? (- 1.0M 1.000M)) |
| 15:45 | clojurebot | true |
| 15:46 | raek | I'm not sure, but maybe java's requirements on .equals has something to do with this |
| 15:46 | hsuh | ok |
| 15:46 | raek | this was changed pretty recently too |
| 15:48 | _schulte_ | so acording to http://clojure.org/lazy filter is not fully lazy, is that still the case? |
| 15:48 | amalloy | _schulte_: that proposal is very old |
| 15:49 | _rata_ | how can I have multiple mutually-referencing objects in one atom? |
| 15:49 | fhd | Is there anything similar to "instanceof" in Clojure? |
| 15:50 | amalloy | ,(instance? 1 Integer) |
| 15:50 | clojurebot | java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Class |
| 15:50 | _rata_ | fhd, instance? |
| 15:50 | _schulte_ | amalloy: but is filter still non-lazy? I have some out-of-memory errors that would indicate that something in the take/filter/map/pmap/filter/repeatedly stack is not lazy |
| 15:50 | amalloy | ,(instance? Integer 1) |
| 15:50 | clojurebot | true |
| 15:50 | amalloy | no, filter is lazy |
| 15:50 | fhd | Ah, great |
| 15:50 | amalloy | ,(supers (class {})) ; also sorta useful maybe |
| 15:50 | clojurebot | #{java.util.concurrent.Callable clojure.lang.IMeta clojure.lang.Counted clojure.lang.Seqable java.lang.Runnable java.io.Serializable clojure.lang.APersistentMap clojure.lang.ILookup java.lang.Object clojure.lang.Associative clojure.lang.IEditableCollection clojure.lang.IPersistentMap clojure.lang.IObj java.util.Map clojure.lang.IPersistentCollection java.lang.Iterable clojure.lang.AFn clojure.lang.IFn} |
| 15:51 | _schulte_ | amalloy: ok, thanks, on a related question then, do you know of a way to explicitly free an object, currently the GC is throwing out-of-memory errors because it's working too hard |
| 15:51 | amalloy | _schulte_: the GC will free things that aren't referenced anymore. can you post a gist or something so we can see what the problem is? |
| 15:52 | hsuh | ,(or (> 1M 1.0M) (< 1M 1.0M) (= 1M 1.0M)) |
| 15:52 | clojurebot | false |
| 15:52 | raek | http://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support <-- mentions something about equality for number types |
| 15:53 | hsuh | tks |
| 15:53 | _schulte_ | amalloy: sure, see http://gist.github.com/628831, something in this loop is running out of memory, the idea behind the code is to cycle through thousands of objects, dumping them to STDOUT and quitting after `out-num' successfull ones have been found |
| 15:53 | _schulte_ | any ideas/feedback are much appreciated |
| 15:54 | plathrop | Do people tend to deploy their Clojure apps with some way to connect and get a repl inside the application? |
| 15:54 | plathrop | So you can do live changes? |
| 15:55 | hsuh | raek: tl;dr: is not a simple problem :) |
| 15:55 | raek | for development, I always run a swank server in the clojure instance |
| 15:57 | raek | for the projects that I have running but not currently developing, I keep a repl in a screen, just in case |
| 15:58 | hsuh | raek: but do you change stuff or its more for peeking around? |
| 15:59 | aavram | Hello, I'm having an issue getting the links to work in labrepl somewhat like as described here : http://github.com/relevance/labrepl/issues/issue/13 . I have tried removing the lib directory and ~/.m2/repository/ but still can't get the links to work. Any suggestions? |
| 15:59 | amalloy | _schulte_: how long does evaluate-asm take to run? it looks like you may be spawning zillons of threads at once before any of them complete |
| 15:59 | raek | in my IRC bot, I change stuff all the time |
| 15:59 | _schulte_ | amalloy: <=8 seconds |
| 15:59 | hsuh | raek: i dont know if that is considered production :) |
| 15:59 | _schulte_ | amalloy: ok, thanks, I'll try removing the pmap |
| 16:00 | plathrop | raek: I do the same in development and was thinking it would be cool when you actually deploy the app to have the ability to connect to arepl. |
| 16:00 | raek | well, I wouldn't consider that project production either |
| 16:00 | _schulte_ | it'd be nice to be able to specify a threadpool size for pmap... |
| 16:00 | amalloy | your code mostly looks like it's fully lazy, so pmap is the only culprit that comes to mind |
| 16:01 | raek | a web app I made is running in the background, but I rarely touch that |
| 16:01 | _schulte_ | great thanks, I was confident in the lazyness until I saw the clojure.org/lazy page which implies that the clojure core isn't quite lazy |
| 16:01 | hsuh | plathrop: that sounds like fun, being able to fix things on the fly and impress people... but on think it would be very popular IRL |
| 16:01 | raek | but it is neat to be able to inspect variables when it's running, if I need to |
| 16:02 | plathrop | It was a useful trick when I was using list. |
| 16:02 | plathrop | lisp even |
| 16:02 | plathrop | Common lisp even :-P |
| 16:03 | hsuh | plathrop: that habit can be transferred to clojure, no prob i guess |
| 16:03 | fhd | In the body of a (for, I can add elements like this [:hello :world]. Can I also add two blocks of elements? |
| 16:04 | hsuh | slime repl lets me connect to a running swank, change namespace, redefine functions, its neat... |
| 16:04 | fhd | I tried [:hello :world][:foo :bar], but it just ignores one entry |
| 16:05 | _rata_ | fhd, what do you want to do? |
| 16:05 | _rata_ | do you want to return the four values from (for ...)? |
| 16:06 | _rata_ | then [[:hello :world] [:foo :bar]] would do it |
| 16:06 | fhd | I have a list of replacements that looks like this [["hello" "world"]["foo" "bar"]] etc. |
| 16:06 | fhd | I only added one replacement on each execution of (for, so this worked. But now I want to add two entries |
| 16:07 | fhd | _rata_: That would create a new vector, like this: [[["hello" "world"]["foo" "bar"]]["normal" "replacement"]] |
| 16:07 | fhd | It's the code amalloy|afk gave me earlier |
| 16:07 | rlb | fhd: not sure you can easily preserve the ends as-is. You could either just pull in the whole doc and filter it via slurp and multiple string/replaces, or write your own lazy seq that keeps the endings. See (source line-seq). Of course the slurp approach will be more expensive. |
| 16:08 | raek | fhd: if I understood the problem correctly, you need to return a collection of things, and apply concat to the seq you get from for |
| 16:08 | fhd | rlb: I guess I'll leave it like this for now. Did some ugly (if (= line (last lines)) "\n") for now |
| 16:09 | raek | ,(apply concat (for [x (range 5)] (if (even? x) [x x] [x]))) |
| 16:09 | clojurebot | (0 0 1 2 2 3 4 4) |
| 16:09 | fhd | raek: I don't think that's it |
| 16:09 | raek | the problem being "replacing certain elements with one elements and other with two" |
| 16:09 | fhd | Simply put, I want to return _two_ values from (for |
| 16:10 | raek | fhd: then you simply have to pair them together in some sort of collection |
| 16:10 | raek | or do two separate fors |
| 16:11 | nishant | ,(doc concat) |
| 16:11 | clojurebot | "([] [x] [x y] [x y & zs]); Returns a lazy seq representing the concatenation of the elements in the supplied colls." |
| 16:12 | raek | ,(map (juxt inc dec) (range 10)) |
| 16:12 | clojurebot | ([1 -1] [2 0] [3 1] [4 2] [5 3] [6 4] [7 5] [8 6] [9 7] [10 8]) |
| 16:13 | raek | fhd: what is your desired input and output? can you provide an example? |
| 16:14 | fhd_ | Hm. So that means I'll have to add my elements wrapped in another vector, than somehow flatten the whole thing and make pairs out of every two elements? |
| 16:16 | dpritchett | argh |
| 16:16 | dpritchett | i took a few months off from clojure and now i can't think functionally anymore |
| 16:17 | dpritchett | given a list of lists how do i return the list with the largest second element? ((1 1) (2 10) (3 4)) should return (2 10) |
| 16:18 | dpritchett | i'll bet i could do it with reduce |
| 16:18 | mrBliss | ,(apply (partial max-key second) '((1 1) (2 10) (3 4))) |
| 16:18 | clojurebot | (2 10) |
| 16:19 | fhd | Is it possible to somehow "flatten" a vector, i.e. turn [[[1 2]][3 4]] into [1 2 3 4]? |
| 16:19 | mrBliss | (doc flatten) |
| 16:19 | clojurebot | "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil." |
| 16:19 | fhd | oh |
| 16:19 | dpritchett | thanks |
| 16:19 | seancorfield | ,(flatten [[[1 2]][3 4]]) |
| 16:19 | clojurebot | (1 2 3 4) |
| 16:19 | seancorfield | note that it returns a seq, not a vector |
| 16:20 | ohpauleez | protocol experts, can someone inform me why I'm seeing a NullPointer when eval'ing this file http://github.com/ohpauleez/net-ns/blob/master/src/net_ns/server/atom_mapper.clj |
| 16:20 | seancorfield | ,(apply vec (flatten [[[1 2 ]][3 4]])) |
| 16:20 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (4) passed to: core$vec |
| 16:20 | seancorfield | hmm, i can never remember how to call vec :) |
| 16:21 | seancorfield | ,(vec (flatten [[[1 2]][3 4]])) |
| 16:21 | clojurebot | [1 2 3 4] |
| 16:21 | LaPingvino | vec works on seqs |
| 16:21 | LaPingvino | more or less like str |
| 16:21 | fhd | I just realized that it's far more elegant if I use a regex instead of two patterns |
| 16:22 | seancorfield | ,(str "Takes " "any" " number of" " strings") |
| 16:22 | fhd | Phew, I really didn't want to use the flatten solution :) |
| 16:22 | clojurebot | "Takes any number of strings" |
| 16:25 | raek | fhd: if you only want to flatten one level, you can use apply concat |
| 16:28 | fhd | raek: But is that really the best solution for adding two or more elements to a list using for? By adding a vector with two elements and then flatten the whole thing later? |
| 16:30 | raek | fhd: so you have a sequence of things, you produce a part of a sequence from each element and want those sequence to be made into one big sequence? |
| 16:31 | fhd | raek: Well, I'm producing a totally different sequence from another one. The sequence I produce has several entries per value of the original sequence. |
| 16:31 | plathrop | Is clojure.contrib.mock the best mock library out there? Trying to add unit tests to code that calls out to Java objects, and I don't want to create real Java objects. |
| 16:32 | rbanffy | technomancy: Thanks. I know it seems to be a bit awkward, but, since swank can do it by itself, there must be some way to teach it to use a different set of .jars |
| 16:33 | raek | fhd: then I would recommend (mapcat f coll), which is the same as (apply concat (map f coll)), or using (apply concat (for ...)) |
| 16:33 | ubii | does anyone know, if the Clojure-conf presentations will be recorded and made available online? |
| 16:33 | fhd | raek: i.e. removing exactly one "layer"? I'll do that then |
| 16:33 | raek | fhd: but to answer your question, yes. I would add them to a vector and use concat |
| 16:34 | raek | also, concat is lazy |
| 16:34 | bmh | Any recommendations for a computational geometry lib? Java or Clojure |
| 16:34 | raek | as is for and map |
| 16:35 | fhd | raek: Wow, it works. Magical. |
| 16:35 | _rata_ | how can I have multiple mutually-referencing objects in one atom? |
| 16:36 | ohpauleez | bmh: I would go with Clojure and call Java as needed |
| 16:37 | ohpauleez | bmh: What specifically are you doing? |
| 16:37 | ohpauleez | ohh, you're looking for a lib, my b |
| 16:37 | bmh | ohpauleez: That's the plan. 3d convex hull / delaunay triangulation on a sphere |
| 16:38 | ohpauleez | both those algos aren't bad to implement, but I'm digging around some code to see if I've used a library ever |
| 16:40 | ohpauleez | bmh: Typically in the past I've just called out to Mathematica and matlab as needed |
| 16:40 | bmh | ohpauleez: oh geez! Ouch |
| 16:41 | ohpauleez | yeah, I'm not coming up with much |
| 16:41 | ohpauleez | sorry bmh |
| 16:41 | bmh | I guess I can implement qhull |
| 16:42 | ohpauleez | yeah, it's pretty straight forward |
| 16:42 | bmh | even in 3d? |
| 16:42 | ohpauleez | if my memory serves me correctly |
| 16:43 | ohpauleez | My old lab just did it on the JVM and published, "On the use of Computational Geometry to Detect Software Faults at Runtime" |
| 16:44 | fhd | Wow, accomplished quite a lot today, thanks to you guys! Cya. |
| 16:45 | bhenry | what would a ring handler look like if i want a link to make the browser ask the user to download a *.xls |
| 16:47 | amalloy | bhenry: the header for that is Content-Disposition=attachment, as i recall. google that and you'll probly find the right answer |
| 16:47 | bhenry | yeah i just dead. do i just give my handler a :headers key? |
| 16:47 | bhenry | i just did* |
| 16:48 | amalloy | bhenry: probably. i don't actually use ring |
| 16:48 | raek | bhenry: include a {"Content-Disposition" "attachment; filename=foo.bar"} header |
| 16:48 | bhenry | raek: thanks. |
| 16:49 | bhenry | when i first started using ring i made a template that takes a context map, and i forgot that i already have a headers key in there. |
| 16:50 | raek | bhenry: also remember to set the Content-Type to the correct MIME type |
| 16:51 | bmh | ohpauleez: found one: http://www.cs.ubc.ca/~lloyd/java/quickhull3d.html |
| 16:52 | ohpauleez | awesome! |
| 16:53 | raek | ohpauleez: I looked at your atom-mapper code, but I could find in the clojure docs that extend-type takes doc strings |
| 16:55 | ohpauleez | ahh, I didn't even think of that. Thanks raek . Let me try that out |
| 16:56 | mattrepl | is there a simple way to get the source path for where a namespace is defined on the class path? |
| 16:58 | ohpauleez | raek: That was it |
| 17:01 | raek | defprotocol takes docstrings though... (and is where (doc someprotocol-method) takes the docs from) |
| 17:02 | ohpauleez | I see that now, thanks! |
| 17:03 | raek | np :) |
| 17:17 | vIkSiT | wow, this place has *grown* in a month :) |
| 17:26 | bhenry | okay so query params come in as either a string or a vector. how can i idiomatically make a one item vector of the string when there is only one? i.e. (something string-or-vec) returns vector of string(s) |
| 17:26 | bhenry | do i have to do a conditional to check if it's a vector or string and act accordingly? |
| 17:27 | gfrlog | ,(vector? [123]) |
| 17:27 | clojurebot | true |
| 17:27 | gfrlog | ,(string? "haha) |
| 17:27 | clojurebot | EOF while reading string |
| 17:28 | raek | are you talking about ring? in that case, when do you get query params as a vector? |
| 17:28 | gfrlog | ,(string? "haha") |
| 17:28 | clojurebot | true |
| 17:29 | bhenry | if the same param is used twice like opt=1&opt=2 |
| 17:29 | bhenry | opt comes in as ["1" "2"] |
| 17:29 | amalloy | ,(let [x "x"] (or (vector? x) [x])) |
| 17:29 | clojurebot | ["x"] |
| 17:29 | amalloy | oh that won't work :P |
| 17:30 | raek | ah, didn't know that ring.middleware.params/wrap-params could do that... |
| 17:30 | bhenry | raek i was surprised too, but i want to use it to my advantage |
| 17:31 | raek | ,(letfn [(vectorize [x] (if (vector? x) x [x]))] [(vectorize 1) (vectorize [1 2])]) |
| 17:31 | clojurebot | [[1] [1 2]] |
| 17:31 | gfrlog | ,(doc letfn) |
| 17:31 | clojurebot | "([fnspecs & body]); Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body. fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+)" |
| 17:32 | gfrlog | clojure documentation does _not_ talk down to you |
| 17:32 | raek | yes, it feels a bit odd that r.m.p/assoc-param need to check whether the param is a vector in order to add more elements, and that the user then needs to check whether it is a vector again in order to use it... |
| 17:32 | raek | :/ |
| 17:34 | raek | maybe this would have been better if it was split into two different wrap-params middlewares |
| 17:36 | raek | to have an as simple as possible "data contract" (what the stuff that goes in and out of functions looks like), is essential in Clojure, IMHO |
| 17:40 | ohpauleez | ~seen stuartsierra |
| 17:40 | clojurebot | stuartsierra was last seen parting #clojure, 212 minutes ago |
| 17:46 | gfrlog | ,(format "%d hours, %d minutes" (quot 212 60) (rem 212 60)) |
| 17:46 | clojurebot | "3 hours, 32 minutes" |
| 18:06 | ohpauleez | _fogus_: ping |
| 18:07 | raek | When speaking only in tautologies, you have to state facts, but also don't, or don't. |
| 18:13 | amalloy | ,((juxt quot rem) 212 60) ; <== gfrlog |
| 18:13 | clojurebot | [3 32] |
| 18:13 | gfrlog | ,(doc juxt) |
| 18:13 | clojurebot | "([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]" |
| 18:14 | gfrlog | amalloy: awesome |
| 18:14 | gfrlog | there's no excuse for repetition |
| 18:14 | amalloy | juxt is a great trick. ever since i saw raek use it for the first time, i try to find juxt in every problem i solve :P |
| 18:15 | gfrlog | hmmmm |
| 18:15 | gfrlog | ,((juxt juxt juxt) juxt juxt) |
| 18:15 | clojurebot | [#<core$juxt$fn__3657 clojure.core$juxt$fn__3657@d1ea84> #<core$juxt$fn__3657 clojure.core$juxt$fn__3657@17baeb1>] |
| 18:15 | amalloy | lol |
| 18:15 | gfrlog | solved that problem |
| 18:15 | amalloy | ,((comp (juxt juxt juxt) juxt) juxt juxt) |
| 18:16 | clojurebot | [#<core$juxt$fn__3655 clojure.core$juxt$fn__3655@b56813> #<core$juxt$fn__3655 clojure.core$juxt$fn__3655@1c3c0fd>] |
| 18:16 | gfrlog | so much abstraction the poor JVM is going through and all we get are some hex codes |
| 18:16 | amalloy | a good lesson: everything is bits, eventually |
| 18:16 | raek | amalloy: :) |
| 18:17 | gfrlog | it'd be fun to have a program that takes a java object and creates a graph of the nested objects all the way down to primitives |
| 18:17 | gfrlog | I guess that's not necessarily acyclic though :( |
| 18:17 | raek | amalloy: (btw, what did I use juxt for that time?) |
| 18:19 | amalloy | raek: awww, i just looked at my logs and it was actually jkkramer; you told him how beautiful it was |
| 18:19 | amalloy | ,(map (juxt first count) (partition-by identity [:a :a :a :b :b :c :d :d])) |
| 18:19 | clojurebot | ([:a 3] [:b 2] [:c 1] [:d 2]) |
| 18:20 | raek | ah, yes... that one is really neat |
| 18:20 | gfrlog | ,(partition-by identity [:a :a :b :b :c :d :d]) |
| 18:20 | clojurebot | ((:a :a) (:b :b) (:c) (:d :d)) |
| 18:20 | Derander | ,(partition-by identity [:a :a :a :b :b :c :d :d]) |
| 18:20 | clojurebot | ((:a :a :a) (:b :b) (:c) (:d :d)) |
| 18:20 | Derander | lol. |
| 18:20 | Derander | ,(count (partition-by identity [:a :a :a :b :b :c :d :d])) |
| 18:20 | clojurebot | 4 |
| 18:21 | gfrlog | ,(+ 4 12) |
| 18:21 | clojurebot | 16 |
| 18:21 | Derander | ,(pow 4 12) |
| 18:21 | clojurebot | java.lang.Exception: Unable to resolve symbol: pow in this context |
| 18:21 | gfrlog | computers know the darndest things |
| 18:21 | gfrlog | ,(#(% %) #(% %)) |
| 18:21 | clojurebot | java.lang.StackOverflowError |
| 18:22 | Derander | okay, so guids collide sometimes. Why can't one prefix a guid with the originating computer's name to avoid collisions? |
| 18:22 | gfrlog | some uuid schemes use that |
| 18:22 | Derander | is there a downside? |
| 18:22 | gfrlog | security I think |
| 18:22 | gfrlog | at least for a general implementation |
| 18:22 | Derander | because someone knows where something comes from? |
| 18:22 | gfrlog | yeah |
| 18:22 | Derander | oh, I don't give a rats ass about that |
| 18:23 | gfrlog | then you're probably fine |
| 18:23 | Derander | just writing a sync engine between my desktop & laptop. okay. |
| 18:23 | Derander | thanks. I was wondering if I'd gone insane and was missing something |
| 18:23 | gfrlog | I doubt you have to worry about collisions though |
| 18:23 | Derander | gfrlog: "In the OSF-specified algorithm for generating new (V1) GUIDs, the user's network card MAC address is used as a base for the last group of GUID digits, which means, for example, that a document can be tracked back to the computer that created it. This privacy hole was used when locating the creator of the Melissa worm[2]. Most of the other digits are based on the time while generating the GUID." |
| 18:24 | Derander | sorry for wall of text, but apparently that is basically what is done already |
| 18:24 | gfrlog | that's on wiki? that's where I read it |
| 18:24 | Derander | mmhm |
| 18:24 | gfrlog | I thought it said there were newer versions though |
| 18:24 | amalloy | Derander: yes, but there are a lot of other GUID/UUID types than v1. as it happens v1 is back in vogue now that cassandra uses them, but for quite a while they were out of fashion |
| 18:25 | Derander | yeah, I've never read anything but hate about guids in general |
| 18:25 | amalloy | v3 and v5 especially, for some reason |
| 18:25 | Derander | when they seem like a decent solution to a common problem |
| 18:25 | gfrlog | we should namespace guids |
| 18:26 | amalloy | ,(in-ns guids) ; this is gonna fail :( |
| 18:26 | clojurebot | java.lang.Exception: Unable to resolve symbol: guids in this context |
| 18:26 | amalloy | ,(ns guids) ; this is gonna fail :( |
| 18:26 | clojurebot | nil |
| 18:26 | amalloy | really? |
| 18:26 | gfrlog | what's the guids ns? |
| 18:27 | amalloy | ,(do (ns guids) *ns*) |
| 18:27 | clojurebot | #<Namespace guids> |
| 18:27 | amalloy | gfrlog: i dunno |
| 18:27 | amalloy | just made it up |
| 18:27 | amalloy | ,(do (ns guiasfdsds) *ns*) |
| 18:27 | clojurebot | #<Namespace guiasfdsds> |
| 18:27 | gfrlog | that's the easiest way to write code ever |
| 18:28 | arrummzen | How do I test for inequality in clojure? |
| 18:28 | amalloy | ,(not= 1 4) |
| 18:28 | clojurebot | true |
| 18:28 | arrummzen | =) |
| 18:29 | gfrlog | ,(if (zero? (- 1 4)) true false) |
| 18:29 | clojurebot | false |
| 18:29 | gfrlog | whoops backwards |
| 18:29 | gfrlog | that one always trips me up |
| 18:29 | amalloy | ,(not (zero? (- 1 4))) |
| 18:29 | clojurebot | true |
| 18:30 | amalloy | gfrlog: (if a true false) is a sin |
| 18:30 | gfrlog | lol |
| 18:30 | amalloy | ,(boolean 'a) |
| 18:30 | clojurebot | true |
| 18:30 | gfrlog | I was about to ask if that exists |
| 18:30 | gfrlog | in other languages you can use !! |
| 18:30 | amalloy | <== always one step ahead |
| 18:30 | gfrlog | which is fun |
| 18:31 | amalloy | try it in java :P |
| 18:32 | gfrlog | oh gross |
| 18:32 | gfrlog | but here goes |
| 18:32 | amalloy | ,(nth (iterate not 'a) 3) |
| 18:32 | clojurebot | false |
| 18:32 | gfrlog | !(ob==null || ob == false) |
| 18:32 | amalloy | ,(tale 5 (iterate not 'a)) |
| 18:32 | clojurebot | java.lang.Exception: Unable to resolve symbol: tale in this context |
| 18:32 | amalloy | ,(take 5 (iterate not 'a)) |
| 18:32 | gfrlog | that probably wouldn't compile |
| 18:32 | clojurebot | (a false true false true) |
| 18:33 | gfrlog | lol |
| 18:33 | gfrlog | why doesn't clojure have an eval-java function? |
| 18:33 | amalloy | gfrlog: it would compile if obj were a Boolean, i think |
| 18:34 | gfrlog | yeah |
| 18:34 | amalloy | ,(not (or (nil? Boolean/TRUE) (false? Boolean/TRUE))) |
| 18:34 | clojurebot | true |
| 18:35 | _ulises | evening folk |
| 18:35 | gfrlog | ,(= Boolean/TRUE true) |
| 18:35 | clojurebot | true |
| 18:35 | amalloy | ,(if (Boolean. "true") 1 2) |
| 18:35 | clojurebot | 1 |
| 18:36 | amalloy | ,(if (Boolean. "false") 1 2) |
| 18:36 | clojurebot | 1 |
| 18:37 | gfrlog | (println "DENIED") |
| 18:37 | gfrlog | dang comma |
| 18:37 | Derander | ,(println "DENIED") |
| 18:37 | clojurebot | DENIED |
| 18:38 | amalloy | ,(or (def x 1) (println 'DENIED)) |
| 18:38 | clojurebot | DENIED |
| 18:38 | gfrlog | omg did it work? |
| 18:38 | amalloy | lol no |
| 18:38 | bmh | What's the correct way to turn a primitive matrix (i.e. int[][]) into a clojure collection? |
| 18:38 | Derander | no one knows |
| 18:38 | gfrlog | :) |
| 18:38 | amalloy | ,(seq (byte-array 10)) |
| 18:38 | clojurebot | (0 0 0 0 0 0 0 0 0 0) |
| 18:39 | bmh | amalloy: wrong direction |
| 18:39 | bmh | oh |
| 18:39 | bmh | seq |
| 18:39 | gfrlog | ,(short-array 10) |
| 18:39 | clojurebot | #<short[] [S@f51f3b> |
| 18:39 | amalloy | ,(map seq (seq (make-array Integer/TYPE 3 3))) |
| 18:39 | clojurebot | ((0 0 0) (0 0 0) (0 0 0)) |
| 18:39 | gfrlog | primitives are fun |
| 18:40 | kmc | i asked this before, but don't recall an answer; sorry if i missed it or something |
| 18:40 | kmc | how lightweight are Clojure threads? |
| 18:40 | gfrlog | I think they are java threads |
| 18:41 | kmc | ok |
| 18:41 | kmc | how lightweight are Java threads? ;) |
| 18:41 | gfrlog | dunno :) |
| 18:41 | gfrlog | they're not erlang I don't think |
| 18:41 | amalloy | not very |
| 18:41 | kmc | ok |
| 18:41 | kmc | so i can't spawn 100,000 of them? |
| 18:42 | amalloy | bad idea; maybe possible |
| 18:42 | gfrlog | time for erlang! |
| 18:42 | kmc | or ghc haskell |
| 18:42 | kmc | new IO manager in GHC 7.0 too |
| 18:42 | amalloy | ,(for [_ 10] (java.lang.Thread.)) |
| 18:42 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer |
| 18:43 | amalloy | ,(for [_ (range 10)] (java.lang.Thread.)) |
| 18:43 | clojurebot | (#<Thread Thread[Thread-1979,5,main]> #<Thread Thread[Thread-1980,5,main]> #<Thread Thread[Thread-1981,5,main]> #<Thread Thread[Thread-1982,5,main]> #<Thread Thread[Thread-1983,5,main]> #<Thread Thread[Thread-1984,5,main]> #<Thread Thread[Thread-1985,5,main]> #<Thread Thread[Thread-1986,5,main]> #<Thread Thread[Thread-1987,5,main]> #<Thread Thread[Thread-1988,5,main]>) |
| 18:43 | gfrlog | (conj todo-list "port clojure to erlang" "learn haskell") |
| 18:43 | raek | kmc: clojure uses java's executor framework for agents and futures |
| 18:43 | Derander | amalloy: is it slightly dangerous that we can spawn threads on clojurebot? |
| 18:44 | raek | kmc: which means that all actions sent to agents with 'send' is handler by a fixed-size thread pool |
| 18:44 | amalloy | yes; it's a possible security hole we found last night |
| 18:44 | Derander | fuuuuuuun |
| 18:44 | amalloy | ,(for [_ (range 10)] (Thread.)) |
| 18:44 | clojurebot | (#<Thread Thread[Thread-1990,5,main]> #<Thread Thread[Thread-1991,5,main]> #<Thread Thread[Thread-1992,5,main]> #<Thread Thread[Thread-1993,5,main]> #<Thread Thread[Thread-1994,5,main]> #<Thread Thread[Thread-1995,5,main]> #<Thread Thread[Thread-1996,5,main]> #<Thread Thread[Thread-1997,5,main]> #<Thread Thread[Thread-1998,5,main]> #<Thread Thread[Thread-1999,5,main]>) |
| 18:44 | kmc | cool raek |
| 18:44 | amalloy | oh. that didn't work before. i think raek blew up more of his security |
| 18:45 | gfrlog | ,(Thread. (partial println "haha")) |
| 18:45 | clojurebot | #<Thread Thread[Thread-2001,5,main]> |
| 18:45 | kmc | when you call (Thread.) with no argument like that, what thread does it actually spawn? |
| 18:45 | _ulises | hey all, I have a bit of an odd request: I am looking for a mentor to improve my knowledge of Clojure and functional programming (amongst other things) so if anybody is interested/up to the task, please take a look at http://pastebin.com/rn4h8Tk1 and let me know your thoughts :) |
| 18:45 | Derander | (Thread.) |
| 18:45 | Derander | ,(Thread.) |
| 18:45 | clojurebot | #<Thread Thread[Thread-2003,5,main]> |
| 18:45 | amalloy | threads don't do anything until you call .start |
| 18:45 | amalloy | so these threads, i think, just get GCed immediately |
| 18:46 | Derander | ,(.start (Thread.)) |
| 18:46 | clojurebot | nil |
| 18:46 | Derander | ,(.start (Thread. (partial println "hi"))) |
| 18:46 | clojurebot | nil |
| 18:47 | gfrlog | the println is apparently invisible either way |
| 18:48 | amalloy | background threads don't have access to the terminal |
| 18:48 | amalloy | iirc |
| 18:48 | raek | ,(.start (Thread. (bound-fn [] (println "hi")))) |
| 18:48 | clojurebot | nil |
| 18:48 | raek | the *out* binding is thread-local |
| 18:48 | amalloy | ,(doc bound-fn) |
| 18:48 | clojurebot | "([& fntail]); Returns a function defined by the given fntail, which will install the same bindings in effect as in the thread at the time bound-fn was called. This may be used to define a helper function which runs on a different thread, but needs the same bindings in place." |
| 18:49 | raek | that's why prints in other threads don't print in the slime repl in emacs |
| 18:49 | gfrlog | ,(.start (Thread. (.println System/out "okay"))) |
| 18:49 | clojurebot | nil |
| 18:49 | raek | new thread gets the root binding of *out*, which is System/out |
| 18:49 | gfrlog | ,(.println System/out "then why don't they work?") |
| 18:49 | clojurebot | nil |
| 18:50 | amalloy | raek: but even in a repl println from a separate thread doesn't work |
| 18:50 | gfrlog | it gets blocked? |
| 18:50 | raek | ,(let [out *out*] (.start (Thread. (binding [*out* out] (println "hi"))))) |
| 18:50 | clojurebot | hi |
| 18:50 | amalloy | oh, nice |
| 18:51 | raek | you can also do (alter-var-root #'*out* (constantly *out*)) to set the root binding of *out* to the one in the current thread |
| 18:51 | gfrlog | raek: is your *out* special in clojurebot, or also System/out? |
| 18:52 | amalloy | ,(let [out *out*] (.start (Thread. (binding [*out* out] (dotimes [n 10] (. java.lang.Thread sleep 5000) (println n))))))) ; does this timeout? |
| 18:52 | clojurebot | Execution Timed Out |
| 18:52 | raek | I don't know how clojurebot is implemented, but I believe *out* is bound to a fn that sends messages over IRC |
| 18:52 | raek | *bound to a writer |
| 18:53 | gfrlog | oh, I mistakenly inferred you wrote it from some previous comment I've forgotten |
| 18:53 | amalloy | raek: i don't think it can be that simple, or my println would write at least once |
| 18:53 | raek | I write bots, but not clojurebot :) |
| 18:53 | raek | clojurebot is hiredman's bot |
| 18:54 | amalloy | clojurebot: author? |
| 18:54 | clojurebot | Pardon? |
| 18:54 | amalloy | clojurebot: author is hiredman |
| 18:54 | clojurebot | Ack. Ack. |
| 18:54 | gfrlog | clojurebot: Pardon? |
| 18:54 | clojurebot | Huh? |
| 18:54 | gfrlog | clojurebot: Huh? |
| 18:54 | clojurebot | excusez-moi |
| 18:54 | rlb | Are there ways other than compile to make 1.2 startup much faster? |
| 18:54 | amalloy | clojurebot: source? |
| 18:54 | clojurebot | source is http://github.com/hiredman/clojurebot/tree/master |
| 18:55 | raek | anyway, println prints to whatever is in *out*. the default root binding of *out* is System/out wrapped in a PrintWriter. |
| 18:55 | amalloy | clojurebot: cake? |
| 18:55 | clojurebot | cheesecake is delicious. |
| 18:55 | amalloy | damn it. he won't remember when i tell him about cake |
| 18:55 | amalloy | rlb: try cake |
| 18:57 | raek | http://github.com/hiredman/clojurebot/blob/master/src/hiredman/sandbox.clj#L123 |
| 19:00 | rlb | amalloy: thanks, I know it might also be possible to use something like nailgun, but in this case I'm interested in speeding up standalone executable time. |
| 19:01 | amalloy | rlb, you could start the jvm in -client mode, but that won't make a very big difference. java is not a fast-startup language, and clojure is another layer on top of it |
| 19:01 | gfrlog | irb starts pretty fast -- maybe implement clojure in ruby |
| 19:06 | rlb | amalloy: right, client doesn't really help. An empty java program runs in about 0.1s here, a compiled empty clojure program, about 0.9s, so about 9x slower, and pushing a notable threshold wrt command-line interactivity. |
| 19:07 | rlb | I was just trying to determine if it might be feasible to use clojure for some command-line tools that needed to be fairly fast. |
| 19:07 | gfrlog | is the Integer constructor the preferred way to convert string to int? |
| 19:08 | rlb | gfrlog: that's reasonable. |
| 19:09 | plathrop | ,(contains? [:plathrop :foo :bar] :plathrop) |
| 19:09 | clojurebot | false |
| 19:09 | plathrop | What am I missing here about contains? I'd expect a true. |
| 19:10 | ohpauleez | plathrop: use some |
| 19:10 | plathrop | ,(some [:plathrop :foo :bar] :plathrop) |
| 19:10 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword |
| 19:10 | ohpauleez | (some #{"a"} ["a" "b" "c"]) |
| 19:10 | raek | plathrop: contains? checks for keys. in arrays, the indicies are the keys |
| 19:10 | ohpauleez | ,(some #{"a"} ["a" "b" "c"]) |
| 19:10 | clojurebot | "a" |
| 19:10 | ohpauleez | ,(some #{"d"} ["a" "b" "c"]) |
| 19:10 | clojurebot | nil |
| 19:11 | plathrop | raek: ah, thanks for the explanation |
| 19:11 | raek | plathrop: either use sets (if you check whether an element is there more that once) or 'some' |
| 19:11 | raek | ,(contains? #{"a" "b" "c"} "a") |
| 19:11 | clojurebot | true |
| 19:12 | raek | sets have constant time* membership tests |
| 19:12 | plathrop | I think sets is what I want. Thanks folks! |
| 19:13 | raek | ,[(#{"a" "b" "c"} "a") (#{"a" "b" "c"} "d")] |
| 19:13 | clojurebot | ["a" nil] |
| 19:13 | raek | also, you can use the set as a predicate directly, unless nil can appear in the set |
| 19:33 | Derander | 1.5 hours until weekend |
| 19:33 | Derander | I have never been more excited to get home and fire up emacs |
| 19:33 | amalloy | Derander: you need to get home to fire up emacs? they don't have ssh at your place of business? |
| 19:33 | Derander | oh, I'm working in emacs on a laptop |
| 19:34 | Derander | it's just that I'm not working on my own programs :-) |
| 19:34 | Derander | I'm @ work right now. |
| 19:34 | amalloy | well, just work on them secretly |
| 19:34 | Derander | there is a thought |
| 19:34 | amalloy | or while your actual work "compiles" |
| 19:34 | Derander | if only ruby compiled |
| 19:35 | amalloy | http://xkcd.com/303/ |
| 19:35 | Derander | I only get to pull that excuse when I'm installing some library |
| 19:35 | Derander | that has c extensions |
| 19:41 | amalloy | Derander: you could recompile ruby. the latest version is much better |
| 19:41 | Derander | yeah, unfortunately I've already got 1.9.2 running :-( |
| 19:53 | bmh | is it possible to list two licenses in project.clj in a lein project? |
| 19:59 | maravillas | bmh: check out http://github.com/technomancy/leiningen/blob/master/sample.project.clj |
| 19:59 | maravillas | the comment above the :license entry says :licenses is supported |
| 19:59 | bmh | maravillas: I did see that, but it doesn't have a use case. If I specify more than one :name it will explode |
| 20:02 | amalloy | bmh: i'd guess it's like: :licenses [{:name foo} {:name bar}] |
| 20:02 | maravillas | did you try :licenses [{:name ...} {:name ...}] ? |
| 20:02 | bmh | that sounds like a reasonable thing to try |
| 20:02 | maravillas | looks like lein pom just concats :licenses, :licences, and the single :license entry |
| 20:03 | maravillas | single :license and :licence entries, that is |
| 20:04 | bmh | hooray |
| 20:04 | amalloy | maravillas: haha, so you don't need to use :licenses if you have two? you can use licenses and licences |
| 20:04 | amalloy | er. but without any Ss |
| 20:05 | maravillas | yeah, seems to be aware of both spellings :) |
| 20:05 | maravillas | http://github.com/technomancy/leiningen/blob/master/src/leiningen/util/maven.clj#L224 |
| 20:06 | bmh | maravillas: very deferential to the Commonwealth, I suppose |
| 20:08 | technomancy | heh; nice. (that wasn't me) |
| 20:10 | maravillas | looks like michal marczyk |
| 20:13 | yayitswei | has anyone deployed a clojure webapp with nginx and can give me some pointers? |
| 20:14 | yayitswei | or if not that, a recommendation for the simplest way to deploy a web app |
| 20:16 | Raynes | yayitswei: In the simplest case, a simple proxy_pass will do the trick. I've had success with this: http://gist.github.com/629193 |
| 20:16 | Raynes | I'd stick around and help more, but I've got to take off. Good luck. <3 |
| 20:16 | yayitswei | thanks Raynes |
| 20:19 | jeff__ | hi all. i'm looking for some advice. what would be the most idiomatic way of processing a very long list/array of numeric data returning a result. the result itself is a bunch of different calculations, some of which are scalars and others are themselves lists. what i'm doing for now is (reduce my-function initial-state) where initial-state is a map which gets new values assoc'ed in my-funtion as appropriate. is this a good way to do |
| 20:19 | jeff__ | this? |
| 20:19 | clojurebot | this is not a bug |
| 20:21 | jeff__ | actually, it's more like: (reduce my-function initial-state my-list-of-numeric-data) |
| 20:40 | _rata_ | is there any problem to have a ref containing a vector of refs? (but the later aren't mutated) |
| 20:45 | quotemstr | Has anyone here worked with JUNG from Clojure? I want to write a program that manipulates a graph and makes a movie out of it, and Java has all the good libraries. |
| 20:59 | nollidj | at the slime repl, is there a way to break a running command and jump into a debugging mode? |
| 21:00 | nollidj | i am wishing i had something like the integration gdb has with emacs, so that i can step ahead, examine the local environment, go up and down the stack, etc, within a running program |
| 21:01 | nollidj | is there a way to get slime to do that? |
| 21:03 | bhenry | nollidj: http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml |
| 21:04 | quotemstr | Awesome! |
| 21:04 | quotemstr | #!/usr/bin/clj works as expected! |
| 21:04 | quotemstr | Is there a performance penalty for doing that? |
| 21:05 | nollidj | bhenry: thanks. it's encouraging that some work is being done, but blegh. i hope this makes it into swank-clojure |
| 21:05 | nollidj | so, is it true that atm there is no way within just emacs/slime/swank-clojure to set a breakpoint? |
| 21:05 | bhenry | it is. |
| 21:06 | bhenry | if you're using swank clojure you should be able to put (swank.core/break) somewhere in your code |
| 21:06 | nollidj | thanks for the info. i'll see what debug-repl can do |
| 21:07 | nollidj | ah, my problem is that somewhere in the program things just stall (cpu usage drops to 0%, memory allocation stops) |
| 21:07 | nollidj | ordinarily, i'd send it a signal while running it in a debugger and step it forward to see what's going on |
| 21:07 | nollidj | i will continue to sprinkle printlns or maybe some clojure.core/breaks |
| 21:07 | bhenry | oh i see. not sure how to go about that |
| 21:07 | nollidj | er, swank.core |
| 21:07 | nollidj | thanks for debug-repl, though |
| 21:08 | bhenry | the article is about how that functionality from debug-repl is now in swank-clojure |
| 21:09 | nollidj | oh, that is good |
| 22:26 | dpritchett | evening |
| 22:27 | mabes | hello |
| 22:30 | jsanda | can someone show me an example of using the map fn on a map. i'm struggling a bit with how to do this |
| 22:32 | dpritchett | C-c M-p is supposed to load the namespace under my cursor into slime, right? |
| 22:32 | mabes | ,(map (fn [[k v]] [(str k) (inc v)]) {:foo 12 :bar 34}) |
| 22:32 | clojurebot | ([":foo" 13] [":bar" 35]) |
| 22:33 | mabes | jsanda: ^ destructuring the k,v is what you need to do |
| 22:33 | jsanda | that's what i'm struggling with |
| 22:33 | jsanda | mabes: thx for the example |
| 22:33 | jsanda | that helps |
| 22:33 | mabes | and if you need it to be a map you can use into |
| 22:33 | mabes | ,(into {} (map (fn [[k v]] [(str k) (inc v)]) {:foo 12 :bar 34})) |
| 22:33 | clojurebot | {":foo" 13, ":bar" 35} |
| 22:37 | Raynes | It might be cleaner to use for if you need to destructure something: (into {} (for [[k v] {:foo 12 :bar 34}] [(str k) (inc v)])) |
| 22:38 | mabes | yeah, good point |
| 22:43 | jsanda | Raynes: that does seem a bit more intuituve |
| 22:43 | jsanda | thx for both examples |
| 23:09 | cemerick | Raynes: how's life lately? :-) |
| 23:09 | Raynes | cemerick: Fantastic. The excitement continues to build. |
| 23:10 | cemerick | good, good |
| 23:11 | Raynes | Yours? :> |
| 23:11 | cemerick | Hectic. Ever so slightly unpleasant, but hopefully that's temporary. |
| 23:29 | bhenry | dpritchett: my slime repl using swank-clojure has the same highlighting as any of my clojure buffers. i didn't have to do anything special |
| 23:29 | bhenry | just used emacs starter kit and elpa |
| 23:30 | dpritchett | i dont have the starter kit |
| 23:30 | dpritchett | i guess i could nuke everything and start over |
| 23:30 | dpritchett | but i'll miss my toolbars |
| 23:30 | rdsr | ,(partition 3 [1 2]) |
| 23:30 | clojurebot | () |
| 23:31 | rdsr | isn't this behaviour a little wierd? |
| 23:31 | mabes | ,(partition-all 3 [1 2]) |
| 23:31 | clojurebot | ((1 2)) |
| 23:31 | rdsr | oops I'm using the wrong fn |
| 23:31 | rdsr | thnks mabes :) |
| 23:31 | mabes | rdsr: np, I knew exactly where you were going ;) |
| 23:32 | rdsr | hehe |
| 23:32 | _rata_ | dpritchett, isn't it clojure-mode what you need? |
| 23:33 | dpritchett | clojure-mode doesn't work with the repl... bhenry seems to be right though |
| 23:34 | bhenry | dpritchett, there's got to be some hook out there |
| 23:35 | dpritchett | it's fine, i didnt' have much in my .emacs.d folder |
| 23:35 | dpritchett | so i'm rebuilding it |
| 23:35 | dpritchett | for the 3rd time today :) |
| 23:35 | technomancy | it's not in the starter kit |
| 23:39 | dpritchett | so technomancy do you have good highlighting in your swank repl? |
| 23:39 | technomancy | I do not |
| 23:39 | technomancy | thats' how I know it's not in the starter kit =) |
| 23:39 | dpritchett | man |
| 23:40 | bhenry | dpritchett: apparently i'm retarded. i just checked and i don't either. my bad. |
| 23:40 | technomancy | (add-hook 'slime-repl-mode-hook 'clojure-mode-font-lock-setup) ;; there's the trick |
| 23:40 | technomancy | makes the prompt non-highlighted though, which is too bad |
| 23:40 | technomancy | still nice |
| 23:40 | technomancy | I should put that in the readme |
| 23:41 | mabes | ahh, clojure-mode-font-lock-setup.. didn't think about that... I had only tried the major mode which didn't work out too well as you could imagine |
| 23:41 | dbleyl | hello |
| 23:41 | technomancy | would be more complicated if you still want to use slime with CL |
| 23:41 | dpritchett | clojure is my only slimy language at the moment |
| 23:41 | dpritchett | so i add that line to the end of init.el i guess? |
| 23:41 | technomancy | apparently there are still some greybeards who care about that; I'll let them come up with a form that works for it. |
| 23:41 | technomancy | ja |
| 23:41 | dpritchett | i just evaled it in my scratch buffer and nothing looks different |
| 23:42 | technomancy | you'd have to reconnect for it to take effect |
| 23:43 | Derander | it took me far too long to learn about c-m-x. |
| 23:43 | Derander | far too many keystrokes wasted moving to the end of the top level sexp and then c-x'ing |
| 23:43 | dbleyl | Is there any way to influence the compiled java output of :gen-class? Trying to interop with a Java lib that expects a run method to be discovered thru reflection. |
| 23:46 | bhenry | technomancy: with that line my emacs loads up fine but then when i connect to swank i get an error in process filter about the font-lock part |
| 23:47 | dpritchett | looking much better now thanks technomancy and bhenry |
| 23:47 | bhenry | okay so i guess it worked for dpritchett, so i'm wondering what i did wrong |
| 23:48 | dpritchett | well i have a fresh install of the starter kit for one :D |
| 23:48 | dpritchett | and then i added the line phil mentioned to ~/.emacs.d/init.el at the end |
| 23:49 | bhenry | i added to the end of my .emacs.d/bhenry/init.el so ... |
| 23:49 | bhenry | hmph |
| 23:49 | bhenry | i guess since my brain falsely remembered having syntax highlighting in the repl it wasn't much of an issue for me to begin with |