User Tools

Site Tools


at:tutorial:basic

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
at:tutorial:basic [2007/04/17 17:04] tvcutsemat:tutorial:basic [2007/06/25 21:03] tvcutsem
Line 34: Line 34:
 </code> </code>
  
-<note>+<note important>
 When using the '':='' assignment operator, beware of the following syntactic annoyance: the expression ''a := 1'' denotes an assignment to the variable ''a'', while ''a:= 1'' is misunderstood by the parser as ''a: = 1'', which is the invocation of a keyworded message named ''a:''. Keyworded message sends will be explained later on in this chapter. Hence, as a general rule, don't forget to always put a space between the variable name and the '':='' operator. When using the '':='' assignment operator, beware of the following syntactic annoyance: the expression ''a := 1'' denotes an assignment to the variable ''a'', while ''a:= 1'' is misunderstood by the parser as ''a: = 1'', which is the invocation of a keyworded message named ''a:''. Keyworded message sends will be explained later on in this chapter. Hence, as a general rule, don't forget to always put a space between the variable name and the '':='' operator.
 </note> </note>
Line 148: Line 148:
 This example also illustrates how a function can be made "private" by means of lexical scoping rules. Variables and functions defined locally to functions are only visible in the scope of the function where there were defined. Note that the local ''inner'' function is only visible inside the ''fac'' function and its nested scopes. This example also illustrates how a function can be made "private" by means of lexical scoping rules. Variables and functions defined locally to functions are only visible in the scope of the function where there were defined. Note that the local ''inner'' function is only visible inside the ''fac'' function and its nested scopes.
    
 +
 ==== Variable-Length Argument Functions ==== ==== Variable-Length Argument Functions ====
  
Line 177: Line 178:
 In that case, the //sum// function still accepts an arbitrary number of arguments as long as two arguments are supplied. //a// and //b// are considered as mandatory arguments of the argument list.  In that case, the //sum// function still accepts an arbitrary number of arguments as long as two arguments are supplied. //a// and //b// are considered as mandatory arguments of the argument list. 
  
-A function can also declare optional arguments as shown below. Optional arguments can be omitted in a function call. Internally, the default value provided in their definition is passed as the argument to the function. +A function can also declare optional arguments as shown below. Optional arguments can be omitted in a function call. If this is the case, the default expression provided in their definition is evaluated and passed as argument to the function instead.
 <code> <code>
 >def incr( number, step := 1){ number + step} >def incr( number, step := 1){ number + step}
Line 186: Line 187:
 >>6 >>6
 </code> </code>
 +
 +As is customary in languages with the above parameter passing semantics, AmbientTalk requires mandatory parameters to be defined //before// optional parameters, which should in turn be defined //before// a variable-argument parameter, if any.
  
 ===== Closures ===== ===== Closures =====
Line 203: Line 206:
 </code> </code>
  
-This example also illustrates how a function can make public some of its local fields or functions by returning them as its return value. The get and set could be then passed as arguments to other functions such as //trustedFunction(get,set)// and  //distrustedFunction(get)//+This example also illustrates how a function can make public some of its local fields or functions by returning them as its return value. The ''get'' and ''set'' operations can then be passed separately throughout the application, e.g. an application module that has read-only access to ''val'' only receives the ''get'' closure.
  
 ===== Blocks ===== ===== Blocks =====
  
-In AmbientTalk, blocks are merely syntactic sugar for anonymous closures (aka lambdas).  Blocks are creating using the {} braces in the form of:+In AmbientTalk, blocks are merely syntactic sugar for the creation of anonymous closures (also known as //lambdas//).  Blocks are creating using curly braces in the form of:
 <code> <code>
 { |<parlist>| <body> } { |<parlist>| <body> }
 </code> </code>
-If the block do not require any parameter, the |<parlist>| can be omitted.  Consider a basic block to sum two numbers:+ 
 +If the block does not require any parameter, the |<parlist>| can be omitted. Consider a basic block to sum two numbers:
 <code> <code>
->{| a, b| a+ b} (3,2)+>{|a, b| a+ b}(3,2)
 >>5 >>5
 </code> </code>
 Note that the argument list passed to the block can define the different types of arguments previously explained. Note that the argument list passed to the block can define the different types of arguments previously explained.
 <code> <code>
->{|a, b, @rest| +>def sum := {|a, b, @rest| 
    def total := a + b;     def total := a + b; 
    foreach: { |el| total := total + el} in: rest; total     foreach: { |el| total := total + el} in: rest; total 
- }(1,2,3)+ }; sum(1,2,3)
 >>6 >>6
 </code> </code>
Line 227: Line 231:
 This example also illustrates that blocks are also used to iterate over enumerations, such as in //foreach: {} in: table//. This example also illustrates that blocks are also used to iterate over enumerations, such as in //foreach: {} in: table//.
  
-AmbientTalk doesn’t support function assigment. Howeverone can assign blocks to variables. In order to call the block the name of the variable must be usedIf the block defined parameters, these are required to the call as argument listWhat follows is an example of such manipulation:+<note> 
 +AmbientTalk borrows its block syntax from languages like Smalltalk and Selfwhere the role of the curly braces is played by square brackets, i.e. ''[ args | body ]''. In AmbientTalk, the ''<parlist>'' is only used to denote parameters to the block, not also for temporary variables as in Smalltalk. 
 +</note> 
 + 
 +===== Keywords ===== 
 + 
 +AmbientTalk supports keyworded messages, as in Smalltalk and Self. We have already seen some examples of keyword messages in the previous sections such as the ''foreach:in:'' call. Here is how to define a simple ''map:onto:'' function that takes a closure as input and applies the closure to each element of a table: 
 <code> <code>
->def square := { |x| x * x +>def map: clo onto: tbl { 
->><closure:lambda> +  def i := 0; 
->square(3) +  def mapped[tbl.length] { 
->>9+    clo(tbl[i:=i+1]) 
 +  }; 
 +
 +>> <closure:map:onto:>
 </code> </code>
  
-===== Keywords =====+It can be invoked as follows: 
 +<code> 
 +>map: square onto: [1,2,3] 
 +>>[1,4,9] 
 +</code>
  
-AmbientTalk supports keyword messages. We have already seen some examples of keyword messages in the previous sections such as the foreach structure. In AmbientTalk keywords are transformed by the parser into functions in the form:+In AmbientTalk keyworded functions and function calls are actually syntactic sugar. They are transformed by the parser into their canonical equivalent. Hence:
 <code> <code>
 def foo: arg1 bar: arg2 {...} def foo: arg1 bar: arg2 {...}
-def foo:bar:(arg1,arg2){..}+</code> 
 +is transformed into: 
 +<code> 
 +def foo:bar:(arg1,arg2){...}
 </code> </code>
  
-===== Native Data Types =====+However, it is impossible to directly call or define a keyworded function in a canonical style.
  
 +===== Native Data Types =====
  
-The basic types in AmbientTalk are numbers, fractions, text, tables and booleans. In fact, these data types are nothing but objects and as such, they respond to a variety of native methods. Objects will be the subject of the next chapter of the tutorial. This section explains the basic data types and includes some examples how to manipulate them. The complete list of methods can be found in the language reference.+The basic data types in AmbientTalk are numbers (i.e. integers), fractions (i.e. double precision floating point numbers), text (i.e. strings), tables (i.e. arrays) and booleans. In fact, instances of these data types are nothing but objects and as such, they respond to a variety of native methods. Objects will be the subject of the next chapter of the tutorial. This section explains the basic data types and includes some examples how to manipulate them. The complete list of methods can be found in the language reference.
  
 ==== Numerical data types ==== ==== Numerical data types ====
  
-AmbientTalk supports numbers and fractions which represent what other languages call integers and floating point numbers, respectively.  +AmbientTalk supports numbers and fractions which represent what other languages call integers and double precision floating point numbers, respectively.
  
-Note that since numerical types are objects in AmbientTalk, the traditional operators +,-,*,/, >, <, <=, >=, =, !=  are nothing but syntactic sugar for method invocations. Therefore,  //1+1// is internally translated into //1.+(1)//. Unary operators are just applications, e.g. //-5// is internally translated into //-(5)//. What follows are some basic examples of manipulations with numeric types:+Note that since numerical types are objects in AmbientTalk, the traditional operators %%+,-,*,/, >, <, <=, >=, =, !=%%  are nothing but syntactic sugar for method invocations. Therefore,  ''1+1'' is internally translated into ''1.+(1)''. Unary operators are just applications, e.g. ''-5'' is internally translated into ''-(5)''. What follows are some basic examples of manipulations with numeric types:
 <code> <code>
 >1.inc() >1.inc()
 >>2 >>2
->-1.abs() 
->>1 
 >1.cos() >1.cos()
 >>0.5403023058681398 >>0.5403023058681398
Line 271: Line 291:
 >>2 >>2
 </code> </code>
 +
 +Beware of the precedence rules for function application versus method invocation, which may lead to unexpected results, e.g.:
 +<code>
 +>-1.abs()
 +>>-1
 +</code>
 +This code is interpreted as ''-(1.abs())'', hence the result.
  
 Numbers also support some useful iterator methods such as: Numbers also support some useful iterator methods such as:
Line 357: Line 384:
 ==== Booleans ==== ==== Booleans ====
    
- +As any native type, booleans are objects so, they respond to keyword messages such as:
-AmbientTalk supports infix operators for booleans as &, | and !. As any native type, booleans are objects so, they respond to keyword messages such as:+
 <code> <code>
 <booleanexpr>.ifTrue: { ...}  <booleanexpr>.ifTrue: { ...} 
Line 366: Line 392:
 </code> </code>
  
-**=** and **!=** are the infix operators for equality and inequality. **true** and **false** are the boolean constant objects. What follows is some basic examples of boolean manipulation:+''='' and ''!='' are the infix operators for equality and inequality. The prefix operator ''!'' represents logical negation. ''true'' and ''false'' are the prototypical boolean singleton objects. What follows is some basic examples of boolean manipulation:
 <code> <code>
 >(0 < 1).ifTrue: { 0 }  >(0 < 1).ifTrue: { 0 } 
Line 380: Line 406:
 </code> </code>
  
-Boolean infix operators such as & and | are not shortcut. Thus, both arguments will be evaluated. For lazy evaluation, you should use the natives methods. For example, false.and: { 1/0 } will return false without executing the second argument.+Compound boolean expressions can be created by means of a boolean's ''and:'' and ''or:'' methodswhich both take a zero-argument closure as argument. For example, ''false.and: { 1/0 }'' will return ''false''. The block is not applied because a logical //and// with ''false'' always fails.
  
-===== Control Flow Structures =====+===== Control Flow Constructs =====
  
-Control flow structures are defined in the lexical root of AmbientTalk. The lexical root is an object containing globally visible native methods. We have already seen in the previous sections examples of usage of the foreach and if/then structures. The complete list of traditional control flow structures defined in AmbientTalk is shown below:+Control flow constructs are defined in the lexical root of AmbientTalk. The lexical root is an object containing globally visible native methods (i.e. it is the top-level environment). We have already seen in the previous sections examples of use of the foreach and if/then structures. list of traditional control flow structures defined in AmbientTalk is shown below:
 <code> <code>
-if: booleanCondition then: consequent } +if: booleanCondition then: consequent 
-if: booleanCondition then: consequent else: alternative } +if: booleanCondition then: consequent else: alternative 
-while: condition do: body } +while: condition do: body 
-foreach: { |v| body } in: table ] +foreach: iteratorclosure in: table 
-do: body if: condition +do: body if: condition 
-do: body unless: condition+do: body unless: condition
 </code> </code>
 +
 +Note that ''condition'' in the ''while:do:'' construct denotes a //closure// that should return a boolean value. It needs to be a closure because the code is evaluated repeatedly until the closure returns false. ''body'', ''consequent'', ''alternative'' all denote zero-argument closures.
 +
 An example of usage for some of these structures is shown below in the definition of the sort function. An example of usage for some of these structures is shown below in the definition of the sort function.
 <code> <code>
Line 427: Line 456:
 >>[2, 4, 5, 6, 8, 37] >>[2, 4, 5, 6, 8, 37]
 </code> </code>
 +
 +AmbientTalk has no ''return'' statement. To achieve a similar jump in the control flow, see the section on [[:at:tutorial:modular#escaping_continuations|escaping continuations]].
at/tutorial/basic.txt · Last modified: 2020/02/09 22:05 by elisag