Prism Rationale, Part 2

David Jeske
Tue, 5 Jan 1999 11:17:35 -0800

On Tue, Jan 05, 1999 at 09:23:21AM +0100, Laurent Martelli wrote:
>     David> I think there is definetly a related issue, where within a
>     David> given language, there are different (traditionally
>     David> syntactic) paradigms going on. For example, in C, do you
>     David> call a function or access an array? In higher-level
>     David> languages like smalltalk/self they homogonized all actions
>     David> into 'method calls/message sends'. However, then the
>     David> different paradigms are different protocols/collections of
>     David> methods. For example, do you use an array index type access
>     David> pattern (i.e. a->itemAt(1);) or do you use a linked-list
>     David> access pattern?
>     David> It's often the case that you have a body of code which uses
>     David> one access pattern, but you'd like to store the data in
>     David> another (usually superior) access pattern because you want
>     David> to add some functionality.
> I call this the problem of the right abstraction. I indexation is
> explicitly used when it is not needed, you are using the wrong
> abstraction. And you will not be able to operate on a non-indexed
> collection without rewriting the code. So at every moment, you should
> the right abstraction, which has the right amount of semantics. If you
> have too few semantics, your function will be too complicated and will
> contain code that would likely be reused somewhere else. But if you
> have too many semantics, you add unnecessary constraints. 

I disagree. I could very well write a piece of code which stores via
just an index, and that code could be fine. I might decide that I also
need to get at that data via some kind of key, so I can change the
storage to a hash table, but the original body of code is just going
to use a numeric index. I certainly can (conceptually) get both pieces
of code to work without changing the abstraction of either. I just
have to make sure the data is stored in such a way that it has both a
numeric index and a hash index.

Issues like this are particularly troublesome in languages like C,
because the syntax I choose to access a piece of data _implies
type_. So if I have some array, and I access it as an array in C, I
can't later change it to a hash-table and provide 'array compatible'
access for that body of code.

However, I don't want to throw out domain specific syntax, because
frankly, compact syntax is easier to understand. Consider:

   [[[a itemAt:1] mul: [b itemAt:2]] div: [c itemAt:3]];  // objective-C

   a[1] * b[2] / c[3];  // standard array syntax

What I do want to do is be able to rebind the meaning of a given
syntax based on the receiver. This is different (in my mind) than
operator overloading, because in traditional class based operator
overloading systems, you are bound to class-based rules like 'you have
to subclass to make a type compatible object'. Wheras I want to
construct a type-compatible object from scratch, and provide different
bindings for the syntax operations which are used on that object.

David Jeske (N9LCA) + +