Tunes Concept of the Week

Francois-Rene Rideau
Wed, 5 Jun 1996 00:24:21 +0200 (MET DST)


>> With this system, any "user" could perform any task normally reserved
>> for "programmers", and any "program" could perform tasks normally
>> reserved for "users".  The system, Tunes, becomes one large, integrated,
>> flexible environment in which the value of each tool is exponentially
>> increased by the ease with which it can connect to all other tools.
> To do that, user interfaces must be dumb an simple. The user
> interfaces here are the "program-human adapters" that sit on top of
> the interfaces for progams. In fact it would be ideal to unify the two
> interfaces by having programs provide only one but with enough high
> level information that could be use to provide a nice human interface
> automatically. A function of type A and B into C could be called by a
> human by dragging a B on a A to produce a C... If this function is not
> convenient you could then try defining new functions to mirror the way
> you'd like to drag and dorp things, these function would then be
> available to programs also.
My proposal is the following:
There is not only the lambda constructor,
that creates functions taking a parameter matching given pattern,
but also an epsilon constructor (as in Hilbert's epsilon symbol),
that "magically" instanciate a variable of matching given pattern,
or fails in a recoverable manner.
   What happens when an epsilon constructor is evaluated,
is that an expression dynamically supplied from the exterior is
evaluated at the place where the epsilon is.
   If no valid expression was supplied anyhow,
then an exception is raised.
But the compiler would generate code from user-controllable tactics,
and the user-interface would trap any remaining epsilon.

Evaluation is doable, because a meta-system can transform
epsilons into lambdas with lots of added parameters that account
for all that's implicitly in the epsilon's context:
every epsilon means that an additional parameter
will be implicitly propagated to all upper expressions,
that will correspond to a function to resolve the epsilon
with all that's statically visible being implicit parameters,
plus optional explicit hints.
   An implementation of epsilons could thus consist
in replacing them by usual lambda stuff
by making explicit all this implicit parameter passing.
   Hence, epsilons are a way to control what's implicit or explicit.
They are a clean way to enhance system expressivity
(more expressive than mere dynamical binding),
without having to rely on the dark side of reflection.

What in BASIC would be

10  INPUT "What's FOO ?";FOO$

would be written in schemish-syntax Tunes primitives as

  (set! FOO (epsilon (string) "What's FOO ?"))

Similarly, printing would be done by inserting an epsilon
expecting an object matching the unit pattern
(something like #f with pattern '#f in scheme, ():unit in ML)
or perhaps rather another pattern meant specifically as a display agent,
which pattern could itself be an implicitly-defined variable.

   10  PRINT FOO$

Would become

   (epsilon (acknowledgement) FOO)

Here acknowledgement is the type returned by the output handler,
and the message FOO is given as a hint to it.

That is, instead of specifying HOW the computer should interact,
or requiring the programmer to give lots of interface-dependent
information in the program, that tie it to some interface,
make it less customizable, prevents extensibility and reuse,
there is a generic escape mechanism
(remember how I called this epsilon construct "escape" in previous messages),
to which you tell WHAT you want, and it manages everything.
   If the epsilon is not caught by any surrounding expression,
then it eventually reaches the user-interface,
which will prompt the user in any conveniently customized way
for a value to which to bind variable FOO so it would match pattern (string),
from the hint "What's FOO ?"
and whatever is visible from the in the epsilon's evaluation context.

Catching an epsilon would be done as in

  (nolispe error
     (ERROR-MESSAGE (string))   ; hint
     ((PACKAGE-NAME (string))   ; implicit parameters from error context
      (LINE-NUMBER (integer)))
     (format "Error at line ~D in package ~A: ~A"

* Of course, other syntaxes than s-exp's could be provided.
See Dylan, CAML, etc.

* I'm not sure what the basic forms should be...

* letting the escape form see everything in the scope of the epsilon is ok,
 because we will have constructs to arbitrarily restrict that scope,
 so as to keep everything statically compilable.

* I first thought about epsilon binding a variable with the escape value,
 rather than directly returning the a result.
 But the latter behavior looks simpler to me.

* The more powerful the meta-patterns used,
 the least statically compilable they are.
 = Particularly, so that it can catch and handle *any* pattern,
  a full-fledged User Interface needs full reflection,
  and isn't statically compilable.
  Sure! Any good UI is reflective. So what?
 = controlling what we want to be statically compiled or not
  should be possible in a way, but I don't know which yet.

* A great problem is to identify precisely the escape point one wants
 to match, particularly when an object calls external objects
 or is being called by other objects, and there appears possible
 name conflicts among different objects, and/or several instances
 of a "same" object.

* While escape values are IMO the Right Way to do I/O,
 it is not the only expressiveness enhancement needed for Tunes:
 I'm thinking about a more general way of extending code,
 so that dynamically adding semantics to objects while
 keeping their existing semantics unchanged be possible.
 That's what I called active annotations.
 Dynamic active annotations sure require full reflective power,
 but again, closing objects to active annotations to allow static
 compilation should be possible.

* The whole point about active annotations is to
 enrich the context in which escape functions are evaluated.
 Actually, epsilon expressions correspond to indeterminacy in
 programs being executed.
 Escape functions are used to solve this indeterminacy,
 by providing a computational behavior.
 Active annotation help collect enough information for
 the indeterminacy to be satisfactorily solved.

--    ,                                         ,           _ v    ~  ^  --
-- Fare -- -- Francois-Rene Rideau -- +)ang-Vu Ban --
--                                      '                   / .          --
Join the TUNES project for a computing system based on computing freedom !
                 TUNES is a Useful, Not Expedient System
WWW page at URL: ""