Node: Control features, Next: , Previous: Vectors, Up: Standard Procedures



Control features

procedure? obj R5RS
Returns #t if obj is a procedure, otherwise returns #f.
          (procedure? car)                            =>  #t
          (procedure? 'car)                           =>  #f
          (procedure? (lambda (x) (* x x)))           =>  #t
          (procedure? '(lambda (x) (* x x)))          =>  #f
          (call-with-current-continuation procedure?) =>  #t
          

apply proc arg1 ... args R5RS
Proc must be a procedure and args must be a list. Calls proc with the elements of the list
          (append (list arg1 ...) args)
          
as the actual arguments.
          (apply + (list 3 4))              =>  7
          
          (define compose
            (lambda (f g)
               (lambda args
                 (f (apply g args)))))
          
          ((compose sqrt *) 12 75)          =>  30
          

map proc list1 list2 ... R5RS
The lists must be lists, and proc must be a procedure taking as many arguments as there are lists and returning a single value. If more than one list is given, then they must all be the same length. Map applies proc element-wise to the elements of the lists and returns a list of the results, in order. The dynamic order in which proc is applied to the elements of the lists is unspecified.
          (map cadr '((a b) (d e) (g h)))   =>  (b e h)
          
          (map (lambda (n) (expt n n))
               '(1 2 3 4 5))                =>  (1 4 27 256 3125)
          
          (map + '(1 2 3) '(4 5 6))         =>  (5 7 9)
          
          (let ((count 0))
            (map (lambda (ignored)
                (set! count (+ count 1))
                count)
                 '(a b)))                   =>  (1 2) or (2 1)
          

for-each proc list1 list2 ... R5RS
The arguments to for-each are like the arguments to map, but for-each calls proc for its side effects rather than for its values. Unlike map, for-each is guaranteed to call proc on the elements of the lists in order from the first element(s) to the last, and the value returned by for-each is void.
          (let ((v (make-vector 5)))
            (for-each (lambda (i)
                        (vector-set! v i (* i i)))
                      '(0 1 2 3 4))
            v)                                =>  #(0 1 4 9 16)
          

every pred list1 list2 ... STKLOS Procedure

every applies the predicate pred across the lists, returning true if the predicate returns true on every application.

If there are n list arguments list1 ... listn, then pred must be a procedure taking n arguments and returning a boolean result.

every applies pred to the first elements of the listi parameters. If this application returns false, every immediately returns #f. Otherwise, it iterates, applying pred to the second elements of the listi parameters, then the third, and so forth. The iteration stops when a false value is produced or one of the lists runs out of values. In the latter case, every returns the true value produced by its final application of pred. The application of pred to the last element of the lists is a tail call.

If one of the listi has no elements, every simply returns #t.

Like any, every's name does not end with a question mark - this is to indicate that it does not return a simple boolean (#t or #f), but a general value.

any pred list1 list2 ... STKLOS Procedure
any applies the predicate across the lists, returning true if the predicate returns true on any application.

If there are n list arguments list1 ... listn, then pred must be a procedure taking n arguments.

any applies pred to the first elements of the listi parameters. If this application returns a true value, any immediately returns that value. Otherwise, it iterates, applying pred to the second elements of the listi parameters, then the third, and so forth. The iteration stops when a true value is produced or one of the lists runs out of values; in the latter case, any returns #f. The application of pred to the last element of the lists is a tail call.

Like every, any's name does not end with a question mark - this is to indicate that it does not return a simple boolean (#t or #f), but a general value.

          (any integer? '(a 3 b 2.7))   => #t
          (any integer? '(a 3.1 b 2.7)) => #f
          (any < '(3 1 4 1 5)
                 '(2 7 1 8 2))          => #t
          

force promise R5RS
Forces the value of promise (see see delay). If no value has been computed for the promise, then a value is computed and returned. The value of the promise is cached (or "memoized") so that if it is forced a second time, the previously computed value is returned.
          (force (delay (+ 1 2)))        =>  3
          (let ((p (delay (+ 1 2))))
            (list (force p) (force p)))  =>  (3 3)
          
          (define a-stream
            (letrec ((next (lambda (n)
                             (cons n (delay (next (+ n 1)))))))
              (next 0)))
          (define head car)
          (define tail (lambda (stream) (force (cdr stream))))
          
          (head (tail (tail a-stream)))  =>  2
          

Force and delay are mainly intended for programs written in functional style. The following examples should not be considered to illustrate good programming style, but they illustrate the property that only one value is computed for a promise, no matter how many times it is forced.

          (define count 0)
          (define p (delay (begin (set! count (+ count 1))
                                  (if (> count x)
                                      count
                                      (force p)))))
          (define x 5)
          p                     =>  a promise
          (force p)             =>  6
          p                     =>  a promise, still
          (begin (set! x 10)
                 (force p))     =>  6
          
Note: See R5RS for details on a posssible way to implement force and delay.

call-with-current-continuation proc R5RS
call/cc proc R5RS
Current version of call-with-current-continuation is not conform to R5RS . Furthermore, the current implementation can lead to a fatal error in some circumstances.

// MUST BE CHANGED FOR NEXT RELEASE

Note: call/cc is just another name for call-with-current-continuation.

values obj ... R5RS
Delivers all of its arguments to its continuation. Note: R5RS imposes to use multiple values in the context of of a call-with-values. In STKLOS, if values is not used with call-with-values, only the first value is used (i.e. others values are ignored).

call-with-values producer consumer R5RS
Calls its producer argument with no values and a continuation that, when passed some values, calls the consumer procedure with those values as arguments. The continuation for the call to consumer is the continuation of the call to call-with-values.
          (call-with-values (lambda () (values 4 5))
                            (lambda (a b) b))                =>  5
          
          (call-with-values * -)                             =>  -1
          

receive <formals> <expression> <body> STKLOS Syntax
This form is defined in SRFI-8 ("Binding to Multiple values"). It simplifies the usage of multiple values. Specifically, <formals> can have any of three forms:
  • (<variable1> ... <variablen>): The environment in which the receive-expression is evaluated is extended by binding <variable1>, ..., <variablen> to fresh locations. The <expression> is evaluated, and its values are stored into those locations. (It is an error if <expression> does not have exactly n values.)
  • <variable>: The environment in which the receive-expression is evaluated is extended by binding <variable> to a fresh location. The <expression> is evaluated, its values are converted into a newly allocated list, and the list is stored in the location bound to <variable>.
  • (<variable1> ... <variablen> . <variablen + 1>): The environment in which the receive-expression is evaluated is extended by binding <variable1>, ..., <variablen + 1> to fresh locations. The <expression> is evaluated. Its first n values are stored into the locations bound to <variable1> ... <variablen>. Any remaining values are converted into a newly allocated list, which is stored into the location bound to <variablen + 1>. (It is an error if <expression> does not have at least n values.)

In any case, the expressions in <body> are evaluated sequentially in the extended environment. The results of the last expression in the body are the values of the receive-expression.

          (let ((n 123))
            (receive (q r)
               (values (quotient n 10) (modulo n 10))
               (cons q r)))
                        => (12 . 3)
          

dynamic-wind before thunk after R5RS
Current version of dynamic-wind mimics the R5RS one. In particular, it does not yet interact with call-with-current-continuation as required by R5RS .

Calls thunk without arguments, returning the result(s) of this call. Before and after are called, also without arguments, as required by the following rules (note that in the absence of calls to continuations captured using call-with-current-continuation the three arguments are called once each, in order). Before is called whenever execution enters the dynamic extent of the call to thunk and after is called whenever it exits that dynamic extent. The dynamic extent of a procedure call is the period between when the call is initiated and when it returns. In Scheme, because of call-with-current-continuation, the dynamic extent of a call may not be a single, connected time period.

See R5RS for more details ...

// MUST BE CHANGED for NEXT RELEASE

eval expression environment R5RS
eval expression R5RS
Current form of STKLOS eval is not conform to R5RS .

// MUST BE CORRECTED FOR NEXT RELEASE

DESCRIBE HERE CALL/EC AND WITH-HANDLER