This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-06-27
Channels
- # announcements (5)
- # aws (2)
- # babashka (2)
- # beginners (79)
- # calva (14)
- # clojure (45)
- # clojure-canada (1)
- # clojure-europe (26)
- # clojuredesign-podcast (14)
- # clojurescript (4)
- # cursive (30)
- # datascript (8)
- # depstar (2)
- # emacs (7)
- # events (1)
- # helix (2)
- # honeysql (4)
- # jobs-discuss (1)
- # off-topic (5)
- # polylith (1)
- # quil (2)
- # reagent (7)
- # shadow-cljs (14)
- # tools-deps (26)
- # xtdb (9)
Hey guys, I'm trying to design a running delay. Multiple processes could add time to the delay, and a function would run whenever the remaining time reaches zero. Any ideas how to simply implement this?
The easiest is just keep an atom, and have a loop that reads the atom sets it to 0, and sleeps until the atom is 0
(def pika-evolutions (r/atom ["Pichu"
"Pikachu"
"Raichu"]))
(def selected-evl (r/atom nil))
(defn vec-remove
"Remove elem in coll"
[pos coll]
(into (subvec coll 0 pos) (subvec coll (inc pos)))) ;; <--- Uncaught Error: Index out of bounds
(defn remove-evolution-form []
[:div
(into [:select {:size 4
:on-change #(reset! selected-evl (-> % .-target .-value))}]
(for [idx (range (count @pika-evolutions))]
(let [evl (get @pika-evolutions idx)]
[:option {:key evl
:value idx} evl])))
[:button
{:on-click (fn []
(let [evl-left (vec-remove @selected-evl
@pika-evolutions)]
(reset! pika-evolutions evl-left)))}
"Remove Evolution"]])
1. I get an error when trying to remove an item from the ratom vector. Uncaught Error: Index out of bounds
Where I'm doing wrong?
2. Do you have any hints on how to debug cljs properly? It seems that the js console doesn't help that much and I feel lost every time a new error came out. Atm I'm trying to reproduce the error with a small sample like the code above, but when the error persist I don't know where to debug properly or check for documentationKeep in mind that I am way more familiar with Clojure than with CLJS, but when I have to debug things related to states in CLJS, I create a bunch of helper functions to allow me to dump it (or part of it) whenever I need. https://github.com/Tyruiop/syncretism/blob/main/datops-frontend/src/main/live_opts/core.cljs#L26. In some other cases I also create writer functions to allow me to interact easily with it.
Also I think you could so with only one atom (and have pika-evolutions
be immutable), by doing something like (let [local-pika-evolutions (->> pika-evolutions (split-with #(not= % @selected-evl)) last)] ...)
Wow, cool. Thanks for sharing! I will try to refactor the code with this idea :thumbsup:
Found the error, the value from the on-change event is a String and needs to be converted to int
Hi there. I’m looking into moving from lein to clj deps for some of my projects, but they all contain some Java files. In lein this is easily set up with :java-source-paths
. Does clj deps offer a way to do the same thing, i.e. to include Java source files along with the CLJ ones as well? My google-fu is not strong enough because I can’t seem to find anything about this. Thanks in advance.
Not yet, but support for that is imminent !
I tried this code:
(ns emotion-modeling-lfb.core
(:require [clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as stest]
[clojure.spec.gen.alpha :as sgen]))
(s/def ::between-0-100
(s/and int?
#(> 101 % 0)))
(s/exercise ::between-0-100)
And got this error message on the exercise function:
Execution error (FileNotFoundException) at emotion-modeling-lfb.core/eval1617 (form-init13010486330272312439.clj:1).
Could not locate clojure/test/check/generators__init.class, clojure/test/check/generators.clj or clojure/test/check/generators.cljc on classpath.
And [org.clojure/test.check “1.1.0”]
is in my Leiningen project dependencies
How can I resolve this?
Just tried restarting the REPL, thanks for the tip. I was just reloading the file into the REPL, which I now know isn’t enough.
Yes it did
Just tried restarting the REPL, thanks for the tip. I was just reloading the file into the REPL, which I now know isn’t enough.
Spec question:
(defn label-map [arousal valence]
{:arousal arousal :valence valence})
(s/fdef label-map
:args (s/cat :is-arousal ::between-0-100 :is-valence ::between-negative-100-and-100))
(stest/instrument 'emotion-modeling-lfb.core/label-map)
(s/exercise-fn label-map)
I receive the error code on exercise-fn: No :args spec found, can't generate
I’m confused why, because isn’t that what I did in the fdef?
You need to pass s/exercise-fn a fully namespace qualified symbol. A handy way is to write `label-map
The backtick will resolve the symbol, for instance label-map => namespace.example/label-map`
The backtick worked perfectly, thank you
(defn emotion-map [arousal valence]
{:arousal arousal :valence valence})
(s/fdef emotion-map
:args (s/cat :is-arousal ::between-0-100 :is-valence ::between-negative-100-and-100))
(stest/instrument 'emotion-modeling-lfb.core/label-map)
(s/exercise-fn `emotion-map)
Okay, so now this is working fine when I only exercise the function ten times. Example output:
`=>
([(26 -1) {:arousal 26, :valence -1}]
[(15 0) {:arousal 15, :valence 0}]
[(5 -1) {:arousal 5, :valence -1}]
[(10 -2) {:arousal 10, :valence -2}]
[(1 -1) {:arousal 1, :valence -1}]
[(6 -1) {:arousal 6, :valence -1}]
[(4 -1) {:arousal 4, :valence -1}]
[(5 0) {:arousal 5, :valence 0}]
[(7 -37) {:arousal 7, :valence -37}]
[(1 29) {:arousal 1, :valence 29}])Then I try
(s/exercise-fn `emotion-map 100)
and it works sometimes, but other times I get:
Error printing return value (ExceptionInfo) at clojure.test.check.generators/fn (generators.cljc:435).
Couldn't satisfy such-that predicate after 100 tries.
What does this error message mean?
check out https://clojure.org/guides/spec#_custom_generators. The paragraph before this section hits this very error. Probably quite worth your time to read this guide carefully
What's the CJ alternative to ...var
in JS (or *var
in Ruby) for list expansion for a fn that takes multiple arguments rather than one argument which is a list?
I want to call something like (sh "ls" "foo")
, but I have all the arguments in a list, so I need something like (sh ...args)
. How can I expend the list?
apply
What if I need to add something to the list, such as (defn zsh [& chunks] (sh "zsh" "-c" ...chunks))
? Do I need to manually create a new list with all the arguments or is there a shortcut? In Ruby it'd be sh *["zsh", "-c", *chunks]
, just like in JS, only replacing *
with ...
.
(apply sh "zsh" "-c" chunks)
dev=> (doc apply)
-------------------------
clojure.core/apply
([f args] [f x args] [f x y args] [f x y z args] [f a b c d & args])
Applies fn f to the argument list formed by prepending intervening arguments to args.
Ah, I see. Cool the (doc ..)
thing, I didn't know about it at all.
Also
dev=> (source apply)
(defn apply
"Applies fn f to the argument list formed by prepending intervening arguments to args."
{:added "1.0"
:static true}
([^clojure.lang.IFn f args]
(. f (applyTo (seq args))))
([^clojure.lang.IFn f x args]
(. f (applyTo (list* x args))))
([^clojure.lang.IFn f x y args]
(. f (applyTo (list* x y args))))
([^clojure.lang.IFn f x y z args]
(. f (applyTo (list* x y z args))))
([^clojure.lang.IFn f a b c d & args]
(. f (applyTo (cons a (cons b (cons c (cons d (spread args)))))))))
(although the source isn't always very instructive, esp. when it just calls into Java under the hood!)
(apply sh args)
Right!
Thanks.
I would like to read some edn I didn't produce. Evidently there's a reader function I need to provide to (edn/read-string {:readers ...} s)
What is it expecting, exactly? I think it's something like... a map from the quoted missing tag name to, anything?
oh, i might get what i need from datascript docs. that's the name in this unknown tag
You don't have to pass read two args, if you just pass it a valid Edn as string I believe it should just parse it as clojure.
I'm not sure what you can pass on opts to reader, likely how to interpret any new data/literals.
had to put this down but, the string was getting parsed as clojure yet it had complaints about not being able to find... uh.... datascript.db
in data-readers?
or provide custom readers for them - thus the extra arg
When typing (map inc (range))
in the repl the form is executed and I have to ctrl-c to stop it. The doc for map
says that it returns a lazy seq. If map
returns a lazy seq, why it runs in the repl? Thanks!
When you print the lazy sequence, it attempts to realize every element.
I have an issue with a macro.
I simplified the macro to:
(defmacro block [name & sexps] (println "BEFORE") ~
@sexps (println "AFTER"))`
And the usage to: (block "test" (println "A") (println "B"))
.
But I'm getting unquote-splice not in list
.
What am I doing wrong?
----
I'd like to also check whether I'm doing the right thing. So the use-case is I'm using babashka to run some sysadmin stuff.
block
is supposed to print "Starting <block-name>", execute all the commands in the block (install this and that, compile emacs 28, that sort of stuff) and then print "Block <block-name> took <number> seconds."
I went for a macro here, since a fn would evaluate all the arguments first, rather than sequentially, so when it'd print out "Starting <block-name>", at that point it would already have run all the sexps
as well.
I imagine macro is the answer to this issue here, is it not?
@jakub.stastny.pt_serv You can only use unquote-splice in a list (or something which expands into a list):
(defmacro foo [xs] `[~@xs])
the expansion of the backtick happens in the reader:
$ bb -e "'\`[~@xs]"
(clojure.core/vec (clojure.core/sequence (clojure.core/seq (clojure.core/concat xs))))
dev=> (defmacro block [name & sexps] `(do (println "Starting" ~name) (do ~@sexps) (println "Completed" ~name)))
#'dev/block
dev=> (block "foo" (println "hello") (println "world") (* 1 2 3))
Starting foo
hello
world
Completed foo
nil
dev=>
As your macro stands it would print BEFORE/AFTER at macro-expansion time -- I assumed you wanted that printed at runtime instead?
@seancorfield yes at runtime.
@seancorfield great, this seems to solve it.
@seancorfield @borkdude thank you guys 🙏:skin-tone-3:
I have a lot to study, macros are really new to me. Very cool thing though!
The first rule of Macro Club is...
...don't use macros 🙂
(but, yes, sometimes they delayed evaluation is exactly what you want)
Bear in mind you could use functions, if you don't mind wrapping the commands in a fn
:
dev=> (defn block [name thunk] (println "Starting" name) (thunk) (println "Completed" name))
#'dev/block
dev=> (block "foo" (fn [] (println "hello") (println "world") (* 1 2 3)))
That transformation -- from & body
to (fn [] ~@body)
-- is fairly common in macros that wrap functions. See https://github.com/seancorfield/next-jdbc/blob/develop/src/next/jdbc.clj#L350-L362 for example.
@seancorfield yeah I thought of that, but the intended result is essentially a (moreless) declarative DSL for specifying how the system should be (with (package <xyz>)
rather than (install <xyz>)
) and I didn't want to litter it with lambdas, as it really is meant to be a declarative abstraction.
It's a good point though!
Looking for advice on using ClojureCLR in an IDE? Calva seems like a good choice, given the VS Code <-> CLR connection? Looked at Cursive, and no obvious way to select the CLR.
I have installed ClojureCLR with dotnet tools install --global Clojure.Main
and can get a repl with just Clojure.Main
. My understanding is that nrepl does not work with ClojureCLR.
I've seen introductions on using clojure.core.repl
with socket servers. They all pass Java properties. What might the .NET equivalent be?
I don't know much about ClojureCLR but I'll point you at https://gitter.im/clojure-clr/community which is where the Clojure CLR community is, apparently (there's a #clr channel here but it just points to that Gitter URL).
Thanks! I'll look there.