Closed lilumat closed 2 years ago
Hi @lilumat. Smalltalk was ahead of its time :)
Looks like what you want is some type of auto-coercion. Although manifold could support this, I tend to stay clear of auto-coercion due to its history of producing unintended results.
One feature manifold offers that may be of use, however, is structural typing. If VarcharSql were a structural interface, you could implement it with String using extension methods and extension interfaces. As such, the example code you have above would work as-is.
Merry Christmas to you too!
Hi, @rsmckinney , I made some tests but it seems that I'am a beginner with Manifold libraries :) It is simple and complex at the same time, the force of this tool !
In my future transpiler "Forms/PL-SQL to Java", all basic types will SqlNumber, SqlVarchar, ... in declaration and used for emulate the native behavior. So I tested this with compile error / runtime error ...
Test for SqlNumber
@Structural public interface SqlNumber {}
@Extension
public abstract class BigDecimalExt implements SqlNumber {
public static BigDecimal plus(@This BigDecimal thiz, BigDecimal operand) {
return thiz.add(operand) ;
}
}
@Test SqlNumber val1 = (SqlNumber) new BigDecimal(19); // the cast not necessary but without there is a warning on interface SqlNumber under IntelliJ "related problem" SqlNumber val2 = (SqlNumber) new BigDecimal(77); SqlNumber vador = val1 + val2 ; // <======= compile error
If I had below in SqlNumber interface : SqlNumber plus(SqlNumber val) ;
Compile ok but error at runtime : java: java.math.BigDecimal is not abstract and does not override abstract method plus(com.airforms.runtime.core.types.SqlNumber) in com.airforms.runtime.core.types.SqlNumber
I will beleive that SqlNumber is like BigDecimal for compiler ...
Test for SqlVarchar
@Structural public interface SqlVarchar { void sayHello(); }
@Extension public abstract class StringExt implements SqlVarchar { public static void sayHello(@This String thiz) { System.out.println("hello world!"); } }
@Test SqlVarchar var1 = "Manifold"; var1.sayHello(); // Error at runtime : java.lang.RuntimeException: Receiver type 'java.lang.String' does not implement a method structurally compatible with method: public abstract void com.airforms.runtime.core.types.SqlVarchar.sayHello()
I will beleive that SqlVarchar is like String for compiler ...
What I don't understand ? Maybe simply, my need is not in the scope
Regards, Thanks to read me
Hi @lilumat. Your use-case has exposed an issue dealing with the trifecta of overloaded operators, extension methods, and structural typing. I have the issue fixed locally and will have a new release ready tomorrow. I also have a better solution for you involving a custom proxy. I'll update this issue with that info after the release. Thanks for reporting this!
Hi @rsmckinney , Very good. I wait next release and your comments. Regards
Note, #333 and #334 address this issue.
Hi @lilumat. A new manifold release (2021.1.36) is out with fixes for this issue. A new manifold plugin release is also available (2021.x.40 & 2020.3.49) sometime Wednesday when JetBrains processes it for their Marketplace.
Note, you must provide an IProxyFactory
service implementation when working with a structural interface that is implemented with extension methods, as with your example above. A later release will generate such proxies automatically, but for now they must be provided explicitly. Here is a zip file containing your project using the latest release: Issue332.zip.
Please let me know if you have questions. And thanks for reporting this!
Feature #337 provides the auto-generated proxy factory, which completes the changes for this issue
Hi, To begin, what a very good job, overloading operators and extension method, !!! It reminds me of my past development with the best langage : Smalltalk ;)
Can you think it's possible to create your own autoboxing ? I work on an emulator of Oracle Forms and I would you like write this in Java :
VarcharSql value = "MANIFOLD";
orpublic VarcharSql killCovid() { return "SUCCESS"; }
where VarcharSql is my java class that used overloading operators and implements the behavior of Varchar2
Regards & Merry XMas