[plt-scheme] naming convention for structure constructor vs. wrapper?

From: Felix Klock's PLT scheme proxy (pltscheme at pnkfx.org)
Date: Fri Jul 2 10:00:06 EDT 2004

On Jul 2, 2004, at 8:13 AM, Michael Sperber wrote:

>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
>>>>>> "Matthias" == Matthias Felleisen <matthias at ccs.neu.edu> writes:
>
> Matthias> One of my students has just had this need to use structs as
> Matthias> procedures.  Correct me if I am wrong but srfi-9 wouldn't
> Matthias> support this.
>
> What do you mean "need"?  A tremor starts in the little toes, sweat
> breaks out, and incomprehensible moans escape if the structs don't
> behave like procedures?  :-)

Well, I may not be the student that Matthias is referring to here, but 
since it is somewhat likely (2:1 odds) that whomever he is referring to 
is using a macro I wrote to define these structures (because for all 
its power, I will admit that MAKE-STRUCT-TYPE has a really obtuse 
interface), I will describe my own need, and how I used 
structures-as-procedures to rid myself of those nasty tremors and 
sweats (I rather liked the moans though).

Off the top of my head, I have used structures-as-procedures in two 
interesting ways.

-----

One was to define a purely functional table object that had no explicit 
lookup operation; instead, when it was used as a procedure, it did a 
lookup.  You had to use other functions to extend the mapping.

This was mostly a syntactic convenience.  There are ways to implement 
tables that do not act like structures, but then you have explicit 
lookup calls, which is a bear when you just want to write (MAP TABLE 
KEYS).

There are also ways to implement procedures that act like tables, but 
then you have to choose between linear lookup times (with the naive 
extension of just wrapping another lambda around the original table 
with the new key), or some sort of weird dispatch based on the number 
of arguments to decide whether you are doing a lookup or exposing the 
mapping.  I never bothered to implement the latter, so I can't say for 
sure whether its as ugly as I imagined it to be.

-----

The other was to define a special kind of partial function that 
operates on a (recursively defined) algebraic datatype, but where you 
can extend the partial function (in a purely functional manner) to 
handle new variants in the datatype's algebra.  Remember, this is a 
recursive datatype; that means that you want any recursive calls in the 
original function definition to call the *extended* version in the 
extension.

A quick example to illustrate what I mean here:

 > (define-extensible (foo num) (add1 num))
 > (define-extension (foo* foo) [(num-tree) (list? x) (map foo* 
num-tree)])
 > (foo 3)
4
 > (foo* '(3 2))
(4 3)
 > (foo* '((3 2) 1))
((4 3) 2)

The above is a silly example; but hopefully you can imagine more 
complex ADTs where you do want to just write the extensions 
incrementally.

One could implement this functionality by writing your code as if you 
were going to use the Y combinator to do the recursion, and then wait 
to actually use Y until after you've incorporated all of the extensions 
of interest.  But that means that you need to juggle two kinds of 
functions: the ones before Y's been applied, and the ones after Y's 
been applied.  Yuck.

I chose instead to approach it from an OO hackers point of view, where 
you explicitly pass a this argument around so that you can recur on it. 
  Of course, I didn't want to have to use an OO syntax like (SEND proc . 
args), so I found myself using structs-as-procedures to implement it.

-----

Perhaps conflating these uses with the core functionality of structures 
is misguided

But the idea of being to associate data with a procedure object (other 
than just the computation it provides) seems quite solid to me.  And in 
that sense, structs seem like an obvious choice, since they're all 
about associating distinct pieces of information with each other.  But 
if you have an alternate syntax/semantics in mind to get this sort of 
functionality, I'd love to hear your thoughts on it.

-Felix



Posted on the users mailing list.