Update documentation for mixed definitions and expressions

* NEWS: Update.
* doc/ref/api-binding.texi (Internal Definitions): Update to mention
  that mixed definitions and expressions are allowed.
* doc/ref/scheme-ideas.texi (Creating a Procedure):
  (Lambda Alternatives): Update documentation to avoid implying that
  bodies are only expressions.
This commit is contained in:
Andy Wingo 2019-08-25 17:05:38 +02:00
commit 5284b9b9c6
3 changed files with 64 additions and 25 deletions

24
NEWS
View file

@ -10,9 +10,10 @@ Changes in alpha 2.9.4 (since alpha 2.9.3):
* Notable changes
** Improved compilation of `sqrt' and `abs'
** Improved compilation of many floating-point primitives
Heavy floating-point computations that use `sqrt' and `abs' will be
Heavy floating-point computations that use `sqrt', `abs', `floor`,
`ceiling`, `sin`, `cos`, `tan`, `asin`, `acos`, and `atan` will be
faster, as the compiler can unbox inexact rationals (flonums) in more
cases.
@ -24,6 +25,25 @@ Ghuloum and Dybvig's "Fixing Letrec (reloaded)" paper. This change
makes internal `define' just as efficient as `let', `let*', `letrec',
and similar.
** Interleaved internal definitions and expressions allowed
It used to be that internal definitions had to precede all expressions
in their bodies; this restriction was relaxed in Guile 3.0. If an
expression precedes an internal definition, it is treated as if it were
a definition of an unreferenced variable. This improves the readability
of Guile programs, as it used to be that program indentation tended to
increase needlessly to allow nested `let' and `letrec' to re-establish
definition contexts after initial expressions, for example for
type-checks on procedure arguments.
** Optimization of top-level bindings within a compilation unit
At optimization level 2 and above, Guile's compiler is now allowed to
inline definitions within a compilation unit. See "Declarative Modules"
in the manual, for full details. This change can improve the
performance of programs with many small top-level definitions by quite a
bit!
Changes in alpha 2.9.x (since the stable 2.2 series):

View file

@ -249,9 +249,9 @@ enclosing form. Let us examine the following example.
@lisp
(let ((frumble "froz"))
(define banana (lambda () (apple 'peach)))
(define apple (lambda (x) x))
(banana))
(define banana (lambda () (apple 'peach)))
(define apple (lambda (x) x))
(banana))
@result{}
peach
@end lisp
@ -281,8 +281,26 @@ is equivalent to
(+ a b)))
@end lisp
Internal definitions are only allowed at the beginning of the body of an
enclosing expression. They may not be mixed with other expressions.
Internal definitions may be mixed with non-definition expressions. If
an expression precedes a definition, it is treated as if it were a
definition of an unreferenced variable. So this:
@lisp
(let ()
(define a 1)
(foo)
(define b 2)
(+ a b))
@end lisp
@noindent
is equivalent to
@lisp
(let ()
(letrec* ((a 1) (_ (begin (foo) #f)) (b 2))
(+ a b)))
@end lisp
Another noteworthy difference to top level definitions is that within
one group of internal definitions all variable names must be distinct.
@ -305,7 +323,9 @@ following case:
@noindent
Guile decided to follow the R6RS in this regard, and now expands
internal definitions using @code{letrec*}.
internal definitions using @code{letrec*}. Relatedly, it used to be
that internal definitions had to precede all expressions in the body;
this restriction was relaxed in Guile 3.0.
@node Binding Reflection

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2012
@c Copyright (C) 1996-1997, 2000-2005, 2012, 2019
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@ -354,18 +354,17 @@ this, you can use the famous @code{lambda} syntax.
For example, the value of the following Scheme expression
@lisp
(lambda (name address) @var{expression} @dots{})
(lambda (name address) @var{body} @dots{})
@end lisp
@noindent
is a newly created procedure that takes two arguments:
@code{name} and @code{address}. The behaviour of the
new procedure is determined by the sequence of @var{expression}s in the
@dfn{body} of the procedure definition. (Typically, these
@var{expression}s would use the arguments in some way, or else there
wouldn't be any point in giving them to the procedure.) When invoked,
the new procedure returns a value that is the value of the last
@var{expression} in the procedure body.
is a newly created procedure that takes two arguments: @code{name} and
@code{address}. The behaviour of the new procedure is determined by the
sequence of expressions and definitions in the @var{body} of the
procedure definition. (Typically, @var{body} would use the arguments in
some way, or else there wouldn't be any point in giving them to the
procedure.) When invoked, the new procedure returns a value that is the
value of the last expression in the @var{body}.
To make things more concrete, let's suppose that the two arguments are
both strings, and that the purpose of this procedure is to form a
@ -433,7 +432,7 @@ A @code{define} expression of the form
@lisp
(define (@var{name} [@var{arg1} [@var{arg2} @dots{}]])
@var{expression} @dots{})
@var{body} @dots{})
@end lisp
@noindent
@ -442,7 +441,7 @@ is exactly equivalent to the longer form
@lisp
(define @var{name}
(lambda ([@var{arg1} [@var{arg2} @dots{}]])
@var{expression} @dots{}))
@var{body} @dots{}))
@end lisp
So, for example, the definition of @code{make-combined-string} in the
@ -459,18 +458,18 @@ of the @code{lambda} expression, which create a procedure that can
accept a variable number of arguments:
@lisp
(lambda (@var{arg1} @dots{} . @var{args}) @var{expression} @dots{})
(lambda (@var{arg1} @dots{} . @var{args}) @var{body} @dots{})
(lambda @var{args} @var{expression} @dots{})
(lambda @var{args} @var{body} @dots{})
@end lisp
@noindent
The corresponding forms of the alternative @code{define} syntax are:
@lisp
(define (@var{name} @var{arg1} @dots{} . @var{args}) @var{expression} @dots{})
(define (@var{name} @var{arg1} @dots{} . @var{args}) @var{body} @dots{})
(define (@var{name} . @var{args}) @var{expression} @dots{})
(define (@var{name} . @var{args}) @var{body} @dots{})
@end lisp
@noindent
@ -479,7 +478,7 @@ For details on how these forms work, see @xref{Lambda}.
Prior to Guile 2.0, Guile provided an extension to @code{define} syntax
that allowed you to nest the previous extension up to an arbitrary
depth. These are no longer provided by default, and instead have been
moved to @ref{Curried Definitions}
moved to @ref{Curried Definitions}.
(It could be argued that the alternative @code{define} forms are rather
confusing, especially for newcomers to the Scheme language, as they hide