This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-01-04
Channels
- # announcements (42)
- # architecture (18)
- # aws (30)
- # beginners (119)
- # calva (1)
- # cider (3)
- # cljs-dev (15)
- # cljsrn (16)
- # clojure (80)
- # clojure-australia (3)
- # clojure-europe (11)
- # clojure-germany (2)
- # clojure-nl (7)
- # clojure-sanfrancisco (4)
- # clojure-spec (12)
- # clojure-taiwan (2)
- # clojure-uk (10)
- # clojurescript (22)
- # events (2)
- # fulcro (31)
- # ghostwheel (3)
- # jobs (1)
- # kaocha (1)
- # luminus (22)
- # meander (1)
- # off-topic (14)
- # pathom (5)
- # portal (10)
- # re-frame (12)
- # reitit (1)
- # shadow-cljs (19)
- # spacemacs (11)
- # tools-deps (34)
Did anyone encounter the following error on java11? Caused by: java.lang.Exception: Cyclic load dependency: [ /clojure/spec/alpha ]->/clojure/walk->[ /clojure/spec/alpha ]->/clojure/main->/clojure/core/server
IIRC I've seen people report this when they add Clojure sources to their classpath along with the jar. But maybe that's not it in this case.
Encountered it here: https://github.com/FieryCod/holy-lambda/issues/26
The error occurs when using clojure >= 1.10.0 only on java11
Hard to say exactly, but my guess is it is some kind of aot related issue. This is kind of hard to wade through (for example the source for the lein plugin doesn't seem to be the repo?) but we can discount the existence of an actual cyclic dependency in clojure. My guess is an aot issue, just because it often is, but I can't recall an aot issue presenting as a cyclic dependency. The repo looks like it is library code, but is also marked to aot compile everything when building an uberjar. Both of which are big red flags with library code. Library code should not be uberjared or aot compiled.
Thanks @U0NCTKEV8! Will check whether removal of aot helps
@U0NCTKEV8 Removed aot compile for library. Allowed aot compilation for hello-lambda code. Still the same errors is there. Maybe Alex would know the answer? EDIT: When trying clojure:1.10.0 (removing require of clojure.walk) and compiling on java8, but still running on java11 the error is different:
Caused by: Syntax error macroexpanding clojure.core/defn at (clojure/spec/alpha.clj:78:1).
at clojure.lang.Compiler.checkSpecs(Compiler.java:6972)
at clojure.lang.Compiler.macroexpand1(Compiler.java:6988)
at clojure.lang.Compiler.macroexpand(Compiler.java:7075)
at clojure.lang.Compiler.eval(Compiler.java:7161)
at clojure.lang.Compiler.load(Compiler.java:7636)
at clojure.lang.RT.loadResourceScript(RT.java:381)
at clojure.lang.RT.loadResourceScript(RT.java:372)
at clojure.lang.RT.load(RT.java:459)
at clojure.lang.RT.load(RT.java:424)
at clojure.core$load$fn__6839.invoke(core.clj:6126)
at clojure.core$load.invokeStatic(core.clj:6125)
at clojure.core$load.doInvoke(core.clj:6109)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invokeStatic(core.clj:5908)
at clojure.core$load_one.invoke(core.clj:5903)
at clojure.core$load_lib$fn__6780.invoke(core.clj:5948)
at clojure.core$load_lib.invokeStatic(core.clj:5947)
at clojure.core$load_lib.doInvoke(core.clj:5928)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$load_libs.invokeStatic(core.clj:5985)
at clojure.core$load_libs.doInvoke(core.clj:5969)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$require.invokeStatic(core.clj:6007)
at clojure.main$loading__6721__auto____8974.invoke(main.clj:11)
at clojure.main__init.load(Unknown Source)
at clojure.main__init.<clinit>(Unknown Source)
... 58 more
Caused by: java.lang.Exception: #object[clojure.spec.alpha$and_spec_impl$reify__2387 0x69d45cca "clojure.spec.alpha$and_spec_impl$reify__2387@69d45cca"] is not a fn, expected predicate fn
I bumped into this with Figwheel. It culprit was cljc dir in the target dir, ie twice. Once in src/ and the second in target/.
lein clean
often helps @UJ1339K2B
Hi @seancorfield. Thank you for an advice! Unfortunately it does not help either. Moved with discussion to this thread https://clojurians.slack.com/archives/C1B1BB2Q3/p1609759205028100
Should I try brew cask install
-ing both adoptopenjdk/openjdk/adoptopenjdk11
and adoptopenjdk/openjdk/adoptopenjdk8
? Will it work? (while being able to switch versions at will)
(don't want to try it right now, lest I break my dev env)
...I'm aware that jenv and sdkman exist. Hadn't had the need so far, although I'm willing to use them
should have rtm :) https://github.com/AdoptOpenJDK/homebrew-openjdk/tree/463eb266789e9e45b4a444923877861a4068c64d#switch-between-different-jdk-versions
I have a bunch of env vars set in my .profile
so I can easily specify JAVA_HOME=$OPEN_JDK<n>
at the start of any command to run whatever version I need for that command.
(I have 8, 11, 14, 15 installed right now)
Hi everyone. I've noticed that if you call realised?
on a delay
that is has already started evaluating, the call blocks until realised?
is true rather than immediately returning false e.g. in the REPL
(def my-delay (delay (Thread/sleep 5000)))
(future (@my-delay))
(realized? my-delay)
The last line will wait 5 seconds before returning true. Is this a bug? is there any way of getting the behaviour I was expecting?Deref and realized https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Delay.java to https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html methods.
> When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
I think it's at least partly to avoid Shrodinger stuff: a delay is either pending or ready -- you can't observe it "getting ready"
hmm ok. In my current design I've got a time-consuming task which several threads might be waiting for, so I put it in a delay, but I guess that's not what delay is meant for, since clojure code is supposed to avoid locking. I guess I need to re-think it.
Well, you can't use a value until it is available. What do those other threads do if the value is not available (yet)? If they simply spin and wait for it, why not have them just use a deref
and block? If they have other work to do, use a future
instead of a delay perhaps? realized?
doesn't block on a future (it calls .isDone
under the hood).
I'm trying to create a kind of cache of memoized results, where if a thread wants something that is already being processed, it just waits for the existing computation to finish. The cache is an atom so I can't swap! a future into it, because creating a future has a side-effect, so I create it as a delay then deref it once the swap is done. Now I'm trying to clear down stale results from the cache so obviously I want to ignore any that are still being computed.
maybe I can just put a promise in the cache and have a free-running future that signals the promise when it's done
i have a scripts/build.clj file that define a function deploy-build. how do i run that (from a terminal)?
Depends what's in it. See if this helps: https://clojure.org/guides/deps_and_cli https://clojure.org/reference/deps_and_cli
clj -M ./scripts/build.clj
Syntax error (FileNotFoundException) compiling at (E:\workspace-clj\screeps-cljs\.\scripts\build.clj:1:1).
Could not locate cljs/build/api__init.class, cljs/build/api.clj or cljs/build/api.cljc on classpath.
@U491NPF2S that file is part of a leiningen project with this project.clj: https://github.com/anisoptera/screeps-cljs/blob/master/project.clj
The README of that project suggests you run this script: https://github.com/anisoptera/screeps-cljs/blob/master/scripts/watch
I guess on windows you would leave out rlwrap but the rest should more or less work, give or take a few slashes
clojure.lang.ExceptionInfo: failed compiling file:src\screeps\memory.cljs {:file #object[java.io.File 0x2bc0b8c8 "src\\screeps\\memory.cljs"]}
Caused by: clojure.lang.ExceptionInfo: No such namespace: cognitect.transit, could not locate cognitect/transit.cljs, cognitect/transit.cljc, or Closure namespace "cognitect.transit" {:tag :cljs/analysis-err
or}
yeah, that's weird. he mentions transit in the README, but it doesn't seem part of the project.clj
export SCREEPS_USERNAME and SCREEPS_PASSWORD (optionally SCREEPS_BRANCH) to autodeploy code.
I have a macro question that has me stumped.
What's a good way to check if a passed in argument is a function? I thought fn?
would work but it doesn't work in a macro as I expected since the macro receives a symbol or a cons with the fn
definition.
Simplified example of what I'm trying to accomplish:
(defn make-comparison-expr [field compare]
(if (fn? compare)
`(~compare ~field)
`(= ~compare ~field)))
I probably need to resolve compare
, but I am not sure what's the best way to do so in this case. An ugly way that works for this scenario:
(if (or (and (symbol? compare) (fn? @#'compare))
(and (seq? compare) (= 'fn* (first compare))))
`(~compare ~field)
`(= ~compare ~field))))
When binding names to values (via let, def, function invocation, etc) the name is known statically (at compile time) while the value is dynamic (known at runtime). Macros are functions that run at compile time, so there is a fundamental mismatch if you are writing a macro that tries to examine the values names are bound to
There is kind of an exception to this for defs, because previous defs run, so their value is part of the compile time environment of the next top level form
But there are other ways to bind names, and your macro won't work correctly for them
Thanks for the details explanation. That's a good point about not knowing what's being referenced at macro eval time. I tried lifting this check to runtime, and it works but generates some pretty odd code. e.g.
(if (fn? 1)
(1 1)
(= 1 1))
Maybe I shouldn't worry about avoiding code like that since (1 1)
will never run, but I felt like it's something I should avoid. Also I will need to mess with eastwood
to get rid of the linting error.fn?
is only true for a surprisingly small subset of things that can be invoked as a function
Ah did not know about multi methods.
I originally chose fn?
to avoid keywords returning true in this case. But maybe it makes more sense to go the other way around and use ifn?
but give keywords special treatment.
macro sugar can often not be worth it. they feel pretty silly to me too if they just serve to prevent you from having to write (fn [] )
around a body
That would definitely simplify things a lot here. Probably too much of my common lisp thinking bleeding through when trying to write this 😄
Thanks for all the discussion and suggestions.
I settled on having two versions of my macro. A plain version that handles the =
case (which is 80% of the time), and a version with -by
appended that only takes callable things. It really simplified the design and overall code.
are you sure you needed a macro? i didn't follow along too much but it seemed it was just performing a check or returning a function to do so?
I'm making a little query dsl. The main purpose being to keep the intent of the query simple and easy to follow. Mainly using the macro to make things easier for the readers of the code.
@hackeryarn You may find https://github.com/clojure-expectations/clojure-test interesting code to read over: it provides a testing DSL where you can say (expect 1 1)
and it tests they are equal or (expect odd? 1)
and it tests the value using the predicate.
(it macroexpands to regular clojure.test
assertions)
Thanks @seancorfield that's exactly the type of syntax I was trying to accomplish!