This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-08-24
Channels
- # babashka (9)
- # beginners (17)
- # biff (1)
- # calva (3)
- # cider (29)
- # clj-kondo (31)
- # clojure (59)
- # clojure-austin (12)
- # clojure-brasil (12)
- # clojure-europe (35)
- # clojure-nl (1)
- # clojure-norway (72)
- # clojure-uk (1)
- # clojurescript (15)
- # clr (4)
- # conjure (1)
- # cursive (2)
- # datahike (2)
- # emacs (3)
- # hyperfiddle (114)
- # introduce-yourself (1)
- # kaocha (3)
- # malli (7)
- # off-topic (19)
- # pathom (2)
- # polylith (5)
- # portal (5)
- # reitit (5)
- # shadow-cljs (2)
- # slack-help (4)
- # tools-deps (42)
- # xtdb (6)
Hi. Team. I have a situation with my code. I am doing the following:
• The mainly NS is having the -main
function which is executed as (-main)
after the declaration
• The situation is when creating the uberjar with a build.clj
with the following code:
(defn uber [_]
(clean nil)
(b/copy-dir {:src-dirs ["resources"]
:target-dir class-dir})
(b/compile-clj {:basis basis
:src-dirs ["src"]
:class-dir class-dir})
(b/uber {:class-dir class-dir
:uber-file uber-file
:basis basis
:main 'finicity-order-generator.core
;; required for building in macOS
:exclude ["LICENSE"]})
(println (format "Uberjar %s built at %s" uber-file (.format (LocalDateTime/now) formatter))))
It is running the -main
function at the moment the clojure -T:build uber
is executed. I don’t want to get it executed in that moment. Any idea if I can stop running the function when the uber is created.The build tooling won’t invoke any functions. Are you sure you don’t have any spots where you call it? Including in user.clj maybe?
Don't call (-main)
in the file
It'll be invoked when you run the jar with something like java -cp foo.jar clojure.main -m foo.core
I am calling the (-main)
in the file due part of the logic I am implementing an AWS Lambda and I need to run some context when the lambda starts.
Well requiring that file will invoke that function. So it will run during building as well
Correct. Every time the file is required it will executed, correct?
What about if using AOT?
Do you think it could fix the issue?
That compiles the namespace which will compile all top level forms. Including the call to main
Sorry… Without AOT.
If you remove the call to compile-clj
you will need to add "src"
to the :src-dirs
in your copy-dir
call, but that should produce a source-based uberjar. You will also need to set :main
to clojure.main
(since it must be a compiled main class) and then you will need to pass -m finicity-order-generator.core
to the JAR when you run it:
java -jar path/to/the.jar -m finicity-order-generator.core
you mean like creating (s/def ::foo (s/keys :req [::bar ::baz]))
forms in a visual editor? not text?
Yes, I have asked this before in malli
group.
For example to create a combobox /textfield/etc depending on keys.
I’m not aware of any ready ones, but I haven’t looked. You can certainly make one as you can get the specs as data with s/describe
but I think specs are missing lots of information you would need in a GUI
like layout and order, proper human readable validation messages, so you would need something extra in any case
I am using scene2d ui from libgdx because it's already included and integrated very nice with libgdx, also quite simple and powerful. Full access to graphics context and configurable. https://libgdx.com/wiki/graphics/2d/scene2d/scene2d-ui
Hello I’m trying to call a method, but it throws an IllegalArgumentException. To me it seems like this method exists. Any pointers would be appreciated 🐛
;; Calling the `add` method on `layers` passing `layer` as an argument
;; throws an exception:
(.add layers layer)
;; => Execution error (IllegalArgumentException) at geotools-crs/eval66608 (REPL:34).
;; No matching method add found taking 1 args for class org.geotools.map.MapContent$LayerList
;; So I list the methods called `add` on `layers`:
(->> (cr/reflect layers) :members (filter #(= (:name %) 'add)))
;; => ({:name add,
;; :return-type void,
;; :declaring-class org.geotools.map.MapContent$LayerList,
;; :parameter-types [int org.geotools.map.Layer],
;; :exception-types [],
;; :flags #{:public}}
;; {:name add,
;; :return-type boolean,
;; :declaring-class org.geotools.map.MapContent$LayerList,
;; :parameter-types [org.geotools.map.Layer],
;; :exception-types [],
;; :flags #{:public}}
;; {:name add,
;; :return-type boolean,
;; :declaring-class org.geotools.map.MapContent$LayerList,
;; :parameter-types [java.lang.Object],
;; :exception-types [],
;; :flags #{:public :bridge :synthetic}}
;; {:name add,
;; :return-type void,
;; :declaring-class org.geotools.map.MapContent$LayerList,
;; :parameter-types [int java.lang.Object],
;; :exception-types [],
;; :flags #{:public :bridge :synthetic}})
;; Here we see one method taking a `org.geotools.map.Layer` as input,
;; this is the method I think I'm calling:
{:name add,
:return-type boolean,
:declaring-class org.geotools.map.MapContent$LayerList,
:parameter-types [org.geotools.map.Layer],
:exception-types [],
:flags #{:public}}
;; Here I confirm that the argument i'm passing is of the expected
;; type:
(instance? org.geotools.map.Layer layer)
;; => true
;; So why does (.add layers layer) tell me there is no matching
;; method?
(.add layers layer)
;; => Execution error (IllegalArgumentException) at geotools-crs/eval66626 (REPL:87).
;; No matching method add found taking 1 args for class org.geotools.map.MapContent$LayerList
Just guessing here, maybe it is because there is another overload of add
that takes an Object as an argument, and since Clojure compiler can't guess which one you want to invoke, it generates IAE during reflection?
Try doing (.add layers ^org.geotools.map.Layer layer)
and see if it's still the same
I tried that, but I got the same result
(.add layers ^org.geotools.map.Layer layer)
;; => Execution error (IllegalArgumentException) at geotools-crs/eval66642 (REPL:91).
;; No matching method add found taking 1 args for class org.geotools.map.MapContent$LayerList
adding a type hint to the first argument too worked though 🎉
(.add ^org.geotools.map.MapContent$LayerList layers ^org.geotools.map.Layer layer)
;; => true
Thanks a lot!Hello,
I have trouble extending a type with a protocol which has a function with multiple arities. Could help me figure out what I am missing? Interestingly, the 3-arity version works. I have only trouble with the 2-arity variant.
proto.clj
(ns proto)
(defrecord Record [])
(defprotocol Protocol
(func [this param1] [this param1 param2]))
app.clj
(ns app
(:require [proto])
(:import (proto Record)))
(extend-type Record
proto/Protocol
(func [this param1] (func this param1 :param2))
(func [this param1 param2] [param1 param2]))
(comment
(proto/func (proto/->Record) :a :b) ; works => [:a :b]
(proto/func (proto/->Record) :a) ; Wrong number of args (2) passed to: app/eval9854/fn--9855
,,,)
when redirecting, you must specify not func but namespace/func since it comes not from the current namespace but from somewhere else
Ah good point, I missed that. Unfortunately, it did not solve to problem. That is probably the next issue I would have faced if I could get the arities working. I got the same error. It turns out if I completely remove the implementation, that still does not work:
(extend-type Record
proto/Protocol
(func [this param1])
(func [this param1 param2] [param1 param2]))
Bumping this in case someone has an idea what the problem is. I do not know how to debug this further.
Aaah got it. The syntax is different. I managed to get it working by:
(extend-type Record
proto/Protocol
(func
([this param1] (proto/func this param1 :param2))
([this param1 param2] [param1 param2])))
I think maybe I found a bug in clojure (or at least a core libraries)
(clojure.edn/read-string (str {(keyword "bad;keyword") 5}))
this produces the exception EOF while reading
I can’t decide if the blame lies with keyword or read-string. Since this seems work:
(type (keyword "bad;keyword"))
=> clojure.lang.Keyword
I would love some feedback before I start filling out forms. Anyone else think this is a bug?
This is an example of clojure's "garbage in, garbage out" philosophy. Calling keyword
on an unreadable keyword produces undefined behavior.
In this case the result is a keyword which, once printed, cannot be read back in.
yeah, I agree with that
should a keyword be able to be created that is invalid edn?
or maye edn should be able to ‘escape’ it somehow?
I think what would be desirable here is a way to print data guaranteed as valid edn
and that is something that is on our radar as it comes up a lot

as a note, this also fails differently but sorta the same
(clojure.edn/read-string (str {(keyword "bad
keyword") 5}))`
@U064X3EF3 that makes sense to me
There is quite a bit of code out in the wild that relies on being able to create "illegal" keywords (i.e., that aren't valid according to Clojure's description of what a keyword is and are therefore "unreadable").
There are also a few things that are not technically legal keywords but the reader does still accept them (e.g., :1
) and, again, there's code out there in the wild that relies on that working.
creating unreadable keyword objects is not a problem, but printing them is
the even more general problem right now is that printing is an open global system when it would often be useful to create scoped modifications of printing in different contexts. if such a thing existed, you could create a set of printing rules for printing edn, or printing somewhere else and use them both at the same time in a clojure runtime. I think a separate concern is how you would want to be notified of something that cannot be printed - that starts to feel instead more like validation. this space is complex and deeply woven into lots of real code, but is a real common problem. I continue to lobby Rich to work on it. :)
About :1
: IIRC, it wasn't working initially in clojurescript. It has been patched since then to have the same behavior as in clojure. Wouldn't it mean that it's a valid keyword?
To me it sounds like it could be useful to have the ability to have a dynamic scope with-methods
which includes local overrides to specific methods on a multimethod, similar to with-redefs
but thread-local.
That is one of many possible solution spaces
Considering we're already supporting code that has invalid keywords for the indefinite future, we might consider relaxing the constraints of what symbols are allowed, which would be backwards compatible
Then maybe a compiler flag to warn, and/or assert in dev builds when you use illegal chars. Although i'm sure this topic has been talked about ad nauseam already .
I'm definitely guilty of not using the strictly valid keywords, even with full consciousness of it 😕 E.g. reading in weird JSON at system boundary, and keywordizing