2014-06-27
| 00:00 | dbasch | if anything, the point of fnil is to recover from null pointers and avoid a null pointer exception |
| 00:00 | boltR | ah I see |
| 00:01 | boltR | I was trying to create an anonymous function for passing to update-in |
| 00:02 | boltR | I think I can just use an if-else |
| 00:02 | dbasch | you want to throw an exception in the middle of an update? |
| 00:02 | boltR | yeah if a key doesn't already exist in the hashmap |
| 00:05 | dbasch | boltR: update-in will create them if they don't, so you'd have to check |
| 00:07 | dbasch | e.g. |
| 00:07 | dbasch | ,(update-in {:a {:b 1}} [:a :c] str) |
| 00:07 | clojurebot | {:a {:c "", :b 1}} |
| 00:14 | boltR | dbasch: ah I see |
| 00:14 | boltR | so I need to check the hash before the update-in call |
| 00:19 | trptcolin | ,(update-in {:a {:b 1}} [:a :b] #(if % (inc %) (throw (Exception. "this is bad code")))) |
| 00:19 | clojurebot | {:a {:b 2}} |
| 00:19 | trptcolin | ,(update-in {:a {:b 1}} [:a :c] #(if % (inc %) (throw (Exception. "this is bad code")))) |
| 00:19 | clojurebot | #<Exception java.lang.Exception: this is bad code> |
| 00:26 | boltR | trptcolin: why is that considered bad code? |
| 00:29 | trptcolin | don’t mind me, i’ve been watching monad videos |
| 00:30 | trptcolin | it works, just not a use case where i’d typically reach for exceptions |
| 00:33 | boltR | trptcolin: i just realized i'm not supposed to put the exception in the update-in line |
| 00:33 | boltR | haha |
| 00:33 | boltR | oh well.. still good to know |
| 00:41 | ndp | Hey all, what's the right way to compare keywords in ClojureScript? |
| 00:41 | ndp | Right now I'm using keyword-identical? but it's not working when getting a value from a map to compare against. |
| 00:43 | ndp | Ah, never mind - I found the problem as I was copying here. I had an extra ":" floating around. |
| 00:52 | ttasterisco | ,(= :k1 :k2) |
| 00:52 | clojurebot | false |
| 00:52 | ttasterisco | ,(let [x :k1] (= :k1 x)) |
| 00:52 | clojurebot | true |
| 00:53 | ttasterisco | ,(doc keyword-identical?) |
| 00:53 | clojurebot | It's greek to me. |
| 00:55 | john2x | how do I upgrade my leiningen? I tried `lein upgrade`, but it seems it's intended for projects? |
| 00:56 | trptcolin | `lein upgrade` should work for the normal case. perhaps you have lein installed via a package manager? |
| 00:56 | trptcolin | what is the problem you’re seeing? |
| 00:57 | john2x | sorry, got disconnected. trptcolin, you mean me? |
| 00:57 | ttasterisco | yes |
| 00:58 | john2x | "Couldn't find project.clj, which is needed for upgrade" |
| 00:58 | ttasterisco | huh |
| 00:58 | john2x | It does update a bunch of libraries in my .lein/profiles.clj though |
| 00:58 | john2x | but I want to update to lein 2.4.x (currently on 2.3.4) |
| 00:59 | ttasterisco | I just updated my lein with lein upgrade |
| 00:59 | ttasterisco | Leiningen 2.4.2 on Java 1.8.0_05 Java HotSpot(TM) 64-Bit Server VM |
| 01:00 | john2x | strange.. i installed this via homebrew.. but on brew it's still at 2.3.4.. and I don't want to use HEAD |
| 01:00 | john2x | I guess I should re-install from the github downloads? |
| 01:00 | ttasterisco | https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein |
| 01:02 | trptcolin | john2x: yeah `lein upgrade` doesn’t work for package managers unless they go in and tweak the script (which nobody does, i don’t think): https://github.com/technomancy/leiningen/issues/1377 |
| 01:03 | john2x | thanks. oh and it seems it's at 2.4.2 in homebrew now.. guess I'll just keep on brewin' |
| 01:05 | ddellacosta | john2x: not sure but I think most folks avoid leiningen via homebrew. YMMV |
| 01:06 | john2x | hmm yeah.. probably would cause more hard-to-diagnose issues someday. |
| 01:23 | Raynes | john2x: It's just that leiningen is just a shell script and a jar file. |
| 01:23 | Raynes | So using a package manager feels strange :P |
| 02:58 | Klaufir | how can I generate a vec using a function ? |
| 02:58 | Klaufir | I have tried |
| 02:58 | Klaufir | (reduce #(cons (rand 1) %1) [] (range 10)) |
| 02:59 | Klaufir | but this is problematic because #(...) here takes only 1 argument |
| 03:09 | AimHere | Klaufir, what do you mean by 'generate a vec using a function'? |
| 03:11 | AimHere | ,((fn [] (vec (range 10)))) |
| 03:11 | clojurebot | [0 1 2 3 4 ...] |
| 03:11 | Klaufir | AimHere: call a function n times, then put the n results into a vec |
| 03:11 | AimHere | Oh, well that's outwith the functional idiom |
| 03:12 | Klaufir | AimHere: how would you generate a vec of random numbers? |
| 03:12 | Klaufir | given by the function 'rand'? |
| 03:13 | AimHere | (vec (take 10 (repeatedly rand))) |
| 03:13 | AimHere | ,(vec (take 10 (repeatedly rand))) |
| 03:13 | clojurebot | [0.12962159592537548 0.31180927009168413 0.7594697727309286 0.7412669247226338 0.18135883841833167 ...] |
| 03:13 | AimHere | You should be thinking in terms of laziness and sequences in Clojure, for that sort of thing |
| 03:14 | AimHere | You *could* write a reentrant function using atoms or refs as static variables, but it's unidiomatic |
| 03:16 | Klaufir | AimHere: thanks, this looks great |
| 03:38 | ddellacosta | ,(clojure-version) |
| 03:38 | clojurebot | eval service is offline |
| 03:38 | ddellacosta | damnit |
| 03:38 | ddellacosta | &(clojure-version) |
| 03:38 | lazybot | ⇒ "1.4.0" |
| 03:38 | ddellacosta | &(name :/) |
| 03:38 | lazybot | java.lang.RuntimeException: Invalid token: :/ |
| 03:38 | ddellacosta | &(name :-) |
| 03:38 | lazybot | ⇒ "-" |
| 03:39 | ddellacosta | &(name (keyword "/")) |
| 03:39 | lazybot | ⇒ "/" |
| 03:39 | ddellacosta | &(keyword "/") |
| 03:39 | lazybot | ⇒ :/ |
| 03:39 | blur3d | Hey guys, I’m trying to make a way to visualise data collected in real-time from an Arduino. Basically, data comes in at unpredictable intervals (potentially 100,000 of data points). It could contain anolog inputs (0-1023) or digital inputs (0-1), as well as other data. So basically, I have lots of specific timeseries, and I was wondering hwo I should go about jumping back in time and getting the whole system state. |
| 03:40 | blur3d | I’m fine with creating snapshots of data every second or something if that is required, and then that could be used to slide back in time to a past state |
| 03:40 | blur3d | oh, and I am hoping to do this is clojurescript |
| 03:41 | ddellacosta | blur3d: I guess my first instinct would be to snapshot everything with the timestamp as the hashmap key, perhaps? |
| 03:41 | ddellacosta | blur3d: in an atom |
| 03:42 | ddellacosta | blur3d: depending on how the data looks you could diff the previous state and store that each time, or start with some default state and just store diffs, computing the state at any given point? |
| 03:43 | blur3d | Yeah, I’m just not sure how to keep as much resolution as possible in the data, and the history |
| 03:43 | blur3d | because a value could update 100s of times a second |
| 03:44 | blur3d | but more likely 100Hz would be plenty |
| 03:44 | ddellacosta | blur3d: ah, I see. Are the updates subsets of data, or do you get an entire snapshot? |
| 03:45 | ddellacosta | blur3d: one idea is to use a counter and ignore updates unless you've hit a timeout/passed a threshold |
| 03:45 | blur3d | well, the arduino input would have no real relation to past data for 50% of the time |
| 03:45 | ddellacosta | blur3d: I see, so it's a snapshot of the entire system state? Sorry if I'm not getting it, never used an arduino |
| 03:46 | blur3d | well, the state that matters…. not all the microcontroller inputs/outputs might be being used |
| 03:47 | blur3d | and they could just default to some initial state |
| 03:47 | blur3d | http://icant.co.uk/talks/h5/pictures/smashingconf/shorterjourney.jpg |
| 03:47 | ddellacosta | blur3d: not sure what you mean by that image |
| 03:48 | blur3d | that is kind of the same problem I am trying to solve.. I’m just really new to it and haven’t found many OSS to peer at |
| 03:48 | blur3d | see how the player state is snapshot over time… ie. you can see where he was and where he is going |
| 03:48 | Frozenlock | blur3d: could you describe what you want to accomplish by keeping all these samplings? |
| 03:48 | blur3d | in that case it is just x and y over time |
| 03:49 | blur3d | Basically, lets say I have a temperature sensor I hook up to the arduino |
| 03:49 | ddellacosta | blur3d: well, the choice is simple it seems to me--you either keep an entire snapshot of state at a regular interval, or just updates to an initial state, which you compute on the fly if you need to go back in time |
| 03:49 | blur3d | it will give me back a temperature each microcontroller cycle (not at a set interval) |
| 03:50 | blur3d | I want to read those values into a clojurescript app in real time and display visualisations on the current state |
| 03:50 | blur3d | (obviously temperature is not important enough to read at 100Hz, but think of motors and such) |
| 03:51 | Frozenlock | Even with motors, I don't really see why 100hz... I mean, the human eye can't see that :-p |
| 03:51 | ddellacosta | blur3d: I mean, there are a ton of variables in here that you will need to fine-tune, but the heuristic seems pretty simple |
| 03:51 | blur3d | no, but it would change the speed and therefore effect distance travelled etc |
| 03:52 | ddellacosta | blur3d: obviously if you need to get something that is going to fool the eye, as Frozenlock says, it has to be fast enough--but doesn't need to be past 16 frames a second or something |
| 03:52 | ddellacosta | whatever that is. 24? I forget |
| 03:52 | Frozenlock | 60 for a good FPS :-p |
| 03:52 | Frozenlock | (first person shooter) |
| 03:53 | ddellacosta | blur3d: right; but that's why you take a snapshot at a regular interval regardless, and you make sure you can either compute the entire system's state, or it is all stored for that snapshot |
| 03:53 | blur3d | sure, I might use moving averages for the visualisations |
| 03:53 | blur3d | but I was keen to somehow also keep mass data for playback/simulation later |
| 03:53 | blur3d | yeah, ok.. I’ll give it a go |
| 03:53 | blur3d | ddellacosta Frozenlock thanks |
| 03:53 | Frozenlock | blur3d: I'd store a snapshot of all the values every MCU cycle |
| 03:54 | ddellacosta | blur3d: I mean, I guess there is a tricky bit where you get something inside the threshold, if you are listening vs. polling |
| 03:56 | Frozenlock | (assuming you don't run it for an hour) |
| 03:56 | blur3d | yeah, I would just have to accept it may be lossy |
| 03:56 | ddellacosta | blur3d: yeah, but (say if it was an animation output) as long as you fooled the human eye it doesn't matter if the update came in at T150ms and you played it back at T155ms or whatever |
| 03:56 | ddellacosta | blur3d: anyways, good luck, hope this helped at least to think through it |
| 03:56 | blur3d | yeah, I have a better idea now… Thanks again |
| 03:56 | Frozenlock | I remember programming MCUs in C... without a repl... |
| 03:56 | Frozenlock | Terrible, terrible times. |
| 03:58 | ddellacosta | haha |
| 03:58 | blur3d | The Arduino IDE doesn’t have a repl yet, haha |
| 03:59 | ddellacosta | yeah, I vaguely remember doing a bit of that sort of thing, writing stuff into a terrible proprietary editor and then pushing it to the microcontroller |
| 03:59 | ddellacosta | I guess Arduino is better than that |
| 04:02 | blur3d | This is the general idea of what I am working on http://vimeo.com/97903574 (15 min video). Basically a real-time dashboard for what exactly the arduino is doing |
| 04:04 | Frozenlock | "You sit at your desk and look at this tiny rectangle" Pfff, my rectangle isn't tiny |
| 04:16 | blur3d | haha, he may of.. but he’s been doing similar stuff for a few years now |
| 04:18 | blur3d | I’ll take a look… it sounds nice |
| 04:18 | blur3d | and it seems fairly popular - I’ve never head of it |
| 04:18 | Frozenlock | If you do use crossfilter, you should really take a snapshot of all the values everytime. |
| 04:20 | blur3d | ok, well any value updates come in one at a time. I’ll work on getting the foundation setup, and then I’ll look at how much data I actually need/want |
| 04:21 | blur3d | the difficulty is that I was hoping to let the users send data whenever they feel necessary… and that could be very often |
| 04:21 | blur3d | but it may also be once a minute, or 10 minutes |
| 05:22 | blah | Why does my page display only Test2 in the following code ? http://bpaste.net/show/C6qQOHrUAwdHWgQbKS0J/ |
| 05:22 | blah | This is attempting to use om |
| 05:38 | Slotkenov | What might I be doing wrong when in the repl "(cemerick.austin.repls/browser-connected-repl-js)" works fine, but "(require [cemerick.austin.repls :refer [browser-connected-repl-js]])" returns the error "CompilerException java.lang.ClassNotFoundException: cemerick.austin.repls, compiling:(/tmp/form-init4786187161975553725.clj:1:1)"? |
| 05:48 | Slotkenov | I forgot to quote in the require statement :) |
| 05:54 | jonathanj | how do i concisely write: if (f.foo() && f.bar()) { X } else { Y } in clojure? |
| 06:02 | Slotkenov | @jonathanj (if (and (foo) (bar)) X Y) |
| 06:21 | jonathanj | how do i give a typehint of an array of something? eg. Foo[] |
| 06:27 | TEttinger | jonathanj, ah that's a classic thing |
| 06:27 | TEttinger | there's a good post on it... |
| 06:27 | TEttinger | http://www.learningclojure.com/2010/09/macros-and-type-hints-metadata-and.html |
| 06:28 | clgv | jonathanj: for objects there is "^objects" |
| 06:28 | TEttinger | err, http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html |
| 06:31 | clgv | ,(-> (into-array Long/TYPE (range 3)) class ((juxt identity #(.getCanonicalName %)))) |
| 06:31 | clojurebot | [[J "long[]"] |
| 06:32 | clgv | ,(-> (into-array Long/TYPE (range 3)) class ((juxt #(.getName %) #(.getCanonicalName %)))) |
| 06:32 | clojurebot | ["[J" "long[]"] |
| 06:35 | jonathanj | thanks |
| 06:58 | jonathanj | hrm, so if i do: lein uberjar, i can't run the resulting jar as-is: Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/IFn |
| 06:58 | jonathanj | presumably i need some clojure stuff in my classpath but i'm not sure what or how |
| 07:03 | jonathanj | oh there is a separate standalone jar, my bad |
| 07:21 | ambrosebs | is it possible to extend an Object[] to a protocol? |
| 07:22 | ambrosebs | VerifyError (class: clojure/core/typed/array$eval13206, method: invoke signature: ()Ljava/lang/Object;) Incompatible object argument for function call java.lang.Class.getDeclaredConstructors0 (Class.java:-2) |
| 07:22 | ambrosebs | I seem to get that. |
| 07:22 | ambrosebs | Integer[] seems to work. |
| 07:25 | clgv | ambrosebs: extend-protocol together with (java.lang.Class/forName "[Ljava.lang.Object;") worked |
| 07:25 | ambrosebs | ah, I tried extend-type with (class (object-array [])) |
| 07:26 | ambrosebs | weird that (class (make-array Integer 0)) worked for Integer[] |
| 07:27 | ambrosebs | right, Class/forName still gives me the same error. |
| 07:27 | clgv | ambrosebs: again some core.typed "overload" like "fn" last time? |
| 07:28 | ambrosebs | clgv: most likely, I'll try somewhere else :P |
| 07:29 | clgv | I tried in an almost fresh repl ;) |
| 07:29 | jonathanj | hrm, is there a shorter way of writing (apply #(Foo. %1 %2 %3 %4) [12 34 56 78]) |
| 07:30 | jonathanj | (in reality the args vector comes from splitting a string and is checked for exactly 4 arguments) |
| 07:30 | vmarcinko | hello, just wondering - if I increment some counter contained in plain clojure vector (integer element) a billion times, it will take significant amount of memory for this action since clojure's immutable structures don't upodate anything, but only add new data states in memory, (similar to Git)? |
| 07:31 | ambrosebs | clgv: https://gist.github.com/frenchy64/19e299d0c96524afc5d5 |
| 07:33 | clgv | jonathanj: thats a record or deftype right? than there is (->Foo 12 34 56 78) |
| 07:35 | jonathanj | hmm? |
| 07:36 | jonathanj | it's a com.itext.text.Rectangle in this particular case |
| 07:37 | jonathanj | i ended up using vec destructuring and :as |
| 07:43 | clgv | jonathanj: well than not ;) |
| 07:44 | clgv | jonathanj: in case of deftype and defrecord you get that convenience function |
| 07:47 | ambrosebs | I'm on java7 fwiw. |
| 07:47 | ambrosebs | I'll try clojure 1.6 |
| 07:47 | clgv | ambrosebs: Clojure 1.6 on Java 7 here |
| 07:48 | ambrosebs | eh same error for me |
| 07:48 | ambrosebs | weird! |
| 07:48 | razum2um | vmarcinko: see transient topic |
| 07:48 | razum2um | vmarcinko: http://clojure.org/transients |
| 07:49 | clgv | ambrosebs: https://www.refheap.com/87610 |
| 07:50 | clgv | vmarcinko: transient vector and assoc! should do the trick |
| 07:51 | razum2um | folks, is there any clojure online playgrounds like http://www.tryerlang.org/ ? |
| 07:52 | nathan7 | razum2um: http://tryclj.com/ |
| 07:52 | clgv | razum2um: http://tryclj.com/ |
| 07:52 | clgv | :P |
| 07:55 | razum2um | oh, not correct example, i asked for http://www.jsfiddle.net/ more. you gave link to refheap, but what if i just want to fork&edit code on link above with instant feedback from repl |
| 08:00 | ambrosebs | clgv: huh, does (blubb (object-array 1)) work for you? |
| 08:00 | ambrosebs | into-array works for me |
| 08:00 | razum2um | hm, realized that I thought about lighttable online + collaborative editing like gits |
| 08:01 | razum2um | s/gits/gist/ |
| 08:01 | clgv | ambrosebs: no it does not |
| 08:01 | ambrosebs | I have no idea why |
| 08:03 | ambrosebs | ,(identical? (class (object-array 0)) (class (into-array Object [1 2]))) |
| 08:03 | clojurebot | true |
| 08:03 | petrust | how do I include an unstable clojure dependency that is not on clojars? e.g. reagent 0.4.3 ? |
| 08:04 | vmarcinko | <razum2um>: thanx |
| 08:04 | vmarcinko | razum2um: thanx |
| 08:05 | hyPiRion | petrust: git clone the repo, then perform `lein install` in its root directory |
| 08:07 | clgv | ambrosebs: thats pretty damn weird |
| 08:07 | razum2um | yep, such already exists but doesnt support clj - https://eval.in/ |
| 08:10 | clgv | ambrosebs: ##(let [a1 (object-array [1 2]), a2 (into-array Object [1 2])] (println (identical? (class a1) (class a2)) (java.util.Arrays/equals a1 a2))) |
| 08:10 | lazybot | ⇒ true true nil |
| 08:11 | michaelr525 | hello |
| 08:14 | ambrosebs | clgv: looks like into-array is created with reflection and object-array is created with java syntax. |
| 08:14 | ambrosebs | the only difference I can see. |
| 08:15 | clgv | ambrosebs: should be the same though? "length" is in fact done via java.reflect.Array as well afaik |
| 08:16 | clgv | interesting mail topic for clojure-dev though ;) |
| 08:16 | ambrosebs | perhaps there's a subtle difference between Array.newInstance(Object, 1) and Object[1] |
| 08:16 | clojurebot | It's greek to me. |
| 08:17 | clgv | ambrosebs: wouldnt that even violate the java spec? |
| 10:22 | Klaufir | i need some help understanding dependency management in cider + lein |
| 10:23 | Klaufir | first, how do I download dependencies? |
| 10:24 | Klaufir | say I want 'data.json', and have the following line in project.clj |
| 10:24 | Klaufir | :dependencies [[org.clojure/clojure "1.6.0"] [org.clojure/data.json "0.2.5"]] |
| 10:24 | cbp | you declare them in your project.clj and lein will download them automatically if it needs to |
| 10:24 | cbp | after you do something like lein repl |
| 10:24 | Klaufir | I see |
| 10:25 | teslanick | You can force it by running `lein deps` on the command line |
| 10:25 | Klaufir | thanks |
| 10:25 | Klaufir | and how do I make sure these deps are available in the REPL after cider-jack-in ? |
| 10:25 | Klaufir | for example when editing core.clj, and have a project file with [org.clojure/data.json "0.2.5"] included |
| 10:26 | Klaufir | I can't seem to access the json functions |
| 10:26 | Klaufir | is cider-jack-in supposed to resolve dependencies using lein ? |
| 10:28 | cbp | cider-jack-in calls lein repl so yes |
| 10:29 | Klaufir | can you point me towards some useful documentation regarding dependency management in clojue ? |
| 10:29 | Klaufir | so far, its very unintuitive, confusing and buried behind lein magic |
| 10:30 | cbp | https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md |
| 10:30 | _Atom_ | HELLO IS MY FRIEND HENRY HERE? |
| 10:30 | _Atom_ | LOL |
| 10:31 | Klaufir | cbp: exactly what I was looking for, thank you :) |
| 10:31 | deathknight | what's this doing here |
| 10:31 | _Atom_ | fgt shit |
| 10:31 | rplaca | Klaufir: I think you might be confusing the dependency management with accessing namespaces |
| 10:32 | rplaca | Klaufir: if your project.clj is set up like you say, you should have the dependency available and you just need to do a require when you want to access it |
| 10:33 | rplaca | e.g. at the repl: (require '[data.json :as json]) |
| 10:34 | rplaca | or in the ns form of your core.clj: (:require [data.json :as json]) |
| 10:37 | Klaufir | rplaca: thanks :) |
| 10:38 | rplaca | Klaufir: hope that helps! |
| 11:43 | orend | hey, I have a midje question: is there a way to ask midje to load the test lein profile? I want to make sure it uses the test database, and I want to clear it before the tests |
| 11:44 | orend | core.test is loading the test profile in lein, midje doesn't seem to do it |
| 11:52 | gfredericks | orend: `lein with-profile +test whatever-the-midje-task-is` will do it |
| 11:52 | gfredericks | and you can make an alias for that |
| 12:17 | dgleeson | does memoize have any memory impacts I should be considering before using it? |
| 12:17 | arrdem | dgleeson: memoize has an unbounded cache size.. |
| 12:18 | ambrosebs | https://github.com/clojure/core.cache |
| 12:18 | arrdem | at least clojure.core/memoize does... core cache fixes that nicely. |
| 12:18 | Bronsa | there's also core.memoize that's built on top of core.cache and it's friendlier |
| 12:19 | dgleeson | interesting thanks! |
| 13:02 | mmitchell | anyone here use clj-logging-config for log configuration? |
| 13:21 | bbloom | Bronsa: symbol-macrolet was super easy to add & solves my problem quite nicely :-) |
| 13:22 | AeroNotix | Just been to EuroClojure. What's with the bruce meme? |
| 13:24 | seangrove | AeroNotix: What bruce meme? |
| 13:26 | AeroNotix | seangrove: a lot of talks contained a picture of a guy called "Bruce" with a goatee |
| 13:30 | AeroNotix | https://skillsmatter.com/members/otfrom |
| 13:30 | AeroNotix | oh this guy |
| 13:31 | arrdem | I'd bet he's an organizer and it was presenters screwing with him |
| 14:10 | amalloy | bbloom: what problem did symbol-macrolet solve? i'm always excited to hear about new uses of it |
| 14:11 | bbloom | amalloy: in eclj i didn't want to special case fields inside deftype method bodies. so i used symbol-macrolet to expand field names to (.-field this) style forms |
| 14:12 | amalloy | ah. sounds perfect, yep yep |
| 14:12 | Bronsa | bbloom: oh so it worked, cool |
| 14:12 | bbloom | Bronsa: yup: https://github.com/brandonbloom/eclj/commit/bb885d02079387c675065d3347754f4bb1e54e29 |
| 14:12 | bbloom | and https://github.com/brandonbloom/eclj/commit/d99ba8f2fe72b71d360e602f2c466faf03ec01ac |
| 14:12 | bbloom | (deftype is still a slow as shit dirty hack, but i'm not worried about the perf of it until i get to the compiler) |
| 14:13 | bbloom | going to generalize set! too... basically to CL's setf |
| 14:13 | Bronsa | woah |
| 14:14 | Bronsa | bbloom: that sounds fun but I'm not really sure if it would be really useful in clj given absence of pervasive mutability |
| 14:14 | Bronsa | bbloom: do you have specific use-cases for that or is it just something cool you want to implement? |
| 14:17 | bbloom | Bronsa: i need to rework my code for set! anyway to understand symbol macros & it's pretty easy to just make that a protocol... effectively providing setf |
| 14:17 | bbloom | right now it's an if/else and will become a cond, so might as well make it a proto fn and call it done :-P |
| 14:18 | bbloom | but i don't need field setting yet, so i'll cross that bridge when i come to it |
| 14:19 | bbloom | i'm doing JIT development :-) |
| 14:21 | Bronsa | bbloom: ah yeah, I probably need to do something like that too |
| 14:22 | Bronsa | right now (set! foo bar) compiles to a setfield while (set! (.-foo this) bar) uses reflection IIRC |
| 14:22 | Bronsa | it should definitely be possible to make the latter compile to a setfield too |
| 14:23 | Bronsa | nevermind it already does. |
| 14:23 | Willis1 | bbloom |
| 15:28 | catern | agh |
| 15:28 | catern | Is there a "Java for Clojure developers" tutorial anywhere? |
| 15:28 | ndaly | haha |
| 15:28 | ndaly | I thought the same thing |
| 15:28 | catern | I've never actually worked in Java before, so |
| 15:31 | mikerod | Is it safe to use (clojure.lang/RT/nextID) as a way of getting a unique identifier within a given JVM instance? |
| 15:31 | cbp | I recommend Java in Action which is probably as close as you can get |
| 15:31 | mikerod | I know this is used by `gensym` |
| 15:31 | mikerod | but here, we don't actually need a symbol and do not want the overhead of creating one |
| 15:32 | catern | cbp: I really don't want to learn Java, though |
| 15:32 | catern | (as the exposure I have had to it, even before Clojure, convinces me it is garbage) |
| 15:32 | ndaly | it is |
| 15:33 | catern | I come to Clojure from Lisp, not Java :) |
| 15:33 | cbp | I'm not sure how to help you learning something without learning it |
| 15:34 | ndaly | Rich Hickey's talks (on youtube) entitled Clojure for Java Programmers is a gentle way to get some indirect understanding of the Java you might want to know |
| 15:34 | ndaly | while learning some interesting stuff about Clojure and it's implementation |
| 15:34 | mikerod | Rich Hickey also has a talk Clojure for Lisp programmers |
| 15:34 | ndaly | that one won't play past like minute 6 for me |
| 15:34 | ndaly | which is killing me, cuz I really want to watch it |
| 15:35 | mikerod | https://www.youtube.com/watch?v=cPNkH-7PRTk |
| 15:35 | mikerod | I've listened to both the Java and Lisp variety. The Lisp one is probably more insightful in my opinion. However, I'd think they both have value. |
| 15:35 | mikerod | Not to mention the Lisp one does assume you know something about Lisp. However, this is what catern said he was from. |
| 15:36 | ndaly | yeah, that video dies at 6:35 |
| 15:36 | mikerod | weird |
| 15:37 | mikerod | I haven't tried |
| 15:37 | mikerod | it used to work :P |
| 15:39 | dbasch | mikerod: I would use my own atom rather than rely on nextID |
| 15:39 | cbp | why not a uuid4 or something? |
| 15:40 | dbasch | cbp: he said he doesn't need uuids, only something unique within that jvm |
| 15:41 | Shayanjm | catern: why dive into java when you know clojure? |
| 15:41 | Shayanjm | I would imagine you can accomplish the same thing(s), just without consistently shooting yourself in the foot |
| 15:41 | catern | Shayanjm: I don't want to dive into Java |
| 15:41 | dbasch | Shayanjm: because using Clojure properly requires knowing Java |
| 15:41 | dbasch | to some extent, at least |
| 15:41 | Shayanjm | That's fair, but Java development is INCREDIBLY OO centric |
| 15:42 | Shayanjm | keeping code DRY is an impossible feat |
| 15:42 | catern | Shayanjm: I want to lightly touch the surface of Java, while heavily insulated by Clojure's protective embrace |
| 15:42 | dbasch | Shayanjm: so? You don't need to code in java |
| 15:42 | Shayanjm | dbasch: I know - that's why I was asking why catern was asking about 'java for clojure devs' |
| 15:42 | catern | Shayanjm: also I only need to be able to read Java code, not write it. And occasionally run it |
| 15:42 | Shayanjm | if he wanted to actually -learn- java |
| 15:43 | mikerod | cbp: As dbasch said, I do not want to pay any overhead for getting a UUID |
| 15:43 | Shayanjm | or learn how to build stuff with clojure while using java interfaces |
| 15:43 | Shayanjm | gotcha catern |
| 15:43 | mikerod | I only care about the uniqueness at the per-JVM instance level |
| 15:43 | mikerod | dbasch: Why make your own atom? |
| 15:43 | mikerod | dbasch: The RT/nextID method is not something you think is stable? |
| 15:44 | dbasch | mikerod: it's not a documented feature of the language |
| 15:44 | dbasch | mikerod: and it will leave holes in your ids, fwiw |
| 15:45 | dbasch | all it does is use a java AtomicInteger I believe |
| 15:45 | jconnoll1 | quick and dumb question... I have a vector [1 2 3 4 5], I want to create another vector that's just [0.0 0.0 0.0 0.0 0.0] of length of the first vector... |
| 15:46 | mikerod | dbasch: holes do not matter for me, but it being undocumented makes some sense |
| 15:46 | cbp | jconnolli: (vec (repeat (count my-vec) 0.0)) |
| 15:46 | jconnolly | cbp: beauty, thanks |
| 15:47 | ndaly | god I love how concise that is |
| 15:48 | catern | I wish there was a #(+ % 5) style form for defining functions returning simple data structures, like say #[%] or #{:value %} |
| 15:49 | dbasch | you could also do (vec (for [x my-vec] 0.0)) |
| 15:49 | catern | Simple transformations I mean |
| 15:50 | ndaly | catern: I'm confused about what you want to be able to do |
| 15:50 | catern | ndaly: define a function returning a vector or map, parameterized with % |
| 15:51 | catern | (and the variations on %) |
| 15:51 | dbasch | also, (mapv (constantly 0.0) my-vec) |
| 15:51 | catern | constantly |
| 15:51 | catern | That is a nice function |
| 15:52 | catern | thanks dbasch, did not know of it |
| 15:52 | dbasch | ,(mapv (constantly 0.0) [:a :b :c]) |
| 15:52 | clojurebot | [0.0 0.0 0.0] |
| 16:13 | fifosine | Is there a standard/good-practice for defining and loading properties from a properties file? For example, I'd like to write a properties file for database credentials and keep it separate from version control. |
| 16:14 | bbloom | fifosine: something wrong with slurp and pr-str ? |
| 16:14 | bbloom | er read-str ? |
| 16:15 | Raynes | read-str is a thing? |
| 16:15 | bbloom | argh. |
| 16:15 | bbloom | read-string |
| 16:15 | bbloom | (def read-str read-string) |
| 16:15 | ttasterisco | use environ |
| 16:15 | ttasterisco | ,(google "clojure environ") |
| 16:15 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: google in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:15 | bbloom | then somebody do a vary-meta to :deprecate read-string :-P |
| 16:16 | Raynes | Well, he almost certainly wouldn't want read-string. |
| 16:16 | fifosine | bbloom: I'm sure there are many ways to do this. Using java.util.Properties is recommended here https://stackoverflow.com/questions/7777882/loading-configuration-file-in-clojure-as-data-structure. I am curious if there is an idomatic way to do this. |
| 16:16 | ttasterisco | https://github.com/weavejester/environ |
| 16:16 | Raynes | $google clojure environ |
| 16:16 | lazybot | [weavejester/environ · GitHub] https://github.com/weavejester/environ |
| 16:16 | bbloom | fifosine: depends on what context you want idioms from |
| 16:16 | fifosine | A clojure context. |
| 16:16 | bbloom | if you're deploying a unix process on heroku or in docker or whatever, use environment |
| 16:17 | bbloom | if you have a jvm cluster w/ devops that know those tools, use java properties |
| 16:17 | Raynes | I generally use environment variables for most of my configuration. If I want configuration files, I serialize Clojure data structures by printing them to files and reading them with clojure.edn/read-string |
| 16:17 | Raynes | Or I use toml. |
| 16:17 | Raynes | Lately I mostly use toml for configuration I expect a user to have to modify. |
| 16:17 | bbloom | if your config is too big for the environment, put a file path in the environment |
| 16:18 | fifosine | bbloom: My config won't be big, it's just going to be a db user and pass as of now |
| 16:18 | bbloom | if you don't know anything about java properties, then ignore them |
| 16:18 | bbloom | just use the env |
| 16:18 | Raynes | Yeah, you don't want properties for this. |
| 16:18 | fifosine | bbloom: When you say, "use the env" do you mean use environ? |
| 16:18 | Raynes | ENVIRONMENT VARIABLES |
| 16:19 | Raynes | Environ can handle those for ye |
| 16:19 | bbloom | ,(get System/getenv "PATH") |
| 16:19 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to find static field: getenv in class java.lang.System, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:19 | Raynes | Though I personally never totally got the purpose of environ. |
| 16:19 | bbloom | ,(get (System/getenv) "PATH") |
| 16:19 | clojurebot | #<AccessControlException java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv.*)> |
| 16:19 | bbloom | aw |
| 16:19 | Raynes | I generally just do what bbloom is desperately struggling to do. |
| 16:19 | bbloom | i swear that works locally |
| 16:20 | Raynes | Haha, yeah, the second one is fine. |
| 16:20 | fifosine | lul |
| 16:20 | Raynes | I think (System/getenv "PATH") would also work. |
| 16:20 | Raynes | But I can't recall for certain. |
| 16:20 | bbloom | Raynes: yup does |
| 16:24 | bbloom | i'm still trying to understand the equals/equiv and hashCode/hasheq dichotomy |
| 16:24 | bbloom | why doesn't hashCode delegate to hasheq ? |
| 16:25 | ttasterisco | ,(doc hasheq) |
| 16:25 | clojurebot | Titim gan éirí ort. |
| 16:28 | bbloom | https://docs.google.com/a/thinkrelevance.com/document/d/1DT2uXlAwH5NstgYSeqbOXb_8K6Gwnw99QksCaUKpCjU/edit?pli=1 says: |
| 16:28 | bbloom | The Java Collections API specifies required algorithms for calculating the hash code of sets, maps, lists, etc from their elements. We wish to be compatible with the collections API |
| 16:28 | bbloom | blargh :-P |
| 16:29 | tolitius | is there a way to see what is (file name/function) being compiled? I have a dozen of files, one of which needs aot [hence compiles all the dependent ns], and it takes about 5 minutes to finish (where it should take about 5 seconds), I just want to figure out which file causes the compilation hiccup. |
| 16:30 | andyf_ | bbloom: Does that answer your question about why they both exist, or only adds to it? |
| 16:30 | bbloom | andyf_: it gives me a guess, but i'm still not totally sure |
| 16:31 | bbloom | andyf_: my guess is that java.collections tests hashcode equality in some cases & needs to work with heterogeneous collection impls |
| 16:31 | bbloom | maybe? |
| 16:32 | xeqi | bbloom: didn't the 1.6 hash changes break that compatibility? |
| 16:32 | bbloom | xeqi: best i can tell both code paths are still there |
| 16:33 | andyf_ | I am not 100% in the loop on Clojure design decisions, I do believe that they wanted equals and hashCode to be consistent for Clojure collections and their nearest equivalent in the Jaca Collections library |
| 16:33 | xeqi | ah, found http://dev.clojure.org/jira/browse/CLJ-1372 |
| 16:33 | xeqi | which is about the extent of my knowledge in this area, other then stuff is happening/happened |
| 16:34 | andyf_ | xeqi: 1.6 should not have changed hashCode ret val for anything |
| 16:34 | andyf_ | It did change hasheq ret val for many things |
| 16:40 | dbasch | fifosine: you mean a .properties file in the typical java format? |
| 16:43 | dbasch | never mind, had missed the rest of the backlog |
| 16:58 | fifosine | How do I debug this issue? http://pastebin.com/3HQFwRmw I know that this jar exists in the repo. |
| 17:01 | xeqi | fifosine: by carefulling checking the group:artifact:version in the error |
| 17:01 | xeqi | (missing a q I believe) |
| 17:04 | fifosine | xeqi: Still getting it :/ http://pastebin.com/1y6AuLVT |
| 17:16 | xeqi | fifosine: that version doesn't exist by that group/artifact: http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22postgresql%22%20AND%20a%3A%22postgresql%22 |
| 17:16 | xeqi | perhaps you want group "org.postgres" |
| 17:16 | xeqi | bah |
| 17:16 | xeqi | org.postgresql |
| 17:16 | bbloom | is there some way to stop ctrl-c from closing `lein repl` ? |
| 17:16 | bbloom | i want to actually be able to interrupt an evaluation... |
| 17:16 | fifosine | xeqi: Looks like that was it! |
| 17:16 | amalloy | bbloom: i don't think there's a portable way, but https://github.com/flatland/useful/blob/develop/src/flatland/useful/java.clj#L10-L16 works on some jvms. register a handler for sigint, maybe? |
| 17:16 | bbloom | amalloy: but the damn nrepl middleware is called "InterruptableEval" |
| 17:16 | bbloom | c'mon now cemerick/technomancy |
| 17:16 | bbloom | et al |
| 17:16 | andyf_ | bbloom: In my quick test on Mac OS X with Lein 2.3.4, it already does what you want. Lein 2.4 the behavior changed |
| 17:16 | cbp | my lein repl only quits by ctrl-d |
| 17:16 | bbloom | andyf_: i just upgraded recently, which would explain why i only started noticing this... i could have sworn it used to work |
| 17:16 | cbp | Unless i spam control-c it too many times apparently |
| 17:16 | amalloy | oh, yeah. in lein repl, C-c just interrupts for me |
| 17:16 | cbp | s/it// |
| 17:16 | andyf_ | Lein upgrade 2.3.4 should work to downgrade |
| 17:16 | bbloom | andyf_: but i want the latest lein for https://github.com/greglook/whidbey |
| 17:16 | andyf_ | I usually keep a numbered backup of Lein bash scripts before upgrading |
| 17:16 | andyf_ | I would have guessed you were kidding when you gave that URL, but looks like a real thing :-) |
| 17:16 | bbloom | i wrote fipp in the hope that somebody would integrate it in to nrepl/lein. whedbey realizes that dream :-) |
| 17:16 | bbloom | whidbey* |
| 17:16 | andyf_ | File a Lein bug, and see where it goes - or maybe there is one already? |
| 17:16 | dbasch | lein 2.4.2 on OSX, ctrl-c doesn't kill it |
| 17:16 | andyf_ | It does for me |
| 17:16 | bbloom | https://github.com/technomancy/leiningen/issues/1583 |
| 17:16 | andyf_ | Not sure, but may be a dupe of 1570 |
| 17:17 | andyf_ | Holy cow - 1538 issues closed on leiningen. That's a bunch |
| 17:19 | xeqi | andyf_: and all as a labor of love / no corporate donations |
| 17:19 | xeqi | perhaps sponser would be a better term there |
| 17:19 | cbp | you can dotane to tehcnomancys git tip :-P |
| 17:19 | cbp | donate even |
| 17:20 | arrdem | I think he gets like $3.50/wk... |
| 17:20 | arrdem | which is pretty absurd given how much value lein generates. |
| 17:20 | andyf_ | I've never donated via git tip before. URL handy? |
| 17:20 | arrdem | https://www.gittip.com/technomancy/ |
| 17:21 | cbp | clearly he shouldve been involved in npm instead |
| 17:21 | arrdem | lol |
| 17:22 | andyf_ | No way to do 1 time gift, only periodically? |
| 17:27 | bbloom | weird... i'm trying to use yourkit on something in the repl & java.io.PushbackInputStream.read is running on an agent thread (i'm not using agents) & shows as the primary hot method |
| 17:28 | bbloom | it's "own time" metric is climbing rapidly |
| 17:28 | bbloom | s/it's/its |
| 17:28 | amalloy | bbloom: it's consuming 100% of a single thread |
| 17:28 | amalloy | that happens all the time with repl/swank. i just right-click and Ignore that method |
| 17:28 | bbloom | amalloy: yeah, but why is it doing anything, i'm not evaluating anything |
| 17:29 | bbloom | what's it think it's doing? |
| 17:29 | amalloy | it's waiting for you to type something |
| 17:29 | amalloy | that's blocking, so it isn't taking up actual cpu time, but it is time a thread is spending inside a method |
| 17:30 | bbloom | odd. hadn't seen that before |
| 17:30 | amalloy | i think that's the general outline, anyway |
| 17:30 | amalloy | happens to me anytime i use yourkit on a jvm i'm also attached to via swank |
| 17:30 | bbloom | good to know. i had never noticed it with visualvm |
| 17:42 | bbloom | i apparently have no idea how to use yourkit |
| 17:42 | bbloom | (time ...) reports 11 seconds. sum of "own time" yourkit is ~2 seconds |
| 17:42 | bbloom | those don't add up.... |
| 17:43 | amalloy | own time doesn't include any other functions called by f, in (time (f)) |
| 17:43 | bbloom | amalloy: i said "sum of" |
| 17:44 | amalloy | oh. how are you even summing the own time of all methods invoked by a specific instance of (time (f))? |
| 17:44 | bbloom | i manually summed the top 10 calls or so, then multiplied the value of the 11th by the approximate number of rows |
| 17:44 | bbloom | remaining rows |
| 17:44 | bbloom | so that should be an approximate upper bound |
| 17:44 | bbloom | but it's 2ish seconds, instead of 11 |
| 17:45 | bbloom | even if that's cpu time, i doubt there's 9 seconds of wall clock waiting |
| 17:49 | DilatedPupils|TH | pen tested a site today, able to intercept the request going to paypal and changed the payment to 1p, how many of the sites use the wrong implementation |
| 17:49 | arrdem | DilatedPupils|TH: cool result, wrong channel? |
| 17:50 | DilatedPupils|TH | sure, sorry |
| 17:50 | bbloom | amalloy: found the perf problem with some manually placed (time ...) statements. easy fix |
| 17:50 | bbloom | my experience with profilers is almost always pretty poor |
| 17:54 | andyf | dbasch: Try an infinite loop like (count (range)) and then ctrl-c to interrupt it |
| 17:55 | dbasch | andyf: works just fine |
| 17:56 | andyf | Must be some other diff in our software I guess |
| 18:04 | dbasch | andyf: Leiningen 2.4.2 on Java 1.7.0_51 Java HotSpot(TM) 64-Bit Server VM |
| 18:08 | andyf | Same here, plus os x 10.8.5 and no ~/.lein/profiles.clj file. Throws exception and exits Lein repl consistently when I try to interrupt evaluation. Seems like Lein/reply folks are on the issue. |
| 18:12 | amalloy | bbloom: you must be looking at the wrong stuff. i find yourkit often points me right at the hotspots |
| 18:13 | bbloom | i guess i just have no idea how to use it, b/c i put the hotspot back in and tried jvisualvm & it pointed it out right away |
| 18:13 | amalloy | i turn on cpu sampling, let it run for a while, capture a snapshot, and then look around in the method list and/or hotspot list |
| 18:14 | bbloom | that's exactly what i did |
| 18:14 | amalloy | maybe computers just find you offensive |
| 18:14 | bbloom | like true |
| 18:15 | hiredman | maybe you should have written a map reduce job in erlang |
| 18:15 | bbloom | huh? |
| 18:16 | hiredman | bad advice for every situation |
| 18:16 | ttasterisco | lol |
| 18:19 | Shayanjm_ | https://gist.github.com/shayanjm/7a085ad77514290c4986 <-- this code immediately prints "Elapsed time: 0.899 msecs" |
| 18:19 | Shayanjm_ | but it actually returns values much later |
| 18:19 | Shayanjm_ | any ideas how I can capture the WHOLE time it takes to return everything to the last form? |
| 18:20 | bbloom | put a doall on your pmap |
| 18:20 | hiredman | ugh |
| 18:20 | hiredman | pmap inside a transaction |
| 18:20 | bbloom | but yeah, what hiredman said. don't do that |
| 18:20 | hiredman | bbloom: that may actually deadlock |
| 18:20 | bbloom | that code is all kinds of wrong |
| 18:21 | hiredman | does pmap use agents? maybe I am thinking of seque |
| 18:21 | bbloom | hiredman: it's built from futures |
| 18:21 | hiredman | also ref-set |
| 18:21 | bbloom | or maybe it's delays |
| 18:22 | amalloy | hiredman: pmap uses futures, seque uses agents |
| 18:22 | Shayanjm_ | should i throw the pmap into a let, and then throw that into the refset? |
| 18:22 | hiredman | terrible thing #1 using pmap, this is indefensible, #2 using the stm, if you try very hard you may be able to defend this |
| 18:22 | amalloy | bbloom: http://i.imgur.com/ENtJs.png is the reference from hiredman you seem to have missed |
| 18:23 | Shayanjm | hiredman: very very very new to clojure |
| 18:23 | Shayanjm | what should I do instead? |
| 18:23 | bbloom | amalloy: lol awesome |
| 18:23 | hiredman | Shayanjm: depends what you are doing |
| 18:24 | Shayanjm | hiredman: I have a list of URLS. I have a function that 'gets' the article content body from the URL and stubs it into a string |
| 18:24 | hiredman | Shayanjm: but, basically, write functions that take immutable values as arguments, and return an immutable value as a result |
| 18:25 | Shayanjm | and then I have another function that analyzes the sentiment of the string glob, and returns a list of numbers signifying each sentence's sentiment |
| 18:25 | Shayanjm | I would like to be able to iterate through the list of URLS in my 'newswire' ref, and analyze each article's sentiment and store the result in a second ref |
| 18:25 | hiredman | why is newswire a ref? |
| 18:26 | hiredman | is it logically a collection of values, or a work queue little machines pull work from? |
| 18:28 | Shayanjm | hiredman: It was an atom, but I assumed that I would need some level of transactional guarantee on it and the second 'thing' (whether it's an atom or a ref) |
| 18:28 | Shayanjm | that way I don't have a set of sentiment analysis results that are out of sync with the list of URLs |
| 18:30 | dbasch | Shayanjm: I would make sentiment analysis results be a function of a url snapshot, which is immutable |
| 18:30 | Shayanjm | a url snapshot? |
| 18:30 | hiredman | Shayanjm: that just isn't a good way to break it up, have a single function that takes a {:title … :url …} and returns a {:title … :url … :sentiment …} |
| 18:30 | dbasch | Shayanjm: e.g. nytimes.com/index.html at 3:29 PST 6/28/2014 |
| 18:31 | Shayanjm | hmmk |
| 18:31 | hiredman | then replace newswire with a queue of {:title … :url …} |
| 18:31 | dbasch | a url doesn't have a sentiment, the content does |
| 18:31 | hiredman | then fire off futures or use an executor directly that runs the function taking one element from the queue at a time |
| 18:32 | Shayanjm | Yeah I'm not sure about that fundamentally |
| 18:32 | Shayanjm | as it stands right now: each component is simplistic and straight forward |
| 18:32 | hiredman | collecting the results somewhere (maybe another queue for whatever the next stage is) |
| 18:32 | dbasch | (waiting for an example like http://sad-domain/sad-path-to-sadness.html) |
| 18:32 | Shayanjm | I'm not sure what composing the functions into one large 'get-sentiment-from-url' function will do for the time issue I was running into |
| 18:33 | hiredman | neither pmap nor the stm are simple |
| 18:33 | Shayanjm | stm? |
| 18:33 | hiredman | Shayanjm: software transactional memory, what dosync and refs are |
| 18:33 | Shayanjm | Sure so arguably I don't even need the second ref |
| 18:34 | Shayanjm | it was just for the sake of having something available to capture the results of the functions |
| 18:34 | hiredman | you should not need *any* refs |
| 18:34 | Shayanjm | I think a single atom is necessary for managing the data coming in from the API, is it not? |
| 18:34 | hiredman | Shayanjm: atoms are not refs |
| 18:34 | justin_smith | Shayanjm: http://clojure.org/refs this explains refs / stm |
| 18:35 | hiredman | Shayanjm: and in any case I suspect a work queue would be better |
| 18:35 | Shayanjm | Probably, hiredman. Do you suggest I build one myself or is there a library option available? |
| 18:36 | hiredman | Shayanjm: java.util.concurrent has a few queues |
| 18:37 | Shayanjm | Anyway, as I mentioned before - I don't know how this has anything to do with the weirdness surrounding the time function |
| 18:37 | hiredman | you could pull in core.async and use a channel as a work queue too |
| 18:38 | hiredman | Shayanjm: pmap is sort of lazy |
| 18:38 | Shayanjm | does anyone know why time is being printed before every form has finished evaluating? |
| 18:38 | Shayanjm | oh really? |
| 18:38 | bbloom | Shayanjm: i answered your question in my very first comment: try doall |
| 18:38 | hiredman | Shayanjm: did you read the doc string for pmap? |
| 18:38 | justin_smith | Shayanjm: a function can return a result that is lazy before the result is realized |
| 18:38 | hiredman | (doc pmap) |
| 18:38 | clojurebot | "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead." |
| 18:38 | bbloom | it will prevent the laziness.... butthen you should listen to hiredman |
| 18:38 | Shayanjm | ok thanks bbloom |
| 18:38 | Shayanjm | I see |
| 18:39 | hiredman | but pmap is terrible |
| 18:39 | hiredman | ~pmap |
| 18:39 | clojurebot | pmap is not what you want |
| 18:39 | bbloom | (dec pmap) |
| 18:39 | lazybot | ⇒ -1 |
| 18:39 | bbloom | sheesh, that's too almost positive |
| 18:39 | bbloom | (dec pmap) |
| 18:39 | lazybot | ⇒ -2 |
| 18:39 | bbloom | (dec pmap) |
| 18:39 | lazybot | ⇒ -3 |
| 18:39 | bbloom | (dec pmap) |
| 18:39 | lazybot | Do I smell abuse? Wait a while before modifying that person's karma again. |
| 18:39 | bbloom | better |
| 18:40 | Shayanjm | wait so what is pmap useful for then? |
| 18:40 | hiredman | nothing |
| 18:40 | Shayanjm | My understanding is that it's just like map, but it threads each iteration? |
| 18:40 | Shayanjm | (apparently clojure for the brave lied to me) |
| 18:41 | bbloom | that is what it is, it's just that that is not useful |
| 18:41 | hiredman | it isn't just that |
| 18:41 | tuft_ | is there a preferred alternative these days? |
| 18:41 | justin_smith | bbloom: wouldn't it still be useful, if your function was more expensive than the future spawning overhead? |
| 18:41 | hiredman | it also imposes an ordering on the results, it trys to run only as many jobs as there are cores at a time |
| 18:41 | hiredman | it is semi lazy |
| 18:41 | hiredman | but then does weird things on chunked seqs |
| 18:42 | hiredman | all of those things are basically things you never want |
| 18:44 | hiredman | I recommend getting familiar with the executors framework http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html etc |
| 18:45 | hiredman | a fundamental problem of pmap is it takes in a seq and produces a seq |
| 18:45 | hiredman | the seq abstraction is terrible for parallelism because it enforces linear access |
| 18:46 | tuft | ".. but i was promised if i used seqs and maps i'd get parallelism for free? 😢 " |
| 18:47 | hiredman | by who? |
| 18:48 | tuft | haha |
| 18:48 | tuft | can't remember exactly where that came from |
| 18:48 | hiredman | http://xahlee.info/comp/i/ICFPAugust2009Steele.pdf |
| 18:48 | tuft | generally getting more abstract than a for loop seems to have that promise though |
| 18:49 | hiredman | sure |
| 18:49 | hiredman | in order to have parallelism you need a datastructure with random access |
| 18:50 | tuft | that makes sense |
| 18:51 | dbasch | hiredman: that's not strictly true, you can have a sequential pipeline of things that execute in parallel |
| 18:55 | hiredman | dbasch: concurrent vs. parallel |
| 18:56 | dbasch | hiredman: yes, I meant parallel, as in a factory pipeline with workers doing things in parallel |
| 18:57 | danielszmulewicz | Is clj-time still the best option to work with times in Clojure? I need to determine if a given date is in the future. |
| 18:57 | dbasch | in order to have parallelism you just need entities who have work to do |
| 18:57 | hiredman | dbasch: they are not concurrent, the "pipeline" sychronizes access |
| 18:58 | dbasch | hiredman: you said parallelism, not concurrency |
| 18:58 | seancorfield | danielszmulewicz: depends on what format your initial date is... java.util.Date or Joda Time? |
| 18:58 | danielszmulewicz | seancorfield: java.util.Date (it's coming from Monger) |
| 18:58 | seancorfield | At World Singles we use both date-clj (for java.util.Date stuff) and clj-time for more complex stuff |
| 18:58 | seancorfield | date-clj/before? is probably the easiest then |
| 18:59 | justin_smith | ,(compare (java.util.Date.) (java.util.Date.)) danielszmulewicz |
| 18:59 | danielszmulewicz | seancorfield: Very cool. Thank you. |
| 18:59 | clojurebot | 0 |
| 18:59 | hiredman | dbasch: I said lots of things |
| 18:59 | justin_smith | you don't need to get fancy for that |
| 18:59 | danielszmulewicz | justin_smith: Thanks. That's cool as well. |
| 18:59 | justin_smith | I mean if you need to do math on time objects, or read format strings, yeah use a lib |
| 18:59 | dbasch | hiredman: I was commenting on "hiredman: in order to have parallelism you need a datastructure with random access" |
| 19:00 | justin_smith | but you don't need anything but the built in class for comparing sequentiality |
| 19:00 | danielszmulewicz | justin_smith: Just this one, and maybe one or two more. |
| 19:00 | amalloy | &(frequencies (repeatedly 10000 #(compare (java.util.Date.) (java.util.Date.)))) |
| 19:00 | lazybot | ⇒ {0 9991, -1 9} |
| 19:00 | justin_smith | fascinating |
| 19:01 | amalloy | not really important to this discussion, but i thought you might like it, justin_smith |
| 19:01 | justin_smith | indeed |
| 19:01 | danielszmulewicz | amalloy: Care to explain to a dummy? |
| 19:01 | amalloy | danielszmulewicz: you build two date objects and compare them. usually, they're in the same millisecond |
| 19:01 | ndaly | wow |
| 19:01 | amalloy | but every so often, you slip across a millisecond boundary between building the first and building the second, so they compare as different |
| 19:01 | danielszmulewicz | amalloy: Oh, nice. |
| 19:02 | ndaly | wait, is that building 10000 pairs of date objects? |
| 19:02 | amalloy | yeah |
| 19:02 | ndaly | very nice |
| 19:02 | amalloy | i suppose it would have been more apropos to generate them all in parallel with pmap |
| 19:03 | justin_smith | yeah, the jvm handles micro-liftime objects very nicely |
| 19:03 | ndaly | I wonder how much of the JVM being good can be attributed to it needing to make up for Java being bad |
| 19:04 | justin_smith | ndaly: I think there is more the fact that very well funded companies poured a lot of resources and exceptional talent into the jvm |
| 19:05 | amalloy | incidentally, that frequency chart gives a good estimate of how long it takes to construct a Date object. 0.1% of a millisecond, right? so ##(time (dotimes [_ 1000] (java.util.Date.))) should take about 1ms |
| 19:05 | lazybot | ⇒ "Elapsed time: 7.151076 msecs" nil |
| 19:06 | amalloy | hmph. i want a refund. i don't know why that's off by a factor of 7 |
| 19:06 | hiredman | the jvm it does things |
| 19:09 | danielszmulewicz | (+ seancorfield) |
| 19:09 | danielszmulewicz | hehe, how does this karma things work again? |
| 19:09 | oskarkv | inc |
| 19:09 | danielszmulewicz | right, thanks |
| 19:09 | danielszmulewicz | (inc seancorfield) |
| 19:09 | lazybot | ⇒ 13 |
| 19:09 | amalloy | hiredman: yeah, i guess that's what it is. if i go from 1000 dates to 10000, the time taken only doubles |
| 19:09 | danielszmulewicz | (inc justin_smith) |
| 19:09 | lazybot | ⇒ 51 |
| 19:09 | seancorfield | thank you danielszmulewicz! |
| 19:10 | danielszmulewicz | seancorfield: Thank you! |
| 19:10 | danielszmulewicz | (inc amalloy) |
| 19:10 | lazybot | ⇒ 134 |
| 19:12 | dbasch | &(time (dotimes [_ 1000])) |
| 19:12 | lazybot | ⇒ "Elapsed time: 3.850407 msecs" nil |
| 19:13 | dbasch | (dec dotimes) |
| 19:13 | lazybot | ⇒ -1 |
| 19:13 | dbasch | ,(time (dotimes [_ 1000])) |
| 19:13 | clojurebot | "Elapsed time: 0.164555 msecs"\n |
| 19:14 | bbloom | ,(dotimes [_ 10] (time (dotimes [_ 100]))) |
| 19:14 | clojurebot | "Elapsed time: 0.136017 msecs"\n"Elapsed time: 0.004059 msecs"\n"Elapsed time: 0.003686 msecs"\n"Elapsed time: 0.00368 msecs"\n"Elapsed time: 0.003563 msecs"\n"Elapsed time: 0.003803 msecs"\n"Elapsed time: 0.003647 msecs"\n"Elapsed time: 0.003657 msecs"\n"Elapsed time: 0.003569 msecs"\n"Elapsed time: 0.003598 msecs"\n |
| 19:14 | bbloom | ,(dotimes [_ 10] (time (dotimes [_ 1000]))) |
| 19:14 | clojurebot | "Elapsed time: 0.152137 msecs"\n"Elapsed time: 0.025343 msecs"\n"Elapsed time: 0.209708 msecs"\n"Elapsed time: 0.002701 msecs"\n"Elapsed time: 0.00244 msecs"\n"Elapsed time: 0.002395 msecs"\n"Elapsed time: 0.002409 msecs"\n"Elapsed time: 0.002404 msecs"\n"Elapsed time: 0.002389 msecs"\n"Elapsed time: 0.002377 msecs"\n |
| 19:14 | bbloom | computers. how do they work? |
| 19:16 | gfredericks | ,(macroexpand-1 '(dotimes [_ 1000])) |
| 19:16 | clojurebot | (clojure.core/let [n__4379__auto__ (clojure.core/long 1000)] (clojure.core/loop [_ 0] (clojure.core/when (clojure.core/< _ n__4379__auto__) (recur (clojure.core/unchecked-inc _))))) |
| 19:17 | danielszmulewicz | $help |
| 19:17 | lazybot | You're going to need to tell me what you want help with. |
| 19:17 | amalloy | what in the world. did i turn this into #dotimes? |
| 19:17 | danielszmulewicz | dbasch: What is the meaning of the ampersand at the beginning of the expression you typed earlier? |
| 19:18 | cj3kim | hi, in (defn [& args] ;code ) is args an vector? |
| 19:18 | dbasch | danielszmulewicz: asking lazybot to evaluate |
| 19:18 | amalloy | cj3kim: it's a seq |
| 19:18 | danielszmulewicz | dbasch: is that not the coma? |
| 19:18 | dbasch | danielszmulewicz: that's clojurebot |
| 19:18 | cj3kim | amalloy: thank you! |
| 19:18 | danielszmulewicz | dbasch: oh, how many bots do we have here? |
| 19:19 | amalloy | at least two. jury's still out on justin_smith |
| 19:19 | dbasch | danielszmulewicz: I am not a bot |
| 19:19 | danielszmulewicz | hehe |
| 19:19 | dbasch | I am a 13 year old boy from Ukraine |
| 19:20 | ttasterisco | ew |
| 19:21 | bbloom | Bronsa: i think i'm gonna have to start on the compiler sooner rather than later... the more of core i make symbolic, the slower everything goes... i'm working on lazy seqs now, it's making everything 20X slower (which i guess is expected for interpreter vs compiler) |
| 19:23 | amalloy | bbloom: i wonder, are you chunking lazy seqs? that brings a surprisingly large speedup |
| 19:24 | bbloom | amalloy: just the overhead of the itnerpreter for first/next/seq dispatch is killing me |
| 19:27 | justin_smith | amalloy: me? Ha! I would appreciate it if you would continue. |
| 19:28 | amalloy | Why would you appreciate it if I would continue? |
| 19:29 | justin_smith | What do you think? |
| 19:29 | dbasch | now this is #clojure-chatbots |
| 19:33 | TEttinger | bbloom, is this for clojure-in-clojure? |
| 19:33 | bbloom | TEttinger: not for the official c-in-c stuff going on in tools analyzer etc. it's for my hacky thing |
| 19:33 | amalloy | dbasch: for some reason back in march i spent a few days as /nick amalloybot instead of amalloy. i don't really remember why i thought this was funny |
| 19:34 | amalloy | er, hours. not days. jeez |
| 19:34 | dbasch | amalloy: were you trying to pass the reverse turing test? |
| 19:35 | amalloy | the only person who really believed i had become a bot was bbloom |
| 19:36 | bbloom | amalloy: i mean, it would explain your code golf skills |
| 19:36 | bbloom | you're clearly a search algorithm |
| 19:42 | cj3kim | how do you know which index the for loop is processing for every cycle? ie if I wanted to know what index (for row[matrix]) was processing? |
| 19:42 | hiredman | ~for |
| 19:42 | clojurebot | for is awesome |
| 19:43 | hiredman | erm |
| 19:43 | hiredman | ~for |
| 19:43 | clojurebot | for is swanking |
| 19:43 | hiredman | feh |
| 19:43 | hiredman | for isn't a loop |
| 19:43 | hiredman | (says so in the doc string if I recall) |
| 19:43 | Glenjamin | ,(doc for) |
| 19:43 | clojurebot | "([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], ... |
| 19:43 | hiredman | "List comprehension" |
| 19:43 | justin_smith | cj3kim: the classic is to use map-indexed on the sequence (for [[i e] (map-indexed identity elements)] ...) |
| 19:44 | justin_smith | where i will be the number, e the element |
| 19:44 | cj3kim | oh :[ |
| 19:44 | hiredman | justin_smith: identity doesn't work |
| 19:44 | Glenjamin | although if your for is simple, you're probably better off doing the work in the fn passed to map-indexed |
| 19:44 | justin_smith | hiredman: oh, it needs two args, sorry |
| 19:44 | justin_smith | (for [[i e] (map-indexed list elements)] ...) |
| 19:45 | hiredman | http://en.wikipedia.org/wiki/List_comprehension |
| 19:45 | michaniskin | (def indexed (partial map-indexed vector)) |
| 19:45 | cj3kim | thank you |
| 19:46 | hiredman | that use of map-indexed is also vaguely amusing, because map-indexed was created because there was some contrib function that created indexed sequences |
| 19:46 | hiredman | and people wanted it in core, but rich hated the idea of constructing pairs when you are just going to rip them apart again |
| 19:47 | amalloy | hiredman: named indexed, in fact |
| 19:47 | hiredman | it is a hilarious cycle |
| 19:47 | hiredman | maybe ridiculous cycle would be a better name |
| 19:47 | amalloy | http://clojuredocs.org/clojure_contrib/clojure.contrib.seq/indexed |
| 19:49 | amalloy | there is some weird stuff in old contrib |
| 19:49 | michaniskin | it's something you need to do sometimes, deal with it lol |
| 19:50 | hiredman | if you don't give people a way to do what they want easily, even if it is inefficient, they are just going to go out of their way to do it and complain about the difficulty |
| 19:50 | dbasch | hiredman: hence pmap :P |
| 19:51 | amalloy | map-vals being hiredman's favorite example of this, i would think |
| 19:52 | hiredman | amalloy: there are too many examples of this in clojure to pick a favorite |
| 19:52 | justin_smith | michaniskin: fyi, I just benchmarked w/ criterium, and vector takes 3 times as long as list in a test case where I just add the results (vectors are high overhead for small collections) |
| 19:52 | justin_smith | https://www.refheap.com/87634 |
| 19:53 | michaniskin | justin_smith: vectors are nice though because using things like indexed in macros, you don't want to inadvertently evaluate the items in there |
| 19:55 | michaniskin | if you emit lists you have to watch out for that |
| 19:58 | justin_smith | michaniskin: good news is, with hotspot turned on, both run much faster, and the difference is very small |
| 19:58 | cj3kim | justin_smith: for loop isn't working. could you take a look at the gist and let me know what's up? https://gist.github.com/cj3kim/01279c340d54db9a5caf |
| 19:58 | justin_smith | michaniskin: https://www.refheap.com/87634 updated with hotspot results |
| 19:59 | amalloy | justin_smith: that benchmark shows vector being way faster than list, not the other way around |
| 19:59 | dbasch | cj3kim: for is not a loop |
| 19:59 | justin_smith | cj3kim: as mentioned before, it is not a for loop |
| 19:59 | dbasch | cj3kim: you want doseq |
| 19:59 | justin_smith | cj3kim: calling it a loop is misleading |
| 19:59 | michaniskin | justin_smith: wow, that's a pretty big improvement |
| 19:59 | cj3kim | got it |
| 19:59 | cj3kim | thank you |
| 19:59 | dbasch | it's unfortunate that for means one thing in math and another in imperative languages |
| 20:00 | justin_smith | cj3kim: calling dimension-index as if it was a function makes no sense |
| 20:00 | amalloy | it's probably mostly the time spent destructuring, not the time spent on actually building the lists/vectors |
| 20:00 | justin_smith | that should be giving an error |
| 20:00 | justin_smith | that is not how for works |
| 20:00 | justin_smith | (or doseq for that matter) |
| 20:01 | cj3kim | justin_smith: i'm very new to clojure and i'm sure I'm committing grave sins |
| 20:01 | justin_smith | not sins, just invalid function calls |
| 20:01 | dbasch | cj3kim: the important thing here: for creates a lazy sequence |
| 20:01 | cj3kim | got it |
| 20:02 | dbasch | cj3kim: you don't want a lazy sequence, you want to iterate over something for side effect |
| 20:02 | dbasch | s |
| 20:02 | justin_smith | also, it looks like, based on your error message, something in your core ns is shadowing the definition of for |
| 20:03 | dbasch | justin_smith: the error I see is legit |
| 20:03 | dbasch | he is passing 3 arguments to for |
| 20:03 | amalloy | justin_smith: yeah, that's a normal error for for |
| 20:03 | justin_smith | oh, never mind |
| 20:03 | amalloy | there's no implicit-do, because you're not supposed to do side effects |
| 20:04 | justin_smith | I thought it had an implicit do, my bad |
| 20:04 | justin_smith | I guess I never bothered trying to put more than one expression in a for |
| 20:04 | justin_smith | odd |
| 20:05 | dbasch | I do that for debugging once in a while, and wrap everything in a do |
| 20:05 | cj3kim | solved, thanks guys |
| 20:05 | cj3kim | my background is in oo javascript so clojure has been a mind fuck |
| 20:19 | Shayanjm | hiredman: I know you said not to use pmap - but it's cutting down execution time by 50% |
| 20:19 | Shayanjm | (as opposed to just throwing it into a map. Haven't experimented with a job queue yet) |
| 20:22 | hiredman | mashing the accelerator to the floor and not letting up goes fast too |
| 20:36 | tuft | maybe not an efficient way to get somewhere fast, but it does work! |
| 20:39 | danielszmulewicz | Is there not a built-in map that prunes nils? Is that a bad design idea? |
| 20:39 | hiredman | ,(doc keep) |
| 20:39 | clojurebot | "([f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects." |
| 20:41 | danielszmulewicz | hiredman: Oh, nice. Am I being disingenuous if I ask why does f has to be free of side-effects? |
| 20:42 | amalloy | danielszmulewicz: "must be free of side effects" has been sprinkled around the clojure.core docstrings as seasoning |
| 20:43 | danielszmulewicz | amalloy: Exactly my point. |
| 20:43 | danielszmulewicz | (inc amalloy) |
| 20:43 | lazybot | ⇒ 135 |
| 20:43 | danielszmulewicz | (inc hiredman) |
| 20:43 | lazybot | ⇒ 48 |
| 20:43 | amalloy | it's not any more true for keep than it is for map, which is to say you should be careful with side effects as always, but nothing drastic will happen if you ignore that warning |
| 20:45 | danielszmulewicz | amalloy: Very true. The docstrings were always throwing me off. What? I can't do that? But it is exactly what I need! Now I just ignore them, but like you say, act with caution. |
| 20:49 | danielszmulewicz | ,(false? nil) |
| 20:49 | clojurebot | false |
| 20:49 | danielszmulewicz | ,(if nil "ee" "rr") |
| 20:49 | clojurebot | "rr" |
| 20:49 | danielszmulewicz | jeez |
| 20:49 | danielszmulewicz | or should I say wat? |
| 20:56 | rplaca | danielszmulewicz: |
| 20:56 | rplaca | ,(true? "hello") |
| 20:56 | clojurebot | false |
| 20:57 | rplaca | ,(if "hello" "ee" "rr") |
| 20:57 | clojurebot | "ee" |
| 21:01 | danielszmulewicz | rplaca: exactly. |
| 21:01 | rplaca | also: |
| 21:01 | rplaca | ,(nil? false) |
| 21:01 | clojurebot | false |
| 21:02 | danielszmulewicz | rplaca: to be included in a wat series |
| 21:02 | amalloy | danielszmulewicz: true? and false? ask "is this the boolean true [or false]", not "would this be treated as truthy or falsey in a boolean context?" |
| 21:02 | rplaca | true?, false? and nil? are equality predicates not thuthiness predicates |
| 21:02 | amalloy | you're apparently looking for ##(doc boolean) |
| 21:02 | lazybot | ⇒ "([x]); Coerce to boolean" |
| 21:02 | rplaca | *truthiness |
| 21:03 | danielszmulewicz | rplaca: all correct, but still not friendly. |
| 21:04 | rplaca | doesn't seem to difficult to me. nil and false are falsey and everything else is truthy |
| 21:04 | gfredericks | danielszmulewicz: what would you use a truthy? function for? |
| 21:04 | danielszmulewicz | http://langnostic.blogspot.co.il/2013/05/truthy-and-falsy-vs-explicit.html |
| 21:04 | amalloy | danielszmulewicz: you'd *really* be saying "wat" if (= true x) gave different results than (true? x) |
| 21:04 | rplaca | turns out to be what you want almost all the time in idiomatic code |
| 21:05 | amalloy | this is just a case of "gosh, i'm asking a question different than the one i meant to, and the computer is answering the question i'm actually asking" |
| 21:05 | danielszmulewicz | That is true. |
| 21:05 | gfredericks | I guess boolean == truthy?, and not == falsy? |
| 21:06 | gfredericks | so we already have them |
| 21:06 | gfredericks | boolean isn't strictly very useful though |
| 21:07 | gfredericks | I keep using it where I don't quite need to |
| 21:07 | danielszmulewicz | I like the "non-conclusion" of the author of this post: http://langnostic.blogspot.co.il/2013/05/truthy-and-falsy-vs-explicit.html |
| 21:09 | rplaca | It should be noted that in his empty list example, the idiomatic clojure would be (yay-nay (seq '())) |
| 21:09 | gfredericks | clojure's truthiness violates the zero-one-infinity rule |
| 21:09 | amalloy | gfredericks: aha, but without boolean how could we write pithy truthiness examples? ##(group-by boolean [true false () nil {} "" 0]) |
| 21:09 | lazybot | ⇒ {true [true () {} "" 0], false [false nil]} |
| 21:09 | gfredericks | amalloy: w000h pith! |
| 21:10 | gfredericks | test.check has an alternate truthiness paradigm internally |
| 21:10 | gfredericks | https://github.com/clojure/test.check/blob/master/src/main/clojure/clojure/test/check.clj#L29-32 |
| 21:11 | danielszmulewicz | The more I learn about Haskell, the more I'm drawn to it. So appeallingly clean and logical. |
| 21:14 | amalloy | gfredericks: that is weird as heck. it's hard to imagine it being used in a way that doesn't make it hard to write tests for which returning (not throwing) exceptions is the expected behavior |
| 21:14 | rplaca | gfredericks: did Reid get that from quick-check or did he do it to fit what he was doing? |
| 21:15 | ybit2 | https://github.com/swannodette/om/wiki/Conceptual-overview |
| 21:15 | ybit2 | """Functional programming is not a silver bullet but its emphasis on unadorned data is a guiding light. No models.""" |
| 21:15 | ybit2 | would someone mind explaining this? |
| 21:16 | rplaca | gfredericks: oh - but you don't *always* have to use that, do you? |
| 21:16 | ybit2 | https://github.com/heath/treemap/blob/master/app/models/trees.coffee |
| 21:16 | ybit2 | i'm not validating the data passed around |
| 21:17 | oskarkv | ybit2 what is it that you don't understand, about that quote? :P |
| 21:19 | oskarkv | I'm going to bet, but ybit2 you might wanna watch this http://www.infoq.com/presentations/Value-Values |
| 21:19 | ybit2 | i'm not entirely sure why you wouldn't need models, i think the answer for "what goes in its place" is "persistent data structures" |
| 21:19 | oskarkv | bed* :P |
| 21:19 | gfredericks | amalloy: that's my reaction too, but considering that the tests are supposed to be predicate-like, I don't think there's any realistic use for that |
| 21:20 | gfredericks | or at least wrapping it in boolean is an easy workaround |
| 21:20 | gfredericks | rplaca: it's an internal function, the user doesn't use that at all; but amalloy is right that if your test returns an exception it will be misinterpreted |
| 21:22 | rplaca | ahh, interesting |
| 21:22 | gfredericks | it's exactly as inhibiting as if (is (Exception. "")) fails |
| 21:23 | oskarkv | ybit2 I'm not entirely sure about the "No models" thing. :P It leaves much to the imagination. |
| 21:24 | ybit2 | hah :) |
| 21:24 | ybit2 | he was saying that facts have "set" methods |
| 21:24 | ybit2 | i'm so glad that was a joke :) |
| 21:24 | oskarkv | hehe yeah |
| 21:24 | gfredericks | Integer#setPositive |
| 21:25 | amalloy | gfredericks: i'm really surprised that someone who wrote a monad-based testing library would do that. like, surely it's possible to build an Either Result Failure, and know the difference between (Left (Exception.)) and (Right (Exception.)) |
| 21:26 | gfredericks | amalloy: I actually wrote that function, but was just refactoring some logic that was already there; but yeah I agree |
| 21:26 | gfredericks | I was thinking of making a microlibrary with that the other day |
| 21:26 | gfredericks | ,(defrecord Either [val ex]) |
| 21:26 | clojurebot | sandbox.Either |
| 21:27 | gfredericks | wait that doesn't work :P |
| 21:27 | gfredericks | ,(defrecord Either [val ex?] clojure.lang.IDeref (deref [_] (if ex? (throw val) val))) |
| 21:27 | clojurebot | sandbox.Either |
| 21:28 | gfredericks | ,(defmacro eitherly [ex-class expr] `(try (Either. ~expr false) (catch ~ex-class e# (Either. e# true)))) |
| 21:28 | clojurebot | gfredericks: Pardon? |
| 21:28 | gfredericks | clojurebot: fine. |
| 21:28 | clojurebot | Cool story bro. |
| 21:29 | reiddraper | gfredericks: amalloy: one of you mind filing an issue? |
| 21:29 | gfredericks | amalloy: dangit now look what you did |
| 21:30 | reiddraper | :D |
| 21:30 | gfredericks | reiddraper: should we have a whole namespace with some Either functions? |
| 21:30 | amalloy | gfredericks: it's either that or nothing |
| 21:31 | reiddraper | I agree that returning an exception should not count as a failure |
| 21:32 | gfredericks | amalloy: MULTIMONADIC PUN |
| 21:33 | amalloy | forever $ putStrLn "lol" |
| 21:36 | blur3d | has anyone had problems with maps/deref working properly in async/go blocks? |
| 21:36 | blur3d | actually.. let me update some dependancies first |
| 21:37 | hiredman | ~anyone |
| 21:37 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 21:38 | blur3d | hiredman: can you rephrase the above into an example message? |
| 21:38 | hiredman | "I got error message X, what am I doing wrong?" |
| 21:39 | blur3d | sure, but in this case there is no error |
| 21:39 | amalloy | blur3d: "when i do X in a go block, Y happens, which makes me think something is wrong with deref" |
| 21:39 | danielszmulewicz | "Thruthiness" is not a thing. It is subjective and language-dependent. Logical truth is objective and can be reasoned about without intermediate or underlying implementation details. That's what bothers me. |
| 21:39 | blur3d | and it is likely a dependancy bug |
| 21:39 | hiredman | "I have problem X, what am I doing wrong?" |
| 21:40 | blur3d | not sure I agree still, but let me check dependancies before I try again |
| 21:40 | hiredman | having problems with X is the general state of programming, if you want to really discuss things you need to be more specific |
| 21:41 | hiredman | the most specific being a pastebin of code and a description of the problem you have with it |
| 21:42 | amalloy | hiredman: i feel compelled to come up with more specific problem statements |
| 21:43 | hiredman | amalloy: huh? |
| 21:43 | amalloy | "here is a snapshot of a VM; if you boot it up and do xyz, you'll encounter problem abc" |
| 21:43 | amalloy | (more specific than a pastebin of some code) |
| 21:44 | hiredman | amalloy: the purpose of the pastebin of code is so others can read it, not execute it |
| 21:44 | hiredman | I've never tried to read a vm to determine what will happen when I boot it |
| 21:48 | hiredman | oh man, I just had an idea |
| 21:49 | hiredman | imagine an irc room for writers, who are, you know, working on their prose |
| 21:49 | gfredericks | danielszmulewicz: truthiness is how dynamically typed languages deal with the possibility of arbitrary objects being used in a condition |
| 21:50 | hiredman | and they never share what they have actually written for review, they just sort of trade vague descriptions of their work to see what others think |
| 21:50 | gfredericks | danielszmulewicz: the only way to avoid partitioning things into truthy and falsy is to throw an exeception when non-booleans are used |
| 21:51 | hiredman | "I have this chapter, it is written in the third person, but I don't think it works, what should I do?" |
| 21:51 | hiredman | "have you tried showing and not telling?" |
| 21:52 | gfredericks | "does anybody here have experience with alternating between first-person and third-person each chapter?" |
| 21:52 | hiredman | "I killed my pov character, but there is more story to tell, what do I do?" |
| 21:54 | catern | haha |
| 21:54 | amalloy | "i've been practicing by reading moby dick, and i think it would be better without the whale. can someone help me do that?" |
| 21:54 | catern | "Whenever I read one of my chapters I get a NoPlotFoundException, can anyone help?" |
| 21:55 | gfredericks | amalloy: "you thinking about it all wrong" |
| 21:56 | danielszmulewicz | gfredericks: Very interesting. Truthiness is a property then, not a value. When it is encoded in a type, you don't need to infer that property. I'm just wondering how more convenient that is in practice. I wish people with experience with Haskell could weigh in. |
| 21:56 | rplaca | danielszmulewicz: thuthiness may not be a thing but defining in a way that fits with the other paradigms of the language can lead to cleaner, more readable code |
| 21:56 | gfredericks | danielszmulewicz: well statically typed languages avoid the issue altogether since they can enforce booleans-only at compile time |
| 21:56 | gfredericks | does scala do that? |
| 21:57 | hiredman | writing prose continues to be my favorite analog for writing code |
| 21:57 | rplaca | dynamic laguages could do that to (just like Clojure won't do + except on numbers) |
| 21:57 | amalloy | danielszmulewicz: haskell doesn't really care about truthiness, because using booleans is not super-common; you just pattern-match on stuff |
| 21:58 | rplaca | but everyone would just be annoyed by it :) |
| 21:58 | amalloy | Bool and if aren't language built-ins; the former is just `data Bool = True | False`, and if is just `if :: Bool -> a -> a -> a; if True t _ = t; if False _ f = f` |
| 21:59 | amalloy | (well, it's not *really* that, because of the if/then/else syntax. but it could be) |
| 22:00 | danielszmulewicz | One thing is for sure: truthiness is not spread across dynamic languages in a uniform way, which means that in practice you need to remember language-specific things when dealing with conditions. Annoying. |
| 22:01 | rplaca | danielszmulewicz: true, but it's more important that it fit the paradigm of the specific language. |
| 22:01 | rplaca | and it's not *that* hard to remember if you're writing more than a few lines of code in the language |
| 22:02 | amalloy | if every language were the same, they'd all be the same. what fun would that be? |
| 22:06 | danielszmulewicz | amalloy: I'm still stuck in the fantasy of the "ultimate" language. I should get over it...but only after learning Haskell :-) |
| 22:11 | geardev | is a multi-method kind of like pattern matching in haskell? |
| 22:11 | gfredericks | what they don't tell you is that after learning haskell you have to start wanting to learn idris |
| 22:11 | gfredericks | geardev: it has some overlap; multimethods support inheritance in a couple ways too |
| 22:12 | gfredericks | another big difference is that multimethods are open |
| 22:12 | danielszmulewicz | gfredericks: spot on. Very true. Dependent types is the next thing. |
| 22:12 | danielszmulewicz | gfredericks: there's no end. |
| 22:13 | geardev | multimethods are like pattern matching, but they also have inheritance |
| 22:14 | gfredericks | actually any similarity to pattern matching is pretty shallow |
| 22:17 | Frozenlock | bbloom: I updated cljs for a project and I get weird errors which seem related to metadata. Do you know if there was some mentions of problems for metadata recently? (say since 0.0-2173) |
| 23:23 | halogenandtoast | If anyone is feeling particularly generous, I’m trying to write a game in which cards are dealt to players but I can’t seem to get the logic right. Currently I get “clojure.lang.Cons cannot be cast to clojure.lang.IF” at I think line 57 of https://gist.github.com/halogenandtoast/58cf169f271d49f69005 but haven’t been able to figure out why. I bet there are a number of things I’m doing wrong so any help would be |
| 23:23 | halogenandtoast | much appreciated. |
| 23:24 | trptcolin | ,(doc update-in) |
| 23:24 | clojurebot | "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created." |
| 23:25 | trptcolin | halogenandtoast: update-in wants the thing where you have `new-hand` to be a function |
| 23:25 | trptcolin | that’s what the “clojure.lang.Cons cannot be cast to clojure.lang.IFn” error msg is trying to tell you |
| 23:26 | halogenandtoast | trptcolin: makes sense. |
| 23:27 | halogenandtoast | it almost works now, the conj doesn’t really like my values but I can work with that. |
| 23:28 | halogenandtoast | switched conj to into, much better |
| 23:29 | halogenandtoast | Thanks trptcolin |
| 23:29 | trptcolin | halogenandtoast: sure. |
| 23:29 | halogenandtoast | I feel like most of what I wrote could be more succint, but I’m just not there yet. |
| 23:31 | trptcolin | yeah, if you wanted you could probably collapse those 3 lines with the `let`s into 1 with update-in, something like (update-in state [:players player-number :hand] into cards) |
| 23:32 | halogenandtoast | Yeah the let for the hand isn’t used. |
| 23:32 | halogenandtoast | (update-in state [:players player-number :hand] #(into cards %)) |
| 23:34 | trptcolin | ah right you want cards first |
| 23:34 | halogenandtoast | At least I think I do, the whole functional aspect of this is warping my brain. |
| 23:35 | trptcolin | nice. it gets easier |
| 23:37 | halogenandtoast | I’d imagine. I figured this would be a good exercise to start understanding clojure. |
| 23:39 | trptcolin | cool, yep |