PLE treasure hunt -- Sather

Since Sather's semantics are readily absorbed by those who know C++, we will focus on linguistic issues, not programming.

Code inheritance

The substitution model of code inheritance seems rather dangerous, as old code drops into a new namespace. The modularity problems are akin to those for call-by-name and dynamic scoping: the particular names that are chosen, even if private, affect behavior.

In the programming-by-contract model promoted by CLU, code is only used across a contractual interface. Code inclusion in Sather violates this principle, since arbitrary parts of a class can be replaced. The parts do not have a contract unto themselves; only the class as a whole does.

Like call-by-name, code-copying relaxes the need to plan for change, since any free name can be changed. So authoring code seems easier. However, reusing code is riddled with gotchas. For example, suppose we want to define a class which borrows code from two other classes:

 
class A is
  foo is #OUT + secret; end;
  private secret : INT is return 2; end;
end;

class B is
  bar is #OUT + secret; end;
  private secret : INT is return 3; end;
end;

class C is
  include A;
  include B;
end;

class MAIN is
  main is
    C::foo;  -- should print 2
    C::bar;  -- should print 3
  end;
end;
Sather doesn't let this compile, because of a private name clash. Can renaming resolve this?

Do Python and Self avoid these problems?

Efficiency vs. generality; return to reuse

In the Python treasure hunt we noticed that naive programming can produce unreusable code. What can a language do to prevent unreusable code? How much should programmers have to plan for reuse?

In Sather we seem to get an example of what not to do. By supporting efficiency vs. generality tradeoffs, such as monomorphic variables, Sather tempts programmers to write bad code.

Here are some arguments, from both sides (feel free to supply more):

Typecase

While statically typechecked, Sather provides a facility for run-time type checking, called typecase:
x : $OB;   -- the "any" type
typecase x
  when INT then #OUT + "INT\n";
  when FLT then #OUT + "FLT\n";
end;
What is the purpose of typecase, given language support for overloading? Alternatively, is overloading needed, given typecase? The Sather documentation says that typecase "makes the performance consequences of multi-argument dispatch explicit." Does typecase really just cover up a lack of expressiveness in the type system?

Consider the use of typecase in this program:

-- type of classes supporting equality method
type $IS_EQ is
  is_eq(k : $IS_EQ) : BOOL;
end;

class FOO < $IS_EQ is               -- FOO implements an equality method
  is_eq(k : $IS_EQ) : BOOL is
    typecase k
      when FOO then return true;    -- equal to any other FOOs
      else raise "Bad comparison";  -- can't handle this case
    end;
  end;
end;
Can the typecase be removed?

Type-regress

We saw that Sather effectively had two kinds of functions: from values to values and from types to types. However, there are other combinations. For example, C allows an array type to be parameterized by an integer; this is a function from value to type. The Sather instantiation operator # is a function from type to value. These latter two kinds of functions are "bridges" between the value and type languages.

Generality argues against having several different forms of the concept "function." Is there a way to unify the value and type languages, so that only one function construct is required to express all of these forms? Is the situation analogous to the distinction between class and instance, and the resulting infinite regress of meta-classes? How did Self solve that problem? How can we solve it for types?


PLE Home page
Last modified: Mon Aug 22 17:56:14 GMT 2005