[Fwd: Re: Prism Rationale, Part 1]

Jim Little jiml@inconnect.com
Wed, 06 Jan 1999 19:45:34 -0700

The following message is one of several that was accidently sent
directly to David Jeske instead of to the mailing list.  I don't know if
you'll find it useful, but here it is:

-------- Original Message --------
Subject: Re: Prism Rationale, Part 1
Date: Tue, 05 Jan 1999 02:07:55 -0700
From: Jim Little <jiml@inconnect.com>
To: David Jeske <jeske@home.chat.net>
References: <369196EA.4C3A0F6A@inconnect.com>

David Jeske wrote:
> I've read much of the Prism stuff. I like where you're going. There
> definetly sounds like there is some crossover with my own ideas,
> particular the whole idea of allowing people to use several domains
> (i.e. syntax, structure, etc) seamlessly together.

Thanks!  I was hoping there would be some crossover, and it seemed like
it from reading the list, but you never can be sure.  :)

> I think the way you describe 'domains' they are very similar to
> 'aspects' in an aspect oriented programming model.

There is a lot of similarity between Prism and AOP.  The difference is
mostly a matter of scope, I think.  AOP, as I see it, is trying to
define a single DSL which uses multiple languages which are "woven"
together at compile time.  Prism, on the other hand, is trying to define
a system in which multiple DSL's can be "patched" together to create a
large system.

To use an analogy, aspect-oriented programming is like weaving a rug. 
Each thread is a different domain abstraction and they're all mingled
together to produce the result.  Prism programming is like sewing a
quilt.  Each square is a different domain abstraction and they're all
grouped together to produce the result.

Although AOP and Prism are similar from the outside, the approach they
take on the inside is very different.  Prism focuses very strongly on
enabling the user to create his own domain abstractions via the
"reflection domain".  AOP, on the other hand, has (I think) a fixed set
of "aspect languages" which the Aspect Weaver(tm) is aware of.  Prism
also uses a semantic approach to programming, while AOP uses a more
traditional syntactic approach.

I could be totally wrong, though.  There's a lot more on the AOP web
site than there was last time I looked.  :)

> I tend to think of "system abstraction" as the idea of doing a sort of
> linear expansion of functionality.  Where one 'instruction' may 
> expand into a single machine instruction or if it's abstracted,
> a large set of instructions.
> While "domain abstraction" I tend to think of as places where the
> abstraction affects code generated for logical constructs.
> I don't know how useful that description is for anyone else, and it's
> not 100% clear or thought out, but there is this gestalt in my head
> and that's my best description of it.

You're exactly right, though.  I would only add that the word
"instruction" could actually be replaced with any word, like "object" or
"make file".  The important thing is that (as you say), from the outside
a system abstraction looks like a single component.

It's probably worth noting that system abstraction, as I define it, is a
superset of lambda abstraction (as I understand it).

>> * Semantic errors may be reduced by using a programmable system whose
>> semantics are as close as possible to the semantics of the problem
>> domain.
> Sounds like the same justification for using 'domain specific
> languages'.

You beat me to it.  :)  I go into exactly that point in the second part
of my article.

> > If anybody got this far, let me know and I'll send you a virtual
> > lollipop.  :)
> I definetly got this far. :)

Great!  Thanks for commenting.  You have no idea how nice it is to talk
to somebody about this after working on it for nine months and getting
nothing but groans and blank stares every time I brought it up.  So
here's your virtual lollipop:  o---  Enjoy!  :)

Nine months... hmm... that number sounds familiar...

While I was writing the above response, your response to the second part
of my article came in.  Here's my response to your response:

>> I call this philosophy "Paradigm-Independent Software Engineering"
>> (PISE).  The idea is that no one programming technique, be it
>> object-oriented programming, functional programming, or even spaghetti
>> programming :), is the right tool for every job.  But they're all the
>> right tool for some jobs (yes, even spaghetti programming... um, maybe).
> I think there is definetly a related issue, where within a given
> language, there are different (traditionally syntactic) paradigms
> going on. For example, in C, do you call a function or access an
> array?

I agree.  In fact, if you think about the languages which are considered
the most complex and hard to predict, I think you'd find that they were
the languages which tried to cover the most paradigms.

For example, C is a fairly straightforward language.  It's uses
low-level imperative paradigm.  There's some quirks (like not being able
to take the reference of a global array) but even these make sense when
you consider how the language maps to the hardware.

C++ and Perl, on the other hand, are the two most complex languages I
can think of.  They both mix multiple paradigms, leading to syntax which
doesn't clearly map to semantics.  C++ tries to be the ultimate
low-level imperative language as well as the ultimate object-oriented
language.  Heck, it even has a bit of programmer-directed domain
abstraction, in the form of templates and operator overloads.  

And Perl-- Perl tries to be, well, everything.  In my opinion, it
succeeds badly.  :)  Don't get me wrong, I like Perl, it's incredibly
convenient, but whenever I go back to it after a break I have a
hellacious time making my programs work.

Looking back at what you said, I think I completely misunderstood you. 

> In higher-level languages like smalltalk/self they homogonized
> all actions into 'method calls/message sends'. However, then the
> different paradigms are different protocols/collections of
> methods. For example, do you use an array index type access pattern
> (i.e. a->itemAt(1);) or do you use a linked-list access pattern?
> It's often the case that you have a body of code which uses one access
> pattern, but you'd like to store the data in another (usually
> superior) access pattern because you want to add some functionality.

Even though I'm not sure what you're saying here, I'll take this
opportunity to go off on a tangent.  :)  Even though the object-oriented
paradigm is very nice -- simple, complete, powerful -- it still doesn't
do everything well.  For example, in writing the Prism Compiler, I used
Smalltalk's Model-View-Controller pattern... aka "Observer" in GOF's
_Design Patterns_ book.

That pattern works really well, it's powerful, but aren't I just trying
to emulate a higher-level domain abstraction with objects?  Just like
you can emulate object-oriented programming in a structured language
(trust me, I did it in QuickBasic -- and if you can do it in QuickBasic,
you can do it in anything! :) )  ...Uh, anyway, aren't I basically
emulating event-oriented programming with objects?  As I was programming
that code, I couldn't but thinking it would be a lot more convenient if
I could just create an event-oriented domain abstraction in which I
would say "when X changes, tell Y" or even "Y depends on X."   Without
all that observer/listener code I had to keep writing over and over in
each class.

Your original statement about system abstraction and domain abstraction
is very true.  System abstraction means viewing a chunk of code as one
instruction.  Domain abstraction means factoring out repeated chunks of
code.  I think any time we look at a program and see that every function
(or class, or whatever) repeats the same pattern of identical or
nearly-identical lines of code, there we have a candidate for domain

Of course, from a software engineering standpoint, I'd rather identify a
domain abstraction by looking at problem domains than source code, but
either way works.  :)

Jim Little  (jiml@inconnect.com)
Prism is at http://www.teleport.com/~sphere