Title

Author

Status

This SRFI is currently in final status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-26@nospamsrfi.schemers.org . To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.

Draft: 2002-02-06--2002-04-06

Revised: 2002-02-15

Revised: 2002-02-28

Revised: 2002-06-04

Revised: 2002-06-06

Final: 2002-06-14

Abstract

cons

(lambda (x) (cons 1 x))

The mechanism proposed here allows to write this sort of specialization in a simple and compact way. The mechanism is best explained by a few examples:

(cut cons (+ a 1) <>) is the same as (lambda (x2) (cons (+ a 1) x2)) (cut list 1 <> 3 <> 5) is the same as (lambda (x2 x4) (list 1 x2 3 x4 5)) (cut list) is the same as (lambda () (list)) (cut list 1 <> 3 <...>) is the same as (lambda (x2 . xs) (apply list 1 x2 3 xs)) (cut <> a b) is the same as (lambda (f) (f a b))

As you see, the macro cut specializes some of the parameters of its first argument. The parameters that are to show up as formal variables of the result are indicated by the symbol <> , pronouced as "slot". In addition, the symbol <...> , pronounced as "rest-slot", matches all residual arguments of a variable argument procedure. As you can see from the last example above, the first argument can also be a slot, as one should expect in Scheme.

In addition to cut , there is a variant called cute (a mnemonic for " cut with evaluated non-slots") which evaluates the non-slot expressions at the time the procedure is specialized, not at the time the specialized procedure is called. For example,

(cute cons (+ a 1) <>) is the same as (let ((a1 (+ a 1))) (lambda (x2) (cons a1 x2)))

As you see from comparing this example with the first example above, the cute -variant will evaluate (+ a 1) once, while the cut -variant will evaluate it during every invokation of the resulting procedure.

The mechanism proposed in this SRFI allows specializing any subset of the variables of a procedure. The result can be of fixed arity or of variable arity. The mechanism does not allow permutation, omission, duplication or any other processing of the arguments; for this it is necessary to write to use a different mechanism such as lambda .

Rationale

(cons 1)

Yet, Scheme is not a curried language---the number of arguments passed to a procedure must match the number of its parameters at all times. This allows zero- and variable-arity procedures but in order to specialize parameters one usually has to write down a lambda-expression and invent some irrelevant identifiers for its formal variables ( x in the example). For this reason, the mechanism proposed in this SRFI provides a simple and compact notation for specializing any subset of the parameters of a procedure.

Note: The mechanism proposed here is not currying!

The purpose of the mechanism proposed here is to make the benefits of currying available within the programming language Scheme. There are two primary benefits of currying in practice: Higher-order types are substantially simplified and there is a simple notation for specializing parameters. The type aspect is irrelevant as Scheme has latent typing. The specialization aspect is largly covered with this SRFI.

Here are a few more examples for illustration:

(map (cut * 2 <>) '(1 2 3 4)) (map (cut vector-set! x <> 0) indices) (for-each (cut write <> port) exprs) (map (cut <> x y z) (list min max)) (for-each (cut <>) thunks)

Specification

<cut-expression> --> (cut <slot-or-expr> <slot-or-expr>*) | (cut <slot-or-expr> <slot-or-expr>* <...>) ; with "rest-slot" | (cute <slot-or-expr> <slot-or-expr>*) ; evaluate non-slots at specialization time | (cute <slot-or-expr> <slot-or-expr>* <...>) ; with "rest-slot" <slot-or-expr> --> <> ; a "slot" | <expression> ; a "non-slot expression"

The macro cut transforms a <cut-expression> into a <lambda expression> with as many formal variables as there are slots in the list <slot-or-expr>* . The body of the resulting <lambda expression> calls the first <slot-or-expr> with arguments from <slot-or-expr>* in the order they appear. In case there is a rest-slot symbol, the resulting procedure is also of variable arity, and the body calls the first <slot-or-expr> with all arguments provided to the actual call of the specialized procedure.

The macro cute is similar to the macro cut , except that it first binds new variables to the result of evaluating the non-slot expressions (in an unspecific order) and then substituting the variables for the non-slot expressions. In effect, cut evaluates non-slot expressions at the time the resulting procedure is called, whereas cute evaluates the non-slot expressions at the time the procedure is constructed.

Implementation

cut

cute

<slot-or-expr;>

(param ... slot)

Finally, there is a small collection of confidence tests. It checks some special cases of the mechanism defined in this SRFI and signals an error in case something is wrong. Passing the tests does not mean a correct implementation.

Design Rationale

Why not real currying/uncurrying?

cut

Why not a more general mechanism, also allowing permutation, omission and duplication of arguments?

Why are the macro called cut/cute and not [enter your favourite here]?

curry

section

specialise

specialize

partial-apply

partial-call

partial-lambda

_j

_i

$

&

srfi-26

foobar

xyz

schoenfinkelize

curry-which-isnt-curry

tandoori

cut

cut

cut!

cutlet

cut*

cute

Is it possible to implement the SRFI without macros?

cute

cut

Why is there another symbol for the rest-slot when lambda-expressions use the dotted notation for variable length argument lists?

Why is it impossible to specify when a non-slot is evaluated individually per non-slot?

Cut

cute

let

lambda

Why is (cut if <> 0 1) etc. illegal?

<slot-or-expr>

<expression>

if

<expression>

cut

cute

Acknowledgements

Copyright

Copyright (C) Sebastian Egner (2002). All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.