2011-05-12
| 00:05 | sorenmacbeth | anyone? bueller? |
| 00:11 | intlkleinblue | exit |
| 00:31 | scgilardi | sorenmacbeth: what did you try? could be done with loop/cond/recur |
| 00:42 | sorenmacbeth | I got it done with reduce |
| 00:57 | tomoj | oh, of course filter isn't variadic |
| 00:57 | tomoj | sorry, whoever I told that |
| 00:59 | sorenmacbeth | nope, I take it back, reduce doesn't quite do what I want |
| 01:00 | sorenmacbeth | scgilardi: I'll look into loop/cond/recur |
| 01:00 | tomoj | &(->> ["7" "7 elements" "7 elements landing" "7 elements landing page" "add"] (partition 2 1 nil) (remove (fn [[a b]] (and b (.contains b a)))) (map first)) |
| 01:00 | sexpbot | ⟹ ("7 elements landing page" "add") |
| 01:00 | nick001 | hi, what is the preferred website used here to show code snippits in? (its been a while) |
| 01:00 | tomoj | wonder if this just happens to work in that case |
| 01:02 | tomoj | nick001: gist is popular, and it's got clojure highlighting. preferred? dunno |
| 01:03 | nick001 | thanks! |
| 01:06 | hippiehunter | why are long and double the only primative type hints supported? |
| 01:11 | markoman | I have a nested vector or sequence produced by recursive function and Id like to flatten it by certain criteria |
| 01:11 | dnolen | hippiehunter: exponential number of interfaces to support, 4 args (Object, long, double) and return (Object, long, double) is 300+ Java interfaces. interfaces used to get the fastest perf of the JVM. |
| 01:12 | sorenmacbeth | tomoj: thank you! that's works |
| 01:13 | markoman | [[['a 'b]['b 'c]]['a]] should become [['a 'b]['b 'c]['a]] |
| 01:14 | tomoj | is it a 1.3 thing that only long/double are supported? |
| 01:14 | hippiehunter | it doesnt mean anything pre 1.3 |
| 01:15 | markoman | levels of nests can be deeper too, but result should always be a vector containing vector of items. with flatten I always get only one level |
| 01:15 | dnolen | tomoj: yes. |
| 01:16 | tomoj | oh, I saw ^floats and was confused, but that's different |
| 01:16 | dnolen | hippiehunter: 1.2 doesn't have much in the way of good primitive arithmetic support. |
| 01:16 | dnolen | in 1.3 primitives can flow freely without ever getting boxed. |
| 01:16 | markoman | could I surround the final level of vector with something, that it keeps the "shape" ?Im thinking something like : [[{['a 'b]}{['b 'c]}]{['a]}] |
| 01:17 | hippiehunter | dnolen: does that include things like map, filter, etc |
| 01:18 | dnolen | hippiehunter: that's forward looking but yes, part of the reason for the changes were wanting to allow higher order usage that can operate efficiently on collections of primitives. |
| 01:19 | dnolen | hippiehunter: primitives can flow, and we have vectors that can hold primitives, but some more stuff to sort before we get there. |
| 01:24 | markoman | im thinking something like: (for [x (flatten [[{:set ['a 'b]}{:set ['b 'c]}]{:set ['a]}])] (:set x)) |
| 01:55 | tomoj | markoman: are you flattening it just to get the answer or do you use the nested version for something? |
| 01:55 | tomoj | just curious, maybe you can produce it flattened in the first place |
| 01:55 | amalloy | (inc tomoj) |
| 01:55 | sexpbot | ⟹ 1 |
| 01:55 | amalloy | that is very often the better way |
| 01:59 | markoman | I need to use recursive function to get data but I also need to preserve last shape of vectors |
| 02:00 | markoman | last shape means any of these [1 2] [1] [1 2 3] ... |
| 02:00 | amalloy | markoman: so? make the recursive function return a seq of the meaningful seqs |
| 02:01 | amalloy | when it recursively calls itself it can splice them in rather than re-nesting |
| 02:03 | markoman | hmh... I have a for structure inside recursive function too. combination of these makes I cant get flatten to work as I want |
| 02:03 | amalloy | &(letfn [(thing [n] (condp = n, 0 '(base), 1 (into '((item1)) (thing 0)), 2 (mapcat thing [1 0])))] (thing 2)) |
| 02:03 | sexpbot | ⟹ (base (item1) base) |
| 02:03 | amalloy | &(letfn [(thing [n] (condp = n, 0 '((base)), 1 (into '((item1)) (thing 0)), 2 (mapcat thing [1 0])))] (thing 2)) |
| 02:03 | sexpbot | ⟹ ((base) (item1) (base)) |
| 02:04 | amalloy | turn the for into a mapcat, or (apply concat (for...)), and you can |
| 02:11 | markoman | hmh, thats new to me, it might work here |
| 02:55 | raek | ah, the silence! |
| 02:59 | amalloy | raek: you can just block nujkcom |
| 02:59 | amalloy | i blocked him when someone (stuart s?) mentioned he was clogging the clojure feed, though i don't actually follow #clojure |
| 03:09 | raek | last time I tried I got the impression that a block hides tweets directed to you but not that person's tweets from searches |
| 03:11 | TheBusby | amalloy: After implementing what we discussed, and porting the loading parsing to JNI, I finally figured out where all the memory was going... |
| 03:11 | amalloy | raek: you could be right |
| 03:12 | TheBusby | amalloy: I was dealing with roughly 125M strings, and evidently Java has a massive overhead dealing with String (38B + 2B per char). |
| 03:14 | TheBusby | my input file was utf-8 (primarily single byte characters), so just storing the data as a string doubled the size (1GB to 2GB), and with the overhead of storing each field you're looking at another 4.4GB of memory consumption |
| 03:14 | no_mind | Is there a way to execute more than one expression inside an if clause ? |
| 03:15 | TheBusby | use "do"? |
| 03:18 | amalloy | yah, (do a b c) is what you want. or you can use (when test a b c) if you don't need an else clause |
| 03:20 | Derander | my desk is literally covered in paper |
| 03:20 | Derander | this is wonderful |
| 03:20 | cais2002 | hello guys |
| 03:23 | cais2002 | wrt java interop, how do I deal with generic type? e.g., a java method with a signature methodA(List<String> p1) , how do I invoke it from Clojure? |
| 03:44 | amalloy | cais2002: generics are a figment of javac's imagination. pass them objects, you'll be fine |
| 03:44 | amalloy | ie, (.methodA whateverTarget ["string1" "string2"]) will work |
| 03:44 | roamer01 | hi, i am trying to get a library to run, this one "enlive", i am fairly new, example on https://github.com/cgrand/enlive/wiki/getting-started , i installed enlive using leiningen, (also ran lein deps) however, when i try to run : user=> (ns x (:use net.cgrand.enlive-html)) i get could not locate init class, the lib dir is on my path, and the enlive jar is also there |
| 03:46 | zmila | how to check if input is sequence or not? |
| 03:46 | zmila | ;(seq? []) |
| 03:47 | cais2002 | amalloy, thanks.. got the method name wrong while testing it.. :| |
| 03:47 | amalloy | zmila: (sequential? x) is usually good enough, with some caveats |
| 03:48 | zmila | thanks, amalloy! |
| 03:48 | cais2002 | what's the best way to inspect an object to discover what methods are available? I sometimes got "No matching method" exception or "No matching ctor found for class" but have no clue what goes wrong.. |
| 03:50 | amalloy | cais2002: (use '[clojure.contrib.repl-utils :only [show]]) (show foo) |
| 03:53 | zmila | if this is java object, then you may call (bean object) - it returns map |
| 03:57 | thorwil | roamer01: the ns form is for files, on the repl one usually uses require or use directly. (use 'net.cgrand.enlive-html) or (require '[net.cgrand.enlive-html :as en]) |
| 03:58 | cais2002 | show works well |
| 04:17 | neotyk | Good morning everyone! |
| 04:27 | markoman | Good noon :) |
| 04:29 | clgv | $source pcalls |
| 04:29 | sexpbot | pcalls is http://is.gd/JyjUUT |
| 05:02 | raek | rowth: how did you start clojure? lein repl? |
| 05:03 | raek | oh, sorry. wrong person |
| 05:03 | raek | oh, roamer01 left |
| 06:30 | no_mind | I have a function in another file and I am loading that file with load-file . I want to know if there is a way to check if the namespace/file has been previously loaded and avoid loading the file everytime the function is called ? |
| 06:38 | fliebel | Is there a clean way to do select-keys on a vector? |
| 06:39 | fliebel | no_mind: find-ns ? |
| 07:05 | mduerksen | fliebel: select-keys does work on vectors, but it probably doesn't have the result you'd expect. (select-keys [1 3 5] [1 2]) => {2 5, 1 3}, rather than [3 5] |
| 07:07 | fliebel | mduerksen: I know, so I had (vals (select-keys)) but then it gets out of order. so (vals (into (sorted-map) (select-keys))) would work, but who wants that? |
| 07:12 | mduerksen | fliebel: true. if your vector is short, you could just use destructuring with some _ for the indeces you dont need. but when your vector is longer than 4 or so, it would be ugly and not very readable since you'd have to count to find out which indeces your actually selecting |
| 07:13 | fliebel | With assoc, you can do multiple associations in one, I wonder why get doesn't do that. |
| 07:16 | mduerksen | you could do this: ((juxt #(get % 1) #(get % 2)) [1 3 5]). in combination with apply, you could create a fn multiple-get that does that |
| 07:16 | fliebel | $source assoc |
| 07:16 | sexpbot | assoc is http://is.gd/hulXLR |
| 07:17 | fliebel | So basically just some recursive version of get would work. Only the default argument would need to leave. |
| 07:18 | fliebel | (map (partial get m) [1 2 3]) would work as well. |
| 07:19 | mduerksen | ((apply juxt (map (fn [idx] (fn [v] (get v idx))) [1 2])) [1 3 5]) |
| 07:20 | mduerksen | i think your is simpler and does the job |
| 07:21 | mduerksen | *yours |
| 07:28 | raek | ,(let [v [1 3 5]]] (map v [1 2])) |
| 07:28 | clojurebot | Unmatched delimiter: ] |
| 07:28 | raek | ,(let [v [1 3 5]] (map v [1 2])) |
| 07:28 | clojurebot | (3 5) |
| 07:28 | fliebel | true :) I forgot vector is ifn also. |
| 07:29 | fliebel | s/(partial get m)/m/g |
| 07:41 | raek | $findfn [1 3 5] [1 2] [3 5] |
| 07:41 | sexpbot | [clojure.core/map clojure.core/replace clojure.core/pmap clojure.core/keep] |
| 07:42 | raek | wait what? replace? |
| 07:42 | raek | hrm |
| 07:42 | raek | ,(replace [1 3 5] [1 2]) |
| 07:42 | clojurebot | [3 5] |
| 07:42 | raek | ,(replace {0 1, 1 3, 2 5} [1 2]) |
| 07:42 | clojurebot | [3 5] |
| 07:43 | Chousuke | heh |
| 08:07 | mec | anyone gotten durendal to work with clojurebox? |
| 09:18 | saml | hey, do you like OSGi? |
| 09:18 | saml | does clojre need osgi? |
| 09:20 | joly | I'm playing with core.logic and an example that's similar in form to the zebra puzzle. Is there something like not-membero so I can say something like (not-membero ['spaniard _ _ 'snails _] hs) ? |
| 09:20 | joly | should be two separate underlines instead of one long one... |
| 09:21 | chouser | saml: clojure does not require OSGi. There have been various attempts to make clojure work with OSGi, and I'm not sure what state any of those efforts are in. |
| 09:21 | saml | i don't even know what OSGi tries to solve |
| 09:21 | saml | it looks like java complication |
| 09:21 | cemerick | odd to ask about it then ;-) |
| 09:22 | saml | i mean.. but i might be just stupid. do you have use cases for OSGi? |
| 09:23 | cemerick | module systems like osgi make it possible to update/modify long-running systems built with static components. |
| 09:23 | technomancy | osgi is one of those things like dependency injection where you can read words that describe it without having those words convey any particular impression of meaning to your mind. |
| 09:24 | cemerick | Very little to do with Clojure, or Clojure-idiomatic practice. |
| 09:26 | saml | osgi is trouble. hot swapping means bugs won't be apparent during deployment |
| 09:27 | saml | you deploy bundle Foo.. until you deploy bundle Bar, bugs won't appear |
| 09:27 | cemerick | It doesn't really work like that. |
| 09:27 | cemerick | But, I don't really want to talk about osgi, either. :-P |
| 09:28 | saml | no.. that's how i experienced it. deployed foo.jar to staging. worked fine. pushed foo.jar to production. works fine.. now someone deploys bar.jar.. it breaks |
| 09:28 | saml | there's no dependency.. just they both exports same package :P |
| 09:29 | Fossi | pfft, dependency injection... i like "inversion of control" better. at first you have control, then... |
| 09:34 | technomancy | add-classpath is the only dependency injection I need, amirite? |
| 11:40 | malkomalko | I see (clojure.string/replace) but when I try to access it from the repl it's not able to find that namespace.. I'm on 1.2.0, am I doing something wrong? |
| 11:42 | mec | malkomalko: did you (require 'clojure.string)? |
| 11:43 | malkomalko | thought so, I think I required something wrong |
| 11:43 | malkomalko | *face palm* |
| 11:43 | malkomalko | :) |
| 11:43 | manutter | malkomalko: what was it? |
| 11:44 | malkomalko | I wasn't calling the required ns properly |
| 11:44 | malkomalko | and I wasn't reading things correctly and was getting back the wrong version of replace |
| 11:54 | ilyak | hi * |
| 11:55 | ilyak | Is there some kind of wrapper over proxy to proxy one-method, one-class, empty-constructor classes or interfaces? |
| 11:56 | ilyak | something along the lines (proxy [Work] [] (execute [conn] (use-conn conn))) -> (proxy-one Work execute [conn] (use-conn conn)) |
| 11:56 | ilyak | I understand that I can probably write that myself as a macro |
| 11:59 | mec | if its an interface you can (reify Work (execute [conn] (use-conn conn))) but theres nothing specifically for what you're asking |
| 12:07 | amalloy | ilyak: no, i don't think there is. you could write the macro yourself, but it saves you about five characters and doesn't really add any readability |
| 12:23 | amalloy | fliebel: ##((juxt 0 2) [:a :b :c]) or ##(map [:a :b :c] [0 2]) should both work |
| 12:23 | sexpbot | ((juxt 0 2) [:a :b :c]) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn |
| 12:23 | sexpbot | (map [:a :b :c] [0 2]) ⟹ (:a :c) |
| 12:23 | amalloy | oh, except the first one :P |
| 12:26 | manutter | That's weird, I didn't know you could use map like that |
| 12:26 | manutter | or maybe I didn't know you could use vectors like that |
| 12:28 | amalloy | manutter: probably vectors |
| 12:29 | amalloy | &([:a :b :c] 2]) |
| 12:29 | sexpbot | java.lang.Exception: Unmatched delimiter: ] |
| 12:29 | amalloy | &([:a :b :c] 2) |
| 12:29 | sexpbot | ⟹ :c |
| 12:31 | Kototama | how can i read a clojure file and have its content represented in a sequence (as a tree) ? |
| 12:33 | amalloy | (read-string (slurp file)) if it's just one data structure |
| 12:34 | Kototama | it's not, i would like to read a whole program |
| 12:35 | amalloy | &(with-in-str "(def a 1) (inc a)" (doall (take-while (complement #{::done}) (repeatedly #(read *in* false ::done))))) |
| 12:35 | sexpbot | ⟹ ((def a 1) (inc a)) |
| 12:35 | amalloy | Kototama: that is the general idea |
| 12:36 | amalloy | you can use with-open and a reader on the file instead of with-in-str if you don't want the whole thing in memory at once, but it's probably not worth the effort |
| 12:37 | Kototama | https://github.com/xebia/clj-metrics/blob/master/src/clj_metrics/core.clj#L24 is maybe the correct tricks |
| 12:38 | amalloy | sure, that looks easier, i suppose. i think you should probably *understand* how to use the reader for more sophisticated things, even if "tricking" it with some extra parens is the solution that's easier |
| 12:41 | Kototama | yes you're right, i didn't see that posted code actually, thanks for that |
| 12:50 | mec | (read-string (str "[" (slurp file) "]")) ;p |
| 12:50 | technomancy | (take-while #(not= % ::done) (repeatedly #(read rdr false ::done))) |
| 12:50 | mec | oh, which is exactly whats in the file |
| 12:55 | amalloy | technomancy: isn't that just what i did? |
| 12:56 | amalloy | (though i like (complement #{::done}), even if it is like twice as long) |
| 12:56 | technomancy | amalloy: yeah... I only read like 5 lines of back-chat. |
| 12:56 | technomancy | heh |
| 12:57 | Kototama | and how can I know if something is an 'atom' (in the common lisp sense) ? |
| 12:58 | amalloy | (complement coll?) is close |
| 12:58 | amalloy | but since clojure doesn't really have the atom-vs-list dichotomy it's not a perfect mapping |
| 12:59 | ilyak | Is there a page with simple macro examples somewhere? |
| 13:01 | mec | ilyak: http://java.ociweb.com/mark/clojure/article.html#Macros or http://en.wikibooks.org/wiki/Learning_Clojure/Macros have some simple ones |
| 13:04 | no_mind | I am building a module based application where each module has its on namespace. I have 2 questions 1) Is this correct approach to keep every module in a separate namespace or there are other approaches ? 2) I want each module to register a function for receiving events. How do I make modules register for events at the start of application ? |
| 13:06 | technomancy | no_mind: for #2 you would either have to list them in a config file or search the classpath and keep it in namespace metadata |
| 13:06 | technomancy | I strongly favour the latter approach |
| 13:07 | amalloy | for contrast, sexpbot searches the classpath but doesn't use namespace meta; it just looks for a function called load-this-plugin or something |
| 13:08 | technomancy | yeah, actually there is a bug in the clojure compiler where ns metadata is lost when you AOT compile, so probably a def in the ns would be better |
| 13:08 | no_mind | technomancy: I cant understand the first part, searching the classpath |
| 13:08 | technomancy | no_mind: relevant: https://github.com/technomancy/slamhound/blob/master/src/slam/hound/regrow.clj#L93 |
| 13:11 | technomancy | something like this would work once you've pre-loaded everything on the classpath: (doseq [n (all-ns) :when (ns-resolve n 'receiver)] (register (ns-resolve n 'receiver))) |
| 13:13 | amalloy | technomancy: use a :let before the :when to avoid duplicated code? |
| 13:20 | technomancy | yeah |
| 14:16 | technomancy | has anyone used the junit output adapter for clojure.test for hudson/jenkins reporting? |
| 14:17 | S11001001 | technomancy: our team has, specifically, the test-out lein plugin |
| 14:18 | technomancy | S11001001: so you can get more detailed failure stats over time? that sounds handy. |
| 14:23 | technomancy | I wonder if test-out could be made to work with test-selectors. hopefully it can be made more composable. |
| 14:30 | shortlord | clojure and lisp in general are oviously very close to a raw syntax tree. it's trivial for (+ 1 2) wich is the node + with 1 and 2 as the leafs. But how can ((partial + 1) 2 3) be displayed as a syntax tree? (or any other expression where the first list item is itself a complex expression) |
| 14:34 | technomancy | shortlord: there's no reason the first position in the AST has to point straight to a function |
| 14:34 | technomancy | as long as it evaluates to a function |
| 14:35 | TimMc | shortlord: + isn't the node, it's the first child |
| 14:36 | shortlord | technomancy: but that makes it quite hard to display in a graphical tree, right? I was thinking about visualizing clojure code, but I have no idea how I could put something like that into a tree structure |
| 14:37 | shortlord | TimMc: why? I mean, "+" is the first 'child' in the list, but after evaluating the expression, it would be the node of the syntax tree, wouldn't it? |
| 14:39 | TimMc | shortlord: If you're doing a strictly algebraic reduction of the tree, then you would replace the node with the results of the evaluation. |
| 14:40 | TimMc | I think you're conflating values and syntax at this point, though. |
| 14:41 | shortlord | TimMc: hmm, you might be right. Seeing the opening list parenthesis as the node would also solve the problem of displaying the tree |
| 16:00 | dnolen | cemerick: I fear that you've only caused more confusion. |
| 16:01 | cemerick | dnolen: hopefully only revealed it? |
| 16:01 | dnolen | cemerick: yeah, the problem is what people *thought* was happening before. |
| 16:02 | cemerick | Rich was banging the drums from the start that hints weren't type declarations. *shrug* |
| 16:02 | cemerick | The concept of hints is pretty foreign to most, I'd say. |
| 16:02 | dnolen | cemerick: but you talking about return types doesn't help that's a fiction. |
| 16:03 | hiredman | also, everyone is chiming in, even if they have no idea what they are talking about |
| 16:04 | hiredman | obviously everyone needs javap-mode and should read the bytecode their clojure code is compiled to |
| 16:04 | cemerick | hiredman: good luck with that |
| 16:05 | hiredman | :) |
| 16:05 | cemerick | dnolen: Yeah, I'm never as precise as I should be. |
| 16:06 | cemerick | That's often true, more true these days as I'm trying to synthesize reasonable ways to describe these things to people that will never (and don't want to) grok the subtleties involved. |
| 16:07 | dnolen | cemerick: the key is that in 1.2.0 *expressions* can be hinted. defn is no exception. no return type enters *anywhere* |
| 16:08 | dnolen | cemerick: in 1.3.0 you can define real *signatures*. I don't see how that be reconciled with expression hinting w/o work. |
| 16:10 | cemerick | dnolen: I promise I understand. But you keep talking about semantics of implementation details; my thread only cares about syntax. |
| 16:10 | cemerick | If the different hints really are different in order to communicate the semantic distinction, then they need to be *more* different. |
| 16:12 | dnolen | cemerick: the other problem is you state the problem. no path to solution, no discussion of pitfalls, no solutions around those pitfalls. the tension is that 1.3.0 brings real types into a primarily dynamically typed language. |
| 16:14 | dnolen | cemerick: my fear is that conversation will thus die, with many parties further in the dark then they were before. |
| 16:14 | cemerick | I don't have any solutions; I was only hoping to be educated and maybe provoke some clarifying discussion so everyone could better understand rationales, etc. |
| 16:15 | cemerick | dnolen: I don't think the balance of the world rests in that thread. :-) |
| 16:15 | dnolen | cemerick: no of course not :) |
| 16:15 | cemerick | It's all bleeding edge stuff that may or may not get swapped out for whatever is in the oven now — no way to know. |
| 16:18 | dnolen | cemerick: heh in Clojure time 7-8 months ain't bleeding edge. |
| 16:19 | cemerick | heh, yes and no :-) |
| 16:21 | cemerick | dnolen: Just something to think about: for all intents and purposes, _everyone_ thinks type hints are type declarations. If you come at it from that perspective, 1.3.0's use of hat-syntax just seems strange. |
| 16:27 | dnolen | cemerick: then the problem is false expectations, right? |
| 16:27 | seancorfield | technomancy: quick lein Q - is there an easy way to run tests wrapped in with-junit-output so i can run my clojure tests as part of an ant build and treat them just like normal junit tests (for xml output) |
| 16:28 | dnolen | cemerick: it's why I don't really buy your argument. If you remember that Clojure is through and through untyped, 1.3.0 isn't that confusing. |
| 16:28 | technomancy | seancorfield: yeah, I was just asking about that a few hours ago |
| 16:28 | technomancy | apparently there's a lein test-out plugin |
| 16:28 | technomancy | I haven't tried it myself, and it looks like it doesn't honor test selectors |
| 16:28 | technomancy | but it should get you what you want |
| 16:31 | seancorfield | thanx... i'll go look at that |
| 16:38 | chouser | while we're harping on var meta tags and syntax, it may be worth remembering that even in that (simple, relative to primitives declarations) case, the meaning is under contention. |
| 16:38 | seancorfield | aweseome technomancy works like a charm! |
| 16:38 | chouser | the tag on a var can mean either the type that the var *is*, or the type that the var would *return* if called as a function. |
| 16:38 | technomancy | seancorfield: are you using it with hudson/jenkins? |
| 16:39 | seancorfield | it does complain about eval-in-project's handler argument is deprecated. |
| 16:39 | seancorfield | i will be using it with hudson, yes |
| 16:39 | seancorfield | but right now i just want to get my ant build running the lein tests |
| 16:40 | seancorfield | and i'm already running mxunit tests (junit for cfml effectively) |
| 16:41 | technomancy | yeah; I was just wondering what the hudson history looks like |
| 16:42 | technomancy | and yeah, the test-out plugin needs to be tweaked to be more composable. it should leverage the existing test forms, I think. |
| 16:44 | dnolen | chouser: but is that really true? you have invoke expression which use their fn expression which is a var expression to determine what their own tag will be. var always *is*. the invoke expression steals it's tag from it. |
| 16:53 | hiredman | dnolen: thats an interesting point I wonder if (def ^String x inc) (map x (range 10)) would emit some kind of cast of x to String |
| 16:53 | hiredman | I guess it only would if you tried to do something like call a method on x |
| 16:57 | chouser | (def ^Long x {:a 1}) ; I promise to only put Longs in the this map |
| 16:57 | chouser | (.byteValue (x :a)) ; so I can do this without reflection |
| 16:58 | chouser | (.get x :a) ; but if I wanted to *this* without reflection, I should have used ^java.util.Collection or some such instead |
| 16:59 | chouser | the tag on that var is used to mean two different things. An unfortunate conflation in a language that succeeds in avoiding so many more common conflations. |
| 16:59 | chouser | And of course that's a silly example as I should just use 'get' instead of '.get', but the nevertheless the conflation remains. |
| 17:17 | technomancy | hm; it would be easy for me to add the functionality of the test-out plugin straight to lein |
| 17:17 | technomancy | could be done in ~5 LOC, but I would have to change the signature of leiningen.test/form-for-testing-namespaces |
| 17:23 | technomancy | http://p.hagelb.org/junit-out.html <= 10 LOC and it works, but grooooooss |
| 17:23 | dnolen | chouser: yes the essential ambiguity is that the *expressions* (x :a) and x both have the tag Long. but it has nothing to do with whether x is called as function or not. |
| 17:23 | dnolen | chouser: (do (set! *warn-on-reflection* true) (.byteValue (apply x [:a]))), reflection warning. |
| 17:24 | technomancy | seancorfield: are there any other use cases for wanting junit output besides hudson? |
| 17:25 | technomancy | and does anyone use TAP output? |
| 17:27 | chouser | dnolen: but isn't that example just because apply strips the tag entirely? |
| 17:28 | chouser | my point is that one could imagine the expression x using metadata like :eval-tag, and (x :a) using :return-tag, and then both could be declared when defining the var |
| 17:29 | dnolen | chouser: my point is that all higher order uses of type hinted fns show that the notion that type hints are somehow about return types completely falls apart. |
| 17:30 | chouser | so what is ^Long in my example above, if not a hint on the return type of x when called as a function? |
| 17:31 | dnolen | chouser: a limited convenience, since ^Long is meaningless in higher order usage. |
| 17:31 | gfrlog | $findfn -3 3 |
| 17:31 | sexpbot | [clojure.core/unchecked-negate clojure.core/-] |
| 17:31 | chouser | ah, fair enough. limited convenience, but nontheless one explicitly supported by the current clojure compiler. |
| 17:31 | gfrlog | there's really no (abs)? |
| 17:32 | dnolen | ,(Math/abs -1) |
| 17:32 | clojurebot | 1 |
| 17:32 | gfrlog | ,(Math/abs -39829842984892949829849829843979724972849232) |
| 17:32 | clojurebot | java.lang.ExceptionInInitializerError |
| 17:32 | gfrlog | ,(Math/abs -8.83) |
| 17:32 | clojurebot | 8.83 |
| 17:32 | gfrlog | good enough |
| 17:34 | chouser | dnolen: are we going to have logic programs that deduce the return types of high-order expressions to avoid reflection? |
| 17:34 | dnolen | chouser: man wouldn't that be awesome :) |
| 17:34 | chouser | :-) |
| 17:34 | gfrlog | chouser: what's the return type of (apply partial (repeat partial))? |
| 17:35 | hiredman | IFn |
| 17:36 | hiredman | gfrlog: you're asking the type system to tell you if a program halts |
| 17:36 | gfrlog | ah, not paramaterized then |
| 17:36 | gfrlog | I am? |
| 17:36 | chouser | apply has no return tag |
| 17:37 | hiredman | gfrlog: if you generate a fn from an infite seq of fns, and you want a strict haskellish signature, yes |
| 17:37 | gfrlog | I was just about to ask if such a function could exist in haskell |
| 17:39 | gfrlog | I find that function hard to reason about. Like could it have a recursive type that always returns itself? |
| 17:39 | hiredman | you are effectively creating a program that infinitely recurses, which is no different from so a fib program with a broken base case that never terminates |
| 17:40 | gfrlog | only if I pass it to trampoline... |
| 17:40 | gfrlog | (on a side note, when I pass it to trampoline the stack overflows, and I'm not sure why that's the case either) |
| 17:41 | hiredman | gfrlog: it depends, I am kind of interpolating what you mean, because the code pasted doesn't actually express any interesting properties |
| 17:41 | hiredman | because it doesn't do what you think it does |
| 17:41 | gfrlog | I think that it returns a function that returns a function that returns a ... |
| 17:42 | hiredman | nope |
| 17:42 | gfrlog | at some point it does not return a function? |
| 17:43 | pjstadig | infinitely recursive types exist all over the place |
| 17:43 | pjstadig | a cons cell is infinitely recursive |
| 17:44 | gfrlog | that makes sense. So I would assume that's the type of the function, but hiredman is telling me I don't understand it. |
| 17:44 | gfrlog | so I probably don't understand it. |
| 17:44 | hiredman | gfrlog: *shrug* I may be misreading it too |
| 17:44 | clojurebot | Excuse me? |
| 17:46 | gfrlog | in the repl it keeps returning functions |
| 17:50 | gfrlog | because (apply partial (repeat partial)) should be equivalent to (partial partial partial partial ...) |
| 17:50 | gfrlog | which is a function that ought to return something equivalent to (partial partial partial partial partial ...) |
| 17:50 | gfrlog | etc. |
| 17:56 | amalloy | gfrlog: so it's a function that evaluates to itself. it's not clear what impact this has on type systems of any kind |
| 17:56 | amalloy | rather: when called, returns itself |
| 17:56 | gfrlog | not much. I had gotten past that and was now trying to figure out why hiredman thought I didn't understand what it did. |
| 17:56 | amalloy | it's equivalent to (fn x [& _] x) |
| 17:57 | amalloy | i think |
| 17:57 | gfrlog | I understand that it's not interesting for type systems |
| 17:57 | amalloy | you started the discussion with "what is the type of (apply partial (repeat partial)) |
| 17:57 | amalloy | so that is probably the angle hiredman was working from |
| 17:58 | gfrlog | well when I said that it was a function that returns a function that returns ..., he said that was incorrect |
| 18:07 | amalloy | well, it's clearly true that that's what it does |
| 18:08 | amalloy | &(nth (iterate #(%) (apply partial (repeat partial))) 5) |
| 18:08 | sexpbot | ⟹ #<core$partial$fn__3684 clojure.core$partial$fn__3684@e9e439> |
| 18:09 | gfrlog | yep. |
| 18:09 | amalloy | as long as you don't imagine that those partials get invoked as functions in any way other than something like this iterate, you're not wrong |
| 18:09 | gfrlog | I tried passing some other args to the functions to see what would happen, and it didn't seem to change anything |
| 18:09 | amalloy | gfrlog: no, because they get added to the end of the infinite seq |
| 18:10 | amalloy | which is why i said it's basically equivalent to (fn x [& _] x) |
| 18:10 | amalloy | ignore args, return self |
| 18:10 | amalloy | &(take 5 (iterate #(%) (apply partial (repeat partial)))) |
| 18:10 | gfrlog | right |
| 18:10 | sexpbot | ⟹ (#<core$partial$fn__3684 clojure.core$partial$fn__3684@d95700> #<core$partial$fn__3684 clojure.core$partial$fn__3684@ded3e6> #<core$partial$fn__3684 clojure.core$partial$fn__3684@129be35> #<core$partial$fn__3684 clojure.core$partial$fn__3684@186a0bd> #<core$partial$f... http://gist.github.com/969581 |
| 18:10 | amalloy | you do get different objects, though; they just behave the same |
| 20:18 | AardMark | hey hey hey |
| 20:20 | AardMark | why doesn't anyone talk in here? |
| 20:20 | AardMark | it's a ghost town |
| 20:20 | duck1123 | sometimes |
| 20:21 | duck1123 | it all depends if anyone has anything to say |
| 20:21 | AardMark | how are you duck? |
| 20:21 | AardMark | im a haskeller, but i bough programming clojure the other day |
| 20:21 | AardMark | gonna give it a shot |
| 20:21 | duck1123 | annoyed that I still can't find my keys, just gave up to do some coding |
| 20:21 | AardMark | bought* |
| 20:22 | duck1123 | that was a good book, has it been updated yet? it's probably somewhat out of date |
| 20:22 | AardMark | ya, i got it at a used book store |
| 20:22 | AardMark | its a few years old |
| 20:22 | AardMark | i have the pdf of the joy of clojure |
| 20:23 | AardMark | not read either one yet though |
| 20:25 | dnolen | AardMark: it's all ebb and flow in this channel. |
| 20:25 | duck1123 | hmm... it appears that lamina, clojure 1.3, and numbers like 1e3 don't get along |
| 20:29 | amalloy | eg clojure.contrib.duck-streams is like whoa old |
| 20:29 | amalloy | (sorry if i sent that twice; seem to be having client issues) |
| 22:37 | technomancy | boston clojure group hacks: https://github.com/technomancy/quickbeam |
| 23:05 | stirfoo | If I try to add $HOME/.m2/repository/org/clojure-contrib/1.1.0/clojure-contrib-1.1.0.jar to the CLASSPATH var of ~/.lein/bin/swank-clojure, swank-clojure fails with a long trace |
| 23:10 | symbole | When building ad-hoc hierarchies, why must keywords be namespace qualified? |
| 23:17 | cemerick | symbole: to make it difficult for unrelated hierarchies to interfere with each other |
| 23:19 | symbole | What interference could there be if one were to use unqualified keywords? |
| 23:21 | cemerick | symbole: Library A and library B would then both be defining relationships over the same keyword space. |
| 23:21 | cemerick | That remains possible with namespaced keywords, but you need to rightly be explicit about it. |
| 23:23 | symbole | For library A and library B to both be using the same keyword space, wouldn't they need to use unqualified keywords? |
| 23:24 | jedi | isn't that what you asked? |
| 23:24 | symbole | jedi: I asked, why do keywords need to be qualified, as opposed to not being qualified. |
| 23:25 | cemerick | symbole: no, library A can refer to namespaced keywords used by library B |
| 23:26 | cemerick | The answer to the "why" question is "to enforce sane idiomatic usage". |
| 23:28 | symbole | So from a semantical perspective, the behavior is the same regardless of whether or not qualified or not qualified keywords are used? |
| 23:29 | hippiehunter | the more i'm getting into this the more i'm having a problem, char is not a first class primative in 1.3, I cant type hint it nor does it promote to long, not having char makes writing a parser very hard. |
| 23:29 | cemerick | symbole: yes, if namespace-less keywords could be used within hierarchies. |
| 23:31 | cemerick | hippiehunter: You need primitive char returns for your parser? |
| 23:32 | hippiehunter | returns are nice but parameters are more important |
| 23:32 | cemerick | hippiehunter: why? |
| 23:33 | hippiehunter | because im parsing one char at a time then dispatching to finish the token |
| 23:34 | hippiehunter | i had grown to accept that long wouldnt really be much of a problem on 64bit but char doesnt seem to play nice with long |
| 23:34 | hippiehunter | I might just be misunderstanding whats going on though |
| 23:35 | cemerick | hippiehunter: I still fail to understand why you need primitive chars? |
| 23:35 | hippiehunter | one object per char in a large file feels like its going to be a little slow |
| 23:36 | cemerick | very unlikely |
| 23:36 | cemerick | char boxing is _very_ fast, since a constant pool is used |
| 23:37 | hippiehunter | oh, that sounds nice |
| 23:37 | hippiehunter | is that specific to hotspot or jvm's in general? |
| 23:37 | hiredman | you can also do stuff like use definline |
| 23:37 | cemerick | hippiehunter: JVM's in general, IIRC |
| 23:38 | hiredman | which tells the compiler to inline your functions, so you don't box at the function boundries |
| 23:38 | cemerick | hippiehunter: "If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2." http://java.sun.com/docs/books/jls/third_edition/html/conversions.html |
| 23:38 | cemerick | so… |
| 23:38 | cemerick | ,(identical? (first "f") (first "f")) |
| 23:38 | clojurebot | true |
| 23:40 | hippiehunter | well i guess you learn something new every day |
| 23:40 | cemerick | :-) |
| 23:41 | cemerick | Code first, optimize later. And if you really need to, hiredman's suggestion will bail you out. |
| 23:41 | cemerick | s/to/it |
| 23:45 | hippiehunter | cemerick: i'm usually the first to quote that to people but there just a few things i cant bring myself to ignore. constant costs on O(n) where n is known to be excessively high are one of those things. Also im really a CLR guy and we dont have the optimization :p |
| 23:46 | hippiehunter | still getting used to the cost differences on jvm |
| 23:56 | symbole | cemerick: I think I understand the reason behind qualification. It makse sense. |
| 23:59 | cemerick | symbole: OK. To be sure, consider the potential otherwise: I say (derive :a :z), and you say (derive :b :z), and our libraries are loaded in the same VM. We'll both be surprised by the results of (ancestors :a) or (ancestors :b), depending on which one we're concerned with. |