2014-07-25
| 01:20 | ruzu | ahoy mateys |
| 01:21 | justinholguin | Ahoy, ruzu |
| 02:02 | x1337807x | Easy one: I just setup my first ever clojure app with lein and I want to test my hello_world function - Is there a way to test that something is written to stdout? Can I expect that println is called with a specific argument? |
| 02:05 | x1337807x | Got it - with-out-str |
| 02:35 | munichlinux | clojure noob here. I was trying to write a fn to compute sum of integers from 1 to n. https://gist.github.com/anonymous/4930ef53d70379726ee8, I wasn't accumulating the sum in a local so i expected the return value to the value x, it wasn't the case. I am trying to figure out why, any pointers? |
| 02:41 | ambrosebs | ,(apply + (range 1 6)) |
| 02:41 | clojurebot | 15 |
| 02:41 | ambrosebs | looks correct to me? |
| 02:51 | gws | munichlinux: are you comfortable with recursion in general? |
| 02:54 | munichlinux | gws: yes |
| 02:55 | munichlinux | gws: why did you ask that? |
| 02:58 | gws | what you have is a pretty straightforward recursive function, and "15" is what i'd expect from it as well |
| 03:01 | munichlinux | gws: sure, (+ x (sigma (- x 1)) => 15 but how did x became 15. |
| 03:01 | ambrosebs | how do I use ASM to modify a method on a deftype? It seems like you'd usually look for a .class file on the classpath, but I don't think a deftype has one? |
| 03:03 | munichlinux | i did not return (+ x (sigma (- x 1)) but x |
| 03:04 | gws | munichlinux: yes, as the base case for recursion - i.e. only when (pos? x) fails, so when x first becomes 0 in this case |
| 03:04 | gws | ,(pos? 1) |
| 03:04 | clojurebot | true |
| 03:04 | gws | ,(pos? 0) |
| 03:04 | clojurebot | false |
| 03:06 | gws | but the first 5 times you are indeed returning (+ x (sigma (- x 1)) |
| 03:09 | gws | plus an extra right paren because i can't count |
| 03:11 | munichlinux | gws: got it, I was under the impression that when x became 0 the else part would get returned (which is x) |
| 03:11 | gws | and you're absolutely correct |
| 03:11 | gws | it does do that |
| 03:12 | gws | at that point, the stack you built up doing those recursive calls unwinds, and collapses into 15 |
| 03:13 | munichlinux | gws: got it |
| 03:15 | gws | ,(+ 5 (+ 4 (+ 3 (+ 2 (+ 1 0))))) |
| 03:15 | clojurebot | 15 |
| 03:16 | munichlinux | ya |
| 03:17 | swi | Greetings :) |
| 03:23 | alainpicard | hello all! I have a Q about when clojure decides to eval a lazy sequence |
| 03:24 | alainpicard | in particular, if I'm sending an HTTP response, like (response {:foo (compute-this)}) ... |
| 03:24 | alainpicard | wouldn't that force evaluation of result of COMPUTE-THIS automatically? |
| 03:24 | alainpicard | 'cause it doesn't seem to, and I find that... surprising. |
| 03:32 | gws | if (response) just returns a ring response map, i wouldn't necessarily expect (compute-this) to be forced at that point, just as you wouldn't expect it to be forced if you simply had {:bar {:foo (compute-this)}} |
| 03:36 | alainpicard | but, eventually, ring wants to send out the string on the socket, no? |
| 03:36 | alainpicard | won't that force it? |
| 03:39 | gws | if whatever you've got there is actually part of the HTTP response and ring doesn't throw that key away, then i would think so too |
| 03:41 | alainpicard | okay. I must be doing something stupid somewhere else then. thanks for the sanity check! |
| 03:42 | Glenjamin | unless i'm missing something, evaluation is inside-out |
| 03:43 | Glenjamin | so (compute-this) should be evalled right away |
| 03:43 | Glenjamin | oh, sorry lazy sequence |
| 03:43 | Glenjamin | missed that bit :) |
| 03:56 | Glenjamin | alainpicard: depending on what middleware you have, it might not attempt to realise the sequence |
| 03:56 | Glenjamin | ,(str {:a (repeat 1 5)} |
| 03:56 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 03:56 | Glenjamin | ,(str {:a (repeat 1 5)}) |
| 03:56 | clojurebot | "{:a (5)}" |
| 03:56 | Glenjamin | ,(.toString {:a (repeat 1 5)}) |
| 03:56 | clojurebot | "{:a (5)}" |
| 04:26 | vdmit11_ | Hi folks. What protocol I need to implement to provide a custom ".ToString()" (or something like this) for my custom type? |
| 04:28 | ambrosebs | vdmit11_: (deftype A [] Object (toString [this] "mystring")) |
| 04:30 | vdmit11_ | ambrosebs, thanks, sorry for the stupid question |
| 04:31 | ambrosebs | vdmit11_: no such thing, np |
| 05:00 | vdmit11_ | why can't I override Object's toString method for records? I mean, this one works fine: (deftype A [] Object (toString [this] "mystring")), but this doesn't: (defrecord B [] Object (toString [this] "mystring")). Why? |
| 05:01 | ambrosebs | vdmit11_: defrecord does extra things implicitly. |
| 05:01 | ambrosebs | vdmit11_: I think it already extends toString |
| 05:02 | ambrosebs | defrecord is very single-purpose, if you want to do anything beyond it, use deftype |
| 05:08 | vdmit11_ | But defrecord provides a handy HashMap interface out of the box, I would like to use it. For me it looks easier to override somehow the toString method than implement those HashMap methods. |
| 05:08 | gws | ,(do (defrecord B [] Object (toString [this] "mystring")) (str (->B))) |
| 05:08 | clojurebot | "mystring" |
| 05:09 | ambrosebs | I stand corrected |
| 05:09 | ambrosebs | IIRC there are some thing you can't do with a defrecord, apparently toString isn't one of them |
| 05:11 | ambrosebs | ,(ancestors (defrecord B [])) |
| 05:11 | clojurebot | #{clojure.lang.IRecord clojure.lang.IPersistentMap clojure.lang.IPersistentCollection clojure.lang.IKeywordLookup clojure.lang.ILookup ...} |
| 05:11 | vdmit11_ | ,(do (defrecord B [] Object (toString [this] "mystring")) (->B)) |
| 05:11 | clojurebot | #sandbox.B{} |
| 05:11 | vdmit11_ | why the result is not "mystring"? |
| 05:11 | swi | How can i compose N function in one ? I mean somthing like foo . bar .zoo in haskell ? |
| 05:12 | gws | vdmit11_: all you did there was construct an instance of B |
| 05:12 | hyPiRion | swi: use comp: (comp foo bar zoo) |
| 05:12 | hyPiRion | ,(println (->B)) |
| 05:12 | clojurebot | #sandbox.B{}\n |
| 05:12 | vdmit11_ | ,(println (->A)) |
| 05:12 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ->A in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:13 | vdmit11_ | ,(do (deftype A [] Object (toString [this] "mystring")) (->A)) |
| 05:13 | clojurebot | #<A mystring> |
| 05:13 | swi | hyPiRion: thanks |
| 05:14 | vdmit11_ | why in this case the repl called the toString method, but in case of defrecord it didn't? |
| 05:15 | clgv | vdmit11_: the repl uses the print-method |
| 05:16 | clgv | vdmit11_: which is defined for records but not for arbitrary types |
| 05:17 | clgv | ,(defmethod print-method A [v ^java.io.Writer w] (.write w "#A")) |
| 05:17 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:17 | hyPiRion | clgv: that doesn't explain why my (println (->B)) didn't print out "mystring" |
| 05:18 | clgv | hyPiRion: I think it does. B is a record and is printed as tagged literal followed by a string representation of the map |
| 05:19 | vdmit11_ | It seems the toString method is overriden correctly for both deftype and defrecord: |
| 05:19 | hyPiRion | clgv: right, I forgot println isn't Bystem.out.println |
| 05:19 | vdmit11_ | ,(do (defrecord J [] Object (toString [this] "mystring")) (.toString (J.))) |
| 05:19 | clojurebot | "mystring" |
| 05:19 | vdmit11_ | So I think the trick is somewhere in print- methods |
| 05:19 | vdmit11_ | definitely |
| 05:19 | hyPiRion | ,(. System/out (println (->B))) |
| 05:19 | clojurebot | nil |
| 05:20 | clgv | hyPiRion: indeed, you can trace it back to clojure.core/pr-on which uses print-method if *print-dup* is false |
| 05:20 | clgv | ,(.println System/out (->B)) |
| 05:20 | clojurebot | nil |
| 05:20 | clgv | ,(->B) |
| 05:20 | clojurebot | #sandbox.B{} |
| 05:21 | clgv | ,(.toString (->B)) |
| 05:21 | clojurebot | "mystring" |
| 05:21 | hyPiRion | clgv: that's a bug with clojurebot I guess |
| 05:21 | hyPiRion | ,(.println System/out "foobar") |
| 05:21 | clojurebot | nil |
| 05:21 | clgv | ah right |
| 05:22 | hyPiRion | System/out is not *out*, and I guess clojurebot is just binding *out* |
| 05:22 | clgv | hyPiRion: probably due to rewiring input output for its repl^^ |
| 05:22 | hyPiRion | yeah |
| 05:22 | clgv | yeah |
| 05:23 | hyPiRion | ,(.println System/err "RELEASE ME :'(") |
| 05:23 | clojurebot | nil |
| 05:23 | clgv | vdmit11_: yeah, you'd need to implement print-method for your specific record type - but is that really desirable? |
| 05:23 | clgv | hyPiRion: probably showing up in some log ;) |
| 05:23 | hyPiRion | clgv: yeah, that's what I'm hoping for :p |
| 05:26 | clgv | hyPiRion: "Help me! I am a slave in a Chinese fortune cooky factory!" :P |
| 05:26 | clgv | *cookie |
| 05:26 | hyPiRion | hehe |
| 05:27 | vdmit11_ | clgv, no, because print-method affects only the repl in my case, but I need a sort of serialization, I tested the toString incorrectly by printing the object, now I understand that and the problem is resolved |
| 05:30 | pyrtsa | ,#'clojure.walk/macroexpand-all |
| 05:30 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve var: clojure.walk/macroexpand-all in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:30 | hyPiRion | ,(require '[clojure.walk :refer [macroexpand-all]]) |
| 05:30 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 05:30 | hyPiRion | whaaa |
| 05:30 | pyrtsa | :( |
| 05:30 | hyPiRion | ,(use 'clojure.walk) |
| 05:30 | clojurebot | nil |
| 05:30 | hyPiRion | there you go |
| 05:31 | pyrtsa | Thanks. |
| 05:31 | pyrtsa | ,(defmacro env [] (into {} (map #(vector (list 'quote %) %) (keys &env)))) |
| 05:31 | clojurebot | #'sandbox/env |
| 05:31 | pyrtsa | ,(env) |
| 05:31 | clojurebot | {} |
| 05:31 | pyrtsa | ,(let [x 1, y (inc x)] (env)) |
| 05:31 | clojurebot | {y 2, x 1} |
| 05:31 | clgv | hyPiRion: interesting inconsistent sandbox config |
| 05:31 | hyPiRion | hrm. Such weird inconsistent rules. |
| 05:31 | hyPiRion | yeah |
| 05:31 | pyrtsa | ,(macroexpand-all '(let [x 1, y (inc x)] (env))) |
| 05:31 | clojurebot | (let* [x 1 y (inc x)] {}) |
| 05:31 | pyrtsa | :( |
| 05:32 | clgv | yeah you'll get more differences when using destructuring in the let |
| 05:32 | pyrtsa | Working with macros can be painful. ^ |
| 05:32 | hyPiRion | pyrtsa: oh wow, that's nasty |
| 05:32 | hyPiRion | Must've been painful to find |
| 05:32 | pyrtsa | None of the variants of macroexpand are able to resolve &env in that. |
| 05:33 | pyrtsa | At least of what I could find. |
| 05:33 | pyrtsa | hyPiRion: Nah, it wasn't buried that deep when I was playing with it. Fortunately. |
| 05:34 | hyPiRion | that's good, because that one sounds very painful to debug |
| 05:34 | pyrtsa | But: PROTIP, the above (env) macro could be very useful when dealing with preconditions and such: makes it easy to tell what the local state was when things went wrong. |
| 05:36 | pyrtsa | ,(defmacro must [expr] `(if ~expr true (throw (AssertionError. (pr-str :expr '~expr :env (env)))))) |
| 05:36 | clojurebot | #'sandbox/must |
| 05:36 | pyrtsa | ,(let [xs [1 2 3]] (assert (must (every? odd? xs)))) |
| 05:36 | clojurebot | #<CompilerException java.lang.RuntimeException: No such var: sandbox/env, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:36 | pyrtsa | ,(defmacro env [] (into {} (map #(vector (list 'quote %) %) (keys &env)))) |
| 05:37 | clojurebot | #'sandbox/env |
| 05:37 | pyrtsa | ,(let [xs [1 2 3]] (assert (must (every? odd? xs)))) |
| 05:37 | clojurebot | #<AssertionError java.lang.AssertionError: :expr (every? odd? xs) :env {xs [1 2 3]}> |
| 05:38 | pyrtsa | ,((fn [xs] {:pre [(must (every? odd? xs))]} xs) [1 2 3]) |
| 05:38 | clojurebot | #<AssertionError java.lang.AssertionError: :expr (every? odd? xs) :env {xs [1 2 3]}> |
| 05:38 | hyPiRion | pyrtsa: what are you doing, you're making clojure errors readable |
| 05:38 | pyrtsa | :D |
| 05:38 | pyrtsa | Indeed. |
| 05:40 | TEttinger | ,(reduce #(Math/expt %1 %2) (range 2 10)) |
| 05:40 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: No matching method: expt, compiling:(NO_SOURCE_PATH:0:0)> |
| 05:40 | TEttinger | ,(reduce #(Math/pow %1 %2) (range 2 10)) |
| 05:40 | clojurebot | Infinity |
| 05:40 | TEttinger | wow |
| 05:40 | TEttinger | ,(reduce #(Math/pow %1 %2) (range 2N 10N)) |
| 05:40 | clojurebot | Infinity |
| 05:43 | TEttinger | ,(reduce #(.scaleByPowerOfTen %1 %2) (range 2M 4M)) |
| 05:43 | clojurebot | 2E+3M |
| 05:43 | TEttinger | ,(reduce #(.scaleByPowerOfTen %1 %2) (range 2M 10M)) |
| 05:43 | clojurebot | 2E+42M |
| 05:44 | TEttinger | ,(reduce #(.scaleByPowerOfTen %1 %2) (range 2M 1000M)) |
| 05:44 | clojurebot | 2E+499497M |
| 05:46 | hyPiRion | ,(reduce #(.pow % %2) (.toBigInteger 2N) (range 3 10)) |
| 05:46 | clojurebot | 7628045462646269549938976891875320382369142773966779250433383862468136427071492332052290036238273567369166292537839519107420501593575384831894619073527853412088564527569473310793304373165199270832509630979462174093467427044817508289080036667855823736716211224317100708646525267755964878000278158240303705956088198499788045494885732510171221517843527982835625514436506476212438271589497730043764762558... |
| 05:54 | cstamm | hi. Is it possible to add a build number to the version of jar created by lein uberjar? Like one generated by the CI-server at build time? |
| 05:57 | cstamm | sorry. googled it myself |
| 06:00 | xsyn | I'm trying to do a cons on two maps |
| 06:00 | xsyn | but when I do, the second map loses it's structure |
| 06:00 | xsyn | Is there a way that I can keep it |
| 06:01 | Bronsa | xsyn: what's your input and what's the desired output? |
| 06:02 | xsyn | (cons #clojurewerkz.neocons.rest.records.Node{:id 418, :location-uri http://localhost:7474/db/data/node/418, :data {:id 27737500949}} clojurewerkz.neocons.rest.records.Node{:id 418, :location-uri http://localhost:7474/db/data/node/418, :data {:id 27737500949}} ) |
| 06:02 | xsyn | ( irc://irc.freenode.net:6667/#clojurewerkz.neocons.rest.records.Node%7B:id 418, :location-uri http://localhost:7474/db/data/node/418, :data {:id 27737500949}} clojurewerkz.neocons.rest.records.Node{:id 418, :location-uri http://localhost:7474/db/data/node/418, :data {:id 27737500949}}) |
| 06:02 | Bronsa | xsyn: so you just want to put two maps in a list? |
| 06:03 | Bronsa | ,(list {:a 1} {:b 2}) |
| 06:03 | clojurebot | ({:a 1} {:b 2}) |
| 06:03 | xsyn | ugh, that easy? |
| 06:03 | xsyn | thanks :) |
| 06:03 | xsyn | let me test |
| 06:04 | xsyn | is perfect |
| 06:05 | xsyn | thank you |
| 06:05 | Bronsa | np |
| 06:23 | boxed | yogthos: getting midje-readme to run on clj-pdf was a bit troublesome.. partly because there was a power outage here last night :P |
| 06:24 | boxed | but I’m getting a weird “Wrong number of args (3) passed to: […]rot[…]” which I can’t figure out too… it works in the example.clj where it’s copied from... |
| 06:29 | xsyn | misplaced bracket? |
| 06:30 | swi | btw, clojure.string/upper-case is the same as (.upUpperCase) ? |
| 06:31 | swi | ooh, yep, just a wrap over :) |
| 06:40 | boxed | xsyn: I’ve copy-pasted from the working example several times :P |
| 07:06 | SagiCZ1 | ,(defn foo [[x]] x) |
| 07:06 | clojurebot | #'sandbox/foo |
| 07:06 | SagiCZ1 | ,(foo ["red" "meat" "juicy"]) |
| 07:06 | clojurebot | "red" |
| 07:06 | SagiCZ1 | i dont get it |
| 07:08 | __daniel__ | SagiCZ1: you're destructuring the first element |
| 07:08 | __daniel__ | ,(foo ["meat" "juicy"]) |
| 07:08 | clojurebot | "meat" |
| 07:08 | gauravagarwalr | its called destructuring.. |
| 07:08 | SagiCZ1 | why is it not affecting the other elements |
| 07:08 | SagiCZ1 | ,(defn foo [[x y]] (list x y)) |
| 07:08 | clojurebot | #'sandbox/foo |
| 07:08 | SagiCZ1 | ,(foo ["red" "meat" "green" "grass"]) |
| 07:08 | clojurebot | ("red" "meat") |
| 07:08 | boxed | SagiCZ1: “[x] x” means “create a new variable x that is the first element of the old variable x, throw away the rest" |
| 07:09 | gauravagarwalr | its same as: (defn foo [[x _ _]] x) |
| 07:09 | gauravagarwalr | (defn foo [[x _ _]] x) |
| 07:09 | SagiCZ1 | boxed: i dont understand what you said |
| 07:09 | gauravagarwalr | '(defn foo [[x _ _]] x) |
| 07:09 | boxed | hmm.. actually, another question might be: what would you expect? |
| 07:09 | SagiCZ1 | gauravagarwalr: ok that makes sense |
| 07:10 | gauravagarwalr | ,(defn foo [[x _ _]] x) |
| 07:10 | clojurebot | #'sandbox/foo |
| 07:10 | SagiCZ1 | i would expect that i would be the vector "unwrapped" |
| 07:11 | __daniel__ | ,(defn foo [[& x]] x) |
| 07:11 | clojurebot | #'sandbox/foo |
| 07:11 | __daniel__ | ,(foo ["red" "meat" "juicy"]) |
| 07:11 | clojurebot | ("red" "meat" "juicy") |
| 07:11 | SagiCZ1 | ,(defn foo [not-in-vector [x y]] not-in-vector)) |
| 07:11 | clojurebot | #'sandbox/foo |
| 07:11 | gauravagarwalr | I guess __daniel__ has posted what you were looking for! |
| 07:11 | SagiCZ1 | ,(foo "hello" [4 5 6]) |
| 07:11 | clojurebot | "hello" |
| 07:15 | boxed | SagiCZ1: How can it “unwrap” a vector into a single variable? |
| 07:16 | boxed | again I have to ask: what do you expect? one variable is one variable, it can’t be three variables… |
| 07:18 | gauravagarwalr | ,(defn foo [& x] x) |
| 07:18 | clojurebot | #'sandbox/foo |
| 07:19 | gauravagarwalr | ,(foo "red" "meat" "juicy") |
| 07:19 | clojurebot | ("red" "meat" "juicy") |
| 07:19 | gauravagarwalr | @boxed I think this is what he meant! |
| 07:20 | boxed | gauravagarwalr: I think it’s pretty bad to keep guessing what he means… it’s better to get a good understanding from him |
| 07:20 | gauravagarwalr | boxed: ok |
| 07:20 | boxed | gauravagarwalr: your example doesn’t seem reasonable becaue if that’s what he wanted then that’s what he already had in “x”… so why do a destructuring in the first place? |
| 07:21 | gauravagarwalr | @SagiCZ1 What is it that you originally required? |
| 07:29 | __daniel__ | i'll take another guess that he was just playing with destructuring |
| 07:29 | __daniel__ | with no particular aim |
| 07:30 | gauravagarwalr | :D |
| 07:30 | boxed | “i would expect that i would be the vector "unwrapped”” <- I think that suggests intent |
| 07:30 | boxed | or at least some expectation of outcome |
| 07:31 | __daniel__ | in a way, it is unwrapping the vector, not just returning x |
| 07:31 | __daniel__ | ,(foo [1 2 3]) |
| 07:31 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 07:31 | __daniel__ | is returning a seq |
| 07:44 | gauravagarwalr | too much to speculate on! ;) |
| 07:53 | SagiCZ1 | sorry guys.. was fetching some lunch |
| 07:53 | SagiCZ1 | yeah i was really just playing with destructuring.. |
| 07:53 | SagiCZ1 | i guess i am not sure what i really expected |
| 07:54 | SagiCZ1 | just this way of choosing a first element of collection seems weird [[x]] .. |
| 07:54 | SagiCZ1 | [x] followed by (first x) seems more readable to me |
| 07:55 | boxed | you mean “x (first x)” |
| 07:55 | boxed | yea you can do that too |
| 07:55 | boxed | ,(let [x (first [1 2 3]) x) |
| 07:55 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )> |
| 07:55 | boxed | ,(let [x (first [1 2 3])] x) |
| 07:55 | clojurebot | 1 |
| 07:56 | SagiCZ1 | boxed: yeah that would make more sense to me.. |
| 07:57 | SagiCZ1 | ,(= (let [x (first [1 2 3])] x) (let [[x]] [1 2 3])) |
| 07:57 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: let requires an even number of forms in binding vector in sandbox:, compiling:(NO_SOURCE_PATH:0:0)> |
| 07:57 | boxed | it’s a bit cumbersome when moving on to [x y] foo though |
| 07:57 | hyPiRion | you can say boxed helped you … unbox that value. |
| 07:57 | boxed | clojurebot ignores everything except the first form btw |
| 07:57 | hyPiRion | You can also do -> |
| 07:57 | SagiCZ1 | hyPiRion: who would expect that :) |
| 07:58 | SagiCZ1 | thanks very much.. am i getting repetetive? i really love the community, always someone here who is eager to help.. |
| 07:58 | hyPiRion | ,(= (let [x (-> [[1 2 3]] first first)] x) (let [[[x]] [[1 2 3]]] x)) |
| 07:58 | clojurebot | true |
| 07:58 | boxed | hyPiRion: blech |
| 08:00 | SagiCZ1 | ,(def v [[1 2] [3 4] [5 6]]) |
| 08:00 | clojurebot | #'sandbox/v |
| 08:00 | SagiCZ1 | ,(first (first v)) |
| 08:00 | clojurebot | 1 |
| 08:00 | SagiCZ1 | ,(-> v first) |
| 08:00 | clojurebot | [1 2] |
| 08:00 | SagiCZ1 | ,(-> v first first) |
| 08:00 | clojurebot | 1 |
| 08:01 | SagiCZ1 | (doc ->) |
| 08:01 | clojurebot | "([x & forms]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc." |
| 08:01 | boxed | the doc for that is not super helpful I think :P |
| 08:01 | SagiCZ1 | boxed: i have found most of the docs very cryptic sadly :( |
| 08:02 | boxed | clojuredocs is normally superior |
| 08:02 | boxed | although a bit dated :( |
| 08:02 | SagiCZ1 | boxed: but they just copy the same doc.. ? |
| 08:02 | SagiCZ1 | boxed: u mean the examples? |
| 08:03 | boxed | yea, the examples |
| 08:03 | SagiCZ1 | boxed: why is it dated? can we update it? |
| 08:04 | boxed | I guess the guy who updated it isn’t doing it and isn’t allowing anyone else in |
| 08:04 | SagiCZ1 | boxed: i see |
| 08:04 | boxed | grimoire is an attempt at replacing it |
| 08:04 | SagiCZ1 | btw is there a way to make this prettier? (first (first (filter f coll))) |
| 08:05 | hyPiRion | (ffirst (filter f coll)) |
| 08:05 | SagiCZ1 | ffirst.. seriously |
| 08:05 | SagiCZ1 | (doc ffirst) |
| 08:05 | clojurebot | "([x]); Same as (first (first x))" |
| 08:05 | SagiCZ1 | :D |
| 08:05 | augustl | there's also fffffffffffffffffffffirst and fffffffffffffffffffu |
| 08:06 | SagiCZ1 | no way |
| 08:06 | boxed | hah |
| 08:06 | augustl | a reader macro that looked for symbols that started with fff* would have been neat :) |
| 08:06 | SagiCZ1 | wait what does ([x]) this mean in the clojurebot response? |
| 08:06 | boxed | just doing “first” is pretty horrible for maintainability and readability |
| 08:07 | SagiCZ1 | boxed: whats wrong with it? |
| 08:07 | hyPiRion | SagiCZ1: ([x]) is the list of argument lists. |
| 08:07 | hyPiRion | so it only accepts a single argument. |
| 08:07 | SagiCZ1 | oh i see |
| 08:07 | boxed | SagiCZ1: why first? why not second, third, fourth? accessing stuff based on index with magic index numbers is not so nice imo |
| 08:07 | hyPiRion | (doc reduce) |
| 08:08 | clojurebot | "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val is supplied, returns t |
| 08:08 | hyPiRion | So reduce can either be done with 2 or 3 arguments. |
| 08:08 | SagiCZ1 | boxed: lets say i have some collection of pairs.. and once i select the pair i need the first one.. |
| 08:08 | SagiCZ1 | once i select A pair i want the first element of the pair |
| 08:08 | boxed | SagiCZ1: ok, but WHY do you have a collection of pairs? why not something better like a collection of maps or a records? |
| 08:09 | augustl | boxed: first/rest is a pretty common pattern though |
| 08:09 | augustl | car/cdr all the way |
| 08:10 | boxed | augustl: sure, when it’s a list of things, but see? SagiCZ1 is clearly talking about using tuples :P |
| 08:10 | SagiCZ1 | boxed: i have a map of transistions, where the keys are "states to move to" and their values are "conditions that have to be fulffiled for the transition" .. like this: |
| 08:10 | SagiCZ1 | {:water #(= % :melting) |
| 08:10 | SagiCZ1 | :vapor #(= % :sublimation)} |
| 08:11 | augustl | is there an executor/thread pool combo that will allow multiple threads running, but only a single thread per "id"? So, when I want to execute, I pass in the ID, and only one thread may run at any given time for that ID |
| 08:11 | boxed | yea ok, so you’re just destructuring a map? then (for [[k v] map] …) is pretty good |
| 08:12 | SagiCZ1 | boxed: yeah i need to rework it.. its ugly.. i just realized what im doing wrong |
| 08:14 | hyPiRion | augustl: Need more information: Should you block or try another work function if "id" is already in use? |
| 08:14 | boxed | or put in a queue? |
| 08:18 | augustl | hyPiRion: block |
| 08:18 | augustl | err, put in a queue :) |
| 08:20 | stuartsierra | augustl: Clojure agents will do that :) |
| 08:20 | SagiCZ1 | boxed: can i break out of the "for" once i find what i need? |
| 08:22 | SagiCZ1 | i am looking for a certain value in a map, and once i find it i need to return its key |
| 08:23 | boxed | that sounds a bit backwards :P |
| 08:23 | SagiCZ1 | boxed: i know right.. |
| 08:23 | SagiCZ1 | boxed: i know the map is backwards.. it just feels more natural when inputing it for this case.. |
| 08:24 | augustl | stuartsierra: ah, will look into that |
| 08:24 | SagiCZ1 | boxed: maybe i should first fix the map and then work with it as normal |
| 08:24 | hyPiRion | SagiCZ1: you don't break out of a for. That's not how for works. |
| 08:25 | hyPiRion | It's not like Java's for loop. It's a for comprehension. Think of it as a way to use map/filter in a neat way. |
| 08:27 | SagiCZ1 | hyPiRion: yeah i think i understood that although i keep forgetting its not like regular for.. doseq is closer to a regular for |
| 08:27 | hyPiRion | right |
| 08:27 | SagiCZ1 | but doseq cant return anything.. just for sideeffects right? |
| 08:28 | hyPiRion | right |
| 08:30 | boxed | SagiCZ1: loop/recur will do it… |
| 08:33 | hyPiRion | if you want to get some key/value pair where you already know the value, do (first (for [[k v] :when (= v known-val)] [k v])) |
| 08:34 | hyPiRion | whoops, (first (for [[k v] m :when (= v known-val)] [k v])) I meant |
| 08:35 | clgv | hyPiRion: I'd advise the more performant reduce-kv |
| 08:35 | clgv | together with `reduced` |
| 08:37 | hyPiRion | clgv: I'd advise for another data model if that query is going to happen frequently |
| 08:40 | clgv | hyPiRion: well, that's true. but might be some compromise... |
| 08:41 | lvh | clgv: huh what's a reduced |
| 08:41 | lvh | I know about reduce-kv |
| 08:41 | clgv | ,(doc reduced) |
| 08:41 | clojurebot | "([x]); Wraps x in a way such that a reduce will terminate with the value x" |
| 08:42 | lvh | whaaa |
| 08:42 | clgv | ;) |
| 08:42 | Glenjamin | ,(reduce (reduced 1)) |
| 08:42 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core/reduce> |
| 08:42 | lvh | clgv: I seriously have no idea what that is |
| 08:42 | lvh | clgv: the source code didn't help either |
| 08:43 | lvh | clgv: Would you mind typing a reduce(-kv) example that uses it? |
| 08:43 | Glenjamin | ,(reduce list (reduced 1)) |
| 08:43 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Reduced> |
| 08:43 | lvh | also grimoire doesn't know about it |
| 08:43 | hyPiRion | ,(reduce list (reduced 1) ()) |
| 08:43 | clojurebot | #<Reduced@1c2df08: 1> |
| 08:43 | clgv | lvh: `reduce` will terminate if something wrapped in `reduced` is returned from the function no matter if the given collection was traversed completely |
| 08:43 | hyPiRion | uh |
| 08:44 | clgv | no must be returned from the function |
| 08:44 | Glenjamin | http://stackoverflow.com/questions/15625341/reduce-a-lazy-sequence-like-a-loop-with-a-condition-in-clojure |
| 08:44 | clgv | ,(reduce (fn [x y] (reduced x)) 1 (range)) |
| 08:44 | clojurebot | 1 |
| 08:45 | Glenjamin | oh, that's neat |
| 08:45 | hyPiRion | clgv: sure, I was just confused about the fact that the init value isn't considered a value returned by f |
| 08:45 | Glenjamin | like an early return |
| 08:45 | Glenjamin | ,(reduce list (reduced 1) '(1)) |
| 08:45 | clojurebot | (#<Reduced@47fdc3: 1> 1) |
| 08:45 | Glenjamin | ,(reduce second (reduced 1) '(1)) |
| 08:45 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/second> |
| 08:46 | hyPiRion | clgv: the docs are ambiguous enough to not specify what should happen. |
| 08:46 | clgv | ,(reduce (fn [x y] (cond-> y (and (even? y) (< 3 y)) reduced) (range)) |
| 08:46 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 08:46 | Glenjamin | ,(reduce #(apply second) (reduced 1) '(1)) |
| 08:46 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/eval215/fn--216> |
| 08:46 | clgv | ,(reduce (fn [x y] (cond-> y (and (even? y) (< 3 y)) reduced)) (range)) |
| 08:46 | clojurebot | 4 |
| 08:46 | lvh | so, on the first call, you get (reduced 1) |
| 08:46 | clgv | hyPiRion: yeah, doc jira issue? ;) |
| 08:47 | hyPiRion | yeah, on it |
| 08:47 | lvh | you get ((fn [x y] (reduced x)) 1 0) == (reduced 1) |
| 08:47 | lvh | then you get... ((fn [x y] (reduced x)) (reduced 1) 1) ? |
| 08:48 | clgv | only the function return values are checked for `reduced` wrappers |
| 08:48 | bacon1989 | I was wondering how I can fix problems involving dynamic, and unbound variables |
| 08:48 | clgv | bacon1989: bind them? :D |
| 08:48 | bacon1989 | I have a function that I can't compile, and it isn't accessible until runtime |
| 08:48 | bacon1989 | it says it's unbound |
| 08:49 | bacon1989 | I tried @(delay (foo)), but I don't think I have the right idea |
| 08:49 | lvh | clgv: oh |
| 08:50 | lvh | clgv: so reduce and reduce-kv know about reduced, and if they find that, they go "welp I'm done" and return the wrapped value? |
| 08:50 | clgv | lvh: that's the idea ;) |
| 08:50 | lvh | I'll try to write out the reduce-kv to find a key given a value in a map later :) |
| 08:50 | Glenjamin | this seem reasonable? https://github.com/arrdem/grimoire/pull/56 |
| 08:51 | clgv | bacon1989: sounds pretty weird. maybe you should describe your concrete application problem |
| 08:52 | clgv | Glenjamin: shouldnt such an example be executable? and I 'd definitely add a short description what the whole expression is supposed to calculate |
| 08:52 | Glenjamin | what do you mean by executable? |
| 08:53 | clgv | Glenjamin: well the code you posted there cannot be run in a repl |
| 08:53 | Glenjamin | oh, i see |
| 08:53 | bacon1989 | clgv: it is weird, i'm using clojure-android |
| 08:53 | Glenjamin | heh, that's what i get for blindly copying stack overflow |
| 08:53 | bacon1989 | the function is unbound for some reason |
| 08:53 | clgv | better make up your own example searching for an element with a specific property |
| 08:53 | bacon1989 | I can't figure out 'why' it's not unbound, because it's clearly bound |
| 08:53 | bacon1989 | *is unbound |
| 08:54 | clgv | Glenjamin: or take that one ##(reduce (fn [x y] (cond-> y (and (even? y) (< 3 y)) reduced)) (range)) |
| 08:54 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: cond-> in this context |
| 08:54 | Glenjamin | ,(reduce (fn [a v] (if (> 5 v) a (conj a v))) #{} (range)) |
| 08:54 | Glenjamin | oh |
| 08:54 | clgv | oops. lazybot is lame nowadays... |
| 08:54 | Glenjamin | forgot to reduced |
| 08:54 | clojurebot | eval service is offline |
| 08:55 | hyPiRion | bacon1989: try to sharp-quote it. May be that the delay captures the unbound value the var refers to |
| 08:55 | bacon1989 | sharp quote? |
| 08:56 | bacon1989 | `? |
| 08:56 | bacon1989 | hmm yeah, I guess I could just deref that |
| 08:57 | bacon1989 | you do mean like this, @`(foo)? |
| 08:58 | bacon1989 | i can't dereference that |
| 08:58 | Glenjamin | ,(reduce (fn [a v] (if (> 5 v) (reduced a) (conj a v))) #{} (range)) |
| 08:58 | clojurebot | #{} |
| 08:59 | Glenjamin | have i done something dumb there? |
| 08:59 | hyPiRion | bacon1989: #' is sharp-quote |
| 08:59 | Glenjamin | ,(reduce (fn [x y] (cond-> y (and (even? y) (< 3 y)) reduced)) (range)) |
| 08:59 | clojurebot | 4 |
| 08:59 | hyPiRion | bacon1989: so (delay (#'foo)) should not fail if foo is a nullary function |
| 09:01 | clgv | bacon1989: build a minimal failing example of your code and post it as a gist |
| 09:03 | Glenjamin | here we go, updated: https://github.com/arrdem/grimoire/pull/56 |
| 09:04 | bacon1989 | clgv: it's still unbound, i'm using clojure-android, on an android product with lein-droid |
| 09:04 | bacon1989 | maybe I should be asking about this in the official channel |
| 09:10 | bacon1989 | looks like this though https://gist.github.com/benzap/8cf4526f413339624c92 |
| 09:10 | clgv | Glenjamin: :D |
| 09:10 | clgv | Glenjamin: but I would add a comment what it does ^^ |
| 09:11 | Glenjamin | you mean like walking through the algorithm it implements? |
| 09:11 | clgv | bacon1989: where does the exception originate from? |
| 09:12 | bacon1989 | refresh, I left a comment with the stacktrace |
| 09:12 | clgv | Glenjamin: no just like -> the example extracts all numbers smaller than 5 until a number >= 5 is encountered - or something similar ;) |
| 09:12 | Glenjamin | right, seems sensible |
| 09:13 | bacon1989 | clgv: if I use the repl, the code works fine, but compiling doesn't work |
| 09:13 | hyPiRion | clgv: http://dev.clojure.org/jira/browse/CLJ-1474 |
| 09:13 | bacon1989 | i've had the same issue before regarding stubs, but I solved those by using delays |
| 09:13 | bacon1989 | this time it's different, I can't figure out what's causing it to be unbound at compile-time |
| 09:14 | clgv | bacon1989: weird - does it also work in a fresh repl? |
| 09:15 | bacon1989 | clgv: it works on a repl |
| 09:16 | clgv | bacon1989: also a restarted one? |
| 09:16 | bacon1989 | idk about restarted, I just use the repl that's provided when the app starts up |
| 09:18 | clgv | bacon1989: I mean did you restart the repl and try? |
| 09:18 | bacon1989 | yes |
| 09:19 | bacon1989 | i'll try again just to make sure, but it was definitely working |
| 09:20 | bacon1989 | which doesn't solve my issue, it's needs to be compiled into the application |
| 09:20 | clgv | well if it works in the repl after restart you definitely have to ask the clojure-android guys |
| 09:21 | bacon1989 | yeah, I just tested it, it works |
| 09:21 | clgv | a minimal runnable project with the same error will be appreciated and speed up things I guess |
| 09:22 | bacon1989 | do you have an android device? |
| 09:22 | bacon1989 | i could probably throw together a simple project |
| 09:22 | clgv | I got no android dev env... |
| 09:22 | bacon1989 | i'm going to post in the google group through |
| 09:38 | TimMc | arrdem: I see you've avoided clojuredocs' .. problem. |
| 09:39 | TimMc | arrdem: I'm curious why you decided to trim off leading and trailing underscores, though. |
| 09:48 | gauravagarwalr | clear |
| 09:49 | gauravagarwalr | (use '[clojure.java.shell :only [sh]]) |
| 09:49 | gauravagarwalr | (sh "free") |
| 09:49 | gauravagarwalr | ,(use '[clojure.java.shell :only [sh]]) |
| 09:49 | gauravagarwalr | ,(sh "free") |
| 09:49 | clojurebot | nil |
| 09:49 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 09:50 | clgv | gauravagarwalr: next try would have been "rm -rf /" ? :P |
| 09:56 | bacon1989 | clojurebot has been locked down pretty well, there's an intersting article on all of the holes some guy found |
| 09:56 | bacon1989 | they were able to patch it up pretty well |
| 09:57 | hyPiRion | $google xeqixeqi clojurebot |
| 09:57 | lazybot | [Breaking lazybot out of clojail - Nelson Morris] http://nelsonmorris.net/2012/09/06/breaking-lazybot-out-of-clojail.html |
| 09:59 | gauravagarwalr | :D |
| 10:00 | gauravagarwalr | It never hurts to try! :P |
| 10:00 | boxed | is there a way to make everything non-lazy? this debugging with prints that are interleaved and shit is killing me |
| 10:02 | gauravagarwalr | boxed: If you are trying to print stuff.. then as soon as you output it to console it starts to evaluate.. |
| 10:03 | gauravagarwalr | Aren't you using lighttable? :P |
| 10:04 | boxed | https://www.refheap.com/88574 |
| 10:13 | stuartsierra | boxed: It's much easier with a real logging framework, although non-trivial to set up. |
| 10:18 | andyf | Can anyone recommend a tool for creating class/interface inheritance diagrams for Clojure's Java implementation code, preferably one simple to set up, or there are documented instructions for setting it up you could send me a link for? |
| 10:18 | gtrak | boxed: tried the dbg macro? http://www.learningclojure.com/2010/09/clojure-macro-tutorial-part-i-getting.html |
| 10:20 | stuartsierra | andyf: https://github.com/stuartsierra/class-diagram |
| 10:21 | andyf | stuartsierra: Thanks! I'll give that a go. |
| 10:36 | lvh | clgv: ping, re: earlier where we talked about reduced, and map + val -> key, were you thinking something like: |
| 10:36 | lvh | (defn val->key [val map] (reduce-kv (fn [cur k v] (if (== v val) (reduced k) nil)) nil map)) |
| 10:37 | lvh | seems kinda weird to me, since cur is always nil basically |
| 10:38 | clgv | lvh: yeah an impl via reduce-kv could look like that; better use `when? |
| 10:38 | clgv | `when` |
| 10:40 | clgv | lvh: if you have some kind of bijection there that is used often it is probably worth to main one map for each mapping direction |
| 10:41 | lvh | okay, so my understanding of reduced is now "fine here have your answer stop reducing" |
| 10:41 | lvh | makes sense |
| 10:41 | lvh | I thought it'd be some crazy functional hackery |
| 10:41 | clgv | hm no it is not ;) |
| 10:55 | lsdafjklsd | a |
| 11:01 | trptcolin | anybody got a foolproof demo proving that Atoms retry when the CAS fails? i know how it works [i’m pretty sure anywa], just having a rough time getting an actual demo showing it. |
| 11:07 | Bronsa | trptcolin: http://sprunge.us/EGKS?clj |
| 11:12 | trptcolin | Bronsa: thanks, i see my mistake |
| 11:13 | trptcolin | i was dumbly putting the sleep outside the swap fn |
| 11:13 | trptcolin | which isn’t going to work :) |
| 11:38 | hcumberdale | why is (cond-> a :x print) working >> {:x "abc} but not (cond-> a :x #(print %)) ? |
| 11:38 | hcumberdale | ,(cond-> {:x "abc"} :x print) |
| 11:38 | clojurebot | {:x abc} |
| 11:39 | hcumberdale | ,(cond-> {:x "abc"} :x #(print %)) |
| 11:39 | clojurebot | #<sandbox$eval52$G__51__53 sandbox$eval52$G__51__53@75b962> |
| 11:39 | clgv | hcumberdale: becauce cond-> is a macro manipulating the execution forms |
| 11:40 | hcumberdale | so I can't use # and fn there? |
| 11:40 | hcumberdale | how to access "abc" then? |
| 11:40 | clgv | hcumberdale: in that case #(print % a) is the resulting form that is executed if :x is truthy in a |
| 11:40 | arrdem | you can totally use #() in there, you just have to apply the fn represented with #() yourself. |
| 11:40 | BobSchack | seangrove are you looking for a fressian port to clojurescript? |
| 11:40 | joegallo | (#(print %)) |
| 11:41 | clgv | hcumberdale: do you want (cond-> a :x (print %))? |
| 11:41 | seangrove | BobSchack: Specifically looking for an efficient way to send huge clj/cljs datastructures with tons and tons of structural sharing over the wire efficient |
| 11:41 | clgv | hcumberdale: or do you want to creat an anonymous function? |
| 11:41 | hcumberdale | (cond-> a :x (spit % somethinghere)) |
| 11:42 | BobSchack | I've ported fressian to cljs if you are interested |
| 11:42 | seangrove | BobSchack: That's fantastic, I'm definitely interesting in checking it out |
| 11:42 | hcumberdale | where (:x a) is the filename |
| 11:42 | seangrove | I think I saw on hn that you have it 40% faster than edn? |
| 11:42 | BobSchack | https://github.com/spinningtopsofdoom/longshi |
| 11:43 | BobSchack | so far it uses typed arrays so you'll have that restriction |
| 11:44 | BobSchack | so far doing perf tests with large edn data it's about 40% faster |
| 11:45 | BobSchack | I'm still doing perf improvement and looking any tricks the did for transit |
| 11:45 | hcumberdale | clgv: (#(...)) works! |
| 11:46 | BobSchack | It's my first non toy clojure library so any feedback is welcome |
| 11:47 | clgv | hcumberdale: but then you could just use (cond-> a :x print) |
| 11:48 | hcumberdale | clgv yes for print. But I want to call (spit (:x a) graph). |
| 11:48 | seangrove | BobSchack: This si great, thank you. How does the domain-aware compression work? What kidn of compression ratio do you get? |
| 11:48 | hcumberdale | Basically I have that graph and I work on cli options for the output |
| 11:49 | clgv | hcumberdale: if the function is more complicate you probably should "defn" it anyway ;) |
| 11:49 | hcumberdale | using clojure.tools/cli I have a options map. I want to be able to create both graphml files for yed and yaml output |
| 11:52 | awwaiid | icfp contest today! |
| 11:52 | hcumberdale | I've choosen cond-> because of it's behavior not to short circuit |
| 11:53 | hcumberdale | Is there a better alternative to cond-> if I just want a not short circuit cond but not changing my forms? |
| 11:53 | BobSchack | seangrove to cache you can either use (write-object object cahce-flag) in the write handler or cache an individual object by calling (cache object) |
| 11:54 | BobSchack | Fressian caching is really awesome but very poorly documented :( |
| 11:55 | seangrove | BobSchack: Any chance of a few code examples in the readme or examples dir? |
| 11:56 | BobSchack | Yep working on this today with 20% time any use cases you'd like to see? |
| 12:00 | ppppaul | i can't find david nolens blog post about using core.async to make a typeahead |
| 12:01 | nullptr | ppppaul: http://swannodette.github.io/2013/08/17/comparative/ ? |
| 12:02 | seangrove | BobSchack: Not sure. Generaly usage - I'll play around with this tonight or this weekend if the examples are there |
| 12:03 | ppppaul | thanks nullptr |
| 12:49 | mpenet | huh, take! doesn't work on sliding buffers ? |
| 12:50 | mpenet | c.c.async map uses that internally and breaks stuff down the road I think |
| 12:51 | mpenet | c.c.async/map |
| 12:51 | mpenet | map< even, anyway... |
| 12:52 | vdmit11 | hi folks, how can I define a constructor for a custom type? |
| 12:53 | vdmit11 | I mean, can I define different arities for the automatically generated constructor? |
| 12:53 | bbloom | vdmit11: no, just use a function |
| 12:54 | mpenet | ,(use 'clojure.core.async) |
| 12:54 | clojurebot | #<FileNotFoundException java.io.FileNotFoundException: Could not locate clojure/core/async__init.class or clojure/core/async.clj on classpath: > |
| 13:09 | kwladyka | What is the most mature (the best) webframework using Clojure? I know in google is many articles about that but not actual any more. |
| 13:29 | bridgethillyer | kwladyka: take a look at Luminus, Pedestal, Om, and Hoplon |
| 13:29 | bridgethillyer | Which one you pick depends on your needs |
| 13:29 | bridgethillyer | In Clojure, it’s more a set of libraries than an entire framework |
| 13:30 | bridgethillyer | Although Pedestal could be considered a framework |
| 13:30 | boxed | and Reagent! |
| 13:31 | johnwalker | what is :scope "provided"? |
| 13:31 | johnwalker | https://github.com/swannodette/om-sync/blob/master/project.clj |
| 13:31 | hiredman | hoplon seems to come with its own build system, it maybe a framework :) |
| 13:31 | johnwalker | is it clojurescript only? |
| 13:35 | bridgethillyer | hiredman: more a worldview :) |
| 13:36 | llasram | johnwalker: It's a Maven thing which means that in production the actual implementation for dependency will be provided by e.g. some sort of framework |
| 13:37 | johnwalker | ahh, so one of the other dependencies in the project? |
| 13:37 | llasram | johnwalker: I'm not sure what the intent is there in that project.clj file though. The resulting pom.xml will have the deps marked as sscope=provided, but Leiningen expects "provided" dependencies to go in the "provided" profile |
| 13:38 | llasram | johnwalker: No, but I could be mistaken |
| 13:38 | llasram | Usually you use it to indicate actual dependencies of the project, but which dependencies shouldn't be added to e.g. an uberjar, because they'll be provided at runtime in some other fashion |
| 13:39 | llasram | I don't know what it means heer |
| 13:39 | llasram | here |
| 13:39 | johnwalker | ok, so it also works for clojure? |
| 13:40 | johnwalker | er, that should have been a statement |
| 13:40 | johnwalker | thanks llasram |
| 13:40 | johnwalker | (inc llasram) |
| 13:40 | lazybot | ⇒ 29 |
| 13:40 | llasram | np... I hope actually helpful :-) |
| 13:41 | johnwalker | definitely |
| 13:42 | technomancy | johnwalker: iiuc :provided only makes sense for a project that's distributed via uberjar but not run via `java -jar ...` |
| 13:43 | technomancy | I don't know anything about this project, but it seems a bit fishy |
| 13:48 | johnwalker | technomancy: llasram: the plot thickens |
| 13:51 | johnwalker | (inc technomancy) |
| 13:51 | lazybot | ⇒ 126 |
| 13:59 | kwladyka | bridgethillyer any good comperassion about that framework from about last 3-moths? :) I need create web app and need solutions like validation example http://laravel.com/docs/validation#available-validation-rules and relationships in DB like http://laravel.com/docs/eloquent#relationships, clever forms like http://laravel.com/docs/html#form-model-binding |
| 14:00 | kwladyka | Any framework or framework + some packages can give me that stable? |
| 14:02 | kwladyka | Clojure is specific language... i am not sure how to thing about that... get simply framework and find packages or get complex framework. In other languages i am sure i want complex framework but Clojure is functional language and i am not so expirence with that. |
| 14:03 | boxed | those validation rules seems like just simple functions in the standard lib… but maybe you want something like http://let-caribou.in ? |
| 14:03 | boxed | or rather.. that’s what you’re looking for, but it might not be the best thing! |
| 14:03 | kwladyka | mayby in Clojure all is so simply to glue together so i can easy get simply web framework, some package for relationships and validation on database structer etc. and it will always work together stable |
| 14:04 | boxed | for example: that form “bindings” thing can be done much easier and simpler in Reagent |
| 14:04 | kwladyka | boxed: yes, its simply but there is more things like that, it's about time of coding |
| 14:05 | boxed | I mean in time of coding easier and simpler too… but of course using something new takes more time |
| 14:06 | kwladyka | boxed: for me is always better has ready solution for example validations with most possibilites what i want then write my own |
| 14:06 | boxed | eh.. depends |
| 14:06 | kwladyka | also the same with database relationship |
| 14:06 | kwladyka | but ofcourse example i always preffer my own solutions for front-end, using ready solutions always *ucks :) |
| 14:06 | ToBeReplaced | silly little puzzle... what's a nice way to go from [0 1 2 3] to ([0 1 2 3] [1 2 3] [2 3] [3]) ? All i've got is (->> [0 1 2 3] (iterate next) (take-while some?))... which is close enough, but doesn't read very well |
| 14:07 | boxed | kwladyka: try Reagent. Really! |
| 14:10 | boxed | ,(let [x [0 1 2 3]] (for [i (range (count x))] (drop i x))) |
| 14:10 | clojurebot | ((0 1 2 3) (1 2 3) (2 3) (3)) |
| 14:11 | boxed | reads pretty clearly imo |
| 14:12 | ToBeReplaced | boxed: not sure i agree, but subjective so ::shrug:: |
| 14:13 | boxed | “give me the list dropping nothing, then give me the list dropping one, and so forth until the list is empty” |
| 14:13 | ToBeReplaced | boxed: i don't like that it requires x to be countable |
| 14:13 | boxed | ah |
| 14:13 | boxed | you want something that works for a seq of 1 2 3 too? |
| 14:14 | ToBeReplaced | boxed: but maybe that's a feature for readability |
| 14:14 | boxed | I think it can be :P |
| 14:14 | ToBeReplaced | boxed: i don't know what i want / don't have anything in particular i'm looking for... just realized that i didn't care for what i had and was interested in seeing other ways |
| 14:16 | boxed | to my mind it makes more sense to make the terminating form as explicit as possible.. “(take-while some?)” doesn’t really speak to me but “(drop i x)” is very clear |
| 14:16 | kwladyka | boxed reagent is javascript not "clear" Clojure? Damn... so many things to test and thing about the choice :) |
| 14:17 | boxed | kwladyka: it’s for ClojureScript not Clojure yea, so you run it on the client instead of javascript |
| 14:18 | kwladyka | is it somethig similar to meteor framework? |
| 14:20 | kwladyka | ok so i have last question :) |
| 14:20 | boxed | kwladyka: not really.. meteor seems to go the entire way to the DB which sounds like a horribly bad idea. Reagent is more like… angular maybe? but imo better and based on React so much much faster |
| 14:22 | kwladyka | Clojure is functional language and i am beginner with that. Example in PHP is good to have big complex framework with everything because glues some idenpedned parts is not easy. How is it look in Clojure? Better is get complex framework or simply framework + package for validation + package for database structure etc. What do you thing about that? |
| 14:22 | kwladyka | or mayby packages like that doesn't exist :) |
| 14:23 | boxed | you don’t need a big package for validation. Just make a simple if statement. |
| 14:23 | kwladyka | boxed i have to write "Reagent" in my notes to check this :) |
| 14:23 | kwladyka | i know but the question is about something else |
| 14:23 | boxed | kwladyka: http://yogthos.net/blog/54-Building+Single+Page+Apps+with+Reagent |
| 14:24 | kwladyka | how easy and stable is glue many small element in Clojure, better then one complex framework or not? |
| 14:24 | boxed | putting together parts is mostly a lot easier yea |
| 14:24 | TimMc | ToBeReplaced: ##(reverse (rest (reductions conj () (reverse (range 4))))) |
| 14:24 | lazybot | ⇒ ((0 1 2 3) (1 2 3) (2 3) (3)) |
| 14:24 | TimMc | Now, just to replace conj with something that starts with "re"... |
| 14:24 | boxed | but it’s also early days in Clojure, so maybe there _should_ be a big framework that is a collection of good stuff |
| 14:25 | technomancy | boxed: iiuc that's what luminus is |
| 14:25 | boxed | technomancy: ok.. haven’t gotten that far yet :P |
| 14:25 | technomancy | I haven't used it either |
| 14:25 | boxed | kwladyka: so look at luminus too! :P |
| 14:27 | kwladyka | boxed, i don't know today how it should works in functional language... i know in non-functional is good to have complex solutions but only because is hard to integrate all this things. But from other side having all complex give some problems when you want something more custom... i guess the only one way to figure out what is better in Clojure is learn and try both ideas. |
| 14:27 | verma | is there a reason to use emacs over vim + fireplace for clojure(script) dev? |
| 14:28 | technomancy | verma: lots of reasons to, and lots of reasons not to |
| 14:28 | boxed | kwladyka: addaboy! |
| 14:28 | kwladyka | lighttable looks good as editor |
| 14:28 | kwladyka | i think :) |
| 14:28 | kwladyka | because i am beginner but it look really good |
| 14:28 | jcromart_ | OK so I am going to say, I really really really like Enlive for most things |
| 14:28 | jcromart_ | but when it comes to something like forms |
| 14:28 | jcromart_ | I am at a loss |
| 14:28 | jcromart_ | forms are like, blech |
| 14:28 | boxed | kwladyka: I find that clojure seems to be nice to plug things together because of a strong culture of keeping the data itself simple with maps, sets and lists. That makes combining things much much easier than in OOP |
| 14:28 | jcromart_ | I mean HTML forms are always kind of like that |
| 14:29 | kwladyka | boxed: but example in PHP i can definitly say what is better... just expirience :) |
| 14:29 | jcromart_ | I guess not everything in my views needs to be an Envlive defsnippet |
| 14:30 | kwladyka | boxed: yes and this is the reason why i am thinging about try more small ements then less bigger in Clojrue. Becaouse of cluture of maps etc. |
| 14:30 | verma | technomancy, I see emacs being popular among clojure developers, wonder if that's because its a concious choice over vim or is it just because that's what they've been using before clojure |
| 14:30 | moquist | kwladyka: There's some good advice here (blog.getprismatic.com/software-engineering-at-prismatic/) about how to think differently in Clojure-land than in OOP-land. Note the gentle push away from frameworks and toward libraries. |
| 14:31 | moquist | kwladyka: I use emacs+EVIL+cider for Clojure work, but highly recommend checking out lighttable. |
| 14:31 | technomancy | verma: well it is a lisp virtual machine |
| 14:32 | kwladyka | moquist: thx, i will read that |
| 14:32 | kwladyka | Anybody use lighttable? |
| 14:32 | verma | technomancy, sure, but does that play a part in day to day software dev? |
| 14:32 | kwladyka | http://www.lighttable.com/ |
| 14:32 | verma | kwladyka, I've "tried it" sure |
| 14:33 | technomancy | verma: it does if you're using it correctly |
| 14:33 | kwladyka | verma and what do you think about that? |
| 14:33 | verma | technomancy, nice, tell me more, or point me to somewhere |
| 14:33 | technomancy | working in programs that don't have a repl as an integral part of them is just a nightmare |
| 14:33 | boxed | kwladyka: yea I code clojure in it… it’s a bit rough but has some really nice things too |
| 14:33 | kwladyka | its really similar edior to Sublime Text 3 as in my opinion is one of the best |
| 14:33 | technomancy | well, programs with nontrivial interfaces |
| 14:34 | verma | kwladyka, vi bindings were a little iffy, so I never gave it much time, but it seemed like I could customize it a lot |
| 14:34 | technomancy | it's just ... you're a programmer. you should be programming your programs as you use them. that should be your natural state. |
| 14:34 | technomancy | but so much crap is hard-coded and impossible to modify. |
| 14:34 | verma | technomancy, :) |
| 14:35 | technomancy | the fact that browsers don't work this way should be a source of great shame for the entire industry |
| 14:35 | technomancy | http://technomancy.us/161 |
| 14:35 | technomancy | this isn't specific to emacs or anything |
| 14:36 | technomancy | smalltalk and genera are the same way |
| 14:37 | verma | technomancy, hmm nice |
| 14:38 | boxed | technomancy: I looked into fiddling with the syntax highlighting of clojure in light table… turns out it’s all a big hairy javascript parser that’s pretty damn horrible. I just gave up |
| 14:38 | boxed | I wanted to add reasonable things like marking the keys in maps diffently from the values… but yea |
| 14:39 | tjd | is there an idiomatic way to version records with edn? |
| 14:39 | Glenjamin | Firefox sorta works that way, it's a shame there was that dark spell where venkman and dom inspector weren't supported well |
| 14:39 | tjd | like #com.example.Product.V1 {:foo "bar"} |
| 14:40 | tjd | but that feels dirty |
| 14:41 | dnolen_ | ClojureScript 0.0-2277 released, should fix REPL issues to Google Closure Library changes |
| 14:41 | dnolen_ | due to |
| 14:42 | technomancy | Glenjamin: in a way that's even worse |
| 14:42 | technomancy | because there's no technical reason it sucks so bad |
| 14:42 | technomancy | all the parts are there to build something sensible, and no one has done it |
| 14:43 | Glenjamin | UI was all hackable XUL and JS, extensions can do basically anything |
| 14:43 | Glenjamin | Not sure how true that is anymore |
| 14:43 | Jaood | technomancy: so is it emacs what drove to you clojure? :) |
| 14:43 | technomancy | Jaood: absolutely |
| 14:44 | Jaood | thought so by reading that post |
| 14:44 | boxed | what’s the name of that site that shows you which clojure libs are used by which projects and how popular libs are? I can never remember |
| 14:44 | technomancy | boxed: http://clojuresphere.com |
| 14:45 | Glenjamin | Cross clj as well? |
| 14:45 | boxed | huh, that wasn’t the one I was thinking about but that’s cool :P |
| 15:01 | Bronsa | hiredman: ping |
| 15:02 | hiredman | yo |
| 15:02 | hiredman | I mean pong |
| 15:03 | Bronsa | hiredman: hi, I'm looking at your patch&comments on CLJ-701 and you mention you're seeing some verification errors |
| 15:03 | hiredman | yes, which I have had no luck solving |
| 15:03 | Bronsa | I've been implementing loop/try hoisting on tools.emitter.jvm myself over the last couple of days & it compiles data.json fine |
| 15:04 | hiredman | lucky you :) |
| 15:04 | Bronsa | do you have any specific code you can give me that causes the error so I can help you out? |
| 15:04 | hiredman | https://github.com/clojure/data.json/blob/master/src/test/clojure/clojure/data/json_compat_0_1_test.clj#L221 |
| 15:04 | hiredman | I have been meaning to do a gist or something writing up the current issue I am having |
| 15:06 | hiredman | basically, it sort of looks like operations on longs are not being emitted in such a way as to properly take in to take in to account how many local slots a long takes up |
| 15:06 | hiredman | I am not 100% sure that is accurate, but it is what seems to be the case |
| 15:08 | hiredman | but I don't think the compiler at all concerns itself with that issue, defering to asm to track it internally, so how it could be a problem I have no idea |
| 15:08 | Bronsa | hiredman: ok I've confirmed that it works w/ t.e.j, I'll look into it when I have some time |
| 15:08 | Bronsa | hiredman: uhm, I'm pretty sure the compiler needs to deal with it actually |
| 15:09 | kwladyka | boxed: thx again for http://www.clojuresphere.com/ :) |
| 15:09 | Bronsa | hiredman: for longs/doubles it needs to reserve 2 local slots |
| 15:10 | hiredman | right |
| 15:10 | gfrederi` | so leiningen profiles |
| 15:10 | hiredman | but I haven't seen a place in the compiler where it does that |
| 15:10 | gfredericks | if I have a profile that adds a dependency |
| 15:10 | gfredericks | should `lein with-profile +foo uberjar` actually work? |
| 15:10 | hiredman | (which I thought it must, for deftypes with primitives, primitive lets, etc) |
| 15:10 | gfredericks | or is uberjar going to undermine my efforts? |
| 15:11 | hiredman | so I assumed asm's internal machinery must be doing the bookkeeping |
| 15:14 | hiredman | maybe I am just not doing the registerlocal thing correctly |
| 15:14 | hiredman | anyway, I spent all of yesterday pointedly not thinking about it :) |
| 15:16 | Bronsa | hiredman: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L5213, https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7998, https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L4296 |
| 15:16 | vdmit11 | Hi folks. I'm implementing a bunch of custom types. For instance, there are 'Action' and 'Process', a Process consists of Actions. Both types have a property called 'duration'. But the Process needs to calculate the 'duration' as a sum of all nested Actions. So I'm going to define a protocol. So there is a question: how to put such a "field" to a protocol? Is there an idiomatic way, something more handy than a getter and a setter method? Is it idiomatic to comb |
| 15:19 | Bronsa | hiredman: + all the places where it checks to know whether to emit pop or pop2 |
| 15:20 | hiredman | right |
| 15:20 | hiredman | interesting |
| 15:21 | hiredman | (I was aware of the pop2 thing, but somehow must have missed this) |
| 15:36 | gfredericks | oh I see the problem |
| 15:37 | gfredericks | if my :dev profile includes the :foo profile, then I'm unable to add :foo to the uberjar task |
| 15:37 | gfredericks | i.e., it silently doesn't add it |
| 15:39 | gfredericks | does anybody know if this is a bug? |
| 15:49 | llasram | gfredericks: I think it's a known issue... The problem is that the :dev profile gets unmerged as part of the uberjar task |
| 15:50 | llasram | Hmm, which. Yeah, maybe it is a bug |
| 15:50 | llasram | My absence means I'm out of the loop -- jcrossley fixed some related-in-my-mind bugs right before the last release |
| 15:52 | llasram | The profile unmerging stuff always goes fuzzy unless I focus my entire consciousness on it |
| 15:52 | gfredericks | yeah I don't have any guesses how it works |
| 15:54 | gfredericks | my use case is just that I want different versions of a dependency |
| 15:54 | gfredericks | seems innocuous enough |
| 15:55 | gfredericks | and the versions actually have different group names, so I can't put a default in the main :dependencies list |
| 15:55 | llasram | Ugh. Yeah, I hate that |
| 15:56 | gfredericks | so I did :profiles {:a {deps w/ a} :b {deps w/ b} :dev' {normal dev stuff} :dev [:dev' :a]} |
| 15:57 | llasram | Last time I fought with something like that, I ended up using with-profile aliases to entirely replace the default profile set |
| 15:57 | llasram | https://github.com/damballa/parkour/blob/master/project.clj#L39-L52 |
| 15:58 | mdrogalis | stuartsierra: Component question. Why'd you decide to wrap up exceptions emitted from start/stop-system into the cause of another exception? |
| 16:00 | stuartsierra | mdrogalis: They're wrapped to convey the last known state of the system before the exception was thrown, so you can use it to recover or clean up. |
| 16:02 | mdrogalis | stuartsierra: Hm, alright. |
| 16:03 | stuartsierra | It's not necessarily sufficient: if a component's `start` method created some partial state and then threw an exception, you will not have any way to get at the partially-constructed state. |
| 16:04 | stuartsierra | I can't fix this: you have to write your `start` and `stop` methods carefully if you want to protect against this. |
| 16:06 | jcromart_ | where is the appropriate channel on freenode for venting/rambling? |
| 16:10 | technomancy | #emacs for the latter |
| 16:12 | llasram | The mission of #clojure-offtopic seems broad enough to encompass nearly anything |
| 16:13 | technomancy | you can also do a private message to clojurebot |
| 16:13 | mr-foobar | i have regexes, start and end, to define a text region. how can I extract multiple regions from a text file, functionally ? |
| 16:13 | llasram | technomancy: That seems so... extra sad though |
| 16:14 | technomancy | llasram: well you never know when something you say may resurface |
| 16:16 | alexyakushev | Hi everyone. What would be the best way to get a dependency tree of namespaces for one chosen namespace? I'm thinking about clojure.tools.namespace, but not sure how to apply it |
| 16:17 | stuartsierra | alexyakushev: tools.namespace does have the necessary pieces... |
| 16:17 | alexyakushev | I suppose functions from clojure.tools.namespace.dependency should help, right? |
| 16:18 | stuartsierra | That's part of it, but that's just the dependency tree data structure, not specific to namespaces. |
| 16:19 | stuartsierra | Shortest way right now is to create a project with your namespace + tools.namespace, call `clojure.tools.namespace.repl/refresh`, then get the dependency graph from (:clojure.tools.namespace.track/deps @#'clojure.tools.namespace.repl/refresh-tracker) |
| 16:20 | stuartsierra | Not at all obvious, I know. |
| 16:20 | alexyakushev | stuartsierra: Yeah, and kinda side-effectish |
| 16:21 | alexyakushev | stuartsierra: Seems like I'll have to do it manually by calling read-ns-decl |
| 16:22 | stuartsierra | tools.namespace mostly works with files, and relies on the ability to parse the `ns` declaration without evaluating it. |
| 16:25 | alexyakushev | Can I somehow infer a list of required namespaces in pure Clojure? |
| 16:25 | alexyakushev | Maybe from "mappings" or "namespaces" maps |
| 16:33 | stuartsierra | alexyakushev: You could get close with `ns-refers` and `ns-aliases`, but neither tells you if a namespace :require's another namespace without aliasing or referring any symbols. |
| 16:33 | stuartsierra | e.g. (ns foo (:require bar)) |
| 16:35 | alexyakushev | stuartsierra: Well, I guess I'll stick to tools.namespace then |
| 16:35 | stuartsierra | ^^ The dependency of 'foo' on 'bar' cannot be determined from runtime metadata. |
| 16:36 | stuartsierra | It's tricky because Clojure doesn't really have a notion of a compilation unit larger than a single expression. |
| 16:37 | stuartsierra | Files are just sequences of expressions to the compiler; `in-ns` and `require` are side-effects. |
| 16:37 | technomancy | depending on what it's for, it may be reasonable to say that if you alias or refer without a require, you're doing it wrong, and the tool is just not going to help you |
| 16:37 | technomancy | slamhound does plenty of that |
| 16:37 | technomancy | and some people don't like it, but I can just say "too bad; that's not what slamhound is for" and get on with life. |
| 16:38 | stuartsierra | I agree that using a namespace without 'require'ing it is probably a mistake, but I do sometimes :require a full name without an alias or a refer. |
| 16:39 | fifosine | If I change a method in hashmap, is there a way to force all other methods to return the same type (i.e., a hashmap with the same changed method)? |
| 16:41 | alexyakushev | stuartsierra, technomancy: Thank you for clarification |
| 16:42 | alexyakushev | The usecase actually is to get the list of all clj files in my own library, but in the "correct" order |
| 16:42 | alexyakushev | So I can control if I refer anything without :require (which I don't) |
| 16:46 | hoverbear | I've got a "io.undertow.servlet.util.IteratorEnumeration@3b9c778e" .... How do I "unwrap" this in Clojure? |
| 16:46 | stuartsierra | alexyakushev: Something like this might work (-> (clojure.tools.namespace.dir/scan (clojure.tools.namespace.track/tracker) "src") :clojure.tools.namespace.track/deps clojure.tools.namespace.dependency/topo-sort) |
| 16:48 | alexyakushev | stuartsierra: Can I make it scan files on the classpath? |
| 16:49 | stuartsierra | alexyakushev: yes, use java.classpath to get a list of directories on the classpath |
| 16:51 | alexyakushev | stuartsierra: Well, what I meant is that I want to scan files that are in a jar |
| 16:51 | stuartsierra | That's much harder. |
| 16:51 | stuartsierra | alexyakushev: You can expand files in the jar with java.classpath too. |
| 16:51 | justin_smith | alexyakushev: a jar is a zip file, open it with your favorite zip file software |
| 16:52 | justin_smith | unless you mean you have to do it inside clojure at runtime |
| 16:52 | stuartsierra | alexyakushev: What are you really trying to do? |
| 16:54 | alexyakushev | stuartsierra: It's complicated:). @bbatsov and @trptcolin are trying to replace clojure-complete with Compliment in Reply. There is a usecase in Reply where it has to transmit all clojure files for the underlying completion backend to the remote nREPL instance. |
| 16:54 | alexyakushev | stuartsierra: The order of files transmitted should be such that if evaluated one after one it will work correctly |
| 16:55 | alexyakushev | stuartsierra: I don't like to hardcode all of the Compliment files inside Reply, so I'm searching a way for Reply to build that list of files automatically |
| 16:57 | stuartsierra | alexyakushev: OK, so you want to search for *all* .clj files anywhere on the classpath then, right? |
| 16:58 | alexyakushev | stuartsierra: Ideally for all files that belong to "compliment/" directory in resources, but yes, I can search for all and filter them after |
| 16:58 | BobSchack | seangrove: I just pushed perf improvements, api improvements and an in depth caching example. |
| 17:00 | stuartsierra | alexyakushev: Why does 'Reply' need to know about all the namespaces in 'Compliment'? |
| 17:00 | BobSchack | I'll be busy during the weekend but feel free to email me any questions you have and pain points you discover and I should be able to get to them next week. |
| 17:01 | alexyakushev | stuartsierra: That's even more complicated. Reply supports mode when it connects to a remote nREPL instance that might not have any completion backend loaded. So in order to provide completion it transfers all the files for completion backend to that nREPL instance and loads them there. |
| 17:06 | stuartsierra | alexyakushev: I have to say, this all sounds excessively complicated to me. But if you really want to do it... yes, you could use java.classpath to enumerate every file on the classpath, filter them by name, then use tools.namespace.file to add each file to a dependency graph, get the topologically-sorted list, then filter again by your namespace prefix. |
| 17:08 | alexyakushev | stuartsierra: At this point the hardcoding solution doesn't seem that bad |
| 17:08 | stuartsierra | alexyakushev: yes. |
| 17:08 | technomancy | alexyakushev: bultitude does this |
| 17:08 | technomancy | oh, but you probably can't add a dep |
| 17:09 | seangrove | BobSchack: That's awesome, thank you |
| 17:09 | mikerod | what is a good use case for `var-get`? |
| 17:10 | mikerod | it looks like `deref` is the same thing for a var |
| 17:10 | mikerod | and it is used by it |
| 17:10 | alexyakushev | technomancy: Perhaps I could try to use builtitude, thanks |
| 17:10 | mikerod | if(!threadBound.get()) |
| 17:11 | mikerod | maybe this is the difference, but I don't see what the implications of this is |
| 17:11 | mikerod | So, can `var-get` give you a different result than `deref` for some Var object? |
| 17:11 | alexyakushev | technomancy: If it's only one dependency, I can probably talk Colin into it |
| 17:11 | technomancy | "It's not just a Clojure lib... it's a Raynes® lib." |
| 17:12 | technomancy | taste the difference |
| 17:12 | trptcolin | alexyakushev: fwiw my principal dependency concerns are for lein users |
| 17:13 | technomancy | bultitude is already in lein, but not on the project side |
| 17:13 | trptcolin | and since lein already uses bultitude (in the lein process/classloader) it should probably be fine |
| 17:13 | Raynes | technomancy and I are the king of ignoring stuartsierra's objections to features and just writing our own libraries. :P |
| 17:13 | stuartsierra | :) |
| 17:13 | technomancy | Raynes: but... it's part of this complete breakfast |
| 17:13 | trptcolin | btw how do people feel about this potential clojure-complete -> compliment transition? |
| 17:14 | stuartsierra | trptcolin: This discussion isn't filling me with confidence. |
| 17:14 | trptcolin | the big win as far as i’m concerned is being able to complete available java instance methods |
| 17:14 | Raynes | In all seriousness, the original reason for bultitude's existence was an issue with the other lib breaking on malformed ns lines. |
| 17:14 | Raynes | I don't think we communicated the issue well enough to stuartsierra so he declined a fix. |
| 17:14 | Raynes | In case anyone was ever wondering. |
| 17:15 | stuartsierra | Or it was just my natural obtuseness. :P |
| 17:15 | alexyakushev | stuartsierra: Well, that mess is not about Compliment. REPLy already did the files-transaction-evaluation thing, but clojure-complete had just one file |
| 17:15 | stuartsierra | obtusity? |
| 17:15 | Raynes | Bultitude is basically a leiningen-optimized version of stuartsierra's lovely library. |
| 17:15 | stuartsierra | obtusiveness? |
| 17:16 | technomancy | Raynes: didn't a lot of it come from swank? |
| 17:16 | Raynes | technomancy: I don't think so? |
| 17:16 | technomancy | oh |
| 17:16 | technomancy | carry on then |
| 17:16 | Raynes | technomancy: I'm pretty sure you just copied stuart's library and changed like a line of code. |
| 17:16 | Raynes | Then I moved it into a separate library |
| 17:16 | Raynes | And then people added features ad infinitum. |
| 17:16 | stuartsierra | alexyakushev: So can you fit your library in one file? |
| 17:17 | alexyakushev | stuartsierra: nah, that was my original gripe with clojure-complete |
| 17:17 | alexyakushev | Well, one of |
| 17:18 | stuartsierra | Then I think I give up. :) |
| 17:20 | technomancy | Raynes: you still want a keyboard? |
| 17:21 | Raynes | technomancy: My body says yes but my bank account says next month. |
| 17:21 | technomancy | works for me |
| 17:21 | alexyakushev | stuartsierra: You've tried though:) Anyway thank you for fruitful discussion, I now know better to accept low-hanging approaches and not over-engineer |
| 17:21 | Raynes | technomancy: I'll set a reminder to send you a bag of cash on the 1st. |
| 17:21 | stuartsierra | alexyakushev: You're welcome. Good luck! |
| 17:22 | technomancy | gold coins would be ok too |
| 17:22 | Raynes | technomancy: To be clear, I just said "Ok google, remind me on the 1st of August to buy a keyboard from Phil Hagelberg" and my WRISTWATCH set a reminder. |
| 17:22 | Raynes | Just so you know how much technology I just used. |
| 17:23 | technomancy | I'm holding out for smart pocket watches |
| 17:24 | seangrove | technomancy: Same here, can't wait for google monocle |
| 17:24 | Raynes | technomancy: The best part was that it even got the spelling of your name right. |
| 17:24 | stuartsierra | technomancy: like … a phone? |
| 17:26 | technomancy | stuartsierra: it's not the same without the gold chain |
| 17:26 | technomancy | future status http://86bb71d19d3bcb79effc-d9e6924a0395cb1b5b9f03b7640d26eb.r91.cf1.rackcdn.com/wp-content/uploads/2011/06/zelda-ocarina-of-time-money-cheat-big-and-purple-rupees-guide-screenshot.jpg |
| 17:26 | technomancy | heh, this one is pretty good too though http://www.funnyjunk.com/channel/legend-of-zelda/I/onkrDba |
| 17:27 | pmonks | I’m still waiting for smart people to be as ubiquitous as smart gadgets (present company excluded, of course!). |
| 17:27 | stuartsierra | http://www.amazon.com/FOSC-Crossbody-Wearable-Silicone-Samsung/dp/B00EVZRPNK |
| 17:28 | technomancy | not bad |
| 17:31 | mimieux | |
| 17:45 | PigDude | What is the idiomatic way to update multiple record fields? I have been using merge |
| 17:45 | PigDude | (-> r (assoc :k v) (assoc :k v)) i don't like the repeated assoc |
| 17:46 | Bronsa | ,(assoc {} :a 1 :b 2) |
| 17:46 | clojurebot | {:b 2, :a 1} |
| 17:47 | dbasch | PigDude: assoc takes multiple kvs, see the docs |
| 17:47 | PigDude | oh ok, thanks dbasch |
| 17:50 | _2_candy12345 | :D:D:D:D:D:D:D |
| 17:54 | bbloom | does anybody else consistently accidentally lose *e by causing another exception while trying to inspect *e ? |
| 17:54 | perplexa | haha |
| 17:54 | Bronsa | me too |
| 17:54 | perplexa | +1 |
| 17:54 | Bronsa | bbloom: I learned to (def a *e) because I'm too stupid |
| 17:55 | bbloom | idea: if the symbol *e appears in the expression, then don't set *e... sound like it would help? |
| 17:55 | bbloom | could anything horrible go wrong with that? |
| 17:56 | bbloom | Bronsa: heh, why not (def e *e) .... |
| 17:56 | ambrosebs | (pst) ;=> ; No such var |
| 17:56 | bbloom | ambrosebs: argh. |
| 17:56 | bbloom | i actually despise the relative nature of *1 etc too |
| 17:57 | gfredericks | erlang style integers would be cool |
| 17:57 | Bronsa | haha I actually constantly mess up *1 & friends too |
| 17:57 | bbloom | mathematica has Out[n] |
| 17:57 | bbloom | with shorthand %n |
| 17:57 | bbloom | but also supports arbitrary strings of % |
| 17:57 | Bronsa | 85% of the times I (use 'clojure.pprint) and forget to replace *1 with *2 on the previous input |
| 17:57 | bbloom | so you get both relative and absolute |
| 17:58 | gfredericks | my bg macro defs things with incrementing integers |
| 17:58 | bbloom | http://reference.wolfram.com/language/ref/Out.html |
| 17:58 | gfredericks | but that's only useful for backgrounding slow things |
| 17:59 | bbloom | seems like %% is represented by Out[-2] |
| 17:59 | bbloom | that's basically what i want |
| 17:59 | bbloom | (clojure.repl/in n) and (clojure.repl/out n) |
| 17:59 | bbloom | and (clojure.repl/err n) |
| 18:00 | bbloom | with both absolute & relative |
| 18:00 | gfredericks | negatives for relative? |
| 18:00 | bbloom | yes |
| 18:01 | gfredericks | should this be nrepl client stuff or middleware stuff or regular lib stuff? |
| 18:01 | bbloom | i think it needs to be part of nrepl, but i'm not an expert on that stuff |
| 18:01 | bbloom | i also want the default history to be at least 100 |
| 18:01 | ambrosebs | oh boo, I hope this interview gets put back up http://codequarterly.com/2011/rich-hickey/ |
| 18:02 | mlb- | I'm setting a exception handler via Thread/setDefaultExceptionHandler (to simply call println, for now), but when I run (future (Thread/sleep 500) (/ 1 0)), I don't see any stdout. Am I missing something? |
| 18:02 | gfredericks | mlb-: yes |
| 18:02 | gfredericks | mlb-: futures will catch the exception and store it for throwing on deref |
| 18:03 | gfredericks | so the default exception handler doesn't factor in |
| 18:03 | mlb- | hmm. Okay. |
| 18:03 | gfredericks | try (.start (Thread. #(...))) |
| 18:03 | mlb- | Is that the same for core.async? |
| 18:04 | PigDude | why does (assoc r ..) return a new record, but (dissoc r) returns PersistentArrayMap? |
| 18:04 | gfredericks | no the default exception handler is relevant for at least some core.async usage |
| 18:04 | PigDude | is this behavior of assoc supported? the docs don't mention returning records |
| 18:04 | mlb- | gfredericks: okay, thanks much! =] |
| 18:04 | gfredericks | PigDude: a record has to have the basis keys |
| 18:04 | gfredericks | PigDude: so you always get records back unless you remove a basis key |
| 18:04 | PigDude | gfredericks: so assoc nil |
| 18:04 | gfredericks | mlb-: np |
| 18:05 | gfredericks | PigDude: not sure what you mean? |
| 18:05 | PigDude | gfredericks: if i want to unset a record field i need to assoc nil or otherwise create a new record, dissoc will remove the basis as you said |
| 18:06 | PigDude | gfredericks: is that right? |
| 18:07 | gfredericks | depends on what you're trying to achieve -- I think as envisioned removing a basis key is a weird thing to do |
| 18:07 | bbloom | ,`*1 ; ugh, forgot about that |
| 18:07 | clojurebot | clojure.core/*1 |
| 18:07 | bbloom | they aren't in clojure.repl or clojure.tools.nrepl or whatever |
| 18:08 | gfredericks | well nrepl does have to bother to set them |
| 18:08 | bbloom | yeah |
| 18:09 | gfredericks | PigDude: assoc nil is probably normal, yeah |
| 18:09 | gfredericks | I use that with component |
| 18:11 | PigDude | ok, thanks gfredericks ! |
| 18:13 | PigDude | gfredericks: and then i just wrote (reduce dissoc {:a 1 :b 2 :c 3} [:a :b]) before thinking hm ... i bet dissoc takes multiple keys too :) |
| 18:26 | bmabey | I am using java.data and I want to define a multimethod that extends the functionality of the :default multimethod. How can I explicitly call the :default method so I can then adjust the results? |
| 18:28 | bbloom | (doc get-method) ; bmabey |
| 18:28 | clojurebot | "([multifn dispatch-val]); Given a multimethod and a dispatch value, returns the dispatch fn that would apply to that value, or nil if none apply and no default" |
| 18:29 | bmabey | bbloom: ah, thanks |
| 18:42 | lxsameer | hey guys, I'm totally new to clojure, is there any lib to develop android native apps using clojure ? |
| 18:45 | Atlanis | there was a really useful library I'd toyed with before, i'm looking to see if i can find it again |
| 18:45 | Atlanis | at least, you'll want lein-droid. |
| 18:46 | Atlanis | lxsameer: neko (https://github.com/clojure-android/neko) |
| 18:48 | lxsameer | Atlanis: thanks |
| 18:57 | Atlanis | Jaood: its about the same as on any other computer (~3 seconds). way longer than i want to wait for an app to launch, but with the way android works most apps dont launch often |
| 18:57 | Atlanis | clojure launch time still frustrating though :( |
| 18:57 | benkay | so frustrating. |
| 20:00 | bobby_tables | I am using the clojure.tools.analyzer.jvm namespace and the ast generation is taking FOREVER on even relatively small code samples. is anyone else running into this, or is there something that can be done to limit the analysis to speed it up? thanks! |
| 20:03 | ambrosebs | bobby_tables: it shouldn't be more than 10x slow afaik |
| 20:03 | ambrosebs | but its faster than that in my experience |
| 20:03 | bobby_tables | ambrosebs: hmm... |
| 20:03 | ambrosebs | um, you're not printing the output are you? |
| 20:03 | ambrosebs | otherwise, do you have an example? |
| 20:04 | bobby_tables | ambrosebs: well, thanks for letting me know that you are at least having a different experience so i can see if it is something else that is going on |
| 20:05 | bobby_tables | pprint... ahh, right... great point... i didn't cosider that it had to analyse the layout - thanks, I will give that a try |
| 20:05 | ambrosebs | if you're printing it, make sure *print-length* and *print-level* are defined |
| 20:06 | bobby_tables | yeeeeppp... that was it... it was nearly instantaneous without the pprint formatting |
| 20:06 | ambrosebs | otherwise the ast will probably crash your program |
| 20:06 | bobby_tables | ambrosebs: thanks a ton! |
| 20:06 | bobby_tables | ambrosebs: okay, I will do that |
| 20:06 | ambrosebs | I have this in my profiles.clj: {:user {:injections [(set! *print-level* 10) (set! *print-length* 10)]}}} |
| 20:07 | ambrosebs | erm extra } |
| 20:07 | ambrosebs | stolen from Bronsa |
| 20:07 | bobby_tables | ambrosebs: cool... thanks |
| 20:07 | bobby_tables | bronsa... and thanks to you as well... |
| 20:07 | ambrosebs | np |
| 20:13 | bobby_tables | ambrosebs: the binding change made a ton of difference... thanks |
| 20:14 | ambrosebs | great |
| 20:14 | Balveda | Has anyone used clj-pdf? |
| 20:15 | Balveda | I need to format data from an excel so that I can spit out cards on a pdf for future printing; |
| 20:16 | Balveda | And for that I need to take a bunch of vectors of maps and format the data in such a manner that I'm creating vectors and essentially... rotating the data from the initial vector |
| 20:17 | Balveda | so the thing in the first row turns into the first column, etc |
| 20:17 | Balveda | What would be a good way to do this? |
| 20:46 | PigDude | is there a shortcut for (zipmap (map k coll) coll)? |
| 20:48 | justin_smith | (reduce (fn [m v] (assoc m v (k v))) {} coll) not a shortcut, but is an laternate option |
| 20:49 | PigDude | sometimes i see people do weird (apply hash-map)-type stuff where zipmap would work |
| 20:50 | PigDude | (apply hash-map (interleave ...) or something |
| 20:50 | hyPiRion | (into {} (map (juxt k identity) coll)) |
| 20:50 | PigDude | is there a reason for that or just to feel smart? |
| 20:50 | justin_smith | (inc hyPiRion) |
| 20:50 | lazybot | ⇒ 40 |
| 20:50 | justin_smith | yeah, I like that one best |
| 20:50 | PigDude | hehe |
| 20:51 | PigDude | ok thank you |
| 20:51 | justin_smith | PigDude: apply hash-map makes sense when the things you want are already alternating in one sequence |
| 20:52 | justin_smith | in k,v,k,v ... order |
| 20:53 | justin_smith | zipmap makes most sense when the source of the keys and the source of the vals are totally independent, but when they come from the same sequence (which is the majority of cases I see) it seems a bit odd to walk something twice to get one result |
| 20:53 | justin_smith | though the performance implications there are not likely huge |
| 20:54 | PigDude | justin_smith: yea, what surprised me was to see taking two sequences that could be (zipmap s s2) and doing (apply hash-map (interleave s s2)) |
| 20:55 | justin_smith | yeah, that's a silly one for sure |
| 20:55 | justin_smith | (though I know I am guilty of worse) |
| 20:55 | PigDude | like making a mess to clean it up :) |
| 20:55 | PigDude | yea, core is big |
| 21:02 | Raynes | guys |
| 21:02 | Raynes | I need Chas's flowchart for whether or not to use records an stuff |
| 21:02 | Raynes | and* |
| 21:03 | justin_smith | http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/ |
| 21:03 | justin_smith | lol, as usual, I had it in my bookmarks but it was easier to find it via google |
| 21:03 | Raynes | thnx |
| 21:03 | justin_smith | np |
| 21:17 | tuft_ | finally the weekend is here. time for clojure programming |
| 21:17 | PigDude | tuft: and here i am trying to fix this bug so i can start my weekend and not think about clojure programming for 48hrs |
| 21:17 | Balveda | did anyone reply? I dropped |
| 21:19 | justin_smith | Balveda: vectors as in the clj datatype and rotating values, or as in vectorial data in a pdf and rotating the x/y coords? |
| 21:19 | tuft | PigDude: hah, isn't that the way |
| 21:19 | Balveda | as in the data type |
| 21:19 | tuft | PigDude: btw don't make me think about python for at least that long |
| 21:19 | arrdem | damnit is ambrose gone already.. |
| 21:19 | mthvedt | anger leads to hate, hate leads to object oriented frameworks |
| 21:19 | arrdem | (inc mthvedt) |
| 21:20 | lazybot | ⇒ 4 |
| 21:20 | Balveda | Basically I'm lifting data from an excel, so I get each row as a vector with all its information |
| 21:20 | justin_smith | ,(apply map vector [[0 1 2] [3 4 5] [6 7 8]]) Balveda |
| 21:20 | clojurebot | ([0 3 6] [1 4 7] [2 5 8]) |
| 21:20 | Balveda | ah |
| 21:20 | Balveda | interesting |
| 21:20 | Balveda | thanks |
| 21:20 | justin_smith | np |
| 21:21 | PigDude | tuft: don't make me think about python either :) too soon |
| 21:21 | PigDude | tuft: i am picking up sml in my free time :) |
| 21:22 | justin_smith | Balveda: you can even do (def transpose (partial apply map vector)) |
| 21:22 | justin_smith | though that may look like magic and may call for a comment explicating wtf that is doing :) |
| 21:23 | Balveda | well, i think i get the transpose part |
| 21:23 | Balveda | but the partial, no idea |
| 21:24 | justin_smith | partial returns a function that takes some more args, and applies all preceding args to it |
| 21:24 | justin_smith | ,(map (partial + 20) (range 5)) |
| 21:24 | clojurebot | (20 21 22 23 24) |
| 21:25 | Balveda | i see |
| 21:25 | justin_smith | well, that was a sloppy description, but hopefully the example helps :) |
| 21:25 | PigDude | Balveda: that works because of how (map) consumes extra collections: |
| 21:25 | PigDude | ,(map #(identity %&) [1 2 3] [4 5 6])) |
| 21:25 | clojurebot | ((1 4) (2 5) (3 6)) |
| 21:25 | justin_smith | PigDude: hah, using the implicit list generation of varargs, nice |
| 21:26 | PigDude | ;) |
| 21:27 | justin_smith | though I prefer (fn [& l] l) -- it's two characters shorter |
| 21:27 | justin_smith | or perhaps just list |
| 21:27 | justin_smith | heh |
| 21:27 | justin_smith | ,(map list [1 2 3] [4 5 6]) |
| 21:27 | clojurebot | ((1 4) (2 5) (3 6)) |
| 21:27 | Balveda | clojure is magic sometimes. |
| 21:28 | justin_smith | Balveda: there are lot's of funny tricks, but if you hang around here you'll see a lot of them |
| 21:28 | Balveda | what's the deal with map though? |
| 21:28 | justin_smith | Balveda: it's vararg |
| 21:28 | Balveda | how come the mapping rotates the vectors? |
| 21:28 | verma | is there a way to do a update-in style swap-in for atoms? which limits the swap to a certain key or seq of keys? |
| 21:29 | justin_smith | Balveda: if you map across multiple sequences, your function gets the first element of each one as args |
| 21:29 | justin_smith | then, it gets the second element of each one |
| 21:29 | justin_smith | etc. until you get to the end of the shortest one |
| 21:29 | justin_smith | if all you want is to rotate columns / rows, then you make a list of all the first items, then a list of all the second items, then a list of all the third items... |
| 21:30 | PigDude | (swap! a |
| 21:30 | Balveda | I see |
| 21:30 | PigDude | sorry wrong window |
| 21:30 | Balveda | I'll try this out as soon as I get my setup in this thing |
| 21:30 | Balveda | I have all my stuff in the linux partition |
| 21:30 | justin_smith | yeah, dev on linux tends to be more sane |
| 21:30 | verma | it'd be nice to do a (swap-in! atom [:hello :world] assoc :what "world") -> {:hello {:world {:what "world"}}} |
| 21:31 | Balveda | can't play masterwork dwarf fortress on linux though.. at least not the latest version |
| 21:31 | Balveda | and after a couple of hours of trying to get that to work i needed a break, heh |
| 21:31 | ToBeReplaced | "block and consume everything until channel is closed" -> (async/reduce (constantly nil) nil channel)? something more idiomatic? |
| 21:31 | justin_smith | verma: why not (swap! atom assoc-in [:hello :world :what] "world") |
| 21:32 | justin_smith | ,(swap! (atom {}) assoc-in [:hello :world :what] "world") |
| 21:32 | clojurebot | {:hello {:world {:what "world"}}} |
| 21:32 | verma | justin_smith, because I am going to replace the assoc with a more complex function |
| 21:32 | justin_smith | then use update-in |
| 21:32 | ToBeReplaced | i have a case where i'm using a channel as a sentinel... thread X periodically checks if channel is closed, if it is, stops |
| 21:32 | verma | that was just an example |
| 21:33 | verma | justin_smith, sure, just thought there was some better way :) thanks |
| 21:33 | justin_smith | ,(swap! (atom {}) update-in [:hello :world] #(assoc % :what "world")) |
| 21:34 | clojurebot | {:hello {:world {:what "world"}}} |
| 21:34 | verma | oh |
| 21:34 | verma | justin_smith, sweet |
| 21:34 | verma | justin_smith, much better than that what I was going to do :) |
| 21:34 | verma | (inc justin_smith) |
| 21:34 | lazybot | ⇒ 53 |
| 21:47 | drguildo | does anyone have any idea what's causing this when i run cider-jack-in? https://www.refheap.com/88607 |
| 21:48 | drguildo | i don't have any functions called create in my project |
| 21:49 | drguildo | or other symbols |
| 21:50 | justin_smith | what is in C:\Users\Simon.Simon-T400\AppData\Local\Temp\form-init6118470964490798405.clj |
| 21:51 | justin_smith | it has an error on line 4009 |
| 21:52 | justin_smith | sounds like either cider is broken by an update, or your install is hosed (hell, it could be both) |
| 21:52 | drguildo | it looks like some kind of intermediate compiled version of the code |
| 21:53 | justin_smith | some transformed version of your own namespaces? |
| 21:53 | drguildo | which looks pretty much like gibberish to me |
| 21:53 | drguildo | i guess |
| 21:57 | drguildo | it seems to work since i did "lein new" using a normal command prompt instead of one running inside emacs |
| 21:57 | drguildo | *shrug* |
| 21:58 | drguildo | oh wait |
| 21:58 | drguildo | i forgot to paste the code into the buffer |
| 22:02 | drguildo | yeah looks like shell+cmd messed things up |
| 22:07 | technomancy | justin_smith: eval-in-project writes forms to a file since windows can't handle command-line args of the length we need |
| 22:08 | justin_smith | technomancy: oh, interesting |
| 22:09 | justin_smith | technomancy: so that file will have everything cider has evaluated in it |
| 22:10 | nkozo | there is a way in prismatic schema to specify an specific value? this doesnt work: (schema.core/validate {:k 3} {:k 3})) |
| 22:10 | technomancy | justin_smith: just the first eval-in-project call |
| 22:10 | technomancy | which is usually from lein repl, not cider |
| 22:11 | justin_smith | ahh |
| 22:11 | nkozo | ok, found it, is schema.core/eq |
| 22:12 | justin_smith | it's funny all the different ways windows users get hobbled because ms so extensively commited to the philosophy of "standards are for the other guy" |
| 22:12 | clojurebot | Huh? |
| 22:12 | cespare | When I do deftype, why can't I add an extra method not on the interface I provided? ("Can't define method not in interfaces") |
| 22:17 | technomancy | justin_smith: more like "command lines are for the other guy" |
| 22:17 | technomancy | where "other" here means "the 1980s" |
| 22:17 | technomancy | I mean, it's certified posix compliant, so... |
| 22:19 | justin_smith | lol |
| 22:20 | justin_smith | btw, linux is not posix compliant |
| 22:22 | bbloom | cespare: in theory, you shouldn't need them. although i'll admit there are a few cases i've wanted a private method or two |
| 22:22 | technomancy | I wish I could remember the exact wording, but someone once said that Posix is to the aftermath of the unix wars as the restrictions on naval tonnage was to the aftermath of WWI. |
| 22:23 | justin_smith | hah |
| 22:23 | bbloom | standards are overrated anyway |
| 22:23 | sm0ke | linux is not posix? really? |
| 22:24 | p_l | sm0ke: it's not certified |
| 22:24 | sm0ke | who all are certified? |
| 22:25 | justin_smith | sm0ke: irony being windows is certified (and barely if at all usable as a posix system) |
| 22:25 | cespare | bbloom: why shouldn't I need them? |
| 22:25 | p_l | POSIX certs are outdated, these days you want SUSv3 |
| 22:25 | cespare | bbloom: methods are the only place I can use set!, yes? |
| 22:25 | p_l | justin_smith: windows posix subsystem gave about as good as OpenBSD, afaik, with better GUI and driver support ;) |
| 22:25 | bbloom | cespare: that's the one case where a private method would actually be useful, and i'd agree it's an oversight |
| 22:26 | cespare | bbloom: I'm still missing something though -- why wouldn't one expect to add any methods you want? In Java, you can define any methods that aren't on the interfaces you're implementing, right? |
| 22:26 | cespare | bbloom: and what's the workaround; make a protocol that has what I need? |
| 22:27 | bbloom | cespare: public methods that aren't part of an interface is a generally bad idea |
| 22:28 | bbloom | cespare: "always code to an abstraction" when working with objects |
| 22:28 | cespare | bbloom: okay, I wasn't aware of that. I'm not a java programmer. |
| 22:28 | cespare | thanks |
| 22:28 | bbloom | cespare: that's a controversial statement for java programmers, but not so for java programmers who write clojure on the side :-P |
| 22:29 | cespare | bbloom: I just wanted to implement IDeref |
| 22:29 | cespare | but also have some other methods. |
| 22:29 | bbloom | cespare: so what other public methods do you need? |
| 22:29 | bbloom | cespare: just define a protocol |
| 22:29 | bbloom | it's that simple |
| 22:29 | cespare | yeah, makes sense. |
| 22:29 | technomancy | bbloom: wait, "always code to an abstraction" is good, but private vars are bad? |
| 22:29 | technomancy | how is this possible |
| 22:31 | bbloom | technomancy: i didn't say private vars were bad |
| 22:31 | bbloom | technomancy: i said i'd like private methods |
| 22:31 | technomancy | ok, I was recalling a twitter conversation from a few days ago, but maybe I got the names mixed up |
| 22:31 | bbloom | i don't buy in to the idea that encapsulation has absolutely no place, only that it's significantly less useful when you have immutable data |
| 22:32 | technomancy | I'm glad that Clojure makes it both 0) easy to declare things as private and 1) nearly as easy to get around that declaration when you decide it's worth the risk |
| 22:33 | eggsby | less reason to have private stuff when you don't carry around a bunch of mutable state |
| 22:33 | bbloom | technomancy: agreed for vars, but the situation with deftype is a little less good |
| 22:33 | technomancy | I wouldn't know |
| 22:33 | technomancy | eggsby: having the freedom to change your arglists and know you're not going to break downstream consumers is a wonderful thing |
| 22:34 | technomancy | there are a bunch of places in lein where we have just a complete mess because it would be a breaking change to do the thing that actually makes sense |
| 22:34 | eggsby | isn't that kind of solved by versioning your api technomancy |
| 22:34 | bbloom | eggsby: i don't know of any decent API versioning support in any language really |
| 22:34 | technomancy | eggsby: there are various reasons why you would want to space out breaking changes by a year or more |
| 22:35 | eggsby | technomancy: I guess it is a litle ridiculous to think every refactor might lead to a version bump |
| 22:35 | technomancy | granted it's not as bad for most libs |
| 22:35 | technomancy | as it is with lein |
| 22:36 | eggsby | when I'm programming java I often feel the need to make things private to protect them from would-be future use |
| 22:38 | eggsby | well, probably b/c every third party api is stateful and mutable... |