home *** CD-ROM | disk | FTP | other *** search
-
-
- Introduction to Gofer 6. FUNCTION NAMES - IDENTIFIERS AND OPERATORS
-
-
- 6. FUNCTION NAMES - IDENTIFIERS AND OPERATORS
-
- As the examples of the previous section show, there are two kinds of
- name that can be used for a function; identifiers such as "sum" and
- operator symbols such as "+" and "*". Choosing the appropriate kind of
- name for a particular function can often help to make expressions
- involving that function easier to read. If for example the addition
- function was represented by the name "plus" rather than the operator
- symbol "+" then the sum of the integers from 1 to 5 would have to be
- written as:
-
- plus (plus (plus (plus 1 2) 3) 4) 5
-
- In this particular case, another way of writing the same sum is:
-
- plus 1 (plus 2 (plus 3 (plus 4 5)))
-
- Not only does the use of the identifier "plus" make these expressions
- larger and more difficult to read than the equivalent expressions using
- "+"; it also makes it very much harder to see that these two
- expressions do actually have the same value.
-
- Gofer distinguishes between the two types of name according to the way
- that they are written:
-
- o An identifier begins with a letter of the alphabet optionally
- followed by a sequence of characters, each of which is either a
- letter, a digit, an apostrophe (') or an underbar (_).
- Identifiers representing functions or variable must begin with a
- lower case letter (identifiers beginning with an upper case letter
- are used to denote a special kind of function called a
- `constructor function' described in section 11.1). The following
- identifiers are examples of Gofer variable and function names:
-
- sum f f'' integerSum african_queen do'until'zero
-
- The following identifiers are reserved words in Gofer and cannot
- be used as the name of a function or variable:
-
- case of where let in if
- then else data type infix infixl
- infixr primitive class instance
-
- o An operator symbol is written using one or more of the following
- symbol characters:
-
- : ! # $ % & * + . / < = > ? @ \ ^ | -
-
- In addition, the tilde character (~) is also permitted, although
- only in the first position of an operator name. [N.B. Haskell
- also makes the same restriction for the minus/dash character
- (-)]. Operator names beginning with a colon are used for
- constructor functions in the same way as identifiers beginning
- with a capital letter as mentioned above. In addition, the
- following operator symbols have special uses in Gofer:
-
-
-
- 8
-
-
-
-
- Introduction to Gofer 6. FUNCTION NAMES - IDENTIFIERS AND OPERATORS
-
-
- :: = .. @ \ | <- -> ~ =>
-
- All other operators symbols can be used as variables or function
- names, including each of the following examples:
-
- + ++ && || <= == /= // .
- ==> $ @@ -*- \/ /\ ... ?
-
- [Note that each of the symbols in the first line is used in the
- standard prelude. If you are interested in using Gofer to develop
- programs for use with a Haskell compiler, you might also want to
- avoid using the operator symbols := ! :+ and :% which are used to
- support features in Haskell not currently provided by the Gofer
- standard prelude.]
-
- Gofer provides two simple mechanisms which make it possible to use an
- identifier as an operator symbol, or an operator symbol as an
- identifier:
-
- o Any identifier will be treated as an operator symbol if it is
- enclosed in backquotes (`) -- for example, the expressions using
- the "plus" function above are a little easier to read using this
- technique:
-
- (((1 `plus` 2) `plus` 3) `plus` 4) `plus` 5
-
- In general, an expression of the form "x `op` y" is equivalent to
- the corresponding expression "op x y", whilst an expression such
- as "f x y z" can also be written as "(x `f` y) z".
-
- [NOTE: For those using Gofer on a PC, you may find that your
- keyboard does not have a backquote key! In this case you should
- still be able to enter a backquote by holding down the key marked
- ALT, pressing the keys '9' and then '6' on the numeric keypad and
- then releasing the ALT key.]
-
- o Any operator symbol can be treated as an identifier by enclosing
- it in parentheses. For example, the addition function denoted by
- the operator symbol "+" is often written as "(+)". Any expression
- of the form "x + y" can also be written in the form "(+) x y".
-
- There are two more technical problems which have to be dealt with when
- working with operator symbols:
-
- o Precedence: Given operator symbols (+) and (*), should "2 * 3 + 4"
- be treated as either "(2 * 3) + 4" or "2 * (3 + 4)"?
-
- This problem is solved by assigning each operator a precedence
- value (an integer in the range 0 to 9). In a situation such as
- the above, we simply compare the precedence values of the
- operators involved, and carrying out the calculation associated
- with the highest precedence operator first. The standard
- precedence values for (+) and (*) are 6 and 7 respectively so that
- the expression above will actually be treated as "(2 * 3) + 4".
-
- o Grouping: The above rule is only useful when the operator symbols
-
-
- 9
-
-
-
-
- Introduction to Gofer 6. FUNCTION NAMES - IDENTIFIERS AND OPERATORS
-
-
- involved have distinct precedences. For example, should the
- expression "1 - 2 - 3" be treated as either "(1 - 2) - 3" giving a
- result of -4, or as "1 - (2 - 3)" giving a result of 2?
-
- This problem is solved by giving each operator a `grouping'
- (sometimes called its associativity). An operator symbol (-) is
- said to:
-
- o group to the left if "x - y - z" is treated as "(x - y) - z"
-
- o group to the right if "x - y - z" is treated as "x - (y - z)"
-
- A third possibility is that an expression of the form "x - y - z"
- is to be treated as ambiguous and will be flagged as a syntax
- error. In this case we say that the operator (-) is
- non-associative.
-
- The standard approach in Gofer is to treat (-) as grouping to the
- left so that "1 - 2 - 3" will actually be treated as "(1-2)-3".
-
- By default, every operator symbol in Gofer is treated as
- non-associative with precedence 9. These values can be changed by a
- declaration of one of the following forms:
-
- infixl digit ops to declare operators which group to the left
- infixr digit ops to declare operators which group to the right
- infix digit ops to declare non-associative operators
-
- In each of these declarations ops represents a list of one or more
- operator symbols separated by commas and digit is an integer between 0
- and 9 which gives the precedence value for each of the listed operator
- symbols. The precedence digit may be omitted in which case a value of
- 9 is assumed. There are a number of restrictions on the use of these
- declarations:
-
- o Operator declarations can only appear in files of function
- definitions which are loaded into Gofer; they cannot be entered
- directly whilst using the Gofer interpreter.
-
- o At most one operator declaration is permitted for any particular
- operator symbol (even if repeated declarations all specify the
- same precedence and grouping as the original declaration).
-
- o Any file containing a declaration for an operator precedence and
- grouping must also contain a (top-level) declaration for that
- operator.
-
- In theory, it is possible to use an operator declaration at any point
- in a file of definitions. In practice, it is sensible to ensure that
- each operator is declared before the symbol is used. One way to
- guarantee this is to place all operator declarations at the beginning
- of the file [this condition is enforced in Haskell]. Note that until
- an operator declaration for a particular symbol is encountered, any
- occurrence of that symbol will be treated as a non-associative operator
- with precedence 9.
-
-
-
- 10
-
-
-
-
- Introduction to Gofer 6. FUNCTION NAMES - IDENTIFIERS AND OPERATORS
-
-
- The following operator declarations are taken from the standard prelude:
-
- -- Operator precedence table
-
- infixl 9 !!
- infixr 9 .
- infixr 8 ^
- infixl 7 *
- infix 7 /, `div`, `rem`, `mod`
- infixl 6 +, -
- infix 5 \\
- infixr 5 ++, :
- infix 4 ==, /=, <, <=, >=, >
- infix 4 `elem`, `notElem`
- infixr 3 &&
- infixr 2 ||
-
- and their use is illustrated by the following examples:
-
- Expression: Equivalent to: Reasons:
- ----------- -------------- --------
- 1 + 2 - 3 (1 + 2) - 3 (+) and (-) have the same precedence
- and group to the left.
- x : ys ++ zs x : (ys ++ zs) (:) and (++) have the same precedence
- and group to the right
- x == y || z (x == y) || z (==) has higher precedence than (||).
- 3 * 4 + 5 (3 * 4) + 5 (*) has higher precedence than (+).
- y `elem` z:zs y `elem` (z:zs) (:) has higher precedence than elem.
- 12 / 6 / 3 syntax error ambiguous use of (/); could mean
- either (12/6)/3 or 12/(6/3).
-
- Note that function application always binds more tightly than any infix
- operator symbol. For example, the expression "f x + g y" is equivalent
- to "(f x) + (g y)". Another example which often causes problems is the
- expression "f x + 1", which is treated as "(f x) + 1" and not as
- "f (x+1)" as is sometimes expected.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 11
-
-
-