2011-08-25
| 00:02 | scottj | the difficulty of getting libraries to compile responses made me appreciate the jvm |
| 00:28 | dnolen | chouser: slides? |
| 01:05 | leeda | Hi, if I have a byte-array, how can I tell if it corresponds to a JPG image? |
| 01:05 | ibdknox | don't jpegs have a header? |
| 01:06 | leeda | Probably. So I should just try to look at the header? I was wondering if there's any library that can look at a byte-string and detect the mimetype automatically? |
| 01:09 | nkoza | leeda: http://sourceforge.net/projects/jmimemagic/ |
| 01:16 | nkoza | if I change an atom inside a dosync block, and the transaction fails.. is the atom reverted to their previous state? |
| 01:29 | MasseR | nkoza: AFAIK yes, but it is later retried |
| 01:29 | MasseR | SO that there are no dirty values anywhere |
| 01:29 | MasseR | No wait, atom? Not inside transaction afaik |
| 01:30 | nkoza | so if transaction is retried the atom will be mutated again? |
| 01:30 | MasseR | Only refs |
| 01:30 | MasseR | I'd say so |
| 01:30 | MasseR | Don't count on me |
| 01:45 | amalloy | go ahead, count on MasseR |
| 02:18 | scottj | where is the cljs require goog magic covered? goog.dom and goog.events don't make sense to me, I'm not sure what they refer to. [goog.Timer :as timer] makes sense, I can see Timer in the closure api. [goog.events.EventType :as event-type] makes sense I see it in the api too. but how dom/append gets mapped to DomHelper (guessing) and how events/listen maps to EventHandler (guessing) O dpm |
| 02:18 | scottj | I don't understand |
| 02:29 | scottj | nm I was in the package reference all this time not the file reference |
| 03:29 | klutometis | There doesn't appear to be a `transient?' predicate; does any know how I'd fake one? |
| 03:32 | amalloy | &(for [x [{}, (transient {})]] (instance? x clojure.lang.ITransientCollection)) |
| 03:32 | lazybot | java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Class |
| 03:32 | amalloy | &(for [x [{}, (transient {})]] (instance? clojure.lang.ITransientCollection x)) |
| 03:32 | lazybot | ⇒ (false true) |
| 03:34 | klutometis | amalloy: Ah, fantastic; thanks. |
| 03:35 | amalloy | klutometis: you can derive these yourself by having a look at ##(supers (class (transient {}))) |
| 03:35 | lazybot | ⇒ #{clojure.lang.ILookup clojure.lang.ITransientMap java.lang.Runnable clojure.lang.ITransientAssociative java.lang.Object clojure.lang.ATransientMap java.util.concurrent.Callable clojure.lang.Counted clojure.lang.AFn clojure.lang.ITransientCollection clojure.lang.IFn} |
| 03:39 | klutometis | amalloy: Indeed; for some reason I was thinking of transients as magical types and it didn't occur to me that they're classes like everything else. ;) |
| 03:40 | amalloy | heh. in java everything's a type, even when that obviously makes no sense |
| 03:40 | amalloy | er, an object. or has a type? i'm kinda sleepy, apparently |
| 03:47 | klutometis | amalloy: Yeah, I was about to modify my statement that "transients are types (classes)" to "transients are objects," until I realized that both are true (even in the plural). |
| 04:12 | robbe- | I have a circular structure (basically conscell with refs), how would I print a ref without the REPL exploding? |
| 04:13 | robbe- | Using format instead of print seems to be a good start. |
| 04:17 | amalloy | &(doc *print-depth*) |
| 04:17 | lazybot | java.lang.Exception: Unable to resolve var: *print-depth* in this context |
| 04:17 | amalloy | &(doc *print-level*) |
| 04:17 | lazybot | ⇒ "; *print-level* controls how many levels deep the printer will print nested objects. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum level to print. Each argument to print is at level 0; if an arg... http://gist.github.com/1170222 |
| 04:21 | robbe- | Oh, thanks :) |
| 04:28 | wgethis | how to do (length ("hello")) in clojure? |
| 04:46 | raek | wtetzner: (count "hello") |
| 05:02 | scottj | &(get (assoc (clojure.lang.PersistentTreeMap.) :a 1) "from") |
| 05:02 | lazybot | java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String |
| 05:03 | scottj | wtf? |
| 05:14 | thorwil | ,(get (assoc (clojure.lang.PersistentTreeMap.) :a 1) :a) |
| 05:14 | clojurebot | 1 |
| 05:14 | thorwil | scottj: how is it supposed to deliver a value for "from", when there is no such key? |
| 05:14 | scottj | is it part of PersistentTreeMap's contract that all keys be the same type? Does clojure never promote maps automatically to PersistentTreeMap? |
| 05:14 | scottj | thorwil, I expected nil |
| 05:15 | scottj | &(get (assoc {} :a 1) "from") |
| 05:15 | lazybot | ⇒ nil |
| 05:17 | thorwil | it does seem like clojure.lang.PersistentTreeMap does not like non-keyword keys (?) |
| 05:17 | scottj | no it's fine with them, they just have be the same and you have to request the right one |
| 05:17 | thorwil | ,(type (assoc {} :a 1)) |
| 05:17 | clojurebot | clojure.lang.PersistentArrayMap |
| 05:18 | scottj | &(get (assoc (clojure.lang.PersistentTreeMap.) "a" 1) "from") |
| 05:18 | lazybot | ⇒ nil |
| 05:19 | robbe- | Is there a difference in behaviour with nested dosync blocks vs one big dosync block enclosing all operations? |
| 05:19 | thorwil | ic |
| 05:22 | scottj | robbe-: I don't think so, http://soft.vub.ac.be/~tvcutsem/talks/presentations/STM-in-Clojure.pdf |
| 05:23 | robbe- | Hey, that's my professor. |
| 05:23 | robbe- | :D |
| 05:24 | thorwil | scottj: you don't need the get in front, even |
| 05:25 | scottj | robbe-: I don't use the stm, was just going off the couple words about that in his slides, there may be differences in the real implementation |
| 05:34 | dhaivat | Clojure has waaaay too many parentheses. I wrote one web app, and it (in total) had 748 parentheses. |
| 05:36 | scottj | dhaivat: save them, you can recycle them with cut and paste |
| 05:49 | Chousuke | dhaivat: have you ever counted the number of parentheses in a java app? |
| 05:50 | robbe- | (or the loc) |
| 05:50 | robbe- | :p |
| 05:50 | Chousuke | you're likely to have more parens in a typical java app than in a clojure app that does the same thing :P |
| 05:50 | Chousuke | they're just better hidden |
| 05:54 | scottj | (defn write [code, like, this] |
| 05:54 | scottj | (to really, piss, people, off); |
| 05:54 | scottj | ) |
| 08:35 | MasseR | Damnit, if clojure would just start up faster, I'd probably write all my tools in it |
| 08:35 | manutter | jark |
| 08:36 | manutter | or nailgun I suppose |
| 08:37 | MasseR | Having a server running for command line programs seems kinda wrong. Been thinking that though |
| 08:37 | MasseR | Hm.. jark seems interesting |
| 08:38 | manutter | Yeah me too, if I had more RAM to throw around I probably would think about it some more |
| 08:38 | MasseR | Oh yeah, that too |
| 08:38 | MasseR | what is the memory footprint of jvm/clojure? |
| 08:39 | bsteuber | how about js startup time? |
| 08:39 | bsteuber | if it's good, why not use clojurescript for your tools? |
| 08:40 | MasseR | openjdk |
| 08:40 | MasseR | I'm intrigued by it, but not enough to install sunjdk ) |
| 08:40 | MasseR | :) |
| 08:43 | manutter | looks like I'm soaking up just over 500M on a clean start of the jark vm |
| 08:44 | manutter | That's going to be subject to the params you start the vm with of course. |
| 08:48 | Chousuke | at one point I was running the cake vms persistently at about 32 MB at start |
| 08:48 | Chousuke | it really depends on the JVM parameters |
| 08:50 | Chousuke | I think the default is to preallocate 128MB or something |
| 08:50 | Chousuke | the JVM expects that it will be running something enterprisey for a long time so it optimises for it :P |
| 08:55 | MasseR | Hmm... I think I'm going to like jark |
| 08:57 | manutter | jark is kinda fun :) |
| 08:58 | manutter | No! No! Bad programmer! Close that window and get back to PHP! |
| 08:58 | manutter | *sigh* |
| 08:58 | MasseR | manutter: I feel you |
| 08:58 | MasseR | FOr a while I laughed. Then I realized I'm in the same boat |
| 09:01 | agz | (-> 1 #(+ % 1)) -> gives me java.lang.Integer cannot be cast to clojure.lang.ISeq |
| 09:01 | MasseR | jark doesn't recognize my -main function :/ |
| 09:02 | agz | is it right? |
| 09:02 | agz | (-> 1 inc) -> is just fine |
| 09:02 | MasseR | ,(-> 1 #(+ % 1)) |
| 09:02 | clojurebot | #<CompilerException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.ISeq, compiling:(NO_SOURCE_PATH:0)> |
| 09:03 | manutter | You can't use the -> macro with the #() macro, bad things happen |
| 09:03 | MasseR | manutter: Why is that? |
| 09:04 | agz | ,(-> 1 (fn [x] (+ x 1))) |
| 09:04 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: nth not supported on this type: Long> |
| 09:04 | manutter | (macroexpand '(-> 1 #(+ 1 %))) |
| 09:04 | agz | and this why not? |
| 09:04 | manutter | doh |
| 09:04 | manutter | ,(macroexpand '(-> 1 #(+ 1 %))) |
| 09:04 | clojurebot | (fn* 1 [p1__8345#] (+ 1 p1__8345#)) |
| 09:04 | manutter | eh, maybe I'm misremembering |
| 09:05 | agz | feels a bit inconsistent :( |
| 09:05 | manutter | I thought something like this had come up before and that was the answer |
| 09:05 | manutter | but looks like the cases aren't quite parallel |
| 09:05 | agz | hmm -> can be parallelized? :O |
| 09:06 | manutter | no, wait |
| 09:06 | agz | (don't think so) |
| 09:06 | dnolen | agz: -> is pure syntax transformation. you're pushing anything through anything. |
| 09:06 | manutter | I missed the fn* 1 in the expansion |
| 09:06 | manutter | I was right after all |
| 09:06 | agz | yep but then why not accept the fn -version |
| 09:06 | dnolen | ,(-> 1 ((fn [x] (+ x 1)))) |
| 09:06 | clojurebot | 2 |
| 09:06 | agz | ,(-> 1 (fn [x] (+ x 1))) |
| 09:06 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: nth not supported on this type: Long> |
| 09:06 | manutter | ,(macroexpand '(-> 1 (fn [x] (inc x)))) |
| 09:07 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: nth not supported on this type: Long> |
| 09:07 | dnolen | agz: you need to wrap in an extra set of parens. |
| 09:07 | agz | dnolen: what is the special character there? :O |
| 09:07 | agz | dnolen: ohh .. OHHH!!! thx :D |
| 09:07 | dnolen | ,(-> 1 (#(% + 1))) |
| 09:07 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 09:07 | manutter | basically, -> is a macro that re-writes your source code |
| 09:08 | dnolen | ,(-> 1 (#(+ % 1))) |
| 09:08 | clojurebot | 2 |
| 09:08 | manutter | There we go |
| 09:08 | manutter | I didn't know there was a workaround, but that makes sense |
| 09:08 | agz | yeah it's really cool |
| 09:09 | agz | another one guys |
| 09:09 | agz | I installed a lots of leiningen stuff |
| 09:09 | agz | and my interpreter "lost" my agents :) |
| 09:10 | agz | (def a (agent [])) (send a conj 1) (await a) <- and no response, interpreter hangs(?) as the thread never finishes |
| 09:10 | manutter | Hmm, I've seen that one |
| 09:11 | agz | I've deleted ~/.m2 and just started a plain new clojure 1.2.1 |
| 09:11 | manutter | Yep, same thing happened to me |
| 09:11 | agz | but still no |
| 09:11 | agz | manutter: ohh what was the solution? :O |
| 09:11 | manutter | I ended up re-installing a bunch of stuff, I think my .lein dir and possibly my .m2 dir |
| 09:11 | manutter | clean re-install of the latest lein cleared it up |
| 09:12 | agz | ahhaaam |
| 09:12 | agz | so you deleted .lein also? |
| 09:12 | agz | (where lein selfinstall puts stuff??) |
| 09:14 | MasseR | \o/ I broke jark already :D |
| 09:15 | manutter | agz: I believe that's how I fixed it, it's been a few weeks |
| 09:15 | manutter | MasseR: lol, how? |
| 09:16 | MasseR | manutter: By doing 'jark lein' on a non lein directory |
| 09:16 | MasseR | I can't start the jark vm server anymore |
| 09:16 | manutter | oh, ouch |
| 09:16 | agz | manutter: thx, i will try it out! |
| 09:17 | MasseR | "exception failure: int_of_string" |
| 09:18 | manutter | MasseR: the vm server isn't hanging around stuck somewhere is it? |
| 09:19 | MasseR | pgrep jark and pgrep jvm both return nothing |
| 09:19 | manutter | how about "java"? |
| 09:19 | manutter | netstat -lanp | grep 4005 |
| 09:19 | MasseR | ha! There |
| 09:20 | MasseR | Yup, jark lein kills it |
| 09:20 | MasseR | Even on a lein project |
| 09:21 | manutter | I've never used jark lein, what's it supposed to do? |
| 09:22 | MasseR | I don't know. That's what I was testing |
| 09:23 | MasseR | But even still, apparently unlike jark website says, jark isn't started automatically and it doesn't recognize the -main function so as it is, it's quite useless |
| 09:23 | MasseR | ./ |
| 09:23 | MasseR | :/ |
| 09:25 | manutter | hmm, I'm pretty sure I did a simple "hello world" type jark script, but I don't recall what the exact syntax was. |
| 09:26 | MasseR | http://pastebin.com/nmG7xXHZ that's quite as simple as it gets. (The dofoo was for testing) |
| 09:28 | manutter | how did you run the command? |
| 09:29 | MasseR | ./foo.clj and jark foo.clj |
| 09:29 | manutter | I wonder if it matters which dir you start jark from vs which dir you start the script from, hmm... |
| 09:29 | manutter | did you get any errors or just no output? |
| 09:30 | MasseR | With little modifications I get no output but also no errors (If I do (def foo (println "foo"))) it prints the foo), but that version prints 'clojure.lang.Var\n2' |
| 09:31 | manutter | when I run your script locally I get "java.io.FileNotFoundException: Could not locate foo__init.class or foo.clj on classpath" |
| 09:32 | manutter | oh, duh, I didn't name it "foo". |
| 09:33 | manutter | There, with proper naming, I get "Hello world" as my output. |
| 09:33 | MasseR | jark client version 0.4 |
| 09:36 | MasseR | Odd |
| 09:40 | manutter | I just re-installed and restarted jark, and I get "Hello World" just fine using your code. |
| 09:40 | manutter | openjdk vs sun-java6? |
| 09:42 | robbe- | Is filter the idiomatic way to find an element in a list? |
| 09:42 | robbe- | I need only one result, so that would be (first (filter ... |
| 09:45 | MasseR | openjdk |
| 09:46 | manutter | MasseR: I'm on sun-java6, maybe thats the difference? |
| 09:48 | Somelauw | openjdk works for nonreparenting windows if you modify your .xinitrc, but sunjdk is what you need to get intellij to work. Since I don't use intellij, I go for openjdk. |
| 09:49 | MasseR | manutter: I'll try changing |
| 09:57 | MasseR | No luck with suns jdk |
| 10:03 | MasseR | If I prepend the file with a (comment) it doesn't throw any errors |
| 10:46 | Scorchin | Is there any way to do order-by on multiple keys in a map? E.g. I have a list of maps holding :name and :sport keys and I want them to be grouped by :name and then for each :name — e.g. "Bob" — to have their sports in ascending order. |
| 10:57 | gtrak | how would you get to a servlet request attribute from a custom ring middleware? |
| 10:59 | babilen | Scorchin: Take a look at sort-by -- For example: (sort-by (columns [:name :sport] YOUR_MAP)) (not necessarily correct, play with it) |
| 11:00 | babilen | Scorchin: Err, you probably want to switch :name and :sport -- I'll be back later. |
| 11:01 | tufflax | babilen what is that columns fn? |
| 11:03 | Scorchin | babilen: thanks, will check it out |
| 11:04 | gtrak | oh, I see there's a :servlet-request attribute |
| 11:04 | tufflax | Scorchin sort seem to be stable, so you can sort by sport first, then by name. Or of couse you can make a new comparator fn, it's easy in this case. But maybe there is something better... hmm |
| 11:05 | tufflax | seems* |
| 11:06 | MasseR | Is clojureql capable of sqlite btw? |
| 11:07 | coopernurse | MasseR: haven't tried it, but I suspect if you get the right JDBC driver it would work |
| 11:07 | gtrak | clojureql doesn't do any ddl stuff |
| 11:08 | coopernurse | perhaps this one: http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC#UsingSQLiteJDBCwithMaven2 |
| 11:10 | coopernurse | which in project.clj would look like: [org.xerial/sqlite-jdbc "3.6.16"] |
| 11:10 | coopernurse | again, haven't tried it though.. |
| 11:12 | coopernurse | looks like that driver has some native code. not sure how that plays with maven/lein - presumably you'd have to manually install the .so/.dll file |
| 11:14 | MasseR | coopernurse: xerial? |
| 11:19 | coopernurse | MasseR: yeah, that appears to be one java sqlite driver, which might work with clojureql |
| 11:19 | lrenn | I don't suppose I could get some volunteers to run: (java.net.InetAddress/getByName "4294967303") |
| 11:20 | lrenn | For some reason it resolve to an IP for me even though dig/nslookup/etc don't resolve. |
| 11:20 | lrenn | also different on Lion vs. Snow Leopard which is blowing up a test. |
| 11:21 | coopernurse | ; user=> (java.net.InetAddress/getByName "4294967303") |
| 11:21 | coopernurse | ; #<Inet4Address 4294967303/72.3.199.16> |
| 11:21 | coopernurse | that's on clj 1.2.1 - snow leopard |
| 11:21 | Fossi | user=> (java.net.InetAddress/getByName "4294967303") |
| 11:21 | Fossi | java.net.UnknownHostException: 4294967303 (NO_SOURCE_FILE:0) |
| 11:21 | Fossi | linux gentoo |
| 11:21 | lrenn | See, wtf? |
| 11:22 | coopernurse | lemme try some os tools with that. very ood |
| 11:22 | Fossi | 1.6.0_26 Java HotSpot(TM) Client VM |
| 11:22 | coopernurse | odd |
| 11:22 | coopernurse | $ host 4294967303 |
| 11:23 | coopernurse | 4294967303 has address 72.3.199.16 |
| 11:23 | lrenn | yeah, host gives me two different ips, then says not found. |
| 11:23 | coopernurse | honestly, I'm not sure what that even means.. what would a dns server do with that |
| 11:23 | lrenn | is it converting the string into bytes or something... |
| 11:23 | coopernurse | great question |
| 11:24 | coopernurse | dig resolves it too |
| 11:24 | lrenn | host 42949673034294967303 has address 8.15.7.1174294967303 has address 63.251.179.13Host 4294967303 not found: 3(NXDOMAIN) |
| 11:24 | Fossi | Host 4294967303 not found: 3(NXDOMAIN) |
| 11:24 | Fossi | dig resolves it for me |
| 11:25 | manutter | ,(+ (* 72 256 256 256) (* 199 256 256) (* 3 256) 16) |
| 11:25 | clojurebot | 1221002000 |
| 11:25 | manutter | interesting... |
| 11:25 | Fossi | stil, what kind of address is that supposed to be? |
| 11:26 | lrenn | when it resolves, we all resolve it to something different, so i don't think that's it. |
| 11:26 | lrenn | it's not supposed to be an address, we have some code that was expecting an UnknownHostException. |
| 11:26 | lrenn | One of our devs upgraded to Lion and the test started failing. |
| 11:27 | lrenn | we all use macs at work, but I checked my linux box on home and it does the same thing Lion is doing (resolves) |
| 11:27 | coopernurse | lemme try a linux vps box I have |
| 11:27 | coopernurse | ok, interesting |
| 11:28 | coopernurse | it appears to depend on your nameserver |
| 11:28 | coopernurse | linux vps - running bind locally, doesn't resolve |
| 11:28 | coopernurse | linux vm on my mac - hitting a DNS server on my dlink access point - does resolve |
| 11:32 | lrenn | thanks guys. i don't want waste anymore of anyones time on it. |
| 11:32 | lrenn | strange though... |
| 11:32 | Fossi | the implementation might have changed |
| 11:32 | Fossi | // if host is an IP address, we won't do further lookup |
| 11:32 | Fossi | if (Character.digit(host.charAt(0), 16) != -1 |
| 11:32 | Fossi | || (host.charAt(0) == ':')) { |
| 11:32 | lrenn | Lion actually resolves it to 0.0.0.7 |
| 11:32 | lrenn | :) |
| 11:33 | Fossi | that smells like a fishy bit to me |
| 11:33 | cemerick | Do pull requests always notify everyone that has commit privs on a repo? |
| 11:39 | Fossi | lrenn: i would guess it's somehow interpreted as an ipv6 address |
| 11:39 | Fossi | and depending on the machines setup that might resolve or not |
| 11:39 | lrenn | Fossi: thought of that, but it returns an instance of IPV4 |
| 11:39 | lrenn | #<Inet4Address 4294967303/72.3.199.16> |
| 11:39 | lrenn | (even the odd 0.0.0.7) |
| 11:40 | lrenn | gotta split, thanks again everyone. |
| 11:45 | babilen | Scorchin, tufflax: Ah, sorry - forgot about that. It is : http://paste.debian.net/127362/ -- It is from "The Joy of Clojure" 7.1.2 |
| 11:49 | Scorchin | babilen: I google'd it when I started getting stack traces :) |
| 11:49 | Scorchin | babilen: but, thanks! |
| 11:50 | babilen | Scorchin: Actually just read http://clojuredocs.org/clojure_core/clojure.core/sort-by (the third example is exactly what you are looking for and uses an anonymous function instead) |
| 11:51 | Scorchin | babilen: yup, that's what I'm using :) |
| 11:51 | Scorchin | but now I've got another issue :/ |
| 11:51 | babilen | Scorchin: Perfect -- Sorry for the confusion :) |
| 11:52 | Scorchin | I now have a sorted list of maps — where maps containt :name and :sport keys — but I only want the very last :sport key for each :name. This seems like a difficult thing to pull off :/ |
| 12:00 | whidden_ | Hi guys, question: When using swank.clojure where do the pre/post function assertion messages go? I don't seem to see them on in any of the regular places. |
| 12:01 | arohner | whidden_: it depends on how your code was called |
| 12:02 | arohner | usually, it goes to where the repl output goes, but if the call happened in another thread, it might go to the console (the terminal where you started the app) |
| 12:03 | arohner | whidden_: actually, wait. there are no messages, unless the assertion failed, or you did {:post [(do (println ...) true)]} |
| 12:03 | whidden_ | arohner: hmmm that is what I thought too, and I don't see any messages for assertion failure in those places. Is the assertion a checked or unchecked exception? |
| 12:04 | arohner | whidden_: it's a j.l.AssertionError |
| 12:05 | arohner | what does your assertion look like? |
| 12:07 | whidden_ | arohner: |
| 12:07 | whidden_ | {:pre [(string? label) (map? resource-map) (or (empty? resource-map) (:map-start-time resource-map)) |
| 12:07 | whidden_ | (map? tsk) (:duration tsk) (or (nil? fit-time) (float? fit-time) (integer? fit-time))] |
| 12:07 | whidden_ | :post [(map? %)]} |
| 12:07 | arohner | whidden_: do the assertions fire if you call the fn in the repl? |
| 12:07 | whidden_ | yes |
| 12:08 | arohner | whidden_: so then what's the problem? |
| 12:09 | whidden_ | arohner: when running from another thread or jar file, i don't see the assertion messages anywhere and thus don't know the cause of the failure. |
| 12:10 | arohner | whidden_: there isn't a message by default. the assertion just throws the j.l.AssertionError if it fails |
| 12:11 | arohner | whidden_: maybe you're not catching the exception? or catching it somewhere you don't intend? |
| 12:11 | whidden_ | arohner: <bing!> crap... I see now what is going on when running.. I catch all those errors in one bucket :( |
| 12:11 | whidden_ | arohner: catching it in another place and thinking its an entirly different beast... thanks.. mystery solved. |
| 12:11 | arohner | np |
| 12:20 | lobotomy_ | hmm, trying to run lazybot, it says: Exception in thread "main" java.io.FileNotFoundException: Could not locate irclj/core__init.class or irclj/core.clj on classpath: (registry.clj:1) |
| 12:20 | lobotomy_ | i ran "lein deps" which put an irclj jar into libs/ |
| 12:20 | michaelr525 | hhey!! |
| 12:21 | lobotomy_ | and the ./lazybot does "java -cp lib/*: ..." so it should pick that up? |
| 12:24 | manutter | lobotomy_: are you building a jar file with lein jar? |
| 12:24 | manutter | or lein uberjar |
| 12:25 | lobotomy_ | hmm, no, just "lein deps", edit .lazybot/info.clj, then "./lazybot" |
| 12:31 | pjstadig | cemerick: yes they do, but i think you get the option to pare the list |
| 12:31 | cemerick | pjstadig: hrm? |
| 12:31 | cemerick | oh, notifications |
| 12:31 | pjstadig | cemerick: yeah |
| 12:32 | cemerick | pjstadig: how? I don't see any X's, hovers, etc… |
| 12:34 | lobotomy_ | ok, "lein jar" from the main lazybot dir gives the same error, irclj not found... |
| 12:34 | lobotomy_ | wonder if my lein on this machine is somehow broken. grr |
| 12:34 | michaelr525 | Error occurred during initialization of VM Could not reserve enough space for object heap |
| 12:34 | pjstadig | cemerick: yeah never mind...they just show a list of "people to be notified" on the right hand side now |
| 12:35 | pjstadig | i thought they used to be checkboxes |
| 12:35 | cemerick | Yeah; it makes me feel a little bad to send a pull request and pop notifications on dozens of people. |
| 12:35 | technomancy | they used to let you choose who to notify with a big ol' "notify everyone who has ever touched this project" featured prominently at the top |
| 12:35 | technomancy | now it's just committers I think, but it's easy for them to turn down the noise if someone's annoyed |
| 12:36 | cemerick | technomancy: Where's *that* knob? I get a pile of noise from repos I have commit on… |
| 12:36 | cemerick | I think you can only turn them on/off globally, which sucks. |
| 12:37 | technomancy | it's hidden pretty deep iirc |
| 12:38 | technomancy | oh, never mind; I'm thinking of the option to abdicate committership |
| 12:39 | mbac | curl: (22) The requested URL returned error: 404 |
| 12:39 | mbac | Failed to download https://github.com/downloads/technomancy/leiningen/leiningen-2.0.0-SNAPSHOT-standalone.jar |
| 12:39 | mbac | :( |
| 12:39 | simonjb | hi all, I've got a newbie swank-clojure question maybe someone could help me with -- if I've messed up my VM, say by redefining some fundamental function, can I reset swank without restarting emacs? |
| 12:41 | mdeboard` | simonjb: Did you do M-x swank<tab> to see if tab-completion has like a swank-reset ? I believe it does |
| 12:42 | lobotomy_ | now on this other machine, "git clone https://github.com/flatland/lazybot.git" is failing with fatal: https://github.com/flatland/lazybot.git/info/refs download error - The requested URL returned error: 403 |
| 12:42 | mdeboard` | swank-repl-restart or something |
| 12:42 | mbac | oh that was head in the repo not the stable one |
| 12:42 | mdeboard` | lobotomy_: Use the git:// or git@ directory |
| 12:42 | mdeboard` | imo |
| 12:42 | simonjb | mdeboard`: I'll have a look, thanks! |
| 12:43 | lobotomy_ | ok, s/https/git/ indeed works... sigh |
| 12:45 | simonjb | mdeboard`: M-x swank<tab> isn't finding anything |
| 12:45 | mdeboard` | wow did i say git@ directory? ugh |
| 12:45 | mdeboard` | anyway lobotomy_ glad it worked |
| 12:45 | lobotomy_ | ok, "lein jar" is giving the same error on this machine as well |
| 12:46 | lobotomy_ | so in short, lazybot doesn't seem to compile |
| 12:46 | mdeboard` | simonjb: uh hm, were you in a clojure-mode buffer when you tried it? |
| 12:47 | simonjb | mdeboard`: yes, also tried from the slime-repl buffer -- maybe my swank setup is different from yours? |
| 12:48 | mdeboard` | simonjb: Sounds like you tried to do too much getting emacs configured properly for clojure |
| 12:48 | lobotomy_ | (though on this machine, just "lein" seems to hang forever, after displaying the help text. wtf. how do i determine whether it's my lein or lazybot (or something else) that's broken here) |
| 12:48 | mdeboard` | simonjb: I say that because you're' having the problems I did when I first started. Simple fact is that most of the tutorials and blog posts about using slime-repl with emacs are woefully out of date |
| 12:49 | mdeboard` | simonjb: All you need is leiningen and clojure mode, really. |
| 12:49 | mdeboard` | lobotomy_: lein takes forever because the jvm takes forever |
| 12:49 | lobotomy_ | you mean literally forever? |
| 12:49 | mdeboard` | simonjb: So if you've got like "require swank" or "require slime" somewhere in your .emacs/init.el you're doing it wrong |
| 12:50 | mdeboard` | lobotomy_: Oh. Well, no. :P |
| 12:52 | simonjb | mdeboard`: I'll check -- I think my setup is pretty minimal -- I installed clojure-mode using package.el and then used leiningen to install swank-clojure; I'm using clojure-jack-in to start swank and slime |
| 12:53 | mdeboard` | yeah that sounds about right |
| 12:53 | mdeboard` | Oh |
| 12:53 | mdeboard` | right, sorry, M-x slime-repl<tab> will yield restart results. I'm not sure about restarting swank independently of emacs. I'd suspect just stopping the slime-repl then jacking in again would be helpful... but I'm assuming you tried that and it didn't owrk? |
| 13:00 | technomancy | simonjb: you should be able to kill the *swank* buffer and re-run M-x clojure-jack-in |
| 13:01 | mdeboard` | Oh yeah, derp. Been awhile since I've clojured anything :-\ |
| 13:01 | tufflax | Scorchin babilen (sort-by (juxt :a :b) ...) is better that columns, because it's in core and it takes all kinds of fns not only keywords, so you can do (sort-by (juxt first second) ...) |
| 13:03 | lobotomy_ | (heh, "lein" does not in fact hang forever, it just takes around 74 seconds to finish) |
| 13:04 | technomancy | lobotomy_: probably you are starting up a non-daemon threadpool which shuts itself down after 60s |
| 13:04 | lobotomy_ | i am? hmm... ok |
| 13:05 | technomancy | fsvo "you" |
| 13:05 | lobotomy_ | this is from the lazybot main dir |
| 13:05 | simonjb | technomancy: perfect! thanks very much -- super awesome job on all your clojure tooling by the way! |
| 13:07 | lobotomy_ | i see "lein" takes the same 74ish seconds from just my home dir, which has no project.clj in it |
| 13:07 | lobotomy_ | so why would lein start a non-daemon threadpool? is my install broken? |
| 13:09 | technomancy | oh, if it's happening in ~ then it must be something else |
| 13:12 | lobotomy_ | but i'd be more interested in getting lazybot to work/compile/anything, not sure if that's related to the state of my lein :) |
| 13:13 | mdeboard` | lobotomy_: I had trouble compiling one of amalloy's project's too :( 4clojure |
| 13:13 | mdeboard` | I say we blame him |
| 13:13 | mdeboard` | well, not compiling. I couldn't get 4clojure to work locally because of some threading issue or another that i can't remember |
| 13:14 | babilen | tufflax: thanks |
| 13:18 | amalloy | in fairness, lazybot is more Raynes's than mine |
| 13:18 | babilen | tufflax: Indeed, much better. |
| 13:19 | mdeboard` | amalloy: :P |
| 13:19 | tufflax | babilen :) |
| 13:20 | srid | is there actually a ring middleware that autocompiles ssas -> css? (google doesn't show any) |
| 13:21 | lobotomy_ | amalloy, so how do i compile and/or run lazybot? |
| 13:22 | amalloy | lobotomy_: i just use lein swank to start interactive development |
| 13:22 | amalloy | and ./lazybot will launch it externally |
| 13:24 | lobotomy_ | ok, wtf. lein swank seems to actually work |
| 13:25 | lobotomy_ | ./lazybot gives that error it always did (see above) |
| 13:27 | amalloy | lobotomy_: that's a lot of text to search to try and find your complaint |
| 13:29 | lobotomy_ | git clone https://github.com/flatland/lazybot.git ; cd lazybot ; lein deps ; ./lazybot |
| 13:29 | lobotomy_ | result: Exception in thread "main" java.io.FileNotFoundException: Could not locate irclj/core__init.class or irclj/core.clj on classpath: (registry.clj:1) |
| 13:29 | lobotomy_ | there is in libs/ an libclj*.jar, which was put there by the lein deps |
| 13:29 | lobotomy_ | and the ./lazybot script says something like java -cp lib/*:... so it should notice it too |
| 13:31 | amalloy | works for me |
| 13:31 | mdeboard` | works on my machine* |
| 13:32 | amalloy | fresh clone of lazybot with lein 1.5.2 |
| 13:32 | lobotomy_ | lein 1.5.2... hmm, i have 1.4.2 |
| 13:33 | technomancy | lobotomy_: lib/* requires java 6 |
| 13:37 | lobotomy_ | i have java 1.6.0_26 |
| 13:42 | lobotomy_ | lein 1.6.1 and ./lazybot gives the same error... sigh |
| 13:43 | lobotomy_ | but now "lein jar" gives a different one: Exception in thread "main" java.security.AccessControlException: access denied (java.lang.RuntimePermission modifyThread) (NO_SOURCE_FILE:1) |
| 13:54 | lobotomy_ | but why does "lein swank" work when "./lazybot" doesn't. ps aux|grep java tells me that with "lein swank", the full command line includes "-classpath <long list of jars including lib/irclj*.jar>". but the ./lazybot script should also do that, with the -cp thing... arrrgh |
| 13:55 | lobotomy_ | fucking hell, i'll soon start programming in c, this java+clojure+leiningen+whatever bullshit is just ridiculous |
| 13:55 | lobotomy_ | and i'll link all the libs statically too! so there |
| 13:56 | mdeboard` | lobotomy_: Calm down :P I agree it is frustrating working with the JVM |
| 13:57 | mdeboard` | sometimes* |
| 14:00 | lobotomy_ | well, i'd just like to know exactly how to debug this mess |
| 14:00 | lobotomy_ | is there a "clojure classpath & class loader basics for dummies" guide somewhere? |
| 14:01 | mdeboard` | lobotomy_: You ARE developing in WinXP right??? |
| 14:01 | lazybot | mdeboard`: Oh, absolutely. |
| 14:01 | lobotomy_ | hmm... "lein repl" starts up, gives the same exception (can't find irclj*), but still starts up; but then i enter anything into the repl and it says java.security.AccessControlException: access denied (java.lang.RuntimePermission createClassLoader) |
| 14:02 | mdeboard` | lobotomy_: Are your permissions set properly? |
| 14:02 | lobotomy_ | apparently not |
| 14:15 | lobotomy_ | amalloy, so the newest lazybot is working for you... could you list exactly what you did (which commands) to try it out? |
| 14:15 | mdrogalis | Is anyone planning to write a book or longer tutorial about Conjure? |
| 14:16 | amalloy | $ git clone git@github.com:flatland/lazybot.git tmp-lazy; cd tmp-lazy; lein deps; ./lazybot |
| 14:16 | mdeboard` | mdrogalis: Get Joy of Clojure, and/or Practical Clojure |
| 14:17 | mdrogalis | Okay, thanks mdeboard! |
| 14:17 | amalloy | mdrogalis: did you really mean Conjure? |
| 14:17 | gtklocker | Hello |
| 14:17 | amalloy | i don't think conjure is very popular |
| 14:17 | mdrogalis | Yeah, amalloy |
| 14:18 | mdrogalis | Really? Does it not get much pull for web frameworks, then? |
| 14:19 | amalloy | no, not really. depending on where you want the tradeoff between magic and control, most people use noir or compojure |
| 14:19 | lobotomy_ | amalloy, and you have leiningen 1.5.2 and java... what? |
| 14:19 | lobotomy_ | amalloy, the first command there is hopefully equivalent to "git clone git://github.com/flatland/lazybot.git tmp-lazy" |
| 14:20 | amalloy | lobotomy_: yes, though note that git@github.com works even if you don't have commit rights |
| 14:20 | amalloy | java version "1.6.0_20"; OpenJDK Runtime Environment (IcedTea6 1.9.9) (6b20-1.9.9-0ubuntu1~10.04.2); OpenJDK Client VM (build 19.0-b09, mixed mode, sharing) |
| 14:21 | lobotomy_ | Permission denied (publickey). <- no it doesn't :p |
| 14:21 | whidden_ | Is list all callers C-c C-w c, a slime function, not working for clojure? |
| 14:21 | amalloy | well, you have to have a key with github |
| 14:21 | amalloy | whidden_: probably not |
| 14:21 | lobotomy_ | i have leiningen 1.6.1 and java 1.6.0_24 (official sun thing) |
| 14:21 | lobotomy_ | and, yeah, it doesn't work |
| 14:22 | whidden_ | <sigh>, if only I had another 36 more hours to the day, i'd try to fix that... oh well. |
| 14:23 | amalloy | whidden_: you'd need to fix it on the swank side, which i suspect would be pretty complicated |
| 14:23 | amalloy | in the meantime, M-x find-grep is good enough most of the time :P |
| 14:23 | lobotomy_ | git clone git://github.com/flatland/lazybot.git tmp-lazy ; cd tmp-lazy ; lein deps ; ./lazybot # crashes due to not finding irclj |
| 14:24 | whidden_ | yeah, find-grep is our friend. |
| 14:24 | technomancy | whidden_: there's some who-calls support in swank-clojure, but it's a bit rudimentary |
| 14:25 | technomancy | (I didn't write it) |
| 14:25 | amalloy | lobotomy_: lib/ should contain irclj-0.4.0-20101122.230502-4.jar |
| 14:26 | whidden_ | technomancy: ok, i'll just stick with find-grep for now. |
| 14:26 | amalloy | (though wouldn't it be nice if Raynes ever released a non-snapshot version) |
| 14:27 | lobotomy_ | other machine with java 1.6.0_26 (64 bit) does the same thing |
| 14:28 | lobotomy_ | 10597 2011-08-25 21:27 lib/irclj-0.4.0-20101122.230502-4.jar |
| 14:28 | lobotomy_ | that's there on both machines, lein deps fetches it |
| 14:29 | lobotomy_ | what else... both machines are running ubuntu |
| 14:29 | lobotomy_ | 9.10 for the java 1.6.0_24 one and 10.04 LTS for the newer 64-bit one |
| 14:33 | scottj | anyone know if clojure will ever automatically change maps into PersistentTreeMaps? |
| 14:34 | cemerick | those are for sorted maps |
| 14:34 | amalloy | scottj: huh? |
| 14:34 | S11001001 | scottj: it's extremely unlikely |
| 14:35 | scottj | amalloy: I'm using congomongo 1.4 and it was giving me them |
| 14:35 | amalloy | S11001001: yes, i guess that's a good answer even though i don't understand the question. any way you read it it's not likely to happen |
| 14:37 | scottj | cemerick: ahh I was looking for PTM in the code but will search for sorted |
| 14:37 | amalloy | scottj: i can't think of a reason for it to sort things for you, but i also can't see why it would matter if it did |
| 14:37 | cemerick | scottj: You almost certainly shouldn't care about the implementing class. |
| 14:38 | scottj | amalloy: if you ask PTM's about a key with the wrong type you get an exception instead of nil, as opposed to other map types |
| 14:38 | amalloy | cemerick: say, do you know why sorted maps don't have a transient mode? is it somehow technically unfeasible, or just too much work to implement? |
| 14:38 | scottj | cemerick: that's what I thought, but turns out not in this case |
| 14:39 | scottj | &((assoc (clojure.lang.PersistentTreeMap/EMPTY) :a 1) "a") |
| 14:39 | lazybot | java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String |
| 14:39 | amalloy | scottj: well, that depends on the comparator you use for your sorted map |
| 14:39 | cemerick | scottj: keys in sorted maps or sets need to be comparable |
| 14:39 | scottj | &((assoc {} :a 1) "a") |
| 14:39 | lazybot | ⇒ nil |
| 14:40 | scottj | cemerick: in which case you have to care about it |
| 14:40 | amalloy | but sure, fair enough |
| 14:40 | cemerick | scottj: you have to care about the semantics of the data structure, *not* its implementing class |
| 14:41 | cemerick | amalloy: I don't know right off. Probably more like, no one's gotten around to it. |
| 14:41 | cemerick | I know a fair bit of the transients impl. was done by cgrand, so it may simply be a matter of someone stepping up. |
| 14:41 | dnolen | amalloy: I think the goal was to have transients for all the current persistent data structures. |
| 14:42 | dnolen | sadly Clojurists are not as avid about putting new data structures together as the Scalaists |
| 14:42 | amalloy | hah |
| 14:42 | amalloy | we have hash maps, who needs data structures |
| 14:42 | cemerick | Someone could probably knock them out using deftype in fairly short order. |
| 14:42 | ibdknox | (inc amalloy) ;) |
| 14:42 | lazybot | ⟹ 1 |
| 14:43 | dnolen | amalloy: that really is part of the problem. you can go really far with the core data structures even if they are not always ideal. |
| 14:44 | amalloy | dnolen: yeah, that wasn't all a joke |
| 14:44 | ibdknox | dnolen: this is a problem with any language I think, though |
| 14:45 | dnolen | ibdknox: I dunno. Haskell and Scala seem to have data structures for every occasion. |
| 14:45 | mdrogalis | I'm trying to make a function that generates an infinite sequence of numbers, 1 to infinity |
| 14:45 | amalloy | ibdknox: what? nothing's ever stopped java developers from writing more classes |
| 14:45 | mdrogalis | Why does this cause a stack overflow? http://pastebin.com/fnM1EkNF |
| 14:45 | amalloy | (iterate inc 1) |
| 14:45 | ibdknox | dnolen: they may have many of them |
| 14:45 | mdrogalis | I wanted to write a function for it, amalloy. :) |
| 14:45 | ibdknox | dnolen: how often do they get used? |
| 14:45 | mdrogalis | Just to play with constructing an infinite sequence |
| 14:45 | ibdknox | dnolen: you have to first teach people what a finger tree is before they'll use it |
| 14:45 | dnolen | ibdknox: precisely when you need them which always at the worst time ;) |
| 14:46 | amalloy | $google dbyrne stackoverflow prime sequence |
| 14:46 | lazybot | [recursion - Recursive function causing a stack overflow - Stack ...] http://stackoverflow.com/questions/2946764/recursive-function-causing-a-stack-overflow |
| 14:46 | ibdknox | haha |
| 14:46 | amalloy | mdrogalis: ^ is why |
| 14:46 | mdrogalis | Thanks amalloy! Ill read it now |
| 14:46 | ibdknox | amalloy: I meant more that people won't use them even if they're there, simply because they don't know what they are, or often, know enough to look for something else |
| 14:48 | mdrogalis | amalloy: My function doesn't use filter |
| 14:48 | amalloy | mdrogalis: you also seem to be mixing data types. a has to be a seq in order to concat it, and it has to be a number in order to add it |
| 14:48 | amalloy | it uses concat |
| 14:48 | amalloy | which is also lazy |
| 14:48 | amalloy | but now that i look again, that's not your problem |
| 14:48 | mdrogalis | Ah, yeah that's wrong, amalloy |
| 14:48 | amalloy | your problem is that everything here is evaluated eagerly |
| 14:49 | mdrogalis | What's forcing it to do that? |
| 14:49 | manutter | mdrogalis: how are you calling generate-infinite-seq? |
| 14:49 | mdrogalis | concat? |
| 14:50 | mdrogalis | (take 10 (generate-infinite-seq)) |
| 14:50 | amalloy | no, just the fact that everything is eager unless you say so |
| 14:50 | manutter | ok, I see it |
| 14:50 | amalloy | &(nth ((fn f [n] (concat [n] (f (inc n)))) 1) 1e5) |
| 14:50 | lazybot | java.lang.StackOverflowError |
| 14:50 | manutter | I think I see it |
| 14:50 | amalloy | &(nth ((fn f [n] (lazy-seq (concat [n] (f (inc n))))) 1) 1e5) |
| 14:50 | lazybot | ⇒ 100001 |
| 14:50 | manutter | Isn't concat going to evaluate it's args first? |
| 14:51 | mdrogalis | In short, I'm jut trying to write a function that takes 0 parameters, or 1 parameter. If 0 parameters, join "1" with "2 3 4 5" |
| 14:51 | mdrogalis | If 2 parameters, return "2 3 4 5.." |
| 14:51 | manutter | or rather, clojure is going to evaluate the args to concat before passing them to concat proper |
| 14:51 | mdrogalis | Ah, that's much clearer, manutter |
| 14:51 | mdrogalis | So I need lazy-cat? |
| 14:51 | manutter | sounds like a winner :) |
| 14:51 | amalloy | mdrogalis: that would probably work, but it's not the right answer |
| 14:51 | manutter | I've never used it so I won't vouch for it personally ;) |
| 14:52 | mdrogalis | Right, the types are still wrong |
| 14:52 | amalloy | or, not the idiomatic one |
| 14:52 | amalloy | meh. the issue is more like "you shouldn't be using concat" |
| 14:52 | mdrogalis | I know it's not idiomatic Clojure. I just want to try making an infinite sequence myself. |
| 14:52 | mdrogalis | Why is that? |
| 14:52 | amalloy | mdrogalis: because you're just adding one element to the front of a sequence. that's what cons is for |
| 14:53 | mdrogalis | So I'm really looking for an "append" sort of function? |
| 14:53 | mdrogalis | IE [1 2] + [3] => [1 2 3] |
| 14:53 | ibdknox | ,(doc cons) |
| 14:53 | clojurebot | "([x seq]); Returns a new seq where x is the first element and seq is the rest." |
| 14:53 | manutter | Yeah, I think you might be better off using lazy-seq directly and cons |
| 14:53 | amalloy | no, you're not. you want to put stuff in front |
| 14:53 | amalloy | just like you're doing. but use cons, not concat |
| 14:53 | mdrogalis | I thought that's inefficient? |
| 14:53 | ibdknox | ? |
| 14:53 | mdrogalis | Okay, wait. What's the difference, then? |
| 14:53 | manutter | if you're being lazy, efficiency is not an issue ;) |
| 14:53 | amalloy | &(cons 1 [2]) |
| 14:54 | lazybot | ⇒ (1 2) |
| 14:54 | mdrogalis | Ah. I guess changing the head makes sense, that would be quick.. |
| 14:54 | amalloy | &(concat [1] [2]) |
| 14:54 | lazybot | ⇒ (1 2) |
| 14:54 | amalloy | cons is like the fastest list-building operation there is |
| 14:55 | amalloy | concat has to do a bunch of work, create a lazy seq, look inside some other lazy seqs...cons is just a java constructor invocation |
| 14:55 | mdrogalis | I was in here once and someone told me not to use it because it's low level |
| 14:55 | mdrogalis | Okay. So now I'm really confused. When do I want cons, concat, or lazy-seq? |
| 14:55 | amalloy | mdrogalis: indeed. use (iterate inc 1) instead. but since you want to rewrite low-level operations, use low-level operations :P |
| 14:55 | dnolen | speaking of which, chouser, you never tried using finger trees w/ to represent source when macros have you? |
| 14:56 | mdrogalis | amalloy: Well said. Makes sense. |
| 14:56 | dnolen | writing macros I mean. |
| 14:56 | amalloy | dnolen: compile-time efficiency problems with match? |
| 14:56 | manutter | mdrogalis: so you want cons instead of concat to put them together, and lazy-seq to keep them from generating eagerly |
| 14:57 | amalloy | (inc manutter) |
| 14:57 | lazybot | ⟹ 2 |
| 14:57 | dnolen | amalloy: yeah I think the source of slowness w/ large matches is not the compilation algo, it's the source concatenation. |
| 14:57 | dnolen | we're not doing it very intelligently, but maybe it makes sense to just use a better data structure. |
| 14:58 | mdrogalis | I would have thought that (lazy-seq [1] [2] [3]) would return [1 2 3] |
| 14:58 | mdrogalis | Why's it just return (3)? |
| 14:58 | ibdknox | ,(doc lazy-seq) |
| 14:58 | clojurebot | "([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls. See also - realized?" |
| 14:58 | amalloy | &(do [1] [2] [3]) |
| 14:58 | lazybot | ⇒ [3] |
| 14:59 | mdrogalis | I guess the doc doesn't make sense to me. |
| 14:59 | amalloy | ~source lazy-seq |
| 14:59 | ibdknox | amalloy: that link is broken |
| 14:59 | ibdknox | https://github.com/clojure/clojure/blob/f128af9d36dfcb268b6e9ea63676cf254c0f1c40/src/clj/clojure/core.clj#L557 |
| 14:59 | mdeboard` | Yeah those docs are impenetrable sometimes |
| 15:00 | mdeboard` | worst part of clojure imo |
| 15:00 | amalloy | it expands to, basically, (fn [] [1] [2] [3]), which evaluates the first two for side effects and returns the second |
| 15:00 | amalloy | *third |
| 15:01 | mdrogalis | How is that useful? :/ Im not getting it |
| 15:01 | amalloy | uhh |
| 15:01 | manutter | mdrogalis: look at the docs for lazy-seq on clojuredocs.org |
| 15:01 | amalloy | it's useful for people trying to do things differently than you are |
| 15:01 | mdrogalis | Okay. I think something just isn't clicking about manipulating sequences, is all. |
| 15:01 | amalloy | but generally, don't try to put multiple expressions in a (lazy-seq ...) |
| 15:02 | amalloy | it will just end in tears |
| 15:02 | ibdknox | http://clojuredocs.org/clojure_core/clojure.core/lazy-seq |
| 15:03 | mdrogalis | Ohhh, I think I get it |
| 15:03 | mdrogalis | So lazy-seq generally takes 1 sequence as its argument? |
| 15:03 | manutter | mdrogalis: the argument to lazy-seq is a function body -- when you call (lazy-seq [1] [2] [3]), it's like writing a function (defn lazy-body [] [1] [2] [3]) |
| 15:03 | manutter | oops, cross-talk |
| 15:03 | mdrogalis | Its starting to make sense now |
| 15:03 | clojurebot | Huh? |
| 15:03 | mdrogalis | Its like passing it a generator? |
| 15:03 | amalloy | mdrogalis: it takes an expression, which it later evaluates to produce a sequence |
| 15:04 | mdrogalis | And it only produces that sequence on demand, right? |
| 15:04 | manutter | mdrogalis: that's basically it |
| 15:04 | mdrogalis | That makes much more sense |
| 15:05 | manutter | It does not give you the seq, it gives you a function that gives you a seq |
| 15:05 | mdeboard` | mdrogalis: Functions in Clojure (and lisps in general) only RETURN their final value, aka the value in the tail position. All other values NOT in the tail position (aka not last) simply get evaluated for their side effects. They do not RETURN anything. |
| 15:05 | ibdknox | mdrogalis: lazy seqs are clojure's version of the generator pattern, yes. |
| 15:06 | mdrogalis | Okay, yeah I got'cha now |
| 15:07 | mdrogalis | That cleared up a lot for me, thanks guys! |
| 15:08 | tomoj | a bit weird to say that it gives you a function |
| 15:09 | ibdknox | tomoj: hm? |
| 15:09 | tomoj | unless I misunderstood, that lazy-seq gives you not a seq but a function that gives you a seq |
| 15:09 | ibdknox | ,(type (range 0 3)) |
| 15:09 | clojurebot | clojure.lang.LazySeq |
| 15:10 | tomoj | which is suggestively correct maybe but sounds misleading, since you actually get a seq, and not a function |
| 15:10 | ibdknox | ,(satisfies? iseq (range 0 3)) |
| 15:10 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: iseq in this context, compiling:(NO_SOURCE_PATH:0)> |
| 15:11 | ibdknox | ,(seq? (range 0 3)) |
| 15:11 | clojurebot | true |
| 15:11 | arohner | is there already a bug for a gen-class not paying attention to an :import? |
| 15:11 | tomoj | &(isa? clojure.lang.LazySeq clojure.lang.ISeq ) |
| 15:11 | lazybot | ⇒ true |
| 15:11 | arohner | i.e. (:import foo.Bar) (:gen-class :methods [method [Bar] boolean]) |
| 15:11 | mdeboard` | You're tearing me apart, isa? |
| 15:11 | ibdknox | hahaha |
| 15:12 | cemerick | arohner: That's by design IIRC. All class names in gen-class specs must be fully qualified. |
| 15:12 | arohner | cemerick: why? |
| 15:13 | arohner | if I have an import that matches, why not use it? |
| 15:14 | cemerick | arohner: I can only speculate at the rationale. |
| 15:14 | arohner | cemerick: sigh. Ok, thanks |
| 15:15 | cemerick | gen-class is often used in areas where the class in question hasn't been generated yet — so I can imagine that trying to carefully resolve only those short class names that are available and imported might have made an already-complicated macro even moreso. |
| 15:17 | cemerick | One could write a gen-class+ that addresses that fairly easily. |
| 15:17 | cemerick | (if one were to really care about it, that is) |
| 15:19 | coopernurse | hey folks, I just got a lein build working on a hosted Jenkins service.. cloudbees.com - they have a free tier. (sorry, this sounds like an ad, but I'm just some guy..) |
| 15:19 | technomancy | coopernurse: cool! did you have to install lein yourself? |
| 15:19 | coopernurse | I can share the incantation if anyone is interested.. they basically give you a private EC2 slice, and lein will happily bootstrap |
| 15:20 | coopernurse | technomancy: I followed the guide you had here (sort of) https://github.com/technomancy/leiningen/wiki/Using-Leiningen-with-the-Jenkins-CI-server |
| 15:20 | technomancy | I've contacted cloudbees about getting it preinstalled, but I haven't heard back from them in a while |
| 15:20 | coopernurse | but it turned out to be even easier |
| 15:20 | srid | coopernurse: where can I find details on limitations of their free tier? |
| 15:20 | coopernurse | srid: http://www.cloudbees.com/platform-pricing.cb |
| 15:20 | coopernurse | you get 300 minutes/month |
| 15:20 | coopernurse | on a ec2.small |
| 15:21 | srid | coopernurse: thx. oh, does it require me to pay for the EC2 instances? |
| 15:21 | coopernurse | technomancy: here's the build steps I used: http://i.imgur.com/2fJPG.png |
| 15:22 | srid | given the pain involved in keeping hudson running reliably for more than few days, i'd be inclined to pay for such a service anyway. |
| 15:22 | coopernurse | srid: agreed - it's just one of those things you don't want to deal with.. |
| 15:22 | Hodapp | hmm.... we use Jenkins here and it rarely breaks |
| 15:22 | srid | would be awesome if they visually integrate with github |
| 15:22 | technomancy | coopernurse: lein test! is deps, clean, test fwiw |
| 15:23 | coopernurse | technomancy: ah, thanks |
| 15:23 | srid | its not so much about jenkins breaking as maintaining the whole ecosystem of CI servers. |
| 15:25 | technomancy | there's also travis for OSS CI; very interesting crowdsourced model |
| 15:41 | amalloy | wandering back into a previous conversation, mdrogalis and tomoj, i would say that it gives you a sequence which is backed by a function instead of by data |
| 15:42 | dnolen | nice, Racket recommends someone writing a Clojure compat layer, https://github.com/plt/racket/wiki/Intro-Projects |
| 15:45 | kwertii | anyone heard of Opa? (http://lambda-the-ultimate.org/node/4336) seems like an ideal sort of application for Clojure |
| 15:46 | ska2342 | Hi. Is anyone around who understands the impl of the history of Refs? |
| 15:47 | ibdknox | kwertii: I'm wary of anything that abstracts away that you're programming for the web. Those sorts of things are always very limited |
| 15:48 | kwertii | ibdknox: what do you mean by abstracts away that you're programming for the web? from what I can see, Opa is explicitly about writing web apps and only web apps |
| 15:48 | ibdknox | " aiming to make web programming transparent" |
| 15:48 | ibdknox | maybe I'm reading that wrong |
| 15:49 | kwertii | ibdknox: that means it handles generating boilerplate clientside javascript, validation, XSS protection, database CRUD, etc. for you |
| 15:49 | kwertii | ibdknox: http://opalang.org/ |
| 15:50 | Somelauw | opa sounds funny |
| 15:50 | ibdknox | it means grandfather in German lol |
| 15:50 | amalloy | sounds yiddish |
| 15:50 | gtrak | how do I use the merge-servlet-keys fn in ring.util.servlet? I'm trying to add a middleware that blocks on authentication errors that depends on that |
| 15:50 | kwertii | I don't like the syntax, but it looks like (conceptually) an ideal way to set up web dev. I always hated doing all that redundant boilerplate CRUD code that's 99% exactly the same |
| 15:50 | amalloy | hey, i was right! |
| 15:50 | technomancy | means father in Korean iirc |
| 15:50 | solussd | I guess if anything goes wrong, you can use say 'oopa!' |
| 15:50 | kwertii | amalloy: Yiddish is almost exactly the same as German :p |
| 15:51 | ibdknox | kwertii: rails tries to do this too |
| 15:51 | ibdknox | I've also tried to d oit |
| 15:51 | kwertii | ibdknox: sort of... and fails... |
| 15:51 | ibdknox | eh |
| 15:51 | ibdknox | no real webapp is simple enough to make almost completely declarative |
| 15:51 | ibdknox | which the goal of something that abstracts crud boilerplate |
| 15:51 | ibdknox | is* |
| 15:52 | amalloy | my webserver is just (constantly {:status 404}) |
| 15:52 | ibdknox | haha |
| 15:52 | gtrak | django's admin stuff seems pretty neet, but it's a headache to dig through the layers of abstraction |
| 15:52 | amalloy | seems pretty declarative |
| 15:52 | ibdknox | ^ best programmer ever |
| 15:53 | ibdknox | gtrak: that's how it always is |
| 15:53 | kwertii | ibdknox: consider, say, a user signup page that just collects a username and password. How many times do you have to redundantly declare that in a Rails app (or any other standard web framework)? You have to have a database schema declaration (migration in Rails), a model that maps the db to Ruby, an HTML layer page that shows a box for it, Javascript that validates it on the client, and a controller that glues all of that together. |
| 15:53 | ibdknox | yep |
| 15:53 | Somelauw | ibdknox: In dutch as well :D |
| 15:53 | ibdknox | and you could standardize that |
| 15:53 | ibdknox | but what happens when it needs to be slightly different? |
| 15:53 | kwertii | ibdknox: yeah, 90%+ of that could be autogenerated |
| 15:53 | ibdknox | websites are rarely consistent |
| 15:54 | ibdknox | they're not like applications sadly |
| 15:54 | ibdknox | they're more like interactive images than anything |
| 15:54 | ivan__ | ibdknox: yeah, and its not like a lot of the autogened stuff actaully takes long to write from scratch either |
| 15:54 | kwertii | ibdknox: it's a pareto distribution, 80% of your cases will be the same. do those automatically and the other 20% manually. ideally, instrument the autogenerator to allow you to plug in modification code, something clojure would be good at. |
| 15:54 | ivan__ | its just we have a desire to automate things :P |
| 15:55 | gtrak | I was trying to learn web programming with django a couple years back, I scrapped that and know I'm building everything from scratch with clojure as a learning experiment |
| 15:55 | ibdknox | kwertii: scaffolding is generally frowned upon these days |
| 15:55 | gtrak | too much crap at once |
| 15:55 | ibdknox | gtrak: I bet you'll have a much better understanding of the web as a result |
| 15:55 | ivan__ | that new seam framework uses it, i immediatly stopped looking at it |
| 15:56 | amalloy | gtrak: yes, i like using ring because i can tell exactly what i'm actually doing |
| 15:56 | ivan__ | spring roo... |
| 15:56 | gtrak | yea, that's the plan, though I'm constantly paying the 'new and shiny' context switching overhead |
| 15:56 | gtrak | clojurescript came out and punched me in the face :-) |
| 15:57 | ibdknox | lol |
| 15:57 | ibdknox | gtrak: me too I guess |
| 15:57 | ibdknox | I've spent many years trying to create the ideal web framework |
| 15:57 | kwertii | ibdknox: I'm not sure what you mean by 'scaffolding'. if you mean it in the Rails sense of a code template engine that spits out some templates for you to edit, that's not at all what I mean. I mean an engine that auto-generates stuff at runtime which is parameterizable at runtime. |
| 15:58 | ibdknox | kwertii: I've written that too |
| 15:58 | kwertii | ibdknox: full stack from db to javascript? |
| 15:58 | ibdknox | kwertii: I ended up essentially replacing *all* of the crud functionality it generated at run time |
| 15:58 | kwertii | ibdknox: I would say that means there is some sort of design flaw somewhere :p |
| 15:58 | ibdknox | haha |
| 15:58 | ibdknox | you may think so |
| 15:59 | ibdknox | and I'm sure there were flaws |
| 15:59 | kwertii | ibdknox: I imagine that every step would be potentially customizable, but any given use of it would not need to customize more than 10% or 20% |
| 15:59 | gtrak | functional programming has more possibility of composition than OO anyway |
| 15:59 | dnolen | interesting, kinda suspected, Opa is built by a bunch of French OCaml hackers. |
| 16:00 | dnolen | https://github.com/MLstate/opalang/graphs/languages |
| 16:00 | kwertii | it's 2011 and we still have netsplits? |
| 16:00 | mbac | i know kwertii |
| 16:00 | mbac | wtf |
| 16:01 | ibdknox | kwertii: I'm not sure I agree. In my experience you still need to customize those sorts of components quite a bit |
| 16:01 | mbac | dnolen, is that a breakdown of LOCs in their git rpos? |
| 16:01 | dnolen | mbac: in the opalang repo yeah |
| 16:02 | mbac | wow it's based on ocaml? |
| 16:02 | mbac | opalang |
| 16:02 | kwertii | ibdknox: how about building it in pieces... instead of the Grand Unified Vision, some code that would handle generating Javascript for the client that validates the input and AJAX-syncs it to the database layer, all transparently? |
| 16:02 | dnolen | lang itself seems a bit odd syntax wise, like a JavaScript-y OCaml |
| 16:02 | kwertii | ibdknox: also, without such a framework, you're writing 100% of the code custom anyway, so if you can get that down to 90%, that's a win in some sense |
| 16:03 | mbac | yeah, it's thwarting my expectations |
| 16:03 | pjstadig | f |
| 16:03 | ibdknox | kwertii: some of what you just described is what I'm going to do with pinot |
| 16:03 | pjstadig | oops sorry stray keystroke |
| 16:03 | ibdknox | kwertii: though my goal isn't to create standard forms, just make them very easy to create |
| 16:04 | ibdknox | kwertii: remotes, for example handle abstracting the ajax away |
| 16:04 | kwertii | ibdknox: why Rails owned the market is because it automated 10% of what we were all doing in Struts or something similar.. and struts automated 10% of what we were all doing in manually created JSP stuff.. |
| 16:04 | kwertii | ibdknox: that sounds very cool |
| 16:05 | ibdknox | kwertii: Rails lowered the barrier to entry I think. What they found out in the long run, however, was that they lowered it too far |
| 16:05 | ibdknox | kwertii: I think a library of common components can be built |
| 16:05 | ibdknox | kwertii: I don't think we have the base for such a thing yet though |
| 16:05 | kwertii | ibdknox: they stopped caring about improving it conceptually when they realized they could go around and charge ${ large number} for training and speaking fees |
| 16:06 | kwertii | ibdknox: yeah, it will have to be built up piecemeal and then assembled later |
| 16:06 | ibdknox | what I suspect we'll start to see are libraries that include cljs and clj |
| 16:06 | ibdknox | and you just require those in the right places |
| 16:06 | ibdknox | and the rest is magic |
| 16:06 | lnostdal | clojure needs a hackable reader :> |
| 16:07 | ibdknox | at some level, pinot is an example of that |
| 16:07 | kwertii | ibdknox: a layered system.. there could be a high level Opa-like abstraction on the very top for people who don't care about customization. or, if you do, you can rip that layer off and use the component subsystems yourself, directly.. much like Noir / Compojure / Ring |
| 16:07 | ibdknox | yep |
| 16:08 | ibdknox | but again, those pieces have to exist and they don't currently |
| 16:08 | ibdknox | some of them do |
| 16:08 | kwertii | we really need a Clojure equivalent of AllegroCache |
| 16:09 | kwertii | writing relational database mapping layers to Clojure makes me sad |
| 16:10 | ibdknox | You know, I don't generally here much talk of ClojureScript here. I get the feeling that the people most excited about it are actually outside of the "core" Clojure community. |
| 16:10 | ibdknox | hear* |
| 16:10 | mbac | i know ocaml and scheme what clojure tutorial would speak to me |
| 16:10 | ibdknox | which is interesting to me |
| 16:10 | ibdknox | amalloy: are you excited about cljs? |
| 16:10 | amalloy | ibdknox: meh |
| 16:10 | ibdknox | why? |
| 16:10 | clojurebot | ibdknox: because you can't handle the truth! |
| 16:10 | gtrak | it's still kind of a pain to get that all set up, compared to normal clojure |
| 16:11 | ibdknox | clojurebot: shutup :-p |
| 16:11 | clojurebot | It's greek to me. |
| 16:11 | kwertii | mbac: if you know Scheme already, I'd just jump in at learn-clojure.com or clojure.org and start reading about the software transactional memory |
| 16:11 | hiredman | because a big chunk of the clojure community doesn't do webapps |
| 16:11 | hiredman | they do big data processing apps |
| 16:11 | mbac | oh i don't know THAT much scheme |
| 16:11 | mbac | i know like 100x more ocaml than scheme |
| 16:11 | dnolen | ibdknox: I'm excited but been too busy to play around much with it yet. |
| 16:11 | ibdknox | dnolen: you have more important things to work on ;) |
| 16:12 | kwertii | ibdknox: I haven't heard much about Clojurescript in general. I've long thought that there should be some abstraction layer on top of javascript for doing DOM manipulation stuff in an arbitrary language, since that's the only way you will get non-JS to work on a Microsoft browser. |
| 16:12 | ibdknox | hiredman: based on the state of clojure survey the vast majority of Clojurians are doing websites |
| 16:12 | kwertii | ibdknox: I get the sense that most of those are hobby projects though |
| 16:12 | ibdknox | that's fair |
| 16:12 | pjstadig | ibdknox: or the vast majority of the survey respondents |
| 16:12 | kwertii | ibdknox: hiredman is probably right that most PAID Clojurians are doing data stuff |
| 16:13 | hiredman | ibdknox: the vast majority of professional clojure devs? |
| 16:13 | ibdknox | haha I may be the exception |
| 16:13 | kwertii | ibdknox: you are definitely the exception |
| 16:14 | kwertii | the vast majority of Clojure job ads I've seen are either investment banks / hedge funds, or "we're processing Big Data® in Clojure and we have this nifty Ruby on Rails frontend..." |
| 16:14 | dnolen | ibdknox: there's quite a few web projects written in Clojure. I'm sure if ClojureScript had come out sooner, the Clojure web projects would be using it. |
| 16:14 | ibdknox | dnolen: assuming someone cleans it up some, yeah. Working with it at this point is... rough. |
| 16:14 | ibdknox | the goog.* api's are awful |
| 16:14 | dnolen | ibdknox: the woven guys (FlightCaster) assessed and seem positive about it, which is a good sign. |
| 16:15 | hiredman | actually there is a guy, I forget his name, who wrote a clojure->js compiler months ago and it actually integrates well with existing clojure projects |
| 16:15 | amalloy | ibdknox: i may be more excited when there are decent development tools for cljs |
| 16:15 | hiredman | (crazy as that sounds) |
| 16:15 | mbac | there's no clojure on http://pleac.sourceforge.net/ eh? |
| 16:15 | sjl | I tried Clojurescript one night soon after it first came out… it turned out to be way more painful to actually get something on the screen to play with than, say, coffee script. |
| 16:16 | ibdknox | dnolen: yeah, we're excited about it too. The stuff I've been able to accomplish is encouraging. |
| 16:16 | ibdknox | amalloy: like what? (I'll build them.) |
| 16:16 | kwertii | I am convinced that the single main reason Clojure is not used more in pro web frontends now is that there is no ActiveRecord equivalent easy persistence solution, whereas there are thousands of code monkeys who can throw together a Rails app in a few days. doesn't make economic sense to pay someone to hand-roll a DB mapping layer in Clojure. |
| 16:16 | dnolen | sjl: agreed. Though I think that is readily fixed by something like cljs-watch. |
| 16:16 | amalloy | heh, i know |
| 16:16 | hiredman | https://github.com/zkim/cljs |
| 16:16 | sjl | dnolen: Ah, that definitely didn't exist when I was trying it out, yeah. |
| 16:17 | Somelauw | Where to find clojure job ads anyway? |
| 16:17 | ibdknox | I'll gladly build those sorts of things |
| 16:17 | kwertii | Somelauw: indeed.com |
| 16:17 | ibdknox | if I know what they are |
| 16:17 | ibdknox | I think the cljs-watch at least makes it bearable |
| 16:17 | sjl | The "development mode" instructions on the wiki are just so much stranger and more involved than other foo-to-js languages. |
| 16:17 | ibdknox | sjl: agreed |
| 16:18 | sjl | I have to pull in two separate js files? and goog.require? I just want to use jQuery. |
| 16:18 | ibdknox | well, I make that simpler at least |
| 16:18 | ibdknox | include bootstrap.js, and roll |
| 16:18 | hiredman | sjl: if you look at zkim/cljs it is way simple, it is really too bad using clojurescript with regular clojure got ignored |
| 16:18 | mbac | am i just unable to read or is there really no pleac clojure? |
| 16:18 | mbac | seems like some low-hanging fruit |
| 16:19 | sjl | hiredman: what does this fork change? |
| 16:19 | hiredman | it isn't a fork |
| 16:19 | dnolen | sjl: I'm sure after 2 months CoffeeScript was equally rough ;) |
| 16:19 | hiredman | it is a completely seperate implemention from before clojurescript existed |
| 16:19 | ibdknox | dnolen: I'm actually not sure |
| 16:20 | ibdknox | dnolen: so far the focus for cljs has been on correctness as opposed to experience |
| 16:20 | dnolen | ibdknox: what I mean the lang was sorted enough to be useful. ClojureScript is ahead on that front. |
| 16:20 | sjl | dnolen: Oh yeah, I just think the choice to build on/around Closure is going to add some inescapable painfulness that Coffeescript just doesn't have. |
| 16:20 | sjl | hiredman: Ahh |
| 16:20 | dnolen | sjl: beyond the limitations of what ClojureScript offers as a language sure. |
| 16:20 | ibdknox | yeah |
| 16:21 | dnolen | sjl: I like CoffeeScript, and use it. But it's the same stuff I've been doing for like 7 years now. |
| 16:21 | ibdknox | the problem is that Google Closure isn't a particularly well respected thing in the JS community |
| 16:21 | sjl | I really hope I'm wrong though, because Coffeescript is ugly as sin to me while Clojurescript looks a lot nicer as a language. |
| 16:21 | ibdknox | the result of that is that no one cares, there's no experiential documentation for it |
| 16:22 | dnolen | ibdknox: the JS community ... meh |
| 16:22 | tomoj | good, that gives us a head start |
| 16:22 | tomoj | :P |
| 16:22 | ibdknox | dnolen: I agree |
| 16:22 | dnolen | ibdknox: this part of what I'm going to rail on in my Strange Loop talk :D |
| 16:22 | ibdknox | dnolen: but the lack of experiential documentation *really* hurts a community that hitched their wagon onto it |
| 16:22 | gtrak | is there a swank for cljs? |
| 16:23 | dnolen | ibdknox: oh definitely. function of time. sure I wish things happened faster. |
| 16:24 | ibdknox | dnolen: yeah, I know. Ideally, we just completely abstract closure away and then it doesn't matter. |
| 16:24 | ibdknox | sjl: it *is* a lot nicer. I wrote a basic clone of d3 in maybe 100 lines of CLJS |
| 16:25 | dnolen | ibdknox: my challenge to front end web development. jQuery is too small. SproutCore too big. WTF. Somebody needs to work on that. |
| 16:25 | ibdknox | dnolen: on it. |
| 16:26 | sjl | ibdknox: so for cljs-watch, it says the default output is to "resources/public/cljs/bootstrap.js" |
| 16:26 | ibdknox | sjl: you can change it |
| 16:26 | sjl | Is that the only js file my web server needs to serve, or are there other ones skulking around somewhere that I need to be serving? |
| 16:27 | ibdknox | sjl: just that one |
| 16:27 | sjl | So it dumps Closure, etc all into that one file? That'd be perfect. |
| 16:27 | ibdknox | yes |
| 16:27 | ibdknox | it uses the simple optimization by default |
| 16:27 | ibdknox | which compiles everything into one file |
| 16:28 | ibdknox | you can change it to be like the dev instructions too though if you want it to be faster |
| 16:28 | ibdknox | I generally find it acceptable in terms of compilation time |
| 16:29 | sjl | Cool, I'll have to try it out |
| 16:29 | sjl | So… how do I install this and use it? |
| 16:29 | ibdknox | grab the cljs-watch file and put it on your path |
| 16:29 | ibdknox | as long as you have CLOJURESCRIPT_HOME setup, you're good to go |
| 16:30 | ibdknox | ./cljs-watch starts watching the src/ directory based on wherever it was invoked |
| 16:30 | sjl | CLOJURESCRIPT_HOME is the git clone of the clojurescript repo, right? |
| 16:31 | ibdknox | it's the path to it, yes |
| 16:31 | ibdknox | without a trailing slash |
| 16:32 | ibdknox | and you have to have done script/bootstrap in clojurescript |
| 16:35 | sjl | Dear god, that was so much easier than when I last tried it. |
| 16:35 | ibdknox | haha |
| 16:35 | dnolen | sjl: open source man. |
| 16:35 | ibdknox | for other fun toys |
| 16:35 | ibdknox | look at brepl |
| 16:36 | sjl | dnolen: Yeah, but if I can't even get something on the screen to poke at it it's hard to contribute. |
| 16:36 | scottj | ibdknox: maybe add :output-to to the extended example to make it slightly easier for non-noir people to see specific syntax |
| 16:36 | dnolen | sjl: I agree. I haven't had toyed with CLJS much because of the slow code/compile cycle. |
| 16:37 | ibdknox | scottj: it's the compiler options syntax, but yeah, that would help :) |
| 16:37 | dnolen | ibdknox: did they get our CA? |
| 16:37 | dnolen | your |
| 16:37 | sjl | dnolen: Yeah, though cljs-watch seems to reuse the same JVM so it's not excruciating. |
| 16:37 | ibdknox | dnolen: they did, I'm on the list now |
| 16:37 | dnolen | ibdknox: cool. |
| 16:38 | ibdknox | I'm doing the node knockout this weekend |
| 16:38 | ibdknox | but after that I'll throw a patch together to add it to cljs proper |
| 16:38 | dnolen | ibdknox: gonna write yr knockout in cljs? |
| 16:39 | ibdknox | dnolen: I've thought about it... but given the short time period I'm too worried I'll run into an issue that'll eat all our time |
| 16:39 | dnolen | ibdknox: 48 hours? |
| 16:39 | ibdknox | dnolen: yessir |
| 16:40 | ibdknox | dnolen: doing a multiplayer tower defense game :) |
| 16:40 | scottj | gtrak: nope, there is a swank-js but not sure if any of it is useful from cljs. |
| 16:40 | scottj | ibdknox: I love that game :) |
| 16:40 | neotyk | Good morning everyone! |
| 16:41 | gtrak | ah |
| 16:41 | sjl | ibdknox: Hmm, what I am doing wrong here? $ cljs-watch '{:output-to "public/scripts/test.js"}' |
| 16:41 | gtrak | don't really understand how you can write clojure without slime/swank |
| 16:41 | scottj | gtrak: inferior-lisp |
| 16:41 | ibdknox | sjl: cljs-watch src/ {:output-to "blah" :output-dir "blah"} |
| 16:42 | gtrak | o i c |
| 16:42 | neotyk | cljs-watch? where do I get it from? |
| 16:43 | ibdknox | http://github.com/ibdknox/cljs-watch |
| 16:43 | scottj | ibdknox: is your td game going to be open sourced? |
| 16:43 | neotyk | found it |
| 16:44 | scottj | does anyone else using zsh have to escape the {} to cljs? |
| 16:44 | ibdknox | scottj: I dunno :) We'll have to see how it goes |
| 16:44 | sjl | scottj: Yes |
| 16:44 | scottj | sjl: is it all zsh's or some option we have enabled? |
| 16:44 | ibdknox | scottj: I definitely don't have to on bash |
| 16:45 | sjl | scottj: Not sure, but I'd be surprised if it were an option. |
| 16:45 | mbac | can you use defn to pattern match strings? |
| 16:46 | dnolen_ | mbac: Clojure doesn't have native pattern matching support. But I've been working on that. |
| 16:46 | mbac | hmm |
| 16:46 | dnolen_ | mbac: https://github.com/swannodette/match |
| 16:46 | michaelr525_ | what's your regular clojure news site? I'm updating from http://planet.clojure.in/ |
| 16:46 | scottj | michaelr525_: disclojure.org |
| 16:46 | gtrak | dnolen_, does lisp have native support for anything? |
| 16:47 | scottj | gtrak: lists |
| 16:47 | gtrak | ha, i guess so |
| 16:47 | ibdknox | dnolen_: btw, I'd love to have a chat sometime about what you'd like to see for the web. |
| 16:47 | dnolen_ | mbac: pretty much anything you're using to from another lang is in match and then some. |
| 16:47 | dnolen_ | ibdknox: definitely. |
| 16:48 | dnolen_ | gtrak: well I guess i mean anything in the core clojure library. |
| 16:48 | mbac | hm. can you not define functions with def? |
| 16:48 | mbac | is it defn only? |
| 16:48 | gtrak | you can, ##(def (fn [] "yo")) |
| 16:48 | lazybot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 16:48 | mbac | sorry if this is the wrong place for ultra noob questions |
| 16:49 | scottj | ibdknox: are there multiplayer td's for mobile? I'd pay for that. |
| 16:49 | gtrak | def just binds a var at root level |
| 16:49 | lnostdal | any "verbose mode" for lein? .. it seems stuck doing nothing; using CPU for a while, then 0% |
| 16:49 | mbac | oh. why's def bad? |
| 16:49 | gtrak | mbac, it doesn't work here b/c of the sandbox |
| 16:49 | mbac | oh is fn lambda? |
| 16:49 | ibdknox | scottj: I'm not sure, to be honest lol |
| 16:49 | gtrak | yes |
| 16:49 | scottj | ibdknox: ok, was thinking you could phonegap it |
| 16:49 | ibdknox | scottj: I haven't seen many (any?) actually multiplayer tower defense games |
| 16:50 | scottj | ibdknox: the original(?) starcraft map |
| 16:50 | ibdknox | scottj: yeah if it goes well, we may very well try to do that with it |
| 16:50 | mbac | er, wait, what did you bind (fn [] "yo") to? |
| 16:50 | gtrak | mbac, I forgot to put in the name of the var, like (def myfn (fn [] (body)) |
| 16:50 | ibdknox | scottj: true |
| 16:50 | mbac | haha |
| 16:50 | scottj | ibdknox: multiplayer is how I first played it and spent an entire day strategizing with my freshman roomies on our build order |
| 16:50 | gtrak | my bad |
| 16:50 | ibdknox | scottj: I guess I see that as a step above simple tower defense |
| 16:50 | mbac | why is def considered bad? |
| 16:50 | gtrak | it's not bad |
| 16:50 | ibdknox | scottj: that's in the real-time strategy category for me |
| 16:51 | hiredman | mbac: def is not define |
| 16:51 | gtrak | mbac, why do you consider it bad? |
| 16:51 | mbac | 16:49 < lazybot> java.lang.SecurityException: You tripped the alarm! def is bad! |
| 16:51 | mbac | something gives me a feeling |
| 16:51 | hiredman | mbac: def does not create locals |
| 16:51 | gtrak | haha, lazybot is sandboxed to prevent any globabl state or I/O, that doesn't mean you can't do it in your own code |
| 16:52 | mbac | oh, does def stick things into the toplevel no matter what scope you say it in? |
| 16:52 | gtrak | yes |
| 16:52 | mbac | cool |
| 16:52 | scottj | ibdknox: are you going to go the all game state in a big map + pure functions route? |
| 16:52 | sjl | ibdknox: still no luck. Here's what my session looks like: http://d.pr/etek |
| 16:52 | mbac | why does dynamic scoping exist at all? |
| 16:52 | gtrak | mbac, but the real story is more complicated, you can bind vars thread-locally and unwind them like a stack |
| 16:53 | mbac | is this just to keep it lispy? |
| 16:53 | scottj | btw anyone found a cljs unit testing setup they like? |
| 16:53 | hiredman | mbac: it is useful for repl work |
| 16:53 | mbac | right, why not just have a let that special-cases top-level bindings? |
| 16:53 | hiredman | you can re-def a function without having to re-def all the functions that call it |
| 16:54 | mbac | oh, it's mutable |
| 16:54 | ibdknox | sjl: {:output-to "script/test.js" :output-dir "srcipt/"} |
| 16:54 | sjl | ibdknox: I mean I can just symlink the bootstrap.js script to where I want it, so it's not a huge deal. |
| 16:54 | gtrak | though sometimes when you re-def a def, you get old functions pointing at the value of the var before |
| 16:54 | ibdknox | sjl: yeah, but that should work, so if it doesn't I wanna figure out why :) |
| 16:55 | gtrak | you have to refer to the function you're re-deffing all the time by (var thevar) to avoid that and use late-binding |
| 16:55 | gtrak | or #'thevar |
| 16:55 | hiredman | gtrak: subtly incorrect |
| 16:55 | gtrak | damn, where'd i go wrong? |
| 16:56 | mbac | is defn preferred for defining functions even if you're not defining poly-arity function? |
| 16:56 | amalloy | mbac: yes, for defining top-level functions use defn |
| 16:56 | mbac | i suspect (def a (fun [] "yo")) tickles performance-nazis |
| 16:56 | sjl | ibdknox: Yeah, still no luck |
| 16:57 | amalloy | mbac: huh? why? |
| 16:57 | ibdknox | sjl: I wonder if the escaping screws it up somehow |
| 16:57 | gtrak | oh, the definition of defn is more complex than I expected |
| 16:57 | mbac | amalloy, don't performance-nazis freak out about unnecessary closures? :) |
| 16:58 | wwmorgan | Is there a ring wrapper that takes URL parameters like foo[0]=bar&foo[1]=baz and turns it into { "foo" ["bar", "baz" } ? |
| 16:58 | sjl | ibdknox: I tried just passing all the options as a big old string, but that doesn't help either |
| 16:58 | gtrak | wth is it doing? |
| 16:58 | mbac | (i expect defn does some magic to avoid the closure, but have no idea) |
| 16:58 | michaelr525_ | after reading this: http://blog.jayfields.com/2011/08/clojure-partition-by-split-with-group.html |
| 16:58 | amalloy | (a) no, they don't; (b) neither of those is a closure |
| 16:58 | ibdknox | sjl: I used the same function that clojurescript's cljsc uses |
| 16:58 | michaelr525_ | Isn't the separate function from clojure.contrib.seq iterates over the seq twice? |
| 16:58 | amalloy | (that is, neither a def/fn version nor a defn version |
| 16:59 | ibdknox | sjl: to grab those options |
| 16:59 | ibdknox | sjl: can you try it too |
| 16:59 | ibdknox | clojurescript/bin/cljsc ../samples/hello/ {:output ...} |
| 16:59 | amalloy | mbac: (fn [] "a") has no free variables, only free constants; "a" is embedded into the generated class |
| 17:00 | mbac | oh, you're right. |
| 17:00 | amalloy | and closures are super-cheap anyway; you get more performance benefit from using them to close over constant expressions than you lose from having to call a few more constructors |
| 17:01 | sjl | ibdknox: cljsc works |
| 17:01 | wwmorgan | FYI: got it, it's wrap-nested-params |
| 17:01 | ibdknox | sjl: k, I will have to figure that out then. |
| 17:01 | ibdknox | sjl: can't do it right this second, but I'll have a fix by tonight |
| 17:02 | sjl | ibdknox: It's cool, I'm not using clojurescript for anything important at the moment, just poking around. No rush. |
| 17:02 | sjl | My Clojure Minecraft bot framework is eating up all the free time I have to play with Clojure-related things anyway, hah. |
| 17:03 | ibdknox | hehe :) |
| 17:03 | mbac | i really like the stylish use of vectors in clojure |
| 17:03 | mbac | breaks up the parenthetical monotony |
| 17:04 | michaelr525_ | ,(require 'clojure.repl ) |
| 17:04 | clojurebot | nil |
| 17:04 | ibdknox | sjl: clojurecraft certainly does look like fun, so I don't blame you |
| 17:04 | sjl | ibdknox: It's very fun, just lots to do to make it useful/practical |
| 17:04 | michaelr525_ | ,(require 'clojure.contrib.seq) |
| 17:04 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate clojure/contrib/seq__init.class or clojure/contrib/seq.clj on classpath: > |
| 17:05 | michaelr525_ | ,(require 'clojure.contrib.seq-utils) |
| 17:05 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate clojure/contrib/seq_utils__init.class or clojure/contrib/seq_utils.clj on classpath: > |
| 17:05 | michaelr525_ | err sorry\ |
| 17:05 | gtrak | mbac, wait till you get to destructuring |
| 17:06 | michaelr525_ | This function really bothers me: http://clojuredocs.org/clojure_contrib/clojure.contrib.seq/separate |
| 17:06 | michaelr525_ | Isn't the sequence iterated twice here? It doesn't seem to be performance wise.. |
| 17:06 | gtrak | michaelr525, it's lazy |
| 17:06 | amalloy | michaelr525_: it's surprisingly difficult to iterate the sequence only once |
| 17:07 | michaelr525_ | amalloy: using a for loop in c for example |
| 17:07 | gtrak | hopefully whatever you're doing to the data is more complex than an iteration step |
| 17:07 | amalloy | because you can't just mutate the lazy-seq returned by (remove) when the one returned by (filter) discovers that the predicate doesn't pass |
| 17:08 | michaelr525_ | I haven't been writing code in C for years, but when I see something like this it bothers me :) |
| 17:08 | gtrak | michaelr525, how would you even do it in C? make copies? |
| 17:08 | gtrak | that seems much worse |
| 17:09 | gtrak | this is a clean, lazy, functional approach |
| 17:09 | michaelr525_ | well, suppose that you have immutable collections in C, it would be same as in clojure except that it would be iterated only once |
| 17:10 | gtrak | you're really not thinking this through |
| 17:10 | amalloy | michaelr525_: except it wouldn't be lazy |
| 17:10 | mbac | grak, ? |
| 17:10 | michaelr525_ | amalloy: ok, let's say that these immutable C sequences are lazy as well :) |
| 17:11 | mbac | destructuring-bind? |
| 17:11 | gtrak | mbac, something like that, yes |
| 17:11 | amalloy | michaelr525_: that's my point! C would have the same problem then - you couldn't do it |
| 17:11 | amalloy | try it. pretend you have immutable lazy sequences in C, and split an input sequence up based on a predicate. you can't do it |
| 17:12 | amalloy | you could do it eagerly in clojure if you wanted, by using doall to force everything before you return it |
| 17:12 | michaelr525_ | hmm |
| 17:12 | hiredman | if the language was lazy (not just seqs) you could do it as a reduce |
| 17:13 | amalloy | hiredman: really? i guess i'm not used to thinking that lazily |
| 17:13 | amalloy | how would it work in, say, haskell? |
| 17:14 | amalloy | michaelr525_: it annoyed me too, so i wrote https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L23 |
| 17:15 | amalloy | which transforms the input to make sure the predicate is only called once per item, but now it traverses the input seq three times |
| 17:15 | hiredman | (reduce (fn [[t f] e] (if (pred e) [(conj t e) f] [t (conj f e)])) [[] []] ...) |
| 17:15 | michaelr525_ | amalloy: how about something like this: |
| 17:15 | michaelr525_ | while( seq.next ){ if( seq.val is odd ) add to collection1 else add to collection2 } |
| 17:16 | michaelr525_ | pseudo c\ ;) |
| 17:16 | amalloy | michaelr525_: you forgot "immutable" |
| 17:16 | amalloy | how do you implement "add to ___"? |
| 17:17 | michaelr525_ | well, "it just works" :) |
| 17:17 | amalloy | good luck with that |
| 17:18 | michaelr525_ | amalloy: i can't understand what is the principal problem doing it? |
| 17:18 | gtrak | ah, C just works so good, why don't we all use it? |
| 17:19 | leeda | with leiningen, how can i specify the type of a dependency as "pom"? /cc @technomancy |
| 17:20 | michaelr525_ | hiredman: so is this solution faster than the elegant one with two filters? |
| 17:20 | hiredman | michaelr525_: no idea, and it's not lazy at all in clojure |
| 17:20 | amalloy | michaelr525_: it's a solution that would only work if clojure were inherently lazy like haskell is. in clojure as it is now, hiredman's solution eagerly constructs both input seqs immediately |
| 17:20 | amalloy | *output |
| 17:21 | michaelr525_ | hmm i see |
| 17:21 | amalloy | michaelr525_: your solution involved mutating sequence B while you traverse sequence A - discarding immutability. you can discard laziness instead, if you want, but in an eager language you can't create two lazy outputs from the same input without either either mutation or multiple iteration |
| 17:21 | michaelr525_ | what causes the evaluation of the seq? |
| 17:21 | leeda | technomancy: or, is it possible to just specify this: https://gist.github.com/a0ebc8b00fda0db6d831 as a dependency? :P |
| 17:22 | gtrak | leeda, anything is possible with robert-hooke |
| 17:22 | amalloy | pft |
| 17:22 | michaelr525_ | hehe |
| 17:22 | leeda | gtrak: heh |
| 17:23 | hiredman | michaelr525_: anything that isn't lazy |
| 17:23 | hiredman | (e.g. if it doesn't return a lazy-seq it will most likely force at least some part of a lazy-seq) |
| 17:23 | amalloy | i think the answer to his specific question in this case was "reduce forces the whole input sequence" |
| 17:23 | michaelr525_ | reduce is lazy, no? |
| 17:23 | hiredman | no |
| 17:24 | michaelr525_ | ah |
| 17:24 | hiredman | there is no way to make reduce lazy in a non-lazy language |
| 17:24 | gtrak | how does haskell do it? |
| 17:24 | michaelr525_ | why clojure is not fully lazy? |
| 17:24 | hiredman | haskell is lazy |
| 17:24 | technomancy | leeda: dependencies must be in maven repositories, if that's what you're asking |
| 17:24 | gtrak | i would think the inherent nature of reduce, turning a vector value into a scalar, can't be lazified |
| 17:25 | hiredman | michaelr525_: there are a set of tradeoffs around laziness, but the simplest answer is java interop |
| 17:25 | technomancy | gtrak: laziness in clojure is only for seqs, but for haskell it applies to any value |
| 17:25 | leeda | technomancy: yeah, i'm trying to specify javax.media/jai_core "1.1.3" as a dependency, but it doesn't seem to be working |
| 17:25 | leeda | technomancy: i found this article: http://sahits.ch/blog/?p=1038 |
| 17:25 | hiredman | gtrak: if a process proceeds by the application of functions, and those functions are lazy, the process is lazy |
| 17:26 | gtrak | hiredman, can't you just wrap all that in closures and make it lazy? |
| 17:26 | technomancy | leeda: gross. did you try :type "pom"? |
| 17:26 | leeda | technomancy: which seems to say that i need to specify the dependency type as "pom" (<dependency>...<type>pom</type></dependency>) |
| 17:26 | michaelr525_ | is there an irc program with a reversed flow - from the top down? |
| 17:26 | leeda | technomancy: but where would i put that? |
| 17:26 | michaelr525_ | I get tired always looking down at the newest text |
| 17:26 | technomancy | leeda: in the dependency vector |
| 17:26 | hiredman | gtrak: you would effectively be writing a lazy sub language unable to interop easily with the rest of the language |
| 17:26 | leeda | [javax.media/jai_core "1.1.3" {:type "pom"}]? |
| 17:27 | leeda | technomancy: ^ |
| 17:27 | gtrak | ah, but that would suffice, that's how ring does its middlewares |
| 17:27 | technomancy | leeda: lose the brackets and you're set |
| 17:27 | technomancy | err--the braces |
| 17:27 | technomancy | curlies |
| 17:27 | leeda | ah ok |
| 17:28 | leeda | technomancy: awesome, looks like that worked. thanks! |
| 17:29 | technomancy | cool |
| 17:30 | gtrak | if we have immutable structures, it wouldn't be too hard to make a lazify and deref macro to go with it |
| 17:31 | technomancy | sure, it's called delay |
| 17:32 | technomancy | just need all consumers ever to call force |
| 17:33 | technomancy | (doseq [n (all-ns) [_ v] (ns-map n)] (alter |
| 17:33 | hiredman | all the time, before everything |
| 17:33 | gtrak | i think non-lazy is a sane default for reasoning about a program, no? |
| 17:33 | technomancy | -var-root v (fn [f] (fn [o & args] (apply o (map force argsr))))) |
| 17:33 | technomancy | tada! |
| 17:34 | gtrak | technomancy, that makes me afraid |
| 17:34 | technomancy | gtrak: I had to split it into two IRC messages because a single one could not contain SO MUCH POWER |
| 17:34 | technomancy | much like the Killer Joke that had to be translated one word at a time |
| 17:36 | gtrak | my god |
| 17:37 | gtrak | does the universe explode if you run that on clojure.core? |
| 17:37 | technomancy | sure, FSVO universe |
| 17:37 | hiredman | yes |
| 17:38 | technomancy | considering it doesn't check for ifn? first, absolutely. |
| 17:44 | leeda | technomancy: another question, is it possible to force lein to use a specific repository for a certain dependency? |
| 17:44 | gtrak | so delay all the stuff you're interested in, then make a reader macro to do the force for you |
| 17:45 | amalloy | gtrak: sure, eager is a sane default if you're used to it, just like imperative is. i'm used to eager, so thinking about a lazy language is hard for me; but there was a time when i was used to imperative/mutation too |
| 17:45 | leeda | technomancy: since the one on maven is not working, i want to use a different repository for it |
| 17:45 | leeda | technomancy: but it seems to prefer maven's |
| 17:45 | michaelr525_ | why i can't any longer mark and install packages in package-list-packages? |
| 17:45 | gtrak | amalloy, yea, I've never used haskell so I guess I can't make the judgment |
| 17:45 | michaelr525_ | I an X don't do anytjhin |
| 17:45 | gtrak | I think immutability simplifies things very much |
| 17:47 | michaelr525_ | oh, it's a built in package |
| 17:48 | gtrak | amalloy, the jump from mutability to immutability is not conceptually difficult i think, but it can be hard to persuade someone that it's better and necessary full-on, I'm already persuaded that laziness is better at times, but... it messes with the whole knowing what it's going to do aspect of programming that we rely on so much. Is it not an issue in haskell? |
| 17:48 | leeda | technomancy: ok, never mind, it was my mistake |
| 17:48 | amalloy | (a) i think moving to immutability scares a lot of people; (b) i barely know my way around in haskell, so ask someone else :P |
| 17:49 | michaelr525` | hello |
| 17:49 | gtrak | well, it made me feel all giddy, but i've only spent a few years programming in total |
| 17:50 | technomancy | gtrak: it's a known issue in haskell that you can't easily reason about performance; see http://ro-che.info/ccc/11.html |
| 17:51 | gtrak | ha |
| 17:51 | technomancy | (I really wish that comic had gone for more than 12 strips) |
| 17:51 | hiredman | but in some sense everything has the same issue |
| 17:52 | hiredman | reasoning about performance in the presence of a jit is difficult, etc |
| 17:53 | gtrak | hiredman, yes, so no real-time perf guarantees, but there's a whole bunch of work where the benefits outweigh the costs, for instance, you can't have immutables without a GC or ref-counting at least |
| 17:54 | hiredman | but even the architecture of a cpu is getting to the point where it can be hard to eyeball performance for native code |
| 17:55 | gtrak | on a much smaller scale, though |
| 17:55 | dnolen_ | hiredman: but you can still ballpark it. I dunno, Clojure kind of maps directly to JVM bytecodes almost, so I think reasoning about performance in Clojure is not so hard. |
| 17:55 | technomancy | yeah, that's true. brb; switching to forth. |
| 17:55 | technomancy | =) |
| 17:56 | gtrak | all the cache-optimizing stuff is harder to do |
| 17:56 | dnolen_ | Haskell on the other hand goes through some hardcore transformations. |
| 17:58 | hiredman | dnolen_: it does map really well to jvm bytecode, but what is the performance of the bytecode, hard to tell without profiling |
| 17:59 | gtrak | hickey cares about identity at slices in time though, that's one of the trade-offs |
| 18:00 | dnolen_ | hiredman: I dunno. Java was designed to make typical C++ code run quickly. It's easy to see what going to be fast. mutable fields, method lookup, arithmetic. |
| 18:00 | dnolen_ | C++ looking code. |
| 18:01 | dnolen_ | all those things are preserved in Clojure, since they are the fast path. |
| 18:01 | hiredman | mmm |
| 18:02 | dnolen_ | of course there's weird run time optimizations, like collapsing method calls, but that's just icing. |
| 18:02 | Somelauw | wouldn't dynanicismn make it a bit slower |
| 18:03 | hiredman | dnolen_: by collapsing method calls you mean inlining? |
| 18:03 | dnolen_ | hiredman: yeah |
| 18:03 | gtrak | not terribly 'weird' |
| 18:03 | hiredman | because I am pretty sure every jvm talk I've seen has called that "THE optimization" |
| 18:03 | hiredman | instead of just "icing" |
| 18:04 | hiredman | inlining multiplies the power of other optimizations by giving them more code to work with |
| 18:05 | dnolen_ | hiredman: point is, yes it's hard to reason about the nature of the inlining. But I think it's not hard to see what style of code has the potential to get inlined. |
| 18:06 | hiredman | dnolen_: sure |
| 18:09 | gtrak | dnolen_, it'll run faster than you think it will, not so hard :-) |
| 18:14 | gtrak | there was a cool article about that, something about putting a for-loop body in a separate method can help a lot |
| 18:15 | gtrak | i think b/c it's likely to lower the code in the method under the inlining threshold |
| 18:29 | Somelauw | When doing (let [x 5]) would the clojure compiler infer that x is a static int? |
| 18:32 | Scriptor | Somelauw: infer wouldn't really be the right word, I think |
| 18:33 | Scriptor | x would just be pointing to something that happened to be an int, just like in any other dynamically typed language |
| 18:34 | hiredman | actually for locals create by let you do get type inference |
| 18:34 | hiredman | x would be a primitive long (in 1.3) |
| 18:40 | Somelauw | Scriptor: I though java created ints on the stack like c. |
| 18:41 | hiredman | you asked about clojure, not java |
| 18:41 | amalloy | Somelauw: java puts all locals on the stack. it's just that for pointer-typed locals, it has to allocate an object on the heap for the local to point at |
| 18:43 | Somelauw | So clojure uses an Integer for that by default? |
| 18:43 | Scriptor | exactly |
| 18:43 | hiredman | depends |
| 18:43 | Scriptor | well |
| 18:43 | Scriptor | doesn't it use Long a lot of the time? |
| 18:43 | hiredman | no |
| 18:44 | dnolen_ | Somelauw: 1.2 boxed Integer, not 1.3, unboxed long |
| 18:44 | Somelauw | Go clojure 1.3 :D |
| 18:44 | Scriptor | yea, long, not Long :p |
| 18:44 | dnolen_ | Somelauw: arith perf in 1.3 is stellar with much less type hinting. |
| 18:45 | mbac | how does the jvm tell the difference between immediates and references? does it use a tag bit? |
| 18:45 | amalloy | well, there are still a lot of Longs being used in 1.3 because you pass them around to other functions. but locally you can use primitive longs |
| 18:45 | mbac | oh, maybe there's runtime type information |
| 18:45 | mbac | duh |
| 18:45 | dnolen_ | amalloy: unless of course you're passing them to fns w/ prim signatures. |
| 18:45 | amalloy | sure |
| 18:46 | dnolen_ | like +, -, *, = etc |
| 18:46 | Somelauw | ok thanks |
| 18:46 | amalloy | mbac: java has compile-time and run-time type information. stuff like "is this an int or an object" is done at compile time |
| 18:48 | hiredman | dnolen_: which are likely to be inlined into static method calls by the compiler and then into jadd by the jit |
| 18:48 | dnolen_ | hiredman: :) |
| 18:48 | mbac | amalloy, is the run-time type information for the GC only? |
| 18:48 | amalloy | no, it's mostly to preserve type safety |
| 18:48 | hiredman | if only I did expensive computations on numbers, how fast my programs would be |
| 18:49 | mbac | oh right, casts |
| 18:49 | amalloy | right |
| 18:49 | amalloy | and also virtual/dynamic method dispatch |
| 18:49 | mbac | oh right, inheritance :) |
| 18:50 | Scriptor | so with 1.2 and before with the boxed ints, did variables just store a reference to an Object? |
| 18:51 | dnolen_ | hiredman: Clojure is one giant expensive computation on numbers. |
| 18:51 | hiredman | dnolen_: blah blah blah turning blah blah blah |
| 18:52 | hiredman | turing |
| 18:52 | dnolen_ | all the persistent data structure we love so much ... |
| 18:52 | hiredman | Scriptor: (let [x (int 1)] ...) x is a primitve int |
| 18:55 | Scriptor | as in x is directly placed on the stack as an int? |
| 18:55 | hiredman | depends on the jvm |
| 18:56 | hiredman | x inside that let is equiv to 'int x;' in a java method body |
| 18:56 | Scriptor | ah, got it |
| 18:57 | Scriptor | what if you did (def x 1), I know it creates a Var object, but what does that point to? |
| 18:57 | hiredman | a Long or Integer |
| 18:57 | hiredman | vars hold objects |
| 18:58 | Scriptor | ah, so unboxing won't work with def? |
| 18:58 | Scriptor | meaning, it won't store it as an unboxed long |
| 18:59 | hiredman | right, but you can do (def x 1) … (let [x (int x)] …) … |
| 18:59 | Scriptor | interesting, thanks! |
| 19:04 | amalloy | several times i've seen code like (if (> (count xs) 3) ...), which counts the whole sequence even though it doesn't have to. of course it's not hard to do the short-circuiting manually, but does anyone know of a built-in like (has-more-than 3 xs) that i can point people at? |
| 19:09 | Somelauw | amalloy: Unpacking it in a let? |
| 19:09 | amalloy | huh? |
| 19:12 | Somelauw | Well you don't need to check its length since you can unpack it. Like (let [[a b c & d] 3-elementer] body) |
| 19:14 | Somelauw | Oh wait, that doesn't check its length. nvm. Only if-let does for a single element. |
| 19:21 | ibdknox | does anyone know the implications of the EPL license on Clojure? Does it limit a company in some way? |
| 19:21 | amalloy | Somelauw: that also only works if the length is known at compile time, and is small enough that it's not painful to type out a long destructuring form |
| 19:22 | danlarkin | ibdknox: it limits a company in exactly the ways specified in the license, and no others |
| 19:22 | amalloy | the easiest way to do it is like (if (nthnext xs 2) (...there are at least three elements...)) |
| 19:22 | ibdknox | danlarkin: why thank you for that wonderful response. |
| 19:23 | danlarkin | ask smart questions if you want smart answers :) |
| 19:23 | amalloy | but of course for vectors and other Counted things, that's actually slower than just calling count and comparing |
| 19:23 | danlarkin | sorry, that was a little too mean |
| 19:23 | ibdknox | Yeah |
| 19:24 | ibdknox | definitely encourages people to participate |
| 19:24 | danlarkin | yeah yeah yeah |
| 19:24 | ibdknox | My question was legitimate, this room is full of professional clojure devs who use clojure at a company. I was essentially asking if anyone hit any gotchas with the license. |
| 19:25 | danlarkin | ibdknox: do you have specific concerns about the EPL? or just asking in general |
| 19:25 | ibdknox | I'm trying to make sure it's safe for me to leave Noir as EPL |
| 19:25 | danlarkin | wikipedia has a good summary |
| 19:26 | ibdknox | danlarkin: I've read it. |
| 19:26 | ibdknox | Again, just asking if anyone has hit any issues |
| 19:27 | technomancy | ibdknox: it means no one can distribute modified versions of noir without making them public, which is probably what you want. |
| 19:27 | ibdknox | technomancy: yeah, I thought so too. |
| 19:31 | Somelauw | How about (if (last (take 3 (iterate next seq)))) |
| 19:32 | Somelauw | Nevermind. There is nthnext like you posted. |
| 19:32 | mbac | how does clojure qualify .methodCall foo? |
| 19:32 | mbac | does it figure it out based on the type of foo? |
| 19:33 | mbac | that seems impossible |
| 19:33 | amalloy | Somelauw: and last/take won't work anyway, because the sequence could be [1 2 nil] |
| 19:34 | mbac | i notice, say, .substring works even though i didn't import anything |
| 19:34 | technomancy | mbac: for non-hinted calls it reflects at runtime |
| 19:34 | Somelauw | mbac: I think it is a long sequence of foe getClass getMethods invoke |
| 19:35 | mbac | woa |
| 19:35 | gtrak | mbac, if you turn on reflection warnings, you can see exactly what it infers or doesn't |
| 19:46 | amalloy | mbac: importing has nothing to do with it, in either java or clojure |
| 19:46 | mbac | what does import do, then? |
| 19:47 | amalloy | it just gives you shortcuts for the classnames, when you need to type them, such as to declare a new variable or perform a cast |
| 19:47 | mbac | er? isn't that the same as qualifying names? |
| 19:48 | amalloy | System.out.println(x) works, even though i haven't imported the PrintWriter class of which println is a member |
| 19:49 | mbac | oic |
| 21:37 | gridaphobe | is there any reason to worry about reflection if i'm not doing any java interop? |
| 21:37 | amalloy | no |
| 21:38 | gridaphobe | thanks :) |
| 21:38 | gridaphobe | that's what i thought |
| 22:50 | gstamp | is it possible to type hint a def? I have (def english-analyzer (EnglishAnalyzer. Version/LUCENE_31 #{})) and I'm not sure how it is supposed to be type hinted. |
| 22:54 | gstamp | actually, it looks like if I type hint it where it's used then it works |
| 22:59 | cemerick | gstamp: you hint the var's name |
| 23:00 | amalloy | cemerick: i was just thinking, you could pick up the hint from the init expr in this case, but it would be wrong in general because vars can change, right? |
| 23:00 | gstamp | cemerick: thanks. that seems to work well. |
| 23:01 | cemerick | gstamp: *or* the symbol at the call site — either way. Didn't mean to imply one was necessarily superior. |
| 23:02 | cemerick | amalloy: Yeah, alter-var-root, and then newly-loaded code is not helped at all. |
| 23:02 | cemerick | or binding, or whatever |
| 23:02 | gstamp | cemerick: I imagine in general it would be easier to manage on the var |
| 23:03 | amalloy | okay. just wanted to make sure my hinting fundamentals are halfway solid :P |
| 23:03 | cemerick | gstamp: Certainly easier if you have multiple ambiguous interop usages. Plus, it's reasonable documentation. |
| 23:03 | cemerick | amalloy: :-) |
| 23:04 | cemerick | If you're concerned on that front, make sure you keep an eye on 811. |