Parameter types

Currently the parameter types for Simplexx methods can be of java primitive data types. Is it possible to update and use their equivalent wrapper classes? If :+1:, what classes need to be touched?

What would be the use case here? If you use the primitive types in the signature and pass a boxed value, the Java compiler should automatically unbox it before the call. This seems like it would add complexity without really gaining anything. Is there an example you have where it isn’t working as expected?

@ewpatton Let's say you have below. This will be caught as error in ComponentProcessor because its matching. Some users, when creating extensions, just use Boolean instead of boolean; hence causing the compile time issue

@SimpleFunction
public YailList RemoveDuplicates(Boolean enabled)

I’d still recommend that they use the primitive types. But if you really want to submit a patch for it, you’d have to modify ComponentProcessor#javaTypeToYailType(String) to map the box classes.

I did, but that doesn’t completely solve the issue.

If we add condition to check for java.lang.Boolean, should the return be boolean? If yes, .aix gets created successfully (no compile error), but then there would be runtime error. If you like, I can reproduce the error and post screenshot

If you like, I can reproduce the error and post screenshot

Yes, please. I made a test extension and was able to get it to run in the companion. All the method does is return a YailList containing the flag passed in via the parameter.

blocks(7)

  @SimpleFunction
  public YailList RemoveDuplicates(Boolean enabled) {
    return YailList.makeList(new Object[] { enabled });
  }
1 Like

huh :thinking: ? I trimmed down to a very simple extension and it actually worked! Maybe some kinda caching issues.
Let me give it more tries.
image

Also, wouldn't this be helpful for extension developers?

In practice, yes, but it also carries some potential risks because boxed types are much less memory efficient than their primitive peers because they need 16 bytes for the value on the heap (ref) and 4 bytes for each reference because boxed values are stored on the heap rather than the stack and the VM needs to keep a pointer on the stack to the value on the heap [1]. If they are used everywhere, then that's going to be a significant memory burden on devices not necessarily equipped with a lot of RAM. If they're using boxed values someplace like this I expect they may be used elsewhere in the code as well when a primitive type would do.

[1] Technically, boolean doesn't suffer this because there is an optimization done where there are only two Boolean objects TRUE and FALSE created on the heap and then you only need the 4 bytes of reference pointing to the shared 16-byte values. However, 4 bytes is still 4 times the space needed for a single boolean (1 byte). Boolean arrays also cause additional overhead because primitive boolean can be packed into 8 values per byte so are stored more efficiently whereas a Boolean array needs 4 bytes per Boolean rather than .125 bytes per boolean.

1 Like

Very good points Evan.
Given your points, maybe tailor the error message to be more descriptive and mention that need to use equivalent primitive type instead of:

Cannot convert Java type xxx to Yail type

FYI

2 Likes

Thanks Evan. I was doing exact same updates :slight_smile: THANKS

if (mapBoxedTypes.containsKey(type)) {
throw new RuntimeException(
String.format("Please use primitive data type of '%s' instead of '%s'", mapBoxedTypes.get(type), type));
}