CleanX/ext/for-notation
編集   新規   履歴   最終更新者 lethevert   最終更新時刻 2007-07-30 14:55:31 UTC

The for-notation extension is an extention to help programming with unique typing. Here is a simple example.

hello f =
    for f
      fwrites "your name? "
      s <- freadline
      s = chop s
      fwrites "Hello, " $> s $> newline
      return

This is interpreted as the following.

hello f =
    case f of
      f # f = f |> fwrites "your name? "
          (s,f) = f |> freadline
          s = chop s
          f = f |> fwrites "Hello, " $> s $> newline
        = f

Basic Rules

Beginning of the notation

The first line of the notation is the following.

  ... for <expression-1>

This <expression-1> will be used for a hidden object during this for-notation. The scope of this notation is indicated by indent rule.


Simple statement

A simple statement like the following is interpreted to be complemented by the hidden object.

    fwrites "your name? "

will be

    f = f |> fwrites "your name? "

The '|>' operator is a pipeline operator defined in OptBase module in OptEnv library.

// pipeline operator
(|>) infixl 0 //:: .a (.a -> .b) -> .b
(|>) a f :== f a

Assign statement

A statement with '<-' is an assign statement and the left variables are complemented by a tuple with the hidden object.

    s <- freadline

will be

    (s,f) = f |> freadline

Another example is the case when there are two left variables.

    ok, i <- freadi

will be

    (ok, i, f) = f |> freadi

Bind statement

A statement with '=' is a bind statement and it is interpreted as it is.

    s = chop s

Return statement

A statement beggining with 'return' is a return statement and it is the returning statement of the for-notation. It is interpreted as it is the body of the function.

    return

will be

    = f

If a return statement has some arguments, a tuple with the hidden object complements the statement.

    return ok, i

will be

    = (ok, i, f)

Guard statement

A line beginning with '|' is a guard. Unlike standard clean syntax, a guard of for-notation must be in a single line and does not allow including a body of the guard.

Body statements follows after the guard line with indentation. The body lines will be also interpreted as a part of for-notation.

    ok, i <- freadi
    | not ok
      return -1
    return i

will be interpreted as

    # (ok, i, f) = f |> freadi
    | not ok
      = (-1, f)
    = (i, f)

Auxiliary functions

For-notation can have auxiliary functions. Those functions also have a hidden object as the main part.

  for f
    ok, i <- freadi
    i <- check ok i
    return i
  check False _
    fwrites "read error\n"
    return -1
  check True i
    return i

In the above sample, 'check' function is an auxiliary function of the for-notation. This function is interpreted as the following.

  check False _ f
    # f = f |> fwrites "read error\n"
    = (-1, f)
  check True i f
    = (i, f)

Continue statement

A statement beginning with 'continue' is a continue statement and it is the tail call statement of the for-notation. It is interpreted as it is the body of the function with function call.

    continue next_call str

will be interpreted as

    = f |> next_call str

Except pattern

A line beginning with '?' is a except pattern. It is used for focusing a main process while handling an exceptional process with an auxiliary function.

  for f
    ? True, i <- freadi
    return i
  except False _
    fwrites "read error\n"
    return -1

will be interpreted as

  case f of
    f = case f |> freadi of
          (True, i, f) = (i, f)
          (ok, i, f) = except ok i f
    with
      except False _ f
        # f = f |> fwrites "read error\n"
        = (-1, f)

If some letters or numbers follow the leading '?' without any spaces, it is interpreted as those will be added to the except function name. For example if a leading symbol is '?1' then the except function name is 'except1' and if '?_foo' then 'except_foo.'


Nested for-notation

For-notation can be nested. Here is a sample below.

Start w =
    for w
      f <- stdio
      f = for f
            fwrites "your name? "
            s <- freadline
            fwrites "Hello, " $> s
            return
      _ <- fclose f
      return

The program can also be written as the following.

Start w =
    for w
      f <- stdio
      _ <- for f
             fwrites "your name? "
             s <- freadline
             fwrites "Hello, " $> s
             continue fclose
      return