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/05 14:03] – elisag | at:tutorial:basic [2007/04/06 08:33] – * elisag | ||
---|---|---|---|
Line 1: | Line 1: | ||
< | < | ||
- | **UNDER CONSTRUCTION!!** | + | **IN PROGRESS: FIRST DRAFT!!** |
+ | |||
+ | - Add quasi-quoting? | ||
</ | </ | ||
====== Functional and Imperative Programming ====== | ====== Functional and Imperative Programming ====== | ||
Line 108: | Line 110: | ||
</ | </ | ||
- | Variables and functions defined locally to functions are only visible in the scope of the function where there were defined. | + | This example also illustrates how a function can be made private by means of lexical scope. |
- | === Variable-Length Argument Functions === | + | ==== Variable-Length Argument Functions |
You can create functions that take an arbitrary | You can create functions that take an arbitrary | ||
Line 143: | Line 145: | ||
>>6 | >>6 | ||
</ | </ | ||
- | |||
===== Closures ===== | ===== Closures ===== | ||
- | The function name can also be used just to refer the function | + | As you have probably noticed in the previous examples, |
+ | |||
+ | The function name can be thus used to refer the function | ||
+ | < | ||
+ | >def makeCell(val){ | ||
+ | def getter() { val} ; | ||
+ | def setter(v) {val := v}; | ||
+ | [getter, setter] | ||
+ | } | ||
+ | >>< | ||
+ | >def [get, set] := makeCell(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 as arguments to other functions such as // | ||
===== Blocks ===== | ===== Blocks ===== | ||
Line 153: | Line 168: | ||
In AmbientTalk, | In AmbientTalk, | ||
< | < | ||
- | { | < | + | { |< |
</ | </ | ||
If the block do not require any parameter, the |< | If the block do not require any parameter, the |< | ||
Line 168: | Line 183: | ||
>>6 | >>6 | ||
</ | </ | ||
+ | |||
+ | This example also illustrates that blocks are also used to iterate over enumerations, | ||
+ | |||
AmbientTalk doesn’t support function assigment. However, one can assign blocks to variables. In order to call the block the name of the variable must be used. If the block defined parameters, these are required to the call as argument list. What follows is an example of such manipulation: | AmbientTalk doesn’t support function assigment. However, one can assign blocks to variables. In order to call the block the name of the variable must be used. If the block defined parameters, these are required to the call as argument list. What follows is an example of such manipulation: | ||
< | < | ||
Line 174: | Line 192: | ||
> | > | ||
>>3 | >>3 | ||
+ | </ | ||
+ | |||
+ | ===== 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: | ||
+ | < | ||
+ | def foo: arg1 bar: arg2 {...} | ||
+ | def foo: | ||
+ | </ | ||
+ | |||
+ | ===== 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. This section shows some examples how to manipulate the basic types. The complete list of methods can be found in the language reference. | ||
+ | |||
+ | ==== Numerical data types ==== | ||
+ | |||
+ | AmbientTalk supports numbers and fractions which represent what other languages call integers and floating point numbers, respectively. | ||
+ | |||
+ | Note that since numerical types are objects in AmbientTalk, | ||
+ | < | ||
+ | >1.inc() | ||
+ | >>2 | ||
+ | > | ||
+ | >>1 | ||
+ | >1.cos() | ||
+ | >> | ||
+ | >1 ** 5 | ||
+ | >>[1, 2, 3, 4] | ||
+ | >5 *** 1 | ||
+ | >>[5, 4, 3, 2, 1] | ||
+ | > | ||
+ | >>1 | ||
+ | > | ||
+ | >>1 | ||
+ | > | ||
+ | >>2 | ||
+ | </ | ||
+ | |||
+ | Numbers also support some useful iterator methods such as: | ||
+ | < | ||
+ | >6.to: 0 step: 2 do: { |i| system.println(i) } | ||
+ | 6 | ||
+ | 4 | ||
+ | 2 | ||
+ | >> | ||
+ | > | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
+ | >>nil | ||
+ | </ | ||
+ | |||
+ | ==== Texts ==== | ||
+ | |||
+ | |||
+ | A text data type represent a string of characters. Texts are often created using sequences of characters surrounded by double quotes ("). AmbientTalk doesn' | ||
+ | < | ||
+ | >" | ||
+ | >> | ||
+ | >" | ||
+ | >> | ||
+ | >" | ||
+ | | ||
+ | } | ||
+ | >>" | ||
+ | >" | ||
+ | >>" | ||
+ | >" | ||
+ | >>11 | ||
+ | </ | ||
+ | |||
+ | AmbientTalk also provides some useful support for pattern matching using regular expressions. | ||
+ | < | ||
+ | >" | ||
+ | >> | ||
+ | >" | ||
+ | >> | ||
+ | </ | ||
+ | |||
+ | ==== Tables ==== | ||
+ | |||
+ | TODO! | ||
+ | |||
+ | ==== Booleans ==== | ||
+ | |||
+ | |||
+ | AmbientTalk supports infix operators for booleans as &, | and !. As any native type, booleans are objects so, they respond to keyword messages such as: | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | **=** 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: | ||
+ | < | ||
+ | >(0 < 1).ifTrue: { 0 } | ||
+ | >>0 | ||
+ | >(3 != 5).ifTrue: { 1 } ifFalse: { 0 } | ||
+ | >>1 | ||
+ | > def [i, j] := [1,3] | ||
+ | >>> | ||
+ | >{i < j}.whileTrue: | ||
+ | 1 | ||
+ | 2 | ||
+ | >>nil | ||
+ | </ | ||
+ | |||
+ | 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 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: | ||
+ | < | ||
+ | if: booleanCondition then: { consequent } | ||
+ | if: booleanCondition then: { consequent } else: { alternative } | ||
+ | while: { condition } do: { body } | ||
+ | foreach: { |v| body } in: [ table ] | ||
+ | do: { body } if: condition | ||
+ | do: { body } unless: condition | ||
+ | </ | ||
+ | An example of usage for some of these structures is shown below in the definition of the sort function. | ||
+ | < | ||
+ | >def sort(table, cmp := { |e1,e2| e1 < e2 }) { | ||
+ | def quickSort(table, | ||
+ | def left := low; | ||
+ | def right := high; | ||
+ | def pivot := table[(left+right) /- 2]; | ||
+ | def save := nil; | ||
+ | while: { left <= right } do: { | ||
+ | while: { cmp(table[left], | ||
+ | left := left + 1 | ||
+ | }; | ||
+ | while: { cmp(pivot, table[right]) } do: { | ||
+ | right := right - 1 | ||
+ | }; | ||
+ | if: (left <= right) then: { | ||
+ | // swap elements | ||
+ | save := table[left]; | ||
+ | table[left] := table[right]; | ||
+ | table[right] := save; | ||
+ | left := left + 1; | ||
+ | right := right - 1; | ||
+ | }; | ||
+ | }; | ||
+ | if: (low< | ||
+ | if: (high> | ||
+ | | ||
+ | }; | ||
+ | quickSort(table, | ||
+ | }; | ||
+ | >>< | ||
+ | > | ||
+ | >>[2, 4, 5, 6, 8, 37] | ||
</ | </ |
at/tutorial/basic.txt · Last modified: 2020/02/09 22:05 by elisag