|
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.
|