at:tutorial:basic
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
at:tutorial:basic [2007/04/06 08:33] – * elisag | at:tutorial:basic [2007/07/05 11:44] – elisag | ||
---|---|---|---|
Line 1: | Line 1: | ||
< | < | ||
- | **IN PROGRESS: FIRST DRAFT!!** | + | **This Tutorial is still under heavy construction!!** |
- | + | ||
- | - Add quasi-quoting? | + | |
</ | </ | ||
====== Functional and Imperative Programming ====== | ====== Functional and Imperative Programming ====== | ||
- | This part of the tutorial | + | This part of the tutorial |
===== 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 so, variables do not have a type but, they just contain | + | 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, so variables do not have a type but can contain |
- | In the examples we use the interactive AmbientTalk shell (iat) where the input and output prompt are represented by > and >> | + | In the examples we use the interactive AmbientTalk shell (iat) where the input and output prompt are represented by > and %%>>%% respectively. |
< | < | ||
Line 21: | Line 19: | ||
</ | </ | ||
- | Variable definitions can be combined with assignments as shown above. As in Pico, assignments uses the ":=" | + | Variable definitions can include an initialization expression that immediately initializes the variable. Variable assignment is performed by means of the well-known '' |
- | An assignment consists of one or more expressions, | ||
< | < | ||
>[x, y] := [ y, x ] | >[x, y] := [ y, x ] | ||
>> | >> | ||
</ | </ | ||
- | Reference | + | |
+ | As we will explain later, the '' | ||
+ | |||
+ | The variable name is used to refer a variable. The variable is evaluated when referenced. | ||
+ | < | ||
+ | >x | ||
+ | >>7 | ||
+ | </ | ||
+ | |||
+ | <note important> | ||
+ | When using the '': | ||
+ | </ | ||
===== Tables ===== | ===== Tables ===== | ||
- | Indexed tables represent | + | The //table// is AmbientTalk' |
< | < | ||
- | def t[ <size> ] { <expression> } | + | def t[ <sizeexpression> ] { <initexpression> } |
</ | </ | ||
- | This means that the <expression> will be evaluated | + | This constructs a table, |
< | < | ||
>def z := 0 | >def z := 0 | ||
Line 44: | Line 53: | ||
</ | </ | ||
- | 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 | + | Although there is no special constructor for definition of multidimensional tables, a table entry can contain another table. This is internally stored as a one-dimensional |
< | < | ||
- | > | + | > |
>> | >> | ||
- | > | + | > |
>>[1, 2, [" | >>[1, 2, [" | ||
> | > | ||
Line 54: | Line 63: | ||
</ | </ | ||
- | 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 | + | As shown in the definition of the variable '' |
< | < | ||
Line 61: | Line 70: | ||
</ | </ | ||
- | === Table Splicing === | + | ==== Table Splicing |
- | TODO! | + | AmbientTalk provides the //splice operator// '' |
+ | < | ||
+ | > | ||
+ | >>[1, 2, 3, 4] | ||
+ | >[1, @[2,[3]], [4], @[5], @[], 6] | ||
+ | >>[1, 2, [3], [4], 5, 6] | ||
+ | </ | ||
+ | |||
+ | The splicing operator can be also used in the left-hand side of an assignment or definition to separate the head of a table with its rest elements, as shown below. | ||
+ | < | ||
+ | >def [first, @rest] := [1,2,3,4] | ||
+ | >>[1, 2, 3, 4] | ||
+ | >rest | ||
+ | >>[2, 3, 4] | ||
+ | </ | ||
===== Functions ===== | ===== Functions ===== | ||
- | As variables and tables, functions are defined with the keyword **def** in the form of: | + | Analogous to variables and tables, functions are defined with the keyword **def** in the form of: |
< | < | ||
def functionname( < | def functionname( < | ||
</ | </ | ||
- | The argument list is just a list of local variables which are always evaluated one by one from left to right. A basic function looks like this: | + | The argument list is just a list of local variables which are always evaluated one by one from left to right. Hence, AmbientTalk employs // |
< | < | ||
>def square (x) { x*x } | >def square (x) { x*x } | ||
Line 78: | Line 101: | ||
>>25 | >>25 | ||
</ | </ | ||
- | This example also illustrates | + | This example also illustrates |
< | < | ||
- | >def f(){nil} | + | >def f() { nil } |
>>< | >>< | ||
>f() | >f() | ||
>>nil | >>nil | ||
</ | </ | ||
- | The return value of a function is the result of the last statement | + | The return value of a function is the result of the last executed |
+ | |||
+ | < | ||
+ | A function definition is a statement. The body of a function | ||
+ | < | ||
+ | def funA() { | ||
+ | | ||
+ | } | ||
+ | def funB() { | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | The parser will complain saying that '' | ||
+ | </ | ||
- | Functions | + | Functions |
< | < | ||
>def counter := 0 | >def counter := 0 | ||
Line 101: | Line 137: | ||
>def fac(n) { | >def fac(n) { | ||
def inner(n, result) { | def inner(n, result) { | ||
- | if: (n =0) then: { result } else: { inner( n-1, n * result) | + | if: (n = 0) then: { result } else: { inner( n-1, n * result) |
}; | }; | ||
inner(n,1) | inner(n,1) | ||
Line 110: | Line 146: | ||
</ | </ | ||
- | This example also illustrates how a function can be made private by means of lexical | + | This example also illustrates how a function can be made "private" |
+ | |||
==== Variable-Length Argument Functions ==== | ==== Variable-Length Argument Functions ==== | ||
- | You can create functions that take an arbitrary | + | You can create functions that take an arbitrary number of arguments |
< | < | ||
- | >def sum(@args){ { | + | >def sum(@args) { |
def total := 0; | def total := 0; | ||
foreach: { |el| total := total + el } in: args; | foreach: { |el| total := total + el } in: args; | ||
- | total} | + | total |
+ | }; | ||
>>< | >>< | ||
> | > | ||
Line 125: | Line 163: | ||
</ | </ | ||
- | When the //sum// function is called, the arguments are passed to the function | + | When the //sum// function is called, the //args// table is spliced and passed |
+ | |||
+ | Alternatively, | ||
< | < | ||
>def sum(a, b, @rest){ { | >def sum(a, b, @rest){ { | ||
Line 136: | Line 176: | ||
</ | </ | ||
- | In this example | + | In that case, the //sum// 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. | ||
< | < | ||
>def incr( number, step := 1){ number + step} | >def incr( number, step := 1){ number + step} | ||
Line 145: | Line 187: | ||
>>6 | >>6 | ||
</ | </ | ||
+ | |||
+ | 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 160: | Line 204: | ||
>def [get, set] := makeCell(42); | >def [get, set] := makeCell(42); | ||
>> | >> | ||
+ | >get(); | ||
+ | >>42 | ||
</ | </ | ||
- | 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 | + | 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 '' |
===== Blocks ===== | ===== Blocks ===== | ||
- | In AmbientTalk, | + | In AmbientTalk, |
< | < | ||
{ |< | { |< | ||
</ | </ | ||
- | If the block do not require any parameter, the |< | + | |
+ | If the block does not require any parameter, the |< | ||
< | < | ||
- | >{| a, b| a+ b} (3,2) | + | >{|a, b| a+ b}(3,2) |
>>5 | >>5 | ||
</ | </ | ||
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. | ||
< | < | ||
- | >{|a, b, @rest| | + | >def sum := {|a, b, @rest| |
def total := a + b; | def total := a + b; | ||
| | ||
- | | + | }; |
+ | >>< | ||
+ | >sum(1,2,3) | ||
>>6 | >>6 | ||
</ | </ | ||
Line 186: | Line 235: | ||
This example also illustrates that blocks are also used to iterate over enumerations, | This example also illustrates that blocks are also used to iterate over enumerations, | ||
- | AmbientTalk | + | < |
- | < | + | AmbientTalk |
- | >def square := { |x| x * x } | + | </note> |
- | >>< | + | |
- | > | + | |
- | >>3 | + | |
- | </code> | + | |
===== Keywords ===== | ===== 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 '' | ||
- | AmbientTalk supports keyword messages. We have already seen some examples of keyword messages in the previous sections such as the foreach structure. | + | < |
+ | >def map: clo onto: tbl { | ||
+ | def i := 0; | ||
+ | def mapped[tbl.length] { | ||
+ | clo(tbl[i: | ||
+ | }; | ||
+ | } | ||
+ | >> < | ||
+ | </ | ||
+ | |||
+ | It can be invoked | ||
+ | < | ||
+ | >map: square onto: [1,2,3] | ||
+ | >> | ||
+ | </ | ||
+ | |||
+ | In AmbientTalk | ||
< | < | ||
def foo: arg1 bar: arg2 {...} | def foo: arg1 bar: arg2 {...} | ||
- | def foo: | ||
</ | </ | ||
+ | is transformed into: | ||
+ | < | ||
+ | def foo: | ||
+ | </ | ||
+ | |||
+ | However, it is impossible to directly call or define a keyworded function in a canonical style. | ||
===== Native Data Types ===== | ===== Native Data Types ===== | ||
- | + | The basic data types in AmbientTalk are numbers | |
- | 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 | + | |
==== 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 |
- | Note that since numerical types are objects in AmbientTalk, | + | Note that since numerical types are objects in AmbientTalk, |
< | < | ||
>1.inc() | >1.inc() | ||
>>2 | >>2 | ||
- | > | ||
- | >>1 | ||
>1.cos() | >1.cos() | ||
>> | >> | ||
Line 231: | Line 295: | ||
>>2 | >>2 | ||
</ | </ | ||
+ | |||
+ | Beware of the precedence rules for function application versus method invocation, which may lead to unexpected results, e.g.: | ||
+ | < | ||
+ | > | ||
+ | >>-1 | ||
+ | </ | ||
+ | This code is interpreted as '' | ||
Numbers also support some useful iterator methods such as: | Numbers also support some useful iterator methods such as: | ||
Line 275: | Line 346: | ||
==== Tables ==== | ==== Tables ==== | ||
- | TODO! | + | |
+ | 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. | ||
+ | < | ||
+ | > | ||
+ | >>[1, 3] | ||
+ | > | ||
+ | >>[2, 3, 4] | ||
+ | >def vowels := [" | ||
+ | >> | ||
+ | > | ||
+ | >>5 | ||
+ | > | ||
+ | >>" | ||
+ | > | ||
+ | >>" | ||
+ | > | ||
+ | >> | ||
+ | > | ||
+ | >>" | ||
+ | > | ||
+ | >> | ||
+ | </ | ||
+ | |||
+ | Tables also support some useful iterator methods as shown below. | ||
+ | |||
+ | < | ||
+ | >def sum:= 0; | ||
+ | >>0 | ||
+ | > | ||
+ | >> | ||
+ | >sum | ||
+ | >>6 | ||
+ | >def sumNnum (@args) { | ||
+ | args.inject: | ||
+ | } | ||
+ | >>< | ||
+ | > | ||
+ | >>6 | ||
+ | </ | ||
==== 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: | + | |
< | < | ||
< | < | ||
Line 288: | Line 396: | ||
</ | </ | ||
- | **=** and **!=** are the infix operators for equality and inequality. | + | '' |
< | < | ||
>(0 < 1).ifTrue: { 0 } | >(0 < 1).ifTrue: { 0 } | ||
Line 302: | Line 410: | ||
</ | </ | ||
- | 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' |
- | ===== Control Flow Structures | + | ===== Control Flow Constructs |
- | Control flow structures | + | Control flow constructs |
< | < | ||
- | if: booleanCondition then: { consequent | + | if: booleanCondition then: consequent |
- | if: booleanCondition then: { consequent | + | if: booleanCondition then: consequent else: alternative |
- | while: | + | while: condition do: body |
- | foreach: | + | foreach: |
- | do: { body } if: condition | + | do: body if: condition |
- | do: { body } unless: condition | + | do: body unless: condition |
</ | </ | ||
+ | |||
+ | Note that '' | ||
+ | |||
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. | ||
< | < | ||
Line 349: | Line 460: | ||
>>[2, 4, 5, 6, 8, 37] | >>[2, 4, 5, 6, 8, 37] | ||
</ | </ | ||
+ | |||
+ | AmbientTalk has no '' |
at/tutorial/basic.txt · Last modified: 2020/02/09 22:05 by elisag