| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| 6.16.1 Procedures | ||
| 6.16.2 Applicable objects | ||
| 6.16.3 Continuation | ||
| 6.16.4 Multiple values | ||
| 6.16.5 Delayed evaluation |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[R5RS]
Returns #t if obj is a procedure, #f otherwise.
[R5RS]
Calls a procedure proc with a list of arguments,
(arg1 … . args).
The last argument args must be a proper list.
Returns (a) value(s) proc returns.
(apply list 'a 'b '(c d e)) ⇒ (a b c d e) (apply + 1 2 '(3 4 5)) ⇒ 15 |
| 6.16.1.1 Mapping | ||
| 6.16.1.2 Combinators | ||
| 6.16.1.3 Optional argument parsing | ||
| 6.16.1.4 Procedure arity |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[R5RS+]
Applies proc for each element(s) of given list(s),
and returns a list of the results. R5RS doesn't specify
the application order of map, but Gauche guarantees
proc is always applied in order of the list(s).
Gauche's map also terminates as soon as one of
the list is exhausted.
(map car '((a b) (c d) (e f))) ⇒ (a c e) (map cons '(a b c) '(d e f)) ⇒ ((a . d) (b . e) (c . f)) |
Note that the gauche.collection module (See section gauche.collection - Collection framework)
extends map to work on any type of collection.
[R5RS]
Applies proc for each element(s) of given list(s) in order.
The results of proc are discarded. The return value of
for-each is undefined. When more than one list is given,
for-each terminates as soon as one of the list is exhausted.
Note that the gauche.collection module (See section gauche.collection - Collection framework)
extends for-each to work on any type of collection.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Gauche has some primitive procedures that allows combinatory programming.
Partial application. Returns a procedure, and when it is
called with arguments m …, it is equivalent to call
(proc arg … m …).
(define add3 (pa$ + 3)) (add3 4) ⇒ 7 (map (pa$ * 2) '(1 2 3)) ⇒ (2 4 6) |
Macros cut and cute defined in SRFI-26 provide
a similar abstraction, with a bit more flexible but less compact
notation. See section Making Procedures.
Partial application versions of apply, map and for-each.
(define map2* (map$ (pa$ * 2))) (map2* '(1 2 3)) ⇒ (2 4 6) |
Partial application versions of some srfi-1 procedures
(See section srfi-1 - List library).
Combine procedures. All arguments must be procedures.
When two procedures are given, (compose f g) is equivalent to
the following code:
(lambda args (call-with-values (lambda () (apply g args)) f)) |
When more than two arguments are passed, they are composed as follows:
(compose f g h ...) ≡ (compose (compose f g) h ...) |
Some examples:
(define not-zero? (compose not zero?)) (not-zero? 3) ⇒ #t (not-zero? 0) ⇒ #f (define dot-product (compose (apply$ +) (map$ *))) (dot-product '(1 2 3) '(4 5 6)) ⇒ 32 |
A couple of edge cases: if only one argument is given, the argument
itself is returned. If no arguments are given, the procedure values
is returned.
Returns a procedure that reverses the meaning of the predicate pred. That is, for the arguments for which pred returns true return false, and vice versa.
(map (complement even?) '(1 2 3)) ⇒ '(#t #f #t) (map (complement =) '(1 2 3) '(1 1 3)) ⇒ '(#f #t #f) ((complement (lambda () #f))) ⇒ #t |
Returns a procedure which applies given argument(s) to
each predicate pred. If any pred returns
a non-#f value, the value is returned. If all the preds
return #f, #f is returned.
(define string-or-symbol? (any-pred string? symbol?))
(string-or-symbol? "abc") ⇒ #t
(string-or-symbol? 'abc) ⇒ #t
(string-or-symbol? 3) ⇒ #f
(define <> (any-pred < >))
(<> 3 4) ⇒ #t
(<> 3 3) ⇒ #f
((any-pred (cut memq <> '(a b c))
(cut memq <> '(1 2 3)))
'b) ⇒ '(b c)
|
Returns a procedure which applies given argument(s) to
each predicate pred. If every pred returns
a non-#f value, the value returned by the last pred
is returned. If any pred returns #f, every-pred
returns #f without calling further preds.
((every-pred odd? positive?) 3) ⇒ #t ((every-pred odd? positive?) 4) ⇒ #f ((every-pred odd? positive?) -3) ⇒ #f (define safe-length (every-pred list? length)) (safe-length '(a b c)) ⇒ 3 (safe-length "aaa") ⇒ #f |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To have optional arguments or keyword arguments in Scheme, you have to take variable arguments as a list and decompose them by yourself. The following macros help it.
Given a list of values restargs, binds variables according to var-spec, then evaluates body.
Var-spec can be either a symbol, or a list of two elements and its car is a symbol. The symbol is the bound variable name. The values in restargs are bound to the symbol in order. If there are not as many values in restargs as var-spec, the rest of symbols are bound to the default values, determined as follows: If var-spec is just a symbol, the default value is undefined. If var-spec is a list, the default value is the result of evaluation of the second element of the list. In the latter case the second element is only evaluated when there are not enough arguments. The binding proceeds in the order of var-spec, so the second element may refer to the bindings of previous var-spec.
In the second form, restvar must be a symbol and bound to the list of values whatever left from restargs after binding to var-spec.
It is not an error if restarg has more values than var-specs. The extra values are simply ignored in the first form.
(define (proc x . args)
(let-optionals* args ((a 'a)
(b 'b)
(c 'c))
(list x a b c)))
(proc 0) ⇒ (0 a b c)
(proc 0 1) ⇒ (0 1 b c)
(proc 0 1 2) ⇒ (0 1 2 c)
(proc 0 1 2 3) ⇒ (0 1 2 3)
(define (proc2 . args)
(let-optionals* args ((a 'a) . b)
(list a b)))
(proc2) ⇒ (a ())
(proc2 0) ⇒ (0 ())
(proc2 0 1) ⇒ (0 (1))
(proc2 0 1 2) ⇒ (0 (1 2))
(define (proc3 . args)
(let-optionals* args ((a 0)
(b (+ a 1))
(c (+ b 1)))
(list a b c)))
(proc3) ⇒ (0 1 2)
(proc3 8) ⇒ (8 9 10)
(proc3 8 2) ⇒ (8 2 3)
(proc3 8 2 -1) ⇒ (8 2 -1)
|
This is a short version of let-optionals* where you have only one optional argument. Given the optional argument list restargs, this macro returns the value of optional argument if one is given, or the result of default otherwise. Default is not evaluated unless restargs is an empty list.
(define (proc x . maybe-opt)
(let ((option (get-optional maybe-opt #f)))
(list x option)))
(proc 0) ⇒ (0 #f)
(proc 0 1) ⇒ (0 1)
|
This macro is for keyword arguments. Var-spec can be one of the following forms:
(symbol expr)If the restrag contains keyword which has the same name as symbol, binds symbol to the corresponding value. If such a keyword doesn't appear in restarg, binds symbol to the result of expr.
(symbol keyword expr)If the restarg contains keyword keyword, binds symbol to the corresponding value. If such a keyword doesn't appear in restarg, binds symbol to the result of expr.
The default value expr is only evaluated when the keyword is not given to the restarg.
If you use the first form, let-keyword regards it an error
when restarg contains a keyword argument that is not listed
in var-specs. For the backward compatibility it only issues
warning now, but in future releases it will raise an error.
When you want to allow keyword arguments other than listed in
var-specs, use the second form.
In the second form, restvar must be either a symbol or #f.
If it is a symbol, it is bound to a list of keyword arguments
that are not processed by var-specs. If it is #f,
such keyword arguments are just ignored.
(define (proc x . options)
(let-keywords options ((a 'a)
(b :beta 'b)
(c 'c)
. rest)
(list x a b c rest)))
(proc 0) ⇒ (0 a b c ())
(proc 0 :a 1) ⇒ (0 1 b c ())
(proc 0 :beta 1) ⇒ (0 a 1 c ())
(proc 0 :beta 1 :c 3 :unknown 4) ⇒ (0 a 1 3 (:unknown 4))
|
Like let-keywords, but the binding is done in the order of
var-specs. So each expr can refer to the variables bound by
preceding var-specs.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Interface to query procedure's arity. The API is taken from MzScheme (PLT Scheme).
Given procedure proc, returns an integer, an arity-at-least object, or a list of integer(s) and arity-at-least objects.
An integer result indicates proc takes exactly that number
of arguments. An arity-at-least indicates proc takes
at least (arity-at-least-value arity-at-least)
arguments. The list indicates there are multiple procedures
with different arities.
Since one can add methods to an existing procedure or generic function
at any moment in Gauche, the value returned by arity only
indicates the current state of the procedure. It will change
if new method is added to the procedure/generic-function.
(arity cons) ⇒ 2 (arity list) ⇒ #<arity-at-least 0> (arity make) ⇒ (#<arity-at-least 1>) |
Returns true if obj is an arity-at-least object.
Returns the number of required arguments the arity-at-least object indicates.
If a procedure proc can take k arguments, returns #t.
Otherwise returns #f.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Gauche has a special hook to make an arbitrary object applicable.
If an object that is neither a procedure nor a generic function
is applied to some arguments,
the object and the arguments are passed to a generic function
object-apply.
This can be explained better by examples.
For example, suppose you try to evaluate the following expression:
("abcde" 2)
|
The operator evaluates to a string, which is neither a procedure nor a generic function. So Gauche interprets the expression as if it were like this:
(object-apply "abcde" 2) |
Gauche doesn't define a method of object-apply that takes
<string> and <integer> by default, so this signals an error.
However, if you define such a method:
(define-method object-apply ((s <string>) (i <integer>)) (string-ref s i)) |
Then the first expression works as if a string is applied on the integer:
("abcde" 2) ⇒ #\c
|
This mechanism works on almost all occasions where a procedure is allowed.
(apply "abcde" '(1)) ⇒ (#\b) (map "abcde" '(3 2 1)) ⇒ (#\d #\c #\b) |
Among Gauche built-in objects, <regexp> object and
<regmatch> object have object-apply defined.
See section Regular expression.
If a form of applying an applicable object appears in the first position
of set! form, this method is called, that is:
(set! (object arg …) value) ⇒ ((setter object-apply) object arg … value) |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[R5RS]
Encapsulates the current continuation to a procedure
(“continuation procedure”), and calls proc with it.
When proc returns, its value becomes call/cc's value.
When the continuation procedure is invoked with zero or more arguments
somewhere, the further calculation is abandoned and call/cc returns
with the arguments given to the continuation procedure.
First class continuation is one of the most distinct feature of Scheme, but this margin is too small to contain explanation. Please consult to the appropriate documents.
Gauche supports full continuation, with a few limitations in rare cases. Normally a continuation has an unlimited extent. However, if a continuation is created during “callback” from C code— that is, you call some C-implemented function that calls Scheme code again—the continuation's extent is limited until the Scheme evaluation returns to the C code. If you try to invoke the continuation from out of its extent, Gauche detects it and signals an error. This is a fundamental limitation and not likely to be addressed.
Note that it is still allowed to invoke a continuation from
such callbacks.
Also, the typical higher-order functions such as map, for-each
or apply are not using callbacks, and not affected by this limitation
Fortunately, there are not much cases that you need to create an unlimited extent continuation in such callbacks. So far, the following code is executed in such callbacks. Besides them, typical callback functions from external C libraries, like GUI toolkit, obeys the same limitation.
write-object method that is invoked from write,
display or format (See section Output).
gauche.vport - Virtual ports).
This macro expands to :
(call/cc (lambda (var) body …)).
The API is taken from PLT Scheme.
[R5RS]
Before, thunk and after are all procedures with
no arguments.
In normal situation, dynamic-wind calls before, then thunk,
then after, then returns whatever value(s) thunk returned.
If a control flow goes out from thunk by invoking a continuation
captured outside of the dynamic scope of dynamic-wind
(for example, an error is signalled in thunk),
after is called.
If a control flow goes into thunk by invoking a continuation
captured inside thunk from outside of the dynamic
scope of dynamic-wind, before is called.
(letrec ((paths '())
(c #f)
(add (lambda (s) (push! paths s))))
(dynamic-wind
(lambda () (add 'connect))
(lambda ()
(add (call/cc (lambda (c0) (set! c c0) 'talk1))))
(lambda () (add 'disconnect)))
(if (< (length paths) 4)
(c 'talk2)
(reverse paths)))
⇒ (connect talk1 disconnect connect talk2 disconnect)
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[R5RS]
Returns obj … as multiple values.
Caller can capture multiple values by a built-in syntax
receive (Binding constructs), or the R5Rs procedure
call-with-values described below.
See also srfi-11 - Let-values.
(values 1 2) ⇒ 1 and 2
|
[R5RS] Call a procedure producer with no argument. Then applies a procedure consumer on the value(s) producer returned. Returns the value(s) consumer returns.
(call-with-values (lambda () (values 1 2)) cons) ⇒ (1 . 2) |
Returns k-th value of what mv-expr returns. Conceptually, it is the same as the following code.
(call-with-values (lambda () mv-expr) (lambda r (list-ref r k))) |
This macro uses shortcuts for the typical cases like k is zero.
Similar to Common Lisp's nth-value, but the argument order
is flipped to match other Scheme's *-ref procedures.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Gauche provides an extended lazy evaluation mechanism according
to srfi-45. Instead of two primitives as R5RS, we have three:
lazy, delay, and force.
It is found that the traditional mechanism that uses only
delay and force didn't mix well with tail-recursive
algorithms: It required unbound memory, despite that the
body of the algorithm could be expressed in iterative manner.
For the detailed explanation please look at the srfi-45 document.
Here we explain how to use those primitives.
[SRFI-45][R5RS]
These forms creates a promise that delays the evaluation
of expression. Expression will be evaluated
when the promise is passed to force.
If expression itself is expected to yield a promise,
you should use lazy. Othewise, you should use delay.
If you can think in types, the difference may be clearer.
lazy : Promise a -> Promise a delay : a -> Promise a |
Since we don't have static typing, we can't enforce this usage.
The programmer has to choose appropriate one from the context.
Generally, lazy appearers only to surround the entire
body of function that express a lazy algorithm.
For the real-world example of use of lazy,
you may want to check the implementation of util.stream
(See section util.stream - Stream library).
[R5RS] If promise is not a promise, it is just returned.
Otherwise, if promise's value hasn't been computed,
force makes promise's encapsulated expression
be evaluated, and returns the result.
Once promise's value is computed, it is memorized in it
so that subsequent force on it won't cause the computation.
Returns #t iff obj is a promise object.
The following example represents Fibonacci numbers by
a lazy list. The list fib is calculated by
adding fib itself shifted one element.
Since it uses cached result of previous elements, calculation
of n-th Fibonacci number can be done in O(n).
(define (lcar lis) ;; lazy car
(car (force lis)))
(define (lcdr lis) ;; lazy cdr
(cdr (force lis)))
(define (ltake lis n) ;; lazy take
(if (<= n 0) '() (cons (lcar lis) (ltake (lcdr lis) (- n 1)))))
(define (lmap proc l1 l2) ;; lazy map
(if (null? l1)
'()
(cons (proc (lcar l1) (lcar l2))
(delay (lmap proc (lcdr l1) (lcdr l2))))))
;; lazy list of fibonacci numbers
(define fibs (list* 1 1 (delay (lmap + fibs (cdr fibs)))))
;; take a look
(ltake fibs 20)
⇒ (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
987 1597 2584 4181 6765)
|
Note that, although it is elegant, it also requires O(n) storage
even when you only need n-th Fibonacci number. That's because
the delay expression in the tail of fibs is grabbing
the head of fibs list and never releases it.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated by Shiro Kawai on October, 7 2008 using texi2html 1.78.