@c =================================================================== @c
@c    serrano/prgm/project/bigloo/manuals/core.texi                    @c
@c    ------------------------------------------------------------     @c
@c    Author      :  Manuel Serrano                                    @c
@c    Creation    :  Sat Feb 23 07:14:12 2002                          @c
@c    Last change :                                                    @c
@c    Copyright   :  2002 Manuel Serrano                               @c
@c    ------------------------------------------------------------     @c
@c    The Bigloo core language                                         @c
@c =================================================================== @c

@c ------------------------------------------------------------------- @c
@c    The Core language                                                @c
@c ------------------------------------------------------------------- @c
@node Core Language, Standard Library, Modules, Top
@chapter Core Language

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

@menu
* Syntax::                      Identifiers and typed identifiers
* Comments::                    Bigloo comments
* Expressions::                 Expressions
* Definitions::                 Global definitions
@end menu

@c ------------------------------------------------------------------- @c
@c    The syntax                                                       @c
@c ------------------------------------------------------------------- @c
@node Syntax, Comments, Core Language, Core Language
@comment  node-name,  next,  previous,  up
@section Syntax
@cindex 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 @code{lambda}, @code{let}, 
@code{define}, ...) and those identifiers holding type information are 
referred to as typed identifiers.

@cindex Typed identifier
They are defined by the following grammar:

@smallexample
<ident>        @expansion{} <r5rs-ident> | <typed-ident>
<typed-ident>  @expansion{} <r5rs-ident>::<r5rs-ident>
<r5rs-ident>   @expansion{} @r{the standard Scheme identifiers}
@end smallexample

For details of the standard Scheme identifiers, see 
@ref{Lexical structure, token,,r5rs.info,R5RS}.

@pindex Multi-line comments 
@cindex Multi-line comments 
@cindex SRFI-30

Multi-lines comments (see @url{http://srfi.schemers.org/srfi-30/}) 
are defined as:

@smallexample
<ident>        @expansion{} <r5rs-ident> | <typed-ident>
<comment>      @expansion{} ;<all subsequent characters up to a line break>
       	       | #| <comment-text> (<comment> <comment-text>)* |#
<comment-text> @expansion{} <character sequence not containing #| or |#>
@end smallexample

@c ------------------------------------------------------------------- @c
@c    Comments                                                         @c
@c ------------------------------------------------------------------- @c
@node Comments, Expressions, Syntax, Core Language
@comment  node-name,  next,  previous,  up
@subsection Comments
@cindex comments

Comments and whitespaces are the same as in 
@ref{Whitespace and comments,,r5rs.info,R5RS}.

@smalllisp
;;; 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))))))
@end smalllisp


@c ------------------------------------------------------------------- @c
@c    Expressions                                                      @c
@c ------------------------------------------------------------------- @c
@node Expressions, Definitions, Comments, Core Language
@comment  node-name,  next,  previous,  up
@subsection Expressions
@cindex Expressions

Bigloo expressions are the same as in @ref{Expressions, , r5rs.info, R5RS}.
Bigloo has more syntactic keywords than Scheme. The Bigloo syntactic
keywords are:

@example
=>                      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*
@end example

@noindent All other non atomic Bigloo forms are evaluated as function
calls or macro class.

@deffn {syntax} @r{<variable>}
@deffnx {syntax} quote datum
@deffnx {syntax} @code{'}@r{datum}
@deffnx {syntax} @r{<constant>}
@smalllisp
(define x 28)                          @result{}
x                                      @result{} 28
(quote a)                              @result{} A
(quote #(a b c))                       @result{} #(A B C)
(quote (+ 1 2))                        @result{} (+ 1 2)
'a                                     @result{} A
'#(a b c)                              @result{} #(A B C)
'()                                    @result{} ()
'(+ 1 2)                               @result{} (+ 1 2)
'(quote a)                             @result{} (QUOTE A)
'"abc"                                 @result{} "abc"
"abc"                                  @result{} "abc"
'145932                                @result{} 145932
145932                                 @result{} 145932
'#t                                    @result{} #t
#t                                     @result{} #t
@end smalllisp
@end deffn

@deffn {syntax} operator operand @dots{}
@cindex @w{procedure call}
@cindex @w{call}
@smalllisp
(+ 3 4)                                @result{} 7
((if #f + *) 3 4)                      @result{} 12
((lambda (x) (+ 1 x)) 5)               @result{} 6
@end smalllisp
@end deffn

@deffn {syntax} lambda  formals body
@smalllisp
(lambda (x) (+ x x))                   @result{} @emph{a procedure}
((lambda (x) (+ x x)) 4)               @result{} 8

(define reverse-subtract
  (lambda (x y) (- y x)))
(reverse-subtract 7 10)                @result{} 3

(define add4
  (let ((x 4))
    (lambda (y) (+ x y))))
(add4 6)                               @result{} 10

((lambda x x) 3 4 5 6)                 @result{} (3 4 5 6)
((lambda (x y . z) z)
 3 4 5 6)                              @result{} (5 6)
@end smalllisp
@end deffn

@deffn {syntax} if test consequent [alternate]
@smalllisp
(if (> 3 2) 'yes 'no)                  @result{} yes
(if (> 2 3) 'yes 'no)                  @result{} no
(if (> 3 2)
    (- 3 2)
    (+ 3 2))                           @result{} 1
@end smalllisp
@end deffn

@deffn {syntax} set!  variable expression
@smalllisp
(define x 2)
(+ x 1)                                @result{} 3
(set! x 4)                             @result{} @emph{unspecified}
(+ x 1)                                @result{} 5
@end smalllisp
@end deffn

@deffn {library syntax} cond clause clause @dots{}
@smalllisp
(cond ((> 3 2) 'greater)
      ((< 3 2) 'less))                 @result{} greater

(cond ((> 3 3) 'greater)
      ((< 3 3) 'less)
      (else 'equal))                   @result{} equal

(cond ((assv 'b '((a 1) (b 2))) => cadr)
      (else #f))                       @result{} 2
@end smalllisp
@end deffn

@deffn {library syntax} case key clause clause @dots{}
@smalllisp
(case (* 2 3)
  ((2 3 5 7) 'prime)
  ((1 4 6 8 9) 'composite))            @result{} composite
(case (car '(c d))
  ((a) 'a)
  ((b) 'b))                            @result{} @emph{unspecified}
(case (car '(c d))
  ((a e i o u) 'vowel)
  ((w y) 'semivowel)
  (else 'consonant))                   @result{} consonant
@end smalllisp
@end deffn

@deffn {library syntax} and test @dots{}
@smalllisp
(and (= 2 2) (> 2 1))                  @result{} #t
(and (= 2 2) (< 2 1))                  @result{} #f
(and 1 2 'c '(f g))                    @result{} (f g)
(and)                                  @result{} #t
@end smalllisp
@end deffn
 
@deffn {bigloo syntax} and-let* test @dots{}
@cindex SRFI-2

In case of an ordinary @code{and} formed of proper boolean
expressions: @code{(and e1 e2 ...)}  expression @var{e2}, if it gets
to be evaluated, knows that @var{e1} has returned
non-@code{#f}. Moreover, @var{e2} knows exactly what the result of
@var{e1} was -- @code{#t} -- which @var{e2} can use to its
advantage. If @var{e1} however is an extended boolean expression,
@var{e2} can no longer tell which particular non-@code{#f} value
@var{e1} has returned. Chances are it took a lot of work to evaluate
@var{e1}, and the produced result (a number, a vector, a string, etc)
may be of value to @var{e2}. Alas, the @code{and} form merely checks that
the result is not an @code{#f}, and throws it away. If @var{e2} needs
it, it has to compute that value anew. This proposed @code{and-let*}
special form lets constituent expressions get hold of the results of
already evaluated expressions, without re-doing their work.

@code{and-let*} can be thought of as a combination of @code{let*} and
@code{and}, or a generalization of @code{cond}'s send operator
@code{=>}. An @code{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. @code{and-let*} differs in that it checks to make sure that
every produced result "makes sense" (that is, not an @code{#f}). The
first "failure" triggers the guard and aborts the rest of the sequence
(which presumably would not make any sense to execute anyway).

@smalllisp
(and-let* ((x 1) (y 2)) (cons x y))    @result{} (1 . 2)
(and-let* ((x 1) (z #f)) x)            @result{} #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)))
@end smalllisp

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

@smallexample
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.
@end smallexample

@end deffn
 
@deffn {library syntax} or test @dots{}
@smalllisp
(or (= 2 2) (> 2 1))                   @result{} #t
(or (= 2 2) (< 2 1))                   @result{} #t
(or #f #f #f)                          @result{} #f
(or (memq 'b '(a b c)) 
    (/ 3 0))                           @result{} (b c)
@end smalllisp
@end deffn

@deffn {library syntax} let [name] (binding @dots{}) body
@smalllisp
(let ((x 2) (y 3))
  (* x y))                             @result{} 6

(let ((x 2) (y 3))
  (let ((x 7)
        (z (+ x y)))
    (* z x)))                          @result{} 35

(let loop ((l '(1 2 3)))
   (if (null? l)
       '()
       (cons (+ 1 (car l)) 
             (loop (cdr l)))))         @result{} (2 3 4)
@end smalllisp
@end deffn

@deffn {library syntax} let* (binding @dots{}) body
@smalllisp
(let ((x 2) (y 3))
  (let* ((x 7)
         (z (+ x y)))
    (* z x)))                          @result{} 70
@end smalllisp
@end deffn

@deffn {library syntax} letrec (binding @dots{}) body
@smalllisp
(letrec ((even?
          (lambda (n)
            (if (zero? n)
                #t
                (odd? (- n 1)))))
         (odd?
          (lambda (n)
            (if (zero? n)
                #f
                (even? (- n 1))))))
  (even? 88))   
                                       @result{} #t
@end smalllisp
@end deffn

@deffn {bigloo syntax} labels ((name (arg @dots{}) body) @dots{}) body
The syntax is similar to the Common Lisp one [Steele90],
where created bindings are immutable.

@smalllisp
(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) '()))
   @result{} (2 3 4)
@end smalllisp
@end deffn

@deffn {library syntax} begin expression expression @dots{}
@smalllisp
(define x 0)

(begin (set! x 5)
       (+ x 1))                        @result{} 6

(begin (display "4 plus 1 equals ")
       (display (+ 4 1)))              @result{} @emph{unspecified}
                                       @print{} 4 plus 1 equals 5
@end smalllisp
@end deffn

@c @deffn {library syntax} do ((variable init step)@dots{})
@deffn {library syntax} do ((variable init step) @dots{}) (test expression @dots{}) body
@smalllisp
(do ((vec (make-vector 5))
     (i 0 (+ i 1)))
    ((= i 5) vec)
  (vector-set! vec i i))               @result{} #(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)))                @result{} 25
@end smalllisp
@end deffn

@deffn {library syntax} delay expression
@end deffn

@deffn {syntax} quasiquote template
@deffnx {syntax} @t{`} template
@cindex @w{quotation}
@smalllisp
`(list ,(+ 1 2) 4)                     @result{} (list 3 4)
(let ((name 'a)) `(list ,name ',name))           
          @result{} (list a (quote a))
`(a ,(+ 1 2) ,@@(map abs '(4 -5 6)) b)           
          @result{} (a 3 4 5 6 b)
`((@samp{foo} ,(- 10 3)) ,@@(cdr '(c)) . ,(car '(cons)))           
          @result{} ((foo 7) . cons)
`#(10 5 ,(sqrt 4) ,@@(map sqrt '(16 9)) 8)           
          @result{} #(10 5 2 4 3 8)
`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)           
          @result{} (a `(b ,(+ 1 2) ,(foo 4 d) e) f)
(let ((name1 'x)
      (name2 'y))
  `(a `(b ,,name1 ,',name2 d) e))           
          @result{} (a `(b ,x ,'y d) e)
(quasiquote (list (unquote (+ 1 2)) 4))           
          @result{} (list 3 4)
'(quasiquote (list (unquote (+ 1 2)) 4))           
          @result{} `(list ,(+ 1 2) 4)
     @emph{}i.e., (quasiquote (list (unquote (+ 1 2)) 4))
@end smalllisp
@end deffn

@c ------------------------------------------------------------------- @c
@c    Definitions                                                      @c
@c ------------------------------------------------------------------- @c
@node Definitions, , Expressions, Core Language
@comment  node-name,  next, Expressions,  up
@subsection Definitions
@cindex Definitions

Global bindings are introduced by the @code{define} form:
@deffn {syntax} define variable expression
@deffnx {syntax} define (variable arg @dots{}) body
@smalllisp
(define add3
  (lambda (x) (+ x 3)))
(add3 3)                               @result{} 6
(define first car)
(first '(1 2))                         @result{} 1
@end smalllisp
@end deffn

@xref{Definitions, ,r5rs.info}, for more details. The Bigloo module
language (See @ref{Module Declaration}) enables @emph{exports} and
@emph{imports} of global definitions.


