From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,df854b5838c3e14 X-Google-Attributes: gid103376,public From: bobduff@world.std.com (Robert A Duff) Subject: Re: C/C++ knocks the .... Date: 1996/02/24 Message-ID: X-Deja-AN: 140859664 references: <4g2r2r$ded@stc06.ctd.ornl.gov> <4gicoc$cqi@stc06.ctd.ornl.gov> organization: The World Public Access UNIX, Brookline, MA newsgroups: comp.lang.ada Date: 1996-02-24T00:00:00+00:00 List-Id: In article <4gicoc$cqi@stc06.ctd.ornl.gov>, Matt Kennel wrote: >No argument. > >However, Eiffel programmers won't have to deal with these much much less >often than an Ada programmer will have to deal with packages. Perhaps >only when the # of classes starts to exceed a few hundred. You can >write many substantial eiffel programs without needing class >categories. Well sure, but big programs are where things get interesting. If you're writing 50-line programs, you don't need OOP. If you're writing 1000-line programs, you don't need Ada's child packages or Eiffel's class categories. Any feature that tries to make software engineering easier is irrelevant for sufficiently small programs. Besides, it seems like programs these days tend to suck in large pieces of re-usable code. E.g. lots of programs interface to some sort of windowing system. Even if you're writing a small piece of code, but it interfaces to some huge piece of software written by somebody else, you want to have some nice features for controlling your name space. You want to draw a line around the entire window subsystem, and give that part a name, and be clear about what code is in that part, and what code is not. For that, using classes isn't good enough -- classes are too "small". >Quick test. Your boss' boss comes in unexpectedly. He(she) asks out of >the blew "so what is the structural organization of your program?" hands >you a felt pen and points you at the white board. > >Do you draw most blobs for packages, or for types? > >Don't think. What was your reflexive response? > >I'm guessing that most Ada programs would be described as packages not >types. The 'intellectual unit' in A95 feels like packages more than types. Yes, I suppose so. I'm not sure what you're getting at, though. >Suppose you wanted to have 'invariants' as in Eiffel. Where would they go? Interesting question. I think you would want package invariants (for operations that modify package-level data), and type invariants (for operations that modify objects). Now, I suppose you'll say "Hahah! That proves that splitting classes into packages and types adds complexity." Well, maybe, maybe not. You could write: invariant X = Length(Y); and if that happens to appear in a package, it's a package invariant, and if it happens to appear in a type, then it's a type invariant. Just like if I write "X: Integer;", if it's in a package, it's a package-level variable, and if it's in a record type or record extension, it's a component of the type. This all seems pretty natural, once you've gotten used to the idea that packages aren't types. The rules for when to check invariants would be similar to Eiffel's. For package invariants, when you call / return-from a procedure in the package. For type invariants, when you call / return-from a procedure that has visibility on the implementation of the type, and takes a parameter of the type -- presumably, all parameters of the type would be checked. A more difficult question is where to put the invariants -- spec or body? In Eiffel, *some* assertions are considered part of the specification, but not all. But since Eiffel doesn't split specs and bodies, the question of placement doesn't arise. I must say that Eiffel's decision of *not* splitting specs and bodies is a big simplification. For example, Eiffel doesn't need anything like Ada's freezing rules, which make my brain hurt every time I try to think about them. Nor does Eiffel need Ada's access-before-elaboration checks on procedure calls. Note that some have mentioned that Modula-2 and Modula-3 have split specs and bodies. But things are a lot simpler for those languages than for Ada, because declarations don't have executable code. Ada needs freezing rules and ABE checking because of the nasty interactions between splitting things into two pieces, combined with the fact that declarations do stuff at run time. And you want to look at just the spec in Eiffel, you just run a tool that extracts the spec from the code. Also, somebody mentioned that abstract types can behave like specs. I'm not sure what the "right answer" is on this issue. >In Eiffel, when you combine package and type, it becomes very clear >whose routines are "mine" and whose routines are "theirs", Well, that's pretty clear in Ada, too. A procedure inside a package can have visibility on the implementation of a private type declared in that package. So can a procedure declared in a child package of that package. A procedure declared outside the package does not. >... and hence it's >clear exactly where and when all the preconditions and postconditions and >invariants ought to be checked. This is a major point of "programming >by contract." > >For instance, take class invariants. These are checked after somebody >*outside* the type makes a call; but if a method owned by the type >makes a call to another method owned by the type that MUST NOT generate >an invariant check. Why? Because that other method might be 'preparing' >the internal state to be acceptable by the invariant, but non-trivial >invariants cannot be expected to hold everywhere during the execution of >a class method. (otherwise you can't do anything). Yes, I think that makes sense. But could you please give an example, so I can be sure I understand why this is necessary? >Would an Ada95 + pre/postconditions + invariants put them with types or >with packages? Programmer's choice. Just like it's the programmer's choice whether to make a given object a package-level object, or a component of a record type. >> It is interesting to note that Java has the notion >> of "package" for defining groups of classes. This seems >> like a reasonable compromise, though it still loses out on some of the >> other advantages of defining abstractions using a package rather than a >> class, such as symmetry of parameters in binary operations, and elimination >> of the pesky "once" or "static" qualifiers of Eiffel/C++/Java that are >> needed to turn a "component" of a type into a component of a module. > >Why are these 'pesky'? Well, I suppose it's just a matter of taste. But I agree with "pesky". It just feels wrong to declare a thing *inside* a class, and then add a keyword saying, "It's not *really* inside -- it's the same for all instances of the class -- that is, there's really only one of this thing." >C++'s name of "static" is dopey, "once" is better, Sather calls them >"shared". Well, I agree that "once" and "shared" are less dopey, but however you spell the keyword, the concept still feels wrong to me. >I agree about the binary operations. > >I have an alternative syntax proposal for eiffel like langauges though >to help with the binary operator problem: > >"object.method(argument)" should have the alternate syntax > >"(object method argument)" with required parentheses. No different semantics >from ordinary function call. I don't understand how this helps. In fact, it seems that Smalltalk already has this. E.g., you write "X + Y" in Smalltalk, to add two things, but that's just syntactic sugar. It *looks* symmetric, but it's not -- X is still "special", semantically. For example, the "+" method can look at private data of X, but not private data of Y. In my experience, this leads to exporting lots of extra methods that really should be private, so that X's + method can get the data it needs from Y. How does this work in Eiffel? That is, for "X.Foo(Y)", if X and Y are instances of the same class, can Foo look at Y's private data? (Sorry, it's been a while since I read the Eiffel book, and I haven't done any programming in it.) - Bob