This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-01-21
Channels
- # beginners (29)
- # calva (4)
- # clerk (10)
- # clojure (23)
- # clojure-doc (10)
- # clojure-europe (2)
- # clojure-norway (5)
- # clojure-poland (1)
- # clojuredesign-podcast (3)
- # data-science (1)
- # datomic (3)
- # emacs (38)
- # fulcro (4)
- # humbleui (8)
- # hyperfiddle (36)
- # introduce-yourself (4)
- # off-topic (10)
- # portal (14)
- # reitit (6)
- # specter (6)
The Clojure JVM compiler will wrap a try
form in a fnonce
and then call it immediately, if the try
is not in return position. Anyone know why? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L2279-L2280
Probably because of this (the date of the commit is the same as the date of the messages): https://groups.google.com/g/clojure/c/Y6fHOCjmcxk/m/YuIGPMpHMRAJ
It still doesn't quite explain what the problem would be. I'm suspecting it's JVM-specific, but I'll need to look into what a VerificationError
is.
Good catch. This has some interesting info. https://stackoverflow.com/questions/100107/causes-of-getting-a-java-lang-verifyerror
> You would get this error if the bytecode size of your method exceeds the 64kb limit; but you would probably have noticed that.
Either way, definitely something JVM-specific. I'll try without it in jank and see what we run into. I appreciate the help!
Oh, that's fun! I got pre-1.0.0 Clojure up and running to reproduce it:
Clojure
user=> (def k)
#'user/k
user=> (. k dosomething (do (try :something (catch java.lang.Exception
e :something-else)) nil))
java.lang.VerifyError: (class: user/eval__3741, method: invoke signature: ()Ljava/lang/Object;) Inconsistent stack height 0 != 5
java.lang.VerifyError: (class: user/eval__3741, method: invoke signature: ()Ljava/lang/Object;) Inconsistent stack height 0 != 5
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2398)
at java.lang.Class.getConstructor0(Class.java:2708)
at java.lang.Class.newInstance0(Class.java:328)
at java.lang.Class.newInstance(Class.java:310)
at clojure.lang.Compiler$FnExpr.eval(Compiler.java:2984)
at clojure.lang.Compiler.eval(Compiler.java:3843)
at clojure.lang.Repl.main(Repl.java:75)
The bytecode that try/catch compiled to doesn't really have expression semantics, the easiest way to make it an expression is to lift it into a method, and the easiest way to lift it into a method is to wrap it in a fn
I can get that. Early jank codegen (to C++) wrapped everything in lambdas for expression semantics as well. I suppose this is a limitation at the JVM bytecode level.
Gotcha. Thanks for the additional context. I'm happy to see the few cases where jank gets to be simpler than Clojure, since the vast majority of the cases the JVM is helping, not getting in the way. 😄
https://clojure.atlassian.net/browse/CLJ-701 an annoying thing is the wrapping loses type hints