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?
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):
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
typecasereally 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
#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?