This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
at:tutorial:multiparadigm [2007/06/19 11:53] tvcutsem * |
at:tutorial:multiparadigm [2011/06/07 18:29] tvcutsem *minor |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== On Scoping, Closures, Methods and Messages ====== | ||
- | < | ||
- | |||
- | This tutorial chapter goes into a bit more detail on the subtle interplay between AmbientTalk' | ||
- | |||
- | ===== Lexical Scope vs Object Scope ===== | ||
- | |||
- | AmbientTalk distinguishes between two kinds of scopes: | ||
- | - the **lexical scope**, which is the set of all variables that are lexically visible in the program text. In other words: all variables in an enclosing scope are part of the lexical scope of the enclosed (nested) scope. | ||
- | - the **object scope**, which is delimited by a chain of delegating objects. When sending a message to an object, the object and its parent objects delimit the scope in which the message is looked up. | ||
- | |||
- | The rules for distinguishing which scope to use when resolving an identifier are straightforward: | ||
- | - Unqualified access to a variable, e.g. '' | ||
- | - Qualified access to a variable, e.g. '' | ||
- | |||
- | These rules also hold for method invocation: the invocation '' | ||
- | |||
- | Probably the most important conseqence of these rules is that great care has to be taken when an object accesses its own fields or methods. It can now do so in two ways. For example: | ||
- | |||
- | < | ||
- | def o := object: { | ||
- | def x := 5; | ||
- | def getStatic() { x }; | ||
- | def getDynamic() { self.x }; | ||
- | } | ||
- | </ | ||
- | |||
- | In the code snippet above, '' | ||
- | |||
- | < | ||
- | def o2 := extend: o with: { | ||
- | def x := 6; | ||
- | } | ||
- | </ | ||
- | |||
- | This program behaves as follows: | ||
- | < | ||
- | > | ||
- | >> 5 | ||
- | > | ||
- | >> 5 | ||
- | > | ||
- | >> 5 | ||
- | > | ||
- | >> 6 | ||
- | </ | ||
- | |||
- | As can be derived from the rules defined above, the access to '' | ||
- | |||
- | < | ||
- | For many object-oriented programmers, | ||
- | </ | ||
- | |||
- | The distinction between '' | ||
- | |||
- | Second, the difference between early and late binding offers objects a very fine-grained control over what field and method accesses may be trapped and overridden by child objects. For example, in the code snippet above, '' | ||
- | |||
- | ==== Nesting Objects ==== | ||
- | |||
- | AmbientTalk exploits its lexical scoping rules to the fullest extent by allowing as much program elements as possible to be nested. For example, it is possible to lexically nest objects within other objects, or even to nest functions within other functions. In this section, we describe how nested objects interact with the scoping rules presented above. | ||
- | |||
- | One of the most appealing use cases for nesting objects is that it allows a very secure kind of //sharing// between objects: all objects that are nested within another object have the privilege of all sharing the same lexical scope. This form of sharing is much more secure that sharing data via delegation, because the set of objects sharing the scope is statically fixed. In the [[www.erights.org|E language]], such nested objects are called [[http:// | ||
- | |||
- | As an example, the following code snippet defines a '' | ||
- | |||
- | < | ||
- | def cell := object: { | ||
- | def contents := nil; | ||
- | def reader := object: { | ||
- | def read() { contents } | ||
- | }; | ||
- | def writer := object: { | ||
- | def write(x) { contents := x } | ||
- | }; | ||
- | } | ||
- | </ | ||
- | |||
- | The advantage of having defined '' | ||
- | |||
- | < | ||
- | distrustedFunction(cell.reader); | ||
- | </ | ||
- | |||
- | The '' | ||
- | |||
- | ==== Methods vs Closures ==== | ||
- | |||
- | ==== External Methods ==== | ||
- | |||
- | ===== First-class Methods ===== | ||
- | |||
- | ===== First-class Messages ===== |