Comments (12)
Right, @phase - as long as EO will let you implement any Java interface out of the box - even if it say has more than 4 methods (that check would be done on the EO type
declaration, not implementing it from object
) - then the EO object can be sent straight back to Java callbacks. Easy peasy!
Q: Would the interface need to be EO clean, e.g. not declare any parameter types that are not interfaces?
But some cases in Java (e.g. in Swing I think?) you have to subclass an abstract class and send that back after filling in the abstract
methods -- those would be inaccessible from EO as you can't subclass (only subtype). Perhaps we would need to again have a 'virtual' EO type for the missing abstract methods, and another type for the methods that already exist in the abstract class (as you may have to call them from your implementation!).
Thus you would then have to do it as an EO bridge instead. Let's say we have this bad guy in Java (slightly modified, the truth is worse):
public abstract class JComponent {
public Dimension getDimension();
abstract public void paint(Graphics g);
}
Now obviously to implement paint()
you need to know your Dimension
so you don't paint outside where you should be - in a way a JComponentImpl object needs to call the "super" JComponent object.
(Let's forget for now possibility of overriding getDimension()
- although some Java patterns also have such "no-op" pretend-abstract void methods that needs to be overriden, e.g. in a file tree walker)
In EO we can then have two types. Let's assume Dimension
and Graphics
are already EO types - mapping all of swing to be EO clean would be a big job!
type ComponentDimension:
Dimension getDimension()
type ComponentPainting:
Graphics paint(Graphics g)
We can then "instantiate" the abstract class (!) JComponent
from the JVM:
object jcomponent javaObject(JComponent.class,ComponentPainting.class, ComponentDimension.class)
as ComponentPainting, ComponentDimension
Here javaObject
would return an object that implement ComponentPainting and ComponentDimension in EO land, and have ComponentPainting @super
which is not yet initialized, as well as a ComponentDimension @impl
. The generated proxy methods will call @impl
if covered by that interface, otherwise @super
.
The returned ComponentDimension
is then the argument to our jComponent
constructor call.
(Calling any method on it now would throw IllegalStateException
).
object fancyPaint(jcomponent)
as ComponentPainting, ComponentDimension:
ctor(ComponentDimension dimension):
@dimension = dimension(fancyPaint);
Graphics paint(Graphics g):
g.draw(@dimension.x, @dimension.y, 1);
Note when assigning @dimension
in its ctor
we actually copy the dimension
to provide ourself (Q: Can we access fancyPaint
here, or do we need this
keyword?) .
This allows the jcomponent copy to populate its @super
with a generated subclass of JComponent
that calls the @impl
methods and complete the wire-up. (It can then call the JVM-side JComponent
constructor which for all we know may want to call .paint()
right away).
So in a way there would then be two bridges - one from JVM jcomponent
to fancyPaint
, and another from fancyPaint
to jcomponent
- which together work like an unwrapped abstract class hierarchy.
Not sure if this would require cyclic references.. see #4.
from eo.
I would say we should focus first on how to access JVM objects client-wise from EO - as to provide EO objects to JVM (e.g. to register a handler) probably means we need to have a better idea about introspection and type generation in EO first.
Perhaps any object that is from non-EO-land needs to be declared with an interop
keyword/type, so that the compiler can flag it and ensure that null
etc. don't leak out. It's also a big warning to developers as it means "Warning: EO rules no longer apply".
Should it be possible to use such interop
types (e.g. java.util.UUID
) directly in a EO type declaration (e.g. as a return type), or can they only be used from inside an object with EO wrappers both ways?
It might be beneficial to define an EO type from exactly what we expect to expose from the Java object, as it probably don't play well along with the EO rules. The compiler could then for instance wrap the JVM object through an encapsulating EO object that implement said type(s) and ensure EO-ness (e.g. avoid null
returns).
This may require retro-fitting interfaces to non-interface JVM return types - could get messy?
A simpler approach is like how Clojure does interop with direct access through a special syntax/method. You could argue this makes it too easy to cheat, particularly if those also work on EO objects.
I think for static methods in JVM classes we can just expose them as an object of the class itself - in a way there's a separate interface for the static methods. (In Java you can't declare an interface for static methods)
from eo.
provide EO objects to JVM (e.g. to register a handler)
If EOs compile to JVM classes, then there's no handler to register. Java can just call it.
It might be beneficial to define an EO type from exactly what we expect to expose from the Java object, as it probably don't play well along with the EO rules.
What kind of type are you talking about? An interface for the JVM class to implement?
The compiler could then for instance wrap the JVM object through an encapsulating EO object that implement said type(s) and ensure EO-ness (e.g. avoid null returns).
If EOs only call EOs, all of which can't have null, then we're good. If a call to a JVM method returns null, we can wrap it with a check and throw a runtime exception.
// outside class
public class JavaTest {
public String test() {
return null;
}
}
// EO code calling JVM method (not EO syntax obviously)
let javaTest = JavaTest()
let x = javaTest.test()
// statements above compile to JVM bytecode equivalent to the following
JavaTest javaTest = new JavaTest();
String x = javaTest.test();
if (x == null) {
throw new NullPointerException("JVM method returned null");
}
from eo.
@g4s8 definitely a good question, thanks! I like what @phase is offering -- runtime exceptions if Java code violates our rules, e.g. returns NULL. I think that in this EO-to-Java integration we will do something similar to what Java has for integration with C: JNI.
from eo.
JNI is overly complicated, and nowadays people use JNA for accessing native code. But we don't need anything like this if EO is running on the JVM. If EOs compile to JVM classes, there's no boilerplate needed.
from eo.
@phase well, how we will call StringUtils.join()
(static method from utility class) from EO?
from eo.
I think that if we consider the class StringUtils
with its static methods as an object itself, it clearly violates EO rules as the exposed public methods are not declared in a corresponding interface.
So EOLang should be unhappy about any EO code trying to call such methods directly -- "unshielded" so to speak. We'll have to retrofit an interface, but only for the things we need. This can then be subjected to the usual EO rules -- it would also be beneficial when upgrading that Java library.
Let's assume you are trying to write an object implementing JoinedString
but you need to access org.apache.commons.lang3.StringUtils
:
/** A non-empty string that separates items in a JoinedString
typically 1 character long */
type Separator extends String
/** A string joined using a separator */
type JoinedString extends String
Separator separator()
/** Partial EO exposure of org.apache.commons.lang3.StringUtils -
for clarity we'll call it EOStringUtils rather than StringUtils
*/
type EOStringUtils
/** This signature must be subclass-like compatible with the Java signature */
String join(Separator sep, String a, String b)
/** Create stringUtils using javaObject() wrapper that
match methods with type, adds null checks etc.
*/
object stringUtils javaObject(org.apache.commons.lang3.StringUtils.class,
EOStringUtils.class) as EOStringUtils
/** Now we can use the stringUtils object
when implementing JoinedString
*/
object joinedString as JoinedString:
Separator @separator
String @joined
ctor(Separator sep, String a, String b):
@separator = sep
// Call the now null-safe and mapped EO object stringUtils
@joined = stringUtils.join(sep, a, b)
// Proxy the @joined methods from the String type:
int length(): @joined.length()
bytes bytes(Charset charset): @joined.bytes(charset)
// ...
If javaObject
is not to be a special form/keyword in the language (just have a non-EO implementation), then EO would definitely need generics so it can receive the correct types.
If javaObject
(jvmObject
?) it is a keyword you can simplify the call, e.g. no need to provide EOStringUtils.class
javaObject()
could work the same for existing JVM objects or classes, but for the class it would access the static methods rather than the methods of java.lang.Class
.
from eo.
Q: If a Java object has more than 4 methods from a single JVM class/interface - would you then need to have multiple such interface-wrappings of the same object, or should javaObject()
allow multiple interfaces to implement?
from eo.
If the Java object already implements a JVM interface that EO is happy to use directly, then no type
declaration would be needed, just wrapping it with javaObject()
to say which interfaces you want.
from eo.
@yegor256 I propose closing this issue since it is unmanageable because of its wide objective. We'd better decompose the
Java<--->EO
interoperability bridge later.
At the moment, the issue is out of the scope of the project. But sooner or later, it will be inside the scope and deep decomposition would be needed.
Also, I propose tagging this issue with a special tag java-eo-interop
for future reference. The ideas here are great, so a tag for future reference would be useful.
from eo.
@nlchar I agree, let's close and deal with this problem in smaller steps
from eo.
Job gh:cqfn/eo#52
is not assigned, can't get performer
from eo.
Related Issues (20)
- Make XSD as powerful and as restrictive as possible HOT 1
- `PullMojo` and `ResolveMojo` are not proxy-aware HOT 1
- Move `eo-sys` to `eo-runtime` HOT 3
- File name too long HOT 4
- pom.xml:340-343: Enable PMD check for... HOT 2
- BytesOf.java:34-38: This class requires refactoring. As a... HOT 4
- Data.java:196-199: This method should be refactored... HOT 2
- Can we use some static analysis like Sonar in CI on PR? HOT 1
- Failed build: daily HOT 10
- Add `+rt node` meta to work with js compiler HOT 1
- merge smaller libs into this repo HOT 7
- Printing PHI Expressions Extremely Slow HOT 4
- list.eo:208-211: The object does not work. After moving... HOT 2
- PhPackage need update HOT 2
- BytesRaw.java:33-36: Method {@link BytesOf#shift} should... HOT 2
- align-test-classes.xsl:27-28: Add link to corresponding... HOT 2
- remove-high-level-inner-classes.xsl:27-28: Create... HOT 14
- map.eo:105-112: Find a way to link hash code and index of... HOT 2
- text.eo:313-315: Implement text.replaced object. This... HOT 3
- Replace `int` and `float` with `number` HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from eo.