Fork me on GitHub
#clojure
<
2017-06-27
>
stuartrexking01:06:12

Is there a nice way to get specific elements, by index, from a vector, returning a new vector?

jcromartie01:06:47

(mapv #(get v %) indices)

jstokes01:06:49

or even just (mapv v indices)

jcromartie01:06:10

that won't return a vector

jcromartie01:06:36

I misread that as "map"

jcromartie01:06:00

vectors are functions of their indices

jcromartie01:06:03

I forgot about that

joshjones02:06:02

yes, just have to be careful with index out of bounds with the (mapv v indices) version. Can filter out nils from the get-based version and not have to worry about exceptions. Unless you want an exception with a bad index, in which case the vector-as-a-function solution works perfectly

laujensen09:06:09

Do we have some nice tools for remotely debugging JVMs? I have a Clojure app thats leaking memory

mccraigmccraig09:06:48

@laujensen i've used yourkit with great success. there is also visualvm which is a lot freer, but i haven't used it

laujensen09:06:03

@mccraigmccraig , I’ll check ‘em out, thanks

mahdix09:06:00

A quick question: Clojure supports closure where the closure has access to data defined in the parent function.

mahdix09:06:19

On the other hand, you can re-assign a new value to an existing variable. And this variable might be visible to the closure.

mahdix09:06:38

Doesn’t this cause data race?

mahdix09:06:45

Isn’t this some kind of mutable shared state?

a1310:06:45

if your data are atoms, why not?

mahdix10:06:42

Suppose that they are atoms.

mahdix10:06:09

I see. In this case it won’t be data race.

mahdix10:06:22

But it will still be a shared mutable state (but in a safe way)

mahdix10:06:26

Is that correct?

noisesmith12:06:22

mahdix: atoms won't race if you use them correctly: that is, if you use swap! to update their value, and don't have side effects or deref other mutable containers in the function you pass to swap!.

a1310:06:49

well, more or less — yes

a1310:06:35

You just have to remember what atoms really are

a1310:06:27

and no, there won't be data race (at least there shouldn't be :)

hmaurer10:06:40

Hey! Could anyone recommend me a great Clojure book for someone who is new to the language but mostly familiar with functional programming? I have already read Clojure for the Brave and the True

yogidevbear10:06:40

I purchased Living Clojure and thought it was great. I've also heard good things about The Joy of Clojure, but as a more advanced follow-on book

hmaurer10:06:17

Thank you!

sgerguri10:06:11

The Joy of Clojure is advanced, and I’m not sure if you need that much info upfront. I maintain that Programming Clojure by The Pragmatic Bookshelf is by far the best resource available, and written in a style that is true to the language. There is a new 3rd edition coming up, see https://pragprog.com/book/shcloj3/programming-clojure-third-edition.

shan10:06:18

Clojure Applied is also one to look at

hmaurer11:06:45

@U067BPAB1 thank you! How advanced are we talking about here with regard to the Joy of Clojure?

sgerguri11:06:18

You should have written something in the language already to really benefit from the book.

sgerguri11:06:16

I wouldn’t rush into it, personally - I’m into my second year doing Clojure commercially after years of FP in Erlang and hobby toying around with Clojure/Scala, and I’ve yet to seriously touch the book. I find that actually writing code is more useful than reading about it - which, admittedly, is much easier to do when you’re paid to do it!

sgerguri11:06:29

This is also the reason why I like Programming Clojure so much - the book doesn’t faff around and goes straight to the point, all the while (indirectly) teaching you all the good habits required for writing nice, clean, composable Clojure code.

hmaurer11:06:30

@U067BPAB1 I’ll definitely get myself a copy then! Have you read the ebook? Or is there a way to get a paperback?

sgerguri11:06:36

I have both the paper and the electronic version of the second edition, which covers version 1.3. Personally I would get the beta ebook for the 3rd edition and just read that, all PragProg books are super easy to read on screen and very well hyperlinked, plus it’s nice to have a bit of color as well.

hmaurer11:06:52

@U067BPAB1 Ok, thanks a lot for the advice

sgerguri11:06:32

Np. I also recommend http://4clojure.com if you haven’t come across that already, it’s a good way to learn an idiomatic way of solving isolated problems using the standard library. And above all, try to get a job with it. That’ll boost your understanding much quicker than any book ever can.

hmaurer11:06:00

@U067BPAB1 I am actually pushing to use clojure on a new project at my current job

hmaurer11:06:03

thus my interest

hmaurer11:06:40

I didn’t know 4clojure; thanks!

hmaurer11:06:01

Out of curiosity, what has your experience been going from Erlang to Clojure @U067BPAB1 ?

hmaurer11:06:18

It’s one of those languages (Erlang) that is on my “to learn” list but never quite got around to doing it

hmaurer11:06:47

And did you have a good time with Erlang?

sgerguri11:06:34

Clojure is a much better language. Erlang is more interesting from a concurrency perspective than an FP one, since the FP there is completely incidental (it was deemed necessary to implement the platform) rather than intentional. Both teach you something new, so if you feel like learning something else after Clojure I can recommend it. I enjoyed my time with Erlang but after 4+ years of it I think I’ve exhausted the platform, and I personally don’t think it’s the right fit in 90% of modern distributed/concurrent system development as a lot of the big selling points (failure handling, concurrency etc.) have been implemented outside of the VM these days and I just think that’s the right way to do it instead of having to think about these explicitly within a service.

erwinrooijakkers11:06:16

Joy of Clojure is fun, and from a practical point of view I loved Learning ClojureScript, but that’s about ClojureScript

manutter5111:06:12

@U5ZAJ15P0 I’m planning to learn Erlang too. Well, ok, I’ll probably learn Elixir instead, but that’s derived from Erlang.

hmaurer12:06:44

@U06CM8C3V yes Elixir looks interesting!

viesti11:06:33

hmm, seems that eastwood doesn’t like defrecord forms produced by [org.clojure/clojure “1.9.0-alpha17”]

bronsa11:06:15

what's the issue?

boldaslove15611:06:29

Hello! Can anyone help me understand the use-case of defrecord? Everytime I write a code, it is usually enough with just a function, but I'm afraid I'm missing the good parts of it!

viesti11:06:29

== Eastwood 0.2.4 Clojure 1.9.0-alpha17 JVM 1.8.0_131
Directories scanned for source files:
  src test
== Linting lol.core ==
Entering directory `/private/tmp/lol'
src/lol/core.clj:3:1: suspicious-expression: condp called with 3 args.  (condp pred test-expr expr) always returns expr.  Perhaps there are misplaced parentheses?
where source is
0% cat src/lol/core.clj
(ns lol.core)

(defrecord Lol [])

erwinrooijakkers11:06:15

When running around 1000 simultaneous clj-http/get requests with :async? true I get this error:

Exception in thread "async-dispatch-6" Exception in thread "async-dispatch-5" java.lang.OutOfMemoryError: unable to create new native thread
Is there a way to circumvent this?

noisesmith12:06:16

erwinrooijakkers: the correct way to deal with this is to use a queue or channel to line up requests, and then use a fixed number of threads to do the work on that queue or channel. The claypoole library makes it easy to create a pool that works this way and call it the same way you would use futures of pmap normally.

noisesmith12:06:26

of course you can also increase your max memory usage parameter, but there's still always a limit beyond what your hardware can support, and then you need to control thread creation / usage

qqq12:06:29

@seancorfield : is it public if your team uses GAE or AWS ?

seancorfield15:06:41

@U3JURM9B6 we use a mixture of traditional data center and AWS at the moment.

viesti12:06:05

hrm, having hard time trying to teach eastwood to ignore defrecord

viesti12:06:22

(disable-warning
 {:linter :suspicious-expression
  :for-macro 'clojure.core/defrecord
  :reason "Clojure 1.9 defrecord output causes false warning"})
doesn’t seem to work

gfredericks12:06:56

what's the proper spelling for a new version of foo-bar? foo-bar2 or foo-bar-2?

tjtolton12:06:41

gfredericks: seems like it would be the former in most cases

tjtolton12:06:55

foo-bar-2, I think, more strongly implies it was intended to be a distinct symbol with a similar naming scheme, while foo-bar2 is more clearly a mutation of the original foo-bar

gfredericks12:06:05

and what about foo*? foo*2 or foo2*?

tjtolton12:06:57

again, my preference would be appending the mutation to the original symbol unmodified. so foo*2 this strategy will help you out if you ever need to grep your service for any instances of that function, in any versions that exist

jcromartie12:06:33

that's how I've usually done it

jcromartie12:06:36

read as "foo-bar prime"

jcromartie12:06:45

and foo-bar'' etc.

tjtolton12:06:12

for instance, if you did ctrl + f foo-bar* you would get instances of foo-bar* and foo-bar*2

tjtolton12:06:29

if you altered the symbol in some other way, that trick wouldnt work

tjtolton12:06:30

obviously @jcromartie is using the same strategy, just with prime ticks instead of numbers

gfredericks12:06:08

@jcromartie this is specifically re: the new guidelines from rich etc. regarding avoiding breaking changes, which explicitly recommended integers

jcromartie12:06:40

I haven't seen that

jcromartie12:06:58

cool, thanks!

gfredericks12:06:37

I guess the slides in that talk probably indicate an opinion about foo2 vs foo-2

gfredericks12:06:53

ah ha! the slides have foo-2

gfredericks12:06:58

which was my preference anyhow

danielneal13:06:09

real-foo 😛

gfredericks13:06:50

@U051H1KL1 and real-real-foo for the next one?

danielneal13:06:10

only then can you go real-real-foo-2

danielneal13:06:22

after that its real-foo-final and that's all the foo you need

tjtolton14:06:03

huh, well. how about that. my preference differs.

tjtolton14:06:09

real_foo_final_fixed_fixed_for_real_this_time

viesti12:06:54

so the actual use for a defrecord without fields was a com.stuartsierra.component

octahedrion12:06:52

is there a spec for the s/describe of a spec ?

jcromartie12:06:26

I'd love to use spec, but I'm not brave enough to jump onto an alpha version of Clojure itself

seancorfield15:06:31

@jcromartie we're on alpha 17 in production. High traffic. Large codebase. Heavy use of spec.

jcromartie15:06:51

Oh? That's reassuring! Thanks.

jcromartie15:06:56

I might give it a try after all.

seancorfield15:06:46

FWIW, we’ve been using Clojure Alphas in production since 2011 (1.3 Alpha 7 or 😎. I think we’ve had one “bad” build in all that time (degraded performance). We happened to skip 1.5.0 in production (the only memory leak I can recall) because our release schedule fell in such a way that we went from a solid prerelease of 1.5 directly to 1.5.1.

spieden18:06:52

afaik clojure 1.9 doesn’t muck with many internals in a risky way, too. mostly adding features

gfredericks12:06:00

stu halloway was in town last week and made a big deal about "alpha" merely meaning "subject to change" and not "low quality" or any of the other associations

octahedrion12:06:44

yeh I've been using Spec for a couple of projects & its great!

noisesmith12:06:51

yeah, clojure alphas tend to be quite good (as long as you are willing to rewrite code that uses the new features)

henrik13:06:51

Is it good practice to use (get a-collection :a-key) over (:a-key a-collection)?

noisesmith13:06:36

I use get only if the keyword is in a bound name and not a literal

noisesmith13:06:45

when it's a literal, it's always clear what the keyword is doing

henrik13:06:40

Whereas if it’s in a bound name, it’s ambiguous whether it’s a function, keyword or what-have-you. Gotcha.

octahedrion13:06:02

eh I use keywords, vectors and maps as functions - because they're all functions

henrik13:06:14

Fair enough

octahedrion13:06:56

so what if it might seem ambiguous - if it works and you've tested it then it's clear by the fact that they're first in the list that they're supposed to be a fn

alexmiller13:06:41

@octo221 you should only vectors/maps as functions when they are guaranteed to be non-null (because otherwise you’ll get an npe)

noisesmith13:06:47

@octo221 my concern is readability and refactorability, I like to use constructs that reduce ambiguity when they are available and they don't impede other development goals

octahedrion13:06:43

@alexmiller naturally, but then anything could be nil and cause a NPE - that's part of testing & maybe Specing

alexmiller13:06:01

no, using a keyword as function (or get) will not have that behavior

noisesmith13:06:15

but using get directly is free, and solves the issue

octahedrion13:06:15

I don't think it affects readability at all, actually it's more clear sometimes

noisesmith13:06:26

I strongly disagree

jcromartie13:06:36

I only ever use keywords like (:foo bar) when it's exactly like that: a keyword literal and a very simple form

jcromartie13:06:59

if I want to get a default value I use get like (get bar :foo :default)

jcromartie13:06:12

never (:foo bar :default)

henrik13:06:35

It’d certainly be easier to see what (get a-collection unknown-thing) is doing as opposed to (unknown-thing a-collection)

octahedrion13:06:52

why is your unknown-thing unknown ?

octahedrion13:06:06

just ensure it's a keyword

jcromartie13:06:08

because we aren't using Haskell

octahedrion13:06:30

no we're using a better language, with a REPL and Spec

jcromartie13:06:07

Clojure lets you inspect the state of things after you run your code

jcromartie13:06:12

which is nice

octahedrion13:06:31

running a compiler (which is a program) to infer what your program would do if run, is no more powerful than simply running your program

carocad14:06:11

@alexmiller out of curiosity: is there a general convention for the naming of clojure repos in github? I see lots of data. math but also some more exotic names, just got me thinking 😄

alexmiller14:06:56

carocad: there are just a handful of top level “categories” used for contrib libraries - algo, core, data, java, math, test, tools. And then there are other things as well (web sites like clojure-site and clojurescript-site), clojurescript, clojure clr and clr ports

xiongtx21:06:17

I’ve always found tools, util, etc. to be problematic namespaces--everything gets shoved in there. E.g. why does java.util.Date belong with java.util.LinkedList?

alexmiller22:06:08

I’ve been using Java since before LinkedList existed. back then, the JDK was a lot smaller and no one anticipated how Java would grow. at the time, it seemed fine!

xiongtx21:06:07

Yeah, just hoping clj won’t follow down the same bad (class)path

alricu14:06:00

Hi I have a problem with ssl in jetty, I implemented https with an issued certificate by a recognized institution however, I am receiving in firefox this message: SSL_ERROR_NO_CYPHER_OVERLAP

alricu14:06:11

in chrome it works well; but in firefox it does not work, it shows a yellow message

alricu14:06:02

any idea about how to fix that in Clojure?

jcromartie14:06:52

@alricu Jetty and Chrome do not have any ciphers in common

jcromartie14:06:45

but it's worth repeating: asking "how do I fix the SSL cipher suite in Jetty" is like asking "what's the best shoe to hammer a nail?"

jcromartie14:06:59

Put something that's better at SSL in front of your app.

jcromartie14:06:09

Don't do SSL in your embedded Jetty.

alricu14:06:23

I understand that there are better ways to do that @jcromartie; but in this application i cannot change or implement other things

alricu14:06:29

I have to adjust to jetty

alice15:06:47

This may sound like a strange question

alice15:06:02

But would it be possible in any way to observe Clojure as it runs

alice15:06:14

so that one could track all evaluated code

alice15:06:19

and implement a way to say

alice15:06:25

EVERYTHING UP TO THIS BIT WORKS

alice15:06:39

b/c that would fix like half of what makes clojure so broken, the dumb error messages

jcromartie15:06:11

yes, you want a debugger

jcromartie15:06:14

with breakpoints

jcromartie15:06:04

I'd recommend IntelliJ IDEA with Cursive

richiardiandrea15:06:40

@alice for your use case I would go for clojure.tools.trace which allows you to print out everything that is going on in a namespace or for a var

alice15:06:00

@jcromartie I don't need a debugger, I'm plenty comfy in Emacs, I'm just wondering how dead-simple it'd be possible to make troubleshooting

jcromartie15:06:18

but you described a debugger with breakpoints

alice15:06:26

I suppose it's similar

alice15:06:33

but it's less about defining breakpoints

alice15:06:42

and more about deducing where the issue is exactly programmaticallyy

jcromartie15:06:58

stack traces get you most of the way there

jcromartie15:06:08

the trick is defining the starting point of tracing executing

alice15:06:39

It'd probably be something you defined in the code, which may be cumbersome

alice15:06:49

(trace this-ns)

jcromartie15:06:23

well as @richiardiandrea suggested you can trace the fns in a namespace

jcromartie15:06:41

(trace-ns some.problematic.namespace)

alice15:06:43

I'm gonna write the best damn debugger that ever did darn dun existed

jcromartie15:06:05

but you have to specify each namespace and/or function that you want to show up in the trace

richiardiandrea15:06:45

Cider has trace built-in if I remember correctly so you might not even need to evaluate that at the repl

alice15:06:11

I haven't tried anything, it was just an idea I had

alice15:06:25

But this actually looks like almost exacttly what I wanted

alice15:06:30

so maybe I'm late to the party

niten.sagar15:06:26

I would appreciate if someone can guide me on reading data from AVRO file in clojure?

jcromartie15:06:21

Just use the Java libs

alice15:06:24

Well, never used hadoop, but slurp it in and go from there?

trptcolin16:06:51

re: debugging / finding the source of issues, i find an approach like stu’s here to be the easiest & most widely applicable: http://blog.cognitect.com/blog/2017/6/5/repl-debugging-no-stacktrace-required

noisesmith17:06:37

Also - an underrated approach is to experiment in the repl, but reify those experiments into unit tests. I wrote a library that makes it easier to take data you have in your repl and inject it into tests https://github.com/noisesmith/poirot

noisesmith17:06:14

experimenting in the repl helps today, and is great if you are never going to edit or refactor your code, tests are great to have if you think your codebase might ever change

bbloom17:06:38

any jdbc experts know why (j/execute! pg ["SET LOCAL app.session_id = 'x'"]) works but (j/execute! pg ["SET LOCAL app.session_id = ?" "x"]) yields a BatchUpdateException “was aborted” with syntax error at the column with the ??

bbloom17:06:00

the exception message shows the interpolated query, which seems to have the right ‘x’ in it

a1317:06:39

@noisesmith looks promising! how about publishing it on clojars?

noisesmith17:06:56

I thought I had

noisesmith17:06:07

I probably need to add the info to the readme

noisesmith17:06:43

it's still pretty young, but good enough to be useful, in my experience at least

a1317:06:34

BTW, TIL about Reader Conditionals! thanks again!

noisesmith17:06:17

@a13 I don't think I've pushed the cljs support to clojars yet, but you can get it via lein install - I haven't used the feature enough to make it feel publishable (I work on clj code a lot more)

charlieroth18:06:18

Hey I am new to Clojure and I was wondering if you guys could share some of your favorite resources for learning Clojure. I have already checked out Clojure For The Brave And True but I am learning Clojure for the purpose of eventually building React apps with clojurescript and reagent. Thanks!

jumar05:06:43

charlieroth: ClojureScript Unraveled is also good, especially for getting started with ClojureScript if you are an experienced programmer: https://funcool.github.io/clojurescript-unraveled/

spieden18:06:33

i’m late to the using maps and vectors as functions discussion, but i don’t think anyone mentioned polymorphism. e.g. can be handy to have the option of passing a map or a function depending

noisesmith18:06:18

sure - but the context was implying that it was always being used for lookup

noisesmith18:06:36

and I'd definitely pass in :foo instead of #(get % :foo)

spieden18:06:04

hmm, yeah maybe not as useful when expecting a map and passing a fn vs expecting a fn and passing a map(?)

dpsutton18:06:44

interesting code and examples, good narrative, and pretty comprehensive. It's made for new people. It also isn't scared of java so you'll have a good introduction to the host language if you're unfamiliar

bbloom19:06:42

heh, wow, just remembered that ::keys is new in clojure 1.9 - feels like i’ve been using that forever 😛

spieden20:06:01

@bbloom i hit that with seqable? the other day =)

zylox20:06:04

@noisesmith this looks interesting. weve been having trouble with data in defs getting too large for tests (yay memory issues), wonder if this could help

zylox20:06:59

(referencing poirot)

noisesmith20:06:10

@zylox it might help - especially if you load the data locally in the test so that it gets cleaned up when that test exits...

zylox20:06:00

ya that would be the idea.

mbertheau21:06:06

Is there a difference between (for [x l] ...) and (map (fn [x] ...) l)?

noisesmith21:06:40

not if the binding vector looks like that, no

mbertheau21:06:45

I.e. between for and map with one coll.

noisesmith21:06:06

but for has some other tricks you can do with the binding vector, even with one coll

mbertheau21:06:29

Ok, but apart from that these expressions do the same thing

noisesmith21:06:53

+user=> (take 10 (for [x (range) y (range) :while (> x y)] [x y]))
([1 0] [2 0] [2 1] [3 0] [3 1] [3 2] [4 0] [4 1] [4 2] [4 3])

mbertheau21:06:41

Ah, a misplaced ) is responsible for the confusion. Thanks for the backup!

alexmiller22:06:06

what’s the question?

alexmiller22:06:46

a profiler dump isn’t too helpful w/o the code