This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-02-20
Channels
- # announcements (1)
- # beginners (65)
- # calva (16)
- # cider (44)
- # clara (16)
- # clojure (84)
- # clojure-dev (48)
- # clojure-europe (5)
- # clojure-finland (4)
- # clojure-houston (1)
- # clojure-italy (19)
- # clojure-nl (27)
- # clojure-russia (6)
- # clojure-spec (37)
- # clojure-uk (123)
- # clojured (11)
- # clojurescript (21)
- # datomic (40)
- # duct (4)
- # emacs (6)
- # figwheel (4)
- # figwheel-main (5)
- # fulcro (34)
- # jackdaw (8)
- # juxt (117)
- # kaocha (3)
- # klipse (1)
- # leiningen (33)
- # luminus (2)
- # nyc (3)
- # off-topic (29)
- # om (1)
- # pedestal (7)
- # planck (4)
- # re-frame (27)
- # reagent (8)
- # reitit (5)
- # rum (2)
- # shadow-cljs (428)
- # spacemacs (5)
- # tools-deps (15)
- # yada (6)
On a lein of 2.9.0 on Java 1.8 and a cider/nrepl of 0.21, I am unable to ctrl-D to interrupt infinite loops. Anyone else see this? It was perfectly fine until 0.20
can you open an issue with a simple repro? I understood it was supposed to be better in this release
anyone know of a way to programmatically upgrade lein that skips the confirm? i'm doing yes | lein upgrade 2.9.0
but i once made a 3GB file this way so i'd prefer a flag if it was available
Is there a way to call a static method from native binary compiled via graalvm native-image command?
Can anybody provide a little assistance please? I have this function
(defn color
[r g b]
(java.awt.Color. r g b))
that wraps the java.awt.Color constructor.
When I use the function like this (color 255 255 255)
, this (java.awt.Color. 255 255 255)
and this (java.awt.Color. 1.0 1.0 1.0)
it works, but not (color 1.0 1.0 1.0)
It throws an exception IllegalArgument ... No matching ctor found for class java.awt.Color
But when calling directly the constructor it works, any idea how to deal with it?
turn on reflection warnings and you'll see that your call inside the body of that function is reflective.
you'll need to hint either the args to the function or the args to the constructor (both are not necessary)
https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/awt/Color.html there are two constructors and clojure can't tell your intent statically
interesting. how would you make the color
function polymorphic (like the Java constructor is)?
I thought I could use the dynamism of clojure to have both constructor wrapped in the same function. And I thought I can't have multiple definition of the same arity? Like how to differentiate one constructor from the other? (appart from creating two functions)
(defn color
([r g b]
(java.awt.Color. r g b))
([rf gf bf]
(java.awt.Color. rf gf bf)))
I cant do that can I?nor
(defn color
([^long r ^long g ^long b]
(java.awt.Color. r g b))
([^double rf ^double gf ^double bf]
(java.awt.Color. rf gf bf)))
@julien.rouse no, but you can do (if (double? rf) (java.awt.Color ^double rf ^double gf ^double bf) (java.awt.Color. ^int rf ...)))
You are asking Clojure to make a decision at runtime, in any case, but it doesn't know how.
@eraserhd oh I see, doing runtime type checking to select the right constructor
Thanks, didn't thougt about that
@kwcharllie379 as long as it's not reflective, or you've configured reflection for that class, it should work.
Hey i'm back with question about wrapping the java.awt.Color constructor
(defn color
[r g b]
(cond
(instance? java.awt.color.ColorSpace r)
(let [cspace r
components g
alpha b]
(java.awt.Color. ^java.awt.color.ColorSpace cspace (float-array components) alpha))
(float? r)
(java.awt.Color. ^double r ^double g ^double b)
:default
(java.awt.Color. ^long r ^long g ^long b))
In the case with the ColorSpace parameter, I can't make it work as I believe I need to add typehint but I don't know how
I try to use it like this
(defn get-components
([^java.awt.Color color]
(vec (.getComponents color nil)))
([^java.awt.Color color comp-array]
(vec (.getComponents color (float-array comp-array))))
([^java.awt.Color color cspace comp-array]
(vec (.getComponents color cspace (float-array comp-array)))))
(def cspace (java.awt.color.ColorSpace/getInstance java.awt.color.ColorSpace/CS_sRGB))
(construct-color cspace (get-components white) 1.0)
and white
is defined as (def white java.awt.Color/white)
When I try to construt the Color, I het the error:
(construct-color cspace (get-components white) 1.0)
Execution error (IllegalArgumentException) at joy-of-clojure-exo.clj-awt.color/construct-color (color.clj:61).
No matching ctor found for class java.awt.Color
It's kind of the same error I got earlier (https://clojurians.slack.com/archives/C03S1KBA2/p1550678389005500), and the fix was to add more typehint
Here I add ^java.awt.color.ColorSpace cspace
and I thought it was enough, but apparently not, any idea?
(java.awt.Color. (float r) (float g) (float b))
should work. By default, Clojure uses Double
and Long
only (boxed) and you need float
primitives here.
my guess is you switched to calling that function color, and then didn't update the calling code to call color instead of construct-color
how sorry I renamed color to construct-color in between..
But the error still stand, but adding the suggestion of seancorfield helps!
wrapping alpha
in (float alpha)
resolve the problem
java.awt.Color
has seven constructors and three of them take three arguments so you need to provide assistance so the correct constructor is selected.
In particular (java.awt.Color. 1 1 1)
and (java.awt.Color. 1.0 1.0 1.0)
produce completely different colors (the first is very dark gray, the second is white).
yes eraserhd provided assistance with that https://clojurians.slack.com/archives/C03S1KBA2/p1550678839014300
Your Clojure code will need to distinguish between which version you actually need based on something other than just three arguments.
He told me that I could do a cond
with typecheking as predicate to differentiate the constructor, and add typehint to help the compiler
the result is as follow
(defn construct-color
"Creates either:
- (int) an opaque sRGB color with the specified combined RGB value consisting of the red component in bits 16-23,
the green component in bits 8-15, and the blue component in bits 0-7
- (int, boolean) an sRGB color with the specified combined RGBA value consisting of the alpha component in bits 24-31,
the red component in bits 16-23, the green component in bits 8-15, and the blue component in bits 0-7
- (float, float, float) an opaque sRGB color with the specified red, green, and blue values in the range (0.0 - 1.0)
- (int, int, int) an opaque sRGB color with the specified red, green, and blue values in the range (0 - 255)
- (float, float, float, float) an sRGB color with the specified red, green, blue, and alpha values in the range (0.0 - 1.0)
- (int, int, int, int) an sRGB color with the specified red, green, blue, and alpha values in the range (0 - 255)
- (ColorSpace, float[], float) a color in the specified ColorSpace with the color components specified in the float array and the specified alpha
(depending on the number of arguments and their types)."
([rgb]
(java.awt.Color. rgb))
([rgba has-alpha]
(java.awt.Color. rgba has-alpha))
([r g b]
(cond
(instance? java.awt.color.ColorSpace r)
(let [cspace r
components g
alpha b]
(java.awt.Color. ^java.awt.color.ColorSpace cspace (float-array components) (float alpha)))
(float? r)
(java.awt.Color. ^double r ^double g ^double b)
:default
(java.awt.Color. ^long r ^long g ^long b)))
([r g b a]
(if (double? r)
(java.awt.Color. ^double r ^double g ^double b ^double a)
(java.awt.Color. ^long r ^long g ^long b ^long a))))
But i need to remove ^double
and replace them with (float x)
I agree. I would use different function names to avoid the ambiguity that Java creates.
The problem you have with the above is if you accidentally call construct-color
with a mix of Long
and Double
arguments now -- you're internally dispatching on only the type of the first argument. So (construct-color 1 1.0 1)
and (construct-color 1.0 1 1)
are going to create very different colors...
@seancorfield and @ghadi so create function with differents name to call the same constructor but with different type?
(defn construct-float-color [r g b] (java.awt.Color. (float r) (float g) (float b))
and (defn construct-int-color [r g b] (java.awt.Color. (int r) (int g) (int b))
etc?
Also I have never used spec
but would it help in that case?
I would give them better names more aligned with the problem domain but, yes.
I'm not sure about the use of clojure.spec
here since I don't know much about your problem domain (it's clearly more than just writing a very thin wrapper around a Java API?).
(I would start with looking at how you need to create RGB(A) colors in whatever code you're writing and only create wrapper functions for those -- and even then it might not be worth the effort: it's idiomatic Clojure to just use Java interop directly for a lot of things)
Right now it's only wrapping java.awt, then I use it to create images, just a toy project to learn Java interop
@julien.rouse I'd probably just :import (java.awt Color)
and invoke (Color. ...)
directly as needed rather than trying to wrap it in Clojure functions. There are other things in AWT that would likely benefit from wrapper functions, and probably higher-level abstractions you could build.
Could you elaborate a bit? I'm still fairly new to both Java (and especially java.awt) and Clojure, and I'd love to learn about Java interop, and writing wrapper while also doing something that could benefits others
It's hard to be specific for this case, as I'm not familiar with AWT, but in general writing a wrapper that has close to a 1:1 mapping from Clojure functions to Java methods doesn't add much value -- it's just syntactic sugar.
A good example of a higher-level wrapper is Seesaw (a wrapper for Swing). https://gist.github.com/daveray/1441520
It tries to map Swing operations to a simple set of primitives with data describing things.
Thanks I'll take a look at that, thanks very much!
How do I use the clojure slim jar in a project? what should my coordinate look like?
org.clojure/clojure$slim
in deps
Requiring a namespace which transitively loads a lot of things is causing it, but I can't see any code in my whole jar which calls underive
or global-hierarchy
different classloader?
it's the same repl, so unless my clojure is changing inside the repl, I don't think so
just telling you one way that could happen...
the global-hierarchy is a var - you could attach a watcher to it
I think I have managed to manually whittle it down, with a little luck, the problem was high in the list.
are you seeing something weird inside a go block?
did you have your watcher dump its stack when it goes clear?
I think the watchers are fired in same thread doing the alter
Oh really? I didn't know that, I'll print the stack. I don't think it's inside a go block, just that requiring manifold.stream in my repl causes the global hierarchy to reset