Fork me on GitHub
#beginners
<
2019-11-12
>
hiredman00:11:03

you shouldn't put things in resources/ you don't want included in built artifacts

zlrth00:11:28

i’m still interested though

zlrth00:11:02

i found: :uberjar-exclusions [#"resources/my-excluded-directory/*"]

noisesmith00:11:00

that's not the correct format though - it's a regex not a shell glob

noisesmith00:11:13

each file is checked against the regex

zlrth00:11:15

is the problem with that then that it’s slow?

noisesmith00:11:42

it's that nothing that it tries to put in the jar will match that pattern

noisesmith00:11:16

other than the directory itself I guess - that * is "zero or more /" which isn't useful

zlrth00:11:47

ah thanks-- do i undertand correctly that :uberjar-exclusions [#"resources/my-excluded-directory/.*"] fixes it?

noisesmith01:11:12

yeah - that should do it - I'm not sure if leiningen is doing a whole string match or substring match though

zlrth01:11:18

ok--i was wondering why it seemed to do what i want. files like resources/my-excluded-directory/myfile.xml were being excluded because they match my first regex.

noisesmith01:11:02

oh - then it's doing substring exclusion - the * threw me off because it's a valid glob and this matcher is definitely not doing glob matches

noisesmith01:11:20

so you can use your original without the * and the substring match should suffice

seancorfield01:11:50

Because it would have matched zero or more / at the end so it was matching the directory and excluding everything in it 🙂

Ivan Koz01:11:48

More of a Java question, does anybody know why

CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs)
has a varargs argument and lets say not a Collection

ghadi01:11:46

so that you can write anyOf(cf1, cf2, cf3) and not create a List

Ivan Koz02:11:03

eh.. not fun, ty ghadi

seancorfield02:11:37

@k.i.o One of those interop cases where a wrapper can make life a bit more friendly...

solf03:11:30

After a fresh lein new app and a (require '[clojure.spec.alpha :as s]) (same thing if adding it to ns), the only method defined is s/even-number-of-forms?. No s/valid?, etc. What did I do wrong?

solf03:11:12

Nevermind, it was a typo.

seancorfield04:11:38

Is even-number-of-forms? something from the core.specs for the language itself @dromar56?

solf04:11:03

I think it's a helper function for the specs of core. When doing the require using auto-complete I somehow required clojure.core.specs.alpha instead of clojure.spec.alpha

seancorfield04:11:18

Ah, yeah, sounds about right.

Quade07:11:00

Hi everyone! Have any of you guys tried static analysis with SonarQube for Clojure? I'm having trouble running it on a multi-level project, because it says "plugin_name is not a task", but when I run it in every individual sub-project it runs fine. with all of its plugins (cloverage, lein ancient, kibit, nvd)

Mehdi H.09:11:22

hello! I am using vase and trying to allow CORS on the underlying jetty server. But adding :io.pedestal.http/allowed-origins {:allowed-origins (constantly true)} to the http-options for the service map doesn't have any effect (I even set :io.pedestal.http/secure-headers {:cross-domain-policies-settings "all"} out of desperation). Anyone has any clue what I am doing wrong? My service is up (a request targetting localhost works), but not when I use my IP, I get a connection refused...

walterl10:11:52

"Connection refused" implies that the problem is lower down in the stack than CORS. Are you perhaps running a server bound to the localhost interface (127.0.0.1) only?

Mehdi H.13:11:01

no I am not. Maybe a problem with a WSL iptable or firewall but I see none being active

Mehdi H.13:11:29

Hold on, you may be right, but I have no clue how I did that if that is the problem. How can one specify which interface to bind the service to?

walterl15:11:12

How are you running your server?

walterl15:11:42

Nm. I see you got helped 🙂

Mehdi H.20:11:58

yeah but you helped me first! Thanks a lot for that!!

Mehdi H.10:11:13

I am on WSL running ubuntu 18.04. I deactivated the windows host firewall but with no luck. I thought WSL1 didn’t support iptables but this could be a reason (that or a firewall in ubuntu...)

Mehdi H.13:11:49

So it turns out that I may be indeed running a server bound to the localhost interface only. Can someone lend me a hand in understanding how to launch my server and bind it to 0.0.0.0 instead?

valerauko14:11:10

i don't know how pedestal wraps it, but servers usually accept options like :host and :port

valerauko14:11:08

for ring's run-jetty i'd give {:port 3000 :host "0.0.0.0"}. the 0.0.0.0 makes it listen on every address

valerauko14:11:35

you should run it with a similar 0.0.0.0 option too (and be sure the port in question is accessible from the host)

Mehdi H.14:11:35

thanks a lot!

Mehdi H.14:11:48

just tried :host indeed and it works with 0.0.0.0

Mehdi H.14:11:58

much appreciated

valerauko14:11:24

:+1: good luck!

Mehdi H.14:11:48

thanks, needed badly haha

Edward Hughes14:11:03

Hey there, I just downloaded the clojure RealWorld API backend from https://github.com/furkan3ayraktar/clojure-polylith-realworld-example-app to play around with it a bit but I've had some trouble actually getting it running. Tried calling lein run server-headless at the command line from the development directory as indicated, but it threw a compiler exception while getting the dependencies. Somehow got a syntax error while macroexpanding something from clojure.core. Not sure what could be causing it - apart from some arcane dependency issue - or what to do, really.

Sandae Macalalag15:11:44

leningen or boot? which should I use for new project

uosl15:11:46

If you don't know that you need boot, use leiningen.

uosl15:11:01

This podcast ep is great if you want to delve more into it https://clojuredesign.club/episode/040-should-i-use-lein-boot-or-tools-deps/

Sandae Macalalag15:11:23

Thanks, I'm back to leiningen

Sandae Macalalag15:11:04

I'm coming from JS land, what's the best way to interact with a REST API in clojure?

Sandae Macalalag15:11:19

Is it still clj-http? Sorry been hiatus with Clojure and now I'm trying back don't know whats modern way anymore.

Edward Hughes15:11:07

That's what I would use in forming the requests, yeah.

Sandae Macalalag15:11:00

Does anyone here uses VSCode + Calva + VIM plugins?

Sandae Macalalag15:11:20

It seems VIM is not working properly, ESC not working on the editor when I'm trying to get back to navigation mode

andy.fingerhut15:11:59

I do not know, but noticed there is a #calva-dev channel on Slack that you could try asking in.

pez17:11:05

For completeness, this is the relevant doc: https://calva.readthedocs.io/en/latest/vim.html

Sandae Macalalag15:11:12

I remap the keys for now, seems the keys are conflicting

Andrea Imparato16:11:07

hello, anybody can help me? I’m trying to connect to a repl inside a docker container and I get CompilerException java.lang.ClassNotFoundException: nrepl.core even though I added nrepl as dependency both in the host and in the container

dpsutton16:11:44

how did you require it?

Andrea Imparato16:11:08

[org.clojure/tools.nrepl "0.2.13"]

Andrea Imparato16:11:19

in the lein profiles.clj file

Andrea Imparato16:11:52

and in the project.clj file of the project that runs in docker

dpsutton16:11:08

that's extremely old. you probably want [nrepl/nrepl "0.6.0"]

dpsutton16:11:14

and how are you requiring it from your code?

Andrea Imparato16:11:54

in the lein :dependencies

dpsutton16:11:22

in your code presumably you have (:require [nrepl.server :as server]) or something similar?

dpsutton16:11:32

and use the newer version i listed above

Andrea Imparato16:11:56

i’m not using it programmatically, i just want to connect to the repl that is running in the container

Andrea Imparato16:11:19

namely by running lein :connect docker-port

Andrea Imparato16:11:45

so, let me explain better 🙂

Andrea Imparato16:11:02

in docker compose i run: lein repl :start :host 0.0.0.0 :headless :port 5678; as the container’s command

Andrea Imparato16:11:10

this opens a repl

Andrea Imparato16:11:31

from the host i try to connect to this repl by doing lein repl :connect 5678

Andrea Imparato16:11:48

and then i get that exception, CompilerException java.lang.ClassNotFoundException: nrepl.core,

Andrea Imparato16:11:55

makes sense? 🙂

dpsutton16:11:18

ah, remove the [org.clojure/tools.nrepl "0.2.13"] from your deps. lein provides this by itself and the newer version and older version conflict

Andrea Imparato16:11:21

still same error 😕

dpsutton16:11:00

did you rebuild the containers?

Andrea Imparato16:11:06

i might have found the issue, the nrepl version running in the container is nREPL 0.2.12

dpsutton16:11:40

what version of lein is that?

Andrea Imparato16:11:29

if i upgrade it to the latest one everything works

Andrea Imparato16:11:57

(in the host i have 2.9.1)

dpsutton16:11:40

ah. yeah. there's a mismatch there. you had old nrepl connecting to new nrepl

Andrea Imparato16:11:45

thanks a lot @dpsutton for the support 🙂

SoV418:11:18

Hallo, I'm trying to use Selmer to render some user data. I have the user data in an atom.

SoV418:11:50

looks like { "" {:prop1 "" :prop2 "" :prop3 ""}}

SoV418:11:40

Selmer lets me do {% for user in users %} but i'm not sure how to do sub-indexing on each email. I can do {{user}} and get the whole chunk, email and props. how can i dissect this?

SoV418:11:03

oh neat I can just use numbers! 😃

SoV418:11:19

user.1 and user.1.prop1 work great

SoV418:11:31

how 2 numbers in for loop....

SoV418:11:59

{{users.{{forloop.counter}}.prop1}} does not work, how can I iterate over this data?

SoV418:11:46

Nevermind. I was doing too much work xD

SoV418:11:50

it's all there

Aleks Abla20:11:00

Hi everyone! Hope you are all having a great day. I am a novice programmer, who recently picked up Clojure. It's been a lot of fun, and I have started playing around with ClojureScript and Re-Frame.

Aleks Abla20:11:12

I am having trouble wrapping my head around the interplay of routers, data stores, views, handlers and subscriptions. I understand what each one does theoretically, but I am shaky on how each interacts, especially as the app listens to the user and adapts. Could anyone recommend good resources to for me to look at? I am trying to build a single page application, that would act as a dashboard with basic statistics. Further down the line would love to add graphs and whatnot.

manutter5120:11:09

I gave a talk at the last conj that might be helpful https://www.youtube.com/watch?v=JCY_cHzklRs

Aleks Abla21:11:54

Thank you Mark! I will watch it and follow-up with you after.

Aleks Abla14:11:26

Mark, I watched the video and it was extremely helpful, particularly the diagram between app db, components and event handler. A cherry on the cake would have been to see a similar inner-working diagram for the code of subs, dispatching and handling. Any chance you have some resources on those?

manutter5115:11:30

I think the best resources for those are the re-frame docs themselves. https://github.com/day8/re-frame/tree/master/docs

Aleks Abla22:11:01

Yep, I found this which has been a step in the right direction. Thanks for all the help!

tdantas21:11:06

I heard in many talks the expression “please, push the side effects to the edge” or “isolate the side effects” .. I was re-studying the haskell and purescript. both languages the side effect is delayed until really is needed and isolated on IO/Effects. two questions: 1. How can I accomplish that using clojure ? 2. What benefits isolating side effects the project will gain ? ( will make tests easy — how ? )

ataggart21:11:05

I have always viewed it as an issue of code structure, rather than language feature. An application is a system which composes pure logic with effectful behaviour, so the "isolate side effects" is about structuring your code into pure functions, effectful functions, and application logic to explicitly compose them together. Not specifically about side-effects, but I found this talk by Rafal Dittwald very helpful in conveying the benefits of good code structure: https://www.youtube.com/watch?v=vK1DazRK_a0

ataggart21:11:18

As for benefits, testing and reasoning about decoupled components is easier in that pure logic can be tested, say, without setting up a database. Likewise, testing that your side-effects behave properly doesn't require understanding a bunch of unrelated logic.

noisesmith21:11:28

what "push effects to the edges" means in practice is when writing abstractions, don't hide side effects under layers of abstractions, rather make abstractions for the things that are "pure" (don't rely on external state or mutation), and then put the side effects generally closer to the top

noisesmith21:11:12

because what happens when you put side effecting code inside supposedly functional abstractions is that every layer between the top level and the side effect now has to care about that side effect

noisesmith21:11:38

which tends to make code harder to maintain and more complex to test

tdantas21:11:27

generally, my code contains “3” layers, web (handlers, validating output values ), service layer ( coordination ) and datalayer ( talks with persistence ). my service layer will communicate with my datalayer ( side effect ) .. how could achieve that using my “3" layers

noisesmith21:11:32

the way that tests are made easier is that in order to test something with side effects you need to manage and/or mock state, with pure code none of that matters, you can just use it directly

noisesmith21:11:47

all three of those layers are side effects

noisesmith21:11:20

inside each one you isolate the action (store data, send data to a user, get data from a user) from the transforms (strict function of input to output)

tdantas21:11:32

my service layer is responsible for the logic … for instance, my invoice system will sum the invoice items and validate with invoice total

noisesmith21:11:54

I might have misunderstood what you mean by "coordination"

noisesmith21:11:11

if it communicates to another layer that isn't on the same cpu or in the same program, that's a side effect

tdantas21:11:35

yeah, maybe not the best word . I meant , my service layer will be responsible to call the function which will validate the invoice, and then call the database layer

noisesmith21:11:56

right, and calling something which does a side effect is a side effecting operation

noisesmith21:11:50

so it's not just your service layer that has logic in it - really every useful program has some combination of data -> data pure operations, and something that pokes or responds to external state

noisesmith21:11:23

and in clojure every working function is a program

tdantas21:11:39

(defn create-invoice [db invoice-payload] 
   (ensure-valid-invoice invoice-payload)
   (db/save-invoice db invoice-payload))

tdantas21:11:06

ensure will throw exception if invoice-payload is not valid (ex-info "invalid invoice" {:type :invalid-invoice :reason "whatever" })

tdantas21:11:16

don’t know how to refactor that, for instance

noisesmith21:11:30

there's no logic there - it's just side effects

noisesmith21:11:37

a throw is also a side effect

noisesmith21:11:48

the logic is already factored into ensure-valid-invoice

tdantas21:11:49

so, what could be a logic then ?

noisesmith22:11:30

there's logic inside each of the functions you call there, surely - logic you don't have to care about in that top level function (which is a sign it's already well factored surely)

noisesmith22:11:21

what the guideline we are talking about addresses is for example usage of map and filter - these are lazy functions best suited to pure code, and if you do side effecting ops like validating data (with a potential throw) or io to a db, inside them, you will get weird and hard to debug problems

tdantas22:11:31

yeah, makes sense

SoV421:11:25

Hi is there a way to process human readable dates easily/

SoV421:11:56

I'd like to be able to type in 2020-12-9 and not break the world 😄

Lu21:11:22

Check Selmer docs there’s everything about formatting dates :).. just today I parsed that into Dec 9, 2020

ataggart21:11:24

What's the issue? The 9 instead of 09?

SoV421:11:05

Thanks @UE35Y835W I will take a look. I'm mostly trying to do time equality check to see if subscriptions are valid currently

SoV421:11:14

I have an atom indexed by e-mail

SoV421:11:34

{ email {:prop1 val1 ...}} how can i swap and add a new entry like the one above?

SoV421:11:58

(swap! atom conj email {:k v}) is not working

SoV421:11:19

maybe i'm missing something

ataggart21:11:45

you want to add a new entry in the {:prop val1 ...} map?

ataggart21:11:24

(swap! atom update :email assoc :k :v)

ataggart21:11:04

or (swap! atom assoc-in [:email] :k :v)

Lu21:11:25

I guess email is not a keyword but the actual email string

Lu21:11:38

But yeah the idea is the same

ataggart21:11:43

then assoc-in

ataggart21:11:08

it has the benefit of creating intermediate maps if they don't yet exist

SoV421:11:23

i'm adding a new entry

SoV421:11:27

i don't get it

ataggart21:11:51

user=> (assoc-in {} [:a :b :c] :val)
{:a {:b {:c :val}}}

Lu21:11:28

(swap! atom assoc email {:k v})

Lu21:11:55

Or the above

SoV421:11:13

mm.. still not getting the result i'm expecting

Lu21:11:36

What are you expecting

SoV421:11:42

{"[email protected]" {:p v}
 "" {:p v}}

SoV421:11:10

the email is not getting written, just the map i have with it

Lu21:11:33

(swap! atom assoc email {:p v})

SoV421:11:43

Okay it must be a typo someplace then

SoV421:11:32

Thanks it is working ^.^

dpsutton21:11:12

you're using it like assoc

Lu21:11:14

Replace assoc with conj indeed