4. Bigloo -- Core Language

Browsing

Home: | Bigloo A ``practical Scheme compiler'' User manual for version 2.6b December 2003
Previous chapter: | Modules
Next chapter: | Standard Library

Core Language

4.1 | Syntax
| 4.1.1 | Comments
| 4.1.2 | Expressions
| 4.1.3 | Definitions

Chapters

| Acknowledgements
1. | Table of contents
2. | Overview of Bigloo
3. | Modules
4. | Core Language
5. | Standard Library
6. | Pattern Matching
7. | Object System
8. | Threads
9. | Regular parsing
10. | Lalr(1) parsing
11. | Errors and Assertions
12. | Eval and code interpretation
13. | Macro expansion
14. | Command Line Parsing
15. | Explicit typing
16. | The C interface
17. | The Java interface
18. | Bigloo Libraries
19. | Extending the Runtime System
20. | SRFIs
21. | DSSSL support
22. | Compiler description
23. | User Extensions
24. | Bigloo Development Environment
25. | Global Index
26. | Library Index
| Bibliography

This chapter presents the Bigloo basics. It presents the elements that compose the body of a module (see Modules).

4.1 Syntax

The syntax of Bigloo is that of Scheme (a parenthesis based one) with two exceptions: type information and multi-line comments. Type information is supplied when identifiers are introduced (via `lambda`, `let`, `define`, ...) and those identifiers holding type information are referred to as typed identifiers.
They are defined by the following grammar:

    <ident>        ==> <r5rs-ident> | <typed-ident>
    <typed-ident>  ==> <r5rs-ident>::<r5rs-ident>
    <r5rs-ident>   ==> the standard Scheme identifiers

For details of the standard Scheme identifiers, see info-file `r5rs.info', .
Multi-lines comments (see http://srfi.schemers.org/srfi-30/) are defined as:

    <ident>        ==> <r5rs-ident> | <typed-ident>
    <comment>      ==> ;<all subsequent characters up to a line break>
           	       | #| <comment-text> (<comment> <comment-text>)* |#
    <comment-text> ==> <character sequence not containing #| or |#>

### 4.1.1 Comments

Comments and whitespaces are the same as in r5rs, Whitespace and comments.

    ;;; The FACT procedure computes the factorial
    ;;; of a non-negative integer.
    (define fact
      (lambda (n)
        (if (= n 0)
            1        ;; Base case: return 1
            (* n (fact (- n 1))))))

### 4.1.2 Expressions

Bigloo expressions are the same as in r5rs, Expressions. Bigloo has more syntactic keywords than Scheme. The Bigloo syntactic keywords are:

    =>                      do                    or
    and                     else                  quasiquote
    begin                   if                    quote
    case                    lambda                set!
    cond                    let                   unquote
    unquote-splicing        define                let*
    delay                   letrec                module
    labels                  try                   define-struct
    unwind-protect          bind-exit             define-inline
    regular-grammar         lalr-grammar          regular-search
    define-expander         define-macro          match-case
    match-lambda            pragma                failure
    assert                  define-generic        define-method
    instantiate             duplicate             with-access
    widen!                  shrink!               multiple-value-bind
    let-syntax              letrec-syntax         define-syntax
    cond-expand             receive               args-parse
    define-record-type      and-let*

All other non atomic Bigloo forms are evaluated as functioncalls or macro class.

<variable> | syntax

quote datum | syntax

`'`datum | syntax

<constant> | syntax

    (define x 28)                          =>
    x                                      => 28
    (quote a)                              => A
    (quote #(a b c))                       => #(A B C)
    (quote (+ 1 2))                        => (+ 1 2)
    'a                                     => A
    '#(a b c)                              => #(A B C)
    '()                                    => ()
    '(+ 1 2)                               => (+ 1 2)
    '(quote a)                             => (QUOTE A)
    '"abc"                                 => "abc"
    "abc"                                  => "abc"
    '145932                                => 145932
    145932                                 => 145932
    '#t                                    => #t
    #t                                     => #t

operator operand ... | syntax

    (+ 3 4)                                => 7
    ((if #f + *) 3 4)                      => 12
    ((lambda (x) (+ 1 x)) 5)               => 6

lambda formals body | syntax

    (lambda (x) (+ x x))                   => a procedure
    ((lambda (x) (+ x x)) 4)               => 8

    (define reverse-subtract
      (lambda (x y) (- y x)))
    (reverse-subtract 7 10)                => 3

    (define add4
      (let ((x 4))
        (lambda (y) (+ x y))))
    (add4 6)                               => 10

    ((lambda x x) 3 4 5 6)                 => (3 4 5 6)
    ((lambda (x y . z) z)
     3 4 5 6)                              => (5 6)

if test consequent [alternate] | syntax

    (if (> 3 2) 'yes 'no)                  => yes
    (if (> 2 3) 'yes 'no)                  => no
    (if (> 3 2)
        (- 3 2)
        (+ 3 2))                           => 1

set! variable expression | syntax

    (define x 2)
    (+ x 1)                                => 3
    (set! x 4)                             => unspecified
    (+ x 1)                                => 5

cond clause clause ... | library syntax

    (cond ((> 3 2) 'greater)
          ((< 3 2) 'less))                 => greater

    (cond ((> 3 3) 'greater)
          ((< 3 3) 'less)
          (else 'equal))                   => equal

    (cond ((assv 'b '((a 1) (b 2))) => cadr)
          (else #f))                       => 2

case key clause clause ... | library syntax

    (case (* 2 3)
      ((2 3 5 7) 'prime)
      ((1 4 6 8 9) 'composite))            => composite
    (case (car '(c d))
      ((a) 'a)
      ((b) 'b))                            => unspecified
    (case (car '(c d))
      ((a e i o u) 'vowel)
      ((w y) 'semivowel)
      (else 'consonant))                   => consonant

and test ... | library syntax

    (and (= 2 2) (> 2 1))                  => #t
    (and (= 2 2) (< 2 1))                  => #f
    (and 1 2 'c '(f g))                    => (f g)
    (and)                                  => #t

and-let* test ... | bigloo syntax

In case of an ordinary `and` formed of proper boolean expressions: `(and e1 e2 ...)` expression `e2`, if it gets to be evaluated, knows that `e1` has returned non-`#f`. Moreover, `e2` knows exactly what the result of `e1` was -- `#t` -- which `e2` can use to its advantage. If `e1` however is an extended boolean expression, `e2` can no longer tell which particular non-`#f` value `e1` has returned. Chances are it took a lot of work to evaluate `e1`, and the produced result (a number, a vector, a string, etc) may be of value to `e2`. Alas, the `and` form merely checks that the result is not an `#f`, and throws it away. If `e2` needs it, it has to compute that value anew. This proposed `and-let*` special form lets constituent expressions get hold of the results of already evaluated expressions, without re-doing their work.
`and-let*` can be thought of as a combination of `let*` and `and`, or a generalization of `cond`'s send operator `=>`. An `and-let*` form can also be considered a sequence of guarded expressions. In a regular program, forms may produce results, bind them to variables and let other forms use these results. `and-let*` differs in that it checks to make sure that every produced result "makes sense" (that is, not an `#f`). The first "failure" triggers the guard and aborts the rest of the sequence (which presumably would not make any sense to execute anyway).

    (and-let* ((x 1) (y 2)) (cons x y))    => (1 . 2)
    (and-let* ((x 1) (z #f)) x)            => #f

    (and-let* ((my-list (compute-list)) ((not (null? my-list))))
              (do-something my-list))

    (define (look-up key alist)
      (and-let* ((x (assq key alist))) (cdr x)))

    (or (and-let* ((c (read-char))
                   ((not (eof-object? c))))
                  (string-set! some-str i c)
                  (set! i (+ 1 i)))

Note: This documentation has been written by Oleg Kiselyov under the following copyright:

    Copyright (C) Oleg Kiselyov (1998). All Rights Reserved.

    This document and translations of it may be copied and furnished to
    others, and derivative works that comment on or otherwise explain it
    or assist in its implementation may be prepared, copied, published and
    distributed, in whole or in part, without restriction of any kind,
    provided that the above copyright notice and this paragraph are
    included on all such copies and derivative works. However, this
    document itself may not be modified in any way, such as by removing
    the copyright notice or references to the Scheme Request For
    Implementation process or editors, except as needed for the purpose of
    developing SRFIs in which case the procedures for copyrights defined
    in the SRFI process must be followed, or as required to translate it
    into languages other than English.

    The limited permissions granted above are perpetual and will not be
    revoked by the authors or their successors or assigns.

    This document and the information contained herein is provided on an
    "AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL
    WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
    WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY
    RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
    PARTICULAR PURPOSE.

or test ... | library syntax

    (or (= 2 2) (> 2 1))                   => #t
    (or (= 2 2) (< 2 1))                   => #t
    (or #f #f #f)                          => #f
    (or (memq 'b '(a b c))
        (/ 3 0))                           => (b c)

let [name] (binding ...) body | library syntax

    (let ((x 2) (y 3))
      (* x y))                             => 6

    (let ((x 2) (y 3))
      (let ((x 7)
            (z (+ x y)))
        (* z x)))                          => 35

    (let loop ((l '(1 2 3)))
       (if (null? l)
           '()
           (cons (+ 1 (car l))
                 (loop (cdr l)))))         => (2 3 4)

let* (binding ...) body | library syntax

    (let ((x 2) (y 3))
      (let* ((x 7)
             (z (+ x y)))
        (* z x)))                          => 70

letrec (binding ...) body | library syntax

    (letrec ((even?
              (lambda (n)
                (if (zero? n)
                    #t
                    (odd? (- n 1)))))
             (odd?
              (lambda (n)
                (if (zero? n)
                    #f
                    (even? (- n 1))))))
      (even? 88))
                                           => #t

labels ((name (arg ...) body) ...) body | bigloo syntax

The syntax is similar to the Common Lisp one [Steele90], where created bindings are immutable.

    (labels ((loop (f l acc)
                   (if (null? l)
                       (reverse! acc)
                       (loop f (cdr l) (cons (f (car l)) acc)))))
       (loop (lambda (x) (+ 1 x)) (list 1 2 3) '()))
       => (2 3 4)

begin expression expression ... | library syntax

    (define x 0)

    (begin (set! x 5)
           (+ x 1))                        => 6

    (begin (display "4 plus 1 equals ")
           (display (+ 4 1)))              => unspecified
                                           -| 4 plus 1 equals 5

do ((variable init step) ...) (test expression ...) body | library syntax

    (do ((vec (make-vector 5))
         (i 0 (+ i 1)))
        ((= i 5) vec)
      (vector-set! vec i i))               => #(0 1 2 3 4)

    (let ((x '(1 3 5 7 9)))
      (do ((x x (cdr x))
           (sum 0 (+ sum (car x))))
          ((null? x) sum)))                => 25

delay expression | library syntax

quasiquote template | syntax

``` template | syntax

    `(list ,(+ 1 2) 4)                     => (list 3 4)
    (let ((name 'a)) `(list ,name ',name))
              => (list a (quote a))
    `(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b)
              => (a 3 4 5 6 b)
    `((foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))
              => ((foo 7) . cons)
    `#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8)
              => #(10 5 2 4 3 8)
    `(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)
              => (a `(b ,(+ 1 2) ,(foo 4 d) e) f)
    (let ((name1 'x)
          (name2 'y))
      `(a `(b ,,name1 ,',name2 d) e))
              => (a `(b ,x ,'y d) e)
    (quasiquote (list (unquote (+ 1 2)) 4))
              => (list 3 4)
    '(quasiquote (list (unquote (+ 1 2)) 4))
              => `(list ,(+ 1 2) 4)
         i.e., (quasiquote (list (unquote (+ 1 2)) 4))

### 4.1.3 Definitions

Global bindings are introduced by the `define` form:

define variable expression | syntax

define (variable arg ...) body | syntax

    (define add3
      (lambda (x) (+ x 3)))
    (add3 3)                               => 6
    (define first car)
    (first '(1 2))                         => 1

See r5rs, Definitions, for more details. The Bigloo module language (See Module Declaration) enables exports and imports of global definitions.

This Scribe page has been generated by `scribeinfo`.
Last update Tue Dec 16 13:46:41 2003