|
|
# Log of most important changes between subsequent AmbientTalk releases
|
|
|
|
|
|
## development (trunk)
|
|
|
|
|
|
|
|
|
## build130418 (v. 2.23)
|
|
|
- In this distribution iat script forces java to use ipv4 so that VM discovery works. This is a temporary solution until distribution layer is updated to use ipv6.
|
|
|
- Fixing error on networking layer raising an exception in Mac because sockets were being created until the maximum limit of files was reached.
|
|
|
- Modification on the runm2mpdaemon to make sure ipv4 configuration is used.
|
|
|
- By popular request, the `to:do:` method defined on AmbientTalk numbers got modified in a backwards-incompatible way. Previously,
|
|
|
|
|
|
```
|
|
|
1.to: 5 do: { | i | system.println(i) }
|
|
|
```
|
|
|
|
|
|
would print the numbers `1,2,3,4`
|
|
|
In other words, the upper bound was **exclusive**
|
|
|
|
|
|
It was pointed out that this is inconsistent with the array indexing conventions used in AmbientTalk, which indexes arrays (called "tables") from 1 up to table.length (i.e. we use 1-indexed, not 0-indexed arrays).
|
|
|
|
|
|
As such, when using to:do: to iterate over or to initialize a table, one had to use the following pattern:
|
|
|
|
|
|
```
|
|
|
def table[{ nil }
|
|
|
1.to: table.length + 1 do: { | i | table[i](5]) := i * i }
|
|
|
```
|
|
|
|
|
|
Notice the `+ 1` increment on the upper bound.
|
|
|
|
|
|
`to:do:` is now modified so that `to:do:`'s upper bound is **inclusive**, i.e.:
|
|
|
|
|
|
```
|
|
|
1.to: 5 do: { | i | system.println(i) }
|
|
|
```
|
|
|
|
|
|
will print the numbers `1,2,3,4,5`
|
|
|
|
|
|
and this range now corresponds one-to-one to our array indexing:
|
|
|
|
|
|
```
|
|
|
def table[{ nil }
|
|
|
1.to: table.length do: { | i | table[i](5]) := i * i }
|
|
|
```
|
|
|
|
|
|
Another change is that to:do: no longer automatically "counts down" when the start is bigger than the end, i.e. currently:
|
|
|
|
|
|
```
|
|
|
5.to: 1 do: { | i | system.println(i) }
|
|
|
```
|
|
|
|
|
|
will print the numbers `5,4,3,2`
|
|
|
|
|
|
This code now instead never execute its block. There is a new `downTo:do:` method that works as follows:
|
|
|
|
|
|
```
|
|
|
5.downTo: 1 do: { | i | system.println(i) }
|
|
|
```
|
|
|
|
|
|
will print the numbers `5,4,3,2,1`
|
|
|
|
|
|
Notice that the `downTo:do:` method's lower bound is inclusive, to match the behavior of the `to:do:` method.
|
|
|
|
|
|
All of the above changes also apply to `to:step:do:` and the new `downTo:step:do:` method.
|
|
|
|
|
|
## build060213 (v. 2.22)
|
|
|
|
|
|
- Fixed issue #60: AmbientTalk now errors on case mismatches between filenames and module names (/.at.Hello.woRld vs .../at/hello/world.at) (Dries)
|
|
|
- Low-level ANTLR exceptions are now reported with a filename and approximate location. (Dries)
|
|
|
- Added @Async annotation: AmbientTalk methods called from Java return immediately, if the interface method is tagged with @Async. (Dries)
|
|
|
|
|
|
## build190412 (v. 2.21)
|
|
|
|
|
|
- Allow passing AT strings to methods that accept a CharSequence. Typically used in Android widget classes, for example http://bit.ly/xwoxrZ (Dries)
|
|
|
- Fixed issue #58.
|
|
|
- Allow UTF-8 in input files and IAT. Currently only allowed in string literals. (Dries)
|
|
|
- Bugfix in the soft reset functionality. The exported objects and far references table were not cleaned when reseting an AT VM.
|
|
|
- Both the IAT and interpreter project uses now IATIO for printing error messages and AT exception stack traces. This allows that an embedded IAT in a Java project can have full control of the interpreter output. It is currently used in the embedded IAT launched when debugging an AT file in the Eclipse plugin (which redirects all the interpreter output to a dedicated Eclipse console).
|
|
|
- Enhanced REME-D's debugging functionalities:
|
|
|
- Added a stepReturn command geared towards debugging future-type asynchronous messages. It pauses the actor receiving the return value of the computation when returning from a future-type message.
|
|
|
- Re-design of the catalog of breakpoints. A breakpoint can be defined in terms of a line of code, or a condition (i.e. a predicate returning true/false). In addition, a breakpoint can be active at the actor sending a message or at the receiver actor. There are a number of predefined breakpoints currently supported in REME-D:
|
|
|
- **Message breakpoints**. A message breakpoint defines a breakpoint on a line of code of an asynchronous message send. The actor execution pauses when the message reaches the head of its mailbox, i.e. before the receiver invokes the method corresponding to the asynchronous message.
|
|
|
- **Message resolve breakpoints**. A message resolve breakpoint defines a breakpoint on a line of code of an future-type message send. The actor execution pauses when the message carrying the return value of the computation reaches the head of its mailbox, ie. after the message is processed but, before the sender receives the return value of the computation.
|
|
|
- **Method breakpoints**. A method breakpoint defines a breakpoint on a line of code of a method definition. The actor execution pauses when any asynchronous message invoking the method defined on the given line of code reaches the head of its mailbox.
|
|
|
- **Symbol breakpoints**. A symbol breakpoint defines a breakpoint on a method name corresponding to the given symbol. The actor execution pauses before the receiver invokes a method whose name is the given symbol. It has a similar effect than a method breakpoint but it denotes a conditional breakpoint rather than a line of code breakpoint.
|
|
|
|
|
|
Other breakpoints are available in `/at/support/breakpoint.at` file but they are only used by REME-D implementation (e.g. future breakpoint is used to implement a stepReturn command).
|
|
|
Note that the current version of the plugin, only allows to set in the Debug GUI message-type breakpoints, and method breakpoints. Conditional breakpoints and symbol breakpoints need to be manually installed calling the corresponding method of the debugger manager by means of the "AT Debugger Manager" console.
|
|
|
|
|
|
- A new type tag /.at.lang.types.Hashable is available. Objects tagged with this type may implement a hashCode() method to override the default Java hashCode(). This is useful for AmbientTalk objects that get inserted into Java hashtables. (Thanks to Kevin Pinte)
|
|
|
|
|
|
|
|
|
## build230112 (v. 2.20)
|
|
|
|
|
|
- New wrappers around Java collection types: see `atlib/at/collections/java` (thanks to Kevin Pinte)
|
|
|
|
|
|
## build110511 (v. 2.19.1)
|
|
|
|
|
|
- AmbientTalk now supports java 1.5 enums and static inner classes.
|
|
|
- Bugfix in `atlib/at/collections/java/vector.at`
|
|
|
|
|
|
## build220411 (v. 2.19)
|
|
|
|
|
|
- Added new native methods "toText" on numerics (numbers and fractions) to convert them to text (strings). Example: (3.14).toText() => "3.14"
|
|
|
- Added new native method "toNumber" on text, to convert characters (strings of length 1) to their numeric unicode value. Example: "A".toNumber() => 10
|
|
|
- The `cancel` method on publication and subscription objects is now an actual method, not a field bound to a closure. That means that `pub.cancel` will now trigger the method instead of returning a closure. See #49
|
|
|
- Fixed bug where aLetter.cancel() would not remove the letter from the actor's inbox.
|
|
|
- Added asCode: serialization allowing serialization of AmbientTalk object graphs to AmbientTalk source code. Example:
|
|
|
|
|
|
```
|
|
|
>def o := object: { def m() { 1 + 2 } }
|
|
|
>><obj:833460463{m}>
|
|
|
>asCode: o
|
|
|
>>"{def _v1 := object: { def m(){1.+(2)} }; _v1}()"
|
|
|
```
|
|
|
|
|
|
## build231210 (v. 2.18)
|
|
|
|
|
|
- Android-compatible release.
|
|
|
- Improved speed of regular, sequential, programs by a factor of x5-x10 by avoiding the use of Java reflection for the invocation of methods on a select number of native types.
|
|
|
- Fixes in the iat.bat windows startup script
|
|
|
- The initialization file (`init.at` by default) is no longer loaded for the discovery actor. While this could technically break existing code, since the discovery actor is not made visible and only runs code related to type tag subtests (matching required and provided type tags), this should not be a problem in practice. Future editions may even do away with the discovery actor as a real AmbientTalk actor altogether.
|
|
|
- Added `reflectOnActor().behaviour` to get access to the "behaviour" object of an actor. The oncoming AmbientTalk debugger needs this. Unless you're writing a metaprogram such as a debugger, don't use this.
|
|
|
- Added customization of the logging priorities for the interpreter execution. An -l option has been added to iat which similar to -o option, expects a list of 'loggerName=priority' pairs separated by ':' (UNIX/Mac) or ';' (Windows), where priority is one of DEBUG, WARN, INFO, ERROR, FATAL. If 'all' is used as loggerName, the given priority is used for all logs in the system. In absence of this command line parameter, the logging support is initialized with the priorities stored in the logging.props file.
|
|
|
- Far references are now kept in a thread pool per VM reducing considerably number of threads created in the vm.
|
|
|
- Includes REME-D (read as remedy), a Reflective Epidemic Message-Oriented Debugger for ambient-oriented programs. More info can be found in a dedicated tutorial page at [Debugging In Eclipse](Debugging-In-Eclipse)
|
|
|
|
|
|
## build080710 (v 2.17)
|
|
|
|
|
|
- `iat` now supports multi-line input: if the input string contains unbalanced brackets (`[braces (`{`) or parens (`(`), `iat` will output a continuation prompt (`.`) to read additional lines. Entering an empty string on a continuation line will force evaluation of the input parsed thus far.
|
|
|
- Attempting to evaluate the empty string will no longer throw a parse error, but evaluate to `nil` instead.
|
|
|
- Added a utility control structure named `whenever:discovered:within:` to `init.at` which makes it easy to put a timeout on service discovery.
|
|
|
- Added aliases `@OneWay` and `@TwoWay` for the more verbose `OneWayMessage` and `FutureMessage` type tags in `/.at.lang.futures`.
|
|
|
- Bugfix: `retract:` now works correctly when applied to a future.
|
|
|
|
|
|
## build230610 (v 2.16)
|
|
|
|
|
|
- The AmbientTalk library namespace shipped with the default distribution has been reorganized. Applications are now under `/.applications`, tests under `/.test`, demo apps under `/.demo`, bridges for external libraries under `/.bridges` and frameworks under `/.frameworks`. Only core libraries remain under `/.at`. All of these directories are added to the object path by default.
|
|
|
- Parser now recognizes keywords using inline syntax, e.g. calling `foo:bar:(x,y)` instead of `foo: x bar: y`
|
|
|
- Improved support for android. Setting the `AT_STACK_SIZE` VM property allows you to manually set the stack size of AmbientTalk event loop threads.
|
|
|
- New functionality added to `init.at`
|
|
|
|
|
|
## build160410 (v 2.15)
|
|
|
|
|
|
- Support for tracing using Causeway debugger (see [Debugging](Debugging) wiki page)
|
|
|
- Stack traces now contain source code positioning information
|
|
|
- Includes TOTAM: Ambient tuple space library
|
|
|
- Support for context-aware tuples via CRIME
|
|
|
- `iat -a` option allows you to explicitly specify the IP address with which AmbientTalk should connect to the network
|
|
|
- Improvements to the parser
|
|
|
- A couple of new demo apps in `at/demo`
|
|
|
|
|
|
## build091109 (v 2.14)
|
|
|
|
|
|
Bugs:
|
|
|
- Fixed a bug where asynchronously invoked listeners like when:disconnected: and when:reconnected: could cause an actor's code to be executed by the wrong thread. This was an extremely tricky concurrency bug. Thanks to Ben Maene for submitting a bug report that allowed me to track it down. More info about the bug can be found here: #35
|
|
|
|
|
|
For those that have their own branches of the interpreter, it is suggested you merge this bugfix with your branch as it's a pretty critical one.
|
|
|
|
|
|
- when:disconnected: and when:reconnected: listeners could be invoked multiple times (doh!)
|
|
|
- the subscription objects returned from when:disconnected: , when:reconnected: and when:expired: listeners did not properly unsubscribe their handler closure.
|
|
|
- there were some bugs in the unit tests (!). Among others in the DisconnectTest test suite. Some when:disconnected: handlers were sometimes invoked, and sometimes not at all. The problem is believed to be Garbage collection: adding when:... observers to far references does not prevent these references from becoming garbage! Hence, when the ref became garbage, the listeners would never be called and the test would fail. The bad thing about this is that it depended on GC, and was thus entirely non-deterministic.
|
|
|
|
|
|
Features:
|
|
|
- Elisa included a -nojline command line option to opt out of JLine support (mainly because JLine is not supported on mobile platforms like Android).
|
|
|
- Build 2.14 of the interpreter should now run unmodified on Google's Android platform (if iat is ran with the -nojline option).
|
|
|
- This version comes with (a preliminary version of) Urbiflock included. Visit http://soft.vub.ac.be/amop/at/urbiflock for details.
|
|
|
- Added methods `millisec`, `seconds` and `minutes` to AmbientTalk's numbers, which return `self` converted to a Java `long` in milliseconds. It is now possible to write, for example: `2.seconds` to denote the Java long 2000. This is primarily useful for passing the number to timing functions such as `when:elapsed:`.
|
|
|
|
|
|
## build080509 (v 2.13)
|
|
|
|
|
|
- Thanks to Kevin Pinte, it is now possible to disconnect far references to objects running on the same AmbientTalk VM. The call `disconnect: o` disconnects all far references to `o`. This triggers all `when:disconnected:` listeners for far references to `o` in other actors. If the given 'o' is already a far reference, the construct only disconnects this far reference.
|
|
|
|
|
|
More generally, you can reconnect the reference by doing:
|
|
|
```
|
|
|
def ref := disconnect: o;
|
|
|
ref.reconnect();
|
|
|
```
|
|
|
|
|
|
The call to `reconnect` triggers the `when:reconnected:` listeners. If the object being disconnected was also exported using `export:as:`, it will automatically be unexported. When the object is reconnected, it will automatically be exported once more (this may cause `when:discovered:` listeners to trigger again on the same object)
|
|
|
|
|
|
Far references disconnected by means of the disconnect: construct exhibit similar semantics than references disconnected as a result of a network disconnection: they buffer messages while disconnected.
|
|
|
|
|
|
Note that triggering a disconnection by means of disconnect:, should not be used in combination with network.offline() which triggers a network disconnection as both change the state of a far reference. We assume that disconnect: is used on far references within the same AmbientTalk VM.
|
|
|
|
|
|
- Bugfix: `system.readNextLine:catch:` failed when invoked as part of a iat shell startup script (i.e. when invoked before the REPL started).
|
|
|
|
|
|
## build041108 (v 2.12)
|
|
|
|
|
|
- Support for declarative Guards to perform conditional/behavioral synchronization (see at/lang/guards.at)
|
|
|
- An improved object inspector by Christophe (see the file at/support/inspectorGui.at)
|
|
|
- Many small bugfixes (a.o. fixes for issues #3 and #26)
|
|
|
- Added a type tag `@Required` which can be used to tag methods that a trait requires. These methods are defined only for documentation purposes and will automatically be excluded upon `import`.
|
|
|
- When importing objects that themselves imported other objects in a typical "diamond" structure, the interpreter is now smart enough to not raise a name conflict for methods originating from the same object. That is, methods inherited via multiple import paths are merged again in the composite (even if they were aliased along the path).
|
|
|
- Up to now, when doing an `import`, the names of primitive methods like `new`, `init` and `==` were added to the `excludes` list by default. This is no longer the case now. Methods with these names will now also be imported, but only if they were overridden from `nil` (i.e. `import` never imports the primitive methods from `nil`). This change is due to the fact that new, init and == are no longer present in *each* AT object (only by default in `nil`).
|
|
|
- Bugfix: toString, hashCode and equals were executed by non-actor threads when invoked from Java on coerced AmbientTalk objects.
|
|
|
- Added a port of the Self/Squeak Morphic UI framework in AmbientTalk to the main distribution (in the directory `at/morphic`. See the `at/morphic/apps` subdirectory for example applications.
|
|
|
- Added support for slot removal by means of a novel `removeSlot(slotName)` meta-level operation defined on mirrors. For a small example of slot removal, see the `testSlotRemoval` unit test in `at/unit/bugfixes.at`.
|
|
|
- Added support for determining the set of free variables required by a new `isolate: {...} ` or `actor: {...} ` expression. It is now possible to declare such expressions without explicitly listing the lexically free variables used in the code as formal parameters of the closure used to initialize the isolate/actor. Please note the following details:
|
|
|
- Lexically free variables bound to methods are not imported. However, lexically free variables bound to closures *are* imported. For example:
|
|
|
```
|
|
|
def m() { ... } // m bound to method
|
|
|
def c := &m; // c bound to closure
|
|
|
def i := isolate: {
|
|
|
... m() ... // wrong: m is not imported because bound to method
|
|
|
... c<-apply([... // right: c is imported because bound to closure
|
|
|
}
|
|
|
```
|
|
|
- Variables defined in the root object (the global lexical scope) are also not imported (an isolate will have access to its own root, and thus these variables need not be imported, but are rather rebound to a new root).
|
|
|
- Lexically free variables within an `isolate:` or `actor:` expression which cannot be resolved (i.e. whose lookup in the lexical scope yields an error) are not imported. It is assumed that these "missing" lexical variables are bound by means of `import` statements in the new isolate or actor at runtime.
|
|
|
- it is still possible to override the automatic derivation algorithm by listing the free variables to copy explicitly. This also means that this change is backwards-compatible with all code that still lists the free variables explicitly.
|
|
|
- Automatically imported variables are *not* defined within the isolate object or the actor behavior itself. Rather, they are imported within a separate lexical scope, such that they essentially become "private". Making automatically imported free variables "private" also has an advantage when the isolate/actor uses `import` to bind some lexically free variables. Such variables will be "accidentally" imported (because they are lexically free variables) but because they are defined in their own scope, their definition will simply be shadowed by the `import`-ed definitions, and no import conflict will occur. Example:
|
|
|
```
|
|
|
import /.at.support.timer; // imports functions like seconds, minutes, etc.
|
|
|
def a := actor: {
|
|
|
import /.at.support.timer; // actor imports the module itself
|
|
|
// seconds is a lexically free variable of the actor and will thus be automatically
|
|
|
// imported from the surrounding actor's scope, however, because the outer definition
|
|
|
// of 'seconds' is in its own lexical scope, the definition of 'seconds' by the inner import
|
|
|
// will override that definition, so the actor will still use its "own" timer module definitions.
|
|
|
when: seconds(10) elapsed: { ... }
|
|
|
}
|
|
|
```
|
|
|
- Changed the way objects are printed: rather than displaying the hashcode, the printed format now summarizes the object's slot names.
|
|
|
- Changed semantics of takeOffline contruct: rather than notifying only remote VMs when taking an object offline, it also notifies the local VM where the takeOffline was executed so that if any inner actor has local far references to that object, now it will also get notified. In other words, if you takeOffline an object, all actors holding far references to it (independent of their location) get notified.
|
|
|
- This change of semantics can be useful for unit test purposes where concurrency is typically used to simulate distribution. However, we couldn't simulate network disconnections at actor level since network.offline() simulates a VM disconnection. With takeOffline upgrade, you can cut the accessibility of an object contained in any actor ( within the same VM or a remote one).
|
|
|
|
|
|
## build090708 (v 2.11)
|
|
|
|
|
|
- The interactive AmbientTalk shell `iat` now supports "shell commands". Every input to the `iat` shell starting with a ":" is interpreted as a shell command. The shell currently supports two commands:
|
|
|
- :q or :quit = quit the interpreter
|
|
|
- :l or :load filename = load a file as if it was passed as the file argument to `iat` (i.e. the content of the file is evaluated in the context of the behaviour object of the evaluator actor).
|
|
|
- The interactive AmbientTalk shell `iat` now supports command-line editing and history thanks to the [http://jline.sourceforge.net JLine](])) library.
|
|
|
- Exceptions occuring in actors other than the REPL-actor are now also reported to the standard output. This allows iat users to more quickly detect errors, but beware that errors may interfere with input in this way.
|
|
|
- Refactored `system.readln` to become asynchronous rather than blocking. The new method is:
|
|
|
```
|
|
|
system.readNextLine: { |line| ... } catch: { |ioException| ... }
|
|
|
```
|
|
|
- Dropped support for `system.read`.
|
|
|
- Fixed the object inspector. One can visually inspect an object `obj` by invoking `/.at.support.inspector.inspect(obj)`
|
|
|
|
|
|
## build030708 (v 2.10)
|
|
|
|
|
|
- Added the methods `addSlot(method)`, `grabSlot(selector)` and `listSlots()` to the interface of mirrors on objects. These methods represent fields as accessor/mutator method pairs at the meta-level. As such, they allow even the metaprogrammer to completely abstract from the distinction between state and behavior. An auxiliary function called `createFieldSlot` in `at/lang/values.at` allows the metaprogrammer to reflectively add "fields" to an object using the slot-based API as follows:
|
|
|
```
|
|
|
def [mutatorSlot](accessorSlot,) := /.at.lang.values.createFieldSlot(`foo, 5);
|
|
|
(reflect: anObject).addSlot(accessorSlot);
|
|
|
anObject.foo; // returns 5
|
|
|
```
|
|
|
|
|
|
- The evaluation rules for table access (i.e. `t[and table assignment (i.e. `t[i](i]`)) := v`) have been changed such that `t` can now be any object that implements the methods `at(idx)` and `atPut(idx, value)`. It no longer needs to be a table object or implement `asTable`.
|
|
|
- `when:disconnected:` and `when:reconnected:` now properly only invoke their argument closure at most once. Previously, they were simply aliases for `whenever:disconnected:` and `whenever:reconnected:`.
|
|
|
- Futures are now attached to regular messages on a per message send basis. That is: when the same message object is used several times in a message send expression (e.g. using `rcvr <+ msg`), the expression will evaluate to a new future upon each send. Up to now, a message was only equipped with a single future, causing only the first message send to work correctly. All subsequent return values from subsequent sends were ignored.
|
|
|
- Added a mirror factory for actor-level mirrors in the form of the function `getExplicitActorMirror` defined on the implicit actor mirror.
|
|
|
- An explicit mirror on an actor can now be acquired by invoking `reflectOnActor()` rather than `actor`.
|
|
|
- Refactored the `invoke` meta-level operation such that this operation now takes two arguments: the receiver (or 'delegate') and an invocation object (containing the invocation's selector and arguments). The invocation object can further be annotated with type tags to add additional metadata to the invocation.
|
|
|
- The actor MOP now supports retrieving the current subscriptions (`listSubscriptions`) and publications (`listPublications`).
|
|
|
- The `install:` primitive defined on the explicit actor mirror (previously `actor`) has been renamed to `becomeMirroredBy:`
|
|
|
- Added a novel way to define mirages:
|
|
|
```
|
|
|
object: { ... } mirroredBy: { |base| LogMirror.new(base) }
|
|
|
```
|
|
|
The `mirroredBy:` keyword can now also take a unary closure as an argument. The semantics is that this closure is invoked with the **uninitialized** mirage and should return a mirror for the mirage. As such, mirror creation becomes explicit in the program. It is still possible to pass a prototype mirror to `mirroredBy:`, which will still be implicitly instantiated. Another advantage of passing a closure is that a "constructor function"-creation style can now also be applied to mirror creation (i.e. one is not forced to use the object-based inheritance pattern for mirrors).
|
|
|
- The actor MOP now supports a scheduling protocol consisting of three methods: `listIncomingLetters`, `schedule` and `serve`.
|
|
|
- The "primitive methods" that used to be part of **every** object, i.e. `==`, `new` and `init`, are now moved to the `nil` object. These methods can still be invoked on every object, because all objects eventually delegate to `nil`.
|
|
|
- A new metalevel operation has been added to the `actor` mirror, namely `createReference(toObject)`. Overriding this hook allows changing what default 'far references' are created when parameter-passing by-reference objects.
|
|
|
- It is now possible to select constructors from a Java class and cast them to the correct signature. Consider for instance the following code excerpt which creates a java TreeSet with a custom comparator (for AmbientTalk numbers):
|
|
|
```
|
|
|
def TreeSet := jlobby.java.util.TreeSet;
|
|
|
def makeTreeSet := TreeSet.&new;
|
|
|
def makeTreeSetWithComparator := makeTreeSet.cast(jlobby.java.util.Comparator);
|
|
|
def myComparator := object: { def compare(x, y) { x - y } };
|
|
|
def myTreeSet := makeTreeSetWithComparator(myComparator);
|
|
|
```
|
|
|
|
|
|
- Support to add annotations to method definitions is now provided. These annotations are type tags which can be used to simply tag methods. Additionally, the type tags can override the default annotateMethod implementation to transform the method that is being annotated. The following example shows the definition of a Logged message annotation:
|
|
|
```
|
|
|
deftype Logged;
|
|
|
Logged := extend: Logged with: {
|
|
|
def annotateMethod(meth) {
|
|
|
extend: meth with: {
|
|
|
def apply(args, ctx) {
|
|
|
system.println("invoking " + super.name + " on " + ctx.receiver + " with " + args);
|
|
|
def result := super^apply(args, ctx);
|
|
|
system.println("invoking " + super.name + " on " + ctx.receiver + " yielded " + result);
|
|
|
result } } } };
|
|
|
|
|
|
def m(x, y) @Logged { x - y };
|
|
|
```
|
|
|
|
|
|
- Adding behavior to an asynchronous message annotation now needs to be done using annotateMessage, rather than annotate.
|
|
|
|
|
|
## build140508 (v 2.9)
|
|
|
|
|
|
- The 'TFarRef' trait has been renamed to 'TEventualRef'. All custom object references actually denote custom 'eventual references' (in E terminology). "Far references" only denote AmbientTalk's native remote object references. The dependent language modules (ambient refs, futures, leased refs, multirefs, ...) have been changed accordingly.
|
|
|
- The meta_receive operation is now invoked in the same execution turn as when the message is sent. The return value of receive is no longer 'ignored', but rather becomes the return value of the message send (''o<-m()'') itself. This makes it possible for custom eventual references to immediately intervene in the message sending process (without having to install a custom actor mirror that overrides send). For 'local'/'near' references, receive simply schedules the message in the actor's own message queue.
|
|
|
- When an actor processes the next msg from its inbox, it again dispatches to the meta_receive operation of the receiver. Hence, receive can be used by proxies to intervene in the async message sending process, and by all other objects to intervene in the async message delivery process.
|
|
|
- the send operation is still defined on the actor mirror and can still completely override the behaviour of message sending (which is still used by the futures language module).
|
|
|
- When type tag objects are used to annotate messages (i.e. <-m()@Annotation), they can intervene in the message sending process by implementing a method named 'annotate', which takes the constructed message object as argument and should return a possibly extended message object (which may then e.g. override base_sendTo such that it incorporates novel message sending semantics)
|
|
|
- We changed the implementation of AmbientTalk's support for regular expressions. Whereas we previously relied on a java.util.regexp port for pre-1.4 JVMs, we now rely on the Apache Regexp library. This may affect regular expressions written in AmbientTalk, since they must now follow the language provided by Apache Regexp. For most patterns, the syntax should remain the same.
|
|
|
- Bugfix: [[Symbiosis]] AT nil value sometimes erroneously converted into Java null value (tvcutsem)
|
|
|
- Bugfix: [[Symbiosis]] constructor of XSymbiosisFailure does not deal with a null symbiont (in case of a static method) (tvcutsem)
|
|
|
- Bugfix: [[Evaluation|Protocol]] Quoting a universal message send with something other than a message creations raises a type mismatch (tvcutsem)
|
|
|
- Bugfix: [[Evaluation|Protocol]] Quoting a message creation with a single annotation raises a type mismatch (tvcutsem)
|
|
|
- Bugfix: [Shell](IAT) IAT can't handle empty lines (tvcutsem)
|
|
|
|
|
|
## build130208 (v 2.8)
|
|
|
|
|
|
- AT objectpath is now separated according to system-specific path separator, not according to ':' on all platforms.
|
|
|
- Added a lot of functionality to the standard lib. See at.ambient and at.lang
|
|
|
- bugfix: [whenever:discovered: uses the service object of the first match for all subsequent matches (stimberm)
|
|
|
- bugfix: [[Distribution|(AmbientTalk layer)]] multiple discovery listeners for the same type are triggered too much (tvcutsem)
|
|
|
- bugfix: [[Evaluation|Protocol]] Fields and methods with same name can co-exist in one object (tvcutsem)
|
|
|
- bugfix: [[Distribution|(AmbientTalk layer)]] Objects are exported under a new object id every time they are parameter-passed (tvcutsem)
|
|
|
- bugfix: [[Distribution|(Network layer)]] failed to online network (tvcutsem)
|
|
|
- bugfix: [[Distribution|(Network layer)]] Cannot access system or lobby in code deserialized in the discovery actor (tvcutsem)
|
|
|
|
|
|
## build170907 (v 2.7)
|
|
|
|
|
|
- added a library to do 'structural typing' (see at/lang/structuraltypes.at)
|
|
|
- added a library to do more robust trait composition (see at/lang/traits.at)
|
|
|
- added a library to access the M2MI Distributed programming library (see at/m2mi)
|
|
|
- Asynchronous messages no longer carry a 'receiver' field. Instead, they only contain selector, arguments and types. The receiver is now specified in the send meta-level method, which now takes both receiver and asynchronous message explicitly. The important implication is that asynchronous message objects may now be safely sent multiple times. This used to fail because the receiver field could be erroneously re-assigned while a message would be in the inbox already.
|
|
|
- Asynchronous message objects now carry a 'from(sender)' method which can be used to turn a message into a closure. The closure is a unary closure which asks the sender to send the encapsulated message to the receiver argument. Example:
|
|
|
[1, 2, 3](Actors/Concurrency]).map: .+(1).from(self) => [- booleans now have support methods and:and: and or:or: to avoid having to write too many braces :)
|
|
|
- the nil object now understands '!=', i.e. nil != obj
|
|
|
- the try:catch:using: family of language constructs is extended with an finally: clause which allows specifying a block of code which is to be executed whenever the scope of the construct is left, whether by succesful termination, handler execution or exception propagation.
|
|
|
- round, floor and ceiling are now also defined on numbers (and they all return self; they were previously only defined on fractions)
|
|
|
- the iat shell now supports multiline input. When a line ends with a \ character, the next line is implictly read. This change also affects the behaviour of system.readln()
|
|
|
- Added a safety check when using "import" that first checks whether the imported object defines slots for all referenced aliased and excluded symbols.
|
|
|
- it is now legal to write empty closures and method bodies, as in "object: { }" or "def m() { }".
|
|
|
- Bugfix: [Serialisation/Parameter Passing](2,3,4]) Isolates that use import cannot be safely parameter-passed (tvcutsem)
|
|
|
- Bugfix: [[Parser]] Parser fails to parse files ending in single line comments (tvcutsem)
|
|
|
- Bugfix: [Asynchronous messages behave ill-defined when used multiple times (tvcutsem)
|
|
|
- Bugfix: f0a0a50127e00c3ff07fc99de605d9aa Classloader used by Coercer not always correct (tvcutsem)
|
|
|
- Bugfix: d8dce698b2aada3359876b2ccbc606b2 Selection of keyworded methods (tvcutsem)
|
|
|
- Bugfix: 3b4fa5117fd3b13dec53ec93eea28b08 Equality of introspective mirrors is ill-defined (tvcutsem)
|
|
|
|
|
|
## build270707 (v 2.6)
|
|
|
|
|
|
- changed part of the semantics of method invocation. AmbientTalk now supports the so-called [[at:tutorial:objects#uniform_access|uniform access principe]](Actors/Concurrency]) that allows client objects to abstract from the fact that a 'property' is implemented as a field or as a zero-argument method. Hence, from now on:
|
|
|
a) o.m == o.m() if m is bound to a method (if it is bound to a field, the field's value is still returned)
|
|
|
b) m == m() if m is bound to a lexically visible method
|
|
|
c) first-class methods are still supported, but require explicit syntax:
|
|
|
o.&m will grab the method as a first-class closure. If m is bound to a field instead, o.&m will return an "accessor" closure which is a nullary closure yielding the field's value upon application. Method selection also works lexically: &m yields an accessor or closure for a lexically visible field or method.
|
|
|
d) assignment is now treated as message passing, with x := 5 being equal to lexically invoking a method named "x:=" and o.x := 5 being equal to sending o the message "x:=".
|
|
|
|
|
|
The UAP change is unfortunately not entirely backward-compatible with existing AmbientTalk code. When you upgrade to this release, you'll have to check the following:
|
|
|
a) where you used to write 'o.m' to select a method as a first-class closure value, you should now write 'o.&m' because 'o.m' is now treated as invoking the method (i.e. o.m())
|
|
|
b) where you used to write 'm' to select a lexically visible method to grab a method as a first-class closure value, you should now write '&m' because 'm' is interpreted as applying the method (i.e. m())
|
|
|
- added ''at.support.util.at'' file to the system library. This file defines a number of utility functions. More information can be found in the file itself.
|
|
|
- added the construct ''isolatelambda:'' to init.at, which allows the creation of 'pass-by-copy' closures.
|
|
|
- Various bugfixes w.r.t. serialization of objects (isolates).
|
|
|
|
|
|
## build190607 (v 2.5)
|
|
|
|
|
|
- Consistently renamed 'stripes' to 'type tags'. While we originally based our "stripes" on the StripeTalk papers, we now seem to use them more for intensionally classifying objects according to types than for extensional classification. Hence, from now on:
|
|
|
- ''defstripe'' keyword becomes ''deftype''
|
|
|
- the ''stripesOf:'' meta-method becomes ''tagsOf:''
|
|
|
- the ''object:stripedWith:'' method becomes ''object:taggedAs:''
|
|
|
- the ''is:stripedWith:'' method becomes ''is:taggedAs:''
|
|
|
|
|
|
While this change is not backwards-compatible with current AT code (you really need to find/replace all occurences of these language constructs), we feel it is best to make this name change as soon as possible, rather than carrying an ill-chosen name for the rest of AT/2's life.
|
|
|
|
|
|
## build080507
|
|
|
|
|
|
- added support for leased object references (see at/lang/leasedrefs.at)
|
|
|
- the symbiosis layer now treats symbiotic calls to AmbientTalk objects representing a java.util.EventListener as pure asynchronous calls
|
|
|
- added support for test suites which group the execution of multiple independent unit tests
|
|
|
- added support for asynchronous unit tests: these are test methods prefixed with 'testAsync' which should return a future. The test only fails or succeeds if the future is resolved.
|
|
|
- added support to unquote objects in a quasiquoted expression. Furthermore, the unquote of an expression is also allowed when the parser expects a symbol, provided that the unquoted expression evaluates to a symbol
|
|
|
- added restrict:object to: interface construct which implements a simple variant of encapsulation policies using first-class delegation.
|
|
|
|
|
|
Bugfixes:
|
|
|
- [[Parser]] Cannot unquote-splice into parameterlist and body (smostinc)
|
|
|
- [[Parser]] Escape characters do not work in text (smostinc)
|
|
|
- [[Parser]] Unquoting in symbol position not possible (smostinc)
|
|
|
- [[Reflection]] Unquoting objects in a parse tree yields incorrect conversions to Expressions (smostinc)
|
|
|
- [[Evaluation|Protocol]] Quoting a "selection" evaluates its subexpressions instead of quoting them (stimberm)
|
|
|
- [[Distribution|(AmbientTalk layer)]] After retracting unsent messages, far references won't transmit any messages anymore (tvcutsem)
|
|
|
- [[Symbiosis]] Creation of java.lang.Long aftected by Bugfix 0000014 (tvcutsem)
|
|
|
- [[Natives]] Support for native types conversions (tvcutsem)
|
|
|
- [[Distribution|(AmbientTalk layer)]] when:disconnected: may be invoked when far ref already disconnected (tvcutsem)
|
|
|
- [[Symbiosis]] Symbiotic instances of NAT classes are wrapped (tvcutsem)
|
|
|
- [[Evaluation|Protocol]] Unquoting operator unquotes too much (tvcutsem)
|
|
|
- [[Parser]] Cannot invoke methods on literal numbers (tvcutsem)
|
|
|
- [[Evaluation|Protocol]] Cannot negate fractions directly (tvcutsem)
|
|
|
|
|
|
## build060407
|
|
|
|
|
|
System library additions:
|
|
|
- added a unit testing framework, see at/unit/test.at
|
|
|
- added a proper vector abstraction, see at/collections/vector.at
|
|
|
- added support for ambient references, see at/lang/ambientrefs.at
|
|
|
- added initial support for exceptions, see at/exceptions.at
|
|
|
- added a small timer library for scheduling code, see at/support/timer.at
|
|
|
- added a minimal object inspector using symbiosis with java, see at/support/inspector.at
|
|
|
|
|
|
Implementation changes:
|
|
|
- The AT/2 interpreter no longer uses any of the JGroups or Log4J Dependencies. Rather, distributed network communication is performed in a dedicated manner. This improved performance, made AT/2 less dependent on external libraries, has a tremendous effect on the memory footprint and - most importantly - has enabled AT/2 to be used on the J2ME CDC platform. To the AT/2 programmer, the interface remains the same.
|
|
|
|
|
|
Bugfixes:
|
|
|
|
|
|
- Bug in Detection of offline VMs (in new distribution layer) (tvcutsem)
|
|
|
- Race condition in distribution layer when going offline (tvcutsem)
|
|
|
|
|
|
## build230307
|
|
|
|
|
|
- added a new option '--network' or '-n' to IAT which allows you to configure the name of the JGroups overlay network that the AmbientTalk VM should join. Very useful for debugging or demo purposes (allows you to set up a 'private' network of AT/2 VMs)
|
|
|
- Symbiosis: when Java code performs obj.equals(obj2), and obj is an AmbientTalk object, the implementation now correctly invokes the obj.==(obj2) AmbientTalk method (provided that obj2 is also an AmbientTalk object)
|
|
|
- Meta-level interface: createMessage's interface has changed: the method now takes as arguments the selector, a table of arguments and a table of stripes. The sender is no longer taken into account and the table of stripes is used to stripe the created message with.
|
|
|
- Added new syntax to support the 'annotation' of message sends with stripes. For example, you can write o<-m()@Foo, which is equivalent to writing actor.createMessage(`m, [[[Foo]]).sendTo(o). Any expression can be put after the '@'. It is the intent that the result of evaluating that expression is either one stripe or a table of stripes (e.g. o<-m()@[Foo,Bar](],)). Synchronous message sends can also be annotated.
|
|
|
- Reworked the futures language module to support 'annotated' message sends. When loading the futures using FuturesModule.enableFutures(), you can pass an optional boolean argument (by default false) which says whether the futures language module should apply to unannotated messages or not.
|
|
|
The futures language module now also exports two stripes, 'FutureMessage' and 'OneWayMessage'. When the 'FutureMessage' is attached to a message send, the message will always return a future (if the futures language module is activated). If 'OneWayMessage' is attached to a message send, the message will use the default behaviour (i.e. normally return 'nil') even if the futures are enabled.
|
|
|
Hence, you have two options to work with futures from now on: you can evaluate 'enableFutures(true)' to make <- return futures by default, and use o<-m()@OneWayMessage to create pure asynchronous messages without futures, or you can evaluate 'enableFutures(false) to make <- behave normally (i.e. return nil) and then use o<-m()@FutureMessage to explicitly require the creation of futures.
|
|
|
- distributed memory management extensions by Elisa: it is now possible to take an exported object offline (using the takeOffline native). Far references that point to objects that are taken offline perceive this event as though it was a disconnection, and hence this will trigger any when:disconnected: listeners on that object. Additionally, when:expired: observers can be registered on a far reference to be notified explicitly when an object has been taken offline rather than disconnected (otherwise there is no means to distinguish between takeOffline/disconnection)
|
|
|
- added the 'mobiTunes' demo program to the system library (under at/demo/mobiTunes.at)
|
|
|
|
|
|
## build150307
|
|
|
|
|
|
- Contains important bugfixes w.r.t the 050307 release.
|
|
|
- Based on comments by all of you during our meeting, we changed the semantics of actor.install: { code }
|
|
|
actor.install: now takes an arbitrary 'protocol' object and installs that object as the mirror of the actor. Also, its return value is no longer an object you can use to 'unmix' the protocol. Rather, it now returns the old installed protocol.
|
|
|
If you still want to mimick the old behaviour, you can do so with code like:
|
|
|
```
|
|
|
def mixin(protocolCode) {
|
|
|
def oldActor := actor.install: (extend: actor with: protocolCode);
|
|
|
object: {
|
|
|
def uninstall() {
|
|
|
// restore the previously active protocol
|
|
|
actor.install: oldActor
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
- The import: native now works, but to make it work, we had to implement it as syntax, not as a native method. Here's an example of how to use import:
|
|
|
```
|
|
|
def trait := object: {
|
|
|
def foo() { self.bar() + 3 };
|
|
|
def bar() { 5 };
|
|
|
def baz := 3;
|
|
|
};
|
|
|
|
|
|
def obj := object: {
|
|
|
import trait alias bar := tralala exclude baz;
|
|
|
def bar() { 1 };
|
|
|
}
|
|
|
|
|
|
obj.bar() => 1
|
|
|
obj.foo() => 4
|
|
|
obj.baz => error
|
|
|
obj.tralala() => 5
|
|
|
```
|
|
|
- The futures language mixin now works! Please check out the source code in the native library provided with the distribution under at/lang/futures.at
|
|
|
Example:
|
|
|
```
|
|
|
import /.at.lang.futures;
|
|
|
enableFutures(); // changes the MOP of the current actor
|
|
|
def id(x) { x }
|
|
|
when: self<-id(42) becomes: { |val| system.println(val == 42) }
|
|
|
```
|
|
|
It might be that we later decide to invoke 'enableFutures()' automatically when you load the futures module.
|
|
|
- The mirror architecture has been updated, but I'm not going to detail all bugfixes/changes here :-)
|
|
|
- Project/build changes:
|
|
|
- Don't forget to change the value of the AT_HOME environment variable in TextMate to point to the latest build!
|
|
|
- Based on the proposal by StijnT, I changed the structure of the AmbientTalk 'object path' argument from
|
|
|
path1:path2:path3:...
|
|
|
to
|
|
|
name1=path1:name2=path2:name3=path3:...
|
|
|
The names given in the path will be the names of slots defined in the lobby at startup time. For example, if you specify:
|
|
|
```iat -o foo=/Users/me/test:bar=/usr/local/lib```
|
|
|
Then in AmbientTalk:
|
|
|
lobby.foo is bound to the namespace "/Users/me/test" and
|
|
|
lobby.bar is bound to the namespace "/usr/local/lib"
|
|
|
- By default, if you do not give an object path to iat in the command line (using -o), IAT will use the following path:
|
|
|
```$AT_OBJECTPATH:at=$AT_HOME/at```
|
|
|
In other words: it uses the value of ''$AT_OBJECTPATH'' if that variable exists (cfr. Java's ''$CLASSPATH'') and always includes the 'native' library which will be known under the name ''at''. You will see that in the new build, the native library is shipped in the ''at'' subdirectory.
|
|
|
It is now allowed to shadow names in the object path (a warning is printed on the console to make you aware of the shadowing). For example, if your ''$AT_OBJECTPATH'' equals ''foo=/usr/lib/ambienttalk'' and you start ''iat'' using:
|
|
|
```iat -o foo=/test:$AT_OBJECTPATH```
|
|
|
then ''lobby.foo'' will be bound to ''/test''
|
|
|
- If you do not give the location of an init file to iat (using ''-i''), iat will try to load $AT_HOME/at/init/init.at or fail if it cannot find this file.
|
|
|
- In order to run IAT properly from within Eclipse with this new semantics, you have to set the value of the AT_HOME environment variable in your 'run configuration'. Go to the 'run' menu, select the IAT run, in the 'arguments' tab, enter the following under VM Arguments:
|
|
|
```-DAT_HOME="${project_loc:AT2 Library}/edu/vub"```
|
|
|
This passes to the JVM the value of the ''AT_HOME'' property. It is set to the location of the edu/vub subdirectory of the AT2 Library project, which contains the native AT library. Note that if you named that project differently, you need to adapt the string "AT2 Library" to match your project name. |