#clojure log - Apr 12 2016

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

2:13 akonring: \list

2:14 ben_vulpes: ,list

2:14 clojurebot: #object[clojure.lang.PersistentList$Primordial 0x794a8a15 "clojure.lang.PersistentList$Primordial@794a8a15"]

2:38 asdf12z_: if i have a map, is there an easy way to cherry pick a few keys off it to make a new map?

2:40 ah select-keys

2:48 dysfun: asdf12z_: you may find http://conj.io/ a useful reference

2:48 i tend to just ctrl-f through the page

2:54 ben_vulpes: so i get this bright idea to rewrite my deploy stack such that it never actually needs code on the remote hosts. "no github, no problem!" i think to myself. "compile locally, and ship jars around!" i think to myself "way faster than actually compiling or god forbid lein running on a t1.micro," i think

2:55 and it works fine. great, actually, at the office.

2:55 amalloy: uberjars are somewhat large

2:55 ridcully: rsync is your friend

2:55 amalloy: is where this is inevitably heading

2:55 ben_vulpes: but scping this bloated mason jar of deps over my home internet connection is, well, horseshit.

2:56 amalloy: i would be surprised if rsync helped at all with schlepping giant jars around

2:56 ben_vulpes: ridcully: are uberjars even amenable to optimization via rsync?

2:56 * ben_vulpes doesn't actually know what's in the box

2:57 ridcully: well helps me. my rsyncs are about 5mb on 100mb wars

2:57 but this is with gradle stuff

2:57 but i doubt that lein will make such a mess with each new build, that rsync can not cope with it

2:58 * ben_vulpes goes, tries

3:02 ben_vulpes: ibd

3:02 ridcully: my heeeero

3:03 dunno why i never thought of that.

3:03 ridcully: well i'd expect it to be only usefull, if you have huge junks of jars, that stay more or less on the "same place" in the file

3:03 also i dont know how how smart rsync is

3:04 ben_vulpes: me neither but that was about a zillion percent speedup

3:56 tolstoy: bittorrent sync? ;)

8:33 russellw: intaparse is slower than I was hoping for, is there a way to speed it up? http://stackoverflow.com/questions/36572997/any-way-to-speed-up-instaparse

8:50 dysfun: wow, that's impressively slow

8:59 if you find there isn't a way to speed it up, i can recommend parse-ez. it shouldn't take long to convert such a small grammar

9:03 russellw: It is indeed! Thanks, though I'll probably just end up switching to a handwritten parser

9:53 Lewix: Hi

9:59 Glenjamin: russellw: could you try streaming into that?

9:59 probably a bit late now

10:02 it also sounds like instaparse intends to be fast enough for what you want to do, so submitting that question as an issue might give the maintainer something to look at

10:02 there's a nice write up of its perf goals on the github project

10:03 oh, it only takes a string

10:23 russellw: Glenjamin, yeah. In any case, the time taken to read the string from the file is negligible

10:25 But okay yeah, I've submitted it as an issue

10:49 timmc: not very insta

10:49 MJB47: insta is obviously short of instagate

10:51 ridcully: i don't remember the source (might be something from clojuretv), but the solution suggested there was to chunk the input - might not always be possible

10:52 justin_smith: asdf12z_: regarding constants in let vs. defs, it's the opposite, defs have a performance penalty compared to let, which is more efficient

10:52 though (def ^:const foo 1) should in practice be equal to (let [foo 1] ....)

11:22 om`: ,(keyword "@")

11:23 clojurebot: :@

11:23 om`: ,(read-string (keyword "@"))

11:23 clojurebot: #error {\n :cause "clojure.lang.Keyword cannot be cast to java.lang.String"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.lang.String"\n :at [clojure.core$read_string invokeStatic "core.clj" 3677]}]\n :trace\n [[clojure.core$read_string invokeStatic "core.clj" 3677]\n [clojure.core$read_string invoke "core.clj" 3677]\n [sandbox$eval49 i...

11:23 ridcully: ,(keyword "Double/NaN")

11:23 clojurebot: :Double/NaN

11:23 om`: :@ is a legal keyword but the reader can't read it

11:28 MJB47: ,(name (keyword "@")) ; atleast this works

11:28 clojurebot: "@"

11:29 justin_smith: no, it's an illegal keyword, but the keyword function is happy to construct it anyway

11:29 ,(keyword " ")

11:29 clojurebot: :

11:29 justin_smith: keyword has no error checking whatsoever

11:30 tobyirc: hi! is anyone using Yesql with the latest java.jdbc?

11:30 because now jdbc logs deprecation warnings on every query

11:30 I can open a yesql issue but it seems println-ing the deprecation warnings is a bit heavy handed

11:30 "DEPRECATED: unrolled key/value arguments to query"

11:31 justin_smith: tobyirc: so the issue is that yesql uses functions in a way that is deprecated with the latest clojure.java.jdbc?

11:31 om`: thanks, justin (I wanted to use it to construct RDF prefixes)

11:32 tobyirc: justin_smith: yes but since it's the nicest way to do sql in clojure it seems that jdbc shouldn't have deprecated this :)

11:32 justin_smith: om`: yeah, keyword will accept any input, but the fact that it doesn't error is no proof that the keyword is acceptable, you should use the reader as a test for that if anything (but even then, the reader accepts keywords that the spec says are not valid)

11:32 om`: is there a way to know what keywords are (il)legal?

11:32 tobyirc: I think the secondary issue is that println isn't a great way to notify devs of deprecation

11:32 justin_smith: tobyirc: that sounds totally backwards to me

11:33 tobyirc: yeah, but java logging sucks

11:33 there's no universal logger they can count on there

11:33 tobyirc: indeed, but it would be nice to have a proper warning that could be disabled

11:33 or just note in the docs that it's deprecated instead of println

11:34 justin_smith: short-term hack would be with-out-str (which I admit is terrible)

11:34 tobyirc: yeah, that's pretty brutal :P

11:34 justin_smith: ,(do (with-out-str (println "shouting into the void")) nil)

11:34 clojurebot: nil

11:36 jjmalina: anyone have any good articles/talks that make the clojure is more simple and better than scala for newcomers?

11:37 +argument

11:41 Matrixiumn: spanner: ay

11:42 ¯\_(ツ)_/¯

11:42 tobyirc: justin_smith: turns out the correct answer is to just use hugsql http://www.hugsql.org

11:43 justin_smith: jjmalina: regarding the "simpler" part, I would consider that aspect uncontroversial, even to those who prefer Scala. Scala wants to abstract the JVM's model, Clojure follows it, one of these approaches is inarguably simpler than the other.

11:43 tobyirc: but yesql is pretty cool...

11:43 tobyirc: yep, although hugsql looks almost equivalent

11:44 justin_smith: tobyirc: oh, I had no idea...

11:45 tobyirc: yeah me either, a friend who turned me on to yesql says he uses this now and is much happier with it

11:48 jjmalina: justin_smith the argument I'm being given is that clojure's syntax is lisp therefore scala is easier for new people

11:48 MJB47: thats subjective

11:48 i would argue lisp syntax is much simpler, but less known/familiar

11:48 justin_smith: jjmalina: simple != familiar

11:49 jjmalina: clojure is unfamiliar to most, but lispish syntax is an order of magnitude simpler than the alternatives

11:49 Glenjamin: is Scala ML syntax? or some weird Java/ML hybrid?

11:49 justin_smith: Glenjamin: the latter

11:49 jjmalina: justin_smith i agree. but not sure how to express that argument

11:49 so I'm asking y'all for help :)

11:49 Glenjamin: i seem to recall it as ruby-esque precedence issues

11:49 tobyirc: because clojure is a lisp, you're able to tap into 50+ years of computer science literature. Scala is it's own thing and a dead end lineage. Your Scala knowledge will not be useful in the future.

11:50 gilch: operator precedence, for one thing.

11:50 Glenjamin: jjmalina: who do you need to convince? Can you make them watch simple made easy?

11:50 justin_smith: jjmalina: look at eg. logjban - an english speaker would call it "complicated" because they don't know it yet, but it is much simpler than english

11:50 Glenjamin: iirc there are some scala constructs where a() and a () do very different things

11:50 jjmalina: Glenjamin CTO

11:50 justin_smith: and this isn't a random assertion - it's a measurable property of its rules - same with clojure and scala

11:50 Glenjamin: then yeah, ask them to watch simple made easy before any more discussion

11:51 justin_smith: jjmalina: there could be an argument to be made that familiar is better than simple, but "simple" means something, and scala is not it

11:51 Glenjamin: see if they have an equivalent talk they think you should watch to be convinced

11:51 gilch: try writing a parser for Scala vs one for Clojure. which is easier?

11:51 Glenjamin: justin_smith: in clojure-land we choose to try and be precise about being simple, i'd argue that's not quite the same as "simple means something"

11:51 jjmalina: i like simple made easy, though it's a long talk

11:52 MJB47: i would go with, explain the 4 basic data structures, and thats it

11:52 thats the syntax

11:52 everything else is sugar

11:52 Glenjamin: except reader conditionals :p

11:52 justin_smith: Glenjamin: systems theory defines it :P - simple and complex are not weird new definitions hickey invented

11:52 Glenjamin: justin_smith: idd, but that precise use is not widely adopted

11:52 justin_smith: Glenjamin: complexity is measurable via systems theory, and simplicity is a low complexity measure

11:52 jjmalina: but yeah i think there are ways to dissect the familiar -> simple argument

11:53 justin_smith: these aren't subjective things, they are measurable

11:53 Glenjamin: words are all subjective

11:53 you're using precise definitions, which i agree with

11:54 but the person you're talking to might not

11:54 dysfun: language is hard, yo

11:54 Glenjamin: this is why simple made easy starts with a discussion of how the terms will be used, and why I recommend it so much

11:54 jjmalina: i'm coming from python and clojure seems more familiar to me than scala tbh

11:55 though I started writing my python as if it were clojure almost :P

11:55 * dysfun came from perl, and found the same, while his flatmate went off to scala. we both think we found the more perlish option

11:55 jjmalina: lol

11:55 Glenjamin: "this is a term, this is a precise meaning, this is why that's useful. Now: lets compare things using this term"

11:55 jjmalina: i tried reading "Programming Scala" and it was quite overwhelming

11:56 dysfun: Glenjamin: pah, just TLA the wibblywobble and frobnicate the flimflam

11:56 justin_smith: Glenjamin: you are right, I learned systems before I learned to program even, so the whole "this is what simple means" thing was just background noise to me, thanks for reminding me that most people lack that background

11:56 Glenjamin: see, this is why I like this IRC channel

11:56 dysfun: jjmalina: it's a bit of a kitchen sink language, that's why the book is so big

11:57 Glenjamin: Although I did actually manage to get in and out of haskell with an answer and no arguments the other day

11:57 dysfun: i did eventually find a use for it: propping up my monitor

11:57 it combines the functionality of two books into one

11:57 Glenjamin: so maybe IRC is getting better

11:58 dysfun: i got useful advice in #haskell today

11:58 justin_smith: Glenjamin: imho arguing is for when you respect the other person's intellect and think they might teach you something, if I just think someone is wrong it's not worth the wear on my keyboard switches to keep typing :)

11:59 Glenjamin: mm, the times when i do let myself drawn into an argument it's usually because I want to understand why the other person thinks something - what context do they have which i'm missing

11:59 dysfun: justin_smith: the harder thing is when you respect the person but not the viewpoint. quite a few of my friends have been embarrassing themselves of late :/

12:00 justin_smith: dysfun: oh yeah... when politics comes into play for example it can get painful...

12:01 dysfun: actually in this case, someone who has decided their pet technology is the best thing ever slagged off basically every language ever invented. badly. in ways i know to be wrong (in particular, clojure)

12:01 rcassidy: yeah, favoring a certain tool in the toolbox is a quick way to not get jobs done

12:02 Glenjamin: s/favouring/blindly favouring/ i'd say :)

12:02 dysfun: yeah, he focused his career energy on getting a name with one tool

12:02 justin_smith: rcassidy: "I need to remove this screw, and since I like my shiny sledgehammer so much, I'll just use that"

12:02 * dysfun has focused his career energy on learning new stuff

12:02 Glenjamin: hopefully everything I don't like, I can articulate why

12:02 and ideally, I can articulate why others do like it

12:03 dysfun: Glenjamin: until you can give me ten good reasons you hate a thing, you don't know it

12:03 Glenjamin: i do still get a bit annoyed when people tell me go is simple though :D

12:04 dysfun: go is the new php. except with concurrency. and non-thread-safe basic collections

12:04 Glenjamin: this page is my go-to for why I don't like it: https://github.com/golang/go/wiki/SliceTricks

12:04 dysfun: i am on a JVM performance list and the gist is "aww, that's sweet, they're finally having the discussion we had ten years ago about GC"

12:08 jjmalina: this ones good too http://www.jtolds.com/writing/2016/03/go-channels-are-bad-and-you-should-feel-bad/

12:09 Glenjamin: damn, I thought channels were one of the good bits

12:09 jjmalina: it's easy to get yourself into channel/go-routine hell

12:09 MJB47: they are controversial from what i can tell

12:15 dysfun: Glenjamin: basically, it's not CSP that is broken, it's go

12:15 Glenjamin: hrm, does that teardown apply to clojure too?

12:15 dysfun: not really

12:15 Glenjamin: the crux appears to be stopping a go-routine

12:16 dysfun: and not leaking them

12:16 (unlike core.async, you need to close channels)

12:17 jjmalina: it's funny that core.async has a "go" function

12:17 dysfun: it's not funny, that was rich's tribute to go for popularising the model

12:17 justin_smith: dysfun: aren't there issues with leaking resources in core.async too? (eg. go blocks that don't exit, so their resources stick around, if they are not exited properly?)

12:18 dysfun: justin_smith: not on the same scale

12:18 justin_smith: why's that?

12:18 (sorry for the toddler level question)

12:18 dysfun: go simply has a broader canvas of destruction

12:18 you have to explicitly free things etc.: you will fuck up more often

12:19 justin_smith: ahh, needing to explicitly reclaim things could get ugly with CSP, yeah, Ican see that

12:19 dysfun: and of course you'll be needing to guard everything with mutexes

12:19 data is generally mutable in go

12:20 that article has a good example. but in the real world you need to do this all the time

12:20 core.async comparatively lets you forget about things. go adds programmer load

12:41 sdegutis: Never mind, fixing it now.

12:43 justin_smith: I wonder if that was in reference to "justin_smith I have a race condition" at 7 last night, lol

12:43 Glenjamin: so if incoming requests started go blocks per "game", I don't see why we wouldn't hit the issue about zombie games filling up

12:43 apart from that in clojure we'd probably use an atom for that anyway

12:44 justin_smith: Glenjamin: well, it's a question of making sure the go blocks exit, right?

12:44 Glenjamin: i think so - in the go example they just loop on the incoming request, no :exit message

12:45 but that seems just as easy to do in clojure

12:45 so i wonder if there's something else i'm missing

13:26 jjmalina: rewatching simple made easy and it's hitting me pretty hard

13:27 prohobo: jjmalina: what?

13:28 jjmalina: it's very relatable :)

13:28 prohobo: what is it though?

13:29 jjmalina: prohobo http://www.infoq.com/presentations/Simple-Made-Easy

13:29 prohobo: thx

13:30 i like this

13:30 ty

13:30 here's an example of this in action: https://www.reddit.com/r/GlobalOffensive/comments/4efmes/this_would_be_a_couple_of_lines_of_code_for_valve/

13:31 > valve can't add a simple button to a menu because of design complexity

13:31 > everyone goes nuts

14:08 jrc_: Hi guys, I'm new to Clojure. I installed it via MacPorts, but Leiningen is using a different version somehow: http://pastebin.com/raw/vNWZ1fzB Is it possible that an older version of Clojure ships with OS X? And if so how can I configure Leiningen to use the Macports version?

14:09 justin_smith: jrc_: just use leiningen, don't use a package manager, leiningen is a better package manager than any one your OS offers

14:10 jrc_: So Clojure comes bundled with Leiningen?

14:10 justin_smith: jrc_: clojure is a library, leiningen uses your config to decide which version of that library to use

14:10 jrc_: there is no global install of clojure, as far as leiningen is concerned, this is actually a very nice thing

14:11 jrc_: leiningen is a tool that figures out which jars to download and add to the classpath when building / running your app, one of those jars is clojure.jar

14:12 jrc_: Oh I see, I had the wrong version in the project.clj dependencies

14:12 Thank you for the clarification, justin_smith

14:13 justin_smith: np, glad Icould help

15:17 mettekou: Is there an advantage of refs over atoms when updating a single storage location?

15:19 turbofail: nope

15:33 ben_vulpes: https://www.refheap.com/117424 << slamming into interop problems. anyone know why clojure can't find a ctor for this class?

15:33 * ben_vulpes restarts jvm just in case cljr's hotloading is weird somehow

15:39 ben_vulpes: aaaaa

15:39 afaict i'm doing exactly this, but in different parens: https://github.com/thebusby/clj-aws-iam/blob/master/src/aws/sdk/iam.clj#L38

15:45 picking the right version helped, fwiw

15:46 no idea why 1.3.23 didn't work though. NO TIME NO TIME.

16:31 cespare: Does anyone know why #^:optional [:foo] works? (It seems to be the same as ^:optional [:foo] )

16:31 ^ isn't mentioned as something that can follow the # in http://clojure.org/reference/reader#_dispatch

16:34 hiredman: #^ is old deprecated syntax that meant the same thing as ^

16:34 cespare: ah, thanks!

17:00 bmuk`: Hey everyone, I'm getting a classcastexception when I try to json/read a file I've slurped: https://gist.github.com/bmuk/7afe39e86b47f5c6cd611690904d9918

17:02 justin_smith: bmuk`: json/read wants something it can read from, you can use read-string or pass it the file instead of the text slurped out of the file

17:02 bmuk`: so I can just pass it a path?

17:02 justin_smith: (eg use clojure.java.io/file instead of slurp

17:03 bmuk`: slurp does not return a path either

17:03 maybe a path works, Iknow a file would

17:03 bmuk`: java.lang.ClassCastException: java.io.File cannot be cast to java.io.Reader

17:03 changed slurp to io/file

17:04 justin_smith: try io/reader maybe? something like that should work

17:05 bmuk`: that worked, thanks! It's sort of slow with how many files I'm throwing at it, though

17:12 asdf12z_: whats a beautiful way to do error handling, specifically im trying to do a http request, i wonder if there's a better way than if statement? or case statement

17:14 faxmodem: asdf12z_: try?

17:15 asdf12z_: ok just wanted to know my options, still learning, and i shouldn't say statements, i meant expressions hehe

17:16 justin_smith: asdf12z_: one nice compromise between throwing exceptions to indicate failure, and using failure-values, is to throw an ex-info

17:16 (doc ex-info)

17:16 clojurebot: "([msg map] [msg map cause]); Create an instance of ExceptionInfo, a RuntimeException subclass that carries a map of additional data."

17:16 justin_smith: so the one catching the ex-info can use that map to look for useful data about the failure

17:19 asdf12z_: justin_smith, it feels weird to have a user catch an exception though? especially when the outcome is kind of predictable, like in a http request it either succeeds or fails?

17:20 justin_smith: asdf12z_: exceptions are for things that a caller would know how to handle

17:21 asdf12z_: if it is not recoverable, use an error instead

17:21 aloha_: Hi! I’m having a hard time passing a little Ruby function to Clojure (it’s for a little test I did). I was able to do it in Ruby no much trouble, I'm a Rails guy, but I don’t understand almost nothing of Clojure as I only did some little things with Clojure some years ago. Is a little function to print an array of strings (and nested arrays of strings) with a each index

17:22 For example, if you have this array: `list = ['a stringy', ['y','e','s'], 'cheese', ['tomato']]` and you call the function printList (let’s call it that way) like this `printList('Goo', list)`, you would get the following output: `Goo.0: a stringy \n Goo.1.0: y \n Goo.1.1 : e` etc

17:22 justin_smith: asdf12z_: you can fight the platform (jvm) and use some kind of monad instead, (some sort of Maybe), but this is computationally expensive, and increases complexity to little benefit, IMHO

17:22 sdegutis: Is there something like assert that returns your value if it passes a test?

17:22 Something like (assert-test pos? n) which returns n if it's pos? or throws an exception otherwise.

17:22 justin_smith: sdegutis: doto

17:22 aloha_: I pasted in Repl.it if you want to see my little Ruby solution: https://repl.it/CEt1/0

17:22 asdf12z_: justin_smith, ok that's good info, i just didn't know if it was normal for me to expect users of my lib to catch

17:23 sdegutis: justin_smith: Exactly.

17:23 asdf12z_: since i just want to be able to communicate back heres the success data, or err

17:23 ben_vulpes: aloha_: i...

17:23 sdegutis: But I thought there was a built-in thing.

17:23 ben_vulpes: don't think things work like that around here.

17:23 you might do something with a for loop and format but uh

17:23 why do you need the list.idx.subidx noise?

17:24 sdegutis: justin_smith: also, doto doesn't work

17:24 ben_vulpes: oh that's your formatter in ruby i see

17:24 aloha_: Imagine you can do that little function in 2 minutes, just iterate each with index and print if its a string, or call itself recursivelly if not

17:25 yeah in ruby to interpolate variables in strings you use "TEXT#{var}TEXT"

17:25 like in JS "text" + var + "text"

17:25 ben_vulpes: ,(format "text%stext" "NOTTEXTATALL")

17:25 clojurebot: "textNOTTEXTATALLtext"

17:26 ben_vulpes: ,(def z :zazzle)

17:26 clojurebot: #'sandbox/z

17:26 ben_vulpes: (format "text:%s:text" z)

17:26 ,(format "text:%s:text" z)

17:26 clojurebot: "text::zazzle:text"

17:27 aloha_: cool!

17:27 ben_vulpes: something like that?

17:27 justin_smith: sdegutis: (fn [x f] (assert (f x)) x) is what you want, right?

17:27 sdegutis: Yeah.

17:27 I'll just do that for now.

17:27 But I really thought there was some function in clojure.core that was like that.

17:27 justin_smith: oh, and you might want a custom assertion string too...

17:27 sdegutis: Right on!

17:27 justin_smith: sdegutis: not that I know of

17:28 aloha_: ben_vulpes something like that for the formatting, yeah

17:29 sdegutis: Pkay, thanks.

17:30 aloha_: but how do I loop an array (with an index) and check if the item is a string, and if it is print it like that format (format "text:%s:text" z) and if not, recursivelly loops again the same function?

17:30 ben_vulpes: loop and recur

17:30 aloha_: I took the FizzBuzz code for Clojure from Rosetta code but can´t understand it, it’s like backwards for me haha

17:30 sdegutis: Uh oh.

17:30 I'm about to use (flatten).

17:30 help whatdoido

17:31 aloha_: then I thought maybe there is a clojure irc with lots of clojure hackers haha

17:31 sdegutis: aloha_: unfortunately nope theres not

17:32 aloha_: haha :p

17:32 sdegutis: ,(str "foo" 3 "bar")

17:32 clojurebot: "foo3bar"

17:32 sdegutis: ,({get get} {get get} {get get})

17:32 clojurebot: {#object[clojure.core$get 0x4330ea6a "clojure.core$get@4330ea6a"] #object[clojure.core$get 0x4330ea6a "clojure.core$get@4330ea6a"]}

17:32 sdegutis: ,(= {get get} ({get get} {get get} {get get}))

17:32 clojurebot: true

17:33 aloha_: so how do I do loop and recur? don´t kill me plz

17:33 jeaye: ,(doc loop)

17:33 clojurebot: "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target."

17:34 justin_smith: that doc string could be a 10 page tutorial instead

17:35 jeaye: Yeah, it's not very helpful.

17:35 sdegutis: Why doesn't this work?

17:35 ,(keyword :foo :bar)

17:35 clojurebot: #error {\n :cause "clojure.lang.Keyword cannot be cast to java.lang.String"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.lang.String"\n :at [clojure.core$keyword invokeStatic "core.clj" 595]}]\n :trace\n [[clojure.core$keyword invokeStatic "core.clj" 595]\n [clojure.core$keyword invoke "core.clj" 595]\n [sandbox$eval119 invokeStatic "N...

17:35 sdegutis: Why it has to be astring?

17:36 ,(keyword "foo" "bar")

17:36 clojurebot: :foo/bar

17:38 jeaye: sdegutis: The one taking just a name can be a string, symbol, or keyword.

17:38 The one taking a ns and name needs both to be strings.

17:39 https://www.conj.io/store/v1/org.clojure/clojure/1.8.0/clj/clojure.core/keyword

17:40 If you're asking for the actual "why," I don't know.

17:40 sdegutis: Right.

17:40 jeaye: ,(keyword (str *ns*) "foo")

17:40 clojurebot: :sandbox/foo

17:40 sdegutis: Thanks! jeaye.

17:40 jeaye: You been doing CLojure long?

17:41 jeaye: About 6 months. Not long.

17:43 hiredman: use ns-name, not str

17:47 sdegutis: Whoa, concat is literally unnecessary. It's probably pre-processed out during read time.

17:47 ,(= () (concat))

17:47 clojurebot: true

17:47 sdegutis: They're identical.

17:48 What does flatten due to maps?

17:49 ,(flatten [{:a [{:b 2}]]}])

17:49 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>

17:49 sdegutis: ,(flatten [{:a [{:b 2}]}])

17:49 clojurebot: ({:a [{:b 2}]})

17:49 sdegutis: ,(flatten [{:c 3, :a [{:b 2}]}])

17:49 clojurebot: ({:c 3, :a [{:b 2}]})

17:49 sdegutis: Hmm. Weird.

17:56 bmuk`: I'm not sure why, but my parse-file-set function is returning {}? https://gist.github.com/bmuk/49c9be5eda264966c26f19cae9b5b126

17:58 sdegutis: Whoa, why does assert not throw Exception?

17:58 I mean, AssertionError does not hail from Exception!

17:59 bmuk`: am I not using swap! correctly?

18:05 hiredman: ~map

18:05 clojurebot: map is lazy

18:05 bmuk`: but I requested the final value?

18:06 ridcully: what is gained here by using that local atom?

18:07 bmuk`: probably nothing; my thought process was: mutability -> atom

18:08 if I don't update the value I'll just be calling with an empty {} every time

18:11 hiredman: is there a strict version of map?

18:11 amalloy: bmuk`: you don't need mutability at all for that. it's a classic reduce

18:11 ridcully: well i have not looked at all of it, but at first glance this looks like a reduce

18:11 ben_vulpes: http://i.imgur.com/bZSGX6M.png << gross gross gross gross gross

18:12 what'd be a more idiomatic approach to marshalling all of this oop around?

18:13 amalloy: ben_vulpes: the grossest part of this is that you linked to a png instead of text

18:13 ben_vulpes: :(

18:14 amalloy: meanie

18:14 https://www.refheap.com/117432

18:14 bmuk`: amalloy: you're right

18:14 can I keep parse-api-call the same? Trying to wrap my head around converting this to reduce

18:15 ridcully: is that def right in the middle intended?

18:16 ben_vulpes: i did not want to, no.

18:16 amalloy: bmuk`: you can mostly. you might have to flip the order it takes arguments

18:17 ben_vulpes: alternative appeared to be to bind all of the side-effecty shit to _ in the let

18:17 i am already adequately guilty of doing all of my imperative programming in let statements, ridcully

18:17 but perhaps here it is justified? i bring it to the sages for dissection.

18:17 amalloy: ben_vulpes: you can inline anything that's only used once

18:17 ben_vulpes: no, no. in-fn defs are never justified.

18:17 amalloy: user-request, for example

18:18 i would probably turn this into a mess of doto and ->, which some people would hate

18:19 ridcully: i guess even some let cascade would look better

18:19 ben_vulpes: > let cascade

18:20 yeah i considered that too

18:20 i mean it's trivially refactored, i'm mostly curious about how the pros would handle this kind of oop marshalling cleanly.

18:21 (justin_smith ??)

18:22 bmuk`: amalloy: this worked, thanks a billion: https://gist.github.com/bmuk/49c9be5eda264966c26f19cae9b5b126/revisions

18:23 sdegutis: Throwable it is then

18:24 amalloy: ben_vulpes: you could do something like https://gist.github.com/amalloy/b7a552dd3d2d16e66cff80c7c04b4180, which is what i was saying re doto

18:25 ridcully: ben_vulpes: well that leaves me out ;) i'd try to bring the two policy thingies up into the let (use doto) and then deal with the client at the end. if the policy-result needs another let, so be it. then try to inline the policy thingies and see how that looks

18:26 ben_vulpes: amalloy: notbad

18:26 way cleaner

18:26 ty

18:26 ridcully and friends thanks as well

18:26 amalloy: doto is a better java than java

18:26 ben_vulpes: hyuuuuu

18:34 aloha_: well my first try to make the printList function is giving a StackOverflowError (imagine something with the loop. here it is: https://gist.github.com/anonymous/7f2d86b1895bebb1aa573febaf3b99f8

19:08 momerath: so, I just did a bunch of misguided debugging surround lein and my system, because it was stalling out, with no visual output (and I get some at compile time from macro debug prints). I discovered the problem was (as I should have known because I just did it), that I'd moved a top level def, which called a function that wasn't safe to call at compile time, from a test namespace, where it worked, to a

19:08 src namespace. So, I don't need help debugging that, but can anyone tell me if there is an idiomatic way to assert in functions like that (ie, what's a good way to detect that it's compile time?)?

19:11 amalloy: momerath: *ns* will be bound to something interesting while compiling. at runtime it's probably something like clojure.core, or user

19:12 but of course "compile time" includes anything you're doing in a repl

19:12 momerath: hrm- yeah, that's a problem :-/ I guess I'll just guard against use when the specific environmental things are missing from a given function

19:46 justin_smith: momerath: the real thing to do is not put things with side effects at the top level of your code

19:46 and if you do, you'll learn to recognie the errors this causes

19:47 tolstoy: Would `delay` help?

19:49 momerath: I do; this is the first time I've run into it in 18 months of full time clojure. it happened because it was safe to do in a test.check test that I was still developing, and there seems to be a trick to calling functions defined in test namespaces at the repl (ie, (ns 'my-proj.thing-test) succeeds but the functions are undefined)

19:50 justin_smith: momerath: ns does not load source files (except via require clause)

19:50 momerath: ah- that would explain it. so I should look to 'require'?

19:50 justin_smith: (doto 'my-proj.thing-test require in-ns)

19:51 is the nifty way to do it

19:51 momerath: heh- that is nifty :)

19:51 thanks!

20:57 bmuk: I'm having trouble writing a function to operate on my data. I have hashmap with method names as keys, and a list of hashmaps as values, each with a :request key (hashmap value) and a :response key (same). I want to reduce the list of calls to a single hashmap (:request and :response as keys) with all the keys present in the entire list accounted for and with the Type of the current value as their value

20:57 Right now I'm like 3 lambdas deep and I realize I'm probably going about this the wrong way

20:57 clojurebot: It's greek to me.

20:58 TEttinger: hey bmuk

20:59 are they method names or methods?

20:59 because you CAN use fns as keys

20:59 bmuk: method names

20:59 TEttinger: ,(map #((first %) (second %)) {inc 1 dec 10})

20:59 clojurebot: (2 9)

21:00 bmuk: they are strings, not clojure method names

21:00 TEttinger: ok

21:00 bmuk: hang on, I'll filter out sensitive data and make a gist of an example

21:00 tolstoy: Hi folks. Is there a way to detect arity errors at runtime?

21:01 Sorry, compile time?

21:01 amalloy: you can run eastwood. it catches some such errors

21:01 TEttinger: bmuk: is Type referring to Typed Clojure stuff?

21:01 tolstoy: But in general, that's just the nature of the dynamic language, right?

21:02 amalloy: yes, the languages is designed to defer type errors to runtime

21:02 bmuk: TEttinger: no, the result of (type %)

21:04 TEttinger: so what does the current value refer to in the last section of your message?

21:05 bmuk: it's hard to explain since it's so nested, I'm cleaning up the test data now and I'll post a gist

21:06 TEttinger: I'm pretty sure this will be possible with some fancy one-liners, knowing the people here who like to code golf :)

21:07 as the saying goes though, it takes a village to write a clojure one-liner

21:08 amalloy: i predict that with "standard" indenting and newlines it will take 4-7 lines, but could be squeezed into one on irc

21:09 TEttinger: with "non standard" indenting it could be stretched to many more!

21:10 bmuk: here is an example of a map of just one method: https://gist.github.com/bmuk/46df9d90ccd3fde52bae5bb80625b1be

21:14 I want a map with "SignIn" as the key and a map as the value (henceforth called apicall). Apicall has two keys, :request and :response. The value associated with :request should be a map with a superset of the keys in every :request in the current list of maps associated with "SignIn", the values of those keys should be the type of the current values where possible, nil where not. :response should be the same

21:16 Basically the end result I'm looking for is a map from api method names to request/response object pairs that have all the possible data. I want to use this to generate documentation where I can

21:24 amalloy: bmuk: i would write https://gist.github.com/amalloy/f4744a190594c6d2f25909b9a8370f84

21:24 where "inputs" is the map you pasted

21:25 took me 8 lines, though. i guess i could have collapsed line 3-4 into: {}, (for ...)

21:26 and it doesn't address the question of maps as arguments

21:29 bmuk: thank you amalloy!

21:29 amalloy: like a lot of things, you can split this into two parts: one part that consumes the raw input and produces some intermediate useful structure (here, a list of pairs like [["signin" :request "invitation-id"] String]), and then a second part that consumes that useful structure, often with a reduce

21:30 bmuk: what is generally your strategy when dealing with a complex structure like this?

21:31 amalloy: mmm. iterate over it, really, until i get to a point when there's nothing interesting left to iterate over, and then see what useful data i can produce

21:31 for is pretty good at consuming nested structures, so i often start there

21:32 bmuk: It definitely looks like it; I wasn't aware of for

21:32 amalloy: this particular question is one i've answered a lot of times, so i already knew the answer. you want to iterate over a nested map and produce a series of the legal keyseqs in that map

21:33 bmuk: I'm essentially bumbling through learning clojure by making useful things

21:33 amalloy: good plan

21:56 bmuk: Is this stylistic and idiomatic? https://gist.github.com/bmuk/49c9be5eda264966c26f19cae9b5b126

21:56 in other words is there anything glaring I can improve?

22:00 amalloy: there's nothing too awful. your -main is rather messy in general; you're missing a chance to simplify with destructuring at https://gist.github.com/bmuk/49c9be5eda264966c26f19cae9b5b126#file-core-clj-L16; #(cons whatever %) should probably just be conj whatever in https://gist.github.com/bmuk/49c9be5eda264966c26f19cae9b5b126#file-core-clj-L40

22:02 bmuk: what do you mean specifically regarding destructuring?

22:08 amalloy: you're taking in a 3-vector, and instead of destructuring it you call first and last

22:14 bmuk: ahh got it

22:16 conj over cons because I want to append instead of prepend?

22:17 amalloy: because you don't care whether you append or prepend, and conj fits into the update-in model better

22:18 bmuk: ok. would breaking out the argument parsing into it's own method make -main more palatable?

22:31 sdegutis: What's the thing like flatten but only at one level?

22:34 asdFREjglk: not sure.. concat can do that...

22:34 amalloy: ~flatten

22:35 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

22:35 amalloy: bmuk: i don't really have time for detailed feedback on -main now, sorry

22:37 bmuk: that's fine

22:44 sdegutis: Thanks

23:50 tolstoy: Golang insists on tabs for spacing? *shudder*

23:50 blockzombie: oh really?

23:50 jack_rabbit: Yeah, there's a few formatting things golang insists on that are sort of crappy.

23:50 blockzombie: I have been playing with it and didn't notice that

23:50 jack_rabbit: there are, rather.

23:50 blockzombie: ew

23:51 I'm ok with how python does it

23:51 tolstoy: https://golang.org/doc/effective_go.html#formatting See the "Indentation" hanging indent list.

23:51 "We use tabs for indentation and gofmt emits them by default. Use spaces only if you must."

23:51 blockzombie: thanks for the link

23:52 oh ok but it's not a compile error

23:52 tolstoy: So, "insists" is a bit strong, but maybe "strongly encourages" is more accurate?

23:52 blockzombie: ok so they're weird, not unreasonable

23:53 tolstoy: Yeah. But, oy. I think Emacs isn't too friendly with that kind of thing.

23:53 And then looking at code in github with those wide, wide tabs.....

23:54 But, yes. A matter of taste.

23:55 Seems like a neat little non-functional language, though. I wonder if it's a much smaller memory footprint than the JVM?

Logging service provided by n01se.net