#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

Logging service provided by n01se.net