#clojure logs

2014-02-15

00:00jph-:)
00:04TravisDDoes clojure have much of a scientific computing community?
00:05amalloyTravisD: probably a little, but i think most of those guys use matlab, python, or fortran or something
00:07TravisDamalloy: Yeah, but sadly both matlab and python are too slow to implement any real algorithms in. They're mostly wrappers and glue for hooking together fast implementations of common operations
00:07jph-i wonder if julia will supplant them
00:07TravisDOne hopes
00:11TravisDThis isn't meant to be an inflammatory comment, but does clojure have a larger and more active community than the variants of scheme?
00:13egghead TravisD i'm not familiar with scheme variants, but clojure has a large and active community
00:13TravisDAnd is clojure mainly used for web development?
00:15eggheadTravisD: a lot of people use it for web development, but it is general purpose like java, so a lot of people use it for other things as well, clojure has a particular specialty in things like concurrency
00:16TravisDalright, thanks :)
00:24`cbpsuddenly all the bugs are tracked to me typing OAauth
00:25logic_progopen awesome Auth
00:27munderwoSo I'm trying to use the new jdbc API vs the old. But although I am using the clojure.java.jdbc 0.3.3 version in my project.clj, I don't have the insert! function in the repl. How do I verify the version of a library form the repl?
00:31ddellacostamunderwo: if you do (require '[clojure.java.jdbc :as j]) you don't have j/insert! available to you?
00:31ddellacostamunderwo: I don't know how to verify a version number from the repl, but if you run lein deps from another terminal window that should tell you
00:32ddellacostamunderwo: er, lein deps :tree is what you want, sorry
00:33ddellacostaTravisD: I know there is a lot of machine learning going on in Clojure as well, for one
00:33munderwoddellacosta: so this is what I'm getting https://www.refheap.com/39074
00:33munderwoand its rather confusing..
00:33munderwobecause from what I can tell the jdbc driver from 0.3.0 onwards should have insert!
00:35munderwoIf I try to just do the insert! function then it says no such var.
00:36munderwoI'm not sure if somehow I've messed up my class path because I have an older version of the jdbc driver in there? where are these stored?
00:36ddellacostamunderwo: does insert! show up when you do this? (keys (ns-publics 'clojure.java.jdbc))
00:37munderwoddellacosta: nope https://www.refheap.com/39075 ...
00:37munderwoWhere are the jars that leiningen downloads stored?
00:38munderwoI know that they get caches in ~/.m2 but is there anywhere else?
00:38ddellacostamunderwo: I don't get it, I clearly see [org.clojure/java.jdbc "0.3.3"] in your lein deps :tree output
00:38ddellacostamunderwo: are you running the repl w/a profile?
00:38munderwoyeah I know… its kinda got me stump..
00:40munderwothis is my profile.clj https://www.refheap.com/39076
00:40ddellacostamunderwo: no, I mean are you running the repl like `lein with-profile dev repl` or something?
00:40munderwonope… just `lein repl`
00:41ddellacostamunderwo: and you're definitely running it in the same project directory you showed us that lein deps output from, right?
00:42munderwoddellacosta: I just redid the whole set of steps… https://www.refheap.com/39077
00:42munderwojust to make sure… coz gravity doesn't feel right.. and that normally means I've done something stupid
00:44ddellacostamunderwo: yeah, that's weird, that's obviously the deprecated interface
00:45munderwoddellacosta: yeah its weird… thanks for your help. at least I know I'm only going a little crazy.. gotta run.
00:59danielcomptonIs there a version of cond that will evaluate each test and it's expression if the test is true? The scenario is I'm wanting to validate a form in cljs and set dom error messages for each error message that I find. I could put a number of when statements in a line but I wondered if there was something more idiomatic?
01:01TravisDDoes anyone know of a quick introduction to clojure? I'm somewhat familiar with lisp and FP, and I have quite a bit of programming experience
01:08jph-TravisD, http://adambard.com/blog/clojure-in-15-minutes/
01:09TravisDawesome, thanks
01:10jph-TravisD, i also refer to http://clojure.org/cheatsheet all the time
01:11TravisDhmm, clojure has special forms, no? Like, is (ns test) actually a function call? Or is it a special namespace form?
01:12oskarkvTravisD yes there are special forms, but I think `ns` is a macro
01:12TravisDah
01:23ddellacosta,(source ns)
01:23clojurebotSource not found\n
01:23ddellacostad'oh
01:24ddellacostaTravisD: anyways, you can do that ^ in the repl to learn more about a function/macro/special-form
01:24beamso,(doc clojure.core/ns)
01:24clojurebot"([name docstring? attr-map? references*]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class .....
01:24TravisDcool, thanks
01:24TravisDnormally (source x) gives you the definition of x?
01:25ddellacostaTravisD, beamso: yeah, good point--that should tell you if it's a special form too
01:25ddellacosta,(doc loop)
01:25clojurebot"([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target."
01:25beamsoand it's (clojure.repl/source ns) as well
01:25ddellacostahrm
01:25ddellacosta&(doc loop)
01:25dsrx,(doc .)
01:25lazybot⇒ "Macro ([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target."
01:25clojurebotCool story bro.
01:25ddellacostabeamso: I don't need to qualify it with the namespace in my repl...clojure.repl gets loaded automatically by default
01:27beamsotrue
01:27beamsomaybe the bot needs a namespace specified :/
01:27TravisDis there a way to get the clojure repo to use readline?
01:27TravisDrepl*
01:27ddellacostabeamso: naw, it's not that it didn't find it, it probably just doesn't allow you to do that to avoid noise in IRC I suspect
01:28ddellacostaTravisD: huh, it uses readline by default I thought
01:28TravisDhmm, the version I installed through macports doesn't seem to :(
01:28beamsolein uses jline by default
01:29logic_progtbaldridge: !!!
01:29ddellacostabeamso: ah, I stand corrected
01:29logic_progtbaldridge: your youtube videos are awesome
01:29TravisDhm, so now I've installed jline. Is there something more I need to do to get clojure to use it?
01:30beamsohttp://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Enhancing_Clojure_REPL_with_JLine
01:30beamsomaybe that
01:30TravisDthanks
01:32amalloyTravisD: whoa, installing clojure (or lein) through macports is pretty nuts
01:32TravisDamalloy: How come?
01:33TravisDbeamso: I switched to macports because they've started shipping binaries
01:33TravisDcan save a lot of time
01:33amalloyfollow the instructions at the lein readme (https://github.com/technomancy/leiningen/blob/master/README.md), which amount to "download this script and put it on your path"
01:33amalloystuff in package managers is always out of date and/or awful, eg not including jline support
01:34TravisDlooks like it's up to date, and relatively easy to add jline support
01:35ddellacostaTravisD: most Clojure folks I know use the default leiningen setup for installing/update
01:35TravisDah
01:35ddellacostaTravisD: especially as you don't need the package manager to get updates for lein
01:36amalloylein really is way better at managing clojure (and itself!) than any package manager
01:36ddellacosta^^ what he says ^^
01:37TravisDyeah, I'll probably switch to that
01:37TravisDso the recommended approach is to instal lein manually and use it to install and update clojure?
01:37ddellacostaTravisD: yep.
01:38ddellacostaTravisD: after the initial install it is as simple `lein upgrade`
01:39ddellacostaTravisD: technomancy makes announcements when a new version gets released on the mailing list
01:39TravisDawesome :)
01:39ddellacostaTravisD: and upgrading clojure is kind of not exactly how it works; you set the clojure version in your projects' dependencies, so you are not constrained to a specific version.
01:40TravisDAh, I see
01:40TravisDOutside of a project, will there be a clojure repl available?
01:40ddellacostaTravisD: yeah, I like lein a lot, after coming from Ruby and using Rake and gem and bundler and whatnot...which is not bad, but I find lein better. Which is amazing considering it's managing maven ugliness.
01:41ddellacostaTravisD: sure, you can start a repl anywhere.
01:41TravisDThe closest to lein I've come is (C)makefiles
01:41TravisDddellacosta: So the globally available version of clojure is also installed by leon?
01:41TravisDlein*
01:42ddellacostaTravisD: I don't have a great answer for you on that one--I assume that leiningen has a default Clojure version set, but I'll let someone more knowledgeable than I tell you more... technomancy or amalloy?
01:43amalloyTravisD: there's no particular reason to have a version of clojure that's "global". you have a version of clojure specified by each project you're in
01:43TravisDamalloy: While I'm learning I might like to have one I can just play around with
01:44Raynes`lein repl`
01:44amalloyif you're doing something quick outside a project, like a repl, you get the default, which is probably 1.5.1, but you can override that with something in ~/.lein/something
01:44TravisDawesome :)
01:44ddellacostaamalloy: sorry, I should be more clear about the context--TravisD was asking in the context of running a repl outside of a specific project
01:44TravisDI will read some on my own now
01:44TravisDthanks for the advice and tips
01:45ddellacostaTravisD: good luck TravisD...enjoy! :-)
01:48ddellacostahuh, haven't seen this CLJS exception before, any ideas? Exception in thread "main" java.lang.RuntimeException: Unable to resolve var: reader/*alias-map* in this context, compiling:(cljs/analyzer.clj:1498:11)
01:49ddellacostajust trying to add CLJS to a previously running project, I get this when I run lein cljsbuild auto dev
02:02TravisDIs there a translation of SICP to clojure?
02:03TravisDnot sure if they are compatible enough languages for that to work
02:04ddellacostaTravisD: lots of stuff pops up on Google, but I can't vouch for any of it...I've only ever used racket to try to go through SICP
02:05ddellacostaTravisD: http://sicpinclojure.com/ for example
02:05ddellacosta"You should not be here yet."
02:05amalloyTravisD: attempts have been made, but really i'd just go through the actual book
02:05ddellacostawhoops
02:05TravisDamalloy: It would be nice if there was an annotated version of the book that had the rleated clojure information
02:06amalloythere's very little syntax used in sicp, so learning the few clojure constructs you'll need for the book is not that big a deal
02:06TravisDhehe, alright
02:10ddellacostalooks like I had an out-of-date tools.reader for anyone who encounters the same issue with CLJS I had above (ring and lib-noir were the culprits in my case): http://clojure-log.n01se.net/#01:48
02:10ddellacostanow I have a completely different, lovely Google Closure error
02:15ddellacosta...which was caused by stefon loading the google closure compiler in addition to clojurescript. Hope that doesn't break stefon. *sigh*
02:23szymanowskihi, is there a function like haskell's 'tails' in clojure?
02:23seangroveddellacosta: On noir eh? Legacy in the Clojure world...
02:23seangroveszymanowski: What does tails do?
02:24seangroveNevermind, looked it up
02:24szymanowskighci> tails "w00t"
02:24szymanowski["w00t","00t","0t","t",""]
02:24ddellacostaseangrove: well, just lib-noir for sessions (https://github.com/noir-clojure/lib-noir). Not a huge fan of it in any case. Lots of state management weirdness in noir, in my opinion
02:24szymanowskiit is simple to implement but just want to know
02:25seangroveszymanowski: I don't think there's one built in
02:25seangroveLooks like someone wrote about it here http://joshrotenberg.com/posts/2013-12-31-datalist-functions-in-clojure.html
02:25dsrx,(take-while not-empty (iterate rest "w00t"))
02:25clojurebot("w00t" (\0 \0 \t) (\0 \t) (\t))
02:26szymanowskithank you dsrx
02:26just-a-devinteresting...
02:27just-a-dev,(str "testing irc bot")
02:27clojurebot"testing irc bot"
02:34just-a-dev,(for [c (range 65 91)] [(char c) (char (+ 32 c))])
02:34clojurebot([\A \a] [\B \b] [\C \c] [\D \d] [\E \e] ...)
02:59szymanowskii would like to implement a reduce function that stops iteration when returned accumulator is nil, does anyone could help me?
03:01sk052how to do xml parsing in clojure
03:01szymanowskihttp://clojuredocs.org/clojure_core/clojure.xml/parse
03:05sk052xml parsing api is it stax, sax or dom
03:09oskarkvszymanowski what exactly do you need help with
03:11szymanowskidoes my question make sense? or do you want me to rephrase it?
03:12sk052i have a zip file with 500+ xml file and each file is 300MB , need to parse them efficiently and load in db
03:12oskarkvszymanowski you mean you would like a new reduced function, like reduce', that stops when the the intermediate result is nil?
03:13oskarkvreduce*
03:13szymanowskiyes
03:13szymanowskiexactely
03:14szymanowskimaybe i should use reductions for that
03:14szymanowskireductions returns a lazy seq?
03:15oskarkvyes you could, but it would not be the most performant solution ever
03:15oskarkvI think, but not that big of a deal maybe
03:15szymanowskiok, if you have a better idea i would like to know it!
03:15oskarkvszymanowski maybe this https://www.refheap.com/39081
03:17szymanowskii didn't know refheap it looks nice!
03:17szymanowskithank you i will try this
03:19szymanowskiit works well thank you oskarkv
03:19oskarkvnp
04:17szymanowskiwhat is the best way to check if at least 1 item of coll1 is in coll2?
04:18amalloyszymanowski: as long as you're on clojure 1.5, you could just use ordinary reduce, and return (reduced nil) to mean "the answer is nil, now stop"
04:18amalloy(some (set coll1) coll2)
04:19szymanowskigreat thank you
04:23szymanowskireduced function looks handy, i didn't know it
04:39muhooreduced is nice for when you really don't want to loop/recur
04:46borkdudehttps://gist.github.com/borkdude/9016815
04:53borkdudewow, eh, even this works ;)
04:53borkdude IFn eval = Clojure.var("clojure.core","eval");
04:53borkdude Object expr = Clojure.read("(+ 1 2 3)");
04:53borkdude Long res = (Long) eval.invoke(expr);
04:56borkdudealso nice Date d = (Date) Clojure.read("#inst \"2014-12-12\"");
04:56borkdude System.out.println(d);
04:56borkdudeI think Clojure can be a nice utility in many java projects =)
05:10borkdudeclojure.inspector - why didn't I know about that before? https://www.dropbox.com/s/1t0ftj5bo2qpltg/Screenshot%202014-02-15%2011.05.57.png
05:33borkdudeis there a built in clj function which gives me a file tree instead of seq?
05:40raekborkdude: there's always the File API... but using that the tree shape is in your recursive calls rather than in some data structure
05:41raekhttp://stackoverflow.com/questions/8566531/listing-files-in-a-directory-in-clojure/8567237#8567237
05:41borkduderaek I already found something in Raynes's fs lib "iterate-dir" which gives me something like that
05:42borkduderaek yeah, I even answered in that thread I see, but I'm just too lazy to type that all in ;)
05:42raekborkdude: oh, I see :-)
05:42borkduderaek I wanted to have a tree to play with in (clojure.inspector/inspect-tree ...)
05:42borkduderaek since I just discovered that neat utility
05:44borkdudeI think I could have used inspect-tree when plowing through a lot of json-esque data :-s
05:46borkdudeI'm starting to get convinced that I should use mapv filterv etc by default and not map, filter, unless lazyness is explicitly wanted.
05:54pyrtsaborkdude: I often do the same. Especially when generating something like JSON output, it's much nicer that any errors in the processing happen at the call site rather than in the final rendering to string.
05:54borkdudepyrtsa yes, exactly the problem I had yesterday
05:54borkdudepyrtsa I have been bitten by lazyness in more cases
05:55pyrtsaLaziness in Clojure is second-class, unfortunately. :|
05:55borkdudepyrtsa for example, someone used a dynamic var and binding. But my lazyseq was evaluated outside the scope of that binding, later. ;)
05:55borkdudepyrtsa I agree that using arguments instead of dynamic vars is better generally
05:56pyrtsaI'm trying to do my best to avoid dynamic vars altogether.
05:56borkdudeit would also prevent this situation
06:11borkdudeproblem reconstructed: https://gist.github.com/borkdude/10ec65989ef4d371bbcd
06:14borkdudeso any recent new clojure (related) books?
06:16borkdudeIs this book any good, Clojure high performance? http://shop.oreilly.com/product/9781782165606.do?sortby=publicationDate
06:43borkdudeare there any people doing serious java development in emacs btw
06:46borkdudemaybe there should be something a la clojure.inspector in emacs, so you can use it also on servers without GUI. does it exist?
07:09borkdudeawesome: https://github.com/magnars/clj-refactor.el
08:28szymanowskiwhat is the best way to check if multiple preds are true for a value
08:28szymanowski?
08:32szymanowskilike (all-true? 10 pos? (partial < 11)) => true
08:33szymanowskii don't want to write (and (pos? 10) (> 11 10))
08:33szymanowskiedit: (partial > 11)
08:35szymanowski(defn all-true? [d & preds]
08:35szymanowski (eval `(and ~@(map #(list % d) preds))))
08:35szymanowskiis this make sense?
08:37AimHere,(every? identity ((juxt pos? even? #(< % 10)) 10))
08:37clojurebotfalse
08:37AimHere,(every? identity ((juxt pos? even? #(< % 10)) 8))
08:38clojurebottrue
08:38AimHereSeems to take clojurebot too much time to work that out for some reason
08:39AimHereChances are, if you're using 'eval', whatever you're doing is non-idiomatic
08:41szymanowskithank you!
08:42szymanowskiso it is preferable to make a macro than a function that return (eval `(...)) ??
08:42lazybotszymanowski: Definitely not.
08:42AimHereIgnore the bot, in that case, a macro would be preferable
08:42szymanowskiok
08:54elephantTechnoHi, i'm currently writting a program where a global variable shared accross threads can be mutated at a first staged and is guaranteed not to mutate anymore at a second stage. Basically i'm in a "treasure hunting" situation where the fastest pirate gets all the gold while the others get nothing. I could just wrap the value ("treasure!" or nil) into a ref that I'd consider as my treasure chest. But I fear that
08:54elephantTechnoletting all the other pirates engage in STM races for a chest that is guaranteed to be nil at some point and forever, can lead to mismanaging cpu cycles in an impacting way.
08:55elephantTechnoAre my concerns justified ?
08:58carkthere is no race if you're only reading
08:59carkalso you might want to consider using an atom
09:02elephantTechnoThank you
09:03carkto make it clear : transactions only retry when you're modifying the ref
09:03cark*risk to retry
09:06elephantTechnoBecause you're forced to proxy the change through a dosync block
09:48jro_Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String at clojuresque.tasks.repl$eval863$start_repl_task_driver__865.invoke(repl.clj:11) at clojuresque.tasks.repl$eval863$start_repl__868.invoke(repl.clj:9)
09:48jro_while trying to start clojure repl with gradle clojureRepl
09:49jro_clojuresque 1.7.0 and nrepl 0.2.3
10:05sdegutisGood morning everyone.
10:28michaniskingood morning :)
10:28michaniskinEST representing
10:28michaniskinalso it's 2^10 o'clock!
10:43btcNeverSleepsDoes Clojure's "future" macro exist in JavaScript?
10:44btcNeverSleepserf, in ClojureScript I meant of course
11:37michaniskinbtcNeverSleeps: i don't think so. i don't see it in the source, and i tried on http://himera.herokuapp.com and it wasn't there either
11:37michaniskinbtcNeverSleeps: however i do not have a repl handy with the latest cljs version
11:38michaniskinbtcNeverSleeps: what are you trying to do? maybe core.async would be something you could use instead?
12:48logic_progdoes clojure support setting up callbacks on atoms ?
12:48logic_progi.e. on agents, I have watchers
12:48logic_progcan I register something similar for atoms, where it gets fired off whenver the atom changes?
12:50gfredericksyes
12:50dnolen_logic_prog: add-watch
12:50qbgAs per the documentation of add-watch: Adds a watch function to an agent/atom/var/ref reference.
12:50gfredericks,(doc add-watch)
12:50clojurebot"([reference key fn]); Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their functions called. The watch fn will be called synchronously, on the agent's thread if an agent, before any pending sends if agent or re...
12:50bbloombut use them *sparingly* please!
12:51gfredericksbbloom: yeah?
12:51bbloomi've only ever used add-watch for enhancing my reload-file workflow. you only need ONE-ish callback for that
12:51bbloomessentially to dispose old-val and initialize new-val
13:02pyrtsabbloom: You don't even need add-watch for that. Can achieve the same with compare-and-set!.
13:02bbloompyrtsa: nah, add the watch to a var & then simply reloading the file will cause the watcher to run
13:03pyrtsaAh, I see.
13:03pyrtsaThought you were using it for an atom.
13:23btcNeverSleepsmichaniskin: (was afk)... Thanks for the answer about future. Not trying to do anything in particular: but I'm writing Clojure code and future makes concurrency trivial. I was wondering if my code would be portable to ClojureScript or not : )
13:24btcNeverSleepswell, "trivial" compared to concurrency in Java I mean (I don't think concurrency is ever trivial)
13:24bbloombtcNeverSleeps: core.async is your best bet for concurrency in cljs. you can use channels like futures with relative ease too
13:25btcNeverSleepsbbloom: thx a lot, I love the dnolen/swanodette posts and videos about core.async. It's on my "todo list" anyway ^ ^
13:27btcNeverSleepsbtw how do you call it in Clojure when you do '@': say @(future ...) [not that that example would be particularly smart] Do you "deref" a future?
13:27btcNeverSleeps(not a native english speaker and pretty new to Clojure btw)
13:28bbloomyes, which is short for "dereference"
13:28btcNeverSleepsbut a 'future' ain't really an atom?
13:28bbloomdereference is an abstract operation
13:28btcNeverSleepsoh, ok.
13:28bbloomthe concrete operation varies by type of the reference object
13:28btcNeverSleepsbbloom: thanks a lot
13:28bbloomfor a future, you "get" or "await" it
13:56jro_jwave.core=> (time (doseq [i (range 1000) j (range 1000)] (aset arr i j (double 1.0))))
13:56jro_"Elapsed time: 10991.86 msecs"
14:10logic_progFor agents, I can attach watchers to it. For atoms, is there anything similar to wathchers I can attach to?
14:10logic_progI.e. some function that is called whenever something changes.
14:11aphyrIf anyone else has thoughts on (some?), (when-some), (if-some), I'd appreciate your comments here: http://dev.clojure.org/jira/browse/CLJ-1343?focusedCommentId=33790#comment-33790
14:11aphyrnot sure if I'm just misunderstanding things or if this is actually confusing.
14:13Bronsaaphyr: it is actually confusing.
14:14teslanickSeems like some? should be named nnil? or something like that. I haven't looked at the 1.6 docs yet, but I assumed there was a relationship between some and some?
14:14ambrosebsIt seems Clojure has moved on from c.c/some.
14:16bbloomambrosebs: yeah, i think the word "some" now just means not-nil and the name of c.c/some is now considered a wart?
14:16ambrosebsbbloom: seems like it
14:16gfrederickssome?/if-some/when-some/some-> are as unrelated to clojure.core/some as all the namespace functions are to clojure.core/namespace
14:17gfredericksbbloom: yeah especially since some uses traditional truthiness semantics
14:17BronsaI don't really care for the "some" part of the criticism, but the lack of "-let" really bothers me
14:17gfredericksyeah that part was pretty unexpected
14:17bbloomi think core.async is motivating if-some a bit
14:17bbloomthat would be my guess
14:18gfrederickssix months from now these things will just be endearing
14:18bbloomi have a dorecv macro that is basically the same as for/range over a channel in Go
14:18bbloompretty useful
14:18ambrosebsI assume the nil channel semantics for core.async are concrete now.
14:19ambrosebsotherwise these wouldn't have turned up
14:19gfrederickscommitment to alpha API details will be announced by adding new core functions that relate to them
14:20ambrosebsgfredericks: yep
14:20bbloomBronsa: the lack of the -let doesn't bother me
14:20bbloomBronsa: there are lots of macros that have bindings w/o a name that hints it
14:20gfredericksbbloom: usually because it's obvious they take one?
14:21gfredericksthere isn't an extremely natural variant without a binding?
14:21ambrosebsoh they take a let binding?
14:21Bronsa... see
14:21bbloomgfredericks: eh, clojure is anti-anaphoric. so it doesn't make much sense to test an expression without offering a binding for it
14:21gfredericksbbloom: if-some and when-some could be just alternate-truthiness versions of if and when
14:22bbloomgfredericks: i understand where your confusion comes from, but it's like "oh, these take a let binding? ok then" and i get on with my day
14:22bbloomespecially since there isn't much benefit in terms of cleaner syntax without the let binding
14:23bbloom(if-some x y z) vs (if (some? x) y z) vs (if-some [_ x] y z)
14:23gfredericksgood point
14:23gfredericksif-not-nil-and-let's-call-it
14:23bbloomlol
14:23gfredericksif-some-here-comes-a-binding-wait-for-it
14:25bbloomit's funny to me that rich had the foresight to avoid fancy truthiness, but still couldn't avoid the siren song of falsey nils
14:25bbloomthen sure enough, lazy seq enhancements come along, and we need (seq ...) everywhere anyway to deal with the subtle nature of next vs rest
14:25bbloomjust goes to show that you can solve 783957935 problems in a language design, and still miss.. INFINITELY MANY MORE
14:25bbloom:-P
14:26TimMcand nil being punned as the empty seq as wlel
14:26ambrosebsbbloom: is this stuff easier to handle with just one false value?
14:27ambrosebsbbloom: the lazy seq stuff
14:27bbloomambrosebs: and just one true value, yeah i think so
14:28bbloomyou'd have (if BOOLEAN x y) and then if-let would only make sense as not-nil
14:28bbloomor None rather
14:28bbloommake nil be the empty seq, use None for logically no value
14:29dnolen_ambrosebs: bbloom: I don't see how one value solves the lazy-seq thing. you don't use seq to differentiate rest and next
14:29dnolen_seq + rest just works. if you use next you generally only call seq once.
14:30bbloomdnolen_: (rest [1]) would return nil and (rest nil) would return None, then you'd iterate until empty?. would be a bit clearer, but is basically a total rewrite of core :-P
14:30bbloomnot saying that what we have now isn't good
14:30bbloomjust saying that it can, as always with anything, be better
14:32ambrosebsbbloom: trying to unlearn clojure to grok your point ..
14:33bbloomambrosebs: actually, (rest nil) could be a type error
14:33TimMc&(assoc nil 4 5)
14:33lazybot⇒ {4 5}
14:33bbloom,(first nil)
14:33clojurebotnil
14:33TimMc^ seriously bizzare
14:33bbloomturns out, in clojure, nil actually represents an infinite list of nils :-P
14:34gfrederickseach of which in turn,
14:34TimMcbbloom: Each one of which is an infinite list of nils...
14:34teslanickThat's a pretty awesome language wtf. :)
14:34bbloomTimMc: ok, fine an infinite tree of nils :-)
14:34bbloomnil is used for all loads of stuff
14:34bbloombut we're mainly stuck with it thanks to java
14:34gfredericksa tree with infinite branches at each node and no leaves
14:35gfredericksambrosebs will save us from the nils
14:35r0b1bbloom: mainly stuck with nil due to java?
14:35bbloomreally, we're stuck with *null* which is a useless form of none :-P
14:35hyPiRiongfredericks: and the branches are ordered too
14:35TravisDteslanick: Being strange makes it awesome?
14:35bbloomr0b1: calling java code can return null, so we need to be able to deal with null references in clojure
14:35r0b1ah
14:36bbloombut in a sane language, there would be no null references, only null pointers. if you wanted a null reference, you'd have a single instance of a None type
14:36teslanickTravisD: Maybe? Does that make Javascript *the most awesome* ?
14:36TravisDteslanick: I wouldn't think so :P
14:36munderwoHi all. I've got a question about defining a db connection? code and question here https://www.refheap.com/39431. ...
14:37TimMcbbloom: I still don't understand the difference between a null pointer and null reference.
14:37teslanickI'm trying to get better string comparisons in a clojure unit test. I'm just using clojure.test right now, does midje offer clearer diffing?
14:38bbloomTimMc: a null pointer is a pointer to memory address zero. the pointer is a first class thing you can manipulate. a null reference is a null pointer that you can't talk about directly, ie to differentiate between the reference itself and the thing it refers to
14:38hyPiRionTimMc: A null pointer is of type Null/Void, containing nothing. A null reference is of type X
14:38ambrosebsI'm working on some destructuring macros that makes this kind of stuff explicit. Map destructuring fails on a missing key (dynamically and statically) unless you provide :or. Vector destructuring statically checks bounds by default, has options to check dynamically or use a default value for nth.
14:38hyPiRionSeems like I have completely different ideas about this than bbloom.
14:38bbloomTimMc: null references are not possible in C++, for example
14:39hyPiRionI'm not alone.
14:39hyPiRionbbloom: So you say you cannot do &NULL in C++?
14:39bbloomhyPiRion: http://stackoverflow.com/questions/4364536/c-null-reference
14:40bbloomsmalltalk (and by extension ruby) got this right: null is an object
14:41bbloomto be pedantic, null can actually be non-zero on some old/weird architectures/operating-systems
14:41hyPiRionI feel it's more correct to consider Null/None/Void as a noninstantiable type. But that would of course require statical typing.
14:41TimMcWhere null is an object, doesn't that mean a null reference?
14:42bbloomTimMc: no, it's a reference TO the null object. not a reference that points nowhere
14:42bbloomhyPiRion: void is a class with ZERO instances
14:42aphyrmunderwo: Use (def ^:dynamic *db* {...})
14:42bbloomhyPiRion: where as None is a call with one instance :-P
14:43aphyrThen you can override it with (binding [*db* {... some-other-db ...}] (more-functions))
14:43munderwocool, I'll give that a go. Does that make the var definable on a per thread basis? I think I remember reading about that.
14:43aphyrYep.
14:43hyPiRionbbloom: yeah, but it's defined differently in different languages. Haskell and Rust uses None, for instance.
14:43aphyrBut honestly, you may want to consider just making db a parameter to your functions.
14:43hyPiRionOh wait, I gotcha now.
14:43aphyrEasier to test and reason about.
14:43bbloomhyPiRion: i'm generalizing names across languages. there are several concepts to contend with....
14:44TimMcbbloom: So in smalltalk you have a reference to the null object, whose memory location is zero?
14:44hyPiRionbbloom: yeah, Void is uninstantiable, whereas None is a singleton
14:44bbloomTimMc: no. the memory location of null is not zero in smalltalk or ruby
14:44bbloomirb(main):002:0> nil.object_id
14:44bbloom=> 4
14:44TimMcSo it's not a null pointer either?
14:44TimMcmore like Unit
14:45bbloomTimMc: yeah, more similar to Unit, which is, THE "unit" type, b/c it has only one instance, but None is *also* a unit type, just not THE unit type
14:45bbloomTimMc: that's why i don't like the name Unit for a type b/c it's confusing... it suggests you can't have other unit types
14:45TimMchmm
14:47TimMcf10dd67234035228da3ec382bab7a49b
14:47bbloomlol
14:49hyPiRionIt's a shame Java doesn't have generic enumerations. That would've solved a lot.
14:50bbloomanyway, if it were up to me, i'd break everybody and just redefine (if-let [x (evaluates-to-false)] ...)" to be a bug
14:50bbloomactually, hmmm... can we do that? lol
14:51hyPiRionbbloom: alter-var-root?
14:51bbloom:-)
14:52hyPiRionI tried to manipulate false to return true through reflection once, but it segfaults the JVM unfortunately
14:52bbloomno seriously... the only difference between if-let and if-some is the handle of false
14:52bbloomhandling*
14:52bbloomit would be a breaking change for anybody who passes false to if-let, but could easily be worked around by passing nil instead
14:53bbloomseems like if-let should have always been if-some
14:54ambrosebsbbloom: I could add a case in dynalint.. :)
14:55ambrosebsbbloom: I've considered adding a case for (some #{nil false} ...)
14:56hyPiRionambrosebs: you should, it always return nil regardless.
14:56dnolen_bbloom: various proposals for things like if-some have come up in the past, it's an obvious generalization of if-let
14:56bacon1989Hello, I was wondering if someone could point me in the right direction with a fairly simple data-restructuring problem. Say I have a hashmap, like {:first-name "John" :last-name "Doe" :age 24} and I wish to create a new hash-map with only the :first-name and :last-name keys, what are some possible ways to do this?
14:56bbloomdnolen_: it's not a generalization
14:56dnolen_bacon1989: dissoc
14:56paulswilliamsesqHi all, can any kind soles assist in explaining why code seems to execute in functions when the functions haven't been invoked?
14:56bbloomdnolen_: it's a workaround for a semantics bug, IMO
14:56dnolen_bbloom: how is it not?
14:56ambrosebsbacon1989: select-keys
14:57dnolen_bbloom: no semantic far as I can see.
14:57bbloomdnolen_: "generalization" implies it solves a more general class of problems
14:57hyPiRionbacon1989: (select-keys my-map [:first-name :last-name]) will ensure that only first-name adn last-name is contained
14:57dnolen_bbloom: it does, multiple bindings, multiple tests
14:57dnolen_this happens all the time and it's ugly
14:58bbloomdnolen_: i think you didn't follow my though process above
14:58CaptainLexSo I assume this question is asked all the time
14:58CaptainLexbut
14:58CaptainLexwhy doesn't clojure support tail-recursion optimization?
14:58dnolen_bbloom: I did, but I also didn't agree or see the point.
14:59bbloomdnolen_: the point is that if-let testing truthiness was always an approximation for the desired semantics of checking non-nil-ness
15:00aphyrif-let*
15:00bbloomdnolen_: (if-let [x false] ....) is just not very useful
15:00aphyrbbloom: I actually use that form all the time
15:00bacon1989ah thanks guys, i'll look at those functions
15:00bbloomaphyr: you use if-let with an expectation of a false value all the time?
15:01aphyrWith the expectation of a non-false or non-nil value.
15:01bbloomaphyr: but do you ever expect false? or always nil vs not nil ?
15:02aphyrI typically don't want to bind false.
15:02munderwoaphyr: yeah thats probably what I would do in other languages, all the examples I've seen have defined it in the file and then just referred to the global after that. So I wasn't sure if there was some clojure-esque reason to do that, or they were just simplified cases.
15:03bbloomaphyr: but do you want to bind true?
15:03bbloomaphyr: presumably when you use (if-let [x ...) you want a useful payload in x
15:03aphyrSometimes the values of x might be either false or a number.
15:03dnolen_bbloom: (if-let [x (and (pred? y) (compute z))] ...)
15:04aphyrI dunno, I can certainly see an argument for changing if-let and when-let to non-nil as opposed to truthy.
15:04bbloomdnolen_: that's not what if-some is
15:04dnolen_bbloom: you're right that if-some is generalization of a particular usage of if-let
15:04aphyrBut that seems confusing when you compare it to (if) and (when)
15:04bbloomdnolen_: oh wait....
15:05bbloomdnolen_: sorry, my bad
15:05dnolen_(if-let [...] (if-let [...]))
15:05bbloomdnolen_: i'm looking at the ticket now
15:05bbloomdnolen_: or the actual patch rather
15:05bbloominstead of the comments in the thread
15:05dnolen_heh
15:05bbloomoh wow
15:05dnolen_starting in the wrong place man
15:05bbloomnevermind, these names are mega confusing lol
15:05gfredericksoh geez
15:05bbloomif-pred
15:05hyPiRionwhat, there's an if-pred?
15:05bbloomok i still stand by all the stuff i said above about if-let
15:06gfredericksbbloom: what aspect do you think is confusing?
15:06sjlif-some == if-not-nil-let
15:06aphyrYep.
15:06gfredericksbbloom: (I'm not sure how you were misunderstanding it)
15:06bbloommaybe i'm not... hold on
15:06bbloomi'm looking at http://dev.clojure.org/jira/secure/attachment/12790/clj-1343-4.patch
15:07bbloomthat patch seems to not match what rich is saying
15:07hyPiRionwhat. I had the intuition that if-some was (if (not (nil? z))) x y)
15:07gfrederickshyPiRion: that's most people's complaints wrt confusing names
15:07sjlhyPiRion: no, it binds things like if-let
15:07sjleven though there's no -let in the name
15:07bbloomdnolen_: no no, i'm right
15:07bbloomdnolen_: there is no explicit predicate
15:07bbloomit's not a generalization
15:08hyPiRionsjl: yeah, I gathered. I even read the 1.6 changelog and still thought it acted like that.
15:08sjlhyPiRion: yeah that's because the naming is confusing
15:08sjlhah
15:08bbloomdnolen_: it would be a generalization if it took an explicit predicate
15:08aphyrI could see (let-some)
15:08bbloomdnolen_: there is a generalization if if-let and if-some that would be if-pred
15:10paulswilliamsesqin particular, defn-ing a function with (defn draw-frame [f x y] (let [frame (java.awt.Frame.)])) causes a Frame to be instanciated yet I haven't invoked the function.
15:10bbloomdnolen_: `(defmacro if-some [[k & v] then else] `(if-pred (comp not nil?) [~k ~v] ~then ~else)) ; for some hypothetical if-pred, then if-pred would be the generalization of if-some and if-let, where if-let's explicit predicate is simply `boolean
15:10bbloomi stand by everything i said above :-)
15:12ambrosebspaulswilliamsesq: does it still show a frame when compiled in a REPL? Perhaps you're running other things accidentally.
15:12paulswilliamsesqambrosebs: yeah - I've loaded a new repl and defn that function. I can't actually see a frame but a seperate window appears to open.
15:12bbloom,(defn test-pred [pred x] (if (pred x) x nil))
15:12clojurebot#'sandbox/test-pred
15:13bbloom,(map #(test-pred odd? %) [3 4 5 6])
15:13clojurebot(3 nil 5 nil)
15:13bbloomdnolen_: ^^ there, now you don't need if-pred :-)
15:13bbloom,(if-let [x (test-pred odd? 5]] :yup :nope)
15:13clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
15:14bbloom,(if-let [x (test-pred odd? 5)] :yup :nope)
15:14clojurebot:yup
15:14bbloom,(if-let [x (test-pred odd? 6)] :yup :nope)
15:14clojurebot:nope
15:14bbloom:-)
15:14hyPiRion,(if-let [x (test-pred false? false)] :is-false :is-true)
15:14clojurebot:is-true
15:14hyPiRion:)
15:14bbloomhyPiRion: clearly you need to use if-some, since if-let is broken
15:15bbloomhyPiRion: but the bots aren't up to date, so i just assumed clojure 2.0 where this is fixed ;-)
15:15bbloomor maybe it's bbloom 1.0
15:15hyPiRionbbloom: good call
15:15bbloomwhatever :-)
15:15sjl,(if-some [x (test-pred nil? nil)] :is-nil :wat)
15:15clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: if-some in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:16bbloom,(defmacro if-some [bindings then else] (let [form (bindings 0) tst (bindings 1)] `(let [temp# ~tst] (if (nil? temp#) ~else (let [~form temp#] ~then)))))
15:16clojurebot#'sandbox/if-some
15:16bbloom,(if-some [x (test-pred nil? nil)] :is-nil :wat)
15:16clojurebot:wat
15:16bbloomhyPiRion: there you go
15:17sjlbbloom: that's wrong though
15:17sjlbbloom: the predicate is nil
15:17sjl?
15:17hyPiRionbbloom: heh.
15:17sjlnil satisfies the predicate
15:17sjland yet the else clause is returned
15:18erdoshello everybody, i have a symbol object that behaves a little bit strange for me: for (str), (type), (symbol?), (name), (bean) it returns: use, clojure.lang.Symbol, true, nil, {:namespace nil, :name use, :class clojure.lang.Symbol}; my question is, why is it possible it gives nil for (name)? thanks!
15:18bbloomsjl: and now you see why type theory people argue for sum types :-)
15:18sjlyep
15:18bbloomat this point, you need quoting :-P
15:18bbloomb/c you need None and Some(None)
15:18sjlyou need to disentangle the value from the predicate check
15:18sjla hypothetical if-pred would be fine
15:19bbloomand an if that only operates on booleans would help too
15:19sjlbut that if-some form is basing its decision on both the result of the predicate and (if test-pred passes it through) the value itself
15:21hyPiRionerdos: That's strange, how did you construct the symbol?
15:21hyPiRionI can't reproduce that
15:21hyPiRion,(name 'use)
15:21clojurebot"use"
15:23paulswilliamsesqambrosebs: well, it appears not to draw the frame, but definately starts some other process up. I'm on OSX and get a new window opened with a Main menu item if that makes sense?
15:23erdoshyPiRion: hello, i used clojure.tools.reader/read
15:23erdoshyPiRion: even (.getName) returns the correct value. also (string?) is false.
15:24heathi was watching rich give a presentation on csp about a week ago on callbacks
15:24ambrosebspaulswilliamsesq: unless there is some macro that spins up a process when it expands, I don't see how that's possible
15:25heathhe mentioned promise libs are popular again because of this
15:25ambrosebspaulswilliamsesq: I guess you've tried restarting your JVM?
15:26heathi was under the impression while he was talking that promises are something you wouldn't want to utilize, but i'm seeing in the notes of the latest clojure release that promises are available and stable?
15:26heathWhy does clojure have promises, and are these the same types of promises he was referencing in the talk?
15:26ambrosebserdos: can you elaborate more on where the symbol is coming from? is it metadata?
15:27paulswilliamsesqambrosebs: no I don't either. yes, I've killed all JVMs.
15:27eggheadheath: the general idea is that promises are good for one-off async events, but they aren't too good for streams
15:27paulswilliamsesqnew lein repl from my home directory which has't got a lein project installed.
15:27ambrosebspaulswilliamsesq: perhaps try it in a completely empty project? I'm out of ideas.
15:27paulswilliamsesqambrosebs: yeah, wil do.
15:28erdosambrosebs: hello, i am parsing ns declarations of source files with clojure.tools.reader 0.7.7 . strangely .getName is ok.
15:28ambrosebserdos: can you show some code?
15:29erdosambrosebs: working on it
15:29heathcool, thanks egghead
15:29ambrosebserdos: would like to know out of morbid curiosity as well ;)
15:29dnolen_bbloom: yes I said agreed, it generalizes a very specify use of if-let
15:30dnolen_s/specify/specific
15:30bbloomdnolen_: i think disagree on what the word "generalizes" means...
15:32aphyrhaha
15:32bbloomdnolen_: it specializes a more general predicate/binding/branching pattern. if-let is also a specialization of that same general thing
15:33dnolen_bbloom: macro sugar generalizes patterns as far I am concerned.
15:34bbloomdnolen_: generalize is not the word you're looking for
15:35dnolen_generalizes syntactical patterns, or perhaps you don't believe that macros do this?
15:35dnolen_bbloom: then give me a better word?
15:35hyPiRionunboilerplatify them at least
15:35dnolen_:P
15:36bbloomabbreviate? i dunno
15:36bbloomdefinitely not generalize
15:36dnolen_bbloom: then rewrite in your brain my points and we can move on :)
15:37bbloomdnolen_: yeah, the word "abbreviate" works for your points, heh
15:38benmossdnolen_: can you explain the conceptual difference between state stored on the owner vs on the component in Om?
15:38bbloomonce again, 99% of all disagreements can be divided in to one of two fundamental categories: operating from different definitions or operating from different motivational principals
15:38bbloomi'd imagine 60 to 80% are in the definitions camp :-P
15:39dnolen_benmoss: Om uses delegation, there's only one React component type in Om, so we delegate to your reify instance.
15:39dnolen_benmoss: component local state is actually stored on the React component that "owns" your reify instance
15:45benmosshmm I'm afraid i don't follow
15:46dnolen_benmoss: above you're describing a distinction that does exist. That's what I was trying to explain.
15:46dnolen_s/does/doesn't
15:46benmossyeah, that's what i suspected
15:49benmossso to use a concrete example, in your todo app you set "needs-focus" on the owner, whereas you set "editing" on the component. are you saying they actually are both on the owner?
15:50dnolen_benmoss: easier to understand what you're struggling w/ if you give me links to line numbers?
15:50benmossyeah was about to get that
15:50eggheadhm
15:51benmosshttps://github.com/swannodette/todomvc/blob/gh-pages/labs/architecture-examples/om/src/todomvc/item.cljs#L31 sets "needs-focus" on the owner, https://github.com/swannodette/todomvc/blob/gh-pages/labs/architecture-examples/om/src/todomvc/item.cljs#L31 reads "editing" off the todo
15:51eggheadi figured the app-state was things like the stuff that comes over your web api, and the owner-state was stuff that had to do with the state of your components like async chans or things like error messages, etc
15:51benmosswoops
15:51eggheadbut I could see something like 'is this component in edit mode' going into owner state
15:51benmosshttps://github.com/swannodette/todomvc/blob/gh-pages/labs/architecture-examples/om/src/todomvc/item.cljs#L66 for the second link
15:52eggheadI guess that's just an organization sort of thing?
15:52dnolen_benmoss: so the second is link is what is referred to in the React world as "props"
15:52dnolen_benmoss: the first link is setting component local state
15:53dnolen_benmoss: in Om "props" are values from the app-state atom
15:53benmossyeah
15:53benmossso i think that is what i was trying to get at, what is the conceptual difference between what you would store in app-state vs component local state
15:53dnolen_benmoss: usually anyway, props can actually be anything.
15:54dnolen_benmoss: very little should go into local state, like egghead said - channels, transient information (like mouse position, element dimensions), etc
15:55dnolen_benmoss: however there is no hard fast rule, if you want to snapshot many points in a graphical editing application, maybe you do want to store what you normally consider transient state
15:57benmossi'm trying to model a chess game and think i need a place for "the possible moves for a given piece/position"
15:58benmossit both represents the legal moves for that piece, as well as the information for which other positions to highlight
15:59dnolen_benmoss: but I don't think you need to store that you can compute that
16:01benmosshm, through each individual square checking to see if it is eligible for being moved from a piece of top-level app state about the currently selected square?
16:03benmosslike the app-state would contain {:currently-selected "e8"} or whatever, and each square could check what piece is on e8 and thus if that piece could move to them?
16:03TravisDCan anyone suggest a library that facilitates linear algebra and plotting? I was looking at Incanter, but it seems somewhat outdated
16:04dnolen_benmoss: no you would compute the grid based on the information you have and then render it.
16:05dnolen_benmoss: individual squares compoent should just render the data they get - no logic except maybe click event
16:07TravisDActually, incanter looks pretty nice.
16:07dnolen_benmoss: a better way in mind would be a component to get {:current-selected true} and have some additional behavior because of this.
16:10benmossyeah so a function that passed {:selected true} to the selected square, and like {:targetable true} to the squares the piece can reach
16:10dnolen_benmoss: yep
16:11benmossthanks, it seems so obvious now :)
16:12dnolen_benmoss: chess is actually a pretty good thing to try with Om.
16:12dnolen_benmoss: this actually a pretty presentation that someone did at RubyFuza on Om http://www.slideshare.net/danieroux/rubyfuza-2014, uses chess as an example
16:12benmossyeah, i saw you posted that on twitter
16:13dnolen_s/pretty/pretty sweet
16:14benmosslooks very similar, i think we both ripped off the same html chess board
16:17bbloomdnolen_: thank you so much for helping react take off :-)
16:17bbloomwe as a profession will escape the brain dead OOP GUI model some day
16:17dnolen_bbloom: haha, yeah it's exploded!
16:17dnolen_bbloom: finally people are looking past JSX
16:18bbloomdnolen_: my guess was that it was an audience targeting issue. the typical javascript folks didn't understand why it was interesting and the folks who would understand simply have given up looking at javascript stuff
16:18dnolen_bbloom: haha
16:18bbloomthe cljs community was inherently the right overlap
16:19bbloomie people who care about browser GUIs AND sane semantics
16:22dnolen_bbloom: yeah, I'm starting to see that React/Om really shines though w/ core.async
16:22bbloomdnolen_: have you baked it in to Om yet? / will you?
16:22dnolen_like multiple om-syncs can write to a channel and you can write batch update logic to server. w/o screwing around w/ your code.
16:22dnolen_bbloom: probably won't do that. Om is close to "done". Only interested in internal improvements and more performance.
16:23bbloomdnolen_: ok cool
16:23bbloomfor further communal self congratulations: gotta love libraries that are "done"
16:26AmnesiousFunesdnolen_: Thanks for your work with Om; it's a really pleasant library, and I see myself using it as much as possible in the future.
16:26benmossmeanwhile thousands of people use the perpetually in-beta ember-data
16:26dnolen_benmoss: lol
16:26dnolen_AmnesiousFunes: thanks!
16:27AmnesiousFunesbenmoss: I remember Discourse (the big forum project) electing to use Ember because they felt it was "future-proof".
16:27bbloombenmoss: over 10k of javascript for that thing... and it has dependencies too
16:28bbloomklocs, that is
16:28bbloomnot kb
16:29AyeyDoes Discourse use ember-data? I thought they avoid it because it was unstable.
16:29benmossthey don't
16:31Ayeyph, okay
16:31Ayeyoh*
16:34benmossit is an ORM for APIs, it is a horrible thing
16:36bbloomtwo things i dislike :-P
16:36bbloomi'm pretty sure that my hate gets multiplied together, rather than added
16:38btcNeverSleeps,(doc doc) ; just trying if doc works here
16:38clojurebot"([name]); Prints documentation for a var or special form given its name"
16:38bbloombtcNeverSleeps: doc also works here without the ,
16:38bbloom(doc doc)
16:38clojurebot"([name]); Prints documentation for a var or special form given its name"
16:38btcNeverSleepsbbloom: oh cool ^ ^
16:41btcNeverSleepsI'm doing this: (make-array (type XXX) x y)) because I don't know what type XXX is. Is it ok to use (type ...) on something to pass the type around without knowing what the type is?
16:42bbloombtcNeverSleeps: seems fine, but do you actually want a typed jvm array or do you want Object[] ?
16:44btcNeverSleepsbbloom: Object[] would be fine too. In my case I was instantiating an array of sha-256 hashes, so it's an array of byte arrays.
16:44bbloom,(make-array Byte/TYPE 5)
16:44clojurebot#<byte[] [B@4ed19b>
16:44bbloombtcNeverSleeps: is that what you want?
16:45bbloombtcNeverSleeps: if you know that the array contains only primitives of one type, then you probably want a primitive array to avoid boxing
16:45btcNeverSleepsbbloom: well, yes but... My question was more like: is it ok to simply do (make-array (type (byte-array [])) or, more generally, (make-array (type ...)) when you don't know what type you're dealing with.
16:45btcNeverSleepsbbloom: oooh gotcha
16:45bbloombtcNeverSleeps: oh i see, an array of byte arrays
16:45bbloombtcNeverSleeps: arrays are, themselves, boxed types. so it won't matter
16:46bbloomunless you care about interop with some java API
16:46bblooman array of objects is fine for the outer array
16:48bbloombtcNeverSleeps: make sense? so you can just use object-array or into-array without a type argument
16:48hyPiRionit's not hard to just do (make-array (Class/forName "[B") dims) either
16:49bbloomhyPiRion: there is no benefit to doing so. actually it probably hurts, since you'll get an extra type check at runtime
16:49benmossis there something more succinct than (if (pred? x) (conj x foo) x)
16:49bbloomhyPiRion: java's array variance stuff is all kinds of weird
16:49btcNeverSleeps(was afk)
16:49btcNeverSleepsbbloom: yup, makes lots of sense
16:49benmosslike an if/when that defaults to returning the value
16:49hyPiRionbenmoss: (cond-> x (pred? x) (conj foo))
16:50benmosshyPiRion: thanks
16:50hyPiRionbbloom: funny, didn't know that
16:51bbloomhyPiRion: i mean, i'm just guessing about how the jvm works here, but think about it.... it has to throw an error if hte type doesn't match
16:51bbloomhyPiRion: but if you already have a boxed pointer, you can just copy it w/o checking it, right?
16:51hyPiRionbbloom: right, but then you'd have to check at read time then?
16:52btcNeverSleepshyPiRion: I know it's not hard to do (make-array (Class/forName "[B") ...) but I was wondering, when you don't know if it's [B or [I or whatever, is it ok to just create a "dummy" object and call "type" on it. IOW: (Class/forName "[B") vs (type (byte-array []))
16:52btcNeverSleepsfor it feels like some kind of a "hack" to write (make-array (type ...) ...)
16:52danneu(Class/forName "[B") is 'hard' though
16:52danneuugh
16:52btcNeverSleepsdanneu: well, I come from many years of Java so it doesn't look too alien but I tend to agree it's 'hard' ^ ^
16:53Cr8,(class (byte-array []))
16:53clojurebot[B
16:53bbloomhyPiRion: hm, that is true...
16:53hyPiRionbtcNeverSleeps: Well, you could just do (def byte-array-type (type (make-array Byte/TYPE))), if you're afraid of perf
16:54bbloomhyPiRion: perf likely depends on whether your calling a virtual method or not. if it's a non-virtual method, then yeah, you need to pay a type check cost for that. but if it's a virtual method, you'd likely get a polymorphic cache at the call site, so it wouldn't matter either way
16:55bbloombtcNeverSleeps: either way, use the more specific type if it makes you feel good or if you benchmark it and it matters :-P
16:55btcNeverSleepsbbloom: :)
16:55danneuClojure has been a joy for working with bytes. (map int <bytes>), (map (partial bit-and 0xff) <bytes>), (map unchecked-byte <ints>)
16:56hyPiRionheh, I've sort of given up on an actual analysis of performance wrt. time.
16:56bbloomheh
17:05NooobHi, guys, Im a Clojure newbie, and I have a simple question that I think you guys can help me with... which IDE should I use?
17:05aphyrNooob: most folks use emacs or vim.
17:06aphyrThough any text editor you like should work fine.
17:06aphyrSome folks use LightTable, which is a clojure-specific IDE, but I don't think that's common yet.
17:07Nooobaphyr I was messing with emcas, but feels weird
17:08dnolen_Nooob: CursiveClojure is very good, probably the best traditional IDE experience
17:08Nooobhummm
17:08dnolen_Nooob: LT is simple and pretty easy to use
17:08AmnesiousFunesCIDER is quite good as well. Light Table is very immediate and accessible.
17:10r0b1Nooob: i was going to suggest emacs as well but it doesn't seem to be for everybody. it has the bonus that you can extend the editor with lisp though.
17:10danneuI tried various editors when I was learning Clojure. I can't imagine fiddling with an editor during that stage
17:11qbgNooob: Are you comfortable with with an IDE for another programming language?
17:11Nooobr0b1 this ability to extend the editor really makes the difference?
17:12Nooobqbg yes =)
17:12qbgWhich one?
17:12AmnesiousFunesNooob: For "serious" usage, yes. (By the way, Light Table is also extensible.)
17:12r0b1Nooob: "with lisp", yeah :) as you learn clojure you'll become more comfortable learning elisp and vice versa i'd guess.
17:12AmnesiousFunes(It is much less mature than Emacs with CIDER at this stage, though.)
17:13danneuNooob: For Clojure, what matters is arriving at a quick iteration where you can eval code within the editor (not in a REPL)
17:13Nooobqbg Eclipse, NetBeans...
17:13r0b1that are horrible "editors"
17:13r0b1those*
17:14aphyr(I basically just use vim as a dumb text editor, and use `lein repl` for live evaluation.)
17:14qbgIn the past I've used Counterclockwise with Eclipse, but I've been out of the Clojure loop for a while
17:14danneuaphyr: how do you get code to the repl?
17:16Nooobwell, I think ill try Cursive and give emcas another shot hehe
17:17AmnesiousFunesdanneu: lein repl can load namespaces automatically; read about leiningen configuration for more information
17:19aphyrdanneu: (use 'foo.core :reload)
17:20aphyrThough most often I have lein prism running, so I just write the file and it automatically re-runs the tests.
17:20danneuyeah, i don't know why i asked that
17:20danneuthat's how often i've used a repl
17:21danneuaphyr: have you ever used an editor that lets you eval the buffer? i only ask because evaling the buffer or the selected region or previous form are the most productive things to ever happen to my workflow.
17:21r0b1your repl can help in cases like this by better supporting "repl-driven development"
17:24Nooobwell, guys thank you very much for the tips ^^ I really appreciate, and sorry for my bad english hehe
17:24kozHi everyone! I've just installed Linux Mint 16, and set up leiningen for it. However, when I tried to run 'lein upgrade', it told me that I should be using apt instead of leiningen for upgrades.
17:24kozHow do I do that?
17:26benmoss`apt-get install leiningen`?
17:26kozbenmoss: really? OK... simpler than I thought.
17:26kozThanks!
17:26kozAlso, does SciTE have any support for Clojure?
17:27benmossnever even heard of SciTE, no idea
17:27kozWhat's a good text editor with Clojure support for Linux. Other than Emacs/vim.
17:28koz(Although I should learn Emacs some time)
17:28systemfaultkoz: Perhaps lighttable
17:28benmosspeople were just talking about this, yeah light table is a popular choice
17:28danneukoz: does `lein` do anything when you run it?
17:28benmossif you don't have any prior allegiances
17:28kozdanneu: Yeah, it works for everything as normal.
17:28danneukoz: what version is it
17:28kozbenmoss: I'm new to Linux. So no, no priors.
17:29benkay,(map #(inc %) [1 2 3])
17:29clojurebot(2 3 4)
17:29kozdanneu: 1.7.1
17:29benkay(map #(inc %) [1 2 3 \f])
17:29kozWhich I assume is the latest.
17:29benkay,(map #(inc %) [1 2 3 \f])
17:29clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number>
17:29danneukoz: `apt-get install leiningen` installs an old version. install it by hand
17:29hyPiRionkoz: no, 2.3.4 is the latest one
17:29amalloy$google leiningen readme
17:29benkayright, so how do I shoehorn a try/catch into that mapping?
17:29lazybot[leiningen/README.md at master · technomancy/leiningen · GitHub] https://github.com/technomancy/leiningen/blob/master/README.md
17:29danneukoz: https://github.com/technomancy/leiningen
17:29kozAh, I see.
17:29kozThanks.
17:30hyPiRionkoz: so you'd do `sudo apt-get remove leiningen` first, to remove the apt installed version
17:30benmossmy bad, i had no idea apt was out of date
17:30amalloyi don't think apt-get install installs the latest version of *anything*, but it's more out of date than usual for clojure stuff
17:30kozThanks for the warning guys.
17:30danneuyeah, it gets brought up some time. it's unfortunate that apt is out of date and it makes things not work in nonobvious ways
17:30amalloydanneu: i mean, that's like a core feature of apt. things get in when they're stable, not when they're new
17:30benmossand that the old lein upgrade warning tells you to use apt
17:31danneuamalloy: sure, i mean unfortunate for a newcomer that doesn't know
17:31gwsbenkay: do you expect the result to be nil or (2 3 4) or something else?
17:31benkayah it's not the result i'm terrifically concerned with so much as the inputs
17:32kozSo you want it to fail if you feed it a list with anything other than a number?
17:32benkaywell, it's an example.
17:32benkayi want to catch exceptions thrown in the mapped function
17:33kozCan't you wrap the whole map call in a try-catch?
17:33gwsyeah, and then do what with the result
17:33hyPiRionkoz: unfortunately, map is lazy, so that won't do
17:33benkayuh, log it, throw it away, i don't care fuckit.clj
17:34benkaythe root question i'm pursuing here is how best to implement a try/catch with a mapped function
17:34benkaymap the try/catch form?
17:34benkay(map #(try (my-fn %) (catch some.java.whatever) [list-o-stuff]))?
17:34kozbenkay: Not what I meant. Wrap the actual map call in a try-catch.
17:35hyPiRion,(try (doall (map inc [1 2 3 \f])) (catch Exception e :error))
17:35clojurebothyPiRion: Cool story bro.
17:35hyPiRion&(try (doall (map inc [1 2 3 \f])) (catch Exception e :error))
17:35lazybotjava.lang.SecurityException: You tripped the alarm! catch is bad!
17:35hyPiRionblugh.
17:35hyPiRionWell, the point is that you have to wrap it in a doall or replace it with mapv. Otherwise the exception could get thrown outside
17:36benkaysure, makes sense. the actual funcall is happening inside a doall already and is being pmapped to make things worse and more complex
17:37benkayso walk me through one more time in words of single syllables why mapping the try/catch is not going to work?
17:38hyPiRionMapping the try/catch would work nice, but I have no idea what you'd like the mapping to return then
17:39benkayit's a nasty side-effecty thing don't worry about it
17:39benkay,(map #(try (inc %) (catch java.lang.ClassCastException (println "nooooo"))) [1 2 3])
17:39clojurebotbenkay: No entiendo
17:39benkayyeah me neither clojurebot
17:40benkayokay well in that case i'm going to defer to your sage advice hyPiRion and wrap the doall.
17:41kozOK, manual install worked.
17:41hyPiRionbenkay: well, I mean. It sort of depends on what you want. catching outside would stop the execution of later function calls (sort-of, pmap is its own beast), whereas wrapping it inside the function would not
17:41kozThanks everyone.
17:41benkayhyPiRion: just figured that out :(
17:41benkayyeah! i think i really want to pmap the try/catch itself if i can..
17:42hyPiRionbenkay: yeah, go ahead. Noone's stopping you
17:42beamso,(doc int?)
17:42clojurebotPardon?
17:43beamsoyou could do a check to ensure every item in the vector was an integer
17:44benkayagain, beamso, that's not really what's at issue here.
17:44kozOK.... maybe not.
17:44kozI get
17:44koz'THe program 'lein' is currently not installed. You can install it by typing: sudo apt-get install leiningen
17:44kozBut that will give me the old version
17:45hyPiRionkoz: okay, where did you place the lein script?
17:45qbglein is probably not on your path
17:45kozin ~/bin, which is on my path.
17:45hyPiRionkoz: did you do `chmod u+x ~/bin/lein` ?
17:46hyPiRion(to make it executable)
17:46beamsomove the 'inc' into it's own function where you handle the exception there and provide a default value/no value to return?
17:46kozNo - I did chmod +x
17:46kozSo I need the u as well.
17:46hyPiRionwell, that shouldn't matter I think
17:46qbgHow long has ~/bin been on your path?
17:46hyPiRionI'd try to restart the shell, sometimes it may not detect stuff at once
17:46kozI just put it there, and I restarted the shell.
17:47kozIf I type echo $PATH, it's definitely there.
17:47koz(As the very last entry)
17:48qbgwhat does `which lein` return?
17:48kozNothing.
17:48qbgPerhaps PATH is malformed?
17:48kozI'll just copy-paste the result of echo $PATH
17:49koz/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:home/koz/bin
17:49qbgyou need /home there
17:49qbgnot home
17:49kozAh,
17:49kozOK.
17:50kozFixed. Also FML. I'm too used to Windows shell.
17:50hyPiRionkoz: It'll go over eventually. We've all been noobs at shell and Linux once
17:51kozhyPiRion: Thanks. Appreciate the sympathy. :)
17:51kozOK, it's downloaded a jar.
17:51kozI guess I have to run it?
17:51hyPiRionkoz: no, lein does everything by itself, managing upgrades and stuff
17:51AimHereI think it's best to remain a noob at shell; learn to invoke perl or python or your scripting language of choice from the command line
17:52kozWell, I ran the self-install.
17:52qbgjust run `lein` then :)
17:52kozAh.
17:52kozThere we go.
17:52kozIt's getting a whole shittonne of jars
17:52kozMeaning I probably did something right.
17:52amalloythat's maven for you
17:53hyPiRionkoz: yeah, it's downloading the Internet
17:53kozYay, the whole Internet!
17:53kozOK, I now have Leiningen 2.3.4
17:53kozSuccess!
17:53systemfaultOh yeah
17:54amalloyAimHere: i think it's reasonable to be pretty bad at writing .sh files, but some familiarity with the actual shell is good - you can be a lot more concise than you could be if you had to write it as a python script
17:54kozIn this case, these commands are so simple that knowing them helps. Plus, I've kinda gotten into the CLI habit.
17:54kozAnd I like working with a shell.
17:54kozIt's easier.
17:54kozOK, maybe you guys can help me with this one.
17:55kozI've installed Linux Mint, and I want it to dual-boot with my Windows 7.
17:55kozI partitioned my drive and everything, and the install went fine.
17:55kozBut I can't boot the Linux half - at boot time, it just goes straight to Win7.
17:55AyeyWhat order did you install them?
17:55kozWin7 was there first.
17:55systemfaultSure... Windows doesn't care about your bootloader, it kills it.
17:55amalloywindows hates dual-booting iirc, you have to have grub on the MBR
17:56kozMBR?
17:56danneuAimHere: it's useful to be able to approximate shell scripts that you encounter in the wild though. i.e. a heroku buildpack you might be using
17:56AyeyMaster boot record i think
17:56qbgmaster boot record
17:56AimHereamalloy, well you do need a minimul level of familiarity, but between the bad syntax and the need to invoke 1001 different command line utilities you want to minimise it
17:56kozOK... so how do I do that?
17:56amalloykoz: install windows first, then mint. tell mint you want to dual-boot; i think it asks when you're installing
17:56AyeyLive-CD into a linux, and install Grub on a boot or root partions
17:56hyPiRionkoz: that's the order I did it when I first started with Linux. I just followed a tutorial really, but then again, I am using Debian
17:56kozYeah - Mint doesn't give me that option on the installer.
17:56amalloyor if you don't want to restart stuff from scratch, you can do it some other way; what Ayey says sounds fine
17:57kozI had to basically partition manually.
17:57kozLiveCD in? OK.
17:57kozI can do that.
17:57kozHow do I install grub after that?
17:57AyeyRemeber to install os-proper, so grub-config can detect Windows
17:57amalloyi mean, there are a *lot* of resources on the web about doing exactly this
17:57AyeyEh, let me try to find you a proper guide..
17:57kozThanks - much appreciated.
17:57zoldarkoz: http://community.linuxmint.com/tutorial/view/245
17:58kozI've been having some issues with this, since I'm a complete noob at Linux.
17:58qbgyou could be super lazy and put it in a VM :p
17:58kozAnother minor thing - my Mint has Firefox as the default browser, which is... undesirable. I'm using Midori, but it's not the default. So if I click a link, it goes to FF.
17:58kozHow can I change that?
17:59kozMidori doesn't seem to have... well, any sort of options menu I could find.
17:59AyeyThat is the system that contols it
17:59danneugoogle 'default browser debian'
17:59AyeyYou should be able to find default-applications somewhere in your settings
17:59kozAyey: Thanks - I'll check.
18:00zoldarkoz - it's update-alternatives for x-www-browser most of the time
18:00zoldarkoz: as in "sudo update-alternatives --config x-www-browser"
18:00kozThanks - there seems to be a graphical utility for this under Mint.
18:01kozThanks everyone - you've all been incredibly helpful.
18:01hyPiRionkoz: good luck fixing stuff :)
18:01kozI may well need it.
18:01AyeyIndeed, thats where you'll learn the most :)
18:02kozWell, I already learned a bit from trying to install Debian and having it fry on me.
18:03kozAlso, as a complete aside, Pandora is awesome.
18:03zoldarkoz: there's a nice middleground between plain debian and ubuntu-based mint - linux mint debian edition
18:03kozzoldar: I decided to go for the Xfce Mint instead.
18:03kozWas that a mistake?
18:04AyeyXFCE is a good choice
18:04kozIt's minimal, and the first machine I installed Linux Mint on is an old Eee-PC.
18:04AyeyMint is a fine distro, just too bloated with stuff for my taste :)
18:04zoldarkoz: not, it's also a good choice
18:05kozI was mostly inspired to get into Linux by 'The Art of Unix Programming'.
18:05kozSeriously awesome book.
18:06alexanderkyteI was inspired by my grandfather's autocoder operator's manual
18:06systemfaultI hated linux until I tried FreeBSD... then everything made sense to me after.
18:06r0b1hah
18:06r0b1unusual
18:06akyteI miss Ctrl+T
18:06kozOK, this guide is already doing odd things.
18:07akyteWhich guide?
18:07kozhttp://community.linuxmint.com/tutorial/view/245
18:07kozIt says 'type Gparted into the menu from the LiveCD'
18:07kozAnd.... I get nothing.
18:07akyteI usually just chroot back in to my old install and use that to install
18:08AyeyJust open gparted?
18:08akyteSuperstition on versioning
18:08Ayeysystemfault, freebsd? How come? I always wanted to give it a go
18:08kozIt seems it's not on my LiveCD.
18:08kozOr at least I can't find it anywhere.
18:08akytesudo apt-get install gparted
18:08AyeyThen install it with apt-get :)
18:08kozOK.
18:09zoldarkoz: if that's only for the purpose of checking partition layout, "fdisk -l" is usually sufficient
18:09kozAh. Well, I started downloading it already, so wfe.
18:09systemfaultAyey: FreeBSD felt simpler, more coherant... all the userland utils felt better integrated. Using ports sucks though, I hate compiling software.
18:10kozBut thanks for that.
18:10systemfault*coherent
18:10akyteI loved ports. I hated how bad the package defaults were. Vim behaves like it does on no linux distro and ssh is far too nice for my opinion
18:11systemfaultakyte: I hate compiling :) The flexibility ports provide is really good though
18:12kozOK, in this guide, I'm meant to find the Linux Mint partition. I have two - root and the other one.
18:12koz(Not swap)
18:12kozWhich one does it want?
18:12AyeyHow does ports differ from packages from apt-get/pacman?
18:12Ayeyroot
18:12Ayeyi guess the other one is /home
18:12akyteWell it's ostensibly a way for you to use make to build all of your packages
18:12kozYeah, the other one is a home partition. Thanks.
18:12akyteBut most use portmaster
18:12akyteThink "patchwork gentoo"
18:13AyeyHuh, intresting.. I should give it a go sometime
18:15akyteWhich distros have you ran before?
18:15kozGoddamn it.
18:15kozSame as before.
18:16kozI get the CLI GRUB.
18:17Ayeyakyte, Have used arch as my primary for around a year, some ubnuntu/debian before that
18:18akyteArch is cool, but I prefer gentoo. I like to be able to make all of my architectural choices.
18:19Ayeywhat do you me?
18:19Ayeymean*
18:21kozOK, thanks guys. Gonna try the Mint irc channel to see if they can help me at all.
18:22kozSee ya!
18:27dnolen_new Om tutorial, Speculative UI Programming - https://github.com/swannodette/om/wiki/Intermediate-Tutorial#wiki-speculative-ui-programming
18:30bbloomdnolen_: awesome.
18:30bbloomdnolen_: so i'm i'm understanding this correctly, you're implemented one speculative state... PER COMPONENT right?
18:31bbloomdnolen_: ie two different comment boxes can do optimistic posts in parallel, yes?
18:31dnolen_bbloom: yes they could, however how to reconcile those is something that needs thinking
18:32dnolen_bbloom: this is why om-sync can write the operation into a channel
18:32dnolen_instead of actually doing it
18:32dnolen_so you could have independent parties doing things, and I think the coordination logic could happen in another go loop that actually commits these operations and observes their results
18:36bbloompretty interesting... probably works just fine with isolated sub trees, but need a proper computational model for communicative distributed systems once you start trying to merge and whatnot
18:36clojurebotHuh?
18:38dnolen_bbloom: yes, works great for isolated sub trees - people will need to do some experimenting to figure out the hard
18:38dnolen_bbloom: but at least they can now :)
18:38dnolen_s/hard/hard stuff
18:39r0b1systemfault: yeah compiling can take time but there is prebuilt packages for most of the bigger packages (like X11).
18:40systemfaultRight
18:40bbloomdnolen_: cool stuff
18:40bbloomgood work
18:40dnolen_bbloom: thanks
18:50qbgOm is omsome!
19:20echosaHey, room. What's the preferred/standard/usual way of capturing key presses in a console app? Looking at add vim/rogue style keybindings to a program I'm making.
19:22sjlechosa: http://sjl.bitbucket.org/clojure-lanterna/ is what I made/use
19:22sjldepends on what exactly you need though
19:22sjlit might be overkill for you
19:23echosaYou actually made it? That's pretty sweet. I tried it last night, but couldn't get it to work. `lein run` and `lein trampoline run` both resulted in the program producing no output (which it should) and hanging. Maybe I just did something wrong.
19:23sjlechosa: I made the clojure wrapper around lanterna
19:23sjland wrote the docs
19:23echosaah, cool
19:23echosayeah, I tried out lanterna as well as jline
19:23sjlI haven't updated it in quite a while so it might be something to do with the latest clojure, but it should at least crash or something, not just hang
19:24clojurebotCool story bro.
19:24echosajline seemed... old and dated.
19:25echosaI'm surprised clojure doesn't already have an easy way to grab a key press (not read a character, which requires pressing return) already
19:25sjlit's a deeper rabbit hole than you might think
19:25sjlif you want to dive in http://www.linusakesson.net/programming/tty/
19:26echosaOh wow, you have to go all the way to the TTY level? There's not higher level abstractions built in already?
19:26sjl(specifically about raw/cooked input in a terminal)
19:27sjllanterna *is* the abstraction
19:27sjlit puts the terminal in raw mode and handles the fiddly bits of writing/reading in that mode
19:27sjlyou could certainly make a lighter-weight version that did less
19:28echosaRight, but I'm saying without a third party plugin/dependency, there's nothing built into clojure itself.
19:28echosaI'll play with lanterna a bit more before I toss it out.
19:29qbgThe Java Class Libraries don't expose a way to get raw input IIRC
19:29qbgAt least nothing nice
19:29echosaFair enough.
19:30qbg(non JNI or the like that is)
19:31echosaSpeaking of which... coming from Common Lisp (with sbcl) and elisp, when I'm writing clojure I tend to... avoid Java constructs. I use things like (.indexOf) and such, but I don't create/use Java objects. I sort of pretend all that Java stuff isn't there and just write the way I would any other Lisp.
19:31echosaIs that bad(™)?
19:31qbgjava.io.Console.readPassword is about as special as you get
19:33hyPiRionechosa: that's not bad. I seldom use java unless it's necessary
19:33AimHereechosa, no. It's good.
19:33hyPiRionunless when it is necesssary, rather.
19:33sjlechosa: if you're not specifically interop'ing with Java, no, it's not bad. be thankful you don't have to.
19:33echosaI'm glad I'm not alone, then.
19:33AimHereThe javaisms are just warts you have to use in order to Get Stuff Done
19:33r0b1love me some java
19:34AimHereWhen you don't have to Get Stuff Done, you don't need to pretend to use Java!
19:34qbgJust bury them with a shov--uh, function and get on with it
19:34echosayeah, sjl: I just tried the "hello world" code for lanterna, and when I `lein run` I get a java process running, no output (which I get if I remove that code) and it it seems to hang. FYI
19:35qbgDoesn't lein run do some socket or i/o redirection fun?
19:35echosaI'm trying to pick up best practices, not just learn the language raw. I'm learning clojure in an attempt to get a job writing it.
19:36sjlechosa: are you pressing a key?
19:36sjloh wait, there's a typo in the hello world because I'm an idiot
19:36sjlthe first s/stop should be s/start
19:36echosayes, and FWIW, I have print statements before the lanterna "hello world" code that I would expect to be executed first.
19:36echosaah
19:36echosaI wondered about that
19:37echosaI figured the first "stop" was more a "reset"
19:37echosaespecially since it deals with TTY
19:37sjlnah, it should be start
19:37sjloh yeah this example is totally hosed
19:37sjlhang on
19:38echosaOk, so now it ran, opened another window (wierd?) then waiting for key press before showing my (print) output, which, again, come before the lanterna code in my (-main)
19:38echosasjl: ok, thanks.
19:38sjlechosa: https://gist.github.com/sjl/9027448
19:39sjlscreens are buffered, so you have to tell it to redraw to make the text actually appear
19:40sjlechosa: the "second window" is probably it creating a swing terminal emulator. lanterna includes its own little swing "terminal" so you can run your app in places that don't have a decent one
19:40sjle.g.: windows
19:40sjlif you say (s/get-screen :text) instead of just get-screen it will force it to try to actually stay in the shell
19:41sjl(also the swing terminal is great when you're developing, because you can have the REPL running and the output terminal be separate
19:42sjlbasically once you actually see it working you need to read the docs though, because there's a lot going on to wrap your head around if you want to use it
19:42echosaah, ok. I'm starting to understand. So, if I want to use lanterna, I'll have to use (s/put-string) and (s/redraw) everywhere I was currently using (print)?
19:42sjlI promise they docs aren't too horrifying
19:42sjlyeah, the idea of lanterna is that it takes over your screen, and you write to it as if it were a canvas
19:43sjlit's great for making e.g. roguelikes, or a text editor or something
19:43sjlit may be overkill for what you need
19:43echosaI'm actually ok with that, because one of the next things I was going to have to write was screen clearing stuff. Looks like this may take care of that, or at least make it easy.
19:43echosaWell, I'm trying to remake the BSD version of the game "greed".
19:44echosawhich uses hjklyubn movement keys
19:44akurilin2Weird quirk, wondering if people might have seen this before: I stated a new lein project recently and clojure won't find clojure.set namespace in my tests.
19:44akurilin2When I open up the namespace in a repl, it finds clojure.set just fine
19:44akurilin2Never seen anything like this before
19:47sjlechosa: oh yeah, that's pretty much exactly what lanterna is designed for
19:48sjlechosa: e.g. if the user's position changes, you put the @ at the new place and a space at the old place, and tell lanterna to redraw, and it's smart enough to only draw those two characters
19:48sjlinstead of redrawing the entire screen
19:48echosayeah, I've got the internals of moving, replacing moved over positions with spaces, etc. all built and supported with tests (TDD test first, of course)
19:49echosaand I had display working with print, just not keymapping
19:49echosaso I"ll just convert my normal prints to lanterna calls and add the key presses and see what happens
19:49sjlyeah, testing is tricky with lanterna. there's not a really good way to scrape the screen with it
19:50echosaI won't test front end stuff, at least not with clojure.test
19:50sjlmight be worth looking at then
19:50echosaI might add some BDD or spec style tests to test user input, but for now the backend unit tests are more than enough
19:51qbgakurilin2: Which namespace are you openning up in the REPL? The namespace with the tests?
19:54effyif i understand well, inside a (dosync) body if any operation fail, the whole thing is rollbacked and retried, is there a mechanism in clojure that ensure that behavior not to cause famine? (imagining 2 threads doing dosync operation on the same refs, one of them is a fast dosync operation the other one has a slow dosync operation, would the slow dosync operation have a guarantie to ever finished successfully?)
19:56akurilin2qbg: yes
19:59qbgeffy: http://java.ociweb.com/mark/stm/article.html
20:00qbgTo quote: Suppose transactions A and B start in that order and are running concurrently. If they both attempt to modify the same Ref using ref-set or alter (write conflict), preference is given to transaction A because it has been running the longest (provided it has been running for a minimal amount of time). This avoids livelock that might occur if retries were based on the order in which refs are set.
20:01qbgakurilin2: Do the test succeed if you run the tests from the REPL?
20:04akurilin2qbg: something seems to be off about my environment atm, not sure what's going on, brb
20:04effyqbg: this article seems really interesting, thanks
20:10akurilinSo yeah when I run "lein test" now I get Caused by: java.io.IOException: error=7, Argument list too long
20:10akurilinNo idea what I did to cause that
20:11qbgAny stack trace?
20:13akurilinqbg: oh nvm. I use lein's checkouts and I think I caused a wonderful circular reference of symlinks in there
20:17aphyreffy: if I recall, either atoms or the STM is actually missing stochastic backoff.
20:18echosasjl: Whenever the program crahses, I get ";135R" at my prompt. When the program finished running successfully, I see "[[37;135R" in the console output. I realize these are TTY codes, but why are they being returned/displayed?
20:19aphyrhttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Atom.java#L33-L45 yeah, there really should be a sleep there
20:22hyPiRionaphyr: or a Thread.yield() ?
20:23qbgstochastic backoff likely isn't good enough
20:25effyaphyr: yeah you are right, this piece seems like it could loop forever if the "IFn f" is slow enough to run and another thread is pummeling at it with a faster "f"
20:28qbgIf you want to intermix long running and short running functions together at a sufficiently high rate, CAS semantics might not be what you actually want
20:33echosaprobably a *really* dumb question... but does clojure have an equivalent to elisp's (setq)? For instance, if I do (let [x 0] ...) then inside the body, I want to do something like (setq x (inc x)) to increment x
20:34qbgYou can use set! with vars
20:34qbglocals are immutable otherwise
20:34hyPiRionechosa: not in general. You'd have to use atoms for such things
20:34qbgThough there is this: https://github.com/ztellman/proteus
20:35aphyrechosa: typically you want a.) a second let binding or b.) proteus
20:35aphyrLet bindings being the fastest option for limited mutation.
20:35aphyrIf you're doing something iteratively, (loop [x 2 y 3] ... (recur (inc x) (inc y))) is best
20:37hyPiRionhrmm, proteus
20:37hyPiRionhttps://twitter.com/danielwithmusic/status/426133408498995201
20:39qbgFunctional programmers hate this!
20:40echosaHm. Will recur work with mapcat?
20:40echosanot sure how it would
20:40qbgwhat do you mean 'with'?
20:40echosayou can (recur) inside a (loop) so recur works with loop
20:40echosa^ s/loop/mapcat/
20:40echosa?
20:41qbgAre you talking about using recur in the function passed to mapcat
20:41qbgwithout tha function having the loop in it?
20:41qbg*that
20:41qbgbecause that won't work
20:41echosaoh, yeah, I guess it would be passed to the function passed to mapcat, since that's where the arguments being incremented would have to be
20:42echosahm
20:42qbgdo you really need to bang on those locals?
20:43echosaI need to keep track of x/y coords to pass to lanterna so it knows where to print stuff to the string inside two nested mapcats
20:43qbgWhat if you have the mapcats produce a description of what needs to be done, and then have some other code consume that description and actually do it?
20:44qbgare you using the mapcats for side effects only?
20:46echosalet me gist what I've got
20:46echosathat'll be easier
20:50echosaHere's what I'm working with with comments explaining what's going on: https://gist.github.com/echosa/9028090
20:51qbgWhy not use doseq instead?
20:52qbgfor the x/y values, and then look up corresponding value in the grid from that
20:52echosaBear in mind, I'm using this project to learn clojure. I didn't know about doseq.
20:52benkayhow would i go about starting a lein repl up in such a way that it used as much of the host horsepower as was feasible?
20:52echosacorresponding value in the grid? not sure what you mean... like using (.indexOf)?
20:52qbgnth
20:53echosaoh, right
20:53echosaduh
20:53qbg,(get-in [[1 2 3] [4 5 6] [7 8 9]] [1 1])
20:53clojurebot5
20:53echosawell, let me go look at doseq
20:53qbgor that
20:53echosaoh wow... (get-in)... that's handy as all hell
20:54Cr8And then there's update-in
20:54qbgand assoc-in
20:54Cr8,(update-in [[1 0] [0 1]] [0 1] inc)
20:54clojurebot[[1 1] [0 1]]
20:54aphyrbut somehow, no update
20:54echosa...
20:55echosayou've got to be kidding me
20:55qbgaphyr: In what way would update make sense?
20:55Cr8qbg: (update {:a 1} :a inc) => {:a 2}
20:55qbg,(update-in {:a 1} [:a] inc)
20:55Cr8is to update-in as assoc as assoc-in
20:55clojurebot{:a 2}
20:55echosaupdate-in exists and here I went and wrote (and unit tested) this: https://gist.github.com/echosa/9028135
20:55qbgnot god enough? :)
20:56Cr8qbg: sure, but assoc-in and get-in have assoc and get, respectively
20:56qbgfair enough
20:56echosaI think I can completely replace that function with (update-in)
20:56qbg,(assoc [1 2 3 4] 1 10)
20:56clojurebot[1 10 3 4]
20:56qbgechosa: You'd want to use that for updating a vector
20:57echosause what? my function or update-in?
20:57qbgassoc for a single vector
20:57echosabecause that's what my fuctnion does
20:57Cr8confusingly, synthread calls what we'd call "update" by this convention "assoc" =P
20:57Cr8or really, ->/assoc if you use the recommended ns alias
20:57Cr8https://github.com/LonoCloud/synthread
20:57qbgrather than all of those subvec and into calls
20:59echosaI basically use the (subvecs) to split the nested vectors into three groups: the ones before the one to be updated, the one to be updated (which is similarly split into three), and the ones after the one to be updated. That way, I can update the one and they all just get conj-ed together
20:59echosabut, from what I've seen, (update-in) will handle this for me
21:00qbgI'm just saying that if you really did need to write set-thing-at-grid-position, you'd want to use assoc instead of that into expression
21:00echosa,(update-in [[1 2 3][4 5 6][7 8 9]] [1 1] (fn [x] 0))
21:00clojurebot[[1 2 3] [4 0 6] [7 8 9]]
21:00echosaYep. update-in does exactly what I need for that second gist I posted.
21:00qbg,(assoc-in [[1 2 3][4 5 6][7 8 9]] [1 1] 0)
21:00clojurebot[[1 2 3] [4 0 6] [7 8 9]]
21:01echosaSo much wasted work. Well, not wasted, but I learned a lot about testing and clojure...
21:01echosaAh, Even better.
21:01qbgI'd recommend skimming through http://clojuredocs.org/quickref/Clojure%20Core if you haven't yet
21:01echosaI have. I've even done the clojure-koans thing, though a lot of that info just didn't stick.
21:02qbgno problem
21:02echosalanguage familiarity will come with time
21:02echosa(hopefully)
21:03echosaStill need to work out my mapcat -> doseq business, though.
21:03echosaHooray for learning.
21:03qbgdoseq is the side effect version of for
21:04echosahm
21:04qbg,(for [y (range 3) x (range 3)] [x y])
21:04clojurebot([0 0] [1 0] [2 0] [0 1] [1 1] ...)
21:07bob2is there an elegant way to go from [{:foo A :x somethingelse} {:foo B :z blah}] -> {A {:x somethingelse} B {:z blah}} ?
21:08echosa,(let [grid [[1 2 3][4 5 6][7 8 9]]] (for [x (range (count (first grid))) y (range (count grid))] (print (nth (nth grid y) x))))
21:08clojurebot(147nil nil 258nil nil nil 369...)
21:08echosa,(let [grid [[1 2 3][4 5 6][7 8 9]]] (for [x (range (count (first grid))) y (range (count grid))] (print (nth (nth grid x) y))))
21:08clojurebot(123nil nil 456nil nil nil 789...)
21:08echosawhat's with the nils?
21:08qbgprint returns nil
21:09echosaoh right
21:09qbgyou want to use doseq instead of for
21:09echosaI'm getting return val here, not output
21:09qbgfor produces a lazy seq, so that is why you see the intermixing
21:09echosasame syntax as for?
21:09qbg,(let [grid [[1 2 3][4 5 6][7 8 9]]] (doseq [x (range (count (first grid))) y (range (count grid))] (print (nth (nth grid x) y))))
21:09clojurebot123456789
21:09qbgyep
21:09echosa,(let [grid [[1 2 3][4 5 6][7 8 9]]] (doseq [x (range (count (first grid))) y (range (count grid))] (print (nth (nth grid x) y))))
21:09clojurebot123456789
21:09echosawin
21:10qbg,(let [grid [[1 2 3][4 5 6][7 8 9]]] (doseq [x (range (count (first grid))) y (range (count grid))] (print (get-in grid [y x]))))
21:10clojurebot147258369
21:10qbg,(let [grid [[1 2 3][4 5 6][7 8 9]]] (doseq [x (range (count (first grid))) y (range (count grid))] (print (get-in grid [x y]))))
21:10clojurebot123456789
21:11qbg,(let [grid [[1 2 3][4 5 6][7 8 9]]] (doseq [y (range (count grid)) x (range (count (first grid)))] (print (get-in grid [y x]))))
21:11clojurebot123456789
21:11qbg^ That might be the one you want
21:12echosa(get-in)... right.
21:12echosaI have so much to memorize.
21:12qbgyou get to dramatically shrink your line count though :)
21:12echosaI'm very much looking forward to that.
21:13echosaIn for familiar lisps I'm used to being clever to reduce code amount.
21:13echosaClojure is a whole new beast.
21:13qbgNow don't just use cl-format because you have it :p
21:13benkayhow would i determine what brand of jvm a given leiningen install put on my system?
21:14benkayi just spun up a vm for some processing - would it be the same as the output of `which java`?
21:14qbg`java -version` might be of interest
21:15benkaymhm.
21:15echosaIT LIVES... er, WORKS! Jesus... 4 hours yesterday, give or take, improved drastically by a couple hours on IRC
21:15bob2'lein version'?
21:18benkaythanks bob2, qbg.
21:18benkayhar, now do either of you know anything about making the jvm as big as possible on a given host?
21:18qbg-Xmx to increase the maximum heap size
21:19qbgIIRC, there is a place in your project.clj where you can place those jvm arguments
21:19bob2java-opts
21:19qbgAre you running out of memory benkay?
21:19bob2at some point you've made the heap too big, though
21:19benkayyeah i'm familiar with java opts, just not en-honk-ifying a jvm
21:20qbgare you having perf issues?
21:20benkaynah, big job
21:20bob2you can't just set it to a high random value
21:20benkayscripted it up in clojure for the heckofit
21:20benkaypmap being a useful thing in the context
21:20bob2gc pauses are a real thing
21:20qbghow big of a heap are you going to want?
21:21benkayheap isn't so much of a concern - it's running on an 8 core box and i'd like to utilize as many as possible
21:22bob2that just happens, without configuration
21:22qbghow much work does the function you pass to pmap do?
21:22benkaysqueeeee clojure
21:22benkaynone
21:22qbgif it isn't enough, the overhead is going to kill the gains
21:22benkayit's like "try to s3 cp this object from bukkit a to bukkit b"
21:22benkaythere's just a mess of things to get copied and there's no reason to do it serially.
21:23Cr8benkay: used reducers yet?
21:23Cr8wouldn't be appropriate in this case
21:23benkayah only to do dumb dumb stuff like ,(reduce [1 2 3])
21:23Cr8but they are a neat thing
21:23qbgbenkay: you're code is I/O bound rather than CPU bound?
21:23benkayah only to do dumb dumb stuff like ,(reduce + [1 2 3])
21:23benkayyeah, very much io bound
21:23Cr8benkay: clojure.core.reducers I mean
21:23bob2if you want to do it fast, you'd want async network io, not more cpus or threads
21:23qbgpmap probably isn't what you want then
21:24qbg(inc bob2)
21:24lazybot⇒ 1
21:25benkaything is that i'm working with weavejester's s3 library and this bit of code is a one-off
21:25benkay(famous words before one-off script becomes central to biz processes)
21:26Cr8(my current weekend is fixing up some "one-off" scripts I wrote last week so that they can become productionized)
21:26Cr8luckily they're currently -so- "one-off" that they only run on my machine
21:27benkayif we copy any more gigantic s3 buckets i'll have to have some words with business people about costs incurred that could be avoided with a bit of time.
21:28qbgwhat is roughly the upper limit on the size of the sequence you're sending to pmap currently?
21:29aphyryeah, suggest not using pmap for any more than, say, 1000 items.
21:29benkayinteresting
21:29aphyrJVM doesn't deal so well with infinite threads.
21:29benkayi figured something like that'd be the case, so i wrote it to perform things batch-ed-ly
21:29qbgaphyr: pmap doesn't send everything to its own thread
21:30qbgthe number of computations in flight is limited
21:30benkaywhat are the constraints on length of lists over which to pmap?
21:30bob2depends on what your function does
21:31benkayit's a mystery!
21:31benkayjokes aside as i dig through the s3 client source what should i be aware of
21:32aphyrOh shit, pmap changed!
21:32aphyrDidn't realize.
21:32qbghttp://stackoverflow.com/questions/5021788/how-many-threads-does-clojures-pmap-function-spawn-for-url-fetching-operations
21:35bob2ugh threads for url fetching
21:35benkayhey man i'm just a mechanical engineer trying to make his way in this over complex world of computer you people have munged together over the past twenty years. tell me how to do it right!
21:36qbgI think it is a bit more than 20 :p
21:36benkaywell 20 years ago we had symbolics machines iirc
21:37benkayjokes its 2014
21:37benkayso 29 years
21:37qbgWhy not go all the way back to the IBM 704?
21:38benkaydid it run lisp?
21:38bob2yes
21:38bob2in like 61
21:38benkaywell then sure :)
21:38bob2for your thing, pmap is probably fine as a balance between effort and performance
21:39benkay's what i thought too. glad to have someone with experience (assumption!) confirm.
21:39echosaWho needs the Turing test. It's all about the Lisp test: does it run lisp? :)
21:39bob2for something non-one-off, something like http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/ is going to be a lot faster
21:39bob2disclaimer, I have only a little clojure experience
21:40benkaybob2: i think i'm actually going to go down the nio rabbit hole next time i come around to this problem
21:40bob2oh, aleph is apparently a thing to loko at
21:40benkaywhich is particularly amusing because i have zero java experience beyond the interop that's been forced on my from time to time
21:40benkayi'm aware of aleph yeah
21:40benkaywhat do you think of: https://github.com/pjstadig/nio
21:41bob2really I just want Twisted for clojure
21:41bob2nio looks very far below the 'do lots of http requests' level you were talking about earlier
21:42benkayah well you see the next networky thing i have on my plate is lots of binary over tcp
21:43bob2aleph apparently does tcp stuff too
21:46benkayhm yeah
21:46quizdrare circular references a problem in clojure as they are in some languages? can I have 2 source files that each refer each other?
21:46qbgthat is going to be difficult
21:47benkaybut all this framework of expectations and data flow is a bit much cognitive overhead for my tastes.
21:47qbgSee if you can clean up your design
21:52beamsoquizdr: while i've never experienced that i believe it can be a problem
21:52qbgClojure effectively enforces good design here
22:05quizdr,(println (str (take 3 "abcdef")))
22:05clojurebotclojure.lang.LazySeq@1ecc1\n
22:05quizdrshouldn't println force the output of above?
22:06beamso,(apply str (take 3 "abcdef"))
22:06clojurebot"abc"
22:06quizdrgotcha
22:07beamsothe docs for str don't say that it returns a lazy sequence :/
22:07qbgtake returns a lazy seq
22:07qbgand you're turning that lazy seq into a string with str
22:08qbg(in your original code)
22:08beamsoyeah
22:08beamsothe take returns a lazy seq
22:08beamsothe str' With more than
22:08beamso one arg, returns the concatenation of the str values of the args.'
22:17qbgprintln also uses a different code path than str
22:19amalloyqbg: println just calls str
22:20t0m`hi
22:20qbgthere is a bit more magic though than that
22:20t0m`hey i'm dealing with deeply nested maps, is there something like xpath but for nested maps?
22:21qbgamalloy: println can handle unbounded output
22:22amalloywhat does "unbounded output" even mean?
22:22qbginfinite seq for example
22:23amalloy&(println (range))
22:23lazybotjava.lang.OutOfMemoryError: Java heap space
22:23amalloythat's not handling it super-impressively
22:23qbglazybot has to capture the output
22:24qbgif you're writing to the console, then everything is fine
22:24amalloyi mean, yes, you can (println (range)) in a repl, and it probably writes forever. i'm not sure that's much of a feature
22:24amalloyat any rate, i was definitely wrong that println just calls str
22:25qbgprintln doesn't also need to generate an entire string before printing
22:27ambrosebsbbloom: I haven't been able to get if-pred out of my head all morning
22:28ambrosebsbbloom: really helped pinpoint the problems with if-let
22:31bbloomambrosebs: you're the types guy, you should have been all over that one :-)
22:33ambrosebsbbloom: I have much to learn
22:35bbloomambrosebs: besides typed racket and now core.typed, do you know of any languages that have a sensible type system with union types instead of sum types?
22:36amalloybbloom: if-pred?
22:36bbloomamalloy: long story. discussion about if-some, see logs
22:39ambrosebsbbloom: hmm there is SML CIDRE which is a refinement type checker for SML. The way I look at it, it looks like you're defining sum types (called data "sorts") but you don't actually "construct" data sorts; they are refinements on existing SML types.
22:39ambrosebshttp://www.cs.cmu.edu/afs/cs/user/rowan/www/src/red-black.sml
22:40ambrosebsthe equivalent types in cor.etyped https://github.com/clojure/core.typed/blob/master/src/test/clojure/clojure/core/typed/test/rbt_types.clj
22:40bbloomambrosebs: so is "refinement types" the magic phrase for this sort of thing in the literature?
22:41bbloomambrosebs: and how does that relate to "occurrence typing" ?
22:42ambrosebsbbloom: often when general unions and intersections are discussed in the context of ML-like type systems, it's related to refinement types
22:45killerswanso, do any of you have tips on parsing XML from within ClojureScript?
22:45ambrosebsbbloom: I haven't looked too much into this, but here's an example http://www.cs.cmu.edu/~joshuad/papers/tridirectional-typechecking/Dunfield04_tridirectional.pdf
22:45ambrosebsbbloom: if you're from CMU, it's "type refinements"
22:45ambrosebsbbloom: and a "refinement type" checker :)
22:46ambrosebsmy honours supervisor wrote CIDRE for his phd http://www.cs.cmu.edu/~rwh/theses/davies.pdf
22:47bbloomand if you're the racket people (is that northeastern or something?) then it's occurrence typing?
22:48dnolen_killerswan: use an existing JS XML lib?
22:48ambrosebsbbloom: hmm
22:49bbloomambrosebs: or utah? i don't know anything about CS graduate programs :-P
22:49ambrosebsbbloom: occurrence typing is an approach to eliminating union types are programs progress
22:49bbloomok so they are different? i guess i'll need to study them at some point
22:49killerswandnolen_: any recommended tutorial on how to set up externs for that? (jay's tutorial links to some externs from MANY versions ago of jQuery...)
22:49killerswans/jay/jayq/
22:49ambrosebsbbloom: essentially occurrence typing eliminates unions as it gets further into the program
22:50ambrosebsbbloom: as I understand it, refinement type checkers are intended to check each possible combination of types, which might mean checking a program many times with different types
22:50ambrosebsbbloom: so two approaches to a similar goal
22:51dnolen_killerswan: http://docs.closure-library.googlecode.com/git/closure_goog_dom_xml.js.html
22:51bbloomambrosebs: hm ok, i'll dig in to it all eventually
22:56killerswandnolen_: OK, thanks
23:45TravisDin case forms, is it standard to use "true" as the catch-all case? Or is there some syntactic sugar for that?
23:46qbg_case, or cond?
23:46qbg_:else seems to be idiomatic for cond
23:46TravisDoh, sorry, cond
23:47TravisD:else is considered true in cond?
23:47mischovI believe catchall for case is a last statement without a condition.
23:47mischov:else for cond
23:47bbloomTravisD: it's just an idiom, any logically true value would suffice
23:47bbloom,(cond :false "omg")
23:47bbloom&(cond :false "omg")
23:47lazybot⇒ "omg"
23:47bbloomdamn bots :-P
23:48TravisDHehe, is there a simple characterization of logically true values?
23:48clojurebot"omg"
23:48bbloomTravisD: false and nil are the *only* logically false values. everything else is true
23:48TravisDoh, alright :)