#clojure log - May 16 2016

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

0:24 dysfun: ilevd: ?

0:25 two timed bigger than what?

0:25 ilevd: Than it was in database

0:25 dysfun: how do you work that out?

0:26 ilevd: I do select it returns [B

0:27 It seems it needs to return bytea as string

0:27 dysfun: that sounds about right

0:27 hex encoded, probably

0:29 there's a bug against mpg to give you back a bytebuffer for bytea

0:30 meanwhile the project lead on that has gone awol and my release manager has also gone awol, so it's fun times trying to get clojure out recently :)

0:30 TEttinger: oh, and the byte array could possibly be 2 times bigger, but it depends on encoding I think

0:30 UCS-4 would be 4 tims bigger :D

0:30 or at least twice

0:31 dysfun: TEttinger: however, i happen to know there are only two internal encodings used by postgres: hex and the old one that uses prefix escapes

0:32 both take ascii

0:32 ilevd: yeah http://www.postgresql.org/docs/9.5/static/datatype-binary.html

0:33 Ok, but how can I get it, I need something like SELECT to_hex(bytea_field) FROM ..

0:34 dysfun: well what do you actually get back?

0:34 ilevd: [B

0:34 dysfun: that's byte[], right?

0:35 ilevd: Yes

0:35 dysfun: but what is in it?

0:35 it's mysteriously twice as big, are you sure it's not hex?

0:35 ilevd: I tried to do String.

0:36 (4b030 vs 504b030

0:36 Some symbols are different

0:36 dysfun: those are the hex representations?

0:36 ilevd: Yes

0:37 dysfun: that looks like it's length prefixed (??)

0:37 but 50 is a lot more than 4 characters

0:37 sorry, i have no idea. try asking #postgresql

0:38 they've been quite good at helping me figure things out for mpg

0:49 idev: I have sequence of maps

0:50 how do I convert this to json

0:50 I have [Elem], wehre each Elem is a map from :keyword => string/double

0:50 how do I convert this to json ?

0:50 dysfun: do you want it to be a json array?

0:50 idev: sure

0:50 dysfun: in mpg we use cheshire

0:50 it's just a single function in cheshire.core

0:51 idev: I like that

0:51 generate-string ?

0:51 dysfun: yeah

0:51 seqs should get turned into lists

0:51 er arrays

0:55 idev: dysfun: it works; this was precisely what I was looking for; thanks!

0:55 (inc dysfun)

0:55 dysfun: there hasn't been a karmabot for a while :)

0:56 idev: dysfun: it's not the karma, it's the thought that counts :-)

0:56 dysfun: :)

0:56 i just like helping

0:56 idev: actually, can I tell you a secret?

0:56 dysfun: it's about all i can do while i wake up enough to do my own stuff

0:56 sure, but the channel is publically logged :)

0:56 idev: I like types and I'm a haskell user. I'm just using clojure to use apache pdfbox to do pdf processing.

0:57 dysfun: fair enough. i'm also a haskell user :)

0:57 but i write more clojure than haskell

0:57 ilevd: dysfyn, it needs to return it as SELECT encode(bytea_filed, 'hex') ..

0:57 idev: I like "lein repl" more than I like "cabal repl", but at around 2000 lines ,I really start liking types

0:57 dysfun: thanks. could you drop a note on the relevant issue please?

0:58 ilevd: Ok

0:58 dysfun: idev: once you're more familiar with clojure you learn how to make it scale better

0:58 the trick to good clojure is to create fewer, not more types

0:59 for the most part i only use the type system for performance reasons

0:59 idev: I use clojure for about 4 years.

0:59 then I swithced to haskell.

0:59 this isn't my first run with clojure :-)

0:59 dysfun: fair enough

0:59 well i like haskell types too, but they're also very annoying at times

1:00 i've got a totally insane template haskell project

1:00 idev: TH is insane

1:00 I don't like TH

1:00 dysfun: nobody who has used TH likes TH

1:01 i feel like haskell is 'getting there' these days. it's got most of what you need to deploy it to production. but it's still going to leave you in hot water wanting to do certain things

1:01 and believe it or not TH was the easy option

1:02 idev: almost entirley my project is in haskell

1:02 it's just that I don't trust ghostscript to process pdfs; and refer apachebox/jvm

1:02 break ghostscript ==> exploit

1:03 dysfun: uhuh

1:03 idev: break apchepdfbox ==> good luck trying to breka the jvm

1:03 engblom: I think Haskell is a great language, and still to this day, I have not found a language easier to read than Haskell. If I look at my own old Haskell code, or if I look at code someone else wrote, I learn a lot faster what it does

1:03 idev: engblom: agreed

1:03 okay, 'spit' is easiest way to do "String :: Content, String :: FilePath -> IO ()" right? :-)

1:03 engblom: The biggest drawback of Haskell I think is cabal. It is not just once I got bitten by the dependency hell

1:04 idev: engblom: stack/nix has solved a lot of that for me

1:04 all of us haskell sleeper agents have revealed ourselves, the #clojure purists just these logging who's who :-)

1:04 dysfun: engblom: i think that's true until people start pissing about with advanced type system stuff

1:04 and overuse of typeclasses

1:04 engblom: dysfun: That is very true

1:05 dysfun: see, i still program haskell like a c++ programmer - using the type system to enforce properties of my program

1:05 that's not to say my haskell looks anything like my c++, obviously

1:05 just the general theme of using the type system to gain safety

1:06 and part of my problem is i don't understand some of the more advanced typesystem crack

1:06 undecidableinstances and such

1:06 idev: when ghc suggest I use undecidbleinstances, I rewrit emy typecalsses

1:07 I don't like 'undecidable' in my compilation process

1:07 dysfun: well i'm not terribly keen either, but sometimes when you want to do a thing you know regular haskell can't, you go looking in the extensions page

1:08 'oh, that sounds plausible, what's the worst that could happen'

1:08 idev: anyone have sample code for pdf -> [images] with pdfbox ? :-)

1:08 dysfun: just translate the java code you find on stackoverflow to clojure?

1:09 it'll remind you how much less typing you do in clojure than java :)

1:10 idev: okay, I just need https://gist.github.com/anonymous/3aec465332e06f34326b4630c1c84b44

1:10 to conver to clojure

1:10 engblom: I am not a professional programmer, I just write 1-2 small projects a year in my spare time. Because of this I am very slow to progress in a language as there are often more than a half year between the coding sessions. For me, Clojure is the language I am most productive in given the little time I have for programming nowadays.

1:10 idev: oh yeah, that's why I'm using clojure and not java

1:10 engblom: haskell has a steep steep learning curve

1:11 the other day I was reading LogicT (equiv to scheme's minikanren and clojure's core.logic

1:11 it took me 2 days to even understand what the types meant

1:13 dysfun: haha

1:13 i get bored well before that happens

1:14 engblom: I think the learning curve for Haskell is not particularly steep if you take a book like "Learn you a Haskell for great good". It all depends on what material you learn from

1:15 It took not long time for me to have the computer to play perfect "NIM" (The real multirow NIM) against me after I read that book.

1:20 dysfun: idev: i commented on it with most of the hard work done, the rest is just clojure

1:20 you will need to :import the appropriate things

1:27 engblom: i wish they would put different wording into the books where monads are concerned though

1:27 it's difficult for newbs to figure out how to make io stuff work

1:53 idev: does clojure have C's fprintf ?

1:53 I want to have a string of the form " .... special chars ... " and then the args after it

1:54 dysfun: sprintf, you mean?

1:54 TEttinger: ,(doc format)

1:54 clojurebot: "([fmt & args]); Formats a string using java.lang.String.format, see java.util.Formatter for format string syntax"

1:55 TEttinger: ,(format "%04d then a thing here %04d" 1 10)

1:55 clojurebot: "0001 then a thing here 0010"

2:10 idev: okay, got that working

2:10 thanks!

2:10 dysfun: TEttinger : yes, got it working :-)

2:10 http://www.oracle.com/technetwork/articles/javaee/jai-142803.html <-- apparently apache pdfbox is complaining I don't have this iamge

2:10 dysfun: :)

2:10 idev: this library installed

2:10 what is the line to add to project.clj for http://www.oracle.com/technetwork/articles/javaee/jai-142803.html ?

2:11 May 15, 2016 11:10:52 PM org.apache.pdfbox.filter.JPXFilter decode

2:11 SEVERE: ImageIO.read() did not return any data - is JAI installed?

2:11 dysfun: no idea. see if you can find a maven example

2:12 idev: maybe https://gist.github.com/anonymous/31ff55d0c259f012174d5ed739f561cf

2:14 dysfun: there you go

2:14 [javax.media.jai/com.springsource.javax.media.jai.core "1.1.3"]

2:21 ilevd: One line is less than five

2:21 dysfun: yup

2:29 idev: :-)

2:29 this is something that I know how to do in haskell

2:30 let's see if we can do it in clojure

2:30 I have a function f which has side effects

2:30 I want to call it 200 different times, on different args, i..e (f a1) (f a2) ... (f a200)

2:30 now, I have 8 cores, so I want 8 of these to run at any given time

2:30 how do I express this concurrency primitive in clojure?

2:30 (defn run-8-at-a-time [f lst] .... )

2:32 dysfun: you want a thread pool library

2:32 idev: I don't need to run all 200 at the same time

2:32 I'm okay with *delaying the fork*

2:32 dysfun: what fork? there won't be a fork

2:33 TEttinger: there is a thread pool in java by default

2:34 idev: these thigns ar ememory heavy

2:34 TEttinger: threads? yes

2:34 idev: I don't want (f 9) to even start procesing until one of (f 1) -> (f 8) has finished

2:34 dysfun: right. do you want to list your actual requirements all at once rather than dripfeeding them?

2:34 idev: sorry

2:35 this is my fault

2:35 let me wirte up a gist

2:35 I also want this to be webscale: https://www.youtube.com/watch?v=b2F-DItXtZs

2:35 dysfun: there is a video somewhere on the internet of the audience chanting 'web scale' at me every time i say it on stage

2:36 (may have been using my platform as a conference speaker to mock technology again)

2:37 TEttinger: webscale is a fun non-meaningful term

2:37 like dynamic

2:37 dysfun: oh dynamic is a well defined term

2:37 idev: https://gist.github.com/anonymous/f0d5bf799975b2e3876f56f76502429f

2:37 dysfun: it means "moves underneath you unexpectedly a lot". "a dynamic specification"

2:38 TEttinger: dynamic programming, dynamic typing, like a dynamo

2:38 idev: dysfun: let me know if any part of that is not clear

2:38 basically, I'm after conclbock from zsh http://galvanist.com/post/67095577027/revisiting-shell-concurrency-this-time-in-zsh

2:38 TEttinger: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html I believe does this, you'd want a lib that wraps it because it's kinda nasty

2:39 dysfun: idev: yeah, have a look at the pools listed on clojure-toolbox.com

2:39 idev: http://stackoverflow.com/questions/1768567/how-does-one-start-a-thread-in-clojure

2:39 I want to wrap a (.start (Thread ... ))

2:39 dysfun: you don't start a thread, you use a thread pool

2:40 because starting a thread is asking for trouble

2:40 idev: why not? with a thread pool, how can I control when something is started

2:40 dysfun: you cap the size of the thread pool and then queue up work

2:41 TEttinger: yeah

2:43 huh, weird I can only find https://github.com/TheClimateCorporation/claypoole/

2:44 dysfun: there's also https://github.com/ztellman/dirigiste/

2:46 TEttinger: dirigiste looks good

2:51 engblom: idev: Before taking a library into use, you could check if pmap is close enough to your requirements to work in your case. pmap will check how many cores are available and tries to max them out.

2:51 TEttinger: uh...

2:52 dysfun: engblom: don't recommend pmap

2:52 TEttinger: not in this case I wouldn't recommend it

2:52 dysfun: pmap?

2:52 clojurebot: pmap is not what you want

2:52 TEttinger: in most cases

2:52 dysfun: botsnack!

2:52 TEttinger: pmap would try to run I believe 34 instances of his super-memory-using state-affecting fn

2:52 engblom: The biggest problem with pmap, in my opinion, is the semi lazyness

2:53 TEttinger: it was a weird number higher than most core counts I recall, not 34 necessarily

2:55 engblom: n (+ 2 (.. Runtime getRuntime availableProcessors)) <---- Is from (source pmap)

2:58 TEttinger: hm. I'd still be careful with it, I haven't yet encountered a problem where pmap actually produces a speedup

3:08 engblom: http://drcabana.org/2011/06/04/a-simple-parallel-computation/ <--- In this case map seem to be 3.5 times slower than pmap

3:09 But I agree it might be difficult to find good cases for pmap

3:14 TEttinger: that seems kinda dated, he isn't using +' so that would have been from when + auto-promoted

3:16 ilevd: Some big tasks, like get and parse html, no?

3:49 ben_vulpes: https://www.youtube.com/watch?v=fA9ZXy4N13s&index=6&list=PLZdCLR02grLq4e8-1P2JNHBKUOLFTX3kb << relevant

5:07 idev: is there a shorter way to write (fn [x] (.getName x))

5:08 dysfun: #(.getName x)

5:08 idev: err, the x isn't defined in your code

5:08 dysfun: %

5:08 (.getName %)

5:08 M570`: #(.getName %)

5:09 dysfun: also (memfn getName)

5:10 idev: #(.getName %) looks familiar

5:10 works

5:10 is what I was trying to recall

5:33 how do I check if a string ends in ".pdf"

5:33 dysfun: (.endsWith string "\\.pdf")

5:34 drk_lrd_777_: hi is this the correct place to post if I am having a problem with leiningen?

5:34 dysfun: drk_lrd_777_: it's as good as any

5:34 douglarek: drk_lrd_777_:maybe should use a paste

5:34 service like gists

5:35 drk_lrd_777_: The issue I am having is that when I compile my file through lein, the resulting jar file does not print to stdout when run.

5:35 I can see the code works fine

5:35 as it makes a HTTP call

5:35 which i have traced usign tcpdump

5:36 but the final output is not printed to screen

5:36 any help is appreciated

5:36 thanks in advance! :)

5:36 dysfun: that's weird

5:37 how are you printing to the screen?

5:38 TEttinger: drk_lrd_777_: running with java (java.exe on windows) or javaw (javaw.exe)?

5:39 if you double click a jar it runs with javaw by default on windows, which suppresses the console

5:39 drk_lrd_777_: the usual (print "printme")

5:39 and im using linux

5:39 TEttinger: I mean how are you running the jar?

5:39 drk_lrd_777_: java -jar filename.jar

5:40 here is my project.clj in case it may be of any help http://pastebin.com/EhrWcq4h

5:40 ill post the code too

5:40 TEttinger: was it made with the command "lein uberjar", which is a recommended way to build self-contained runnable jars?

5:40 drk_lrd_777_: yes

5:40 i ran "lein compile && lein uberjar"

5:40 TEttinger: project.clj looks solid

5:41 uberjar should do the first step

5:41 clean it may not do

5:41 drk_lrd_777_: main file :: http://pastebin.com/zRFZYjBW

5:41 TEttinger: do you have a -main fn in there? I'll look

5:41 drk_lrd_777_: yes

5:42 TEttinger: this looks solid so far... not sure what's up. try changing print to println, it could be a terminal needing to flush a line

5:43 drk_lrd_777_: okay im trying that

5:44 TEttinger: what does rss/channel-xml do? I'm wondering if the whole of the xml string is empty

5:45 drk_lrd_777_: it generates an rss feed

5:45 it works fine when i run on the REPL

5:45 which is why im confused

5:45 TEttinger: ok, maybe try changing the (def xml ...) to (def xml "a placeholder")

5:46 you can comment out the current def

5:46 my favorite way is with #_(def ...)

5:46 which causes the whole form to be ignored as long as the parens match

5:46 drk_lrd_777_: okay lets see how this goes

5:47 im waiting for it to compile to try the println thing first

5:47 after that ill try this

5:47 TEttinger: sure

5:47 is compilation taking a long time? I know uberjar slows things down a bunch

5:47 drk_lrd_777_: it takes about 2 minutes

5:47 TEttinger: you can test with "lein run" as well

5:48 which won't make the jar

5:48 drk_lrd_777_: but it works fine with lein run

5:48 TEttinger: oh. weird...

5:48 can you send the jar over? I don't know what sites host that, https://ge.tt maybe?

5:49 drk_lrd_777_: wow

5:49 the println thing worked

5:49 TEttinger: haha whaaaaat

5:49 drk_lrd_777_: but i dont understand why

5:49 TEttinger: consoles are magical snowflakes

5:50 I think this one wouldn't print a line until the line was finished, println (or printing a newline) should flush the line, but I'm no expert

5:50 dysfun: hysterical raisins

5:50 drk_lrd_777_: hahahah weird stuf

5:50 TEttinger: i'm stealing that dysfun

5:50 dysfun: see also gary bernhardt's talk about why the terminal sucks

5:51 drk_lrd_777_: thanks a lot though

5:51 TEttinger: glad to help!

5:51 that's a weird bug!

5:51 dysfun: such bugs are quite commonplace

5:51 TEttinger: your code looks fine, are you just starting out? It looks like the project is new but you already know what libs to use

5:51 dysfun: a lot of things rely upon the c libraries

5:51 drk_lrd_777_: yeah

5:52 im laerning functional

5:52 so started whith clojure

5:52 TEttinger: it's a good choice

5:52 the names of things are so important and clojure mostly has excellent names

5:52 drk_lrd_777_: my design is not "elegent" though im trying to improve on that

5:52 hahah yeahh

5:52 TEttinger: like "reductions"

5:53 dysfun: and not like 'eductions'

5:53 TEttinger: it's the sequence of stuff produced at each step of reduce

5:53 drk_lrd_777_: im really happy with the number of libraries it has

5:53 TEttinger: clojure calls reductions scan or scanl I think

5:53 drk_lrd_777_: hmm dont know about that yet

5:53 TEttinger: even though it's clearly related to foldl in haskell, reduce in clojure

5:53 err

5:54 haskell calls reductions scan

5:54 dysfun: oh, i hadn't realised

5:54 TEttinger: you'll use reductions rarely, but the name explains it's related to reduce

5:54 drk_lrd_777_: yeah i just googled it

5:54 reading the first article it shows

5:54 TEttinger: ,[(reduce + [1 2 3 4 5]),(reductions + [1 2 3 4 5])]

5:55 clojurebot: [15 (1 3 6 10 15)]

5:55 TEttinger: (put in one vector because clojurebot returns one thing at a time)

5:56 dysfun: ,(let [a (reductions + [1 2 3 4 5])] [a (reduce + a)])

5:56 clojurebot: [(1 3 6 10 15) 35]

5:56 drk_lrd_777_: wait .. how did you do that?

5:56 TEttinger: nice thing about clojure's lisp-y stuff, comma is just a whitespace char

5:56 drk_lrd_777_: I want to use the bot!

5:56 TEttinger: oh uh

5:56 dysfun: you put a comma on the front

5:56 drk_lrd_777_: ,(println "hello")

5:56 clojurebot: hello\n

5:56 drk_lrd_777_: omg

5:56 TEttinger: comma then a single clojure form like (+ 1 (* 3 5))

5:56 drk_lrd_777_: yeah i figured it out

5:56 TEttinger: it's sandboxed very well

5:57 drk_lrd_777_: this is awesome!

5:57 TEttinger: I don't think anyone has broken lazybot

5:57 err clojurebot

5:57 lazybot had some flaws but is no longer here

5:57 drk_lrd_777_: what if someone gives it like the ackerman function?

5:57 TEttinger: it only prints the first 5 elements

5:57 ,(range)

5:57 clojurebot: (0 1 2 3 4 ...)

5:57 drk_lrd_777_: ahh

5:57 nice

5:58 TEttinger: lots of channels have these bots, clojurebot happens to be a very nice one :)

5:58 dysfun: but i miss karma

5:59 drk_lrd_777_: ,(print "my jar wont print this")

5:59 clojurebot: my jar wont print this

5:59 drk_lrd_777_: lol

5:59 TEttinger: ,(def PHI (* 0.5 (inc (Math/sqrt 5)))

5:59 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

5:59 TEttinger: ,(def PHI (* 0.5 (inc (Math/sqrt 5))))

5:59 clojurebot: #'sandbox/PHI

5:59 dysfun: yeah, clojurebot doesn't support autocompletion or paren matching

5:59 TEttinger: ,(def TAU (* 0.5 (- 1 (Math/sqrt 5))))

5:59 clojurebot: #'sandbox/TAU

6:00 TEttinger: ,(defn fibonacci [n] (/ (Math/pow PHI n) TAU))

6:00 clojurebot: #'sandbox/fibonacci

6:00 TEttinger: ,(map fibonacci (range 5))

6:00 clojurebot: (-1.6180339887498947 -2.618033988749895 -4.23606797749979 -6.854101966249684 -11.090169943749475)

6:00 TEttinger: ugh

6:01 dysfun: ,(def a (agent []))

6:01 clojurebot: #'sandbox/a

6:02 dysfun: ,(doseq [i (range 10)] (send-off conj :foo))

6:02 clojurebot: #error {\n :cause "clojure.core$conj__4345 cannot be cast to clojure.lang.Agent"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.core$conj__4345 cannot be cast to clojure.lang.Agent"\n :at [clojure.core$send_via invokeStatic "core.clj" 2009]}]\n :trace\n [[clojure.core$send_via invokeStatic "core.clj" 2009]\n [clojure.core$send_via doInvoke "core.clj" 2009]\n [clojure.lang....

6:02 dysfun: ,(doseq [i (range 10)] (send-off a conj :foo))

6:02 clojurebot: nil

6:02 dysfun: ,a

6:02 clojurebot: #object[clojure.lang.Agent 0x298a64c4 {:status :ready, :val []}]

6:03 dysfun: hrm. i suspect you could probably denial of service. does it have a timeout?

6:03 TEttinger: yes

6:03 all defs are erased every 10 minutes

6:05 ,(defn fibonacci [n] (/ (Math/pow (* 0.5 (inc (Math/sqrt 5)) n) (Math/sqrt 5)))

6:05 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

6:05 TEttinger: ,(defn fibonacci [n] (/ (Math/pow (* 0.5 (inc (Math/sqrt 5)) n) (Math/sqrt 5))))

6:06 clojurebot: #'sandbox/fibonacci

6:06 TEttinger: ,(map fibonacci (range 5))

6:06 clojurebot: #<ArithmeticException java.lang.ArithmeticException: Divide by zero>

6:06 TEttinger: gah

6:06 ,(map fibonacci (range 1 6))

6:06 clojurebot: (0.3409490070205292 0.07237122042538442 0.029228994185835057 0.015361809062386312 0.009327064627560907)

6:06 TEttinger: I screwed up

6:06 ,(defn fibonacci [n] (/ (Math/pow (* 0.5 (inc (Math/sqrt 5))) n) (Math/sqrt 5)))

6:06 clojurebot: #'sandbox/fibonacci

6:06 TEttinger: ,(map fibonacci (range 1 6))

6:06 clojurebot: (0.7236067977499789 1.1708203932499368 1.8944271909999157 3.065247584249853 4.959674775249769)

6:06 TEttinger: ,(defn fibonacci [n] (Math/round (/ (Math/pow (* 0.5 (inc (Math/sqrt 5))) n) (Math/sqrt 5))))

6:06 clojurebot: #'sandbox/fibonacci

6:06 TEttinger: ,(map fibonacci (range 1 6))

6:06 clojurebot: (1 1 2 3 5)

6:07 TEttinger: there we go

6:21 ilevd: ,fibonacci

6:21 clojurebot: #error {\n :cause "Unable to resolve symbol: fibonacci in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: fibonacci in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: fibon...

6:22 ilevd: ,(def a 1)

6:22 clojurebot: #'sandbox/a

6:22 ilevd: ,a

6:22 clojurebot: 2

6:22 ilevd: :D

6:27 idev: how do I wrap a function to say "if this function throws an exception, just return :foo-bar instead of having it propogate ?"

6:28 (try ... (catch Exception e :foo-bar))

6:32 dysfun: you have answered your own question?

6:33 idev: yes

6:33 I wrote my question, then I wondered "what would dysfun say"

6:33 and I wrote that down

6:33 it's like rubber duck debugging

6:33 dysfun: haha

6:33 idev: also happened to be one of the top results on google

6:33 dysfun: "what would dysfun say?" would make a great t-shirt

6:35 idev: https://gist.github.com/816e017356c1ad4ce6a303c70079d910

6:35 that should, in theory, prevent the exception from propogating upwards right?

6:35 because it's not

6:36 dysfun: huh?

6:36 are you sure you haven't just typo'd it somewhere?

6:36 cause that really should

6:37 idev: let me check for dumbass mistakes

6:38 https://gist.github.com/anonymous/290358e678edff8d970486b530074b84 is the error

6:39 it hosuld be catchable right?

6:42 hmm

6:42 does Excpetion catch *JAVA* exceptions

6:42 or only Clojure Exceptions ?

6:43 dysfun: Exception is a java class

6:43 all Exceptions inherit from it, including Clojure's

6:45 shiranaihito: does something throw a Throwable instead of Exception?

6:45 (because IIRC that would not be caught by catching Exception)

6:45 idev: code: https://gist.github.com/anonymous/d9a512484242b1c0bc18c95150fedc5b

6:45 dysfun: this is ArrayIndexOutOfBoundsException

6:45 idev: error: https://gist.github.com/anonymous/91c03f360533477e7c37bc2e2f3dd3d7

6:45 there's only one source file

6:47 sorry for messy code; have not done clj in recent past

6:48 shiranaihito: well.. maybe it gets thrown outside of your catch for Exception? .. you have some threading stuff going on there?

6:49 idev: I don't think taht is problem, but I will single thread it for this

6:50 without future/deref: https://gist.github.com/1d8fc760637081267dc9794c0410f131

6:51 same error: https://gist.github.com/anonymous/3c795b4c08523ee4e7cbab632a5d19bf

6:57 alright; time to get my rubber duck

6:57 if this was haskell, i'd be thikning laziness issues

6:57 and returning a thunk that is not caught

6:57 but this is clojure

7:02 dysfun: clojure des have lazy seqs

7:03 idev: yeah; but IO should not be lazy

7:04 dysfun: no, it's not

7:04 idev: hmm; with Throwable, it continues

7:05 whoever that told me to try Throwable -- I'm sorry I didn't listen to you

7:05 but why does Throwable work ?

7:05 dysfun: presumably the exception you got is not a subclass of Exception but implements Throwable

7:06 idev: https://docs.oracle.com/javase/7/docs/api/java/lang/ArrayIndexOutOfBoundsException.html

7:06 dysfun: i thought all errors in the standard library were subclasses of Exception, however

7:06 idev: but taht clearly is an Exception

7:06 kwladyka: Is there somebody who use atom editor for Clojure?

7:07 dysfun: yep, it clearly is

7:07 MJB47: i do

7:07 kwladyka: I was trying emacs, but in my subjective opinion..... it is step backward not forward (don't banish me please, i know it is like religion)

7:07 and now i consider atom vs intellij

7:07 idev: clearly I should println the Throwable

7:08 MJB47: atom clojure isnt as mature as emacsw

7:08 but lisp paredit is suitable (though noticeably missing raise by default :( )

7:08 and proto-repl is pretty cool

7:08 it works well enough

7:08 ridcully_: kwladyka: what are your major pain points with intellij that make you look for an alternative?

7:08 MJB47: though not as feature rich as cider

7:08 engblom: kwladyka: Have you had a look at https://sekao.net/nightcode/ ?

7:09 idev: dysfun:

7:09 dysfun: https://gist.github.com/anonymous/a1383f0a5d7c1d2c133d44e0c84d0306

7:09 looks like the ApachePDFBox code prints the eception

7:09 then throws an error

7:09 WTF

7:09 engblom: kwladyka: While I use vim myself, I have had success in introducing other to Clojure using Nightcode as IDE

7:10 dysfun: Errors are supposed to be unrecoverable btw

7:11 amoe: using prismatic schema, I tried to create a schema which matches either the keyword :all or a list of arbitrary keywords. I came up with this. (s/validate (s/conditional keyword? :all :else [s/Keyword]) :all)

7:11 engblom: kwladyka: The reload function works quite well in Nightcode, so once you begin writing something, just keep the REPL running and click the "Reload" button to thest the newly written function

7:11 amoe: But this fails with the error "IllegalArgumentException No implementation of method: :spec of protocol: #'schema.core/Schema found for class: clojure.lang.Keyword clojure.core/-cache-protocol-fn (core_deftype.clj:568)"

7:14 kwladyka: I like to have editor with using mouse less as possible like emacs, but with power and usability of intellij and additions. Like for example less file type syntax what sucks in emacs or easy configuration. Something where things are ready. I don't want write my own editors, i want use it :)

7:15 engblom you made things more complex, now +1 editor to consider :)

7:15 shiranaihito: idev: wow.. :p

7:16 idev: dysfun: I think this is okay in this case, since I'm writing out pages of a pdf

7:16 so if page 23 fucks up, there's no reason it prevents me from writing page 25

7:16 engblom: kwladyka: Nightcode can be used with keyboard...

7:17 dysfun: okay :)

7:17 glad you solved it anyway

7:17 bonkers erorr

7:18 amoe: actually, more generally

7:18 what's wrong with this: (s/validate {:foo :bar} {:foo :bar})

7:18 shiranaihito: idev: so PDFBox swallows an Exception, prints its stacktrace, and then throws an Error instead?

7:19 idev: shiranaihito: apparently so :-)

7:19 shiranaihito: .. glorious :P

7:20 are you going to send them a bug report or something?

7:20 idev: no

7:20 I don't want to deprive anyone else of the learning experience

7:20 shiranaihito: :P

7:20 idev: this has taught me to be fucking paranoid with try/catch

7:20 dysfun: it's java, java is shit, end of.

7:20 shiranaihito: i'm sure someone will be just as thankful to you as you are to Apache :p

7:21 but i think it would be better to report it

7:21 who knows, maybe they'd even fix it

7:21 dysfun: like every boss i've ever had?

7:22 shiranaihito: Java itself is not shit, but maybe a programmer somewhere is

7:22 amoe: Ah, I need to use s/eq for the leaf values

7:22 dysfun: the apache libraries vary massively in quality

7:23 the apache foundation these days is a dumping ground for everyone's old unfashionable shit with the occasional gem mixed in

7:23 shiranaihito: just like all open source in general? :)

7:24 dysfun: exactly

7:25 shiranaihito: and yet, somehow lots of pretty good libraries have such professional maintainers that they don't mind those eternal apache-commons turdnuggets from the 90's or something among their libs' dependencies!

7:29 dysfun: frequently the libraries make it possible but not easy

7:29 great libraries, terrible APIs

7:29 shiranaihito: make what possible?

7:29 dysfun: whatever the task they solve is

7:33 idev: https://clojuredocs.org/clojure.core/add-watch

7:33 where is the full watch documentation?

7:33 clojurebot: It's greek to me.

7:33 idev: I'm looking for all ops I can perform on references / watches

7:35 shiranaihito: dysfun: i'm not sure we were talking about the same thing

7:36 justin_smith: ,(supers clojure.lang.Ref) ; idev

7:36 shiranaihito: anyway, i just wanted to take an opportunity to complain about pointless commons libs still being lugged around :)

7:36 clojurebot: #{java.lang.Comparable clojure.lang.IFn clojure.lang.IReference java.util.concurrent.Callable clojure.lang.ARef ...}

7:36 justin_smith: idev: it's a larger set, but anyway, the details of each of those interfaces should let you know what they can do.

7:37 ,((ref +) 1 1) ; TIL

7:37 clojurebot: 2

7:37 justin_smith: thanks idev, I would never have thought to check what a ref would do when used as a function :)

7:37 idev: I think http://clojure.org/reference/refs is what I wnat

7:38 justin_smith: that page doesn't mention the above trick last I checked

7:38 so you don't want all the operations, just the normal / recommended ones

7:41 idev: how do I implement consumer/producerin clojure with a shared queue?

7:41 justin_smith: the simplest way is with a shared queue.

7:41 haha

7:41 idev: what java calss is that?

7:42 justin_smith: anyway, people usually use core.async (but many times it's much more than they need)

7:42 idev: java.util.concurrent.PersistentBlockingQueue

7:42 you can read from it in one thread and write to it in another

7:43 err

7:43 java.util.concurrent.ArrayBlockingQueue https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ArrayBlockingQueue.html

7:45 ,(def q (ref clojure.lang.PersistentQueue/EMPTY)) ; another option

7:45 clojurebot: #'sandbox/q

8:00 idev: so clojure does NOT provide tail call recursion

8:00 but provides loop/recur ?

8:01 dysfun: loop/recur implements tail call recursion

8:02 idev: right

8:02 but in scheme I can just recursively call self as last pos

8:02 in clojure I can't do this due to java stack frames?

8:03 dysfun: it's a jvm limitation

8:03 it matters less in practice than you'd think

8:03 (idiomatic clojure tends to use builtins)

8:04 idev: yeah; but I'm implementing my own worker-consumer system

8:04 and I want to amke sur etaking from the queue does not consume stack sapce :-)

8:05 dysfun: so use an atom and a PersistentQueue

8:06 idev: ended up using a LinkedBlockingQueue

8:06 all these "usupported/disable doperation" makes me uncomforable (from apache pdfbox)

8:09 damn it robust systems are so hard

8:09 but I think I got it owrkking now

8:13 shiranaihito: so how rickety is PDFBox in general? :)

8:13 idev: it's pretty nice

8:13 much better than ghostscript imho

8:13 I'm just a retard and didn't consdier all possible exceptions/errors that can be thrown

8:13 for examle: can't open a pdf file ==> need to catch exception, otherwise a worker thread dies :-(

8:14 so it's relaly more my incompotencen and not so much pdfbox fault

9:04 shiranaihito: idev but throwing Error is pretty nasty

9:05 weird shit

9:29 jonathanj: idev: what are you using pdfbox for?

9:47 dysfun: saving a pdf to images

9:55 jonathanj: idev: what process are you using to convert pdf documents to images? my experience using PDFRenderer was that it was ridiculously (multiple seconds per page) slow, searching the mailing lists this is kind of a known thing

9:56 dysfun: jonathanj: if you have a backlog, we discussed this earlier

9:56 jonathanj: idev: we recently switched to using imagemagick "convert" (which i guess uses ghostscript under the hood?) and now we're getting <2s render times for entire documents

9:57 dysfun: he was untrusting of ghostscript

9:58 jonathanj: i see

10:05 dimon_: hi, guys, do you mind take a look at this https://stackoverflow.com/questions/37255809/how-to-setup-korma-in-luminus-or-compojure-projects ?

10:06 dysfun: dimon_: you'll typically load it from a config file

10:06 not project.clj, just an ordinary config file

10:07 if you fix it in your project.clj then when you go to production you won't be able to change which db server it points to without rebuilding the artifact!

10:07 dimon_: dysfun: is there any example?

10:08 dysfun: i quite like https://github.com/TouchType/conf-er

10:08 but it depends on your config needs

10:08 dimon_: dysfun: "if you fix it in your project.clj then when you go to production " -- why not if I setup the production connection string before I build the jar?

10:09 dysfun: you'll just have to trust me on this, but when you're in production, you either want something that doesn't need a configuration or a config file

10:10 in fact, i'm an advocate of putting the structure of your application in a config file! https://github.com/irresponsible/oolong/

10:11 dimon_: dimon_: sorry, I don't understand why not.

10:11 thanks for the links, but that's for configs.

10:11 whereas I'd like to know

10:11 the idiomatic way to setup Korma

10:11 and sorry, I don't understand why I can't use project.clj

10:11 dysfun: in production, you don't have a project.clj

10:11 dimon_: for the production connection string

10:12 dysfun: the simplest way to deploy an app is java -jar my.jar

10:12 dimon_: but it's it or its content get embedded into a jar?

10:12 dysfun: if you put your data in project.clj (as you can do with some libraries), then it's hardbaked in when you build the jar

10:12 no, they do not

10:13 there is some metadata xml and your clojure files and java files. that is it

10:14 so what you should do instead is deploy a directory containing a jar, a config file and any resources you require that the user might want to update (i.e. that aren't baked into the jar)

10:14 dimon_: alright, so I can create a config file and copy it on a prod. server?

10:14 dysfun: yes. at deploy time, you will copy over your jar and config file

10:15 and any resources your jar is dependent on that aren't baked in

10:15 (e.g. html templates)

10:15 dimon_: ok. but today I deploy only a single jar without the directory "templates" and it worked well.

10:16 dysfun: did you bake templates into the jar?

10:16 dimon_: hmmm, I think I haven't copied those template files on the server

10:16 dysfun: (if you put them in resources, probably)

10:16 dimon_: dysfun: probably, I just built a jar the way you normally do.

10:16 dysfun: that's a perfectly valid strategy, but bear in mind that you can't then change it while the server is running

10:17 dimon_: ah, yes, they're in the "resources" directory, so I can put my config in it as well. Although I think it's better not to.

10:18 dysfun: i tend to find it inconvenient rebuilding releases just to change some configuration

10:18 dimon_: I see. Thanks

10:18 dysfun: yw :)

10:19 there are two schools of thought on this btw

10:19 the other one favours environment variables

10:20 and clojurists who grew up on java might even say properties files

10:20 but they're wrong ;)

10:22 https://github.com/weavejester/environ has support for what you actually asked for if you're convinced i'm wrong

10:23 sdegutis: Good morning. What are transducers useful for to an app developer (not library developer)

10:23 MJB47: performance (sometimes)

10:24 dysfun: reuse of a transform (e.g. across core.async)

10:33 sdegutis: MJB47_: when?

10:33 MJB47_: when you chain transducers, they do the transformation without the intermediary data structures

10:33 so instead of doing map, and then filter, it does them both in 1 go

10:33 which helps... sometimes

10:36 sdegutis: MJB47_: Ah, that could be very helpful to me. Thanks!

10:37 ilevd: Can Clojure be faster than Java?

10:38 MJB47_: hard to define

10:38 they both compile down to JVM byte code

10:38 so in theory they are comparably performant

10:38 but the thing is

10:38 Arie: anyone here using re-frame?

10:39 MJB47_: do you mean perfectly performance tuned clojure vs perfectly performance tunes java? or idiomatic clojure vs idiomatic java? etc

10:39 in general, clojure will be/can be as or more performant than java

10:39 there isnt anything necessarily holding it back

10:39 ilevd: Clojure with some magic like transducers vs idiomatic Java

10:40 MJB47_: well you can do the same sort of thing in java

10:40 and if performance were a main concern, you probably would

10:41 ilevd: Yeah

10:41 It's nice that one can add java files to clojure project

10:42 Arie, I only read about it and want to use :)

11:05 justin_smith: idev: dysfun: there's no reason that clojure could not detect tail-calls and turn them into recur automatically, but it's actually useful (and prevents a common source of errors) to require the usage of recur explicitly, so that you can reject it when it's not the tail position

11:05 now generalized tail-call elimination (that might not be recursive) - that is a jvm limitation - goto can't cross method boundaries

11:06 and a good scheme or common lisp can eliminate tail-calls that are not recursive

11:11 ilevd: transducers can help you approach the performance of idiomatic java, but persistent data structures have a cost (though they are very optimized), in clojure code that's in a bottleneck and needs to be faster, sometimes it makes sense to use java arrays and hash-maps for the extra performance boost.

11:12 But there's tradeoffs there between performance and correctness / clarity.

11:54 wutf: anyone using lispy-mode?

11:54 i can't figure out how to write a simple defn with args because [ and ] are bound !

11:54 supposedly it's been tuned for clojure

12:09 justin_smith: wutf: I just skimmed the docs, but shouldn't [ and ] only do their special thing when your cursor is on a paren?

12:11 wutf: that's what i thought, but it doesn't work that way

12:53 lokien_: hey guys, long time no see

12:54 hey guys, long time no see

12:54 what are the best bindings for javafx?

12:56 are you using javafx with clojure at all?

13:27 :^(

15:24 Wojciech_K: ,((fn [f] (f 3)) Math/sqrt)

15:24 clojurebot: #error {\n :cause "Unable to find static field: sqrt in class java.lang.Math"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to find static field: sqrt in class java.lang.Math, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to find stat...

15:25 Wojciech_K: sqrt is Math static field

15:25 (Math/sqrt 3)

15:25 ,(Math/sqrt 3)

15:25 clojurebot: 1.7320508075688772

15:25 Wojciech_K: ?

15:29 a wrapper works fine

15:29 ,((fn [f] (f 3)) (fn [x] (Math/sqrt x))

15:29 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

15:29 Wojciech_K: ,((fn [f] (f 3)) (fn [x] (Math/sqrt x)))

15:29 clojurebot: 1.7320508075688772

16:02 justin_smith: Wojciech_K: on the jvm, a static field is not a first class entity

16:02 as such, you can't pass it as an argument to a function

16:02 arguably, clojure could implicitly wrap it in a lambda, but the choice was made to make that conversion explicit (it isn't free)

16:03 Wojciech_K: oh, it isn't a field, it's a method - the vm handles those things differently

16:04 a static field can have its value resolved, and that value can be used as an arg

16:04 ,(* Math/PI Math/E)

16:04 clojurebot: 8.539734222673566

16:04 justin_smith: sorry for the inaccuracy of the initial reply

16:11 herakleitos: Does anyone know if calling keys on a map is stable? I noticed that there's a comment on clojuredocs saying that keys doesn't always return in the same order, but I was wondering if that's been fixed since.

16:12 luma: there's no defined order for keys in a map (unless it's a sorted map)

16:12 justin_smith: herakleitos: "fixed"?

16:12 herakleitos: there is a guarantee that keys and vals return items in matching order

16:12 but no guarantee about order between elements in general

16:13 luma: for the same map instance, the order is always the same

16:14 herakleitos: Thanks, that's what I wanted.

16:15 justin_smith: also, for code that needs keys and vals to be in the same order, there is often a simpler and more efficient alternative that iterates over the pairs rather than iterating over two separate sequences

16:17 herakleitos: I'm calling keys on the same map instance at 2 different places in my code and I want to be sure that it'll always return in the same order.

16:18 justin_smith: for the same map, yeah

16:31 sdegutis: Sometimes I want (contains-value? val coll)

16:32 justin_smith: like contains? but with the args in the wrong order and checking vals not keys?

16:32 luma: (some #{val} coll)

16:33 sdegutis: justin_smith: yes, so that I can chain it at the end of a ->>

16:34 (->> coll (map :something) (filter wicked-cool?) (some #{needle}))

16:34 luma: thanks

16:34 luma: note: might break if val is falsy

16:34 sdegutis: right

16:35 I don't think I've ever run into that use-case yet.

16:35 Never needed to search for "false" in a collection to date.

16:38 justin_smith: ,(.indexOf [true nil false :a] false) ; sdegutis

16:38 clojurebot: 2

16:38 sdegutis: justin_smith: hi

16:52 justin_smith: ,(def contains-value? (comp (complement neg?) #(.indexOf %2 %)))

16:52 clojurebot: #'sandbox/contains-value?

16:52 justin_smith: ,(contains-value? false [:a :b :c false])

16:52 clojurebot: true

16:52 justin_smith: ,(contains-value? false [:a :b :c])

16:52 clojurebot: false

16:55 amalloy: justin_smith: .contains

16:56 justin_smith: d'oh, of course!

16:56 much simpler

17:55 sfz-: amalloy: you're my hero

Logging service provided by n01se.net