#clojure log - Mar 02 2011

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:01 amalloy: tomoj: (concat (drop x) [(first x)]) and (cons (last x) (butlast x)) seems to work okay; if you require that the input is a vector you can do these operations in constant time

0:01 the issue of course is that what you get out is no longer a vector

0:01 tomoj: and I'd want constant in the number of rotations as well

0:03 amalloy: tomoj: you can implement a new thing like subvec

0:03 tomoj: no fair that rich gets to use inheritance for that

0:03 whereas the first thing I think of is a nasty deftype that just delegates everything with a few minor change

0:05 amalloy: tomoj: proxy APersistentVector?

0:07 $findn 2 [1 2 3 4 5] [4 5]

0:07 $findfn 2 [1 2 3 4 5] [4 5]

0:07 sexpbot: [clojure.core/take-last]

0:15 amalloy: $findfn 2 [1 2 3 4 5] [1 2 3]

0:15 sexpbot: [clojure.core/drop-last]

0:16 amalloy: three cheers for findfn, joshua____

0:18 joshua____: `(repeatedly 3 #(cheer "findfn"))

0:20 $findfn [1 2 3] [3 1 2]

0:20 sexpbot: []

0:20 joshua____: No rotate.

0:20 amalloy: tried it already

0:33 DespiteItAll: Does findfn just try all the functions?

0:33 joshua____: DespiteItAll, yes.

0:33 amalloy: DespiteItAll: yeah. for given values of "all", anyway

0:33 DespiteItAll: Nice

0:35 Looking at the source I couldn't really tell where the functions were coming from. But I see the call to ns-publics now.

0:35 joshua____: Why is it take-nth, but just plain drop for drop?

0:36 Seems inconsistent.

0:36 DespiteItAll: they do different things

0:36 amalloy: joshua____: take-nths is different

0:37 &((juxt take drop take-nth) 2 (range 10))

0:37 sexpbot: ⟹ [(0 1) (2 3 4 5 6 7 8 9) (0 2 4 6 8)]

0:37 DespiteItAll: take-nth is like "take every third". drop is like "drop 3".

0:38 I guess there is no drop-nth

0:38 joshua____: Oh.

0:38 DespiteItAll: drop-last is interesting. How can it be lazy and know how many items are left at the same time

0:39 amalloy: DespiteItAll: it has to buffer N items

0:39 i believe

0:40 DespiteItAll: It does something weird. I'm not sober enough to understand it right now.

0:40 amalloy: $source drop-last

0:40 sexpbot: drop-last is http://is.gd/JdGkUR

0:41 amalloy: oh hahaha

0:42 it takes advantage of (map foo a b) stopping after the shorter of a or b ends

0:42 DespiteItAll: oh, hahahah, nice

0:42 amalloy: to basically map identity over s, until (drop n s) is empty

0:42 joshua____: https://gist.github.com/850531

0:42 amalloy: that's pretty sneaky

0:43 joshua____: Implemented rotatel and rotater

0:43 Might not be as perforfmant, but at least it is out there now.

0:43 amalloy: joshua____: i'm actually working on a tool called hot-potato that will include these as well as reordering function args, as of discovering that they don't exist

0:44 fwiw i like (apply concat ((juxt drop take) n col))

0:44 joshua____: What happens if they say rotate 1000 with that call?

0:44 amalloy: same as for you. they're identical

0:44 joshua____: Oh.

0:44 Oh!

0:45 and rotater would be: (apply concat ((juxt drop-last take-last) n col)) ?

0:45 amalloy: right

0:45 joshua____: ,(doc juxt)

0:45 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, a...

0:46 joshua____: amalloy, thanks for the heads up on that function. It seems like it will help make my code that much more concise.

0:53 amalloy: joshua____: i use (juxt identity some-fn) a whole lot. i want to give it its own function but i can't decide exactly how it should behave

0:54 ((decorate class) myobj), or (annotate class myobj)? both names and usages seem to make sense

0:56 joshua____: preserve and maintain are what popped to my mind. Yours seem fine too.

0:56 amalloy: yeah, i'm less bothered about the name than about whether it returns a juxt-ish function or immediately returns its result

0:58 joshua____: I would skip the issue by writing both.

0:59 amalloy: hm

1:00 joshua____: Then I would use the more concise (returns results directly) form whenever I wasn't calling the function in multiple places.

1:00 amalloy: (def decorate (partial juxt identity)), (defn annotate [& args] ((apply decorate (butlast args)) (last args)))?

1:01 joshua____: ,(doc partial)

1:01 clojurebot: "([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. ...

1:01 joshua____: ,(doc butlast)

1:01 clojurebot: "([coll]); Return a seq of all but the last item in coll, in linear time"

1:01 amalloy: joshua____: sexpbot doesn't trim the docs

1:01 &(doc partial)

1:01 sexpbot: ⟹ "([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."

1:03 joshua____: Something like that. I think. I haven't actually run the stuff though.

1:03 amalloy: neither have i :P

1:05 joshua____: amalloy, seems to work, though it doesn't work for functions that take multiple arguments.. though I don't expect that to be your intention.

1:05 amalloy: really?

1:06 oh, i forgot an apply

1:06 oh right

1:06 no the point was that it can't work for multiple args

1:06 since identity has to work

1:06 i've forgotten and re-discovered that five times today :P

1:20 hm. clojars tells me the group name "amalloy" is already taken, even though i own the username amalloy and have no projects with a groupid of amalloy

1:21 i'm still fairly clueless about clojars. anyone have useful advice?

1:22 tomoj: groupids are free for the taking

1:22 maybe there's someone you can complain to, though?

1:23 easier to complain about a domain groupid I'd imagine..

1:23 amalloy: tomoj: sure, but nobody else has a project with groupid amalloy as far as i can tell

1:24 tomoj: oh, weird

1:24 amalloy: i guess i can make it org.clojars.amalloy

1:24 which i clearly do own

1:24 but blech

1:42 kilo_: hi, is there a equivalent for clojure skill levels - like this article ? http://www.scala-lang.org/node/8610

1:50 mids: kilo_: only if you play it on the xbox

1:52 kilo_: mids, xbox ? no understand....

1:56 amalloy: mids: gotta choose your audience more carefully, it seems

2:03 Scriptor: kilo_: I think mids just means it's not really the best way to look at learning a language as an absolutely established series of steps like that

2:10 amalloy: Scriptor: a much more eloquent translation than i was able to come up with

2:14 Scriptor: amalloy: thanks :)

2:17 amalloy: i guess cdddr and joshua are both gone now, but i've pushed 0.1.0 of hot-potato to clojars

2:29 kilo_: Scriptor : thanks for the explanation.. mids, too

2:37 I was just wondering if there's some sort of map to follow while learning

2:48 LauJensen: kilo_: Solve Eulers 1 - 50 use purely functional constructs. Thats the roadmap :)

2:59 kilo_: LauJensen : thanks

3:42 amalloy: $source fn?

3:42 sexpbot: fn? is http://is.gd/V6o9rh

4:05 Ptival: can someone point me to the right way to have clojure.contrib available in a lein repl?

4:09 bobo_: Ptival: its in the default projekt when you create a projekt with elin, so lein new myproject, cd myproject, lein deps, lein repl

4:15 Ptival: bobo_: ok I got it working thanks

4:28 http://paste.lisp.org/display/120114 what's wrong with this?

4:33 thorwil: Ptival: is the the dot at the end of java.text.SimpleDateFormat. supposed to be there?

4:34 Ptival: thorwil: well, I think :\ I am trying to call the constructor for SimpleDateFormat object...

4:34 clgv: Ptival: the constructor call seems correct

4:35 can you print the stacktrace? the you'll know which line it caused

4:35 there is a print-stack-trace in clojure.stacktrace

4:36 probably you should use it like (print-stack-trace (.getCause *e))

4:36 Ptival: I'll try

4:37 thorwil: Ptival: how/where is the "format" in (. formatter format date buffer 0) defined?

4:37 hoeck: Ptival: the last arg to format must be a java.text.FieldPosition

4:37 Ptival: hoeck: oh...

4:37 hoeck: at least thats what the javadocs about .format say

4:37 Ptival: yes, I overlooked that

4:37 thanks I'll fix it

4:38 hoeck: (java.text.FieldPosition. 0)

4:38 clgv: there is a buildin format within clojure

4:38 Ptival: also, is there a way I don't have to fully qualify every Java class?

4:39 clgv: oh well wrong method.

4:39 raek: note that java methods that are variadic (e.g. int a, int... foo) needs to be called with an array as the last arg

4:39 clgv: but a short version: (.format (SimpleDateFormat. "yyyyMMdd-HHmm") (Date.) )

4:39 kilo_: got mah first projet-euler solution right !! huzzah for loop and recur....

4:40 clgv: ,(.format (SimpleDateFormat. "yyyyMMdd-HHmm") (Date.) )

4:40 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: SimpleDateFormat

4:41 clgv: ,(.format (java.text.SimpleDateFormat. "yyyyMMdd-HHmm") (java.util.Date.) )

4:41 clojurebot: "20110302-0132"

4:41 Ptival: thanks clgv

4:42 kilo_: http://paste.lisp.org/display/120116 - any comments

4:44 am i using recur right ?

4:53 clgv: oh just noticed that (dorun (map ...)) has a significant overhead over loop-recur. in the case I rewrote the loop-recur version isnt even looking more complex

4:54 so I guess if I use (dorun (map ...)) I should generally consider using loop-recur instead if it isnt more complicated.

4:54 right?

5:11 hoeck: clgv: right, map is not good for hot inner loops, because of the laziness overhead it has

5:14 clgv: most of my loops are expressable with reduce, and I'm really only using loop/recur where I'm caring about performance

5:15 clgv: hoeck: ok thanks. I am using loop-recur in some reduce cases - but the first reason was that I dont have to go over the whole sequence which is not possible with reduce

5:16 mids: kilo_: who do you need recursion for that?

5:24 oh euler...

5:24 (apply + (filter multiple-of-3-or-5? (range 1 1000)))

5:28 Ptival: does someone know where clojure.contrib.logging actually logs to?

5:31 mids: Ptival: to Apache

5:31 commons-logging, log4j, and finally java.util.logging

5:33 zoldar: mids, what if there was max accumulated sum condition? would it be possible without loop-recur? I've tried to think out something along take-while with iterate, but it would include using refs..

5:35 Ptival: mids: well yes, the doc says that this should be my "preferred logging system", yet I don't know what it is or where the data is actually sent...

5:38 mids: Ptival: I think the default output of jaba.util.logging is stderr

5:38 Ptival: mids: ok thanks

5:40 I don't know, maybe the repl is eating my logs for dinner

5:41 mids: what level are you logging at?

5:41 zoldar: maybe the sum condition could be added to the reduce function; not that it would make things simpler

5:46 ronnie`: how does "resources" work with lein. I got a few txt files (maps/maze layouts), I need to read one of these files (filename as command line arg), just trying to work out the correct way to refer to that folder.

5:46 zoldar: mids, well, from what I see, reduce would blow up on infinite seq

5:46 Ptival: mids: I tried trace and debug

5:49 __name__: good day

5:51 mids: Ptival: that might be below the default log level

5:53 Ptival: mids: ok, I'll check this, thanks

5:53 mids: Ptival: http://www.paullegato.com/blog/setting-clojure-log-level/

6:52 octe: can i extend a java class and define fields in it somehow?

6:53 seems i can only define methods on proxies

6:53 Dranik: octe, you can't define fields but you may define getters/setters

6:53 ah, sorry

6:54 there is a special option in genclass, if I not mixing something

6:56 zoldar: octe: there's :state parameter in gen-class, maybe this will do

6:57 octe: however, this won't be a field in the meaning of object member

6:58 octe: zoldar, yeah, that's what i need

6:58 java interop

7:53 ,(deftype B [a] clojure.lang.IPersistentMap)

7:53 clojurebot: sandbox.B

7:53 octe: ,(do (deftype B [a] clojure.lang.IPersistentMap) (B. 1))

7:53 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.AbstractMethodError>

7:53 octe: shouldn't that work?

8:19 seancorfield: you haven't defined any methods on type B

8:20 Chousuke: octe: Yeah, you're not actually implementing IPersistentMap, you just claim you do :P

8:20 octe: "If you specify IPersistentMap as an interface, but don't define methods for it, an implementation will be generated automatically.⇧

8:21 Chousuke: $source deftype

8:21 sexpbot: deftype is http://is.gd/Y341QH

8:21 Chousuke: seems a bit broken :P

8:21 octe: yeah

8:22 frankly, deftype feels a bit too magical.. you can specify an interface, protocl or Object. Specifying some special interfaces will automatically generate methods

8:23 timvisher: hi all

8:23 octe: marking a field as mutable implies creating your own getters and setters

8:23 Chousuke: You're not supposed to use deftype anyway

8:23 unless you really need to

8:23 timvisher: I'm trying to write a doseq expression that 'maps' fs/copy+ over two seqs

8:23 I'm struggling to write the biding expression though

8:23 octe: Chousuke, maybe not, playing around with it..

8:23 timvisher: I had a working version with map, but that's 'wrong', yes?

8:24 Chousuke: timvisher: not really, just use doall

8:24 octe: wow, has java.net been down for everyone for the whole day?

8:25 Chousuke: octe: actually the docstring for deftype makes no mention of IPersistentMap. Are you sure you're looking at recent documentation :/

8:25 +?

8:25 clojurebot: ,(let [testar (fn [x y] (cond (= (reduce + (filter odd? (range 0 x))) y) (str y " is a")) )] (testar 11 25))

8:25 octe: Chousuke, perhaps not, i'm looking at http://www.assembla.com/wiki/show/clojure/Datatypes

8:25 timvisher: Chousuke: hmm. My problem isn't with the expression not being evaluated (although I've only used it from the repl at this point so that could easily turn out to be the case). My problem was using map to get side effects

8:25 Chousuke: octe: yeah, assembla is old

8:25 octe: which might just be rich's mental notes?

8:26 :p

8:26 oh ok

8:26 timvisher: I thought the idiomatic way to do that was to use one of the various 'do' constructs

8:26 octe: if assembla is obsolete, shouldn't it be taken down or something?

8:26 Chousuke: http://dev.clojure.org replaced assembla

8:26 octe: it should link to the new dev forum :/

8:26 octe: Chousuke, yeah

8:26 the banner should say that everything was moved to dev.clojure.org, not just the issue tracking :)

8:26 Chousuke: it does on the main page I suppose.

8:27 octe: ah

8:27 what i'm playing around with is a way to define structs in clojure that i can use with jna

8:28 since i can't extend Structure and define java fields in clojure

8:28 sattvik: octe: Have you looked at defrecord?

8:28 octe: i suppose i should look at that instead

8:29 sattvik: A defrecord type can act like a map within clojure, but also create immutable fields that may be easier for interop.

8:29 octe: will (keys some-record) return the keys in the same order as the they're defined?

8:29 sattvik, i'd actually prefer mutable fields in this case

8:30 but it doesn't really matter i suppose

8:30 sattvik: Ah, in that case, defrecord is out.

8:30 octe: well it's just a preference, which is why i looked at deftype

8:30 but if i'm not supposed to use it..

8:31 that leaves defrecord

8:31 timvisher: Anyone mind checking this defn to see if I'm doing side effects right? https://gist.github.com/850917

8:32 Chousuke: I wonder if it's possible to make the dev.clojure.org link to JIRA on the main page. Or does it do that already?

8:32 sattvik: I don't think you're not supposed to use it. It's simply a bit lower-level, but not as low level as gen-class. I think you are, in general, encourage to use higher level abstractions, but the low-level stuff is there for interop.

8:33 Chousuke: sattvik: Clojure itself uses deftype to implement gvecs AFAIK.

8:33 and records of course

8:34 it's there if you need it but most common things are done for you. :)

8:53 sattvik: Chousuke: That's true.

8:53 timvisher: I think it looks OK. If you don't need to hold on to the results of the map, you can use dorun instead of doall.

9:06 timvisher: sattvik: thanks!

9:20 fliebel: Is Cake able to compile java source files?

9:20 dpritchett: this isn't really a clojure question per se but i figured there are people here who could help me understand anyway...

9:20 given that mod_php was crucial to PHP's growth, how hard is it to build something that works similarly for other languages like node or clojure?

9:20 fliebel: I found some that are not even worth a maven file, but to large to convert to Clojure for fun.

9:21 dpritchett: You mean fastcgi?

9:21 dpritchett: i might mean if i knew more about fastcgi ;)

9:22 i am not sure exactly how cgi/mod_php work under the covers, i'm just thinking of the experience of being able to build a web app by dropping 1+ .php files into ~/public_html on a cheap host

9:22 nevermind services etc

9:22 fliebel: dpritchett: You wont be able to run Clojure on a cheap PHP host ;)

9:23 But you can generate a war file from a Ring app and drop that in a Java host.

9:23 So, Ring is the way to go.

9:23 dpritchett: i guess it needs to be an interpreted language to have a hope there

9:24 fliebel: dpritchett: What does being interpreted have to do with it?

9:25 clgv: how can I check if something is a double array?

9:25 dpritchett: replicating the "drop in a text file, click f5" deployment method

9:25 i guess you could have some build daemon to fake that

9:26 TimMc: dpritchett: You really don't want to start the JVM for each request.

9:27 fliebel: TimMc: Isn't that what FastGI and Cake are all about?

9:27 TimMc: Oh, does FastCGI keep a process up?

9:27 dpritchett: perhaps something like pharen would be a quicker solution

9:28 heck it even says on its front page: "This combines Lisp’s advantages of uniform syntax and homoiconicity (among others) and PHP’s advantage of…being everywhere."

9:28 i'm going to read up on how python's wsgi servers work, it might give me some needed perspective

9:29 fliebel: dpritchett: wsgi = rake = ring

9:29 (not sure about the ruby name)

9:29 dpritchett: unicorn & passenger i think

9:34 dnolen: fliebel: been digging into that arithmetic bug. Hope to have that wrapped up today or tomorrow.

9:35 fliebel: dnolen: Fantastic! Do you know where the problem lies yet? Is it in the scheme code, in my code or in Logos?

9:36 "cake compile ;; Compile all clojure and java source files." So where do I put these java files?

9:37 dnolen: fliebel: I think mplus-concat is still wrong. it's still going eagerly down some branches when it should not.

9:38 fliebel: dnolen: So, the duplicate results I was seeing are due to interleaving?

9:38 dnolen: fliebel: and the stack overflow errors as well. They are related.

9:39 fliebel: been working out adder-o operation by hand to see what's going on :)

9:40 fliebel: dnolen: How are you doing that? I found it was to complex to keep in mind, but I was unable to find a way to clearly capture the recursion in writing.

9:41 dnolen: fliebel: well I wrote out most of the earlier code in TRS so I got used to writing it out in a way that made sense to me.

9:41 pencil and paper all the way.

9:43 fliebel: dnolen: Of course pencil, but once you start binding conses, and recur on the rest, I have trouble writing that out.

9:44 gen-adder-o, for example...

9:46 dnolen: fliebel: yeah that's tricky. Just came up with a simple way to show backtracking. Stating which step to go back to fill in the newly ground vars.

9:48 fliebel: dnolen: hm, I'll have to try it.

10:07 TimMc: Is the following a true statement? "Symbols evaluate to a lexically bound value, vars evaluate to a dynamically bound value."

10:09 If so, I think I finally understand their relationship.

10:10 opqdonut: symbols evaluate to values, vars are values that can be dereffed

10:10 :)

10:10 TimMc: hmm

10:11 Oh! So they can. (deref (var foo)) works for (def foo ...)

10:12 BUt the value they deref to may depend on the dynamic environment?

10:12 opqdonut: it does depend

10:13 TimMc: Is it fair to say that all those environments share the same var, even though it derefs to different things?

10:13 (different threads, different (binding ...) clauses)

10:16 It's just not fair... Java's scoping rules are so damn easy! :-P

10:18 Fossi: orly?

10:19 TimMc: I found them so.

10:20 I think what's bugging me here is namespaces, actually.

10:20 _fogus: The whole point of things like AspectJ is to put dynamic binding into Java.

10:22 TimMc: eep

10:22 dnolen: _fogus: there's some interesting papers about Datalog + AspectJ point cuts that I recently ran into.

10:22 _fogus: dnolen: !!! links please :-)

10:23 dnolen: http://abc.comlab.ox.ac.uk/documents/abc-2006-2.ps

10:23 http://citeseerx.ist.psu.edu/viewdoc/download?doi=

10:23 there' s more, Google Datalog AspectJ point cuts should reveal a couple others.

10:24 _fogus: These couldn't have come at a better time.

10:24 Thank you

10:24 dnolen: np

10:28 TimMc: OK... would it be fair to say that symbols without a namespace qualification are just a shorthand?

10:28 I feel like I don't have a good formalization of symbols, namespaces, and vars in Clojure.

10:33 OK... let's try this again.

10:34 raek: TimMc: for symbols that represents vars, yes. but symbols can also represent values bound by let, function parameters, special forms, etc

10:34 clgv: TimMc: I think there is the following connection. A symbol is nothing more than a name. symbols can be resolved to vars

10:35 TimMc: I'm ignoring special forms for now -- I just assume the compiler intercepts those.

10:36 "Symbols eval to values. Some are via lexical scope, and others are via dynamic scope, using the namespace as a lookup table for vars. (Unqualified symbols use the current ns.) Vars are automatically dereferenced in the current environment when used this way."

10:37 I take it that macros receive the qualified versions of the symbols?

10:37 raek: it's actually syntax-quote that does that part

10:38 ,`foo

10:38 clojurebot: sandbox/foo

10:40 TimMc: Ah, yes it is. (defmacro foo [x] (println x)) shows me that the macro can receive unqualified symbols just fine.

10:40 raek: macros should always emit qualified symbols when the symbols represent vars

10:40 since you don't know where the macro may end up being expanded

10:40 and syntax-quote makes that easy

10:40 TimMc: Makes total sense.

10:43 What do you think of my longer statement just before the macros one?

10:46 raek: "Symbols eval to values" - when normal evaluaiton rules apply (i.e. this may not hold when the symbol is and argument to a special form or macro)

10:47 variables are always lexically scoped

10:48 (but vars may be rebound dynamically)

10:48 when a symbols does not represent a function parameter, let'ed value or special form, it is resolved to a var

10:49 and the namespace is used as a lookup table for that

10:50 TimMc: (defn maker [] (defn bar [] (println "bar!")) nil)

10:50 (defn flurb [] (bar))

10:51 If I run (flurb) now, I get an error about user/bar being unbound. Does that mean that the lookup in the namespace failed?

10:52 raek: first of all, defn creates or updates a global var, so it not limited to the scope of the make fn

10:52 TimMc: right

10:52 raek: (so in this manner, defn is very different from scheme's define)

10:53 TimMc: Once (maker) is run, (flurb) will work.

10:53 raek: yes, when flurb is evaluated, bar will be resolved

10:53 and the compiler will look for the var #'user/bar

10:53 which does not exist yet

10:54 TimMc: Oh! (ns-interns *ns*) shows that user/bar is already there!

10:54 So the compiler discovers internal defns and interns the names, but until the defn is *run* the var is just unbound.

10:54 raek: (normally, you should not execute any def or defn forms at run time)

10:55 TimMc: Yeah, I discovered this by acciden before I was using paredit. :-P

10:55 raek: (since those are meant to be used to hot-swap code fixes)

10:56 AWizzArd: When something is resolved, what is it then? A resolution? i.e. (let [resolution (resolve my-symbol)] ...) ?

10:56 raek: ,(class (resolve 'inc))

10:56 clojurebot: clojure.lang.Var

10:57 raek: TimMc: the compiler will not intern anything related to "bar" in your maker function

10:58 TimMc: That's not what I saw in my REPL.

10:58 raek: the bar parameter to defn will not be evaluated, since defn is a special form

10:58 (...) in your maker function, when (defn maker ...) is evaled

10:59 TimMc: If I do (defn a [] (defn b [] (defn c [] nil))) then (ns-interns *ns*) gives {b #'user/b, c #'user/c, a #'user/a}

11:00 raek: hrm. this is unexpected...

11:01 looks like this did not quote work as I thought it did

11:02 TimMc: you are right. the compiler discovers the defs and interns vars for them.

11:02 howoever, having nested defns is expremely rare

11:02 TimMc: Understood.

11:03 I can't think of a valid use-case.

11:05 raek: this makes sense.

11:07 TimMc: anyway, sorry for spreading false information :)

11:07 TimMc: heh, no worries

11:08 One thing that was not really discussed when I learned Scheme was homoiconicity.

11:09 (This was in school, BTW.) I mean, we learned that "code is data" and had a little exposure to macros, but I never got that names like "apply" were symbols too.

11:12 Chousuke: One of the main reasons I like Clojure is that it gives vectors and maps a place as "code" too.

11:12 You can design more expressive macros since you have additional elements available.

11:13 TimMc: I thought that was *fantastic* when I found out.

11:13 Chousuke: sets, too, I guess, but those really don't get much use in macros :P

11:15 TimMc: So vars are discovered via namespace lookup, and dereferenced according to their dynamic binding.

11:15 Chousuke: in eg. common lisp you only really have lists and symbols to work with, really, so you need to "overload" the semantics.

11:17 TimMc: 1.3 changes that a bit I think. If you want dynamic vars you need to be explicit about it.

11:18 TimMc: That's reasonable.

11:19 At usage or definition time?

11:19 Chousuke: definition

11:19 TimMc: OK, yay! raek, Chousuke -- thanks. I think I get vars and namespaces and symbols now.

11:20 Chousuke: Well, symbols in clojure are pretty simple. They're just names. In other lisps they're also containers :/

11:21 TimMc: lalalalala I can't hear you :-P

11:21 Chousuke: the mapping goes symbol (name) -> var -> value

11:22 except with locals, where there is no var involved

11:22 fliebel: Chousuke: When is something local?

11:22 Chousuke: instead there is some magic storage somewhere that holds the name -> value mappings.

11:22 TimMc: Chousuke: lexical scope, yeah?

11:22 Chousuke: fliebel: let-ed things or function parameters I guess.

11:22 yeah

11:23 fliebel: oh, right. I've been doing to much 7 languages.

11:23 companion_cube: this implementation must be quite slow, isn't it ?

11:24 Chousuke: why would it be?

11:24 the symbol -> var mapping is done at compile time

11:24 and getting the value is just a deref

11:25 and as far as I understand, in 1.3, you'll get static behaviour by default which means there won't even be derefs in most cases.

11:25 but I don't know the details about that so take it with a grain of salt :P

11:25 cdddr: amalloy_: Awesome.

11:28 fliebel: Ugh, this gets me every time. When I do ->, I can use ->> once to move the argyment to the back, but when I do ->>, there is no obvious way to get it as the first argument.

11:29 (->> for (#(except % this)))

11:29 TimMc: Haha, that's terrible!

11:30 ahihi: how does an atom behave if it's dereferenced while being mutated? does it return the previous value instantly, or b[C[C[C[C[Clock?

11:30 wow, sorry. block*

11:30 fliebel: ahihi: Previous

11:30 Read up on MVCC if you want to know more.

11:31 ahihi: ok, thanks :)

11:31 fliebel: TimMc: It totally is :(

11:32 TimMc: fliebel: Could you write a <<- macro or something to move it back?

11:33 fliebel: (defmacro <<- [form] (#(except % this)))) ;) almost… at least…

11:37 TimMc: Or a new macro that used some unhygienic marker for the stitch points.

11:37 fliebel: TimMc: Go wash your mouth! haha

11:38 TimMc: (--> (foo <> 4) (bar 5 <>) qux)

11:38 fliebel: TimMc: There are proposals like that floating around. I got one that involves letting % repeatedly.

11:38 TimMc: Or use amalloy's fantastic new hot-potato library to reorder the functions' arguments!

11:39 fliebel: what?

11:39 clojurebot: what is cells

11:41 TimMc: fliebel: https://github.com/amalloy/hot-potato <- It's a library of higher-order functions that rearraange the arguments passed to other functions.

11:42 https://github.com/amalloy/hot-potato/blob/master/test/hot_potato/core_test.clj

11:43 fliebel: scary...

11:43 TimMc: :-)

11:44 As far as readability is concerned, marking the stitch points explicitily seems superior.

11:45 cdddr: I am proud to be a small cause of that coming around, having irritated amalloy into writing it down. ;)

11:45 TimMc: I wonder if anyone will use it in a non-horrifying manner?

11:46 cdddr: Does reordering for partial count as horrifying?

11:46 fliebel: TimMc: https://gist.github.com/9b5abe112cf69ea5356e

11:47 cdddr: That said, I've discovered that nested defs really do away with 90% of the case I might want to use partial.

11:48 TimMc: fliebel: I'm trying to decode that thing...

11:48 fliebel: TimMc: macroexpand is your friend ;)

11:48 TimMc: No, I think I've got it...

11:49 That's pretty fantastic, although unary functions will still have to be used like (identity %).

11:49 Very clever.

11:49 fliebel: It was written long ago by someone else in here. I had a macro that was far more complex, and actually nested stuff.

11:50 TimMc: A little preprocessing before the interpose step ould take care of that.

11:52 What does nesting give you?

11:58 jweiss_: is there something i am missing in my leiningen project.clj that gives me line numbers in stack traces that contain my code?

11:58 currently I get "Unknown source"

11:58 and that's using the classes compiled by lein

11:59 TimMc: jweiss_: You're using lein compile, and then java -jar to run?

11:59 jweiss_: TimMc: well, java -cp `lein classpath`

12:00 basically the same i guess

12:00 TimMc: (Right, I was thinking of lein uberjar, nvm.)

12:02 Let me try this out on my own code.

12:02 Nope, I'm getting line numbers.

12:02 You're using pretty much the default project.clj?

12:03 jweiss_: TimMc, it's a project mixed java/clj. some of the clj is AOT

12:03 TimMc: Eeep, OK. I wouldn't know, then.

12:03 jweiss_: but java classes don't get line numbers

12:04 so i don't think it has anything to do with clj or aot

12:07 TimMc: If you write a little Java class that just throws an exception in main, and compile and run that, do you get line numbers?

12:32 fliebel: Hm, pity methods are not real functions.

12:39 Kruppe: fliebel: care to elaborate?

12:40 fliebel: Kruppe: Try (apply .someMethod arg arg2 argseq)

12:41 Kruppe: fliebel: oh you meant java methods?

12:41 fliebel: yea

12:41 Kruppe: fliebel: i thought you meant clojure methods, like defmethod

12:42 fliebel: and yeah it's kind of annoying :(

12:43 TimMc: &(apply (memfn toString) "r")

12:43 sexpbot: ⟹ "r"

12:43 TimMc: :-/

12:43 fliebel: &(doc memfn)

12:43 sexpbot: ⟹ "Macro ([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn."

12:44 Kruppe: TimMc: annoying as in an irritant, not as in impossible to work with

12:44 TimMc: Hence the :-/

12:44 I wonder if there's anything blocking the compiler from automatically converting .foo into (memfn foo) when not in head position.

12:45 It's not a legal name anyway.

12:45 Kruppe: TimMc: if this were CL I would play around with it

12:46 TimMc: I think . is implemented in java though

12:46 dnolen: there are so many times where you don't want to overhead of converting Java method to an fn.

12:46 Kruppe: TimMc: some kind of reader macro

12:46 TimMc: dnolen: This would be an extension, though -- it wouldn't change existing code.

12:47 dnolen: TimMc: what do you mean, like a compiler flag?

12:47 TimMc: No, a change in the default behavior of the compiler.

12:48 I don't think (... .foo ...) appears in existing code.

12:48 (modulo any rearrangement by macros)

12:49 dnolen: TimMc: how would you turn off this 'default behavior'?

12:49 TimMc: If someone wants to use a .method across a bunch of values, won't they write (memfn .method) anyway?

12:49 dnolen: Why should it be turned off?

12:49 dnolen: TimMc: I never use memfn

12:50 TimMc: OK, so you write #(.method %) instead?

12:51 Let's say you want to (map .toString some-stuff) - what do you generally write?

12:51 technomancy: TimMc: generally for. but yeah, I agree about the overhead being negligible

12:52 dnolen: TimMc: depends on what I'm doing. I wouldn't use map at all if I care about performance. If I don't care, (map #(.toString ..)) sure.

12:53 TimMc: And that's appreciably faster to run than using memfn?

12:54 dnolen: TimMc: Maybe in some cases it can be JITed away, not sure. Write you own simple test and compare :)

12:56 TimMc: I suppose that using a function literal takes away the need for arity-based dispatch.

12:57 Is your concern that given a shorthand for memfn, people would use that instead of a (potentially faster) function literal and unknowingly incur a performance hit?

12:58 dnolen: TimMc: memfn is the shorthand for what you want. JVM methods cannot be made first class.

12:59 TimMc: This machine will be going down in a few minutes. Switching over...

12:59 not-timmc: ...to this nick.

13:01 dnolen: not-timmc: unwrapped methods also have the benefit of flowing type information and not boxing.

13:02 not-timmc: Oh, good point.

13:33 fliebel: Why can't Incanter just plot some vectors/maps of data… I am making a heat-map, and it wants a function.

13:48 32 is more than 0 is it? Or is there a branch of statistical computing where this is not so? user=> (view (heat-map (partial heatfn *2) 0 32 0 32)) => java.lang.IllegalArgumentException: Requires lowerBound < upperBound.

13:50 Raynes: fliebel: There is a parallel universe that I visit on the weekends where negative numbers are greater than positive numbers.

13:50 * amalloy does all his math mod 31

13:50 amalloy: er...mod 33? whatever makes 32 === -1

13:51 TimMc: Begone, pale imitation!

13:51 Raynes: amalloy: http://raynes.me/logs/irc.freenode.net/atomo/2011-02-08.txt Looks like he has been in #atomo as well.

13:51 Er, wrong channel.

13:51 amalloy: lol way to mischan

13:52 TimMc: Much better.

13:52 amalloy: TimMc: stylish

13:53 fliebel: But, anyone know what I do wrong?

23:20 joshua__: This: http://www.amazon.com/gp/offer-listing/0070131511/ref=tmm_hrd_used_olp_sr?ie=UTF8&condition=used

23:20 This: http://www.amazon.com/gp/offer-listing/0072970545/ref=tmm_hrd_used_olp_0?ie=UTF8&condition=used

23:20 What is the difference? Is it just the CD?

23:21 Can I get the book that doesn't have the CD safely?

23:21 I'm having trouble wrapping my head around the CD being valued at 20ish dollars.

Logging service provided by n01se.net