#clojure log - Jan 05 2017

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

10:44 smandy: hi all, has anyone got a simple example of embedding nrepl into an existing app so I can poke at it from cider in emacs?

10:44 the examples I find are mostly clojure examples. I'd like to see a java one...

10:45 dysfun: there are mostly just gists floating around on github i think

10:46 smandy: dysfun: thanks - found one.

10:46 dysfun: clojure is super easy to embed, so you have the option of just using the snippet on the "java interop" page and adapting it

10:48 smandy: dysfun: yeah what I'm doing not working. Does clojur eneed to have a runtime booted up or something?

10:50 dysfun: it needs to be included as a dependency in your build

10:51 org.clojure/clojure

10:51 (e.g. 1.8.0 )

10:51 smandy: dysfun: I've got that far. Cider seems to connect then immediately disconnect. Neither party reporting anything too helpful :-(

10:52 dysfun: lovely

10:52 smandy: Hmm.. in messages cider claims 'Establishing SSH tunelled connection' Not sure if that's what I wanted... (using cider-connect).

10:52 dysfun: *ssh* tunnelled?

10:53 how are you connecting to nrepl from cider?

10:54 smandy: cider-conect then answering host/port questions...

10:54 sobel: my brief experience adding clojure to a java project: i think i saved myself some trouble by deploying an uberjar to a local maven repo, so all the clojure-side deps got managed by lein

10:55 then i simply added a dep on that uberjar from my java app, regular maven style (hacking pom.xml)

10:55 dysfun: can't maven recursively add deps?

10:55 sobel: of course it can

10:56 the thing was letting lein indicate all my clojure deps in the ubjerjar and maven resolves those recursively from the java app side

10:57 point being, i gotta list the deps in project.clj, deploying an ubjerjar automates those into my java app via 1 dep

10:58 maintaining similar lein deps in pom.xml seems error-prone. i like the automation for progmatically squeezing out a class of build error.

11:13 * osfabibisi grows at boot.properties

11:13 osfabibisi: it has a list of what look like environment variables

11:13 but aren't

11:13 it would actually be Really Convenient to have boot set some environment variables for us in development ...

11:14 e.g. so that we can run 'boot test' and 'boot run' locally, instead of 'some-locally-hacked-together-boot-wrapper test'

11:30 dysfun: osfabibisi: however the properties do share the name of environment variables

11:31 but no, they're java properties in a properties file

11:31 osfabibisi: we're doing that part of 12-factor

11:31 so much of our config is in environment (via baked AWS config, or consul or whatever)

11:31 I don't understand java properties at all

11:32 but certainly going to boot repl and typing (get-env) doesn't show me anything usefully like the result of (System/getenv)

11:42 sobel: really? aren't they a serialization of HashMap?

11:42 that you can access via the classpath

11:43 i always liked the pattern of hardcoded defaults -> props files -> env vars

11:43 (order of priority/fwd reference)

11:44 so props files might indicate env vars that could contain values that override defaults or props. for example.

11:51 osfabibisi: ah. I don't really know java, which doesn't help

11:51 and when you search for e.g. "how do I get boot to set environment variables?" it doesn't help that it talks about "environment" and you don't know whether it means the OS ENV, or Java environemnt, or the "boot environment"

11:54 sobel: "the environment" generally means the actual OS-supplied environment variables. i've never heard it to mean props files. sometimes people point to props files with env vars or vice-versa but they are distinct in my experience

11:56 osfabibisi: ok... but in your build.boot, (set-env!) doesn't set an environment variable

11:57 sobel: i think that's an unfortunate overloading of "environment" in/by boot docs

12:12 dm3: osfabibisi: Boot has its own environment which you modify with `set-env!`/`merge-env!` and the likes. The system environment in Java/Clojure is accessed via `System/getenv`/`System/getProperties` and various other wrappers people have built around it (e.g. https://github.com/weavejester/environ)

12:14 osfabibisi: ah yes, "It works well for applications following the 12 Factor App pattern"

12:15 I think we'd glanced at it briefly, and though it was better to use System/ for now

12:15 but I'll have another look, ta dm3

12:18 sobel: 12 factors sounds like a lot

12:19 technomancy: it signifies completion or perfection in jewish numerology

12:19 sobel: that's obnoxious of boot to overload "environment"

12:19 numerology has a place in s/w eng?

12:21 technomancy: software engineering is largely superstition anyway; might as well openly acknowledge it

12:21 sobel: ...

12:22 technomancy: "I heard node.js is really good at scaling because it has async."

12:22 osfabibisi: I hear it's web scale

12:22 and real-time

12:24 jmasseo: i liek empiricism in my software

12:25 osfabibisi: imperialist swine!

12:28 deadghost_: webscale non-blocking scrum enterprise waterfall

12:30 make sure to spin your laptop around 3 times before running your tests

12:30 MJB47: hands up who has a rubber duck on their desk

12:31 TMA: those are immensely hard to come by

12:31 osfabibisi: if they're hard, the rubber has probably degraded

12:31 TMA: not cool enough for the toy stores to stock them, not enough geek stores around

12:34 hiredman: clojurebot: hiredman is a rubber duck

14:00 justin_smith: TMA: your city and mine are different

14:28 dysfun: oops, i appear to be drunk and in charge of clojurescript

14:29 justin_smith: dysfun: this day in history, 1998: "oops, I appear to be sniffing glue and in charge of PHP"

14:30 dysfun: no dude, my descent into depravity isn't for another decade yet (i hope!)

15:12 tdammers: justin_smith: sadly, not much has changed, except the amount of glue

15:14 ragepandemic: Is there a recommended way of dealing with uniqueness validation spanning multiple columns in the luminus stack? I haven't really found any info in bouncer

15:14 tolstoy: Does :pre / :post go before the docstring, or after?

15:14 After params, before docstring?

15:15 amalloy: tolstoy: everything after the params is function body

15:15 tolstoy: Where is this documented?

15:15 amalloy: there is no such place as "after params, before docstring", because the docstring goes before the params

15:15 (doc defn)

15:15 clojurebot: "([name doc-string? attr-map? [params*] prepost-map? ...] [name doc-string? attr-map? ([params*] prepost-map? body) + ...]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata. prepost-map defines a map with optional keys :pre and :post that contain collections of pre or post conditions."

15:15 tolstoy: Oh, right.

15:16 amalloy: really, you put prepost-map after params?

15:16 it this a dang joke?

15:16 tolstoy: And there I was wandering around in special-forms.

15:16 amalloy: i guess it makes sense because the preconditions depend on params

15:16 tolstoy: Yeah.

15:16 (defn name doc-string? attr-map? [params*] prepost-map? body)

15:17 amalloy: kinda funny though that if you want to define a function that returns a precondition map (eg for use in a macro) you'd have to wrap it in (do {:pre ...})

15:20 tolstoy: I've seen new folks put the doc string after the params and ... it doesn't error out. ;)

15:21 ragepandemic: I have these DB constraints https://www.refheap.com/124505 and I haven't really found a "nice" way of dealing with them (E.g. django which throws a validation exception). I could always do an explicit query for title, artist and album, but that doesn't feel like a nice way of doing it

15:23 kwladyka: (s/def ::weight (s/and number? pos?)) -> generate Infinity - is it something new for clojure spec? i didn't notice it before.

15:23 i really don't want such value, how to remove it?

15:24 ridcully: ,(Double/POSITIVE_INFINITY)

15:24 clojurebot: Infinity

15:25 kwladyka: ok but how to prevent clojure spec to generate this value?

15:26 oh probably i should add something like int? there

15:26 luma: by changing the spec so that infinity isn't a valid value

15:26 kwladyka: hmm i didn't notice it before...

15:26 amalloy: "new folks". i do it myself all the time, tolstoy. aside: one good reason to run a linter

15:28 kwladyka: sorry, my fault

15:28 osfameron: what's a good clojure linter?

15:28 ragepandemic: amalloy, are there any linters?

15:29 ridcully: 1.9 would fail to compile, right?

15:29 atleast there is a spec for defn

15:29 amalloy: eastwood

15:29 luma: there's eastwood

15:30 * osfameron giggles at terrible pun

15:31 technomancy: https://p.hagelb.org/clap.gif

15:31 I. Just. Got. That.

15:32 now I know how those people who get the Leiningen reference after using it for three years feel like I guess

15:32 ragepandemic: nice, thanks

15:33 technomancy, can you explain, just incase there's people here that don't know... haha

15:33 osfameron: the Leiningen one probably requires you to aware of the obscure children's book doesn't it?

15:33 technomancy: it's not a children's book, but sure; it's obscure

15:34 https://en.wikipedia.org/wiki/Leiningen_Versus_the_Ants

15:34 osfameron: leiningen is a terrible name, but at least it's googlable. boot one-upped them on that front...

15:34 technomancy: on the other hand it did get made into a film with Charleton Heston

15:34 ridcully: theres a movie?

15:34 technomancy: https://en.wikipedia.org/wiki/The_Naked_Jungle

15:35 ragepandemic: well, TIL

15:35 thanks

15:35 technomancy: ...any time?

15:35 osfameron: hmm, I wonder why I thought it was a kids' book, nvm

15:36 ridcully: that sounds awesome

16:08 Frozenlock: osfameron: because once upon a time kids stories were full of violence and dire consequences.

16:09 osfameron: just like the Tiger Who Came To Tea!

16:13 Frozenlock: I was thinking a little older. Like this one https://en.wikipedia.org/wiki/Pied_Piper_of_Hamelin

16:14 ragepandemic: does compojure-api support spec by any chance?

16:14 osfameron: woo, ooo, another thing that a linter might have caught... boils down to e.g. (defn foo [a] + a a)

16:14 what does that *actually* do?

16:15 oh, because you can have any number of forms in a function, and those forms can be atoms

16:15 they're just helpfully ignored (except the last)?

16:32 amalloy: osfameron: (a) "atom" is a different thing in clojure; (b) they're evaluated for side effects, not ignored

16:35 scriptor: hm

16:35 is there any tway that just referencing a var could cause a side effect?

16:36 amalloy: well if the var doesn't exist, you will get the side effect of an exception being thrown

16:37 at compile time, i guess

16:43 justin_smith: if you expand from vars to classes, there are definitely classes that do weird things when referenced (even if you don't do anything to them)

16:44 amalloy: well. when referenced for the first time

16:44 loading them isn't really the same thing as referencing them at all

16:47 timvisher: i desire a positional data structure that is indexed by a string, such that index-of is constant time.

16:48 so (index-of ["foo" "bar" "bat"] "bar") => 1 or whatever

16:49 rather than using, say, a hash-map with values as the position

16:49 i feel like this must already exist

16:49 amalloy: constant time lookup by an arbitrary string? i feel like this not only doesn't already exist but is impossible

16:50 log(n) is easy

16:50 TEttinger: yeah, constant time is probably right out because keys require some amount of time to hash, longer for longer strings

16:50 technomancy: constant time is also somewhat at odds with special relativity

16:51 timvisher: hmm… am i using the wrong term?

16:51 TEttinger: oh you

16:51 technomancy: TEttinger: =D

16:51 TEttinger: O(1) is constant time, sorta

16:51 timvisher: aren't key lookups in hash-maps considered 'constant time'?

16:51 TEttinger: strictly speaking, no

16:51 timvisher: ah

16:52 TEttinger: they're O(something related to k)

16:52 where k is the key size

16:52 not sure if it's log(k) or k

16:52 timvisher: well then i guess what i mean is that i want a data structure that i can dump stuff into, and then use the stuff dumped into it to lookup what order i dumped it in as

16:52 that has something like the performance of a hash map :)

16:53 TEttinger: you may want ordered collections,which are a clojure lib called... ordered

16:53 in flatland

16:53 those don't, as far as I recall, allow you to get what ordering position an item is at

16:53 amalloy: they also assume items in the coll are unique

16:54 timvisher: the items i'm dealing with are unique

16:54 TEttinger: but it's trivial to use two collections here, one a map of strings to ints (assigned sequentially) , and one a vector of strings

16:55 amalloy: "trivial" unless you ever want to remove items

16:55 timvisher: i'm mapping a string to a priority, and i was hoping to avoid the monkey work of manually writing out the ordering

16:55 TEttinger: (it gets less trivial if it changes, yeah)

16:55 timvisher: and yes, making it easier to edit

16:55 whatever :)

16:55 TEttinger: immutable, though, amalloy :)

16:55 amalloy: what does immutable have to do with it. disj and pop exist

16:56 and dissoc

16:56 timvisher: but yeah i guess this is less common then i thought it would be :)

16:57 TEttinger: amalloy: I was being somewhat snarky about how clojure data doesn't change after creation

16:57 amalloy: timvisher: if you can reframe your problem to generate a lazy seq of all insertions you need to do up-front, then you can just wrote (zipmap insertions (range))

16:57 timvisher: amalloy: right. i can play with it like that. just figured this would be a standard data structure that i hadn't heard of before :)

16:58 there is of course .indexOf on a vector but that's not anything like a hash-map lookup

16:58 but honestly what i'm playing with right now is so small it's not going to matter

17:08 technomancy: psa: seattle clojure group is this evening

17:09 justin_smith: so is portland clojure group

17:09 sorry, you have to pick one, can't be at both

17:09 jeaye: What about SF Clojure group, if there's such a thing? :)

17:20 justin_smith: things not to do: debug code with the cache layer in front of it still turned on

17:55 ryan123: What books do you all recommend for a Clojure beginner? I got half way though "living clojure" and "clojure for the brave and true" and didn't like them much. I like books that have me writing code and thinking as I learn, not just copying code line by line from the book to see what it does... I really like the K&R C book.. show me a few key thing

17:55 and have me write code and try to solve small problems...

17:56 tolstoy-: Maybe you don't need a book at all?

17:56 Just start up a project, then ask Google?

17:57 ridcully: or go for one of the code challenge sites out there (e.g. 4clojure)

17:58 tolstoy-: I tend to want to learn, first, how to query a database or set up a quick webservice before I get interested in partition or group-by or whatever, so I'm guessing it depends on how you learn.

17:58 ryan123: Good suggestions.. I do like learning from a book first though... or along side something like 4clojure.

17:59 Has anyone read "professional clojure" or the o'reilly "clojure programming" books?

18:17 technomancy: the oreilly one is great

18:29 devn: long live clojure irc

18:53 justin_smith: professional clojure is very good too

18:54 it has a bunch of stuff I had to learn by hanging out in IRC because it wasn't in books at the time

18:59 mikeyhc: https://www.tab.co.nz/racing/runner.html?date=2017-01-06&meetno=2&raceno=1&entryno=1

18:59 whoops, ww

20:48 itissid: Does someone have access to clojure source Javadoc

20:48 Link pls..

20:53 om: itissid: they are on maven

20:59 itissid: om: https://mvnrepository.com/artifact/org.clojure/clojure/1.9.0-alpha14 ?

20:59 Thats just the jar. I wanted a browsable javadoc link though..

21:00 om: yeap

21:01 itissid: if you use Dash, you can import the jar and browse it there

21:02 itissid: but there are very few comments, you'd be better off reading the source

23:27 marshzor: ,(->> (range) (filter odd?) (map (+ 2)) (take 3))

23:27 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

23:34 justin_smith: marshzor: (+ 2) is 2

23:34 2 is not a function

23:34 ,(+)

23:34 clojurebot: 0

23:34 justin_smith: ,(+ 2)

23:34 clojurebot: 2

23:35 justin_smith: ,(1 2 3)

23:35 clojurebot: #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval113 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval113 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval113 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 69...

23:35 justin_smith: err

23:35 ,(+ 1 2 3)

23:35 clojurebot: 6

23:36 justin_smith: ,(sequence (comp (filter odd?) (map #(+ 2 %)) (take 3)) (range))

23:36 clojurebot: (3 5 7)

23:36 justin_smith: (bonus transducer version)

23:43 marshzor: ,(->> (range) (filter odd?) (map #(+ 2 %)) (take 3))

23:43 clojurebot: (3 5 7)

23:43 marshzor: is there a better way?

23:44 justin_smith: the transducer version avoids making three out of the four lazy seqs that the ->> version makes

23:45 the clojure compiler is not especially smart, and (take ... ( map ... (filter ... (range)))) makes four lazy seqs, and throws three of them away

23:45 technomancy: I just realized the l2l compiler tries to calculate transducers for nested map/filter stuff at compile time

23:45 confused the hell out of me when I read the source

23:46 justin_smith: l2l?

23:46 technomancy: lisp->lua compiler

23:47 https://github.com/meric/l2l/blob/master/l2l/ext/iterator.lisp#L73 completely unreadable imo

23:48 but I asked him about it and I *think* the answer he gave was actually transducers even though he didn't use the term

23:48 cemerick: cfleming: defaulting to aligning comments to column 60? We need to have a talk. ;-P

23:48 technomancy: cemerick: so I hear you are looking for a keyboard

23:48 and maybe a text editor?

23:48 I can give you a 2 for one deal

23:48 cemerick: heh

23:49 I think you're probably late on the latter

23:49 I'd already been using intellij for java stuff, and cursive is the Real Deal™ at this point

23:50 I spent a day with proto-repl and atom, and that would have been perfectly workable and a fun thing to contribute to (in my copious free time I guess?), but mmm that static analysis is sweet stuff.

23:50 technomancy: oh yeah I forgot Java is a thing

23:50 cemerick: nice burn

23:51 technomancy: but I have the atreus page open right now

23:51 technomancy: I should mention in the salespitch that it's designed using lisp

23:51 cemerick: heh

23:52 I really like it fundamentally, but the layers thing makes me think I'd never actually use it

23:52 technomancy: it takes some getting used to

23:52 having a numpad is a lot nicer than digits across the top once you do IMO

23:54 cemerick: I'm more worried about cursor keys, I think?

23:54 technomancy: you have the cursor keys on the home row with fn

23:55 if I was local to you I'd offer a loaner =)

23:56 cemerick: what do you do about left/right alt (for compose key, etc?)

23:57 technomancy: I don't do it personally but you can set fn+alt to right alt

23:57 cemerick: ok

23:57 I dunno, this is almost foot-pedal-for-esc territory :-)

23:58 technomancy: yeah it's definitely optimized for emacs/vim users to be sure

23:58 cemerick: well, I plan on reviving my actual-vim use for non-clojure/java stuff, and ideavim is supposed to be good, so

23:59 do you find that you're able to use regular keyboards still without too much pain?

23:59 technomancy: it's not bad unless I try to go back to qwerty

23:59 cemerick: oh, you're dvoraking?

23:59 technomancy: yup yup

Logging service provided by n01se.net