|
This chapter presents the Bigloo basics. It presents the elements
that compose the body of a module (see Modules).
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 |#>
|
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))))))
|
In addition, Bigloo supports s-expressions comments. These
are introduced with the #; syntax:
;;; The FACT procedure computes the factorial
;;; of a non-negative integer.
(define fact
(lambda (n)
#;(if (< n 2) 1 (* #;n (fact (- n 1))))
(if (= n 0)
1
(* n (fact (- n 1))))))
|
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* letrec*
|
All other non atomic Bigloo forms are evaluated as functioncalls or macro class.
(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 |
Bigloo considers else as a keyword. It thus ignores clauses
following an else -clause.
(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 |
(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)))
|
|
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)
|
If a binding is a symbol, then, it introduces a variable bound
to the #unspecified value.
(let (x)
x) => #unspecified
|
Bigloo's named let differs from R5Rs named let because name
is bound in binding . That is,
(let ((l 'a-symbol))
(let l ((x l))
x)) => #<procedure>
|
while R5Rs states that,
(let ((l 'a-symbol))
(let l ((x l))
x)) => a-symbol
|
|
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
|
|
letrec* (binding ...) body | bigloo syntax |
Each binding has the form
((<variable1> <init1>) ...)
|
Each <init> is an expression.Any variable must not appear more
than once in the <variable> s.
The <variable> s are bound to fresh locations, each <variable>
is assigned in left-to-right order to the result of evaluating the
corresponding <init> , the <body> is evaluated in the resulting
environment, and the values of the last expression in <body> are
returned. Despite the left-to-right evaluation and assignment order,
each binding of a <variable> has the entire letrec* expression as its
region, making it possible to define mutually recursive procedures.
Examples:
(letrec* ((x 1)
(f (lambda (y) (+ x y))))
(f 3))
=> 4
(letrec* ((p (lambda (x)
(+ 1 (q (- x 1)))))
(q (lambda (y)
(if (zero? y)
0
(+ 1 (p (- y 1))))))
(x (p 5))
(y x))
y)
=> 5
|
It must be possible to evaluate each <init> without assigning or
referring to the value of the corresponding <variable> or the
<variable> of any of the bindings that follow it in
<bindings>. Another restriction is that the continuation of each
<init> should not be invoked more than once.
|
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 |
`(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))
|
|
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.
|