|
|
# HelloWorld example in AmbientTalk
|
|
|
|
|
|
# Hello World in AmbientTalk
|
|
|
|
|
|
Traditionally, the "Hello world"-program is considered the simplest program that can be written in a programming language, thereby introducing the basic syntax and concepts of the language. So let's have some informal "Hello world"-fun in AmbientTalk!
|
|
|
|
|
|
We will build a small HelloPeers program, step by step. Unless you'd rather jump directly to the full code: [Hello Peers!] (#hello-peers).
|
|
|
|
|
|
## Hello Peer
|
|
|
|
|
|
AmbientTalk is a distributed programming language, designed to write peer-to-peer applications. So, rather than saying hello to the world, we'll say hello to the "peers" we discover around us.
|
|
|
|
|
|
Let's start by creating an object that represents a peer:
|
|
|
|
|
|
|
|
|
```
|
|
|
def me := object: {
|
|
|
def name := "Kevin";
|
|
|
def sayHello(peerName) {
|
|
|
system.println(peerName + " says hello!");
|
|
|
};
|
|
|
};
|
|
|
```
|
|
|
|
|
|
Now we have a variable `me` that points to an object that represents a peer. This object has one field `name` that contains the name of the peer. And we created a method `sayHello` on the object that can be used by another peer to say hello.
|
|
|
|
|
|
Locally accessing the fields and methods of this object is simple:
|
|
|
`me.name` returns the string "Kevin" and `me.sayHello("Dries")` prints: "Dries says hello!"
|
|
|
|
|
|
## Now for some distribution
|
|
|
|
|
|
First some logistics: by default, the network access is disabled in AmbientTalk. We bring the network up by simply calling:
|
|
|
|
|
|
```
|
|
|
network.online();
|
|
|
```
|
|
|
|
|
|
Time to say hello to the peers around us now. First, we need to announce that we are here, available to be said hello to:
|
|
|
|
|
|
```
|
|
|
deftype FriendlyPerson;
|
|
|
export: me as: FriendlyPerson;
|
|
|
```
|
|
|
|
|
|
What we just did is announce our presence in the network using the `export:as:` primitive. Therefore, we created a so-called typetag: `FriendlyPerson`. Just think of a typetag as a label we stick to our foreheads. Now, peers looking for "friendly people" can easily find us amongst the other creatures on the network.
|
|
|
|
|
|
At this point, other peers in the network can find us and call our `sayHello` method. Let's add some final code that allows us to discover other peers and say hello to them!
|
|
|
|
|
|
```
|
|
|
whenever: FriendlyPerson discovered: { |remotePeer|
|
|
|
remotePeer<-sayHello(me.name);
|
|
|
};
|
|
|
```
|
|
|
|
|
|
|
|
|
You can read this code as: "every time we discover something in the network that has `FriendlyPerson` sticked to its forehead, we greet it by calling its `sayHello` method with our name as argument".
|
|
|
|
|
|
Using `whenever:discovered:` we install a block of code that will be called every time a peer labeled `FriendlyPerson` is discovered in the network. The block of code receives one argument: a remote reference (or far reference) to the discovered peer, in our example this argument is bound to the variable `remotePeer`.
|
|
|
|
|
|
Using this reference we can access the fields and methods of the peer remotely. Since we contact the peer across the network, we cannot use the dot-operator. To access fields or invoke methods remotely, we use the `<-` operator.
|
|
|
|
|
|
## Hello peers!
|
|
|
|
|
|
The whole HelloPeers program should now look like this:
|
|
|
|
|
|
```
|
|
|
def me := object: {
|
|
|
def name := "Kevin";
|
|
|
def sayHello(peerName) {
|
|
|
system.println(peerName + " says hello!");
|
|
|
};
|
|
|
};
|
|
|
|
|
|
network.online();
|
|
|
|
|
|
deftype FriendlyPerson;
|
|
|
export: me as: FriendlyPerson;
|
|
|
|
|
|
whenever: FriendlyPerson discovered: { |remotePeer|
|
|
|
remotePeer<-sayHello(me.name);
|
|
|
};
|
|
|
```
|
|
|
|
|
|
## Running the example
|
|
|
|
|
|
Say there are three other peers on the same network as us, running this program. Then we would see as output:
|
|
|
|
|
|
```
|
|
|
"Dries says hello!"
|
|
|
"Andoni says hello!"
|
|
|
"Elisa says hello!"
|
|
|
```
|
|
|
|
|
|
All of these peers will see a line on their standard output (amongst the geetings from other peers) saying:
|
|
|
```
|
|
|
"Kevin says hello!"
|
|
|
```
|
|
|
|
|
|
![HelloPeers](HelloPeers.png)
|
|
|
|
|
|
## Source code
|
|
|
|
|
|
```
|
|
|
def me := object: {
|
|
|
def name := "Andoni";
|
|
|
def sayHello(peerName) {
|
|
|
system.println(peerName + " says hello!");
|
|
|
};
|
|
|
};
|
|
|
|
|
|
network.online();
|
|
|
|
|
|
deftype FriendlyPerson;
|
|
|
export: me as: FriendlyPerson;
|
|
|
|
|
|
whenever: FriendlyPerson discovered: { |remotePeer|
|
|
|
remotePeer<-sayHello(me.name);
|
|
|
};
|
|
|
|
|
|
system.println("peer name: " + me.name);
|
|
|
```
|
|
|
|
|
|
<img width=100px src="HelloPeersQR.png">
|
|
|
|
|
|
|
|
|
That's it for our very first distributed "Hello world"-program!
|
|
|
|
|
|
(To be continued with extensions of this example). |