|
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*
|
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 |
(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 |
`(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.
|