User Tools

Site Tools


Sidebar

Jump to
AmbientTalk
CRIME
iScheme

at:tutorial:symbiosis

This is an old revision of the document!


This Tutorial is still under heavy construction

Symbiosis with Java

AmbientTalk is fully implemented in Java and runs on top of the JVM. Java provides an extensive class library that can be accessed from within AmbientTalk. In other words, Java classes can be instantiated and messages can be sent to Java objects from within AmbientTalk.

The reverse, namely that AmbientTalk objects can accessed from within Java is also possible. AmbientTalk objects are reified at the Java level such that the Java language can be used to send messages and create new objects.

This chapter explains how both sides of this symbiotic relationship between Java and AmbientTalk can be leveraged. The goal of this symbiotic relationship is to complement the advantages of both languages and to alleviate their disadvantages. For example, AmbientTalk can use the extensive class library from Java and Java can benefit from AmbientTalk's superior concurrency abstractions.

Symbiosis Architecture

AmbientTalk has been implemented in Java. Because of this, Java plays two roles: it is both a symbiont language and the implementation language of AmbientTalk (and hence of the linguistic symbiosis itself). The figure below illustrates the different objects that play a part in the AmbientTalk/Java symbiosis, according to the implementation model of Inter-language reflection. AmbientTalk objects are physically implemented as Java objects. This is illustrated by means of the “represents” relationship. To enable symbiosis, additional objects are required which denote the appearance of objects from one language in the other language. At the implementation level, such appearances are implemented as wrapper objects, which wrap an object from a different language and which perform the protocol mapping which translates between the semantics of the symbiont languages.

Symbiotic representation of AmbientTalk and Java Objects

Accessing Java from within AmbientTalk

Accessing Java classes

The complete set of classes that are available in the class path of a running JVM are accessible from AmbientTalk through the jlobby object. For example, referencing the Java Vector class from within AmbientTalk can be accessed with:

>def Vector := jlobby.java.util.Vector
>><java:class java.util.Vector>

Creating Java objects

Java classes can be instantiated in AmbientTalk similar to how AmbientTalk objects are instantiated, i.e. by sending new to the wrapper for the class, which returns a wrapped instance of the Java class. Arguments to new are passed as arguments to the Java constructor. For example, in the snippet code below new method is invoked on the class Vector.

>def aVector := Vector.new()
>><java:[]>

All constructors defined in the corresponding Java class can be accessed too. For example, the Vector class also has a constructor that takes an initial capacity as its argument. This constructor can be called using an integer as the argument of new.

>aVector := Vector.new(30)
>><java:[]>

Invoking methods on Java objects

Java objects appear as AmbientTalk objects whose field and method slots correspond to public instance-level fields and methods in the Java object. These are accessed or invoked as if they were plain AmbientTalk slots. In the example, this means that all public methods and fields of the Vector class are accessible from within AmbientTalk. Hence, to add elements to the vector we can simply invoke the add method on the AmbientTalk wrapper object.

>1.to: 10 do: { |i| aVector.add(i) }
>>nil
>aVector
>><java:[1, 2, 3, 4, 5, 6, 7, 8, 9]>

The AmbientTalk/Java symbiosis treats message sends from AmbientTalk to Java as follows: if a message is sent to a class wrapper, only static fields or methods of the Java class are considered. If the message is sent to an instance wrapper, only non-static fields or methods of the Java class of the wrapped object are considered. If the AmbientTalk selector uniquely identifies a method (i.e. no overloading on the method name is performed in Java), the matching method is invoked. All AmbientTalk arguments are converted to Java objects. This is done by wrapping them into Java objects in the case of custom objects or by converting them to native Java values if possible (e.g. for the different number types and strings). The Java return value is mapped back to an AmbientTalk value.

Overloading

In Java methods can be overloaded based on the number of arguments and the types of the arguments. Invoking an overloaded method from within AmbientTalk requires special consideration. If the Java method is overloaded based on arity (i.e. each overloaded method takes a different number of arguments), the number of arguments in the AmbientTalk invocation can be used to identify a unique Java method. Hence, overloading based on arity does not require special attention. If the Java method is overloaded based solely on argument types, the interpreter may derive that the actual arguments can only be converted from AmbientTalk to the appropriate Java types for one of the matching overloaded signatures. Again, if only one match remains, the unique match is invoked. In the remaining case in which the actual AmbientTalk arguments satisfy more than one overloaded method signature, the symbiotic invocation fails. It is then the AmbientTalk programmer's responsibility to provide explicit type information in the method invocation.

Selection of the correct overloaded method is done using the cast method. In the example below the expression aVector.remove returns a closure for the Java method remove. This closure understands the cast method which takes a variable argument list. The arguments supplied to this method are the types of the method that needs to be selected. In the example below the method remove, which is overloaded with the primitive type int and the type Object, are first selected and then invoked with the argument 0 and the argument 3. In the former case the first element in the list will be removed. In the latter case the object 3 is removed from the vector.

>aVector.remove.cast(jlobby.java.lang.Integer)(0)
>>
>aVector
>>
>aVector.remove.cast(jlobby.java.lang.Object)(3)
>>true
>aVector
>>

Accessing AmbientTalk from within Java

Invoking AmbientTalk methods in Java

Besides calling Java methods from within AmbientTalk it is also possible to call AmbientTalk methods from within Java. To illustrate this consider the code snippet shown below. The SymbiosisDemo class is loaded and an instance is assigned to javaDemo variable. The method run is invoked on this object and an AmbientTalk object atObject is passed as its argument.

def SymbiosisDemo := jlobby.at.tutorial.SymbiosisDemo;

def showSymbiosis() {
	def javaDemo := SymbiosisDemo.new();
	
	def atObject := object: {
		def ping() { 
          system.println("ping!"); 
          javaDemo.run2(self); 
        };
		def pong() { 
          system.println("pong!"); 
          42 
        }
	};
	
	javaDemo.run(atObject);
};

self

When an AmbientTalk object is passed as an argument to a Java method expecting an object of an interface type, the AmbientTalk object will appear to Java objects as a regular Java object implementing that interface. In the example the Java interface PingPong contains the two methods ping and pong that were defined in atObject. This interface is also the type of the Java method run. Hence, messages sent to this wrapped AmbientTalk object appear as regular Java method invocations on an interface type. Also, note the return type of the methods ping and pong: since the AmbientTalk implementation of pong returns an integer, which is also the return value of the method ping.

package at.tutorial;

public class SymbiosisDemo {
	public interface PingPong {
		public int ping();
		public int pong();
	}
	
	public int run(PingPong pp) {
		return pp.ping();
	}

	public int run2(PingPong pp) {
		return pp.pong();
	}
	
}

If Java invokes a method declared in an interface with an overloaded method signature, all overloaded invocations are transformed into the same method invocation on the AmbientTalk object. In other words, the AmbientTalk object does not take the types into consideration. However, if the Java method is overloaded based on arity, the AmbientTalk programmer can take this into account in the parameter list of the corresponding AmbientTalk method, by means of a variable-argument list or optional parameters. Otherwise, the Java invocation may fail because of an arity mismatch.

at/tutorial/symbiosis.1183583106.txt.gz · Last modified: 2007/07/05 09:34 (external edit)