Fork me on GitHub
#beginners
<
2021-06-02
>
rafalw06:06:58

Hi, lets say I have a module that is designed to handle some data manipulation for a model. I need to have two getter functions, one not safe, if key is missing throws exception, another safe, if key is missing returns nil (get model attr) ;; => throws if attr is not in the model (get-safe model attr) ;; => returns nil if attr is not in the model The logic is that attr in 99% cases should be in the model and if it's not it's an error, second function is for 1% cases for which is ok to no have attr My question is it's creating two separate functions a good approach, if yes is there any naming convention for such case?

phronmophobic06:06:16

Having two separate functions seems reasonable. get-safe appears to be the same as clojure.core/get so I would just use get. for the version that throws, I would consider some other short names, but try to make sure they are distinct from get so that it's easy to distinguish safe vs unsafe: • get!grabmustpicknabnetclutch

Bryce Tichit09:06:02

Hey guys, does someone know how to copy the whole block of code I've just written using rebel-readline ? Thanks for the help 🙂

Stuart09:06:24

You entered the code directly into the repl? You want to not do that. The repl should be the target where the code is evaluated but you should be typing your code into an editor hooked up to your repl.

Bryce Tichit10:06:20

I understand but for simple use cases I wanted to use the REPL directly, if it's not possible when I will use an editor but seem overkill to me

practicalli_john10:06:16

Suggest using the command history. Use the up arrow to go back through the history and down arrow to go forward through history

practicalli_john10:06:07

If you want to copy the code from the terminal into another application, then select it with a mouse 🤷

practicalli_john10:06:29

Ah, Ctrl-U will kill the line and should put it into the clipboard / kill ring

practicalli_john10:06:46

but that probably only works if the code is on the same line...

Bryce Tichit10:06:02

Thanks for the insights ! The problem is that if your input is multi-line this does not work because either rebel add #_ prefix and Ctrl U only kill one line

Bryce Tichit10:06:08

So yes I think I will use an editor seem easier haha

practicalli_john10:06:38

I start rebel readline in the terminal along with an nREPL server, so I can connect to that repl process from Clojure editors

Bryce Tichit10:06:30

Thanks a lot seems really good, will try that

practicalli_john10:06:24

If you are using Clojure CLI tools to run the REPL, I have example aliases for running rebel and nrepl together https://github.com/practicalli/clojure-deps-edn#repl-terminal-ui

1
JohnJ16:06:07

For those that had to talk to SOAP service, how did you go about approaching it from Clojure?

delaguardo17:06:13

However not any wsdl can be processed by that lib.

seancorfield17:06:57

We used wsdl2java to produce Java source classes, and compiled them into a library, which we used directly from Clojure via interop — and then plain HTTP to talk to the SOAP service with the XML those classes produced.

seancorfield17:06:19

(it was a while back and, luckily, we don’t have to talk to any SOAP services now)

JohnJ17:06:03

@U04V70XH6 yep, looks like the "simplest" approach

JohnJ17:06:17

@U04V4KLKC yeah, need wsdl processing

delaguardo17:06:19

I made a mistake in my sentence) corrected - not every wsdl can be processed. So you can try yours )

JohnJ17:06:09

Oh ok, will take a look, thx

Nom Nom Mousse16:06:04

When I use sh with escaped characters it turns them into literals:

(sh "bash" "-c" "bwa mem -R '@RG\tID:A\tSM:A'  hg19.fasta  | samtools view -Sb - > result.delteme")
gives the error:
[E::bwa_set_rg] the read group line contained literal <tab> characters -- replace with escaped tabs: \\t

ghadi17:06:32

those are literal tabs in your clojure strings

ghadi17:06:55

if you want to have SLASH-T, you need to escape the slash in your literal: "\\t"

ghadi17:06:35

"\t" is clojure syntax for a string containing only tab character, aka ascii/unicode 9

ghadi17:06:51

"\\t" is a two character string, slash followed by t

Nom Nom Mousse17:06:39

Understood. So there is nothing like pythons r"\t" (where r denotes a raw string)?

ghadi17:06:42

if you want a raw string, you can read a file

ghadi17:06:09

via slurp, just not in situ in source code

Jacob Rosenzweig17:06:16

Can someone explain to me how exactly specs or malli "replaces" types? I see that they're good descriptive frameworks for specifying, validating, and conforming data but outside of generated tests and markdown documentation (e.g. autodoc can use specs), I don't see how they replace types. I suppose it offers alternatives to types (just use unit tests if you want safety as you develop), but maybe I'm missing something.

seancorfield18:06:56

We’ve been heavy users of Spec at work since it first appeared (way back in the 1.9 prerelease cycle). This blog post talks about the ways we use it: https://corfield.org/blog/2019/09/13/using-spec/

👍 2
alexmiller17:06:12

they don't replace types

ghadi17:06:07

x "replaces" y is a big (maybe unnecessarily) assertion, so I'm going to set that aside for a second. there's a short but dense paragraph in the rationale doc that offers some insight into the contrast of spec / types https://clojure.org/about/spec#_expressivity_proof

Jacob Rosenzweig17:06:28

One thing I'm starting to see is the use of these DSLs for creating validation "functions". That way you can have sanitizers around your functions without introducing "types" that just result in runtime errors (as opposed to here where a wrong "type" could result in anything you want: an error, a default value, etc.

;; Spec
(s/def :clean-event/user (s/keys ...))
(s/def :raw-event/user (s/nilable :clean-event/user))
(s/def :event/cleaned? boolean?)

(defmulti event-cleaned? :event/cleaned?)
(defmethod event-cleaned? false [_]
  (s/keys :req [:event/cleaned? :raw-event/user]))
(defmethod event-cleaned? true [_]
  (s/keys :req [:event/cleaned?] :opt [:clean-event/user]))

(s/def :event/event (s/multi-spec event-cleaned? :event/cleaned?))
;; Code cleanup
(defn cleanup [{:raw-event/keys [user] :as event}]
  (-> event
      (dissoc :raw-event/user)
      (assoc :event/cleaned? true)
      (assoc-unless-nil
        :clean-event/user user)))

Jacob Rosenzweig17:06:23

Is this very common? For me, this seems like a more flexible alternative to appending ::pre and ::post to all my functions.

ikitommi17:06:59

tools like clj-kondo can push the spec/malli function validation to static analysis phase, but they are still not types. Would love to see more developer tooling for these. Intellisense/autocompleting based on specs/schemas etc.

ikitommi18:06:07

just looked at typehole, a VSCode plugin for creating TypeScript definitions from sample data. Wound be easy to do with Clojure.

borkdude18:06:32

didn't you already support something like this with malli?

ikitommi18:06:10

yes, but that could be integrated into editors.

ikitommi18:06:56

also malli->TypeScript might be useful.