This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-04
Channels
- # announcements (2)
- # babashka (7)
- # beginners (168)
- # boot (8)
- # cider (10)
- # clara (1)
- # clj-kondo (19)
- # cljdoc (8)
- # cljs-dev (16)
- # clojars (1)
- # clojure (208)
- # clojure-europe (10)
- # clojure-germany (1)
- # clojure-losangeles (1)
- # clojure-uk (56)
- # clojurescript (63)
- # conjure (23)
- # core-typed (2)
- # cursive (5)
- # data-science (1)
- # datomic (35)
- # emacs (1)
- # exercism (58)
- # graalvm (2)
- # graphql (1)
- # jobs (3)
- # kaocha (1)
- # lambdaisland (2)
- # malli (19)
- # meander (5)
- # off-topic (2)
- # pathom (25)
- # pedestal (3)
- # reagent (53)
- # reitit (4)
- # remote-jobs (2)
- # shadow-cljs (26)
- # spacemacs (3)
- # sql (22)
- # tools-deps (17)
Should I be using spec’s s/valid?
or s/assert
in my pre/post conditions?
s/assert
seems more useful, but maybe I’m doing it wrong
@jings.bill :pre
/`:post` conditions -- makes more sense to me to use a predicate (`s/valid?`). I personally don't like :pre
/`:post` conditions and I don't much like assertions. If I want argument checking in dev/test, I'd rather use s/fdef
and instrumentation. When I want to check data for validity -- and handle that as part of my design -- I'll use s/valid?
(or s/conform
) in production code inside the function.
Ahh. I had no idea that was what fdef
did.
Good saturday morning everyone. I'm trying to start refactoring a file, for the first time. I want to have some core functions, some testing infrastructure functions, some functions which use the core and testing infrastructure, and also some utility functions. Currently all functions are defined in the same core file, and I want to distribute the functions to the appropriate other files. As I understand the tooling for closure requires that I decare one namespace per file, whereas in Common Lisp I'd declare one namespace and have several files just use that name space with the equivalent of in-ns
The structure should be core requires util, util requires nothing, tester requires nothing, rte-tester requires tester and core.
When I create a file named rte_tester.clj
which declare no function but begins with
(ns clojure-rte.rte-tester
(:require [clojure-rte.tester :refer :all]
[clojure-rte.core :refer :all]
)
(:gen-class))
loading it causes the following error.
Syntax error (IllegalStateException) compiling at (rte_tester.clj:1:1).
random-test already refers to: #'clojure-rte.core/random-test in namespace: clojure-rte.rte-tester
What does this mean?I already restarted cider a couple of times, and that doesn't help.
It is certainly common to have a one-to-one correspondence between file and Clojure namespaces, and some tools do expect that. It isn't a requirement of the language implementation itself, though. I wouldn't veer away from that unless you were curious whether the tooling you are using handles it, and/or really really prefer otherwise.
@andy.fingerhut yes, i was trying to embrace the standard advice and do just that. But having trouble understanding how to do it. Is there something wrong with that (ns ...)
expression at the top of an otherwise empty file?
I would recommend leaving out (:gen-class)
unless you know for a fact that you absolutely need it for some reason.
OK, I don't even know what :gen-class does, lein just put it in the original file and I copied it.
What does it mean?
It directs the Clojure compiler to create a Java class file with some particular Clojure-specific conventions for some things. It isn't typically needed. I can't answer in any great detail because I have so rarely encountered it.
I thought it was probably related to making a standalone application, unix level application. Because lein also defined a -main
function
Do you define a function random-test
in any of those namespaces?
Even if I take out the :gen-class
I define random-test only in the core. and I'm NOT redefining it in this file.
Clojure on Java will look for compiled JVM byte code in files whose names end in .class
on the JVM class path, and use those if they exist, and I think there is another condition like their time stamp must be more recent than a corresponding file with suffix .clj
or .cljc
. Depending on the tooling you are using, there may be old .class
files around created from before the time you moved functions from one namespace to another.
Deleting all of those and starting a fresh JVM could help in that case
I believe lein clean
may do that, but you can also use Unix-y commands like find
to check if you want to be certain
Here are the three files.
Can you take a look at the files and see if there's something obvious wrong.
I tried lein clean, and then restart-cider, but same problem occurs.
Are all of those files in a directory named clojure_rte
, and that directory is inside of a directory named src
in the root of your project?
When I put those files into a directory src/clojure_rte
of a project template that I created using lein new clojure_rte
, and then run the command lein repl
, I do not see the error you showed above, but I do see other errors, e.g. warnings about vars with names having asterisks around them, but not declared dynamic (that is only a warning), but also an error about unable to resolve traverse-pattern
I did not use CIDER to get that result, just lein repl
command in a terminal, in project root dir
It does appear that there is a call in your core.clj
source file to traverse-pattern
before it is defined.
OK, it sounds like I'm on the right track, there must be something cached somewhere.
I am not claiming that is the root cause of the behavior you are seeing, which sounds like something else. I don't use CIDER, so am not a good person to try to reproduce that aspect of it.
called before defined, yes that's something I need to work through,
it was one reason to separate into seperate files. to get a better handle on what requires what.
sure, there are typically a flurry of errors while you reorganize things
it would be cool if the clojure compiler would internally perform a topological sort of the top level forms before compiling the file.
how did you fine the used before defined? was that a warning by the loader. I don't see it.
You can use (declare traverse-pattern)
early in a file if you like the order things exist in, and such a thing is necessary for mutually recursive top level functions.
this one is not mutually recursive, I'll re-order it. But how did you find it?
I saw an error message about traverse-pattern
in the output of the lein repl
command I typed with a fresh lein new clojure_rte
template, plus your 3 files copied into src/clojure_rte
directory.
I don't see any warning.
ahh, it's something which lein found, not something that load/compile found.
Typing lein repl
from terminal, in project root, starts a JVM process, and with the project.clj
file created in the template, there is this line: :repl-options {:init-ns clojure-rte.core}
and I believe that directs Leiningen to try to load that namespace when starting a REPL
Here is the output I see when typing lein repl
command:
$ lein repl
Warning: *rte-hash* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *rte-hash* or change the name. (clojure_rte/core.clj:47)
Warning: *traversal-functions* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *traversal-functions* or change the name. (clojure_rte/core.clj:48)
#error {
:cause Unable to resolve symbol: traverse-pattern in this context
:via
[{:type clojure.lang.Compiler$CompilerException
:message Syntax error compiling at (clojure_rte/core.clj:50:14).
:data #:clojure.error{:phase :compile-syntax-check, :line 50, :column 14, :source clojure_rte/core.clj}
:at [clojure.lang.Compiler analyze Compiler.java 6808]}
{:type java.lang.RuntimeException
:message Unable to resolve symbol: traverse-pattern in this context
:at [clojure.lang.Util runtimeException Util.java 221]}]
:trace
[[clojure.lang.Util runtimeException Util.java 221]
[clojure.lang.Compiler resolveIn Compiler.java 7414]
[clojure.lang.Compiler resolve Compiler.java 7358]
[clojure.lang.Compiler analyzeSymbol Compiler.java 7319]
[clojure.lang.Compiler analyze Compiler.java 6768]
[clojure.lang.Compiler analyze Compiler.java 6745]
[clojure.lang.Compiler$InvokeExpr parse Compiler.java 3820]
[clojure.lang.Compiler analyzeSeq Compiler.java 7109]
[clojure.lang.Compiler analyze Compiler.java 6789]
[clojure.lang.Compiler analyze Compiler.java 6745]
[clojure.lang.Compiler$BodyExpr$Parser parse Compiler.java 6120]
[clojure.lang.Compiler$FnMethod parse Compiler.java 5467]
[clojure.lang.Compiler$FnExpr parse Compiler.java 4029]
[clojure.lang.Compiler analyzeSeq Compiler.java 7105]
[clojure.lang.Compiler analyze Compiler.java 6789]
[clojure.lang.Compiler analyzeSeq Compiler.java 7095]
[clojure.lang.Compiler analyze Compiler.java 6789]
[clojure.lang.Compiler analyze Compiler.java 6745]
[clojure.lang.Compiler$MapExpr parse Compiler.java 3104]
[clojure.lang.Compiler analyze Compiler.java 6797]
[clojure.lang.Compiler access$300 Compiler.java 38]
[clojure.lang.Compiler$DefExpr$Parser parse Compiler.java 596]
[clojure.lang.Compiler analyzeSeq Compiler.java 7107]
[clojure.lang.Compiler analyze Compiler.java 6789]
[clojure.lang.Compiler analyze Compiler.java 6745]
[clojure.lang.Compiler eval Compiler.java 7181]
[clojure.lang.Compiler load Compiler.java 7636]
[clojure.lang.RT loadResourceScript RT.java 381]
[clojure.lang.RT loadResourceScript RT.java 372]
[clojure.lang.RT load RT.java 459]
[clojure.lang.RT load RT.java 424]
[clojure.core$load$fn__6839 invoke core.clj 6126]
[clojure.core$load invokeStatic core.clj 6125]
[clojure.core$load doInvoke core.clj 6109]
[clojure.lang.RestFn invoke RestFn.java 408]
[clojure.core$load_one invokeStatic core.clj 5908]
[clojure.core$load_one invoke core.clj 5903]
[clojure.core$load_lib$fn__6780 invoke core.clj 5948]
[clojure.core$load_lib invokeStatic core.clj 5947]
[clojure.core$load_lib doInvoke core.clj 5928]
[clojure.lang.RestFn applyTo RestFn.java 142]
[clojure.core$apply invokeStatic core.clj 667]
[clojure.core$load_libs invokeStatic core.clj 5985]
[clojure.core$load_libs doInvoke core.clj 5969]
[clojure.lang.RestFn applyTo RestFn.java 137]
[clojure.core$apply invokeStatic core.clj 667]
[clojure.core$require invokeStatic core.clj 6007]
[clojure.core$require doInvoke core.clj 6007]
[clojure.lang.RestFn invoke RestFn.java 408]
[user$eval5 invokeStatic form-init5776825426719157634.clj 1]
[user$eval5 invoke form-init5776825426719157634.clj 1]
[clojure.lang.Compiler eval Compiler.java 7177]
[clojure.lang.Compiler eval Compiler.java 7166]
[clojure.lang.Compiler eval Compiler.java 7166]
[clojure.lang.Compiler load Compiler.java 7636]
[clojure.lang.Compiler loadFile Compiler.java 7574]
[clojure.main$load_script invokeStatic main.clj 475]
[clojure.main$init_opt invokeStatic main.clj 477]
[clojure.main$init_opt invoke main.clj 477]
[clojure.main$initialize invokeStatic main.clj 508]
[clojure.main$null_opt invokeStatic main.clj 542]
[clojure.main$null_opt invoke main.clj 539]
[clojure.main$main invokeStatic main.clj 664]
[clojure.main$main doInvoke main.clj 616]
[clojure.lang.RestFn applyTo RestFn.java 137]
[clojure.lang.Var applyTo Var.java 705]
[clojure.main main main.java 40]]}
nREPL server started on port 52150 on host 127.0.0.1 -
REPL-y 0.4.4, nREPL 0.6.0
Clojure 1.10.1
Java HotSpot(TM) 64-Bit Server VM 1.8.0_192-b12
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
clojure-rte.core=>
Those warnings and error messages I am 99.9% sure are from the Clojure compiler, not something added by Leiningen
Thanks for the help with this namespace issue. When I start a new cider, and ask it to run the tests, they all pass.
however, i still get the error trying to load the "rte_test.clj" file 😞
maybe it's just something about cider?
If you are willing to make your entire project public, e.g. on Github, someone in #cider channel may be willing to take a look
how am I supposed to name top level variable definitions if not *something*
?
(a) You can ignore the warnings. They are harmless. (b) You can leave off the 'earmuffs'. (c) If you want dynamically bindable Vars, you can use (def ^:dynamic *something* ...)
Cool, I marked them dynamic for now. I need to figure out later whether they should be dynamic or not.
Not sure if you saw replied in a thread above about error messages I saw on my system. I put them there because they include a fairly long chunk of text
I am not sure, but I suspect with your familiarity with Common Lisp, and newness to Clojure, you are probably feeling like an American in the UK, occasionally using words you think are harmless but offend people, or vice versa 🙂
Did I say something offensive? Sorry. 😞
Sorry, I did not mean you said anything that offended me, or anyone here. Only offensive to the software on your computer - I was making a bad analogy
we nerds sometimes get too excited with technical things.
I did recently accidentally find the clojure function cl-format
I laughed.
i'm curious how complete it is. cl-format
is a dsl unto itself.
@ahmed1hsn are you a cl-format
user?
Where's a good place to pose cider related questions. I don't see a #cider channel here
in a (cond ...)
we have a sequence of test consequent pairs, if test is true, then cond evaluates to the consequent, if not, the next test is considered ... is there a way to tell cond for a particular consequent I just want to return the value of the test?
if not, this might be my first excuse to write a clojure macro, cl-cond
I see there is a https://stackoverflow.com/questions/4128993/consolidated-cond-arguments-in-clojure-cl-style with a buggy macro implementation provided.
Here is my suggested solution
(defmacro cl-cond [[if1 then1] & others]
;; implementation from
;;
(when (or if1 then1 others)
(let [extra-clauses# (if others `(cl-cond [email protected]))]
(if then1
`(if ~if1 ~then1 ~extra-clauses#)
`(or ~if1 ~extra-clauses#)))))
It's a bit ugly but this works: using metadata to tell the macroexpand to return the predicate
(defmacro cond*
[& clauses]
(when clauses
(let [p (first clauses)
return? (:return (meta p))]
(if return?
`(if ~p
~p
(cond* [email protected](next clauses)))
`(if ~p
~(if (next clauses)
(second clauses)
(throw (IllegalArgumentException.
"cond requires an even number of forms")))
(cond* [email protected](nnext clauses)))))))
(cond*
^:return p1
p2 c2
p3 c3)
I found a but in my implementation.
(cl-cond
(a (f1) (f2) (f3)))
If a is true, his should return (f3)
but should evaluate (f1)
and (f2)
.
Here is my updated implementation in case anyone is interested.
(defmacro cl-cond
"Like CL:cond. Each operand of the cl-cond is a list of length at least 1.
The same semantics as clojure cond, in that the return value is
determined by the first test which returns non-false. The
important semantic difference is that an agument has 1, then the
specified form is both the test and the return value, and it is
evaluated at most once.
Implementation from:
"
[[if1 & then1] & others]
(when (or if1 then1 others)
(let [extra-clauses# (if others `(cl-cond [email protected]))]
(if then1
`(if ~if1 (do [email protected]) ~extra-clauses#)
`(or ~if1 ~extra-clauses#)))))
Why does this fail:
(doc (first (apropos "run")))
but this succeed?
(doc clojure.core/dorun)
Lots of functions in clojure take a predicate. Is there a function to logically invert a predicate? For example
(filter (logically-invert seq?) items)
this would return a sequence of those elements from items which are not sequences.found it! its called complement
thanks for the useful observation
However, there are lots of functions which take a predicate, perhaps not all come in filter/remove pairs. complement
will be a useful function.
You can also negate the predicate with not
- what complement
does internally. https://github.com/clojure/clojure/blob/clojure-1.10.1/src/clj/clojure/core.clj#L1433
No, (not seq?)
is false
which does not test for not-a-sequence
These two are equivalent, 1) (filter (complement even?) [1 2 3 4 5])
and 2) (filter #(-> % even? not) [1 2 3 4 5])
.
Yes, but (complement f)
is not (not (f args))
... it is rather (fn [x] (not (f x)))
plus some cases for other arities.
I think that's probably what you meant.
@sfyire doc
is a macro which expects an unquoted symbol, not the list (first (apropos "run"))
, which the doc
macro will not evaluate
doc
calls a function in its implementation, which you could call from the REPL, but it isn't exactly convenient to type in its built-in form, although you could of course write your own function that makes it more convenient.
(let[n(read-string(first *command-line-args*))](print(and(> n 1)(=(reduce #(* %1(if(=(mod n %2)0)0 1))1(range 2 n))1))))
I am writing program to check if no. is prime or not. And i am getting an error: Execution error.
ERROR: TypeError: cljs.user.read_string is undefined
cljs.user=> (apropos "read")
(cljs.core/*print-readably* cljs.core/spread)
there is no clojurescript read-string. But you can use the cljs.edn namespace:
cljs.user=> (require '[clojure.edn :as edn])
nil
cljs.user=> (dir edn)
read
read-string
ljs.user=> (doc edn/read-string)
-------------------------
clojure.edn/read-string
([s] [opts s])
Reads one object from the string s.
Returns nil when s is nil or empty.
Reads data in the edn format (subset of Clojure data):
opts is a map as per cljs.tools.reader.edn/read
nil
cljs.user=> (edn/read-string "bob")
bob
cljs.user=> (edn/read-string "{:a [1 2 3] :b {:c :d}}"
)
{:a [1 2 3], :b {:c :d}}
cljs.user=> (edn/read-string "{:a [1 2 3] :b {:c :d}}")
{:a [1 2 3], :b {:c :d}}
cljs.user=> (type *1)
cljs.core/PersistentArrayMap
cljs.user=>
i called doc
on it. it can take either a string or options and a string. it reads a string into clojure data
Yes you can. Just use ':as'
(let [[a b c :as v] [1 2 3]] (println a b c v))
=> 1 2 3 [1 2 3]
Thanks! I had this idea it only works with maps. And then I got the syntax wrong when trying it. So inside the vector, of course!
Yeah I was happy when I stumbled upon using :as in vector destructuring my first time too!
I want to generate some random data that has one decimal point, as a number type rather than a string. If I wanted a string, I'd use format
.
I can use rand
to generate random decimal numbers, but only want one decimal place. Wrapping with float
gives too many decimal places.
Math/round
returns a whole number, with-precision
doesn't truncate the number of decimal points...
Any suggestions (I dont care about rounding errors, its mock data). Thank you.
Something like this?
(/ (int (* 10 (rand))) 10.0)
Ah, now that's a nice bit of lateral thinking. Thank you.
There was a very nice one-liner in the thread that suits me. I also tried DecimalFormat Java class, but its still a string and a lot of code. Had to remember how to do Java Interop for about 30 seconds 🙂
(import java.text.DecimalFormat)
(def decimal-format
(DecimalFormat. "#.#"))
(.format decimal-format (rand 20))
org.postgresql.util.PSQLException: ERROR: column "seller_id" specified more than once| Position: 66
because you're specifying it twice, once as a string key "selled_id", and once as your new keyword key :seller_id
{name Burton Board, description Snowboard, price 100, quantity 1, seller_id 8e85d9c3-c800-4d03-b79c-286343ad6020, :seller_id #uuid "8e85d9c3-c800-4d03-b79c-286343ad6020"}
what you probably mean to do is update item "seller_id" #(java.util.UUID/fromString %)
, or something like that
also using update gives me the original error i was having of java.lang.ClassCastException: java.util.UUID cannot be cast to clojure.lang.IFn
worth noting that you have to wrap in an anonymous fn only because it's a Java method, for regular Clojure functions you can just pass it in like (update item "seller_id" from-string)
Is there a simple way to get a formatted version of a map?
I'm imaginging somethign like pprint, but not tied to any output. Just a fancy string
nvm, solved my own problem. In cljs, it's (with-out-str (cljs.pprint/ppring coll))
I’m loading a file in a fresh REPL, and it’s failing to find a dependency:
Syntax error compiling at (src/gascan/posts.clj:1:1).
namespace 'gascan.post-spec' not found
I’m at a loss for why it’s failing to find this namespace. src/gascan/post_spec.clj
exists and contains the namespace in question:
(ns gascan.post-spec
(:require [clojure.spec.alpha :as s]))
If you start a REPL, is it automatically loading some namespaces, or no? If not, maybe you could try (require 'gascan.post-spec)
as the first thing in the new REPL and see if there are any errors?
hmm, no errors. but the file still fails to load.
gascan.core> (require 'gascan.post-spec)
nil
gascan.core> (ns-interns 'gascan.post-spec)
Execution error at gascan.core/eval15313 (form-init6807784250795486954.clj:46).
No namespace: gascan.post-spec found
My mind isn't jumping to any theories about why that might happen...
Any stale .class files around you can try deleting? Other cached stuff? Try a fresh git clone of the same project on a different machine? etc.?
The fact that your REPL prompt is gascan.core
makes me wonder whether when you typed (require 'gascan.post-spec)
it has already earlier tried to do that, and failed, and your require is doing nothing.
Might give more info or error if you can make (require 'gascan.post-spec)
be the first thing that Clojure does in the new JVM
that was it
i put together a deps.edn so I could fire up a bare clj REPL (`lein repl` loads a lot of stuff right at the bat)
user=> (require 'gascan.post-spec)
Syntax error compiling at (gascan/post_spec.clj:4:10).
No such namespace: java-time
that was very confusing. not the first time i’ve been confused by errors in cold start loading my REPL. is there a better place to find those errors than in the REPL itself?
There are at least a dozen different ways to start a Clojure REPL. Where error messages go in each case can differ. I would check carefully the output of your earlier attempts to see if there was no such error message anywhere, and if not, maybe describe how you start your REPL, and people familiar with that way of doing it might know.
I’m starting it with a leiningen project in cider. The main REPL window doesn’t show any errors
In general, Leiningen has more stuff it tries to do for you under the hood, and so the #leiningen channel is a good place to find people expert in what kinds of things can cause this behavior, but it is so widely used that this shouldn't be a bad channel to ask, either.
You could try asking in #cider channel if startup errors maybe go to some other Emacs buffer, perhaps.
Great. Thanks!
Hello Clojurians, I've tried to update the db in re-frame in this inelegant way
(re-frame/reg-event-db
:getTagValue
(fn [db [_ data]]
(assoc-in db [:tag-table :foo :current] (data "value"))
(assoc-in db [:tag-table :foo :unit] (data "unit"))
(update-in db [:tag-table :foo :history] conj (data "value"))))
But it doesn't seem to work.
Maybe the way to do it is using a function I pass to update-in instead of conj?
Like
(update-in db [:tag-table :foo] magic-function-that-updates-3-values-at-once data)
assoc-in
and update-in
don't mutate db
. They return a new db
value. So you're computing new db values and only returning the result of your call to update-in
.
A common way to chain together changes to a map is the thread-first macro ->
. Your event should work the way you expect if you formulate it as
(re-frame/reg-event-db
:getTagValue
(fn [db [_ data]]
(-> db
(assoc-in [:tag-table :foo :current] (data "value"))
(assoc-in [:tag-table :foo :unit] (data "unit"))
(update-in [:tag-table :foo :history] conj (data "value")))))
That's syntactic sugar for the very difficult to read
(re-frame/reg-event-db
:getTagValue
(fn [db [_ data]]
(update-in (assoc-in (assoc-in db [:tag-table :foo :current] (data "value")) [:tag-table :foo :unit] (data "unit")) [:tag-table :foo :history] conj (data "value"))))
The important part of that is that each operation is being done on the result of the previous one, rather than just on db
.