#clojure logs

2011-08-25

00:02scottjthe difficulty of getting libraries to compile responses made me appreciate the jvm
00:28dnolenchouser: slides?
01:05leedaHi, if I have a byte-array, how can I tell if it corresponds to a JPG image?
01:05ibdknoxdon't jpegs have a header?
01:06leedaProbably. 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:09nkozaleeda: http://sourceforge.net/projects/jmimemagic/
01:16nkozaif I change an atom inside a dosync block, and the transaction fails.. is the atom reverted to their previous state?
01:29MasseRnkoza: AFAIK yes, but it is later retried
01:29MasseRSO that there are no dirty values anywhere
01:29MasseRNo wait, atom? Not inside transaction afaik
01:30nkozaso if transaction is retried the atom will be mutated again?
01:30MasseROnly refs
01:30MasseRI'd say so
01:30MasseRDon't count on me
01:45amalloygo ahead, count on MasseR
02:18scottjwhere 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:18scottjI don't understand
02:29scottjnm I was in the package reference all this time not the file reference
03:29klutometisThere doesn't appear to be a `transient?' predicate; does any know how I'd fake one?
03:32amalloy&(for [x [{}, (transient {})]] (instance? x clojure.lang.ITransientCollection))
03:32lazybotjava.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Class
03:32amalloy&(for [x [{}, (transient {})]] (instance? clojure.lang.ITransientCollection x))
03:32lazybot⇒ (false true)
03:34klutometisamalloy: Ah, fantastic; thanks.
03:35amalloyklutometis: you can derive these yourself by having a look at ##(supers (class (transient {})))
03:35lazybot⇒ #{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:39klutometisamalloy: 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:40amalloyheh. in java everything's a type, even when that obviously makes no sense
03:40amalloyer, an object. or has a type? i'm kinda sleepy, apparently
03:47klutometisamalloy: 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:12robbe-I have a circular structure (basically conscell with refs), how would I print a ref without the REPL exploding?
04:13robbe-Using format instead of print seems to be a good start.
04:17amalloy&(doc *print-depth*)
04:17lazybotjava.lang.Exception: Unable to resolve var: *print-depth* in this context
04:17amalloy&(doc *print-level*)
04:17lazybot⇒ "; *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:21robbe-Oh, thanks :)
04:28wgethishow to do (length ("hello")) in clojure?
04:46raekwtetzner: (count "hello")
05:02scottj&(get (assoc (clojure.lang.PersistentTreeMap.) :a 1) "from")
05:02lazybotjava.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String
05:03scottjwtf?
05:14thorwil,(get (assoc (clojure.lang.PersistentTreeMap.) :a 1) :a)
05:14clojurebot1
05:14thorwilscottj: how is it supposed to deliver a value for "from", when there is no such key?
05:14scottjis it part of PersistentTreeMap's contract that all keys be the same type? Does clojure never promote maps automatically to PersistentTreeMap?
05:14scottjthorwil, I expected nil
05:15scottj&(get (assoc {} :a 1) "from")
05:15lazybot⇒ nil
05:17thorwilit does seem like clojure.lang.PersistentTreeMap does not like non-keyword keys (?)
05:17scottjno it's fine with them, they just have be the same and you have to request the right one
05:17thorwil,(type (assoc {} :a 1))
05:17clojurebotclojure.lang.PersistentArrayMap
05:18scottj&(get (assoc (clojure.lang.PersistentTreeMap.) "a" 1) "from")
05:18lazybot⇒ nil
05:19robbe-Is there a difference in behaviour with nested dosync blocks vs one big dosync block enclosing all operations?
05:19thorwilic
05:22scottjrobbe-: I don't think so, http://soft.vub.ac.be/~tvcutsem/talks/presentations/STM-in-Clojure.pdf
05:23robbe-Hey, that's my professor.
05:23robbe-:D
05:24thorwilscottj: you don't need the get in front, even
05:25scottjrobbe-: 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:34dhaivatClojure has waaaay too many parentheses. I wrote one web app, and it (in total) had 748 parentheses.
05:36scottjdhaivat: save them, you can recycle them with cut and paste
05:49Chousukedhaivat: have you ever counted the number of parentheses in a java app?
05:50robbe-(or the loc)
05:50robbe-:p
05:50Chousukeyou're likely to have more parens in a typical java app than in a clojure app that does the same thing :P
05:50Chousukethey're just better hidden
05:54scottj(defn write [code, like, this]
05:54scottj (to really, piss, people, off);
05:54scottj)
08:35MasseRDamnit, if clojure would just start up faster, I'd probably write all my tools in it
08:35manutterjark
08:36manutteror nailgun I suppose
08:37MasseRHaving a server running for command line programs seems kinda wrong. Been thinking that though
08:37MasseRHm.. jark seems interesting
08:38manutterYeah me too, if I had more RAM to throw around I probably would think about it some more
08:38MasseROh yeah, that too
08:38MasseRwhat is the memory footprint of jvm/clojure?
08:39bsteuberhow about js startup time?
08:39bsteuberif it's good, why not use clojurescript for your tools?
08:40MasseRopenjdk
08:40MasseRI'm intrigued by it, but not enough to install sunjdk )
08:40MasseR:)
08:43manutterlooks like I'm soaking up just over 500M on a clean start of the jark vm
08:44manutterThat's going to be subject to the params you start the vm with of course.
08:48Chousukeat one point I was running the cake vms persistently at about 32 MB at start
08:48Chousukeit really depends on the JVM parameters
08:50ChousukeI think the default is to preallocate 128MB or something
08:50Chousukethe JVM expects that it will be running something enterprisey for a long time so it optimises for it :P
08:55MasseRHmm... I think I'm going to like jark
08:57manutterjark is kinda fun :)
08:58manutterNo! No! Bad programmer! Close that window and get back to PHP!
08:58manutter*sigh*
08:58MasseRmanutter: I feel you
08:58MasseRFOr a while I laughed. Then I realized I'm in the same boat
09:01agz(-> 1 #(+ % 1)) -> gives me java.lang.Integer cannot be cast to clojure.lang.ISeq
09:01MasseRjark doesn't recognize my -main function :/
09:02agzis it right?
09:02agz(-> 1 inc) -> is just fine
09:02MasseR,(-> 1 #(+ % 1))
09:02clojurebot#<CompilerException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.ISeq, compiling:(NO_SOURCE_PATH:0)>
09:03manutterYou can't use the -> macro with the #() macro, bad things happen
09:03MasseRmanutter: Why is that?
09:04agz,(-> 1 (fn [x] (+ x 1)))
09:04clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: nth not supported on this type: Long>
09:04manutter(macroexpand '(-> 1 #(+ 1 %)))
09:04agzand this why not?
09:04manutterdoh
09:04manutter,(macroexpand '(-> 1 #(+ 1 %)))
09:04clojurebot(fn* 1 [p1__8345#] (+ 1 p1__8345#))
09:04manuttereh, maybe I'm misremembering
09:05agzfeels a bit inconsistent :(
09:05manutterI thought something like this had come up before and that was the answer
09:05manutterbut looks like the cases aren't quite parallel
09:05agzhmm -> can be parallelized? :O
09:06manutterno, wait
09:06agz(don't think so)
09:06dnolenagz: -> is pure syntax transformation. you're pushing anything through anything.
09:06manutterI missed the fn* 1 in the expansion
09:06manutterI was right after all
09:06agzyep but then why not accept the fn -version
09:06dnolen,(-> 1 ((fn [x] (+ x 1))))
09:06clojurebot2
09:06agz,(-> 1 (fn [x] (+ x 1)))
09:06clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: nth not supported on this type: Long>
09:06manutter,(macroexpand '(-> 1 (fn [x] (inc x))))
09:07clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: nth not supported on this type: Long>
09:07dnolenagz: you need to wrap in an extra set of parens.
09:07agzdnolen: what is the special character there? :O
09:07agzdnolen: ohh .. OHHH!!! thx :D
09:07dnolen,(-> 1 (#(% + 1)))
09:07clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
09:07manutterbasically, -> is a macro that re-writes your source code
09:08dnolen,(-> 1 (#(+ % 1)))
09:08clojurebot2
09:08manutterThere we go
09:08manutterI didn't know there was a workaround, but that makes sense
09:08agzyeah it's really cool
09:09agzanother one guys
09:09agzI installed a lots of leiningen stuff
09:09agzand my interpreter "lost" my agents :)
09:10agz(def a (agent [])) (send a conj 1) (await a) <- and no response, interpreter hangs(?) as the thread never finishes
09:10manutterHmm, I've seen that one
09:11agzI've deleted ~/.m2 and just started a plain new clojure 1.2.1
09:11manutterYep, same thing happened to me
09:11agzbut still no
09:11agzmanutter: ohh what was the solution? :O
09:11manutterI ended up re-installing a bunch of stuff, I think my .lein dir and possibly my .m2 dir
09:11manutterclean re-install of the latest lein cleared it up
09:12agzahhaaam
09:12agzso you deleted .lein also?
09:12agz(where lein selfinstall puts stuff??)
09:14MasseR\o/ I broke jark already :D
09:15manutteragz: I believe that's how I fixed it, it's been a few weeks
09:15manutterMasseR: lol, how?
09:16MasseRmanutter: By doing 'jark lein' on a non lein directory
09:16MasseRI can't start the jark vm server anymore
09:16manutteroh, ouch
09:16agzmanutter: thx, i will try it out!
09:17MasseR"exception failure: int_of_string"
09:18manutterMasseR: the vm server isn't hanging around stuck somewhere is it?
09:19MasseRpgrep jark and pgrep jvm both return nothing
09:19manutterhow about "java"?
09:19manutternetstat -lanp | grep 4005
09:19MasseRha! There
09:20MasseRYup, jark lein kills it
09:20MasseREven on a lein project
09:21manutterI've never used jark lein, what's it supposed to do?
09:22MasseRI don't know. That's what I was testing
09:23MasseRBut 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:23MasseR./
09:23MasseR:/
09:25manutterhmm, I'm pretty sure I did a simple "hello world" type jark script, but I don't recall what the exact syntax was.
09:26MasseRhttp://pastebin.com/nmG7xXHZ that's quite as simple as it gets. (The dofoo was for testing)
09:28manutterhow did you run the command?
09:29MasseR./foo.clj and jark foo.clj
09:29manutterI wonder if it matters which dir you start jark from vs which dir you start the script from, hmm...
09:29manutterdid you get any errors or just no output?
09:30MasseRWith 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:31manutterwhen I run your script locally I get "java.io.FileNotFoundException: Could not locate foo__init.class or foo.clj on classpath"
09:32manutteroh, duh, I didn't name it "foo".
09:33manutterThere, with proper naming, I get "Hello world" as my output.
09:33MasseRjark client version 0.4
09:36MasseROdd
09:40manutterI just re-installed and restarted jark, and I get "Hello World" just fine using your code.
09:40manutteropenjdk vs sun-java6?
09:42robbe-Is filter the idiomatic way to find an element in a list?
09:42robbe-I need only one result, so that would be (first (filter ...
09:45MasseRopenjdk
09:46manutterMasseR: I'm on sun-java6, maybe thats the difference?
09:48Somelauwopenjdk 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:49MasseRmanutter: I'll try changing
09:57MasseRNo luck with suns jdk
10:03MasseRIf I prepend the file with a (comment) it doesn't throw any errors
10:46ScorchinIs 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:57gtrakhow would you get to a servlet request attribute from a custom ring middleware?
10:59babilenScorchin: Take a look at sort-by -- For example: (sort-by (columns [:name :sport] YOUR_MAP)) (not necessarily correct, play with it)
11:00babilenScorchin: Err, you probably want to switch :name and :sport -- I'll be back later.
11:01tufflaxbabilen what is that columns fn?
11:03Scorchinbabilen: thanks, will check it out
11:04gtrakoh, I see there's a :servlet-request attribute
11:04tufflaxScorchin 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:05tufflaxseems*
11:06MasseRIs clojureql capable of sqlite btw?
11:07coopernurseMasseR: haven't tried it, but I suspect if you get the right JDBC driver it would work
11:07gtrakclojureql doesn't do any ddl stuff
11:08coopernurseperhaps this one: http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC#UsingSQLiteJDBCwithMaven2
11:10coopernursewhich in project.clj would look like: [org.xerial/sqlite-jdbc "3.6.16"]
11:10coopernurseagain, haven't tried it though..
11:12coopernurselooks 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:14MasseRcoopernurse: xerial?
11:19coopernurseMasseR: yeah, that appears to be one java sqlite driver, which might work with clojureql
11:19lrennI don't suppose I could get some volunteers to run: (java.net.InetAddress/getByName "4294967303")
11:20lrennFor some reason it resolve to an IP for me even though dig/nslookup/etc don't resolve.
11:20lrennalso different on Lion vs. Snow Leopard which is blowing up a test.
11:21coopernurse; user=> (java.net.InetAddress/getByName "4294967303")
11:21coopernurse; #<Inet4Address 4294967303/72.3.199.16>
11:21coopernursethat's on clj 1.2.1 - snow leopard
11:21Fossiuser=> (java.net.InetAddress/getByName "4294967303")
11:21Fossijava.net.UnknownHostException: 4294967303 (NO_SOURCE_FILE:0)
11:21Fossilinux gentoo
11:21lrennSee, wtf?
11:22coopernurselemme try some os tools with that. very ood
11:22Fossi1.6.0_26 Java HotSpot(TM) Client VM
11:22coopernurseodd
11:22coopernurse$ host 4294967303
11:23coopernurse4294967303 has address 72.3.199.16
11:23lrennyeah, host gives me two different ips, then says not found.
11:23coopernursehonestly, I'm not sure what that even means.. what would a dns server do with that
11:23lrennis it converting the string into bytes or something...
11:23coopernursegreat question
11:24coopernursedig resolves it too
11:24lrennhost 42949673034294967303 has address 8.15.7.1174294967303 has address 63.251.179.13Host 4294967303 not found: 3(NXDOMAIN)
11:24FossiHost 4294967303 not found: 3(NXDOMAIN)
11:24Fossidig resolves it for me
11:25manutter,(+ (* 72 256 256 256) (* 199 256 256) (* 3 256) 16)
11:25clojurebot1221002000
11:25manutterinteresting...
11:25Fossistil, what kind of address is that supposed to be?
11:26lrennwhen it resolves, we all resolve it to something different, so i don't think that's it.
11:26lrennit's not supposed to be an address, we have some code that was expecting an UnknownHostException.
11:26lrennOne of our devs upgraded to Lion and the test started failing.
11:27lrennwe all use macs at work, but I checked my linux box on home and it does the same thing Lion is doing (resolves)
11:27coopernurselemme try a linux vps box I have
11:27coopernurseok, interesting
11:28coopernurseit appears to depend on your nameserver
11:28coopernurselinux vps - running bind locally, doesn't resolve
11:28coopernurselinux vm on my mac - hitting a DNS server on my dlink access point - does resolve
11:32lrennthanks guys. i don't want waste anymore of anyones time on it.
11:32lrennstrange though...
11:32Fossithe implementation might have changed
11:32Fossi // if host is an IP address, we won't do further lookup
11:32Fossi if (Character.digit(host.charAt(0), 16) != -1
11:32Fossi || (host.charAt(0) == ':')) {
11:32lrennLion actually resolves it to 0.0.0.7
11:32lrenn:)
11:33Fossithat smells like a fishy bit to me
11:33cemerickDo pull requests always notify everyone that has commit privs on a repo?
11:39Fossilrenn: i would guess it's somehow interpreted as an ipv6 address
11:39Fossiand depending on the machines setup that might resolve or not
11:39lrennFossi: thought of that, but it returns an instance of IPV4
11:39lrenn #<Inet4Address 4294967303/72.3.199.16>
11:39lrenn(even the odd 0.0.0.7)
11:40lrenngotta split, thanks again everyone.
11:45babilenScorchin, tufflax: Ah, sorry - forgot about that. It is : http://paste.debian.net/127362/ -- It is from "The Joy of Clojure" 7.1.2
11:49Scorchinbabilen: I google'd it when I started getting stack traces :)
11:49Scorchinbabilen: but, thanks!
11:50babilenScorchin: 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:51Scorchinbabilen: yup, that's what I'm using :)
11:51Scorchinbut now I've got another issue :/
11:51babilenScorchin: Perfect -- Sorry for the confusion :)
11:52ScorchinI 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:00whidden_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:01arohnerwhidden_: it depends on how your code was called
12:02arohnerusually, 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:03arohnerwhidden_: actually, wait. there are no messages, unless the assertion failed, or you did {:post [(do (println ...) true)]}
12:03whidden_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:04arohnerwhidden_: it's a j.l.AssertionError
12:05arohnerwhat does your assertion look like?
12:07whidden_arohner:
12:07whidden_{:pre [(string? label) (map? resource-map) (or (empty? resource-map) (:map-start-time resource-map))
12:07whidden_ (map? tsk) (:duration tsk) (or (nil? fit-time) (float? fit-time) (integer? fit-time))]
12:07whidden_ :post [(map? %)]}
12:07arohnerwhidden_: do the assertions fire if you call the fn in the repl?
12:07whidden_yes
12:08arohnerwhidden_: so then what's the problem?
12:09whidden_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:10arohnerwhidden_: there isn't a message by default. the assertion just throws the j.l.AssertionError if it fails
12:11arohnerwhidden_: maybe you're not catching the exception? or catching it somewhere you don't intend?
12:11whidden_arohner: <bing!> crap... I see now what is going on when running.. I catch all those errors in one bucket :(
12:11whidden_arohner: catching it in another place and thinking its an entirly different beast... thanks.. mystery solved.
12:11arohnernp
12:20lobotomy_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:20lobotomy_i ran "lein deps" which put an irclj jar into libs/
12:20michaelr525hhey!!
12:21lobotomy_and the ./lazybot does "java -cp lib/*: ..." so it should pick that up?
12:24manutterlobotomy_: are you building a jar file with lein jar?
12:24manutteror lein uberjar
12:25lobotomy_hmm, no, just "lein deps", edit .lazybot/info.clj, then "./lazybot"
12:31pjstadigcemerick: yes they do, but i think you get the option to pare the list
12:31cemerickpjstadig: hrm?
12:31cemerickoh, notifications
12:31pjstadigcemerick: yeah
12:32cemerickpjstadig: how? I don't see any X's, hovers, etc…
12:34lobotomy_ok, "lein jar" from the main lazybot dir gives the same error, irclj not found...
12:34lobotomy_wonder if my lein on this machine is somehow broken. grr
12:34michaelr525Error occurred during initialization of VM Could not reserve enough space for object heap
12:34pjstadigcemerick: yeah never mind...they just show a list of "people to be notified" on the right hand side now
12:35pjstadigi thought they used to be checkboxes
12:35cemerickYeah; it makes me feel a little bad to send a pull request and pop notifications on dozens of people.
12:35technomancythey 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:35technomancynow it's just committers I think, but it's easy for them to turn down the noise if someone's annoyed
12:36cemericktechnomancy: Where's *that* knob? I get a pile of noise from repos I have commit on…
12:36cemerickI think you can only turn them on/off globally, which sucks.
12:37technomancyit's hidden pretty deep iirc
12:38technomancyoh, never mind; I'm thinking of the option to abdicate committership
12:39mbaccurl: (22) The requested URL returned error: 404
12:39mbacFailed to download https://github.com/downloads/technomancy/leiningen/leiningen-2.0.0-SNAPSHOT-standalone.jar
12:39mbac:(
12:39simonjbhi 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:41mdeboard`simonjb: Did you do M-x swank<tab> to see if tab-completion has like a swank-reset ? I believe it does
12:42lobotomy_now on this other machine, "git clone https://github.com/flatland/lazybot.git&quot; is failing with fatal: https://github.com/flatland/lazybot.git/info/refs download error - The requested URL returned error: 403
12:42mdeboard`swank-repl-restart or something
12:42mbacoh that was head in the repo not the stable one
12:42mdeboard`lobotomy_: Use the git:// or git@ directory
12:42mdeboard`imo
12:42simonjbmdeboard`: I'll have a look, thanks!
12:43lobotomy_ok, s/https/git/ indeed works... sigh
12:45simonjbmdeboard`: M-x swank<tab> isn't finding anything
12:45mdeboard`wow did i say git@ directory? ugh
12:45mdeboard`anyway lobotomy_ glad it worked
12:45lobotomy_ok, "lein jar" is giving the same error on this machine as well
12:46lobotomy_so in short, lazybot doesn't seem to compile
12:46mdeboard`simonjb: uh hm, were you in a clojure-mode buffer when you tried it?
12:47simonjbmdeboard`: yes, also tried from the slime-repl buffer -- maybe my swank setup is different from yours?
12:48mdeboard`simonjb: Sounds like you tried to do too much getting emacs configured properly for clojure
12:48lobotomy_(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:48mdeboard`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:49mdeboard`simonjb: All you need is leiningen and clojure mode, really.
12:49mdeboard`lobotomy_: lein takes forever because the jvm takes forever
12:49lobotomy_you mean literally forever?
12:49mdeboard`simonjb: So if you've got like "require swank" or "require slime" somewhere in your .emacs/init.el you're doing it wrong
12:50mdeboard`lobotomy_: Oh. Well, no. :P
12:52simonjbmdeboard`: 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:53mdeboard`yeah that sounds about right
12:53mdeboard`Oh
12:53mdeboard`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:00technomancysimonjb: you should be able to kill the *swank* buffer and re-run M-x clojure-jack-in
13:01mdeboard`Oh yeah, derp. Been awhile since I've clojured anything :-\
13:01tufflaxScorchin 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:03lobotomy_(heh, "lein" does not in fact hang forever, it just takes around 74 seconds to finish)
13:04technomancylobotomy_: probably you are starting up a non-daemon threadpool which shuts itself down after 60s
13:04lobotomy_i am? hmm... ok
13:05technomancyfsvo "you"
13:05lobotomy_this is from the lazybot main dir
13:05simonjbtechnomancy: perfect! thanks very much -- super awesome job on all your clojure tooling by the way!
13:07lobotomy_i see "lein" takes the same 74ish seconds from just my home dir, which has no project.clj in it
13:07lobotomy_so why would lein start a non-daemon threadpool? is my install broken?
13:09technomancyoh, if it's happening in ~ then it must be something else
13:12lobotomy_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:13mdeboard`lobotomy_: I had trouble compiling one of amalloy's project's too :( 4clojure
13:13mdeboard`I say we blame him
13:13mdeboard`well, not compiling. I couldn't get 4clojure to work locally because of some threading issue or another that i can't remember
13:14babilentufflax: thanks
13:18amalloyin fairness, lazybot is more Raynes's than mine
13:18babilentufflax: Indeed, much better.
13:19mdeboard`amalloy: :P
13:19tufflaxbabilen :)
13:20sridis there actually a ring middleware that autocompiles ssas -> css? (google doesn't show any)
13:21lobotomy_amalloy, so how do i compile and/or run lazybot?
13:22amalloylobotomy_: i just use lein swank to start interactive development
13:22amalloyand ./lazybot will launch it externally
13:24lobotomy_ok, wtf. lein swank seems to actually work
13:25lobotomy_./lazybot gives that error it always did (see above)
13:27amalloylobotomy_: that's a lot of text to search to try and find your complaint
13:29lobotomy_git clone https://github.com/flatland/lazybot.git ; cd lazybot ; lein deps ; ./lazybot
13:29lobotomy_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:29lobotomy_there is in libs/ an libclj*.jar, which was put there by the lein deps
13:29lobotomy_and the ./lazybot script says something like java -cp lib/*:... so it should notice it too
13:31amalloyworks for me
13:31mdeboard`works on my machine*
13:32amalloyfresh clone of lazybot with lein 1.5.2
13:32lobotomy_lein 1.5.2... hmm, i have 1.4.2
13:33technomancylobotomy_: lib/* requires java 6
13:37lobotomy_i have java 1.6.0_26
13:42lobotomy_lein 1.6.1 and ./lazybot gives the same error... sigh
13:43lobotomy_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:54lobotomy_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:55lobotomy_fucking hell, i'll soon start programming in c, this java+clojure+leiningen+whatever bullshit is just ridiculous
13:55lobotomy_and i'll link all the libs statically too! so there
13:56mdeboard`lobotomy_: Calm down :P I agree it is frustrating working with the JVM
13:57mdeboard`sometimes*
14:00lobotomy_well, i'd just like to know exactly how to debug this mess
14:00lobotomy_is there a "clojure classpath & class loader basics for dummies" guide somewhere?
14:01mdeboard`lobotomy_: You ARE developing in WinXP right???
14:01lazybotmdeboard`: Oh, absolutely.
14:01lobotomy_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:02mdeboard`lobotomy_: Are your permissions set properly?
14:02lobotomy_apparently not
14:15lobotomy_amalloy, so the newest lazybot is working for you... could you list exactly what you did (which commands) to try it out?
14:15mdrogalisIs anyone planning to write a book or longer tutorial about Conjure?
14:16amalloy$ git clone git@github.com:flatland/lazybot.git tmp-lazy; cd tmp-lazy; lein deps; ./lazybot
14:16mdeboard`mdrogalis: Get Joy of Clojure, and/or Practical Clojure
14:17mdrogalisOkay, thanks mdeboard!
14:17amalloymdrogalis: did you really mean Conjure?
14:17gtklockerHello
14:17amalloyi don't think conjure is very popular
14:17mdrogalisYeah, amalloy
14:18mdrogalisReally? Does it not get much pull for web frameworks, then?
14:19amalloyno, not really. depending on where you want the tradeoff between magic and control, most people use noir or compojure
14:19lobotomy_amalloy, and you have leiningen 1.5.2 and java... what?
14:19lobotomy_amalloy, the first command there is hopefully equivalent to "git clone git://github.com/flatland/lazybot.git tmp-lazy"
14:20amalloylobotomy_: yes, though note that git@github.com works even if you don't have commit rights
14:20amalloyjava 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:21lobotomy_Permission denied (publickey). <- no it doesn't :p
14:21whidden_Is list all callers C-c C-w c, a slime function, not working for clojure?
14:21amalloywell, you have to have a key with github
14:21amalloywhidden_: probably not
14:21lobotomy_i have leiningen 1.6.1 and java 1.6.0_24 (official sun thing)
14:21lobotomy_and, yeah, it doesn't work
14:22whidden_<sigh>, if only I had another 36 more hours to the day, i'd try to fix that... oh well.
14:23amalloywhidden_: you'd need to fix it on the swank side, which i suspect would be pretty complicated
14:23amalloyin the meantime, M-x find-grep is good enough most of the time :P
14:23lobotomy_git clone git://github.com/flatland/lazybot.git tmp-lazy ; cd tmp-lazy ; lein deps ; ./lazybot # crashes due to not finding irclj
14:24whidden_yeah, find-grep is our friend.
14:24technomancywhidden_: there's some who-calls support in swank-clojure, but it's a bit rudimentary
14:25technomancy(I didn't write it)
14:25amalloylobotomy_: lib/ should contain irclj-0.4.0-20101122.230502-4.jar
14:26whidden_technomancy: ok, i'll just stick with find-grep for now.
14:26amalloy(though wouldn't it be nice if Raynes ever released a non-snapshot version)
14:27lobotomy_other machine with java 1.6.0_26 (64 bit) does the same thing
14:28lobotomy_10597 2011-08-25 21:27 lib/irclj-0.4.0-20101122.230502-4.jar
14:28lobotomy_that's there on both machines, lein deps fetches it
14:29lobotomy_what else... both machines are running ubuntu
14:29lobotomy_9.10 for the java 1.6.0_24 one and 10.04 LTS for the newer 64-bit one
14:33scottjanyone know if clojure will ever automatically change maps into PersistentTreeMaps?
14:34cemerickthose are for sorted maps
14:34amalloyscottj: huh?
14:34S11001001scottj: it's extremely unlikely
14:35scottjamalloy: I'm using congomongo 1.4 and it was giving me them
14:35amalloyS11001001: 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:37scottjcemerick: ahh I was looking for PTM in the code but will search for sorted
14:37amalloyscottj: 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:37cemerickscottj: You almost certainly shouldn't care about the implementing class.
14:38scottjamalloy: 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:38amalloycemerick: 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:38scottjcemerick: that's what I thought, but turns out not in this case
14:39scottj&((assoc (clojure.lang.PersistentTreeMap/EMPTY) :a 1) "a")
14:39lazybotjava.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.String
14:39amalloyscottj: well, that depends on the comparator you use for your sorted map
14:39cemerickscottj: keys in sorted maps or sets need to be comparable
14:39scottj&((assoc {} :a 1) "a")
14:39lazybot⇒ nil
14:40scottjcemerick: in which case you have to care about it
14:40amalloybut sure, fair enough
14:40cemerickscottj: you have to care about the semantics of the data structure, *not* its implementing class
14:41cemerickamalloy: I don't know right off. Probably more like, no one's gotten around to it.
14:41cemerickI know a fair bit of the transients impl. was done by cgrand, so it may simply be a matter of someone stepping up.
14:41dnolenamalloy: I think the goal was to have transients for all the current persistent data structures.
14:42dnolensadly Clojurists are not as avid about putting new data structures together as the Scalaists
14:42amalloyhah
14:42amalloywe have hash maps, who needs data structures
14:42cemerickSomeone could probably knock them out using deftype in fairly short order.
14:42ibdknox(inc amalloy) ;)
14:42lazybot⟹ 1
14:43dnolenamalloy: 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:44amalloydnolen: yeah, that wasn't all a joke
14:44ibdknoxdnolen: this is a problem with any language I think, though
14:45dnolenibdknox: I dunno. Haskell and Scala seem to have data structures for every occasion.
14:45mdrogalisI'm trying to make a function that generates an infinite sequence of numbers, 1 to infinity
14:45amalloyibdknox: what? nothing's ever stopped java developers from writing more classes
14:45mdrogalisWhy does this cause a stack overflow? http://pastebin.com/fnM1EkNF
14:45amalloy(iterate inc 1)
14:45ibdknoxdnolen: they may have many of them
14:45mdrogalisI wanted to write a function for it, amalloy. :)
14:45ibdknoxdnolen: how often do they get used?
14:45mdrogalisJust to play with constructing an infinite sequence
14:45ibdknoxdnolen: you have to first teach people what a finger tree is before they'll use it
14:45dnolenibdknox: precisely when you need them which always at the worst time ;)
14:46amalloy$google dbyrne stackoverflow prime sequence
14:46lazybot[recursion - Recursive function causing a stack overflow - Stack ...] http://stackoverflow.com/questions/2946764/recursive-function-causing-a-stack-overflow
14:46ibdknoxhaha
14:46amalloymdrogalis: ^ is why
14:46mdrogalisThanks amalloy! Ill read it now
14:46ibdknoxamalloy: 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:48mdrogalisamalloy: My function doesn't use filter
14:48amalloymdrogalis: 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:48amalloyit uses concat
14:48amalloywhich is also lazy
14:48amalloybut now that i look again, that's not your problem
14:48mdrogalisAh, yeah that's wrong, amalloy
14:48amalloyyour problem is that everything here is evaluated eagerly
14:49mdrogalisWhat's forcing it to do that?
14:49manuttermdrogalis: how are you calling generate-infinite-seq?
14:49mdrogalisconcat?
14:50mdrogalis(take 10 (generate-infinite-seq))
14:50amalloyno, just the fact that everything is eager unless you say so
14:50manutterok, I see it
14:50amalloy&(nth ((fn f [n] (concat [n] (f (inc n)))) 1) 1e5)
14:50lazybotjava.lang.StackOverflowError
14:50manutterI think I see it
14:50amalloy&(nth ((fn f [n] (lazy-seq (concat [n] (f (inc n))))) 1) 1e5)
14:50lazybot⇒ 100001
14:50manutterIsn't concat going to evaluate it's args first?
14:51mdrogalisIn 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:51mdrogalisIf 2 parameters, return "2 3 4 5.."
14:51manutteror rather, clojure is going to evaluate the args to concat before passing them to concat proper
14:51mdrogalisAh, that's much clearer, manutter
14:51mdrogalisSo I need lazy-cat?
14:51manuttersounds like a winner :)
14:51amalloymdrogalis: that would probably work, but it's not the right answer
14:51manutterI've never used it so I won't vouch for it personally ;)
14:52mdrogalisRight, the types are still wrong
14:52amalloyor, not the idiomatic one
14:52amalloymeh. the issue is more like "you shouldn't be using concat"
14:52mdrogalisI know it's not idiomatic Clojure. I just want to try making an infinite sequence myself.
14:52mdrogalisWhy is that?
14:52amalloymdrogalis: because you're just adding one element to the front of a sequence. that's what cons is for
14:53mdrogalisSo I'm really looking for an "append" sort of function?
14:53mdrogalisIE [1 2] + [3] => [1 2 3]
14:53ibdknox,(doc cons)
14:53clojurebot"([x seq]); Returns a new seq where x is the first element and seq is the rest."
14:53manutterYeah, I think you might be better off using lazy-seq directly and cons
14:53amalloyno, you're not. you want to put stuff in front
14:53amalloyjust like you're doing. but use cons, not concat
14:53mdrogalisI thought that's inefficient?
14:53ibdknox?
14:53mdrogalisOkay, wait. What's the difference, then?
14:53manutterif you're being lazy, efficiency is not an issue ;)
14:53amalloy&(cons 1 [2])
14:54lazybot⇒ (1 2)
14:54mdrogalisAh. I guess changing the head makes sense, that would be quick..
14:54amalloy&(concat [1] [2])
14:54lazybot⇒ (1 2)
14:54amalloycons is like the fastest list-building operation there is
14:55amalloyconcat 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:55mdrogalisI was in here once and someone told me not to use it because it's low level
14:55mdrogalisOkay. So now I'm really confused. When do I want cons, concat, or lazy-seq?
14:55amalloymdrogalis: indeed. use (iterate inc 1) instead. but since you want to rewrite low-level operations, use low-level operations :P
14:55dnolenspeaking of which, chouser, you never tried using finger trees w/ to represent source when macros have you?
14:56mdrogalisamalloy: Well said. Makes sense.
14:56dnolenwriting macros I mean.
14:56amalloydnolen: compile-time efficiency problems with match?
14:56manuttermdrogalis: so you want cons instead of concat to put them together, and lazy-seq to keep them from generating eagerly
14:57amalloy(inc manutter)
14:57lazybot⟹ 2
14:57dnolenamalloy: yeah I think the source of slowness w/ large matches is not the compilation algo, it's the source concatenation.
14:57dnolenwe're not doing it very intelligently, but maybe it makes sense to just use a better data structure.
14:58mdrogalisI would have thought that (lazy-seq [1] [2] [3]) would return [1 2 3]
14:58mdrogalisWhy's it just return (3)?
14:58ibdknox,(doc lazy-seq)
14:58clojurebot"([& 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:58amalloy&(do [1] [2] [3])
14:58lazybot⇒ [3]
14:59mdrogalisI guess the doc doesn't make sense to me.
14:59amalloy~source lazy-seq
14:59ibdknoxamalloy: that link is broken
14:59ibdknoxhttps://github.com/clojure/clojure/blob/f128af9d36dfcb268b6e9ea63676cf254c0f1c40/src/clj/clojure/core.clj#L557
14:59mdeboard`Yeah those docs are impenetrable sometimes
15:00mdeboard`worst part of clojure imo
15:00amalloyit expands to, basically, (fn [] [1] [2] [3]), which evaluates the first two for side effects and returns the second
15:00amalloy*third
15:01mdrogalisHow is that useful? :/ Im not getting it
15:01amalloyuhh
15:01manuttermdrogalis: look at the docs for lazy-seq on clojuredocs.org
15:01amalloyit's useful for people trying to do things differently than you are
15:01mdrogalisOkay. I think something just isn't clicking about manipulating sequences, is all.
15:01amalloybut generally, don't try to put multiple expressions in a (lazy-seq ...)
15:02amalloyit will just end in tears
15:02ibdknoxhttp://clojuredocs.org/clojure_core/clojure.core/lazy-seq
15:03mdrogalisOhhh, I think I get it
15:03mdrogalisSo lazy-seq generally takes 1 sequence as its argument?
15:03manuttermdrogalis: 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:03manutteroops, cross-talk
15:03mdrogalisIts starting to make sense now
15:03clojurebotHuh?
15:03mdrogalisIts like passing it a generator?
15:03amalloymdrogalis: it takes an expression, which it later evaluates to produce a sequence
15:04mdrogalisAnd it only produces that sequence on demand, right?
15:04manuttermdrogalis: that's basically it
15:04mdrogalisThat makes much more sense
15:05manutterIt does not give you the seq, it gives you a function that gives you a seq
15:05mdeboard`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:05ibdknoxmdrogalis: lazy seqs are clojure's version of the generator pattern, yes.
15:06mdrogalisOkay, yeah I got'cha now
15:07mdrogalisThat cleared up a lot for me, thanks guys!
15:08tomoja bit weird to say that it gives you a function
15:09ibdknoxtomoj: hm?
15:09tomojunless I misunderstood, that lazy-seq gives you not a seq but a function that gives you a seq
15:09ibdknox,(type (range 0 3))
15:09clojurebotclojure.lang.LazySeq
15:10tomojwhich is suggestively correct maybe but sounds misleading, since you actually get a seq, and not a function
15:10ibdknox,(satisfies? iseq (range 0 3))
15:10clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: iseq in this context, compiling:(NO_SOURCE_PATH:0)>
15:11ibdknox,(seq? (range 0 3))
15:11clojurebottrue
15:11arohneris there already a bug for a gen-class not paying attention to an :import?
15:11tomoj&(isa? clojure.lang.LazySeq clojure.lang.ISeq )
15:11lazybot⇒ true
15:11arohneri.e. (:import foo.Bar) (:gen-class :methods [method [Bar] boolean])
15:11mdeboard`You're tearing me apart, isa?
15:11ibdknoxhahaha
15:12cemerickarohner: That's by design IIRC. All class names in gen-class specs must be fully qualified.
15:12arohnercemerick: why?
15:13arohnerif I have an import that matches, why not use it?
15:14cemerickarohner: I can only speculate at the rationale.
15:14arohnercemerick: sigh. Ok, thanks
15:15cemerickgen-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:17cemerickOne could write a gen-class+ that addresses that fairly easily.
15:17cemerick(if one were to really care about it, that is)
15:19coopernursehey 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:19technomancycoopernurse: cool! did you have to install lein yourself?
15:19coopernurseI can share the incantation if anyone is interested.. they basically give you a private EC2 slice, and lein will happily bootstrap
15:20coopernursetechnomancy: I followed the guide you had here (sort of) https://github.com/technomancy/leiningen/wiki/Using-Leiningen-with-the-Jenkins-CI-server
15:20technomancyI've contacted cloudbees about getting it preinstalled, but I haven't heard back from them in a while
15:20coopernursebut it turned out to be even easier
15:20sridcoopernurse: where can I find details on limitations of their free tier?
15:20coopernursesrid: http://www.cloudbees.com/platform-pricing.cb
15:20coopernurseyou get 300 minutes/month
15:20coopernurseon a ec2.small
15:21sridcoopernurse: thx. oh, does it require me to pay for the EC2 instances?
15:21coopernursetechnomancy: here's the build steps I used: http://i.imgur.com/2fJPG.png
15:22sridgiven 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:22coopernursesrid: agreed - it's just one of those things you don't want to deal with..
15:22Hodapphmm.... we use Jenkins here and it rarely breaks
15:22sridwould be awesome if they visually integrate with github
15:22technomancycoopernurse: lein test! is deps, clean, test fwiw
15:23coopernursetechnomancy: ah, thanks
15:23sridits not so much about jenkins breaking as maintaining the whole ecosystem of CI servers.
15:25technomancythere's also travis for OSS CI; very interesting crowdsourced model
15:41amalloywandering 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:42dnolennice, Racket recommends someone writing a Clojure compat layer, https://github.com/plt/racket/wiki/Intro-Projects
15:45kwertiianyone heard of Opa? (http://lambda-the-ultimate.org/node/4336) seems like an ideal sort of application for Clojure
15:46ska2342Hi. Is anyone around who understands the impl of the history of Refs?
15:47ibdknoxkwertii: I'm wary of anything that abstracts away that you're programming for the web. Those sorts of things are always very limited
15:48kwertiiibdknox: 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:48ibdknox" aiming to make web programming transparent"
15:48ibdknoxmaybe I'm reading that wrong
15:49kwertiiibdknox: that means it handles generating boilerplate clientside javascript, validation, XSS protection, database CRUD, etc. for you
15:49kwertiiibdknox: http://opalang.org/
15:50Somelauwopa sounds funny
15:50ibdknoxit means grandfather in German lol
15:50amalloysounds yiddish
15:50gtrakhow 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:50kwertiiI 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:50amalloyhey, i was right!
15:50technomancymeans father in Korean iirc
15:50solussdI guess if anything goes wrong, you can use say 'oopa!'
15:50kwertiiamalloy: Yiddish is almost exactly the same as German :p
15:51ibdknoxkwertii: rails tries to do this too
15:51ibdknoxI've also tried to d oit
15:51kwertiiibdknox: sort of... and fails...
15:51ibdknoxeh
15:51ibdknoxno real webapp is simple enough to make almost completely declarative
15:51ibdknoxwhich the goal of something that abstracts crud boilerplate
15:51ibdknoxis*
15:52amalloymy webserver is just (constantly {:status 404})
15:52ibdknoxhaha
15:52gtrakdjango's admin stuff seems pretty neet, but it's a headache to dig through the layers of abstraction
15:52amalloyseems pretty declarative
15:52ibdknox^ best programmer ever
15:53ibdknoxgtrak: that's how it always is
15:53kwertiiibdknox: 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:53ibdknoxyep
15:53Somelauwibdknox: In dutch as well :D
15:53ibdknoxand you could standardize that
15:53ibdknoxbut what happens when it needs to be slightly different?
15:53kwertiiibdknox: yeah, 90%+ of that could be autogenerated
15:53ibdknoxwebsites are rarely consistent
15:54ibdknoxthey're not like applications sadly
15:54ibdknoxthey're more like interactive images than anything
15:54ivan__ibdknox: yeah, and its not like a lot of the autogened stuff actaully takes long to write from scratch either
15:54kwertiiibdknox: 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:54ivan__its just we have a desire to automate things :P
15:55gtrakI 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:55ibdknoxkwertii: scaffolding is generally frowned upon these days
15:55gtraktoo much crap at once
15:55ibdknoxgtrak: I bet you'll have a much better understanding of the web as a result
15:55ivan__that new seam framework uses it, i immediatly stopped looking at it
15:56amalloygtrak: yes, i like using ring because i can tell exactly what i'm actually doing
15:56ivan__spring roo...
15:56gtrakyea, that's the plan, though I'm constantly paying the 'new and shiny' context switching overhead
15:56gtrakclojurescript came out and punched me in the face :-)
15:57ibdknoxlol
15:57ibdknoxgtrak: me too I guess
15:57ibdknoxI've spent many years trying to create the ideal web framework
15:57kwertiiibdknox: 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:58ibdknoxkwertii: I've written that too
15:58kwertiiibdknox: full stack from db to javascript?
15:58ibdknoxkwertii: I ended up essentially replacing *all* of the crud functionality it generated at run time
15:58kwertiiibdknox: I would say that means there is some sort of design flaw somewhere :p
15:58ibdknoxhaha
15:58ibdknoxyou may think so
15:59ibdknoxand I'm sure there were flaws
15:59kwertiiibdknox: 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:59gtrakfunctional programming has more possibility of composition than OO anyway
15:59dnoleninteresting, kinda suspected, Opa is built by a bunch of French OCaml hackers.
16:00dnolenhttps://github.com/MLstate/opalang/graphs/languages
16:00kwertiiit's 2011 and we still have netsplits?
16:00mbaci know kwertii
16:00mbacwtf
16:01ibdknoxkwertii: I'm not sure I agree. In my experience you still need to customize those sorts of components quite a bit
16:01mbacdnolen, is that a breakdown of LOCs in their git rpos?
16:01dnolenmbac: in the opalang repo yeah
16:02mbacwow it's based on ocaml?
16:02mbacopalang
16:02kwertiiibdknox: 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:02dnolenlang itself seems a bit odd syntax wise, like a JavaScript-y OCaml
16:02kwertiiibdknox: 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:03mbacyeah, it's thwarting my expectations
16:03pjstadigf
16:03ibdknoxkwertii: some of what you just described is what I'm going to do with pinot
16:03pjstadigoops sorry stray keystroke
16:03ibdknoxkwertii: though my goal isn't to create standard forms, just make them very easy to create
16:04ibdknoxkwertii: remotes, for example handle abstracting the ajax away
16:04kwertiiibdknox: 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:04kwertiiibdknox: that sounds very cool
16:05ibdknoxkwertii: 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:05ibdknoxkwertii: I think a library of common components can be built
16:05ibdknoxkwertii: I don't think we have the base for such a thing yet though
16:05kwertiiibdknox: they stopped caring about improving it conceptually when they realized they could go around and charge ${ large number} for training and speaking fees
16:06kwertiiibdknox: yeah, it will have to be built up piecemeal and then assembled later
16:06ibdknoxwhat I suspect we'll start to see are libraries that include cljs and clj
16:06ibdknoxand you just require those in the right places
16:06ibdknoxand the rest is magic
16:06lnostdalclojure needs a hackable reader :>
16:07ibdknoxat some level, pinot is an example of that
16:07kwertiiibdknox: 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:07ibdknoxyep
16:08ibdknoxbut again, those pieces have to exist and they don't currently
16:08ibdknoxsome of them do
16:08kwertiiwe really need a Clojure equivalent of AllegroCache
16:09kwertiiwriting relational database mapping layers to Clojure makes me sad
16:10ibdknoxYou 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:10ibdknoxhear*
16:10mbaci know ocaml and scheme what clojure tutorial would speak to me
16:10ibdknoxwhich is interesting to me
16:10ibdknoxamalloy: are you excited about cljs?
16:10amalloyibdknox: meh
16:10ibdknoxwhy?
16:10clojurebotibdknox: because you can't handle the truth!
16:10gtrakit's still kind of a pain to get that all set up, compared to normal clojure
16:11ibdknoxclojurebot: shutup :-p
16:11clojurebotIt's greek to me.
16:11kwertiimbac: 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:11hiredmanbecause a big chunk of the clojure community doesn't do webapps
16:11hiredmanthey do big data processing apps
16:11mbacoh i don't know THAT much scheme
16:11mbaci know like 100x more ocaml than scheme
16:11dnolenibdknox: I'm excited but been too busy to play around much with it yet.
16:11ibdknoxdnolen: you have more important things to work on ;)
16:12kwertiiibdknox: 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:12ibdknoxhiredman: based on the state of clojure survey the vast majority of Clojurians are doing websites
16:12kwertiiibdknox: I get the sense that most of those are hobby projects though
16:12ibdknoxthat's fair
16:12pjstadigibdknox: or the vast majority of the survey respondents
16:12kwertiiibdknox: hiredman is probably right that most PAID Clojurians are doing data stuff
16:13hiredmanibdknox: the vast majority of professional clojure devs?
16:13ibdknoxhaha I may be the exception
16:13kwertiiibdknox: you are definitely the exception
16:14kwertiithe 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:14dnolenibdknox: 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:14ibdknoxdnolen: assuming someone cleans it up some, yeah. Working with it at this point is... rough.
16:14ibdknoxthe goog.* api's are awful
16:14dnolenibdknox: the woven guys (FlightCaster) assessed and seem positive about it, which is a good sign.
16:15hiredmanactually 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:15amalloyibdknox: i may be more excited when there are decent development tools for cljs
16:15hiredman(crazy as that sounds)
16:15mbacthere's no clojure on http://pleac.sourceforge.net/ eh?
16:15sjlI 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:16ibdknoxdnolen: yeah, we're excited about it too. The stuff I've been able to accomplish is encouraging.
16:16ibdknoxamalloy: like what? (I'll build them.)
16:16kwertiiI 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:16dnolensjl: agreed. Though I think that is readily fixed by something like cljs-watch.
16:16amalloyheh, i know
16:16hiredmanhttps://github.com/zkim/cljs
16:16sjldnolen: Ah, that definitely didn't exist when I was trying it out, yeah.
16:17SomelauwWhere to find clojure job ads anyway?
16:17ibdknoxI'll gladly build those sorts of things
16:17kwertiiSomelauw: indeed.com
16:17ibdknoxif I know what they are
16:17ibdknoxI think the cljs-watch at least makes it bearable
16:17sjlThe "development mode" instructions on the wiki are just so much stranger and more involved than other foo-to-js languages.
16:17ibdknoxsjl: agreed
16:18sjlI have to pull in two separate js files? and goog.require? I just want to use jQuery.
16:18ibdknoxwell, I make that simpler at least
16:18ibdknoxinclude bootstrap.js, and roll
16:18hiredmansjl: if you look at zkim/cljs it is way simple, it is really too bad using clojurescript with regular clojure got ignored
16:18mbacam i just unable to read or is there really no pleac clojure?
16:18mbacseems like some low-hanging fruit
16:19sjlhiredman: what does this fork change?
16:19hiredmanit isn't a fork
16:19dnolensjl: I'm sure after 2 months CoffeeScript was equally rough ;)
16:19hiredmanit is a completely seperate implemention from before clojurescript existed
16:19ibdknoxdnolen: I'm actually not sure
16:20ibdknoxdnolen: so far the focus for cljs has been on correctness as opposed to experience
16:20dnolenibdknox: what I mean the lang was sorted enough to be useful. ClojureScript is ahead on that front.
16:20sjldnolen: 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:20sjlhiredman: Ahh
16:20dnolensjl: beyond the limitations of what ClojureScript offers as a language sure.
16:20ibdknoxyeah
16:21dnolensjl: I like CoffeeScript, and use it. But it's the same stuff I've been doing for like 7 years now.
16:21ibdknoxthe problem is that Google Closure isn't a particularly well respected thing in the JS community
16:21sjlI really hope I'm wrong though, because Coffeescript is ugly as sin to me while Clojurescript looks a lot nicer as a language.
16:21ibdknoxthe result of that is that no one cares, there's no experiential documentation for it
16:22dnolenibdknox: the JS community ... meh
16:22tomojgood, that gives us a head start
16:22tomoj:P
16:22ibdknoxdnolen: I agree
16:22dnolenibdknox: this part of what I'm going to rail on in my Strange Loop talk :D
16:22ibdknoxdnolen: but the lack of experiential documentation *really* hurts a community that hitched their wagon onto it
16:22gtrakis there a swank for cljs?
16:23dnolenibdknox: oh definitely. function of time. sure I wish things happened faster.
16:24ibdknoxdnolen: yeah, I know. Ideally, we just completely abstract closure away and then it doesn't matter.
16:24ibdknoxsjl: it *is* a lot nicer. I wrote a basic clone of d3 in maybe 100 lines of CLJS
16:25dnolenibdknox: my challenge to front end web development. jQuery is too small. SproutCore too big. WTF. Somebody needs to work on that.
16:25ibdknoxdnolen: on it.
16:26sjlibdknox: so for cljs-watch, it says the default output is to "resources/public/cljs/bootstrap.js"
16:26ibdknoxsjl: you can change it
16:26sjlIs 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:27ibdknoxsjl: just that one
16:27sjlSo it dumps Closure, etc all into that one file? That'd be perfect.
16:27ibdknoxyes
16:27ibdknoxit uses the simple optimization by default
16:27ibdknoxwhich compiles everything into one file
16:28ibdknoxyou can change it to be like the dev instructions too though if you want it to be faster
16:28ibdknoxI generally find it acceptable in terms of compilation time
16:29sjlCool, I'll have to try it out
16:29sjlSo… how do I install this and use it?
16:29ibdknoxgrab the cljs-watch file and put it on your path
16:29ibdknoxas long as you have CLOJURESCRIPT_HOME setup, you're good to go
16:30ibdknox./cljs-watch starts watching the src/ directory based on wherever it was invoked
16:30sjlCLOJURESCRIPT_HOME is the git clone of the clojurescript repo, right?
16:31ibdknoxit's the path to it, yes
16:31ibdknoxwithout a trailing slash
16:32ibdknoxand you have to have done script/bootstrap in clojurescript
16:35sjlDear god, that was so much easier than when I last tried it.
16:35ibdknoxhaha
16:35dnolensjl: open source man.
16:35ibdknoxfor other fun toys
16:35ibdknoxlook at brepl
16:36sjldnolen: Yeah, but if I can't even get something on the screen to poke at it it's hard to contribute.
16:36scottjibdknox: maybe add :output-to to the extended example to make it slightly easier for non-noir people to see specific syntax
16:36dnolensjl: I agree. I haven't had toyed with CLJS much because of the slow code/compile cycle.
16:37ibdknoxscottj: it's the compiler options syntax, but yeah, that would help :)
16:37dnolenibdknox: did they get our CA?
16:37dnolenyour
16:37sjldnolen: Yeah, though cljs-watch seems to reuse the same JVM so it's not excruciating.
16:37ibdknoxdnolen: they did, I'm on the list now
16:37dnolenibdknox: cool.
16:38ibdknoxI'm doing the node knockout this weekend
16:38ibdknoxbut after that I'll throw a patch together to add it to cljs proper
16:38dnolenibdknox: gonna write yr knockout in cljs?
16:39ibdknoxdnolen: 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:39dnolenibdknox: 48 hours?
16:39ibdknoxdnolen: yessir
16:40ibdknoxdnolen: doing a multiplayer tower defense game :)
16:40scottjgtrak: nope, there is a swank-js but not sure if any of it is useful from cljs.
16:40scottjibdknox: I love that game :)
16:40neotykGood morning everyone!
16:41gtrakah
16:41sjlibdknox: Hmm, what I am doing wrong here? $ cljs-watch '{:output-to "public/scripts/test.js"}'
16:41gtrakdon't really understand how you can write clojure without slime/swank
16:41scottjgtrak: inferior-lisp
16:41ibdknoxsjl: cljs-watch src/ {:output-to "blah" :output-dir "blah"}
16:42gtrako i c
16:42neotykcljs-watch? where do I get it from?
16:43ibdknoxhttp://github.com/ibdknox/cljs-watch
16:43scottjibdknox: is your td game going to be open sourced?
16:43neotykfound it
16:44scottjdoes anyone else using zsh have to escape the {} to cljs?
16:44ibdknoxscottj: I dunno :) We'll have to see how it goes
16:44sjlscottj: Yes
16:44scottjsjl: is it all zsh's or some option we have enabled?
16:44ibdknoxscottj: I definitely don't have to on bash
16:45sjlscottj: Not sure, but I'd be surprised if it were an option.
16:45mbaccan you use defn to pattern match strings?
16:46dnolen_mbac: Clojure doesn't have native pattern matching support. But I've been working on that.
16:46mbachmm
16:46dnolen_mbac: https://github.com/swannodette/match
16:46michaelr525_what's your regular clojure news site? I'm updating from http://planet.clojure.in/
16:46scottjmichaelr525_: disclojure.org
16:46gtrakdnolen_, does lisp have native support for anything?
16:47scottjgtrak: lists
16:47gtrakha, i guess so
16:47ibdknoxdnolen_: btw, I'd love to have a chat sometime about what you'd like to see for the web.
16:47dnolen_mbac: pretty much anything you're using to from another lang is in match and then some.
16:47dnolen_ibdknox: definitely.
16:48dnolen_gtrak: well I guess i mean anything in the core clojure library.
16:48mbachm. can you not define functions with def?
16:48mbacis it defn only?
16:48gtrakyou can, ##(def (fn [] "yo"))
16:48lazybotjava.lang.SecurityException: You tripped the alarm! def is bad!
16:48mbacsorry if this is the wrong place for ultra noob questions
16:49scottjibdknox: are there multiplayer td's for mobile? I'd pay for that.
16:49gtrakdef just binds a var at root level
16:49lnostdalany "verbose mode" for lein? .. it seems stuck doing nothing; using CPU for a while, then 0%
16:49mbacoh. why's def bad?
16:49gtrakmbac, it doesn't work here b/c of the sandbox
16:49mbacoh is fn lambda?
16:49ibdknoxscottj: I'm not sure, to be honest lol
16:49gtrakyes
16:49scottjibdknox: ok, was thinking you could phonegap it
16:49ibdknoxscottj: I haven't seen many (any?) actually multiplayer tower defense games
16:50scottjibdknox: the original(?) starcraft map
16:50ibdknoxscottj: yeah if it goes well, we may very well try to do that with it
16:50mbacer, wait, what did you bind (fn [] "yo") to?
16:50gtrakmbac, I forgot to put in the name of the var, like (def myfn (fn [] (body))
16:50ibdknoxscottj: true
16:50mbachaha
16:50scottjibdknox: multiplayer is how I first played it and spent an entire day strategizing with my freshman roomies on our build order
16:50gtrakmy bad
16:50ibdknoxscottj: I guess I see that as a step above simple tower defense
16:50mbacwhy is def considered bad?
16:50gtrakit's not bad
16:50ibdknoxscottj: that's in the real-time strategy category for me
16:51hiredmanmbac: def is not define
16:51gtrakmbac, why do you consider it bad?
16:51mbac16:49 < lazybot> java.lang.SecurityException: You tripped the alarm! def is bad!
16:51mbacsomething gives me a feeling
16:51hiredmanmbac: def does not create locals
16:51gtrakhaha, 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:52mbacoh, does def stick things into the toplevel no matter what scope you say it in?
16:52gtrakyes
16:52mbaccool
16:52scottjibdknox: are you going to go the all game state in a big map + pure functions route?
16:52sjlibdknox: still no luck. Here's what my session looks like: http://d.pr/etek
16:52mbacwhy does dynamic scoping exist at all?
16:52gtrakmbac, but the real story is more complicated, you can bind vars thread-locally and unwind them like a stack
16:53mbacis this just to keep it lispy?
16:53scottjbtw anyone found a cljs unit testing setup they like?
16:53hiredmanmbac: it is useful for repl work
16:53mbacright, why not just have a let that special-cases top-level bindings?
16:53hiredmanyou can re-def a function without having to re-def all the functions that call it
16:54mbacoh, it's mutable
16:54ibdknoxsjl: {:output-to "script/test.js" :output-dir "srcipt/"}
16:54sjlibdknox: I mean I can just symlink the bootstrap.js script to where I want it, so it's not a huge deal.
16:54gtrakthough sometimes when you re-def a def, you get old functions pointing at the value of the var before
16:54ibdknoxsjl: yeah, but that should work, so if it doesn't I wanna figure out why :)
16:55gtrakyou have to refer to the function you're re-deffing all the time by (var thevar) to avoid that and use late-binding
16:55gtrakor #'thevar
16:55hiredmangtrak: subtly incorrect
16:55gtrakdamn, where'd i go wrong?
16:56mbacis defn preferred for defining functions even if you're not defining poly-arity function?
16:56amalloymbac: yes, for defining top-level functions use defn
16:56mbaci suspect (def a (fun [] "yo")) tickles performance-nazis
16:56sjlibdknox: Yeah, still no luck
16:57amalloymbac: huh? why?
16:57ibdknoxsjl: I wonder if the escaping screws it up somehow
16:57gtrakoh, the definition of defn is more complex than I expected
16:57mbacamalloy, don't performance-nazis freak out about unnecessary closures? :)
16:58wwmorganIs there a ring wrapper that takes URL parameters like foo[0]=bar&foo[1]=baz and turns it into { "foo" ["bar", "baz" } ?
16:58sjlibdknox: I tried just passing all the options as a big old string, but that doesn't help either
16:58gtrakwth is it doing?
16:58mbac(i expect defn does some magic to avoid the closure, but have no idea)
16:58michaelr525_after reading this: http://blog.jayfields.com/2011/08/clojure-partition-by-split-with-group.html
16:58amalloy(a) no, they don't; (b) neither of those is a closure
16:58ibdknoxsjl: I used the same function that clojurescript's cljsc uses
16:58michaelr525_Isn't the separate function from clojure.contrib.seq iterates over the seq twice?
16:58amalloy(that is, neither a def/fn version nor a defn version
16:59ibdknoxsjl: to grab those options
16:59ibdknoxsjl: can you try it too
16:59ibdknoxclojurescript/bin/cljsc ../samples/hello/ {:output ...}
16:59amalloymbac: (fn [] "a") has no free variables, only free constants; "a" is embedded into the generated class
17:00mbacoh, you're right.
17:00amalloyand 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:01sjlibdknox: cljsc works
17:01wwmorganFYI: got it, it's wrap-nested-params
17:01ibdknoxsjl: k, I will have to figure that out then.
17:01ibdknoxsjl: can't do it right this second, but I'll have a fix by tonight
17:02sjlibdknox: It's cool, I'm not using clojurescript for anything important at the moment, just poking around. No rush.
17:02sjlMy Clojure Minecraft bot framework is eating up all the free time I have to play with Clojure-related things anyway, hah.
17:03ibdknoxhehe :)
17:03mbaci really like the stylish use of vectors in clojure
17:03mbacbreaks up the parenthetical monotony
17:04michaelr525_,(require 'clojure.repl )
17:04clojurebotnil
17:04ibdknoxsjl: clojurecraft certainly does look like fun, so I don't blame you
17:04sjlibdknox: It's very fun, just lots to do to make it useful/practical
17:04michaelr525_,(require 'clojure.contrib.seq)
17:04clojurebot#<RuntimeException java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate clojure/contrib/seq__init.class or clojure/contrib/seq.clj on classpath: >
17:05michaelr525_,(require 'clojure.contrib.seq-utils)
17:05clojurebot#<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:05michaelr525_err sorry\
17:05gtrakmbac, wait till you get to destructuring
17:06michaelr525_This function really bothers me: http://clojuredocs.org/clojure_contrib/clojure.contrib.seq/separate
17:06michaelr525_Isn't the sequence iterated twice here? It doesn't seem to be performance wise..
17:06gtrakmichaelr525, it's lazy
17:06amalloymichaelr525_: it's surprisingly difficult to iterate the sequence only once
17:07michaelr525_amalloy: using a for loop in c for example
17:07gtrakhopefully whatever you're doing to the data is more complex than an iteration step
17:07amalloybecause 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:08michaelr525_I haven't been writing code in C for years, but when I see something like this it bothers me :)
17:08gtrakmichaelr525, how would you even do it in C? make copies?
17:08gtrakthat seems much worse
17:09gtrakthis is a clean, lazy, functional approach
17:09michaelr525_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:10gtrakyou're really not thinking this through
17:10amalloymichaelr525_: except it wouldn't be lazy
17:10mbacgrak, ?
17:10michaelr525_amalloy: ok, let's say that these immutable C sequences are lazy as well :)
17:11mbacdestructuring-bind?
17:11gtrakmbac, something like that, yes
17:11amalloymichaelr525_: that's my point! C would have the same problem then - you couldn't do it
17:11amalloytry 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:12amalloyyou could do it eagerly in clojure if you wanted, by using doall to force everything before you return it
17:12michaelr525_hmm
17:12hiredmanif the language was lazy (not just seqs) you could do it as a reduce
17:13amalloyhiredman: really? i guess i'm not used to thinking that lazily
17:13amalloyhow would it work in, say, haskell?
17:14amalloymichaelr525_: it annoyed me too, so i wrote https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L23
17:15amalloywhich transforms the input to make sure the predicate is only called once per item, but now it traverses the input seq three times
17:15hiredman(reduce (fn [[t f] e] (if (pred e) [(conj t e) f] [t (conj f e)])) [[] []] ...)
17:15michaelr525_amalloy: how about something like this:
17:15michaelr525_while( seq.next ){ if( seq.val is odd ) add to collection1 else add to collection2 }
17:16michaelr525_pseudo c\ ;)
17:16amalloymichaelr525_: you forgot "immutable"
17:16amalloyhow do you implement "add to ___"?
17:17michaelr525_well, "it just works" :)
17:17amalloygood luck with that
17:18michaelr525_amalloy: i can't understand what is the principal problem doing it?
17:18gtrakah, C just works so good, why don't we all use it?
17:19leedawith leiningen, how can i specify the type of a dependency as "pom"? /cc @technomancy
17:20michaelr525_hiredman: so is this solution faster than the elegant one with two filters?
17:20hiredmanmichaelr525_: no idea, and it's not lazy at all in clojure
17:20amalloymichaelr525_: 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:20amalloy*output
17:21michaelr525_hmm i see
17:21amalloymichaelr525_: 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:21michaelr525_what causes the evaluation of the seq?
17:21leedatechnomancy: or, is it possible to just specify this: https://gist.github.com/a0ebc8b00fda0db6d831 as a dependency? :P
17:22gtrakleeda, anything is possible with robert-hooke
17:22amalloypft
17:22michaelr525_hehe
17:22leedagtrak: heh
17:23hiredmanmichaelr525_: anything that isn't lazy
17:23hiredman(e.g. if it doesn't return a lazy-seq it will most likely force at least some part of a lazy-seq)
17:23amalloyi think the answer to his specific question in this case was "reduce forces the whole input sequence"
17:23michaelr525_reduce is lazy, no?
17:23hiredmanno
17:24michaelr525_ah
17:24hiredmanthere is no way to make reduce lazy in a non-lazy language
17:24gtrakhow does haskell do it?
17:24michaelr525_why clojure is not fully lazy?
17:24hiredmanhaskell is lazy
17:24technomancyleeda: dependencies must be in maven repositories, if that's what you're asking
17:24gtraki would think the inherent nature of reduce, turning a vector value into a scalar, can't be lazified
17:25hiredmanmichaelr525_: there are a set of tradeoffs around laziness, but the simplest answer is java interop
17:25technomancygtrak: laziness in clojure is only for seqs, but for haskell it applies to any value
17:25leedatechnomancy: 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:25leedatechnomancy: i found this article: http://sahits.ch/blog/?p=1038
17:25hiredmangtrak: if a process proceeds by the application of functions, and those functions are lazy, the process is lazy
17:26gtrakhiredman, can't you just wrap all that in closures and make it lazy?
17:26technomancyleeda: gross. did you try :type "pom"?
17:26leedatechnomancy: which seems to say that i need to specify the dependency type as "pom" (<dependency>...<type>pom</type></dependency>)
17:26michaelr525_is there an irc program with a reversed flow - from the top down?
17:26leedatechnomancy: but where would i put that?
17:26michaelr525_I get tired always looking down at the newest text
17:26technomancyleeda: in the dependency vector
17:26hiredmangtrak: you would effectively be writing a lazy sub language unable to interop easily with the rest of the language
17:26leeda[javax.media/jai_core "1.1.3" {:type "pom"}]?
17:27leedatechnomancy: ^
17:27gtrakah, but that would suffice, that's how ring does its middlewares
17:27technomancyleeda: lose the brackets and you're set
17:27technomancyerr--the braces
17:27technomancycurlies
17:27leedaah ok
17:28leedatechnomancy: awesome, looks like that worked. thanks!
17:29technomancycool
17:30gtrakif we have immutable structures, it wouldn't be too hard to make a lazify and deref macro to go with it
17:31technomancysure, it's called delay
17:32technomancyjust need all consumers ever to call force
17:33technomancy(doseq [n (all-ns) [_ v] (ns-map n)] (alter
17:33hiredmanall the time, before everything
17:33gtraki think non-lazy is a sane default for reasoning about a program, no?
17:33technomancy-var-root v (fn [f] (fn [o & args] (apply o (map force argsr)))))
17:33technomancytada!
17:34gtraktechnomancy, that makes me afraid
17:34technomancygtrak: I had to split it into two IRC messages because a single one could not contain SO MUCH POWER
17:34technomancymuch like the Killer Joke that had to be translated one word at a time
17:36gtrakmy god
17:37gtrakdoes the universe explode if you run that on clojure.core?
17:37technomancysure, FSVO universe
17:37hiredmanyes
17:38technomancyconsidering it doesn't check for ifn? first, absolutely.
17:44leedatechnomancy: another question, is it possible to force lein to use a specific repository for a certain dependency?
17:44gtrakso delay all the stuff you're interested in, then make a reader macro to do the force for you
17:45amalloygtrak: 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:45leedatechnomancy: since the one on maven is not working, i want to use a different repository for it
17:45leedatechnomancy: but it seems to prefer maven's
17:45michaelr525_why i can't any longer mark and install packages in package-list-packages?
17:45gtrakamalloy, yea, I've never used haskell so I guess I can't make the judgment
17:45michaelr525_I an X don't do anytjhin
17:45gtrakI think immutability simplifies things very much
17:47michaelr525_oh, it's a built in package
17:48gtrakamalloy, 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:48leedatechnomancy: ok, never mind, it was my mistake
17:48amalloy(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:49michaelr525`hello
17:49gtrakwell, it made me feel all giddy, but i've only spent a few years programming in total
17:50technomancygtrak: it's a known issue in haskell that you can't easily reason about performance; see http://ro-che.info/ccc/11.html
17:51gtrakha
17:51technomancy(I really wish that comic had gone for more than 12 strips)
17:51hiredmanbut in some sense everything has the same issue
17:52hiredmanreasoning about performance in the presence of a jit is difficult, etc
17:53gtrakhiredman, 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:54hiredmanbut even the architecture of a cpu is getting to the point where it can be hard to eyeball performance for native code
17:55gtrakon a much smaller scale, though
17:55dnolen_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:55technomancyyeah, that's true. brb; switching to forth.
17:55technomancy=)
17:56gtrakall the cache-optimizing stuff is harder to do
17:56dnolen_Haskell on the other hand goes through some hardcore transformations.
17:58hiredmandnolen_: it does map really well to jvm bytecode, but what is the performance of the bytecode, hard to tell without profiling
17:59gtrakhickey cares about identity at slices in time though, that's one of the trade-offs
18:00dnolen_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:00dnolen_C++ looking code.
18:01dnolen_all those things are preserved in Clojure, since they are the fast path.
18:01hiredmanmmm
18:02dnolen_of course there's weird run time optimizations, like collapsing method calls, but that's just icing.
18:02Somelauwwouldn't dynanicismn make it a bit slower
18:03hiredmandnolen_: by collapsing method calls you mean inlining?
18:03dnolen_hiredman: yeah
18:03gtraknot terribly 'weird'
18:03hiredmanbecause I am pretty sure every jvm talk I've seen has called that "THE optimization"
18:03hiredmaninstead of just "icing"
18:04hiredmaninlining multiplies the power of other optimizations by giving them more code to work with
18:05dnolen_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:06hiredmandnolen_: sure
18:09gtrakdnolen_, it'll run faster than you think it will, not so hard :-)
18:14gtrakthere was a cool article about that, something about putting a for-loop body in a separate method can help a lot
18:15gtraki think b/c it's likely to lower the code in the method under the inlining threshold
18:29SomelauwWhen doing (let [x 5]) would the clojure compiler infer that x is a static int?
18:32ScriptorSomelauw: infer wouldn't really be the right word, I think
18:33Scriptorx would just be pointing to something that happened to be an int, just like in any other dynamically typed language
18:34hiredmanactually for locals create by let you do get type inference
18:34hiredmanx would be a primitive long (in 1.3)
18:40SomelauwScriptor: I though java created ints on the stack like c.
18:41hiredmanyou asked about clojure, not java
18:41amalloySomelauw: 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:43SomelauwSo clojure uses an Integer for that by default?
18:43Scriptorexactly
18:43hiredmandepends
18:43Scriptorwell
18:43Scriptordoesn't it use Long a lot of the time?
18:43hiredmanno
18:44dnolen_Somelauw: 1.2 boxed Integer, not 1.3, unboxed long
18:44SomelauwGo clojure 1.3 :D
18:44Scriptoryea, long, not Long :p
18:44dnolen_Somelauw: arith perf in 1.3 is stellar with much less type hinting.
18:45mbachow does the jvm tell the difference between immediates and references? does it use a tag bit?
18:45amalloywell, 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:45mbacoh, maybe there's runtime type information
18:45mbacduh
18:45dnolen_amalloy: unless of course you're passing them to fns w/ prim signatures.
18:45amalloysure
18:46dnolen_like +, -, *, = etc
18:46Somelauwok thanks
18:46amalloymbac: java has compile-time and run-time type information. stuff like "is this an int or an object" is done at compile time
18:48hiredmandnolen_: which are likely to be inlined into static method calls by the compiler and then into jadd by the jit
18:48dnolen_hiredman: :)
18:48mbacamalloy, is the run-time type information for the GC only?
18:48amalloyno, it's mostly to preserve type safety
18:48hiredmanif only I did expensive computations on numbers, how fast my programs would be
18:49mbacoh right, casts
18:49amalloyright
18:49amalloyand also virtual/dynamic method dispatch
18:49mbacoh right, inheritance :)
18:50Scriptorso with 1.2 and before with the boxed ints, did variables just store a reference to an Object?
18:51dnolen_hiredman: Clojure is one giant expensive computation on numbers.
18:51hiredmandnolen_: blah blah blah turning blah blah blah
18:52hiredmanturing
18:52dnolen_all the persistent data structure we love so much ...
18:52hiredmanScriptor: (let [x (int 1)] ...) x is a primitve int
18:55Scriptoras in x is directly placed on the stack as an int?
18:55hiredmandepends on the jvm
18:56hiredmanx inside that let is equiv to 'int x;' in a java method body
18:56Scriptorah, got it
18:57Scriptorwhat if you did (def x 1), I know it creates a Var object, but what does that point to?
18:57hiredmana Long or Integer
18:57hiredmanvars hold objects
18:58Scriptorah, so unboxing won't work with def?
18:58Scriptormeaning, it won't store it as an unboxed long
18:59hiredmanright, but you can do (def x 1) … (let [x (int x)] …) …
18:59Scriptorinteresting, thanks!
19:04amalloyseveral 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:09Somelauwamalloy: Unpacking it in a let?
19:09amalloyhuh?
19:12SomelauwWell you don't need to check its length since you can unpack it. Like (let [[a b c & d] 3-elementer] body)
19:14SomelauwOh wait, that doesn't check its length. nvm. Only if-let does for a single element.
19:21ibdknoxdoes anyone know the implications of the EPL license on Clojure? Does it limit a company in some way?
19:21amalloySomelauw: 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:22danlarkinibdknox: it limits a company in exactly the ways specified in the license, and no others
19:22amalloythe easiest way to do it is like (if (nthnext xs 2) (...there are at least three elements...))
19:22ibdknoxdanlarkin: why thank you for that wonderful response.
19:23danlarkinask smart questions if you want smart answers :)
19:23amalloybut of course for vectors and other Counted things, that's actually slower than just calling count and comparing
19:23danlarkinsorry, that was a little too mean
19:23ibdknoxYeah
19:24ibdknoxdefinitely encourages people to participate
19:24danlarkinyeah yeah yeah
19:24ibdknoxMy 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:25danlarkinibdknox: do you have specific concerns about the EPL? or just asking in general
19:25ibdknoxI'm trying to make sure it's safe for me to leave Noir as EPL
19:25danlarkinwikipedia has a good summary
19:26ibdknoxdanlarkin: I've read it.
19:26ibdknoxAgain, just asking if anyone has hit any issues
19:27technomancyibdknox: it means no one can distribute modified versions of noir without making them public, which is probably what you want.
19:27ibdknoxtechnomancy: yeah, I thought so too.
19:31SomelauwHow about (if (last (take 3 (iterate next seq))))
19:32SomelauwNevermind. There is nthnext like you posted.
19:32mbachow does clojure qualify .methodCall foo?
19:32mbacdoes it figure it out based on the type of foo?
19:33mbacthat seems impossible
19:33amalloySomelauw: and last/take won't work anyway, because the sequence could be [1 2 nil]
19:34mbaci notice, say, .substring works even though i didn't import anything
19:34technomancymbac: for non-hinted calls it reflects at runtime
19:34Somelauwmbac: I think it is a long sequence of foe getClass getMethods invoke
19:35mbacwoa
19:35gtrakmbac, if you turn on reflection warnings, you can see exactly what it infers or doesn't
19:46amalloymbac: importing has nothing to do with it, in either java or clojure
19:46mbacwhat does import do, then?
19:47amalloyit 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:47mbacer? isn't that the same as qualifying names?
19:48amalloySystem.out.println(x) works, even though i haven't imported the PrintWriter class of which println is a member
19:49mbacoic
21:37gridaphobeis there any reason to worry about reflection if i'm not doing any java interop?
21:37amalloyno
21:38gridaphobethanks :)
21:38gridaphobethat's what i thought
22:50gstampis 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:54gstampactually, it looks like if I type hint it where it's used then it works
22:59cemerickgstamp: you hint the var's name
23:00amalloycemerick: 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:00gstampcemerick: thanks. that seems to work well.
23:01cemerickgstamp: *or* the symbol at the call site — either way. Didn't mean to imply one was necessarily superior.
23:02cemerickamalloy: Yeah, alter-var-root, and then newly-loaded code is not helped at all.
23:02cemerickor binding, or whatever
23:02gstampcemerick: I imagine in general it would be easier to manage on the var
23:03amalloyokay. just wanted to make sure my hinting fundamentals are halfway solid :P
23:03cemerickgstamp: Certainly easier if you have multiple ambiguous interop usages. Plus, it's reasonable documentation.
23:03cemerickamalloy: :-)
23:04cemerickIf you're concerned on that front, make sure you keep an eye on 811.