User Tools

Site Tools


at:tutorial:modular

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
at:tutorial:modular [2007/04/22 17:26]
tvcutsem added
at:tutorial:modular [2013/05/17 20:24]
tvcutsem adjusted
Line 1: Line 1:
-====== Modular Programming ====== 
  
-<note> 
-This Tutorial is still under heavy construction! 
-</note> 
- 
-In this tutorial chapter, we introduce AmbientTalk's language features that have to do with writing //modular// programs. The term "modular" can be taken quite broadly in this context. By "modular" programming, we here mean programs hierarchically structured into multiple files and objects composed from multiple so-called "trait" objects. We also describe AmbientTalk's lightweight support for classifying objects and how this enables exception handling based on "types". 
- 
-===== Namespaces and the lobby ===== 
- 
-In AmbientTalk, programs are primarily partitioned into multiple files. Hence, a file can be regarded as the most coarse-grained module in an AmbientTalk system. Each file has its own namespace: a "global" variable is only globally visible in the file in which it has been defined. There is only one exception to this rule: definitions in the "init" file (which is by default the file ''at/init/init.at'' available in the system library) are considered global to all files. 
- 
-==== Namespaces ==== 
-In order for AmbientTalk programs to use code defined in other files, a file loading mechanism is required. AmbientTalk provides the concept of a namespace object to perform this task. A namespace object is an object which is internally connected to a directory path on the local file system (how a namespace object is tied to this path will be explained later). By accessing a namespace object's slots, files can be loaded. Consider, for example, a namespace object stored in the variable ''lib'' which is internally tied to the directory ''/home/ambienttalkuser/examples''. Also consider that in the ''examples'' directory, there exists a file named ''math.at'' with the following contents: 
- 
-<code> 
-object: { 
-  def factorial(n) { 
-    if: (n = 0) then:  { 
-      1 
-    } else: { 
-      n*factorial(n-1) 
-    } 
-  }; 
-  def fib(n) { 
-    if: (n <= 1) then: { 
-      n 
-    } else: { 
-      fib(n-1)+fib(n-2) 
-    } 
-  }; 
-}; 
-</code> 
- 
-This file can now be loaded by means of the ''lib'' namespace object as follows: 
-<code> 
-def mathModule := lib.math; 
-system.println(mathModule.factorial(5)); 
-</code> 
- 
-When the namespace object's ''math'' slot is accessed for the first time, the namespace object checks whether its encapsulated directory contains: 
-  * a file named ''math.at'' 
-  * a subdirectory named ''math'' 
-In this example, there exists a file ''/home/ambienttalkuser/examples/math.at''. In this case, the file is loaded and the result of evaluating the code in that file is bound to the ''math'' slot. Recall that the ''math.at'' file defined one object with two methods. The above code snippet shows how these methods can now simply be used in the context of another file. 
- 
-If the ''math'' slot is accessed a second time, the ''math.at'' file will not be loaded again. Rather, the ''math'' slot simply contains the return value from the loaded code. Hence, namespaces provide the desirable semantics that a file is loaded only the first time it is required. If the ''math.at'' file would not have existed, the call ''lib.math'' may still have succeeded if there would have existed a subdirectory named ''math'' in ''lib'''s directory. In that case, ''lib'''s ''math'' slot would be bound to a new namespace object encapsulating the directory ''/home/ambienttalkuser/examples/math''. 
- 
-<note> 
-By representing hierarchical directories as nested namespace objects, the AmbientTalk programmer can abstract over the actual files and directories of the underlying file system. For example, imagine that the designer of the ''math.at'' file later decides to change the file structure of his library by creating a directory named ''math'' and by placing the code of each function in a separate file (named ''factorial.at'' and ''fib.at''). The code defined above would not be affected: the expression ''lib.math'' would then evaluate to a namespace object for the ''math'' subdirectory, and the expression ''mathModule.factorial'' would load the file ''factorial.at'' which returns a closure that is immediately invoked. 
- 
-Obviously, this approach works both ways: if the library designer had started out organizing his project using subdirectories and multiple files, he can always restructure the library's file organization without breaking the interface to clients by replacing a subdirectory with an AmbientTalk file that evaluates to an object whose public slot names correspond to the file names of the original subdirectory. 
-<note> 
- 
-==== The lobby ==== 
- 
-We have yet to explain how namespaces are initially tied to directories. One possibility is to define a ''root'' variable which would be bound to the "/" directory (i.e. the root directory of the file system). However, to load the contents of the file ''/home/ambienttalkuser/examples/math.at'', this would require writing: 
-<code> 
-root.home.ambienttalkuser.examples.math 
-</code> 
- 
-The downside of such as scheme is that the absolute path name of the ''math.at'' file is hardcoded in the AmbientTalk application. If we would later decide to move the file, our AmbientTalk code using that file would be broken! To avoid these problems, AmbientTalk provides the ''lobby'' object. The ''lobby'' is an object defined in the top-level scope whose slots are bound to namespace objects. The names of the slots, and the directory paths of the namespace objects bound to them are not provided in AmbientTalk directly, but rather when starting the AmbientTalk interpreter. 
- 
-The [[at:tutorial:iat|interactive ambienttalk shell]] (''iat'') has a command-line parameter called the **object path**. This argument is a list of "name=path" entries separated by colons. For example, in order to create a namespace object called ''lib'' which is bound to ''/home/ambienttalkuser/examples'', it suffices to start ''iat'' as follows: 
- 
-<code> 
-iat -o lib=/home/ambienttalkuser/examples 
-</code> 
- 
-Whenever a new actor is created by the AmbientTalk interpreter, it uses the entries in the object path to initialize the ''lobby'' object of the actor. Hence, by starting up the interpreter as shown above, executing ''lobby.lib'' in any actor returns a reference to a namespace object bound to the ''examples'' directory. This effectively removes absolute path names from AmbientTalk source code and even enables you to quickly reconfigure AmbientTalk code to use other libraries by loading the code using another object path. 
- 
-<note> 
-AmbientTalk provides an alias for the ''lobby'' variable named ''/''. Hence, rather than writing ''lobby.lib'', it is also possible to write ''/.lib'' which is often more convenient, although perhaps a bit more cryptic. 
-</note> 
- 
-==== The current namespace ==== 
- 
-AmbientTalk provides a slot named ''~'' which is always bound to the "current namespace", the namespace in which the current file is contained. This is useful for loading files in a relative manner. For example, in the ''math.at'' file defined above, evaluating ''~'' would result in the ''lib'' namespace. Hence, if there would be a file named ''discretemath.at'' in the directory ''/home/ambienttalkuser/examples'', then the ''math.at'' file could load it by writing: 
- 
-<code> 
-def discreteMathModule := ~.discretemath; 
-</code> 
- 
-Loading a module this way is useful because the author of ''math.at'' does not necessarily know of the ''lib'' namespace. Also, using ''lobby.lib'' introduces the implicit requirement that an object path for ''lib'' must be given. The slot ''~'' is always well-defined, so using it does not introduce additional dependencies. 
- 
-===== Importing objects ===== 
- 
-explain: import native, using import for importing external file definitions. Warning: importing from namespaces 
- 
-===== Objects as traits ===== 
- 
-explain: using import as an object-composition mechanism: concepts behind traits (required/provided interface), aliasing, exclusion. 
- 
-===== Classifying objects using stripes ===== 
- 
-explain: what are stripes? what kind of objects are they, stripe subtyping, stripe test, what default stripes exist 
- 
-===== Exception Handling ===== 
- 
-explain: raise, try-catch and variants, first-class handlers, role of stripes, interface of an exception object 
at/tutorial/modular.txt ยท Last modified: 2013/05/17 20:24 by tvcutsem