Fork me on GitHub
#beginners
<
2019-07-04
>
seancorfield00:07:48

I believe Leiningen doesn't pull in JAR files for dependencies that contain only POMs -- you have to specify the individual dependencies instead -- or use a plugin that pulls them in @pvillegas12

seancorfield00:07:05

(the plugin I was thinking of is called lein-bom but it doesn't seem to work with that wss4j project, so perhaps it isn't a Bill-Of-Materials project...? I'm not Maven-savvy enough to understand that stuff)

drewverlee01:07:13

Are there pros and cons to using get and nth compared to using the data structure itself as a function? For a long while I thought they were the only way to return a not found value, but i just noticed that you can get that behavior with the structures themselves.

({:a :b} :x :y) => :y

andy.fingerhut01:07:53

One difference is in how get treats a collection that is nil, e.g.

user=> (def m {:a 1 :b 2})
#'user/m
user=> (m :a)
1
user=> (get m :a)
1
user=> (def m nil)
#'user/m
user=> (m :a)
Execution error (NullPointerException) at user/eval5 (REPL:1).
null
user=> (get m :a)
nil

👍 1
pavlosmelissinos07:07:28

However, you can use (:a m) instead of (m :a) and you'll get the same result as (get m :a) in a cleaner, imho, way

jaihindhreddy07:07:06

And keywords and symbols can be called with a default as well. get looks better (to my eyes) when used inside a -> through

mr2204:07:12

Hello, I'm just starting work with clojure. I'm trying to use +`` in the CIDER REPL and getting the error Unable to resolve symbol: + in this context.``

mr2205:07:13

Ok, I figured it out. The (ns ... ) did not include (ns ... (:gen-class))

dangercoder12:07:18

Hi, I have a question regarding records. Do you send them to your functions as a map or do you send them as parameters? I have like 3 records currently which I want to "Flow" through my functions.

dangercoder12:07:41

i will use maps, wondering whats idiomatic though 😉

noisesmith12:07:19

by records, do you mean things defined by defrecord or just generally composite data?

Casey12:07:11

I must be doing something obviously wrong, but I can't format a java-time instant:

(jt/format "YYYY/mm/DD" (jt/instant 1555970400000))
Execution error (UnsupportedTemporalTypeException) at java.time.Instant/get (Instant.java:565).
Unsupported field: DayOfWeek

practicalli_john14:07:56

There is an example on the http://Clojure.org website, maybe that will help https://clojure.org/about/jvm_hosted

practicalli_john14:07:29

This stack overflow reply says you need a specify a Time Zone https://stackoverflow.com/questions/25229124/format-instant-to-string

dangercoder12:07:29

@noisesmith things defined by defrecord. I am using protocols to be able to "Mock" any dependencies to things such as the database.

dangercoder12:07:15

Right now i just have a :records key in a map where I keep the implementations

noisesmith12:07:30

a great example of doing this IMHO is stuartsierra/component, which allows the definition of stateful components that can depend on each other with defined startup and shutdown tasks

dangercoder08:07:45

yeah im using integrant right now @noisesmith 🙂

noisesmith12:07:49

and that uses exactly what you are describing, a hash map of records that is passed to each one

Casey13:07:08

anyone have any insight into my instant formatting trouble?

ben16:07:45

Hi all, I have a long running process (refreshing a postgres materialised view) that I want to expose via an API route. The idea being that hitting the API route will trigger the process. Since the process takes a while to complete, I don’t want to wait (and timeout) before giving the API response. I was suggested to use future solve this & set the process off in a separate thread. Will this work? Are there any “gotcha”s I should be aware of while doing this?

noisesmith16:07:49

@ben606 there are a few gotchas to using futures - in particular they swallow exceptions and they get thrown later if/when you deref the result of the future

😮 1
ben16:07:36

I guess that makes sense conceptually, but also sounds a little scary

noisesmith16:07:30

the two simple workarounds are to always eventually consume the result of the future (via deref) that will expose exceptions if any; or to put a try/catch with whatever logging etc. you need inside the future

ben16:07:16

> always eventually consume the result Is this considered a best practice? In all honesty, what I’m doing feels like a bit of a hack (even if I can’t pin down exactly why).

noisesmith16:07:17

surely you need the data that the future collected or generated - if you are doing db inserts, you can have a task that consumes the futures as their data is available, and reports any exceptions thrown (or recovers as applicable)

noisesmith16:07:45

but if you are just doing db inserts from the future itself, you can always use try/catch and do the apropriate logging or recovery in that

noisesmith16:07:08

but the real problem is ignoring / dropping error conditions - that's no way to run a service :D

ben16:07:04

Yep! Although in my case, I’m not actually doing the inserts, rather triggering a refresh in the database, so there’s no return value per se. Maybe that’s a hint I should be doing something else

drewverlee17:07:27

Why are you refreshing the view? if its because the view is "outdated" then it might be possible to make the view reactive. This is part of what the recent drive towards having streaming systems like onyx, flink, spark, etc... is about.

drewverlee17:07:31

In my experience, the hacky part to updating the a view is that most pre streaming systems dont give you a options to specify when that when, how, why things should be updated.

ben15:07:12

The reason is actually worse than that… We have a table in which each row contains the parameters that define a distribution. We want to sample from that distribution regularly. The view simply adds a column with an extra field containing that sampled variable (and some indexing).

noisesmith16:07:02

but that seems like a sensible approach

ben16:07:11

Is there an obvious (idiot-friendly) reason why I would use executorservice over futures?

noisesmith16:07:09

the executorservice abstracts the concept of a group of tasks which are related, where you can iterate them all, check their status, etc.

noisesmith16:07:39

you probably want something like that, and with futures you'd have to reinvent it (and ironically future uses an executorservice under the hood, borrowed from clojure.lang.Agent)

ben16:07:44

Right. I think that makes sense. Thank you @noisesmith!

damaxi18:07:59

what does it mean ^ in clojure?

Roman Meier20:07:24

Hello everyone, is there a reduce-right in clojure?

andy.fingerhut20:07:52

none I am aware of

andy.fingerhut20:07:07

pretty straightforward to write a correct one given what is available, if you aren't worried about optimizing to the utmost.

Roman Meier20:07:02

if i reverse the vector i pass in, wouldn't that suffice?

andy.fingerhut20:07:57

It depends upon whether the operations you want to do between "pairs" of things is commutative or not.

andy.fingerhut20:07:34

e.g. if the sequence contains strings, and your goal is to concatenate all of them, the result will come out quite different than a reduce-right

andy.fingerhut20:07:43

Assuming that by reduce-right you mean what I am guessing you mean.

Roman Meier20:07:53

i was just thinking of it as starting from the last element instead of the first

Roman Meier20:07:23

thanks anyway andy. made me think about this 👍

andy.fingerhut21:07:07

I don't know whether js reduceRight gives the same behavior as reduceLeft on the reverse of the array, or not. Haskell has foldl and foldr, where I am almost certain that foldr is not the same as reversing the list and passing it to foldl.

mfikes21:07:01

If it is true, then consider rseq; when applied to vectors it produces a reduceable result