hws@icsib1.berkeley.edu (Heinz Schmidt) (02/16/90)
I'm working with Eiffel for some time now (2.2A only since Jan) and have a few questions and suggestions on how the language and the environment might be improved. Maybe this is a forum to discuss some of these? Eiffel is quite satisfactory for my purpose, which is currently a design problem and will soon be an efficiency problem. No need to repeat the arguments in detail. from static_typing until runtime_system invariant clean_semantics loop arguments pro eiffel end; Yet, for the first throw-away mini prototype of a new project, I still prefer CLOS. The main reason: missing incremental prototyping support in A RUNNING SYSTEM. The central problem here seems to me that you cannot load a new or modified class into the running system, inspect the datastructures, step through the code as you can in most Common Lisps. Is this really true, what is your experience? Actually it is not a missing interpreter for Eiffel that I'm looking for to fill this gap. I used interpreted Common Lisp only locally and very rarely when I cannot otherwise figure out what's going on. Rather I'm looking for dynamic binding/loading of compiled features. I can picture that most of the flavor of this functionality could be achieved in Eiffel through persistency according to the slogan "if the feature cannot come to the data, the data must go to the feature": run your system, find some odd things, modify some feature, recompile a class, restart the system and, surprise, you find yourself in the "same" world, because the relevant instances were persistent in the first place. Taking for granted improved compilation speed and highly incremental recompilation, this scheme might have similar effects on productivity as a more dynamic Lisp environment. Is there anything like this out there? Compared to C++, Eiffel seems to be more incremental and it has some clever optimization techniques. Yet I think some additional declarations might be in order to help the compiler do a better job (no flames for the syntax, not my point right now) o definite types: v =: bar or foo( ... ) =: bar is ... end; might mean that the value of v and that of current.foo(...) is definitely a bar and not of some subtype of bar. o define: foo(...): ... is defined end; might be a new form of redefinition allowing me just to specialize the SIGNATURE but inheriting the IMPLEMENTATION of foo. o inline/notinline: inline foo, bar; notinline baz; might mean that the compiler inlines code for foo and bar whereever its type (class) can be uniquely inferred. Inline is local i.e. it affects only local feature definitions, hence no inlining for inherited features. The inline property is inherited. It can only be 'stopped' in a descendant by use of notinline (with the opposite effect). o optimized: (somewhat symmetrical to inline) foo (...): .. is optimized end; might mean that the compiler should reconsider the inherited foo in the context of this class and implement an optimized body taking into consideration the new type context. Maybe I overlook something and some of this can be achieved already in a clean way? Inline/notinline and optimize may also be well placed in the SDF file. This might allow final tuning without even touching the source code. Only optimize violates incremental compilation (implementing foo by an optimized version of a copy of the inherited implementation) but it does not violate encapsulation. But then, the user decides what should be 'optimize'd and the system can keep track of which descendants require recompilation if the depended-upon ancestor features change. -- hws ------------------------------------------------------------------------------- Heinz W. Schmidt hws@icsi.berkeley.edu International Computer Science Institute (415) 643-9153 x175 1947 Center Street, Ste. 600 /\/\|;; a delay is better than Berkeley, CA 94704 \/\/|-- a desaster