This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
at:introduction [2007/04/07 15:23] tvcutsem *added |
at:introduction [2008/07/15 12:19] tvcutsem * |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== What is AmbientTalk? | ||
- | {{: | ||
- | |||
- | For the programming language adepts: AmbientTalk is: | ||
- | * **dynamically typed**, which is **not** the same as being untyped: AmbientTalk //values// are typed, but // | ||
- | * object-oriented, | ||
- | * Like Smalltalk, Self and Ruby, AmbientTalk embraces the use of elegant and expressive **block closures** to achieve a level of reusability far exceeding that of Java or similar languages lacking true closures. | ||
- | * event-driven: | ||
- | * distributed: | ||
- | * **symbiotic**: | ||
- | |||
- | A word of warning, though: AmbientTalk is **not**: | ||
- | * a stable development platform. Rather, it is a research artifact used as a " | ||
- | * a secure distributed computing platform. | ||
- | * a customisable or language-neutral distributed computing platform. | ||
- | |||
- | ===== AmbientTalk in a nutshell ===== | ||
- | |||
- | Enough talking, let's delve into some AmbientTalk code by means of a simple example to see whether we can spark your interest in AmbientTalk. The demo program we're about to explore is an extremely simple instant messenger program. Each instant messenger runs on e.g. a PDA, laptop or cell phone. When peers join the ad hoc network, the instant messenger should issue a warning to the user that a new buddy is available for chatting. The user can then send simple text messages to that buddy. When peers leave the ad hoc network, the user should also be notified. Off we go. | ||
- | |||
- | ==== Designing the Instant Messenger ==== | ||
- | |||
- | Here is the skeleton code for the instant messenger: | ||
- | |||
- | < | ||
- | def createInstantMessenger(username) { | ||
- | def TextMessage := ...; // object encapsulating a text message | ||
- | def buddyList := ...; // maps buddy names to remote IM objects | ||
- | |||
- | // the interface to the IM for local objects | ||
- | def localInterface := object: { | ||
- | def sendTextMessage(to, | ||
- | }; | ||
- | // the interface to the IM for remote objects | ||
- | def remoteInterface := object: { | ||
- | def getName(replyTo) { ... }; | ||
- | def receiveTextMessage(textMessage, | ||
- | }; | ||
- | | ||
- | // engage in peer-to-peer service discovery | ||
- | defstripe InstantMessenger; | ||
- | export: remoteInterface as: InstantMessenger; | ||
- | whenever: InstantMessenger discovered: { |messenger| | ||
- | ... | ||
- | }; | ||
- | localInterface; | ||
- | }; | ||
- | </ | ||
- | |||
- | An instant messenger object is created by invoking a function called '' | ||
- | |||
- | Within the lexical scope of the '' | ||
- | |||
- | The '' | ||
- | |||
- | ==== Implementing the Instant Messenger ==== | ||
- | |||
- | Let's delve into the method bodies and see how the instant messengers engage in distributed communication: | ||
- | |||
- | < | ||
- | def createInstantMessenger(username) { | ||
- | def TextMessage := isolate: { | ||
- | def from := nil; | ||
- | def content := nil; | ||
- | def init(f,c) { | ||
- | from := f; | ||
- | content := c; | ||
- | }; | ||
- | def printMessage() { | ||
- | system.println(from + ": " + content) | ||
- | }; | ||
- | }; | ||
- | def buddyList := jlobby.java.util.HashMap.new(); | ||
- | ... | ||
- | }; | ||
- | </ | ||
- | |||
- | The '' | ||
- | |||
- | Also interesting is the initialisation code of the '' | ||
- | |||
- | Now let us delve into the details of the local interface object: | ||
- | |||
- | < | ||
- | def localInterface := object: { | ||
- | def sendTextMessage(to, | ||
- | def buddy := buddyList.get(to); | ||
- | if: (nil == buddy) then: { | ||
- | system.println(" | ||
- | } else: { | ||
- | def msg := TextMessage.new(username, | ||
- | buddy< | ||
- | def uponReceipt() { | ||
- | msg.printMessage(); | ||
- | } | ||
- | }); | ||
- | }; | ||
- | }; | ||
- | }; | ||
- | </ | ||
- | |||
- | The '' | ||
- | |||
- | < | ||
- | A small note for the language adepts: the '' | ||
- | < | ||
- | def if: cond then: cons else: alt { | ||
- | cond.ifTrue: | ||
- | }; | ||
- | </ | ||
- | This code should look familiar to Smalltalk/ | ||
- | |||
- | All curly braces in AmbientTalk denote first-class blocks, they never denote hard-wired syntax as in C or Java. | ||
- | </ | ||
- | |||
- | Let us look in more detail at the '' | ||
- | |||
- | < | ||
- | def remoteInterface := object: { | ||
- | def getName(replyTo) { replyTo< | ||
- | def receiveTextMessage(textMessage, | ||
- | textMessage.printMessage(); | ||
- | replyTo< | ||
- | }; | ||
- | }; | ||
- | </ | ||
- | |||
- | The protocol of the instant messenger is very straightforward: | ||
- | |||
- | Finally, here is the code for managing the discovery of instant messengers: | ||
- | |||
- | < | ||
- | defstripe InstantMessenger; | ||
- | export: remoteInterface as: InstantMessenger; | ||
- | whenever: InstantMessenger discovered: { |messenger| | ||
- | messenger< | ||
- | def receive(name) { | ||
- | if: (nil == buddyList.get(name)) then: { | ||
- | buddyList.put(name, | ||
- | system.println(" | ||
- | when: messenger disconnected: | ||
- | system.println(" | ||
- | }; | ||
- | when: messenger reconnected: | ||
- | system.println(" | ||
- | }; | ||
- | }; | ||
- | }; | ||
- | }); | ||
- | }; | ||
- | </ | ||
- | |||
- | The '' | ||
- | |||
- | Finally, notice how AmbientTalk allows you to deal with //partial failures//: you can register two kinds of // | ||
- | |||
- | ===== Conclusion ===== | ||
- | |||
- | You might wonder what is so special about the above example. After all, it is simply an application that sends simple strings across the network and displays them on the screen. But keep in mind all of the things you did **not** have to do: | ||
- | * no explicit thread management | ||
- | * not having to prevent data-level race conditions, not having to define locks, not having to debug the ensuing deadlocks | ||
- | * not having to manually serialize/ | ||
- | * not having to manage low-level socket connections | ||
- | * no need to setup a name server or similar lookup service | ||
- | * no annoying configuration files | ||
- | * not one XML document in sight | ||
- | * not having to manage complex buffering to ensure messages sent to disconnected objects are not lost | ||
- | * no need to write the boring Singleton design pattern to make your classes look like objects | ||
- | * no need to generate stubs, skeletons or other kinds of proxies to manage remote objects | ||
- | |||
- | Of course, we are not claiming that AmbientTalk is a good replacement for standards such as CORBA, which are much more flexible, at the cost of increasted complexity. AmbientTalk is simply a lightweight alternative for doing experimental research. | ||
- | |||
- | So, you read the introduction and are interested in all of the gory details of the language? In that case, you can go ahead and [[at: |