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/06 08:27] – * elisagat:tutorial:basic [2007/04/17 16:41] – * tvcutsem
Line 1: Line 1:
 <note> <note>
-**IN PROGRESS: FIRST DRAFT!!** +**This Tutorial is still under heavy construction!!**
- +
-- TODO: Adding Table splicing, quasi-quoting?+
 </note> </note>
 ====== Functional and Imperative Programming ====== ====== Functional and Imperative Programming ======
    
-This part of the tutorial shows AmbientTalk as a simple expression language with a minimum syntax which resembles very on Java script. This section mainly describes the basic features of the language, namely variables, functions and tables and control flow.+This part of the tutorial explains AmbientTalk as a simple expression language with a flexible syntax which resembles languages like Ruby, Python and Javascript. This section mainly describes the basic features of the language, namely variables, functionstables (i.e. arrays) and control flow primitives.
  
 ===== Variables ===== ===== Variables =====
    
-As usual, one can define, assign and refer to a variable. Variable definitions are made with the keyword **def**. Note that AmbientTalk is a dynamically typed language sovariables do not have a type but, they just contain values.+As usual, one can define, assign and refer to a variable. Variable definitions are made with the keyword **def**. Note that AmbientTalk is a dynamically typed languageso variables do not have a type but can contain any value.
  
-In the examples we use the interactive AmbientTalk shell (iat) where the input and output prompt are represented by > and >> respectively. +In the examples we use the interactive AmbientTalk shell (iat) where the input and output prompt are represented by > and <code>>></code> respectively. 
  
 <code> <code>
Line 21: Line 19:
 </code> </code>
  
-Variable definitions can be combined with assignments as shown aboveAs in Pico, assignments uses the ":=" operator. Note that there must be an space between the variable and the ":=" operator in order for the parse to resolve the ambiguity between a keyword message and a assignment, e.g. ":= 1" is understood as an assignment while "a:" as a keyword. We will further elaborate on keywords in the following sections.+Variable definitions can include an initialization expression that immediately initializes the variableVariable assignment is performed by means of the well-known ":=" operator. AmbientTalk supports assignment to multiple variables as a single assignment expression. For this to work, the number of variable names on the left hand side of ":=" must match the number of expressions on the right hand side of ":=". A typical application of this is to swap the values of two variables more easily:
  
-An assignment consists of one or more expressions, providing that the number of expressions on the right hand side match the number of variables on the left hand side. This allows a permutation of variables such as: 
 <code> <code>
 >[x, y] := [ y, x ] >[x, y] := [ y, x ]
 >>[7,5] >>[7,5]
 </code> </code>
-Reference is just done by evaluating the variable. + 
 +As we will explain later, the ''[y,x]'' syntax simply denotes a literal table (a.k.a. an array). 
 + 
 +The variable name is used to refer a variable. The variable is evaluated when referenced.  
 +<code> 
 +>x 
 +>>7 
 +</code> 
 + 
 +<note> 
 +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>
  
 ===== Tables ===== ===== Tables =====
Line 46: Line 54:
 Although there is no special constructor for definition of multidimensional tables, a table entry can contain another table. This is internally stored as a unidimensional table whose entries are other tables. Although there is no special constructor for definition of multidimensional tables, a table entry can contain another table. This is internally stored as a unidimensional table whose entries are other tables.
 <code> <code>
->def vocals := ["a", "e", "i", "o", "u"]+>def vowels := ["a", "e", "i", "o", "u"]
 >>["a", "e", "i", "o", "u"] >>["a", "e", "i", "o", "u"]
->table[3] := vocals+>table[3] := vowels
 >>[1, 2, ["a", "e", "i", "o", "u"], 4, 5] >>[1, 2, ["a", "e", "i", "o", "u"], 4, 5]
 >table[3][2] >table[3][2]
Line 54: Line 62:
 </code> </code>
  
-As shown in the definition of the varible //vocals//, evaluating a series of comma-separated abstract grammar values between square brackets (aka a tabulation) results in a table.+As shown in the definition of the varible //vowels//, evaluating a series of comma-separated data types between square brackets (aka a tabulation) results in a table.
  
 <code> <code>
Line 61: Line 69:
 </code> </code>
  
-=== Table Splicing ===+==== Table Splicing ====
  
-TODO!+AmbientTalk provides the operator @ to splice tables into surrounding table expressions.  
 +<code> 
 +>[1,@[2,3],4] 
 +>>[1, 2, 3, 4] 
 +>[1, @[2,[3]], [4], @[5], @[], 6] 
 +>>[1, 2, [3], [4], 5, 6] 
 +</code> 
 + 
 +The splicing operator can be also used for matching table elements as shown below. 
 +<code> 
 +>def [first, @rest] := [1,2,3,4] 
 +>>[1, 2, 3, 4] 
 +>rest 
 +>>[2, 3, 4] 
 +</code>
  
 ===== Functions ===== ===== Functions =====
Line 112: Line 134:
 This example also illustrates how a function can be made private by means of lexical scope. Variables and functions defined locally to functions are only visible in the scope of the function where there were defined. Note that local //inner// function is only visible inside the //fac// function and its nested scopes. Thus, calling //fac.inner(2,3)// will return a lookup failure error. This example also illustrates how a function can be made private by means of lexical scope. Variables and functions defined locally to functions are only visible in the scope of the function where there were defined. Note that local //inner// function is only visible inside the //fac// function and its nested scopes. Thus, calling //fac.inner(2,3)// will return a lookup failure error.
    
-=== Variable-Length Argument Functions ===+==== Variable-Length Argument Functions ====
  
-You can create functions that take an arbitrary  number of arguments by means of the splicing operator **@** as shown below:+You can create functions that take an arbitrary number of arguments by means of the splicing operator **@** which splices the table containing the parameters into the argument list.
 <code> <code>
 >def sum(@args){ {  >def sum(@args){ { 
Line 125: Line 147:
 </code> </code>
  
-When the //sum// function is called, the arguments are passed to the function in a table called //args// which can also be modified inside the body of the function. An alternative definition of the //sum// function follows:+When the //sum// function is called, the //args// table is spliced and passed as the argument list to the function. Note that the //args// table can also be modified inside the body of the function.  
 + 
 +Alternatively, we could define the //sum// function to take at least two numbers as shown below:
 <code> <code>
 >def sum(a, b, @rest){ {  >def sum(a, b, @rest){ { 
Line 136: Line 160:
 </code> </code>
  
-In this example the //sum// function accepts an arbitrary number of arguments as long as two arguments, //a// and //b//, are supplied. //a// and //b// are thus considered as mandatory arguments. A function can also declare optional arguments as shown below:+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. 
 <code> <code>
 >def incr( number, step := 1){ number + step} >def incr( number, step := 1){ number + step}
Line 190: Line 216:
 >def square := { |x| x * x } >def square := { |x| x * x }
 >><closure:lambda> >><closure:lambda>
->square(1,2+>square(3
->>3+>>9
 </code> </code>
  
 ===== Keywords ===== ===== Keywords =====
- 
  
 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: 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:
Line 206: Line 231:
  
  
-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. This section shows some examples how to manipulate the basic types. The complete list of methods can be found in the language reference.+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.
  
 ==== Numerical data types ==== ==== Numerical data types ====
Line 253: Line 278:
 >"ambienttalk".explode() >"ambienttalk".explode()
 >>["a", "m", "b", "i", "e", "n", "t", "t", "a", "l", "k"] >>["a", "m", "b", "i", "e", "n", "t", "t", "a", "l", "k"]
->"one, two, three".split(", ")+>"one, two, three".split(",")
 >>["one", "two", "three"] >>["one", "two", "three"]
->"ambienttalk".replace: "[aeiou]" by: { |vowel| vowel.toUpperCase() }+>"ambienttalk".replace: "[aeiou]" by: { 
 + |vowel| vowel.toUpperCase()  
 +}
 >>"AmbIEnttAlk" >>"AmbIEnttAlk"
 >"A".toLowerCase() >"A".toLowerCase()
Line 273: Line 300:
 ==== Tables ==== ==== Tables ====
    
 +
 +We have already introduce how to define tables. Let us now focus on how to manipulate them with the native methods provided by the table object.
 +<code>
 +>[1,2,3].filter: {|e| e != 2 }
 +>>[1, 3]
 +>[1,2,3].map: { |i| i + 1 }
 +>>[2, 3, 4]
 +>def vowels := ["a", "e", "i", "o", "u"]
 +>>["a", "e", "i", "o", "u"]
 +>vowels.length
 +>>5
 +>vowels.at(1)
 +>>"a"
 +>vowels.atPut(1, "z")
 +>>"z"
 +>vowels
 +>>["z", "e", "i", "o", "u"]
 +>vowels.select(2,5).implode()
 +>>"eio"
 +>vowels.isEmpty()
 +>>false
 +</code>
 +
 +Tables also support some useful iterator methods as shown below.
 +
 +<code>
 +>def sum:= 0; 
 +>>0
 +>[1,2,3].each: { |i| sum := sum + i }
 +>>nil
 +>sum
 +>>6
 +>def sumNnum (@args) {
 +  args.inject: 0 into: { |total, next| total + next}
 +}
 +>><closure:sumNnum>
 +>sumNnum(1,2,3)
 +>>6
 +</code>
  
 ==== Booleans ==== ==== Booleans ====
Line 300: Line 366:
  
 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. 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.
- 
  
 ===== Control Flow Structures ===== ===== Control Flow Structures =====
Line 321: Line 386:
      def pivot := table[(left+right) /- 2];      def pivot := table[(left+right) /- 2];
      def save := nil;      def save := nil;
-     while: { left <= right } do: {+        while: { left <= right } do: {
      while: { cmp(table[left], pivot) } do: {       while: { cmp(table[left], pivot) } do: { 
                 left := left + 1                  left := left + 1 
at/tutorial/basic.txt · Last modified: 2020/02/09 22:05 by elisag