2014-04-18
| 00:16 | base698 | Anyone know how to get this to work: (-> [old-position move] (partial apply interleave)) setting (def f (partial apply interleave)) works. |
| 00:17 | Frozenlock | ,(macroexpand-1 '(-> [old-position move] (partial apply interleave))) |
| 00:18 | clojurebot | (partial [old-position move] apply interleave) |
| 00:18 | base698 | well that's helpful |
| 00:18 | Frozenlock | base698: I suppose that's not what you wanted :-p |
| 00:18 | base698 | nope |
| 00:19 | Frozenlock | (macroexpand-1 '(->> [old-position move] (apply interleave))) |
| 00:19 | Frozenlock | ,(macroexpand-1 '(->> [old-position move] (apply interleave))) |
| 00:19 | clojurebot | (apply interleave [old-position move]) |
| 00:20 | base698 | hmm. |
| 00:22 | base698 | success! |
| 00:28 | base698 | Frozenlock: thanks. first time I've used ->> in the wild. |
| 00:29 | Frozenlock | base698: No problem. |
| 00:29 | Frozenlock | However I'm not sure this increase readability. I suppose there's some other stuff going in the ->> macro? |
| 00:29 | base698 | yeah, it's super long |
| 00:30 | base698 | not sure if that pasted |
| 00:31 | base698 | there was a map and partition and some other stuff |
| 01:24 | serjeem | Sort of specific question, but: I'm trying to play with libgdx in a repl. I've got everything running just fine, but when I try to exit the window, it crashes the repl, complaining that the "subprocess failed". |
| 01:25 | serjeem | Is there a way to keep the repl running even when the subprocess dies? |
| 02:07 | hiredman | serjeem: likely libgdx is kill the clojure/jvm process when the window closes, there should be an option in libgdx to disable that |
| 02:08 | hiredman | serjeem: lein runs two jvms, one is actually running lein, the second is your projects, if that message is from lein it is because the project jvm (where your code is being run) is dying |
| 02:42 | danielszmulewicz | Are forward declarations broken with the latest clojurescript? Doesn't seem to work here. |
| 03:16 | martintrojer | ,(= false) |
| 03:16 | clojurebot | true |
| 03:16 | martintrojer | great |
| 03:17 | Frozenlock | (= nil false) |
| 03:17 | Frozenlock | ,(= nil false) |
| 03:17 | clojurebot | false |
| 03:17 | martintrojer | ,(every? (constantly false) []) |
| 03:17 | clojurebot | true |
| 03:17 | martintrojer | perfect |
| 03:25 | dbasch | ,(= = - = =) |
| 03:25 | clojurebot | false |
| 03:25 | martintrojer | ,(every? (constantly false) [false]) |
| 03:25 | clojurebot | false |
| 03:26 | dbasch | ,(every? (constantly false) [true]) |
| 03:26 | clojurebot | false |
| 03:27 | martintrojer | ,(every? (constantly false) []) |
| 03:27 | clojurebot | true |
| 03:27 | dbasch | ,(every? every? []) |
| 03:27 | clojurebot | true |
| 03:28 | mpenet | ,(and) |
| 03:28 | clojurebot | true |
| 03:37 | Frozenlock | Is it an emacs function that 'prettify' the requires into equal length vectors? |
| 03:45 | owl-v- | how do i use mutable list? |
| 03:46 | dbasch | owl-v-: what do you mean mutable list? what do you want to do? |
| 03:47 | owl-v- | update list and use it as stack |
| 03:47 | dbasch | owl-v-: but why do you need to mutate it, as opposed to appending to an immutable one? |
| 03:50 | owl-v- | is there reason to use immutable list? |
| 03:50 | dbasch | owl-v-: normally you need a reason to use mutable structures |
| 03:50 | dbasch | the default is immutability |
| 03:51 | dbasch | ,(pop [1 2 3 4 5]) |
| 03:51 | clojurebot | [1 2 3 4] |
| 03:52 | owl-v- | im using a list as an argument and iterate through and create new list then use this new list as argument of new function |
| 03:52 | yedi | what are the best clojure codebases to read for learning some of the better clojure development strategies |
| 03:53 | owl-v- | ,(pop [1 2 3 4 5]) |
| 03:53 | clojurebot | [1 2 3 4] |
| 03:53 | owl-v- | ,(push 6 [1 2 3 4 5]) |
| 03:53 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: push in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 03:53 | owl-v- | ,(push [1 2 3 4 5] 6 ) |
| 03:53 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: push in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 03:53 | dbasch | ‘(conj (pop [1 2 3 4 5]) 6) |
| 03:53 | dbasch | ,(conj (pop [1 2 3 4 5]) 6) |
| 03:53 | clojurebot | [1 2 3 4 6] |
| 03:54 | Jaood | ,(peek [3 5 7 9]) |
| 03:54 | clojurebot | 9 |
| 03:54 | owl-v- | ,(conj [list 1 2 3 4 5] 6 ) |
| 03:54 | clojurebot | [#<clojure.lang.PersistentList$1@67c93d> 1 2 3 4 ...] |
| 03:54 | owl-v- | ,(conj [1 2 3 4 5] 6 ) |
| 03:54 | clojurebot | [1 2 3 4 5 ...] |
| 03:54 | owl-v- | what's that '...'? |
| 03:55 | dbasch | ellipsis |
| 03:55 | owl-v- | ,(conj [1 2 3 ] 4 ) |
| 03:55 | clojurebot | [1 2 3 4] |
| 03:55 | dbasch | clojurebot truncates results |
| 03:55 | owl-v- | and fifo? |
| 03:57 | owl-v- | ,(reverse (conj [1] 2)) |
| 03:57 | clojurebot | (2 1) |
| 03:57 | owl-v- | why do i get list when reverse? |
| 03:57 | Jaood | (first (conj [] 9)) |
| 03:57 | Jaood | ,(first (conj [] 9)) |
| 03:57 | clojurebot | 9 |
| 03:58 | owl-v- | ,(reverse [1 2 3]) |
| 03:58 | clojurebot | (3 2 1) |
| 03:58 | Jaood | ,(first (into [] [1 2 3])) |
| 03:58 | clojurebot | 1 |
| 03:58 | owl-v- | ,(first (conj [1 2] 3)) |
| 03:58 | clojurebot | 1 |
| 03:58 | owl-v- | ,(ast (conj [1 2] 3)) |
| 03:58 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ast in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 03:58 | owl-v- | ,(last (conj [1 2] 3)) |
| 03:58 | clojurebot | 3 |
| 03:59 | dbasch | ,(type []) |
| 03:59 | clojurebot | clojure.lang.PersistentVector |
| 03:59 | dbasch | ,(type (reverse [])) |
| 03:59 | clojurebot | clojure.lang.PersistentList$EmptyList |
| 03:59 | owl-v- | list out of vector? |
| 03:59 | owl-v- | ,(conj (1 2)) |
| 03:59 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 03:59 | dbasch | ,(into [] (reverse [1 2 3]) |
| 04:00 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 04:00 | owl-v- | ,(conj (1 2) 3) |
| 04:00 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 04:00 | owl-v- | ,(cons (1 2) 3) |
| 04:00 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 04:00 | owl-v- | ,(cons [1 2] 3) |
| 04:00 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 04:00 | owl-v- | ,(conj (reverse (conj [1 2] 3)) 4) |
| 04:00 | clojurebot | (4 3 2 1) |
| 04:00 | dbasch | ,(into [] (reverse [1 2 3])) |
| 04:00 | clojurebot | [3 2 1] |
| 04:01 | owl-v- | reverse of vector should return reversed vector :( |
| 04:02 | dbasch | no |
| 04:02 | dbasch | “reverse: Returns a seq of the items in coll in reverse order. Not lazy.” |
| 04:03 | dbasch | ,(rest [1 2 3 4]) |
| 04:03 | clojurebot | (2 3 4) |
| 04:03 | dottedmag | owl-v-: You're mixing it up with Haskell :) |
| 04:08 | owl-v- | not logical... god da@# it! |
| 04:11 | dbasch | owl-v-: a vector is not a seq. reverse returns a seq |
| 04:12 | dbasch | it’s good to know why and when to use a vector, and it’s not just because typing square brackets is convenient :) |
| 04:20 | owl-v- | so, i'm using two vectors in this function. and i have errors on line 12 and 4: https://www.refheap.com/77370 |
| 04:20 | owl-v- | v and vv |
| 04:27 | dbasch | you’re calling your function with a vector of vectors, so you’re trying to decrement a vector |
| 04:28 | owl-v- | decrement a vector? |
| 04:28 | owl-v- | when v is [[]] , item is [] |
| 04:29 | owl-v- | (first item) is first element of item which is just a number 99 in the first case. |
| 04:29 | dbasch | print n and m before line 12 and you’ll see |
| 04:29 | owl-v- | so n == 99 |
| 04:30 | owl-v- | omg!!!!!! |
| 04:32 | owl-v- | why item is not iterated element of v? |
| 04:32 | owl-v- | when looped? |
| 04:34 | owl-v- | because it is not for loop? |
| 04:34 | dbasch | v is a vector of vectors |
| 04:34 | dbasch | [[99 99]] |
| 04:34 | dbasch | the first element of that is [99 99] |
| 04:34 | owl-v- | yes. that's what i want |
| 04:34 | dbasch | it’s also the last element, of course |
| 04:34 | sm0ke | can core.typed be used to enforce function argument/return types? |
| 04:34 | owl-v- | but item==[[99 99 ]] |
| 04:35 | sm0ke | so for e.g. what if i declare `inc` as [Num -> String], would core.typed throw exception? |
| 04:35 | dbasch | yes, item starts as v |
| 04:36 | owl-v- | i guess (loop [item v] ...) this simply initialize value item=v which is not what i want. |
| 04:55 | ambrosebs | sm0ke: not currently |
| 04:56 | owl-v- | ,(let [v []] (let [n 3] (conj v 3) ) |
| 04:56 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 04:56 | owl-v- | ,(let [v []] (let [n 3] (conj v 3) )) |
| 04:56 | clojurebot | [3] |
| 04:56 | ambrosebs | sm0ke: working on generating casts from types |
| 04:56 | ambrosebs | sm0ke: but there's always going to be a core of "trusted" annotations. |
| 04:56 | owl-v- | ,(let [v []] (let [n 3] ((conj v 2) (conj v 3)) )) |
| 04:56 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Key must be integer> |
| 04:57 | owl-v- | illegal? |
| 04:58 | TEttinger | ,(let [v []] (let [n 3] (do (conj v 2) (conj v 3)) )) |
| 04:58 | clojurebot | [3] |
| 04:59 | owl-v- | -.- |
| 05:00 | owl-v- | what happened to (conj v 2)? |
| 05:02 | owl-v- | ,(let [v []] (let [n 3] (do (conj v 2) (conj v 3)) )) |
| 05:02 | clojurebot | [3] |
| 05:02 | owl-v- | ,(let [v []] (let [n 3] (do (conj v 2) (do (conj v 3))) )) |
| 05:02 | clojurebot | [3] |
| 05:04 | ucb | ,(doc conj) |
| 05:04 | clojurebot | "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type." |
| 05:04 | ucb | owl-v-: conj returns a new collection |
| 05:05 | akazlou | interesting found that get/assoc/assoc-in work nice with nil map passed, is it by design? |
| 05:06 | katratxo | akazlou: "nil keys and values are ok" http://clojure.org/data_structures#Data%20Structures-Maps%20%28IPersistentMap%29 |
| 05:08 | owl-v- | ucb; how do i update one at a time? |
| 05:08 | ucb | owl-v-: you don't? What are you trying to do? |
| 05:12 | owl-v- | add two vectors to a vector |
| 05:12 | owl-v- | [] -> [[1 2]] -> [[1 2] [1 3]] |
| 05:14 | Frozenlock | ,(conj [] [1 2] [1 3]) |
| 05:14 | clojurebot | [[1 2] [1 3]] |
| 05:14 | akazlou | katraxo: thank you for the link, but what I meants, that (assoc nil {:lang "Clojure"}) or (get nil :lang) is ok, so map passing into assoc/get/assoc-in can be nil, and no NullPointerException, |
| 05:14 | akazlou | for example in my sample ring app: |
| 05:14 | akazlou | (-> (response-util/file-response file {:root "public"}) |
| 05:14 | akazlou | (response-util/content-type content-type)) |
| 05:14 | akazlou | if file doesn't exist file-response returns nil, but then content-type return {:headers {"Content-Type" content-type}} which is not right ring response |
| 05:14 | akazlou | just found it interesting |
| 05:22 | kras | what's wrong with this function? |
| 05:22 | kras | (defn flt [lis acc] |
| 05:22 | kras | (if (not (seq? (first lis))) |
| 05:22 | kras | (do (conj acc (first lis)) (recur (rest lis) acc)) |
| 05:22 | kras | (recur (first lis) acc))) |
| 05:23 | kras | it just hangs when I eval (flt '(1 2 (3 4)) ()) |
| 05:24 | ivan | kras: conj doesn't mutate acc |
| 05:25 | ivan | it returns a new value that you threw away |
| 05:26 | kras | oops !!! |
| 05:27 | kras | lets say I throw away the result |
| 05:28 | kras | it still doesn't explain why it should hang? |
| 05:28 | owl-v- | Frozenlock: thanks |
| 05:28 | kras | might be missing something else here |
| 05:28 | clgv | owl-v-: please do read some introductory material on clojure, you'll be learning much faster. |
| 05:28 | kras | here's the easier to read code https://www.refheap.com/77372 |
| 05:29 | clgv | kras: good move. always post more than one-line code in a gist:) |
| 05:29 | kras | clgv: yeah realized it after seeing the code I posted |
| 05:30 | ivan | ,(seq? (first '(1 2))) |
| 05:30 | clojurebot | false |
| 05:31 | clgv | kras: you know that you always have to pass on the "modified" object. your (conj acc (first lis)) does not have any effect on future recursive invocations. and you are missing a base case where the recursion stops |
| 05:31 | clgv | kras: what exectly do you want to do? |
| 05:33 | kras | clgv: thanks for the hint |
| 05:33 | kras | I think I undertsood the problem |
| 05:33 | kras | I am basically trying to flatten a given nested list |
| 05:33 | kras | let me try for some more time |
| 05:33 | beamso | ,(doc flatten) |
| 05:33 | clojurebot | "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns an empty sequence." |
| 05:34 | clgv | beamso: I think it is a learning exercise ;) |
| 05:34 | beamso | oh |
| 05:34 | kras | yep |
| 05:36 | owl-v- | why is it harder to think in clojure/lisp than think in python? |
| 05:36 | owl-v- | or c or c++ |
| 05:36 | llasram | Lack of experience |
| 05:36 | owl-v- | -.- |
| 05:36 | clgv | owl-v-: you are probably struggling with imperative programming vs functional programming |
| 05:36 | beamso | for me it's a) lazy evaluation and b) functions that return something vs functions that return nothing |
| 05:37 | clgv | owl-v-: that's why I suggested to you several times already to read introductory material on clojure - this will speed up your learning process |
| 05:37 | beamso | e.g. doall vs dorun |
| 05:38 | clgv | owl-v-: get one of the books and do the reading + experimenting cycle ^^ |
| 05:39 | owl-v- | simple breath first tree search is not fun in clojure :( |
| 05:39 | llasram | And why do you say that? |
| 05:40 | clgv | owl-v-: why is that? you can directly translate the recursive function from c/c++/java to clojure. but naturally you might suffer a stackoverflow as you would in c/c++/java ;) |
| 05:44 | kras | this is what I came up with: https://www.refheap.com/77374 |
| 05:45 | kras | ofcourse since I am throwing away the conj result it returns an empty seq now |
| 05:45 | clgv | kras: still the same error with the "conj" I told you before |
| 05:45 | clgv | kras: do you know "cond"? |
| 05:45 | kras | like a case statement? |
| 05:46 | clgv | kras: it is a compact form to write those nested "if" statements (nested in the else case) |
| 05:47 | kras | okay, let me check that |
| 05:49 | owl-v- | ,(for [i (1 2)] (print i)) |
| 05:49 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 05:49 | owl-v- | ,(for [i (1 2)] (println i)) |
| 05:49 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 05:50 | clgv | ,(for [i '(1 2)] (println i)) |
| 05:50 | clojurebot | (1\n2\nnil nil) |
| 05:50 | owl-v- | ,(for [i (1 2)] (prn i)) |
| 05:50 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 05:50 | owl-v- | ? |
| 05:50 | clgv | read please^^ |
| 05:50 | kras | owl-v-: please read the docs |
| 05:50 | beamso | (1 2) is calling the function 1 with an argument of 2. '(1 2) is the list of 1 and 2. |
| 05:50 | clgv | ,(1 2) |
| 05:50 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 05:50 | clgv | ^^ |
| 05:50 | owl-v- | docs didn't help me at all |
| 05:51 | kras | (1 2) clojure expects 1 to be callable |
| 05:51 | kras | or special form |
| 05:51 | owl-v- | ,(for [i [1 2]] (prn i)) |
| 05:51 | clojurebot | (1\n2\nnil nil) |
| 05:51 | owl-v- | ,(for [i [1 2]] (println i)) |
| 05:51 | clojurebot | (1\n2\nnil nil) |
| 05:51 | kras | if you want clojure to stop doing that then you have to quote it |
| 05:51 | kras | ,(doc quote) |
| 05:51 | clojurebot | Huh? |
| 05:51 | clgv | $doc quote |
| 05:52 | clgv | &1 |
| 05:52 | lazybot | ⇒ 1 |
| 05:52 | clgv | &(doc quote) |
| 05:52 | lazybot | ⇒ "Special: quote; Yields the unevaluated form." |
| 05:52 | owl-v- | java runtime error :( |
| 05:53 | clgv | owl-v-: you'll have many more of those disappointing experiences if you dont try to learn clojure in a structured way, i.e. reading something that explains you the big picture and the mandatory basics |
| 05:54 | kras | owl-v-: clojure is a lisp, if that helps :-) |
| 05:55 | beamso | i recommend http://www.clojurebook.com/ . for me it was better than the pragprog books on clojure. |
| 05:56 | kras | one think which still confuses me a hell lot is recur |
| 05:56 | kras | used to recursion with function names |
| 05:56 | clgv | kras: just imagine it is the function name of your current function^^ |
| 05:56 | kras | any good article which explains why we need a special form recur instead of just using traditional recursion |
| 05:56 | clgv | kras: provided you have no loop surrounding it ;) |
| 05:57 | clgv | kras: because the JVM is not able to do Tail Call Optimization |
| 05:57 | daitya | owl-v-: section 1.1 of chapter 1 will help you get started thinking in lisp http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html#%_toc_start |
| 05:58 | owl-v- | ,(let [v []] (for [item [1 2 3]] (conj v item))) |
| 05:58 | clojurebot | ([1] [2] [3]) |
| 05:59 | clgv | kras: you tell the Clojure compiler to use tail call optimization by using recur. through the use of recur the compiler can also determine whether it really occurs in a tail call position |
| 05:59 | owl-v- | ...list |
| 06:00 | owl-v- | ,(let [v []] (for [item [1 2 3]] (conj v item)) v) |
| 06:00 | clojurebot | [] |
| 06:00 | clgv | owl-v-: well you are wrong in interpreting that code as imparative code :P |
| 06:00 | kras | so if I implement a traditional recursion it will be translated to pure JVM recursion which doesn't support Tail resursion optimization? |
| 06:01 | clgv | kras: right. that does only matter if your recursion works on large data structures. so sometimes a traditional recursion is totally suitable if you know that the number of recursive calls is bounded by a small number |
| 06:02 | kras | ok makes sense now |
| 06:02 | owl-v- | ,(let [v []] (do (for [item [1 2 3]] (conj v item) v)) |
| 06:02 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 06:02 | kras | clgv: thank you |
| 06:03 | Frozenlock | I've always found the lack of tail recursion optimization in Clojure... unfortunate. |
| 06:03 | owl-v- | ,(let [v []] (do (for [item [1 2 3]] (conj v item)) v)) |
| 06:03 | clojurebot | [] |
| 06:03 | clgv | Frozenlock: huh? you get tco by using recur explicitely. |
| 06:03 | clgv | Frozenlock: you'd want it implicitly if applicable? |
| 06:04 | Frozenlock | Yes |
| 06:04 | Frozenlock | Wouldn't you? |
| 06:04 | clgv | wasnt there some discussion regarding that design choice? |
| 06:04 | owl-v- | ,(let [v []] (do (for [item [1 2 3]] (conj v item)) (println v) )) |
| 06:04 | clojurebot | []\n |
| 06:04 | clgv | well coming from C++/Java I never had TCO in the first place ;) |
| 06:05 | llasram | This may be the Stockholm syndrome talking, but given that general-case TCO isn't possible on the JVM, I'd rather have an explicit construct for it than have it just not TCO when it couldn't |
| 06:05 | clgv | llasram: yeah I also like the check telling me that I misplaced the recur^^ |
| 06:05 | owl-v- | ,(let [v []] (for [item [1 2 3]] (conj v item) (print v) )) |
| 06:05 | clojurebot | #<CompilerException clojure.lang.ArityException: Wrong number of args (3) passed to: core/for, compiling:(NO_SOURCE_PATH:0:0)> |
| 06:06 | clgv | owl-v-: could you please use your own local repl? |
| 06:06 | llasram | Or just /query clojurebot |
| 06:06 | kras | or you can use http://tryclj.com/ |
| 06:06 | kras | please stop using this as a REPL |
| 06:06 | owl-v- | cool! thanks |
| 06:06 | llasram | Many options! |
| 06:08 | llasram | owl-v-: But FYI, that last bit of code you tried can't do what you want w/ immutable vectors |
| 06:08 | llasram | Not to mention `for` as generating a lazy sequence |
| 06:11 | owl-v- | :( but it works when (conj [] 1 2 3) |
| 06:11 | owl-v- | or (conj v 1) (conj v 2) (conj v 3) |
| 06:12 | owl-v- | i mean (conj (conj ( conj v 1) 2) 3) |
| 06:12 | llasram | owl-v-: Yes, but those are operating on the return value of conj in each case |
| 06:13 | llasram | You're doing the same thing as ##(for [i (range 1 4)] (conj [] i)) |
| 06:13 | lazybot | ⇒ ([1] [2] [3]) |
| 06:13 | llasram | Because `v` doesn't change -- it stays bound to `[]` |
| 06:13 | owl-v- | T.T |
| 06:13 | owl-v- | my python way of thinking... |
| 06:14 | owl-v- | i miss mutable list... |
| 06:15 | llasram | And my experience is that once I learned to use immutable data structures, I miss *those* in every language lacking them :-) |
| 06:15 | llasram | You have complete access to mutable datastructures in Clojure |
| 06:16 | clgv | llasram: cant wait for the version of the above code using java.util.ArrayList ^^ |
| 06:16 | llasram | ,(let [v (java.util.ArrayList.)] (doseq [i (range 3)] (.add v i)) v) |
| 06:16 | clojurebot | [0 1 2] |
| 06:16 | anna_ | why clojure error reporting sucks ? |
| 06:16 | anna_ | :(} |
| 06:16 | clgv | llasram: damn, you should have used `for` ;) :P |
| 06:17 | llasram | clgv: Let's not be crazy now :-p |
| 06:17 | llasram | One problem at a time |
| 06:18 | clgv | anna_: mostly due to the JVM since the only possibility for runtime errors are exceptions. but certainly there could be improvements trying to translate those exceptions into better user friendly error messages |
| 06:18 | daitya | owl-v-: if you want tutorial-style learning, many options to learn from: http://www.purelyfunctional.tv/ ... http://www.braveclojure.com/ ... http://aphyr.com/tags/Clojure-from-the-ground-up |
| 06:19 | clgv | the one from aphyr looks nice |
| 06:19 | daitya | and the best way is to try stuff in your local repl... it puts things in context (as opposed to clojurebot) |
| 06:19 | llasram | clgv: I don't think that's true... (re: errors) My reasons: |
| 06:19 | llasram | anna_: Because (a) rhickey isn't interested; (b) with some familiarity, most of the error messages do tell you what went wrong; and (c) because it's honestly difficult given the language design |
| 06:20 | clgv | llasram: well my answer would be in (c) I guess^^ |
| 06:21 | owl-v- | i was doing http://projecteuler.net |
| 06:21 | daitya | llasram: i doubt if (a) is even within the answer space |
| 06:21 | clgv | owl-v-: better switch to 4clojure.com and start with the basic ones |
| 06:21 | llasram | daitya: Really? I think it's definitely a reason the Clojure error messages aren't better :-) |
| 06:22 | llasram | rhickey is completely fine with Clojure core macros (like defn) just throwing whatever exception bad input causes them to generate |
| 06:22 | clgv | llasram: provided those execptions carry enough information the error messages could be improved in the repl frontends |
| 06:22 | llasram | I'm skeptical |
| 06:22 | clgv | llasram: probably the compiler should throw ExceptionInfo objects with enough information |
| 06:23 | llasram | Maybe, but arbitrary code getting arbitrarily incorrect data -- there's only so much you can do |
| 06:23 | llasram | You'd really need every macro to carefully check what it expects vs what it recieves |
| 06:25 | clgv | right |
| 06:25 | clgv | but do you do that in your own code 100% of the time? |
| 06:26 | llasram | Of course not. And I'm not even saying that I think clojure.core should |
| 06:26 | llasram | I'm just saying I think it's what you need to do to get significantly better error messages, and that that kind of philosophical direction would need to come from the top |
| 06:28 | daitya | llasram: :) ... I feel there must be a good reason out there somewhere... it's completely counterintuitive that a carefully-designed language would deliberately not provide clean, useful feedback to its user |
| 06:29 | llasram | Well, I mean, it *does*, if you've got a certain mental model and level of familiarity. That's (b), and it's kind of a chicken-egg + self-selection thing |
| 06:29 | clgv | daitya: requiring a certain amount of effort would be one reason if the developers are not convinced the effort is worth it |
| 06:30 | llasram | If you stick around Clojure, you learn enough of the implementation to interpret the error messages. Once you've learned enough of the implementation, the error messages frequently tell you *exactly* what went wrong |
| 06:30 | llasram | ,(1) |
| 06:30 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 06:30 | durm | guys, help me please! |
| 06:30 | durm | I want to do fs walk and store file to another place |
| 06:30 | llasram | Clojure expected an IFn (a function object) and found a Long |
| 06:30 | durm | i have a function |
| 06:31 | durm | (defn walk [dirpath pattern] |
| 06:31 | durm | (doall (filter #(re-matches pattern (.getName %)) |
| 06:31 | durm | (file-seq (file dirpath))))) |
| 06:31 | llasram | An error like "non-function used in call position" would be newbie friendly, but tell you *less* about exactly what went wrong |
| 06:31 | durm | which can walk over fs |
| 06:31 | durm | and return file handlers |
| 06:32 | llasram | durm: In the future, please use a paste service like refheap.com for code longer than 1-liners |
| 06:32 | durm | oh sorry |
| 06:32 | durm | ok |
| 06:32 | durm | and in another expression i want to store the file |
| 06:33 | daitya | llasram: i'm fairly new to clojure, and that has been my experience... these days i get surprised that--more often than not--i barely glance at the error and know where I made a mistake... it took some effort, but now i have a certain level of comfort |
| 06:33 | durm | like (map #(println (__create media %)) (walk import-dir #".*")) |
| 06:33 | durm | but it doesnt work |
| 06:33 | durm | I think because of lazyness |
| 06:34 | owl-v- | why this is true? (= (list :a :b :c) (vec '(:a :b :c))) |
| 06:34 | Frozenlock | I remember coming to clojure without knowing any java at all. I wanted to throw my computer at the ground everytime I saw one of those horrible error messages. |
| 06:34 | daitya | owl-v-: hint... sequence abstraction |
| 06:34 | durm | how can I do it? |
| 06:35 | llasram | durm: Um, well `dorun` will force a lazy sequence and discard the results, if you just want to force it for side-effects |
| 06:35 | owl-v- | but this is java runtime error: (= (list a b c) (vector a b c)) |
| 06:35 | llasram | durm: You might also consider using `doseq` instead of `map` if you just want to run some code for side-effects |
| 06:36 | daitya | owl-v-: what is the difference between 'a' and ':a'? |
| 06:36 | llasram | daitya: Oooh, the Socratic method. Fancy |
| 06:36 | owl-v- | just an element? |
| 06:36 | owl-v- | just elements? |
| 06:36 | durm | llasram: thanks, I will try it |
| 06:37 | owl-v- | http://www.4clojure.com/problem/6 |
| 06:38 | daitya | owl-v-: do you have a running repl? |
| 06:38 | owl-v- | yes |
| 06:38 | owl-v- | with :a works but with 'a' does not |
| 06:38 | daitya | correct, but why? |
| 06:39 | daitya | llasram: oh don't tease ... any resemblance is purely coincidental |
| 06:40 | daitya | owl-v-: try this... first feed (def a "foo") to your repl, then feed 'a' to it |
| 06:41 | daitya | without the quotes |
| 06:43 | Guest27066 | lol funny name daitya |
| 06:43 | owl-v- | daitya: "foo" |
| 06:44 | daitya | owl-v-: aha! now type in :a |
| 06:44 | daitya | Guest27066: http://vedabase.net/d/daitya ... a subtle pun on my real name |
| 06:44 | akazlou | :require vs :use in ns definition, which one is usually used? |
| 06:44 | owl-v- | daitya; :a |
| 06:44 | jonasen | akazlou: :require |
| 06:44 | Frozenlock | akazlou: :require |
| 06:45 | clgv | daitya: lol. you started a tutorial "clojure on hands and knees" just now ;) |
| 06:45 | Frozenlock | :use is evil |
| 06:45 | akazlou | or preference/difference between them? |
| 06:45 | akazlou | why :use is evil? |
| 06:45 | Guest27066 | :use is daitya |
| 06:45 | Guest27066 | :D |
| 06:46 | clgv | akazlou: in (ns) only use ":require". in repl (use ...) is often pretty handy |
| 06:46 | daitya | owl-v-: before you bound a to something--that is, "foo"--it didn't exist |
| 06:46 | jonasen | I wouldn't say that :use is evil. It's just that :require can do everything (and more) that :use can do. So :use is not really needed |
| 06:46 | daitya | Guest27066: :D |
| 06:46 | clgv | akazlou: usually you use something like (:require [clojure.string :as str]) and then (str/join ", " (range 10)) |
| 06:46 | Frozenlock | akazlou: Personally I hate it because it brings everything into the namespace. Want to know from which library a function is coming just by looking at the code? Good luck... |
| 06:47 | jonasen | Frozenlock: you can (:use ... :only ..) |
| 06:47 | Frozenlock | Sure, but do you really? :-p |
| 06:47 | kras | finally ended up with this: https://www.refheap.com/77391 |
| 06:47 | jonasen | Frozenlock: no |
| 06:48 | owl-v- | daitya; a still shows "foo" but :a shows :a |
| 06:48 | clgv | jonasen: but why when (:require ... :refer ...) is equivallent? |
| 06:48 | jonasen | but I do use (:require [foo.bar :refer ..]) |
| 06:48 | akazlou | ok, so with use you can't assign name to the import, but :as require will allow you to do it, or nice |
| 06:48 | daitya | owl-v-: and that is the correct behaviour |
| 06:48 | jonasen | clgv: exactly! :require can do al that :use can.. so :use is not needed |
| 06:48 | daitya | owl-v-: http://clojure.org/data_structures#toc8 |
| 06:49 | akazlou | thanks |
| 06:49 | daitya | :a is a keyword... it evaluates to itself |
| 06:50 | daitya | whereas a is a symbol that means nothing till you bind it to something |
| 06:50 | clgv | ,'a |
| 06:50 | clojurebot | a |
| 06:50 | clgv | ,(class 'a) |
| 06:50 | clojurebot | clojure.lang.Symbol |
| 06:51 | daitya | ,(class :a) |
| 06:51 | clojurebot | clojure.lang.Keyword |
| 06:51 | clgv | ,(class (read-string "a")) |
| 06:51 | clojurebot | clojure.lang.Symbol |
| 06:51 | daitya | more correctly, a will not mean anything to _you_ unless you bind it to something |
| 06:53 | daitya | ,a |
| 06:53 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 06:54 | owl-v- | (def :a "boo") -> "java.lang.RuntimeException: First argument to def must be a Symbol" because :a is not a symbol |
| 06:55 | clgv | ,(def a 42) |
| 06:55 | clojurebot | #'sandbox/a |
| 06:55 | clgv | ,a |
| 06:55 | clojurebot | 42 |
| 06:56 | daitya | owl-v-: yes, because :a already is--crudely speaking--permanently bound to a value... itself |
| 06:57 | owl-v- | but when do we use :keyword? in dictionary? |
| 06:58 | daitya | yes, that's the most common use case; keywords are used as keys in a map |
| 06:58 | daitya | ,{:a :a} |
| 06:58 | clojurebot | {:a :a} |
| 06:58 | daitya | but this is a perfectly valid map ^ |
| 06:59 | clgv | ,({:a :a} {:a :a} {:a :a}) |
| 06:59 | clojurebot | {:a :a} |
| 07:00 | daitya | clgv: ooh... why did that happen? let me go find out |
| 07:00 | daitya | (serious ^) |
| 07:00 | clgv | daitya: :D |
| 07:00 | clgv | ,({:a :a} {:b :b} {:c :c}) |
| 07:00 | clojurebot | {:c :c} |
| 07:03 | owl-v- | returns last dic? |
| 07:04 | owl-v- | i think that's correct behavior :) |
| 07:04 | owl-v- | i tried on http://tryclj.com/ |
| 07:05 | jonasen | ,({:a 1 :b 2} :a :not-found) |
| 07:05 | clojurebot | 1 |
| 07:05 | jonasen | ,({:a 1 :b 2} :c :not-found) |
| 07:05 | clojurebot | :not-found |
| 07:06 | daitya | clgv: D'oh ... default value >_< |
| 07:06 | clgv | daitya: yeah you could just write a "get" in front to have it pretty obvious ;) |
| 07:07 | daitya | clgv: well, careless of me, because i knew about the optional default |
| 07:08 | daitya | thanks for the knock on the head :) |
| 07:09 | owl-v- | what does ( ) do on ({:a 1} :a :whatever) ? |
| 07:10 | daitya | try it in your repl |
| 07:10 | clgv | ,((#{{}} {}) {} {}) |
| 07:10 | clojurebot | {} |
| 07:11 | Guest27066 | how stupid is the idea to have a line-reader in clojure which collapses all the ending paranthesis? so intead of something like )]})]}))))) we can just write somthing like ...) |
| 07:11 | Guest27066 | :P |
| 07:12 | clgv | ,((#{{}} {}) (#{{}} {}) (#{{}} {})) |
| 07:12 | clojurebot | {} |
| 07:13 | Guest27066 | ignoring that it will just blow off all the existing tools and ides for clojure, its a nice idea |
| 07:13 | daitya | owl-v-: seriously, you will do well to read this: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-10.html#%_sec_1.1 |
| 07:14 | clgv | Guest27066: I guess it wont work in general, since there scenarios when you need to look ahead to be able to determine what closing paranthesis you need and especially which are closed later |
| 07:15 | Guest27066 | hmm i am not sure if its entirly correct |
| 07:15 | Guest27066 | every ...) will look ahead for the first unmatched ( |
| 07:15 | Guest27066 | thats it |
| 07:16 | clgv | no. you need to know all closing ones that are ahead.. |
| 07:16 | Guest27066 | yes |
| 07:16 | clgv | and I guess for that you'd need to read until the end of the document |
| 07:16 | Guest27066 | beginnging you mean? |
| 07:16 | clgv | no |
| 07:17 | clgv | you need to know which paranthesis to insert instead of ...) you know the possible ones from the opening counter parts but some of them might be closed later on so you have to exclude those |
| 07:18 | clgv | and you cant tell if there is still a closing one before you readched the end of the file |
| 07:18 | clgv | -d |
| 07:21 | owl-v- | does (set (list)) make array-map? |
| 07:21 | clgv | no, it creates a set |
| 07:22 | clgv | ,(class (set (list))) |
| 07:22 | clojurebot | clojure.lang.PersistentHashSet |
| 07:22 | clgv | ,(class #{}) |
| 07:22 | clojurebot | clojure.lang.PersistentHashSet |
| 07:26 | Guest27066 | is there something like take-while but still extract the last failing element |
| 07:27 | clgv | Guest27066: you probably need something that would be called "take-until" then... refering to the looping constructs... |
| 07:27 | Guest27066 | ,(take-while #(< % 10) (range 20)) |
| 07:27 | clojurebot | (0 1 2 3 4 ...) |
| 07:28 | Guest27066 | ,(take-while #(< % 5) (range 20)) |
| 07:28 | clojurebot | (0 1 2 3 4) |
| 07:28 | clgv | Guest27066: with numbers it's easy to patch but you probably have something different |
| 07:28 | Guest27066 | i can use 6 here, but thats not the point |
| 07:28 | Guest27066 | clgv: right |
| 07:28 | clgv | ,(source take-while) |
| 07:28 | clojurebot | Source not found\n |
| 07:28 | clgv | $source take-while |
| 07:29 | lazybot | take-while is http://is.gd/6y8gU0 |
| 07:29 | Guest27066 | i can always write a reduce and reduced |
| 07:29 | clgv | Guest27066: write take-until base on take-while. you just have to move the "when" |
| 07:29 | Guest27066 | but thats 1.5+ |
| 07:34 | clgv | Guest27066: https://www.refheap.com/77393 |
| 07:35 | Guest27066 | nice |
| 07:35 | Guest27066 | (inc clgv) |
| 07:36 | lazybot | ⇒ 16 |
| 07:37 | Guest27066 | hurmm |
| 07:37 | Guest27066 | hey! take until? |
| 07:37 | Guest27066 | oh ok |
| 07:37 | clgv | corresponding to the difference between while loop and repeat-until loop |
| 07:39 | clgv | oh humm concerning that the sematic is wrong. the predicate needs to be inverse for that naming^^ |
| 07:40 | Guest27066 | may be it should be named take-unless |
| 07:41 | Guest27066 | take-unless-and-until |
| 07:41 | Guest27066 | weird |
| 07:42 | owl-v- | why ({:a 10, :b 20, :c 30} :b) == (:b {:a 10, :b 20, :c 30}) ? |
| 07:42 | clgv | Guest27066: ok there are two variants in the gist now ;) |
| 07:42 | clgv | (take-until #{6} (range)) ; => (0 1 2 3 4 5 6) |
| 07:43 | clgv | (take-while+1 #(< % 6) (range)) ; => (0 1 2 3 4 5 6) |
| 07:44 | clgv | owl-v-: because keywords act as functions |
| 07:44 | clgv | owl-v-: you'd know that if you read anything about clojure at all.. :/ |
| 07:44 | Guest27066 | i will go with take-until |
| 07:44 | Guest27066 | makes sense |
| 07:46 | daitya | clgv: +1 / owl-v- please do read the learning material available, otherwise you'll hit really unnecessary roadblocks, like you are doing now... for example, http://www.braveclojure.com/ and aphyr.com/tags/Clojure-from-the-ground-up |
| 07:47 | owl-v- | i read "Maps store key-value pairs. Both maps and keywords can be used as lookup functions." and couldn't understand |
| 07:49 | martinklepsch | anyone having used Schema here? |
| 07:50 | martinklepsch | Is there a way to require a key to be i.e. a string? |
| 07:50 | agarman | @martinklepsch: yeah, both ole Scheme and Racket |
| 07:50 | martinklepsch | agarman, actually talking about prismatic/schema here :P |
| 07:54 | martinklepsch | [(s/one s/Str "s") s/Str] — does it forme |
| 08:06 | Guest27066 | anyone using fireplace facing problem of reloading record definitions? |
| 08:06 | Guest27066 | re-definitions* |
| 08:06 | Guest27066 | i guess it must be a clojure problem in general |
| 08:14 | martinklepsch | hey |
| 08:24 | gfredericks | Guest27066: yeah that can be tricky; I think every time you reload you get a new class on the jvm; old instances have the old method definitions |
| 08:24 | gfredericks | even weirder if you reload protocols that the records implement |
| 08:25 | Guest27066 | yep, i end up killing the repl and restarting |
| 08:26 | martinklepsch | (zf/xml1-> xml-zipper :a :b zf/text) — how could I write this so that I can supply :a :b as list? |
| 08:26 | gfredericks | Guest27066: I can usually stay on top of things by making sure to reload protocols, then records, then restart stuff (e.g. w/ stuartsierra/component) |
| 08:27 | martinklepsch | seems like something where you'd use apply but I'm not sure how since there is another mandatory thing at the end |
| 08:27 | Guest27066 | hurm i find it very constraining |
| 08:34 | gfredericks | martinklepsch: you could work something out with reduce for sure |
| 08:34 | gfredericks | Guest27066: what are you using records for? |
| 08:35 | Guest27066 | gfredericks: just some abstraction which user can hold on to |
| 08:35 | gfredericks | Guest27066: when I use records I tend to minimize the amount of code inside the methods so it doesn't change as often |
| 08:35 | Guest27066 | yep i noticed that |
| 08:35 | Guest27066 | but i feels like a cheat |
| 08:36 | Guest27066 | it* |
| 08:36 | agarman | , (#(apply + 1 (concat % [5])) [2 3 4]) |
| 08:36 | clojurebot | 15 |
| 08:36 | Guest27066 | reloading function which records use works seamlessly nonethless |
| 08:37 | Guest27066 | hurm may be i can follow that more strictly |
| 08:37 | gfredericks | Guest27066: yeah; I've found that even when changing the implementations, I don't need to restart if I'm thorough about what gets reloaded |
| 08:38 | gfredericks | and it's usually obvious if I've screwed it up somehow |
| 08:38 | Guest27066 | yeah changes are easy to track and reload |
| 08:38 | Guest27066 | just canhe function and reload is what i usually do |
| 08:39 | Guest27066 | change* |
| 08:39 | martinklepsch | gfredericks, any more pointers? kinda lost I guess... |
| 08:41 | gfredericks | martinklepsch: I'm not familiar with the xml stuff in particular, but I'd imagine (zf/xml1-> xml-zipper (as-> <> (reduce #(zf/xml1-> %1 %2) <> [:a :b])) zf/text) |
| 08:41 | gfredericks | there might be a more succinct version based on what zf/xml1-> does exactly |
| 08:44 | ryanbraganza | newbie question - how do I print a big number without the trailing N? e.g. user=> (println 1234123946812893467981236478921697384671823649612934678126389461278364912763461265216385123478213749712893478912378947) |
| 08:44 | ryanbraganza | 1234123946812893467981236478921697384671823649612934678126389461278364912763461265216385123478213749712893478912378947N |
| 08:44 | martinklepsch | https://github.com/clojure/data.zip/blob/b165e0c9d4ccd83280ac0462a36718b216b0ed20/src/main/clojure/clojure/data/zip/xml.clj#L56 |
| 08:45 | llasram | ryanbraganza: You `str` it first |
| 08:45 | martinklepsch | gfredericks ^ — will look into your suggestion, thx! |
| 08:46 | ryanbraganza | llasram: thanks! |
| 08:52 | martinklepsch | gfredericks, turns out I can just (zf/text (xml1-> .... )) |
| 09:38 | akazlou | hi, guys, having difficulties understanding the behavior of apply fn: |
| 09:38 | akazlou | (apply conj [1 2 3] 4) ;=> doesn't compile |
| 09:38 | akazlou | (apply conj [1 2 3] [4]) ;=> [1 2 3 4] |
| 09:38 | akazlou | although: |
| 09:38 | akazlou | (conj [1 2 3] [4]) ;=> [1 2 3 [4]] |
| 09:38 | akazlou | what is happening in the background when apply is called? |
| 09:40 | beamso | ,(conj [1 2 3] 4) |
| 09:40 | clojurebot | [1 2 3 4] |
| 09:40 | beamso | ,(apply conj [1 2 3] 4) |
| 09:40 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 09:41 | agarman | ,(apply conj [1 2 3] [4 5 6]) |
| 09:41 | clojurebot | [1 2 3 4 5 ...] |
| 09:41 | agarman | ,(doc apply) |
| 09:41 | clojurebot | "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args." |
| 09:41 | BobSchack | ,(apply conj [3] 3 1 3 4 4 [1 2 3]) |
| 09:41 | clojurebot | [3 3 1 3 4 ...] |
| 09:42 | BobSchack | akazlou for apply it appears the last argument is expected to be a collection of arguements |
| 09:42 | agarman | ditto what BobSchack said |
| 09:45 | BobSchack | so you have (apply <your function> <arg1> <arg2> [<arg3> .. <argN>]) which is (<your function> <arg1> <arg2> <arg3> ... <argN>) |
| 09:46 | akazlou | what are the use cases when you need to use apply, instead of <your function> directly? |
| 09:46 | teslanick | Apply lets you hand a constructed list of arguments to a function, where you may not know what those arguments are ahead of time. |
| 09:47 | BobSchack | It's the same use case as *args in python |
| 09:48 | agarman | ,(apply + (range 3 11 7/9)) |
| 09:48 | clojurebot | 682/9 |
| 09:48 | agarman | ,(doc +) |
| 09:48 | clojurebot | "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'" |
| 09:49 | teslanick | One where you might not know the arguments or the number of arguments ahead of time: |
| 09:49 | teslanick | ,(apply + (take (rand-int 20) (repeatedly #(rand-int 10)))) |
| 09:49 | clojurebot | 6 |
| 09:49 | agarman | for a fn like +, that's expecting a individual args, apply allows you to pass a sequence of args instead |
| 09:50 | teslanick | Sum a set of random integers between 0 and 10, between 0 and 20 members in size. |
| 09:51 | agarman | apply & reduce are similar |
| 09:51 | akazlou | ok, need to think about it, thank you guys |
| 09:52 | akazlou | reduce is a little bit different as I may say: reduce is (f (f (f (args))) |
| 09:52 | akazlou | when in apply f is called only once |
| 09:53 | akazlou | but, yes, they are similar |
| 10:00 | akazlou | in addition to apply question above: |
| 10:00 | akazlou | ,(source apply) |
| 10:00 | clojurebot | Source not found\n |
| 10:01 | akazlou | (source apply) |
| 10:01 | akazlou | (defn apply |
| 10:01 | akazlou | "Applies fn f to the argument list formed by prepending intervening arguments to args." |
| 10:01 | akazlou | {:added "1.0" |
| 10:01 | akazlou | :static true} |
| 10:01 | akazlou | ([^clojure.lang.IFn f args] |
| 10:01 | akazlou | (. f (applyTo (seq args)))) |
| 10:01 | akazlou | ([^clojure.lang.IFn f x args] |
| 10:01 | akazlou | (. f (applyTo (list* x args)))) |
| 10:01 | akazlou | ([^clojure.lang.IFn f x y args] |
| 10:01 | akazlou | (. f (applyTo (list* x y args)))) |
| 10:01 | akazlou | ([^clojure.lang.IFn f x y z args] |
| 10:01 | akazlou | (. f (applyTo (list* x y z args)))) |
| 10:01 | akazlou | ([^clojure.lang.IFn f a b c d & args] |
| 10:02 | akazlou | so (apply conj [1 2 3] [4]) ;=> (apply conj (list* [1 2 3] 4)) |
| 10:02 | akazlou | ,(list* [1 2 3] 4) |
| 10:02 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 10:02 | akazlou | ,(list* [1 2 3] [4]) |
| 10:02 | clojurebot | ([1 2 3] 4) |
| 10:02 | akazlou | and this result is then applied to conj |
| 10:02 | akazlou | which conj expects |
| 10:04 | akazlou | through conj.applyTo, (every fn is an instance of clojure.lang.IFn?) |
| 10:04 | dnolen_ | akazlou: please don't paste into the channel, use a paste service |
| 10:05 | akazlou | sorry |
| 10:06 | teslanick | akazlou: Yes. Every function (and many "not functions") are IFns |
| 10:06 | teslanick | (e.g. keywords are IFns too) |
| 10:06 | agarman | and maps |
| 10:06 | agarman | and sets |
| 10:07 | teslanick | I always forget about that. I find (:foo {:foo "bar"}) easier to think about than the inverse. |
| 10:07 | teslanick | ({:foo "bar"} :foo) |
| 10:08 | teslanick | ,({:foo "bar"} :foo) |
| 10:08 | clojurebot | "bar" |
| 10:09 | teslanick | But applyTo takes a list of arguments: |
| 10:09 | teslanick | ,(. conj (applyTo '([1 2 3] 4))) |
| 10:09 | clojurebot | [1 2 3 4] |
| 10:12 | akazlou | yes, this is what list* produces I guess |
| 10:13 | teslanick | ,(doc list*) |
| 10:13 | clojurebot | "([args] [a args] [a b args] [a b c args] [a b c d & ...]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence." |
| 10:25 | btcNeverSleeps | ouch, my Emacs / erc session crashed... If anyone did answer about my "lein test" hanging on an assert failing, it would be great if you could paste the answer again ^ ^ |
| 10:45 | gfredericks | teslanick: I think keywords-as-fns is useful for record-like maps while maps-as-fns is useful for homogeneous hash-map-like maps |
| 10:45 | akazlou | on clojure.test/is is there any convention which value in = comes first expected or actual: |
| 10:45 | akazlou | i.e. (is (= <expected> <actual>)) or (is (= <actual> <expected>)), I see the value having <expected> first |
| 10:46 | stuartsierra | (is (= <expected> <actual>)) is the norm but not enforced |
| 10:46 | teslanick | gfredericks: That's actually a really good point that I hadn't thought about. I rarely use maps as hash-map-like maps (to my own detriment; it's hard to shake my JS-provided worldview) |
| 10:47 | gfredericks | teslanick: I think it's the same use cases for using a hashmap *at all* in a statically typed language |
| 10:47 | gfredericks | in my experience it's usually in algorithmic contexts rather than data/logic contexts |
| 10:48 | akazlou | thanks stuartsierra |
| 10:50 | akazlou | and if keywords and maps are both function, and in simple cases can be used interchangeably to get the value from the map, again which way is more common: (:keyword {<map>}) or ({<map>} :keyword)? |
| 10:52 | teslanick | As gfredericks pointed out, if you're using your map as a record of keyword->value, it's ocmmon to do (:keyword {map of kw->value}) |
| 10:53 | teslanick | But not all map keys need to be keywords. You could do { 'foo "at foo" } |
| 10:54 | teslanick | In which case, you would use the other form: |
| 10:54 | teslanick | ,({ 'foo "AT FOO" } 'foo) |
| 10:54 | clojurebot | "AT FOO" |
| 10:54 | gfredericks | if you're writing code that you want to work with arbitrary maps and keys, the safest route is clojure.core/get |
| 11:10 | akazlou | yes, clojure.core/get is even necessary when you do (->) and keys are not keywords |
| 11:10 | akazlou | ,(-> {:headers {"Content-Type" "text/html"}} :headers (get "Content-Type")) |
| 11:10 | clojurebot | "text/html" |
| 11:13 | bbloom | akazlou: that's a good spot for a get-in |
| 11:13 | bbloom | (get-in {:headers {"Content-Type" "text/html"}} [:headers "Content-Type"]) |
| 11:13 | bbloom | ,(get-in {:headers {"Content-Type" "text/html"}} [:headers "Content-Type"]) |
| 11:13 | clojurebot | "text/html" |
| 11:17 | akazlou | cool :) |
| 11:19 | akazlou | still trying to remember that you can any symbol in clojure fn name, like ? instead of is-, and even < and > :), which seems pretty common for Clojure |
| 11:20 | seangrove | ,(def : get) |
| 11:20 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: :> |
| 11:20 | seangrove | Sadly, lots of symbols you can't use (or at least start with), otherwise writing perl in clojure would be a lot easier |
| 11:20 | martinklepsch | anyone a clever suggestion for something easily accessible like a map with multiple keys for the same value? |
| 11:21 | martinklepsch | {15 [:subdoc-abstract :paragraph] |
| 11:21 | martinklepsch | 16 [:subdoc-abstract :paragraph] |
| 11:21 | martinklepsch | 40 [:abstract] |
| 11:21 | martinklepsch | 41 [:abstract]} |
| 11:22 | seangrove | martinklepsch: Probably a fn to construct that |
| 11:23 | seangrove | (mk-hash-map [15 15] [:subdoc-abstract] [40 41] [:abstract] [[:nested :vector] 99] [:example]) |
| 11:24 | martinklepsch | seangrove, yeah, probably just making a function that copies into the empty spots is simplest |
| 11:27 | mikerod | are there any good clj libs for working with Jar streams (input is my concern currently)? they are just annoying. |
| 11:28 | mikerod | clojure.java.io doesn't quote do it all for me; maybe I just don't know how to use it good enough :P |
| 11:30 | stuartsierra | mikerod: https://github.com/clojure/java.classpath may help a little |
| 11:41 | felher | Hey folks. Say I have an impure function that returns something I need, like `create-random-card-deck`, whats the easiest way to get a sequence of n times invoking that function? (doall (map (fn [f] (f)) (repeat n create-random-card-deck))) doesn't strike me as being overly convenient. |
| 11:41 | llasram | &(doc repeatedly) |
| 11:41 | lazybot | ⇒ "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it" |
| 11:41 | mikerod | stuartsierra: thanks! I'll take a look. after reading this project description, I think it is useful for other things I've been looking at to. win-win |
| 11:41 | felher | llasram: perfect! Thanks! |
| 11:49 | TimMc | seangrove: "sadly", yes... |
| 11:56 | martinklepsch | (fun :that :takes :a :lot :of :arguments) how could I rewrite that so that it takes a list which supplies some of those arguments? like (fun % :more :arguments) |
| 12:01 | seangrove | martinklepsch: apply? |
| 12:01 | seangrove | (doc apply) |
| 12:02 | clojurebot | "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args." |
| 12:03 | seangrove | (map (partial apply +) [[1 1] [2 2] [3 3]]) |
| 12:03 | seangrove | ,(map (partial apply +) [[1 1] [2 2] [3 3]]) |
| 12:03 | clojurebot | (2 4 6) |
| 12:07 | rasmusto | ,(apply vector 1 2 3 [4 5]) |
| 12:07 | clojurebot | [1 2 3 4 5] |
| 12:08 | hfaafb | require_once("../../lib/WebServiceCore.class.php"); |
| 12:08 | hfaafb | my bad! |
| 12:09 | hfaafb | how embarassing |
| 12:09 | hfaafb | <_< |
| 12:09 | rasmusto | ~php |
| 12:09 | clojurebot | php is http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/ |
| 12:09 | nullptr` | hfaafb: yeah, here we say (require-once "../../lib/WebServiceCore.class.php") -- sheesh |
| 12:09 | hfaafb | :) |
| 12:09 | rasmusto | :) |
| 12:13 | jcromartie | ,((memfn .toUpperCase) "test") |
| 12:13 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: .toUpperCase for class java.lang.String> |
| 12:13 | jcromartie | WHY? |
| 12:14 | nullptr` | ,((memfn toUpperCase) "test") |
| 12:14 | clojurebot | "TEST" |
| 12:14 | jcromartie | oh... |
| 12:14 | jcromartie | thanks |
| 12:16 | martinklepsch | seangrove, rasmusto, that works if I only want to append fn-arguments but not if I want to insert them in the middle |
| 12:19 | felher | Why does the following code stack overflow? (println (reduce #(map + %1 %2) (repeat 2000 [1]))) |
| 12:19 | felher | I guess there some lazy-magic going on there, since doing #(doall (map + %1 %2)) seems to fix the problem. |
| 12:21 | justin_smith | felher: for me that does not so, and returns quickly |
| 12:21 | justin_smith | ,(println (reduce #(map + %1 %2) (repeat 2000 [1]))) |
| 12:21 | clojurebot | (#<StackOverflowError java.lang.StackOverflowError> |
| 12:21 | TEttinger | heh |
| 12:21 | justin_smith | odd |
| 12:21 | felher | :) |
| 12:22 | stuartsierra | felher: Lazy sequences nest. If you wrap too many of them, it overflows the stack when you try to consume it. |
| 12:23 | stuartsierra | This shows up often if you use `concat` to build up a long sequence in a loop. |
| 12:23 | TEttinger | ,(reduce #(mapv + %1 %2) (repeat 2000 [1])) ; I wonder... |
| 12:23 | clojurebot | [2000] |
| 12:24 | TEttinger | mapv does avoid the laziness from repeat, interesting |
| 12:24 | felher | stuartsierra: oh, okay, thanks :) |
| 12:25 | justin_smith | TEttinger: I think the problem was the map laziness - it is reduce that eliminates the repeat laziness |
| 12:25 | TEttinger | ah |
| 12:26 | justin_smith | TEttinger: the reduce ends up building a long chain of map upon map, none forced until the print stage |
| 12:26 | TEttinger | ah! that makes sense |
| 12:28 | tudd | if you create a defrecord `RecordType` and define an instance with (def RecordType some-record) can you later pass that some-record into another fn and reference some-record.property |
| 12:28 | tudd | seems like a straightforward thing to do in OOP-land.. |
| 12:28 | base698 | is there a better repl so you can use emacs bindings to go back in history, jumper words etc? |
| 12:29 | jcromartie | base698: cider |
| 12:29 | justin_smith | tudd: that makes very little sense |
| 12:29 | jcromartie | base698: you can use it to connect to an nREPL in your leiningen projects |
| 12:29 | jcromartie | or anywhere, like on a production server :) |
| 12:30 | jcromartie | base698: that's an Emacs mode, BTW |
| 12:30 | TEttinger | (def RecordType some-record) can't be the right syntax |
| 12:30 | justin_smith | clojure version (def instance (RecordType. arg0 arg1 arg2 ... argN)) (:property instance) |
| 12:30 | justin_smith | or even (.property instance) |
| 12:33 | tudd | http://pastebin.com/htSdGhwY |
| 12:33 | justin_smith | ,(do (defrecord RecordType [property]) (def instance (RecordType. 42)) (-> instance .property)) |
| 12:33 | clojurebot | 42 |
| 12:35 | justin_smith | tudd: in that example, you can use (.ticker order) instead of order.ticker |
| 12:35 | justin_smith | or (:ticker order) |
| 12:35 | justin_smith | or (-> order .ticker) |
| 12:35 | justin_smith | but order.ticker is an error |
| 12:36 | justin_smith | and the right way to do it: {:params order :handler handler ...} |
| 12:36 | tudd | justin_smith: yep. error. but not in the repl |
| 12:36 | justin_smith | I am extremely skeptical that it would not be an error in the repl |
| 12:36 | justin_smith | just pass order as the params, clojure will use it as a map, it will just work |
| 12:37 | tudd | LT is cool with returning order.broker |
| 12:37 | justin_smith | also in this case you could just use a map instead of defining an Order record |
| 12:37 | justin_smith | then LT is broken |
| 12:37 | justin_smith | because that is not clojure code |
| 12:38 | lorefyr | Hi everyone |
| 12:38 | tudd | I didn't think so. But coming over from JS land, that does work, normally ;) |
| 12:39 | justin_smith | right, clojure is not js though |
| 12:39 | tudd | cljs |
| 12:40 | justin_smith | cljs is not js either |
| 12:41 | justin_smith | The google results for searching "clojure publish rss" are filled with useless results (pages that have the word "rss" somewhere, because that page has a feed) - any good libs out there for publishing rss with clojure? |
| 12:41 | seangrove | justin_smith: (js/console.log "x") is valid cljs |
| 12:42 | justin_smith | seangrove: oh, weird |
| 12:42 | seangrove | (js/Math.floor ...) |
| 12:42 | seangrove | etc. |
| 12:42 | tudd | https://github.com/yogthos/clj-rss |
| 12:42 | justin_smith | never mind my above question, I found yogthos/clj-rss |
| 12:42 | justin_smith | hah, thanks :) |
| 12:42 | stuartsierra | Sometimes the ClojureScript compiler will let through things like `foo.bar`. I wouldn't rely on that, though. |
| 12:43 | justin_smith | stuartsierra: so that isn't an intentional feature? |
| 12:43 | seangrove | justin_smith: With cljs, it's always hard to tell :) |
| 12:43 | tudd | As it spits errors when called from within another fn, I won't |
| 12:44 | justin_smith | seangrove: the js murkiness sneaks in, I guess :( |
| 12:45 | seangrove | justin_smith: A bit. A lot of it is just unspecified behavior that'll be nailed down as practices are established |
| 12:45 | tudd | foo.bar is NOT idiomatic clojure(script), and even though you want it to ultimately become js, not gonna let you! |
| 12:46 | justin_smith | yeah, I never even thought to try foo.bar in cljs |
| 12:47 | tudd | don't bother. LT gets red-in-the-face mad at ya |
| 12:47 | mr-foobar | cljsc nodehello.cljs '{:optimizations : :target :nodejs}' > nodehello.js |
| 12:47 | justin_smith | which dead horse? |
| 12:47 | mr-foobar | is giving me "goog.addDependency("base.js", ['goog'], []); ..." in the compiled file |
| 12:47 | seangrove | foo.bar |
| 12:48 | justin_smith | it was new to me, sorry |
| 12:48 | seangrove | justin_smith: Oh, not at all ;) |
| 12:48 | seangrove | Anyway, just added a css reset: * { position: absolute; top: 0px; left: 0px;}, let's see how this goes |
| 12:50 | tudd | justin_smith: thx again! collapsing LOC nicely after your suggestion |
| 12:50 | tudd | plus that, it now works! thing |
| 12:50 | justin_smith | tudd: cool |
| 12:50 | justin_smith | so you are just passing :params order now? |
| 12:51 | tudd | yep |
| 12:51 | justin_smith | a similar trick is (select-keys order [:keys :we :use :here]) |
| 12:51 | justin_smith | or (assoc order :this "also" :and "this") |
| 13:07 | gozala | tbaldridge: Do you have time for a question regarding core.async/net ? |
| 13:07 | tbaldridge | sure |
| 13:10 | gozala | tbaldridge: so I was looking at the source |
| 13:10 | gozala | tbaldridge: and notice pattern similar to one I used |
| 13:10 | gozala | for buliding node.tcp module using core.async |
| 13:11 | gozala | tbaldridge: https://github.com/Gozala/node.core/blob/master/src/node/tcp.cljs |
| 13:11 | gozala | tbaldridge: only thing I noticed though |
| 13:11 | gozala | or rather did not quite got |
| 13:11 | tbaldridge | gozala: what do you mean by core.async/net btw? that doesn't quite exist? |
| 13:12 | gozala | tbaldridge: I was looking at |
| 13:12 | gozala | https://github.com/clojure/core.async/blob/net-channels/src/main/clojure/clojure/core/async/net.clj |
| 13:12 | gozala | tbaldridge: I’m aware it’s does not exists yet :) |
| 13:13 | tbaldridge | so I'll caution you as that has mostly been considered a bad idea and discontinued :-P |
| 13:13 | gozala | tbaldridge: Anyway what I was trying to understand was what’s a good way to deal with errors |
| 13:13 | gozala | tbaldridge: I see |
| 13:14 | gozala | tbaldridge: are there any ideas right now that are considered good ? |
| 13:14 | gozala | in terms of networking or any IO really ? |
| 13:15 | tbaldridge | gozala: errors are one thing, that we can discuss. Trying to create channel like semantics over a unreliable connection (like TCP or any net connection) creates a ton of problems. |
| 13:16 | gozala | tbaldridge: are those problems listed somewhere ? I would like to look at them |
| 13:16 | gozala | tbaldridge: I would also like to discuss errors |
| 13:17 | gozala | tbaldridge: so now I define connection in terms of a ISocket |
| 13:17 | gozala | that is record of input, output, and error channels |
| 13:18 | gozala | so data read from the connection is put onto input |
| 13:18 | gozala | data put onto output channel is written into underlying connection |
| 13:19 | gozala | if there is an error it’s put onto error channel |
| 13:19 | gozala | tbaldridge: ^ |
| 13:20 | gozala | does that sounds reasonable so far ? |
| 13:21 | gozala | or did I ignored tons of problems already ? |
| 13:24 | gozala | tbaldridge: So my question regarding errors was mainly regarding how one would distinguish between write and read errors |
| 13:24 | gozala | or how had error would carry info regarding where did it happened |
| 13:26 | gozala | tbaldridge: I other words I am no longer sure that dedicated error channel for buth input / output errors was such a good idea |
| 13:26 | justin_smith | gozala: tcp connections introduce complications in error handling - like with a socket being held open, you don't get an error when you send the message that fails, you get an error later because tcp is retrying (you probably already know this I guess) |
| 13:27 | gozala | justin_smith: so that is more or less why I’m bringing it up |
| 13:28 | gozala | justin_smith: also I would kind of run into same issue if I would implement something like buffered FileWriter |
| 13:28 | tbaldridge | gozala: sorry, had to run for a sec, back now |
| 13:29 | gozala | where it’s not obvious how to associate error with chunk that was put |
| 13:29 | tbaldridge | gozala: justin_smith brings up some good points, and that's all part of the fun of working with tcp. |
| 13:29 | justin_smith | gozala: it forces everything to be async and nonlinear |
| 13:30 | tbaldridge | gozala: that's why I took a different approach with Hermod (kindof the successor to core.async/net): https://github.com/halgari/com.tbaldridge.hermod |
| 13:30 | justin_smith | so you should make your model so that it maps cleanly to tcp's weird time semantics |
| 13:30 | tbaldridge | gozala: if you push error handling off on to the app code things get a bit simpler for both the library and the app (imo). |
| 13:31 | gozala | tbaldridge: looking at that lib now |
| 13:32 | justin_smith | tbaldridge: gozala: yeah, that looks like the kind of approach I was suggesting actually |
| 13:32 | tbaldridge | yeah it's a lot like the actor model, except processes aren't tied to mailboxes. |
| 13:33 | gozala | justin_smith: tbaldridge I’m afraid it’s not clear to me yet what the approach looks like yet |
| 13:34 | gozala | tbaldridge: are there any examples anywhere outlining error handling ? |
| 13:36 | gozala | tbaldridge: or is idea is that if message send timed out that is an error ? |
| 13:36 | seangrove | bbloom: In your layout system, is slot meant to be absolutely positioned against the entire screen, and content relative to its parent? |
| 13:38 | bbloom | seangrove: i forget how i implemented it, but generally i prefer local coordinates wherever possible |
| 13:38 | tbaldridge | gozala: sending a message is always non-blocking, so sending always succeeds, but the message may not get to the other end |
| 13:38 | bbloom | game dev habits die hard |
| 13:38 | gozala | tbaldridge: so if I read correctly |
| 13:38 | tbaldridge | gozala: so the only way to ensure delivery is to send a message with a "respond-do" address and wait until you hear back from the receiver. If you don't get a reply, try resending the message, or give up. |
| 13:38 | tbaldridge | "respond-to" |
| 13:38 | gozala | there are things like ::errro put on channel |
| 13:39 | gozala | tbaldridge: ok I see |
| 13:40 | gozala | tbaldridge: I guess what I am looking is something more abstract |
| 13:40 | gozala | tbaldridge: Can I give that FileWriter example I mentioned eariler |
| 13:40 | bbloom | for the record, i don't think CSP makes any sense in a distributed context |
| 13:41 | tbaldridge | and that's the problem. it really doesn't |
| 13:41 | tbaldridge | channels are transactional, blocking and guaranteed delivery, that's pretty much the exact opposite of network connections. |
| 13:42 | justin_smith | bbloom: I think it can make sense, but only with the added abstraction allowing you to describe tentative and retroactively failed communications - not as a direct mapping (which is the naive and common first approach) |
| 13:42 | danielszmulewicz | dnolen_: ping |
| 13:42 | dnolen_ | danielszmulewicz: pong |
| 13:42 | danielszmulewicz | Hi David, you helped me yesterday with bringing javascript objects to participate in pattern matching. I'm wondering now about Javascript arrays. According to the documentation, any Sequential type is eligible, but Javascript arrays are not sequential. Am I right that I could aim to reify array instances with the ISequential protocol? I can't find anything on that. Can you point me to the right direction? |
| 13:42 | gozala | tbaldridge: I think it’s not only about networking though |
| 13:42 | seangrove | tbaldridge: Is it used for distributed things in Go? I've not seen it at all, so not sure |
| 13:43 | bbloom | justin_smith: when failure is the norm, not the exception, i'd prefer a different model |
| 13:43 | tbaldridge | seangrove: sure, but go doesn't attempt to make a "distributed channel". |
| 13:43 | gozala | if you do any IO and you have a buffered channel to feed data into it |
| 13:43 | gozala | tbaldridge: you hit more or less same problem |
| 13:43 | bbloom | tbaldridge: justin_smith: CSP is slightly different than just sockets + queues... you can make stuff like zmq work nicely in a distributed context |
| 13:44 | seangrove | bbloom: Presumably the global offsets should be passed in as well. I'm thinking of draggable snap-to-guideline/grid/other-thing outside of the component itself |
| 13:44 | bbloom | but it's much more complex than shared memory networking |
| 13:44 | justin_smith | fair enough :) I'm just saying with the right abstraction failure can be integrated into the CSP model I think - as long as you don't expect the network to be a transperent medium |
| 13:44 | seangrove | tbaldridge: Ok, makes sense |
| 13:44 | bbloom | seangrove: ok, get ready... i'm going to send you another MSDN link lol |
| 13:44 | bbloom | seangrove: http://msdn.microsoft.com/en-us/library/ms743737(v=vs.110).aspx |
| 13:44 | gozala | on one of the writes to disk writer may fail and there is no clear way to communicate that to a producer |
| 13:44 | gozala | or data provider |
| 13:45 | tbaldridge | bbloom: YAY! more XAML based stuff |
| 13:45 | seangrove | Adorners! |
| 13:45 | seangrove | ffs |
| 13:45 | tbaldridge | (seriously, the only thing I hated about XAML was the XML part and the mutability, that stuff rocks) |
| 13:45 | bbloom | tbaldridge: no really, you're right. xaml is a good idea wrapped in a cloth of bad ideas |
| 13:45 | bbloom | tbaldridge: fundamentally, the good idea is basically EDN :-) |
| 13:46 | bbloom | general purpose, extensible data construction syntax |
| 13:46 | seangrove | Ah, but this does seem like a a good idea |
| 13:46 | bbloom | tbaldridge: oh jeeze, i'm sorry |
| 13:46 | bbloom | javafx was oracle getting WPF envy and fucking it up |
| 13:46 | tbaldridge | javafx2 isn't as bad |
| 13:47 | tbaldridge | and don't knockit till you try it, edn syntax + clojure primitive and core.async makes it quite nice actually. |
| 13:47 | bbloom | heh ok, i can buy that |
| 13:48 | bbloom | at least compared to HTML and/or swing, for sure |
| 13:48 | tbaldridge | yeah exactly |
| 13:48 | tbaldridge | and now back to working with metadata and macros....to whomever wanted good line numbers inside a go macro....I hate you right now |
| 13:48 | tbaldridge | lol |
| 13:48 | bbloom | seangrove: anyway, fns to map between local & global coordinates are context-dependent (of course) so you should use local coordinates wherever possible to avoid having to do lots of inverse transformations |
| 13:49 | bbloom | seangrove: also, it's ok to put things at negative relative positions, you just need to deal with clipping policy |
| 13:50 | danielszmulewicz | dnolen_: Hi David, you helped me yesterday with bringing javascript objects to participate in pattern matching. I'm wondering now about Javascript arrays. According to the documentation, any Sequential type is eligible, but Javascript arrays are not sequential. Am I right that I could aim to reify array instances with the ISequential protocol? I can't find anything on that. Can you point me to the right direction? |
| 13:52 | dnolen_ | danielszmulewicz: I think for now you need to do (matchv :clojure.core.match/objects [arr] ...) |
| 13:53 | dnolen_ | danielszmulewicz: I recommend looking at the ClojureScript tests for examples - also feel free to update the wiki, I'm sure other people have similar questions. |
| 13:53 | danielszmulewicz | dnolen_: OK, I'll do that. Thanks. |
| 13:54 | danielszmulewicz | dnolen_: By the way, converting my array with js->clj doesn't hurt neither. Does this seem acceptable to you? |
| 13:55 | seangrove | "The arrange pass begins with a call to the Arrange method. During the arrange pass, the parent Panel element generates a rectangle that represents the bounds of the child. This value is passed to the ArrangeCore method for processing." |
| 13:55 | seangrove | bbloom: ^^ The rectangle representing the bounds of the child is the slot rectangle in your system, right? |
| 13:55 | dnolen_ | danielszmulewicz: yes if expressivity outweights perf |
| 13:55 | dnolen_ | outweighs |
| 13:56 | bbloom | seangrove: right b/c the child may be given a slot that's too big, so the child has margin & alignment settings to say how it gets positioned within that slot |
| 13:56 | danielszmulewicz | dnolen_: Yes, makes sense. |
| 13:56 | seangrove | bbloom: Alright, hope to have an Om render in an hour or so |
| 13:58 | bbloom | seangrove: just added you to a private repo of mine. plz don't commit to it ;-) it's got a layout.clj file that is more feature complete |
| 13:59 | bbloom | seangrove: if you eval the render forms in core.clj you can play with the layout engine |
| 14:08 | Bronsa | bbloom: just noticed you have a typo in the github description for backtick |
| 14:08 | Bronsa | s/marco/macro |
| 14:09 | bbloom | Bronsa: fixed, thanks |
| 14:13 | mikerod | are there any libs out there that deal with attempting to fully-qualify all symbols in chunks of code and the context of their originating namespace? the goal being to store off the code as pure-data, that is sufficiently descriptive to be read back in and compiled at a later time. |
| 14:14 | mikerod | *chunks of code with the context of their originating namespace* |
| 14:14 | technomancy | mikerod: sounds like the analyzer? |
| 14:14 | amalloy | mikerod: tools.analyzer? |
| 14:17 | mikerod | technomancy: amalloy this is what I thought |
| 14:18 | mikerod | I'm not sure that it actually "qualifies" the symbols; but mabye I haven't dug enough |
| 14:18 | mikerod | I know the idea is to make the AST data though |
| 14:18 | amalloy | it knows where they come from |
| 14:18 | mikerod | ok |
| 14:18 | mikerod | I think I will continue to explore that then |
| 14:18 | amalloy | and then you can write a pass that consumes the AST and produces whatever you want. if you want, that can be a source-code form with qualified symbols, i imagine |
| 14:19 | mikerod | that makes sense |
| 14:19 | mikerod | this sounds promising |
| 14:19 | mikerod | I've only scratched the surface on tools.analyzer; and recently listened to the talk by umm |
| 14:19 | amalloy | by tbaldridge |
| 14:19 | amalloy | (i guess, anyway) |
| 14:20 | mikerod | yes |
| 14:20 | mikerod | that is it :) |
| 14:20 | mikerod | "data all the ASTs" |
| 14:20 | tbaldridge | mikerod: you might checkout this : https://github.com/clojure/tools.analyzer/blob/master/src/main/clojure/clojure/tools/analyzer/ast/query.clj |
| 14:20 | tbaldridge | it stores tools.analyzer asts in Datomic |
| 14:21 | tbaldridge | haven't tried it, but it looks cool. |
| 14:21 | Bronsa | mikerod: there's an emit-form pass that compiles the AST back to clojure source. It doesn't return qualified symbols but I have a branch locally that enables that, I can finish that and push that if you need it. |
| 14:21 | mikerod | tbaldridge: awesome and Bronsa that certainly sounds valuable |
| 14:21 | Bronsa | tbaldridge: it doesn't really store asts in Datomic, it just uses Datomic's datalog |
| 14:22 | mikerod | I have done some "hand-rolling" of my own to qualify symbols |
| 14:22 | mikerod | but not to the extent of the full-blown AST analysis |
| 14:22 | tbaldridge | Bronsa: yeah I just noticed that, lol |
| 14:22 | Bronsa | mikerod: beware that it will macroexpand the source though |
| 14:24 | mikerod | Bronsa: yeah, I am curious on this. I technically have some symbols in the source that do not "make sense" in the initial context. I'm wondering if this will cause the analysis to fail, or if I can "mock out" those symbols into the context to avoid failure. |
| 14:24 | mikerod | This is DSL-stuff |
| 14:24 | Bronsa | mikerod: the analyzis will work only if the source can be eval'ed. |
| 14:25 | Bronsa | mikerod: however you can cheat and give the analyzer a patched-up env |
| 14:25 | mikerod | e.g. I have some code like: (+ a b im-a-undefined-symbol) ; where a and b are defined, the other is not; I will fill it in at a later time when reading back out the code and evaluating |
| 14:25 | mikerod | Bronsa: I think the patched-up env was my hopes/thoughts |
| 14:26 | Bronsa | mikerod: to do that you need to know what locals/vars your code is going to use that are not already defined though |
| 14:26 | jcromartie | for some reason I'm stumped on this one: how to write a HOF which takes a function and returns a new function that ensures the original function is called once and only once |
| 14:27 | mikerod | Bronsa: I figured. I do wish I could "catch" failures to resolve symbols and provide a handler for it. I'm not thinking this is possible, but just a cool idea. |
| 14:27 | Bronsa | mikerod: if you can't know that, a really hackish way to make that work is to redefine this multimethod https://github.com/clojure/tools.analyzer.jvm/blob/master/src/main/clojure/clojure/tools/analyzer/passes/jvm/validate.clj#L19 not to throw |
| 14:27 | Averell | a closure with a flag is not good enough? |
| 14:27 | jcromartie | Averell: derp |
| 14:28 | jcromartie | well no |
| 14:28 | jcromartie | that's not good enough |
| 14:28 | jcromartie | what if it's called from two threads? |
| 14:29 | mikerod | Bronsa: interesting, thanks for the reference |
| 14:29 | jcromartie | oh, maybe a promise is what I'm looking for |
| 14:29 | jcromartie | eh… still, race condition |
| 14:30 | jcromartie | the function that I want to once-ify has side effects |
| 14:31 | jcromartie | hm, maybe laziness is the answer |
| 14:31 | amalloy | jcromartie: you close over a delay |
| 14:31 | amalloy | assuming the args are known already? |
| 14:31 | jcromartie | args are not known |
| 14:32 | jcromartie | basically like memoize |
| 14:32 | jcromartie | but safe for side effects |
| 14:32 | amalloy | eh. so you use the same trick that's available to make memoize avoid side effects |
| 14:33 | amalloy | (defn call-once [f] (let [value (atom nil)] (fn [& args] @(swap! value #(or % (delay (apply f args))))))) |
| 14:33 | amalloy | er, avoid side-effect problems |
| 14:34 | justin_smith | jcromartie: maybe something like https://www.refheap.com/77421 |
| 14:34 | jcromartie | amalloy: memoize is not safe |
| 14:34 | jcromartie | ,(let [f (memoize println)] (dorun (pmap f (repeatedly 10 #(rand-int 10))))) |
| 14:34 | clojurebot | #<SecurityException java.lang.SecurityException: no threads please> |
| 14:34 | amalloy | jcromartie: that's why i said, the trick that's available. you can make memoize safe by storing a delay |
| 14:34 | jcromartie | ok |
| 14:35 | jcromartie | ahhh |
| 14:35 | amalloy | instead of storing the actual value |
| 14:35 | amalloy | i mean, i just typed out my call-once in irc, but i think it's the solution you want |
| 14:37 | amalloy | holy smokes, justin_smith. if you use @ and reset!, you're like never thread-safe |
| 14:38 | justin_smith | good point |
| 14:39 | amalloy | jcromartie: my version returns the result of the first call, regardless of what args are passed to the second call. so that may not be what you want, i suppose |
| 14:44 | Bronsa | mikerod: just pushed the impl: http://sprunge.us/WLaL?clj |
| 14:45 | justin_smith | amalloy: jcromartie: edited https://www.refheap.com/77421 |
| 14:45 | jcromartie | see, this is harder than everybody thinks it is :) |
| 14:45 | mikerod | Bronsa: awesome! thanks. I will definitely start experimenting with this then. |
| 14:46 | amalloy | that has the same problem memoize has, justin_smith. two threads can both be inside that swap! at the same time |
| 14:46 | justin_smith | oh, tricky |
| 14:47 | amalloy | that's, again, not a problem in my solution |
| 14:48 | koreth_ | I want to parse a whitespace-delimited string into a vector of integers. (mapv #(Long. %) (clojure.string/split my-string #"\s")) does the trick but #(Long. %) seems unnecessarily ugly -- is there a more idiomatic "parse a number" function? |
| 14:48 | jcromartie | if it's a thunk it's not a problem |
| 14:49 | amalloy | jcromartie: huh? |
| 14:49 | justin_smith | amalloy: yours not intended for usage with functions that return nil, I assume? |
| 14:49 | amalloy | justin_smith: works for all functions |
| 14:49 | amalloy | try it and see |
| 14:50 | Averell | why is it safe? i don't understand which part hides the locking |
| 14:50 | amalloy | Averell: it's dereffing the delay |
| 14:50 | amalloy | there's a lock around that |
| 14:50 | justin_smith | amalloy: oh, of course, because it returns the delay, and derefs, so that delay will not be nil after the first call |
| 14:50 | justin_smith | smart |
| 14:51 | jcromartie | amalloy: I think yours is good BTW |
| 14:51 | jcromartie | I was saying that if you want to make a thunk callable once it's really easy |
| 14:51 | jcromartie | if you don't have to worry about args |
| 14:52 | amalloy | oh, for sure. that was my original suggestion: close over a delay |
| 14:52 | amalloy | but it only works for thunks |
| 14:52 | nullptr` | koreth_: somewhat clunky, but you can use read-string instead of #(Long. %) |
| 14:52 | koreth_ | Thanks |
| 15:10 | jcromartie | Is there a simpler version of: (not-any? nil? coll) |
| 15:10 | jcromartie | I think it's pretty clear, myself. |
| 15:16 | jcromartie | long-running futures are probably not a good way to handle periodic background tasks |
| 15:16 | jcromartie | like, (loop … (Thread/sleep 300000) (recur)) |
| 15:16 | jcromartie | wrapped in a future |
| 15:19 | teslanick | You could use core.async to handle occasional background tasks. |
| 15:21 | seangrove | bbloom: https://www.refheap.com/fa7a23df23c6a97e7725391be => http://dl.dropbox.com/u/412963/Screenshots/du.png, slots working, content up next |
| 15:22 | bbloom | seangrove: cool |
| 15:22 | Rosnec | is it possible to use ztellman's gloss library to decode bytes from a file where you don't know the byte-count ahead of time? |
| 15:22 | bbloom | seangrove: happy with my approach? i don't remember how i felt about it ;-) |
| 15:23 | seangrove | Black space represent difference between slot-space and content-space. Some cheating in that the browser is still doing some layout intra-component. |
| 15:23 | seangrove | bbloom: So far, mostly very happy. Few questions though |
| 15:23 | bbloom | seangrove: relying on browser for text layout etc is probably quite sensible |
| 15:23 | Rosnec | I can put byte-counts as prefix information, but I still need to be able to read from the file without knowing the size right away |
| 15:24 | bbloom | seangrove: definitely check out how that newer code i gave you access to handles margin & alignment |
| 15:24 | jcromartie | this is how I roll https://gist.github.com/jcromartie/11052252 |
| 15:25 | Bronsa | jcromartie: jesus christ. |
| 15:25 | amalloy | jcromartie: (partial - 0)? that's just - |
| 15:26 | bbloom | jcromartie: #concatenative is that way ----> |
| 15:26 | amalloy | oh, no, i guess it's not, if you pass multiple args? |
| 15:26 | amalloy | but in your case you're not |
| 15:26 | jcromartie | oh, good to know! |
| 15:27 | amalloy | and what is the deal with (comp f (comp g h) blah blah)? |
| 15:27 | amalloy | (if you're going to post silly point-free code i have to assume you're willing to have it picked apart) |
| 15:27 | jcromartie | which line? |
| 15:27 | jcromartie | yes, please |
| 15:27 | amalloy | 10-12 |
| 15:28 | jcromartie | ah yes |
| 15:28 | Averell | btw, vigenere is no longer considered safe by many people. |
| 15:28 | amalloy | (comp (partial map (comp f g)) (partial map h)) is (partial map (comp f g h)) |
| 15:28 | mi6x3m | clojure, why is this working: (map (fn [a] { :a a }) "aaaa"), but this doesn't: (map #({ :a % }) "aaaa") |
| 15:28 | Bronsa | mi6x3m: #(f) is (fn [] (f)) not (fn [] f) |
| 15:29 | seangrove | bbloom: Should components be able to provide default layout guidance? e.g. I have a bootstrap panel, it conceptually has a header and a body. I probably want to think about layout for the body, but not necessarily the panel header (e.g. it should always be 15px heigh and 100% wide if that's what it suggests) |
| 15:29 | amalloy | ,'#({ :a % }) |
| 15:29 | clojurebot | (fn* [p1__25#] ({:a p1__25#})) |
| 15:30 | bbloom | seangrove: the parent shouldn't have any insight in to what's inside the children other than to parameterize them |
| 15:30 | jcromartie | amalloy: excellent |
| 15:30 | amalloy | (partial list cycle [0]) is weird but i don't really get what it's doing |
| 15:30 | bbloom | seangrove: so from the parent's perspective, layout is about bounding rect only |
| 15:30 | mi6x3m | Bronsa: I see, so I have to use a function to create the map? |
| 15:30 | amalloy | (comp reverse (partial list ...)) seems like it ought to be (comp rseq (partial vector ...)) - gotta eke out all that performance! |
| 15:31 | mi6x3m | Bronsa: yeah, works with hash-map |
| 15:31 | mi6x3m | tnx |
| 15:32 | derek_c | does anyone know how to specify a head value in a ring handler? it's returning something like {:status 200 :body "..."}, but I tried adding a :head key and it didn't work |
| 15:32 | derek_c | the resulting HTML has an empty head element |
| 15:32 | hfaafb | :body doesn't mean the contents of <body> |
| 15:33 | hfaafb | it represents the body of the http response |
| 15:33 | derek_c | hfaafb: ah! |
| 15:33 | derek_c | hfaafb: got it. thanks a lot |
| 15:34 | hfaafb | yw |
| 15:34 | jcromartie | amalloy: I had never heard of rseq before… good to know! |
| 15:37 | jcromartie | also, (comp vec (partial map f)) is (comp (partial mapv f)) |
| 15:37 | jcromartie | soon this will be as concise as it would be with arguments! |
| 15:38 | justin_smith | jcromartie: you could also maybe reverse the order of the code and use ->> instead of comp |
| 15:39 | justin_smith | dunno if that defeats the point of what you are trying to do |
| 15:40 | hyPiRion | jcromartie: and `(comp (partial mapv f))` is just `(partial mapv f)` |
| 15:40 | amalloy | (comp reverse (partial list 26)) could also be written as (partial conj '(26)) |
| 15:40 | jcromartie | well true but I have more in the comp |
| 15:41 | jcromartie | amalloy: yeah, just arrived at that oto |
| 15:41 | jcromartie | too |
| 15:41 | amalloy | that's a better solution than my earlier suggestion of comping rseq and vector |
| 15:41 | jcromartie | same for (partial conj (list [0] cycle)) for the args to (partial apply update-in) |
| 15:41 | jcromartie | now here's a question: is |
| 15:41 | jcromartie | is "let" |
| 15:41 | jcromartie | (excuse me, typing difficulties) |
| 15:42 | jcromartie | is "let" considered valid in point-free style? |
| 15:42 | amalloy | certainly not |
| 15:42 | jcromartie | ok |
| 15:42 | justin_smith | it's not really point free is it? |
| 15:42 | jcromartie | justin_smith: why not? |
| 15:42 | justin_smith | the bindings have names |
| 15:42 | amalloy | a "point" is a named variable |
| 15:42 | bbloom | jcromartie: post a before & after when you're done :-P |
| 15:43 | jcromartie | oh let, no |
| 15:43 | justin_smith | or am I missing what you are saying altogether |
| 15:43 | seangrove | bbloom: From the parent's perspective, layout (for the parent, or for any of its children) is about bounding rect only? |
| 15:44 | seangrove | Whoops, meant to ask essentailly, whether the parent knows the layout of its childrent or is allowed to set the bounding rect of its children |
| 15:45 | bbloom | seangrove: only the runtime does any sort of hierarchical layout. any given layout mechanism should only handle a list of rectangles |
| 15:45 | jcromartie | justin_smith: I thought you were talking about the code as a whole, not just let bindings |
| 15:45 | jcromartie | but point-free programming is not just programming without names |
| 15:45 | jcromartie | it's programming without named arguments to functions |
| 15:45 | jcromartie | you still need to name things |
| 15:46 | jcromartie | I'd like to eliminate the redundant (int \A) |
| 15:47 | derek_c | can you write simple text-substitution macros in Clojure? Like for instance, I want a macro that represents two literal elements 1 and 2, so that I can create a vector with 3 elements like this: [(my-macro) 3]. Is that possible? |
| 15:47 | amalloy | that's what juxt is for, jcromartie. create two different functions that both want to receive (int \A) and juxt em together |
| 15:48 | amalloy | derek_c: no |
| 15:48 | amalloy | you can write `[~@(my-macro) 3] |
| 15:48 | justin_smith | derek_c: for that to work, it would need to be possible to return two things that are not joined by some structure, which just isn't a thing in clojure |
| 15:49 | derek_c | the thing is, I'm working with hiccup templates, and I just can't figure out how to properly compose views |
| 15:49 | derek_c | you guys know how hiccup/html takes an arbitrary number of arguments right |
| 15:50 | jcromartie | I can just (def a-start (int \A)) |
| 15:50 | derek_c | so say all my views start with two certain elements, like |
| 15:50 | amalloy | derek_c: you want the function named: list |
| 15:50 | amalloy | (html (list a b) c) is the same as (html a b c) |
| 15:50 | derek_c | amalloy: oh really? |
| 15:51 | derek_c | amalloy: but that's not a language-level thing right? it's just hiccup looks at the argument and say, ok it's a list, so we do this |
| 15:51 | justin_smith | ,(concat [1 2] [3]) in other contexts, there is concat |
| 15:51 | clojurebot | (1 2 3) |
| 15:51 | amalloy | indeed |
| 15:51 | bbloom | seangrove: does that make sense? |
| 15:51 | arav93 | stuartsierra: Does the construct-calendar private function in clojure.instant take a string as input, I felt it's so by reading through the code, just need to confirm.\ |
| 15:53 | stuartsierra | arav93: Honestly I don't remember anything about clojure.instant. |
| 15:53 | arav93 | Yeah, I'm sorry to have disturbed you. |
| 15:53 | derek_c | is (list 1 2) the exact same thing as '(1 2)? |
| 15:54 | derek_c | amalloy: thanks a lot! |
| 15:54 | amalloy | welllllll, there are a lot of ways to understand that question |
| 15:55 | derek_c | found this: http://stackoverflow.com/questions/3896542/in-lisp-clojure-emacs-lisp-what-is-the-difference-between-list-and-quote |
| 15:55 | amalloy | if they're evaluated, then yes they have the same value. but if they're passed to a macro that inspects them, it will see something different. or if you need something that's not a literal, rather than 1 and 2, then the two forms do different things... |
| 15:55 | justin_smith | ,(do (require 'clojure.instant 'clojure.repl) (clojure.repl/source clojure.instant/construct-calendar)) |
| 15:55 | clojurebot | Source not found\n |
| 15:55 | stuartsierra | `clojure.instant/construct-calendar` just takes integer arguments for each component of the Calendar. |
| 15:55 | stuartsierra | https://github.com/clojure/clojure/blob/201a0dd9701e1a0ee3998431241388eb4a854ebf/src/clj/clojure/instant.clj#L237 |
| 15:55 | justin_smith | as is clear if you look at the source |
| 16:00 | jcromartie | (def papply (partial partial apply)) |
| 16:00 | jcromartie | #ohgodwhy |
| 16:01 | amalloy | jcromartie: that's in useful, named ap |
| 16:02 | amalloy | though i don't think i ever actually used it |
| 16:04 | justin_smith | (def pc (partial conj)) would also make it more succinct |
| 16:04 | justin_smith | I meant partial partial conj of course |
| 16:04 | Rosnec | does anybody know if the ztellman/gloss library has a means of reading encoded data from an input which possibly has extra bytes on the end? |
| 16:05 | jcromartie | oh god oh god oh god |
| 16:05 | jcromartie | how about (comp (partial apply mod) reverse (partial list 26)) |
| 16:05 | jcromartie | oops |
| 16:06 | jcromartie | (def parpar (partial partial partial)) |
| 16:07 | hyPiRion | now just throw in a juxt there and you're set |
| 16:07 | justin_smith | (def parpar (apply partial [(take 2 (repeatedly partial))])) ; easier to generalize |
| 16:09 | justin_smith | (def parpar (apply partial (take 2 (repeat partial)))) ; fixed |
| 16:10 | hyPiRion | justin_smith: (repeat 2 partial) is shorter |
| 16:10 | justin_smith | true! |
| 16:10 | jcromartie | nice |
| 16:11 | mi6x3m-alt | hey who here is using nightcode? |
| 16:11 | mi6x3m-alt | is seems to be a fun IDE |
| 16:11 | mi6x3m-alt | quick start and someone effective for small stuff |
| 16:11 | justin_smith | (defn parⁿ [n] (apply partial (take n (repeat partial)))) |
| 16:11 | jcromartie | beat me to it, justin_smith |
| 16:11 | justin_smith | heh, I even put a nice superscript in the name |
| 16:13 | jcromartie | justin_smith: but you have a named arg! |
| 16:22 | oinksoft | what does &name mean in clojure? |
| 16:23 | oinksoft | like &form and &env in the source on http://clojuredocs.org/clojure_core/clojure.core/defn |
| 16:23 | Bronsa | oinksoft: &name has no special meaning in clojure, it's a regular symbol |
| 16:23 | justin_smith | ,((fn [& name] (concat name name)) 1 2 3 4) |
| 16:23 | clojurebot | (1 2 3 4 1 ...) |
| 16:23 | justin_smith | ,((fn [& name] (concat name name)) 1 2) |
| 16:23 | clojurebot | (1 2 1 2) |
| 16:23 | weavejester | oinksoft: They’re special macro symbols |
| 16:23 | oinksoft | Bronsa: how does defn bind to the name without using a macro? |
| 16:24 | weavejester | oinksoft: http://blog.jayfields.com/2011/02/clojure-and.html |
| 16:24 | Bronsa | oinksoft: &form and &env are implicit arguments on macros |
| 16:24 | Bronsa | oinksoft: thei are bound by the defmacro macro |
| 16:24 | oinksoft | but defn isn't defined as a macro? |
| 16:24 | oinksoft | or am i readin gthis wrong http://clojuredocs.org/clojure_core/clojure.core/defn |
| 16:25 | Bronsa | oinksoft: it is declared as a macro later in the source |
| 16:25 | Bronsa | oinksoft: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L318 |
| 16:26 | weavejester | oinksoft: the clojure.core source code shouldn’t be considered idiomatic Clojure, because it’s bootstrapping the language |
| 16:27 | oinksoft | interesting, thanks Bronsa |
| 16:27 | weavejester | defmacro is defined after defn in the source, so defn is “manually” converted into a macro |
| 16:27 | rasmusto | defmacro is a fn? |
| 16:28 | oinksoft | nope it is bootstrapped the same way as a macro |
| 16:28 | weavejester | rasmusto: internally macros are functions that are tagged as being macros |
| 16:28 | oinksoft | and it calls (list '. (list 'var name) '(setMacro)), which is what is done manually for defn and defmacro |
| 16:29 | rasmusto | oh this thing? (. (var defmacro) (setMacro)) |
| 16:29 | oinksoft | thanks Bronsa and weavejester :) |
| 16:29 | Bronsa | rasmusto: yeah. setMacro simply adds :macro true to the Var's meta |
| 16:29 | weavejester | Yeah. Needless to say, this isn’t what you should use in your own Clojure apps. |
| 16:30 | rasmusto | hah, okay. Thanks for the clarification |
| 16:31 | weavejester | Hm, should I go with “reploaded” or “reloaded.repl” for a library of repl functions based off the reloaded workflow |
| 16:32 | arrdem | the latter |
| 16:32 | weavejester | That was my inclination as well. It gives a nicer namespace |
| 16:32 | arrdem | punny names are awesome but hard to remember and search for :P |
| 16:32 | Frozenlock | reloaded.repl is indeed nicer |
| 16:32 | arrdem | $logs |
| 16:33 | arrdem | right. I'm bot ignored. |
| 16:33 | weavejester | punny names do have the advantage of being unique, though. |
| 16:34 | Frozenlock | It's the wild west here, first one to grab a namespace gets it! |
| 16:35 | arrdem | plz no top level packages |
| 16:35 | arrdem | plz |
| 16:37 | hrathod | https://github.com/john2x/repload |
| 16:37 | Frozenlock | Take a dictionary, loop through it and create a clojars project for each one of them... yes, I can see how my master plan would work. |
| 16:37 | Frozenlock | *evil laugh* |
| 16:37 | weavejester | Frozenlock: I actually got burned by something like that. Had to name a project package “lein-gen” instead of “lein-generate” because in Clojars there’s a “lein-generate” that was written in 2010, and has since been abandoned (deleted repo, deleted github user, etc.) |
| 16:38 | rasmusto | org.clojure.core2 |
| 16:38 | Frozenlock | perhaps a year prefix could be the best of both worlds :-/ |
| 16:40 | Frozenlock | weavejester: and contrary to domain names, this one is forever lost :'-( |
| 16:41 | weavejester | Frozenlock: Yeah. I toyed around with the idea of asking to see if it could be removed, since it was only downloaded 4 times, but that kinda sets a bad precedent. |
| 16:42 | weavejester | I kinda think those people who use their domain names in their package names might have a point… :) |
| 16:44 | arrdem | $seen gtrak |
| 16:44 | lazybot | gtrak was last seen quitting 1 hour and 49 minutes ago. |
| 16:45 | arrdem | weavejester: yeah. my stuff is all me.arrdem/* |
| 16:46 | technomancy | domain names are great for common nouns |
| 16:46 | arrdem | because I know _I_'m a singleton, so my stuff is safely unique :D |
| 16:46 | technomancy | but common nouns are boring |
| 16:46 | technomancy | arrdem: good thing domain registrations are forever, right? |
| 16:47 | arrdem | technomancy: I mean.. my namecoins are registered into the next millennium so... |
| 16:48 | weavejester | stuartsierra: Out of curiousity, is the reason for creating one’s own start/stop/reset functions in user.clj just a question of customisability? |
| 16:48 | stuartsierra | weavejester: yes |
| 16:49 | stuartsierra | You need some way to hook in to application code to call a constructor. |
| 16:49 | stuartsierra | I've been thinking about making a generic version using com.stuartsierra/component. |
| 16:50 | weavejester | stuartsierra: That’s what I was thinking of doing. Not only would it cut down on some boilerplate, but I think it would be better when namespaces fail to load |
| 16:51 | stuartsierra | weavejester: Yes. At least one other person has done this that I know of. |
| 16:51 | weavejester | stuartsierra: i.e. you could still have a “reset” even if your own code failed to load. |
| 16:51 | weavejester | stuartsierra: Oh, do you recall who it was? |
| 16:51 | stuartsierra | weavejester: No, it's buried in the comments on my original blog post on thinkrelevance.com |
| 16:51 | weavejester | stuartsierra: I’ll take a look through it. Thanks for the pointer. |
| 16:51 | stuartsierra | you're welcome |
| 16:53 | weavejester | stuartsierra: Incidentally, have you found yourself needing to use “bridge” components at all? For example, I have a HTTP server component, and a component that handles websocket connections. To connect them I use a bridging component that just creates a handler with some static content, but doesn’t actually have state. |
| 16:54 | stuartsierra | weavejester: All the time. Sometimes I even just have an empty map with some dependency metadata. |
| 16:54 | weavejester | stuartsierra: Oh good. It’s not just me, then! |
| 16:55 | stuartsierra | I'm not sure yet if I like it, design-wise, but it doesn't cause any problems that I can see. |
| 16:56 | weavejester | It feels a little off, design-wise, for me too. But I haven’t been able to come up with anything better that doesn’t add unnecessary complication. |
| 16:58 | weavejester | stuartsierra: I was toying around with the idea of a “::provides” metadata value though |
| 16:58 | weavejester | For components that have a single useful value, like :handler |
| 16:59 | stuartsierra | I justify it (empty components) on the grounds that I am merely reifying a structure that was implicit in the code anyway. |
| 16:59 | weavejester | (component/using (component/bridge make-handler) [:app]) |
| 17:00 | stuartsierra | I have also written components whose main job is to create and cache a value. |
| 17:00 | stuartsierra | I usually provide access to that value through a function. |
| 17:01 | stuartsierra | I hadn't thought about declaring that in the metadata. |
| 17:01 | weavejester | stuartsierra: It sounds like it might be possible to write some functions around common patterns, in the same way system-map exists |
| 17:02 | stuartsierra | Very likely. |
| 17:02 | weavejester | I’ll toy around with the concept and see if I can’t come up with something useful. |
| 17:02 | stuartsierra | I always want to try those things out in apps before codifying them in a shared library. That's how system-map came about. |
| 17:03 | weavejester | stuartsierra: Yeah, same here. My feeling is that you need to be pretty sure a function is going to be useful before including it in a library. |
| 17:04 | weavejester | But I think in all the component-based stuff I’ve done, I wind up with an awful lot of components who are depended upon for a single value. |
| 17:04 | weavejester | e.g. databases for their connections. apps for their handler functions. etc. |
| 17:05 | weavejester | ^{::provides :handler} (new-hander-provider …), ^{{:provides :conn} (new-database …) |
| 17:05 | stuartsierra | Yes, I've seen both types as well: "connection" objects and pre-compiled functions. |
| 17:05 | weavejester | Maybe. I’m not sure :) |
| 17:05 | stuartsierra | What would you do with that metadata? |
| 17:07 | weavejester | stuartsierra: Use it when handling the dependencies, so instead of passing the whole component, we pass the value it wraps. |
| 17:07 | stuartsierra | Oh, I see. |
| 17:07 | stuartsierra | Hmmm. |
| 17:08 | weavejester | {:server (using server [:app]), :app (provides app :handler)} |
| 17:08 | stuartsierra | Not sure about that. Feels like it's exposing internal details. |
| 17:08 | weavejester | stuartsierra: Yeah, I’m not sure either. I got halfway writing up an issue about it, then changed my mind. |
| 17:09 | stuartsierra | Try it out and see how it goes. |
| 17:11 | stuartsierra | I'd much rather have experience reports than issues or patches. |
| 17:14 | weavejester | stuartsierra: We’re thinking along the same lines. I was going to try it out in my next project. |
| 17:14 | stuartsierra | weavejester: cool |
| 17:18 | shiranaihito | https://www.refheap.com/77439 -- how do inner maps get created there? |
| 17:21 | dnolen_ | ,(assoc nil :foo 'bar) |
| 17:21 | clojurebot | {:foo bar} |
| 17:21 | dnolen_ | shiranaihito: ^ |
| 17:21 | bbloom | dnolen_: i was literally typing that |
| 17:21 | noonian | me too lol |
| 17:21 | bbloom | well, :x and 1 |
| 17:21 | noonian | :foo and 17 |
| 17:22 | bbloom | noonian: dnolen_ likes the classics |
| 17:22 | shiranaihito | oh :p |
| 17:22 | noonian | yeah, i like using symbols as values also; i think that's something that people new to clojure don't usually understand off the bat |
| 17:22 | shiranaihito | kinky |
| 17:23 | shiranaihito | that seems like weird behaviour though |
| 17:24 | H4ns | hi. it's the simple things that make me struggle always: how do i get {1 2, 3 4} from [1 2 3 4]? |
| 17:24 | noonian | ,(apply hash-map [1 2 3 4]) |
| 17:24 | clojurebot | {1 2, 3 4} |
| 17:24 | noonian | ,(doc hash-map) |
| 17:24 | clojurebot | "([] [& keyvals]); keyval => key val Returns a new hash map with supplied mappings. If any keys are equal, they are handled as if by repeated uses of assoc." |
| 17:24 | H4ns | noonian: ah, thanks! |
| 17:25 | noonian | np |
| 17:27 | shiranaihito | "(apply hash-map [1 2 3 4])" <-- damn, i actually wrote a helper method for that.. :p |
| 17:28 | dnolen_ | ,(into {} [1 2 3 4]) |
| 17:28 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 17:29 | dnolen_ | oops |
| 17:29 | dnolen_ | ,(into {} [[1 2] [3 4]) |
| 17:29 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )> |
| 17:29 | dnolen_ | ,(into {} [[1 2] [3 4]]) |
| 17:29 | clojurebot | {1 2, 3 4} |
| 17:29 | dnolen_ | erg, anyways, also ^ depending |
| 17:32 | rasmusto | ,(into {} (partition 2 [1 2 3 4])) |
| 17:32 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry> |
| 17:32 | rasmusto | ,(into {} (map vec (partition 2 [1 2 3 4]))) |
| 17:32 | clojurebot | {1 2, 3 4} |
| 17:32 | rasmusto | alternatively ##(into {} (mapv identity (partition 2 [1 2 3 4]))) |
| 17:32 | lazybot | java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry |
| 17:32 | rasmusto | hah, nvm |
| 17:38 | TEttinger | I think the apply hash-map solution is cleanest? |
| 17:39 | tuft | i think apply hash-map fixes the concrete type, while into {} doesn't |
| 17:39 | TEttinger | I don't even know what a concrete type is in this context |
| 17:39 | noonian | with into you have to massage the input vector a bit |
| 17:40 | noonian | hash-map vs array-map or tree-map i guess |
| 17:40 | noonian | but i doubt the OP care's |
| 17:41 | itruslove | Can anyone tell me what the "dev-resources" resource path is intended for? |
| 17:41 | itruslove | https://github.com/technomancy/leiningen/blob/7cc9d6163244fba1f0eedea43396b2a6a04528e9/leiningen-core/src/leiningen/core/project.clj#L424 |
| 17:41 | itruslove | It sounds like it's a default resources directory for dev, but it's defined in the :base profile. |
| 17:46 | vendethiel | Mhhm, isn't `(fn [& [a b]] ())` the same as `(fn [a b] ())` ? |
| 17:46 | vendethiel | Ooh; I guess the first form makes them optional |
| 17:47 | technomancy | itruslove: the purpsoe is the same |
| 17:47 | technomancy | if it were in :dev, user-defined :dev profiles would override it |
| 17:50 | itruslove | technomancy: gotcha, thanks |
| 17:51 | holo | hi |
| 17:53 | holo | I have a dilemma (revisited): to store or not to store generated.js and generated.css in git. the problem is, other collaborators may forget to run build after pull and not understand immediately their problem is they are running some outdated version of .js or .css |
| 17:54 | holo | how are you guys/girls doing this? |
| 17:55 | dbasch | holo: explain the required steps in your README file |
| 17:56 | holo | dbasch, that's what I'm doing. my thinking was: humans are just unreliable |
| 17:57 | rasmusto | how about a makefile? :) |
| 17:57 | rasmusto | eh, probably just a blurb in a readme telling them to rerun everything is good |
| 17:57 | rasmusto | so long as they don't have to do anything manually |
| 17:58 | blake | Style/idiom question: Given data of keyed values {:k1 :v1 :k2 :v2} and a map of new names for keys {:k1 :l1 :k2 :l2} I want an output of {:l1 :v1 :l2 :v3}. I'm using: |
| 17:58 | blake | (zipmap (map val a-map) (map data (map key a-map))) |
| 17:58 | nullptr` | echo 'alert("Hey! You need to run lein something-or-other!");' >> generated.js |
| 17:58 | lazybot | 'alert("Hey! You need to run lein something-or-other!");' >> generated.js |
| 17:59 | blake | ((I get the desired results.) |
| 17:59 | holo | rasmusto, that's the point, rerun already implies manual! or at least I think it does |
| 18:00 | rasmusto | holo: so they're just opening this stuff in a browser (without running any clojure tools)? |
| 18:02 | dbasch | blake: http://clojuredocs.org/clojure_core/1.2.0/clojure.set/rename-keys |
| 18:03 | holo | rasmusto, they (one person only actually) are using lein. yeah ok, maybe I can drop also a msg in :init |
| 18:04 | dbasch | ,(clojure.set/rename-keys {:k1 :v1 :k2 :v2} {:k1 :l1 :k2 :l2}) |
| 18:04 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set> |
| 18:04 | holo | rasmusto, actually :repl-options {:welcome "bla"} |
| 18:04 | rasmusto | holo: cool, that should work well imo |
| 18:04 | holo | we are running the app under lein repl :) |
| 18:05 | holo | rasmusto, thanks for the chat hehe :) |
| 18:08 | blake | dbasch: Thanks! |
| 18:11 | blake | dbasch: rename-keys ... cannot resolve symbol.... I need to include clojure.set? |
| 18:12 | dbasch | blake: yes |
| 18:12 | blake | dbasch, tx |
| 18:22 | justin_smith | vendethiel: also the first form allows providing extra ignored args |
| 18:22 | vendethiel | justin_smith: noted, thanks :) |
| 18:24 | perses | what is the wrong in this code, http://sprunge.us/bEjG , it doesn't work |
| 18:27 | justin_smith | perses: I get a stack overflow, try changing the self call in find-sqrt to recur |
| 18:28 | justin_smith | never mind, that just changes the overflow into a seemingly infinite loop |
| 18:29 | perses | justin_smith: can't i make a recursing in clojure? |
| 18:29 | justin_smith | it is not tail call optimized unless you use recur or trampoline |
| 18:29 | justin_smith | without the optimization, this code is running out of stack |
| 18:29 | justin_smith | because somewhere the guess is not getting improved where it should be |
| 18:30 | perses | i guess it should be a very basic for a fp to use recursing in this way |
| 18:31 | justin_smith | you guess wrong, or maybe clojure isn't fp |
| 18:32 | justin_smith | or maybe it is easy but we don't do it anyway |
| 18:32 | perses | maybe i'm wrong about clojure |
| 18:32 | perses | justin_smith: recur don't terminate |
| 18:32 | justin_smith | right, like I said, I added a print statement, and your code keeps guessing 2.0 but not accepting that guess |
| 18:32 | Bronsa | perses: your good-enough? function is wrong |
| 18:33 | amalloy | perses: you may want an absolute-value in good-enough |
| 18:33 | amalloy | oh, and it should read (* guess guess), not (* guess n) |
| 18:33 | amalloy | maybe? i dunno. i'm bad at this. i resign |
| 18:34 | Bronsa | perses: http://sprunge.us/SMec?clj |
| 18:40 | justin_smith | (defn good-enough? [n guess] (<= (Math/abs (- n (square guess))) 0.1)) |
| 18:40 | justin_smith | that def fixes the code |
| 18:41 | justin_smith | also, a good trick when something is recursing infinitely is add a println of the args and a (Thread/sleep 1000) to the top of the thing |
| 18:41 | justin_smith | that often helps expose the problem |
| 18:49 | technomancy | $seen brehaut |
| 18:49 | lazybot | brehaut was last seen quitting 2 weeks ago. |
| 19:02 | Frozenlock | Does lein select JRE by default? |
| 19:03 | justin_smith | it should use your default java |
| 19:03 | justin_smith | I don't think the question of whether it is jre / jdk would come into play normally |
| 19:03 | koreth_ | Is there an equivalent of mapcat that returns a set rather than a list? Obviously (apply hash-set (map f coll)) works, but if there are a lot of duplicate values that'll waste memory building the intermediate list. |
| 19:03 | Frozenlock | justin_smith: Ah I see, so it's my fault :) |
| 19:04 | Frozenlock | Yeah, but I want to use the jvisualvm |
| 19:04 | koreth_ | Or maybe I should be using reduce rather than map. |
| 19:04 | justin_smith | Frozenlock: ahh, so you need the dt-socket to be open - but that should work across jvm versions anyway |
| 19:05 | Frozenlock | justin_smith: I don't know... when I ran jvisualvm it just said that I needed to run the JDK, not the JRE |
| 19:05 | justin_smith | koreth_: yeah, or use into #{} - that shouldn't hold onto the head |
| 19:05 | justin_smith | Frozenlock: oh, ok then |
| 19:06 | justin_smith | ,(into #{} (map inc (range 10))) |
| 19:06 | clojurebot | #{7 1 4 6 3 ...} |
| 19:06 | rasmusto | ##(into #{} (map inc (range 10))) |
| 19:06 | lazybot | ⇒ #{1 2 3 4 5 6 7 8 9 10} |
| 19:06 | rasmusto | just checking hashing order, don't mind me |
| 19:06 | justin_smith | versions! |
| 19:07 | amalloy | rasmusto: /msg the bots, if you don't have a reason for everyone to read what you're writing |
| 19:07 | justin_smith | ,*clojure-version* ##*clojure-version* |
| 19:07 | clojurebot | {:major 1, :minor 6, :incremental 0, :qualifier nil} |
| 19:08 | justin_smith | I guess lazybot has some anti-quine magic |
| 19:09 | hyPiRion | justin_smith: yeah, sorry about that |
| 19:09 | justin_smith | :) |
| 19:09 | amalloy | justin_smith: really it's a quirk of how ## parses - he reads the string that comes after ##, and if it's not a collection (usually a list, of course), he assumes you are talking about an irc channel like ##java or something |
| 19:09 | justin_smith | oh, OK |
| 19:09 | justin_smith | ,*clojure-version* ##(do *clojure-version*) |
| 19:09 | clojurebot | {:major 1, :minor 6, :incremental 0, :qualifier nil} |
| 19:09 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 19:09 | amalloy | lazybot giving an error message after every mention of ##java gets old fast |
| 19:09 | justin_smith | right |
| 19:10 | rasmusto | "##java gets old fast" -amalloy |
| 19:10 | rasmusto | :) |
| 19:11 | dbasch | koreth_: you could do (distinct (map …)), distinct is lazy |
| 19:11 | justin_smith | (inc dbasch) |
| 19:11 | lazybot | ⇒ 1 |
| 19:11 | justin_smith | great idea |
| 19:13 | hyPiRion | rasmusto: keep in mind that the order is incidental |
| 19:14 | seangrove | bbloom: In :fixed vs :canvas (absolute), is the fixed positioning still relative to the parent or to the root view of the UI? I would expect the former. Luckily, CSS does the latter. |
| 19:15 | hyPiRion | ,(apply = (map (comp seq set) [(range -10 11) (range 10 -11 -1)])) |
| 19:15 | clojurebot | true |
| 19:15 | seangrove | s/luckily/irritatingly |
| 19:15 | rasmusto | hyPiRion: ah, I knew that. Was just curious of how the new hash algo ordered integers |
| 19:15 | hyPiRion | alright |
| 19:16 | bbloom | seangrove: i don't recall |
| 19:16 | justin_smith | ##(apply = (map (comp seq set) [(range -10 11) (range 10 -11 -1)])) |
| 19:16 | lazybot | ⇒ false |
| 19:16 | hyPiRion | Hrm, didn't know there were hashing changes from 1.4.0 to 1.5.0 |
| 19:16 | justin_smith | not that any of us should be using 1.4 at this point |
| 19:16 | justin_smith | 1.6.0 |
| 19:16 | amalloy | hyPiRion: there were some in 1.6, not 1.5 |
| 19:17 | amalloy | afaik there weren't in 1.5, anyway |
| 19:17 | hyPiRion | amalloy: (apply = (mapv (comp seq set) [(range -10 11) (range 10 -11 -1)])) returns false on 1.5.1 |
| 19:17 | amalloy | okay, and also in 1.4. so, both of those are different from 1.6, which supports my claim? |
| 19:18 | hyPiRion | oh, I mixed clojurebot and lazybot versions |
| 19:24 | Frozenlock | uh... what is this... I just changed my path, only to realize that the java in the /bin folder is a link to the JRE bin o_O |
| 19:24 | Frozenlock | (trying to get the JDK) |
| 19:25 | justin_smith | you can just replace the symlink to the JRE with a symlink to the JDK, no? |
| 19:25 | hyPiRion | Frozenlock: which OS are you using? |
| 19:25 | Frozenlock | that's the thing, where I was expecting the JDK java, I found a link to the JRE binary |
| 19:25 | Frozenlock | Ubuntu |
| 19:25 | justin_smith | on a debian based system you would use update-alternatives, and it would bea symlink to a symlink |
| 19:25 | justin_smith | Frozenlock: use update-alternatives |
| 19:26 | hyPiRion | Frozenlock: `sudo update-alternatives --config java` |
| 19:26 | justin_smith | https://help.ubuntu.com/community/Java |
| 19:26 | justin_smith | above link also covers manually installed java, so you can make sure it is visible to the alternatives system |
| 19:26 | amalloy | update-alternatives mystifies me. i don't know when i'm supposed to use it or how |
| 19:26 | Frozenlock | hyPiRion: That's what I used first, but I only saw JRE choices |
| 19:27 | hyPiRion | Frozenlock: did you install through apt-get/aptitude? |
| 19:27 | Frozenlock | I honestly don't remember. I might just reinstall everything |
| 19:28 | amalloy | Frozenlock: bathe your computer in acid to make sure the reinstall is complete |
| 19:28 | justin_smith | amalloy: picking defaults - it is done using a system of symlinks; you can manually replace the symlink with one pointing to a different target file, or use their weird semi-interactive CLI |
| 19:28 | Frozenlock | https://www.refheap.com/77448 <---- only JRE choices o_O |
| 19:28 | justin_smith | Frozenlock: you will know it was not installed via apt if it is not presented as an available alternative, my link above shows how to make it one |
| 19:29 | justin_smith | Frozenlock: OK, so use the instructions on my link above under "Oracle Java 7" |
| 19:29 | justin_smith | or just fuck it and replace /usr/bin/java with the symlink or binary of your choice |
| 19:29 | amalloy | Frozenlock: that's fine. my java bin lives in /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java |
| 19:30 | hyPiRion | Frozenlock: yeah, that's the JDK version. Try out `java -version` and see for yourself |
| 19:30 | Frozenlock | OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.12.04.2) |
| 19:30 | Frozenlock | OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode) |
| 19:30 | Frozenlock | |
| 19:30 | Frozenlock | arggg |
| 19:31 | rasmusto | kill -9gauge |
| 19:31 | justin_smith | Frozenlock: just tell the alternatives system that the jdk is the right default |
| 19:31 | justin_smith | hah |
| 19:31 | justin_smith | sometimes I miss xblast |
| 19:32 | seancorfield | (inc rasmusto) |
| 19:32 | lazybot | ⇒ 8 |
| 19:32 | seancorfield | That made me laugh out loud! |
| 19:32 | rasmusto | glad I could help :) |
| 19:33 | technomancy | update-alternatives is like if you took rvm and made it not suck and work for anything |
| 19:36 | Frozenlock | does JDK use a different name than java? (like I said, 'java' in the JDK is a link to the JRE java) |
| 19:38 | amalloy | i'm pretty sure the thing in .../jdk/jre/bin/java is what you want to use |
| 19:39 | justin_smith | Frozenlock: wait, the one inside the jdk folder is a symlink to the jre one? |
| 19:39 | Frozenlock | amalloy: I always used it without any problems. But I want to try jvisualvm and it insists on telling me that I'm using the JRE instead of the JDK. |
| 19:39 | Frozenlock | justin_smith: looks like it |
| 19:40 | amalloy | Frozenlock: no, that's just how the jdk is distributed |
| 19:40 | amalloy | mine looks that way too |
| 19:40 | amalloy | when you download a jdk, it comes with a jre |
| 19:40 | amalloy | and that's the same java |
| 19:40 | amalloy | it's not like it has a different java executable based on whether you want to pretend you're not using a jdk |
| 19:43 | justin_smith | Frozenlock: it could be the jvisualvm is reporting the wrong error, and you are calling a jvisualvm that is incompatible with the specific jvm? |
| 19:44 | Frozenlock | maybe |
| 19:44 | Frozenlock | I'm looking for vjisualvm similar problems |
| 19:44 | justin_smith | there should be a version of visualvm inside the jdk file heirarchy - maybe that is not the same one you are invoking? |
| 19:47 | Frozenlock | eh, it works if I launch with --jdkhome <my-JDK-path>. GOOD ENOUGH |
| 19:47 | blake | If I want "(defn my-func [parm1 parm2 parm3=nil] ..." such that parm3 is either passed in by the user or is nil, do I have to do a multi-arity setup? |
| 19:48 | amalloy | blake: you want to support multiple arities (2 or 3), so... |
| 19:49 | justin_smith | it is doable with (fn [parm1 parm2 & [parm3]] ...) which is also multi-arity, but in a different way |
| 19:49 | blake | amalloy: Just checkin'. It's not like there's only way to do stuff. |
| 19:49 | blake | justin_smith: Yeah, but doesn't that have other implications? |
| 19:49 | justin_smith | also means it will take and ignore any further arguments |
| 19:50 | blake | ...because the remainder of the arguments are passed in a vector and I'm only taking the first element of any vector? |
| 19:50 | justin_smith | but is more concise than the explicit (fn ([p1 p2] ... ) ([p1 p2 p3] ...)) version |
| 19:50 | justin_smith | blake: exactly |
| 19:51 | blake | justin_smith: That makes me nervous because I'm still getting parens wrong enough to where the arity check probably helps me from tearing my hair out (as if I had hair). |
| 19:52 | blake | I guess it seems goofy to have a fn[parm1 parm2 parm3] followed by fn[parm1 parm2]=>(fn parm1 parm2 nil). |
| 19:52 | justin_smith | fair enough, then use the more verbose, more strict version |
| 19:53 | justin_smith | or add an explicit check (fn [a b c & [d :as rest]] (assert (< (count rest) 2))) but that seems a little silly |
| 19:53 | blake | Heh. Yeah. |
| 19:53 | amalloy | justin_smith: btw, you should really avoid doing comparisons on the result of count. you never know when infinite sequences will crop up |
| 19:54 | blake | ooh |
| 19:54 | amalloy | (< (count x) 2) => (not (next x)) |
| 19:54 | justin_smith | amalloy: even in a rest arg ? I guess if someone called apply on something infinite? |
| 19:54 | amalloy | for sure |
| 19:55 | amalloy | you can (apply f (range)), no problem |
| 19:55 | justin_smith | oh, of course |
| 20:21 | coventry | blake: If you're getting parens wrong a lot of the time, it's probably worth taking half and hour or so to learn paredit mode, or whatever the equivalent is in your browser. |
| 20:21 | amalloy | coventry: such a badass he turns paredit on in his browser |
| 20:21 | coventry | s/browser/editor/. :-) Thanks. |
| 20:25 | dbasch | coventry: I’d say it’s worth it regardless. Nobody should be spending cognitive power balancing expressions. |
| 20:27 | coventry | Anyway, kovasb's session has paredit https://github.com/kovasb/session#paredit |
| 20:35 | dsrx | coventry: holy cow that is really cool. stepped away from clj/cljs for a few weeks and this comes out O_O |
| 20:42 | bbloom | coventry: i enjoy the namespace name for his paredit functionality |
| 20:42 | bbloom | it's in subpar/core.cljs :-) |
| 20:45 | coventry | Heh. |
| 20:46 | bbloom | $mail kovasb Hey man, you're paredit functionality is really *ahem* subpar. |
| 20:46 | lazybot | Message saved. |
| 20:46 | bbloom | d'oh i suck at spelling |
| 20:47 | amalloy | bbloom: you can $unmail kovasb, if you don't want him to know your a bad speller |
| 20:47 | bbloom | $unmail kovasb |
| 20:47 | lazybot | Deleted unread messages from bbloom to kovasb |
| 20:47 | bbloom | $mail kovasb Hey man, your paredit functionality is really *ahem* subpar. |
| 20:47 | lazybot | Message saved. |
| 20:48 | bbloom | amalloy: spared me having to write a bad follow up self-deprecating joke |
| 20:48 | amalloy | bbloom: i just wanted an excuse to use the wrong your in my response |
| 20:48 | bbloom | amalloy: haha i didn't even notice |
| 20:49 | bbloom | amalloy: this is my biggest debugging weakness. i'm so used to reading/writing error-filled nonsense on the internet... my eyeballs have built in auto correct |
| 21:11 | eraserhd | Anyone want to converse to try and find an elegant solution to a monad-like kind of problem? |
| 21:12 | eraserhd | The problem is this: I want to find a way to thread functions that deal with two values. 1st is the "state", which should thread much like -> threads through composable functions. |
| 21:13 | eraserhd | But the second is a list of "effects", which I want to hide most of the time. |
| 21:19 | weavejester | eraserhd: A list of effects? Effects on the state, or something else? |
| 21:20 | eraserhd | Effects are tokens that represent side-effectful things to be performed. |
| 21:21 | eraserhd | Examples: [:beep], [:write-file "/tmp/foo.txt" "hello"], ... |
| 21:21 | eraserhd | The idea is to make a composable way to collect these. |
| 21:22 | weavejester | That’s an interesting problem, and as you point out, very close to the state monad. |
| 21:26 | weavejester | eraserhd: I don’t have an immediate answer for you, unless you want to try one of the monad libraries |
| 21:40 | zspencer | is there something similar to apply but doesn't take a collection? |
| 21:41 | zspencer | I've got a map of keywords to functions and I want to execute the returned function inside of a threading operator |
| 21:41 | zspencer | (making an example) |
| 21:42 | eraserhd | zspencer: apply, but make the last argument [] |
| 21:43 | eraserhd | Oh, you can't just ((:foo map)) in the threading operator? |
| 21:44 | zspencer | https://gist.github.com/zspencer/4d378e1d1d833041ccd5 |
| 21:44 | zspencer | yeah, the last argument right now is a vector :( |
| 21:44 | zspencer | The larger context: https://github.com/zspencer/clj-warrior/blob/master/src/play.clj |
| 21:44 | zspencer | also, hi jason :) |
| 21:45 | alew | you could define (defn invoke [f & args] (apply f args)) |
| 21:45 | zspencer | ALL MY FRIENDS ARE IN THE CLOJRUE CHANNEL |
| 21:45 | eraserhd | zspencer: We've been here for years. Glad you gave up ruby. |
| 21:45 | zspencer | alew: that's a reasonable thing; I just figured clojure would have something built in |
| 21:46 | zspencer | i.e in javascript func.call(context, foo, bar) vs func.apply(context, [foo, bar]) |
| 21:46 | eraserhd | The form you're looking for is really just (func foo bar) in clojure, it's the threading macro that's screwing you up. |
| 21:47 | eraserhd | IMHO |
| 21:47 | zspencer | Yea, I switched to the threading operator beacause it seemed clearer |
| 21:48 | zspencer | but maybe I should consider composition for the steps |
| 21:48 | zspencer | i.e. "take the players turn, then the ais turn" |
| 21:48 | zspencer | All my code is bad and I feel bad |
| 22:00 | eraserhd | zspencer :/ |
| 22:08 | hlprmnky | zspencer: the best piece of advice I’ve gotten so far about the threading operator is this, from a code review I was fortunate enough to have Hugo Duncan do of some bad code I’d written - he said, and I paraphrase: What I usually do is get everything working the way I want first, and then go through and look to add threading in a second pass, to make things concise |
| 22:22 | TravisD | Does anyone know of any libraries that allow you to manage your own random number generator, etc? |
| 22:23 | zspencer | hlprmnky: that's a reasonable thing. |
| 22:37 | bob2 | TravisD, as in with a specific seed? http://docs.oracle.com/javase/7/docs/api/java/util/Random.html |
| 22:38 | TravisD | bob2: Ah, yeah, I keep forgetting that all of java is available |
| 22:43 | TravisD | I was also hoping to have some choice of the method used |
| 22:44 | TravisD | and for some snazzy clojure interface :) |
| 22:44 | zspencer | hlprmnky / eraserhd here's what I wound up with: https://github.com/zspencer/clj-warrior/blob/master/src/play.clj#L60 |
| 22:56 | coventry | Is there any test.check code out there already for producing a lot of random deeply nested structures. Ideally with lots of structural sharing, but I can probably add that in myself. |
| 23:25 | owl-v- | how do i add v elements to vv one by one? (let [v [1 2 3]] (let [vv []] (map #(conj vv %) v))) |
| 23:26 | amalloy | owl-v-: you can't do that with map, because clojure data structures are immutable. instead, you would use reduce, something that builds up a single result from multiple input items |
| 23:27 | amalloy | or in the specific case of conj, you can just use into: (into [] v) yields a vector containing all the items in v |
| 23:30 | bodie_ | hi all, not sure if I'm doing something stupid or what -- do I need to be mindful of using hyphens in namespaces / in paths in my project tree with lein? |
| 23:30 | bodie_ | I keep getting a not found error |
| 23:31 | koreth_ | What's the best way to do the equivalent of "rest" on a sorted set without losing the sortedness? (rest (sorted-set 0 1 2)) returns a plain old sequence. |
| 23:31 | koreth_ | ,(rest (sorted-set 0 1 2)) |
| 23:31 | amalloy | yes. namespaces want -, and the path needs _ instead |
| 23:31 | clojurebot | (1 2) |
| 23:31 | koreth_ | ,(sorted-set 1 2) |
| 23:31 | clojurebot | #{1 2} |
| 23:31 | amalloy | disj |
| 23:32 | koreth_ | Thanks |
| 23:32 | bodie_ | http://paste.ubuntu.com/7280810/ |
| 23:32 | bodie_ | I see |
| 23:32 | bodie_ | so, use _ in the path? |
| 23:49 | amalloy | yes, bodie_ |