Fork me on GitHub
#beginners
<
2019-10-26
>
gklijs14:10:05

Using kondo to clean my project a bit, I get quite a bit of missing else warnings when using if. Is there a more idiomatic way to only conditionally do something?

dpsutton14:10:43

Use “when”

gklijs14:10:35

yes, makes sense, harder to make errors when adding additional statements, since it's an inplicit do. thanks

borkdude14:10:21

@gklijs you can turn the linter off if you disagree with Stuart Sierra: {:linters {:if {:level :off}}} 🙂

gklijs14:10:25

I'll agree, I'm just a bit spoiled with clippy, that's suggesting how to fix things 🙂

borkdude15:10:54

yeah, well the fix is ambiguous. you either really forgot something, or you didn't and then you want to use when

gklijs15:10:37

It's a lot harder in Clojure to know what's wrong compared to rust.

👆 4
borkdude15:10:10

Rust can read your mind and knows that you forgot something?

borkdude15:10:31

I guess types help a bit there: when you forget something in the else branch it's probably not the right type

gklijs15:10:11

Well kind of since it's statically types and has the borrow checker. When it sees a certain type, but expects another, it suggest how to get from one to the other. When you use a string inside an enum it suggests to take make it into a reference so the enum will take less space.

borkdude15:10:35

Seems like an interesting language. I have listend to a new Rust podcast today: https://twitter.com/borkdude/status/1188064931272364032

borkdude15:10:02

I have tried Rust a bit in the past, but I haven't got a really good use case for it. CLIs I can make with Graal now

gklijs15:10:30

I still want to try Rust with embedded, but otherwise it was kind of a let down. It takes a lot more time to program, and in some case it's not faster, but even slower than the JVM. Does use a lot less memory but that's hardly a problem. The WASM tooling is great as well. But kind of same story, as long as you don't build games or something cljs will be a lot faster to program.

coder4633415:10:35

Hi everyone! How do I include an NPM package in shadow-cljs? Their documentation list special cases, but I just want the simple, vanilla case. Can't figure it out 😞

thheller15:10:20

npm install the-package then in code (ns (:require ["the-package" :as x]))

borkdude15:10:53

@thheller that's pretty simple 🙂 in normal CLJS what's the bit that you have to do extra here?

thheller15:10:02

basically everything the webpack guides tell you to do https://clojurescript.org/guides/webpack

gklijs15:10:59

or #shadow-cljs 🙂

coder4633415:10:51

wow, that's simple - thanks! And I take care of version bumping like in a normal js project or are thery any gotchas?

thheller15:10:35

you use npm as normal yes, your JS dependencies are kept in package.json and managed by npm/yarn

coder4633415:10:50

perfect, thank you so much!

nmkip16:10:25

Hi, I'm trying to use clojure.java-time/intervalbut I'm getting an exception "No such var: j/interval"

(require '[java-time :as j])
(j/interval (j/instant 10000) (j/duration 15 :minutes))
Has anyone worked with intervals?

papachan16:10:19

it seems it have been removed from java-time

papachan16:10:47

why not using a task scheduler?

papachan16:10:11

(import '(java.util TimerTask Timer))
(let [task (proxy [TimerTask] []
             (run [] (println "Hello!")))]
  (. (new Timer) (schedule task (long 20))))

nmkip17:10:34

I need to know If an instant is contained in time interval

nmkip17:10:12

------|---------|------ t1 t2 I need to know if t is somewhere in between t1 and t2

nmkip18:10:06

I ended up defining some functions to solve this. Maybe there's a lib that already does this for me xD

seancorfield19:10:15

Java Time has no "interval" (so it's not just the clojure.java-time wrapper).

seancorfield19:10:28

See https://github.com/ThreeTen/threeten-extra/issues/2 (by the creator/lead of both Joda Time and Java Time).

Trevor17:10:43

Hi folks, what would be the best way to change this:

[
{:name "a" :args [1 2 3]}
{:name "a" :args [5 6 7]}
{:name "b" :args [1]}
]
into this:
{
:name "a" :arg-list [ [1 2 3] [5 6 7]]
:name "b" :arg-list [[1]]
}
I want to take a vector of maps which have a bunch of duplicate :name values with different vectors of :args and map the :names to a vector of vectors of their args. I'm using Spectre for most of the json transformations, but I'm new to clojure and this transformation is non-obvious to me.

FiVo17:10:23

@trevor670

(def v [{:name "a" :args [1 2 3]} {:name "a" :args [5 6 7]} {:name "b" :args [1]}])

(reduce (fn [m s] (update m (:name s) #(conj % (:args s)))) {} v)

Trevor17:10:10

neato! I'll give it a shot soon! really need to get familiar with the standard library!

sheluchin19:10:24

I can't seem to get support for stuff like :Doc using Clojurescript/vim-fireplace. When I try to use it, I get Unable to resolve var: special-doc in this context at line 1 cljs/user.cljs. Meanwhile, just using clj files, it works fine. Anyone familiar with such a setup?

sheluchin19:10:58

Also, bindings like cpp for sending stuff to the REPL do work.

sheluchin21:10:17

Thanks, didn't know about that one.

heyarne22:10:16

I have a question about conventions… when is a bang actually used to declare side-effects? I'm writing a wrapper for interfacing with a socket. When you send something a robot arm is moved (very bangy to me), when I read something it could until there's new input, so also read-response!? And connect!? In the end I have bangs everywhere, which doesn't seem right

practicalli-johnny13:10:54

My approach is to have a function that only does the side effect and name it with ! at the end. Other functions that call this function do not need the bang as they do not directly have side effects.

erwinrooijakkers09:11:10

I like https://stuartsierra.com/2016/01/09/how-to-name-clojure-functions#orgheadline4 >>>Functions which have side-effects are named with verbs describing what they do. Constructor functions with side-effects, such as adding a record to a database, have names starting with create-. (I borrowed this idea from Stuart Halloway’s Datomic tutorials.) Functions which perform side-effects to retrieve some information (e.g. query a web service) have names starting with get-. For words which could be either nouns or verbs, assume noun by default then add words to make verb phrases. E.g. message constructs a new object representing a message, send-message transmits it. I don’t use the exclamation-mark convention (e.g. swap!) much. Different people use it to mean different things (side effect, state change, transaction-unsafe) so the meaning is vague at best. If I do use an exclamation mark, it’s to signal a change to a mutable reference, not other side-effects such as I/O.

andy.fingerhut22:10:22

Many many people write functions that have side effects with no ! in their names.

andy.fingerhut22:10:41

IIRC, most of the functions in clojure.core that have ! in their names are: (a) because they are unsafe to use within dosync transactions (but not all such functions are so marked, by a long shot), and (b) for the mutating functions on transient collections.

andy.fingerhut22:10:02

For (b), many of those have ! to distinguish them from their immutable counterparts, e.g. conj! vs. conj

mloughlin14:10:55

this is kinda like in Scheme where ! can denote mutation

Yosevu Kilonzo23:10:43

👋 Hello! I'm trying to figure out the best way to read in a directory of files into a .cljs file. I started with a re-frame template and I can read a single file using shadow.resource as described here: https://clojureverse.org/t/using-none-code-resources-in-cljs-builds/3745. It feels like I'm going down the wrong path if I want the a directory of files though. Would anyone have any recommendations?

Drew Verlee19:10:53

So your input is a directory and the expected output is what exactly? When you say "into a .cljs" file its unclear to me. One interperation could be that you read those files via something like slurp then you just add the text into a file. Maybeing saving it as a var. thhellers solution seems to do that as well as fits into the reloading model. > This works fine and is done quite often all over but common implementations suffer from the problem that the compiler doesn’t know that these other resources were used and won’t invalidate caches properly or trigger re-compiles when those resources were modified.

Yosevu Kilonzo18:10:23

Good question @U0DJ4T5U1! I'm not sure what the output should be :thinking_face: This works: (md->html (rc/inline "./docs/example.md")) But guess I'd like a vector of all the markdown files in ./docs.

Yosevu Kilonzo18:10:50

> One interperation could be that you read those files via something like slurp then you just add the text into a file. Maybeing saving it as a var. Do you mean that I read the files in with slurp in a clojure (not clojurescript) file and then referencing the var that contains them in a clojurescript file?