2010-11-24
| 00:06 | Lajla | So why don't lists implement lFn? |
| 00:06 | Lajla | raek, I bet you know this. |
| 00:06 | Lajla | Maybe go first/rest on true/false? |
| 00:12 | replaca | Lajla: the IFn indexers only work on O(1) (or O(log32)) accesses. Lists are O(n) |
| 00:13 | replaca | Lajla: Strings are a result of strings having built-in Java semantics |
| 00:14 | Lajla | replaca, hmm |
| 00:14 | Lajla | What what reason i the first rule? |
| 00:15 | replaca | Lajla: Rich doesn't like "surprise" performance hits |
| 00:15 | replaca | Lajla: and I think this is an example of that |
| 00:18 | Lajla | Ahh |
| 00:18 | Lajla | But like |
| 00:18 | Lajla | it's not more or less surprise than any accessing function right? |
| 00:18 | Lajla | Or isn't there a generic sequence accessor? |
| 00:19 | replaca | Lajla: nth works for anything |
| 00:19 | replaca | but is understood to be variant in it's performance |
| 00:20 | Lajla | Ahhh |
| 00:20 | Lajla | and can't using lFn accessing be? |
| 00:20 | Lajla | also be understood |
| 00:20 | replaca | if you think of maps as functions: f(k) -> v |
| 00:21 | Lajla | Also, you don't really know in vectors when it's O(1) or O(log32) right? |
| 00:21 | Lajla | Yes, I do! |
| 00:21 | replaca | and a vector is just a special kind of map (where k is the index) |
| 00:21 | Lajla | Yes I do! |
| 00:21 | Lajla | I like that. |
| 00:21 | Lajla | And like, sets being maps where k = v |
| 00:21 | replaca | that's what's getting executed in the (m k) style |
| 00:21 | replaca | exactly |
| 00:22 | replaca | and lists don't seem to follow that model |
| 00:22 | replaca | (and least to Rich) |
| 00:22 | replaca | in fact, I *do* find that I'm using maps and vectors as substitutes for "real" functions |
| 00:23 | Lajla | Yeah, but why don't lists? |
| 00:23 | replaca | because lists are not innately indexable |
| 00:23 | Lajla | And can't lists at least be f : {true,false} -> V |
| 00:23 | replaca | you have to walk them |
| 00:23 | Lajla | Ahh |
| 00:23 | Lajla | Yeah, I guess like, it's not primitive. |
| 00:23 | replaca | right |
| 00:24 | replaca | now, that doesn't mean you're argument is without merit, and I get where you're coming from |
| 00:24 | replaca | but I think that was basically Rich's logic |
| 00:25 | replaca | so as a matter of style, we really only use that (m k) style when we mean for the map (or vector) to be a function |
| 00:25 | Lajla | Yeah, I guess. |
| 00:25 | replaca | in that context |
| 00:26 | Lajla | Ahhh |
| 00:26 | Lajla | I guess. |
| 00:26 | Lajla | Rich is dictator in perpetuo. |
| 00:26 | replaca | and we use nth, get, or (:key m) when we're doing lookups |
| 00:27 | replaca | yup, and we're all the better for it, even if we disagree about a feature here or there |
| 00:27 | Lajla | For some decisions though, I want to stab him, and have him look at me, and say και συ, τηκνον;, and then I'll reply with 'What on earth are you saying mate?' |
| 00:27 | Lajla | Clojure is one of those languages for me which is really nice in some spots, but really awful in others. |
| 00:27 | replaca | but I do find I end up agreeing with him a lot of the time after things have soaked in |
| 00:27 | Lajla | Kind of like French. |
| 00:28 | replaca | Hmmm - I'm pretty happy with the language itself |
| 00:28 | replaca | some things like error messages have room for improvement |
| 00:28 | replaca | (but folks are working on them) |
| 00:29 | Lajla | I was hoping that you mentioned the lack of TCO. |
| 00:29 | Lajla | But I do love how vectors and hash maps evaluate to their evaluations |
| 00:29 | Lajla | It almost makes me wish that lists did so as well. |
| 00:30 | Lajla | And a new special datum just for code was invented. |
| 00:30 | replaca | clojure folks typically just use vectors when they want that semantic |
| 00:30 | replaca | I don't care about TCO |
| 00:30 | replaca | there, I said it! :) |
| 00:31 | Lajla | I do. =( |
| 00:31 | Lajla | I am addicted to it. |
| 00:32 | replaca | Yeh, I think it's just a fixation. |
| 00:32 | Lajla | But clojure is kind of oddball in how it treats functional programming, I'd say its a paradigm on its own. |
| 00:32 | Lajla | Nahh, I use mutual recursion quite often. |
| 00:32 | replaca | When I'm writing big systems in production, the lack of TCO is not a pain point at all |
| 00:33 | replaca | as far as I can tell, all functional languages are oddballs relative to ech other |
| 00:33 | replaca | except maybe OCaml and F# |
| 00:34 | Lajla | I wouldn't say that per se. |
| 00:34 | Lajla | But clojure's treatment of generics is unusual I guess. |
| 00:34 | Lajla | How functions can accept multiple types which are often structurally unrelated. |
| 00:34 | replaca | well, clojure is a dynamically types language |
| 00:34 | replaca | *typed |
| 00:35 | Lajla | Usually, functional languages become obsessed with structural perfection to the point that it becomes impractal. |
| 00:35 | Lajla | Well, not that. |
| 00:35 | Lajla | But like, for instance, in clojure it's quite possible that a function accepts strings. |
| 00:35 | Lajla | And when you give it a character |
| 00:35 | replaca | to varying degrees, yeah |
| 00:35 | Lajla | it just treats it like a string of length 1 |
| 00:35 | Lajla | Most functional language eschew such things because it's not 'mathematically elegant' if you get what I mean |
| 00:35 | replaca | yup |
| 00:36 | replaca | I've ridden the Haskell train |
| 00:36 | replaca | :) |
| 00:36 | Lajla | Yeah, it's not per se a thing of dynamic typing, scheme would also not do that. |
| 00:36 | replaca | but rich type systems are just one part of functional programming |
| 00:37 | Lajla | It's more 'elegance over practicality' I guess |
| 00:37 | Lajla | And well, it _could_ go wrong. |
| 00:37 | replaca | Lajla: really, where is scheme different in that than Clojure |
| 00:37 | replaca | ? |
| 00:38 | Lajla | As in functional programming, functions tend to in some way be isomorphic to mathematical definitions, and if the definition is 'inconsistent', you often get infinite recursion or something nonsensical. |
| 00:38 | Lajla | Well, scheme would pretty much never do that. |
| 00:38 | Lajla | Such 'conveniences' |
| 00:38 | replaca | I don't think Clojure really does either |
| 00:38 | Lajla | It would either do something different with that character, or report a type error. |
| 00:38 | Lajla | Well, like |
| 00:38 | Lajla | the -> macro. |
| 00:38 | replaca | Unless you mean at the protocol/interop level where you overload a function |
| 00:38 | Lajla | Like (-> f y x z) |
| 00:39 | Lajla | If y x z are symbols it does something fundamentally differetn then when they are lists. |
| 00:39 | replaca | why couldn't you do the same thing in Scheme |
| 00:39 | replaca | I can do that in CL. |
| 00:39 | Lajla | Scheme would say you have to use (-> 1 (inc) (inc) and not (-> 1 inc inc) |
| 00:39 | Lajla | Well, you can. |
| 00:39 | Lajla | But the standard will never do that. |
| 00:39 | Lajla | and it's seen as 'un scheme' |
| 00:39 | replaca | the macro just looks at what they are when it's expanding |
| 00:40 | replaca | oh yeah, that's a stylistic difference |
| 00:40 | Lajla | Yeah, but such things are generally eschewed in functional programming langauge. |
| 00:40 | Lajla | And clojure does do these things quite often, because it's practical. |
| 00:40 | Lajla | Whereas most functional languages tend to favour 'mathematical elegance'. |
| 00:40 | replaca | yup and because it makes java interop better |
| 00:40 | replaca | yup, no doubt |
| 00:41 | Lajla | Most functional langauges would also not care that much about java interop. =P |
| 00:41 | replaca | to greater or lesser degrees |
| 00:41 | Lajla | But these things somewhat make me 'uncomfortable' I guess, I would write (-> 1 (inc) (inc) (inc)) myself. |
| 00:41 | replaca | for example, Scala is closer to Clojure on that scale, though with a different set of design desicions |
| 00:42 | replaca | *decisions |
| 00:42 | replaca | I think you get used to the idiom and it becomes transparent |
| 00:42 | replaca | similar discussions happen in the Haskell world about how far to take point-free expressions |
| 00:43 | Lajla | replaca, hmm, explain? |
| 00:43 | Lajla | You mean point free function definitions? |
| 00:44 | replaca | well you an use point-free expressions all over and it's not defining a function per se |
| 00:44 | replaca | and it's mind warping when you start to read code that does that a lot |
| 00:45 | replaca | but then you get used to it and you find that it's actually a pretty natural way to express yourself |
| 00:45 | Lajla | Ahhh |
| 00:45 | Lajla | but point free expressions retain the mathematical elegance. |
| 00:45 | Lajla | More so than non point free I would say. |
| 00:46 | replaca | right, but lots of folks don't like them cause they feel opaque |
| 00:46 | Lajla | It's not about redability so much as that in the case of (-> 1 inc) it checks to what inc evaluates, and in the case of (-> 1 (+ 1)) it doesn't check what the (+ 1) expressione valuates to, but just inline inserts it. |
| 00:46 | Lajla | I love these people that express reasonably complex list operations by folding ( : ) and all that though. =P |
| 00:47 | replaca | I know, that's the part I miss in Clojure |
| 00:47 | Lajla | The only one I can do I think is append x y = foldr ( : ) y x |
| 00:47 | Lajla | Not TCO? |
| 00:47 | amalloy | Lajla: -> doesn't check what inc evaluates to at all |
| 00:48 | amalloy | &(macroexpand '(-> 1 bamboozle)) |
| 00:48 | sexpbot | ⟹ (bamboozle 1) |
| 00:48 | amalloy | it just sees that it's a symbol rather than a list |
| 00:48 | replaca | Lajla: nope. I tend to use lazyness more often |
| 00:48 | replaca | or HOFs that give me lazyness |
| 00:49 | replaca | amalloy: that's right, the whole thing is done *before* evaluation starts as a structural transformation |
| 00:49 | replaca | a game that's mostly unique to lisps |
| 00:50 | amalloy | replaca: of course. lajla sounded like he might be confused about that |
| 00:50 | replaca | amalloy: yup, just expanding on your point a little |
| 00:53 | amalloy | Lajla: and if you think about it, it couldn't possibly work even if there were a way for ->> to know what type the expression evaluated to: ##(macroexpand '(->> x (fn [x])))##(macroexpand '(->> x ((fn [x])))) |
| 00:53 | sexpbot | (macroexpand (quote (->> x (fn [x])))) ⟹ (fn* ([x] x)) |
| 00:53 | sexpbot | (macroexpand (quote (->> x ((fn [x]))))) ⟹ ((fn* ([x])) x) |
| 00:53 | KirinDave | Man I wish I hadn't missed the start of this conversation |
| 00:54 | replaca | KirinDave: I'm not sure it's *that* exciting :) |
| 00:54 | amalloy | KirinDave: http://clojure-log.n01se.net/date/2010-11-24.html has most of it |
| 00:54 | amalloy | but it's not that interesting really |
| 00:55 | Lajla | amalloy, yeah, sorry, my phrasing was bad. |
| 00:55 | Lajla | I meant that in the case of a symbol, it inserts it like that, and with a list, it does some thing that is totally unrelated. |
| 00:56 | replaca | Lajla: makes sure it's a list and adds the predecessor as the 2nd element |
| 00:56 | replaca | simple enough |
| 00:56 | Lajla | Yeah, but it does a completely unrelated thing if it's a symbol. |
| 00:56 | Lajla | Maybe it works out on the 'conceptual' level. |
| 00:56 | replaca | Lajla: no, it makes sure it's a list |
| 00:56 | amalloy | Lajla: you keep using that word. i don't think it means what you think it means |
| 00:56 | Lajla | But on the mechanical level it's bizarre. |
| 00:56 | replaca | that was the first part |
| 00:57 | Lajla | the -> macro performs two completely unrealted operations depending on whether it ś a symbol or a list. |
| 00:57 | Lajla | unrelated* |
| 00:58 | amalloy | Lajla: (factorial n) does two completely unrelated operations depending on whether n is greater than one |
| 00:58 | Lajla | Yap |
| 00:58 | replaca | ,((fn [x] (if (list? x) x (list x))) '(a b c) ) |
| 00:58 | clojurebot | (a b c) |
| 00:58 | Lajla | and that is why I do not like such a definition of factorial. |
| 00:58 | amalloy | it's like you're objecting to the fact that clojure has an (if) form |
| 00:58 | replaca | ,((fn [x] (if (list? x) x (list x))) 'a ) |
| 00:58 | clojurebot | (a) |
| 00:58 | Lajla | Either generalize it to all numbers, or live with the fact that it doesn't terminate if it ś negative. |
| 00:59 | replaca | same operation as the first step |
| 00:59 | KirinDave | Lajla: That seems like an impractical stance. |
| 00:59 | Lajla | Maybe, but avoiding it makes me uncomfortable using a language. |
| 00:59 | amalloy | Lajla: if you prefer, it does something different when n is 1 (return 1) than when it isn't (do some multiplication) |
| 00:59 | KirinDave | Lajla: Besides, we can't express all numbers on our computers :) |
| 01:00 | Lajla | Well, let me rephrase, all numbers it doesn't give a type error on. |
| 01:00 | KirinDave | There's always more of them, you see? :D |
| 01:00 | Lajla | I'd rather have two different macros for both cases. |
| 01:00 | replaca | Lajla: even in mathematics, that's not a useful definition |
| 01:00 | Lajla | replaca, what isn't? |
| 01:01 | replaca | Factorial not special-casing 1 |
| 01:01 | Lajla | Oh, I wasn't talking about that. |
| 01:01 | replaca | ok |
| 01:01 | Lajla | I mean |
| 01:01 | Lajla | íf you supply a negative number. |
| 01:01 | Lajla | You can either guard against that |
| 01:01 | Lajla | Or accept that it goes on forever. |
| 01:01 | Lajla | You can let it report an error. |
| 01:01 | Lajla | Which is cool with me. |
| 01:02 | Lajla | Or say that the factorial number of negative numbers is like 1. |
| 01:02 | Lajla | Which is quite commonly done. |
| 01:02 | replaca | ok, but how does that relate to -> ? |
| 01:02 | Lajla | Use (<= 0 n) instead of (zero? n) |
| 01:02 | KirinDave | replaca: He wants function definitions to be continuous. |
| 01:02 | Lajla | Well, the idea is that factorial then performs two functions which I think should have different names. |
| 01:02 | replaca | You mean to accept all elements of the domain |
| 01:03 | Lajla | At the very least, it's not the factorial function |
| 01:03 | amalloy | KirinDave: that's an interesting way to think about what he's saying |
| 01:03 | Lajla | the factorial function is only defined on naturals. |
| 01:03 | KirinDave | Lajla: Lots of functions are defined as different operations within ranges. |
| 01:03 | Lajla | KirinDave, sure. |
| 01:03 | Lajla | But those more often than not freak me out. |
| 01:03 | Lajla | And are more often just approximate modeling of real life cases. |
| 01:03 | KirinDave | Lajla: Then recursion must make you tremendously uncomfortable, as must induction. |
| 01:03 | Lajla | Than something that follows from some elegant mathematical result. |
| 01:03 | replaca | Lajla: the real world is like that |
| 01:03 | Lajla | replaca, well, an approximate model of the real world is like that. |
| 01:04 | replaca | even in advanced math |
| 01:04 | Lajla | KirinDave, the difference is in the case of recursion is that there is a base case, and not a base range. |
| 01:04 | Lajla | And it's actually still 'continuous' then quite often, as you phrased it. |
| 01:04 | Lajla | Like, the definition of the factorial. |
| 01:04 | amalloy | Lajla: how do you feel about fobonacci numbers? |
| 01:04 | Lajla | Where 0 is the base case. |
| 01:05 | Lajla | I'm also fine with that. |
| 01:05 | amalloy | *fib |
| 01:05 | replaca | In response to Lajla, I'll make KirinDave's night with http://xkcd.com/224/ |
| 01:05 | Lajla | But my point about the -> macro is that, to my intuition/feeling, it perofrms two unrelated operations. |
| 01:05 | KirinDave | replaca: Haha. You did the opposite |
| 01:05 | Lajla | And I'd rather see those have different names. |
| 01:05 | KirinDave | replaca: I am one of the writers for xkcdexplained. |
| 01:05 | replaca | KirinDave: that was sarcasm, I know that :) |
| 01:06 | Lajla | What is xkcdexplained? |
| 01:06 | KirinDave | Lololol |
| 01:06 | KirinDave | I never know |
| 01:06 | KirinDave | Actually I haven't written there for months. |
| 01:06 | KirinDave | Ian finally kicked off. |
| 01:06 | amalloy | Lajla: i'd wager that it's xkcd, explained |
| 01:06 | KirinDave | We couldn't take it. |
| 01:06 | Lajla | Explained to whom? |
| 01:06 | Lajla | You mean people who are not as smart as I and don't get them on their won? |
| 01:06 | KirinDave | Lajla: Why not check out the site? |
| 01:06 | Lajla | Ah |
| 01:06 | replaca | KirinDave: nonetheless, there are a few (like that one) that I simply can't resisit |
| 01:06 | Lajla | you could not explain the mutual dream one. |
| 01:06 | replaca | *resist |
| 01:07 | KirinDave | replaca: He hits a few good ones. |
| 01:07 | Lajla | KirinDave, I'm not too pleased with your explanation of the knuth joke. |
| 01:07 | Lajla | I think the principle of explosion deserves a mention. |
| 01:08 | Lajla | But |
| 01:08 | Lajla | the strip is actually incorrect. |
| 01:08 | Lajla | The idea is I think that by exploding logic, she proves that all statements are true, including the negation of any statement. |
| 01:08 | Lajla | But that does not disprove anything. |
| 01:08 | replaca | I think that we need an existence proof of something Lajla *is* happy with before proceeding :) |
| 01:08 | Lajla | That's the fun thing a lot of people misunderstanda bout it. |
| 01:09 | Lajla | It proves that all statements are true, including for intance that the system is consistent |
| 01:09 | Lajla | and that it's not consistent at the same time. |
| 01:09 | Lajla | The whole fact that you can disprove statements by proving their negation relies on the assumption that the model is consistent. |
| 01:09 | Lajla | You can't really disprove statemnets any more by proving their negation once the model is inconsistent. =P |
| 01:09 | Lajla | replaca, =( |
| 01:10 | KirinDave | Lajla: I ahven't written for awhile. But I have a favorite you might enjoy |
| 01:10 | Lajla | I do have dysthimia. |
| 01:10 | replaca | An actual Clojure question: has "as-str" migrated to core in 1.3? |
| 01:10 | Lajla | KirinDave: http://thisdomainisirrelevant.net/1238 |
| 01:10 | Lajla | How do you like that one? |
| 01:11 | replaca | Lajla: sorry to hear it. |
| 01:11 | KirinDave | Lajla: http://xkcdexplained.com/post/805553793/real-medicine |
| 01:11 | Lajla | THat one is also incorrect. |
| 01:11 | Lajla | I know that one. |
| 01:11 | KirinDave | Lajla: Oh? |
| 01:12 | Lajla | It actually inverses it. |
| 01:12 | Lajla | It would be homoeopathic. |
| 01:12 | KirinDave | I can't make heads or tails of what you're saying. |
| 01:12 | Lajla | If semen praevented pregnancy. |
| 01:12 | Lajla | Not caused it. |
| 01:12 | KirinDave | Indeed. |
| 01:12 | dthomas | Can anyone tell me what the equivalent of (vec collection) is for lists? Just (apply list collection)? |
| 01:12 | Lajla | Or ehh |
| 01:12 | Lajla | The reverse |
| 01:12 | Lajla | if it was a homeopathic anti-conception means |
| 01:12 | amalloy | dthomas: list* should work, i think |
| 01:13 | KirinDave | Lajla: Most people don't understand the actual rules of homeopathy. |
| 01:13 | amalloy | &(list* [1 2 3]) |
| 01:13 | sexpbot | ⟹ (1 2 3) |
| 01:13 | KirinDave | Lajla: That they actually use a "law of sympathy" |
| 01:13 | KirinDave | As a preventative. |
| 01:13 | replaca | KirinDave: so if we do understand, are we any better off? |
| 01:13 | KirinDave | replaca: Oh no. The whole thing is absurd |
| 01:14 | KirinDave | replaca: But that explanation touched off a firestorm. |
| 01:14 | replaca | (since asking about Clojure is getting me nowhere :)) |
| 01:14 | KirinDave | replaca: We actually got ddos'd for it. |
| 01:14 | replaca | KirinDave: excellent! that's an accomplishment |
| 01:14 | KirinDave | I was pleased. |
| 01:14 | Lajla | KirinDave, I guess most people think homoeopathy is basically 'natural cures' |
| 01:14 | _mst | homoeopathic DoS attacks... one packet an hour or something? |
| 01:15 | KirinDave | _mst: Haha |
| 01:15 | Lajla | Little do they know that there is no difference between 'natural' and 'unnatural'and that advertisement guys just invented that. |
| 01:15 | KirinDave | _mst: Content-Length attacks could work that way. |
| 01:15 | Lajla | _mst, that would be a homoeopathic guard against DoS |
| 01:15 | Lajla | replaca, also, dysthimia is not that bad I guess, especially because you never knew any other. |
| 01:16 | dthomas | &(list? (list* [1 2 3])) |
| 01:16 | sexpbot | ⟹ false |
| 01:16 | Lajla | It's more of a 'symptomal' disease I guess, in that people who have it would have accepted it as normal because it's all they know and just display symptoms like lack of sleep, energy, appitite et cetera. |
| 01:16 | replaca | Lajla: I think it's natural that we all feel like the balance we have is the only one to have |
| 01:17 | Lajla | Yeah |
| 01:17 | Lajla | If someone asks me 'are you unhappy', I can't really answer that, I have nothing to compare it to. |
| 01:17 | dthomas | amalloy: So the result of list* doesn't seem to be a "list," is that right? |
| 01:17 | replaca | Lajla: the cheerleaders feel the same way at the other end of the spectrum |
| 01:17 | Lajla | All I know is that I display certain outward symptoms associated with it. |
| 01:17 | Lajla | Yeah, I guess. |
| 01:17 | Lajla | It's a philosophical thing. |
| 01:17 | Lajla | Like 'when I see green, do I see the same green others think' |
| 01:17 | replaca | yup |
| 01:18 | amalloy | dthomas: right, it's probably a lazy-seq. but that will behave like a list in every way i can think of |
| 01:18 | amalloy | &(map class (apply list [1 2 3]) (list* [1 2 3])) |
| 01:18 | sexpbot | java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$class |
| 01:18 | amalloy | &(map class [(apply list [1 2 3]) (list* [1 2 3])]) |
| 01:18 | sexpbot | ⟹ (clojure.lang.PersistentList clojure.lang.PersistentVector$ChunkedSeq) |
| 01:19 | dthomas | amalloy: You may be right about that, that this code will work despite it not actually being a list. |
| 01:20 | amalloy | dthomas: most code will work fine on any seq |
| 01:20 | Lajla | But to be honest, I'm not so sure about the desirability of 'happiness', a lot of recent studies seem to suggest that truly ignorance is bliss. And happiness is basically caused by just ignoring any bad news or finding a way to not believe in it. |
| 01:20 | amalloy | what are you doing that you think you need a list for? |
| 01:20 | Lajla | Are lists used in clojure often for anything but code? |
| 01:20 | dthomas | amalloy: Reading forms from Emacs/SLIME in the Clojure swank server. |
| 01:21 | replaca | Lajla: lists are useful when you want to be able to add at the front cheaply |
| 01:23 | Lajla | Ahh |
| 01:23 | Lajla | yeah |
| 01:23 | Lajla | How well does this conj work in generic code by the way? |
| 01:23 | Lajla | I mean, with lists adding the other way than vectors |
| 01:25 | amalloy | dthomas: what about just seq? ##(seq [1 2 3]) |
| 01:25 | sexpbot | ⟹ (1 2 3) |
| 01:25 | amalloy | ##(conj (seq [1 2 3]) 0) |
| 01:25 | sexpbot | ⟹ (0 1 2 3) |
| 01:27 | dthomas | amalloy: Certainly seems to have the same effect as list*. |
| 01:28 | dthomas | amalloy: (In this case where I have just one collection.) |
| 01:28 | amalloy | dthomas: list* isn't really designed for this nonsense; it's actually the same as (apply list) but i thought of it first :P |
| 01:28 | Raynes | Man, don't use ## when it's the first thing in the message. :\ |
| 01:28 | amalloy | Raynes: the # key is easier for me to find than & |
| 01:29 | Raynes | Maybe so, but it's a more limited form of evaluation designed for embedded code that people unfamiliar with him might thing is the shoddy default. |
| 01:29 | Raynes | think, even |
| 01:29 | amalloy | if this is wrong, i don't want to be right |
| 01:29 | Raynes | You make sexpbot cry. |
| 01:30 | amalloy | $kill Raynes |
| 01:30 | sexpbot | KILL IT WITH FIRE! |
| 02:47 | amalloy | thanks clojurebot |
| 02:49 | replaca | wow that was impressive |
| 02:49 | replaca | I caused that by checking in a fix to java-utils |
| 03:00 | amalloy | $mail hiredman fyi, around midnight pacific time clojurebot sent this message five times in as many seconds: (notice) [clojure/clojure-contrib] null - null (null) null |
| 03:00 | sexpbot | Message saved. |
| 03:02 | Raynes | amalloy: He wont get that. |
| 03:02 | Raynes | amalloy: He has sexpbot ignored. |
| 03:02 | Raynes | But your highlighting should suffice. |
| 03:02 | amalloy | Raynes: i figured one or the other would do it |
| 03:03 | Derander | hot |
| 03:03 | kryft | #clojure - a warm community |
| 03:06 | amalloy | heh. silent for hours, until someone drops a gay joke. good old irc |
| 03:06 | replaca | let's see if clojurebot spews again |
| 03:13 | Lajla | I like sexpbot more. |
| 03:13 | Lajla | It doesn't ignore me. |
| 03:33 | jackdempsey | anyway familiar with lein? trying to install relevance's labrepl and i can't tell if it's lein or their project that's borked |
| 03:35 | Lajla | Serial Experimens Lein |
| 03:43 | LauJensen | "Java is a DSL for taking large XML files and converting them to stack traces" AHAHAH :) |
| 03:47 | kryft | LauJensen: Ouch. :) |
| 03:48 | dirchh | LauJensen: quite appropriate. where's that quote from? |
| 03:49 | LauJensen | dirchh: twitter somewhere |
| 04:02 | jave | I want to start a repl inside a portlet running inside liferay, so I can change the code interactively. any hints? |
| 04:11 | raek | clojure.main/repl |
| 04:12 | jave` | Thanks |
| 06:19 | bartj | how do I print the unicode code-points of a string? |
| 06:24 | raek | ,(map int "åäöčšž") |
| 06:24 | clojurebot | (229 228 246 269 353 382) |
| 06:27 | bartj | raek, I thought unicode code points were something like this: \u00a0 |
| 06:27 | bartj | if no, then what is \u00a0 ? |
| 06:28 | dreamreal | bartj: code points are integers, too. \u00a0 is an escaped form of a hex value. |
| 06:28 | bartj | dreamreal, thank you; but I am unable to get the hex value of \u00a0 |
| 06:29 | dreamreal | you don't know what a0 is in decimal? |
| 06:29 | dreamreal | ,(map char 160) |
| 06:29 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer |
| 06:30 | dreamreal | darn it, had to try :) |
| 06:30 | dreamreal | (I don't know clojure) |
| 06:30 | Tordmor | ,(map char '(229 228 246 269 353 382)) |
| 06:30 | clojurebot | (\å \ä \ö \č \š \ž) |
| 06:30 | dreamreal | ,(map char '(160)) |
| 06:30 | clojurebot | (\ ) |
| 06:30 | dreamreal | there you go. |
| 06:34 | bartj | dreamreal, Tordmor thank you very much |
| 06:34 | bartj | the wierd thing is that 160 looks like space but it isn't! |
| 06:35 | dreamreal | it... doesn't. |
| 06:35 | dreamreal | #160 is a nonbreaking space in html, though |
| 06:46 | trybeingarun | (def head-fibo (lazy-cat [0 1] (map + head-fibo (rest head-fibo)))) |
| 06:46 | trybeingarun | This is from programming clojure |
| 06:47 | trybeingarun | Can anybody explain how this works? |
| 06:47 | Chousuke | trybeingarun: lazy-cat doesn't actually evaluate all the expressions immediately |
| 06:48 | trybeingarun | Okay |
| 06:48 | trybeingarun | My first question is what is map expected to do here? |
| 06:48 | trybeingarun | When map is called the first time would head-fibo have been defined? |
| 06:48 | Chousuke | ,(map + [1 2] [10 20]) |
| 06:48 | clojurebot | (11 22) |
| 06:48 | kensho | Hi. Is there something like doto for static methods? This is a bit verbose: (Math/round (Math/max (Math/ceil (Math/sqrt total-area)) (* max-width 1.2))))) |
| 06:48 | Chousuke | trybeingarun: yes. |
| 06:49 | Chousuke | trybeingarun: when you def head-fibo, you just get a thunk. and then when you get to the third element of the sequence, lazy-cat evaluates the (map ...) |
| 06:49 | Chousuke | trybeingarun: and since head-fibo is defined by then, it works |
| 06:50 | trybeingarun | Okay. |
| 06:50 | kensho | Hi. Is there something like doto for static methods, I'd like to make this shorter: (Math/round (Math/max (Math/ceil (Math/sqrt total-area)) (* max-width 1.2))))) |
| 06:50 | Chousuke | kensho: use -> |
| 06:51 | Chousuke | or you can write your own macro |
| 06:51 | kensho | Ah I see. I will try to wrap my head around this :) thanks |
| 06:53 | Chousuke | I don't think you can do much in that case though. |
| 06:54 | Chousuke | too bad clojure doesn't yet have macrolet. Could write a macro like (with-statics Math [round max ceil sqrt] (round ...)) |
| 06:55 | trybeingarun | I would like to understand lazy-seq better. Is there any good material available for that? |
| 06:55 | trybeingarun | I mean right from intro level material... |
| 06:57 | Chousuke | I don't know, but if you have something specific that you don't understand, just ask :) |
| 06:58 | jave | I'm having trouble overriding a method with aot and calling a super method. I get a circular call chain and a stack overflow |
| 06:59 | trybeingarun | I am not getting how lazy-seq works. I would like to understand what the flow for |
| 06:59 | trybeingarun | (take 1 head-fibo) |
| 06:59 | trybeingarun | (take 2 head-fibo) similarly for 3 |
| 06:59 | trybeingarun | works |
| 06:59 | kensho | Chousuke: If I understand correctly -> won't get rid of the repetive "Math" identifier. But it's possible with a custom macro? |
| 06:59 | Chousuke | kensho: yeah |
| 06:59 | kensho | ok I will look into macros then, thanks! |
| 06:59 | trybeingarun | I want to know how the synthesis of the new seq element happens |
| 07:00 | Chousuke | trybeingarun: a lazy seq is basically just one thing: a chunk of code that generates the rest of the sequence |
| 07:00 | Chousuke | that is, until it's realised |
| 07:00 | Chousuke | once the element is generated, it's cached |
| 07:00 | Chousuke | so on subsequent accesses the code is not re-executed |
| 07:00 | trybeingarun | Understood. |
| 07:01 | trybeingarun | Coming back to the example, how does (head-fibo) work? |
| 07:02 | Chousuke | lazy-cat creates a lazy sequence by lazily evaluating the expressions you give to it. |
| 07:02 | Chousuke | :P |
| 07:02 | Chousuke | so it returns a thunk that at first does nothing |
| 07:03 | Chousuke | but when you request the first element, it evaluates the first expression (in this case, [0 1]) |
| 07:03 | Chousuke | and takes the first element of that (after making a sequence out of it, so it actually becomes (0 1)) |
| 07:04 | trybeingarun | Okay. I am beginning to understand it |
| 07:04 | Chousuke | then the "rest" of the sequence is another thunk that does the same for the next element of the vector |
| 07:04 | Chousuke | and the rest of that then notices there are no more elements in the vector and evaluates the next expression (the map one) |
| 07:05 | Chousuke | which gives another lazy sequence; an infinite one in this case. |
| 07:05 | Chousuke | head-fibo is not the easiest lazy seq to explain I guess :P |
| 07:06 | trybeingarun | May be. |
| 07:06 | trybeingarun | But thanks man. At least I am beginning to see the point |
| 07:06 | Chousuke | but let's make a custom one. (defn lazy-ones [] (lazy-seq (cons 1 (lazy-ones)))) |
| 07:07 | trybeingarun | Ah, a simple one at last!!! |
| 07:07 | Chousuke | when you call lazy-ones, it returns a thunk that, when you call seq on it, retuns a sequence of 1, (lazy-ones) |
| 07:08 | trybeingarun | okay |
| 07:08 | Chousuke | but since lazy-ones returns only a thunk, the recursion stops until you really access the next element of the sequence. :) |
| 07:08 | Chousuke | in which case you get another 1 and a thunk |
| 07:08 | trybeingarun | This is how it does not blow up the stack |
| 07:09 | Chousuke | yeah |
| 07:09 | Chousuke | when the thunk is evaluated, the original function call has already completed. |
| 07:09 | trybeingarun | so internally it maintains some sort of a state which says how many elements have actually been realized |
| 07:10 | trybeingarun | and then it will have some object to compute the next element |
| 07:10 | trybeingarun | am i getting it right? |
| 07:10 | Chousuke | You can use parameters too (defn increments [n] (lazy-seq (cons n (series (inc n))))) |
| 07:11 | Chousuke | trybeingarun: there's no need for that. |
| 07:11 | Chousuke | trybeingarun: since sequences are just linked lists of head -> rest |
| 07:11 | Chousuke | and the rest can be either a thunk, or another sequence which is head -> rest |
| 07:12 | trybeingarun | Okay. |
| 07:12 | trybeingarun | Fine. Think I got it. Let me think abt the example you gave and also the example in the book and get back :) |
| 07:13 | Chousuke | try writing some simple lazy seqs yourself |
| 07:13 | Chousuke | see how it works. |
| 07:13 | trybeingarun | Okay. I will write some code with some side effects |
| 07:13 | Chousuke | you can also add print statements to the function so you can see whenever one is evaluated |
| 07:15 | Chousuke | (let [ones (fn ones [] (lazy-seq (print "got one; ") (cons 1 (ones)))) s (ones)] (doseq [i (take 3 ones)] (print "a " i)) (take 3 ones)) |
| 07:16 | Chousuke | ,(let [ones (fn ones [] (lazy-seq (print "got one; ") (cons 1 (ones)))) s (ones)] (doseq [i (take 3 ones)] (print "a " i)) (take 3 ones)) |
| 07:16 | clojurebot | java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: sandbox$eval589$ones__590 |
| 07:16 | Chousuke | oops |
| 07:16 | Chousuke | ,(let [ones (fn ones [] (lazy-seq (print "got one; ") (cons 1 (ones)))) s (ones)] (doseq [i (take 3 s)] (print "a " i)) (take 3 s)) |
| 07:16 | clojurebot | got one; a 1got one; a 1got one; a 1 |
| 07:16 | clojurebot | (1 1 1) |
| 07:17 | Chousuke | (note it's not printing the "got one"s twice even though I do (take 3 s) twice) |
| 07:18 | trybeingarun | Ya |
| 07:20 | Chousuke | take itself returns a lazy seq though; but in this case both of those sequences are forced to be fully realised. |
| 07:20 | Chousuke | one by doseq and one because it's the return value that is printed |
| 07:24 | trybeingarun | understood your code and stu halloway's code dude |
| 07:24 | trybeingarun | I did not realize that head-fibo itself is of type lazy-seq |
| 07:25 | trybeingarun | now I am getting how the sequence is being generated :) |
| 07:25 | trybeingarun | Thanks Chousuke :D |
| 07:28 | djpowell | what's the deal with jira - it says i have an account, but i cant figure out what the password might be - were the accounts imported from assembla, without passwords? |
| 07:50 | raek | trybeingarun: try this: https://gist.github.com/480608 |
| 07:50 | raek | it makes it very clear when the seq is forced |
| 07:54 | raek | although, it does not add very much to Chousuke's explanation |
| 08:26 | jweiss_ | is there an explanation somewhere for what *ns* is exactly? Is it the namespace of the surrounding code? Can i refer to it in a macro? If so, does it refer to the namespace of the macro or the place where the macro is called? |
| 08:27 | jweiss_ | i suppose what i'm asking is, when is the value of *ns* changed. |
| 08:31 | chouser | jweiss_: the value of *ns* is changed by in-ns and ns |
| 08:31 | jweiss_ | chouser: what about at compile time |
| 08:32 | LauJensen | ClojureQL news: 100% transparent auto-parameterization of queries now in MASTER! :) |
| 08:32 | chouser | jweiss_: you should be able to refer to it in a macro (not a macro expansion) and get the namespace being compiled while the macro is being expanded |
| 08:33 | jweiss_ | chouser: the ns where the macro lives, or the ns where the macro call lives? |
| 08:35 | jweiss_ | ok seems to be where the call lives |
| 08:35 | jweiss_ | that's what i wanted |
| 08:36 | raek | jweiss_: it depends on whether you do (defmacro ... *ns* ...) or (defmacro ... `(... *ns* ...)) |
| 08:36 | jweiss_ | raek: *ns* is not quoted |
| 08:37 | raek | hrm. |
| 08:37 | jweiss_ | oh hm, but i did a "use" on the ns with my macro. wonder if it behaves the same if i did require. |
| 08:38 | raek | *ns* is probably dynamically bound during the compilation of the macro |
| 08:38 | raek | and a reference to the var (not the value) is compiled into the macro |
| 08:39 | raek | (let [my-ns *ns*] (defmacro ...)) could perhaps be a way |
| 08:39 | raek | I guess it depends on what you are trying to do |
| 08:40 | jweiss_ | raek: what i want is when i call my macro, i want the macro to get the ns-publics from the namespace I called the macro from, pull the metadata from each 'public', and create a call to gen-class |
| 08:40 | jweiss_ | public = ns-publics |
| 08:41 | jweiss_ | my macro works in that it generates the classes for the right namespace. but it has no annotations. but if i expand the macro myself at the repl, and paste that code in place of the call to the macro in my test file, and compile it, i get the annotations. |
| 08:42 | jweiss_ | that's the part that i'm scratching my head about. |
| 08:44 | jweiss_ | perhaps this has something to do with the order things are compiled |
| 08:46 | chouser | your macro is itself expanding to the gen-class form? |
| 08:46 | jweiss_ | chouser: correct |
| 08:47 | chouser | and you AOT compile the namespace that includes the use of that macro, and can observe that it generates the class but without annotations. |
| 08:47 | jweiss_ | chouser: that's right |
| 08:47 | chouser | can you paste somewhere the macro itself and its expansion? |
| 08:48 | jweiss_ | chouser: yes, 1 sec |
| 08:56 | jweiss_ | chouser: https://gist.github.com/712134 |
| 09:01 | chouser | jweiss_: testng-map is a map? Is there any chance it's values are classes instead of symbols? |
| 09:03 | jweiss_ | chouser: i guess they're classes, i just use the class name with no quote |
| 09:03 | chouser | that may be the problem |
| 09:03 | jweiss_ | as in {:beforeSuite BeforeSuite ... |
| 09:03 | chouser | gen-class is probably expecting symbols that name classes, not classes themselves |
| 09:04 | chouser | so try either quoting your class names, or in as-annotation get the symbol name of the class |
| 09:04 | chouser | ,(symbol (.getName Integer)) |
| 09:04 | clojurebot | java.lang.Integer |
| 09:05 | jweiss_ | chouser: ok thanks |
| 09:11 | jweiss_ | chouser: THANK YOU!!! that was the problem. i could have spent days on this and never figured that out. |
| 09:12 | chouser | heh |
| 09:12 | chouser | you're quite welcome. it's a common "gotcha" with metadata |
| 09:12 | raek | ,java.lang.String |
| 09:12 | clojurebot | java.lang.String |
| 09:12 | raek | ,'java.lang.String |
| 09:12 | clojurebot | java.lang.String |
| 09:13 | chouser | right |
| 09:13 | raek | ,(map class [java.lang.String 'java.lang.String]) |
| 09:13 | clojurebot | (java.lang.Class clojure.lang.Symbol) |
| 09:13 | raek | tricky. |
| 09:13 | jweiss_ | well i guess i am happy that my problem wasn't an obvious one that i should have seen myself :) |
| 09:18 | AWizzArd | Let's say I want to write a dynamical web application. Many people would go with html+js, but let's say I want to run the client inside a JVM instead of a Webbrowser-VM, and do it with Clojure+Swing. Now instead of html my server transfers specs (lists) out of which the client can construct the UI components and position them. |
| 09:19 | chouser | I wonder if it'd be worth having classes print themselves differently than symbols, and then optionally read with that syntax as well |
| 09:19 | AWizzArd | The JS parts become the handlers for UI elements. To transfer those I could simply send out lists to the clients which then eval those. |
| 09:20 | AWizzArd | But if I wanted to send out precompiled code, is then the best way to precompile the code on my server into a class (byte code generation) and load this from the client via Clojures DynClassLoader? |
| 09:21 | chouser | AWizzArd: would that be better than sending uncompiled s-exprs and having the client eval it? |
| 09:21 | AWizzArd | Yes, that is my question basically. I am not sure about it. |
| 09:21 | AWizzArd | It is a not so typical way to create a dynamic web app. |
| 09:22 | AWizzArd | If it were about html+js then yes, the client code would come as open source. And the browsers compile the js then to byte code for their VMs. |
| 09:22 | chouser | well, it stretches the definition of "web app" doesn't it? |
| 09:22 | chouser | if you send compiled Clojure code, the client and server Clojure versions would have to match up pretty well |
| 09:22 | AWizzArd | In some sense yes. A container JFrame plus the JVM of course would take the role of the browser. |
| 09:23 | AWizzArd | The client is just a very small application that basically just loads code from the server. |
| 09:23 | AWizzArd | Like an empty browser window so to say. |
| 09:23 | AWizzArd | Only the server hosts the (mostly static) client code and sends it out. |
| 09:24 | AWizzArd | This then tells the client how to construct itself on the other side. |
| 09:24 | maravillas | Sounds kind of scary when you say it like that |
| 09:24 | maravillas | (loads code from the server) |
| 09:24 | AWizzArd | This is what happens on 97% of all websites. |
| 09:24 | AWizzArd | They load js into the browser. |
| 09:25 | AWizzArd | Pretty static js files get a GET request, and get transmitted as clear text (source code) to the VM, where it gets compiled and executed. |
| 09:25 | maravillas | But your browser won't have the same sandbox and security that browsers get for free |
| 09:25 | maravillas | "free," of course |
| 09:25 | AWizzArd | Right. And my browser has more rights. |
| 09:26 | AWizzArd | I don't know if JS can run sql queries, do ssh, do good bits of file processing, write files to the computer of the user, etc. |
| 09:26 | AWizzArd | At least older versions of JS could basically just do some stuff on the client side. I want to do everything that Clojure allows, plus be able to reuse all Java libs that I need. |
| 09:27 | maravillas | I mentioned that as a downside :) |
| 09:27 | wooby | what's the easiest way to build a maven project against a local build of clojure? |
| 09:27 | AWizzArd | When I did JS and wanted to run a sql query, then I had to do an ajax request to the server and let the server do the work. |
| 09:28 | AWizzArd | But maybe JS can now do sql and basically access the right to run outside the browser sandbox, dunno. |
| 09:29 | AWizzArd | Currently my plan is, like chouser said, to send out lists and let the client eval them. |
| 09:31 | AWizzArd | Another option could be to try to touch the code that eval produces and send out the compiled result directly. |
| 09:32 | chouser | if you send compiled Clojure code, the client and server Clojure versions would have to match up pretty well |
| 09:33 | AWizzArd | Yes. The user receives its Clojure from an initial request during application startup. |
| 09:33 | AWizzArd | But it is true that this can be a disadvantage. |
| 09:34 | Tordmor | AWizzArd: There's java WebStart that does that. Or at least has been some years ago ;) |
| 09:34 | chouser | debugging a stream of bytecode will be trickier than debugging a stream of s-exprs |
| 09:34 | AWizzArd | Tordmor: yes, I have already used that along with Clojure successfuly. |
| 09:34 | AWizzArd | chouser: though in principle instead of Firebug the Client could use any JVM debugger :) |
| 09:35 | chouser | but without access to the source code, a JVM debugger will be less helpful |
| 09:35 | AWizzArd | But yes, with code it is of course much better. |
| 09:35 | AWizzArd | true |
| 09:39 | chouser | AWizzArd: I was once involved in a one-day spike to do roughly what you're describing using jvm+qt for the client, sending UI code from the server in the form of jython |
| 09:40 | chouser | this was before canvas tag, websockets, etc. |
| 09:40 | chouser | we thought it was an interesting way to create a thin client with a rich UI |
| 09:40 | AWizzArd | This solution has its own advantages and disadvantages. |
| 09:40 | chouser | we called it "paris" because we couldn't think of anyone else as thin and rich |
| 09:41 | AWizzArd | (: |
| 09:42 | AWizzArd | What I propose will not run on ipads and Android, but on the classical OSes on desktop PCs or notebooks it will give very much control over what the client can do, run probably more efficiently than JS, and allows us to write Clojure code, instead of having Clojure+html+JS. |
| 09:51 | chouser | I'd rather have a nice brower-compatibility lib in JS, and clojure compiling to JS, and run all that in a regular browser client |
| 09:53 | AWizzArd | This does however not solve the problem to leave the browsers sandbox, to get full control of what programs can do with a computer. |
| 09:54 | chouser | AWizzArd: it strikes me as a rare circumstance that that would be desirable |
| 09:54 | AWizzArd | For websites that want to reach hundreds of thousands of users and just presents some content it is not required. |
| 09:55 | AWizzArd | But what if you want to read data that sits in a local sql db at the client side? |
| 09:55 | chouser | browsers now come with local sql db's that can be read from js. :-) |
| 09:56 | AWizzArd | Let's say your program must be able to read from any db that Java can read from. Is that then also possible? |
| 09:56 | AWizzArd | Also, there are useful Java libs that you may want to use on the client side. Not possible with JS (without starting a JVM). |
| 09:57 | chouser | not without an extra component such as a signed java applet or browser plugin, or something like a websocket adapter for your client-side db. |
| 09:57 | AWizzArd | But sure, if there were a Clojure implementation written in JS which compiles to Browser-Byte-Code, then this would allow for ClojureScript running in browsers, which is nice for the typical case. |
| 09:58 | AWizzArd | I would more like to target a few hundred users who have specific needs. Plus there is no Clojure implementation yet written in JS as far as I know. |
| 09:58 | AWizzArd | Otherwise I could consider it again, though as I said, it would be pretty limited. |
| 09:59 | chouser | not a recent version of clojure, no. |
| 09:59 | AWizzArd | If the browsers would offer a way to go around the sandbox then the browsers could become the new JVM, with JS as their low-level language, which can compile to byte code. |
| 10:00 | chouser | AWizzArd: http://www.mozilla.org/projects/security/components/signed-scripts.html#privs |
| 10:00 | AWizzArd | I am not sure that JS offers random acess to huge files, or good local file handling at all |
| 10:01 | AWizzArd | chouser: yes, interesting. The browsers could come to agreements and produce slowly their replacement of Java and .NET in this decade. |
| 10:02 | AWizzArd | Let's see how soon popular programming language implementations will be available for JS. |
| 10:03 | chouser | js is already more popular than whatever language you're thinking of. :-) |
| 10:04 | AWizzArd | Yes. It sneaked in into our homes by simplicity. |
| 10:04 | chouser | or by ubiquity |
| 10:04 | djpowell | js is an excellent language for animating your geocities 'under contruction' marquee text |
| 10:04 | AWizzArd | Very light weight and simple it was, and grew over time. |
| 10:04 | AWizzArd | chouser: yes |
| 10:05 | djpowell | is there anyone around who can answer my 'how do i log in to jira' question? |
| 10:05 | AWizzArd | Now as it is so popular and gains and power the browser implementors can continue to build upon that base, and add all major functionality that can be found today in Java and .NET. |
| 10:21 | tape_dispencer | I'm having some problems using recur, there error is "Can only occur from tail position", but to me it is in a tail position. Is it appropriate to paste a 6 line function? |
| 10:22 | chouser | tape_dispencer: please paste using paste.lisp.org, gist.github.com, or something similar |
| 10:23 | chouser | (if a b c) ; b and c are tail positions, a is not. |
| 10:24 | chouser | (if a (b (x y) (z)) (c 1 2 (+ 3 4))) ; b and c are still tail positions, as is 'if', but nothing else there is. |
| 10:24 | tape_dispencer | Thank you, i was not aware of such a site |
| 10:25 | tape_dispencer | http://paste.lisp.org/display/116991 |
| 10:25 | chouser | in that paste, 'cons' is in a tail position, but none of its arguments are |
| 10:27 | chouser | x is in the tail position of a function *only* when the return value of the whole function may be exactly x |
| 10:27 | octe | i'm tinkering with writing a game in clojure |
| 10:27 | tape_dispencer | Ohh really? Ahh. In you example, if is a special form, so it can't be in the tail position |
| 10:28 | octe | kind of wondering what a functional way of having state is |
| 10:28 | chouser | in your paste, (fn [] (cons x y)), fn will return cons, but never just x or just y, so x and y are not tail position |
| 10:29 | octe | i made a small test: http://paste.lisp.org/display/116992 |
| 10:29 | octe | but that doesn't feel very scalable once the world grows |
| 10:30 | tape_dispencer | thank you chouser, I'll see what I can do to fix it! |
| 10:30 | chouser | octe: it may or may not be. Have you seen rhickey's ant demo? |
| 10:31 | chouser | tape_dispencer: I learned about moving things into the tail position while reading "On Lisp" by Paul Graham. I'm sure there are other ways to learn it. :-) |
| 10:31 | octe | chouser, nope |
| 10:32 | chouser | octe: he uses one ref for each cell of the board, plus one agent per ant moving on the board. Might be worth looking at. |
| 10:32 | dpritchett | i learned tail recursion by reading SICP-educated schemers dismissing clojure :/ |
| 10:32 | dpritchett | i still havent finished sicp myself |
| 10:32 | tape_dispencer | chouser: That was a good book. I guess I need to re-read it. Thanks |
| 10:32 | octe | chouser, hmm ok |
| 10:33 | octe | is there a prettier way of doing this: |
| 10:33 | octe | (assoc world :player (assoc (:player world) :y (+ (:y (:player world)) 1))) |
| 10:33 | dpritchett | does anyone know how swannodette got websockets working in his iOS video yesterday? I've wanted to try them in clojure but didn't really know where to start |
| 10:34 | dpritchett | Socket.IO in node.js was pretty easy for me |
| 10:34 | chouser | tape_dispencer: the general technique is to pass in an accumulator instead of returning the accumulated value. |
| 10:35 | jarpiain | octe: (update-in world [:player :y] + 1) |
| 10:35 | mduerksen | octe: have a look at "assoc-in" |
| 10:35 | tape_dispencer | chouser" ohh yeah! I remember that now. Yo uhave been a great help. |
| 10:36 | mduerksen | octe: update-in is right :) |
| 10:40 | octe | thanks |
| 10:43 | dpritchett | Fogus's review of Land of Lisp is very complimentary. That was nice of him. |
| 11:29 | trybeingarun | Nice to see RH again in IRC channel! |
| 11:44 | replaca | hiredman: did you see that clojurebot was spewing nulls when I checked stuff into contrib last night? |
| 11:57 | lrenn | I've been meaning to ask this since the conj, does anyone know Rich's Go rank? |
| 12:14 | ohpauleez | lrenn: That's a good question. I also play Go, so I started wondering how many people in the community are go players |
| 12:20 | gfrlog | I'm trying to learn clojureql and am having trouble with the project function |
| 12:20 | gfrlog | the example given shows passing it a set containing one column name |
| 12:20 | gfrlog | if I give it 2 columns names I get java.lang.UnsupportedOperationException: nth not supported on this type: PersistentHashSet |
| 12:21 | gfrlog | ,(println "echo") |
| 12:21 | clojurebot | echo |
| 12:21 | LauJensen | gfrlog: Which example? |
| 12:22 | ohpauleez | gfrlog: You should checkout #clojureql |
| 12:22 | ohpauleez | I think Lau and a few others are in there |
| 12:22 | gfrlog | I probably should |
| 12:22 | gfrlog | the example has |
| 12:22 | gfrlog | @(-> (select users (where (< :id 3))) |
| 12:22 | gfrlog | (project #{:title})) |
| 12:22 | LauJensen | gfrlog: I mean, where did you find that ? |
| 12:23 | gfrlog | the project readme on github |
| 12:23 | gfrlog | https://github.com/LauJensen/clojureql |
| 12:23 | LauJensen | gfrlog: Okay, sorry about that, its outdated, I'll update it asap |
| 12:23 | LauJensen | Check out this post http://bestinclass.dk/index.clj/2010/11/clojureql--1.0.0-now-in-beta.html and the example in there |
| 12:23 | gfrlog | cool, thanks |
| 12:23 | LauJensen | (-> (table :users) (project [:a :b [:c :as :d]])) ... |
| 12:23 | gfrlog | I forked the project earlier, I can update the readme if you like |
| 12:24 | LauJensen | Thanks, but I think I got it, it needs a visit anyway :) You're welcome to join us in #clojureql |
| 12:24 | gfrlog | I just added it in |
| 12:24 | gfrlog | er, joined |
| 12:25 | LauJensen | fixed |
| 12:42 | gfrlog | I use primitive dev tools like vim and "lein repl", and for months now I've had issues with the repl output buffer not flushing |
| 12:42 | gfrlog | I have to issue a second command before the output from the last one will finish printing to the console |
| 12:43 | gfrlog | this happens on every machine I work on, so I imagine this is well known? |
| 12:43 | technomancy | gfrlog: fixed in 1.4 |
| 12:43 | gfrlog | that's lein 1.4? |
| 12:44 | technomancy | right. it's still in release candidate stage, but it's totally usable for everyday work. |
| 12:44 | gfrlog | okay. I'm switching now, thanks |
| 12:45 | technomancy | I never use the repl task, so the bugs there take longer to get fixed =) |
| 12:47 | gfrlog | technomancy: and I have an irrational bias against emacs, so my programs take longer to get written |
| 12:48 | technomancy | It's OK; Emacs will wait for you... as long as it takes. |
| 12:48 | gfrlog | ha |
| 12:50 | gfrlog | technomancy: it looks like upgrading to 1.4 lost my line-runner-reader-whatever stuff? |
| 12:50 | gfrlog | (up-arrow) |
| 12:50 | gfrlog | I just downloaded the script and ran "lein self-install" |
| 12:51 | gfrlog | sorry if that jumble of words wasn't specific enough |
| 12:53 | technomancy | make sure rlwrap is installed? |
| 13:17 | gfrlog | technomancy: that worked, thanks; I'd never heard of that package |
| 13:26 | technomancy | gfrlog: it's a lot better than jline, but the disadvantage is that you can't distribute it in a jar; it has to be installed separately. |
| 13:32 | rlb | If you have an operation that can be naturally expressed as a reduction, but that might need to stop somewhere in the middle and return a particular value, would it be idomatic to use reduce and throw, or something else? |
| 13:33 | chouser | reduce and throw would not be idiomatic. have you looked at 'reductions'? |
| 13:33 | leafw | what do you call a function with 2 arguments? Does it have a formal name? And a function with one argument? |
| 13:34 | rlb | chouser: I had, but had forgotten about it, thx. Though I'm not sure that'll be beter in this particular case. |
| 13:34 | qbg | Continuations would make that nice |
| 13:35 | chouser | rlb: it might not be, depending on how you determine when to stop |
| 13:35 | rlb | leafw: binary and unary? |
| 13:35 | chouser | rlb: loop/recur is often quite nice in such situations |
| 13:35 | amalloy | rlb: reductions is (i think?) lazy, so (first (filter is-okay-return-value (reductions whatever))) should do what you want |
| 13:35 | rlb | chouser: right -- I was wondering if that might actually be better here. |
| 13:35 | leafw | rlb: that's what I thought, but somehow I recall a different set of names |
| 13:36 | leafw | rlb: thanks in any case |
| 13:36 | Raynes | leafw: I call them foo and bar respectively. |
| 13:36 | leafw | Raynes: xD |
| 13:37 | amalloy | rlb: yeah, reductions is lazy, and it's not chunked, so if you filter/remove for the first valid return value, that's effectively stopping in the middle |
| 13:37 | rlb | amalloy: in this case, I want either the *last* value, or BAD-VALUE (nil perhaps), if that comes sooner. |
| 13:38 | rlb | I suspect loop/recur or throw is what I want -- I'll see how it goes. thx. |
| 13:39 | chouser | rlb: I'd really recommend not using throw for that kind of flow control |
| 13:39 | amalloy | rlb: (let [results (reductions ...)] (or (seq (filter is-bad? results)) (last results))) |
| 13:40 | rlb | chouser: right, I'm changing it from a reduce to loop/recur now. |
| 13:40 | rlb | (see how it looks) |
| 13:40 | rlb | Originally, it was a reduce because I didn't need to stop in the middle except when there was an actual error. |
| 13:41 | rlb | amalloy: right, though that keeps the whole seq around (which in this case would be fine)... |
| 13:47 | dpritchett | is there a clojure equivalent to the python raw string? ex: r'/home/daniel/folder name' vs. '/home/daniel/folder\ name' |
| 13:48 | replaca_ | dpritchett: no, but you don't need a \ in front of a space |
| 13:48 | dpritchett | eh that was just an example |
| 13:48 | replaca_ | dpritchett: and there are regex literals |
| 13:48 | dpritchett | i didn't want to say r'c:\program files\Internet Explorer' :P |
| 13:49 | replaca_ | hah hah. You've got to buckle down and double the \s there |
| 13:49 | replaca_ | but that's usually the only place |
| 13:49 | dpritchett | i remember getting really confused reading a regex with the double \\s, i guess the literals are a must for readability |
| 13:49 | amalloy | dpritchett: though don't newer versions of windows tolerate usage of / instead of \? |
| 13:50 | dpritchett | who knows amalloy, i use xp pro at work, vista at home, cygwin on both... hard to keep up with what's allowed and what's just a result of a customization i forgot |
| 13:50 | dpritchett | allowed by default i mean |
| 13:50 | amalloy | heh, so true |
| 13:52 | amalloy | wait until you write a bash script that uses perl to test strings against a windows-path regex. you need at least 8 \s in a row |
| 14:12 | Bahman | Hi all! |
| 14:15 | apgwoz | is the best way to get a number from a string still to use Integer/parseInt, Double/parseDouble? |
| 14:15 | dmart_ | I'm pretty new at it, but I started using the reader after I encountered an integer too big for Integer |
| 14:16 | apgwoz | that makes a lot of sense |
| 14:17 | dmart_ | &(read-string "123456") |
| 14:17 | sexpbot | ⟹ 123456 |
| 14:17 | apgwoz | that's probably the most appropriate thing to do |
| 14:17 | apgwoz | :) |
| 14:17 | dmart_ | &(read-string "123456.12") |
| 14:17 | sexpbot | ⟹ 123456.12 |
| 14:17 | dmart_ | :) |
| 14:18 | dmart_ | I'm waiting for one of the knowledgeable people in here to smite me |
| 14:18 | serp__ | hi guys. how do I access elements in a multidimensional array? |
| 14:19 | chouser | &(read-string "#=(clojure.core/println \"hi!\")") |
| 14:19 | Chousuke | using read is problematic in that you might not get a number |
| 14:19 | Chousuke | &(read-string "x123") |
| 14:19 | sexpbot | ⟹ x123 |
| 14:19 | sexpbot | java.lang.Exception: EvalReader not allowed when *read-eval* is false. |
| 14:20 | amalloy | serp__: aget takes multiple indexes |
| 14:20 | serp__ | oh... I am stupid and didn't see it |
| 14:22 | apgwoz | Chousuke: of course, i'm taking care of that though |
| 14:28 | Raynes | chouser: Thought you were being sneaky, didn't ya? ;) |
| 14:28 | chouser | Yes I did. |
| 14:29 | Raynes | &(* 9999999999999999999999 999999999999999999999) ; I'm still trying to figure this one out. |
| 14:29 | sexpbot | java.lang.Exception: EvalReader not allowed when *read-eval* is false. |
| 14:29 | chouser | &(binding [*read-eval* true] (read-string "#=(clojure.core/println \"hi!\")")) |
| 14:29 | sexpbot | ⟹ hi! nil |
| 14:29 | chouser | hee hee |
| 14:29 | amalloy | chouser: omg haxxx |
| 14:29 | Raynes | chouser: Nice catch. I forgot to blacklist *read-eval*. |
| 14:29 | raek | &((resolve (symbol "eval")) '(+ 1 2)) |
| 14:29 | sexpbot | ⟹ 3 |
| 14:29 | raek | Raynes: touché |
| 14:29 | Raynes | I'm pretty sure I did remember to blacklist resolve, so that one is odd. |
| 14:30 | amalloy | Raynes: (not= ns-resolve resolve) |
| 14:30 | Raynes | amalloy: Oh, right! |
| 14:30 | Raynes | Fixes, comin' up. |
| 14:42 | rata_ | hi |
| 14:42 | ossareh | hey |
| 14:42 | rata_ | =) |
| 14:42 | rata_ | does anybody know how to import a leiningen project into eclipse? |
| 14:42 | ossareh | not me |
| 14:43 | ossareh | does anyone remember the name of the function that takes a fn and it's args and returns an fn that takes more args and applies the new args to the function |
| 14:43 | ossareh | I thought it was comp |
| 14:44 | ossareh | but seems it isn't. |
| 14:44 | rata_ | partial |
| 14:45 | rata_ | =) |
| 14:45 | jweiss_ | ossareh: comp is like f(g(x)) |
| 14:45 | rata_ | a good nmemonic for that is "partial evaluation" |
| 14:45 | rata_ | :) |
| 14:46 | Raynes | &(binding [*read-eval* true] (read-string "#=(clojure.core/println \"hi!\")")) |
| 14:46 | sexpbot | java.lang.SecurityException: You tripped the alarm! *read-eval* is bad! |
| 14:46 | chouser | &(((symbol "eval") (ns-publics 'clojure.core)) '(+ 1 2)) |
| 14:46 | sexpbot | ⟹ 3 |
| 14:46 | chouser | ,(((symbol "eval") (ns-publics 'clojure.core)) '(+ 1 2)) |
| 14:46 | clojurebot | 3 |
| 14:47 | Raynes | chouser: Man, you'd be doing a huge favor by not making me do these one at a time. :p |
| 14:47 | chouser | sorry, just came up with it |
| 14:47 | mjg123 | Hi - how to fix this java.lang.IllegalArgumentException: Can't call public method of non-public class... |
| 14:47 | Raynes | <3 |
| 14:49 | raek | mjg123: if the class is private, are you supposed to fiddle with it? |
| 14:49 | Lajla | &(eval (list (symbol "eval") (list (symbol "+") 1 2 3))) |
| 14:49 | sexpbot | java.lang.SecurityException: You tripped the alarm! eval is bad! |
| 14:49 | chouser | Raynes: how will you be blocking that one? |
| 14:49 | Lajla | Buurrr |
| 14:49 | Raynes | blacklisting ns-publics. |
| 14:49 | Lajla | Raynes, you don't trust me with eval? |
| 14:49 | chouser | really? |
| 14:49 | chouser | ok |
| 14:49 | Raynes | chouser: There isn't really a way around it, unfortunately. |
| 14:49 | raek | mjg123: or is it your own class? |
| 14:49 | mjg123 | no it's a com.sun class |
| 14:50 | raek | which one? |
| 14:50 | LauJensen | in case anybody cares I started on of these http://laujensen.tumblr.com for various rants |
| 14:50 | mjg123 | the code is here: http://paste.lisp.org/display/116997 |
| 14:50 | chouser | Raynes: ns-map |
| 14:50 | amalloy | Raynes: the way around it, eventually, is incremental evaluation |
| 14:50 | Raynes | Yeah. |
| 14:50 | chouser | Raynes: ns-interns |
| 14:51 | mjg123 | .write is a public method on SourceDataLine (an interface) but clojure is complaining... |
| 14:51 | Raynes | chouser: amalloy and I have been cooking up some ideas for incremental evaluation that would make blacklisting useful stuff like this less important. |
| 14:51 | jarpiain | mjg123: try type hinting it as a public superclass or interface |
| 14:51 | ohpauleez | LauJensen: I always care |
| 14:52 | ohpauleez | haha :) |
| 14:52 | jarpiain | mjg123: (.write ^SourceDataLine sdl ...) |
| 14:52 | chouser | &(.findInternedVar (the-ns 'clojure.core) 'eval) |
| 14:52 | sexpbot | java.lang.SecurityException: You tripped the alarm! eval is bad! |
| 14:52 | ohpauleez | Also, this is a good write up to happen upon, I wanted to know the details of the rewrite (saw the commit on github. attn: LauJensen) |
| 14:52 | chouser | &(.findInternedVar (the-ns 'clojure.core) (symbol "eval")) |
| 14:52 | sexpbot | ⟹ #'clojure.core/eval |
| 14:53 | Raynes | I can understand how clojurebot can care a little less about how secure it is since it's sandbox is just a homemade sandbox designed especially for clojurebot. However, I have to make sure that clojail is as safe as imaginably possible by default, since I'm not the only one using it. |
| 14:53 | mjg123 | jarpiain: yes |
| 14:53 | mjg123 | nice one |
| 14:53 | chouser | Raynes: .getMapping .getMappings .intern |
| 14:54 | amalloy | &(class (the-ns 'clojure.core)) |
| 14:54 | sexpbot | ⟹ clojure.lang.Namespace |
| 14:54 | amalloy | Raynes: disallow use of clojure.lang.Namespace's interop methods |
| 14:54 | amalloy | is a better approach than chouser's suggestion |
| 14:54 | Raynes | amalloy: I'd have to disallow clojure.lang.Namespace |
| 14:54 | Raynes | What are the consequences of that? |
| 14:55 | amalloy | nothing i can think of, since you're only intercepting .foo interop calls, right? |
| 14:56 | Raynes | Blacklisting the class will mean that nothing can be called on a namespace object. |
| 14:56 | Raynes | If I remember correctly, I can still blacklist individual methods on a class if that's a problem. |
| 14:56 | Raynes | Just more tedious. |
| 14:57 | chouser | is this blacklisting via JVM sandbox or via s-expr analysis? |
| 14:57 | amalloy | Raynes: clojure functions could still be called on it, iirc |
| 14:57 | clojurebot | sandbox is http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html |
| 14:57 | amalloy | chouser: sexp |
| 14:58 | amalloy | i'd prefer jvm, but Raynes assures me that's hard, and he's the one doing it |
| 14:58 | Raynes | I know essentially nothing about the JVM sandbox. I'm mostly following along with the other sandboxes at this point. |
| 15:00 | chouser | &((clojure.lang.Reflector/invokeInstanceMethod (the-ns 'clojure.core) "intern" (to-array [(symbol "eval")])) '(+ 1 2)) |
| 15:00 | sexpbot | ⟹ 3 |
| 15:01 | chouser | sandboxes are hard |
| 15:01 | Raynes | That one is an actual bug, since I nixed the Reflector class. |
| 15:01 | amalloy | Raynes: (foo/bar) instead of (.bar foo) |
| 15:02 | Raynes | It gets expanded. |
| 15:02 | amalloy | &(macroexpand '(Integer/parseInt "1")) |
| 15:02 | sexpbot | ⟹ (let* [obj-class__3987__auto__ (clojure.core/class Integer)] (clojure.core/if-not (clojure.core/some (if (clojure.core/map? clojail.core/tester) (clojure.core/let [{:keys [blacklist__3988__auto__ whitelist__3989__auto__]} clojail.core/tester] (clojure.core/fn [target... http://gist.github.com/714298 |
| 15:02 | Raynes | It's probably a bug in dot. |
| 15:04 | LauJensen | ohpauleez: thanks :) |
| 15:04 | amalloy | yeah, that is weird |
| 15:04 | amalloy | Raynes: have you thought of giving sexpbot a github account so his gists aren't anonymous? |
| 15:04 | Raynes | Nope. |
| 15:05 | LauJensen | amalloy: great idea though |
| 15:05 | Raynes | It looks like I'm only checking symbols in dot here. How odd. |
| 15:05 | ohpauleez | I half thought about doing that before too |
| 15:05 | ohpauleez | or plugging solr into sexpbot |
| 15:06 | ohpauleez | so you could use him to search all previously seen solutions |
| 15:09 | amalloy | Raynes: is it because in (. Reflector invokeBlah), the target (Reflector) is a Class? |
| 15:11 | Raynes | amalloy_afk: That's probably it. |
| 15:11 | chouser | &(let [[m & a] [(the-ns 'clojure.core) (symbol "eval")] [cm & ca] (map class (cons m a))] ((.invoke (.getMethod cm "intern" (into-array ca)) m (to-array a)) '(+ 1 2))) |
| 15:11 | sexpbot | java.lang.SecurityException: You tripped the alarm! class java.lang.reflect.Method is bad! |
| 15:11 | Raynes | Yeah, at least it blocks that properly. |
| 15:12 | chouser | where's it getting that from? |
| 15:13 | chouser | ,(let [[m & a] [(the-ns 'clojure.core) (symbol "eval")] [cm & ca] (map class (cons m a))] ((.invoke (.getMethod cm "intern" (into-array ca)) m (to-array a)) '(+ 1 2))) |
| 15:13 | clojurebot | 3 |
| 15:13 | Raynes | chouser: Magics. |
| 15:16 | Chousuke | it looks like you need to replace eval with your own function :P |
| 15:21 | Lajla | Chousuke, was that addressed to me? |
| 15:21 | Lajla | Because they also won't let me def. |
| 15:21 | Lajla | But like, how does eval in clojure work. |
| 15:21 | Lajla | Is it just a clojure interpreter written in clojure? |
| 15:21 | Lajla | Like, how much is the penalty. |
| 15:22 | Lajla | How much faster is using (+ 1 2) stead of (eval '(+ 1 2)) ? |
| 15:22 | Chousuke | it's not an interpreter. |
| 15:22 | Chousuke | but it's slower, since it calls the compiler at runtime |
| 15:23 | serp__ | I have a sequence of integer tuples. how do I check if the sequence contains a certain tuple? contains? doesn't work |
| 15:23 | serp__ | ,(contains? [[0 0]] [0 0]) |
| 15:23 | serp__ | => false |
| 15:23 | clojurebot | false |
| 15:24 | Chousuke | ,(some #{[0 0]} [[0 0]]) ; this is the common idiom |
| 15:24 | clojurebot | [0 0] |
| 15:24 | Lajla | Chousuke, so it's a clojure compiler written in clojure? |
| 15:24 | Lajla | Or in Java? |
| 15:24 | Lajla | So like |
| 15:24 | Chousuke | Lajla: it's the same compiler that compiles everything else. |
| 15:24 | Lajla | An arbitrary clojure program has a clojure compiler included? |
| 15:24 | Lajla | So that compiler is included with any clojure executable? |
| 15:24 | Lajla | Also, it's an interpreter. |
| 15:24 | Lajla | People need to learn their terms. |
| 15:25 | Chousuke | no, it's not an interpreter |
| 15:25 | Lajla | A compiler is a translator from one source code to another. |
| 15:25 | Chousuke | it compiles to bytecode |
| 15:25 | Lajla | An interpreter runs a program |
| 15:25 | Lajla | Yes |
| 15:25 | Chousuke | and then that bytecode is run |
| 15:25 | Lajla | an interpreter can feature compilation internally. |
| 15:25 | Lajla | Sure |
| 15:25 | Lajla | So it's an interpreter. |
| 15:25 | Chousuke | whatever |
| 15:25 | Lajla | Any interpreter uses some form of transofmration internally. |
| 15:25 | Lajla | 'interpretation' just has a bad name. |
| 15:25 | Lajla | But a CPU is an interpreter formally. |
| 15:26 | Lajla | It's all too simple, an interpreter runs your program, by whatever means, a compiler translates your program into a program that does the same, but in another language. |
| 15:26 | Lajla | And almost any interpreter does feature some components inside that could be called compilers. |
| 15:27 | Chousuke | that's all completely irrelevant to the common usage of these words. |
| 15:28 | LauJensen | ,(do (time (dotimes [_ 1000] (+ 1 2))) (time (dotimes [_ 1000] (eval '(+ 1 2))))) |
| 15:28 | clojurebot | DENIED |
| 15:28 | LauJensen | &(do (time (dotimes [_ 1000] (+ 1 2))) (time (dotimes [_ 1000] (eval '(+ 1 2))))) |
| 15:28 | sexpbot | java.lang.SecurityException: You tripped the alarm! eval is bad! |
| 15:28 | LauJensen | oh right, they hate that :) |
| 15:28 | Lajla | Chousuke, what is the common usage then? |
| 15:28 | Lajla | The common usage has no meaning because it's not a formal technical term. |
| 15:28 | Lajla | It's as vague as things like 'tree', it has no place in scientific literature. |
| 15:28 | Lajla | Or 'bread' |
| 15:29 | Chousuke | I see no scientific literature here |
| 15:30 | chouser | Lajla: I can't comprehend your use of the informally defined terms "vague", "scientific", and "literature" |
| 15:30 | Lajla | Chousuke, well, this isn't scientific literature. |
| 15:30 | Lajla | But clojure's documentation ought to be. |
| 15:30 | Chousuke | ,(doc eval) |
| 15:30 | clojurebot | DENIED |
| 15:30 | Chousuke | ... duh |
| 15:31 | chouser | clojure's eval converts an s-expression to JVM bytecode using the one clojure compiler that is always used, and then passes it to the JVM to be run. |
| 15:31 | Chousuke | (doc eval) |
| 15:31 | clojurebot | DENIED |
| 15:31 | Lajla | And he's quite simply wrong when he says 'there is no risk of your code being interpreted', that is ludicrous. |
| 15:31 | Lajla | And I have some vague idea what he does mean with it. |
| 15:31 | Lajla | Emphasis on vague. |
| 15:31 | Lajla | But in the end, it's not a clear meaningful statement. |
| 15:31 | Lajla | The repl is an interpreter because it runs your code, by whatever means, some thing which outputs bytecode but doesn't run the process is a compiler. |
| 15:31 | Lajla | Sure |
| 15:31 | Lajla | but the repl returns that result. |
| 15:32 | Chousuke | this is all pointless. :P |
| 15:32 | Lajla | And by that, the whole stuff together is an interpeter, albeit one composed of multiple components, like any interpreter today. |
| 15:32 | Lajla | The JVM is an interpreter for one. |
| 15:32 | Lajla | As is a CPU. |
| 15:32 | Lajla | What he probably just means is 'stuff runs fast' |
| 15:33 | Chousuke | The problem is that that definition of interpreter is completely useless in an informal context. |
| 15:33 | Lajla | But really, any modern interpreter does some translation to a lower level and runs that translated code on some internal virtual machine for efficiency's sake. |
| 15:33 | Chousuke | everything is an interpreter, so why use the word at all? |
| 15:33 | Lajla | A compiler is not an interpreter. |
| 15:33 | Lajla | But the thing on which the compiler runs is. |
| 15:33 | Lajla | A compiler is a translator from one language to another. |
| 15:34 | Lajla | An interpeter is a, perhaps abstract, machine that runs a program specified in a language accordingly its definition to produce the I/O associated with it. |
| 15:34 | Chousuke | Lajla: except when you want to talk about implementation techniques for a language, there is a definition of "interpreter" that is more specific than yours. |
| 15:34 | Chousuke | Lajla: which is what is being used here. |
| 15:34 | Lajla | Chousuke, go on. |
| 15:34 | dnolen | Lajla: Joe Marshall has excellent perspective on the dichotomy of compilation/interpretation, came up on the Racket ML, http://www.mail-archive.com/users@racket-lang.org/msg02358.html |
| 15:36 | Lajla | dnolen, isn't that sort of what I said? |
| 15:37 | dnolen | Lajla: yes but perhaps not as clearly ;) |
| 15:37 | Lajla | Clarity has never been my strength. |
| 15:37 | Lajla | http://community.schemewiki.org/?interpreter I like this explanation though. |
| 15:37 | Lajla | Schemewiki is often quite excellent in making whole articles about terms and concluding at the end that the term is completely vague, useless, and should be avoided. |
| 15:38 | chouser | ugh |
| 15:43 | Lajla | chouser, you're dealing with the big boys babe. |
| 15:46 | Raynes | &((clojure.lang.Reflector/invokeInstanceMethod (the-ns 'clojure.core) "intern" (to-array [(symbol "eval")])) '(+ 1 2)) |
| 15:46 | sexpbot | java.lang.SecurityException: You tripped the alarm! the-ns is bad! |
| 15:46 | Raynes | &((clojure.lang.Reflector/invokeInstanceMethod ( 'clojure.core) "intern" (to-array [(symbol "eval")])) '(+ 1 2)) |
| 15:46 | sexpbot | java.lang.SecurityException: You tripped the alarm! class clojure.lang.Reflector is bad! |
| 15:46 | Raynes | chouser, amalloy_afk: I just forgot to check the actual class instead of just the class of the 'object', which in this case is a class. |
| 15:47 | Raynes | chouser: I really appreciate the breakage, by the way. I'd really hate for someone other than me using clojail to run into these sorts of silly problems. <3 |
| 15:52 | mrBliss` | LauJensen: are you gonna post your experiences with Awesome on that new blog? |
| 15:53 | Raynes | I'm waiting on him to blog about how he got compiz to tile. |
| 15:53 | LauJensen | mrBliss`: I might :) It was a request about that, which got me thinking about Tumblr |
| 15:54 | ohpauleez | I will write an equally long comment just reiterating the points |
| 15:54 | mrBliss` | LauJensen: I'm currently using StumpWM, the Emacs of windows manager. |
| 15:54 | Raynes | LauJensen: Why Tumblr versus your blog? |
| 15:54 | LauJensen | mrBliss`: Yea I was going to try tht myself but ran into installation problems |
| 15:54 | ohpauleez | tmux on OSX Term, Awesome running on one of my spaces on OSX, and Awesome on my Linux box |
| 15:54 | mrBliss` | LauJensen: did you try SBCL or Clisp? |
| 15:54 | LauJensen | Raynes: My blog is for in-depth lengthy Clojure posts, Tumblr is for everything else |
| 15:54 | Raynes | Sounds good. |
| 15:54 | LauJensen | mrBliss`: Ive done SBCL but not for WM |
| 15:55 | gfrlog | is there a recognized clojure style guide? |
| 15:55 | LauJensen | gfrlog: http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards |
| 15:56 | gfrlog | awesome, thanks |
| 15:57 | LauJensen | np |
| 15:59 | mrBliss | I didn't realize you could write map, filter, every?, take-while, group-by, cycle... using reduce or Haskell's foldl/foldr |
| 15:59 | Raynes | mrBliss: It's beautiful, isn't it? |
| 15:59 | mrBliss | Raynes: exactly |
| 16:00 | mrBliss | even more concise than the beauty of cons/car/cdr |
| 16:00 | chouser | can you write clojure's map with clojure's reduce? |
| 16:01 | chouser | I don't think so |
| 16:01 | mrBliss | chouser: I just wrote the 'mapcar' version with only one collection |
| 16:01 | chouser | lazy? |
| 16:01 | clojurebot | lazy is hard |
| 16:02 | Raynes | chouser: That's not fair. |
| 16:02 | Raynes | chouser: You can write Haskell's version though. It wont be lazy in Clojure, but it would be in Haskell because Haskell is lazy. |
| 16:02 | mrBliss | (letfn [(mapf [f xs] (reduce (fn [mapped x] (conj mapped (f x))) [] xs))] (mapf inc '(1 2 3))) |
| 16:03 | amalloy | mrBliss: i thought it was pretty neat when i realized (comp) is a special case of (reduce) |
| 16:03 | mrBliss | ,(letfn [(mapf [f xs] (reduce (fn [mapped x] (conj mapped (f x))) [] xs))] (mapf inc '(1 2 3))) |
| 16:03 | clojurebot | [2 3 4] |
| 16:04 | mrBliss | amalloy: it's almost like a fold-calculus (<-> lambda-calculus) |
| 16:06 | amalloy | &((reduce (fn [f1 f2] (fn [& args] (f1 (apply f2 args)))) [inc inc inc]) 1) |
| 16:06 | sexpbot | ⟹ 4 |
| 16:07 | amalloy | mrBliss: ^^ shiny? |
| 16:07 | mrBliss | amalloy: nice |
| 16:40 | jsanda | what's the best way to dynamically access a function in another namespace? i have a function that takes as an arg the name of another function to invoke and that function will be in a different namespace |
| 16:41 | amalloy | &(doc ns-resolve) |
| 16:41 | sexpbot | java.lang.SecurityException: You tripped the alarm! ns-resolve is bad! |
| 16:41 | amalloy | (doc ns-resolve) |
| 16:41 | clojurebot | "([ns sym]); Returns the var or Class to which a symbol will be resolved in the namespace, else nil. Note that if the symbol is fully qualified, the var/Class to which it resolves need not be present in the namespace." |
| 16:41 | amalloy | jsanda: ^^ |
| 16:42 | jsanda | thx |
| 16:42 | Raynes | ,*ns* |
| 16:42 | clojurebot | #<Namespace sandbox> |
| 16:42 | chouser | jsanda: have you considered passing the function itself or its var instead of its name? |
| 16:42 | jsanda | i won't be able to |
| 16:43 | jsanda | actually what will get passed is the name space with functions to invoke |
| 16:45 | jkndrkn | hi there. has anyone recently experienced lein deps issues related to the clojure-contrib jar? |
| 16:45 | jkndrkn | specifically: |
| 16:45 | jkndrkn | Caused by: org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException: Missing: |
| 16:45 | jkndrkn | ---------- |
| 16:45 | jkndrkn | 1) org.clojure:clojure-contrib:jar:1.2.0-SNAPSHOT |
| 16:45 | jkndrkn | Path to dependency: |
| 16:45 | jkndrkn | 1) org.apache.maven:super-pom:jar:2.0 |
| 16:45 | jkndrkn | 2) org.clojars.leadtune:orolo:jar:0.1 |
| 16:45 | jkndrkn | 3) org.clojure:clojure-contrib:jar:1.2.0-SNAPSHOT |
| 16:46 | jkndrkn | we are currently requiring clojure-contrib as follows: |
| 16:46 | jkndrkn | ... |
| 16:46 | jkndrkn | :dependencies [[org.clojure/clojure "1.2.0"] |
| 16:46 | jkndrkn | [org.clojure/clojure-contrib "1.2.0"] |
| 16:46 | jkndrkn | ... |
| 16:46 | jsanda | chouser: basicallym at start up my function is called with the name of another name space that defines some functions that i want to call |
| 16:47 | jkndrkn | my apologies ^_^; |
| 16:47 | Raynes | jkndrkn: That looks like a problem with one of your other dependencies. |
| 16:47 | Raynes | It looks like one of your other dependencies is trying to find something that doesn't exist. |
| 16:48 | jsanda | so i want to load that name space and then call functions within it. and i am making an assumption that functions with specific names/signatures exist |
| 16:49 | Raynes | https://github.com/leadtune/orolo/blob/master/project.clj this one. |
| 16:49 | Raynes | You might be able to exclude it's version of clojure-contrib, since you have your own. |
| 16:50 | Raynes | I do not remember the syntax for doing so, however. |
| 16:50 | Raynes | jkndrkn: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L38 |
| 16:51 | jkndrkn | cool, thanks for clearing that up! |
| 16:51 | Raynes | I don't know if that will work for sure, but it's worth a try. |
| 16:51 | Raynes | Never had to do it before. |
| 16:56 | LauJensen | If somebody here has a Flattr account and can help me test something please msg me |
| 17:57 | lpetit | Did I already publicly say that cemerick did a splendid work for ccw lately ? Maybe not, so now's the time. Expect a new version of ccw soon, with the brand new REPL UI which is a for-mi-da-ble addition to CCW ! And it already integrates well with the work done on the editor the previous months (paredit, jump to definition) and I'm working on adding the missing pieces (code completion, more... |
| 17:57 | lpetit | ...paredit commands) |
| 17:58 | lpetit | cu soon ! |
| 17:58 | chouser | very cool! |
| 17:58 | lpetit | And again, because he deserves it: long live to cemerick ! |
| 18:47 | ossareh | what is CCW? |
| 18:47 | ossareh | ah, http://code.google.com/p/counterclockwise/ |
| 18:47 | amalloy | clojurebot: ccw? |
| 18:47 | clojurebot | ccw is http://github.com/laurentpetit/ccw |
| 18:53 | zakwilson | Guy L. Steele says you should learn Clojure. |
| 18:56 | mengu_ | he is damn right |
| 19:02 | zakwilson | He also suggests Haskell. |
| 19:04 | jweiss_ | anyone tried to use labrepl recently? running lein deps fails for me - org.apache.maven:super-pom:jar:2.0 artifact is missing |
| 19:05 | jweiss_ | oh wait, it seems to really be complaining that it can't find org.clojure:clojure-contrib:jar:1.1.0-master-SNAPSHOT |
| 19:05 | jweiss_ | i can't figure out why it's trying to get that old version, it's not in the project.clj |
| 19:11 | jweiss_ | looks like autodoc 0.7.0 depends on it |
| 19:31 | jkndrkn | Raynes: thanks for your help earlier. exclusions were of great help here. looks like a bunch of old SNAPSHOT versions of clojure and clojure-contrib are no longer offered up for download via lein deps. |
| 20:19 | amalloy | silly question here: (< x y) always confuses me - it reads like "less than x? y". does anyone have a useful mnemonic so i'll stop writing all my comparisons backwards? |
| 20:21 | _ato | amalloy: some people think of < as "ascending?" |
| 20:26 | _mst | amalloy: I just got into the habit of switching to infix in my head, I have to admit :) Read the first argument first, then the comparator, then the second argument for "x is less than y" |
| 20:46 | Lajla | amalloy, this is why you should keep English out of code I guess. |
| 20:47 | Lajla | Read it as it is, five tokens (, <, x, y, and ) |
| 21:23 | Derander | it's not really x < y though, is it? it's "is this monotonically increasing?" |
| 21:24 | Derander | that's how I remember, at least |
| 21:24 | Derander | it's like a crescendo symbol |
| 21:36 | amalloy | Derander: yeah i know. but it could as easily be "is this monotonically decreasing". what's this crescendo symbol? |
| 21:36 | Derander | music |
| 21:36 | Derander | < says "get louder" |
| 21:37 | Derander | amalloy: http://www.scenicnewengland.net/guitar/notate/images/cres.gif |
| 21:37 | Derander | if you look at it like the music symbol it can only be increasing |
| 21:38 | amalloy | Derander: hm |
| 21:41 | Lajla | Derander, yap. |
| 21:41 | Lajla | But. |
| 21:42 | Lajla | Isn't x < y that also. |
| 21:42 | Lajla | But for only two arguments? |
| 21:42 | Derander | I guess |
| 21:42 | Lajla | Infix notation is stupid anyway. |
| 21:42 | Lajla | It's like the imperial system. |
| 21:42 | Derander | :P |
| 21:42 | Lajla | Completely arbitrary, stupid, overly complicated. |
| 21:42 | Lajla | The only reason people still use it is because they are used for it. |
| 21:42 | Lajla | Like how the US and UK still haven't switched to metric. |
| 21:42 | Lajla | Even though it's much simpler and self-evident how it works. |
| 21:42 | Derander | well, it limits ambiguity in handwriting |
| 21:43 | Lajla | Nahhh |
| 21:43 | Lajla | I mean |
| 21:43 | Derander | + 2 2 2.. is that 6 or 22 + 2? |
| 21:43 | Lajla | if handwriting used praefix only. |
| 21:43 | Lajla | Then handwriting would adapt. |
| 21:43 | Lajla | I mean |
| 21:43 | Lajla | handwriting of mathematicans generally destinguishes × and x. |
| 21:43 | Lajla | And those of non-mathematicians often doesn't. |
| 21:43 | Lajla | People adapt automatically to these situations |
| 21:43 | Derander | hahahahahaha. my handwriting is just terrible everywhere |
| 21:44 | Derander | I've lost a lot of credit in my higher math classes because of the inability to distinguish "s" and "5" in my writing |
| 21:46 | amalloy | Derander: i eventually learned to write my t with a tail, cause otherwise it looked exactly like my + :P |
| 21:46 | Derander | yes! |
| 21:46 | Derander | I do that and my 7 with a cross |
| 21:46 | Derander | but 5 and s are just doomed |
| 21:47 | amalloy | what does 7 without a cross look like? |
| 21:47 | Derander | I'm talking about the cross in the middle |
| 21:47 | Derander | there are 2 horizontal lines in my 7 |
| 21:47 | amalloy | oh i see |
| 21:47 | amalloy | er, no idon't |
| 21:47 | amalloy | what did it look like before you put the cross in it |
| 21:47 | Derander | 7 |
| 21:48 | amalloy | argh |
| 21:48 | Derander | hahaha |
| 21:48 | amalloy | ie, what was the problem you solved by putting a cross in |
| 21:48 | Derander | http://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Hand_written_7.png/50px-Hand_written_7.png |
| 21:48 | Derander | oh |
| 21:48 | Derander | it looks like a 1 |
| 21:48 | Derander | or a t |
| 21:48 | Derander | depending on how sloppy I was |
| 21:49 | Derander | yeah |
| 21:49 | Derander | I think I just suck at handwriting :-) |
| 23:22 | technomancy | Licenser: ping |
| 23:23 | Raynes | Good luck with that. |
| 23:23 | Raynes | He is here about as often as Martin Odersky is around in #scala. |
| 23:24 | technomancy | bummer |
| 23:24 | Raynes | Poor guy. He has a needy girlfriend. |
| 23:24 | technomancy | ruh roh |
| 23:25 | technomancy | he's my only solaris tester. |
| 23:26 | Raynes | What are you needing to test? Leiningen? |
| 23:26 | technomancy | yeah. |
| 23:26 | Raynes | I have ssh access to his solaris server, if it helps. |
| 23:27 | technomancy | it's a minor thing; wanted to confirm my latest commit doesn't break jline for situations when rlwrap is not installed. |
| 23:28 | Raynes | technomancy: I'll try it out in a few. |
| 23:28 | technomancy | cool; thanks |
| 23:28 | technomancy | and here I thought Licenser was the only person on IRC who touched Solaris |
| 23:29 | Lajla | Programming and girlfriends to together like jewishness and no large megacorp in your position. |
| 23:29 | Lajla | posession |
| 23:29 | Raynes | technomancy: He really is. However, he hosts try-clojure.org, so I have to have ssh access to maintain that. I also used to run sexpbot on there before I decided to use mongo, which apparently doesn't work on solaris. |
| 23:30 | amalloy | Lajla: possession |
| 23:30 | technomancy | heh; that explains it |
| 23:30 | Lajla | I never claimed I could English with the best of them. =( |
| 23:30 | Lajla | amalloy, let's worship His Shadow together. |
| 23:31 | Lajla | You and I. |
| 23:49 | Raynes | technomancy: It can't find it's dependencies. I did lein deps in the clone with the main version of leiningen than symlinked bin/lein to ~/bin/lein-n |
| 23:49 | Raynes | Is there a magical step in between that I missed? |
| 23:49 | Raynes | then* |
| 23:51 | technomancy | strange... but bin/lein self-install should do the trick, I think. |
| 23:51 | Lajla | Bin Leiden |
| 23:52 | Raynes | technomancy: That seems to have done the trick. |
| 23:52 | technomancy | jline comes through OK? |
| 23:53 | Raynes | Checking. |
| 23:53 | Raynes | Seems to be working. |
| 23:53 | Raynes | And rlwrap isn't installed. |
| 23:53 | technomancy | excellent; thanks |
| 23:53 | Raynes | Any time. |
| 23:54 | technomancy | so I realized that class lists in :import should be wrapped in () instead of [] |
| 23:54 | technomancy | I've been doing it wrong for years. |
| 23:54 | technomancy | (for indentation purposes) |
| 23:55 | Raynes | Seriously? I'm not sure I want to be right. :< |
| 23:55 | technomancy | http://p.hagelb.org/import-indent.html |
| 23:56 | technomancy | since [] implies entries are peers, while () implies the first entry is special and the rest should be indented together |
| 23:56 | technomancy | [] is still correct for :use :only |
| 23:57 | Raynes | Good. Not sure I could give up this gorgeous ns declaration: https://github.com/Raynes/sexpbot/blob/protocols/src/sexpbot/twitter.clj#L4 |