Just need to know the points. Just data, no graphics. I'm going to use cljfx, but that's irrelevant to the function I'm looking for. Any kind of plot. I know there's different strategies and then surely known algorithms. https://en.wikipedia.org/wiki/Graph_drawing. So 'just an XY scatterplot'.
There's not a ton of documentation but I've been using this to good effect. There are a bunch of examples in the "sketches" directory (results in "results" directory)
And it's possible to just use the scaling stuff here: https://github.com/generateme/cljplot/blob/master/src/cljplot/scale.clj
ohh, that kind of graph. For layouting out graphs (not charts), I've only seen wrappers around graphviz so far
Oh, yeah sorry, I misunderstood as well
some libraries that use graphviz under the hood: β’ https://github.com/clojure/tools.deps.graph β’ https://github.com/daveray/dorothy (it says it's still subject to change, but it hasn't changed in years)
I would also be interested in a library that does graph layout for you that runs on the jvm (no graphviz). would be great to hear if you find something
hmm, there is also https://github.com/totakke/jungerer which wraps http://jrtom.github.io/jung/ which has several graph layout implementations
Thanks @smith.adriane. Yes I might take at look and see if easy to get something out with one of the JUNG implementations, for instance https://github.com/jrtom/jung/blob/master/jung-algorithms/src/main/java/edu/uci/ics/jung/layout/algorithms/SpringLayoutAlgorithm.java. Will definitely share if I can layout a graph from Clojure.
anyone ever seen > Syntax error (VerifyError) compiling new at (/task/sync_databases_test.clj:143:1). > Operand stack underflow
You might try using deftype instead of defrecord there
method resolution is slightly different between java8 and post java9, which could explain the put method confusion passing on java 8 but failing on java 11
I would really like to see the clojure code that produced a verifier error. (Shame on lein for disabling verification)
The verification was an explicit Arg we added here. This is another time Iβve been bitten by the stacktrace thrown into a random temp file on a machine in the cloud. Not a huge fan of that default
@ghadi https://github.com/metabase/metabase/blob/remove-xverify/test/metabase/task/sync_databases_test.clj#L143-L149
Disabling the verifier is a bad idea, there is no good reason to do that (which is why you canβt in newer Javaβs)
yeah. someone added this PR for exactly that reason. it doesn't work going forward and is deprecated in 13+ i think
If you can boil this into a small repro, would definitely like to see an ask question or jira ticket
i just added the option to print the stack trace to stderr so maybe that will give a bit more info
if i can get it there i absolutely will
#error {
:cause "Operand stack underflow\nException Details:\n Location:\n metabase/task/sync_databases_test/MockJobExecutionContext.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @8: areturn\n Reason:\n Attempt to pop empty stack.\n Current Frame:\n bci: @8\n flags: { }\n locals: { 'metabase/task/sync_databases_test/MockJobExecutionContext', 'java/lang/Object', 'java/lang/Object' }\n stack: { }\n Bytecode:\n 0000000: 2a2b 2cb9 017e 0300 b0 \n"
:via
[{:type clojure.lang.Compiler$CompilerException
:message "Syntax error compiling new at (/Users/dan/projects/clojure/metabase/test/metabase/task/sync_databases_test.clj:143:1)."
:data #:clojure.error{:phase :compile-syntax-check, :line 143, :column 1, :source "/Users/dan/projects/clojure/metabase/test/metabase/task/sync_databases_test.clj", :symbol new}
:at [clojure.lang.Compiler analyzeSeq "Compiler.java" 7115]}
{:type java.lang.VerifyError
:message "Operand stack underflow\nException Details:\n Location:\n metabase/task/sync_databases_test/MockJobExecutionContext.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @8: areturn\n Reason:\n Attempt to pop empty stack.\n Current Frame:\n bci: @8\n flags: { }\n locals: { 'metabase/task/sync_databases_test/MockJobExecutionContext', 'java/lang/Object', 'java/lang/Object' }\n stack: { }\n Bytecode:\n 0000000: 2a2b 2cb9 017e 0300 b0 \n"
:at [java.lang.Class getDeclaredConstructors0 "Class.java" -2]}]
:trace
[[java.lang.Class getDeclaredConstructors0 "Class.java" -2]
[java.lang.Class privateGetDeclaredConstructors "Class.java" 3138]
[java.lang.Class getConstructors "Class.java" 1944]
[clojure.lang.Compiler$NewExpr <init> "Compiler.java" 2575]
[clojure.lang.Compiler$NewExpr$Parser parse "Compiler.java" 2667]
[clojure.lang.Compiler analyzeSeq "Compiler.java" 7107]
[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 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 analyzeSeq "Compiler.java" 7095]
[clojure.lang.Compiler analyze "Compiler.java" 6789]
[clojure.lang.Compiler analyze "Compiler.java" 6745]
[clojure.lang.Compiler$BodyExpr$Parser parse "Compiler.java" 6118]
[clojure.lang.Compiler$LetExpr$Parser parse "Compiler.java" 6436]
[clojure.lang.Compiler analyzeSeq "Compiler.java" 7107]
[clojure.lang.Compiler analyze "Compiler.java" 6789]
[clojure.lang.Compiler analyze "Compiler.java" 6745]
[clojure.lang.Compiler$BodyExpr$Parser parse "Compiler.java" 6120]
it seems @hiredmanβs guess about deftype
versus defrecord
was correct. that's some amazing bytecode intuition
https://ask.clojure.org/index.php/9943/defrecord-can-emit-invalid-bytecode
thx
> Attempt to pop empty stack.
Syntax error (VerifyError) compiling new at (********/task/sync_databases_test.clj:143:1).
Operand stack underflow
Exception Details:
Location:
********/task/sync_databases_test/MockJobExecutionContext.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @8: areturn
Reason:
Attempt to pop empty stack.
Current Frame:
bci: @8
flags: { }
locals: { '********/task/sync_databases_test/MockJobExecutionContext', 'java/lang/Object', 'java/lang/Object' }
stack: { }
Bytecode:
0000000: 2a2b 2cb9 017e 0300 b0
Full report at:
/tmp/clojure-18430136797529807953.edn
Tests failed.
a PR removed the jvm option "-Xverify:none"
and this was the result
tests passed on java 8 image but broke with this error on java 11
> Running with these options enables execution of Java programs that violate the Java Virtual Machine Specification. hmm. i'm hoping we're not purposefully emitting programs that violate the jvm spec
Hard to say without more of the stack trace to see where the method is being called but my guess is one of the interfaces you are pulling into the mockjobexecutioncontext is also defining a put method (JobExecutionContext) and defrecord implicitly defines put method (as a map) and something is getting confused about which method is being called
Hi. Is there an interface lower level than ILookup? I want to "proxy" lookups to a record field but can't figure out how to get record fields once I overwrite the ILookup interface for the record. So something like this:
(defrecord foo [id map]
ILookup
(valAt [o key]
(or (get o key)
(get-in o [map key])))
I'm guessing get
and get-in
here would create an infinite lookup loop. Is there a way to do that? Thanksare there any advantages/disadvantages of using clojure.test
over midje
. please feel free to share articles that can help me answer this question
By Sean Corfield, on this Slack some time ago: > I personally would also recommend not using Midje. It's considered non-idiomatic and drags in a lot of transitive dependencies that can be problematic. > Just use plain old clojure.test > Midje isn't compatible with any standard test runners or test tooling.
<3 clojure.test despite its shortcomings
my projects run with both the cognitest test runner and leiningen, so you get the benefit of using more standard tools as well
Was trying to figure out what defrecord
does in the impl of ILookup it generates and I absolutely do not understand that magic. Essentially it amounts to (get __extmap key)
and I can't even figure out how this magical __extmap
gets into scope (a global or some special runtime thing?) and this
isn't even used. Confused
I feel like when it comes to mocking/stubbing, clojure.test
is falling short. is midje better at this?
@franklineapiyo You can consider 1) dynamic vars to swap out existing functions or make tests more flexible, 2) with-redefs
(watch out, not thread-safe)
With option 1) wouldn't I have to re-write the functions I would like to test to use dynamic vars to reference the functions I would like to stub?
yes
oh boy! that doesn't sound very nice π
sometimes it's worth it. E.g. if you're testing a function that does #(System/exit x)
that's pretty much your only option. Or use with-redefs.
Every other mocking technique probably uses this behind the covers anyway
the problem I've found with using with-redefs
is that the tests will not tell you when the stubbed function was not called with the correct/expected arguments; unless of course, you write these instructions into your stub. so, you may have to add this logic to every stub or write some kind of macro to do this. But midje
does it out of the box!
I'm starting to want to use midje. I just want you guys to check the math on why I'm about to use midje π
you have to write the expectations somewhere > unless of course, you write these instructions into your stub that would be the logical place to me.
it's a choice between code that's easy to reason about or some black box testing lib you will depend on
true, true
https://circleci.com/blog/rewriting-your-test-suite-in-clojure-in-24-hours/
> clojure.test is simpler and less magical, with a larger ecosystem of tools and plugins. this is why I use clojure.test
feel free to make your own choices :)
here's a GIF from a show I enjoy βοΈ . Thank you very much.
haha. which show is this?
House M.D.
I think you just call the java .get on the map your record closes on? Potemkin has plenty of magic like this https://github.com/clj-commons/potemkin/blob/master/src/potemkin/collections.clj I also saw pohjavirta do something similar too. https://github.com/metosin/pohjavirta/blob/master/src/pohjavirta/request.clj
problem isn't in delegation - it'll work out of the box since record field value would probably implement its own ILookup. Problem is obtaining record field value in the first place since we are overriding this record's interface
I'll have a look in those libs. Thank you fro pointers!
Potemkin is cheating by rolling out its own type abstraction. I'd rather not go there
If you are changing lookup semantics youβre already there
This is what deftype is for
yeah that's what I figured. IIUC I'll have to extend all the usual interfaces the moment I switch to deftype
. Fair enough
I ended up solving the problem I had differently without proxying, cause in this case it lended itself to this other solution (typical - 9 out of 10 times you don't need special non Clojure sematics). But I still hoped that there was a simpler way to do such delegation.
Hi, what my options for sprinkling a few reactive components in a server side rendered Clojure app without going full SPA, is this doable with Rum? I'm looking to have form inputs filter the the db and return the results client side without incurring a full page refresh. #beginners #programming-beginners
@heyhey This is doable in Rum, and exactly why I use it. I build a SaaS-type web app, where all the pages are HTML pages served by Rum components in .cljc files. Some are completely static, while others have quite complex behavior.
@msolli thanks, that's exactly the type of set-up I had in mind. Glad to hear its being used successfully.
The extmap is just fallback (when you assoc in extra stuff), defined fields go the mapcat's way which I think closes over the values https://github.com/clojure/clojure/blob/38bafca9e76cd6625d8dce5fb6d16b87845c8b9d/src/clj/clojure/core_deftype.clj#L194-L195
user=> (defrecord Bar [a])
user.Bar
user=> (.__extmap (assoc (->Bar 12) :c 42))
{:c 42}
you might get better answers in #clojurescript but I haven't seen anyone talk about using rum in years
I am trying to create a Clojure Google Cloud Function and I have to specify the entrypoint of a leiningen console app (via lein create new app hello-world
):
$ gcloud functions deploy jar-example --entry-point=hello_world_core$_main --runtime=java11 --trigger-http --source=target/uberjar
This entry-point is not correct. /
is not allowed. Any suggestions on how to specify the entry-point
correctly?There are messages in the #google-cloud channel on how to do this. You need to create a Java file as a wrapper
@kevin.van.rooijen had started building a server side rendered reactive application using Reagent at https://github.com/kwrooijen/yggdrasil. But this is not yet production ready I think, but the idea of server side rendering but having Reagent at your disposal (and perhaps even connection with the backend) seems interesting and useful to me. Not sure if there are any other solutions for this
And no documentation π
Except for this https://github.com/kwrooijen/yggdrasil-playground
it should be hello_world.core$_main
hello_world.core$main or elloworld_core$_main or anything like that is almost certainly not correct
those are all "jvm" names for clojure functions, and the gcloud api will have no idea what to do with a clojure function
Thanks! I forgot the logic, this helps π. Still get an error though with --entry-point=hello_world.core$_main
Build failed: build succeeded but did not produce the class "hello_world.core" specified as the function target: Error: class not found: hello_world.core; Error ID: fb35dca7
maybe bash substitution
Ah and with ββ itβs:
Invalid value 'hello_world.core$_main': Entry point name must contain only Latin letters (lower- or upper-case), digits, dot (.) and underscore (_), and must be at most 128 characters long. It can neither begin nor end with a dot (.), nor contain two consecutive dots (..).
you need to look at the documentation for gcloud functions and see what kind of thing it expects as an entry-point, instead of just putting the names of random things in
if entry-point takes a class name, you'll need to ensure that the named class exists in the jar file, and is not a class that is generated while loading clojure code, because gcloud almost certainly doesn't know about loading clojure code
and if it is a class name, that class almost certainly will need at least a specific method, but likely to implement some interface
@erwinrooijakkers Thanks, I'll check it out
originally posted this to #beginners for lack of a good idea to put it, @arthur recommended I post this here instead.
Some related projects, although with a larger scope of running the tasks concurrently and maybe in a distributed manner: - https://github.com/framed-data/overseer - https://github.com/mikub/titanoboa - https://github.com/schmee/daguerreo
the only other library I can think of in the same space is https://github.com/hoplon/javelin, but it's cljs based. Another solution is to wrap functions using https://github.com/clojure/core.memoize and have it automatically cache repeated calculations.
thanks