Coder Social home page Coder Social logo

Java libraries about eo HOT 12 CLOSED

objectionary avatar objectionary commented on August 21, 2024
Java libraries

from eo.

Comments (12)

stain avatar stain commented on August 21, 2024 2

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.

stain avatar stain commented on August 21, 2024

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.

phase avatar phase commented on August 21, 2024

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.

yegor256 avatar yegor256 commented on August 21, 2024

@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.

phase avatar phase commented on August 21, 2024

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.

yegor256 avatar yegor256 commented on August 21, 2024

@phase well, how we will call StringUtils.join() (static method from utility class) from EO?

from eo.

stain avatar stain commented on August 21, 2024

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.

stain avatar stain commented on August 21, 2024

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.

stain avatar stain commented on August 21, 2024

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.

nlchar avatar nlchar commented on August 21, 2024

@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.

yegor256 avatar yegor256 commented on August 21, 2024

@nlchar I agree, let's close and deal with this problem in smaller steps

from eo.

0crat avatar 0crat commented on August 21, 2024

Job gh:cqfn/eo#52 is not assigned, can't get performer

from eo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.