#clojure log - Jan 26 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:00 tomjack: one extension point I discovered: (defmethod core.match/emit-pattern-for-syntax [:foo :default] ...)

0:01 then (match x (:foo y) :ok)

0: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 .

0:04 justin_smith: tomjack: clojure.set/difference

0:04 here's how you can find it ##(apropos "difference")

0:04 lazybot: ⇒ (difference)

0:05 justin_smith: erg... it behaves better in newer versions, heh

0:05 (actually shows the full ns)

0:05 tomvolek: thanks

0:07 justin_smith: yeah, with 1.7.0-alpha4 I see the whole ns with apropos

0:07 &*clojure-version*

0:07 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

0:08 justin_smith: ,*clojure-version*

0:08 clojurebot: {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}

0:17 brainacid: I have installed lein, LightTable and jvm and looking through The Joy of Clojure

0:17 ~book

0:17 clojurebot: book is books

0:17 brainacid: ~book

0:17 clojurebot: book is http://www.pragprog.com/titles/shcloj/programming-clojure

0:19 brainacid: ~book

0:19 clojurebot: book is http://www.pragprog.com/titles/shcloj/programming-clojure

1: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

1:19 EvanR: adios

1:19 justin_smith: jinagarano: the end of your question was cut off, because the question was too long

1:19 jinagarano: justin_smith: where did it cut off?

1:19 justin_smith: ; and teachers will have an address and contact details, bu

1:20 jinagarano: but no emergency contacts.

1: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

1: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.

1:27 justin_smith: jinagarano: I believe so, with h2 at least

1:27 maybe korma has something higher level that you want to use though

1:29 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

1:29 since having one refering id on each would not suffice, of course

1:30 jinagarano: from korma docs:

1:30 ;; Relationships

1:30 (has-one address)

1:30 ;; assumes users.id = address.users_id

1:30 (has-many email)

1:30 ;; assumes users.id = email.users_id

1:30 ;; but gets the results in a second query

1:30 ;; for each element (belongs-to account)

1:30 ;; assumes users.account_id = account.id

1:30 (many-to-many posts :users_posts))

1:30 ;; assumes a table users_posts with columns users_id

1:30 ;; and posts_id

1:30 ;; like has-many, also gets the results in a second

1:30 ;; query for each element

1:30 justin_smith: jinagarano: do not do that

1:30 use a paste site like refheap.com, or provide a link to the source on github

1:30 please

1:31 jinagarano: ok sure, sorry

1:31 i think i know how to do it now, thanks

1: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

1:31 cool

1:32 jinagarano: but do notice that those are query functions - they assume those tables / fields I mentioned above exist already

1:32 but yeah, you should have a clear idea of how to make those columns / tables now

1:49 jinagarano: how do i set up ragtime and h2 for migrating?

1: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

1:53 https://github.com/weavejester/ragtime/wiki/Getting-Started just use the apropriate jdbc url

2: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?

2: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

2:07 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

2: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

2:12 justin_smith: drorbemet: there is a function to insert an ns declaration

2:12 and that is automatic based on the file name

2:13 drorbemet: justin_smith: oh, there is?! great

2:22 justin_smith: cljr-refactor contains an example, cljr-move-form is what I was looking for, thanks

3: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

3:07 SagiCZ1: zacts: little schemer perhaps?

3:07 zacts: hum.. yeah I own that book, but I'm thinking something more textbook style, yet still down to earth

3:07 SagiCZ1: down to earth as in easy to understand?

3:07 zacts: yeah

3:07 perhaps not quite so academic as SICP

3:07 SagiCZ1: i liked this one http://shop.oreilly.com/product/0636920013754.do

3:07 codestorm777: functional thinking, maybe

3:07 zacts: I hope to get through SICP, but that might take months to digest

3:08 codestorm777: is that a book?

3:08 SagiCZ1: oh cool, yeah I plan to read that too

3:08 codestorm777: yes, o’reilyy, it’s also a video series

3:08 zacts: oh neat. I'll check it out

3:09 SagiCZ1: the oreily book has some thoughts about how to make your programs more abstract shown on examples

3:10 zacts: oh cool

3:13 hm.. I can't wait until the grokking functional programming by manning press is out

3:13 that's kind of what I'm looking for

3:13 exactly too

3:13 clojurebot: I don't understand.

3: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

3:43 acron^: morning

3:43 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

3:43 slipset: depends on your timezone, I guess

3:44 SagiCZ1: acron^: i also have morning.. good morning

3:44 acron^: :)

3:44 good [morning|afternoon|evening] then...just in case

3: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

3:45 (doc take)

3: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."

3:45 SagiCZ1: like this

3:45 acron^: ahh

3:45 (defn foo [x]

3:45 "comments here"

3:45 slipset: lines 19 and 26, pull out in functions?

3:46 SagiCZ1: ,(defn foo [x] "comments" x)

3:46 clojurebot: #'sandbox/foo

3:46 acron^: got it

3:46 SagiCZ1: also consider putting the arg list on a new line if it is longer.. depends on your taste though

3:46 acron^: slipset: you mean separate it more?

3:47 slipset: also, I'm not to enthused about prefixing functions as in "fae", but YMMV

3:47 acron^: is there a convention?

3:47 slipset: acron^:yes especially the anon-function in line 26. Imagine you wanted to test that...

3:47 acron^: i guess all the funcs are namespaced so no need for a prefix >

3:48 Glenjamin: isn't it docstring before arglist? i always get mixed up :s

3:48 slipset: acron^: I kind of like writing functions so that I can do the following:

3:48 SagiCZ1: Glenjamin: docs after arglist

3:48 Glenjamin: ,(doc foo)

3:48 clojurebot: "([x]); "

3:48 acron^: whats the 'feel' on anon functions? good? bad?

3:48 SagiCZ1: slipset: i wouldnt extract that.. if it is the only place where he uses it.. he could test the whole function

3:48 slipset: ,(map (partial + 1) [1 2 3])

3:48 clojurebot: (2 3 4)

3:48 SagiCZ1: acron^: they are perfectly idiomatic

3:48 Glenjamin: ,(defn foo "comments" [x] x)

3:48 clojurebot: #'sandbox/foo

3:48 Glenjamin: ,(doc foo)

3:48 clojurebot: "([x]); comments"

3:48 Glenjamin: it's docstring before arglist.

3:49 acron^: :o

3:49 SagiCZ1: Glenjamin: indeed.. my bad

3:49 acron^: ,(defn bar [x] "test" x)

3:49 slipset: SagiCZ1:I would, since then I could give the funciton a name, which kind-of documented what it did.

3:49 clojurebot: #'sandbox/bar

3:49 acron^: ,(doc bar)

3:49 clojurebot: "([x]); "

3: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..

3:50 slipset: That way I didn't have to try to figure out what (assoc

3:50 (:attrs %)

3:50 :desc (:alt (:attrs (first (:content %))))) was trying to achieve

3:50 SagiCZ1: slipset: in this case it would help i guess

3:51 slipset: :)

3:51 acron^: on line 43, I have a dissoc and and assoc

3:51 is there a better way to reformat a dict?

3:51 SagiCZ1: acron^: yeah i dont like that line very much.. try to keep the line shorter

3:51 slipset: acron^: in line 43 you deffo want a ~doseq

3:52 ~do-seq

3:52 clojurebot: It's greek to me.

3: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.

3:52 SagiCZ1: ~doseq

3:52 slipset: ~doseq

3:52 clojurebot: doseq is like for, but for side effects instead of values

3:52 doseq is like for, but for side effects instead of values

3:52 slipset: Thanks SagiCZ1,

3:52 acron^: hmm]

3:52 SagiCZ1: hellofunk: yeah actually i would prefer if i could comment each arity separately..

3:52 slipset: anyways, the println in 43 will not print the whole thing since map is lazy

3:53 SagiCZ1: slipset: print forces the evaluation

3:53 acron^: not sure I understand do-seq but I'll have a play

3: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.

3:53 SagiCZ1: ,(println (map inc (range 99)))

3:53 clojurebot: (1 2 3 4 5 ...)\n

3:54 SagiCZ1: hellofunk: yeah but then i have to specify all the arities in the one docstring

3: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.

3:54 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.

3:55 slipset: and SagiCZ1 is of course totally correct wrt println, my bad

3:55 SagiCZ1: hellofunk: makes sense.. okay

3: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.

3:56 acron^: ahhh

3:56 i get it

3:57 :)

3:57 slipset: in fae-get-image-from-image-page

3:57 could you just continue your threading?

3:57 clojurebot: Excuse me?

3: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

4: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.

4:04 acron^: slipset: can you expand on that?

4:06 slipset: (s/id "content-image"))

4:06 page)

4:06 (first)

4:06 :attrs

4:06 :data-src)

4:08 also, in line 15, you could use def and comp, I guess, instead of defining your own function.

4:09 TEttinger: slipset: defn has the advantage of being able to add a docstring

4:09 not sure if you can do that with comp

4:10 slipset: (def fae-get-list-page (comp get-page-as-hickory format))

4:11 or is it the other way around, I can never remember

4:12 ~def

4:12 clojurebot: excusez-moi

4:13 TEttinger: ,(doc def)

4:13 clojurebot: Titim gan éirí ort.

4:13 slipset: ,(def ted-nugent "The nuge rocks" 123)

4:13 clojurebot: #'sandbox/ted-nugent

4:13 TEttinger: (doc def)

4:13 clojurebot: Cool story bro.

4:13 TEttinger: ha

4:13 ,ted-nugent

4:13 clojurebot: 123

4:13 TEttinger: ,(doc ted-nugent)

4:13 clojurebot: "; The nuge rocks"

4:13 TEttinger: nice

4:14 acron^: ,(doc comp)

4: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."

4:14 acron^: aha

4:15 slipset: I guess the threading macros and comp are somewhat related in terms of functionality

4:15 acron^: just to be totally clear

4:15 -> is a threading macro ?

4:15 zilti: slipset: But threading macros work left-to-right

4:15 SagiCZ1: acron^: yes

4:15 slipset: but since the threading macros, are well, macros, you can't pass them around

4:16 like you can with functions

4:16 zilti: slipset: you could pass around #(-> % whatever fns (you use))

4:16 acron^: so whats the impact of using a thread procedurally like in fae-get-image-from-image-page, line 33?

4:16 TEttinger: ,(apply str (map (comp char (partial + 64)) [3 1 20]))

4:16 clojurebot: "CAT"

4:17 acron^: it's explicitly lazy?

4: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

4:18 slipset: acron^: I'm on a bit of deep water here, but line 33 gets rewritten at compile time.

4:18 acron^: TEttinger: unsurprising, I'm a C programmer, new to Clojure :)

4:18 TEttinger: heh

4:18 slipset: ,(-> 1 (+ 3))

4:18 clojurebot: 4

4:19 slipset: gets rewritten by the macro expander to

4:19 ,(+ 1 3)

4:19 clojurebot: 4

4:19 acron^: slipset: this code is adapted from hickory examples so I guess I dont see the benefit of the thread here

4:19 zilti: ,(macroexpand-1 '(-> 1 (+ 3)))

4:19 slipset: at compile-time, not at run time

4:19 clojurebot: (+ 1 3)

4: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

4:19 TEttinger: ,(-> 1 (/ 3))

4:19 clojurebot: 1/3

4:19 TEttinger: ,(->> 1 (/ 3))

4:19 clojurebot: 3

4:20 acron^: SagiCZ1: ah, that's an important detail

4:20 TEttinger: good to know about ->> , which puts the threaded arg in the last position

4:20 zilti: slipset: It's important to note though that macros *are* available at runtime

4:20 slipset: there is also some-> which is quite nice

4:20 SagiCZ1: acron^: threading as in putting a thread through the needle.. i guess you are not native speaker?

4:20 TEttinger: SagiCZ1, it tripped me up too the first time I heard of a threading macro

4:21 acron^: SagiCZ1: not native clojure speaker :) i just assume threading/threads means OS threads/coroutines

4:21 assumed*

4: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

4:22 acron^: ,(-> 10 (- 5))

4:22 clojurebot: 5

4:22 acron^: ,(->># 10 (- 5))

4:22 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ->># in this context, compiling:(NO_SOURCE_PATH:0:0)>

4:22 acron^: ,(->> 10 (- 5))

4:22 clojurebot: -5

4:22 zilti: ,(macroexpand-1 '(->> 10 (- 5)))

4:22 clojurebot: (- 5 10)

4:23 acron^: ,(macroexpand-1 '(-> 10 (- 5)))

4:23 clojurebot: (- 10 5)

4:23 acron^: magic

4:23 SagiCZ1: acron^: also check out 'doto' which is commonly used with java interop

4:23 zilti: ,(source ->) ; I wonder if that works

4:23 clojurebot: Source not found\n

4:23 SagiCZ1: (source ->)

4:24 acron^: guys, you've been really helpful thanks

4:25 slipset: https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L1558

4:25 alexyakushev: Like Heisenberg said to Hank when he used too many parentheses: "Thread lastly"

4:25 Or was it "Tread lightly"? We'll never know

4:26 * SagiCZ1 chuckles quietly

4: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

4:28 acron^: thanks slipset, I shall

4:29 SagiCZ1: i always think whether i should use partial.. when the #( .. ) construct takes much less space..

4:29 partial is also sensitive to the arg order..

4:29 Glenjamin: partial doesn't generate a class, if that's important to you

4:29 SagiCZ1: #() does?

4:30 slipset: SagiCZ1: http://blog.jayfields.com/2011/01/clojure-partial-and-comp.html

4:30 crap, wrong link

4:30 SagiCZ1: http://blog.jayfields.com/2013/05/emacs-lisp-font-lock-for-clojures.html

4:30 SagiCZ1: beware of your clipboard!

4:31 slipset: l guess I was lucky this time.

4:31 SagiCZ1: re arg order, I tend to like to build my functions such that they fit with partial

4: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

4:32 slipset: yeah.. 3rd party fn dont always work well though..

4:32 slipset: having said that, I really wish there was a (reverse-args f) function in clojure

4:34 Glenjamin: (defn reverse-args [f] (fn [&args] (apply f (reverse args))))

4:35 slipset: Glenjamin: cool! stuff is so simple in Clojure

4: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

4:38 slipset: SagiCZ1: I don't think I've hardly written a loop in Clojure, apart from in a, well, go-loop

4:38 SagiCZ1: slipset: wow.. well you need to teach me your ways

4:38 acron^: i doubt anyone here can claim to be the perfect programmer SagiCZ1 :)

4:38 slipset: SagiCZ1: :)

4:39 SagiCZ1: slipset: loops like this give me trouble https://www.refheap.com/96481

4:40 clgv: SagiCZ1: seems to be more of an `iterate` - but there is no eager version of `iterate`

4:41 ah well recursion itself ;)

4:41 Glenjamin: could write as (reduce) using (reduced), but (loop) seems fine for that

4:41 SagiCZ1: Glenjamin: well.. thats the thing.. is the loop fine or should i always try to get rid of it?

4:41 Glenjamin: is it causing you a problem at the moment?

4:42 SagiCZ1: nope

4:42 Glenjamin: then i'd say it's fine

4:42 SagiCZ1: i just dont want to anger clojure gods

4:42 clgv: SagiCZ1: if you have that patternmore often you can write a fitting higher order function

4:43 SagiCZ1: clgv: function or a macro?

4:43 clgv: SagiCZ1: depends on the details, probably function

4:44 slipset: SagiCZ1: you got me, I'm not even clever enough to see what this is doing.

4:44 SagiCZ1: slipset: it just executes steps updates w and b.. and when e (error) is zero it exits

4:48 slipset: SagiCZ1: would something like (take-while p (partition 3 (repeatedly (partial rand-int 3))))

4:49 be something you could imagine?

4:49 where p is your step and if-test combined?

4:50 SagiCZ1: possibly

4:50 thanks for the idea

4:52 clgv: SagiCZ1: though you will sacrifice speed by rewriting the loop with lazyseq

4:52 SagiCZ1: so there is not much to gain apart from maybe having nicer,, shorter code

4:53 clgv: yeah, but then try `iterate` with a surround `take-while`

4:53 *surrounding

4: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

4:55 clgv: SagiCZ1: I just recommeded it since it matches the semantics of your snippet pretty closely

4:55 SagiCZ1: clgv: yep.. true

5: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?

5: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.

5: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?

5:45 jinagarano: zacts: yes, that's the point.

5:45 samiswellcool: jinagarano: defentity is in korma.core

5:45 zacts: jinagarano: ah cool

5: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.

5:46 samiswellcool: just another use statement (use 'korma.core)

5:46 or in your namespace (ns whatever.whatever (:use korma.core))

5:47 jinagarano: samiswellcool: brillitant, thanks. does a dependency get the files from github/wherever, and make them available in my project?

5:49 samiswellcool: it gets them from clojars I think, but basically yes

5:49 then you have to include them as needed in individual files

5:51 TEttinger: zacts: I think clojure is compatible with anything that supports Java 6 or higher. Might be as low as 5.

5:51 zacts: TEttinger: cool

5:51 I'm just curious how well it runs on FreeBSD / OpenBSD

5:51 I'm considering switching OS on one of my laptops

5:52 TEttinger: almost certain it will run there, not sure if you have access to an Oracle JDK on there

5: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.

5:52 zacts: TEttinger: I usually use OpenJDK

5:52 is that fine for clojure?

5:52 TEttinger: yep!

5:52 zacts: ok neat! :-)

5: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

5:54 it's a total hack but does work fine with OpenJDK

6:08 clgv: TEttinger: zacts: it is Java 6 for Clojure 1.6

6:08 zacts: oh cool

6:08 clgv: the versions before 1.6 required only Java 5

6:17 Glenjamin: TEttinger: sounds similar to capsule

6:17 TEttinger: probably!

6:17 Packr is meant for games, primarily

6:17 Glenjamin: oh, not quite

6:17 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."

6:18 TEttinger: "Java 9 is expected to have a mechanism for packaging stripped-down versions of the JVM."

6:19 interesting

7: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

7:17 Glenjamin: $source future-cancel

7:17 lazybot: future-cancel is http://is.gd/Z4YWxl

7:18 Glenjamin: welp, that wasn't very helpful

7:19 SagiCZ1: i was thinking that it probably needs Thread.yield() somewhere to be able to cancel itself..

7: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

7: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

7:20 clgv: SagiCZ1: you need some predicate (keep-running? ...) in your processing loop

7:20 SagiCZ1: clgv: no other way? thats just awful.. why cant jvm just kill the thread

7:21 clgv: SagiCZ1: just google that, there are a lot of discussions ;)

7:22 SagiCZ1: the magic of clojure could ease the pain. you write a `stopable` macro that does the check almost transparently.

7:22 SagiCZ1: clgv: yeah.. or maybe use the deprecated stop() method

7:23 clgv: SagiCZ1: and achieve nothing?

7: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..

7:24 cfleming: SagiCZ1: You want your code to catch InterruptedException, generally

7:25 SagiCZ1: Then whatever is doing the stopping can interrupt your thread and you can handle it gracefully.

7:25 SagiCZ1: cfleming: would it raise the exception? i though i would need to check isInterrupted() ..

7:25 my future code is already wrapped in try catch and doesnt throw any exception when i call future cancel

7: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.

7:26 SagiCZ1: cfleming: yeah i am not using any concurrency primitives

7:26 cfleming: SagiCZ1: Sure, but Clojure is on your behalf.

7:26 SagiCZ1: well thats just such a bummer.. i thought clojure would have some better mechanism to deal with this madness

7:26 clgv: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt%28%29

7:27 cfleming: seems that exception is just thrown in pretty specific cases

7: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..

7: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.

7:29 clgv: cfleming: the tight loop scenario seems to be the use case of SagiCZ1

7: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.

7: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

7:31 cfleming: SagiCZ1: http://stackoverflow.com/questions/13623445/future-cancel-method-is-not-working

7:31 SagiCZ1: And http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

7:31 SagiCZ1: cfleming: so if i added Thread/yield everywhere it should throw the exception?

7:32 yield is basically 0ms sleep

7:33 nope.. doesnt throw exception

7:33 cfleming: SagiCZ1: I would check the thread interrupted flag

7:33 SagiCZ1: and then throw the exception?

7:33 cfleming: Or exit your loop, or whatever you need to do, yeah

7:33 clgv: SagiCZ1: from the javadoc of yield "It is rarely appropriate to use this method."

7:34 SagiCZ1: well that javadoc can bite me!

7:34 :D

7:34 clgv: SagiCZ1: the remaining description suggest that it is not what you want anyway

7:34 SagiCZ1: (Thread/sleep 0) works.. if i call future-cancel it throws sleep interrupted exception which i can handle

7:35 so just add the sleep to every task and it should work

7: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

7:35 SagiCZ1: Seriously, just check the interrupted flag and throw the exception

7:35 That's what it's for

7:36 SagiCZ1: okay.. i can wrap that into a function so thats ok

7:36 cfleming: Using Thread/sleep will have other effects that you may not want, like affecting the scheduler

7:36 SagiCZ1: thank you very much guys..

7: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.

7:37 SagiCZ1: cfleming: I am learning clojure so I could avoid Java convoluted concurrency mechanisms..

7:37 cfleming: SagiCZ1: The first five chapters (IIRC) give a great background.

7:37 SagiCZ1: but i guess i will have to learn it one day

7:37 cfleming: SagiCZ1: Yeah, but sometimes you just have to know what's going on

7:39 clgv: SagiCZ1: You have to embrace the host platform my young padawan. ;)

7:40 SagiCZ1: clgv: hehe :)

7:40 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

7:43 cfleming: SagiCZ1: Yeah, it should be possible to use code folding for that

7:43 SagiCZ1: what is that?

7:44 cfleming: SagiCZ1: To be honest though, it's going to be a very low priority since I've never really seen the point

7:44 SagiCZ1: cfleming: yeah i thought so

7: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<~>()

7:46 SagiCZ1: oh i know what that is.. ok

7: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

7:46 SagiCZ1: so they'll be hidden, but you can click or hover to see them

7:47 SagiCZ1: cfleming: yeah thats a great idea with the task traces..

7: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.

7:51 SagiCZ1: cfleming: understandable

7:52 clgv: cfleming: does cursive provide a plugin api? then he could implement it himself...

7:52 SagiCZ1: cursive is meant to be stand-alone.. so maybe then

7: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.

7:58 slipset: SagiCZ1: You've probably considered it, but how 'bout using core.async to solve your problem

7:58 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

7: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

7:59 slipset: cool!

8: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.

8:22 Empperi: HOLY SHIT http://www.itworld.com/article/2875112/ibm-is-about-to-get-hit-with-a-massive-reorg-and-layoffs.html

8:23 IBM fires 111 800 people by the end of February

8:23 and no, that number is not a typo

8:24 hyPiRion: "IBM fires 1/3 of Iceland"

8:25 Empperi: those numbers are just staggering

8:25 several cities are going to shake with their economies after this

8:25 hyPiRion: Is IBM mainly located in the US?

8:26 Glenjamin: i'm aware of lots of UK offices

8:26 Empperi: it's very much global company

8:26 xemdetia: hyPiRion, hardly.

8:26 Empperi: there are several offices in Finland too

8:27 hyPiRion: Then it's probably not as bad of a hit for the cities

8:27 Empperi: really?

8:28 when Lehman Brothers bancrupted 26k people lost their jobs

8:28 that with the debt fiasco led to current economic situation

8:28 no four times more people gets fired at once

8:28 that's going to have some serious impact into economy world wide unless those people find new jobs and fast

8:29 hyPiRion: Well, I'm hanging out in #clojure, not #economics. Go figure :p

8: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

8:29 SagiCZ1: Empperi: IBM is all over the world

8:29 Empperi: SagiCZ1: that's what I said?

8:29 SagiCZ1: Empperi: so the impacted is spreaded out

8:30 milions of people lose their jobs every year

8:30 Empperi: yes but not at once and on one industry at the same time

8:30 SagiCZ1: i doubt couple thousand people losing their jobs caused global economic crisis

8:30 xemdetia: Empperi, IBM is not a stranger to deep cuts like that.

8:30 Empperi: yes, they hold the previoius record

8:31 daniel___: its the apocalypse

8:31 Empperi: if there's some people here working for IBM I feel for you guys

8:32 zacts: ok, back to clojure now

8: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

8:32 Glenjamin: ah :(

8:32 Empperi: old mainframe guys, storage unit etc

8:33 business-wise a good move

8:33 SagiCZ1: IBM's services are expensive and useless nowadays.. this was to be expected

8:33 Empperi: but the impact will be felt, badly

8:33 SagiCZ1: yeah

8:33 SagiCZ1: Empperi: doubt it.. maybe locally in the specific areas

8:33 Empperi: their attempts to become a cloud provider have been abysmal

8:34 but yeah, back to clojure now.

8:34 that was just such a huge news I wanted to share it here

8:44 oh, btw to the IBM news: "Most of the layoffs will happen in the US, but some international operations will be affected as well"

8:44 http://www.cultofmac.com/310012/ibm-prepares-largest-corporate-layoff/#uqtJmQqlX00Ar9kG.99

8:44 hyPiRion: alright, that might be pretty bad

8:45 Empperi: most likely the worst hit is centered around few US cities

8:46 yguan: trying to be familiar with core.async. why should the following fail?

8:46 cfleming: https://news.ycombinator.com/item?id=8944999 "Cringely has made dooms day predictions in the past that were widely innacurate"

8:46 yguan: (let [c (chan)]

8:46 (go

8:46 (print (<! c)))

8:46 (go

8:46 (let [f (fn [v]

8:46 (>! c v))]

8:46 (f "ab")))

8:46 (Thread/sleep 100)

8:46 (close! c))

8:46 dnolen: yguan: use a pasting service please :)

8:47 SagiCZ1: yguan: replace thread/sleep with (<! (timeout 100))

8:47 tbaldridge: no, the issue is that you can't use >! and <! outside of a go

8:47 yguan: dnolen, ehh i'll figure out pasting :)

8:47 tbaldridge: and go blocks stop translating at any call to (fn [...] ....)

8:47 SagiCZ1: tbaldridge: he doesnt have them outside of go

8:47 oh

8:47 nvm\

8:48 yguan: tbaldridge, I see, feel a bit black magic here...

8:48 tbaldridge: there'

8:49 go blocks are basically nothing but black magic, elven herbs, and dwarven runes

8:50 gfredericks: stop blocks on the other hand just call System/exit, plain and simple

8:50 hyPiRion: those dwarven FSMs

8: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

8:51 dnolen: yguan: supporting only shallow yield is a pretty common thing actually

9:08 thheller: dnolen: whats the policy for upgrading closure compiler + library for CLJS? It's been about 6 months

9:09 dnolen: thheller: just someone testing it to make sure it doesn't break everything, it's happened before

9:09 thheller: more recent versions of Closure busted browser REPL, not sure if this has been addressed in a release

9:10 thheller: ok thx, will see if I can do some tests

9: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.

9:47 thheller: dnolen: why is the :externs key outside :foreign-libs? I think it should be coupled with the foreign-lib?

9: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

9:47 s/when/where/ - sorry

9: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

9: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

9:50 thheller: I don't have a problem with allowing :externs per lib but will need a patch for that

9:51 stuartsierra: _KryDos_: `future` returns a java.util.concurrent.Future, from which you can get the value returned by the code inside it.

9: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

9:51 stuartsierra: _KryDos_: `future` uses a thread from a cached thread pool which Clojure maintains internally.

9:51 thheller: dnolen: will see how far I get

9:52 dnolen: pretty sure some of the addons require their own externs. thats why I'm asking

9:57 _KryDos_: stuartsierra: thank you so much for the answer

9: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 :)

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 and like I said, if the thread was eg. blocking on a read, it would be stopped automatically as well

10:08 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 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 but now I see that is specific to wait, IO on InterruptibleChannel s and Selector

10:14 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 it works very well

13:00 zacts: I want to make a music composition app with clojure

13:00 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 also, how about ChucK?

13:01 justin_smith: it includes the signal processing stuff, and also higher level event processing too

13:02 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 it cheats by shipping supercollider in the jar :)

13:03 "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 like fractals / designs / etc..

13:07 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 zacts: https://processing.org/

13:09 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 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 something like (~meth ~obj ~val)

13:17 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 so like (. ~obj (~setter ~value))

13:20 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 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 * puredanger thought it'd be good fun

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 (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 (def r reflect/reflect pv)

14:15 f

14:15 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 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 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 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 hellofunk: I have written OOPS as an experiment, although I'm surprised I haven't yet deleted it

14:58 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 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 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 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 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 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 ok

15:08 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 try and keep as much as possible in clojure space, not java space

15:09 and bear in mind that most java data are mutable and require mutation to do things, rather than returning altered copies

15:10 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 ,(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 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 * llasram disbelieves dysfun

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 I'll call it yet another editor editor

15:14 (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 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 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 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 all depends on what you need.

15:23 zacts: ok neat

15:25 clojure reinvents the wheel, but it reinvents it to be a hovercraft

15:25 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 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 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 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:41 * raek wonders if you could implement modules as data in System F...

15:42 hellofunk: dagda1_: well obvious they are opposite tests

15:42 justin_smith: dagda1_: they are opposite conditions

15:42 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 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 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 (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 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 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 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 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 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 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 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 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 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 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 and yeah, the point free doesn't help massively, i only just realised the ys is applied to the folded function

16:44 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 i think separating the reduce into a function from the unrolling would help

16:49 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 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 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 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 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 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 (as the last case)

16:59 Glenjamin: dammit tbaldridge, i was just typing that

17:00 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 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 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 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 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 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 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 amalloy: no regex haha

17:34 just :thingy

17:34 amalloy: tcrayford____: i mean, it uses a regex to match this stuff

17:34 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 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 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 $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 see https://github.com/weavejester/clout/issues/23

17:45 amalloy: ^^

17:45 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 amalloy: I'm unsure why compojure/ring even do their own url munging regex stuff :/

17:54 java has url encoding stuff in the stdlib

17:56 amalloy: well, clout has to understand the urls

17:56 and java.net.url is pretty dreadful

17:58 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 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 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 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 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 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 you just want a function that takes a function and some args

18:50 (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 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 that should be "rite"

19:07 Glenjamin: that code sample is making me imagine a brute force macro

19:08 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 like, from the disk

19:10 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 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 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 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 amalloy: I'm running "lein new compojure app".

20:10 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 and has your hosts file been investigated?

20:52 R0B_ROD: Evening!

20:52 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 ...

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 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 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 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 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 *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 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 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 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 * elarson also hopes that syntax is kind of close to correct as well ;)

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 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 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 also

22:18 &(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 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 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 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 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 not as lookup

23:31 well, OK symbols work, but nothing else

23:31 szatz: clojure decides what to invoke based on what is next to the open paren

23:31 :keyword invokes get

23:32 'symbol will too

23:32 but a function will be called

23:32 ,(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 ,('+ 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 takes everyone to new symbol semantics to immediately grasp what's going on

23:41 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.

Logging service provided by n01se.net