namgk / ambienttalk Goto Github PK
View Code? Open in Web Editor NEWAutomatically exported from code.google.com/p/ambienttalk
Automatically exported from code.google.com/p/ambienttalk
What steps will reproduce the problem?
Evaluate the following script:
deftype T;
def o := object: { nil } taggedAs: [ T ] mirroredBy: { | base | extend:
defaultMirror with: { nil } };
is: o taggedAs: T;
What is the expected output? What do you see instead?
output should be true, but instead it is false. tagsOf: o also returns an empty
table
Original issue reported on code.google.com by [email protected]
on 20 Mar 2010 at 4:19
What steps will reproduce the problem?
1. Compare a numeric value to a non-numeric value (e.g. 5 != nil)
What is the expected output? What do you see instead?
Expected output is <true>, while in the example, nil is implicitly coerced to a
numeric value (to
match the ATNumeric argument type expected by the equality and inequality tests
in the
ATNumeric interface). Subsequently, a selector not found exception is thrown
since nil does not
implement the necessary methods used in the double dispatch to compare numbers.
Please use labels and text to provide additional information.
A fix for this problem has been made in the reactive branch, rev. 1418
Original issue reported on code.google.com by [email protected]
on 22 Nov 2008 at 8:45
Proposal to allow an actor to block on a future, but in an event-driven way
(i.e. blocking as in
suspending while not blocking the main actor event loop).
I would like to be able to implement a construct:
{{{def val := await: future}}}
That can be used to block on the value of a future without disrupting control
flow (i.e. without
requiring the use of {{{when}}}. Unlike the typical {{{touch}}} operation on
classical futures, the
{{{await}}} operation does not block the actor's entire event loop. The actor
simply continues
processing other messages until it encounters a message that 'wakes up' the
execution
(coroutine) that is awaiting the future.
The reason why I want a construct like this is that it allows code to hide
asynchrony. Asynchrony
no longer has to leak through to the caller. This is useful for software
evolution purposes.
This construct could be implemented if we extend AmbientTalk with coroutines:
lightweight co-
operative threads. It does not introduce data races because of the cooperative
scheduling: no two
coroutines can ever be active within the same actor.
Implementing real lightweight coroutines in the interpreter is tricky because
it requires an
explicit reification of the runtime AmbientTalk stack, which we don't have. It
is possible to
implement heavyweight coroutines, however, by suspending threads:
- coroutine yield = suspending the current thread & spawning a new thread
- later, a coroutine can be re-activated by resuming the suspended thread
This leads to a model with one JVM thread / coroutine, which is heavyweight but
OK as long as
coroutines are not heavily used in AmbientTalk.
Original issue reported on code.google.com by [email protected]
on 21 Jul 2009 at 5:08
Currently the AmbientTalk interpreter makes use of TCP/IP sockets for remote
messaging. It also makes use of 'Outputstream.flush()' to flush bytes of the
network socket. However, it takes flush() returning normally to mean that the
bytes were successfully received at the remote end.
The JDK1.5 documentation makes it clear that flush() does not provide such a
guarantee:
"If the intended destination of this stream is an abstraction provided by the
underlying operating system, for example a file, then flushing the stream
guarantees only that bytes previously written to the stream are passed to the
operating system for writing; it does not guarantee that they are actually
written to a physical device such as a disk drive."
In principle, any CMDTransmitATMessage command should be acknowledged by a new
type of command. Only upon reception of an explicit ack should the sending
actor be allowed to drop and forget the sent AmbientTalk message.
Original issue reported on code.google.com by [email protected]
on 28 Jul 2010 at 12:33
When dynamically applying protocols, the use of callbacks can give rise to
unexpected behaviour as
the protocols are no longer active when the call-backs are activated. Moreover,
since the
dynamically activated protocol is not always lexically visible, the call-back
cannot be held
responsible to re-install them (it should be agnostic to their presence).
Hence we propose to introduce a call-back framework where language construct
designers
document when they use a call-back such that dynamic protocols can hook into
this.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 1:47
Currently, in AmbientTalk, when a non-isolate object o extends an isolate
object i, then o will be
automatically turned into an isolate. This means it will not have access to its
lexical scope, and
will be passed by copy, even though it was not declared as an isolate. This
makes sense,
because:
is: o taggedAs: Isolate
returns true (o 'inherits' the type tag from its parent i)
However, we could also make it the responsibility of the programmer to
explicitly tag children of
isolates as isolates themselves. This also allows programmers to make
non-isolate extensions of
isolates. This change would also get rid of some ugly code in the constructor
of NATObject,
which explicitly checks for inheritance of isolates:
// if this object is tagged as at.types.Isolate, flag it as an isolate
// we cannot perform 'this.meta_isTypedAs(ISOLATE)' because this would trigger
mirages too
early
if (isLocallyTaggedAs(NativeTypeTags._ISOLATE_)
|| dynamicParent.meta_isTaggedAs(NativeTypeTags._ISOLATE_).asNativeBoolean().javaValue) {
setFlag(_IS_ISOLATE_FLAG_);
// isolates can only have the global lexical root as their lexical scope
lexicalParent_ = Evaluator.getGlobalLexicalScope();
}
Original issue reported on code.google.com by [email protected]
on 21 Oct 2009 at 1:12
Dynamic typing is cool because it allows for so-called ad hoc polymorphism
(also known as
“duck typing”), where any variable can contain any value, and code will
work as long as an object
can respond to all messages sent to it.
Unfortunately, dynamic typing detects errors very latently, which results in
sometimes confusing
selector not found exceptions.
Static typing the way C and Java introduce them is bad, it couples interface to
specific
implementation and inhibits reuse. Therefore, we propose to extend AmbientTalk
with a
structural typing mechanism, where a type only defines an interface. Any object
that
“implements” that interface can be bound to a variable of the abstract type.
Good examples in the literature are the type system of Emerald and that of
Strongtalk. In
StrongTalk, a protocol defines the interface to an object, so the type system
is based on
structure. It also has good support for parameteric types (generics). Also, it
features the notion
of a brand which allows for nominal typing where necessary.
One step further is the consideration of being able to annotate variables with
guards, as in E. A
guard is a boolean expression that should evaluate to true each time a value is
bound to it. A
false evaluation is a ‘type error’. This is called soft typechecking
because type checks are still
done very latently, but the advantage over regular typing is that you can use
arbitrary runtime
state to perform your “type check”.
Proposal is to be able to annotate formal parameters to
methods/functions/blocks and defined
variables with a guard:
def x : guardexpression := value
def m(par : guardexpression) : returnguardexpression { ... }
{ |a:guard : returnguard| body }
For variables, the guard is evaluated each time the variable is assigned. For
formals, it is checked
upon binding. The return guard is checked upon function return if the function
returns normally.
Idea is that the guard is simply an expression. If the expression evaluates to
true, the guard
passes and nothing happens. If the expression evaluates to false, the
interpreter raises an
exception. If the expression evaluates to an object, the object is sent a
message to check
conformance of the actual arg (e.g. .checkConformance(arg)). The idea is that
different kinds of
types can be implemented like this (i.e. type tags check conformance by
checking whether arg is
tagged with them, structural types check the object’s interface, etc.)
We might even use this feature to add metadata in the sense that the guard
could be used to
annotate its field.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 1:59
I believe "def" should define constant bindings between names and values. This
would require a
new keyword "var" (as in E) for distinguishing constant from variable bindings.
Almost all of the
definitions in AT are conceptually constant, yet we cannot take advantage of
this fact because
there *might* always be an assignment.
Being able to derive that an object is constant has advantages. Take isolates,
for example. The
lexical scoping restriction on isolates is sometimes really annoying. It would
seem nicer to be
able to define pass-by-copy based on mutability: e.g. immutable objects are
pass by copy,
mutable ones are pass by ref. Isolates could then access their lexical scope
but only if the
accessed vars are themselves immutable. A pbc object is copied together with
its lexically free
variables.
Another example: in Newspeak, Bracha requires namespace objects to be
immutable. I haven't
figured out yet what the advantages are in the context of NS.
Note that changing the semantics of "def" may not be enough to achieve "deep"
immutability of
objects. Tables, for example, are also mostly immutable. So perhaps, like in E,
the syntax "[...]"
should create immutable objects that can be used (if necessary) to spawn a
mutable copy
instead.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 3:13
Scheme:
(define x 123)
`(+ 1 `(+ 3 ,(- 3 ,x)))
>> (+ 1 `(+ 3 ,(- 3 123)))
=> x is evaluated
AmbientTalk:
>`(1+`(3+#(3-#x)))
>>1.+(`(3.+(#(3.-(#(x))))))
=> x remains quoted
This is problematic when quoting an unquote or unquote-splice AG, because it
disallows any
further unquoting in the subexpression
Original issue reported on code.google.com by [email protected]
on 14 May 2008 at 8:00
The method !=, defined on 'nil', only works reliably when comparing nil to
another object (i.e.
when sending != to nil). However, because all objects eventually delegate to
nil, all objects
understand !=. Hence, one can write obj1 != obj2. However, a bug in the
implementation of !=
causes != to treat the left-hand side as nil.
So, for example:
def o := object: {};
o != nil
yields false, while obviously, this should yield true!
Should be fixed by turning 'nil' into a real ambienttalk object (not a native).
The primitive
method != does not work reliably because it has to perform a self-send, and
native AT methods
do not have access to the real AT self.
Original issue reported on code.google.com by [email protected]
on 17 May 2008 at 5:00
Idea: enable lightweight compilation for AmbientTalk AST nodes by introducing a
new method on
AST objects:
Code impl_compile(CompilationContext ctx)
the CompilationContext could keep track of static lexical information
(potentially enabling lexical
addressing if it wasn't for "eval" and external slot definitions)
Code objects are simply lambda's, they have 1 main method (apply or maybe
better 'run', to
avoid confusion with ATClosure.apply). Compiled 'Code' is not first-class.
Compilation could be
on a per-method basis, where the top-level Code object is stored in an ATMethod
instance.
The goal is not to have 'Code' be some sort of bytecode format. We should keep
on using
recursive descent on AST nodes (Java JITs are good at inlining those methods).
But introducing a
separate compilation step may enable more efficient evaluation by partially
evaluating the
generic evaluation routine based on statically known information.
Example: AGMethodInvocation.compile could partially evaluate the number of
arguments it
takes, then generate a custom version of meta_eval that only evals x arguments,
where x is the
statically known number of actual args provided to the AST.
Problem: if the custom routine then has to invoke the generic meta_invoke, the
compilation
process won't buy us much...
Original issue reported on code.google.com by [email protected]
on 1 Dec 2009 at 7:18
In distributed programming, when doing an RPC or a RMI, network exceptions may
be raised
during the transmission of a message. There exists this famous undecidability
result in
distributed programming known as the “byzantine general’s problem” which
says that it is
impossible for both sending and receiving parties to know with absolute
probability that a
message was successfully transmitted. For example, the sender which received an
exception
does not know whether the message had actually already been successfully
transmitted or not.
He also does not know whether the network connection died or the remote host
crashed.
In distributed computing, an “orphan” is a computation that was triggered
by a received message
of which the sender does not know for sure that it arrived. Orphans are
dangerous because they
might fool the sender into thinking that a message has not been executed while
it actually has.
For example, if the sender receives a network fault while transmitting a
message, he may try to
resend the message which may lead to executing the corresponding method twice.
The first
execution would be the orphan.
These kinds of problems can occur in AmbientTalk, because remote references by
default re-
enqueue failed messages. We could solve it at the implementation level by
tagging each message
with an increasing integer ID. The receiver can then filter out messages
received twice (such a
receiver is called “idempotent”). The only problem is: how long does the
receiver have to store
the last received message ID? The answer: indefinitely! because the receiver
does not know when
the sender will return. So, either we do not provide support for this but allow
the AmbientTalk
programmer to deal with failed message transmission explicitly, or we provide
system support
and then we have to put an upper bound on the connectivity of far references.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 1:30
When some event handlers like when:disconnected: are invoked, the scheduling of
the event
handlers could happen in the wrong thread (the caller thread instead of the
thread of the actor
that owns the event handler).
The following is a manifestation of the bug as submitted by Ben Maene:
Client:
{{{
import /.at.lang.futures;
enableFutures(true);
deftype Server;
def vector := /.at.collections.vector.Vector;
def serverList := vector.new();
whenever: Server discovered: { |server|
when: server<-getName()@FutureMessage becomes: { |name|
if: (false == serverList.contains(server))
then: {
serverList.add(server);
system.println("Added server: " + name);
whenever: server disconnected: {
system.println("Server offline:" + name);
};
whenever: server reconnected: {
system.println("Server online:" + name);
};
};
};
};
network.online();
}}}
Server:
{{{
deftype Server;
def server := actor: {
def getName(){
def username := jlobby.java.lang.System.getProperty("user.name");
username;
};
};
export: server as: Server;
network.online()
}}}
The discovery of the server works, but if the server becomes disconnected and
the
when:disconnected: handler is triggered, then the following error occurs:
Thu Oct 22 21:15:20 CEST 2009 INFO at.eventloops.vm - event:
memberLeft(/192.168.205.1:60723[AmbientTalk]): VM disconnected:
/192.168.205.1:60723[AmbientTalk]
Thu Oct 22 21:15:20 CEST 2009 DEBUG at.eventloops.remoterefs -
notifyDisconnected for <far
ref:behaviour of <actormirror:585824>>
Thu Oct 22 21:15:20 CEST 2009 ERROR at.eventloops.remoterefs - error invoking
when:disconnected: listener
edu.vub.at.exceptions.XIllegalOperation: Detected illegal invocation of
base_schedule: sharing via
Java level of object <obj:12222848{createMessage}@[FuturesModule]>
at edu.vub.at.objects.coercion.Coercer.invoke(Coercer.java:189)
at $Proxy1.base_schedule(Unknown Source)
at edu.vub.at.actors.natives.ELActor.acceptSelfSend(ELActor.java:319)
at edu.vub.at.eval.Evaluator.trigger(Evaluator.java:494)
at edu.vub.at.actors.natives.NATFarReference.triggerListener(NATFarReference.java:491)
at edu.vub.at.actors.natives.NATFarReference.notifyDisconnected(NATFarReference.java:245)
at edu.vub.at.actors.natives.NATFarReference.disconnected(NATFarReference.java:167)
at
edu.vub.at.actors.net.ConnectionListenerManager.notifyDisconnected(ConnectionLis
tenerManage
r.java:138)
at edu.vub.at.actors.natives.ELVirtualMachine$4.process(ELVirtualMachine.java:237)
at edu.vub.at.actors.natives.ELVirtualMachine.handle(ELVirtualMachine.java:150)
at edu.vub.at.actors.eventloops.EventLoop.execute(EventLoop.java:248)
at edu.vub.at.actors.eventloops.EventLoop$EventProcessor.run(EventLoop.java:269)
Original issue reported on code.google.com by [email protected]
on 25 Oct 2009 at 8:34
[deleted issue]
While the parser currently gathers some source location info (line and column
numbers) and associates it with parsed AST nodes, the information is currently
only accessible from within Java, not from within AmbientTalk.
It would be nice to expose this information via AmbientTalk's mirror system:
(reflect: ast).sourceLocation.lineNo
The source location info has some issues, however:
- the info is stored in ASTs as mutable state. This should become immutable
state (i.e. a final field set in the AST's constructor). This requires a
somewhat significant refactoring of the AGAbstractGrammar subclasses.
- how to deal with source location info for interned ASTs like symbols, which
are shared?
- should the source info be propagated to values that result from ASTs, like
messages and objects? This is not always possible, and sometimes it may be
confusing what the actual source line number is. For example:
def msg := <-foo();
o1 <+ msg;
o2 <+ msg;
What is the source location for 'msg'?
- the ANTLR parser should be modified to provide more accuracte line/column
info. Especially column info can be off in the current system.
Original issue reported on code.google.com by [email protected]
on 12 Oct 2010 at 7:43
In Eclipse plugins the Console typically shows stdout and sterror messages.
Since AmbientTalk logs statements are printed to the System.err, the console
gets polluted with interpreter log statements.
A good enhancement for the plugin would be that the default priority for AT
logging is set to FATAL, and then we add an iat option that allows users to set
the priority to lower levels when launching iat if they want the logs.
This means that "regular" plugin users (e.g. students) will not get the
interpreter logs in the Console, while the "advance" plugin users (e.g.
language developers) can set an appropriate logging level when launching iat
(without having to modify the props file).
Original issue reported on code.google.com by [email protected]
on 13 Dec 2010 at 1:16
Victor Ramiro reported the following problem:
"I'm running the test: testAsyncTypedDiscoveryViaDefaultTracker from the
DiscoveryModuleTest
(at/ambient/discovery.at)
If I run the test, everything goes just perfect. But if I put apart the client
code from the service
code (the code written within the actor) in two different files and run it as
two separate VM I got
an exception:
>>> Exception in actor <actormirror:1911694>: Java exception from packet[<async
msg:reportTo(<m2mi ref for handle Unihandle(011CAFCA97B2-000D93EB3A50-
2FCA9713,Tracker)>)>].unpackUsingClassLoader:
edu.rit.m2mi.SynthesisExceptionM2MIClassLoader: Unknown class Unihandle_1
origin:
at packet.unpackUsingClassLoader(M2MI_getClassLoader())
Mon Sep 29 16:26:50 CLT 2008 ERROR at.eventloops.actors - asynchronous
symbiotic invocation
of invoke failed
edu.rit.m2mi.SynthesisException: M2MIClassLoader: Unknown class Unihandle_1
at edu.rit.m2mi.M2MIClassLoader.getClassFile(M2MIClassLoader.java:491)
at edu.rit.m2mi.M2MIClassLoader.findClass(M2MIClassLoader.java:527)
at java.lang.ClassLoader.loadClass(ClassLoader.java:316)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at edu.vub.at.actors.natives.Packet$HookedObjectInputStream.resolveClass(Packet.java:132)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1544)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466)
...."
Original issue reported on code.google.com by [email protected]
on 30 Sep 2008 at 7:59
Elisa pointed out a problem with when:disconnected and when:reconnected
listeners and
garbage collection. The problem is as follows: a far reference may become
garbage because no-
one refers to it anymore. The question then becomes, can the far reference be
collected if it still
has listeners attached to it? Those listeners might still trigger a useful
computation if the far
reference would become disconnected or reconnected. Obviously, the semantics
should not
depend on whether the race condition is won by the garbage collector or the
network layer (i.e. if
the collector collects the far ref first and then a remote VM dies, the
listener is not triggered but
it would be the other way around).
One possible semantics is that a far reference can never become subject to
garbage collection if
it still has listeners registered for it. The programmer is then, however,
responsible for cancelling
the subscription objects if he wants the far ref to ever become collected.
This is quite a heavy semantics, so perhaps it’s a good idea to introduce two
variants of
when:disconnected: and when:reconnected:, namely the when: variant which may
only trigger
once and then is auto-cancelled, and the whenever: variant which is permanently
attached. This
ensures that the programmer sees more quickly that he has to explicitly cancel
the subscription
of a whenever: observer.
Of course, even with a “may only trigger once” listener you could prevent a
remote ref from being
collected if two VMs remain permanently connected...
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 1:34
Consider introducing another message passing operator (.µ) which sends a
message to an
object’s mirror rather than to the object itself.
obj.µmsg(args) == (reflect: obj).msg(args)
The advantage is that the meta-variant does not require the creation of a
temporary mirror,
which is unnecessary if obj is not a mirage and if the default mirror factory
is installed.
Next to efficiency considerations, the meta-send is also a more concise way of
sending
messages to mirrors.
This kind of mechanism is currently mimicked by means of the @MetaMessage type
tag and
first-class reference mirrors, in the sense that obj<-msg(args)@MetaMessage
sends the
message to obj's mirror. However, this only works for:
- async messages
- objects mirrored by the TEventualRef trait (i.e. objects representing proxies)
Specifically, it does not (yet) work for native far references.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 2:08
Reintroduce the operators & and | for boolean infix logic. This requires
modifying the parser a bit
such that it does not confuse them with .& and {|args|}
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 2:11
The `cancel` methods of subscription and publication objects currently _appear_
to be working synchronously, but they are actually operating asynchronously, by
sending an async message to the discovery actor.
In practice, this means that even after cancelling the publication for an
exported object, the exported object can still be discovered.
Proposed fix for now is to turn pub.cancel() into a sync_event such that the
calling actor blocks until the discovery actor has actually removed the
publication. This is not ideal because the discovery actor can actually do
remote communication, so there could be a high latency in processing the
actor's cancel() request.
In the extreme case, if the discovery actor _itself_ (by overriding the
isSubtypeOf test on a published/subscribed type tag) itself wants to take a
publication object offline (highly unlikely), the discovery actor could now
deadlock.
Therefore, a safer alternative would be to have cancel() return a future, or
even better, to enforce that cancel can only be called asynchronously. (one
could then use futures to synchronize on the fact that the publication was
taken down, like so: when: pub<-cancel()@FutureMessage becomes: { |_| /* pub
taken offline for sure */)
The issue came up in the context of unit testing, where the next test can only
be started after exported objects created in the previous test have been
cancelled.
Original issue reported on code.google.com by [email protected]
on 6 Apr 2011 at 1:59
Nameclashes occur in when importing 'modules' in the classic diamond situation:
O { def a() }
/ \
A B
\ /
C -> nameclash of a()
concrete code example:
import /.at.lang.traits;
def A := object: { import /.at.lang.traits };
import A; //Conflicting names during import:
//requiring:,trait:taggedAs:,trait:requiring:taggedAs:,
//trait:,trait:requiring:,use:,traitFrom:,TraitsTest,traitFrom:taggedAs:,
//traitFrom:requiring:taggedAs:
Original issue reported on code.google.com by [email protected]
on 14 May 2008 at 8:01
When dynamically applying protocols, the use of callbacks can give rise to
unexpected behaviour as
the protocols are no longer active when the call-backs are activated. Moreover,
since the
dynamically activated protocol is not always lexically visible, the call-back
cannot be held
responsible to re-install them (it should be agnostic to their presence).
Hence we propose to introduce a call-back framework where language construct
designers
document when they use a call-back such that dynamic protocols can hook into
this.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 1:47
What steps will reproduce the problem?
1. Change line 111 of the provided file to call pub.cancel and sub.cancel
instead of pub.cancel() and sub.cancel()
2. Run unit tests of the provided file.
3.
What is the expected output? What do you see instead?
Publication/subscription are not cancelled, so the unit test discover objects
from a previous test and fails.
Please use labels and text to provide additional information.
Original issue reported on code.google.com by [email protected]
on 30 Mar 2011 at 3:46
Attachments:
In 80% of the cases, tests for nil in AmbientTalk source are to see whether it
is safe to send a
message to a variable. This boilerplate code can be avoided by allowing nil to
absorb invocations.
Obviously support is then needed to distinguish where a nil result came from.
In other words, if the
result is nil as the consequence of a programming error, nil should contain the
stack of absorbed
calls to be able to determine where things went wrong.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 1:56
What steps will reproduce the problem?
1. add the java files to the svn :)
2.
3.
What is the expected output? What do you see instead?
Please use labels and text to provide additional information.
Original issue reported on code.google.com by [email protected]
on 27 Aug 2008 at 5:23
In retrospect, super should have been a meta-level slot. It says something
about the object itself,
not about the problem domain of the object, so it should be in the mirror.
The downside of AT’s current approach to stratification is that it is rather
cumbersome to use,
especially if one is simply interested in e.g. overriding meta_print to change
the printing
functionality (Java has toString defined on the Object class for such purposes)
E uses “miranda methods” which are prefixed with ‘__’ to allow objects
to interact with the
interpreter. Perhaps a clean way out could be to provide a modifier 'meta' for
fields or methods.
Fields/methods marked with meta automatically end up in the mirror of the
object. This way, they
do not interfere with the base level, while they remain as easy to define as
base-level fields.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 1:35
What steps will reproduce the problem?
1. open file
2. run as.. -> ambientTalk application
What is the expected output? What do you see instead?
you see the AT interpreter log output in the console. You shouldn't see it
because -l all=FATAL is active in the run configuration. The parameter is shown
in the run configuration info but not applied.
Please use labels and text to provide additional information.
Original issue reported on code.google.com by [email protected]
on 21 Feb 2011 at 1:54
Excerpt from a mail between myself and Mark Miller:
> When you pass an AT listener object as argument to a JVM
> {add,remove}BlahListener method, does a new JVM BlahListener wrapper
> get generated per call?
> If so, two newly generated wrappers for the same listener have
> distinct JVM identities. Does removeBlahListener fail to unregister
> the previously registered wrapped AT listener?
> --
> Cheers,
> --MarkM
Currently, it is indeed the case that a wrapper is generated per call. I wrote
a little test-case, and
indeed, removeActionListener fails to remove a previously added action
listener. This probably
indicates that Java AWT at least uses object identity to manage its listeners,
because if it had
used .equals(Object), that call would have been intercepted and correctly
interpreted by the
symbiosis. I guess we will have to ensure that each AmbientTalk object has a
unique wrapper per
interface to avoid issues like the one you mentioned.
Test case: the following code defines a little program that shows a Button.
Normally, when
pressing the button, 'Clicked' should appear the first time the button is
pressed, but subsequent
clicks should not show anything anymore. Currently, 'Clicked' is always
printed, so the listener is
never removed!
def Frame := jlobby.java.awt.Frame;
def Button := jlobby.java.awt.Button;
def f := Frame.new("test");
def b := Button.new("Test");
def al := object: {
def actionPerformed(@args) {
system.println("Clicked");
b.removeActionListener(al);
};
};
b.addActionListener(al);
f.add(b);
f.show();
Original issue reported on code.google.com by [email protected]
on 14 May 2008 at 7:51
Did a small benchmark (see attached file) to measure the impact of the causeway
tracer on
future-type messaging. The results are poor: almost twice as slow. We need to
improve the
performance of future-type message passing when tracing is turned off.
Currently, tracing info is
attached to futures regardless of whether tracing is turned on or off.
Interactive AmbientTalk Shell, version 2.14 [build091109]
time fact(100): <java:48>
time fact(100): <java:50>
time fact(100): <java:49>
time repeat(100): <java:2550>
time repeat(100): <java:2523>
time repeat(100): <java:2539>
Interactive AmbientTalk Shell, version 2.15 (development)
time fact(100): <java:49>
time fact(100): <java:50>
time fact(100): <java:49>
>time repeat(100): <java:4473>
>time repeat(100): <java:4437>
>time repeat(100): <java:4474>
Original issue reported on code.google.com by [email protected]
on 17 Apr 2010 at 2:58
Attachments:
Even though all AG components are serializable, not all of them are tagged with
the Isolate tag,
which identifies by-copy objects.
def AG := /.at.types.AbstractGrammar
> <type tag:AbstractGrammar>
AG.isSubstripeOf(/.at.types.Isolate)
> false
However, for some AG elements, the tag is already in place:
tagsOf: .m()
> [<type tag:Isolate>, <type tag:MethodInvocation>]
Original issue reported on code.google.com by [email protected]
on 14 May 2008 at 8:12
We need some kind of keyworded message sends that are matched against a kind of
‘regular
expression’ for stuff like try-catch and when-catch, such that e.g. the
following invocations all
trigger the same language construct:
when: f becomes: { |v| ... }
when: f becomes: { |v| ... } due: 1000
when: f becomes: { |v| ... } catch: Exc1 using: { |e| ... }
This could be done using optional and vararg parameters with keywords:
def when: future becomes: block due: time := default catch: @blocks {
...
}
This method actually has a selector when:becomes:[due:](catch:)* and regexp
matching could be
used to match invocation with definition.
We really need this kind of semantics if we want to make optional arguments and
varargs work
for keywords.
It becomes really important in the context of the object: object creation
primitives. There are
more than 12 of these keyworded methods because they need to fill in
“default” arguments. The
problem is: adding a new “property” to objects requires re-implementing all
previous object
creation methods to take the new default into account.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 2:06
Limitation in when:discovered: handler discovered by Tomohiro Suzuki:
when using when:discovered: to discover a generic type, the handler cannot
access the actual type of the discovered service. For example:
{{{
when: Type discovered: { |service|
// how to get access to the actual type under which service was exported?
// can be any subtype of 'Type'
}
}}}
We cannot easily pass this type as a second argument to the handler, since this
would make all existing when:discovered: handlers crash. Suggested solution is
to add a new primitive:
{{{
when: Type discoveredAs: { |service, realType|
// realType refers to the exported type tag, for which it holds that:
// realType.isSubtypeOf(Type)
}
}}}
Original issue reported on code.google.com by [email protected]
on 23 Jun 2010 at 8:06
Change the lookup rules such that a failed lexical lookup is not treated like
an exception, but is
rather transformed into a method invocation on self (cfr. Newspeak by Gilad
Bracha). The advantage
there is that a) if you ‘forget’ the self, the method will still be invoked
b) there is more opportunity
for moving code in between lexical and dynamic scope without changes in calling
code. Lexical
scope still has precedence over dynamic scope! This means that we still
maintain the “security”
advantage that if the identifier is lexically visible, it will be that
identifier that will be found, and no
dynamic child can override this behaviour.
See also:
On the Interaction of Method Lookup and Scope with Inheritance and Nesting:
http://dyla2007.unibe.ch/?download=dyla07-Gilad.pdf
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 2:10
What steps will reproduce the problem?
1.I wanted to try implicit reflection on actor as follows.
def actor := reflectOnActor();
actor.becomeMirroredBy: (extend: actor with: {
def createMirror(obj){
extend: super.createMirror(obj) with: {
def addSlot(x){
system.println("you cannot add.");
};
}
};
});
2. above code worked well,but when I typed "ReflectOnActor()" after this,
interpreter freezed. Here is error log.
Exception in thread "Event Loop The Read-Eval-Print Loop"
java.lang.reflect.Unde
claredThrowableException
at $Proxy0.toString(Unknown Source)
at edu.vub.at.IAT.evalAndPrint(IAT.java:520)
at edu.vub.at.IAT$ReadEvalPrintLoop.execute(IAT.java:137)
at
edu.vub.at.actors.eventloops.EventLoop$EventProcessor.run(EventLoop.j
ava:269)
Caused by: edu.vub.at.exceptions.XIllegalOperation: Detected illegal
invocation
of toString: sharing via Java level of object <obj:15293014{createMirror}>
at edu.vub.at.objects.coercion.Coercer.invoke(Coercer.java:152)
... 4 more
What version of the product are you using? On what operating system?
at2dist080509, the newest one. I executed it in Linux(Ubuntu8.04)
I don't know it is a bug or feature but it looks like strange to me.
Thanks.
Original issue reported on code.google.com by [email protected]
on 17 Jul 2009 at 5:13
When performing e.g. ''def o.x := 5'' and ‘x’ was already lexically visible
in the scope of ‘o’, should
this definition become visible, or should all references to ‘x’ in the
scope of o remain bound to the
lexically visible x?
Currently, the external definition will ‘shadow’ the lexically visible
‘x’. Using lexical addressing
might solve such issues, by early-binding the name to the lexically visible
value. Another trick is to
annotate externally added fields/methods. Another way is to have two maps and
method
dictionaries: one for internals and one for externals.
Care has to be taken that import is then not defined in terms of external
method definitions, as
these will definitely not be lexically visible, which is often the purpose of
using import.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 1:29
What steps will reproduce the problem?
1. e.g. parsing "if:then:else:( true, {} , {} )"
What is the expected output? What do you see instead?
The native function equivalent to keyworded functions such as if: () then: {}
else: {} cannot be
parsed. Since these keyworded functions should be syntactic sugar for the
native functions, I would
expect the native functions to be usable too.
Original issue reported on code.google.com by [email protected]
on 6 May 2010 at 9:33
What steps will reproduce the problem?
It don't seem to be reproducible anymore in the trunk after commit 2519.
It was reproducible before in the net-refactor branch sometimes.
It was also reproducible if AT in used in virtual private networks (e.g. if
your laptop uses VMWare software).
What is the expected output? What do you see instead?
Exception in thread "pool-3-thread-1" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:111)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1847)
at java.io.ObjectOutputStream$BlockDataOutputStream.write(ObjectOutputStream.java:1818)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1302)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at edu.vub.at.actors.net.comm.net.NetCommunicationBus.sendSynchronousUnicast(NetCommunicationBus.java:511)
at edu.vub.at.actors.net.cmd.CMDTransmitATMessage.send(CMDTransmitATMessage.java:66)
at edu.vub.at.actors.natives.FarReferencesThreadPool$TransmissionEvent.process(FarReferencesThreadPool.java:117)
at edu.vub.at.actors.natives.FarReferencesThreadPool$1.process(FarReferencesThreadPool.java:168)
at edu.vub.at.actors.natives.FarReferencesThreadPool$Handle.run(FarReferencesThreadPool.java:86)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
Please use labels and text to provide additional information.
This issue seems to be solved by the solution in issue#44
Original issue reported on code.google.com by [email protected]
on 10 Dec 2010 at 1:02
What steps will reproduce the problem?
1. Modify the creation of global lexical scope as follows:
private static NATObject createGlobalLexicalScope() {
NATObject root = new NATObject(OBJLexicalRoot._INSTANCE_) {
// override meta_pass to avoid the creation of a far reference
// when the root object gets parameter passed.
public ATObject meta_pass() throws InterpreterException {
return createSerializedLexicalRoot();
}
};
return root;
}
2. Run an AT application in Android.
What is the expected output? What do you see instead?
You will get an java.lang.StackOverflowError during the serialization of an
NATASyncMessage caused by the serialization of Evaluator.
Please use labels and text to provide additional information.
Original issue reported on code.google.com by [email protected]
on 10 Dec 2010 at 12:24
Next to the == operator, which defines equality through identity, we should
introduce an
operator = which defines structural equality (cfr. eq? versus equal? in
Scheme). e.g. [2,3] is not
== to another [2,3] table, but [2,3] should be = to [2,3]
== is already implemented and falls back on Java’s equals method, which in
turn falls back on
Java’s == operator. Structural equality implies deep equality. For ‘leaf’
objects like symbols,
numbers, etc., deep equality is identity. For ‘compound’ objects like
tables, all elements of the
tables must be deep equal.
This raises the question whether objects should support = and what it means for
them. Objects
can be considered as maps from symbols to values, so two objects are equal if
they map the
same symbols to equal values. The problem here is that performing deep equality
like this is
both A) very costly B) dangerous because it is a graph-traversal (have to keep
track of already
visited objects? even for tables, consider: t[1] := t)
Maybe in a first stage we should simply consider implementing = only on tables
to do a deep
comparison.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 2:04
Introduce the shorthand syntax fun<-(a,b,c) to denote fun<-apply([a,b,c]) such
that remote
references to closures are more easily invokable.
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 2:09
What steps will reproduce the problem?
1. def t[4] { def x := { nil } };
What is the expected output? What do you see instead?
Expected: a table with four (uninteresting) closures.
Result: an exception warning for the duplicate definition of x, when the
closure is ran for the
second time (i.e. t[1] with the above definition works properly). Consequently,
the body of a table
definition can currently not contain any definitions.
The closure is properly run in an activation call frame (i.e. after a t[1] x is
not visible in the outer
scope), yet it appears to be so that the same call frame is reused for
subsequent values.
Original issue reported on code.google.com by [email protected]
on 14 Feb 2009 at 6:26
When an object is being passed to an overloaded Java method, it should be
possible to take the type
tags of the object into account to further distinguish between possible
signatures. This way the
method needs not to be casted provided that the object that is passed has the
correct type tag.
Original issue reported on code.google.com by [email protected]
on 18 Feb 2009 at 4:46
In certain cases, a function can return multiple meaningful values, but one
value is used independently. Here, the programmer has to choose whether to
return a single value or a table of values.
When returning a table of values, the caller has to deconstruct the return
values manually, which can be bothersome if he only want to get hold of the
first result. Other languages solve this problem to a certain extend by having
output or reference variables.
This feature request proposes the introduction of a new composite language
value, akin to a table. Hence, it can be deconstructed using multi-definition
or multi-assignment. However, when assigned to a single variable, only the
first element is returned. The desired semantics is illustrated using long
division.
def div := x /- y;
def [div, mod] := x /- y;
In this case, the long division returns a tuple "<div, mod>". In the first
line, only the first return value is bound. To obtain the same result in case
the long division returns a table "[div, mod]", one would have to write.
def [div, _ ] := x /- y;
Note that in this context "_" does not have a special significance. The above
code example actually defines a variable named "_".
Original issue reported on code.google.com by [email protected]
on 25 Jan 2011 at 1:07
ELFarRef and NATRemoteFarRef keep a reference pointing each other. This keeps
the sendLoop
running in the ELFArRef because NATRemotFarRef is still alive.. although the
only pointer keeping
NATRemotFar alive is the onefrom ELFarRef. If we make this pointer weak then we
may have a
problem if NATRemotFar is only referenced by listeners registered for a network
event (since there
is a dead cycle between NATRemoteFarRef -> Handler (subscription) ->
NATFarRemoteFarREf)
The bugfix basically consist on keop strong the link between ELFarRef and
NATFarRemoteRef as
long as there are any clients registered for disconnection, reconnection or
takenOffline events. Once
no clients are using anymore the remote far ref (i.e. the reference is no
longer locally pointed in the
application) and there is any subscription, NATFarRemoteRef is eventually
collected by the Java gc.
Original issue reported on code.google.com by [email protected]
on 14 May 2008 at 8:15
Using semicolons to terminate method definitions is ugly. The parser should be
smart enough to
see that for:
def m() { ... }
def n() { ... }
the '}' token is the delimiter for between the two def statements. Currently,
one needs to write:
def m() { ... };
def n() { ... }
Original issue reported on code.google.com by [email protected]
on 16 Sep 2008 at 1:37
Reproducable in interpreter/trunk 645 on with InstantMessenger application
Create 2 instant messenger peers (e.g. lisa and stijn) and once they discover
each other, do in
the following commands:
IM peer - command
1. stijn - network.offline()
2. lisa - chat.talk("stijn", "hallo")
wait till the message "hallo" timed out.
3. stijn - network.online()
have a look to stijn IM console messages. You should get:
java.lang.NullPointerException
at edu.vub.at.actors.natives.ELFarReference.retractUnsentMessages(ELFarReference.java:269)
at
edu.vub.at.actors.natives.NATRemoteFarRef.meta_retractUnsentMessages(NATRemoteFa
rRef.java:
65)
at edu.vub.at.objects.natives.OBJLexicalRoot.base_retract_(OBJLexicalRoot.java:653)
at java.lang.reflect.Method.invoke(Native Method)
caused by clientleasedref.at when tries to retract the messages from far remote
reference.
Original issue reported on code.google.com by [email protected]
on 14 May 2008 at 8:09
What steps will reproduce the problem?
1. download at2dist080710.zip on a windows XP system
2. Unzip the Zip at2dist080710.zip
3. In the at2dist080710 directory double click one iat.bat
What is the expected output? What do you see instead?
Expected output, Ambienttalk interactive shell should start. Instead we get a
java exception error
What version of the product are you using? On what operating system?
dist080710
Please provide any additional information below.
To a fix this error you need to modify the iat.bat file (modified file attached)
1. change all the \lib\ to \jlib\ on the @set AT_CLASSPATH line
2. add the missing % after AT_HOME after deomo=%AT_HOME....on the @set
DEFAULT_OBJPATH line
Original issue reported on code.google.com by [email protected]
on 29 Jul 2010 at 12:27
Attachments:
What steps will reproduce the problem?
1. Define a greatest common divisor function as follows
def gcd(a,b){
if: (a == b) then: {a;} else: {
if: (a > b) then: {gcd(a - b,b)} else: {gcd(a,b - a)};
};
}
2. Run gcd(3,648), gcd(3,649) or gcd(648,3). Probably there are a number of
other possibilities
to cause the error, but for most pairs of values the function works (eg
gcd(4,648) is fine). This
was done in the UnitTest framework as follows
def sessionModule := object:{
def sessionTest(){
extend: /.at.unit.test.UnitTest.new("Session1Test") with: {
def testGcd() {
self.assertEquals(1, gcd(647,3));
};
};
};
};
Using a mac I get the following error:
Starting unit test Session1Test(4 tests)
Error in test testGcd: <exception:<type tag:ReflectionFailure>: Native method
base:if:then:else:
threw internal exception caused by null>
Native method base:if:then:else: threw internal exception caused by null
origin:
at if:then:else:(a.==(b), { a }, { if:then:else:(a.>(b), { gcd(a.-(b), b) }, {
gcd(a, b.-(a)) }) })
at gcd(a.-(b), b)
at if:then:else:(a.>(b), { gcd(a.-(b), b) }, { gcd(a, b.-(a)) })
at if:then:else:(a.==(b), { a }, { if:then:else:(a.>(b), { gcd(a.-(b), b) }, {
gcd(a, b.-(a)) }) })
at gcd(a.-(b), b)
at if:then:else:(a.>(b), { gcd(a.-(b), b) }, { gcd(a, b.-(a)) })
at if:then:else:(a.==(b), { a }, { if:then:else:(a.>(b), { gcd(a.-(b), b) }, {
gcd(a, b.-(a)) }) })
at gcd(a.-(b), b)
at if:then:else:(a.>(b), { gcd(a.-(b), b) }, { gcd(a, b.-(a)) })
at if:then:else:(a.==(b), { a }, { if:then:else:(a.>(b), { gcd(a.-(b), b) }, {
gcd(a, b.-(a)) }) })
at gcd(a.-(b), b)
at if:then:else:(a.>(b), { gcd(a.-(b), b) }, { gcd(a, b.-(a)) })
at if:then:else:(a.==(b), { a }, { if:then:else:(a.>(b), { gcd(a.-(b), b) }, {
gcd(a, b.-(a)) }) })
at gcd(a.-(b), b)
...
at testMethod(1)
at sessionModule.sessionTest.runTest()
Original issue reported on code.google.com by [email protected]
on 19 Mar 2009 at 1:35
Because of a bug in the implementation, sometimes a synchronous symbiotic
invocation is
mistaken for a future-type symbiotic invocation.
This happens when the method to be invoked is part of a java.util.EventListener
interface and
returns Object. The interpreter will then perform a future-type invocation,
while it should perform
a synchronous invocation.
Original issue reported on code.google.com by [email protected]
on 21 May 2008 at 3:27
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.