2009-08-03
| 01:31 | mebaran151 | I'd like to have a version of concat that stops concatting at nil |
| 01:33 | mebaran151 | something like concat while |
| 01:33 | cark | someting like (apply concat (take-while ... |
| 01:34 | mebaran151 | will take-while respect laziness? |
| 01:34 | hiredman | ,(doc take-while) |
| 01:34 | clojurebot | "([pred coll]); Returns a lazy sequence of successive items from coll while (pred item) returns true. pred must be free of side-effects." |
| 01:34 | cark | ,(apply concat (take-while identity [[1 2 3] [:a :b :c] nil])) |
| 01:34 | clojurebot | (1 2 3 :a :b :c) |
| 01:35 | mebaran151 | thanks you all |
| 01:36 | mebaran151 | that did the trick nicely |
| 01:36 | mebaran151 | I now have lazy cursors over berkeleydb which is pretty sweet |
| 01:36 | cark | nice =) |
| 01:38 | mebaran151 | is there any reason why iterate always pulls the first iterations of its series? |
| 01:39 | mebaran151 | ,(take 2 (iterate #(prn %1) "no")) |
| 01:39 | clojurebot | ("no" nil) |
| 01:39 | mebaran151 | first three iterations? |
| 01:40 | mebaran151 | that example didn't show it, but it all seems to prefetch the first three chunks |
| 01:40 | cark | hum it used to be like that i think, but not anymore |
| 01:41 | cark | what version of clojure are you using ? |
| 01:43 | mebaran151 | the 1.0 that comes with enclojure |
| 01:44 | mebaran151 | I think it's from may |
| 01:44 | mebaran151 | I don't mind the behavior, because for this application, a little prefectching is actually a pretty good idea |
| 01:45 | cark | 1.0 should not show this behaviour |
| 01:45 | cark | my guess is that your code is to blame =) |
| 01:45 | mebaran151 | mine too |
| 01:45 | mebaran151 | but it's exactly three |
| 01:46 | mebaran151 | I'll lisp paste the relevant functions |
| 01:46 | cark | i'm using an even older version, and i can't reproduce that |
| 01:46 | mebaran151 | ~lisppaste |
| 01:46 | clojurebot | Titim gan éirí ort. |
| 01:46 | cark | clojurebot: paste? |
| 01:46 | clojurebot | lisppaste8, url |
| 01:46 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 01:47 | lisppaste8 | mebaran151 pasted "iterate likes to pull" at http://paste.lisp.org/display/84653 |
| 01:48 | mebaran151 | db-list always pull the first three mores, as verified by my juvenile prn statement |
| 01:49 | mebaran151 | these statements are not recomputed, and the laziness works as before |
| 01:50 | jonase | ,(for [x (range 1 10) y (range 1 10) :while (= y 2)] [x y]) |
| 01:50 | clojurebot | () |
| 01:50 | jonase | ,(for [x (range 1 10) y (range 1 10) :while (= x 2)] [x y]) |
| 01:50 | clojurebot | ([2 1] [2 2] [2 3] [2 4] [2 5] [2 6] [2 7] [2 8] [2 9]) |
| 01:50 | jonase | :while confuses me. |
| 01:53 | cark | mebaran151: sorry i can't help you on this |
| 01:53 | mebaran151 | no problem |
| 01:53 | mebaran151 | so it's nothing super obvious? |
| 01:55 | cark | i think you're looking at the wrong place ... |
| 01:55 | cark | you have these loops in fetch and more |
| 01:55 | mebaran151 | (def ts (apply concat (iterate (fn [x] (prn "MOAR")) 2))) |
| 01:55 | clojurebot | x is y |
| 01:55 | mebaran151 | that function displays the exact same behavior |
| 01:56 | mebaran151 | ,(def ts (apply concat (iterate (fn [x] (prn "MOAR")) 2))) |
| 01:56 | clojurebot | DENIED |
| 01:56 | mebaran151 | printed 3 times to my screen |
| 01:57 | mebaran151 | I think it must be in the application of concat, as concat works through its 3 overloaded forms |
| 01:58 | cark | that makes sense |
| 01:58 | mebaran151 | ,(apply concat (iterate (fn [x] (prn "MOAR")) 2))) |
| 01:58 | clojurebot | java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer |
| 01:59 | mebaran151 | ,(apply concat (iterate (fn [x] (prn "MOAR")) 2)) |
| 01:59 | clojurebot | java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer |
| 01:59 | mebaran151 | ,(apply concat (iterate 2 (fn [x] (prn "MOAR"))) |
| 01:59 | clojurebot | EOF while reading |
| 01:59 | cark | ~def concat |
| 01:59 | mebaran151 | anyway to get a concat that doesn't do this |
| 01:59 | mebaran151 | ? |
| 02:00 | mebaran151 | ,(apply concat (iterate 2 (fn [x] (prn "MOAR")))) |
| 02:00 | clojurebot | java.lang.RuntimeException: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn |
| 02:00 | cark | use lazyseq |
| 02:00 | cark | make a function forit |
| 02:01 | mebaran151 | so I'd just recursively hit that function or something? |
| 02:01 | cark | ~doc mapcat |
| 02:01 | clojurebot | It's greek to me. |
| 02:02 | cark | ~def mapcat |
| 02:02 | cark | mhh nope |
| 02:03 | mebaran151 | it isn't that big deal: in fact it's downright useful for use in db-list (where I'd probably write some prefetching logic anyhow) |
| 02:04 | cark | i'm pretty sure you can do this with lazy-seq ...but yes if it's usefull why bother =) |
| 02:06 | mebaran151 | my other option is just to pad it with nils |
| 02:07 | cark | that's ugly =/ |
| 02:08 | mebaran151 | then it only hits me once |
| 02:11 | mebaran151 | yep |
| 02:11 | mebaran151 | padding with three nils makes it all work out okay |
| 02:13 | mebaran151 | (apply concat (concat [nil nil nil] (iterate (fn [n] (prn "MOAR") n) [2])))) |
| 02:13 | mebaran151 | nasty looking but functional |
| 02:17 | mebaran151 | ,(apply concat (concat [nil nil nil] (iterate (fn [n] (prn "MOAR") n) [2])))) |
| 02:17 | clojurebot | Eval-in-box threw an exception:java.lang.OutOfMemoryError: Java heap space |
| 02:18 | mebaran151 | I didn't see that one coming..... |
| 03:00 | LauJensen | Top of the morning gents |
| 06:01 | cgrand | Hi LauJensen! |
| 06:01 | LauJensen | Mr. Grand! Good to see you |
| 07:32 | JimiDini | Hi |
| 07:33 | JimiDini | sopi: I got your question about status of data. Unfortunately I don't have access to verify the status. X-Fade does |
| 07:41 | Fossi | is the only way to get a float[] (make-array (. Float TYPE) ) and putting stuff in there? or is there a way to use into-array or such? |
| 07:42 | Chousuke | Fossi: (into-array Float/TYPE your-seq)? |
| 07:43 | Chousuke | (You should really avoid using . directly. it's so ugly :() |
| 07:43 | Fossi | Chousuke: i got the (. from the docs ;p |
| 07:44 | Chousuke | well, Float/TYPE does expand to (. Float TYPE) |
| 07:44 | Chousuke | ... hmm |
| 07:44 | Fossi | ah. great http://clojure.org/java_interop#toc27 doesn't mention the type variant |
| 07:45 | Chousuke | Actually, I wonder what Clojure does if a class had a static field identical to an instance field in Class |
| 07:45 | Chousuke | because then (. FooClass fieldName) would be ambiguous |
| 07:48 | Chousuke | hmm, looks like it will choose the static field for that form. |
| 07:48 | Fossi | ah, even better: (float-array 10) |
| 08:24 | angerman | yep, :) |
| 08:38 | rhickey | git question: we have both a tag and a branch 1.0 in the clojure repo, whenever I do anything with git with 1.0 I get a "warning: refname '1.0' is ambiguous.", but it seems to proceed. What does it use by default, the branch or tag? |
| 08:43 | Chouser | #git says: see man git-rev-parse. The tag takes precendence. |
| 08:43 | rhickey | so, git checkout 1.0 pulls the tag |
| 08:43 | rhickey | how do we apply patches to 1.0? |
| 08:44 | opqdonut | checkout, git-apply, commit? |
| 08:44 | rhickey | opqdonut: the question is about disambiguating the tag from the branch |
| 08:45 | opqdonut | have you tried "git checkout branches/1.0" |
| 08:45 | opqdonut | err, "heads/1.0" that should be |
| 08:46 | opqdonut | If you happen to have both heads/master and tags/master, you can explicitly say heads/master to tell git which one you mean. |
| 08:46 | opqdonut | says git-rev-parse |
| 08:47 | rhickey | so anyone who says checkout 1.0 will always get the tag snapshot and everything else we need to do with the branch needs to be qualified? |
| 08:47 | opqdonut | basically, yes |
| 08:47 | rhickey | ugh |
| 08:47 | angerman | rhickey: did you ask in #git already? |
| 08:48 | rhickey | angerman: no |
| 08:48 | angerman | found them helpful the last time I asked ;) |
| 08:48 | rhickey | we need to make a policy decision as to whether we want to work that way, no patches applied to 1.0 yet afaik |
| 08:49 | rhickey | this is just what we got be default from the svn import |
| 08:49 | Chouser | I think that's right. can we rename the tag to 1.0.0 ? |
| 08:49 | rhickey | by default |
| 08:50 | opqdonut | release-1.0.0 or something might be a better tag name |
| 08:50 | rhickey | Chouser: I don't think you can rename tags once people have seen them |
| 08:50 | Chouser | ugh |
| 08:54 | Chouser | bleh. maybe rename the branch (or create a new one) 1.0.x |
| 09:07 | angerman | how does clojure handle the keyword arguments? |
| 09:07 | Chouser | it doesn't. |
| 09:07 | Chouser | or put another way, what keyword arguements? |
| 09:08 | angerman | like in (gen-class :extends ) |
| 09:09 | angerman | I'm wondering how I could rewrite my database abstraction layer to be lisp agnostic... I like clojureql's approach, but maye (query "MyKind" :where (and (= ...)) :order-by xyz) |
| 09:09 | angerman | but if clojure does not support keyworded arguments by default, I guess I'll just not use them |
| 09:12 | durka42 | not by default, but you could construct something with hash-map |
| 09:12 | Chouser | you could use clojure.contrib.def/defnk |
| 09:18 | angerman | ohh dang. I need naturally sorted results. hmm. |
| 09:20 | angerman | how would I sort a vector in clojure if my vectore looks someting like [{:pos 0 :name "x"} ... {:pos 20 :name "x"}] ... obviously not sorted beforehand |
| 09:24 | Neronus | angerman (sort-by #(% :pos) vector) ? |
| 09:25 | angerman | Neronus: thanks, will try. |
| 09:26 | rhickey | so I'm pretty happy with the thread safety now for mutable vectors, as well as the API |
| 09:26 | rhickey | basically mutable vectors enforce use in a single thread |
| 09:26 | rhickey | all mutating ops have ! appended |
| 09:27 | rhickey | but count/get/nth/invoke all work with normal API, yet check thread also |
| 09:27 | rhickey | no use after immutable! call |
| 09:27 | rhickey | so, no fast and safe |
| 09:27 | rhickey | now fast and safe |
| 09:29 | rhickey | I'm amazed, but thread check was practically free perf-wise. Apparently HotSpot caches Thread/currentThread in a register or something |
| 09:30 | Chouser | what does "no use after immutable! call" mean? |
| 09:30 | rhickey | Chouser: throws an exception |
| 09:31 | Chouser | a mutating ! op after an immutable! call throws? |
| 09:31 | rhickey | Chouser: all calls throw after immutable! |
| 09:32 | Chouser | oh! on the old mutable thing. immutable! returns what you want to use. |
| 09:34 | rhickey | the idea is to support single flow usage, just like functional style but with no persistence, trying to avoid bash-in-place use |
| 09:34 | rhickey | so you can take normal (but non-persistent, non-aliasing) functional use and add mutable at front, some !'s and immutable! at end for a batch editing session |
| 09:34 | rhickey | new is the protection against use in other Threads |
| 09:34 | angerman | whee, sorting works. it's dead stupid but it does work. Hmm. |
| 09:34 | rhickey | throws if used in thread other than the one that called mutable |
| 09:35 | rhickey | Chouser: exactly |
| 09:36 | rhickey | originally I had supported calling immutable! then continuing editing, but there's no perf advantage over calling mutable again, and it is much clearer |
| 09:37 | Chouser | sounds really good. |
| 09:37 | rhickey | pv -> (mutable pv) -> mv -> edits! -> (immutable! mv) -> pv |
| 09:37 | Chouser | with structural sharing throughout |
| 09:38 | rhickey | the thread protection takes it to a whole new level, as such use, even with multiple collections is truly safe and a lot more flexible than either all-methods-synchronized (like j.u.Vector) or, shudder, locking |
| 09:39 | rhickey | the fact that this works, as does parallel vector map, with the exact same data structure set is incredibly powerful |
| 09:45 | Chousuke | angerman, Neronus: (sort-by :pos vector) is enough :) |
| 09:51 | Chousuke | rhickey: Maybe you just need to merge them to master to get people to test :P |
| 09:51 | rhickey | Chousuke: yup |
| 09:51 | Chousuke | I wonder if undoing a merge is as easy as reverting the merge commit, though. |
| 09:53 | AWizzArd | As clojure.lang.RT.conj() returns an IPersistentCollection it means I have to cast every time (in Java) when I want to conj something on my vector, right? |
| 09:54 | Chouser | casting doesn't have runtime cost, afaik |
| 09:56 | AWizzArd | No, that's not a problem. I was just curious if there is a trick to go around that need for casting :-) |
| 09:56 | cemerick | Jomyoot: perst is the most likely candidate, IMO. I've enjoyed working with it so far. |
| 09:57 | angerman | ohh no. clojures json seems to choke on utf-8 :/ |
| 09:57 | Chouser | AWizzArd: you could call PersistentVector.cons() instead. |
| 09:57 | danlarkin | angerman: clojure-json? what input |
| 09:58 | cemerick | writing something like that in clojure would make the API a whole lot cleaner, but reinventing proper transactionality, etc., is not something I'm qualified to do (or interested in tackling) |
| 09:58 | angerman | danlarkin: using clojures contrib json module |
| 09:58 | angerman | but it seems to encode it correctly |
| 09:58 | angerman | now I need to find out where the issue resided |
| 09:59 | cemerick | AWizzArd: What Chouser said. Polymorphism is nifty :-) |
| 10:00 | rhickey | cemerick: covariant returns re nifty, were missing in C# |
| 10:00 | angerman | hmm jtable ... hmmm |
| 10:01 | cemerick | rhickey: When I left the shores of scala, I promised myself I'd forget everything I knew about covariance, contravariance, etc etc :-) |
| 10:07 | AWizzArd | Chouser and cemerick: yeah, good trick, that saves a few keystrokes, good. |
| 10:12 | angerman | anyone any idea how to tackle unicode from jtable -(json)-> server -(json)-> jtable? |
| 10:17 | danlarkin | angerman: what's the step that fails? |
| 10:36 | Neronus | Is there an intelligent way to check if (map fn o) can be used with object o (other than the exception way)? |
| 10:46 | LauJensen | Neronus: Generally if (seq? o) is true, then map should work |
| 10:47 | Neronus | yeah, but map works for arrays too, and (seq? (int-array 10)) == false |
| 10:47 | stuartsierra | No, seq? tests if o is already a sequence. |
| 10:48 | Chouser | there's a 'seqable?' in clojure.contrib.core, but I'd wonder if it's thr right solution. |
| 10:49 | rhickey | Neronus: in what situation would you be calling map speculatively? |
| 10:49 | Chouser | Neronus: you really want *anything* that map can work on? And how will you handle the failure? |
| 10:54 | rhickey | mutable vectors and latest ensure code now in master |
| 10:55 | Chouser | exciting!! |
| 10:55 | stuartsierra | What's the purpose of mutable vectors in this case? |
| 10:55 | cemerick | very good news :-) |
| 10:55 | cemerick | next week (hopefully!) we're going to set up our build system to always build against clojure's head automatically |
| 10:56 | Chouser | stuartsierra: chest-crushing, wind-whipping speed. |
| 10:56 | stuartsierra | oh my |
| 10:56 | Chouser | :-) |
| 10:56 | stuartsierra | In a single-threaded context? |
| 10:56 | Chousuke | stuartsierra: it's supposed to be a way to do a "batch update" I guess. |
| 10:57 | Chousuke | a good example is into, I guess. |
| 10:57 | Chousuke | ... I guess too many things. |
| 10:57 | Chousuke | :P |
| 10:57 | Neronus | Chouser, rhickey: I want to do something to all the keys of all maps contained in a collection, recursively. i.e. if a map is found in a collection which is contained in another map, I want to do that for the keys of the innermost map, too. Anything that is not mappable is just left as it is |
| 10:57 | rhickey | stuartsierra: if you have a pure function returning a vector, but building that vector takes a lot of steps, you can get a thread safe mutable version of a vector in O(1), make changes to it in a functional style, just using assoc!, conj! etc, then get an immutable persistent vector to return in O(1) |
| 10:58 | stuartsierra | got it |
| 10:58 | stuartsierra | smart |
| 10:58 | Chouser | Neronus: you probably just want 'coll?' then. Remember that Java arrays, Strings, etc. are mappable |
| 10:58 | cemerick | rhickey: the same thing is coming for all data structures, right? |
| 10:59 | Neronus | Chouser: Again, not true for e.g. arrays |
| 11:00 | Chouser | Neronus: what's not true for arrays? |
| 11:00 | Chousuke | ,(coll? (float-array 1)) |
| 11:00 | clojurebot | false |
| 11:00 | rhickey | cemerick: sure, patches welcome :) |
| 11:00 | cemerick | ah, I thought you had already started work on maps :-) |
| 11:01 | rhickey | cemerick: I haven't, but I think same the mechanism will apply |
| 11:01 | cemerick | I must have transformed a similar comment of yours in my head into ("...and I'm going to apply it to them forthwith!" :-P ) |
| 11:02 | lisppaste8 | rhickey pasted "hest-crushing, wind-whipping speed" at http://paste.lisp.org/display/84670 |
| 11:02 | stuartsierra | woah! |
| 11:02 | rhickey | note how you don't even change the structure of your functional code |
| 11:03 | cemerick | *drool* |
| 11:04 | Neronus | Chousuke: Chousuke demonstrated what I mean |
| 11:05 | Chousuke | :P |
| 11:06 | stuartsierra | That actually answers a question someone brought up on the group -- what if the compiler could substitute mutable structures for immutable when it's safe to do so. It's not automatic, but that's what you've done here. |
| 11:07 | Neronus | grr |
| 11:07 | Chouser | Neronus: you're okay with all such things becoming lazy seqs? |
| 11:07 | cemerick | sometime last week, someone was talking about decorating fns with metadata indicating that they're pure, so that the compiler could do just that. |
| 11:08 | Neronus | Chouser: Yupp |
| 11:08 | Chouser | well, maybe contrib core sequable? is what you want |
| 11:10 | lisppaste8 | rhickey pasted "safe at every speed" at http://paste.lisp.org/display/84672 |
| 11:10 | stuartsierra | Ah, but careful, (seqable? "string") is true. |
| 11:10 | danlarkin | *cough* bad pun |
| 11:13 | LauJensen | Is it just me, or this idea of a mutable vector a little icky and scary? |
| 11:13 | clojurebot | this is not a bug |
| 11:14 | rhickey | LauJensen: don't use them |
| 11:14 | LauJensen | rhickey: dont pout, I just meant generally, in a language which so fully defaults to immutable datatypes, isnt there a better way to handle this? |
| 11:14 | stuartsierra | rhickey: I think it's the scripting folks who want to write APIs that take either a single object or a collection. |
| 11:15 | rhickey | what happens when we define seq on non-collection objects to enumerate their JavaBean properties? |
| 11:15 | stuartsierra | i.e., a Thing and a collection of Things should be "the same." I don't agree, but I get it. |
| 11:15 | stuartsierra | Right, seq is more general than just collections. |
| 11:16 | cemerick | LauJensen: it's perfectly proper when used in conjunction with pure fns |
| 11:16 | rhickey | LauJensen: better way to handle what? |
| 11:16 | stuartsierra | I think a universal "aggregate?" predicate might be useful. |
| 11:16 | LauJensen | rhickey: The fact that you want a mutable object |
| 11:16 | rhickey | stuartsierra: I guess I see seqable? as perpetually ready to break |
| 11:16 | LauJensen | cemerick: How so ? |
| 11:17 | rhickey | LauJensen: I don't want a mutable object, I want the fastest speed in a known, linear, isolated context |
| 11:17 | stuartsierra | rhickey: I agree. What people really want is a single predicate that asks "is this a single thing or a collection of things?" |
| 11:17 | cemerick | LauJensen: because you really don't care what happens to intermediate representations within a pure fn, you only care about the result value |
| 11:17 | cemerick | resulting* |
| 11:17 | rhickey | stuartsierra: exactly, and they will need to option to include strings or not in that logic |
| 11:18 | LauJensen | Ok |
| 11:18 | stuartsierra | I think most people don't think of strings as collections, unless they grew up on C. :) |
| 11:19 | LauJensen | cemerick: I follow that logic actually :) I just had the notion that all things mutable are evil. |
| 11:19 | jdz | world is not black and white |
| 11:19 | rhickey | LauJensen: the beautiful thing is, you write your app as always and only when you have a bottleneck need you tap into this capability, without restructuring your code. Also some library things will do this by default, like "into" |
| 11:19 | stuartsierra | LauJensen: I think *shared* mutable things are evil. |
| 11:20 | rhickey | stuartsierra: right and these things are unshareable |
| 11:20 | LauJensen | rhickey: Sounds good. So only when I have a vector operation which is taking too long will I use this. Got it |
| 11:20 | LauJensen | stuartsierra: Agreed |
| 11:21 | rhickey | They also don't support the persistent modification interface, so assoc/conj etc fail, so you can't accidentally leak them into code expecting persistent data structures |
| 11:21 | LauJensen | Perfect! |
| 11:22 | LauJensen | That type of thinking really makes me love clojure - It protects me against me :) |
| 11:22 | stuartsierra | Without preventing you from doing what you want to do when you know what you're doing. :) |
| 11:23 | LauJensen | I think this calls for a T-Shirt |
| 11:23 | rhickey | stuartsierra: well, they do in some sense, since for example you might be able to share mutable things between threads if you knew what you were doing, these prevent it |
| 11:24 | rhickey | I think thread-local assurance is a huge deal, another safe model other than locks |
| 11:24 | Chouser | most languages attempt to protect you from yourself in some cases and to some extent, while letting you do "dangerous" things in other cases. |
| 11:24 | stuartsierra | Ok, fair enough, but you can always create Java collections if you want to be really sneaky. |
| 11:25 | LauJensen | hehe |
| 11:25 | rhickey | with a lot of power since it supports both composite work on one data structure and work involving multiple data structures |
| 11:25 | Chouser | the question is how well does a particular language fit with your own experience of what is dangerous vs. what is necessary |
| 11:25 | rhickey | stuartsierra: true, I'm trying to make it so you'd never be tempted by that |
| 11:25 | Chouser | this drives some people to enjoy coding in C, because they're unwilling to give up direct pointer manipulation. |
| 11:26 | cemerick | the answer to that question is probably directly corollated with the quality/type of programmers you have around you |
| 11:26 | stuartsierra | Code us not into temptation, but dissociate us from mutability. |
| 11:27 | rhickey | :) |
| 11:28 | LauJensen | rhickey: Could you define what you mean when you say 'thread-local assurance' ? |
| 11:29 | rhickey | LauJensen: rhickey pasted "safe at every speed" at http://paste.lisp.org/display/84672 |
| 11:29 | rhickey | If you try to use one of these mutable things from other than the thread on which they were created it will throw an exception |
| 11:30 | LauJensen | Thats awesome! |
| 11:31 | rhickey | It when coupled with O(1) to/from immutable+persistent, this is, IMO, game-changing |
| 11:32 | stuartsierra | yes, yes |
| 11:33 | LauJensen | rhickey: You should get a blog going and sell subscriptions :) I dont want to be the one to tell you to charge, but I think you could :) |
| 11:34 | stuartsierra | Actually, sounds like a good topic for one of the functional programming conferences. |
| 11:34 | stuartsierra | IFL 2009 is coming up. |
| 11:34 | stuartsierra | Right across the Hudson. :) |
| 11:34 | Chouser | maybe it'd be easier to sell a writeup as an article to a magazine that already has a compensation model. |
| 11:36 | cemerick | do authors get paid for magazine articles anymore? (outside of the mainstream press?) |
| 11:37 | stuartsierra | a little, not much |
| 11:43 | angerman | so with all this parrallelism of clojure can we have some math libs that serioulsy use the parrellism and show that clojure is fast? |
| 11:45 | stuartsierra | Go for it. :) |
| 11:46 | rhickey | angerman: there's a third leg to to this Clojure perf work - parallelism, safe mutability, and finally primitives in Clojure's vectors and fns, the latter is still to come, and will be 'limited' to longs and doubles |
| 11:46 | stuartsierra | why longs & doubles? |
| 11:55 | LauJensen | stuartsierra: ints are too small, doubles have similar speed to floats? :) |
| 11:56 | cemerick | LauJensen: I've been advised by people who would know that doubles *should* be faster than floats in general. |
| 11:57 | LauJensen | Cool - I wasnt quite sure so I took the safe route: theyre similar :) |
| 11:58 | cemerick | I've yet to benchmark the difference in our case, but the rationale I heard made sense to me at the time. :-) |
| 11:58 | stuartsierra | ok, just curious |
| 11:59 | Neronus | Chouser: yeah, thanks, sequable? works for me |
| 11:59 | clojurebot | Why are you asking *him* |
| 11:59 | cemerick | parallelizable primitive arrays! I never thought I'd see the day :-P |
| 12:02 | hiredman | ~botsnack |
| 12:02 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 12:02 | rhickey | stuartsierra: because longs and doubles can accommodate the smaller primitives without loss |
| 12:03 | stuartsierra | Ok, but what if you had a huge array of 'short's? |
| 12:03 | rhickey | float->double byte->short->char->int->long |
| 12:03 | cemerick | stuartsierra: RAM is cheap? |
| 12:03 | stuartsierra | And they wouldn't fit in memory as an array of longs? |
| 12:04 | stuartsierra | I'm thinking search engines, where you might have a billion-element array. |
| 12:04 | rhickey | stuartsierra: oh well, memory is getting cheaper and bigger |
| 12:04 | cemerick | you can always start packing bits |
| 12:05 | cemerick | (if you care that much) |
| 12:06 | stuartsierra | Ok, I guess. Won't affect me personally. But I know people who never have enough RAM. |
| 12:06 | rhickey | but each supported type is a multiplier, i.e. supporting n arg types means n^num-args variations, I'm thinking 3 (Object/long/double) with support for up to 4 args |
| 12:06 | stuartsierra | I understand the problem. |
| 12:07 | stuartsierra | Code generation! |
| 12:08 | rhickey | there may be some flex in the data structures vs fn calling, I'm mostly fixed on long/double for fns, it might be possible to have vectors of shorts going in/out as longs |
| 12:09 | rhickey | stuartsierra: it's not a code generation problem (FWIW, I generated the original IFn overloads in CL), it's a vtable size thing, I'm concerned about that getting out of hand |
| 12:09 | rhickey | oh, yes, fourth leg of perf tuning is new new, in progress |
| 12:10 | stuartsierra | ah, ok |
| 12:11 | hiredman | ,(import 'clojure.lang.AFn) |
| 12:11 | clojurebot | clojure.lang.AFn |
| 12:12 | rhickey | one thing's for sure, drawing conclusions about Clojure perf now is very premature, when all of these are in place it will be stunning |
| 12:12 | hiredman | ,((new [AFn] (invoke [] "foo"))) |
| 12:12 | clojurebot | "foo" |
| 12:14 | rhickey | has anyone tried new new's signature inference? (other than that ^^) :) |
| 12:14 | rhickey | new new is now the only branch not merged into master |
| 12:15 | Chouser | rhickey: I started going through contrib again, but haven't had the time to finish |
| 12:15 | Chouser | ...little time though it should take. |
| 12:16 | rhickey | I swapped out future and promise, where else do we have proxy? xml I guess |
| 12:16 | cemerick | rhickey: I'll probably start beating on it next week. |
| 12:17 | rhickey | new new docs in progress: https://www.assembla.com/wiki/show/clojure/New_new |
| 12:17 | rhickey | volatile now works |
| 12:17 | rhickey | only missing non-reflective self calls |
| 12:17 | Chousuke | hmm |
| 12:17 | rhickey | and stable names during AOT |
| 12:18 | Chousuke | parallel, inspector and xml have proxy calls. |
| 12:18 | Chousuke | and core_proxy of course :P |
| 12:18 | cemerick | rhickey: how are captured locals stored? It'd be great if they were actual fields, with nice (identical, when possible?) names... |
| 12:18 | rhickey | parallel is going to be deprecated |
| 12:19 | Chousuke | heh |
| 12:19 | Chousuke | well, that's where most of the proxy calls are |
| 12:19 | rhickey | cemerick: they are but I am loathe to promise that. The semantics of this are simpler than classes with fields etc |
| 12:20 | cemerick | rhickey: for goodness' sake, think of the tools...! ;-) |
| 12:20 | Jomyoot | what is the best editor for clojure these days? |
| 12:20 | Jomyoot | still Emacs? |
| 12:21 | technomancy | some things never change. =) |
| 12:21 | rhickey | cemerick: what I am trying to do is some up with a story I could explain without reference to Java/C# etc. Then and only then, there could be a description of the intended (non-portable) mapping to host constructs |
| 12:21 | rhickey | cemerick: think of Chouser, writing ClojureScript! |
| 12:22 | cemerick | heh |
| 12:22 | rhickey | cemerick: targeting Javascript is a big deal, and only going to become bigger IMO |
| 12:23 | cemerick | clojurescript is pretty crazily wonderful -- but still crazy :-) |
| 12:23 | rhickey | cemerick: Is GWT crazy, IYO? |
| 12:24 | rhickey | JS engines *are* the VMs of the browsers |
| 12:24 | Chouser | GWT is crazier. Given the choice between writing in Java and Javascript, I choose Java. |
| 12:24 | cemerick | rhickey: in concept, no -- and neither is clojurescript. But I'm guessing the latter will always have a footprint issue. |
| 12:24 | stuartsierra | And these days they do JIT compilation, just like the JVM. |
| 12:24 | hiredman | huh, assembla turns ascii smilies into images |
| 12:24 | Jomyoot | Does ECB work well with clojrue? |
| 12:24 | Chouser | gah! |
| 12:25 | Chouser | Javascript! I choose Javascript! |
| 12:25 | Chouser | sheesh |
| 12:25 | technomancy | Jomyoot: ECB is kind of pointless for Clojure IIRC |
| 12:25 | cemerick | but then, it's all in what you're doing, too. For the web stuff I care to bother with, I'd much rather have a very thin remoting layer so I can touch clojure fns running on the server super-easy. |
| 12:25 | technomancy | it's for Complicated Languages |
| 12:25 | Jomyoot | how come? |
| 12:25 | Jomyoot | technomancy: what if i need project browser like in textmate? |
| 12:26 | Jomyoot | showing folder trees |
| 12:26 | technomancy | Jomyoot: (a) you probably don't; you just think you do and (b) you can use speedbar by itself without ECB. =) |
| 12:26 | cemerick | I really dislike web development, which explains a lot of my preferences :-) |
| 12:27 | rhickey | cemerick: me too, ClojureScript is my best hope :) |
| 12:31 | stuartsierra | I always worry about *-to-JavaScript translators because you have to think about three layers at once -- the source language, the translator, and JavaScript. All three have quirks. |
| 12:33 | alrex021 | How do I, if possible, use :gen-class and run compile in REPL? I am following the http://clojure.org/compilation hello example and get the following exception in my REPL: "Could not locate clojure/examples/hello__init.class or clojure/examples/hello.clj on classpath" |
| 12:33 | Jomyoot | how good is vimclojure? |
| 12:34 | kotarak | Jomyoot: good (shameless advertisement) |
| 12:34 | kotarak | Jomyoot: but has its quirks |
| 12:34 | Jomyoot | kotarak: you made it? |
| 12:34 | Jomyoot | what are the quirks? |
| 12:34 | kotarak | yes |
| 12:34 | Jomyoot | http://kotka.de/projects/clojure/vimclojure.html it looks very good for formating though |
| 12:34 | Jomyoot | lining up the columns |
| 12:34 | cemerick | stuartsierra: js is the new bytecode? *shudder* |
| 12:35 | Chouser | cemerick: so clearly it needs a way to embed source filename and linenumbers |
| 12:35 | Chouser | :-) |
| 12:35 | stuartsierra | cemerick: it's true though, look at Chrome, Gmail, iPhones, Palm's Web OS... |
| 12:36 | kotarak | Jomyoot: it uses the introspection of clojure to provide dynamic things. That means, that it tries to load the file you are editing. => it executes code, must not contain syntax errors... hiredman doesn't like that, for such cases you can turn off dynamic features and just use the static things vim provides. |
| 12:36 | kotarak | Jomyoot: I used to this style and it works perfectly for me. |
| 12:37 | kotarak | Jomyoot: the static things like formatting, syntax highlighting, static completion, are on par with emacs, enclojure, ... you name it. |
| 12:38 | Jomyoot | so typically does emacs or vim wins? |
| 12:38 | stuartsierra | That's been going on for decades. |
| 12:38 | kotarak | Jomyoot: neither, a matter taste I guess |
| 12:38 | rhickey | cinc->js ftw! |
| 12:39 | Jomyoot | can emacs line up columns like in vimclojure? |
| 12:39 | Jomyoot | http://kotka.de/projects/clojure/vimclojure.html |
| 12:39 | technomancy | sure; M-x align-regexp |
| 12:39 | kotarak | It would be surprised if not... |
| 12:39 | kotarak | s/It/I/ |
| 12:42 | cemerick | stuartsierra: all that heat just makes me want to dive under the bed until the market makes some real decisions. I don't want to go platform-hopping every 6 months because Google, Apple, Palm, and 500 spinning VC-backed pre-revenue "companies" collectively sneeze. |
| 12:43 | Chouser | I would guess the safe-mutable collections will be an even bigger win for JS VMs than it is for JVM. |
| 12:43 | cemerick | yeah, I'd presume the VMs' GCs are relatively primitive. |
| 12:43 | stuartsierra | cemerick: In general, though, everyone's coalescing around HTML + CSS + JS as a user interface standard, for better or for worse. |
| 12:45 | cemerick | stuartsierra: oh, don't get me wrong, I think it's for the better! What I really dislike is getting led around by the nose by platform vendors, which is inevitable in any immature tech market. |
| 12:45 | Chouser | cemerick: so quit whining and just use sliverlight already. |
| 12:45 | rhickey | ouch! |
| 12:45 | stuartsierra | Sure, the mobile world is going to be hairy for the next couple of years. But hey, three years ago we couldn't even write mobile apps. |
| 12:46 | cemerick | Chouser: better throw out that wink really fast! :-P |
| 12:46 | rhickey | I don't think js in browsers is going away |
| 12:46 | Chouser | ;-) |
| 12:46 | cemerick | :-D |
| 12:50 | Jomyoot | Is Rich Hickey still using Aquamac? |
| 12:54 | technomancy | Jomyoot: yeah, but he doesn't use slime |
| 12:55 | technomancy | presumably because he knows what the code will do before it executes. =) |
| 12:55 | Jomyoot | why aquamacs and not carbon or cocoa emacs? |
| 12:55 | Jomyoot | u know? |
| 12:55 | LauJensen | And he doesnt use a keyboard either.. he just stays at the compiler until it obeys |
| 12:55 | LauJensen | stares... |
| 12:56 | technomancy | Jomyoot: I don't know. I have heard of a number of weird edge-casey bugs with aquamacs so I don't recommend it myself. |
| 12:56 | technomancy | also since it's not portable it's hard for people to test on it. |
| 12:56 | stuartsierra | I use it, no problem. |
| 12:56 | clojurebot | "There is no problem in computer programming which cannot be solved by an added level of indirection." -- Dr Maurice Wilkes |
| 13:02 | rhickey | so, I need a term for these single-threaded mutable collections that can share structure with the persistent collections. "Mutable" doesn't seem to do them justice, and has bad implications |
| 13:02 | stuartsierra | "fast" |
| 13:02 | rhickey | heh |
| 13:02 | rhickey | editable views? |
| 13:03 | rhickey | batch structures? |
| 13:03 | stuartsierra | that implies some separate, concrete backing object |
| 13:03 | stuartsierra | batch structures is ok |
| 13:03 | rhickey | stuartsierra: yeah, view is scary, since the source is inviolate |
| 13:04 | stuartsierra | "protean" |
| 13:04 | stuartsierra | "mercurial" |
| 13:05 | stuartsierra | "builder structures" |
| 13:06 | stuartsierra | "growth structure" |
| 13:07 | stuartsierra | "fillable container" |
| 13:08 | Chousuke | fillable container sounds redundant :P |
| 13:08 | stuartsierra | "agglomerator" |
| 13:08 | rhickey | breeder/composer/producer |
| 13:09 | stuartsierra | "accumulator" |
| 13:09 | rhickey | interesting |
| 13:10 | rhickey | cached |
| 13:10 | rhickey | very overloaded I know |
| 13:10 | stuartsierra | yeah, "cached" makes me think memoization |
| 13:10 | stuartsierra | "collector" |
| 13:11 | rhickey | assembler, maker |
| 13:11 | rhickey | ooh, collector |
| 13:12 | kotarak | drain |
| 13:12 | rhickey | put your data in the drain? :) |
| 13:12 | rhickey | hrm |
| 13:12 | durka42 | can you flush the drain? |
| 13:13 | stuartsierra | collector/accumulator because they're like accumulator functions in Common Lisp loops. |
| 13:13 | Chousuke | hoard :P |
| 13:14 | stuartsierra | That's actually not bad, you're hoarding a collection. :) |
| 13:14 | rhickey | stuartsierra: hmm, that analogy isn;t helping me. but I like collector. Whatever name wins could replace (mutable coll) and needs a counterpart for yielding the immutable result |
| 13:14 | stuartsierra | "finalize" |
| 13:15 | rhickey | urk |
| 13:15 | kotarak | (flush (drain coll)) :P ;) |
| 13:15 | stuartsierra | :) |
| 13:15 | stuartsierra | "realize" |
| 13:15 | stuartsierra | "conclude" |
| 13:15 | rottcodd | thaw/freeze |
| 13:15 | Chousuke | "seal" |
| 13:15 | rhickey | also, one of the things you can do with these is only remove things, in which case you aren't collecting items, but changes |
| 13:15 | Chousuke | and unseal |
| 13:16 | rhickey | If it could incorporate some sense of the linearity/single-threadedness that would be good too |
| 13:17 | stuartsierra | isolate / share |
| 13:17 | rhickey | except (isolate x) doesn't |
| 13:17 | stuartsierra | ok |
| 13:17 | stuartsierra | tap / untap |
| 13:18 | stuartsierra | crack / seal |
| 13:19 | stuartsierra | immediate / persistent |
| 13:20 | Chousuke | tether/unleash |
| 13:20 | rhickey | (foo immutable-thing) -> threaded-mutable-thing -> (bar threaded-mutable-thing) -> immutable-thing, none of which affects or hinders immutable-thing |
| 13:21 | stuartsierra | threadify / unthreadify :P |
| 13:21 | danlarkin | I like mutable/persistent, not sure why you don't like mutable though |
| 13:21 | Chouser | it's cute that immutable! has a ! but mutable does not. |
| 13:22 | stuartsierra | transient / persistent |
| 13:22 | rhickey | danlarkin: well, and ArrayList is mutable too, but much less powerful |
| 13:22 | rhickey | an ArrayList |
| 13:22 | rhickey | and less safe |
| 13:23 | rhickey | so there are two notions in my view, one is the data structure, and the other is the 'editing session' |
| 13:23 | Chouser | persistent! is nice, then you just need a noun for the safe-mutable thing itself which can also be used as the "factory" fn name. |
| 13:23 | kotarak | editor / save |
| 13:25 | rhickey | transient, ephemeral? |
| 13:25 | Chousuke | thread-bound? |
| 13:25 | Chousuke | hmm |
| 13:26 | rhickey | transient/persistent! |
| 13:27 | Chouser | chameleon |
| 13:28 | rhickey | I like transient, any objections? |
| 13:30 | Chouser | "bum" is shorter and less PC |
| 13:30 | rhickey | hah |
| 13:30 | opqdonut | how about apple/orange |
| 13:30 | Chouser | I guess their transience is no less defining than their other features. |
| 13:31 | danlarkin | it's too bad there's no word that means exactly "locally mutable" |
| 13:31 | hiredman | locutable |
| 13:31 | cgrand | in-flux/solid |
| 13:32 | rhickey | I think the term is kind of open when applied to data structures, so this method can define it. It is a great counterpart to persistent |
| 13:33 | Chouser | inconstans propinquus |
| 13:35 | rhickey | transient data structures "move" through various states, in a single-threaded manner |
| 13:35 | rhickey | they are not memory holes subject to poking from multiple threads |
| 13:35 | rhickey | and calling persistent! stops them |
| 13:36 | danlarkin | get-a-job! |
| 13:36 | rhickey | Chouser: is that a kind of bird or something? |
| 13:37 | rhickey | very funny that transient makes you guys think of drifters |
| 13:38 | Chouser | rhickey: that's a lame attempt at a latin phrase for locally mutable |
| 13:38 | Chouser | I just find it interesting that when other sciences need to name things, they string together latin words until it's unique and then apparently truncate to one or two syllables |
| 13:39 | rhickey | I like the sense of motion and the implied short-livedness in transient |
| 13:39 | rhickey | Chouser: :) |
| 13:39 | Chousuke | rhickey: plus it sounds cool and mysterious |
| 13:39 | Chousuke | which is good for catching people's attention |
| 13:39 | rhickey | Chousuke: there you go! |
| 13:40 | Chouser | while comp. sci. hunts around for related english thing and then overloads it to death, "tree" being the classic example. |
| 13:40 | rhickey | at least they'll have to consider what it means, with mutable they'll presume they know |
| 13:41 | rhickey | ok, well the bum objection notwithstanding, any other objections to transient? |
| 13:43 | Chouser | conclusive silence. |
| 13:44 | rhickey | ok, seems no one else likes it, but no one objects - transient it is - thanks for the help! |
| 13:44 | Chouser | ha! |
| 13:44 | rhickey | will be (transient pv) -> tv -> edit! tv -> (persistent! tv) -> pv |
| 13:45 | Chouser | and we can call the thing transients |
| 13:45 | Chouser | the things |
| 13:45 | rhickey | or bums |
| 13:45 | Chousuke | :P |
| 13:46 | Chouser | transient vectors -- that's indeed better than mutable vectors |
| 13:46 | Chousuke | also implies that you're not supposed to keep them around for long. |
| 13:46 | rhickey | it's a great fit - sparked by your call for (persistent! x) |
| 13:47 | Chouser | "persistent" was stuartsierra |
| 13:48 | rhickey | ok, creds/blame to him when he gets back from lunch |
| 13:52 | rhickey | and a persistent collection capable of producing a transient version? not all will be |
| 13:53 | rhickey | currently "editable" |
| 13:55 | Chouser | transable |
| 13:57 | Chouser | overpaid |
| 13:57 | rhickey | oh boy |
| 13:58 | Chouser | The state prior to becoming a bum might be "lazy", but I guess that won't work. |
| 13:58 | Fossi | ;D |
| 14:01 | rhickey | transient == bum completely doesn't click with me, didn't even consider it |
| 14:02 | Chousuke | transient is apparently a PC way of saying it :P |
| 14:02 | Chouser | I didn't think of it 'til very late. Wasn't a particularly natuarl association. |
| 14:03 | Chouser | I think it was the plural form "transients" that made it click. |
| 14:04 | rhickey | it's a Java keyword, wonder if that will be a problem |
| 14:05 | rhickey | Sun's JVM seem pretty tolerant of names, but IBM's isn't |
| 14:05 | jwhitlark | What's the best way to suggest a minor update to the docs? |
| 14:06 | Chouser | ha! even in Java transient means not persistent. |
| 14:06 | Chousuke | I wasn |
| 14:06 | Chouser | just different meanings of both. :-) |
| 14:06 | rhickey | Chouser: for another definition of persistent |
| 14:06 | Chousuke | I wasn't even aware of transient. :/ |
| 14:06 | Chousuke | the keyword that is. |
| 14:08 | jwhitlark | It would be helpful if the http://clojure.org/java_interop page had a quick note on the requirement to import java inner classes; it took me quite a while to find out. |
| 14:08 | jwhitlark | finally found it here: http://bradfordcross.blogspot.com/2009/05/using-inner-classes-from-clojure.html |
| 14:08 | jwhitlark | so it appears I'm not the only one. |
| 14:09 | Chousuke | I think it is mentioned there. |
| 14:09 | Chouser | "Note that nested classes are named EnclosingClass$NestedClass, per the JVM spec" |
| 14:09 | Chousuke | just not very noticeable. :/ |
| 14:09 | rhickey | jwhitlark: it's in the second paragraph in the explanation of the Dot form |
| 14:09 | Chousuke | hm, looking through the list of java keywords, strictfp seems to be the only other keyword new to me. |
| 14:10 | Chouser | I wonder if a FAQ would be more scannable for some of these issues |
| 14:10 | jwhitlark | yea, I got the $ part of it, it was having to import it that wasn't obvious. |
| 14:10 | jwhitlark | unless I'm still missing something. |
| 14:11 | Chouser | well, the class name itself has the $ in it. |
| 14:11 | rhickey | the transients have moved in: http://github.com/richhickey/clojure/commits/master |
| 14:11 | technomancy | jwhitlark: me too; I thought importing the outer class would let you access the nested class |
| 14:11 | jwhitlark | I'd import the parent class, and try calling it with the $ syntax. I didn't expect that I'd have to import the inner class. |
| 14:12 | Chouser | If named Foo$Bar, Foo is a class but Bar is not -- must use Foo$Bar |
| 14:12 | Chouser | also the #1 example for class name aliases. |
| 14:12 | jwhitlark | technomancy: that's it. It wasn't the naming that was confusing, it was the deliberate import. |
| 14:13 | Chouser | You imported Foo and then tried to use Foo$Bar? |
| 14:14 | jwhitlark | Something along the lines of: "Inner classes must be specifically imported with the $ syntax" would have saved me a lot of puzzlement. |
| 14:14 | jwhitlark | yea. |
| 14:14 | jwhitlark | coming from Python, so perhaps it's a leftover from that. |
| 14:14 | Chouser | but they don't have to be imported at all, any more than other classes. :-/ |
| 14:15 | Fossi | it's also non-obvious coming from java |
| 14:15 | Chouser | you can say com.company.Foo$Bar with no import |
| 14:17 | jwhitlark | true, but when you do (import '(com.company Foo)) a portion of population is going to expect Foo$bar to work. |
| 14:17 | jwhitlark | not saying it's right, just saying a single sentence addition would remove a stumbling block for some people. |
| 14:18 | Chouser | jwhitlark: I'm not arguing against a sentence, just not sure of the right wording. |
| 14:19 | Chouser | "must be imported" seems misleading |
| 14:20 | stuartsierra | "Note that nested Java classes are named OuterClass$InnerClass and must be imported as such." |
| 14:20 | Chouser | the thing is, each unqualified class name used must be specifically named in an import |
| 14:20 | Chouser | stuartsierra: you saw you won? |
| 14:21 | stuartsierra | yes. :-D |
| 14:21 | stuartsierra | Not that it matters. |
| 14:21 | jwhitlark | not sure what the wording should be. |
| 14:21 | Chouser | so whether it's a.b.Foo or a.b.Foo$Bar, you can't get away with only mentioning a.b to get to Foo or a.b.Foo to get to Foo$Bar |
| 14:23 | jwhitlark | so what would be the best way to express that inner classes aren't a special case? |
| 14:23 | jwhitlark | I think that's the assumption that got me into trouble. Thinking of the inner classes more as a member of field. |
| 14:23 | jwhitlark | s/of/or/g |
| 14:24 | jwhitlark | damn, got that wrong twice. |
| 14:25 | jwhitlark | perhaps: Note that inner classes are not a special case, and must either be explicitly imported or fully qualified. |
| 14:28 | jwhitlark | a little redundant with the docs that are already there, but makes a potential pitfall clear. |
| 14:44 | jwhitlark | Chouser: what do you think? Is that closer? |
| 14:45 | Chouser | jwhitlark: yeah. any suggestion on where to put it? |
| 14:47 | jwhitlark | well, the second paragraph of the dot special form discussion seems reasonable, but where it would have really helped me is in api/import |
| 14:48 | jwhitlark | I think either would do. I read them both several times when I was struggling with it. |
| 14:49 | Chouser | I think the import docstring is best. An example of Inner$Outer might be helpful there too. |
| 14:49 | jwhitlark | interesting aside: this is the first time I've had this type of problem with clojure. I'm *really* liking lisp and clojure in particular. |
| 14:50 | jwhitlark | I think that would do very nicely. |
| 14:51 | Chouser | "Note that inner classes (such as Inner$Outer) are not a special case, and must be fully qualified (mypackge.myname.Outer$Inner) or explicitly imported. |
| 14:51 | Chouser | " |
| 14:51 | rhickey | aren't they normally nested, not inner, classes? |
| 14:52 | Chouser | this is where my knowledge of Java breaks down. |
| 14:53 | Chouser | looks like both |
| 14:53 | Chouser | http://java.sun.com/docs/books/tutorial/java/javaOO/innerclasses.html |
| 14:53 | Chouser | http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html |
| 14:53 | jwhitlark | hmm.. I think nested is more proper, but the one time I took a java course, the instructor called them inner. |
| 14:53 | rhickey | inner classes have a relationship to their enclosing instance, nested are more generally just lexically nested, and are the ones you're most likely to use from outside the class |
| 14:54 | jwhitlark | "Note that nested or inner classes ..." |
| 14:54 | jwhitlark | ? |
| 14:54 | Chouser | "Note that nested or inner classes (such as Outer$Nested) are not a special case, and must be fully qualified (mypackge.myname.Outer$Nested) or explicitly imported. |
| 14:55 | jwhitlark | That would have done it for me. |
| 14:59 | jwhitlark | rhickey: I don't normally gush, but I wanted to thank you; even as inexperienced with clojure as I am, it feels like the most clean and powerful language I've ever used. |
| 15:00 | rhickey | jwhitlark: great! thanks |
| 15:19 | cemerick | is it safe to say that clojure is "more dependent" on jit than typical javac'd java? e.g. a particular clojure operation/fn/program requires more "runs" before it's performance settles into a minima? |
| 15:19 | cemerick | that's the impression I get, and I wonder if there's any basis to it. |
| 15:21 | stuartsierra | don't know, maybe the bytecode is less "efficient" on the first pass |
| 15:39 | lizp | hello, shouldn't this expression return 5 - ((first '(+ 2 3)) 2 3) ? |
| 15:39 | lizp | it returns 3 |
| 15:39 | hiredman | ,(first '(+ 2 3)) |
| 15:39 | clojurebot | + |
| 15:39 | hiredman | ,((first '(+ 2 3)) 2 3) |
| 15:39 | clojurebot | 3 |
| 15:39 | hiredman | ,((first '(+ 2 3)) 2) |
| 15:39 | clojurebot | nil |
| 15:40 | Chousuke | lizp: that's because (first '(+ 3 2)) returns the symbol +, not the function |
| 15:40 | hiredman | oh |
| 15:40 | hiredman | duh |
| 15:40 | hiredman | ,((first (list + 2 3)) 2) |
| 15:40 | clojurebot | 2 |
| 15:40 | Chousuke | ('+ 3 2) |
| 15:40 | Chousuke | ,('+ 3 2) |
| 15:40 | clojurebot | 2 |
| 15:40 | hiredman | ,((first (list + 2 3)) 2 3) |
| 15:40 | clojurebot | 5 |
| 15:40 | Chousuke | lizp: symbols have an interesting property: they look themselves up in things when used as functions |
| 15:41 | Chousuke | lizp: but 3 is not associative, so you get nil; however, if there are two arguments, the latter gets used instead of nil |
| 15:41 | Chousuke | ,('foo '{foo bar}) |
| 15:41 | clojurebot | bar |
| 15:41 | Chousuke | ,('fooz '{foo bar} 'default) |
| 15:41 | clojurebot | default |
| 15:42 | lizp | where can i read about the semantics of symbols/functions in clojure? |
| 15:44 | Chousuke | lizp: keywords are also functions. as are maps, sets and vectors |
| 15:44 | hiredman | well |
| 15:44 | hiredman | lizp: http://clojure.org/data_structures#toc10 |
| 15:45 | avital | ,'(+ 1 2) |
| 15:45 | clojurebot | (+ 1 2) |
| 15:45 | avital | ,(list + 1 2) |
| 15:45 | clojurebot | (#<core$_PLUS___4094 clojure.core$_PLUS___4094@e5d622> 1 2) |
| 15:45 | hiredman | lizp: http://clojure.org/vars |
| 15:45 | hiredman | etc |
| 15:45 | avital | so what is ' exactly? |
| 15:45 | avital | isn't it the same as (list ...)? |
| 15:45 | hiredman | quote |
| 15:46 | hiredman | nope |
| 15:46 | hiredman | ,'a |
| 15:46 | clojurebot | a |
| 15:46 | Chousuke | avital: it's "this is an unevaluated code literal" |
| 15:46 | kotarak | ,a |
| 15:46 | clojurebot | java.lang.Exception: Unable to resolve symbol: a in this context |
| 15:46 | hiredman | it keeps the quoted symbol from being evaluated |
| 15:46 | kotarak | ,(list a) |
| 15:46 | clojurebot | java.lang.Exception: Unable to resolve symbol: a in this context |
| 15:46 | kotarak | ,'(a) |
| 15:46 | clojurebot | (a) |
| 15:46 | hiredman | ' is a reader macro for (quote …) |
| 15:46 | kotarak | ,(quote a) |
| 15:46 | clojurebot | a |
| 15:47 | Chousuke | avital: so while in clojure (+ 1 2) gets evaluated and produces 3, '(+ 1 2) produces the list that when evaluated as code would produce 3 |
| 15:47 | hiredman | something quoted is what is read, without any evaluation |
| 15:48 | avital | ,(eval 2) |
| 15:48 | clojurebot | DENIED |
| 15:48 | avital | oh what |
| 15:48 | Chousuke | eval is not allowed :) |
| 15:48 | avital | hehe |
| 15:48 | avital | so i see that (eval +) returns the + function and (eval 2) returns 2 |
| 15:48 | Chousuke | avital: but remember that clojure code is not text. it's made of symbols, lists, vectors, keywords, maps and sets. |
| 15:49 | avital | is there another way to get the + function other than eval? |
| 15:49 | Chousuke | ,+ |
| 15:49 | clojurebot | #<core$_PLUS___4094 clojure.core$_PLUS___4094@e5d622> |
| 15:49 | Chousuke | of course, that has an implicit eval |
| 15:49 | Chousuke | :P |
| 15:49 | hiredman | ,(find-var '+) |
| 15:49 | clojurebot | java.lang.IllegalArgumentException: Symbol must be namespace-qualified |
| 15:49 | hiredman | ,(find-var *ns* '+) |
| 15:49 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: core$find-var |
| 15:49 | hiredman | bah |
| 15:49 | lizp | hehe |
| 15:49 | Chousuke | since the symbol +, when evaled, produces the + function |
| 15:50 | hiredman | ,(find-var (symbol (str *ns*) (name '+))) |
| 15:50 | clojurebot | nil |
| 15:50 | avital | but is there a more direct way? |
| 15:50 | Chousuke | direct? |
| 15:50 | Chousuke | what could be more direct than +? |
| 15:50 | hiredman | avital: what are you trying to do? |
| 15:50 | hiredman | the symbol + evaluates to the function + |
| 15:51 | hiredman | so as long as the you don't quote it (stop evaluation) you will get the function |
| 15:52 | hiredman | … |
| 15:52 | avital_ | sorry lost the last few messages, so is there a simple way to get the + function? |
| 15:52 | Chousuke | :P |
| 15:52 | Chousuke | ,+ |
| 15:52 | clojurebot | #<core$_PLUS___4094 clojure.core$_PLUS___4094@e5d622> |
| 15:52 | Chousuke | there |
| 15:52 | Chousuke | the simplest possible way :9 |
| 15:53 | cark | ,(type +) |
| 15:53 | clojurebot | clojure.core$_PLUS___4094 |
| 15:53 | hiredman | the symbol + evaluates to the function +, so if you don't quote + (stop the evaluation) you will get the function |
| 15:53 | cark | ,(type '+) |
| 15:53 | clojurebot | clojure.lang.Symbol |
| 15:53 | cark | ,(type (find-var 'clojure.core/+)) |
| 15:53 | clojurebot | clojure.lang.Var |
| 15:53 | avital_ | no but wait |
| 15:53 | hiredman | ,(resolve '+) |
| 15:53 | clojurebot | #'clojure.core/+ |
| 15:54 | hiredman | ,(deref (resolve '+)) |
| 15:54 | clojurebot | #<core$_PLUS___4094 clojure.core$_PLUS___4094@e5d622> |
| 15:54 | avital_ | so can we make the ((first '(+ 2 3)) 4 5) example work with minor modifications? |
| 15:54 | avital_ | ,((first '(,+ 2 3)) 4 5) |
| 15:54 | clojurebot | 5 |
| 15:54 | avital_ | doesn't work |
| 15:54 | cark | ah nice hiredman =) |
| 15:54 | hiredman | ((first `(~+ 2 3)) 4 5) |
| 15:54 | hiredman | ,((first `(~+ 2 3)) 4 5) |
| 15:54 | clojurebot | 9 |
| 15:54 | avital_ | wow ok what just happened there? :) |
| 15:54 | Fossi | what do you expect to get? |
| 15:54 | hiredman | avital_: ~ is unquote |
| 15:55 | hiredman | ,((first '(~+ 2 3)) 4 5) |
| 15:55 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn |
| 15:55 | Chousuke | avital_: ` is a special kind of quote, and ~ unquotes :) |
| 15:55 | avital_ | oh right |
| 15:55 | Chousuke | fo you get a list of a function, 2 and 3 |
| 15:55 | avital_ | ok great thanks"! |
| 15:55 | Chousuke | alternatively, you could just use a vector :P |
| 15:55 | hiredman | or a list |
| 15:55 | cark | avital_ : fossi's question might be worth answering |
| 15:55 | Chousuke | that IS a list |
| 15:56 | hiredman | ,((first (list + 2 3)) 4 5) |
| 15:56 | clojurebot | 9 |
| 15:56 | avital_ | cark |
| 15:56 | avital_ | yeah sorry |
| 15:56 | Chousuke | hiredman: the syntax-quoted thing is almost teh same. |
| 15:56 | cark | this strikes me as a very strange way to do things |
| 15:56 | avital_ | Fossi: I wanted to get 9, and hiredman's solution gives me 9. |
| 15:56 | avital_ | I was just experimenting |
| 15:56 | Chousuke | ,((first [+ - /]) 3 4) ; no need for quoting stuff |
| 15:56 | clojurebot | 7 |
| 15:56 | cark | oh ok |
| 15:56 | piggybox | this channel makes me feel like in #haskell... |
| 15:56 | cark | well that's not idiomatic at all |
| 15:56 | Chousuke | (the things in a vector are always evaluated) |
| 15:56 | Chouser | oh dear |
| 15:56 | Chousuke | unless the vector is quoted, of course :P |
| 15:56 | avital_ | DISCLAIMER: THIS IS JUST EXPERIMENTATION TO UNDERSTAND CLOJURE'S LIST SEMANTICS |
| 15:57 | Fossi | omg, now i get it |
| 15:57 | Chouser | piggybox: what can we do to fix that? |
| 15:57 | hiredman | foo :: x -> a -> b |
| 15:57 | hiredman | now it is just like #haskell |
| 15:57 | Chousuke | hiredman: quick, do something cryptic with pl! |
| 15:57 | hiredman | clojurebot: numbers! |
| 15:57 | clojurebot | (pl reverse $ (↕reduce range $ 10 () λxy (↕conj inc $ y x))) |
| 15:57 | Chousuke | excellent! |
| 15:57 | hiredman | actually I don't think I reloaded pl |
| 15:57 | danlarkin | cult of lambda |
| 15:58 | hiredman | ,(pl reverse $ (↕reduce range $ 10 () λxy (↕conj inc $ y x))) |
| 15:58 | clojurebot | (1 2 3 4 5 6 7 8 9 10) |
| 15:59 | piggybox | lOlrz |
| 16:04 | cemerick | hah |
| 16:04 | avital_ | so why would i ever use ' and not `? |
| 16:04 | cemerick | what's pl, anyway? |
| 16:05 | hiredman | pl is a toy |
| 16:05 | Chouser | avital_: ` qualifies symbols into var names and class names |
| 16:05 | hiredman | ,~a |
| 16:05 | clojurebot | java.lang.Exception: Unable to resolve symbol: a in this context |
| 16:05 | hiredman | er |
| 16:05 | hiredman | ,`a |
| 16:05 | clojurebot | sandbox/a |
| 16:05 | Chouser | ,[`foo `map `Integer 'foo 'map 'Integer] |
| 16:05 | clojurebot | [sandbox/foo clojure.core/map java.lang.Integer foo map Integer] |
| 16:05 | hiredman | ,'a |
| 16:05 | clojurebot | a |
| 16:06 | avital_ | Chouser: my question was: if ` is a stronger form of ' that allow to use ~ inside, why would i ever use vanilla '? |
| 16:06 | avital_ | oh |
| 16:06 | avital_ | wht |
| 16:06 | avital_ | hired just answered |
| 16:06 | avital_ | sorry |
| 16:06 | avital_ | hiredman: and what is sandbox/a... ? |
| 16:07 | hiredman | it is a namespace qualified symbol |
| 16:07 | avital_ | and why is it that 'a and `a are diferent? |
| 16:07 | hiredman | symbols quoted with syntax-quote (`) are turned into full qualified symbols |
| 16:07 | hiredman | mostly |
| 16:08 | hiredman | ' is the traditional simpler quoting |
| 16:08 | hiredman | ` and ~ and ~@ are used alot for writing macros |
| 16:09 | avital_ | hiredman: what is ~@? |
| 16:10 | hiredman | unquote splice |
| 16:10 | avital_ | oh right |
| 16:10 | Quiark | ,'a |
| 16:10 | clojurebot | a |
| 16:10 | hiredman | ,`(1 2 ~@(list 3 4 5)) |
| 16:10 | clojurebot | (1 2 3 4 5) |
| 16:10 | Quiark | ,`a |
| 16:10 | clojurebot | sandbox/a |
| 16:11 | Quiark | ,`a# |
| 16:11 | clojurebot | a__2992__auto__ |
| 16:11 | hiredman | oh, right |
| 16:11 | tomoj | autogensyming is awesome |
| 16:11 | hiredman | gensyms working in syntax quote too |
| 16:21 | lizp | thanks btw! |
| 16:58 | JAS415 | ,a# |
| 16:58 | clojurebot | java.lang.Exception: Unable to resolve symbol: a# in this context |
| 16:59 | rhickey | first cut at transient docs - feedback welcome: http://clojure.org/transients |
| 16:59 | Chousuke | foo# is a special feature of syntax-quote |
| 17:02 | technomancy | rhickey: I love the notion that there shouldn't be any "we do this in clojure's internal implementation, but you shouldn't do this in your own code" moments. |
| 17:02 | technomancy | very democratic |
| 17:05 | Chousuke | lisp is (or claims to be!) all about that, isn't it :) |
| 17:05 | angerman | thickey: not bad, I was able to understand it, eh >:) |
| 17:08 | Fossi | rhickey: good read |
| 17:08 | JAS415 | I like using clojure as a java compiler |
| 17:10 | angerman | JAS415: isn't that what we all use clojure for? :) |
| 17:11 | stuartsierra | rhickey: good explanation of transients |
| 17:11 | JAS415 | i guess i mean like pretending that java is the assembly language and then writing functions and macros that arrange the java into the right forms |
| 17:11 | JAS415 | like clojure is the compiler |
| 17:11 | mebaran151 | what version of clojure has transients? |
| 17:12 | rhickey | mebaran151: master |
| 17:12 | mebaran151 | ah so it's bleeding edge stuff |
| 17:12 | angerman | JAS415: well, that's all Suns fault. If they hand's alised java with the jvm and java bytecode ... |
| 17:14 | Chousuke | JAS415: fortunately Clojure does not compile down to Java, but JVM bytecode. |
| 17:14 | rhickey | mebaran151: yes, I added that info on the page |
| 17:15 | Chousuke | I suppose as far as Clojure is concerned, Java is "just another JVM language" (also the implementation language, but...) |
| 17:17 | jwhitlark | JAS415: That's exactly how I think of java, the new assembly language. |
| 17:17 | mebaran151 | it's the new COBOL |
| 17:17 | mebaran151 | or FORTRAN |
| 17:17 | mebaran151 | which ever old school, excessively verbose, down to the metal language floats your fancy |
| 17:18 | JAS415 | right, java is just another jvm language, except clojure has really good support for calling it |
| 17:18 | JAS415 | so you can write a macro that programmatically arranges java into the right clojure code to suite your puroses |
| 17:18 | Chousuke | Clojure doesn't call *java* code per se. it calls *JVM* code |
| 17:18 | JAS415 | its like having a really really large amount of leverage over a language with a ton of libraries |
| 17:19 | JAS415 | doesn't matter really |
| 17:19 | JAS415 | concept is the same |
| 17:19 | Chousuke | I suppose the host interop matches best with java. |
| 17:19 | mebaran151 | anyway are transients like tag types, only supposed to be used in dire emergencies? |
| 17:19 | JAS415 | java just has most libraries |
| 17:19 | JAS415 | fastest libraries too, which counts |
| 17:20 | mebaran151 | eh, C has the most fast libraries, but I've never seen an ffi in which I really would invest a lot of faith |
| 17:20 | jwhitlark | I used to be really down on java programmers, then I realized who I needed to be down on were people who *only* wrote java. |
| 17:20 | Chousuke | JAS415: Well, the libraries could be written in Scala or Groovy too |
| 17:21 | jwhitlark | or jython, I suppose. |
| 17:21 | Chousuke | mebaran151: transients look like they can be used pretty safely anywhere, but I doubt it's worth the trouble unless you have a code path that is a bottleneck |
| 17:21 | JAS415 | hmm, do we have (.. macro or proxy or genclass for scala or groovy? |
| 17:21 | mebaran151 | don't forget JRuby, you could have Clojure on Cleets |
| 17:21 | mebaran151 | *Cleats |
| 17:21 | jwhitlark | Which is actually an interesting idea for me; I could use my knowledge of the python standard library form clojure. hmmmm.... |
| 17:22 | Chousuke | JAS415: how do you call a Scala method from java? |
| 17:22 | Chousuke | JAS415: do that, then translate to clojure interop. That is your scala interop. |
| 17:22 | mebaran151 | Scala builds things that look very similar to Java classes |
| 17:22 | mebaran151 | languages like JRuby and Groovy probably require a bit more dancing |
| 17:22 | Chousuke | not to mention clojure itself. |
| 17:22 | stuartsierra | JRuby's not hard, I use it. |
| 17:23 | Chousuke | Calling clojure stuff through the java interop would probably look a bit ugly... :P |
| 17:23 | mebaran151 | that's what I meant |
| 17:23 | mebaran151 | it would be nasty to write a ruby on rails app in clojure, even though it's technically possible |
| 17:23 | jwhitlark | what we need are reverse macros ;-) |
| 17:24 | jwhitlark | assuming that doesn't have a meaning that I'm unaware of. |
| 17:24 | stuartsierra | Well, if you use Java calling conventions as your common denominator, all the JVM languages create Java classes/methods. |
| 17:25 | headius | not necessarily |
| 17:26 | JAS415 | sorry didn't mean to be rude and dissapear, had to keep dinner from burning... |
| 17:26 | mebaran151 | couldn't some languages make some sort of nasty bytecode that might violate the nice neat modle of JVM classes and methods |
| 17:26 | stuartsierra | Not if they want the JVM to run it. |
| 17:26 | headius | jruby by default interprets code at first, so there's no classes or methods for "java" to call |
| 17:26 | Chousuke | ,(.invoke (clojure.lang.Var/find (clojure.lang.Symbol/intern "clojure.core" "+")) 1 2) ; calling clojure through java interop... |
| 17:26 | clojurebot | DENIED |
| 17:26 | Chousuke | damn |
| 17:27 | headius | stuartsierra: I think you're making some assumptions about what the JVM expects...it's extremely liberal |
| 17:27 | headius | in scala, for example, you can't create a static Java method |
| 17:27 | headius | it's simply not possible |
| 17:28 | headius | on the other hand, a lot of scala's constructs can't easily be called directly from normal Java code because they've got mangled names or singleton abstractions or whatever |
| 17:28 | headius | scala does some really wild and scary things with bytecode and class/method structures |
| 17:28 | stuartsierra | ah, ok |
| 17:28 | JAS415 | i was thinking about stuart, so for example let and def are private/public variables, defn- and def are functional equivalent (sort of) |
| 17:28 | stuartsierra | That's scala's fault, then. :) |
| 17:28 | hiredman | ~scala |
| 17:28 | clojurebot | {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)} |
| 17:28 | headius | clojure does too, really... a class per function immediately makes it harder to interop because you have a million little classes to link against |
| 17:29 | jwhitlark | The transients docs look very good. I went in to it on one end having never heard of it, and came out with a good understanding of when and why I'd use it. In one pass. |
| 17:29 | stuartsierra | But in Clojure you can generate nice normal-looking Java classes. |
| 17:29 | headius | which are just a shim around a million little classes |
| 17:29 | mebaran151 | jwhitlark, agreed |
| 17:29 | Chousuke | headius: but, perversely, that's a requirement for smooth interop :P |
| 17:29 | headius | but yes, it's better for java |
| 17:29 | mebaran151 | Clojure has really good conceptual documentation compared to most languages |
| 17:29 | headius | jruby's various java interop options do the same thing, as does groovy's |
| 17:29 | Fossi | no wonder |
| 17:29 | Chousuke | headius: since it's the only way for every function to sanely implement Callable and Runnable |
| 17:29 | jwhitlark | mebaran151: the best I've ever seen, actually. |
| 17:30 | headius | in almost every case where a language needs to present a "normal" looking Java type, they go above and beyond their own data structures and usually produce something artificial |
| 17:30 | headius | Chousuke: jruby does something similar, but all in memory |
| 17:30 | headius | when you compile a .rb it produces exactly one .class file |
| 17:30 | headius | that .class file generates method stubs on boot |
| 17:30 | Chousuke | mebaran151: Rich does a good job at explaining the concepts, but the actual API docs have much room for improvement. |
| 17:31 | mebaran151 | totally agreed |
| 17:31 | mebaran151 | there is much room for something that's more navigable |
| 17:31 | headius | so jruby doesn't have any easier time of interop...we still need to generate a synthetic Java type that is made up of our Ruby structures behind the scenes |
| 17:32 | hiredman | hmmm |
| 17:32 | mebaran151 | maybe even something like the noobkit docs for ruby, that present a hierarchy for documentation |
| 17:32 | Chousuke | mebaran151: at least there are the "related functions" sections in the reference nowadays... |
| 17:33 | JAS415 | it would have been cleaner if java had been implemented in clojure |
| 17:33 | technomancy | headius: I submitted a talk for RubyConf on using Clojure's STM and data structures from JRuby, so hopefully we'll see some JRuby love there. =) |
| 17:33 | headius | technomancy: neat |
| 17:34 | technomancy | I love the way JRuby procs implement Callable; made it really easy to use them with Clojure. |
| 17:35 | mebaran151 | I wonder if there would be a seamless way adapt multimethods to operate on a ruby class hierarchy |
| 17:37 | mebaran151 | the clojure api could actually use a comments section |
| 17:37 | headius | technomancy: we could improve that consistency a lot...but where we have it it's nice |
| 17:38 | headius | jruby's got a lot of baggage still |
| 17:39 | mebaran151 | and maybe even quick notes as to what is lazy and what isn't |
| 17:39 | headius | I'm obviously very interested in language interop in general |
| 17:39 | headius | there's a lot of people who will never use clojure and prefer jruby, but getting access to clojure's structures would be great for them |
| 17:40 | headius | and lots of people who will never want to write ruby but use clojure, and then want to be able to interop with ruby apps or libraries |
| 17:40 | JAS415 | clojure on ruby on rails |
| 17:40 | headius | it's unfortunate there hasn't been more interest among other language implementers in building a common interop protocol |
| 17:40 | mebaran151 | as I said, Clojure on Cleats |
| 17:40 | headius | the only people who've ever worked on one, as far as I know, are me and Attila |
| 17:41 | headius | and mostly Attila |
| 17:41 | JAS415 | the only thing i would worry about would be programs that use clojure/ruby/python/java/scala/groovy, where you have to have a huge breadth of knowledge to understand the entire codebase |
| 17:42 | headius | well, other than scala, those are all pretty easy to grasp at a glance |
| 17:42 | mebaran151 | wouldn't the ffi stuff be a good conceptual starting point? it seems nasty, but I don't see any more common basis |
| 17:42 | headius | mixing scala into any codebase scares me, but I'm still of the opinion that scala is like programming gymnastics |
| 17:42 | mebaran151 | I've seen ruby C++ C projects before, so it can't be THAT bad |
| 17:42 | JAS415 | haha |
| 17:43 | JAS415 | yeah i just worry about getting the reputationi CL has for maintnence difficulty |
| 17:43 | Chousuke | headius: every example of Scala I've seen thus far has been rather off-putting :P |
| 17:43 | headius | that will always be clojure's cross to bear |
| 17:43 | headius | Chousuke: I've seen some great examples of Scala...unfortunately I wrote all of them myself |
| 17:44 | headius | don't get me wrong, I like scala...but I fear it at the same time |
| 17:44 | Chousuke | I don't have a real opinion of Scala |
| 17:45 | Chousuke | All the times I've tried to learn more about it I've been scared away by cryptic code. |
| 17:45 | headius | me too |
| 17:45 | Chousuke | something about the syntax just doesn't agree with me. |
| 17:45 | headius | alex's book (pragprog) is pretty good, though I've only seen early drafts |
| 17:45 | headius | he teaches scala from a rubyist's perspective |
| 17:45 | mebaran151 | it seems to be weird to try to combine functional techniques with OOP |
| 17:45 | mebaran151 | OOP is all about state |
| 17:46 | JAS415 | its is pretty good in CL actually |
| 17:46 | headius | yeah, it's a weird combination |
| 17:46 | mebaran151 | I bought the scala book: it's a confusing hydra of a language |
| 17:46 | headius | at least it feels weird in scala |
| 17:46 | mebaran151 | well you have to do it differently: you can't use Java style oop |
| 17:46 | headius | I still would rather write something like Duby for my static-typed code |
| 17:46 | piggybox | well, Scala isn't the first one to do that. OCAML comes into my mind |
| 17:46 | mebaran151 | you probably want something akin to the multimethods or what not |
| 17:46 | JAS415 | you use functional for certain things and oop for other things |
| 17:46 | headius | if I ever got Duby finished |
| 17:46 | Chousuke | CL OOP is actually method-oriented programming :P |
| 17:47 | mebaran151 | I don't think OCaml is modula one |
| 17:47 | mebaran151 | * Simula style oop |
| 17:47 | JAS415 | i mean, i find the java oop x-treme methodology to be kind of perverse |
| 17:47 | Fossi | what's a binary or in clojure? |
| 17:47 | mebaran151 | where you have fields that you set |
| 17:47 | Chousuke | Fossi: bit-or I think |
| 17:47 | JAS415 | everything is an object? even abstract stuff? really? |
| 17:47 | Fossi | Chousuke: great. thanks. |
| 17:48 | Chousuke | JAS415: the thing with java is that it doesn't even adhere to the "Everything is an object" thing :P |
| 17:49 | Chousuke | Smalltalk does it right. Even code is objects :) |
| 17:50 | mebaran151 | I remembering reading somewhere you can either represent objects as hashtables or closures conceptually |
| 17:50 | JAS415 | yeah that's the idea behind scheme i think |
| 17:50 | mebaran151 | the hashtable methdology with fields and such, just isn't such a good fit for functional languages, where as closures are a natural way to carry state in real functional languages |
| 17:51 | JAS415 | they had factorial and actorial and it turned out to be the same thing :-) |
| 17:51 | JAS415 | same code* |
| 17:52 | mebaran151 | I don't know much about clos, but I've heard it's filled with Dragos |
| 17:52 | mebaran151 | *Dragons |
| 17:52 | mebaran151 | and Cruft |
| 17:54 | JAS415 | dragons? |
| 17:55 | mebaran151 | as in, it's a convoluted system |
| 17:55 | mebaran151 | with lots of ways to do the wrong thing |
| 17:55 | JAS415 | lisp in general is kind of like that |
| 17:55 | JAS415 | enough rope to hang yourself |
| 17:56 | mebaran151 | I found clojure a lot less crufty than most lisps: it enjoys a sensible design |
| 18:00 | jwhitlark | heh. I'm certainly enjoying clojure more than I did elisp. Although I think I'm getting better at the later from my exposure to the former. |
| 18:02 | JAS415 | i dunno, i guess it depends on what the definition of cruft is |
| 18:03 | JAS415 | there are things in CL that are very very nice, but i never really touch, simply because i don't think to use them |
| 18:05 | mebaran151 | it's nice to break with the past though |
| 18:05 | mebaran151 | try reading an mp3 file in common lisp or anything like that |
| 18:06 | mebaran151 | I can think of 10 Java libraries I can choose from with sane api's |
| 18:06 | JAS415 | yeah definitely |
| 18:06 | JAS415 | try even installing CL without already knowing how to do it |
| 18:06 | JAS415 | i think it took me the better part of a week the first time i did SBCL, and I didn't even have it setup right |
| 18:09 | Chousuke | I think one huge benefit over CL that Clojure has are first-class hashmaps and vectors (and sets). |
| 18:10 | Chousuke | poor sets, always mentioned in parenthesis |
| 18:10 | JAS415 | you can write some pretty macros with that stuff :-) |
| 18:10 | Chousuke | yes. and you don't need four sets of functions, one for each data type. |
| 18:11 | mebaran151 | also found macro writing in clojure more approachable |
| 18:12 | JAS415 | the helper macros being built in... helps :-P |
| 18:12 | Chousuke | helper macros? |
| 18:12 | JAS415 | off the top of my head the `var# macro |
| 18:12 | Chousuke | ahh, autogensyms |
| 18:12 | Chousuke | yes. |
| 18:12 | JAS415 | i think there are others but that is the big one |
| 18:13 | Chousuke | the namespace-qualifying property of syntax-quote is almost as big, if not bigger :) |
| 18:13 | JAS415 | yeah that's true, the trick there is figuring out how to circumvent it |
| 18:14 | Chousuke | which is relatively easy. |
| 18:14 | JAS415 | yeah :-) |
| 18:14 | jwhitlark | I love sets. I had an interview question, where they changed the requirements to keep a unique list of items instead of all items, took me one second to change my code. Got the job. |
| 18:16 | Chousuke | heh |
| 18:24 | mebaran151 | sets are an important data structure |
| 18:24 | mebaran151 | very useful for the current project I'm working on which essentially does a little relational calculus |
| 18:24 | mebaran151 | it's also nice that they are lazy (I think) |
| 18:25 | technomancy | sets can't be lazy. |
| 18:25 | technomancy | since you'd have to realize the whole thing to determine membership. |
| 18:25 | mebaran151 | that does make sense |
| 18:25 | mebaran151 | but luckily I can map over them lazily |
| 18:26 | technomancy | if you're producing a list, yes. |
| 18:26 | mebaran151 | which is where it matters (I don't hit the db, until I need the return value) |
| 18:26 | mebaran151 | working with laziness has turned out to be a lot of fun |
| 18:31 | Chousuke | Laziness can sometimes surprise you though. |
| 18:31 | Chousuke | You may not get what you think you should get :) |
| 19:05 | cemerick | rhickey: the transients document is very good |
| 19:15 | lizp | hi! lets say i want to write the following macro: (defmacro aif [x y] `(let [it ~x] (if it ~y))) and have y be an expression that uses 'it'. my problem is that upon expansion ` makes 'it' become 'user/it' and 'it' doesnt exist.. |
| 19:16 | cark | use this form : ~'it |
| 19:18 | lizp | no, it is still user/it |
| 19:19 | lizp | for example: (aif (+ 2 3) (print it)) |
| 19:19 | cark | mhh there is something like it though ...let me check |
| 19:19 | lizp | ok |
| 19:19 | lizp | ok |
| 19:19 | lizp | sorry |
| 19:20 | tomoj | (let [it# ~x] (if it# ~y)) ? |
| 19:21 | lizp | thank you cark, it works |
| 19:22 | lizp | this works: (defmacro aif [x y] `(let [~'it ~x] (if ~'it ~y))) |
| 19:22 | cark | oh great i was wondering how it was working here and not to your place ! |
| 19:22 | tomoj | isn't that a really bad thing to do, though? |
| 19:22 | cark | no it isn't |
| 19:22 | cark | but i beleive it was made hard to do so that you don't do it by mistake |
| 19:22 | lizp | so ~' is basically unquote then quote? |
| 19:23 | lizp | otherwayaround |
| 19:23 | cark | not the same kind of quotes |
| 19:23 | tomoj | indeed, but... why does lizp want to do it? |
| 19:23 | cark | the aif macro is pretty standard lisp stuff |
| 19:23 | avital | lizp yes why do you want to do it? |
| 19:23 | tomoj | it was made hard for a reason :) |
| 19:23 | cark | "a" stands for ...take a seat .. anamorphic |
| 19:23 | avital | anaphoric |
| 19:24 | cark | oh |
| 19:24 | lizp | why do i want to do the macro or the ~' thing? |
| 19:24 | tomoj | maybe I don't understand what the macro is supposed to do |
| 19:24 | avital | lizp the whole macro |
| 19:24 | cark | avital:indeed =/ |
| 19:25 | cark | you could (if (retreive-customer customer-id) (print it)) |
| 19:25 | cark | you could (aif (retreive-customer customer-id) (print it)) |
| 19:25 | cark | =) |
| 19:26 | lizp | yeah |
| 19:26 | lizp | :) |
| 19:26 | avital | its a quite common scenario - you want to act if something is not nil |
| 19:26 | avital | on that thing |
| 19:26 | avital | instead of writing a let each time |
| 19:26 | tomoj | ok, but suppose I have a variable "it" already |
| 19:26 | avital | this both saves space and makes the code more readable imho |
| 19:26 | tomoj | that macro clobbers it |
| 19:26 | cark | though the macro you wrote won't work that way |
| 19:26 | avital | tomoj: sure you have to take care |
| 19:26 | cark | and they can't be nested |
| 19:27 | avital | yes if you want to nest such things you have to think of a different scheme |
| 19:27 | cark | so we have in clojure : when-let if-let |
| 19:27 | tomoj | oh, gensyms don't work in this case, I see |
| 19:28 | cemerick | jeez, I pop into #haskell for a sec just for the hell of it, and this is the first thing I see: data G = G (G -> a -> b); f :: G -> a -> b; f (G g) a = g a; g (G f) h = f h; h = g (G f) (G f) |
| 19:31 | avital | ,(source if-let) |
| 19:31 | clojurebot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 19:31 | avital | oh |
| 19:31 | cark | ~def if-let |
| 19:32 | avital | cark thanks :) |
| 19:36 | Chousuke | cemerick: what is that supposed to mean? |
| 19:36 | cemerick | absolutely no idea |
| 19:37 | cemerick | I thought of popping in after hiredman got clojurebot to drop some scala :-) |
| 19:37 | tomoj | looks vaguely similar to the Y combinator to me |
| 19:37 | Chousuke | as far as I can tell it's some kind of recursively defined type and then a bunch of functions |
| 19:37 | cemerick | ~scala |
| 19:37 | clojurebot | Scala often gets in the way when trying to write neat code -- seen in #scala |
| 19:37 | cemerick | ~scala |
| 19:37 | clojurebot | {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)} |
| 19:37 | cemerick | there we go :-) |
| 19:37 | hiredman | evaluates to 1, btw |
| 19:38 | tomoj | there apparently is a G combinator |
| 19:38 | tomoj | apparently having something to do with "anaphoric" something or other, interestingly |
| 21:42 | JAS415 | swing feels inelegant, this is kind of frustrating |
| 21:43 | quidnunc | Anyone know how to specify a DNS server when using pppoe client? |
| 21:47 | quidnunc` | Sorry, wrong chan |
| 21:50 | slaney | are these sanctioned? ...like do proceeds help the dev effort? http://www.zazzle.com/clojure+tshirts |
| 21:51 | hiredman | I think Chouser created the store |
| 21:51 | slaney | ok |
| 21:51 | slaney | coolio |
| 21:53 | hiredman | 2009:Feb:16:20:48:26 Chouser : blbrown: you should. I've currently got the keys to that account, but since the ideas are mostly not my own I've already said I'll give the proceeds (if any) over to Rich. |
| 21:54 | slaney | danke |
| 21:57 | Carkh | question : is there a way to detect we're compiling during AOT compilation ? |
| 21:58 | hiredman | ,(doc *compile-files*) |
| 21:58 | clojurebot | "; Set to true when compiling files, false otherwise." |
| 21:58 | Carkh | thanks ! |
| 22:04 | cemerick | Brief/helpful comparison of transients to haskell's SP monad here: http://www.reddit.com/r/programming/comments/977mq |
| 22:04 | cemerick | or, actually: http://www.reddit.com/r/programming/comments/977mq/think_persistent_data_structures_and_functional/c0bo4md |
| 22:13 | hiredman | ~max users |
| 22:13 | clojurebot | Titim gan éirí ort. |
| 22:13 | hiredman | ~max people |
| 22:13 | clojurebot | max people is 149 |
| 22:44 | cemerick | huh, that should be 164 |
| 22:48 | durka42 | does it not count often enough? |
| 22:49 | hiredman | nah |
| 22:49 | hiredman | I reset it to 5 a while back to see if it was working |
| 22:50 | hiredman | ~max people is 164 |
| 22:50 | clojurebot | Roger. |
| 22:50 | onats1 | question guys |
| 22:50 | onats1 | when is clojure useful? |
| 22:50 | hiredman | always |
| 22:51 | onats1 | im just curious about it.. as i've read the label.. |
| 22:51 | hiredman | clojurebot: rationale |
| 22:51 | clojurebot | rationale is http://clojure.org/rationale |
| 22:51 | onats1 | hiredman, can you give me a scenario? like, and end-application that was done using clojure? |
| 22:51 | hiredman | clojurebot |
| 22:52 | hiredman | I have used clojure and htmlunit to do screenscraping with clojure |
| 22:52 | hiredman | clojure and SuperCSV to do CSV processing |
| 22:53 | hiredman | people are using clojure for hadoop jobs |
| 22:53 | hiredman | some people are even using it for writing android apps |
| 22:58 | onats1 | this is a fairly new concept to me |
| 22:58 | onats1 | is it similar to haskell? |
| 22:59 | hiredman | ~blip.tv |
| 22:59 | clojurebot | blip.tv is http://clojure.blip.tv/ |
| 22:59 | hiredman | I would check out the videos |
| 23:00 | onats1 | alright |
| 23:07 | arohner | onats_: I'm making a website using it |
| 23:07 | onats_ | arohner, deployed on what? |
| 23:07 | arohner | compojure & apache on AWS |
| 23:08 | arohner | oh, and jetty |
| 23:08 | arohner | compojure is a clojure web framework |
| 23:47 | tomoj | to me compojure looks more like a tool for building web frameworks |
| 23:48 | tomoj | I guess I'm just used to heavily opinionated frameworks |
| 23:51 | arohner | tomoj: you're not wrong, it is low level, but that's what we have right now. it hasn't been much of a hinderance though |
| 23:52 | Carkh | did they manage to make expiring sessions yet ? |
| 23:52 | tomoj | yeah, I think that's awesome |
| 23:52 | tomoj | I have been pondering writing my own framework based on compojure |
| 23:52 | tomoj | need to learn clojure better first I suppose |
| 23:53 | tomoj | actually I want to go learn seaside first since if I tried now it would just be a clone of rails |
| 23:53 | arohner | Carkh: I haven't heard of anything, though I haven't been following the group closely |
| 23:53 | Carkh | arohner: me neither ... |
| 23:53 | Carkh | though i 'm almost done with an app |
| 23:54 | Carkh | and that's one of those things i still need to look into =/ |
| 23:54 | gko | What's the minimum JDK version to compile Clojure? |
| 23:54 | Carkh | 1.5 |
| 23:54 | gko | Argh... |
| 23:55 | gko | No 1.4 ? |
| 23:55 | Carkh | nope =( |
| 23:55 | gko | Too bad :( |
| 23:55 | hiredman | why dod you need 1.4? |
| 23:55 | hiredman | do |
| 23:56 | gko | Old machines |
| 23:56 | gko | DEC OSF1 |
| 23:56 | hiredman | Oh |
| 23:56 | gko | Can find only 1.4.2 |
| 23:56 | hiredman | ouch |
| 23:57 | gko | yeah |
| 23:57 | mebaran151 | so I've got a bunch of sets and I'd like to lazily combine them |
| 23:57 | mebaran151 | #{0} #{0 6} #{0 6} #{0 6 12} #{0 6 12 18} |
| 23:58 | mebaran151 | essentially I'd like this to look like a lazy list that would go 0 6 12 18 etc |
| 23:58 | mebaran151 | how can I do this? |
| 23:58 | hiredman | sets are not lazy |
| 23:59 | mebaran151 | no I know |
| 23:59 | mebaran151 | but I'd like to lazily combine them |