This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # announcements (1)
- # beginners (119)
- # calva (2)
- # cider (40)
- # cljsrn (14)
- # clojure (145)
- # clojure-dev (122)
- # clojure-europe (4)
- # clojure-italy (9)
- # clojure-nl (5)
- # clojure-spec (2)
- # clojure-uk (32)
- # clojuredesign-podcast (1)
- # clojurescript (10)
- # cursive (44)
- # data-science (1)
- # datomic (53)
- # defnpodcast (6)
- # emacs (6)
- # fulcro (13)
- # garden (25)
- # graalvm (3)
- # graphql (7)
- # jobs (3)
- # liberator (4)
- # nrepl (1)
- # off-topic (21)
- # quil (27)
- # reagent (4)
- # reitit (2)
- # remote-jobs (1)
- # ring-swagger (3)
- # shadow-cljs (3)
- # spacemacs (24)
- # sql (29)
- # tools-deps (68)
- # xtdb (2)
Reading on the web for clojure polymorphism, there is a statement which says use multimetods when you really need them otherwise you just protocols
Do you agree on this in a general manner? Or what is your experience with this, just for curiosity sake 🍶
multimethods are the devil, they can take your nice functions and smear it across several namespaces and change them on import, but sometimes thats what you want (they are also pretty hard to manipulate in the repl)
in general you want to use the most specific/least general abstraction at hand imo, multimethods are extremely open and protocols are contained
As much I read, multimetods are less performant then protocols. And they dispatch on a multiples values rather then protocols where you have your type dispatch
that's true, they are less performant than protocols if you're only measuring method call dispatch and not the work done by the body of the multimethod
Don’t fear multimethod perf - the overhead might be 70 ns vs 15 ns for protocol calls. Yes, that’s more, but probably dwarfed by the parts of your program doing actual work, unless it’s in a very hot loop.
There used to be some much bigger perf issues with multimethods. Those were fixed long ago but the fud lingers.
Both are useful. If you are fundamentally doing type based dispatch, then use protocols. If not, use multimethods.
This is an old repo with some timings (needs an update) https://github.com/puredanger/poly-timing
updated those timings. kind of shocking how much better more recent jdk is on a few of those.
well I changed 3 things at the same time so it's hard to tell :) but I suspect it's a combination.
new computer is possibly actually slower in core speed, certainly not much faster. but the places where the general shape of the answer differs are I suspect java
Hey all - perhaps a silly question here... I'm trying to use spec-tools and it seems like the conditional reader macro is being ignored when I import the CLJC file. Reference of the line: https://github.com/metosin/spec-tools/blob/master/src/spec_tools/impl.cljc#L3 Error:
user=> (require '[spec-tools.core]) Syntax error (FileNotFoundException) compiling at (spec_tools/impl.cljc:1:1). Could not locate cljs/analyzer/api__init.class, cljs/analyzer/api.clj or cljs/analyzer/api.cljc on classpath.
I'm invoking it from Java, using tools.deps (updated
add-libs branch as of 3 days ago) - am I missing something obvious here?
add-libs will try to add a lib and it’s transitive deps in a way that meshes with the current full deps you have
are you sure the version of spec-tools you are using matches the code you are looking at on master?
Depending what those are, it may have used an older version of a dep that is incompatible with spec-tools
https://github.com/metosin/spec-tools/commit/b6054583244ff2448a0996402beab0ade0f260b2#diff-5540e5760a51fbb8e46e11f2195a4327 looks like the reader conditionals were added in 0.1.1
Can you try adding it to your deps and restarting your repl to remove the add-lib variable?
Hi all. I’m getting ready to make the case for Clojure for a new work project (to a team who still use
select! in ruby). One thing I’m concerned about is the additional deployment and maintenance overhead, particularly since I’ve not provisioned a server to run the JVM before (I come from a LAMP background).
What’s the state of the art in deploying clojure apps right now? Are there standard, well-maintained docker images you can point an nginx instance at? And has anybody here worked with applications spread across JVM and non-JVM tech?
Loading it from java, I just mean that it's a Java process (so I expect
cljs reader conditional to be ignored)
@jamie962 I don't think you need to worry too much. you can deploy clj apps to heroku if you expect scale, or if you are just running internally, all you need is a JRE installed
personally for deploying clj apps internally, i'd use a docker image with java installed and just build and copy the jar file in
@chrisjswanson thanks - good to know. we deploy to a kubernetes cluster anyway so the docker angle sounds like a good bet.
so i can just copy an uberjar in to that container and then run it with
since you use k8s you have no worry of watching the process lifecycle, it's already handled
if I did need to worry about process lifecycle, what sort of concerns would there be?
well if you were just running in a vm , for example, then if your app crashed you'd need a nanny script to detect that and re-run it
I’m pretty au fait with most of this stuff, it’s where we sidle into jvm territory that I begin to lose confidence
We use lein to build an uberjar, then run it in a standard Java container with java -jar
clojure image maybe more intended for dev, and then just deploy with adoptopenjdk image. same pattern applies
you don't have to worry too much about JVM , I've found the metrics it exposes to actually be quite helpful. do look into key jvm metrics to track though, they can let you know if your app leaks memory, etc
Not coming from jvm world. What is the meaning for snapshot at the end of the release numbers? Can be removed?
so 0.11.7-SNAPSHOT means, this is some code that exists somewhere between the release of 0.11.7 and the version before 0.11.7
so if you were cutting a release of some project you might switch from the snapshot version to the release version, cut the release, and then switch it to the next snapshot version
Another important thing to remember is that 0.11.7-SNAPSHOT can be a different artifact at different times so you don't want to depend on an artifact by name that could change out from under you.
For example, Clojure has daily builds and they are all named 1.11.0-master-SNAPSHOT every day -- and each of them could be different builds.
Does this exception make sense to folks?
java.lang.ClassCastException: com.badlogic.gdx.physics.bullet.collision.SWIGTYPE_p_p_btCollisionObject cannot be cast to com.badlogic.gdx.physics.bullet.collision.btCollisionObject
btCollisionObjectsomething clojure came up with that makes it so it can't compare itself against the java version of the class?
So it seems im back to my original problem with clojurescript. I have a script I import into my nodejs project using a <script> tag in the public html file. now im trying to do unit testing and this workaround isnt working anymore. Any ideas of how to import a compiled clojurescript into a nodejs app?
you have a node.js server that is showing an HTML file with a ClojureScript app added via a script tag?
java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap at clojure.lang.RT.dissoc (RT.java:887) clojure.core$dissoc.invokeStatic (core.clj:1511) clojure.core$dissoc.invoke (core.clj:1504) leiningen.cljsbuild.config$backwards_compat_crossovers$fn__854.invoke (config.clj:70) clojure.core$map$fn__5851.invoke (core.clj:2753) clojure.lang.LazySeq.sval (LazySeq.java:42) clojure.lang.LazySeq.seq (LazySeq.java:51) clojure.lang.RT.seq (RT.java:531) clojure.lang.LazilyPersistentVector.create (LazilyPersistentVector.java:44) clojure.core$vec.invokeStatic (core.clj:377) clojure.core$vec.invoke (core.clj:367) leiningen.cljsbuild.config$backwards_compat_crossovers.invokeStatic (config.clj:70) leiningen.cljsbuild.config$backwards_compat_crossovers.invoke (config.clj:63) leiningen.cljsbuild.config$backwards_compat.invokeStatic (config.clj:77) leiningen.cljsbuild.config$backwards_compat.invoke (config.clj:76) leiningen.cljsbuild.config$normalize_options.invokeStatic (config.clj:152) leiningen.cljsbuild.config$normalize_options.invoke (config.clj:148) leiningen.cljsbuild.config$extract_options.invokeStatic (config.clj:185) leiningen.cljsbuild.config$extract_options.invoke (config.clj:179) leiningen.cljsbuild$cljsbuild.invokeStatic (cljsbuild.clj:258) leiningen.cljsbuild$cljsbuild.doInvoke (cljsbuild.clj:249) clojure.lang.RestFn.applyTo (RestFn.java:142) clojure.lang.Var.applyTo (Var.java:705) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$partial_task$fn__6592.doInvoke (main.clj:284) clojure.lang.RestFn.applyTo (RestFn.java:139) clojure.lang.AFunction$1.doInvoke (AFunction.java:31) clojure.lang.RestFn.applyTo (RestFn.java:137) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$apply_task.invokeStatic (main.clj:334) leiningen.core.main$apply_task.invoke (main.clj:320) leiningen.core.main$resolve_and_apply.invokeStatic (main.clj:343) leiningen.core.main$resolve_and_apply.invoke (main.clj:336) http://leiningen.do$do.invokeStatic (do.clj:40) http://leiningen.do$do.doInvoke (do.clj:32) clojure.lang.RestFn.applyTo (RestFn.java:139) clojure.lang.Var.applyTo (Var.java:705) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$partial_task$fn__6592.doInvoke (main.clj:284) clojure.lang.RestFn.applyTo (RestFn.java:139) clojure.lang.AFunction$1.doInvoke (AFunction.java:31) clojure.lang.RestFn.applyTo (RestFn.java:137) clojure.core$apply.invokeStatic (core.clj:667) clojure.core$apply.invoke (core.clj:660) leiningen.core.main$apply_task.invokeStatic (main.clj:334) leiningen.core.main$apply_task.invoke (main.clj:320) leiningen.core.main$resolve_and_apply.invokeStatic (main.clj:343) leiningen.core.main$resolve_and_apply.invoke (main.clj:336) leiningen.core.main$main$fn_6681.invoke (main.clj:452) leiningen.core.main$_main.invokeStatic (main.clj:442) leiningen.core.main$_main.doInvoke (main.clj:439) clojure.lang.RestFn.applyTo (RestFn.java:137) clojure.lang.Var.applyTo (Var.java:705) clojure.core$apply.invokeStatic (core.clj:665) clojure.main$main_opt.invokeStatic (main.clj:491) clojure.main$main_opt.invoke (main.clj:487) clojure.main$main.invokeStatic (main.clj:598) clojure.main$main.doInvoke (main.clj:561) clojure.lang.RestFn.applyTo (RestFn.java:137) clojure.lang.Var.applyTo (Var.java:705) clojure.main.main (main.java:37)
the error above is independent from my nodejs problem. but i think i found what im looking for online, finally, but i wont know until i try it and see if it works. it is definitely something i havent tried yet so its worth a shot
i was trying what was described here and im having no luck so far https://lambdaisland.com/blog/2017-05-02-nodejs-scripts-clojurescript
@jason821 it sounds like you don't want to run your ClojureScript in Node.js though
so is the ClojureScript supposed to run in the browser as a UI app, or is it supposed to run on the server side in Node.js?
Node.js runs on the server, so you're not going be able to, for example, update the page dynamically based on your clojurescript code
i dont want to dynamically load it as clojurescript, nodejs will automatically refresh if anything changes
shadow-cljs is a build tool which has built-in configurations for developing node modules
i compile the cljs manually, the nodejs will update it. ideally i would like to have cljs reload but thats not how my project is setup