2015-01-26
| 00:00 | tomjack | one extension point I discovered: (defmethod core.match/emit-pattern-for-syntax [:foo :default] ...) |
| 00:01 | tomjack | then (match x (:foo y) :ok) |
| 00:04 | tomvolek | HI guys, I am trying to execute some sample syntax in Repl like : (difference #{1 2 } #{2 3}) I get error message "CompilerException java.lang.RuntimeException: Unable to resolve symbol: difference in this context," I thouth difference is in the core which gets loaded by Repl . |
| 00:04 | justin_smith | tomjack: clojure.set/difference |
| 00:04 | justin_smith | here's how you can find it ##(apropos "difference") |
| 00:04 | lazybot | ⇒ (difference) |
| 00:05 | justin_smith | erg... it behaves better in newer versions, heh |
| 00:05 | justin_smith | (actually shows the full ns) |
| 00:05 | tomvolek | thanks |
| 00:07 | justin_smith | yeah, with 1.7.0-alpha4 I see the whole ns with apropos |
| 00:07 | justin_smith | &*clojure-version* |
| 00:07 | lazybot | ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"} |
| 00:08 | justin_smith | ,*clojure-version* |
| 00:08 | clojurebot | {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"} |
| 00:17 | brainacid | I have installed lein, LightTable and jvm and looking through The Joy of Clojure |
| 00:17 | brainacid | ~book |
| 00:17 | clojurebot | book is books |
| 00:17 | brainacid | ~book |
| 00:17 | clojurebot | book is http://www.pragprog.com/titles/shcloj/programming-clojure |
| 00:19 | brainacid | ~book |
| 00:19 | clojurebot | book is http://www.pragprog.com/titles/shcloj/programming-clojure |
| 01:18 | jinagarano | i want t build an h2 database to use with korma. i set up a migration file for ragtime that builds the tables "students," "teachers," "guests," "contact-details," "emergency-contacts," and "address." how do i define the relationship between them? eg students should have an address, contact details, and an emergency contact; emergency contacts should have only contact details; and teachers will have an address and contact details, bu |
| 01:19 | EvanR | adios |
| 01:19 | justin_smith | jinagarano: the end of your question was cut off, because the question was too long |
| 01:19 | jinagarano | justin_smith: where did it cut off? |
| 01:19 | justin_smith | ; and teachers will have an address and contact details, bu |
| 01:20 | jinagarano | but no emergency contacts. |
| 01:22 | justin_smith | jinagarano: the typical approach is to have a unique ID column on each table, and then and have fields in other tables with content that points to those ids, and use the id field for a join on the tables in your query |
| 01:26 | jinagarano | justin_smith: if i understand you right, I create tables in SQL and nothing more; i create table entities in korma to match, and don't use "belongs-to" or "has-many" right? i create all linking in the functions that query my db. |
| 01:27 | justin_smith | jinagarano: I believe so, with h2 at least |
| 01:27 | justin_smith | maybe korma has something higher level that you want to use though |
| 01:29 | justin_smith | jinagarano: for many to many you would actually want a separate table, with an a_id column and a b_id column to create each of the cross table relations |
| 01:29 | justin_smith | since having one refering id on each would not suffice, of course |
| 01:30 | jinagarano | from korma docs: |
| 01:30 | jinagarano | ;; Relationships |
| 01:30 | jinagarano | (has-one address) |
| 01:30 | jinagarano | ;; assumes users.id = address.users_id |
| 01:30 | jinagarano | (has-many email) |
| 01:30 | jinagarano | ;; assumes users.id = email.users_id |
| 01:30 | jinagarano | ;; but gets the results in a second query |
| 01:30 | jinagarano | ;; for each element (belongs-to account) |
| 01:30 | jinagarano | ;; assumes users.account_id = account.id |
| 01:30 | jinagarano | (many-to-many posts :users_posts)) |
| 01:30 | jinagarano | ;; assumes a table users_posts with columns users_id |
| 01:30 | jinagarano | ;; and posts_id |
| 01:30 | jinagarano | ;; like has-many, also gets the results in a second |
| 01:30 | jinagarano | ;; query for each element |
| 01:30 | justin_smith | jinagarano: do not do that |
| 01:30 | justin_smith | use a paste site like refheap.com, or provide a link to the source on github |
| 01:30 | justin_smith | please |
| 01:31 | jinagarano | ok sure, sorry |
| 01:31 | jinagarano | i think i know how to do it now, thanks |
| 01:31 | justin_smith | jinagarano: yeah, I didn't see you mention korma at first, and I am not as familiar with that, but if you are using korma it looks like those are the functions you would want |
| 01:31 | justin_smith | cool |
| 01:32 | justin_smith | jinagarano: but do notice that those are query functions - they assume those tables / fields I mentioned above exist already |
| 01:32 | justin_smith | but yeah, you should have a clear idea of how to make those columns / tables now |
| 01:49 | jinagarano | how do i set up ragtime and h2 for migrating? |
| 01:52 | justin_smith | if you are using clojure.java.jdbc, it shouldn't be different from using any other db backend I don't think |
| 01:53 | justin_smith | https://github.com/weavejester/ragtime/wiki/Getting-Started just use the apropriate jdbc url |
| 02:03 | drorbemet | Hi, do you know how to create a new namespace together with a new file and folders in a single command in emacs in a clojure project? |
| 02:06 | justin_smith | drorbemet: specify the full path that reflects the namespace you want to create (even if some subdirectories don't exist), then M-x make-directory and the default option if you hit return is to create all the parent directories for that file |
| 02:07 | justin_smith | drorbemet: when I say "specify the full path", do it as a file open, it will create a new file if the file you attempt to open does not exist |
| 02:09 | drorbemet | justin_smith: ok, that's the first step, but I didn't find a "create new namespace" command, I just want to make shure that I don't miss somthing before I write an elisp function or a yasnippet |
| 02:12 | justin_smith | drorbemet: there is a function to insert an ns declaration |
| 02:12 | justin_smith | and that is automatic based on the file name |
| 02:13 | drorbemet | justin_smith: oh, there is?! great |
| 02:22 | drorbemet | justin_smith: cljr-refactor contains an example, cljr-move-form is what I was looking for, thanks |
| 03:06 | zacts | hum.. I'm looking for a book that teaches functional programming really well, and in a down to earth way, that I could apply directly to clojure |
| 03:07 | SagiCZ1 | zacts: little schemer perhaps? |
| 03:07 | zacts | hum.. yeah I own that book, but I'm thinking something more textbook style, yet still down to earth |
| 03:07 | SagiCZ1 | down to earth as in easy to understand? |
| 03:07 | zacts | yeah |
| 03:07 | zacts | perhaps not quite so academic as SICP |
| 03:07 | SagiCZ1 | i liked this one http://shop.oreilly.com/product/0636920013754.do |
| 03:07 | codestorm777 | functional thinking, maybe |
| 03:07 | zacts | I hope to get through SICP, but that might take months to digest |
| 03:08 | zacts | codestorm777: is that a book? |
| 03:08 | zacts | SagiCZ1: oh cool, yeah I plan to read that too |
| 03:08 | codestorm777 | yes, o’reilyy, it’s also a video series |
| 03:08 | zacts | oh neat. I'll check it out |
| 03:09 | SagiCZ1 | the oreily book has some thoughts about how to make your programs more abstract shown on examples |
| 03:10 | zacts | oh cool |
| 03:13 | zacts | hm.. I can't wait until the grokking functional programming by manning press is out |
| 03:13 | zacts | that's kind of what I'm looking for |
| 03:13 | zacts | exactly too |
| 03:13 | clojurebot | I don't understand. |
| 03:16 | ro_st | any logback pros in the room? i need to log a specific set of namespaces to a different output file without it going to the file that the rest of the namespaces go to |
| 03:43 | acron^ | morning |
| 03:43 | acron^ | new clojurist here; if anyone's got the time, i'd appreciate some feedback on style and form - https://github.com/acron0/fae-scraper/blob/master/src/fae_scraper/core.clj |
| 03:43 | slipset | depends on your timezone, I guess |
| 03:44 | SagiCZ1 | acron^: i also have morning.. good morning |
| 03:44 | acron^ | :) |
| 03:44 | acron^ | good [morning|afternoon|evening] then...just in case |
| 03:44 | SagiCZ1 | acron^: maybe move to comments into the fn? you know if you add string after the arg list it is a regular doc |
| 03:45 | SagiCZ1 | (doc take) |
| 03:45 | clojurebot | "([n] [n coll]); Returns a lazy sequence of the first n items in coll, or all items if there are fewer than n. Returns a stateful transducer when no collection is provided." |
| 03:45 | SagiCZ1 | like this |
| 03:45 | acron^ | ahh |
| 03:45 | acron^ | (defn foo [x] |
| 03:45 | acron^ | "comments here" |
| 03:45 | slipset | lines 19 and 26, pull out in functions? |
| 03:46 | SagiCZ1 | ,(defn foo [x] "comments" x) |
| 03:46 | clojurebot | #'sandbox/foo |
| 03:46 | acron^ | got it |
| 03:46 | SagiCZ1 | also consider putting the arg list on a new line if it is longer.. depends on your taste though |
| 03:46 | acron^ | slipset: you mean separate it more? |
| 03:47 | slipset | also, I'm not to enthused about prefixing functions as in "fae", but YMMV |
| 03:47 | acron^ | is there a convention? |
| 03:47 | slipset | acron^:yes especially the anon-function in line 26. Imagine you wanted to test that... |
| 03:47 | acron^ | i guess all the funcs are namespaced so no need for a prefix > |
| 03:48 | Glenjamin | isn't it docstring before arglist? i always get mixed up :s |
| 03:48 | slipset | acron^: I kind of like writing functions so that I can do the following: |
| 03:48 | SagiCZ1 | Glenjamin: docs after arglist |
| 03:48 | Glenjamin | ,(doc foo) |
| 03:48 | clojurebot | "([x]); " |
| 03:48 | acron^ | whats the 'feel' on anon functions? good? bad? |
| 03:48 | SagiCZ1 | slipset: i wouldnt extract that.. if it is the only place where he uses it.. he could test the whole function |
| 03:48 | slipset | ,(map (partial + 1) [1 2 3]) |
| 03:48 | clojurebot | (2 3 4) |
| 03:48 | SagiCZ1 | acron^: they are perfectly idiomatic |
| 03:48 | Glenjamin | ,(defn foo "comments" [x] x) |
| 03:48 | clojurebot | #'sandbox/foo |
| 03:48 | Glenjamin | ,(doc foo) |
| 03:48 | clojurebot | "([x]); comments" |
| 03:48 | Glenjamin | it's docstring before arglist. |
| 03:49 | acron^ | :o |
| 03:49 | SagiCZ1 | Glenjamin: indeed.. my bad |
| 03:49 | acron^ | ,(defn bar [x] "test" x) |
| 03:49 | slipset | SagiCZ1:I would, since then I could give the funciton a name, which kind-of documented what it did. |
| 03:49 | clojurebot | #'sandbox/bar |
| 03:49 | acron^ | ,(doc bar) |
| 03:49 | clojurebot | "([x]); " |
| 03:50 | SagiCZ1 | slipset: i absolutely hate extracting something just to give it a name.. it fractures the code.. but i understand it is a matter of opinon.. |
| 03:50 | slipset | That way I didn't have to try to figure out what (assoc |
| 03:50 | slipset | (:attrs %) |
| 03:50 | slipset | :desc (:alt (:attrs (first (:content %))))) was trying to achieve |
| 03:50 | SagiCZ1 | slipset: in this case it would help i guess |
| 03:51 | slipset | :) |
| 03:51 | acron^ | on line 43, I have a dissoc and and assoc |
| 03:51 | acron^ | is there a better way to reformat a dict? |
| 03:51 | SagiCZ1 | acron^: yeah i dont like that line very much.. try to keep the line shorter |
| 03:51 | slipset | acron^: in line 43 you deffo want a ~doseq |
| 03:52 | slipset | ~do-seq |
| 03:52 | clojurebot | It's greek to me. |
| 03:52 | hellofunk | if you have trouble remembering if comments come before or after arglists, just remember how multi-arity fns are structured. it's one comment for the function, regardless of the number of arity implementations. |
| 03:52 | SagiCZ1 | ~doseq |
| 03:52 | slipset | ~doseq |
| 03:52 | clojurebot | doseq is like for, but for side effects instead of values |
| 03:52 | clojurebot | doseq is like for, but for side effects instead of values |
| 03:52 | slipset | Thanks SagiCZ1, |
| 03:52 | acron^ | hmm] |
| 03:52 | SagiCZ1 | hellofunk: yeah actually i would prefer if i could comment each arity separately.. |
| 03:52 | slipset | anyways, the println in 43 will not print the whole thing since map is lazy |
| 03:53 | SagiCZ1 | slipset: print forces the evaluation |
| 03:53 | acron^ | not sure I understand do-seq but I'll have a play |
| 03:53 | hellofunk | SagiCZ1: no, because the idea is that the function as a whole is a single function -- which it is, so it should have a single unified purpose. therefore, one comment for the function. |
| 03:53 | SagiCZ1 | ,(println (map inc (range 99))) |
| 03:53 | clojurebot | (1 2 3 4 5 ...)\n |
| 03:54 | SagiCZ1 | hellofunk: yeah but then i have to specify all the arities in the one docstring |
| 03:54 | hellofunk | acron^: doseq is just like for. the only difference is that for generates a lazy seq while doseq makes side effects like printing, etc. if you understand for, you understand doseq. study for first. |
| 03:54 | hellofunk | SagiCZ1: of course but then when an editor gives docstring hints, it doesn't have to know in advance which version of the fn you will use to tell you how the fn works. |
| 03:55 | slipset | and SagiCZ1 is of course totally correct wrt println, my bad |
| 03:55 | SagiCZ1 | hellofunk: makes sense.. okay |
| 03:56 | hellofunk | also key thing to note is that doseq always returns nil. so right there you know it's not designed for generating a sequence but rather doing something off in the world instead. |
| 03:56 | acron^ | ahhh |
| 03:56 | acron^ | i get it |
| 03:57 | acron^ | :) |
| 03:57 | slipset | in fae-get-image-from-image-page |
| 03:57 | slipset | could you just continue your threading? |
| 03:57 | clojurebot | Excuse me? |
| 03:57 | SagiCZ1 | acron^: your map achieves the same thing as doseq but doseq clearly states your intention to not collect the result into a collection |
| 04:01 | jinagarano | i'm trying to build an h2 db and use it via korma. when i compile, i get an error "unable to resolve symbol defentity." why? i added korma as a dependency in project.clj and put (use 'korma.db) in the source file. |
| 04:04 | acron^ | slipset: can you expand on that? |
| 04:06 | slipset | (s/id "content-image")) |
| 04:06 | slipset | page) |
| 04:06 | slipset | (first) |
| 04:06 | slipset | :attrs |
| 04:06 | slipset | :data-src) |
| 04:08 | slipset | also, in line 15, you could use def and comp, I guess, instead of defining your own function. |
| 04:09 | TEttinger | slipset: defn has the advantage of being able to add a docstring |
| 04:09 | TEttinger | not sure if you can do that with comp |
| 04:10 | slipset | (def fae-get-list-page (comp get-page-as-hickory format)) |
| 04:11 | slipset | or is it the other way around, I can never remember |
| 04:12 | slipset | ~def |
| 04:12 | clojurebot | excusez-moi |
| 04:13 | TEttinger | ,(doc def) |
| 04:13 | clojurebot | Titim gan éirí ort. |
| 04:13 | slipset | ,(def ted-nugent "The nuge rocks" 123) |
| 04:13 | clojurebot | #'sandbox/ted-nugent |
| 04:13 | TEttinger | (doc def) |
| 04:13 | clojurebot | Cool story bro. |
| 04:13 | TEttinger | ha |
| 04:13 | TEttinger | ,ted-nugent |
| 04:13 | clojurebot | 123 |
| 04:13 | TEttinger | ,(doc ted-nugent) |
| 04:13 | clojurebot | "; The nuge rocks" |
| 04:13 | TEttinger | nice |
| 04:14 | acron^ | ,(doc comp) |
| 04:14 | clojurebot | "([] [f] [f g] [f g & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc." |
| 04:14 | acron^ | aha |
| 04:15 | slipset | I guess the threading macros and comp are somewhat related in terms of functionality |
| 04:15 | acron^ | just to be totally clear |
| 04:15 | acron^ | -> is a threading macro ? |
| 04:15 | zilti | slipset: But threading macros work left-to-right |
| 04:15 | SagiCZ1 | acron^: yes |
| 04:15 | slipset | but since the threading macros, are well, macros, you can't pass them around |
| 04:16 | slipset | like you can with functions |
| 04:16 | zilti | slipset: you could pass around #(-> % whatever fns (you use)) |
| 04:16 | acron^ | so whats the impact of using a thread procedurally like in fae-get-image-from-image-page, line 33? |
| 04:16 | TEttinger | ,(apply str (map (comp char (partial + 64)) [3 1 20])) |
| 04:16 | clojurebot | "CAT" |
| 04:17 | acron^ | it's explicitly lazy? |
| 04:18 | TEttinger | that fae- stuff seems really C-style to me... the JVM always has namespaces/packages, you aren't going to have name collisions unless you :use or :require with :refer :all |
| 04:18 | slipset | acron^: I'm on a bit of deep water here, but line 33 gets rewritten at compile time. |
| 04:18 | acron^ | TEttinger: unsurprising, I'm a C programmer, new to Clojure :) |
| 04:18 | TEttinger | heh |
| 04:18 | slipset | ,(-> 1 (+ 3)) |
| 04:18 | clojurebot | 4 |
| 04:19 | slipset | gets rewritten by the macro expander to |
| 04:19 | slipset | ,(+ 1 3) |
| 04:19 | clojurebot | 4 |
| 04:19 | acron^ | slipset: this code is adapted from hickory examples so I guess I dont see the benefit of the thread here |
| 04:19 | zilti | ,(macroexpand-1 '(-> 1 (+ 3))) |
| 04:19 | slipset | at compile-time, not at run time |
| 04:19 | clojurebot | (+ 1 3) |
| 04:19 | SagiCZ1 | acron^: by "threading" we dont mean actual OS thread.. its just an expression that says that the following s-expression get rewriten into the familiar nested structure (..(..(..(..))) .. there is no overhead or speeed impact |
| 04:19 | TEttinger | ,(-> 1 (/ 3)) |
| 04:19 | clojurebot | 1/3 |
| 04:19 | TEttinger | ,(->> 1 (/ 3)) |
| 04:19 | clojurebot | 3 |
| 04:20 | acron^ | SagiCZ1: ah, that's an important detail |
| 04:20 | TEttinger | good to know about ->> , which puts the threaded arg in the last position |
| 04:20 | zilti | slipset: It's important to note though that macros *are* available at runtime |
| 04:20 | slipset | there is also some-> which is quite nice |
| 04:20 | SagiCZ1 | acron^: threading as in putting a thread through the needle.. i guess you are not native speaker? |
| 04:20 | TEttinger | SagiCZ1, it tripped me up too the first time I heard of a threading macro |
| 04:21 | acron^ | SagiCZ1: not native clojure speaker :) i just assume threading/threads means OS threads/coroutines |
| 04:21 | acron^ | assumed* |
| 04:21 | SagiCZ1 | yeah okay i guess it's strange even for native speakers.. but yeah it took me some time to understand what it meant |
| 04:22 | acron^ | ,(-> 10 (- 5)) |
| 04:22 | clojurebot | 5 |
| 04:22 | acron^ | ,(->># 10 (- 5)) |
| 04:22 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ->># in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 04:22 | acron^ | ,(->> 10 (- 5)) |
| 04:22 | clojurebot | -5 |
| 04:22 | zilti | ,(macroexpand-1 '(->> 10 (- 5))) |
| 04:22 | clojurebot | (- 5 10) |
| 04:23 | acron^ | ,(macroexpand-1 '(-> 10 (- 5))) |
| 04:23 | clojurebot | (- 10 5) |
| 04:23 | acron^ | magic |
| 04:23 | SagiCZ1 | acron^: also check out 'doto' which is commonly used with java interop |
| 04:23 | zilti | ,(source ->) ; I wonder if that works |
| 04:23 | clojurebot | Source not found\n |
| 04:23 | SagiCZ1 | (source ->) |
| 04:24 | acron^ | guys, you've been really helpful thanks |
| 04:25 | slipset | https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L1558 |
| 04:25 | alexyakushev | Like Heisenberg said to Hank when he used too many parentheses: "Thread lastly" |
| 04:25 | alexyakushev | Or was it "Tread lightly"? We'll never know |
| 04:27 | slipset | acron^: Jay Fields writes nicely on the usage of comp and partial, worth a read http://blog.jayfields.com/2011/01/clojure-partial-and-comp.html |
| 04:28 | acron^ | thanks slipset, I shall |
| 04:29 | SagiCZ1 | i always think whether i should use partial.. when the #( .. ) construct takes much less space.. |
| 04:29 | SagiCZ1 | partial is also sensitive to the arg order.. |
| 04:29 | Glenjamin | partial doesn't generate a class, if that's important to you |
| 04:29 | SagiCZ1 | #() does? |
| 04:30 | slipset | SagiCZ1: http://blog.jayfields.com/2011/01/clojure-partial-and-comp.html |
| 04:30 | slipset | crap, wrong link |
| 04:30 | slipset | SagiCZ1: http://blog.jayfields.com/2013/05/emacs-lisp-font-lock-for-clojures.html |
| 04:30 | SagiCZ1 | beware of your clipboard! |
| 04:31 | slipset | l guess I was lucky this time. |
| 04:31 | slipset | SagiCZ1: re arg order, I tend to like to build my functions such that they fit with partial |
| 04:31 | SagiCZ1 | slipset: oh yeah.. or using an actual lambda symbol for 'fn' .. i saw that in the core.async talk... anyway i will have to ask cfleming if something like that is possible in cursive |
| 04:32 | SagiCZ1 | slipset: yeah.. 3rd party fn dont always work well though.. |
| 04:32 | slipset | having said that, I really wish there was a (reverse-args f) function in clojure |
| 04:34 | Glenjamin | (defn reverse-args [f] (fn [&args] (apply f (reverse args)))) |
| 04:35 | slipset | Glenjamin: cool! stuff is so simple in Clojure |
| 04:36 | SagiCZ1 | slipset: ugh.. not always sadly.. i always struggle rewriting loops into higher order functions like reduce, iterate etc.. i dont always end up with better code |
| 04:38 | slipset | SagiCZ1: I don't think I've hardly written a loop in Clojure, apart from in a, well, go-loop |
| 04:38 | SagiCZ1 | slipset: wow.. well you need to teach me your ways |
| 04:38 | acron^ | i doubt anyone here can claim to be the perfect programmer SagiCZ1 :) |
| 04:38 | slipset | SagiCZ1: :) |
| 04:39 | SagiCZ1 | slipset: loops like this give me trouble https://www.refheap.com/96481 |
| 04:40 | clgv | SagiCZ1: seems to be more of an `iterate` - but there is no eager version of `iterate` |
| 04:41 | clgv | ah well recursion itself ;) |
| 04:41 | Glenjamin | could write as (reduce) using (reduced), but (loop) seems fine for that |
| 04:41 | SagiCZ1 | Glenjamin: well.. thats the thing.. is the loop fine or should i always try to get rid of it? |
| 04:41 | Glenjamin | is it causing you a problem at the moment? |
| 04:42 | SagiCZ1 | nope |
| 04:42 | Glenjamin | then i'd say it's fine |
| 04:42 | SagiCZ1 | i just dont want to anger clojure gods |
| 04:42 | clgv | SagiCZ1: if you have that patternmore often you can write a fitting higher order function |
| 04:43 | SagiCZ1 | clgv: function or a macro? |
| 04:43 | clgv | SagiCZ1: depends on the details, probably function |
| 04:44 | slipset | SagiCZ1: you got me, I'm not even clever enough to see what this is doing. |
| 04:44 | SagiCZ1 | slipset: it just executes steps updates w and b.. and when e (error) is zero it exits |
| 04:48 | slipset | SagiCZ1: would something like (take-while p (partition 3 (repeatedly (partial rand-int 3)))) |
| 04:49 | slipset | be something you could imagine? |
| 04:49 | slipset | where p is your step and if-test combined? |
| 04:50 | SagiCZ1 | possibly |
| 04:50 | SagiCZ1 | thanks for the idea |
| 04:52 | clgv | SagiCZ1: though you will sacrifice speed by rewriting the loop with lazyseq |
| 04:52 | SagiCZ1 | so there is not much to gain apart from maybe having nicer,, shorter code |
| 04:53 | clgv | yeah, but then try `iterate` with a surround `take-while` |
| 04:53 | clgv | *surrounding |
| 04:54 | SagiCZ1 | clgv: i used that construct elsewhere in my project to replace similar loop... i am using atoms to track progress of the loops.. and in the iterate case it was kinda hard to do |
| 04:55 | clgv | SagiCZ1: I just recommeded it since it matches the semantics of your snippet pretty closely |
| 04:55 | SagiCZ1 | clgv: yep.. true |
| 05:32 | zarkone | hello all. When i use REPL with clojurescript, cider-jump-to-var doesn't work. Am I do something wrong or it's not possible for now? |
| 05:42 | jinagarano | i'm trying to build an h2 db and use it via korma. when i compile, i get an error "unable to resolve symbol defentity." why? i added korma as a dependency in project.clj and put (use 'korma.db) in the source file. |
| 05:44 | zacts | where can I get a list of supported clojure platforms? Well, perhaps that's a naive question, is it supported fully by all plaforms that support the jvm fully? |
| 05:45 | jinagarano | zacts: yes, that's the point. |
| 05:45 | samiswellcool | jinagarano: defentity is in korma.core |
| 05:45 | zacts | jinagarano: ah cool |
| 05:46 | jinagarano | samiswellcool: stupid question maybe; where do i put korma.core in my project? i'm new to all this, it's probably obvious. |
| 05:46 | samiswellcool | just another use statement (use 'korma.core) |
| 05:46 | samiswellcool | or in your namespace (ns whatever.whatever (:use korma.core)) |
| 05:47 | jinagarano | samiswellcool: brillitant, thanks. does a dependency get the files from github/wherever, and make them available in my project? |
| 05:49 | samiswellcool | it gets them from clojars I think, but basically yes |
| 05:49 | samiswellcool | then you have to include them as needed in individual files |
| 05:51 | TEttinger | zacts: I think clojure is compatible with anything that supports Java 6 or higher. Might be as low as 5. |
| 05:51 | zacts | TEttinger: cool |
| 05:51 | zacts | I'm just curious how well it runs on FreeBSD / OpenBSD |
| 05:51 | zacts | I'm considering switching OS on one of my laptops |
| 05:52 | TEttinger | almost certain it will run there, not sure if you have access to an Oracle JDK on there |
| 05:52 | jinagarano | to expand on the fundamentals - where can i find the h2 db file? i built it with a ragtime migration, and i think i have to link it with korma via (def h2-db (h2 {db :/....})) - right? well, i can't find the file i created. |
| 05:52 | zacts | TEttinger: I usually use OpenJDK |
| 05:52 | zacts | is that fine for clojure? |
| 05:52 | TEttinger | yep! |
| 05:52 | zacts | ok neat! :-) |
| 05:54 | TEttinger | I wrote a lein plugin to package clojure apps with a standalone JVM, no installation required, using the Packr library. It downloads a pre-made OpenJDK 7 distribution for mac, windows, and/or linux, and assembles an uberjar into one exe with the JVM in a directory next to it |
| 05:54 | TEttinger | it's a total hack but does work fine with OpenJDK |
| 06:08 | clgv | TEttinger: zacts: it is Java 6 for Clojure 1.6 |
| 06:08 | zacts | oh cool |
| 06:08 | clgv | the versions before 1.6 required only Java 5 |
| 06:17 | Glenjamin | TEttinger: sounds similar to capsule |
| 06:17 | TEttinger | probably! |
| 06:17 | TEttinger | Packr is meant for games, primarily |
| 06:17 | Glenjamin | oh, not quite |
| 06:17 | Glenjamin | https://github.com/puniverse/capsule "Have your JAR automatically choose an appropriate JVM version, set JVM flags, and add an embedded JAR to the boot class path." |
| 06:18 | TEttinger | "Java 9 is expected to have a mechanism for packaging stripped-down versions of the JVM." |
| 06:19 | TEttinger | interesting |
| 07:17 | SagiCZ1 | does anyone know how future-cancel works? it cancels toy examples easily but in the real case the thread keeps going even though future-cancel returned true |
| 07:17 | Glenjamin | $source future-cancel |
| 07:17 | lazybot | future-cancel is http://is.gd/Z4YWxl |
| 07:18 | Glenjamin | welp, that wasn't very helpful |
| 07:19 | SagiCZ1 | i was thinking that it probably needs Thread.yield() somewhere to be able to cancel itself.. |
| 07:19 | clgv | SagiCZ1: you cant really use it to reliably stop something that is already processed by a thread. but queue futures should be canceled correctly |
| 07:20 | SagiCZ1 | what is a reliable way to stop the thread then? i see it in every single application.. long running tasks can be cancelled with the cancel button |
| 07:20 | clgv | SagiCZ1: you need some predicate (keep-running? ...) in your processing loop |
| 07:20 | SagiCZ1 | clgv: no other way? thats just awful.. why cant jvm just kill the thread |
| 07:21 | clgv | SagiCZ1: just google that, there are a lot of discussions ;) |
| 07:22 | clgv | SagiCZ1: the magic of clojure could ease the pain. you write a `stopable` macro that does the check almost transparently. |
| 07:22 | SagiCZ1 | clgv: yeah.. or maybe use the deprecated stop() method |
| 07:23 | clgv | SagiCZ1: and achieve nothing? |
| 07:23 | SagiCZ1 | clgv: and see this is where i run into problems.. some of my tasks are loops.. ok they could be dealt with.. but some of them are long running HOF like iterated, reduce etc.. i would have to add the checking mechanism to so many places.. |
| 07:24 | cfleming | SagiCZ1: You want your code to catch InterruptedException, generally |
| 07:25 | cfleming | SagiCZ1: Then whatever is doing the stopping can interrupt your thread and you can handle it gracefully. |
| 07:25 | SagiCZ1 | cfleming: would it raise the exception? i though i would need to check isInterrupted() .. |
| 07:25 | SagiCZ1 | my future code is already wrapped in try catch and doesnt throw any exception when i call future cancel |
| 07:25 | cfleming | SagiCZ1: The Java concurrency primitives check it at various points so you generally don't have to. If the primitives Clojure uses under the hood don't then you'll have to do that yourself, yeah. |
| 07:26 | SagiCZ1 | cfleming: yeah i am not using any concurrency primitives |
| 07:26 | cfleming | SagiCZ1: Sure, but Clojure is on your behalf. |
| 07:26 | SagiCZ1 | well thats just such a bummer.. i thought clojure would have some better mechanism to deal with this madness |
| 07:26 | clgv | http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt%28%29 |
| 07:27 | clgv | cfleming: seems that exception is just thrown in pretty specific cases |
| 07:27 | SagiCZ1 | so we have all these futures and promises and delivers and it just all falls back on the primitive java threads which cant be even reliable stopped.. |
| 07:28 | cfleming | clgv: Yeah, but those cases are actually pretty common. If your code is in a tight loop you'll have to check it yourself, but often you'll finish a bit of work, check a queue or something for more work and get the exception. |
| 07:29 | clgv | cfleming: the tight loop scenario seems to be the use case of SagiCZ1 |
| 07:29 | cfleming | SagiCZ1: You can't stop a thread reliably, right. But the concurrency primitive do provide good (if non-obvious and tricky) ways to do it. |
| 07:30 | SagiCZ1 | so yeah.. my previous solution was to have an atom called progress.. which was repeatedly checked and when someone from the outside set the value to negative, the thread would immediately stop and return.. i thought future cancel would help me avoid writing the atom checks.. btu i guess i have to go back |
| 07:31 | cfleming | SagiCZ1: http://stackoverflow.com/questions/13623445/future-cancel-method-is-not-working |
| 07:31 | cfleming | SagiCZ1: And http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html |
| 07:31 | SagiCZ1 | cfleming: so if i added Thread/yield everywhere it should throw the exception? |
| 07:32 | SagiCZ1 | yield is basically 0ms sleep |
| 07:33 | SagiCZ1 | nope.. doesnt throw exception |
| 07:33 | cfleming | SagiCZ1: I would check the thread interrupted flag |
| 07:33 | SagiCZ1 | and then throw the exception? |
| 07:33 | cfleming | Or exit your loop, or whatever you need to do, yeah |
| 07:33 | clgv | SagiCZ1: from the javadoc of yield "It is rarely appropriate to use this method." |
| 07:34 | SagiCZ1 | well that javadoc can bite me! |
| 07:34 | SagiCZ1 | :D |
| 07:34 | clgv | SagiCZ1: the remaining description suggest that it is not what you want anyway |
| 07:34 | SagiCZ1 | (Thread/sleep 0) works.. if i call future-cancel it throws sleep interrupted exception which i can handle |
| 07:35 | SagiCZ1 | so just add the sleep to every task and it should work |
| 07:35 | cfleming | SagiCZ1: yield (IIRC) was to allow your thread to try to give up its runnable status and allow it to be rescheduled. It's an obsolete method to try to influence thread priorities |
| 07:35 | cfleming | SagiCZ1: Seriously, just check the interrupted flag and throw the exception |
| 07:35 | cfleming | That's what it's for |
| 07:36 | SagiCZ1 | okay.. i can wrap that into a function so thats ok |
| 07:36 | cfleming | Using Thread/sleep will have other effects that you may not want, like affecting the scheduler |
| 07:36 | SagiCZ1 | thank you very much guys.. |
| 07:37 | cfleming | SagiCZ1: If you can get a copy, Java Concurrency In Practice is the bible for this stuff, it's a really great book. |
| 07:37 | SagiCZ1 | cfleming: I am learning clojure so I could avoid Java convoluted concurrency mechanisms.. |
| 07:37 | cfleming | SagiCZ1: The first five chapters (IIRC) give a great background. |
| 07:37 | SagiCZ1 | but i guess i will have to learn it one day |
| 07:37 | cfleming | SagiCZ1: Yeah, but sometimes you just have to know what's going on |
| 07:39 | clgv | SagiCZ1: You have to embrace the host platform my young padawan. ;) |
| 07:40 | SagiCZ1 | clgv: hehe :) |
| 07:40 | SagiCZ1 | cfleming: on a completely unrelated note.. do you think Cursive would be able to replace some common core function names with greek symbols? some people use this in emacs.. for example they use lambda symbol for 'fn' etc.. just visually, not internally |
| 07:43 | cfleming | SagiCZ1: Yeah, it should be possible to use code folding for that |
| 07:43 | SagiCZ1 | what is that? |
| 07:44 | cfleming | SagiCZ1: To be honest though, it's going to be a very low priority since I've never really seen the point |
| 07:44 | SagiCZ1 | cfleming: yeah i thought so |
| 07:45 | cfleming | SagiCZ1: That when IntelliJ allows you to fold code, like top-level forms. Their engine is actually pretty powerful, so it gets used for a lot of other things, e.g. in Java they hide new HashMap<SomeBigLongThing>() as new HashMap<~>() |
| 07:46 | SagiCZ1 | oh i know what that is.. ok |
| 07:46 | cfleming | SagiCZ1: It basically does what you're asking about. I'm going to use it in the REPL to fold stacktraces, so it'll automatically fold non-Clojure items, or items that aren't in your project, or something similar |
| 07:46 | cfleming | SagiCZ1: so they'll be hidden, but you can click or hover to see them |
| 07:47 | SagiCZ1 | cfleming: yeah thats a great idea with the task traces.. |
| 07:51 | cfleming | SagiCZ1: So, to answer your original question - it's possible but it's unlikely to happen unless a lot of people suddenly ask for it. |
| 07:51 | SagiCZ1 | cfleming: understandable |
| 07:52 | clgv | cfleming: does cursive provide a plugin api? then he could implement it himself... |
| 07:52 | SagiCZ1 | cursive is meant to be stand-alone.. so maybe then |
| 07:53 | cfleming | clgv: Not yet - it'll provide an extension API, but I'm not sure this would be something you'd be able to achieve with it, at least initially. Someone could always do it as an IntelliJ plugin. |
| 07:58 | slipset | SagiCZ1: You've probably considered it, but how 'bout using core.async to solve your problem |
| 07:58 | slipset | There is this example floating around, I think in a tbaldridge talk using alts! to choose from diffent channels, one of them being a timeout channel |
| 07:59 | SagiCZ1 | slipset: yeah it would probably solve it... i started this project before i knew about core.async and this is just a finishing touch so i dont want to rewrite it all.. i actually solved the problem quite gracefully with what guys suggested here |
| 07:59 | slipset | cool! |
| 08:00 | jinagarano | if i make an h2 db with ragtime migration, where is the resulting file? i want to build a korma layer on top of it and can't figure out how to link them. |
| 08:22 | Empperi | HOLY SHIT http://www.itworld.com/article/2875112/ibm-is-about-to-get-hit-with-a-massive-reorg-and-layoffs.html |
| 08:23 | Empperi | IBM fires 111 800 people by the end of February |
| 08:23 | Empperi | and no, that number is not a typo |
| 08:24 | hyPiRion | "IBM fires 1/3 of Iceland" |
| 08:25 | Empperi | those numbers are just staggering |
| 08:25 | Empperi | several cities are going to shake with their economies after this |
| 08:25 | hyPiRion | Is IBM mainly located in the US? |
| 08:26 | Glenjamin | i'm aware of lots of UK offices |
| 08:26 | Empperi | it's very much global company |
| 08:26 | xemdetia | hyPiRion, hardly. |
| 08:26 | Empperi | there are several offices in Finland too |
| 08:27 | hyPiRion | Then it's probably not as bad of a hit for the cities |
| 08:27 | Empperi | really? |
| 08:28 | Empperi | when Lehman Brothers bancrupted 26k people lost their jobs |
| 08:28 | Empperi | that with the debt fiasco led to current economic situation |
| 08:28 | Empperi | no four times more people gets fired at once |
| 08:28 | Empperi | that's going to have some serious impact into economy world wide unless those people find new jobs and fast |
| 08:29 | hyPiRion | Well, I'm hanging out in #clojure, not #economics. Go figure :p |
| 08:29 | Glenjamin | there's no shortage of programming jobs, just because IBM is failing doesn't mean people won't be snapped up by other companies |
| 08:29 | SagiCZ1 | Empperi: IBM is all over the world |
| 08:29 | Empperi | SagiCZ1: that's what I said? |
| 08:29 | SagiCZ1 | Empperi: so the impacted is spreaded out |
| 08:30 | SagiCZ1 | milions of people lose their jobs every year |
| 08:30 | Empperi | yes but not at once and on one industry at the same time |
| 08:30 | SagiCZ1 | i doubt couple thousand people losing their jobs caused global economic crisis |
| 08:30 | xemdetia | Empperi, IBM is not a stranger to deep cuts like that. |
| 08:30 | Empperi | yes, they hold the previoius record |
| 08:31 | daniel___ | its the apocalypse |
| 08:31 | Empperi | if there's some people here working for IBM I feel for you guys |
| 08:32 | zacts | ok, back to clojure now |
| 08:32 | Empperi | Glenjamin: IBM does a lot of other stuff too than just programming. Actually most of the layoffs are directed to people not doing programming |
| 08:32 | Glenjamin | ah :( |
| 08:32 | Empperi | old mainframe guys, storage unit etc |
| 08:33 | Empperi | business-wise a good move |
| 08:33 | SagiCZ1 | IBM's services are expensive and useless nowadays.. this was to be expected |
| 08:33 | Empperi | but the impact will be felt, badly |
| 08:33 | Empperi | SagiCZ1: yeah |
| 08:33 | SagiCZ1 | Empperi: doubt it.. maybe locally in the specific areas |
| 08:33 | Empperi | their attempts to become a cloud provider have been abysmal |
| 08:34 | Empperi | but yeah, back to clojure now. |
| 08:34 | Empperi | that was just such a huge news I wanted to share it here |
| 08:44 | Empperi | oh, btw to the IBM news: "Most of the layoffs will happen in the US, but some international operations will be affected as well" |
| 08:44 | Empperi | http://www.cultofmac.com/310012/ibm-prepares-largest-corporate-layoff/#uqtJmQqlX00Ar9kG.99 |
| 08:44 | hyPiRion | alright, that might be pretty bad |
| 08:45 | Empperi | most likely the worst hit is centered around few US cities |
| 08:46 | yguan | trying to be familiar with core.async. why should the following fail? |
| 08:46 | cfleming | https://news.ycombinator.com/item?id=8944999 "Cringely has made dooms day predictions in the past that were widely innacurate" |
| 08:46 | yguan | (let [c (chan)] |
| 08:46 | yguan | (go |
| 08:46 | yguan | (print (<! c))) |
| 08:46 | yguan | (go |
| 08:46 | yguan | (let [f (fn [v] |
| 08:46 | yguan | (>! c v))] |
| 08:46 | yguan | (f "ab"))) |
| 08:46 | yguan | (Thread/sleep 100) |
| 08:46 | yguan | (close! c)) |
| 08:46 | dnolen | yguan: use a pasting service please :) |
| 08:47 | SagiCZ1 | yguan: replace thread/sleep with (<! (timeout 100)) |
| 08:47 | tbaldridge | no, the issue is that you can't use >! and <! outside of a go |
| 08:47 | yguan | dnolen, ehh i'll figure out pasting :) |
| 08:47 | tbaldridge | and go blocks stop translating at any call to (fn [...] ....) |
| 08:47 | SagiCZ1 | tbaldridge: he doesnt have them outside of go |
| 08:47 | SagiCZ1 | oh |
| 08:47 | SagiCZ1 | nvm\ |
| 08:48 | yguan | tbaldridge, I see, feel a bit black magic here... |
| 08:48 | tbaldridge | there' |
| 08:49 | tbaldridge | go blocks are basically nothing but black magic, elven herbs, and dwarven runes |
| 08:50 | gfredericks | stop blocks on the other hand just call System/exit, plain and simple |
| 08:50 | hyPiRion | those dwarven FSMs |
| 08:51 | tbaldridge | yguan: any async translation compiler like core.async, or C#'s async/await is going to have a few caveats, it's just the way the tech has to work if you don't want to transform your entire program |
| 08:51 | dnolen | yguan: supporting only shallow yield is a pretty common thing actually |
| 09:08 | thheller | dnolen: whats the policy for upgrading closure compiler + library for CLJS? It's been about 6 months |
| 09:09 | dnolen | thheller: just someone testing it to make sure it doesn't break everything, it's happened before |
| 09:09 | dnolen | thheller: more recent versions of Closure busted browser REPL, not sure if this has been addressed in a release |
| 09:10 | thheller | ok thx, will see if I can do some tests |
| 09:13 | stuartsierra | thheller: G.Closure compiler releases are on search.maven.org; there are scripts in the ClojureScript tree to build JARs of the G.Closure library. |
| 09:47 | thheller | dnolen: why is the :externs key outside :foreign-libs? I think it should be coupled with the foreign-lib? |
| 09:47 | _KryDos_ | Hi guys. I'm learning Clojure and I need a little help. Could you please explain me the difference between (future) and (.start (Thread. ...))? And could you please give me information when I can search for answers on the similar questions. Thank you |
| 09:47 | _KryDos_ | s/when/where/ - sorry |
| 09:48 | thheller | dnolen: suppose I have a deps.cljs for with a couple of foreign libs where some might be included and some not. a "global" externs might not be available |
| 09:49 | dnolen | thheller: that's just because it's the expected shape of the build description, that is, it worked this way before, this hasn't changed in 3 years. otherwise more processing required |
| 09:50 | dnolen | thheller: I don't have a problem with allowing :externs per lib but will need a patch for that |
| 09:51 | stuartsierra | _KryDos_: `future` returns a java.util.concurrent.Future, from which you can get the value returned by the code inside it. |
| 09:51 | thheller | dnolen: ok, was thinking of building a package for codemirror. there is a whole bunch of optional stuff in it, wiring all of it up via provide/require is gonna take some effort though |
| 09:51 | stuartsierra | _KryDos_: `future` uses a thread from a cached thread pool which Clojure maintains internally. |
| 09:51 | thheller | dnolen: will see how far I get |
| 09:52 | thheller | dnolen: pretty sure some of the addons require their own externs. thats why I'm asking |
| 09:57 | _KryDos_ | stuartsierra: thank you so much for the answer |
| 09:57 | stuartsierra | _KryDos_: You're welcome. |
| 10:05 | dysfun | stuartsierra: just wanted to say thanks for building component. it seems like a nice way of building apps |
| 10:05 | stuartsierra | dysfun: thanks! |
| 10:05 | dysfun | although it'd be even better if you didn't fully qualify it with com.stuartsierra |
| 10:05 | dysfun | :) |
| 10:06 | stuartsierra | dysfun: I'm not going to try to claim ownership of the word "component" at the global Clojure namespace level. |
| 10:06 | hyPiRion | oh no, 16 more characters per require |
| 10:06 | dysfun | ah, point :) |
| 10:06 | justin_smith | SagiCZ1: regarding future-cancel - it won't stop the thread unless it is blocking in specific contexts (which are frequent places to catch it but not guaranteed). You can check (.isInterrupted (Thread/currentThread)) to see if your thread has been cancelled, and use that as a conditional before looping |
| 10:07 | dnolen | thheller: right, happy to take a patch for this - should only need to touch a few bits of code to make it work |
| 10:07 | stuartsierra | And I don't like names that have nothing to do with what the code actually does. |
| 10:07 | SagiCZ1 | justin_smith: and if i call the future-cancel it flips the interrupt flag so at any time after that point if i ask isInterrupted it would always return true, correct? |
| 10:07 | justin_smith | right |
| 10:08 | justin_smith | and like I said, if the thread was eg. blocking on a read, it would be stopped automatically as well |
| 10:08 | justin_smith | but as you saw, that is not something you can always count on |
| 10:09 | hyPiRion | justin_smith: huh? A thread blocking on a read cannot be interrupted before it actually receives some data. |
| 10:09 | SagiCZ1 | justin_smith: okay.. yeah i wrapped the isinterrupt check into a simple function whcih throws an exception.. then i catch the exception much higher in the hierarchy where i can deal with resetting progress bar etc.. its good because the exception propagation is automatic and no extra code is required.. overall i am after all pretty happy with the solution |
| 10:09 | justin_smith | hyPiRion: hmmm... let me double check my source |
| 10:09 | hyPiRion | justin_smith: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4514257 |
| 10:10 | hyPiRion | You can't assume you can at least. |
| 10:11 | justin_smith | hyPiRion: I was going by this http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupt-- |
| 10:12 | justin_smith | but now I see that is specific to wait, IO on InterruptibleChannel s and Selector |
| 10:14 | justin_smith | but regardless, of course, best to explicitly check interrupted status if you want future-cancel to actually work |
| 11:39 | thheller | dnolen: think we should support :source-map for :file-min in foreign-libs? some js libs provide source maps. not sure how that would work if we merge the :file-min into the build though |
| 11:59 | dysfun | i need to do live video encoding. anyone know what the state of tools for clojure is? |
| 12:06 | clgv | s/clojure/java/ |
| 12:06 | TimMc | dysfun: Probably nothing clojure-specific. Try Java-land. |
| 12:06 | dysfun | yeah, i've found jcodec and i'm pondering writing a wrapper |
| 12:11 | TimMc | Does it need wrapping? |
| 12:12 | dysfun | anything that involves me writing lots of code using java method invocation syntax does, yes, for my sanity :) |
| 12:21 | tbaldridge | personally I'd try to keep as much of this out of the JVM as possible, and just do some sort of FFI wrapper around FFMpeg |
| 12:21 | noncom | dysfun: javacv is the option i think |
| 12:21 | djames_ | I just posted a question about a challenge I'm facing with lots of nested functions that use destructuring to the ML. I find it convenient, but it makes memoization harder. I'm curious if others have faced this. I'm also interested in memoization. |
| 12:21 | noncom | i have a *very* positive experience with it |
| 12:22 | djames_ | https://groups.google.com/forum/#!topic/clojure/RZE52iLY0oY |
| 12:22 | noncom | dysfun: worth noticing that javacv != opencv-for-java. it is much more. for example, it provides reach caps in playing and editing and converting video with ffmpeg |
| 12:35 | aaelony | is conj.io down? |
| 12:36 | puredanger | yes, and arrdem is aware |
| 12:36 | aaelony | thx |
| 12:41 | zacts | hum.. I'm finding I really prefer these two books the most: 0) brave clojure, and 1) O'Reilly Clojure Programming |
| 12:46 | dysfun | noncom: ffmpeg sounds like JNI hell to me |
| 12:46 | tbaldridge | for FFI stuff JNA is much easier and almost as fast. |
| 12:48 | dysfun | i'll give it a spin anyway |
| 12:52 | hiredman | swig is nice |
| 12:59 | noncom | dysfun: not at all. ffmpeg is wrapped in javacv for you already |
| 12:59 | noncom | it works very well |
| 13:00 | zacts | I want to make a music composition app with clojure |
| 13:00 | zacts | and a visual composition app |
| 13:01 | justin_smith | zacts: you could look into kunstmusik/pink, it's from one of the lead csound devs |
| 13:01 | zacts | oh neato! |
| 13:01 | zacts | also, how about ChucK? |
| 13:01 | justin_smith | it includes the signal processing stuff, and also higher level event processing too |
| 13:02 | justin_smith | ChucK is novel |
| 13:02 | devn | hola |
| 13:02 | zacts | oh cool |
| 13:02 | noncom | dysfun: here are two files for you to start with: https://www.refheap.com/96496 , https://www.refheap.com/96497 - them are from my project where I use javacv to play video on a JMonkeyEngine texture |
| 13:02 | justin_smith | if you want to target a synthesis language, csound has the most built in stuff, and has the easiest syntax to generate I think |
| 13:03 | zacts | ah ok |
| 13:03 | justin_smith | zacts: but with pink, you don't need to target another synth language, it implements its own in pure clojure |
| 13:03 | zacts | yeah, I'm a newbie in this regard |
| 13:03 | noncom | zacts: heeey, cojurists, do not forget http://overtone.github.io/ ! |
| 13:03 | zacts | oh neat |
| 13:03 | justin_smith | yeah, overtone is an option too |
| 13:03 | justin_smith | it cheats by shipping supercollider in the jar :) |
| 13:03 | justin_smith | "cheats" |
| 13:05 | noncom | java minim and beads libraries could come in handy too... depending on usecase.. |
| 13:07 | zacts | how about visual programming art? |
| 13:07 | zacts | like fractals / designs / etc.. |
| 13:07 | zacts | I think it would be cool to combine music with the visual aspect |
| 13:08 | noncom | zacts: i think that the simplest start for you would be with processing |
| 13:08 | noncom | zacts: https://processing.org/ |
| 13:09 | noncom | zacts: and from the authors of overtone, here comes a clojuric processing wrapper for you: https://github.com/quil/quil |
| 13:10 | zacts | oh cool! |
| 13:10 | zacts | brb, heading out for a sec |
| 13:16 | sorenmacbeth | is it possible to write a macro that calls a java method dynamically? im dying here |
| 13:17 | sorenmacbeth | something like (~meth ~obj ~val) |
| 13:17 | sorenmacbeth | where ~meth is a symbol like .set_something |
| 13:18 | puredanger | sure, although you'll probably want to use just . rather than .method I think |
| 13:19 | puredanger | so like (. ~obj (~setter ~value)) |
| 13:20 | puredanger | I did something similar here: http://stackoverflow.com/questions/27308061/whats-the-idiomatic-way-to-do-this-java-function-in-clojure/27308254#27308254 |
| 13:27 | sorenmacbeth | puredanger: yeah, like that |
| 13:27 | sorenmacbeth | that form didn't work fpr me when I tried it (at 2am) |
| 13:28 | puredanger | it doesn't work between 2-3 am |
| 13:29 | chouser | ha! |
| 13:30 | puredanger | chouser implemented that |
| 13:30 | stuartsierra | chouser: long time, no see |
| 13:32 | chouser | stuartsierra: Hi! |
| 13:38 | Glenjamin | dnolen: would it be fair to say the test.check ClojureScript port was "straightforward", i'm writing up some backstory on checkers ? |
| 14:11 | sorenmacbeth | so that works, but not if you pass in symbols |
| 14:12 | sorenmacbeth | (set-fields my-map my-options) |
| 14:12 | amalloy | sorenmacbeth: you have to use reflection. a macro can't do things "dynamically", because it emits code at compile time |
| 14:13 | sorenmacbeth | amalloy: i was afraid you where going to say that |
| 14:14 | dysfun | noncom: thanks :) |
| 14:15 | sorenmacbeth | (require '[clojure.reflect :as reflect]) |
| 14:15 | sorenmacbeth | (def r reflect/reflect pv) |
| 14:15 | sorenmacbeth | f |
| 14:15 | sorenmacbeth | r |
| 14:16 | sdegutis | Does Clojure have functors? |
| 14:16 | justin_smith | sorenmacbeth: are you trying to use the bot? |
| 14:16 | sorenmacbeth | haa, this is not my REPL buffer |
| 14:16 | stuartsierra | sdegutis: In the ML module functor sense, no. |
| 14:17 | sdegutis | aww |
| 14:17 | sdegutis | What does Clojure have instead? |
| 14:17 | dysfun | sequences |
| 14:17 | justin_smith | functions that operate on protocol / multimethod methods instead of concrete types |
| 14:18 | noncom | dysfun: np. as a notice: i have used a clojure agent as a receiver of frames that a grabber grabs (to later draw on a texture), since i thought of it as of best possible concurrency model for the task.. idk if it is though. |
| 14:18 | stuartsierra | You can simulate functors in Clojure by combining protocols with some kind of dependency injection. |
| 14:19 | dysfun | noncom: in this case i'm encoding video server side so i'm basically shoving it straight back out of a pipe |
| 14:20 | tcrayford____ | sorenmacbeth: hail satan |
| 14:20 | noncom | dysfun: ah, better for you then :) if you read javacv forums and docs, i bet you find much info on converting / encoding and saving video |
| 14:21 | dysfun | heh |
| 14:24 | dysfun | i haven't been able to concentrate easily this week, and i've got to present what i'm doing tomorrow afternoon, so we'll see :) |
| 14:25 | zacts | back |
| 14:25 | R0B_ROD | Hey |
| 14:26 | amalloy | sdegutis: do you mean functors in the ML sense like stuartsierra is saying, or the haskell sense? |
| 14:26 | zacts | heh, R0B_ROD I initially read your nick as ROB_FORD |
| 14:27 | zacts | sorry man |
| 14:30 | sorenmacbeth | tcrayford____: hail satan indeed |
| 14:32 | zacts | ile |
| 14:48 | sdegutis | amalloy: I only know OCaml |
| 14:48 | zacts | darn I forgot my headphones, and I'm at the cafe, so I'll have to try the overtone stuff laters |
| 14:54 | hellofunk | sdegutis: if i remember, you are the author of the great oo library OOPS, am i right? then if so, i can understand your affinity for OCaml |
| 14:57 | sdegutis | hellofunk: no, I am not the author of any great library |
| 14:58 | sdegutis | hellofunk: I have written OOPS as an experiment, although I'm surprised I haven't yet deleted it |
| 14:58 | sdegutis | hellofunk: it's certainly not in use anywhere |
| 14:59 | hellofunk | sdegutis: i was a bit tongue in cheek, though i remember your interest in OO mixed with FP and now see you've discovered OCaml which seems like a worthy exploration for your interestts. |
| 15:01 | sdegutis | hellofunk: I don't know anything about the OO part of OCaml yet. I just think dynamic typing is for toys and static typing is for serious projects, and OCaml has all my favorite Clojure features (destructuring, core.match, simple elegant syntax) and then some (polymorphic variants, etc). |
| 15:02 | hellofunk | theoretical question of the day: is it possible to express a simple average function as a single reduce? |
| 15:02 | llasram | hellofunk: yes |
| 15:03 | hellofunk | llasram: i suppose you'd keep a running count going in your reduction? |
| 15:03 | sdegutis | hellofunk: you'd probably use clojure.core/reductions |
| 15:03 | llasram | hellofunk: even better actually |
| 15:03 | llasram | sdegutis: ho ho ho |
| 15:03 | sdegutis | llasram: did I win that one? |
| 15:03 | tbaldridge | or if your input collection has O(1) count, just use that |
| 15:03 | zacts | my cat named lambda says hi |
| 15:04 | zacts | so how often do clojurists use java libraries? |
| 15:04 | justin_smith | zacts: in every project |
| 15:04 | tbaldridge | zacts: often |
| 15:04 | zacts | oh interesting |
| 15:04 | llasram | hellofunk: something like this: https://gist.github.com/llasram/5860685 |
| 15:04 | justin_smith | in most namespaces |
| 15:04 | tbaldridge | every 5th thursday of the month. |
| 15:05 | sdegutis | zacts: there's no point to clojure unless you're gonna use a java lb |
| 15:05 | llasram | hellofunk: Also numerically stable, unlike naive sum + divide |
| 15:05 | dysfun | sdegutis: or...a clojure lib? |
| 15:06 | dysfun | it's not like we don't have an extensive library ecosystem by now |
| 15:06 | zacts | huh ok, so I guess I need to understand how java's OOP libraries interact with clojure's functional paradigm? |
| 15:06 | zacts | aren't the two kind of conflicting in a sense? |
| 15:06 | turbofail | there's not exactly much to understand... you call java methods when you need to using the (.foo blah) syntax |
| 15:07 | turbofail | occasionally you might need to implement a java interface |
| 15:07 | justin_smith | zacts: that comes up sometimes - eg. when a poorly designed api won't accept implementation of an interface (easy to do from clojure) but instead needs you to subclass (harder to do from clojure) |
| 15:07 | dysfun | first parameter being the object to invoke the method on |
| 15:07 | hellofunk | llasram: i see, so my initial assumption was more or less on point, that you keep a running tally of things as your reduce along |
| 15:07 | dysfun | justin_smith: potemkin makes it pretty easy |
| 15:07 | zacts | huh, cool |
| 15:07 | zacts | ok |
| 15:08 | zacts | well I'm almost to the point of learning about java interop |
| 15:08 | sdegutis | dysfun: it probably uses a java lib |
| 15:08 | dysfun | there's really not much to it |
| 15:08 | justin_smith | dysfun: wait, potemkin allows subclassing arbitrary java classes? |
| 15:08 | dysfun | sdegutis: many do, sure, but that's because we happen to be on java, just as you'd quite often integrate with a c library in ocaml land, i'm guessing |
| 15:08 | zacts | that was my biggest question, if I'm using java libs quite often, how do I not let java's non-pure functionalishness infect my clojure code |
| 15:08 | dysfun | justin_smith: deftype+ |
| 15:09 | dysfun | try and keep as much as possible in clojure space, not java space |
| 15:09 | dysfun | and bear in mind that most java data are mutable and require mutation to do things, rather than returning altered copies |
| 15:10 | dysfun | so reduce and map and all of those won't work so well |
| 15:10 | zacts | hum.. |
| 15:10 | dysfun | there are some macros to make it a bit less painful, like doto and .. |
| 15:10 | dysfun | ,(doc ..) |
| 15:10 | justin_smith | dysfun: hmm... potemkin source indicates that it supports "abstract types", but I see nothing about it allowing the creation of a concrete subclass |
| 15:11 | clojurebot | "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand." |
| 15:11 | dysfun | justin_smith: deftype+ can have a provided parent class type |
| 15:11 | dysfun | justin_smith: the usual case being to inherit from an abstract class |
| 15:12 | zacts | dysfun: Hm.. I'm assuming I'll learn how this all fits together as I gain more clojure experience |
| 15:13 | zacts | so my projects I want to do: 0) make a simple text editor with clojure 1) do music synth 2) do visual fractal art with clojure |
| 15:13 | dysfun | it could be that it *only* works with the def-abstract-type generated classes, but i haven't had to use it since i discovered potemkin |
| 15:13 | justin_smith | llasram: dysfun: yeah I am reading the source and I see nothing that would or could do that so far... |
| 15:14 | alexyakushev | zacts: Go straight for 1) and 2); 0) is boring :O |
| 15:14 | zacts | alexyakushev: ah, ok! :-D |
| 15:14 | zacts | I'll call it yet another editor editor |
| 15:14 | zacts | (kidding) |
| 15:14 | dysfun | zacts: for your music synth project, you'll want to look at overtone |
| 15:14 | alexyakushev | Especially since Clojure already has great tools like Overtone and Quil |
| 15:15 | zacts | I'm also hoping to learn good software abstraction / design ideas from doing music synth with clojure |
| 15:15 | zacts | I'm feeling I'll get more of an intuitive sense of things |
| 15:16 | dysfun | hah, good luck with that |
| 15:16 | alexyakushev | Hey get some inspiration https://twitter.com/jackrusher/status/467571017679114240 |
| 15:17 | zacts | wow that's pretty neat alexyakushev |
| 15:17 | alexyakushev | I keep this tweet in bookmarks so that I finally get to try Quil someday |
| 15:21 | zacts | so what is a good JSON alternative for clojure, is edn like this? |
| 15:22 | zacts | or should I just use clojure data structures in a text file? |
| 15:22 | justin_smith | zacts: it is easy to translate between json and edn, and also there is transit for faster network transfer |
| 15:22 | tbaldridge | edn works well, depends on your needs. |
| 15:22 | zacts | oh cool justin_smith |
| 15:22 | zacts | ah ok |
| 15:22 | justin_smith | for usage within one app, edn is great, if communicating with a client I would use json or transit |
| 15:23 | zacts | so the only issue with edn, is that it's not a tottaly stable api |
| 15:23 | tbaldridge | and if you're going JVM to JVM and clojure (or java) on both ends, Fressian is probably the fastest. |
| 15:23 | justin_smith | cheshire does a good job of translating from edn to json |
| 15:23 | tbaldridge | https://github.com/Datomic/fressian |
| 15:23 | tbaldridge | all depends on what you need. |
| 15:23 | zacts | ok neat |
| 15:25 | zacts | clojure reinvents the wheel, but it reinvents it to be a hovercraft |
| 15:25 | zacts | it's cool, although it still uses previous design lessons |
| 15:25 | tbaldridge | yeah, it learns from the stuff we all forgot 40 years ago. |
| 15:26 | zacts | so perhaps I should ask what would be a good first project to do after reading braveclojure? Can I start right away into the music processing? |
| 15:27 | zacts | oh project euler I did want to try some of those |
| 15:35 | sdegutis | So, anyone here know Haskell and have written a comparison between Clojure and Haskell to get Clojurians up to speed on Haskell? Thanks in advance, regards. |
| 15:37 | dysfun | i imagine if you google 'clojure vs haskell' you'll turn up all sorts of things like that |
| 15:38 | sdegutis | Only one from callen |
| 15:38 | raek | sdegutis: do you happen to know another language from the ML family? |
| 15:39 | hellofunk | sdegutis: i've seen a number of articls on the subject. google was my friend at the time, but you may choose an appropriate alternative as your friend if desired.\ |
| 15:39 | sdegutis | raek: I started learning OCaml and stopped at Functors because it got too confusing to learn just by looking at code examples |
| 15:39 | hellofunk | sdegutis: i wonder if they are anything like c++ functors, probably not |
| 15:40 | dysfun | they are not |
| 15:41 | dysfun | http://www.catonmat.net/blog/on-functors/ |
| 15:41 | raek | it's funny that so many languages use the name "functor" for so completely unrelated concepts |
| 15:41 | justin_smith | sdegutis: functors are like functions, but they operate on modules. To understand why they can't just be functions, you need to understand why modules can't just be normal data. |
| 15:41 | justin_smith | it's a wrinkle in ml, imho |
| 15:41 | dagda1_ | is there any difference between (if (empty? []) or (if (seq [])) I see both ways used. Is there any real difference |
| 15:42 | hellofunk | dagda1_: well obvious they are opposite tests |
| 15:42 | justin_smith | dagda1_: they are opposite conditions |
| 15:42 | justin_smith | hehe |
| 15:42 | hellofunk | ,(doc seq) |
| 15:42 | clojurebot | "([coll]); Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable." |
| 15:42 | raek | sdegutis: There's a guide called "A Gentle Introduction to Haskell". It does not compare Haskell to Clojure though. |
| 15:42 | hellofunk | oh that didn't have the extra bit that i find useful in the seq docstring |
| 15:42 | sdegutis | thanks |
| 15:42 | tbaldridge | And as a favorite language developer of mine said once "If you start trying to implement parameterized namespaces, suddenly you realize that it breaks REPL development, because modules become the unit of compilation instead of the form being the unit of compilation" |
| 15:42 | justin_smith | ,(doc empty) |
| 15:42 | clojurebot | "([coll]); Returns an empty collection of the same category as coll, or nil" |
| 15:43 | justin_smith | ,(doc empty?) |
| 15:43 | clojurebot | "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))" |
| 15:43 | justin_smith | that's the one |
| 15:43 | dagda1_ | ha right, maybe the penny just dropped |
| 15:43 | raek | sdegutis: I found it useful to learn about the basic concepts and their syntax. (I came from Clojure and Standard ML.) |
| 15:43 | hellofunk | justin_smith: yep that's what i was looking for |
| 15:43 | sdegutis | raek: :) |
| 15:43 | sdegutis | I'm probably going to turn into one of those Haskell people for some reason. |
| 15:44 | raek | it doesn't teach you how to "think in Haskell", but I found it useful as a reference manual |
| 15:44 | sdegutis | Probably a lot because of callen's testimony: http://bitemyapp.com/posts/2014-04-29-meditations-on-learning-haskell.html |
| 15:45 | amalloy | i mean, haskell is pretty cool. you don't have to become "a haskell person". you can enjoy both |
| 15:45 | turbofail | unless you're callen |
| 15:45 | raek | sdegutis: both Clojure and Haskell are nice languages... you don't have to abandon one for the other |
| 15:46 | hellofunk | sdegutis: i am quite enamoured with the theories of math and how they intersect with programming, and haskell seems to be the great example of that. Even Sussman thinks haskell is the "greatest of the obsolete languages" (he thinks all programming languages today will soon be obsolete) |
| 15:46 | dysfun | i don't think he's wrong |
| 15:47 | dysfun | do you think we'll still be writing code in 20 years? |
| 15:47 | hellofunk | dysfun: i do. |
| 15:47 | dysfun | i do not |
| 15:47 | justin_smith | people still use lisp, fortran, and cobol, three of the oldest languages |
| 15:48 | turbofail | 20 years isn't all that much time for such a drastic change in how we control computers |
| 15:48 | hellofunk | turbofail: exactly. now, 200 years, that's a different bet |
| 15:48 | dysfun | once we figure out how we can get rid of bizarre languages and communicate more clearly with the computer, development will improve apace |
| 15:48 | hellofunk | dysfun: i doubt that will happen in just 20 years |
| 15:48 | dysfun | we'll see :) |
| 15:49 | tbaldridge | to put it into perspective, Python has been around for 24 years. |
| 15:49 | hellofunk | and the origins of computing itself, as a theory and idea, are approaching a century old now. |
| 15:49 | nuwanda_ | dysfun: we'll be maintaining a bunch of code bases we're creating now in 20 years :) imho |
| 15:49 | hellofunk | well, the modern idea of computing, anyway |
| 15:50 | stuartsierra | Haven't people been predicting the demise of programming languages ever since the invention of programming? |
| 15:50 | dysfun | nuwanda_: that too :) |
| 15:50 | hellofunk | stuartsierra: much like the constant exaggerated claims every few years across all of time about the impending doom or mystiquie of AI. recently there was another spattering of high profile claims. it's ridiculous. |
| 15:51 | dysfun | stuartsierra: moore's law held for long enough that it's possible |
| 15:51 | sdegutis | hellofunk: dunno who sussman is but ok |
| 15:51 | hellofunk | sdegutis: you heard of SICP? |
| 15:51 | sdegutis | oh yeah |
| 15:51 | hellofunk | sdegutis: he's an author of that. MIT professor. quite influenctial. |
| 15:51 | sdegutis | i imagine that guy loves dynamic typing then |
| 15:51 | hellofunk | sdegutis: he's a big fan of haskell, but clearly his background is much in lisp. |
| 15:52 | sdegutis | i imagine he wants a more dynamic, lispy haskell then |
| 15:52 | tbaldridge | I would sit and listen to Sussman for hours if I had the chance. |
| 15:52 | hellofunk | sdegutis: no, you're not going far enough. |
| 15:52 | dysfun | or a more typesafe lisp |
| 15:52 | dysfun | (which is what i want) |
| 15:52 | sdegutis | meh, i have no love for macros |
| 15:52 | hellofunk | no he thinks all manner of computing today is very far from the ideal power that could be available. |
| 15:52 | tbaldridge | Any man who is both an expert programmer and an expert watch maker is pretty awesome IMO. |
| 15:53 | dysfun | preferably with a touch of slightly clearer syntax on top. haskell does a reasonable job there |
| 15:53 | sdegutis | tbaldridge: easy there buddy, hes just a human like you and me |
| 15:53 | hellofunk | tbaldridge: let's not forget his prowess with electronics |
| 15:53 | sdegutis | ;) |
| 15:53 | tbaldridge | yeah, that too. |
| 15:54 | noonian | you can find the sicp lectures on youtube, sussman is very fun to listen to because he's always excited about what he's teaching |
| 15:54 | hellofunk | noonian: i just watched one of this recently, my first. in the beginning i was like, "who is this cliche wearing a pocket protector and flip-up glasses?!" then i realized who he was and was like, dang, son, i'm gonna go get me a pocket protector imminently! |
| 15:55 | noonian | hellofunk: lol |
| 15:58 | dysfun | i never saw a need for a pocket protector anyway, but then by the time i grew up, we'd stopped using slide rules |
| 15:58 | dysfun | we did use fountain pens, but it was such a rare ocurrence to get a leak... |
| 15:59 | noonian | i never knew what a pocket protector protected one from until this moment |
| 16:01 | dysfun | these days noone carries a pen anymore |
| 16:02 | ordnungswidrig | dysfun: the pocket protector picure at wikipedia is weird. |
| 16:04 | puredanger | Sussman took the Haskell workshop when he did the keynote at Strange Loop (iirc it was Bryan O'Sullivan teaching) |
| 16:04 | puredanger | paraphrasing, he said "those people are weird" |
| 16:05 | dysfun | ordnungswidrig: why? because it's got a tux on it? |
| 16:07 | ordnungswidrig | dysfun: absolutly. I only know them blank and "reluctant" |
| 16:08 | dysfun | pretty sure if you wore a pocket protector at my old school you'd've had your head kicked in |
| 16:09 | ordnungswidrig | I still use a fountain pen but never carry it in a shirt pocket. I had no accident ever. |
| 16:16 | samiswellcool | I carry a whole case of pens |
| 16:16 | samiswellcool | and my current notebook and my last notebook |
| 16:27 | aaelony | I'm confused by clj-time: (clj-time.coerce/from-long (long 1418813990)) gives me #<DateTime 1970-01-17T10:06:53.990Z>, but http://www.epochconverter.com gives me GMT: Wed, 17 Dec 2014 10:59:50 GMT (which is correct) for the same value. |
| 16:30 | justin_smith | aaelony: is from-long doing a ms or ns conversion? |
| 16:30 | justin_smith | try adding three zeroes to the end |
| 16:30 | chouser | ,((get get get get) (get get get get) (get get get get) 5) |
| 16:30 | clojurebot | 5 |
| 16:30 | justin_smith | lol |
| 16:30 | aaelony | justin_smith: thank you. |
| 16:30 | aaelony | that works now |
| 16:34 | Glenjamin | ,(def get out) |
| 16:34 | clojurebot | #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:34 | sssilver | Hey guys, what does this Clojure snippet calculate? Any clue? (defn fact [n] (reduce * (range 1 (inc n)))) |
| 16:34 | sssilver | let me rephrase that... does that look like a correct implementation of factorial? |
| 16:34 | amalloy | hellofunk, did you notice http://stackoverflow.com/questions/28131135/how-to-implement-zip-with-foldl-in-an-eager-language ? |
| 16:35 | amalloy | sssilver: try it on a few numbers and see? |
| 16:35 | justin_smith | sssilver: it would take 1 through n inclusive, and take each item in that list and multiply it by the previous total (starting with 1*2) |
| 16:35 | sssilver | amalloy: I don't have clojure on my machine |
| 16:35 | amalloy | ,(map (fn fact [n] (reduce * (range 1 (inc n)))) (range 1 8)) |
| 16:35 | clojurebot | (1 2 6 24 120 ...) |
| 16:36 | amalloy | &(map (fn fact [n] (reduce * (range 1 (inc n)))) (range 1 8)) |
| 16:36 | lazybot | ⇒ (1 2 6 24 120 720 5040) |
| 16:36 | amalloy | there is an abundance of online clojure evaluators, for example http://www.tryclj.com/ if you want to play around without installing anything |
| 16:37 | sssilver | cool, thanks guys |
| 16:39 | Glenjamin | hrm, my mobile friendly PR got merged, but it doesn't look like tryclj is updated yet |
| 16:41 | Glenjamin | amalloy: i'm really confused by that answer, foldl :: (a -> b -> a) -> a -> [b] -> a - but the answer has 3 args to the folding function |
| 16:41 | amalloy | Glenjamin: it's folding up into another function |
| 16:41 | amalloy | ie, the accumulator is itself a function |
| 16:41 | Glenjamin | oh |
| 16:42 | amalloy | a ~ (c -> d) |
| 16:42 | Glenjamin | aha, so it is |
| 16:42 | Glenjamin | i find it really annoying having haskell arguments not named >.< |
| 16:42 | amalloy | what do you mean? |
| 16:43 | justin_smith | Glenjamin: aka point free style? |
| 16:43 | Glenjamin | (a -> b -> a) -> a -> [b] - took me a min to figure out which was which |
| 16:44 | Glenjamin | and yeah, the point free doesn't help massively, i only just realised the ys is applied to the folded function |
| 16:44 | Glenjamin | oh, and so is the (const []) |
| 16:45 | amalloy | well this like...isn't point-free style at all |
| 16:45 | Glenjamin | well, as i think about it more, the lack of parens is my problem |
| 16:45 | amalloy | he could have even removed the 'ys' argument, since applying it at the end is unnecessary: zip1 xs = ... (const []) |
| 16:46 | Glenjamin | which is odd really, as i learnt haskell before any lisps |
| 16:48 | amalloy | the translation of that haskell to clojure is not really made more readable by all the parens: https://www.refheap.com/37b61066156c2265969b7dd89 |
| 16:48 | Glenjamin | haha |
| 16:49 | Glenjamin | i think separating the reduce into a function from the unrolling would help |
| 16:49 | Glenjamin | in the haskell version also |
| 16:50 | tbaldridge | amalloy: this is the code for the "multi arity map" thing from the other day, right? |
| 16:50 | amalloy | tbaldridge: yeah |
| 16:50 | amalloy | well, this is the implementation of zip, which is "the hard part" of multi-arity map |
| 16:51 | tbaldridge | from what I saw of the haskell code the other day, aren't they just turning the second collection into nested closures? If so, then why not use lazy-seqs? |
| 16:52 | amalloy | tbaldridge: my goal in finding this was to refute the claim that you can't do multi-arity map as a reduce. i'm not claiming this is a good implementation of zip that you would actually use |
| 16:53 | amalloy | i don't totally see how you would use lazy seqs instead of these nested closures; you can't really be lazy anyway, when you're reducing |
| 16:53 | hellofunk | amalloy: i'm glad to see you are still thinking about this. i spent the weekend reading about foldl and foldr and really understanding them as much as i can. i was thinking about continuing our conversation on that but am not well enough versed yet |
| 16:53 | hellofunk | amalloy: lots of old threads on the clojure mailing list about this, of which you participated, some going back five years |
| 16:54 | amalloy | haha, do share. i don't remember most of the things i said |
| 16:54 | Glenjamin | i'm not sure that this nested closure solution is really different from the (reverse) |
| 16:54 | hellofunk | my general motivating factor, a theoretical musing perhaps, is the notion of a higher level to HOFs |
| 16:54 | Glenjamin | doesn't it still effectively do two traversals? |
| 16:56 | amalloy | well uh...probably. i can't really tell what's going on tbh |
| 16:56 | amalloy | but it's all one big fold! that was all i was after |
| 16:57 | tbaldridge | amalloy: I always assumed multi-arity map could be done like this: https://www.refheap.com/96507 |
| 16:57 | hellofunk | amalloy: i agree, the idea of folding in general, at the purest level, excites me, especially when a fold can be the composite of many folds, all of which have the same higher structure to each |
| 16:59 | amalloy | tbaldridge: that does seem a lot simpler |
| 16:59 | amalloy | though you want to replace [[] ys] with [[] (seq ys)] |
| 16:59 | tbaldridge | I don't think one is better than the other TBH. They both transverse twice, they both do allocation during reduction. |
| 16:59 | sdegutis | Is it bad practice to use :otherwise in a cond instead of :else? |
| 16:59 | sdegutis | (as the last case) |
| 16:59 | Glenjamin | dammit tbaldridge, i was just typing that |
| 17:00 | Glenjamin | but mine doesn't work yet :) |
| 17:00 | justin_smith | sdegutis: I prefer :YOLO |
| 17:00 | Glenjamin | (inc justin_smith) |
| 17:00 | lazybot | ⇒ 172 |
| 17:00 | sdegutis | justin_smith: whence all dat karma bruh |
| 17:01 | amalloy | justin_smith: hyphenated keyword-haiku |
| 17:01 | justin_smith | sdegutis: I stole it when technomancy wasn't looking |
| 17:01 | samiswellcool | Would you recommend just using clojure.test to write tests? |
| 17:01 | hellofunk | amalloy: unless it's me, the word "zip" seems quite overloaded |
| 17:01 | sdegutis | Too bad about him, up and leaving #clojure like that. |
| 17:01 | justin_smith | samiswellcool: yeah, clojure.test is good |
| 17:01 | amalloy | (cond x y, a b, :Light-of-the-moon-Moves-west-flowers-shadows-Creep-eastward "not found") |
| 17:02 | justin_smith | (inc amalloy) |
| 17:02 | lazybot | ⇒ 216 |
| 17:02 | Glenjamin | i had https://www.refheap.com/96508 |
| 17:02 | Glenjamin | took me 3 goes to remember that i needed the & to destructure |
| 17:04 | amalloy | tbaldridge: do you mind if i post your clojure solution as another answer to that SO question? or you can do so yourself |
| 17:05 | tbaldridge | amalloy: please do |
| 17:06 | zacts | ooh, I want to make an RPG game too |
| 17:06 | Glenjamin | is there a strong reason to prefer first/next vs [x & xs] ? |
| 17:06 | zacts | but mine will be simple |
| 17:07 | hellofunk | amalloy: further to the point is the recent article i read somewhere about how foldl and foldl' are both expressable as foldr, making foldr the higher level |
| 17:07 | amalloy | hellofunk: sure. you can also express foldr as foldl, if you don't mind giving up laziness |
| 17:09 | hellofunk | amalloy: no, the opposite. foldl as foldr |
| 17:09 | amalloy | hellofunk: right, i mean you can go either way |
| 17:09 | amalloy | but if you implement foldr using foldl you can't be lazy |
| 17:11 | hellofunk | amalloy: the other issue that got me curious is the idea of the consumer function. it should be able to evolve during the folding to create interesting patterns. like the consumer is feeding back on itself as a minifold within the larger fold |
| 17:19 | amalloy | tbaldridge: http://stackoverflow.com/a/28159764/625403 |
| 17:23 | amalloy | hellofunk: try picking up haskell, then. it's less hard if you already understand functional programming, although still foreign enough to teach you some new ways of thinking |
| 17:24 | hellofunk | amalloy: the syntax makes my eyes hurt |
| 17:24 | amalloy | hellofunk: complaining about that makes you a big baby, if you'll pardon my rudeness. people say the same thing about lisp all the time and clojure folks scoff at them |
| 17:25 | amalloy | surface syntax is an easy thing to complain about, but not terribly important |
| 17:25 | hellofunk | amalloy: fair enough, but it's still true. after staring at lisp all day, when you see haskell my eyes aren't trained to know where the expressions are delinieated |
| 17:25 | amalloy | sure. i had the same problem too, sometimes still do. the solution is practice, like with anything else |
| 17:25 | metellus | hellofunk: isn't that something you'd get over pretty quickly as you used the language? |
| 17:26 | hellofunk | sure, but i don't use it, but as an example comparison, i also don't use java, having never written a line of it in my life, but somehow java is straightforward to read while haskell, well, my ignorance hurts my eyes |
| 17:27 | turbofail | i still have trouble making sense of scala syntax sometimes |
| 17:27 | turbofail | actually i have more of a problem with writing scala than reading it |
| 17:27 | hellofunk | i feel like i have been spoiled by lisp syntax |
| 17:28 | turbofail | it's often not clear to me why something i've written in scala is a syntax error |
| 17:29 | tcrayford____ | anybody got any idea why ring.util.codec/url-encode doesn't encode "," as "%2C" ? |
| 17:29 | amalloy | tcrayford____: why would it? |
| 17:30 | tcrayford____ | because , isn't a valid url part according to compojure haha :( |
| 17:30 | hellofunk | amalloy: just came across this and interestingly turbofail you are quoted in it: https://gist.github.com/hellofunk/a1582981ecafa6b36e63 |
| 17:30 | tcrayford____ | aka /some-user-defined-path had a "," in it, and compojure just 404s haha |
| 17:30 | amalloy | well, it depends what part of a url, right. like it's valid in a query, but not in a path part |
| 17:31 | tcrayford____ | right |
| 17:31 | amalloy | hellofunk: i mean, java is like super inexpressive: there is a ton of redundant information, lots of whitespace, and a very regular structure |
| 17:32 | tcrayford____ | amalloy: is there a better alternative to url-encode from ring.util.codec for encoding path-parts? |
| 17:32 | turbofail | ah yeah i remember that discussion |
| 17:32 | turbofail | that was in #emacs |
| 17:33 | hellofunk | amalloy: do you have a tip for a quality quick start read in haskell? i can't invest much time but would like to get to the heart of the basics in a hurry without leaving serious parts out |
| 17:33 | amalloy | tcrayford____: actually , is valid in a path part. i was just assuming that it's not because you are having trouble with it |
| 17:33 | uptown | hello out there. i'm trying to retrofit midje into a project which had no tests but despite creating the correct diretory tree, "lein midje :autotest" doesn't find my tests. when autotest starts, it logs loading the source ns but not the test ns. has anyone run across this? i can't find the configuration magic... |
| 17:33 | amalloy | if compojure is having trouble serving routes with a , in them, you might just need to adjust what regex it uses in GET |
| 17:33 | tcrayford____ | amalloy: guess this is actually a problem with clout then :/ |
| 17:34 | tcrayford____ | amalloy: no regex haha |
| 17:34 | tcrayford____ | just :thingy |
| 17:34 | amalloy | tcrayford____: i mean, it uses a regex to match this stuff |
| 17:34 | amalloy | and you can customize what regex is used |
| 17:35 | tcrayford____ | amalloy: got a pointer to that? (this is literally a production bug for an customer) |
| 17:36 | amalloy | i think it's just (GET ["/pages/:foo" :foo #"[\w_,]+"] ...) |
| 17:37 | amalloy | but see https://github.com/weavejester/clout/blob/master/src/clout/core.clj#L108 for details, and note that the stuff after the url in a vector there gets mushed into a hashmap and passed to route-compile |
| 17:37 | amalloy | and of course use a different regex |
| 17:38 | tcrayford____ | ta |
| 17:38 | amalloy | it looks like https://github.com/weavejester/clout/blob/master/src/clout/core.clj#L91 incorrectly excludes , from the characters it's willing to match in a path |
| 17:40 | amalloy | $mail weavejester it looks like https://github.com/weavejester/clout/blob/master/src/clout/core.clj#L91 incorrectly excludes , from the characters it's willing to match in a path, given the characters that are allowed in a path (see http://stackoverflow.com/a/4669755/625403 for one listing of such) |
| 17:40 | lazybot | Message saved. |
| 17:40 | amalloy | i guess i should make a github issue but...irc is so nice |
| 17:40 | tcrayford____ | I'm filing |
| 17:45 | tcrayford____ | see https://github.com/weavejester/clout/issues/23 |
| 17:45 | tcrayford____ | amalloy: ^^ |
| 17:45 | tcrayford____ | thanks btw |
| 17:46 | amalloy | tcrayford____: did the suggested workaround work? |
| 17:46 | tcrayford____ | not tried it yet |
| 17:47 | amalloy | hellofunk: LYAH is pretty great. a bit slow but fun |
| 17:47 | tcrayford____ | think I'm just gonna wrap up my own encoder that escapes , |
| 17:54 | tcrayford____ | amalloy: I'm unsure why compojure/ring even do their own url munging regex stuff :/ |
| 17:54 | tcrayford____ | java has url encoding stuff in the stdlib |
| 17:56 | amalloy | well, clout has to understand the urls |
| 17:56 | amalloy | and java.net.url is pretty dreadful |
| 17:58 | amalloy | but even if you built a url successfully and called getPath on it, you'd *still* need to parse out the path parts, which is the code that's currently not working |
| 17:58 | tcrayford____ | ah, gotcha |
| 18:00 | samiswellcool | I feel like I'm relying too heavily on loop and recur |
| 18:01 | amalloy | you're probably not wrong, samiswellcool |
| 18:06 | amalloy | with some examples somebody could help you rewrite, but in general you probably should be using reduce or lazy sequences most of the time |
| 18:10 | samiswellcool | I'm new enough to clojure that 'it works' is enough of a motivator for now, but I'm going through what I've done so far every now and again and refactoring parts away from recurring loops |
| 18:20 | Glenjamin | amalloy: is anything about loop..recur particularly worse than using reduce? |
| 18:21 | amalloy | Glenjamin: well. is anything better about map than writing for (i = 0; i < xs.size(); i++) {xs.get(i).whatever();}? reduce has the bookkeeping logic already written for you, so it doesn't muddy up the particular thing you're doing |
| 18:22 | Glenjamin | ah right, makes sense |
| 18:22 | Glenjamin | i was thinking they were equivalent, but forgetting you still need to split head/tail when loop ing |
| 18:27 | tbaldridge | also, reduce is much faster for vectors and reduce-kv is faster for maps |
| 18:27 | tbaldridge | less allocation that way |
| 18:44 | eriktjacobsen | Ok Macro wizards! I have a recurive macro problem… Since the failure conditions aren’t known at expansion time, I understand why I get a stack overflow error… I’m having trouble visualizing how to break this apart though… helper functions? some sort of loop-recur inside the macro? http://pastebin.com/Th2uB2gU |
| 18:45 | eriktjacobsen | the macro itself splits the first argument on thrown error into two smaller groups and runs them separately. I want that process to continue until it is running singles… but if I try to wrap the macro around each half-call, obviously it breaks. |
| 18:46 | eriktjacobsen | I’m still starting with macros, so visualizing how to break that into a helper function while maintaining what is a symbol, what is evaluated and what returns as a list is fuzzy for me |
| 18:49 | amalloy | so this doesn't look like a macro problem at all, eriktjacobsen |
| 18:49 | amalloy | you just want a function that takes a function and some args |
| 18:50 | amalloy | (defn split-retry [f main-args more-args] (try (apply f main-args more-args) (catch Exception e (if whatever (split-retry f (first-half-of main-args) more-args))))) |
| 18:52 | eriktjacobsen | My first intention was there was already a ton of code, so wanted something I could just wrap things… but if I did your way I could still make macro that just passed the body into that fn… yeah I way overcomplicated that |
| 18:52 | eriktjacobsen | Thanks. Got stuck in the weeds |
| 18:54 | hellofunk | eriktjacobsen: it is a right of passage in clojure/lisp, the abuse of macros when you first learn the language. |
| 18:54 | hellofunk | that should be "rite" |
| 19:07 | Glenjamin | that code sample is making me imagine a brute force macro |
| 19:08 | Glenjamin | which keeps modifying the input until it stops throwing exceptions |
| 19:09 | Raynes | If you put monkeys in a room with typewriters, eventually they'll produce Shakespeare |
| 19:10 | Glenjamin | i saw a toy language once that deleted your code if it errored |
| 19:10 | Glenjamin | like, from the disk |
| 19:10 | Glenjamin | https://github.com/munificent/vigil |
| 19:11 | amalloy | Glenjamin: https://github.com/mattdiamond/fuckitjs |
| 19:11 | Glenjamin | the support section is a nice touch |
| 19:25 | eriktjacobsen | Glenjamin: Unfortunately, that is not far from the truth. I also have some code that randomly picks dates between 2005 - 2008 to get around same issue…. Its a google API, fyi |
| 19:26 | eriktjacobsen | It randomly fails without any error messaging, even on same input… even with retries. Totally inconsistent, a list of ids that failed today for several hours would work the next day, etc |
| 19:47 | {blake} | Running under Windows (have to test IE) I find that access is denied when I try to open any port with "lein ring server". Python and Smalltalk can open ports with no difficulty. |
| 19:48 | {blake} | Could it be a Java thing? |
| 19:51 | rplevy | Any thoughts on alia vs cassaforte? They seem pretty similar. |
| 19:51 | {blake} | (Running in a corporate environment and situation suddenly changed, so suspecting some kind of remote administration shenanigans, but want to make sure.) |
| 19:56 | {blake} | Crap. It's ONLY Clojure? How is that even possible? |
| 20:07 | Glenjamin | {blake}: check your firewall settings |
| 20:08 | {blake} | Glenjamin: Local firewall isn't running. I can open the port (3000) with Java, Python, Smalltalk. |
| 20:08 | amalloy | {blake}: what is some actual code you are running and what is it doing |
| 20:08 | Glenjamin | that's the extent of my windows knowledge i'm afraid. Maybe check java security settings? |
| 20:09 | amalloy | nobody wants to play twenty questions to narrow down all possible network failures, when you have a specific failure in front of you |
| 20:09 | {blake} | Glenjamin: Weirdly, I just threw up a Java server and it works just fine. |
| 20:09 | {blake} | amalloy: I'm running "lein new compojure app". |
| 20:10 | {blake} | I get "Started server on port 3000" followed immediatel by "Exception in thread "main" java.io.IOException: Failed to open http://localhost:3000/. Error message: Access is denied." |
| 20:38 | insamniac | {blake}: You have no windows network security things running? |
| 20:40 | insamniac | and has your hosts file been investigated? |
| 20:52 | R0B_ROD | Evening! |
| 20:52 | R0B_ROD | Is the 540MB NetBeans IDE worth it at all for clojure?? |
| 20:52 | lazybot | R0B_ROD: Definitely not. |
| 20:53 | R0B_ROD | Ok thanks lazybot |
| 20:53 | amalloy | *chuckle* |
| 20:53 | justin_smith | R0B_ROD: for IDE experience, I think cursive with intellij idea is likely the best right now |
| 20:53 | R0B_ROD | Total newbie here |
| 20:53 | amalloy | bots make some funny conversations. i dunno if netbeans is any good, but you probably shouldn't blindly take lazybot's advice |
| 20:53 | justin_smith | would lazybot every answer yes to two question marks?? |
| 20:53 | lazybot | justin_smith: What are you, crazy? Of course not! |
| 20:54 | amalloy | lazybot: if your friends jumped off a bridge, would you do it too??? |
| 20:54 | lazybot | amalloy: Yes, 100% for sure. |
| 20:54 | amalloy | i love this guy |
| 20:54 | turbofail | what about now?? |
| 20:54 | lazybot | turbofail: Uh, no. Why would you even ask? |
| 20:54 | R0B_ROD | am I brainacid?? |
| 20:54 | lazybot | R0B_ROD: What are you, crazy? Of course not! |
| 20:54 | R0B_ROD | am I brainacid? |
| 20:54 | R0B_ROD | ... |
| 20:54 | TEttinger | brainacid??? |
| 20:54 | lazybot | TEttinger: Oh, absolutely. |
| 20:56 | R0B_ROD | Sure??? |
| 20:56 | lazybot | R0B_ROD: Yes, 100% for sure. |
| 20:56 | R0B_ROD | lazybot: You are correct! |
| 20:57 | R0B_ROD | Well since I dont know what Im getting into yet, I have LightTable for now. Havent 'really' used it yet. |
| 21:09 | elarson | Is there a let* clojure? |
| 21:10 | justin_smith | elarson: let already acts like common lisp let* |
| 21:10 | elarson | ah ok, thanks! |
| 21:10 | justin_smith | ,(let [a 0 b (inc a) c (inc b)] c) |
| 21:10 | clojurebot | 2 |
| 21:20 | gfredericks | ,(def x 5.975884771000674E307) |
| 21:20 | clojurebot | #'sandbox/x |
| 21:21 | gfredericks | ,(Math/toRadians x) |
| 21:21 | clojurebot | 1.0429886497374912E306 |
| 21:21 | gfredericks | ,(Math/toDegrees (Math/toRadians x)) |
| 21:21 | clojurebot | Infinity |
| 21:21 | gfredericks | ,(* 2 x) |
| 21:21 | clojurebot | 1.1951769542001347E308 |
| 21:21 | gfredericks | ^ x is not close to the max double |
| 21:23 | gfredericks | huh; the javadocs say both methods are "generally inexact" |
| 21:25 | Blake2 | insamniac: The security's all taken care of elsewhere. But I haven't checked the HOSTS file out, maybe I fiddled with it. Thanks! |
| 21:26 | Blake2 | Which is sort of like "funny lookin' in a general sort of way". |
| 21:39 | dweave | I’m trying to better understand how macros should be used. It seems like most advice is something like “Macros should be avoided whenever possible”. It’s always POSSIBLE. Right? A prime example is probably compojure. Couldn’t routes be defined using types implementing a ‘view’ interface much the same way we do in rails/django type frameworks. |
| 21:40 | dweave | why do compojure and other libraries chose to use macros for these types of things |
| 21:40 | elarson | I'm positive this is a dumb question, but... are there some functions for reading from a file handle? specifically I'm looking at reading the input stream from a java Process object and wanting to write to the input. |
| 21:40 | dweave | elarson slurp |
| 21:41 | elarson | dweave: I'll take alook |
| 21:41 | elarson | *a look |
| 21:41 | TEttinger | (doc slurp) |
| 21:41 | clojurebot | "([f & opts]); Opens a reader on f and reads all its contents, returning a string. See clojure.java.io/reader for a complete list of supported arguments." |
| 21:41 | justin_smith | slurp works if you want to block until the stream closes |
| 21:41 | justin_smith | if you want to read output from a proc as it is available, you want to do something different than slurp |
| 21:41 | oskarkv | elarson also maybe take a look at http://clojuredocs.org/clojure.java.io |
| 21:42 | elarson | justin_smith: right, that would be my concern. |
| 21:42 | elarson | oskarkv: that looks much closer to what I was thinking. Thanks! |
| 21:43 | justin_smith | if it's a fairly long running process, to get output as it is available, you can use the .read method on the thing and read into a buffer |
| 21:43 | justin_smith | I don't think anything in clojure.java.io will help with that |
| 21:44 | elarson | justin_smith: that should be OK. I'm just checking for a password prompt |
| 21:44 | justin_smith | ahh - yeah password prompt means you definitly want .read, since even an abstraction like line-seq would fuck that up (prompt does not end with a newline) |
| 21:45 | elarson | I'm assuming that something like (.write (clojure.java.io/writer (:in proc) "hello")) would work as expected |
| 21:45 | justin_smith | elarson: you would also want to flush it (usually newline flushes but I am not as sure about process input) |
| 21:46 | elarson | justin_smith: ok, that is also something I was thinking might be necessary :) |
| 21:46 | amalloy | so uh, i have to say that doing this from clojure by hand looks a lot harder than using `expect` or something |
| 21:47 | elarson | justin_smith: btw, thanks for consistently responding to my questions. I hope they aren't so obvious as to assume I'm avoiding RTFM |
| 21:48 | elarson | amalloy: I'll take a look at `expect` as well |
| 21:48 | justin_smith | I still think about making an expect like tool in clojure sometimes |
| 21:56 | amalloy | i expect that the best part of writing your own expect variant would be all the wordplay options it opens up |
| 22:06 | oskarkv | dweave I'm not familiar with compojure. Could you provide another example? :P |
| 22:14 | TimMc | expclject |
| 22:15 | TimMc | ecjpectl |
| 22:15 | amalloy | TimMc: that sounds like a botched magic spell |
| 22:17 | TimMc | ajjume |
| 22:18 | amalloy | now you're just typing sneezes |
| 22:18 | TimMc | all the best library names happen that way |
| 22:18 | TimMc | also |
| 22:18 | TimMc | &(format "lib-%04d" (rand-int 1e4)) |
| 22:18 | lazybot | ⇒ "lib-6971" |
| 22:32 | notbrent_ | if you happen to be in vancouver, canada, i'm organizing a clojure/clojurescript meetup on feb 5 at 6pm to try to revive the meetup group: http://www.meetup.com/Vancouver-Clojure/events/220103236/ |
| 22:56 | jonh | /close |
| 22:58 | dnolen | Om contributions welcome, just me an email to request a CA https://github.com/swannodette/om#contributing |
| 22:58 | dnolen | er, "just send me" |
| 23:00 | TEttinger | I'm glad the clojure community is so friendly |
| 23:11 | mercwithamouth | can anyone tell me if the clojure for the brave book offers more than the web version? |
| 23:12 | mercwithamouth | i've planned on buying it just to support...he gives an excellent introduction... |
| 23:17 | puredanger | afaik, it's same content. but you could just ask Daniel, he is a friendly guy. :) He's @nonrecursive on Twitter. |
| 23:18 | mercwithamouth | puredanger: ok. either way purchasing...it's a really enjoyable book... |
| 23:20 | mercwithamouth | also the web development lispcast package...does anyone know what sort of app he makes? |
| 23:30 | szatz | It seems like it is more idiomatic to access map elements with the key preceding the map, such as (:some-key some-map), but Clojure also proudly totes complex keys. Isn't this preceding key problematic because it could clash with an external function name? |
| 23:30 | justin_smith | szatz: :some-key cannot clash with a function name |
| 23:30 | justin_smith | it is a keyword |
| 23:31 | szatz | Well... You can use things that aren't :-prefixed as keys, too, is what I'm getting at. |
| 23:31 | justin_smith | no |
| 23:31 | justin_smith | not as lookup |
| 23:31 | justin_smith | well, OK symbols work, but nothing else |
| 23:31 | justin_smith | szatz: clojure decides what to invoke based on what is next to the open paren |
| 23:31 | justin_smith | :keyword invokes get |
| 23:32 | justin_smith | 'symbol will too |
| 23:32 | justin_smith | but a function will be called |
| 23:32 | justin_smith | ,(seq {seq 1}) |
| 23:32 | clojurebot | ([#<core$seq__4091 clojure.core$seq__4091@2d973d4f> 1]) |
| 23:33 | justin_smith | ,({seq 1} seq) |
| 23:33 | clojurebot | 1 |
| 23:33 | szatz | Hmm... OK, so ("justin" {"justin" "smith"}) is invalid, but ({"justin" "smith"} "justin") is fine, yet the former is more idiomatic, were it to use a key instead. Does that sound about right? |
| 23:34 | amalloy | szatz: you only look up keywords that way |
| 23:34 | justin_smith | szatz: if your keyword is a literal, put it in the first position |
| 23:34 | amalloy | see http://stackoverflow.com/a/7037211/625403 for a philosophical answer |
| 23:34 | justin_smith | ,('or-symbols '{or-symbols true}) ; but this is more rare |
| 23:34 | clojurebot | true |
| 23:36 | alexyakushev | ,('nowai '{nowai jezaz}) |
| 23:36 | clojurebot | jezaz |
| 23:36 | alexyakushev | Who ever does that? |
| 23:36 | justin_smith | alexyakushev: nobody, but it is worth knowing about because it makes a specific error message easier to understand |
| 23:37 | justin_smith | ,('+ 1 2 3) |
| 23:37 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: Symbol> |
| 23:37 | justin_smith | ,('+ 1 2) ; or lack of error message... |
| 23:37 | clojurebot | 2 |
| 23:38 | alexyakushev | Yes, that thing I remember reading somewhere |
| 23:38 | szatz | justin_smith, amalloy: Thanks for the info! |
| 23:39 | amalloy | i actually have ('foo x) in the source file i have open right now |
| 23:40 | justin_smith | first I've heard of using it intentionally |
| 23:40 | amalloy | i can't remember doing it very many other times, but sometimes a map wants symbols for keys, and when it does, you might as well look them up that way |
| 23:40 | justin_smith | fair enough, yeah |
| 23:41 | alexyakushev | only because of the cognitive gap I would use (get...) in that case |
| 23:41 | alexyakushev | takes everyone to new symbol semantics to immediately grasp what's going on |
| 23:41 | alexyakushev | s/new/know/ |
| 23:53 | szatz | Another question if you guys are still around; In ClojureScript, since it's single-threaded, I'm guessing the main benefit of using reducers would be the lack of intermediate collections from a chain of higher-order functions. Is there much more to it than that? |
| 23:54 | amalloy | szatz: that's the main benefit on the jvm too. parallel fold is a fringe benefit really |
| 23:56 | szatz | Ahh, OK, because the parallelization isn't always guaranteed (associativity required), but the removal of intermediates is, right? |
| 23:56 | amalloy | plus, most of the reducing you do is actually on small collections *anyway* |
| 23:57 | justin_smith | it's also that the overhead of going parallel can be smaller than the gains it provides (with smaller inputs in particular) |
| 23:57 | amalloy | like you reduce over a four-item map, or a vector with a couple dozen items |
| 23:57 | justin_smith | err, s/smaller/bigger |
| 23:57 | amalloy | man i tried subbing out the wrong "smaller", got even more confused |
| 23:58 | justin_smith | amalloy: notice that there was no /g - only subbing the first instance |
| 23:58 | amalloy | yeah but i refuse to believe that anyone does that on purpose |
| 23:59 | szatz | Right, right. You guys are handy. Thanks again. |