JCOERCE vs JCAST (was Re: coerce a number to a short)
Mark Evenson
evenson at panix.com
Tue Feb 11 17:21:29 UTC 2020
> On Feb 10, 2020, at 02:56, somewhat-functional-programmer <somewhat-functional-programmer at protonmail.com> wrote:
>
> Thank you for reviewing the patch.
[…]
> So read on, with our common understanding that I have no objection at all to the
> reversal of the patch :-)…
Cool.
> I like and also thought about looking at the argument values dynamically to help
> determine a proper call site. It certainly makes sense, especially for literal
> values, to not require extra coercion or annotation, to find the proper call
> sites. However, here are a couple of inconsistencies that arise from the current
> implementation (git master branch 702405fe97a1778f5d3683a6a9cc4294071061e6):
>
> ;; the following signals the "no such method" error,
> ;; consistent with my understanding of the intent of the new patch
> (jstatic "reverseBytes" "java.lang.Short" 6300000)
>
> ;; however, this version does not throw and error, and silently narrows
> ;; 63000 the value to a short
> (let ((method
> (jmethod "java.lang.Short" "reverseBytes" "short")))
> (jstatic method nil 6300000)
Confirmed. Mea Maximus Stupidius Culpa in my patch: I didn’t think about/test an explicitly supplied JMETHOD instance.
>
> ;; this version has a different error, IllegalArgumentException
> ;; as the runtime won't automatically convert 32.3 to a short
> (let ((method
> (jmethod "java.lang.Short" "reverseBytes" "short")))
> (jstatic method nil 32.3))
Yes, this should probably be caught in the find call site machinery,
transformed into a Lisp side TYPE_ERROR.
>
> ;; this gives the more familiar no such method error
> (jstatic "reverseBytes" "java.lang.Short" 32.3)
>
> One annoying thing about Java is the "byte" type is signed -- so these value
> checks will still potentially cause trouble for methods taking a "byte”.
[…]
> That brings me to my last question -- What is (java:jcoerce) supposed to do?
>
> I had incorrectly assumed it was much like a Java cast -- in Java one can cast
> from any primitive type to any other primitive type (with the exception of
> boolean). One can also cast within the inheritance hierarchy for references etc.
>
> The docstring for jcoerce says:
> Attempts to coerce OBJECT into a JavaObject of class INTENDED-CLASS.
> Raises a TYPE-ERROR if no conversion is possible.
Tentatively, I would suggest that JCOERCE tries as hard as possible to DWIM,
signalling a TYPE-ERROR (or possibly a subclass) if any coercian would lose
information. Then, JCOERCE is defined as a transformation to values whose
inverse round-trips. As such, we would extend JCOERCE to cover as many types
as possible under this definition, bringing in all Java primtitive types
(float, double, char are what we need I think). For completeness, we should
cover all descendents of java.lang.Number. But *not* try to cover
java.lang.Character. My thinking here is that “char” has a meaning as an
unsigned two bytes value, but not allow coercian of java.lang.Character values
as it can potentially wrap both int and char. I could be talked out of the
last point if someone can defend the interpolation of such values, but I think
users would be too confused.
I agree that we should add a JCAST that potentially strips information according to
the JLS widening and narrowing rules for all its floating port horrors.
>
> Here are some examples of the inconsistencies:
[…]
Studying and incorporating it into tests. Thanks for bagging parts of the shaggy monster…
—
Currently, I am for fixing JCOERCE for abcl-1.6.1, and pushing JCAST off to
either abcl-1.7 or abcl-2.0, whichever I branch first.
yers in CONS,
Mark
--
"A screaming comes across the sky. It has happened before but there is nothing
to compare to it now."
More information about the armedbear-devel
mailing list