In TXR Lisp, the : symbol (keyword with empty string name) plays a big role.
It's used as a third value in situations when t and nil aren't enough.
In the syntax, it sets off optional lambda parameters: (lambda (a b : c d . r)): two required, two optional and a rest.
When an optional parameter is missing an argument, it receives the : value to indicate that, and that triggers the substitution of the default value. The default default value is nil.
The : argument value can be explicitly specified. Thus if a function f has three parameters, which are all optional, we can say:
(f : : 2)
This says, "default the first and second optionals, passing 2 to the third one".
A wrapper function can pull the following trick, where the optional parameters specify : itself as the default value:
(defun wrapper (a b : (c :) (d :))
(target a b c d)) ;; target also has two required, two optional
When you call wrapper as
(wrapper 1 2)
then the missing c and d default to : which is passed to target. Suppose that looks like:
(defun target (a b : (c 3) (d 4)) ...)
Then in target, that : value triggers defaulting: so c takes on 3 and d takes on 4.
This is exactly what would happen if we called (target 1 2), leaving c and d missing.
By using : as the default value for the optionals, the wrapper can propagate their missing status, allowing the target to do all the defaulting.
In the tree-bind destructuring binding construct, if a case yields the : value, it means "fall through to the next case", which allows tree-case to do quite a bit more.
The printed representation of : (the one the machine produces) is just : whereas in some Common Lisps you see something like :||. The empty name is escaped. I think ANSI CL doesn't allow the pppp:xxxx token syntax with xxxx missing. (2.3.5 Valid Patterns for Tokens). That's shame, since it's such a handy critter.
4 comments
[ 1.4 ms ] story [ 211 ms ] threadAre keywords not used as much in Scheme as they are in, say, Common Lisp?
It's used as a third value in situations when t and nil aren't enough.
In the syntax, it sets off optional lambda parameters: (lambda (a b : c d . r)): two required, two optional and a rest.
When an optional parameter is missing an argument, it receives the : value to indicate that, and that triggers the substitution of the default value. The default default value is nil.
The : argument value can be explicitly specified. Thus if a function f has three parameters, which are all optional, we can say:
This says, "default the first and second optionals, passing 2 to the third one".A wrapper function can pull the following trick, where the optional parameters specify : itself as the default value:
When you call wrapper as then the missing c and d default to : which is passed to target. Suppose that looks like: Then in target, that : value triggers defaulting: so c takes on 3 and d takes on 4.This is exactly what would happen if we called (target 1 2), leaving c and d missing.
By using : as the default value for the optionals, the wrapper can propagate their missing status, allowing the target to do all the defaulting.
In the tree-bind destructuring binding construct, if a case yields the : value, it means "fall through to the next case", which allows tree-case to do quite a bit more.
The printed representation of : (the one the machine produces) is just : whereas in some Common Lisps you see something like :||. The empty name is escaped. I think ANSI CL doesn't allow the pppp:xxxx token syntax with xxxx missing. (2.3.5 Valid Patterns for Tokens). That's shame, since it's such a handy critter.