help-jel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Array casts


From: Mark Taylor
Subject: Re: Array casts
Date: Thu, 22 Apr 2021 14:43:31 +0100 (BST)
User-agent: Alpine 2.21 (DEB 202 2017-01-01)

Konstantin,

thank you for the quick response.  If it's a feature that's deliberately
excluded, that's fair enough, but I was wondering if it was an oversight.

I have written an explanation of why I'd like to be able to do this
in a bid to persuade you it's a useful feature to have.
However, having got to the end of the explanation, I hit a reason
that makes me realise it's probably not worth it after all;
so I don't even agree with myself.

Since I got as far as writing it down, I attach the explanation below,
and if you've got any comments they are welcome.  But if you have
better things to do with your time than read it, that's fine!

Thanks again.

Mark

---------------------------8<---------------------------------

I'll explain why I'd like to be able to do this, and you can consider
whether you think it's a good enough reason to introduce it (or advise
how I can solve this some other way); of course I don't insist.

I have implemented some functions that allow users to modify
every element of a supplied array using a JEL mapping expression
(this is using JEL within JEL).  The functions are invoked within
a JEL expression like this:

   doubleArrayFunc("x*0.5", inArray)

If the value of the inArray variable is an int[] array {1,2,3},
then the output is the double[] array {0.5, 1.0, 1.5}.
Users can then manipulate the result as a double[] array,
e.g. to write JEL expressions like:

   doubleArrayFunc("x*0.5", inArray)[2]

It's implemented something like this:

   public static double[] doubleArrayFunc(String expr, Object inArray) {
       return arrayFunc(expr, inArray, double[].class);
   }

   private static <I,O> O arrayFunc(String expr, I inArray, Class<O> outClazz) {
       @SuppressWarnings("unchecked")
       Class<I> inClazz = (Class<I>) inArray.getClass();
       JELArrayFunction<I,O> afunc =
           new JELArrayFunction("x", expr, inClazz, outClazz);
       return afunc.evaluate(inArray);
   }

   public static class JELArrayFunction<I,O> {
       public JELArrayFunction( String xvarName, String fexpr,
                                Class<I> inClazz, Class<O> outClazz )
               throws CompilationException {
           ...
       }
       public O evaluate( I inArray ) {
           ...
       }
   }

The compile-time type of the doubleArrayFunc function is double[]
as declared.  I also have an intArrayFunc function with a declared
return type of int[].  I'd like to avoid writing (and documenting)
functions byteArrayFunc, shortArrayFunc, longArrayFunc, floatArrayFunc,
booleanArrayFunc, stringArrayFunc etc.

If casting to array was permitted, then I could introduce a new static
method with:

   public static Object untypedArrayFunc(String expr, Object inArray) {
       return arrayFunc(expr, inArray, Object.class);
   }

This has a runtime return type (an array type) determined by the
compilation type of the input expr, but a compile-type type of Object.
Users could then write e.g.:

   (long[]) untypedArrayFunc("toLong(x)", inArray)

(given that the toLong function returns a long) to get an array
that they can otherwise manipulate.  As it stands,
although they could write 'untypedArrayFunc("toLong(x)", inArray)'
and get a long[] array as the runtime result, there's no way(?) they
can use it as an array within JEL, since the compile-time
type of the result is Object.

Writing 'arrayFunc("toLong(x)", inArray, long[].class)' looks
at first like it ought to work, but it doesn't because the type
assignment is done by generics magic at application compile time,
and erased back to plain Object by the time JEL sees it
(also no class literals in JEL I think?).

Having got this far, I realise that as well as casting to e.g.
(long[]), I'm probably going to want to cast to (String[]) as well,
which introduces another category of cast types not currently
present in JEL.  So, this may be getting out of hand and probably
I'm better off writing explicit cast functions:

   public static int[] toIntArray(Object arr) {
       return (int[]) arr;
   }
   public static String[] toStringArray(Object arr) {
       return (String[]) arr;
   }

etc.  It's not so bad.

On Thu, 22 Apr 2021, Konstantin L. Metlov wrote:

> Dear Mark,
> 
> Yes, JEL does not support explicit casting to array types.
> 
> In principle this can be implemented on top of JEL (as any other features
> of Java programming language). But my original idea was that JEL is a
> small embeddable compiler, supporting some minimal (yet complete) subset
> of Java while avoiding the features, which are not absolutely necessary.
> 
> In my experience explicit casts can be completely avoided in JEL by
> employing polymorphism in the static and dynamic library functions. This
> will also allow the JEL compiler to detect more type mismatch errors at
> compile time. In the worst case, if they can not be avoided, it is
> possible to implement cast as a function.
> 
> Are you sure the explicit array casts are indeed absolutely necessary ?
> 
> With the best regards,
>                           Konstantin.
> 
> > Dear Konstantin,
> >
> > me again.  It seems like it's not possible to cast to array types
> > in JEL expressions; see the following code:
> >
> >     import gnu.jel.CompilationException;
> >     import gnu.jel.Evaluator;
> >     import gnu.jel.Library;
> >
> >     public class Cast {
> >         public static void main( String[] args ) throws
> > CompilationException {
> >             Library lib = new Library(new Class[] {Cast.CLib.class},
> >                                       null, null, null, null);
> >             Evaluator.compile("iValue(3)", lib, null);
> >             Evaluator.compile("(double) iValue(3)", lib, null);
> >             Evaluator.compile("dArray(3)", lib, null);
> >             Evaluator.compile("(double[]) dArray(3)", lib, null); // error
> > here
> >         }
> >
> >         public static class CLib {
> >             public static int iValue(int i) {
> >                 return i;
> >             }
> >             public static Object dArray(int n) {
> >                 return new double[n];
> >             }
> >         }
> >     }
> >
> > which gives me (JEL 2.1.2):
> >
> >     gnu.jel.CompilationException: Encountered unexpected character ']'
> >
> > Is there some good reason for this?  Could it be fixed so that
> > array casts are possible?
> >
> > Many thanks,
> >
> > Mark
> >
> > --
> > Mark Taylor  Astronomical Programmer  Physics, Bristol University, UK
> > m.b.taylor@bristol.ac.uk          http://www.star.bristol.ac.uk/~mbt/
> >
> >
> 
> 
> 
> 

--
Mark Taylor  Astronomical Programmer  Physics, Bristol University, UK
m.b.taylor@bristol.ac.uk          http://www.star.bristol.ac.uk/~mbt/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]