Updates: Functional style support

Brian Rice water at tunes.org
Wed Feb 16 16:40:01 PST 2005


There's a new set of alpha's and slate-current tarball out with our 
newest features and fixes. Many of them affect the Slate core so I will 
go over these:

Extending the use of backticks (`):

The backtick character is currently used as a prefix for selectors so 
that they will be sent to the pre-evaluated form of the expression - 
that is, the parse tree that the expression forms. This has now been 
extended so that it can preface any expression, with the result being 
the quoted form of it. Equationally, "`(someExpr)" is the same as 
"someExpr `quote" where the quote macro-method simply returned the 
parse tree instead of expanding into it and being evaluated. The 
parentheses may be omitted if it does not conflict with the existing 
message-prefix grammatical usage of backticks (e.g. `4 or `[]).

Macro to generate trivial blocks:

Much of the collection and other protocols depend on creating a 
processing block. Some of the more trivial versions of these just grab 
some arguments, name them, and send them a message. So, we have 
provided the macro `er which takes a selector and expands into such a 
block. So, for example, "[| :x :y | x + y]" could be written as "#+ 
`er" (or "#+`er" which the parser accepts at least for now), which is a 
simple and typical argument for #reduce: or #inject:into:. It is 
expected to be read in a natural way, so that #+`er reads "plus-er" or 
"adder" if you like, and this applies to other selectors, like #name`er 
(which expands to "[| :x | x name]"). So generally, you just have to 
remember that "for selector X, an X`er is a block taking arguments for 
X and applying the selector to them, answering the result". And since 
it is a macro, this is just a syntax expansion that is invisible at 
run-time.

Method introspection:

A number of query methods have been added to method.slate for the 
purpose of easy access to some semantic information. In particular, I 
have made sure that they are polymorphic with existing query methods on 
parse trees. So, for example, to know the number of arguments a method 
requires, just use #arity, e.g. [] arity = 0, [| :x :_ | ] arity = 2. 
To find out what messages are sent, use #allSelectorsSent, which 
returns an array of the symbols directly invoked (magic involving 
creating the symbol at runtime and sendTo:ing that will not be 
processed yet). To find out if a method has a *rest parameter (which 
packages all extraneous positional arguments in an Array as a local to 
the called method), ask the method whether it 
#acceptsAdditionalArguments.

Method composition:

Functional composition has been added for all Method objects using the 
#** selector (also available as #compose:). So X ** Y yields a block 
that when called acts like X(Y(args)). The base case as in most 
functional languages, is that the inner/right function (Y) may take any 
number of arguments, and that X takes 1, and it does everything you 
would expect in a functional language. If both of these are false, then 
there is an extended form of the semantics where the arity of the 
outer/left function (X) is used to group the results of applying the 
inner/right function (Y) to each element in the argument array. The 
groups are then passed as a whole to one application of X. This sounds 
complicated, but is pretty intuitive once the idiom has been read and 
tried a few times. Examples:

Slate> [| :x :y | x ; y] ** [| :x | x name] applyTo: {#foo. #bar}.
'foobar'
Slate> #;`er ** #name`er applyTo: {#foo. #bar}.
'foobar'

Now, since #; is binary, in these examples, we could not join more than 
two Symbols quickly. Some extensions that are being practiced with 
allow easily mapping #reduce: or #collect: or similar selectors across 
a range of values. (Basically replace #;`er with "#;`er reducer".) Olli 
is looking at extending this into support for the full range of 
operations of say, array-processing APL, J, or K languages, but with 
user-level polymorphism and abstraction so they can be extended, 
consistent with the rest of the Slate libraries.

I will document these things in a section of the manual so that they 
can be found easily. Respond if you have any questions, comments, or 
uncertainty.

Thanks to the guys who prompted these improvements, mainly Olli, and 
enjoy!

--
Brian T. Rice
LOGOS Research and Development
http://tunes.org/~water/




More information about the Slate mailing list