Fork me on GitHub
#clojure
<
2020-08-31
>
lilactown00:08:51

@deadghost spec instrumentation/enforcement is opt-in at each call site. there’s not currently a way to spec all usages of a keyword in every map

lilactown00:08:58

(nor would you probably want to)

lilactown00:08:34

IME instrumentation can be a big perf bottleneck. I rarely use it for my entire code base even during development

deadghost00:08:48

Yeah that's what I figured.

seancorfield01:08:00

@deadghost Yeah, as @lilactown says, Spec is entirely opt-in by design and it is also intended more for boundaries than for "everything", so I think what you are asking for is a non-goal for Spec...

seancorfield01:08:24

You can explicitly ask (s/valid? :foo/bar "1"), you can s/instrument a function with an appropriate Spec and then the call will check that, you can s/check a function and have it check returned values against Specs. That's how it is designed.

deadghost01:08:52

Yeah that's reasonable. I don't think specing out the boundaries is too onerous but I'll see when I actually try to do it.

seancorfield01:08:52

A lot of people make the mistake of treating Spec like some sort of "type system" (which it definitely is not) and trying "spec everything" which is a bad idea.

hadils01:08:10

How do I write the specs for a function with map destructured arguments, e.g.,:

(defn budget-item-type
  [{:transaction/keys [amount]}]
  (if (ma/positive? amount) :expense :income))
(s/fdef budget-item-type
  :args (s/keys* :req-un [::specs/money])
  :ret #{:expense :income})
Thanks!

Alex Miller (Clojure team)02:08:07

destructuring really doesn't change how your spec something - from the function perspective you're just receiving a map

Alex Miller (Clojure team)02:08:28

In this case here, your args spec is expecting a kwarg style sequence, not a map though. you either want the function to be a varargs (by using &) or to wrap your spec in s/cat.

Yanna06:08:35

How can I do when one of the properties of a component is another component

p-himik06:08:15

Is it a #reagent -related question?

p-himik07:08:25

Then it should probably be asked in that channel instead. :) Not many people in #clojure use Reagent.

p-himik07:08:15

In any case, your question is very vague. With how it's currently phrased, the only answer I can give is "you just do it".

Yanna07:08:31

ok,thank you for your advice

Saikyun09:08:38

when I try to run clojure on windows, I get the following error:

PS C:<omitted>> clj
java.exe : Downloading: org/clojure/clojure/1.10.1/clojure-1.10.1.pom from central 
 At C:\<omitted>\Documents\WindowsPowerShell\Modules\ClojureTools\ClojureTools.psm1:304 char:5
+     & $JavaCmd -classpath $ToolsCp clojure.main -m clojure.tools.deps ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Downloading: or...om from central:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError 
couldn't find any info on it here: https://github.com/clojure/tools.deps.alpha/wiki/clj-on-Windows anyone in this channel who can help? 🙂 am on windows 10 server, running in powershell, openjdk 13

Dimitar Uzunov09:08:43

you are not using powershell ISE by chance right?

Saikyun09:08:26

tried in ISE-less powershell, now it works. thanks!

Dimitar Uzunov09:08:30

No worries, ISE is meant to be used when writing powershell, it does some weird things with standard output of non-powershell commands (“native commands”)

Saikyun09:08:48

ah, that's good to know. thanks a lot

Karol Wójcik09:08:43

How to process collection in parallel for side effects in clojure? EDIT: I got that temptation to use pmap, but i'm not interested what are the values of operation.

👍 3
Alex Miller (Clojure team)13:08:33

you could use run! and have it launch futures

Alex Miller (Clojure team)13:08:09

that's basically an unconstrained number of jobs

Alex Miller (Clojure team)13:08:01

in between that and pmap would be to use java executors with a thread pool and queue that constrains things however you like

deadghost11:08:05

https://cljdoc.org/d/metosin/spec-tools/0.10.4/doc/spec-coercion#spec-based-transformations anyone happen to know if this can transform the kw as well? For example, :foo/bar -> :foo-bar

ikitommi12:08:35

you can do that

👍 3
deadghost14:08:14

@U055NJ5CC can you point me to the right direction? Just to be clear :foo/bar 1 -> :foo-bar 1.

mokr13:08:03

Hi, my clojure backend needs to to call an external script (script.sh) and this works in development using (clojure.java.shell/sh "./script.sh" …) , (with the script located in project root dir), but when I run the production jar file inside my docker container, it is unable to locate the script. I’ve tried with the script next to the jar file, switching to an absolute path (inside the container) and more, but I keep getting Cannot run program "/script.sh": error=2, No such file or directory I’ve verified that the script is actually inside the container and have also compared with another project where I have this working, but can’t seem spot the difference. Help appreciated.

Alex Miller (Clojure team)13:08:27

"/script.sh" seems like a clue - that looks like . (current directory) is being set to / in this case?

mokr13:08:55

Sorry, I pasted output from another attempt than what I created in the example.

mokr13:08:17

Doing a new attempt now with an absolute path. I can give an example from there when done

mokr13:08:37

Still the same issue. Error: Cannot run program "/app/script.sh": error=2, No such file or directory When I log “ls” and “pwd” right above the sh-call, I see what I would expect to see: pwd: {:exit 0, :out /app, :err } ls: {:exit 0, :out app.jar log script.sh , :err }

dpsutton13:08:31

can you ensure the script is executable?

mokr13:08:43

I’ve checked that, and it is

mokr13:08:12

-rwxr-xr-x

vlaaad13:08:59

I think you need to use just “script.sh”

vlaaad13:08:14

without ./

mokr13:08:19

Thanks, I’ll try that

vlaaad13:08:59

I haven’t read the whole discussion before giving advice 😄

vlaaad13:08:08

have no idea how it’ll work with docker

mokr13:08:43

I would imagine that just the filename without path gives Java some more room to search the class path, so lets see 🙂

cpmcdaniel13:08:22

what is the proper way to test if a var or local is a dereffable thing? (atom, ref, agent, promise, etc)

mokr13:08:34

still failed

Alex Miller (Clojure team)13:08:50

this is a file path, has nothing to do with classpath

dpsutton13:08:08

(map #(instance? clojure.lang.IDeref %) [1 :a (atom 3)]) @cpmcdaniel

mokr13:08:25

@alexmiller Thanks, for the clarification. I was “afraid” of that when I wrote it 🙂 I did not come to Clojure from Java…

Alex Miller (Clojure team)13:08:19

unfortunately, I'm not sure what the issue is - maybe try running bash with the script as an argument? does the script have a shebang at the top?

manutter5113:08:16

It might be an issue with the $PATH environment var being different when you run it --maybe some other file is the one that’s missing?

mokr14:08:21

It is actually an Expect script named script.exp and it has a shebang #!/usr/bin/expect -f And I forgot to install Expect in the container. /app # ./script.exp sh: ./script.exp: not found

mokr14:08:29

Not surprising, but adding RUN apk add expect to my Dockerfile solved the issue. Sorry about all the confusion. I believe my attempt at isolation the problem and removing irrelevant details was not actually helpful.

mokr14:08:51

Thanks for all the suggestions and getting me on the right track

👍 3
mokr14:08:13

(Removed my question to ask in #leiningen instead)

Vishal Gautam15:08:36

Hi, I am trying to create a spec for data that works for both qualified and unqualified keys. Here is the spec. Am I doing it right, or is there a more idiomatic way to do it

(s/def :contact/id uuid?)
(s/def :contact/first-name string?)
(s/def :contact/last-name string?)
(s/def :contact/email string?)

(s/def ::contact-item
  (s/keys
   :req [:contact/id :contact/first-name :contact/last-name :contact/email]))
(s/def ::contact-item-un
  (s/keys
   :req-un [:contact/id :contact/first-name :contact/last-name :contact/email]))

(s/def ::contact
  (s/or :qualified ::contact-item
        :unqualified ::contact-item-un)) 

Alex Miller (Clojure team)15:08:43

I guess I’d wonder if you could transform the data first to have one spec instead

Vishal Gautam16:08:13

@alexmiller that’s true but then I’d have to call that function everywhere I need to transform.

ikitommi17:08:10

something like this, @deadghost

(require '[spec-tools.core :as st])
(require '[clojure.spec.alpha :as s])

(s/def ::my-keyword
  (st/spec
    {:spec simple-keyword?
     :decode/string (fn [_ x] (keyword (str (namespace x) "-" (name x))))}))

(st/coerce
  ::my-keyword
  :foo/bar
  st/string-transformer)
; => :foo-bar

deadghost18:08:54

I'm interested in transforming the k, not the v. (s/def :my/keyword ...) :my/keyword -> :my-keyword.

deadghost18:08:50

The frontend can want odd formats or completely different keys sometimes.

deadghost18:08:47

{:my/keyword "foo"} -> {:my-keyword "foo"}

ikitommi18:08:37

Looking at the code, spec-tools doesn't have an easy way to transform s/keys keys, just s/map-of keys. PR welcome, or you could look either https://github.com/wilkerlucio/spec-coerce or other spec coercion libs

deadghost18:08:14

Thanks, I'll see what can be done

Alex Miller (Clojure team)18:08:53

in my experience, fighting the fight for a canonical representation inside your own program is worth the battle

☝️ 6
deadghost18:08:34

One fight at a time. Frontend already expects JSON encoded :foo-bar and not :foo/bar and unqualified :biz instead of :foo/biz.

markaddleman19:08:17

fwiw, I have a similar challenge in my project. I have a layer that converts between the inconsistent names that the UI expects in JSON and the consistent, qualified names that the backend uses

deadghost19:08:18

@U2845S9KL that's essentially the point I'm trying to reach. Currently I don't even have an explicit layer, the transformations are scattered throughout the code. After that I can push for more consistent frontend data.

markaddleman19:08:19

Yep. That's the situation I was in a few weeks ago. It wasn't too hard to create the "compatibility layer" since I had complete control over it. I have not yet tried to push this out to the UI

Vishal Gautam15:09:04

^ for this case. I found this https://github.com/clj-commons/camel-snake-kebab library super helpful

👍 3