2014-05-17
| 00:11 | emacsnoob | Emacs Live help. I opened a core.clj file from a Leiningen project in Emacs Live then M-x cider-jack-in but still getting nRepl not connected error when tryiung to evaluate forms |
| 00:34 | ty_hayden | Test |
| 00:58 | kenrestivo | hmm, i wonder if openjdk will be forced to disappear now? i kind of like using it, or at least having the choice vs the oracle java, for clojure projects |
| 01:01 | arrdem | well... Oracle owns Java (and apparently the Java API/JVM) so they're the first ones to fall if they start closing off their platform. |
| 01:02 | arrdem | Wouldn't be the first time they've shot themselves in the face WRT open source software. |
| 01:18 | arrdem_ | arrdem: ping |
| 01:31 | TEttinger | kenrestivo: what is this about openjdk disappearing? |
| 01:32 | kenrestivo | TEttinger: dunno, just saw the oracle vs google lawsuit result and wondered what that means for openjdk |
| 01:32 | TEttinger | they solved it? |
| 01:32 | kenrestivo | broke it |
| 01:33 | kenrestivo | apparently in this case the API is copyrightable (not all cases, just this one), if i'm reading it right |
| 01:33 | kenrestivo | so yeah, if i ended up in a world where "to use clojure you must buy a license from oracle" i'd be unhappy |
| 01:34 | kenrestivo | looking a couple steps ahead into the future, that is. |
| 01:35 | TEttinger | more likely, there'd be some new licensing scheme for OSS code that makes the friggin' API open source... grumbling about why it's needed... |
| 01:36 | Pandachips | Read the verdict, just.. wow. |
| 01:36 | kenrestivo | yep. i hope the OSS world routes around this as if it were damage (which, in my view, it is) |
| 01:36 | arrdem | Well 1) Google's gonna appeal. 2) Oracle can't really turn around and sue anyone else until they've beaten Google fair and square (or however lawyers beat people) |
| 01:37 | arrdem | so... who knows. |
| 01:37 | TEttinger | the damages could also be 0 dollars |
| 01:38 | kenrestivo | yeah, hard to say. i used to follow the world of free software very closely, was a bit of an activist, EFF and FSF supporter, but haven't been paying attention in recent years. stuff like this makes me stick my head up and wonder if i need to pay attention again |
| 01:39 | arrdem | can I get a ping? testing irssi notifications |
| 01:39 | kenrestivo | arrdem: yo |
| 01:39 | arrdem | kenrestivo: cheers. working. |
| 01:41 | kenrestivo | arrdem. glad to help. irssi + znc + notification-daemon here. (also andchat on phone and yaaic on tablet, etc) |
| 01:42 | arrdem | kenrestivo: ah. I'm running irssiproxy on the server I'm connected from and then using erc over a vpn to get to it. |
| 04:21 | TerranceWarrior | patent a vm? just change the mnemonic labels of the vm. |
| 04:59 | kzar | Kind of dumb question but I'm trying to figure out how to make an infinite sequence of different combinations of a sequence. Say given the input "abc" you'd get [[\a] [\b] [\c] [\a \a] [\a \b] ...] |
| 05:00 | kzar | I'm trying to do it in a way that doesn't blow up when things get huge. How I was doing it before I think I mapped the previous items adding the new ones but at a certain point it got too much for my computer |
| 08:10 | zerokarmaleft | kzar: (mapcat #(clojure.math.combinatorics/selections "abc" %) [1 2 3]) |
| 08:15 | clgv | $karma zerokarmaleft |
| 08:15 | lazybot | zerokarmaleft has karma 0. |
| 08:19 | wagjo | (inc zerokarmaleft) |
| 08:19 | lazybot | ⇒ 1 |
| 08:19 | zerokarmaleft | I don't feel right |
| 08:20 | wagjo | (dec zerokarmaleft) |
| 08:20 | lazybot | ⇒ 0 |
| 08:20 | zerokarmaleft | better! |
| 08:30 | scape_ | how many threads is core.async willing to use on a system when using go blocks? I counted 58 on mine which more than I expected |
| 08:31 | scape_ | unless I am trying to figure this out using an incorrect method |
| 08:31 | scape_ | https://www.refheap.com/85568 |
| 08:36 | dongl | hi folks. I want to implement a kind of clojure for educational purposes, and trying to do by small steps with tests. How would you go about implementing the compiler or reader? |
| 08:38 | scape_ | dongl: take a look first at eval and read-string. might get you started, until someone wakes up :) |
| 08:38 | dongl | I'd like as a first step for it to evaluate a number to itself, and run adding of integers, so I want to test that '4' evaluates to 4, and (+ 2 3) evaluates to 5. Not sure "evaluate" is the right term. |
| 08:38 | scape_ | also macroexpand, which helps you understand how many of the core clojure methods expand and look like internally |
| 08:40 | scape_ | perhaps assert will be of help? |
| 08:40 | scape_ | ,(assert (= 4 4)) |
| 08:40 | clojurebot | nil |
| 08:40 | scape_ | ,(assert (= 4 3)) |
| 08:40 | clojurebot | #<AssertionError java.lang.AssertionError: Assert failed: (= 4 3)> |
| 08:40 | zerokarmaleft | dongl: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html#%_sec_4.1 |
| 08:40 | zerokarmaleft | for scheme, but the concepts transfer easily |
| 08:41 | dongl | scape_: maybe. I'll look at your references. I just want a first step that reads a .clj file with "4" or (+ 2 2) etc. |
| 08:41 | dongl | zerokarmaleft: i'll have a look |
| 08:41 | clgv | dongl: what exactly is your educational goal? |
| 08:42 | clgv | which java matrix library is recommended with respect to calculation speed? |
| 08:42 | dongl | clgv: to understand clojure better and how it's built. I can read the source and commits but I want to try myself |
| 08:43 | dongl | I mean, I read the source and commits, but I need the actual writing to internalize it |
| 08:43 | clgv | dongl: I'd write applications/algorithms with it for that goal |
| 08:43 | clgv | well in fact I did ;) |
| 08:45 | scape_ | dongl: read-string would technically read a file, using slurp to parse the text. then eval would evaluate |
| 08:45 | clgv | scape_: why not just use `read` together with clojure.java.io/reader? |
| 08:46 | scape_ | because it seems like he wants to do this step-wise clgv .. altogether seems slightly silly since it's not as common as just learning at the repl itself |
| 08:46 | scape_ | but that's my opinion :) |
| 08:47 | clgv | huh what? |
| 08:47 | dongl | i already know clojure. I want to understand it under the hood |
| 08:47 | gfredericks | ways of learning are not silly just by virtue of being uncommon |
| 08:48 | clgv | gfredericks: you got any idea what java matrix lib is preferrable? |
| 08:48 | gfredericks | I don't think I've ever used any of them |
| 08:50 | gfredericks | dongl: what do you mean by implementing a compiler? you want to compile your own simple variant of clojure to proper clojure? or to something else? |
| 08:53 | dongl | gfredericks, i guess i want to compile it to whatever clojure is compiled to. |
| 08:54 | gfredericks | that's jvm bytecode |
| 08:54 | dongl | or at least interpreted as a first step |
| 08:54 | gfredericks | that's a much easier first step :) |
| 08:54 | dongl | ok, so that one. |
| 08:55 | gfredericks | would you rather start by writing your own reader, or use clojure's reader and write your own interpreter? |
| 08:57 | dongl | gfredericks: I'm not sure. I want to pretend clojure isn't available as a tool |
| 08:58 | dongl | But I see rich himself used lisp |
| 08:58 | gfredericks | but you're going to write this code in clojure? or in something else? |
| 09:01 | kzar | zerokarmaleft: Sorry was afk there, thanks for the tip |
| 09:02 | dongl | gfredericks, my constraint is that i can't use clojure and i write the runtime in java |
| 09:03 | dongl | i will use my clojure variant as soon as i can bootstrap it though |
| 09:04 | clgv | dongl: I see you ending up copying frustatedly clojure's java impl ;) |
| 09:04 | dongl | i might :) |
| 09:06 | dongl | what i usually do is decide on some differences. For example, I want everything to be a function, including values. I don't know where it will take me |
| 09:13 | zerokarmaleft | dongl: could try gutting Compiler.java, leaving the most primitive bits and adding stuff selectively back in |
| 09:15 | crispin | greetings all! |
| 09:17 | dongl | zerokarmaleft: very interesting |
| 09:17 | crispin | I'm having problems with java interop |
| 09:18 | crispin | there are two static methods of the same arity, but different types |
| 09:18 | crispin | and clojure keeps calling the second one, and I want to call the first |
| 09:18 | crispin | I want to call this: http://rsb.info.nih.gov/ij/developer/api/ij/IJ.html#createImage(java.lang.String, int, int, int, int) |
| 09:18 | crispin | but it calls the following one |
| 09:18 | crispin | both are 5 arity |
| 09:19 | crispin | heres my code: https://bitbucket.org/retrogradeorbit/jamtools/src/1b0ac63c28991be06a4efa00f10d88723515aba0/src/jamtools/core.clj?at=master |
| 09:19 | crispin | line 69 |
| 09:19 | crispin | I create the right types, but I get java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String |
| 09:20 | crispin | how can I call the first createImage static method? |
| 09:21 | dongl | LispReader.java is also interesting. Anyway, I have a lot to look at now. Thanks people |
| 09:22 | clgv | crispin:first switch on *warn-on-reflection* then add type hint for string and add conversions for int |
| 09:23 | crispin | I have int conversions. Will add the others |
| 09:25 | crispin | how do I hint the string? |
| 09:25 | clgv | ^String |
| 09:25 | crispin | ^String and #^String dont work |
| 09:25 | crispin | do I need them in a vector? |
| 09:25 | crispin | Im getting Metadata can only be applied to IMetas |
| 09:25 | clgv | crispin: line 69? |
| 09:26 | crispin | (IJ/createImage ^String "scaled" (int (* w scale)) (int (* h scale)) (int 1) (int depth)) |
| 09:26 | crispin | yeah |
| 09:26 | clgv | no there is string constant you dont need a type hin then ;) |
| 09:26 | clgv | it should work as is |
| 09:26 | crispin | ok. then its not working :P |
| 09:26 | clgv | do you get any reflection warnings? |
| 09:26 | crispin | readong up on how to switch that on now |
| 09:27 | clgv | (set! *warn-on-reflection* true) |
| 09:27 | clgv | then recompile the namespace |
| 09:27 | clgv | or just that function |
| 09:28 | crispin | ok got a bunch |
| 09:28 | crispin | but on other lines |
| 09:28 | clgv | well then that line should work. you can aot compile that namespace and check with a java decompiler that the correct method is called... |
| 09:29 | crispin | ok let me see |
| 09:31 | crispin | man I used one recently but I forgot its name |
| 09:32 | clgv | procyon with luyten? |
| 09:32 | clgv | jd-gui? |
| 09:33 | crispin | trying procyon |
| 09:33 | crispin | i think that was it |
| 09:33 | clgv | luyten is GUI for it |
| 09:38 | crispin | yep its calling the wrong one |
| 09:38 | crispin | $ java -jar ~/Downloads/procyon-decompiler-0.5.25.jar target/classes/jamtools/core\$_main.class | grep createImage final Object scaled = IJ.createImage((String)"scaled", (String)RT.intCast(Numbers.multiply((long)w, scale)), RT.intCast(Numbers.multiply((long)h, scale)), RT.intCast(1L), RT.intCast(depth)); |
| 09:39 | crispin | the second (String) intCase |
| 09:39 | crispin | intCast |
| 09:39 | crispin | do I need an int type hint, on my int? |
| 09:40 | crispin | nope that didn't work |
| 09:41 | crispin | is it the ij clojar? |
| 09:51 | crispin | ok. tried changing the dep from a clojar ij library to the actual maven one |
| 09:51 | crispin | no difference. Still calling the wrong method. |
| 09:55 | clgv | crispin: no that might be a clojure bug, the auto cast to string |
| 09:55 | clgv | crispin: are you sure you have the correct version of the library where both methods exist? |
| 10:02 | crispin | ok I think I got it |
| 10:02 | crispin | I decompiled IJ.class |
| 10:02 | crispin | and there is only one static method createImage |
| 10:03 | crispin | so the docs are wrong and clojure is working ok |
| 10:03 | clgv | crispin: maybe the library version you have is outdated or newer than the docs |
| 10:05 | crispin | yeah the api docs on the website could be old |
| 10:11 | clgv | so using MTJ (=matrix toolkits java) now |
| 10:25 | kras | HI looking for some examples of using read |
| 10:25 | kras | trying to read and EDN file |
| 10:25 | kras | an* |
| 10:32 | martinklepsch | kras (read-string (slurp "file.clj"))) |
| 10:34 | kras | martinklepsch: thank you |
| 10:35 | kras | Just stumbled on this soln on stackoverflow |
| 10:35 | kras | (with-open [rdr (reader "/Users/krajoli/gate_parser_dict/sample.edn")] (doseq [line (line-seq rdr)] (println line))) |
| 10:35 | kras | trying to understand why we need a doseq here? |
| 10:36 | kras | although martinklepsch soln is what I need exactly |
| 10:39 | martinklepsch | the reader line-seq reads the file line by line, slurp just reads the complete file at once |
| 10:43 | clgv | there is a significant fetish for slurp it seems |
| 10:45 | clgv | (read (clojure.java.io/input-stream "file.clj")) |
| 10:46 | clgv | ah well better use with-open around that ;) |
| 10:46 | scape_ | :) |
| 10:47 | clgv | (with-open [s (clojure.java.io/input-stream "file.clj")] (read s)) |
| 10:48 | kzar | Can you destructure a list to get all but the last items, the last item and then the entire list? |
| 10:50 | scape_ | drop-last and pop may help |
| 10:50 | scape_ | or peek rather |
| 10:50 | clgv | scape_: no peek does that only for a vector ;) |
| 10:50 | clgv | kzar: no you can not |
| 10:50 | clgv | kzar: not via destructuring I mean |
| 10:51 | kzar | OK |
| 10:51 | kzar | ty |
| 10:51 | scape_ | oh right clgv |
| 10:54 | clgv | kza: but if you had a vector and not a list you could efficiently (i.e. in constant time) build all these 3 values |
| 10:54 | clgv | kzar: ^^ |
| 10:54 | clgv | kzar: for a list you'll need linear time |
| 10:55 | kzar | clgv: Cool OK I'll use a vector |
| 10:55 | kzar | :) ty |
| 10:56 | clgv | kzar: you'll need peek and pop |
| 11:08 | kzar | Is there something like repeatedly that passes in the result from the last call into the next one? |
| 11:10 | noidi | ,(doc iterate) |
| 11:10 | clojurebot | "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects" |
| 11:10 | kzar | noidi: Ah thanks |
| 12:13 | kzar | any ideas? https://gist.github.com/kzar/a4a5bfec3105da6077ab |
| 12:13 | kzar | (When I call my function manually each time it works OK but using iterate like shown it blows up) |
| 12:26 | justin_smith | kzar: concat creates a seq |
| 12:26 | justin_smith | you want to keep things vectors to use peek and pop |
| 12:27 | kzar | ,(concat [1] [2]) |
| 12:27 | clojurebot | (1 2) |
| 12:27 | kzar | ahh |
| 12:27 | justin_smith | that's what that exception means - it is saying that you are trying to peek or pop on a seq |
| 12:28 | kzar | justin_smith: there a more elegant way than (conj (conj [1] 0) 0) ? |
| 12:28 | kzar | ,(conj [1] 0) 0) |
| 12:28 | clojurebot | [1 0] |
| 12:28 | kzar | oops |
| 12:28 | kzar | ,(conj (conj [1] 0) 0) |
| 12:28 | clojurebot | [1 0 0] |
| 12:29 | kzar | sweet it's working :) |
| 12:30 | tudd | does anyone know much about java interop: specifically around gen-class |
| 12:31 | ddellacosta | tudd: go ahead and ask and see. ;-) |
| 12:31 | tudd | does :exposes-methods only expose protected superClass Methods.. |
| 12:32 | scape_ | ,(conj [1] 0 0) |
| 12:32 | clojurebot | [1 0 0] |
| 12:32 | kzar | oh cool |
| 12:32 | kzar | ty |
| 12:33 | ddellacosta | tudd: as opposed to private? Sorry, I don't know... |
| 12:33 | tudd | referencing this: https://groups.google.com/forum/#!msg/clojure/H0jg1PQulf0/BnswT4OheLUJ and http://clojuredocs.org/clojure_core/clojure.core/gen-class |
| 12:34 | tudd | I have a protected Java method ... clojure can find the class but not the method. don't know why... |
| 12:34 | tudd | and can find the public methods just fine... |
| 12:35 | scape_ | ,(reduce conj [1] [0 0]) |
| 12:35 | clojurebot | [1 0 0] |
| 12:37 | justin_smith | ,(apply conj [1] [0 0]) another case where apply and reduce do the same thing |
| 12:37 | clojurebot | [1 0 0] |
| 12:37 | scape_ | good point |
| 12:38 | tudd | actually just trying to roll a clojure wrapper around bitcoinj : https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/com/google/bitcoin/kits/WalletAppKit.java line 185 |
| 12:40 | tudd | via https://github.com/tuddman/bitcljoin/blob/master/src/bitcoin/walletappkit.clj line 32 |
| 12:44 | sritchie | hey all - has anyone here checked out ztellman's new automat library? |
| 12:45 | amalloy | sritchie: i proofread the readme, but haven't tried actually using it |
| 12:46 | sritchie | amalloy: I'm writing some code to manage state transitions for various payment transfers to-from stripe, a bank acct, paypal, etc |
| 12:47 | sritchie | amalloy: I'm having trouble figuring out how to map the automat concepts onto a stateful representation - for example, loading up a map out of a database and defining other database operations as state transitions |
| 12:48 | bja | in the past, Clojurescript seemed to support compiling .cljs files without namespaces (essentially limiting you to the core language and js interop). Is this still available somehow? |
| 12:48 | sritchie | ztellman mentioned in his announcement that he wanted to see folks use this for complex logic on websites - the conceptual leap is pretty big, was hoping to track him down in here |
| 12:48 | sritchie | it's clearer how to use https://github.com/cdorrat/reduce-fsm, for example |
| 14:08 | robink | I'm trying to read in a large hashmap (clojure.lang.PersistentArrayMap, hash-map, {}) from a file using edn, but when I do, Clojure complains: "CompilerException java.lang.RuntimeException: Map literal must contain an even number of forms, compiling:(form-init4894105984598281844.clj:1:10)". I'm pretty sure the file (generated with (with-open [edf (io/writer "./outputfile.edn")] (binding [*out* edf] (pr mybighashmap))) ) has an even number of forms in |
| 14:08 | robink | the {}, but I'm not completely sure. Would there be something other than an uneven number of forms in a serialized hashmap that would cause that problem? |
| 14:10 | Bronsa | robink: you probably have *print-length*c set |
| 14:10 | Bronsa | ,(binding [*print-length* 2] (pr {:a 1 :b 2 :c 3})) |
| 14:10 | clojurebot | {:c 3, :b 2, ...} |
| 14:11 | robink | Bronsa: Oh! |
| 14:11 | robink | Bronsa: I had no idea pr limited itself |
| 14:13 | robink | Hm, except there's no ... in the EDN output file |
| 14:16 | robink | Bronsa: and *print-length* nil |
| 14:16 | robink | s/\snil/\ is\ nil/ |
| 14:17 | Bronsa | robink: then it might be something like ##(pr {(symbol "foo bar") 1}) |
| 14:17 | lazybot | ⇒ {foo bar 1}nil |
| 14:17 | robink | hm |
| 14:22 | robink | Huh, works now |
| 14:22 | robink | I'll just scrap the files that didn't parse |
| 14:22 | robink | maybe I interrupted pr when I was writing the older edn file. |
| 14:23 | robink | and the close brace I'm looking at belongs to a child of the root {} |
| 14:23 | lemonodor | it does seem like it would be nice to have an edn-writing function, or even just something like CL’s with-standard-io-syntax |
| 14:27 | robink | but I'm definitely interested in edn as a way to pass data around between different Clojure(Script) processes or other languages that have EDN support. |
| 14:29 | robink | Beats the heck out of Bencode or PHP's serialize. |
| 14:29 | robink | I mean, give them points for succinctness but they're pretty ugly formats |
| 17:39 | Glenjamin | i never really understood what EDN brought over json |
| 17:42 | bbloom | Glenjamin: a big part is right in the name: E is for Extensibility |
| 17:42 | bbloom | how do you encode a date in json? |
| 17:42 | whodidthis | + not just stoppid string keys in maps |
| 17:43 | Glenjamin | bbloom: i've seen that argument - but what is the difference between "something_date": "2014-01-01" and :something_date #inst 2014-01-01 |
| 17:43 | Glenjamin | either way, i need out of band information to know what to *do* with the date |
| 17:43 | bbloom | in the former case, you need out of band information about the schema. in the later case you need out of band information about the "inst" tag |
| 17:44 | Glenjamin | but to do anything clever with a date value, i'd need to know what it represents - the schema |
| 17:45 | bbloom | but where does that cleverness go? |
| 17:45 | Glenjamin | into the application i guess |
| 17:45 | bbloom | and that's a problem... |
| 17:45 | bbloom | the important bit is that extensible tags create a phase shift |
| 17:46 | bbloom | if your application cares about dates, or uuids, or precise fixed point numbers, or database connection strings, or whatever other thing you make up.... |
| 17:46 | bbloom | you can address the data conversion ONCE rather than at each location you interpret data |
| 17:47 | bbloom | inst is interpreted at read time, not at data analysis time |
| 17:47 | bbloom | for example |
| 17:47 | bbloom | ,(class (quote #inst "2014-01-01")) |
| 17:47 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 17:47 | Glenjamin | but that's just a richer deserialisation abstraction, isnt it? |
| 17:47 | bbloom | Glenjamin: sure, but json doesn't offer that capability |
| 17:47 | bbloom | and it's an important one |
| 17:48 | bbloom | &(class (quote #inst "2014-01-01")) |
| 17:48 | lazybot | ⇒ java.util.Date |
| 17:48 | bbloom | clojurebot: get your shit together |
| 17:48 | clojurebot | Excuse me? |
| 17:49 | Glenjamin | so edn readers are forced to have a richer deserialiser, whereas with json you'd have to choose to do that |
| 17:49 | Glenjamin | and it would be implementation specific |
| 17:49 | Glenjamin | i can see that |
| 17:50 | bbloom | Glenjamin: no, you can't choose that with json |
| 17:50 | bbloom | how would you choose that? |
| 17:50 | lemonodor | you write a read-data function that reads JSON then applies further semantics. |
| 17:51 | Glenjamin | (expand-types (parse-json '{"abc": "#inst 2014-01-01"}')) |
| 17:51 | bbloom | and if i want a string that starts with #inst ? |
| 17:51 | Glenjamin | fair point |
| 17:52 | bbloom | there are many other wrong solutions one could propose too |
| 17:53 | bbloom | such as looking at keys for a regex /_date$/ -- what happens if i want a date in an array? |
| 17:53 | lemonodor | i think offering some additional data types as standard is useful. though i wonder about the utility of #uuid. |
| 17:53 | Glenjamin | lemonodor: #whatever is extensible itself |
| 17:54 | lemonodor | right, i’m just wondering what motivated someone to include #uuid in edn. |
| 17:54 | bbloom | *shrug* i use uuids rarely, but often enough for it to be annoying that json can't represent them as a unique type |
| 17:54 | scottj | lemonodor: datomic. |
| 17:54 | lemonodor | ah |
| 17:55 | bbloom | plus rich did C# development for many years... spend enough time with COM and you'll be acutely aware of how many systems can't handle tagged 128 numbers :-P |
| 17:55 | Glenjamin | i'm sold that edn is richer, but i still think that you'll have a part of your application responsible for handing incoming serialised data |
| 17:55 | Glenjamin | and that part will know about the schema, and how to hydrate into application supported data |
| 17:56 | Glenjamin | and it seems to me that would cancel out the advantages |
| 17:56 | Jaood | Glenjamin: you mean is less practical? |
| 17:57 | Glenjamin | Jaood: i'm not sure what you mean - which statement are you referring to? |
| 17:58 | bbloom | what about intermediate processes that don't know anything about the schema but still want to offer useful tools? |
| 17:58 | Glenjamin | thats an interesting angle i hadn't considered |
| 17:58 | bbloom | what about when the schema changes? |
| 17:58 | lemonodor | i don’t underestimate the value of a a literal syntax that supports a rich set of types. i feel like one of the best things about programming these days is how many languages finally have a syntax for map literals. |
| 17:59 | bbloom | should i always have to support /_date$/ keys even when somebody adds /_time$/ or /_at$/ suffixes? |
| 17:59 | lemonodor | i had to listen to common lispers argue that i didn’t need that since you could extend the lisp reader to build hash tables from a custom syntax. |
| 18:00 | bbloom | the CL reader seems silly to me |
| 18:00 | lemonodor | …for far too long |
| 18:00 | Glenjamin | i'm saying i'm unconvinced by generic rich data serialisation, because IME you need schema knowledge to interpret rich data |
| 18:00 | bbloom | why have programability if you're not going to go all out? if you have some gimpy weak progamable parser, might as well just cut the power off & gain features... like reliable universal tagging of literals & context-free parsing |
| 18:00 | Glenjamin | it wouldn't be /_date$/, it'd be "created_date" => (parseDate) |
| 18:01 | bbloom | Glenjamin: right... until you want "important_dates": [....] |
| 18:02 | bbloom | none of the techniques for interpreting data are invalidated by having extensible tagging |
| 18:02 | bbloom | but entire classes of data decoding problems GO AWAY for the 90+% use cases |
| 18:03 | Glenjamin | presumably for any incoming data you still need to do a validation pass |
| 18:03 | bbloom | nevermind the fact that JSON can't even handle the most basic of deserialization tasks |
| 18:04 | Glenjamin | since it's untrusted |
| 18:04 | Glenjamin | and that pass needs schema knowledge |
| 18:04 | Glenjamin | anyway, you have convinced me that edn has advantages i hadn't considered |
| 18:05 | bbloom | > JSON.parse('23372036854775807') |
| 18:05 | bbloom | 23372036854775810 |
| 18:05 | bbloom | whoops! |
| 18:05 | Glenjamin | heh, that's a javascript issue |
| 18:05 | bbloom | which JSON inherits |
| 18:05 | Glenjamin | yeah, i see your point there |
| 18:06 | Glenjamin | of course, if you're sending it to clojurescript you can't win there |
| 18:07 | bbloom | Glenjamin: but if you "fix" JSON, you're no longer spec conforming |
| 18:07 | Glenjamin | can you put comments in edn? |
| 18:07 | Glenjamin | that's one of the annoyances of json's ubiquity, people using it for config |
| 18:08 | lemonodor | i frequently want to send binary data efficiently, so i tend to start with protocol buffers anway |
| 18:09 | lemonodor | and actually, protocol buffers text format is a pretty nice way to do config... |
| 18:11 | lemonodor | lots (most?) of google’s internal config is written in protocol buffer text format |
| 18:17 | gfredericks | the edn spec says the \; character is a line comment |
| 18:17 | gfredericks | and #_ is there as well |
| 19:06 | numberten | is there a way to get a random element from an unordered collection such as a set? |
| 19:06 | numberten | 'rand-nth' only works on lists and vectors afaik |
| 19:10 | fortruce | when using mongodb + monger, should you def a global connection or use a let in every function to connect to the database? |
| 19:12 | gfredericks | numberten: well (comp rand-nth seq) would work of course, but a performant way... |
| 19:28 | amalloy | numberten: no; the way sets are stored (as trees) makes it impossible to implement a rand-nth that performs well and selects uniformly at random |
| 19:29 | amalloy | so if you want to choose at random many times, you need to pour it into a vector first |
| 19:29 | numberten | alright thanks |
| 19:41 | arkh | if I'd like to store code for later execution, e.g. (let [x [] y (conj x '(filter #(= 3 %) (range 1000)))] (comment "blah blah")) , how do I "call" it? |
| 19:41 | arkh | it's for a query engine, of sorts |
| 19:42 | gfredericks | amalloy: if the tree had counted nodes it would be doable |
| 19:42 | gfredericks | at least from inside the class |
| 19:42 | amalloy | gfredericks: right, if it were a finger tree |
| 19:43 | amalloy | i think it'd be too expensive to just add a count to one of the existing tree types? because then updating a subtree isn't isolated |
| 19:43 | dbasch | arkh: probably what you want is letfn |
| 19:44 | gfredericks | amalloy: isolated? like in a threading sort of way? |
| 19:44 | dbasch | arkh: or inside your let, y should be a fn |
| 19:44 | amalloy | no, in that for a persistent collection you only have to update the path from your update back to the root |
| 19:44 | gfredericks | I saw an AtomicReference<Thread> inside the node class of PersistentHashMap and wasn't sure why that was needed |
| 19:44 | amalloy | gfredericks: that's for transients |
| 19:45 | gfredericks | oh of course they use the same nodes |
| 19:45 | arkh | dbasch: I need to store the code as functions ... not sure why I didn't think of that first! thank you |
| 19:45 | amalloy | maybe i'm wrong, though. it seemed to me like a counted node would necessitate changing the counts of lots of nodes when you update |
| 19:45 | gfredericks | amalloy: my gut says the opposite |
| 19:45 | amalloy | i think you're probably right |
| 19:45 | gfredericks | it could still be a perf issue, just not an assymptotic one |
| 19:46 | arkh | dbasch: the idea will be to store a vector of fn's and call as needed |
| 19:47 | gfredericks | we need a shorter word for nonassymptotic performance issues |
| 19:48 | justin_smith | gfredericks: google hit for "assymptote" http://spikedmath.com/437.html |
| 19:48 | amalloy | gfredericks: "uninteresting"? |
| 19:49 | fortruce | justin_smith: that's beautiful :p |
| 19:50 | hyPiRion | gfredericks: constant factors |
| 19:54 | fortruce | how do i find out the version for clojure contrib so that I can include it in my lein project.clj? |
| 20:20 | gfredericks | fortruce: clojure contrib is deprecated |
| 20:21 | gfredericks | justin_smith: that'll help me remember how not to spell it |
| 20:35 | jsk | hey i was wondering if someone could give me a little push. I'm trying to do a hello world app with ring and following a couple examples but I'm getting 'unable to resolve defroutes in this context' error and AFAIK all my imports are setup right and my class path seems to be right |
| 20:36 | jsk | https://gist.github.com/jskulski/577d8dad63f1fc90b8a1 |
| 20:49 | gfredericks | jsk: defroutes presumably comes from compojure, which you're not requiring |
| 20:50 | jsk | gfredericks: yes! I knew it was something dumb |
| 20:50 | jsk | thanks so much |
| 21:00 | numberten | does lein repl have a shortcut for auto reloading the current namespace? |
| 21:24 | fortruce | does anyone know of a good example of a well tested restful api? |
| 21:24 | fortruce | I'm having a hard time figuring out the best way to test my endpoints |
| 21:35 | dbasch | fortruce: twitter is the first one that comes to mind |
| 21:35 | fortruce | dbasch: thanks, i'll give it a look |
| 21:46 | joshhead | There are no refs or dosync in ClojureScript, but since it is single threaded, am I correct that I can deref or swap! on several atoms in the same function without fear of conflicts? Not sure if that's clear, I can try to come up with an example. |
| 21:50 | bbloom | joshhead: you're right... modulo asynchronous callbacks |
| 21:51 | bbloom | joshhead: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L7203 |
| 21:51 | joshhead | thanks bbloom that's what I thought but I didn't want to gamble on it :) |
| 21:51 | bbloom | you'll see no STM or CAS or anything like that |
| 21:57 | eraserhd | Is there a useful way to `extend` PersistentVector? I'll have to extend other types as well, right? |
| 21:59 | bbloom | eraserhd: clojure doesn't believe in deriving from concrete types - you have to implement all of the interfaces/protocols it implements |
| 22:00 | bbloom | eraserhd: and since all the data types predate protocols, that means there's no good way to use clojure.core/extend or anything like that to mimic mixins or the like... so sadly that means you're on your own to implement the interfaces |
| 22:03 | eraserhd | Hrmm. I'm trying to make a splice method which works on strings and persistent vectors. I could use defmulti instead, but ... |
| 22:03 | bbloom | if you only want it to work on strings and vectors, there's always if or cond :-) |
| 22:04 | eraserhd | ... I'm not sure how to make a dispatch fn that allows it to be extensible. |
| 22:04 | eraserhd | Yeah... I could. |
| 22:04 | bbloom | sounds like you're coming from an OOP background where you want to add a method to an object to extend it |
| 22:04 | bbloom | ... we don't do that :-P |
| 22:04 | bbloom | just use regular functions |
| 22:05 | bbloom | it only makes sense for something to be a method or protocol or the like if you want fast single dispatch by type |
| 22:05 | bbloom | you can also argue that it needs to be a method if you want encapsulation, but we don't really believe in that all that much either here... on account of immutability and all :-) |
| 22:06 | bbloom | if you only expect to have a few cases, use if or cond. if you expect to have many, use a multimethod. if you know what you're doing, consider protocols if you need fast single dispatch |
| 22:06 | eraserhd | I'm really curious about what's going to happen with encapsulation as my project gets larger... :) |
| 22:07 | eraserhd | Oh, and you've made me realize the protocol/defmulti is, er, premature extensibility. |
| 22:07 | bbloom | yup |
| 22:07 | bbloom | encapsulation is overrated :-) |
| 22:08 | kenrestivo | i don't see too many clojure projects that are obsessed with encspsulation the way so much java is |
| 22:08 | kenrestivo | it's like java is a game of tetris where the peices never fit together |
| 22:14 | eraserhd | Hey, I'm at 980 lines of clojure. Not bad. |
| 22:15 | eraserhd | Not counting tests. |
| 22:17 | dbasch | kenrestivo: I wonder what’s the largest clojure project out there, from an organizational standpoint |
| 22:17 | dbasch | in Java there are codebases shared by hundreds / thousands of developers |
| 22:18 | fortruce | as I beginner to clojure I have a hard time figuring out the best way to structure my projects though :/ |
| 22:18 | eraserhd | ,(empty "hello?") |
| 22:18 | clojurebot | nil |
| 22:18 | eraserhd | ? |
| 22:18 | bbloom | fortruce: the answer is 1 big file until it hurts |
| 22:18 | bbloom | fortruce: a few thousand lines in a single .clj file isn't that unusual |
| 22:19 | dbasch | (doc empty) |
| 22:19 | clojurebot | "([coll]); Returns an empty collection of the same category as coll, or nil" |
| 22:19 | dbasch | (doc empty?) |
| 22:19 | clojurebot | "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))" |
| 22:20 | fortruce | bbloom: seriously? or am I being trolled...that seems like a great way to accidentally have name collisions |
| 22:20 | bbloom | fortruce: i'm totally serious |
| 22:20 | fortruce | bbloom: okay, just checking haha. Maybe I'm just too stuck in the OO thinking with encapsulation |
| 22:21 | bbloom | fortruce: i'm not recommending a few thousand lines per file.. i'm saying it's not that unusual |
| 22:21 | bbloom | fortruce: if you're coming from java with one class per file, or ruby/rails with tiny partials each getting their own file, or whatever... stop thinking that way |
| 22:22 | bbloom | you can use namespaces/files to separate out entire subsystems |
| 22:22 | fortruce | bbloom: how would you recommend structuring a simple crud rest api? |
| 22:22 | bbloom | how simple? if it's a few dozen endpoints, i might just have it all in one file :-) |
| 22:22 | fortruce | at the moment its a simple demo application so just 2-3 endpoints |
| 22:22 | bbloom | one file. |
| 22:22 | bbloom | period. |
| 22:23 | bbloom | clojure makes it's very easy to move functions between files, what with the pure functions & good namespace support |
| 22:23 | bbloom | so defer that decision until you have to make it |
| 22:23 | fortruce | interesting, i'll give it a go. Only 1 namespace per file though? |
| 22:23 | Frozenlock | 'only' :-p |
| 22:23 | bbloom | yeah, one file == one ns form at the top |
| 22:24 | eraserhd | OK, so in lisp... hell, back in Scheme in 2004, I have always wanted tests right below each function. |
| 22:24 | fortruce | alright, thanks, i'll throw it all in 1 file and see what happens :) |
| 22:24 | eraserhd | People often leave (comment ...) there, I think this shows that people actually want this ... |
| 22:25 | eraserhd | Has anybody done it in clojure? |
| 22:25 | bbloom | eraserhd: big (comment ...) blocks at the bottom of files are common too |
| 22:25 | eraserhd | I saw the ^{:test ...} thing. That's really cool, but nobody seems to really use it. |
| 22:25 | bbloom | inline tests are not common at all |
| 22:28 | fortruce | i was just thinking about tests inline right after the functions but it feels like it would just make it hard to navigate and see all the code |
| 22:28 | fortruce | but would probably be a better way to motivate me to write the tests |
| 22:32 | KeithPM | Good day. Could someone help me out of this fix? I am trying to implement memoization in a map but the map is immutable, how can I overcome that? https://gist.github.com/06d638428479e2f759ac.git |
| 22:33 | bbloom | KeithPM: use something that *isn't* immutable! like an atom |
| 22:34 | fortruce | does 'wrap-json-body' middleware have to come before the api handler? (stupid question) |
| 22:34 | KeithPM | OK. I was checking to see whether there was animmutable solution. Usually in a recursive setting we could pass an accumulator but it doesn't fit this model. |
| 22:34 | quizdr | anyone in here used the webbit webserver in clojure? |
| 22:36 | dbasch | KeithPM: any reason you’re not using memoize? |
| 22:36 | KeithPM | Oh I didn't remember it. Let me take a look. |
| 22:39 | dbasch | fortruce: I think it probably doesn’t matter, the compojure api wrapper deals only with parameters |
| 22:40 | dbasch | fortruce: so it won’t alter the body of the request |
| 22:41 | fortruce | dbasch: thanks, I was actually just forgetting how the threading macro worked for a minute 0_o |
| 23:02 | KeithPM | dbasch: Thanks I used memoize and it worked wonderfully |
| 23:02 | dbasch | KeithPM: np |
| 23:24 | lemonodor | anyone know of an existing emacs flymake mode for clojure? (compiling, not just kibiting) |
| 23:43 | johnjelinek | hihi all |
| 23:43 | johnjelinek | how's it goin'? |
| 23:44 | johnjelinek | does anyone have a recommendation on getting a live coding environment with om + emacs? |
| 23:44 | johnjelinek | the tutorial assumes lighttable |
| 23:44 | johnjelinek | I think maybe austin is the key, but wanted to get y'alls feedback |
| 23:45 | jsk | If anyone has any info on mocking out the file system, I would like to see. Google is coming back blank. |
| 23:53 | joshhead | johnjelinek: I have gotten one going. Not sure it's the best way but happy to share. Maybe someone will set me straight |
| 23:54 | johnjelinek | joshhead: got it up on github? |
| 23:56 | joshhead | johnjelinek, I was thinking it was online, but that was another project. I could upload an example pretty soon |
| 23:57 | johnjelinek | joshhead: great! I look forward to reviewing it |
| 23:57 | joshhead | I went for minimal dependencies, I think there are some more sophisticated setups |