Core Language
This chapter presents the Bigloo basics. It presents the elements that compose the body of a module (see Modules).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 (vialambda
, 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
Lexical structure, token,,r5rs.info,R5RS.
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
Comments and whitespaces are the same as in Whitespace and comments,,r5rs.info,R5RS.;;; 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))))))
Expressions
Bigloo expressions are the same as in Expressions, , r5rs.info, R5RS. 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.
<variable>syntax
quote datumsyntax
'
datumsyntax
<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
.keep
operator operand ...syntax
(+ 3 4) ⇒ 7 ((if #f + *) 3 4) ⇒ 12 ((lambda (x) (+ 1 x)) 5) ⇒ 6
.keep
lambda formals bodysyntax
(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)
.keep
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
.keep
set! variable expressionsyntax
(define x 2) (+ x 1) ⇒ 3 (set! x 4) ⇒ unspecified (+ x 1) ⇒ 5
.keep
cond clause clause ...library syntax
Bigloo considerselse
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
.keep
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
.keep
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
.keep
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)))
.keep
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)
.keep
let [name] (binding ...) bodylibrary 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) ⇒ #unspecifiedBigloo'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
.keep
let* (binding ...) bodylibrary syntax
(let ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) (* z x))) ⇒ 70
.keep
letrec (binding ...) bodylibrary 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
.keep
letrec* (binding ...) bodybigloo 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) ⇒ 5It 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.
.keep
labels ((name (arg ...) body) ...) bodybigloo 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)
.keep
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
.keep
do ((variable init step) ...) (test expression ...) bodylibrary 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
.keep
delay expressionlibrary syntax
.keep
quasiquote templatesyntax
` templatesyntax
`(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) `((__samp__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))
.keep
Definitions
Global bindings are introduced by thedefine
form:
define variable expressionsyntax
define (variable arg ...) bodysyntax
(define add3 (lambda (x) (+ x 3))) (add3 3) ⇒ 6 (define first car) (first '(1 2)) ⇒ 1
.keep
r5rs.info, for more details. The Bigloo module
language (See Module Declaration) enables exports and
imports of global definitions.