8.18
top
← prev up next →

mutable-match-lambdaπŸ”— i

source code: https://github.com/AlexKnauth/mutable-match-lambda

These forms and functions allow mutable generic procedures like this:

Examples:
> (require mutable-match-lambda racket/vector)
> my+

#<procedure:my+>

> (mutable-match-lambda-add-clause! my+#:match-lambda*[(list (?number? ns)... )(apply + ns)])
> (my+12)

3

> (mutable-match-lambda-add-clause! my+#:match-lambda*[(list (?vector? vs)... )(apply vector-map + vs)])
> (my+#(12)#(34))

'#(4 6)

1mutable-match-lambda-procedureπŸ”— i

#:mutable
#:transparent)
name:any/c
procs:(listof procedure? )
represents a procedure, with a prop:procedure property that allows it to be applied as a procedure. It tries each of its procs in order, using mutable-match-lambda-clause-append . Forms like mutable-case-lambda and mutable-match-lambda all create instances of this. When they do, each clause is converted to a procedure (using clause->proc ) and the list of procedures is stored in the procs field.

procedure

...
[ #:namename])
proc:procedure?
name:any/c =#f
equivalent to (mutable-match-lambda-procedure name(list proc... )).

these functions add clauses to a mutable-match-lambda-procedure . The difference between them is that mutable-match-lambda-add-clause-proc! adds a clause that is only used when no other clause matches, and mutable-match-lambda-add-overriding-clause-proc! adds a clause that overrides the other clauses when it matches.

They are defined like this:

Examples:
> (require mutable-match-lambda racket/vector)
> (my+12)

3

> (my+#(12)#(34))

'#(4 6)

> (my+12)

3

> (my+#(12)#(34))

'#(4 6)

> (my+"not a number or a vector")

7

> (my+12)

42

syntax

( mutable-match-lambda-add-clause! proc-exprclause-proc-expr...)

(mutable-match-lambda-add-clause! proc-exprkwclause...)

syntax

( mutable-match-lambda-add-overriding-clause! proc-exprclause-proc-expr...)

these forms add clauses to a mutable-match-lambda-procedure . The first form (for both) adds the clause-proc-exprs to the list of procs, and is exactly like mutable-match-lambda-add-clause-proc! and mutable-match-lambda-add-overriding-clause-proc! . The second form (for both) converts the clauses to procedures (using (clause->proc kwclause)), and then adds those to the list of procs. The difference between them is the same as the difference between mutable-match-lambda-add-clause-proc! and mutable-match-lambda-add-overriding-clause-proc! .

Examples:
> (require mutable-match-lambda racket/vector)
> (mutable-match-lambda-add-clause! my+#:match-lambda*[(list (?number? ns)... )(apply + ns)])
> (my+12)

3

> (mutable-match-lambda-add-clause! my+#:match-lambda*[(list (?vector? vs)... )(apply vector-map + vs)])
> (my+#(12)#(34))

'#(4 6)

> (my+12)

3

> (my+#(12)#(34))

'#(4 6)

> (my+"not a number or a vector")

7

> (my+12)

42

procedure

...
[ #:namename])procedure?
proc:procedure?
name:any/c ='mutable-match-lambda
makes a new procedure that tries all of the procs in order.

This is what mutable-match-lambda-procedure uses to combine its clauses.

if it is called within a mutable-match-lambda-clause procedure, it signals to mutable-match-lambda-clause-append to try the next clause (if there is one). Otherwise it raises an error.

It is similar in spirit to match ’s failure-cont , except that it does escape the current context, and it cares about the dynamic extent, not syntactic scope.

procedure

...
[ #:namename])
proc:procedure?
name:any/c =#f
makes a new mutable-match-lambda-procedure that tries all of the procs in order.

The difference between this and make-mutable-match-lambda is that if a proc is a mutable-match-lambda-procedure , then its procs are spliced into the resulting list. As a result the mutable-match-lambda-procedures are effectively copied (and in fact mutable-match-lambda-copy is defined with mutable-match-lambda-append ).

If you don’t want this copying behavior, you can use make-mutable-match-lambda to achieve that.

if proc is a mutable-match-lambda-procedure , it returns a copy of proc. Otherwise it returns a mutable-match-lambda-procedure that has proc as its only clause.

It is equivalent to (mutable-match-lambda-append proc#:name(mutable-match-lambda-procedure-name proc)).

like make-mutable-match-lambda , except that it can infers the name argument from the context. For example, in (define my-proc(make-mutable-match-lambda/infer-name )), it infers the name 'my-proc.

It is used to infer the names for forms like mutable-case-lambda and mutable-match-lambda .

2mutable-match-lambda, etcπŸ”— i

syntax

( mutable-case-lambda case-lambda-clause...)

like case-lambda , except makes a mutable-match-lambda-procedure that you can add functionality to with procedures such as mutable-match-lambda-add-clause! . By the way, you can add other types of clauses than case-lambda clauses later.

It is defined like this:

Examples:
> (examples)

examples: undefined;

cannot reference an identifier before its definition

in module: top-level

syntax

( mutable-match-lambda match-lambda-clause...)

like match-lambda , except makes a mutable-match-lambda-procedure that you can add functionality to with procedures such as mutable-match-lambda-add-clause! . By the way, you can add other types of clauses than match-lambda clauses later.

It is defined like this:

Examples:
> (examples)

examples: undefined;

cannot reference an identifier before its definition

in module: top-level

syntax

( mutable-match-lambda* match-lambda*-clause...)

like match-lambda* , except makes a mutable-match-lambda-procedure that you can add functionality to with procedures such as mutable-match-lambda-add-clause! . By the way, you can add other types of clauses than match-lambda* clauses later.

It is defined like this:

Examples:
> (examples)

examples: undefined;

cannot reference an identifier before its definition

in module: top-level

3make-clause-proc and clause->procπŸ”— i

procedure

( make-clause-proc test-procthen-proc)procedure?

test-proc:procedure?
then-proc:procedure?
makes a procedure that mutable-match-lambda-procedure can use as a clause-proc. When it is called, it calls test-proc with it’s arguments, and if test-proc returns a true value, it then calls then-proc with its arguments. If test-proc returns #false, then it moves on to the next clause (if there is one).

Examples:
> (require mutable-match-lambda racket/vector)
> (define clause-1(make-clause-proc (λ args(andmap number? args))
(λ args(apply + args))))
> (define clause-2(make-clause-proc (λ args(andmap vector? args))
(λ args(apply vector-map + args))))
> (define my+
(make-mutable-match-lambda clause-1clause-2))
> (my+12)

3

> (clause-112)

3

> (my+#(12)#(34))

'#(4 6)

> (clause-2#(12)#(34))

'#(4 6)

syntax

( clause->proc kwclause)

makes a procedure that mutable-match-lambda-procedure can use as a clause-proc. The keyword specifies what type of clause it is.

For example (clause->proc #:match-lambda*match-lambda*-clause) creates a clause-proc that acts like a match-lambda* clause. It actually expands to (clause->proc/match-lambda* match-lambda*-clause), and then clause->proc/match-lambda* does the rest.

(clause->proc #:whateverclause) expands to (clause->proc/whateverclause), so if you define a macro with the name clause->proc/whatever, then you can use (clause->proc #:whateverclause).

When defining a new clause->proc/whatever macro, it should call mutable-match-lambda-next if it doesn’t match.

clause->proc/case-lambda , clause->proc/match-lambda , and clause->proc/match-lambda* are already defined, so to start with clause->proc supports #:case-lambda, #:match-lambda, and #:match-lambda* as keywords.

Examples:
> (clause->proc #:case-lambda[(xy)(list xy)])

#<procedure:(clause->proc #:case-lambda ((x y) (list x y)))>

> (define-syntax-rule (clause->proc/bool->ansans)
(lambda (x)
(if x
ans
> (define f
(clause->proc #:bool->ans42)
(lambda _ "didn't match")))
> (f#t)

42

> (f#f)

"didn't match"

syntax

( clause->proc/case-lambda clause)

syntax

( clause->proc/match-lambda clause)

these forms produce procedures that mutable-match-lambda-procedure can use as clause-procs, so you can use #:case-lambda etc. as keywords in clause->proc .

top
← prev up next →

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /