2014-02-15
| 00:00 | jph- | :) |
| 00:04 | TravisD | Does clojure have much of a scientific computing community? |
| 00:05 | amalloy | TravisD: probably a little, but i think most of those guys use matlab, python, or fortran or something |
| 00:07 | TravisD | amalloy: 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:07 | jph- | i wonder if julia will supplant them |
| 00:07 | TravisD | One hopes |
| 00:11 | TravisD | This isn't meant to be an inflammatory comment, but does clojure have a larger and more active community than the variants of scheme? |
| 00:13 | egghead | TravisD i'm not familiar with scheme variants, but clojure has a large and active community |
| 00:13 | TravisD | And is clojure mainly used for web development? |
| 00:15 | egghead | TravisD: 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:16 | TravisD | alright, thanks :) |
| 00:24 | `cbp | suddenly all the bugs are tracked to me typing OAauth |
| 00:25 | logic_prog | open awesome Auth |
| 00:27 | munderwo | So 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:31 | ddellacosta | munderwo: if you do (require '[clojure.java.jdbc :as j]) you don't have j/insert! available to you? |
| 00:31 | ddellacosta | munderwo: 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:32 | ddellacosta | munderwo: er, lein deps :tree is what you want, sorry |
| 00:33 | ddellacosta | TravisD: I know there is a lot of machine learning going on in Clojure as well, for one |
| 00:33 | munderwo | ddellacosta: so this is what I'm getting https://www.refheap.com/39074 |
| 00:33 | munderwo | and its rather confusing.. |
| 00:33 | munderwo | because from what I can tell the jdbc driver from 0.3.0 onwards should have insert! |
| 00:35 | munderwo | If I try to just do the insert! function then it says no such var. |
| 00:36 | munderwo | I'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:36 | ddellacosta | munderwo: does insert! show up when you do this? (keys (ns-publics 'clojure.java.jdbc)) |
| 00:37 | munderwo | ddellacosta: nope https://www.refheap.com/39075 ... |
| 00:37 | munderwo | Where are the jars that leiningen downloads stored? |
| 00:38 | munderwo | I know that they get caches in ~/.m2 but is there anywhere else? |
| 00:38 | ddellacosta | munderwo: I don't get it, I clearly see [org.clojure/java.jdbc "0.3.3"] in your lein deps :tree output |
| 00:38 | ddellacosta | munderwo: are you running the repl w/a profile? |
| 00:38 | munderwo | yeah I know… its kinda got me stump.. |
| 00:40 | munderwo | this is my profile.clj https://www.refheap.com/39076 |
| 00:40 | ddellacosta | munderwo: no, I mean are you running the repl like `lein with-profile dev repl` or something? |
| 00:40 | munderwo | nope… just `lein repl` |
| 00:41 | ddellacosta | munderwo: and you're definitely running it in the same project directory you showed us that lein deps output from, right? |
| 00:42 | munderwo | ddellacosta: I just redid the whole set of steps… https://www.refheap.com/39077 |
| 00:42 | munderwo | just to make sure… coz gravity doesn't feel right.. and that normally means I've done something stupid |
| 00:44 | ddellacosta | munderwo: yeah, that's weird, that's obviously the deprecated interface |
| 00:45 | munderwo | ddellacosta: yeah its weird… thanks for your help. at least I know I'm only going a little crazy.. gotta run. |
| 00:59 | danielcompton | Is 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:01 | TravisD | Does 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:08 | jph- | TravisD, http://adambard.com/blog/clojure-in-15-minutes/ |
| 01:09 | TravisD | awesome, thanks |
| 01:10 | jph- | TravisD, i also refer to http://clojure.org/cheatsheet all the time |
| 01:11 | TravisD | hmm, clojure has special forms, no? Like, is (ns test) actually a function call? Or is it a special namespace form? |
| 01:12 | oskarkv | TravisD yes there are special forms, but I think `ns` is a macro |
| 01:12 | TravisD | ah |
| 01:23 | ddellacosta | ,(source ns) |
| 01:23 | clojurebot | Source not found\n |
| 01:23 | ddellacosta | d'oh |
| 01:24 | ddellacosta | TravisD: anyways, you can do that ^ in the repl to learn more about a function/macro/special-form |
| 01:24 | beamso | ,(doc clojure.core/ns) |
| 01:24 | clojurebot | "([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:24 | TravisD | cool, thanks |
| 01:24 | TravisD | normally (source x) gives you the definition of x? |
| 01:25 | ddellacosta | TravisD, beamso: yeah, good point--that should tell you if it's a special form too |
| 01:25 | ddellacosta | ,(doc loop) |
| 01:25 | clojurebot | "([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:25 | beamso | and it's (clojure.repl/source ns) as well |
| 01:25 | ddellacosta | hrm |
| 01:25 | ddellacosta | &(doc loop) |
| 01:25 | dsrx | ,(doc .) |
| 01:25 | lazybot | ⇒ "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:25 | clojurebot | Cool story bro. |
| 01:25 | ddellacosta | beamso: I don't need to qualify it with the namespace in my repl...clojure.repl gets loaded automatically by default |
| 01:27 | beamso | true |
| 01:27 | beamso | maybe the bot needs a namespace specified :/ |
| 01:27 | TravisD | is there a way to get the clojure repo to use readline? |
| 01:27 | TravisD | repl* |
| 01:27 | ddellacosta | beamso: 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:28 | ddellacosta | TravisD: huh, it uses readline by default I thought |
| 01:28 | TravisD | hmm, the version I installed through macports doesn't seem to :( |
| 01:28 | beamso | lein uses jline by default |
| 01:29 | logic_prog | tbaldridge: !!! |
| 01:29 | ddellacosta | beamso: ah, I stand corrected |
| 01:29 | logic_prog | tbaldridge: your youtube videos are awesome |
| 01:29 | TravisD | hm, so now I've installed jline. Is there something more I need to do to get clojure to use it? |
| 01:30 | beamso | http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Enhancing_Clojure_REPL_with_JLine |
| 01:30 | beamso | maybe that |
| 01:30 | TravisD | thanks |
| 01:32 | amalloy | TravisD: whoa, installing clojure (or lein) through macports is pretty nuts |
| 01:32 | TravisD | amalloy: How come? |
| 01:33 | TravisD | beamso: I switched to macports because they've started shipping binaries |
| 01:33 | TravisD | can save a lot of time |
| 01:33 | amalloy | follow 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:33 | amalloy | stuff in package managers is always out of date and/or awful, eg not including jline support |
| 01:34 | TravisD | looks like it's up to date, and relatively easy to add jline support |
| 01:35 | ddellacosta | TravisD: most Clojure folks I know use the default leiningen setup for installing/update |
| 01:35 | TravisD | ah |
| 01:35 | ddellacosta | TravisD: especially as you don't need the package manager to get updates for lein |
| 01:36 | amalloy | lein really is way better at managing clojure (and itself!) than any package manager |
| 01:36 | ddellacosta | ^^ what he says ^^ |
| 01:37 | TravisD | yeah, I'll probably switch to that |
| 01:37 | TravisD | so the recommended approach is to instal lein manually and use it to install and update clojure? |
| 01:37 | ddellacosta | TravisD: yep. |
| 01:38 | ddellacosta | TravisD: after the initial install it is as simple `lein upgrade` |
| 01:39 | ddellacosta | TravisD: technomancy makes announcements when a new version gets released on the mailing list |
| 01:39 | TravisD | awesome :) |
| 01:39 | ddellacosta | TravisD: 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:40 | TravisD | Ah, I see |
| 01:40 | TravisD | Outside of a project, will there be a clojure repl available? |
| 01:40 | ddellacosta | TravisD: 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:41 | ddellacosta | TravisD: sure, you can start a repl anywhere. |
| 01:41 | TravisD | The closest to lein I've come is (C)makefiles |
| 01:41 | TravisD | ddellacosta: So the globally available version of clojure is also installed by leon? |
| 01:41 | TravisD | lein* |
| 01:42 | ddellacosta | TravisD: 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:43 | amalloy | TravisD: 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:43 | TravisD | amalloy: While I'm learning I might like to have one I can just play around with |
| 01:44 | Raynes | `lein repl` |
| 01:44 | amalloy | if 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:44 | TravisD | awesome :) |
| 01:44 | ddellacosta | amalloy: 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:44 | TravisD | I will read some on my own now |
| 01:44 | TravisD | thanks for the advice and tips |
| 01:45 | ddellacosta | TravisD: good luck TravisD...enjoy! :-) |
| 01:48 | ddellacosta | huh, 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:49 | ddellacosta | just trying to add CLJS to a previously running project, I get this when I run lein cljsbuild auto dev |
| 02:02 | TravisD | Is there a translation of SICP to clojure? |
| 02:03 | TravisD | not sure if they are compatible enough languages for that to work |
| 02:04 | ddellacosta | TravisD: 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:05 | ddellacosta | TravisD: http://sicpinclojure.com/ for example |
| 02:05 | ddellacosta | "You should not be here yet." |
| 02:05 | amalloy | TravisD: attempts have been made, but really i'd just go through the actual book |
| 02:05 | ddellacosta | whoops |
| 02:05 | TravisD | amalloy: It would be nice if there was an annotated version of the book that had the rleated clojure information |
| 02:06 | amalloy | there'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:06 | TravisD | hehe, alright |
| 02:10 | ddellacosta | looks 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:10 | ddellacosta | now I have a completely different, lovely Google Closure error |
| 02:15 | ddellacosta | ...which was caused by stefon loading the google closure compiler in addition to clojurescript. Hope that doesn't break stefon. *sigh* |
| 02:23 | szymanowski | hi, is there a function like haskell's 'tails' in clojure? |
| 02:23 | seangrove | ddellacosta: On noir eh? Legacy in the Clojure world... |
| 02:23 | seangrove | szymanowski: What does tails do? |
| 02:24 | seangrove | Nevermind, looked it up |
| 02:24 | szymanowski | ghci> tails "w00t" |
| 02:24 | szymanowski | ["w00t","00t","0t","t",""] |
| 02:24 | ddellacosta | seangrove: 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:24 | szymanowski | it is simple to implement but just want to know |
| 02:25 | seangrove | szymanowski: I don't think there's one built in |
| 02:25 | seangrove | Looks like someone wrote about it here http://joshrotenberg.com/posts/2013-12-31-datalist-functions-in-clojure.html |
| 02:25 | dsrx | ,(take-while not-empty (iterate rest "w00t")) |
| 02:25 | clojurebot | ("w00t" (\0 \0 \t) (\0 \t) (\t)) |
| 02:26 | szymanowski | thank you dsrx |
| 02:26 | just-a-dev | interesting... |
| 02:27 | just-a-dev | ,(str "testing irc bot") |
| 02:27 | clojurebot | "testing irc bot" |
| 02:34 | just-a-dev | ,(for [c (range 65 91)] [(char c) (char (+ 32 c))]) |
| 02:34 | clojurebot | ([\A \a] [\B \b] [\C \c] [\D \d] [\E \e] ...) |
| 02:59 | szymanowski | i would like to implement a reduce function that stops iteration when returned accumulator is nil, does anyone could help me? |
| 03:01 | sk052 | how to do xml parsing in clojure |
| 03:01 | szymanowski | http://clojuredocs.org/clojure_core/clojure.xml/parse |
| 03:05 | sk052 | xml parsing api is it stax, sax or dom |
| 03:09 | oskarkv | szymanowski what exactly do you need help with |
| 03:11 | szymanowski | does my question make sense? or do you want me to rephrase it? |
| 03:12 | sk052 | i have a zip file with 500+ xml file and each file is 300MB , need to parse them efficiently and load in db |
| 03:12 | oskarkv | szymanowski you mean you would like a new reduced function, like reduce', that stops when the the intermediate result is nil? |
| 03:13 | oskarkv | reduce* |
| 03:13 | szymanowski | yes |
| 03:13 | szymanowski | exactely |
| 03:14 | szymanowski | maybe i should use reductions for that |
| 03:14 | szymanowski | reductions returns a lazy seq? |
| 03:15 | oskarkv | yes you could, but it would not be the most performant solution ever |
| 03:15 | oskarkv | I think, but not that big of a deal maybe |
| 03:15 | szymanowski | ok, if you have a better idea i would like to know it! |
| 03:15 | oskarkv | szymanowski maybe this https://www.refheap.com/39081 |
| 03:17 | szymanowski | i didn't know refheap it looks nice! |
| 03:17 | szymanowski | thank you i will try this |
| 03:19 | szymanowski | it works well thank you oskarkv |
| 03:19 | oskarkv | np |
| 04:17 | szymanowski | what is the best way to check if at least 1 item of coll1 is in coll2? |
| 04:18 | amalloy | szymanowski: 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:18 | amalloy | (some (set coll1) coll2) |
| 04:19 | szymanowski | great thank you |
| 04:23 | szymanowski | reduced function looks handy, i didn't know it |
| 04:39 | muhoo | reduced is nice for when you really don't want to loop/recur |
| 04:46 | borkdude | https://gist.github.com/borkdude/9016815 |
| 04:53 | borkdude | wow, eh, even this works ;) |
| 04:53 | borkdude | IFn eval = Clojure.var("clojure.core","eval"); |
| 04:53 | borkdude | Object expr = Clojure.read("(+ 1 2 3)"); |
| 04:53 | borkdude | Long res = (Long) eval.invoke(expr); |
| 04:56 | borkdude | also nice Date d = (Date) Clojure.read("#inst \"2014-12-12\""); |
| 04:56 | borkdude | System.out.println(d); |
| 04:56 | borkdude | I think Clojure can be a nice utility in many java projects =) |
| 05:10 | borkdude | clojure.inspector - why didn't I know about that before? https://www.dropbox.com/s/1t0ftj5bo2qpltg/Screenshot%202014-02-15%2011.05.57.png |
| 05:33 | borkdude | is there a built in clj function which gives me a file tree instead of seq? |
| 05:40 | raek | borkdude: there's always the File API... but using that the tree shape is in your recursive calls rather than in some data structure |
| 05:41 | raek | http://stackoverflow.com/questions/8566531/listing-files-in-a-directory-in-clojure/8567237#8567237 |
| 05:41 | borkdude | raek I already found something in Raynes's fs lib "iterate-dir" which gives me something like that |
| 05:42 | borkdude | raek yeah, I even answered in that thread I see, but I'm just too lazy to type that all in ;) |
| 05:42 | raek | borkdude: oh, I see :-) |
| 05:42 | borkdude | raek I wanted to have a tree to play with in (clojure.inspector/inspect-tree ...) |
| 05:42 | borkdude | raek since I just discovered that neat utility |
| 05:44 | borkdude | I think I could have used inspect-tree when plowing through a lot of json-esque data :-s |
| 05:46 | borkdude | I'm starting to get convinced that I should use mapv filterv etc by default and not map, filter, unless lazyness is explicitly wanted. |
| 05:54 | pyrtsa | borkdude: 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:54 | borkdude | pyrtsa yes, exactly the problem I had yesterday |
| 05:54 | borkdude | pyrtsa I have been bitten by lazyness in more cases |
| 05:55 | pyrtsa | Laziness in Clojure is second-class, unfortunately. :| |
| 05:55 | borkdude | pyrtsa for example, someone used a dynamic var and binding. But my lazyseq was evaluated outside the scope of that binding, later. ;) |
| 05:55 | borkdude | pyrtsa I agree that using arguments instead of dynamic vars is better generally |
| 05:56 | pyrtsa | I'm trying to do my best to avoid dynamic vars altogether. |
| 05:56 | borkdude | it would also prevent this situation |
| 06:11 | borkdude | problem reconstructed: https://gist.github.com/borkdude/10ec65989ef4d371bbcd |
| 06:14 | borkdude | so any recent new clojure (related) books? |
| 06:16 | borkdude | Is this book any good, Clojure high performance? http://shop.oreilly.com/product/9781782165606.do?sortby=publicationDate |
| 06:43 | borkdude | are there any people doing serious java development in emacs btw |
| 06:46 | borkdude | maybe there should be something a la clojure.inspector in emacs, so you can use it also on servers without GUI. does it exist? |
| 07:09 | borkdude | awesome: https://github.com/magnars/clj-refactor.el |
| 08:28 | szymanowski | what is the best way to check if multiple preds are true for a value |
| 08:28 | szymanowski | ? |
| 08:32 | szymanowski | like (all-true? 10 pos? (partial < 11)) => true |
| 08:33 | szymanowski | i don't want to write (and (pos? 10) (> 11 10)) |
| 08:33 | szymanowski | edit: (partial > 11) |
| 08:35 | szymanowski | (defn all-true? [d & preds] |
| 08:35 | szymanowski | (eval `(and ~@(map #(list % d) preds)))) |
| 08:35 | szymanowski | is this make sense? |
| 08:37 | AimHere | ,(every? identity ((juxt pos? even? #(< % 10)) 10)) |
| 08:37 | clojurebot | false |
| 08:37 | AimHere | ,(every? identity ((juxt pos? even? #(< % 10)) 8)) |
| 08:38 | clojurebot | true |
| 08:38 | AimHere | Seems to take clojurebot too much time to work that out for some reason |
| 08:39 | AimHere | Chances are, if you're using 'eval', whatever you're doing is non-idiomatic |
| 08:41 | szymanowski | thank you! |
| 08:42 | szymanowski | so it is preferable to make a macro than a function that return (eval `(...)) ?? |
| 08:42 | lazybot | szymanowski: Definitely not. |
| 08:42 | AimHere | Ignore the bot, in that case, a macro would be preferable |
| 08:42 | szymanowski | ok |
| 08:54 | elephantTechno | Hi, 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:54 | elephantTechno | letting 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:55 | elephantTechno | Are my concerns justified ? |
| 08:58 | cark | there is no race if you're only reading |
| 08:59 | cark | also you might want to consider using an atom |
| 09:02 | elephantTechno | Thank you |
| 09:03 | cark | to make it clear : transactions only retry when you're modifying the ref |
| 09:03 | cark | *risk to retry |
| 09:06 | elephantTechno | Because you're forced to proxy the change through a dosync block |
| 09:48 | jro_ | 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:48 | jro_ | while trying to start clojure repl with gradle clojureRepl |
| 09:49 | jro_ | clojuresque 1.7.0 and nrepl 0.2.3 |
| 10:05 | sdegutis | Good morning everyone. |
| 10:28 | michaniskin | good morning :) |
| 10:28 | michaniskin | EST representing |
| 10:28 | michaniskin | also it's 2^10 o'clock! |
| 10:43 | btcNeverSleeps | Does Clojure's "future" macro exist in JavaScript? |
| 10:44 | btcNeverSleeps | erf, in ClojureScript I meant of course |
| 11:37 | michaniskin | btcNeverSleeps: 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:37 | michaniskin | btcNeverSleeps: however i do not have a repl handy with the latest cljs version |
| 11:38 | michaniskin | btcNeverSleeps: what are you trying to do? maybe core.async would be something you could use instead? |
| 12:48 | logic_prog | does clojure support setting up callbacks on atoms ? |
| 12:48 | logic_prog | i.e. on agents, I have watchers |
| 12:48 | logic_prog | can I register something similar for atoms, where it gets fired off whenver the atom changes? |
| 12:50 | gfredericks | yes |
| 12:50 | dnolen_ | logic_prog: add-watch |
| 12:50 | qbg | As per the documentation of add-watch: Adds a watch function to an agent/atom/var/ref reference. |
| 12:50 | gfredericks | ,(doc add-watch) |
| 12:50 | clojurebot | "([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:50 | bbloom | but use them *sparingly* please! |
| 12:51 | gfredericks | bbloom: yeah? |
| 12:51 | bbloom | i've only ever used add-watch for enhancing my reload-file workflow. you only need ONE-ish callback for that |
| 12:51 | bbloom | essentially to dispose old-val and initialize new-val |
| 13:02 | pyrtsa | bbloom: You don't even need add-watch for that. Can achieve the same with compare-and-set!. |
| 13:02 | bbloom | pyrtsa: nah, add the watch to a var & then simply reloading the file will cause the watcher to run |
| 13:03 | pyrtsa | Ah, I see. |
| 13:03 | pyrtsa | Thought you were using it for an atom. |
| 13:23 | btcNeverSleeps | michaniskin: (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:24 | btcNeverSleeps | well, "trivial" compared to concurrency in Java I mean (I don't think concurrency is ever trivial) |
| 13:24 | bbloom | btcNeverSleeps: core.async is your best bet for concurrency in cljs. you can use channels like futures with relative ease too |
| 13:25 | btcNeverSleeps | bbloom: thx a lot, I love the dnolen/swanodette posts and videos about core.async. It's on my "todo list" anyway ^ ^ |
| 13:27 | btcNeverSleeps | btw 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:27 | btcNeverSleeps | (not a native english speaker and pretty new to Clojure btw) |
| 13:28 | bbloom | yes, which is short for "dereference" |
| 13:28 | btcNeverSleeps | but a 'future' ain't really an atom? |
| 13:28 | bbloom | dereference is an abstract operation |
| 13:28 | btcNeverSleeps | oh, ok. |
| 13:28 | bbloom | the concrete operation varies by type of the reference object |
| 13:28 | btcNeverSleeps | bbloom: thanks a lot |
| 13:28 | bbloom | for a future, you "get" or "await" it |
| 13:56 | jro_ | jwave.core=> (time (doseq [i (range 1000) j (range 1000)] (aset arr i j (double 1.0)))) |
| 13:56 | jro_ | "Elapsed time: 10991.86 msecs" |
| 14:10 | logic_prog | For agents, I can attach watchers to it. For atoms, is there anything similar to wathchers I can attach to? |
| 14:10 | logic_prog | I.e. some function that is called whenever something changes. |
| 14:11 | aphyr | If 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:11 | aphyr | not sure if I'm just misunderstanding things or if this is actually confusing. |
| 14:13 | Bronsa | aphyr: it is actually confusing. |
| 14:14 | teslanick | Seems 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:14 | ambrosebs | It seems Clojure has moved on from c.c/some. |
| 14:16 | bbloom | ambrosebs: yeah, i think the word "some" now just means not-nil and the name of c.c/some is now considered a wart? |
| 14:16 | ambrosebs | bbloom: seems like it |
| 14:16 | gfredericks | some?/if-some/when-some/some-> are as unrelated to clojure.core/some as all the namespace functions are to clojure.core/namespace |
| 14:17 | gfredericks | bbloom: yeah especially since some uses traditional truthiness semantics |
| 14:17 | Bronsa | I don't really care for the "some" part of the criticism, but the lack of "-let" really bothers me |
| 14:17 | gfredericks | yeah that part was pretty unexpected |
| 14:17 | bbloom | i think core.async is motivating if-some a bit |
| 14:17 | bbloom | that would be my guess |
| 14:18 | gfredericks | six months from now these things will just be endearing |
| 14:18 | bbloom | i have a dorecv macro that is basically the same as for/range over a channel in Go |
| 14:18 | bbloom | pretty useful |
| 14:18 | ambrosebs | I assume the nil channel semantics for core.async are concrete now. |
| 14:19 | ambrosebs | otherwise these wouldn't have turned up |
| 14:19 | gfredericks | commitment to alpha API details will be announced by adding new core functions that relate to them |
| 14:20 | ambrosebs | gfredericks: yep |
| 14:20 | bbloom | Bronsa: the lack of the -let doesn't bother me |
| 14:20 | bbloom | Bronsa: there are lots of macros that have bindings w/o a name that hints it |
| 14:20 | gfredericks | bbloom: usually because it's obvious they take one? |
| 14:21 | gfredericks | there isn't an extremely natural variant without a binding? |
| 14:21 | ambrosebs | oh they take a let binding? |
| 14:21 | Bronsa | ... see |
| 14:21 | bbloom | gfredericks: eh, clojure is anti-anaphoric. so it doesn't make much sense to test an expression without offering a binding for it |
| 14:21 | gfredericks | bbloom: if-some and when-some could be just alternate-truthiness versions of if and when |
| 14:22 | bbloom | gfredericks: 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:22 | bbloom | especially since there isn't much benefit in terms of cleaner syntax without the let binding |
| 14:23 | bbloom | (if-some x y z) vs (if (some? x) y z) vs (if-some [_ x] y z) |
| 14:23 | gfredericks | good point |
| 14:23 | gfredericks | if-not-nil-and-let's-call-it |
| 14:23 | bbloom | lol |
| 14:23 | gfredericks | if-some-here-comes-a-binding-wait-for-it |
| 14:25 | bbloom | it'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:25 | bbloom | then sure enough, lazy seq enhancements come along, and we need (seq ...) everywhere anyway to deal with the subtle nature of next vs rest |
| 14:25 | bbloom | just goes to show that you can solve 783957935 problems in a language design, and still miss.. INFINITELY MANY MORE |
| 14:25 | bbloom | :-P |
| 14:26 | TimMc | and nil being punned as the empty seq as wlel |
| 14:26 | ambrosebs | bbloom: is this stuff easier to handle with just one false value? |
| 14:27 | ambrosebs | bbloom: the lazy seq stuff |
| 14:27 | bbloom | ambrosebs: and just one true value, yeah i think so |
| 14:28 | bbloom | you'd have (if BOOLEAN x y) and then if-let would only make sense as not-nil |
| 14:28 | bbloom | or None rather |
| 14:28 | bbloom | make nil be the empty seq, use None for logically no value |
| 14:29 | dnolen_ | 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:29 | dnolen_ | seq + rest just works. if you use next you generally only call seq once. |
| 14:30 | bbloom | dnolen_: (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:30 | bbloom | not saying that what we have now isn't good |
| 14:30 | bbloom | just saying that it can, as always with anything, be better |
| 14:32 | ambrosebs | bbloom: trying to unlearn clojure to grok your point .. |
| 14:33 | bbloom | ambrosebs: actually, (rest nil) could be a type error |
| 14:33 | TimMc | &(assoc nil 4 5) |
| 14:33 | lazybot | ⇒ {4 5} |
| 14:33 | bbloom | ,(first nil) |
| 14:33 | clojurebot | nil |
| 14:33 | TimMc | ^ seriously bizzare |
| 14:33 | bbloom | turns out, in clojure, nil actually represents an infinite list of nils :-P |
| 14:34 | gfredericks | each of which in turn, |
| 14:34 | TimMc | bbloom: Each one of which is an infinite list of nils... |
| 14:34 | teslanick | That's a pretty awesome language wtf. :) |
| 14:34 | bbloom | TimMc: ok, fine an infinite tree of nils :-) |
| 14:34 | bbloom | nil is used for all loads of stuff |
| 14:34 | bbloom | but we're mainly stuck with it thanks to java |
| 14:34 | gfredericks | a tree with infinite branches at each node and no leaves |
| 14:35 | gfredericks | ambrosebs will save us from the nils |
| 14:35 | r0b1 | bbloom: mainly stuck with nil due to java? |
| 14:35 | bbloom | really, we're stuck with *null* which is a useless form of none :-P |
| 14:35 | hyPiRion | gfredericks: and the branches are ordered too |
| 14:35 | TravisD | teslanick: Being strange makes it awesome? |
| 14:35 | bbloom | r0b1: calling java code can return null, so we need to be able to deal with null references in clojure |
| 14:35 | r0b1 | ah |
| 14:36 | bbloom | but 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:36 | teslanick | TravisD: Maybe? Does that make Javascript *the most awesome* ? |
| 14:36 | TravisD | teslanick: I wouldn't think so :P |
| 14:36 | munderwo | Hi all. I've got a question about defining a db connection? code and question here https://www.refheap.com/39431. ... |
| 14:37 | TimMc | bbloom: I still don't understand the difference between a null pointer and null reference. |
| 14:37 | teslanick | I'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:38 | bbloom | TimMc: 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:38 | hyPiRion | TimMc: A null pointer is of type Null/Void, containing nothing. A null reference is of type X |
| 14:38 | ambrosebs | I'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:38 | hyPiRion | Seems like I have completely different ideas about this than bbloom. |
| 14:38 | bbloom | TimMc: null references are not possible in C++, for example |
| 14:39 | hyPiRion | I'm not alone. |
| 14:39 | hyPiRion | bbloom: So you say you cannot do &NULL in C++? |
| 14:39 | bbloom | hyPiRion: http://stackoverflow.com/questions/4364536/c-null-reference |
| 14:40 | bbloom | smalltalk (and by extension ruby) got this right: null is an object |
| 14:41 | bbloom | to be pedantic, null can actually be non-zero on some old/weird architectures/operating-systems |
| 14:41 | hyPiRion | I feel it's more correct to consider Null/None/Void as a noninstantiable type. But that would of course require statical typing. |
| 14:41 | TimMc | Where null is an object, doesn't that mean a null reference? |
| 14:42 | bbloom | TimMc: no, it's a reference TO the null object. not a reference that points nowhere |
| 14:42 | bbloom | hyPiRion: void is a class with ZERO instances |
| 14:42 | aphyr | munderwo: Use (def ^:dynamic *db* {...}) |
| 14:42 | bbloom | hyPiRion: where as None is a call with one instance :-P |
| 14:43 | aphyr | Then you can override it with (binding [*db* {... some-other-db ...}] (more-functions)) |
| 14:43 | munderwo | cool, 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:43 | aphyr | Yep. |
| 14:43 | hyPiRion | bbloom: yeah, but it's defined differently in different languages. Haskell and Rust uses None, for instance. |
| 14:43 | aphyr | But honestly, you may want to consider just making db a parameter to your functions. |
| 14:43 | hyPiRion | Oh wait, I gotcha now. |
| 14:43 | aphyr | Easier to test and reason about. |
| 14:43 | bbloom | hyPiRion: i'm generalizing names across languages. there are several concepts to contend with.... |
| 14:44 | TimMc | bbloom: So in smalltalk you have a reference to the null object, whose memory location is zero? |
| 14:44 | hyPiRion | bbloom: yeah, Void is uninstantiable, whereas None is a singleton |
| 14:44 | bbloom | TimMc: no. the memory location of null is not zero in smalltalk or ruby |
| 14:44 | bbloom | irb(main):002:0> nil.object_id |
| 14:44 | bbloom | => 4 |
| 14:44 | TimMc | So it's not a null pointer either? |
| 14:44 | TimMc | more like Unit |
| 14:45 | bbloom | TimMc: 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:45 | bbloom | TimMc: 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:45 | TimMc | hmm |
| 14:47 | TimMc | f10dd67234035228da3ec382bab7a49b |
| 14:47 | bbloom | lol |
| 14:49 | hyPiRion | It's a shame Java doesn't have generic enumerations. That would've solved a lot. |
| 14:50 | bbloom | anyway, if it were up to me, i'd break everybody and just redefine (if-let [x (evaluates-to-false)] ...)" to be a bug |
| 14:50 | bbloom | actually, hmmm... can we do that? lol |
| 14:51 | hyPiRion | bbloom: alter-var-root? |
| 14:51 | bbloom | :-) |
| 14:52 | hyPiRion | I tried to manipulate false to return true through reflection once, but it segfaults the JVM unfortunately |
| 14:52 | bbloom | no seriously... the only difference between if-let and if-some is the handle of false |
| 14:52 | bbloom | handling* |
| 14:52 | bbloom | it would be a breaking change for anybody who passes false to if-let, but could easily be worked around by passing nil instead |
| 14:53 | bbloom | seems like if-let should have always been if-some |
| 14:54 | ambrosebs | bbloom: I could add a case in dynalint.. :) |
| 14:55 | ambrosebs | bbloom: I've considered adding a case for (some #{nil false} ...) |
| 14:56 | hyPiRion | ambrosebs: you should, it always return nil regardless. |
| 14:56 | dnolen_ | bbloom: various proposals for things like if-some have come up in the past, it's an obvious generalization of if-let |
| 14:56 | bacon1989 | Hello, 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:56 | bbloom | dnolen_: it's not a generalization |
| 14:56 | dnolen_ | bacon1989: dissoc |
| 14:56 | paulswilliamsesq | Hi all, can any kind soles assist in explaining why code seems to execute in functions when the functions haven't been invoked? |
| 14:56 | bbloom | dnolen_: it's a workaround for a semantics bug, IMO |
| 14:56 | dnolen_ | bbloom: how is it not? |
| 14:56 | ambrosebs | bacon1989: select-keys |
| 14:57 | dnolen_ | bbloom: no semantic far as I can see. |
| 14:57 | bbloom | dnolen_: "generalization" implies it solves a more general class of problems |
| 14:57 | hyPiRion | bacon1989: (select-keys my-map [:first-name :last-name]) will ensure that only first-name adn last-name is contained |
| 14:57 | dnolen_ | bbloom: it does, multiple bindings, multiple tests |
| 14:57 | dnolen_ | this happens all the time and it's ugly |
| 14:58 | bbloom | dnolen_: i think you didn't follow my though process above |
| 14:58 | CaptainLex | So I assume this question is asked all the time |
| 14:58 | CaptainLex | but |
| 14:58 | CaptainLex | why doesn't clojure support tail-recursion optimization? |
| 14:58 | dnolen_ | bbloom: I did, but I also didn't agree or see the point. |
| 14:59 | bbloom | dnolen_: the point is that if-let testing truthiness was always an approximation for the desired semantics of checking non-nil-ness |
| 15:00 | aphyr | if-let* |
| 15:00 | bbloom | dnolen_: (if-let [x false] ....) is just not very useful |
| 15:00 | aphyr | bbloom: I actually use that form all the time |
| 15:00 | bacon1989 | ah thanks guys, i'll look at those functions |
| 15:00 | bbloom | aphyr: you use if-let with an expectation of a false value all the time? |
| 15:01 | aphyr | With the expectation of a non-false or non-nil value. |
| 15:01 | bbloom | aphyr: but do you ever expect false? or always nil vs not nil ? |
| 15:02 | aphyr | I typically don't want to bind false. |
| 15:02 | munderwo | aphyr: 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:03 | bbloom | aphyr: but do you want to bind true? |
| 15:03 | bbloom | aphyr: presumably when you use (if-let [x ...) you want a useful payload in x |
| 15:03 | aphyr | Sometimes the values of x might be either false or a number. |
| 15:03 | dnolen_ | bbloom: (if-let [x (and (pred? y) (compute z))] ...) |
| 15:04 | aphyr | I dunno, I can certainly see an argument for changing if-let and when-let to non-nil as opposed to truthy. |
| 15:04 | bbloom | dnolen_: that's not what if-some is |
| 15:04 | dnolen_ | bbloom: you're right that if-some is generalization of a particular usage of if-let |
| 15:04 | aphyr | But that seems confusing when you compare it to (if) and (when) |
| 15:04 | bbloom | dnolen_: oh wait.... |
| 15:05 | bbloom | dnolen_: sorry, my bad |
| 15:05 | dnolen_ | (if-let [...] (if-let [...])) |
| 15:05 | bbloom | dnolen_: i'm looking at the ticket now |
| 15:05 | bbloom | dnolen_: or the actual patch rather |
| 15:05 | bbloom | instead of the comments in the thread |
| 15:05 | dnolen_ | heh |
| 15:05 | bbloom | oh wow |
| 15:05 | dnolen_ | starting in the wrong place man |
| 15:05 | bbloom | nevermind, these names are mega confusing lol |
| 15:05 | gfredericks | oh geez |
| 15:05 | bbloom | if-pred |
| 15:05 | hyPiRion | what, there's an if-pred? |
| 15:05 | bbloom | ok i still stand by all the stuff i said above about if-let |
| 15:06 | gfredericks | bbloom: what aspect do you think is confusing? |
| 15:06 | sjl | if-some == if-not-nil-let |
| 15:06 | aphyr | Yep. |
| 15:06 | gfredericks | bbloom: (I'm not sure how you were misunderstanding it) |
| 15:06 | bbloom | maybe i'm not... hold on |
| 15:06 | bbloom | i'm looking at http://dev.clojure.org/jira/secure/attachment/12790/clj-1343-4.patch |
| 15:07 | bbloom | that patch seems to not match what rich is saying |
| 15:07 | hyPiRion | what. I had the intuition that if-some was (if (not (nil? z))) x y) |
| 15:07 | gfredericks | hyPiRion: that's most people's complaints wrt confusing names |
| 15:07 | sjl | hyPiRion: no, it binds things like if-let |
| 15:07 | sjl | even though there's no -let in the name |
| 15:07 | bbloom | dnolen_: no no, i'm right |
| 15:07 | bbloom | dnolen_: there is no explicit predicate |
| 15:07 | bbloom | it's not a generalization |
| 15:08 | hyPiRion | sjl: yeah, I gathered. I even read the 1.6 changelog and still thought it acted like that. |
| 15:08 | sjl | hyPiRion: yeah that's because the naming is confusing |
| 15:08 | sjl | hah |
| 15:08 | bbloom | dnolen_: it would be a generalization if it took an explicit predicate |
| 15:08 | aphyr | I could see (let-some) |
| 15:08 | bbloom | dnolen_: there is a generalization if if-let and if-some that would be if-pred |
| 15:10 | paulswilliamsesq | in 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:10 | bbloom | dnolen_: `(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:10 | bbloom | i stand by everything i said above :-) |
| 15:12 | ambrosebs | paulswilliamsesq: does it still show a frame when compiled in a REPL? Perhaps you're running other things accidentally. |
| 15:12 | paulswilliamsesq | ambrosebs: 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:12 | bbloom | ,(defn test-pred [pred x] (if (pred x) x nil)) |
| 15:12 | clojurebot | #'sandbox/test-pred |
| 15:13 | bbloom | ,(map #(test-pred odd? %) [3 4 5 6]) |
| 15:13 | clojurebot | (3 nil 5 nil) |
| 15:13 | bbloom | dnolen_: ^^ there, now you don't need if-pred :-) |
| 15:13 | bbloom | ,(if-let [x (test-pred odd? 5]] :yup :nope) |
| 15:13 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]> |
| 15:14 | bbloom | ,(if-let [x (test-pred odd? 5)] :yup :nope) |
| 15:14 | clojurebot | :yup |
| 15:14 | bbloom | ,(if-let [x (test-pred odd? 6)] :yup :nope) |
| 15:14 | clojurebot | :nope |
| 15:14 | bbloom | :-) |
| 15:14 | hyPiRion | ,(if-let [x (test-pred false? false)] :is-false :is-true) |
| 15:14 | clojurebot | :is-true |
| 15:14 | hyPiRion | :) |
| 15:14 | bbloom | hyPiRion: clearly you need to use if-some, since if-let is broken |
| 15:15 | bbloom | hyPiRion: but the bots aren't up to date, so i just assumed clojure 2.0 where this is fixed ;-) |
| 15:15 | bbloom | or maybe it's bbloom 1.0 |
| 15:15 | hyPiRion | bbloom: good call |
| 15:15 | bbloom | whatever :-) |
| 15:15 | sjl | ,(if-some [x (test-pred nil? nil)] :is-nil :wat) |
| 15:15 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: if-some in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:16 | bbloom | ,(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:16 | clojurebot | #'sandbox/if-some |
| 15:16 | bbloom | ,(if-some [x (test-pred nil? nil)] :is-nil :wat) |
| 15:16 | clojurebot | :wat |
| 15:16 | bbloom | hyPiRion: there you go |
| 15:17 | sjl | bbloom: that's wrong though |
| 15:17 | sjl | bbloom: the predicate is nil |
| 15:17 | sjl | ? |
| 15:17 | hyPiRion | bbloom: heh. |
| 15:17 | sjl | nil satisfies the predicate |
| 15:17 | sjl | and yet the else clause is returned |
| 15:18 | erdos | hello 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:18 | bbloom | sjl: and now you see why type theory people argue for sum types :-) |
| 15:18 | sjl | yep |
| 15:18 | bbloom | at this point, you need quoting :-P |
| 15:18 | bbloom | b/c you need None and Some(None) |
| 15:18 | sjl | you need to disentangle the value from the predicate check |
| 15:18 | sjl | a hypothetical if-pred would be fine |
| 15:19 | bbloom | and an if that only operates on booleans would help too |
| 15:19 | sjl | but 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:21 | hyPiRion | erdos: That's strange, how did you construct the symbol? |
| 15:21 | hyPiRion | I can't reproduce that |
| 15:21 | hyPiRion | ,(name 'use) |
| 15:21 | clojurebot | "use" |
| 15:23 | paulswilliamsesq | ambrosebs: 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:23 | erdos | hyPiRion: hello, i used clojure.tools.reader/read |
| 15:23 | erdos | hyPiRion: even (.getName) returns the correct value. also (string?) is false. |
| 15:24 | heath | i was watching rich give a presentation on csp about a week ago on callbacks |
| 15:24 | ambrosebs | paulswilliamsesq: unless there is some macro that spins up a process when it expands, I don't see how that's possible |
| 15:25 | heath | he mentioned promise libs are popular again because of this |
| 15:25 | ambrosebs | paulswilliamsesq: I guess you've tried restarting your JVM? |
| 15:26 | heath | i 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:26 | heath | Why does clojure have promises, and are these the same types of promises he was referencing in the talk? |
| 15:26 | ambrosebs | erdos: can you elaborate more on where the symbol is coming from? is it metadata? |
| 15:27 | paulswilliamsesq | ambrosebs: no I don't either. yes, I've killed all JVMs. |
| 15:27 | egghead | heath: the general idea is that promises are good for one-off async events, but they aren't too good for streams |
| 15:27 | paulswilliamsesq | new lein repl from my home directory which has't got a lein project installed. |
| 15:27 | ambrosebs | paulswilliamsesq: perhaps try it in a completely empty project? I'm out of ideas. |
| 15:27 | paulswilliamsesq | ambrosebs: yeah, wil do. |
| 15:28 | erdos | ambrosebs: hello, i am parsing ns declarations of source files with clojure.tools.reader 0.7.7 . strangely .getName is ok. |
| 15:28 | ambrosebs | erdos: can you show some code? |
| 15:29 | erdos | ambrosebs: working on it |
| 15:29 | heath | cool, thanks egghead |
| 15:29 | ambrosebs | erdos: would like to know out of morbid curiosity as well ;) |
| 15:29 | dnolen_ | bbloom: yes I said agreed, it generalizes a very specify use of if-let |
| 15:30 | dnolen_ | s/specify/specific |
| 15:30 | bbloom | dnolen_: i think disagree on what the word "generalizes" means... |
| 15:32 | aphyr | haha |
| 15:32 | bbloom | dnolen_: it specializes a more general predicate/binding/branching pattern. if-let is also a specialization of that same general thing |
| 15:33 | dnolen_ | bbloom: macro sugar generalizes patterns as far I am concerned. |
| 15:34 | bbloom | dnolen_: generalize is not the word you're looking for |
| 15:35 | dnolen_ | generalizes syntactical patterns, or perhaps you don't believe that macros do this? |
| 15:35 | dnolen_ | bbloom: then give me a better word? |
| 15:35 | hyPiRion | unboilerplatify them at least |
| 15:35 | dnolen_ | :P |
| 15:36 | bbloom | abbreviate? i dunno |
| 15:36 | bbloom | definitely not generalize |
| 15:36 | dnolen_ | bbloom: then rewrite in your brain my points and we can move on :) |
| 15:37 | bbloom | dnolen_: yeah, the word "abbreviate" works for your points, heh |
| 15:38 | benmoss | dnolen_: can you explain the conceptual difference between state stored on the owner vs on the component in Om? |
| 15:38 | bbloom | once 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:38 | bbloom | i'd imagine 60 to 80% are in the definitions camp :-P |
| 15:39 | dnolen_ | benmoss: Om uses delegation, there's only one React component type in Om, so we delegate to your reify instance. |
| 15:39 | dnolen_ | benmoss: component local state is actually stored on the React component that "owns" your reify instance |
| 15:45 | benmoss | hmm I'm afraid i don't follow |
| 15:46 | dnolen_ | benmoss: above you're describing a distinction that does exist. That's what I was trying to explain. |
| 15:46 | dnolen_ | s/does/doesn't |
| 15:46 | benmoss | yeah, that's what i suspected |
| 15:49 | benmoss | so 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:50 | dnolen_ | benmoss: easier to understand what you're struggling w/ if you give me links to line numbers? |
| 15:50 | benmoss | yeah was about to get that |
| 15:50 | egghead | hm |
| 15:51 | benmoss | https://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:51 | egghead | i 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:51 | benmoss | woops |
| 15:51 | egghead | but I could see something like 'is this component in edit mode' going into owner state |
| 15:51 | benmoss | https://github.com/swannodette/todomvc/blob/gh-pages/labs/architecture-examples/om/src/todomvc/item.cljs#L66 for the second link |
| 15:52 | egghead | I guess that's just an organization sort of thing? |
| 15:52 | dnolen_ | benmoss: so the second is link is what is referred to in the React world as "props" |
| 15:52 | dnolen_ | benmoss: the first link is setting component local state |
| 15:53 | dnolen_ | benmoss: in Om "props" are values from the app-state atom |
| 15:53 | benmoss | yeah |
| 15:53 | benmoss | so 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:53 | dnolen_ | benmoss: usually anyway, props can actually be anything. |
| 15:54 | dnolen_ | benmoss: very little should go into local state, like egghead said - channels, transient information (like mouse position, element dimensions), etc |
| 15:55 | dnolen_ | 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:57 | benmoss | i'm trying to model a chess game and think i need a place for "the possible moves for a given piece/position" |
| 15:58 | benmoss | it both represents the legal moves for that piece, as well as the information for which other positions to highlight |
| 15:59 | dnolen_ | benmoss: but I don't think you need to store that you can compute that |
| 16:01 | benmoss | hm, 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:03 | benmoss | like 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:03 | TravisD | Can anyone suggest a library that facilitates linear algebra and plotting? I was looking at Incanter, but it seems somewhat outdated |
| 16:04 | dnolen_ | benmoss: no you would compute the grid based on the information you have and then render it. |
| 16:05 | dnolen_ | benmoss: individual squares compoent should just render the data they get - no logic except maybe click event |
| 16:07 | TravisD | Actually, incanter looks pretty nice. |
| 16:07 | dnolen_ | benmoss: a better way in mind would be a component to get {:current-selected true} and have some additional behavior because of this. |
| 16:10 | benmoss | yeah so a function that passed {:selected true} to the selected square, and like {:targetable true} to the squares the piece can reach |
| 16:10 | dnolen_ | benmoss: yep |
| 16:11 | benmoss | thanks, it seems so obvious now :) |
| 16:12 | dnolen_ | benmoss: chess is actually a pretty good thing to try with Om. |
| 16:12 | dnolen_ | 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:12 | benmoss | yeah, i saw you posted that on twitter |
| 16:13 | dnolen_ | s/pretty/pretty sweet |
| 16:14 | benmoss | looks very similar, i think we both ripped off the same html chess board |
| 16:17 | bbloom | dnolen_: thank you so much for helping react take off :-) |
| 16:17 | bbloom | we as a profession will escape the brain dead OOP GUI model some day |
| 16:17 | dnolen_ | bbloom: haha, yeah it's exploded! |
| 16:17 | dnolen_ | bbloom: finally people are looking past JSX |
| 16:18 | bbloom | dnolen_: 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:18 | dnolen_ | bbloom: haha |
| 16:18 | bbloom | the cljs community was inherently the right overlap |
| 16:19 | bbloom | ie people who care about browser GUIs AND sane semantics |
| 16:22 | dnolen_ | bbloom: yeah, I'm starting to see that React/Om really shines though w/ core.async |
| 16:22 | bbloom | dnolen_: have you baked it in to Om yet? / will you? |
| 16:22 | dnolen_ | 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:22 | dnolen_ | bbloom: probably won't do that. Om is close to "done". Only interested in internal improvements and more performance. |
| 16:23 | bbloom | dnolen_: ok cool |
| 16:23 | bbloom | for further communal self congratulations: gotta love libraries that are "done" |
| 16:26 | AmnesiousFunes | dnolen_: 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:26 | benmoss | meanwhile thousands of people use the perpetually in-beta ember-data |
| 16:26 | dnolen_ | benmoss: lol |
| 16:26 | dnolen_ | AmnesiousFunes: thanks! |
| 16:27 | AmnesiousFunes | benmoss: I remember Discourse (the big forum project) electing to use Ember because they felt it was "future-proof". |
| 16:27 | bbloom | benmoss: over 10k of javascript for that thing... and it has dependencies too |
| 16:28 | bbloom | klocs, that is |
| 16:28 | bbloom | not kb |
| 16:29 | Ayey | Does Discourse use ember-data? I thought they avoid it because it was unstable. |
| 16:29 | benmoss | they don't |
| 16:31 | Ayey | ph, okay |
| 16:31 | Ayey | oh* |
| 16:34 | benmoss | it is an ORM for APIs, it is a horrible thing |
| 16:36 | bbloom | two things i dislike :-P |
| 16:36 | bbloom | i'm pretty sure that my hate gets multiplied together, rather than added |
| 16:38 | btcNeverSleeps | ,(doc doc) ; just trying if doc works here |
| 16:38 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 16:38 | bbloom | btcNeverSleeps: doc also works here without the , |
| 16:38 | bbloom | (doc doc) |
| 16:38 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 16:38 | btcNeverSleeps | bbloom: oh cool ^ ^ |
| 16:41 | btcNeverSleeps | I'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:42 | bbloom | btcNeverSleeps: seems fine, but do you actually want a typed jvm array or do you want Object[] ? |
| 16:44 | btcNeverSleeps | bbloom: 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:44 | bbloom | ,(make-array Byte/TYPE 5) |
| 16:44 | clojurebot | #<byte[] [B@4ed19b> |
| 16:44 | bbloom | btcNeverSleeps: is that what you want? |
| 16:45 | bbloom | btcNeverSleeps: if you know that the array contains only primitives of one type, then you probably want a primitive array to avoid boxing |
| 16:45 | btcNeverSleeps | bbloom: 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:45 | btcNeverSleeps | bbloom: oooh gotcha |
| 16:45 | bbloom | btcNeverSleeps: oh i see, an array of byte arrays |
| 16:45 | bbloom | btcNeverSleeps: arrays are, themselves, boxed types. so it won't matter |
| 16:46 | bbloom | unless you care about interop with some java API |
| 16:46 | bbloom | an array of objects is fine for the outer array |
| 16:48 | bbloom | btcNeverSleeps: make sense? so you can just use object-array or into-array without a type argument |
| 16:48 | hyPiRion | it's not hard to just do (make-array (Class/forName "[B") dims) either |
| 16:49 | bbloom | hyPiRion: there is no benefit to doing so. actually it probably hurts, since you'll get an extra type check at runtime |
| 16:49 | benmoss | is there something more succinct than (if (pred? x) (conj x foo) x) |
| 16:49 | bbloom | hyPiRion: java's array variance stuff is all kinds of weird |
| 16:49 | btcNeverSleeps | (was afk) |
| 16:49 | btcNeverSleeps | bbloom: yup, makes lots of sense |
| 16:49 | benmoss | like an if/when that defaults to returning the value |
| 16:49 | hyPiRion | benmoss: (cond-> x (pred? x) (conj foo)) |
| 16:50 | benmoss | hyPiRion: thanks |
| 16:50 | hyPiRion | bbloom: funny, didn't know that |
| 16:51 | bbloom | hyPiRion: 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:51 | bbloom | hyPiRion: but if you already have a boxed pointer, you can just copy it w/o checking it, right? |
| 16:51 | hyPiRion | bbloom: right, but then you'd have to check at read time then? |
| 16:52 | btcNeverSleeps | hyPiRion: 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:52 | btcNeverSleeps | for it feels like some kind of a "hack" to write (make-array (type ...) ...) |
| 16:52 | danneu | (Class/forName "[B") is 'hard' though |
| 16:52 | danneu | ugh |
| 16:52 | btcNeverSleeps | danneu: well, I come from many years of Java so it doesn't look too alien but I tend to agree it's 'hard' ^ ^ |
| 16:53 | Cr8 | ,(class (byte-array [])) |
| 16:53 | clojurebot | [B |
| 16:53 | bbloom | hyPiRion: hm, that is true... |
| 16:53 | hyPiRion | btcNeverSleeps: Well, you could just do (def byte-array-type (type (make-array Byte/TYPE))), if you're afraid of perf |
| 16:54 | bbloom | hyPiRion: 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:55 | bbloom | btcNeverSleeps: either way, use the more specific type if it makes you feel good or if you benchmark it and it matters :-P |
| 16:55 | btcNeverSleeps | bbloom: :) |
| 16:55 | danneu | Clojure has been a joy for working with bytes. (map int <bytes>), (map (partial bit-and 0xff) <bytes>), (map unchecked-byte <ints>) |
| 16:56 | hyPiRion | heh, I've sort of given up on an actual analysis of performance wrt. time. |
| 16:56 | bbloom | heh |
| 17:05 | Nooob | Hi, 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:05 | aphyr | Nooob: most folks use emacs or vim. |
| 17:06 | aphyr | Though any text editor you like should work fine. |
| 17:06 | aphyr | Some folks use LightTable, which is a clojure-specific IDE, but I don't think that's common yet. |
| 17:07 | Nooob | aphyr I was messing with emcas, but feels weird |
| 17:08 | dnolen_ | Nooob: CursiveClojure is very good, probably the best traditional IDE experience |
| 17:08 | Nooob | hummm |
| 17:08 | dnolen_ | Nooob: LT is simple and pretty easy to use |
| 17:08 | AmnesiousFunes | CIDER is quite good as well. Light Table is very immediate and accessible. |
| 17:10 | r0b1 | Nooob: 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:10 | danneu | I tried various editors when I was learning Clojure. I can't imagine fiddling with an editor during that stage |
| 17:11 | qbg | Nooob: Are you comfortable with with an IDE for another programming language? |
| 17:11 | Nooob | r0b1 this ability to extend the editor really makes the difference? |
| 17:12 | Nooob | qbg yes =) |
| 17:12 | qbg | Which one? |
| 17:12 | AmnesiousFunes | Nooob: For "serious" usage, yes. (By the way, Light Table is also extensible.) |
| 17:12 | r0b1 | Nooob: "with lisp", yeah :) as you learn clojure you'll become more comfortable learning elisp and vice versa i'd guess. |
| 17:12 | AmnesiousFunes | (It is much less mature than Emacs with CIDER at this stage, though.) |
| 17:13 | danneu | Nooob: For Clojure, what matters is arriving at a quick iteration where you can eval code within the editor (not in a REPL) |
| 17:13 | Nooob | qbg Eclipse, NetBeans... |
| 17:13 | r0b1 | that are horrible "editors" |
| 17:13 | r0b1 | those* |
| 17:14 | aphyr | (I basically just use vim as a dumb text editor, and use `lein repl` for live evaluation.) |
| 17:14 | qbg | In the past I've used Counterclockwise with Eclipse, but I've been out of the Clojure loop for a while |
| 17:14 | danneu | aphyr: how do you get code to the repl? |
| 17:16 | Nooob | well, I think ill try Cursive and give emcas another shot hehe |
| 17:17 | AmnesiousFunes | danneu: lein repl can load namespaces automatically; read about leiningen configuration for more information |
| 17:19 | aphyr | danneu: (use 'foo.core :reload) |
| 17:20 | aphyr | Though most often I have lein prism running, so I just write the file and it automatically re-runs the tests. |
| 17:20 | danneu | yeah, i don't know why i asked that |
| 17:20 | danneu | that's how often i've used a repl |
| 17:21 | danneu | aphyr: 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:21 | r0b1 | your repl can help in cases like this by better supporting "repl-driven development" |
| 17:24 | Nooob | well, guys thank you very much for the tips ^^ I really appreciate, and sorry for my bad english hehe |
| 17:24 | koz | Hi 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:24 | koz | How do I do that? |
| 17:26 | benmoss | `apt-get install leiningen`? |
| 17:26 | koz | benmoss: really? OK... simpler than I thought. |
| 17:26 | koz | Thanks! |
| 17:26 | koz | Also, does SciTE have any support for Clojure? |
| 17:27 | benmoss | never even heard of SciTE, no idea |
| 17:27 | koz | What's a good text editor with Clojure support for Linux. Other than Emacs/vim. |
| 17:28 | koz | (Although I should learn Emacs some time) |
| 17:28 | systemfault | koz: Perhaps lighttable |
| 17:28 | benmoss | people were just talking about this, yeah light table is a popular choice |
| 17:28 | danneu | koz: does `lein` do anything when you run it? |
| 17:28 | benmoss | if you don't have any prior allegiances |
| 17:28 | koz | danneu: Yeah, it works for everything as normal. |
| 17:28 | danneu | koz: what version is it |
| 17:28 | koz | benmoss: I'm new to Linux. So no, no priors. |
| 17:29 | benkay | ,(map #(inc %) [1 2 3]) |
| 17:29 | clojurebot | (2 3 4) |
| 17:29 | koz | danneu: 1.7.1 |
| 17:29 | benkay | (map #(inc %) [1 2 3 \f]) |
| 17:29 | koz | Which I assume is the latest. |
| 17:29 | benkay | ,(map #(inc %) [1 2 3 \f]) |
| 17:29 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number> |
| 17:29 | danneu | koz: `apt-get install leiningen` installs an old version. install it by hand |
| 17:29 | hyPiRion | koz: no, 2.3.4 is the latest one |
| 17:29 | amalloy | $google leiningen readme |
| 17:29 | benkay | right, so how do I shoehorn a try/catch into that mapping? |
| 17:29 | lazybot | [leiningen/README.md at master · technomancy/leiningen · GitHub] https://github.com/technomancy/leiningen/blob/master/README.md |
| 17:29 | danneu | koz: https://github.com/technomancy/leiningen |
| 17:29 | koz | Ah, I see. |
| 17:29 | koz | Thanks. |
| 17:30 | hyPiRion | koz: so you'd do `sudo apt-get remove leiningen` first, to remove the apt installed version |
| 17:30 | benmoss | my bad, i had no idea apt was out of date |
| 17:30 | amalloy | i 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:30 | koz | Thanks for the warning guys. |
| 17:30 | danneu | yeah, 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:30 | amalloy | danneu: i mean, that's like a core feature of apt. things get in when they're stable, not when they're new |
| 17:30 | benmoss | and that the old lein upgrade warning tells you to use apt |
| 17:31 | danneu | amalloy: sure, i mean unfortunate for a newcomer that doesn't know |
| 17:31 | gws | benkay: do you expect the result to be nil or (2 3 4) or something else? |
| 17:31 | benkay | ah it's not the result i'm terrifically concerned with so much as the inputs |
| 17:32 | koz | So you want it to fail if you feed it a list with anything other than a number? |
| 17:32 | benkay | well, it's an example. |
| 17:32 | benkay | i want to catch exceptions thrown in the mapped function |
| 17:33 | koz | Can't you wrap the whole map call in a try-catch? |
| 17:33 | gws | yeah, and then do what with the result |
| 17:33 | hyPiRion | koz: unfortunately, map is lazy, so that won't do |
| 17:33 | benkay | uh, log it, throw it away, i don't care fuckit.clj |
| 17:34 | benkay | the root question i'm pursuing here is how best to implement a try/catch with a mapped function |
| 17:34 | benkay | map the try/catch form? |
| 17:34 | benkay | (map #(try (my-fn %) (catch some.java.whatever) [list-o-stuff]))? |
| 17:34 | koz | benkay: Not what I meant. Wrap the actual map call in a try-catch. |
| 17:35 | hyPiRion | ,(try (doall (map inc [1 2 3 \f])) (catch Exception e :error)) |
| 17:35 | clojurebot | hyPiRion: Cool story bro. |
| 17:35 | hyPiRion | &(try (doall (map inc [1 2 3 \f])) (catch Exception e :error)) |
| 17:35 | lazybot | java.lang.SecurityException: You tripped the alarm! catch is bad! |
| 17:35 | hyPiRion | blugh. |
| 17:35 | hyPiRion | Well, 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:36 | benkay | sure, makes sense. the actual funcall is happening inside a doall already and is being pmapped to make things worse and more complex |
| 17:37 | benkay | so walk me through one more time in words of single syllables why mapping the try/catch is not going to work? |
| 17:38 | hyPiRion | Mapping the try/catch would work nice, but I have no idea what you'd like the mapping to return then |
| 17:39 | benkay | it's a nasty side-effecty thing don't worry about it |
| 17:39 | benkay | ,(map #(try (inc %) (catch java.lang.ClassCastException (println "nooooo"))) [1 2 3]) |
| 17:39 | clojurebot | benkay: No entiendo |
| 17:39 | benkay | yeah me neither clojurebot |
| 17:40 | benkay | okay well in that case i'm going to defer to your sage advice hyPiRion and wrap the doall. |
| 17:41 | koz | OK, manual install worked. |
| 17:41 | hyPiRion | benkay: 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:41 | koz | Thanks everyone. |
| 17:41 | benkay | hyPiRion: just figured that out :( |
| 17:41 | benkay | yeah! i think i really want to pmap the try/catch itself if i can.. |
| 17:42 | hyPiRion | benkay: yeah, go ahead. Noone's stopping you |
| 17:42 | beamso | ,(doc int?) |
| 17:42 | clojurebot | Pardon? |
| 17:43 | beamso | you could do a check to ensure every item in the vector was an integer |
| 17:44 | benkay | again, beamso, that's not really what's at issue here. |
| 17:44 | koz | OK.... maybe not. |
| 17:44 | koz | I get |
| 17:44 | koz | 'THe program 'lein' is currently not installed. You can install it by typing: sudo apt-get install leiningen |
| 17:44 | koz | But that will give me the old version |
| 17:45 | hyPiRion | koz: okay, where did you place the lein script? |
| 17:45 | qbg | lein is probably not on your path |
| 17:45 | koz | in ~/bin, which is on my path. |
| 17:45 | hyPiRion | koz: did you do `chmod u+x ~/bin/lein` ? |
| 17:46 | hyPiRion | (to make it executable) |
| 17:46 | beamso | move the 'inc' into it's own function where you handle the exception there and provide a default value/no value to return? |
| 17:46 | koz | No - I did chmod +x |
| 17:46 | koz | So I need the u as well. |
| 17:46 | hyPiRion | well, that shouldn't matter I think |
| 17:46 | qbg | How long has ~/bin been on your path? |
| 17:46 | hyPiRion | I'd try to restart the shell, sometimes it may not detect stuff at once |
| 17:46 | koz | I just put it there, and I restarted the shell. |
| 17:47 | koz | If I type echo $PATH, it's definitely there. |
| 17:47 | koz | (As the very last entry) |
| 17:48 | qbg | what does `which lein` return? |
| 17:48 | koz | Nothing. |
| 17:48 | qbg | Perhaps PATH is malformed? |
| 17:48 | koz | I'll just copy-paste the result of echo $PATH |
| 17:49 | koz | /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:home/koz/bin |
| 17:49 | qbg | you need /home there |
| 17:49 | qbg | not home |
| 17:49 | koz | Ah, |
| 17:49 | koz | OK. |
| 17:50 | koz | Fixed. Also FML. I'm too used to Windows shell. |
| 17:50 | hyPiRion | koz: It'll go over eventually. We've all been noobs at shell and Linux once |
| 17:51 | koz | hyPiRion: Thanks. Appreciate the sympathy. :) |
| 17:51 | koz | OK, it's downloaded a jar. |
| 17:51 | koz | I guess I have to run it? |
| 17:51 | hyPiRion | koz: no, lein does everything by itself, managing upgrades and stuff |
| 17:51 | AimHere | I 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:52 | koz | Well, I ran the self-install. |
| 17:52 | qbg | just run `lein` then :) |
| 17:52 | koz | Ah. |
| 17:52 | koz | There we go. |
| 17:52 | koz | It's getting a whole shittonne of jars |
| 17:52 | koz | Meaning I probably did something right. |
| 17:52 | amalloy | that's maven for you |
| 17:53 | hyPiRion | koz: yeah, it's downloading the Internet |
| 17:53 | koz | Yay, the whole Internet! |
| 17:53 | koz | OK, I now have Leiningen 2.3.4 |
| 17:53 | koz | Success! |
| 17:53 | systemfault | Oh yeah |
| 17:54 | amalloy | AimHere: 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:54 | koz | In this case, these commands are so simple that knowing them helps. Plus, I've kinda gotten into the CLI habit. |
| 17:54 | koz | And I like working with a shell. |
| 17:54 | koz | It's easier. |
| 17:54 | koz | OK, maybe you guys can help me with this one. |
| 17:55 | koz | I've installed Linux Mint, and I want it to dual-boot with my Windows 7. |
| 17:55 | koz | I partitioned my drive and everything, and the install went fine. |
| 17:55 | koz | But I can't boot the Linux half - at boot time, it just goes straight to Win7. |
| 17:55 | Ayey | What order did you install them? |
| 17:55 | koz | Win7 was there first. |
| 17:55 | systemfault | Sure... Windows doesn't care about your bootloader, it kills it. |
| 17:55 | amalloy | windows hates dual-booting iirc, you have to have grub on the MBR |
| 17:56 | koz | MBR? |
| 17:56 | danneu | AimHere: 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:56 | Ayey | Master boot record i think |
| 17:56 | qbg | master boot record |
| 17:56 | AimHere | amalloy, 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:56 | koz | OK... so how do I do that? |
| 17:56 | amalloy | koz: install windows first, then mint. tell mint you want to dual-boot; i think it asks when you're installing |
| 17:56 | Ayey | Live-CD into a linux, and install Grub on a boot or root partions |
| 17:56 | hyPiRion | koz: 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:56 | koz | Yeah - Mint doesn't give me that option on the installer. |
| 17:56 | amalloy | or if you don't want to restart stuff from scratch, you can do it some other way; what Ayey says sounds fine |
| 17:57 | koz | I had to basically partition manually. |
| 17:57 | koz | LiveCD in? OK. |
| 17:57 | koz | I can do that. |
| 17:57 | koz | How do I install grub after that? |
| 17:57 | Ayey | Remeber to install os-proper, so grub-config can detect Windows |
| 17:57 | amalloy | i mean, there are a *lot* of resources on the web about doing exactly this |
| 17:57 | Ayey | Eh, let me try to find you a proper guide.. |
| 17:57 | koz | Thanks - much appreciated. |
| 17:57 | zoldar | koz: http://community.linuxmint.com/tutorial/view/245 |
| 17:58 | koz | I've been having some issues with this, since I'm a complete noob at Linux. |
| 17:58 | qbg | you could be super lazy and put it in a VM :p |
| 17:58 | koz | Another 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:58 | koz | How can I change that? |
| 17:59 | koz | Midori doesn't seem to have... well, any sort of options menu I could find. |
| 17:59 | Ayey | That is the system that contols it |
| 17:59 | danneu | google 'default browser debian' |
| 17:59 | Ayey | You should be able to find default-applications somewhere in your settings |
| 17:59 | koz | Ayey: Thanks - I'll check. |
| 18:00 | zoldar | koz - it's update-alternatives for x-www-browser most of the time |
| 18:00 | zoldar | koz: as in "sudo update-alternatives --config x-www-browser" |
| 18:00 | koz | Thanks - there seems to be a graphical utility for this under Mint. |
| 18:01 | koz | Thanks everyone - you've all been incredibly helpful. |
| 18:01 | hyPiRion | koz: good luck fixing stuff :) |
| 18:01 | koz | I may well need it. |
| 18:01 | Ayey | Indeed, thats where you'll learn the most :) |
| 18:02 | koz | Well, I already learned a bit from trying to install Debian and having it fry on me. |
| 18:03 | koz | Also, as a complete aside, Pandora is awesome. |
| 18:03 | zoldar | koz: there's a nice middleground between plain debian and ubuntu-based mint - linux mint debian edition |
| 18:03 | koz | zoldar: I decided to go for the Xfce Mint instead. |
| 18:03 | koz | Was that a mistake? |
| 18:04 | Ayey | XFCE is a good choice |
| 18:04 | koz | It's minimal, and the first machine I installed Linux Mint on is an old Eee-PC. |
| 18:04 | Ayey | Mint is a fine distro, just too bloated with stuff for my taste :) |
| 18:04 | zoldar | koz: not, it's also a good choice |
| 18:05 | koz | I was mostly inspired to get into Linux by 'The Art of Unix Programming'. |
| 18:05 | koz | Seriously awesome book. |
| 18:06 | alexanderkyte | I was inspired by my grandfather's autocoder operator's manual |
| 18:06 | systemfault | I hated linux until I tried FreeBSD... then everything made sense to me after. |
| 18:06 | r0b1 | hah |
| 18:06 | r0b1 | unusual |
| 18:06 | akyte | I miss Ctrl+T |
| 18:06 | koz | OK, this guide is already doing odd things. |
| 18:07 | akyte | Which guide? |
| 18:07 | koz | http://community.linuxmint.com/tutorial/view/245 |
| 18:07 | koz | It says 'type Gparted into the menu from the LiveCD' |
| 18:07 | koz | And.... I get nothing. |
| 18:07 | akyte | I usually just chroot back in to my old install and use that to install |
| 18:08 | Ayey | Just open gparted? |
| 18:08 | akyte | Superstition on versioning |
| 18:08 | Ayey | systemfault, freebsd? How come? I always wanted to give it a go |
| 18:08 | koz | It seems it's not on my LiveCD. |
| 18:08 | koz | Or at least I can't find it anywhere. |
| 18:08 | akyte | sudo apt-get install gparted |
| 18:08 | Ayey | Then install it with apt-get :) |
| 18:08 | koz | OK. |
| 18:09 | zoldar | koz: if that's only for the purpose of checking partition layout, "fdisk -l" is usually sufficient |
| 18:09 | koz | Ah. Well, I started downloading it already, so wfe. |
| 18:09 | systemfault | Ayey: FreeBSD felt simpler, more coherant... all the userland utils felt better integrated. Using ports sucks though, I hate compiling software. |
| 18:10 | koz | But thanks for that. |
| 18:10 | systemfault | *coherent |
| 18:10 | akyte | I 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:11 | systemfault | akyte: I hate compiling :) The flexibility ports provide is really good though |
| 18:12 | koz | OK, in this guide, I'm meant to find the Linux Mint partition. I have two - root and the other one. |
| 18:12 | koz | (Not swap) |
| 18:12 | koz | Which one does it want? |
| 18:12 | Ayey | How does ports differ from packages from apt-get/pacman? |
| 18:12 | Ayey | root |
| 18:12 | Ayey | i guess the other one is /home |
| 18:12 | akyte | Well it's ostensibly a way for you to use make to build all of your packages |
| 18:12 | koz | Yeah, the other one is a home partition. Thanks. |
| 18:12 | akyte | But most use portmaster |
| 18:12 | akyte | Think "patchwork gentoo" |
| 18:13 | Ayey | Huh, intresting.. I should give it a go sometime |
| 18:15 | akyte | Which distros have you ran before? |
| 18:15 | koz | Goddamn it. |
| 18:15 | koz | Same as before. |
| 18:16 | koz | I get the CLI GRUB. |
| 18:17 | Ayey | akyte, Have used arch as my primary for around a year, some ubnuntu/debian before that |
| 18:18 | akyte | Arch is cool, but I prefer gentoo. I like to be able to make all of my architectural choices. |
| 18:19 | Ayey | what do you me? |
| 18:19 | Ayey | mean* |
| 18:21 | koz | OK, thanks guys. Gonna try the Mint irc channel to see if they can help me at all. |
| 18:22 | koz | See ya! |
| 18:27 | dnolen_ | new Om tutorial, Speculative UI Programming - https://github.com/swannodette/om/wiki/Intermediate-Tutorial#wiki-speculative-ui-programming |
| 18:30 | bbloom | dnolen_: awesome. |
| 18:30 | bbloom | dnolen_: so i'm i'm understanding this correctly, you're implemented one speculative state... PER COMPONENT right? |
| 18:31 | bbloom | dnolen_: ie two different comment boxes can do optimistic posts in parallel, yes? |
| 18:31 | dnolen_ | bbloom: yes they could, however how to reconcile those is something that needs thinking |
| 18:32 | dnolen_ | bbloom: this is why om-sync can write the operation into a channel |
| 18:32 | dnolen_ | instead of actually doing it |
| 18:32 | dnolen_ | 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:36 | bbloom | pretty 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:36 | clojurebot | Huh? |
| 18:38 | dnolen_ | bbloom: yes, works great for isolated sub trees - people will need to do some experimenting to figure out the hard |
| 18:38 | dnolen_ | bbloom: but at least they can now :) |
| 18:38 | dnolen_ | s/hard/hard stuff |
| 18:39 | r0b1 | systemfault: yeah compiling can take time but there is prebuilt packages for most of the bigger packages (like X11). |
| 18:40 | systemfault | Right |
| 18:40 | bbloom | dnolen_: cool stuff |
| 18:40 | bbloom | good work |
| 18:40 | dnolen_ | bbloom: thanks |
| 18:50 | qbg | Om is omsome! |
| 19:20 | echosa | Hey, 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:22 | sjl | echosa: http://sjl.bitbucket.org/clojure-lanterna/ is what I made/use |
| 19:22 | sjl | depends on what exactly you need though |
| 19:22 | sjl | it might be overkill for you |
| 19:23 | echosa | You 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:23 | sjl | echosa: I made the clojure wrapper around lanterna |
| 19:23 | sjl | and wrote the docs |
| 19:23 | echosa | ah, cool |
| 19:23 | echosa | yeah, I tried out lanterna as well as jline |
| 19:23 | sjl | I 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:24 | clojurebot | Cool story bro. |
| 19:24 | echosa | jline seemed... old and dated. |
| 19:25 | echosa | I'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:25 | sjl | it's a deeper rabbit hole than you might think |
| 19:25 | sjl | if you want to dive in http://www.linusakesson.net/programming/tty/ |
| 19:26 | echosa | Oh wow, you have to go all the way to the TTY level? There's not higher level abstractions built in already? |
| 19:26 | sjl | (specifically about raw/cooked input in a terminal) |
| 19:27 | sjl | lanterna *is* the abstraction |
| 19:27 | sjl | it puts the terminal in raw mode and handles the fiddly bits of writing/reading in that mode |
| 19:27 | sjl | you could certainly make a lighter-weight version that did less |
| 19:28 | echosa | Right, but I'm saying without a third party plugin/dependency, there's nothing built into clojure itself. |
| 19:28 | echosa | I'll play with lanterna a bit more before I toss it out. |
| 19:29 | qbg | The Java Class Libraries don't expose a way to get raw input IIRC |
| 19:29 | qbg | At least nothing nice |
| 19:29 | echosa | Fair enough. |
| 19:30 | qbg | (non JNI or the like that is) |
| 19:31 | echosa | Speaking 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:31 | echosa | Is that bad(™)? |
| 19:31 | qbg | java.io.Console.readPassword is about as special as you get |
| 19:33 | hyPiRion | echosa: that's not bad. I seldom use java unless it's necessary |
| 19:33 | AimHere | echosa, no. It's good. |
| 19:33 | hyPiRion | unless when it is necesssary, rather. |
| 19:33 | sjl | echosa: if you're not specifically interop'ing with Java, no, it's not bad. be thankful you don't have to. |
| 19:33 | echosa | I'm glad I'm not alone, then. |
| 19:33 | AimHere | The javaisms are just warts you have to use in order to Get Stuff Done |
| 19:33 | r0b1 | love me some java |
| 19:34 | AimHere | When you don't have to Get Stuff Done, you don't need to pretend to use Java! |
| 19:34 | qbg | Just bury them with a shov--uh, function and get on with it |
| 19:34 | echosa | yeah, 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:35 | qbg | Doesn't lein run do some socket or i/o redirection fun? |
| 19:35 | echosa | I'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:36 | sjl | echosa: are you pressing a key? |
| 19:36 | sjl | oh wait, there's a typo in the hello world because I'm an idiot |
| 19:36 | sjl | the first s/stop should be s/start |
| 19:36 | echosa | yes, and FWIW, I have print statements before the lanterna "hello world" code that I would expect to be executed first. |
| 19:36 | echosa | ah |
| 19:36 | echosa | I wondered about that |
| 19:37 | echosa | I figured the first "stop" was more a "reset" |
| 19:37 | echosa | especially since it deals with TTY |
| 19:37 | sjl | nah, it should be start |
| 19:37 | sjl | oh yeah this example is totally hosed |
| 19:37 | sjl | hang on |
| 19:38 | echosa | Ok, 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:38 | echosa | sjl: ok, thanks. |
| 19:38 | sjl | echosa: https://gist.github.com/sjl/9027448 |
| 19:39 | sjl | screens are buffered, so you have to tell it to redraw to make the text actually appear |
| 19:40 | sjl | echosa: 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:40 | sjl | e.g.: windows |
| 19:40 | sjl | if you say (s/get-screen :text) instead of just get-screen it will force it to try to actually stay in the shell |
| 19:41 | sjl | (also the swing terminal is great when you're developing, because you can have the REPL running and the output terminal be separate |
| 19:42 | sjl | basically 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:42 | echosa | ah, 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:42 | sjl | I promise they docs aren't too horrifying |
| 19:42 | sjl | yeah, the idea of lanterna is that it takes over your screen, and you write to it as if it were a canvas |
| 19:43 | sjl | it's great for making e.g. roguelikes, or a text editor or something |
| 19:43 | sjl | it may be overkill for what you need |
| 19:43 | echosa | I'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:43 | echosa | Well, I'm trying to remake the BSD version of the game "greed". |
| 19:44 | echosa | which uses hjklyubn movement keys |
| 19:44 | akurilin2 | Weird 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:44 | akurilin2 | When I open up the namespace in a repl, it finds clojure.set just fine |
| 19:44 | akurilin2 | Never seen anything like this before |
| 19:47 | sjl | echosa: oh yeah, that's pretty much exactly what lanterna is designed for |
| 19:48 | sjl | echosa: 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:48 | sjl | instead of redrawing the entire screen |
| 19:48 | echosa | yeah, 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:49 | echosa | and I had display working with print, just not keymapping |
| 19:49 | echosa | so I"ll just convert my normal prints to lanterna calls and add the key presses and see what happens |
| 19:49 | sjl | yeah, testing is tricky with lanterna. there's not a really good way to scrape the screen with it |
| 19:50 | echosa | I won't test front end stuff, at least not with clojure.test |
| 19:50 | sjl | might be worth looking at then |
| 19:50 | echosa | I might add some BDD or spec style tests to test user input, but for now the backend unit tests are more than enough |
| 19:51 | qbg | akurilin2: Which namespace are you openning up in the REPL? The namespace with the tests? |
| 19:54 | effy | if 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:56 | akurilin2 | qbg: yes |
| 19:59 | qbg | effy: http://java.ociweb.com/mark/stm/article.html |
| 20:00 | qbg | To 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:01 | qbg | akurilin2: Do the test succeed if you run the tests from the REPL? |
| 20:04 | akurilin2 | qbg: something seems to be off about my environment atm, not sure what's going on, brb |
| 20:04 | effy | qbg: this article seems really interesting, thanks |
| 20:10 | akurilin | So yeah when I run "lein test" now I get Caused by: java.io.IOException: error=7, Argument list too long |
| 20:10 | akurilin | No idea what I did to cause that |
| 20:11 | qbg | Any stack trace? |
| 20:13 | akurilin | qbg: oh nvm. I use lein's checkouts and I think I caused a wonderful circular reference of symlinks in there |
| 20:17 | aphyr | effy: if I recall, either atoms or the STM is actually missing stochastic backoff. |
| 20:18 | echosa | sjl: 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:19 | aphyr | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Atom.java#L33-L45 yeah, there really should be a sleep there |
| 20:22 | hyPiRion | aphyr: or a Thread.yield() ? |
| 20:23 | qbg | stochastic backoff likely isn't good enough |
| 20:25 | effy | aphyr: 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:28 | qbg | If 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:33 | echosa | probably 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:34 | qbg | You can use set! with vars |
| 20:34 | qbg | locals are immutable otherwise |
| 20:34 | hyPiRion | echosa: not in general. You'd have to use atoms for such things |
| 20:34 | qbg | Though there is this: https://github.com/ztellman/proteus |
| 20:35 | aphyr | echosa: typically you want a.) a second let binding or b.) proteus |
| 20:35 | aphyr | Let bindings being the fastest option for limited mutation. |
| 20:35 | aphyr | If you're doing something iteratively, (loop [x 2 y 3] ... (recur (inc x) (inc y))) is best |
| 20:37 | hyPiRion | hrmm, proteus |
| 20:37 | hyPiRion | https://twitter.com/danielwithmusic/status/426133408498995201 |
| 20:39 | qbg | Functional programmers hate this! |
| 20:40 | echosa | Hm. Will recur work with mapcat? |
| 20:40 | echosa | not sure how it would |
| 20:40 | qbg | what do you mean 'with'? |
| 20:40 | echosa | you can (recur) inside a (loop) so recur works with loop |
| 20:40 | echosa | ^ s/loop/mapcat/ |
| 20:40 | echosa | ? |
| 20:41 | qbg | Are you talking about using recur in the function passed to mapcat |
| 20:41 | qbg | without tha function having the loop in it? |
| 20:41 | qbg | *that |
| 20:41 | qbg | because that won't work |
| 20:41 | echosa | oh, 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:42 | echosa | hm |
| 20:42 | qbg | do you really need to bang on those locals? |
| 20:43 | echosa | I 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:43 | qbg | What 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:44 | qbg | are you using the mapcats for side effects only? |
| 20:46 | echosa | let me gist what I've got |
| 20:46 | echosa | that'll be easier |
| 20:50 | echosa | Here's what I'm working with with comments explaining what's going on: https://gist.github.com/echosa/9028090 |
| 20:51 | qbg | Why not use doseq instead? |
| 20:52 | qbg | for the x/y values, and then look up corresponding value in the grid from that |
| 20:52 | echosa | Bear in mind, I'm using this project to learn clojure. I didn't know about doseq. |
| 20:52 | benkay | how 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:52 | echosa | corresponding value in the grid? not sure what you mean... like using (.indexOf)? |
| 20:52 | qbg | nth |
| 20:53 | echosa | oh, right |
| 20:53 | echosa | duh |
| 20:53 | qbg | ,(get-in [[1 2 3] [4 5 6] [7 8 9]] [1 1]) |
| 20:53 | clojurebot | 5 |
| 20:53 | echosa | well, let me go look at doseq |
| 20:53 | qbg | or that |
| 20:53 | echosa | oh wow... (get-in)... that's handy as all hell |
| 20:54 | Cr8 | And then there's update-in |
| 20:54 | qbg | and assoc-in |
| 20:54 | Cr8 | ,(update-in [[1 0] [0 1]] [0 1] inc) |
| 20:54 | clojurebot | [[1 1] [0 1]] |
| 20:54 | aphyr | but somehow, no update |
| 20:54 | echosa | ... |
| 20:55 | echosa | you've got to be kidding me |
| 20:55 | qbg | aphyr: In what way would update make sense? |
| 20:55 | Cr8 | qbg: (update {:a 1} :a inc) => {:a 2} |
| 20:55 | qbg | ,(update-in {:a 1} [:a] inc) |
| 20:55 | Cr8 | is to update-in as assoc as assoc-in |
| 20:55 | clojurebot | {:a 2} |
| 20:55 | echosa | update-in exists and here I went and wrote (and unit tested) this: https://gist.github.com/echosa/9028135 |
| 20:55 | qbg | not god enough? :) |
| 20:56 | Cr8 | qbg: sure, but assoc-in and get-in have assoc and get, respectively |
| 20:56 | qbg | fair enough |
| 20:56 | echosa | I think I can completely replace that function with (update-in) |
| 20:56 | qbg | ,(assoc [1 2 3 4] 1 10) |
| 20:56 | clojurebot | [1 10 3 4] |
| 20:56 | qbg | echosa: You'd want to use that for updating a vector |
| 20:57 | echosa | use what? my function or update-in? |
| 20:57 | qbg | assoc for a single vector |
| 20:57 | echosa | because that's what my fuctnion does |
| 20:57 | Cr8 | confusingly, synthread calls what we'd call "update" by this convention "assoc" =P |
| 20:57 | Cr8 | or really, ->/assoc if you use the recommended ns alias |
| 20:57 | Cr8 | https://github.com/LonoCloud/synthread |
| 20:57 | qbg | rather than all of those subvec and into calls |
| 20:59 | echosa | I 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:59 | echosa | but, from what I've seen, (update-in) will handle this for me |
| 21:00 | qbg | I'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:00 | echosa | ,(update-in [[1 2 3][4 5 6][7 8 9]] [1 1] (fn [x] 0)) |
| 21:00 | clojurebot | [[1 2 3] [4 0 6] [7 8 9]] |
| 21:00 | echosa | Yep. update-in does exactly what I need for that second gist I posted. |
| 21:00 | qbg | ,(assoc-in [[1 2 3][4 5 6][7 8 9]] [1 1] 0) |
| 21:00 | clojurebot | [[1 2 3] [4 0 6] [7 8 9]] |
| 21:01 | echosa | So much wasted work. Well, not wasted, but I learned a lot about testing and clojure... |
| 21:01 | echosa | Ah, Even better. |
| 21:01 | qbg | I'd recommend skimming through http://clojuredocs.org/quickref/Clojure%20Core if you haven't yet |
| 21:01 | echosa | I have. I've even done the clojure-koans thing, though a lot of that info just didn't stick. |
| 21:02 | qbg | no problem |
| 21:02 | echosa | language familiarity will come with time |
| 21:02 | echosa | (hopefully) |
| 21:03 | echosa | Still need to work out my mapcat -> doseq business, though. |
| 21:03 | echosa | Hooray for learning. |
| 21:03 | qbg | doseq is the side effect version of for |
| 21:04 | echosa | hm |
| 21:04 | qbg | ,(for [y (range 3) x (range 3)] [x y]) |
| 21:04 | clojurebot | ([0 0] [1 0] [2 0] [0 1] [1 1] ...) |
| 21:07 | bob2 | is there an elegant way to go from [{:foo A :x somethingelse} {:foo B :z blah}] -> {A {:x somethingelse} B {:z blah}} ? |
| 21:08 | echosa | ,(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:08 | clojurebot | (147nil nil 258nil nil nil 369...) |
| 21:08 | echosa | ,(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:08 | clojurebot | (123nil nil 456nil nil nil 789...) |
| 21:08 | echosa | what's with the nils? |
| 21:08 | qbg | print returns nil |
| 21:09 | echosa | oh right |
| 21:09 | qbg | you want to use doseq instead of for |
| 21:09 | echosa | I'm getting return val here, not output |
| 21:09 | qbg | for produces a lazy seq, so that is why you see the intermixing |
| 21:09 | echosa | same syntax as for? |
| 21:09 | qbg | ,(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:09 | clojurebot | 123456789 |
| 21:09 | qbg | yep |
| 21:09 | echosa | ,(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:09 | clojurebot | 123456789 |
| 21:09 | echosa | win |
| 21:10 | qbg | ,(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:10 | clojurebot | 147258369 |
| 21:10 | qbg | ,(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:10 | clojurebot | 123456789 |
| 21:11 | qbg | ,(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:11 | clojurebot | 123456789 |
| 21:11 | qbg | ^ That might be the one you want |
| 21:12 | echosa | (get-in)... right. |
| 21:12 | echosa | I have so much to memorize. |
| 21:12 | qbg | you get to dramatically shrink your line count though :) |
| 21:12 | echosa | I'm very much looking forward to that. |
| 21:13 | echosa | In for familiar lisps I'm used to being clever to reduce code amount. |
| 21:13 | echosa | Clojure is a whole new beast. |
| 21:13 | qbg | Now don't just use cl-format because you have it :p |
| 21:13 | benkay | how would i determine what brand of jvm a given leiningen install put on my system? |
| 21:14 | benkay | i just spun up a vm for some processing - would it be the same as the output of `which java`? |
| 21:14 | qbg | `java -version` might be of interest |
| 21:15 | benkay | mhm. |
| 21:15 | echosa | IT LIVES... er, WORKS! Jesus... 4 hours yesterday, give or take, improved drastically by a couple hours on IRC |
| 21:15 | bob2 | 'lein version'? |
| 21:18 | benkay | thanks bob2, qbg. |
| 21:18 | benkay | har, now do either of you know anything about making the jvm as big as possible on a given host? |
| 21:18 | qbg | -Xmx to increase the maximum heap size |
| 21:19 | qbg | IIRC, there is a place in your project.clj where you can place those jvm arguments |
| 21:19 | bob2 | java-opts |
| 21:19 | qbg | Are you running out of memory benkay? |
| 21:19 | bob2 | at some point you've made the heap too big, though |
| 21:19 | benkay | yeah i'm familiar with java opts, just not en-honk-ifying a jvm |
| 21:20 | qbg | are you having perf issues? |
| 21:20 | benkay | nah, big job |
| 21:20 | bob2 | you can't just set it to a high random value |
| 21:20 | benkay | scripted it up in clojure for the heckofit |
| 21:20 | benkay | pmap being a useful thing in the context |
| 21:20 | bob2 | gc pauses are a real thing |
| 21:20 | qbg | how big of a heap are you going to want? |
| 21:21 | benkay | heap 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:22 | bob2 | that just happens, without configuration |
| 21:22 | qbg | how much work does the function you pass to pmap do? |
| 21:22 | benkay | squeeeee clojure |
| 21:22 | benkay | none |
| 21:22 | qbg | if it isn't enough, the overhead is going to kill the gains |
| 21:22 | benkay | it's like "try to s3 cp this object from bukkit a to bukkit b" |
| 21:22 | benkay | there's just a mess of things to get copied and there's no reason to do it serially. |
| 21:23 | Cr8 | benkay: used reducers yet? |
| 21:23 | Cr8 | wouldn't be appropriate in this case |
| 21:23 | benkay | ah only to do dumb dumb stuff like ,(reduce [1 2 3]) |
| 21:23 | Cr8 | but they are a neat thing |
| 21:23 | qbg | benkay: you're code is I/O bound rather than CPU bound? |
| 21:23 | benkay | ah only to do dumb dumb stuff like ,(reduce + [1 2 3]) |
| 21:23 | benkay | yeah, very much io bound |
| 21:23 | Cr8 | benkay: clojure.core.reducers I mean |
| 21:23 | bob2 | if you want to do it fast, you'd want async network io, not more cpus or threads |
| 21:23 | qbg | pmap probably isn't what you want then |
| 21:24 | qbg | (inc bob2) |
| 21:24 | lazybot | ⇒ 1 |
| 21:25 | benkay | thing is that i'm working with weavejester's s3 library and this bit of code is a one-off |
| 21:25 | benkay | (famous words before one-off script becomes central to biz processes) |
| 21:26 | Cr8 | (my current weekend is fixing up some "one-off" scripts I wrote last week so that they can become productionized) |
| 21:26 | Cr8 | luckily they're currently -so- "one-off" that they only run on my machine |
| 21:27 | benkay | if 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:28 | qbg | what is roughly the upper limit on the size of the sequence you're sending to pmap currently? |
| 21:29 | aphyr | yeah, suggest not using pmap for any more than, say, 1000 items. |
| 21:29 | benkay | interesting |
| 21:29 | aphyr | JVM doesn't deal so well with infinite threads. |
| 21:29 | benkay | i figured something like that'd be the case, so i wrote it to perform things batch-ed-ly |
| 21:29 | qbg | aphyr: pmap doesn't send everything to its own thread |
| 21:30 | qbg | the number of computations in flight is limited |
| 21:30 | benkay | what are the constraints on length of lists over which to pmap? |
| 21:30 | bob2 | depends on what your function does |
| 21:31 | benkay | it's a mystery! |
| 21:31 | benkay | jokes aside as i dig through the s3 client source what should i be aware of |
| 21:32 | aphyr | Oh shit, pmap changed! |
| 21:32 | aphyr | Didn't realize. |
| 21:32 | qbg | http://stackoverflow.com/questions/5021788/how-many-threads-does-clojures-pmap-function-spawn-for-url-fetching-operations |
| 21:35 | bob2 | ugh threads for url fetching |
| 21:35 | benkay | hey 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:36 | qbg | I think it is a bit more than 20 :p |
| 21:36 | benkay | well 20 years ago we had symbolics machines iirc |
| 21:37 | benkay | jokes its 2014 |
| 21:37 | benkay | so 29 years |
| 21:37 | qbg | Why not go all the way back to the IBM 704? |
| 21:38 | benkay | did it run lisp? |
| 21:38 | bob2 | yes |
| 21:38 | bob2 | in like 61 |
| 21:38 | benkay | well then sure :) |
| 21:38 | bob2 | for your thing, pmap is probably fine as a balance between effort and performance |
| 21:39 | benkay | 's what i thought too. glad to have someone with experience (assumption!) confirm. |
| 21:39 | echosa | Who needs the Turing test. It's all about the Lisp test: does it run lisp? :) |
| 21:39 | bob2 | for 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:39 | bob2 | disclaimer, I have only a little clojure experience |
| 21:40 | benkay | bob2: i think i'm actually going to go down the nio rabbit hole next time i come around to this problem |
| 21:40 | bob2 | oh, aleph is apparently a thing to loko at |
| 21:40 | benkay | which is particularly amusing because i have zero java experience beyond the interop that's been forced on my from time to time |
| 21:40 | benkay | i'm aware of aleph yeah |
| 21:40 | benkay | what do you think of: https://github.com/pjstadig/nio |
| 21:41 | bob2 | really I just want Twisted for clojure |
| 21:41 | bob2 | nio looks very far below the 'do lots of http requests' level you were talking about earlier |
| 21:42 | benkay | ah well you see the next networky thing i have on my plate is lots of binary over tcp |
| 21:43 | bob2 | aleph apparently does tcp stuff too |
| 21:46 | benkay | hm yeah |
| 21:46 | quizdr | are circular references a problem in clojure as they are in some languages? can I have 2 source files that each refer each other? |
| 21:46 | qbg | that is going to be difficult |
| 21:47 | benkay | but all this framework of expectations and data flow is a bit much cognitive overhead for my tastes. |
| 21:47 | qbg | See if you can clean up your design |
| 21:52 | beamso | quizdr: while i've never experienced that i believe it can be a problem |
| 21:52 | qbg | Clojure effectively enforces good design here |
| 22:05 | quizdr | ,(println (str (take 3 "abcdef"))) |
| 22:05 | clojurebot | clojure.lang.LazySeq@1ecc1\n |
| 22:05 | quizdr | shouldn't println force the output of above? |
| 22:06 | beamso | ,(apply str (take 3 "abcdef")) |
| 22:06 | clojurebot | "abc" |
| 22:06 | quizdr | gotcha |
| 22:07 | beamso | the docs for str don't say that it returns a lazy sequence :/ |
| 22:07 | qbg | take returns a lazy seq |
| 22:07 | qbg | and you're turning that lazy seq into a string with str |
| 22:08 | qbg | (in your original code) |
| 22:08 | beamso | yeah |
| 22:08 | beamso | the take returns a lazy seq |
| 22:08 | beamso | the str' With more than |
| 22:08 | beamso | one arg, returns the concatenation of the str values of the args.' |
| 22:17 | qbg | println also uses a different code path than str |
| 22:19 | amalloy | qbg: println just calls str |
| 22:20 | t0m` | hi |
| 22:20 | qbg | there is a bit more magic though than that |
| 22:20 | t0m` | hey i'm dealing with deeply nested maps, is there something like xpath but for nested maps? |
| 22:21 | qbg | amalloy: println can handle unbounded output |
| 22:22 | amalloy | what does "unbounded output" even mean? |
| 22:22 | qbg | infinite seq for example |
| 22:23 | amalloy | &(println (range)) |
| 22:23 | lazybot | java.lang.OutOfMemoryError: Java heap space |
| 22:23 | amalloy | that's not handling it super-impressively |
| 22:23 | qbg | lazybot has to capture the output |
| 22:24 | qbg | if you're writing to the console, then everything is fine |
| 22:24 | amalloy | i 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:24 | amalloy | at any rate, i was definitely wrong that println just calls str |
| 22:25 | qbg | println doesn't also need to generate an entire string before printing |
| 22:27 | ambrosebs | bbloom: I haven't been able to get if-pred out of my head all morning |
| 22:28 | ambrosebs | bbloom: really helped pinpoint the problems with if-let |
| 22:31 | bbloom | ambrosebs: you're the types guy, you should have been all over that one :-) |
| 22:33 | ambrosebs | bbloom: I have much to learn |
| 22:35 | bbloom | ambrosebs: 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:36 | amalloy | bbloom: if-pred? |
| 22:36 | bbloom | amalloy: long story. discussion about if-some, see logs |
| 22:39 | ambrosebs | bbloom: 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:39 | ambrosebs | http://www.cs.cmu.edu/afs/cs/user/rowan/www/src/red-black.sml |
| 22:40 | ambrosebs | the equivalent types in cor.etyped https://github.com/clojure/core.typed/blob/master/src/test/clojure/clojure/core/typed/test/rbt_types.clj |
| 22:40 | bbloom | ambrosebs: so is "refinement types" the magic phrase for this sort of thing in the literature? |
| 22:41 | bbloom | ambrosebs: and how does that relate to "occurrence typing" ? |
| 22:42 | ambrosebs | bbloom: often when general unions and intersections are discussed in the context of ML-like type systems, it's related to refinement types |
| 22:45 | killerswan | so, do any of you have tips on parsing XML from within ClojureScript? |
| 22:45 | ambrosebs | bbloom: 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:45 | ambrosebs | bbloom: if you're from CMU, it's "type refinements" |
| 22:45 | ambrosebs | bbloom: and a "refinement type" checker :) |
| 22:46 | ambrosebs | my honours supervisor wrote CIDRE for his phd http://www.cs.cmu.edu/~rwh/theses/davies.pdf |
| 22:47 | bbloom | and if you're the racket people (is that northeastern or something?) then it's occurrence typing? |
| 22:48 | dnolen_ | killerswan: use an existing JS XML lib? |
| 22:48 | ambrosebs | bbloom: hmm |
| 22:49 | bbloom | ambrosebs: or utah? i don't know anything about CS graduate programs :-P |
| 22:49 | ambrosebs | bbloom: occurrence typing is an approach to eliminating union types are programs progress |
| 22:49 | bbloom | ok so they are different? i guess i'll need to study them at some point |
| 22:49 | killerswan | dnolen_: 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:49 | killerswan | s/jay/jayq/ |
| 22:49 | ambrosebs | bbloom: essentially occurrence typing eliminates unions as it gets further into the program |
| 22:50 | ambrosebs | bbloom: 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:50 | ambrosebs | bbloom: so two approaches to a similar goal |
| 22:51 | dnolen_ | killerswan: http://docs.closure-library.googlecode.com/git/closure_goog_dom_xml.js.html |
| 22:51 | bbloom | ambrosebs: hm ok, i'll dig in to it all eventually |
| 22:56 | killerswan | dnolen_: OK, thanks |
| 23:45 | TravisD | in case forms, is it standard to use "true" as the catch-all case? Or is there some syntactic sugar for that? |
| 23:46 | qbg_ | case, or cond? |
| 23:46 | qbg_ | :else seems to be idiomatic for cond |
| 23:46 | TravisD | oh, sorry, cond |
| 23:47 | TravisD | :else is considered true in cond? |
| 23:47 | mischov | I believe catchall for case is a last statement without a condition. |
| 23:47 | mischov | :else for cond |
| 23:47 | bbloom | TravisD: it's just an idiom, any logically true value would suffice |
| 23:47 | bbloom | ,(cond :false "omg") |
| 23:47 | bbloom | &(cond :false "omg") |
| 23:47 | lazybot | ⇒ "omg" |
| 23:47 | bbloom | damn bots :-P |
| 23:48 | TravisD | Hehe, is there a simple characterization of logically true values? |
| 23:48 | clojurebot | "omg" |
| 23:48 | bbloom | TravisD: false and nil are the *only* logically false values. everything else is true |
| 23:48 | TravisD | oh, alright :) |