You may also want to have a look at syntax choices explained

Lexer

The various tokens:

Parser

Merd's syntax dynamicity rules out any classical parsing.

Common operators

Full list of operators including their priority


Function Calls

e1  = f(x)
e1' = x.f

e2  = f(x,y)
e2'  = x.f(y)
e1 and e1' are equivalent function calls. Same for e2 and e2': no distinction between method and function is done.

Partial application

Partial application is achieved using holes (choice explaination)
gcd10   = gcd(10,)
gcd10'  = x -> gcd(10,x)
gcd10'' = x -> 10.gcd(x)

bad_gcd10  = 10.gcd   #=> missing parameter
bad_gcd10' = 10.gcd() #=> () is not a number

Multi-methods

Method dispatching is done based on all parameters. merd's polymorphism explains this.

Mutators and predicates

This is a convention (it may change). It means xxx? returns a boolean, and xxx! returns Unit (alike void).

This syntax feature is taken from Scheme and Ruby. But contrary to Scheme, identifier of the form xxx!xxx are not allowed (alike Ruby).

Things like xxx!? are mutators that may fail, returning a boolean telling success or error (one could also have a mutator xxx! throwing an exception, but usability differs)


Variables Scope

Parameter variables

Function with parameters create new variables having the function scope:
f(x) = x
# x now out of scope

f = x->x
# x now out of scope

Local variables

New local variables are declared when initialised. Their scope ends when the current block ends [5]:
f(x) =
    i = "i"
    if cond then
        k = "k1"
    # k now out of scope
    else
        k = "k2"
    # k now out of scope

    l =
        m = "m"
        n = "n"
        m+n
    # m,n now out of scope

    o = (p = "p" ; p)

    # i,l,o,x,f still accessible

Special variables

Capitalized tokens are usually constants. But they can be special variables, usually used as type variables [6].

A capitalized token is a special variable if:

A special variable do not behave like a normal variable when used in function parameters and pattern matching:

bool = True | False
f !! bool -> bool
do not behave as wanted, here the type of f is set to bool -> bool which is the same as a -> a (alpha-renaming)
Bool = True | False
g !! Bool -> Bool
works as wanted, Bool being replaced by its value, the type of f is set to True|False -> True|False.

Notes

[1] The regexp for constants truly is [A-Z]\w*[!?']*

[2] The regexp for variables truly is [a-z_]\w*[!?']*

[3] The regexp for integers truly is ([0-9]+ or 0x[0-9a-fA-F]+)

[4] Beware, 2. is not a float otherwise it would conflict with method call: 2.sqrt

[5] Python's blocks do not introduce any scope, variables being function-wide. Block scoped variable gets in the way with languages where the only way to declare variables is affectation.
For example, with block scoped variable you can't write this anymore:

if cond:
    i = 1
else
    i = 2
This can be work-arounded with functional oriented syntax:
i = 
    if cond: 
        1 
    else:
        2
but that's no more python :)

[6] special variables are necessary because of the lack of a special type namespace


Pixel
This document is licensed under GFDL (GNU Free Documentation License).

Release: $Id: syntax.html,v 1.19 2002/09/23 11:25:54 pixel_ Exp $