#clojure log - Aug 07 2015

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

0:28 batam: helloo,,,

2:56 hejki: ohai, how do I use literal '?' with jdbc queries? escaping does not seem to work, neither does using double ?.

3:05 ddellacosta: hejki: what are you using to connect to the DB? clojure.java.jdbc ?

3:05 hejki: clojure.java.jdbc yes

3:05 I am using PostgreSQL with jsonb-fields, and the syntax for checking json object key existence is: json_field_name ? 'keyname'

3:05 so I kinda need to pass the ? without appending any parameter values into it :P

3:06 with a quick glance the lib seems to have no support for "unprepared" statements and/or skipping parameter binding

3:07 ddellacosta: hejki: you should be able to do something like ["INSERT INTO foo (a, b) VALUES (?, ?)" "this" "that"] I believe

3:08 passing that into execute

3:08 hejki: ddellacosta: yes, that works fine, what I cannot do is: ["SELECT COUNT(json_field ? 'somekey') FROM table"]

3:09 ddellacosta: oh sorry, I misunderstood--you want to pass the value '?' in?

3:09 hejki: ddellacosta: so what I want is to tell java.jdbc that the ? in the statement is literal ?, not placeholder for parameter

3:09 yes

3:09 ddellacosta: gotcha

3:09 hejki: maybe ["SELECT COUNT(json_field ? 'somekey') FROM table" "?"] works :D

3:10 ... it does not :<

3:10 ddellacosta: huh, maybe! Dunno if prepared statements make sense with a select, but...

3:10 ah

3:10 one sec

3:12 hejki: so, I just tried (j/query fdb ["SELECT E'?' as foo"]), and that worked

3:12 gave me ({:foo "?"})

3:12 hejki: ahh! :)

3:12 ddellacosta: maybe that'll work for you, like COUNT(json_field E'?' 'somekey') ?

3:13 hejki: y, I am currently testing

3:13 nah... PSQLException ERROR: syntax error at or near "'exception'"

3:13 ddellacosta: hmm, one sec

3:13 I think I have to be trying this on some json data to give you a useful answer

3:17 damn, I need 9.4 for this don't I

3:17 hejki: y

3:17 :P

3:18 ddellacosta: alright, well, I don't care about that actually, if I get the same psql error w/c.j.j then it should work for you

3:20 hmm, this appears to be a java issue actually

3:20 specifically org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet

3:20 not that that helps you. :-p

3:20 hejki: hehe :P

3:21 I kinda guessed it is java issue :P

3:24 ddellacosta: testing out a more recent postgres jar

3:24 this suggests it may be fixed already: http://postgresql.nabble.com/problem-with-pgjdbc-prepared-statements-and-new-jsonb-exists-operator-td5834634.html

3:27 hejki: hmm.. the mentioned version of postgresql lib is not available from clojars

3:28 ddellacosta: you can get it from maven

3:28 w00t, that did it for me

3:28 hejki: 1102 is available from clojars, that should be even newer, testing that no

3:28 now*

3:29 ddellacosta: (j/query fdb ["SELECT '[\"foo\", \"bar\", \"baz\"]'::jsonb ?? 'bar'"])

3:29 PSQLException ERROR: type "jsonb" does not exist

3:29 this is what I have in my project.clj for postgres: [org.postgresql/postgresql "9.4-1201-jdbc41"]

3:29 that works

3:30 anyways, hopefully that does what you need--good luck!

3:30 hejki: same version, still getting PSQLException No value specified for parameter 1.

3:30 ddellacosta: that's the same exception you were getting before?

3:31 hejki: yes, nvm my version was 1102 :P

3:31 testing the 1201

3:31 ahh

3:31 yes

3:31 !

3:31 \o/

3:31 it works

3:31 ty alot

3:31 ddellacosta: sweet!

3:31 glad you got it working

3:31 hejki: yup, have to use double ? though

3:31 ddellacosta: yeah, may be stuck with that for now

3:32 hejki: that is actually tolerable imo

3:32 since it is quite special case

4:11 supersym: Is there a way (like in F#) that I can choose what data from a defrecord to output when printing? I am using one as a storage for blobs of text but it clutters my entire screen making it harden to sift through data

4:11 (just need to keep it to inspect the original texts when something goes wrong)

4:15 Kneiva: supersym: Like this? http://stackoverflow.com/a/3689364/1790621

4:17 supersym: Kneiva: exactly! Thanks for the reference

4:23 Kneiva: np

4:26 slhsen: Hey, anyone used https://github.com/hugoduncan/clj-ssh before? I got a question about it.

5:15 cmarques: Hi, I'm reading through https://github.com/technomancy/leiningen/wiki/Faster, which lists different ways of making leiningen boot faster. However, it's hard to know pros and cons of each strategy. What would be a good general strategy for faster boot time when using leiningen? Thanks!

5:30 kwladyka: i found interesting article about performance in Clojure, just sharing with you http://www.learningclojure.com/2013/02/clojure-is-fast-is-clojure-still-fast.html :)

5:40 jkogut_gs: kwladyka, eeee "Sorry, the page you were looking for in this blog does not exist. "

5:41 oddcully: not true

5:41 loads for me at least

5:42 jkogut_gs: hmmm

5:43 kwladyka: it works for mee

5:43 :)

5:45 jkogut_gs: ok, few times refresh and works

6:24 kwladyka: haha i solved it!!! so many days of work and solve it! So happy, i am going rest :)

6:25 eaz4Ohfi: kwladyka: I have no idea what are you talking about, but congrats anyway :)

7:45 namra: ah strange things :/

7:46 tests run fine, and manual http request via curl throws a cryptic exception :/

8:04 kungi: namra: cryptic?

10:30 hefesto: Good morning :) When I try to use the CIDER repl I get an "java.io.FileNotFoundException: Could not locate clj_antlr/core__init.class or clj_antlr/core.clj ..." error, but using the lein repl works fine. Does anyone know why?

10:40 chouser: hefesto: can you (require 'clj-antlr.core) in the lein repl?

10:40 hefesto: yes

10:41 i even use a function from clj-antlr and it returns the expected

10:42 chouser: and thank you for responding :)

10:45 chouser: hm, maybe paste your project.clj in a gist or something? Anything weird in your .lein/profiles.clj?

10:50 akabander: ?

10:50 hefesto: chouser: I've never used gist. I hope i did it right: https://gist.github.com/hhefesto/0aa1a57bb6120b03ff16

10:50 expez: Has anyone written a lein plugin yet which converts a cljc based lib to an artifact containing only clj and cljs files? I'd like to use cljc, but I don't want to force consumers to use 1.7...

10:56 puredanger: that is effectively what cljx does

10:58 or rather that takes a source template and spits out new source files. doesn't exactly solve this problem, just mean it has the right shape.

11:12 chouser: hefesto: Hm, looks pretty vanilla. I don't really have any explanation. Are there any other errors during cider-jack-in, prior to the FileNotFound?

11:15 hefesto: chouser: It magically got resolved. I'm sorry. I have no idea how. I just called cider-jack-in from project.clj rather than from my src file and it now works.

11:15 chouser: I think if someone needs to apologize, it's not you. :-) Glad it's working for you now.

11:16 hefesto: thank you so much anyway :)

11:17 chouser: np

12:12 {blake}: Is it fair to say "cons always returns a list"? I know there are different classes that might be returned, but they're all broadly "lists" (versus, say, vectors).

12:12 justin_smith: ,(list? (cons :a nil))

12:12 clojurebot: true

12:13 justin_smith: ,(list? (cons :a []))

12:13 clojurebot: false

12:13 justin_smith: ,(type (cons :a []))

12:13 gfredericks: {blake}: if you relax "list" to "seq" then yes

12:13 clojurebot: clojure.lang.Cons

12:13 justin_smith: ,(seq? (cons :a []))

12:13 clojurebot: true

12:14 justin_smith: it's casual friday for lists, they can relax today

12:14 {blake}: gfredericks: So, I guess the question is, is it wrong to do so? Even though it's pretty common to be casual about the word, it could trip you up.

12:15 My "lists" are all in hawaiian shirts and shorts today.

12:18 gfredericks: {blake}: depends on the linguistic context

12:19 Ch3ck_: I'm kinda confused between learning Erlang and Clojure, can anyone just give me some opinions on why I clojure might be the future?

12:19 {blake}: gfredericks: Yeah. There's the other, sorta M. Night Shyamalan side of this: A ha! You never noticed that when I said "list" I meant actual lists, not sequences! That's not great eitehr.

12:21 justin_smith: Ch3ck_: if you want ultimate stability and rolling updates and highest possible availability, I'd go with erlang. If you want a modern language and number crunching speed while being good at concurrency, that would point to Clojure.

12:22 Ch3ck_: then of course there is syntax, ecosystem of libraries, etc. to consider

12:22 Ch3ck_: justin_smith, I like clojure because of it's intersection with Java and the JVM

12:22 justin_smith: yeah, that is a bonus - it's the real reason I can use Clojure at work

12:22 Ch3ck_: so was thinking it will help me some time in the future cover for Java's mistakes with JP

12:23 justin_smith: JP?

12:23 Ch3ck_: justin_smith, sorry FP

12:23 justin_smith: yeah, Clojure is good for that

12:23 Ch3ck_: justin_smith, any recommended books?

12:23 It's confusing looking at the list on stackoverflow ;)

12:24 A newbie might not know which one to choose

12:24 {blake}: Ch3ck_, justin_smith: Yeah, me, too. POI FTW!

12:24 justin_smith: the O'Reilly clojure book is good. Clojure From the Ground Up and Clojure For the Brave and True are free online

12:25 Ch3ck_: thanks justin_smith. {blake} any suggestions too?

12:25 justin_smith: Ch3ck_: if you already have a lispy background (eg. common lisp or scheme experience), Joy of Clojure is excellent

12:25 oddcully: clojure applied tackles real world problems. might be missing in "old lists"

12:25 Ch3ck_: I have no experience with FP.

12:25 Clojure will be my first

12:25 {blake}: Ch3ck_: I don't like the books, although I'm going through Living Clojure right now and hoping it will be better.

12:26 Ch3ck_: Aight, will check justin_smith's recommendations

12:26 justin_smith: Ch3ck_: tbh I learned more about clojure by lurking here and following the conversation than anywhere else

12:26 {blake}: At least for me, I'd start reading one of these things, and there'd be 20 pages up front on Clojure's amazing destructuring capabilities, or some really deep abstraction stuff.

12:26 gfredericks: {blake}: I think technical contexts will always be that way; we don't have nearly enough words for our concepts so we overload them everywhere, and the only way to be sure you're communicating effectively is to clarify a bunch

12:26 {blake}: I managed by alternating between here, 4clojure, the books, and writing code.

12:27 gfredericks: Yes, there's some of that. But each language has its own frailties as far as it goes. Like, for Ruby, it's this gungho "Learn 15 DSLs 'cause Ruby is so easy and it all looks like English!"

12:27 Ch3ck_: Alright, guess. I'll be lurking here more often justin_smith {blake}

12:28 I don't know any programmer who codes in Clojure in my Country

12:28 justin_smith: {blake}: that reminded me of a great thing I heard today "familiarity will increase, but complexity is forever"

12:28 * Ch3ck_ likes the feeling of writing code programmers don't understand ;)

12:28 {blake}: I think FP's--and especially Clojure--"weakness" is that it's demanding. Algol-type languages are easy.

12:29 justin_smith: Yes! Just so.

12:29 justin_smith: Ch3ck_: haha, actually one bonus of Clojure is there is very little syntax, so it can take a bit more effort to really do things obscurely (though we know a few tricks)

12:29 {blake}: And I think the problem with clojure books is that it's hard to remember what it was like to NOT be familiar with things.

12:29 xemdetia: I think it is also important for clojure to at least know some rudimentary things about Java- going into clojure blind without any java background will be painful

12:30 {blake}: (Which is a problem with all tech books written by experts, but doubly so for Clojure.)

12:30 Ch3ck_: I code in Java xemdetia

12:30 justin_smith: {blake}: yeah, writing intro books is hard because memories of what was difficult as a beginner are very unreliable

12:30 Ch3ck_: my GSoC project is in java

12:30 xemdetia: well then at least you understand what the JVM has under the hood that you can call out to

12:30 akabander: Actually I'm using Clojure so I don't have to learn Java (syntax). I don't mind learning about the JVM.

12:30 {blake}: xemdetia: Might be. I think any OO experience is enough.

12:30 justin_smith: xemdetia: eh, it wasn't very painful for me (though I had used other OO languages)

12:31 xemdetia: I think enough java knowledge to be able to read a javadoc is sufficient

12:31 {blake}: justin_smith: Yep. I think I'm pretty good at it, if I say so myself. =P

12:31 Ch3ck_: justin_smith, Yeah

12:31 xemdetia: justin_smith, yeah that's all I was indicating

12:36 gfredericks: justin_smith: good quote

12:41 tmtwd: http://pastebin.com/1GRW3gwX can someone help we figure out how this reagent code is supposed to work?

12:41 *me

12:42 Ch3ck_: tmtwd, have your tried paste.kde.org? it's cleaner

12:42 tmtwd: https://paste.kde.org/p5kjvkgxa ok here you go

12:43 oddcully: tmtwd: onchange gets an event object

12:43 tmtwd: there was another pastebin alt that was awesome but I can't remember what its called

12:43 oddcully: then the code there basically in JS would look like: event.target.value

12:43 tmtwd: so how would I hardcode in a value so it always changes to that value?

12:44 oddcully: #(reset value "lerl")

12:44 tmtwd: oh I see

12:45 BinaryResult_: Hey everyone, we are hiring remote full-stack clojure developers, hope to hear from you! http://discomelee.com/jobs/

12:45 tmtwd: #(reset! value @value) so why can't I just do that?

12:47 oddcully: you can do that. but thats a noop

12:47 gfredericks: mostly

12:47 there's a race condition there where it might undo something else

12:47 but otherwise it's a noop

12:49 oddcully: can it? in javascript?

12:49 race i mean

12:49 tmtwd: oh I think I get it :)

12:50 gfredericks: oddcully: probably not then

12:55 sdegutis: Hi what's Clojure's version of the Haskell thing where you can use (< x) as a function?

12:56 gfredericks: #(< % x)

12:59 justin_smith: gfredericks: I think the retry behavior of atoms ensures that #(reset! % @%) is always a noop

12:59 gfredericks: retries man, I tell ya hwat

13:00 chouser: I don't think that's right. *goes off to test*

13:00 amalloy: justin_smith: no, it can undo something, like gfredericks says

13:01 gfredericks: justin_smith: no way man

13:01 justin_smith: it's (swap! a identity) that's always a noop

13:01 amalloy: if you time things wrong, then running (swap! a inc) and (reset! a @a) at the same time will result in a returning to its old value

13:01 justin_smith: oh, wait - does reset! do retries at all?

13:01 amalloy: no

13:01 justin_smith: aha, that was my mistake

13:01 amalloy: how could it? there's no computation to redo

13:02 justin_smith: d'oh, right

13:02 Bronsa: sdegutis: partial

13:04 sdegutis: Bronsa: partial can place unspecified arguments in arbitrary positions in a function call?

13:06 chouser: ,(let [a (atom 0), f (future (loop [] (reset! a @a)))] (dotimes [_ 1000] (swap! a inc)) (future-cancel f) @a)

13:06 clojurebot: #error {\n :cause "no threads please"\n :via\n [{:type java.lang.SecurityException\n :message "no threads please"\n :at [clojurebot.sandbox$enable_security_manager$fn__857 invoke "sandbox.clj" 94]}]\n :trace\n [[clojurebot.sandbox$enable_security_manager$fn__857 invoke "sandbox.clj" 94]\n [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkAccess nil -1]\n [java.lang.Threa...

13:06 chouser: aww

13:07 &(let [a (atom 0), f (future (loop [] (reset! a @a)))] (dotimes [_ 1000] (swap! a inc)) (future-cancel f) @a)

13:07 lazybot: java.lang.SecurityException: You tripped the alarm! future-call is bad!

13:07 justin_smith: chouser: thanks for the example

13:07 gfredericks: sdegutis: there's no precise syntactic analog; you can write functions/macros to do whatever you want, but nothing will be as succinct as #(...)

13:07 chouser: Oh well. Guess you have to run it yourself. Anyway, if (reset! a @a) were noop then that would always return 1000

13:08 justin_smith: right

13:08 chouser: For me, generally returns something between 850 and 900

13:08 justin_smith: I forgot that reset! never retries

13:08 returned 840 here

13:09 chouser: I actually thought reset did retry like (swap! a (constantly x)), but the (current) code says no: https://github.com/clojure/clojure/blob/1d5237f9d7db0bc5f6e929330108d016ac7bf76c/src/jvm/clojure/lang/Atom.java#L97

13:11 justin_smith: chouser: https://www.refheap.com/107873

13:11 I'm actually surprised at how many times it got the right answer, considering

13:12 chouser: nicely done

13:15 justin_smith: chouser: now I'm confused - that loop doesn't recur, so how does it reduce the total by that much...

13:15 also the version with a recur doesn't return because future-cancel can't cancel it because it doesn't hit a cancellable operation (needs a sleep I guess)

13:15 sdegutis: gfredericks: So #(...) is the transliteration of Haskell's sections?

13:17 justin_smith: if I throw in a (Thread/sleep 1) it behaves exactly like the one without a call to recur

13:19 gfredericks: sdegutis: #() is more general; haskell's syntax only works on binary operators I believe, which isn't a syntactic concept clojure even has

13:20 sdegutis: gfredericks: I didn't know Haskell has "binary operators". I thought they were just ordinary functions that have special permission to be called using infix notation.

13:21 chouser: justin_smith: ha, missed the loop! So the damage is caused entirely by a single reset!

13:21 gfredericks: sdegutis: that's what I meant, they're syntactically special

13:21 that's all I'm using "operator" to mean

13:21 chouser: which explains why sometimes it actually gets all 1000 -- when the reset! doesn't actually fire until after the dotimes is complete

13:21 sdegutis: gfredericks: Oh Nice Thanks.

13:21 justin_smith: chouser: paste updated with proof https://www.refheap.com/107873

13:25 amalloy: gfredericks: i mean you can partially apply either the first or second arg of any function in haskell by making it temporarily infix: filter ((0 ==) . (`mod` 5)) [1..20] == [5,10,15,20]

13:25 chouser: (let [a (atom 0), stop (atom false), f (future (loop [] (when-not @stop (reset! a @a) (recur))))] (dotimes [_ 5000] (swap! a inc)) (reset! stop true) (Thread/sleep 100) [f @a])

13:25 amalloy: so it does only work on infix functions, but those functions can have any number of args, and you can make anything inline if you want

13:26 justin_smith: chouser: the future-cancel works in your original if you add (Thread/sleep 1), that's enough to make the loop cancellable

13:26 chouser: ah, nice

13:26 amalloy: justin_smith: (Thread/yield)

13:26 justin_smith: amalloy: oh, sweet

13:26 (inc amalloy)

13:26 lazybot: ⇒ 289

13:27 amalloy: that's basically a (Thread/sleep 0) that doesn't waste time talking to the system clock or whatever

13:27 justin_smith: very cool

13:28 amalloy: this may be the first time in history anyone has called Thread/yield very cool

13:29 justin_smith: haha, I'm easily impressed

13:43 puredanger: (.join (Thread/currentThread)) ;; the sound of one thread deadlocking

13:53 chouser: heh

13:59 iamjarvo: so i am trying to get lein repl to use a newer version of nrepl right now it uses 0.2.6 from my understanding if i put [org.clojure/tools.nrepl "0.2.10"] in the dependencies in the project.clj it should use a newer version of nrepl but its not :(

14:02 justin_smith: iamjarvo: it's a magic thing where you need the plugin in profiles.clj iirc

14:02 not just the dep

14:03 the job of the plugin is to inject the dep

14:04 iamjarvo: justin_smith so i see this "Retrieving org/clojure/tools.nrepl/0.2.10/tools.nrepl-0.2.10.jar from central

14:04 Retrieving org/clojure/clojure/1.2.0/clojure-1.2.0.jar from central" but then i see this when the repl starts "nREPL server started on port 55376 on host - nrepl://

14:04 REPL-y 0.3.5, nREPL 0.2.6"

14:04 justin_smith: iamjarvo: right, that's because it needs to do its thing as a plugin, it's conflicting with lein stuff

14:05 iamjarvo: justin_smith are you talking about the :plugins in project.clj?

14:05 justin_smith: iamjarvo: it has to be in profiles.clj, but yes, in plugins

14:06 profiles because that takes precedence

14:10 iamjarvo: justin_smith here is a pastie of my setup http://pastie.org/private/7zkcffxw4l8phzaaj9azw

14:10 justin_smith: iamjarvo: that's not a valid profiles.clj

14:11 iamjarvo: crap sorry i double pasted

14:11 justin_smith: haha, OK

14:12 iamjarvo: here is a fresh link http://pastie.org/private/942edrwxn1tb8sybor7v3a

14:13 kwladyka: justin_smith, i solved my problem! :)

14:13 justin_smith: iamjarvo: :plugins is being treated as a profile name

14:13 kwladyka: oh wow, what was the trick?

14:13 kwladyka: justin_smith, algorithm was slaw because of duck duck typing

14:13 justin_smith, i need to declare datatype

14:13 justin_smith: iamjarvo: the tools.nrepl plugin should go inside :user :plugins

14:13 iamjarvo: ahh because its in its own map

14:14 justin_smith: iamjarvo: right, also I don't think you meant to make a profile named :dependencies either :)

14:14 kwladyka: justin_smith, read this article, it is very interesting http://www.learningclojure.com/2013/02/clojure-is-fast-is-clojure-still-fast.html

14:15 justin_smith: kwladyka: someone should have mentioned turning on reflection warnings, I guess I'll remember that next time

14:15 kwladyka: justin_smith, all because of weak typing

14:16 justin_smith, turning on reflection warnings?

14:17 justin_smith: ,(defn foo [x] (.length x))

14:17 clojurebot: #'sandbox/foo

14:17 justin_smith: ,(set! *warn-on-reflection* true)

14:17 clojurebot: #error {\n :cause "Can't change/establish root binding of: *warn-on-reflection* with set"\n :via\n [{:type java.lang.IllegalStateException\n :message "Can't change/establish root binding of: *warn-on-reflection* with set"\n :at [clojure.lang.Var set "Var.java" 221]}]\n :trace\n [[clojure.lang.Var set "Var.java" 221]\n [sandbox$eval48 invokeStatic "NO_SOURCE_FILE" -1]\n [sandbox$eval48 invoke...

14:18 justin_smith: kwladyka: anyway, in a real repl you can use set! like above, and then if you run that defn it will tell you about the reflection

14:18 which is what makes the underspecified code so slow

14:19 kwladyka: so you can turn on *warn-on-reflection* at the top level of your project, and get warnings about the places where your code will be slow because the types are not known

14:19 iamjarvo: justin_smith in my endless changing and trying diff things created those maps. thanks for the second eyes

14:19 justin_smith: iamjarvo: np, hope that helps you solve the issue

14:20 kwladyka: justin_smith, so good to know

14:21 justin_smith, thx

14:21 i am so happy to found out why my algorithm is slow and i learnt a lot

14:22 i am also very surprise about time performance because of duck duck typing

14:44 sdegutis: Can anyone recommend any Clojure library that's simple yet powerful?

14:45 kwladyka: sdegutis, ?

14:45 chouser: clojure.zip ?

14:49 wasamasa: clojure.core

14:50 sdegutis: None of those show up in https://github.com/search?q=simple+powerful&l=Clojure

14:50 wasamasa: lol

14:50 sdegutis: I'm pretty sure you can use this as a metric of language popularity. 68 for Python, 75 for Ruby, 248 for JS

14:51 amalloy: is clojure.zip simple? the implementation isn't, and the api doesn't seem that simple either

14:53 pbx: as a clojure noob coming from python, i'm going to give a short "clojure is cool" talk to my python-using coworkers in an hour. any evangelism tips?

14:54 scriptor: try to use concrete examples

14:55 justin_smith: pbx: I'd stress the easy vs. simple thing - python is often easy, but the semantics are not simple, whereas clojure has simpler semantics

14:55 scriptor: tons of people have said "pure functions make code easier to reason about", it's more effective to show why that's the case

14:56 justin_smith: ahh yeah, a concrete example of where certain common bugs become impossible with immutable datastructures

14:56 scriptor: maybe brainstorm any bugs from your own company's codebase that might've been avoided or better handled with clojure

14:56 amalloy: pbx: how short?

14:57 i have slides for a 40-minute "why clojure" presentation on Drive somewhere

14:57 scriptor: amalloy: I'd be interested in seeing that in general

14:57 pbx: amalloy, 10 minutes

14:58 amalloy: oh i guess i called it "a taste of clojure"

14:58 https://drive.google.com/open?id=1mGihUBBIKMQn5Uz-5DvQ1Vu24qSuk3o4yUoPoBZW3tI

14:59 justin_smith: amalloy: that's a nice demo

14:59 Jaood: pbx: compare python's horrible lambda to clojure ;)

14:59 justin_smith: the third page

14:59 Jaood: ones

14:59 pbx: good stuff amalloy thanks

15:00 justin_smith: amalloy: btw, using Thread/yield instead of Thread/sleep led to me having to run a killall -9 java :(

15:00 amalloy: haha what

15:00 justin_smith: amalloy: the deal is, I was launching 10000 futures, and cancelling each one

15:01 this ran out of threads available, which fucked up nrepl - the client died, but the server was still running

15:01 it got to the point where I couldn't even start new nrepls after a few times (I was trying to figure out what was wrong)

15:02 because future-cancel can't kill a tight loop that is calling Thread/yield on my jvm apparently (though Thread/sleep 1 was killable by future-cancel)

15:02 amalloy: $javadoc Thread yield

15:02 lazybot: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#yield()

15:02 amalloy: oops

15:02 okay so that doesn't ever get interrupted

15:03 justin_smith: amalloy: yeah, I don't think it's on the magical list of things that lead to cancellability

15:03 while waiting on input and sleeping are

15:03 amalloy: justin_smith: it's not so much a magical list of things, as anything that declares it can throw InterruptedException

15:03 justin_smith: ahh, interesting

15:03 very good to know

15:03 amalloy: because those are typically generated only when someone says "hey man, stop this thread, something is happening"

15:04 justin_smith: anyway, this is like the first time in over a year I have had to run killall -9 java, so congrats

15:04 lol

15:06 sdegutis: pbx: nope sorry.. the only things Clojure has over Python are destructuring and JVM libs

15:06 amalloy: haha

15:06 justin_smith: (dorun (repeatedly #(future)))

15:07 what could go wrong

15:07 sdegutis: pbx: and ->> makes map/filter/etc slightly nicer than Python just because Python's dumb and uses global functions unlike Ruby

15:08 This week's Annual Clojure Challenge! What's the most interesting and/or bizarre thing you can do with a Set?

15:08 aaaaaand... Begin!

15:41 dxlr8r: is it possible to "get" all params to a function (defn) to a list without manually assigning them? like "& args" but with named arguments

15:49 (defn [a b c] (print (abc-coll)) :) like that

15:51 tmtwd: I'm trying to do string concat in cljs like this : http://pastebin.com/ab0n9KEh what is the best way to do that?

15:52 chouser: I think you can just leave out the ++'s

15:54 tmtwd: chouser, thanks :)

15:58 irctc: anyone here using domkm/silk on a webserver?

16:04 alex_engelberg: dxlr8r: you could try something like (defn [& [a b c :as all-args]] ...)

16:07 DomKM: irctc: Most users I've talked to use Silk for frontend routing. I think it works best when used on both the frontend and backend simultaneously. Happy to field questions. :)

16:08 irctc: DomKM: Thanks for responding - literally just opened up an issue with you on github.

16:09 I can explain here too though - I'm having trouble specifying request methods in my routes... I can show you code but that might be easier on github.

16:10 amalloy: dxlr8r: the only thing that doesn't involve retyping the arglist is what alex_engelberg is suggesting, but then you lose arity overloading, and arity checking: (foo 1) becomes legal now, setting [a b c] to [1 nil nil]

16:15 DomKM: irctc: Okay. I responded to the issue you opened.

16:57 {blake}: Does Clojure push a context on to the stack? (I'm asking because Smalltalk does but I haven't thought through if the same is necessary or useful in Clojure.)

17:01 amalloy: {blake}: the jvm uses the stack for locals, yes

17:02 {blake}: amalloy: Any non-user designated stuff? System info?

17:03 amalloy: well like, the return address and so on is there, i imagine

17:03 but maybe not

17:03 {blake}: amalloy: OK, fair enough.

17:03 (inc amalloy)

17:03 lazybot: ⇒ 290

17:03 justin_smith: {blake}: as I understand it the jvm is relatively heap happy

17:03 amalloy: i was recently reading the jvm spec actually, and read the bit about stack frames

17:04 justin_smith: it's notorious for being more fragmented for that reason

17:04 amalloy: but i don't remember what is on there other than your locals

17:04 justin_smith: amalloy: what's on the stack will still be essentially a pointer to the actual object in the heap, right?

17:05 amalloy: yes, locals are always primitives or pointers to objects on the heap

17:05 {blake}: In Smalltalk, it's typically the sender, receiver, arguments, selector, locals and a home context.

17:06 amalloy: all of those are just locals on the jvm, except the sender doesn't exist and i don't know what a home context is

17:06 oh or a selector

17:06 justin_smith: is a selector like a method?

17:06 no, that doesn't make sense

17:07 oh wait, it basically is - it's the method name essentially

17:07 amalloy: smalltalk has a much richer stack/environment than any language i know of

17:07 justin_smith: http://www.objs.com/x3h7/smalltalk.htm

17:07 {blake}: justin_smith: A selector is...a selector. =) Typically objects respond to the selector by calling a mathicng method. But they don't have to.

17:07 justin_smith: aha

17:07 {blake}: Yeah, it's one of the few languages I know where it's conceivable to debug with step-backwards.

17:09 Seems like it could happen in Clojure, though.

17:09 justin_smith: {blake}: ocaml has a time-travel debugger

17:09 {blake}: justin_smith: Yeah! I'd heard that. I've only dabbled.

17:51 dxlr8r: alex_engelberg / amalloy: thx, but arity checking is kinda required

17:52 I wrote some macro once to do it, but was to specific, guess I'm not good enough at them :)

18:12 kwladyka: is it possible to write functions like https://www.refheap.com/10aff5cf186a546b78d37dac6 with iterate or something like that?

18:31 justin_smith: kwladyka: that first one could be simpler as a reduce

18:33 (reduce (fn [new-boards board] (increment-board-by-piece board piece new-boards)) (empty boards) boards)

18:33 kwladyka: justin_smith, thx, i will see

18:33 justin_smith: second one is also simple to turn into a reduce

18:34 this general pattern (if you are taking rest on a list on each loop, and updating some value) is what reduce is for

18:35 awwaiid: justin_smith: I dug into ocaml's back-stepping debugger, and as far as I can tell it is actually a fork-based time travel technique. I ported the concept to ruby via pry-byebug. Really it is a unix trick more than anything though -- they are not running their bytecode interpreter backwards as I initially thought

18:36 justin_smith: oh!

18:36 awwaiid: exactly what I said :)

18:37 xemdetia: yes the simplest way to travel back in time is to have multiple times!

18:37 awwaiid: justin_smith: " set processcount count

18:38 Set the maximum number of checkpoints to count. More checkpoints facilitate going far back in time, but use more memory and create more Unix processes. " from http://caml.inria.fr/pub/docs/manual-ocaml/debugger.html

18:38 I think it does a combination of forking and replay

19:01 kwladyka: justin_smith, nice, even better performance and more readable :)

19:01 and... it is time to sleep, goodnight :)

19:08 noncom|2: what is the best library for doing L-systems with clojure today?

19:24 sdegutis: What an exciting competition today! No submissions yet, which means everyone's working hard on something /really cool/!

19:25 For those just joining us: What's the most interesting and/or bizarre thing you can do with a Set?

19:25 First place gets first prize. Second place gets second prize. NOBODY ELSE GETS ANYTHING.

19:28 amalloy: richer how?

19:38 xeqi: sdegutis: i imagine it would be hard to surpass Russell's fun with sets

21:06 devn: Could anyone tell me how (defonce ^:const foo (assoc {:a 1} :b 2)) behaves under the covers?

21:06 Is there anything I should be concerned about when using both defonce and :const metadata?

21:26 bcham: I'm getting something strange. I can't resolve "rename-keys".

21:26 http://pastebin.com/uX7JmH1w

21:26 select-keys works just fine

21:27 but rename keys doesn't, on clojure 1.6

21:27 What am I doing wrong oh wise men of #clojure.

21:27 and women*

21:28 well I figured it out, I had to drop down to clojure.set

21:28 because I'm stupid.

21:29 amalloy: devn: i think that would have the same effect as (defonce foo (...))

21:29 or maybe something totally broken. at any rate it won't do what you wanted

21:32 devn: amalloy: so you think the :const metadata won't do anything?

21:33 amalloy: do you know what ^:const does?

21:52 gfredericks: amalloy: devn: I would definitely expect that ^:const changes things

21:53 defonce means that future calls to defonce are noops; ^:const means that when you use the var elsewhere in the code it compiles to a direct reference to the data, not to the var, so redefinitions aren't seen

21:53 afaik those two things are orthogonal

21:54 amalloy: gfredericks: i was imagining that the problem was in the actual implementation of defonce as a macro that expands to like (do (def ^:const x nil) (alter-var-root x (constantly whatever))

21:54 but i think you are right that the value and the ^:const don't need to be set at the same time

21:55 gfredericks: ,(source defonce)

21:55 clojurebot: Source not found\n

21:55 gfredericks: ~defonce

21:55 clojurebot: defonce is a temptation

21:55 amalloy: ~def defonce

21:56 gfredericks: ~defonce is pronounced more or less like Beyoncé

21:56 clojurebot: c'est bon!

21:56 hiredman: I am amazed that ~def works

21:57 amalloy: hiredman: why?

22:02 hiredman: at one time it was a big pain, because the version of clojure clojurebot used to look up line numbers was way behind master

22:03 which was back around 1.2 I think, and then I pulled the evaluator bit out of the process so it is easy to jump to new clojure versions and I haven't thought about it since

22:08 amalloy: well it's still linking to a really old version of core.clj

22:09 ~def do!

22:09 ,do!

22:09 clojurebot: #error {\n :cause "Unable to resolve symbol: do! in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: do! in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: do! in this conte...

22:09 amalloy: isn't that a thing in 1.7?

22:10 oh, it's run!

22:10 ,run!

22:10 clojurebot: #object[clojure.core$run_BANG_ 0x567f2d92 "clojure.core$run_BANG_@567f2d92"]

22:10 amalloy: ~def run!

22:10 hiredman: huh, so the line number for defonce just happens to be the same

22:11 amalloy: hiredman: no, it's using the old version of clojure to look up a line number, and then linking to the corresponding line in an old blob on github'

22:11 which is why ~def run! doesn't work

22:11 hiredman: Oh, right, didn't you have a pr for that?

22:11 amalloy: not me

22:11 hiredman: hmmm

22:13 and the code lookup stuff is in the main clojurebot process, I was thinking I might fix it to lookup via the evaluator service, but forget it if it involves restarting anything

Logging service provided by n01se.net