From Hans-Dieter.Dreier@Materna.DE Mon May 10 14:51:47 1999 From: Hans-Dieter.Dreier@Materna.DE (Hans-Dieter.Dreier@Materna.DE) Date: Mon, 10 May 1999 15:51:47 +0200 Subject: Modules Message-ID: --U2ADyElC4amfFKEsxlqTOPThSD8WH9pE Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable >Hans-Dieter Dreier wrote: > >>> Why would you want to know that something is conditionally compiled? I= f >>> I use a normal if, it can optimise it out or not, it doesn't affect me >>> for the most part. >> If I see an #if (and know its value) I know definitely which way control >will >> flow.If it is a normal if, I can't be so sure - I first have to check >whether its >> value is constant and known. > >Well, you don't definitely know which way it will flow, you only know >that it will definitely be known at compile time. You can't see that >from an if, instead you have to understand what the identifier >represents. But the constancy should usually be obvious from the name, >e.g. IS_UNIX. I see. Good point. How about having the editor color-code the affected part= s of the source code, according to the current value of the #if? Wouldn't t= hat be nice? >>> (b) To require the programmer to specify redundant information about >>> what they intend to use? >> No, too much hassle. What would be gained? > >Well, the same as any redundant information - to try and prevent errors >by catching inconsistent programming. Sure, but why not let the editor/compiler state what it thinks about it? If= the programmer sees that it is what he/she intended, everything is OK. Oth= erwise the editor/compiler's info also provides a hint to what has gone wro= ng. I'm not at all against having extra information available, I just want = to avoid having to type it myself. >>> (d) If included in types, could be used to restrict what elements a >>> defined method can implicitly access. >> What should that be good for? > >It could be used to prevent it from calling certain methods. It's >basically like a sandbox, ie a set of policies about what other elements >a element can access and in what ways. So it's sort-of "private the other way round" (ie seen from the server inst= ead of the client)? >A sandbox is usually only applied to loaded/generated classes, although >it could become a language entity. Whether this would be worthwhile, I >don't know. And how sophisticated to make it would also be a question. I think the sandbox is particularly useful for environments like Java where= code comes from different sources and security as well as "mixability" is = a major issue. I'm not sure whether this will be the case for a typical Ult= ra environment. >>> That's a good point - the code may change outside of the editor. If >>> it's read-only, it's OK, but if you can write to the code, we could get >>> problems. If we have a lock facility to make it read-only if someone >>> else is editing it, that would work, but what about if not? >>> We probably should attempt to ensure files are not saved if they aren't >>> edited, although this might not be easy given my desire to make them >>> kind of implicit. Or it might be dead easy. If each includeable entity (feature, class, ...) knows its source file, it = shouldn't be difficult. >> Every decent editor does it. The real challenge comes if we attempt to mix changes. Until recently I wou= ld have shuddered at the mere thought of it, but now I've seen what a marve= llous job can be done even mixing C++ source files as long as the common ba= se line is known. Actually, that was one of the sparse moments where I thou= ght "That must be magic": To just hit "perform automated merge" and it gets= it right in 99% of all cases. >It's probably quite doable. We just have to make sure that when a >change is made through a view, which would usually not care about >modules, the editor determines which file this affects and marks it as >changed since save. The complication is that a normal editor usually >only shows a file per window, whereas I'd prefer it in one window. So do I. >That does lead me to comment though that a nice view option would be to >restrict a view to only showing one module. Of course - although being able to restrict the display property-wise (ie j= ust showing the parameters and leaving out everything else) might be even m= ore usable. BTW: In database-speak the former would be a "restriction" (sho= wing only some records), the latter a "projection" (showing only some field= s). Maybe we should adopt these terms for brevity. >> Actually, the standard file format (binary) saves a copy of all the incl= uded >parts >> along with the top-level module. > >Do you mean the code from other modues, or just all the information >necessary to generate the code? All the source code from other modules is always included. Whether compiled= (binary) parts are included depends on when you save: If you save after a = compile, the generated code will be included. If you save after editing, bu= t before compiling, only the source will be included. = >> This results in extremely fast load/save cycles (and in huge files as we= ll, >> but who cares?) and has the added benefit that you need only transfer on= e >> file if you wish to copy a project. If the included files are not presen= t >> at the copy location, the load function will simply complain and continu= e >> to use the existing copy. Otherwise it would have checked the file dates= to >> see whether a refresh was due. > >Well it seems like it could be useful to be able to work in the absence >of the other files, but would you need this often in practice? I found it conventient when I used to transfer code between my office and m= y home, on diskette. But maybe now it isn't that important anymore (as long= as you don't have to transfer a zoo of different file types where some are= needed and some big ones are not, like in VC++). >I'm actually not aware of any compilers that do inheritance >optimisations, but they seem to me to be a very useful if they can be >done. Maybe it's because they decided it's not worth the effort? > By this I mean things like merging two impls together if the >parent impl is only used by one subimpl, doing the same for types, and >removing multiple inheritance where it's unneeded. > >These are based on the premiss that you might have separate entities for >good reason, but in one particular program they might not need to be >separate. And yes, they would usually need to be inter-module. > >As an example take the following (implementation) inheritance hierachy. > > Abstract A Abstract B > / \ / >Concrete C Concrete D > >Consider this to be closed, ie we're guaranteed nothing else will extend >these implementations. Note the impl MI on D. > >Since B is only used by D, we know that Bs methods will only be used in >D. Hence, any methods not used by D can be eliminated, and anything >used by D can be inlined into the body of D, or become Ds methods if >they are inherited but not overridden (which is really a simple case of >inlining), and then eliminated from B. Once all of the methods of B are >eliminated, B can be eliminated. Hence there is one less element in the >system, and there is no MI. You would need to recompile B's methods to reflect the different impl layou= t of their new environment (D). In effect, this is what C++ template classe= s do: Sort-of textual merge. But I think the gain in execution speed would be pretty small, maybe one in= direction per method call or so (whatever MI takes as its toll). The reduct= ion in code size could be significant, though. BTW, >90% of the possible im= provement could be gained by just deleting the superfluous code and NULLing= out any references to it, without changing instance layout or vtable layou= t. That would save of lot of fix-ups. >Types are probably a little more complicated, since they can be used >both in variable declarations, impl declarations and type declarations >rather than just creations and impl declarations. You mean because of inheritance, which is possible for types but not impls?= But I'm not entirely convinced that having a strict impl/type separation i= s so beneficial that it is justified to have it enforced by rules like lang= uage syntax... >An alternative system for doing submodules would be more conventional. = >That is, a particular subtree is specified to be in another module, eg > >/ >| Module A >| = >| / >| | Module C >| \ >\ > >/ >| Module B >\ > >The modules can nest to arbitrary depths, and there is no "detaching". = >Again, you would want to modular boundaries to be visible or not >according to user preference. It gets a little trickier, since it is no >longer a matter of specifying a list of modules, but rather you have to >say C goes into A - kind of like mount points in Unix if you're familiar >with them. Wouldn't that imply that a *whole* module is inserted at *one* place? That would prevent the user from creating something like a debug or trace p= ackage that would extend *several existing* classes: The included source wo= uld need to be splitted up. -- Regards, Hans-Dieter Dreier (Hans-Dieter.Dreier@materna.de)= --U2ADyElC4amfFKEsxlqTOPThSD8WH9pE Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable IDENTIFIKATIONSANGABEN: a21106a.txt IA5 DX-MAIL X.400 User Agent= --U2ADyElC4amfFKEsxlqTOPThSD8WH9pE-- From matty@box.net.au Mon May 10 13:24:48 1999 From: matty@box.net.au (Matthew Tuck) Date: Mon, 10 May 1999 21:54:48 +0930 Subject: GUI Builders (was: More On Multiple Inheritance) References: Message-ID: <3736D00F.FF513ED2@box.net.au> Hans-Dieter.Dreier@materna.de wrote: > If we use the instance layout of the target class for templates as well, a > simple copy constructor can be used as a creation routine. As an additional > benefit, editor (and debugger) can then be used to view "live" configured > instance items as well as templates. This strikes me as basically a prototyping scheme, at least on the data. You're talking about having templates (prototypes) which can have the same impl but differ in their state. And these can in turn be used as a prototype for another template. > Methods are almost always class items since all of the instances share the same > method code. Message handlers are instance items, however. IMO it is a major > design flaw to implement message handlers as class items since this effectively > prohits reuse of that class. Message handlers often need to access the name > space of the _instance_ rather than that of the _class_. If all the contacts to > the instance's environment would have to take place by dynamic dispatch, such a > class would be rather cumbersome to use. I don't think so. If the widget classes are set up to use observers, the widgets are reusable and don't need to be written with any particular message handler in mind. Ideally the widget, handler and the data are totally separate classes, providing more flexibility. Hence handlers should never need to be in the widget. Java 1.0 joined them together - they replaced that model with observers in 1.1. > Dynamic creation of identically configured objects by a program is possible by > calling the creation routine multiple times for a given template. In this case > the instance created by the declaration might be unwanted; we might want to be > able to prevent automatic creation due to the declaration. If this sort of thing ever happened, I would prefer it to be an optimisation, I'm not sure I'd want to give it language status, even though this sort of thing could really happen in any situation. > We could do this by > either adding a key word ("template") to the declaration or by adding a special > outline item (folder) for such templates. The latter is better because the > former would either disrupt the instance layout or leave a NULL reference gaping > if used in the "instance items" section of a class. I'm not sure what you're proposing here. Could you elaborate? I assume you're defining properties to be constant here. Hence a copy is unneeded and you can reuse the same object. If you had properties that were not constant, eg the text font might change due to a checkbox somewhere else being chosen, you would not use that for a property but instead have both fonts as a "initial font" property and "changed font" property respectively. Because a copy is unneeded you might keep a prototype repository where you pass the prototype id and get the prototype back which could be created lazily if desired or the whole lot could be loaded from a file or whatever. This wouldn't require any extra language facility. You might want to keep the prototypes constant or the ability to change a lot of widgets at once might be useful. But there is certainly a distinction between properties like font and transient properties like widget state. It would be very difficult to merge these into one widget prototype if you actually had the message handler in the widget too. >> So do these editors allow you to define a control that inherits the properties >> of another control? > Yes. Usually that will be the surrounding window. When you say "surrounding window" do you mean "surrounding widget" or do you mean it literally? This is one example of allowing the choice between data (constant value inherited at compile-time from another template) and get/sets (code for getting the value from the surrounding widget). Basically I could see the use both of inheriting from the surrounding widget, e.g. pop-up help where you don't have anything more specific to say, or another template and making small changes. In essence the latter could either be a GUI builder only concept (by fully filling in all fields and ignoring the template inheritance relationships) or could actually be used in the creation functions to copy and change a template. And if you could change these templates at run-time, would they be embedding or delegation based, ie would changes to the parents effect children that haven't overridden? At the very least you'd need the ability to create your own templates based on other templates at run-time. > > Window Position // type 3 item - you couldn't add this comment > Top: <0 // type 2 item> > Left: <0> > Widht: <400> > Height: <300> > Window Style > Border? > System Menu? > ... I would expect this to be merely one view of the GUI languages of course. A more graphical dragging and dropping alternative would be another. > I would suggest to keep that editor-related stuff in a separate class to be > able to easily strip it for a release version of the program. I would consider the "class" to be different in the sense of GUI Builders and HLLs. GUI builders have an editor element which is actually a widget defined in the program/language library, whereas a HLL has an editor element which is a language element. Hence they're different things and so a separation is probably necessary for that reason too. This is a bit similar to a JavaBean, which defines things about how a GUI Builder uses it. I'm not up to date on what information it provides however. > You see the similarity to the GUI example above? Function declarations, class > declarations, all that stuff could be made customisable as well. IMO the > benefits would be huge: Everyone could make its own without having to touch the > editor "core". Changes even at edit time were possible. You add a property: Just > change and compile the editor supplement class and there it is, ready for use. > This editor core would also be a (relatively) small affair instead of a big > monolith. (You know I'm in favour of writing frameworks and filling the details > in later, when actually needed). I think this code should never be a part of the editor core since it's view-oriented. The editor core would: o coordinate the shared UI (whatever that might be) o coordinate adding and removing languages, translations and views into/from the system o coordinate translations (ie incremental compilation) o coordinate views (ie ensuring changes made in one window are immediately reflected in others) It strikes me that these similarities are basically in the fact that both the HLL structured view and the GUI Builder structured views are both structured views. Hence they should share a structured view framework instead. If you want to add these properties at edit time, by all means do. Exactly how these are detected, added and removed would be defined by the specific view using the framework. > Sure. The editor somehow needs to know which instance items to treat as > properties. At first glance, I can think of several ways to do this: Maybe you could choose all public fields? > 1. Add a keyword (say, "property") to the instance item's declaration. > Only usable for simple cases since no specific customisation info can be > presented this way. > ... > Writing a keyword is much less work than writing a whole class. > ... I wouldn't say that this action is common enough to warrant introducing a new HLL feature on prototypes. It's certainly useful for widgets and probably some other classes, but at least for widgets I doubt they're defined anywhere near as often as they're used. > All of the above ways silently include the assumption that there is only one > such "customisation set" for each class. This might be sufficient in most cases, > but why should we accept that restriction right from the start? If you chose them all it wouldn't be a restriction. > Some people might prefer a simpler GUI builder that would not expose all of > the available properties (and complexities), but still should be able to use > the same underlying GUI classes. Also, legacy customisation sets could be kept > for a while to allow updating source files. Yes but this is chosen by the user, not by a computational procedure, and hence choosing all we can at first might be acceptable as a default. My thinking of a cset would be merely as a default set of properties that appear. The user could add and remove properties at will. I assume if they were not present, they would take a default value. In this way you could also change csets, wherein all new properties in the cset are added, and all old properties with the default value are removed. If you have manual add and remove facility for individual elements, csets are essentially an add-on. The primitive add-remove functionality is more important. Perhaps the editor would also automatically remove properties set to their defaults at some stage. > When I was looking for a device that could be used to distinguish CSs, > constructors (or "creation functions") came to mind, since there may be many of > them with different parameter sets and names. But after having it thought over a > little bit, I'd refrain from that approach, because we need a bidirectional > mapping: The property set stored with a declaration needs to be read as well as > written by the editor. A constructor shouldn't really be needed if the sets are compile-time known and constant. I'm not really sure that they should be a part of the GUI language, rather than just set up through the editor, either. -- Matthew Tuck - Software Developer & All-Round Nice Guy mailto:matty@box.net.au (ICQ #8125618) Check out the Ultra programming language project! http://www.box.net.au/~matty/ultra/ From matty@box.net.au Mon May 10 12:48:51 1999 From: matty@box.net.au (Matthew Tuck) Date: Mon, 10 May 1999 21:18:51 +0930 Subject: A few comments on the archives References: Message-ID: <3736C7A3.5FCA0F69@box.net.au> "Peter A. Friend" wrote: > I saw a LOT of discussion about outputting bytecodes for the JVM. This > may be handy in the early stages, but there are a lot of things about > the JVM that give me a headache. For one, there are NO unsigned integer > types. This may not sound like a big deal, until you try to start > dealing with things like an IPv4 address in an efficient manner. You > either have to use a long (64 bits, and takes up two slots on the JVM > stack) or you have to do some serious shifting and twiddling nonsense. > Plus, most hardware supports far more operations than the JVM does. > I'll have to check what they all are, but I think circular rotate is > one of one. That also may not sound like a big deal either, until you > try to write an MD5 library with it. Well we're certainly concerned with that a platform might not support all the desired operations. But even if it has to be done kludgily, it can be done. Anything like this would be hidden in the Ultra -> JVM translator, and if you wanted to write a library you'd do in in Ultra where you wouldn't see this detail. So it may not be marvellously efficient, but the first concern is to get something working. > I have to go back and reread the IDE stuff, but I think that making > everything GUI is a bad idea. If it is provided it should be an option. > GUI only slows me down. What do you mean by this statement? Graphical rather than character-based? Windowed rather than command-line? Editor or compilation control via command line? One of the major aims of the IDE stuff up until now is to make things faster. -- Matthew Tuck - Software Developer & All-Round Nice Guy mailto:matty@box.net.au (ICQ #8125618) Check out the Ultra programming language project! http://www.box.net.au/~matty/ultra/ From matty@box.net.au Mon May 10 12:50:56 1999 From: matty@box.net.au (Matthew Tuck) Date: Mon, 10 May 1999 21:20:56 +0930 Subject: Thoughts From The Abyss References: Message-ID: <3736C820.B721F77B@box.net.au> Hans-Dieter.Dreier@materna.de wrote: >> Hans-Dieter's transparent names are easily implementable as shorthands >> if we don't use prototyping, and hence don't require any extra features. > What do you mean by "prototyping" here? As in "an object-based approach where inheritance is perform by copying with update". Hence this operation would be primitive. >> Type layout should never attempted before everything is known, since it >> prohibits elimination of unused methods, etc., which I suspect is a big >> cause of bloat in existing OOP systems. > What do you refer to? Say you wanted to eliminate a method because it's not used in a program. Assume you're not loading/generating classes. It can only be eliminated after linking, and this is rarely done. A simple inter-module analysis could eliminate type methods by simply seeing if they're ever referred to. Hence vtables would be smaller. Actual instance fields being eliminated would shorten object layouts, but fields are harder, since you want to eliminate stuff that is written to but not read from, along with the assignments to them. >From a programmer's point of view, if I can develop in a really modular, flexible way, it reflects on my software by a reduction in bugs, and quicker development/maintenance. And if I can optimise even better than a standard C compiler lets me, it also reflects on my software that it is very fast and small. > Having the original state both unacceptable and modifiable is likely to > cause problems inside the editor. The user is in trouble as soon as he > decides to undo his changes in the middle of editing by restoring the > original state. Not really. The view would support having that value, and allow changing to it, just not letting the user change to it. Hence an undo would just take you back to the unacceptable value and display that it is unacceptable. -- Matthew Tuck - Software Developer & All-Round Nice Guy mailto:matty@box.net.au (ICQ #8125618) Check out the Ultra programming language project! http://www.box.net.au/~matty/ultra/ From Hans-Dieter.Dreier@Materna.DE Mon May 10 13:30:29 1999 From: Hans-Dieter.Dreier@Materna.DE (Hans-Dieter.Dreier@Materna.DE) Date: Mon, 10 May 1999 14:30:29 +0200 Subject: Thoughts From The Abyss In-Reply-To: <3736C820.B721F77B@box.net.au> Message-ID: --nzZsNPcrNH5q4lNPskxUliGADw5fMoIB Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable >Hans-Dieter.Dreier@materna.de wrote: > >>> Hans-Dieter's transparent names are easily implementable as shorthands >>> if we don't use prototyping, and hence don't require any extra features= . >> What do you mean by "prototyping" here? > >As in "an object-based approach where inheritance is perform by copying >with update". Hence this operation would be primitive. Sorry, I still seem to not understand you fully. Maybe you see more in "tra= nsparent names" than I do. For me, they are simply a means to modify the na= me look-up process in the parser, ie the instance that binds an object to a= name). Once this binding has been done, there is no further difference bet= ween a normal name and a transparent one. Everything you can do using trans= parent names, you can do using ordinary qualification ("a.b") as well, only= less comfortable. = >>> Type layout should never attempted before everything is known, since it >>> prohibits elimination of unused methods, etc., which I suspect is a big >>> cause of bloat in existing OOP systems. >> What do you refer to? > >Say you wanted to eliminate a method because it's not used in a >program. Assume you're not loading/generating classes. It can only be >eliminated after linking, and this is rarely done. A simple >inter-module analysis could eliminate type methods by simply seeing if >they're ever referred to. Hence vtables would be smaller. Actual >instance fields being eliminated would shorten object layouts, but >fields are harder, since you want to eliminate stuff that is written to >but not read from, along with the assignments to them. Currently, I wouldn't even bother to optimize such a case. See what you get= : You save one reference per class (not per instance! since vtables are cla= ss items), plus the method body, and no run time, at the expense of another= global optimisation pass after linking. And if the method was statically dispatched to, this task could automatical= ly done be GC anyway. The other example (having a non-read-referenced instance item) should be pr= etty seldom and should trigger a warning, rather. But maybe there are better examples? >From a programmer's point of view, if I can develop in a really modular, >flexible way, it reflects on my software by a reduction in bugs, and >quicker development/maintenance. And if I can optimise even better than >a standard C compiler lets me, it also reflects on my software that it >is very fast and small. True. And also, often underestimated: The smaller & clearer your source cod= e is, the shorter is time-to-market. In this respect, IMHO C++ sometimes re= sembles assemly language. = >> Having the original state both unacceptable and modifiable is likely to >> cause problems inside the editor. The user is in trouble as soon as he >> decides to undo his changes in the middle of editing by restoring the >> original state. > >Not really. The view would support having that value, and allow >changing to it, just not letting the user change to it. Do you mean "letting the user change from it"? Otherwise please explain. >Hence an undo >would just take you back to the unacceptable value and display that it >is unacceptable. That means it is unacceptable but allowed nevertheless? As long as it's the original state? This would do, but writing the user interface that needs to handle that wou= ldn't become easier. -- Regards, Hans-Dieter Dreier (Hans-Dieter.Dreier@materna.de)= --nzZsNPcrNH5q4lNPskxUliGADw5fMoIB Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable IDENTIFIKATIONSANGABEN: a18627a.txt IA5 DX-MAIL X.400 User Agent= --nzZsNPcrNH5q4lNPskxUliGADw5fMoIB-- From matty@box.net.au Mon May 10 13:00:33 1999 From: matty@box.net.au (Matthew Tuck) Date: Mon, 10 May 1999 21:30:33 +0930 Subject: Parameterised Types References: <36EE3D0D.1FE530AB@box.net.au> <36FD1D40.CC6A2DD4@ruhr-uni-bochum.de> Message-ID: <3736CA61.5C0395DD@box.net.au> Hans-Dieter Dreier wrote: > Conceptually, for me type parameters are instance items. Strictly speaking, > List and List are actually the same type, but each > of them may or may not be used in some context because their different > parameterization results in different constraints. Those may or may not > evaluate to true in some context. Example: > > List a ; > List b; > b may be used as a data source where a can be used because in this case the > contents of a may be substituted by the contents of b. So it is legal to > write > a = b; > but it is illegal to write > b = a; This is difficult in general because of the following case. class A Field: X ... procedure ... ... Variable: A := new A Variable.Field := new General Here Variable.Field gets a General object although it is only allowed a special object. Generic parameters have to be invariant where they are used to instantiate read-write variables. Where the X was only used for read-only variables, the covariant relationship you outlined would hold. Where the X was only used for write-only variables, it would be contravariant instead. Hence we might prevent covariant generic parameters from being used in read-write fields and so on. The book "A Theory of Objects" that I recommended before goes into this sort of thing a bit more if you're interested, although I'm not entirely satisfied with the system as I've seen it. Whether or not A and A are the same "type" differs depends on who you talk to and is probably just a semantic quibble anyway. > The implementation of our parser may of course *assume* that there is such a > constraint if a type parameter is of type type because this will most often > be the case. Then things may probably be simplified by making the value of > this type a part of the type name of the parametrized type (similar to name > decoration in C++). But if we do this, we should keep in mind that it is a > mere simplification and not a concept in its own right. Hmm, could you elaborate? > The bounds may even be changed at runtime, resulting in a reallocation. Some > programming languages allow this. I always found it very convenient to use. This is possible, but it would invalidate existing references. How is this usually handled? Copying GCs already have to handle this sort of situation. What languages do you know that do this? This is similar to being able to change an object's impl, parent impl, etc. at run-time. I think some object-based inheritance languages allow the addition of fields at run-time, in parallel to a type downcast. I'm not sure this would always work easily in general however. The canonical example of value-driven data is an array but generic value parameters can be used for typing as well as allocation. Exactly how the changed parameters would affect the dependent entities (ie any contained elements relying on the surrounding generic parameter (which could theoretically cascade deeply) would be interesting. > I'd suggest to write > type Assign : (A, B) < (C, D, E) < F > to clarify operator precedence, if we choose to use such a notation at all. I wasn't really worried about the precedence here, since this is only two level and easily learned. > And if we use it, it should be usable everywhere a comparison is allowed. Regarding using the shorthand everywhere, if you're referring to normal expressions here, maybe. Normal expression "<" could be implemented with shorthands the same as above, but it would be a different shorthand in a different context. The presence of all the other comparison operators could dramatically complicate things, whichly is partly why I only used <. But all this is reliant on what sort of shorthands the shorthand engine makes possible, which is as yet unknown/undecided. >> A "subtype type parameter" is specified by the subtype of the type >> rather than the client. > For me, this would be a (constant) virtual instance item. If the > parameterized type would be declared by normal subtyping, no special syntax > would be needed (the type needs its own name to distinguish it from the base > type anyway). Just the virtual instance item needs to be overridden. Yes, the overriding model probably makes more sense than a default value model, but I'm not sure if it would be enough of a perfect analogy to unify them in the language. > Contravariance is what I would allow by default. That would be the other option I'd take. I haven't really decided whether contravariance or invariance is better. > But we should also allow > constraints that are checked at runtime (since this cannot be checked at > compile time due to its dynamic nature), and the compiler would take their > results into account. So we could place a runtime constraint on the > parameter of the Eat method and the compiler would take it into account even > if it cannot be evaluated at compile time. Details of this idea need to be > worked out, however. You could put a run-time constraint but this dilutes the benefit. The essential problem is that if you want to feed an animal, the information on what food it accepts should not be hidden. Hence making it a parameter to the type ensures it won't and prevents type problems. A standard checked downcast should be adequate to achieve what I think you're looking for. > I'd suggest to use normal function syntax, ie write > AnIntegerArray = new Array (Integer); > instead of > AnIntegerArray = new Array ; Possibly. () is usually used for construction parameters, which are handled differently, so I'd like a way of demonstrating to the reader that they are a different type of parameter, say by putting the type parameters first and separating them by a "|" or similar symbol. Since the type parameter list is defined in a different place to the construction paremeter list, it would be handy to determine which list has been passed to incorrectly better, which would be easier if you separated them. > The C++ template syntax makes parsing unneccessarily hard because <> are > used as operators too. Well I don't think this would affect a top-down parser. A bottom up parser might be affected, but I doubt this is significant. Error recovery could be a bit more important. > Constraints for parameterized types should be declared using the same syntax > as for methods. Possibly. Uniformity would be nice but I don't want perfect uniformity if there are significant differences between the two. That's probably view dependent anyway. Similar format but with a keyword might achieve this. Normal Field Subtype Param Client Param Part Of Variable Type Spec N Y Y Can Be Overriden Y Y N# Can Be Nonconstant Y N N Specified At Instantiation N* N@ Y Restricted To Type Fields N Y Y # = Unless provided as a default value in the absence of client specification. * = Only through constructor parameters. @ = Implictly. -- Matthew Tuck - Software Developer & All-Round Nice Guy mailto:matty@box.net.au (ICQ #8125618) Check out the Ultra programming language project! http://www.box.net.au/~matty/ultra/ From matty@box.net.au Mon May 10 13:11:22 1999 From: matty@box.net.au (Matthew Tuck) Date: Mon, 10 May 1999 21:41:22 +0930 Subject: Modules References: <3709F687.FFCB02AF@box.net.au> <370BD43F.310C1D7F@ruhr-uni-bochum.de> Message-ID: <3736CCEA.DE8378D9@box.net.au> Hans-Dieter Dreier wrote: >> Why would you want to know that something is conditionally compiled? If >> I use a normal if, it can optimise it out or not, it doesn't affect me >> for the most part. > If I see an #if (and know its value) I know definitely which way control will > flow.If it is a normal if, I can't be so sure - I first have to check whether its > value is constant and known. Well, you don't definitely know which way it will flow, you only know that it will definitely be known at compile time. You can't see that from an if, instead you have to understand what the identifier represents. But the constancy should usually be obvious from the name, e.g. IS_UNIX. >> The essential difference is that there is only one instatiation of >> classes. Also, classes can usually not contain other classes, although >> in Java's case, it is allowed. Hence the need for the distinction is >> disappearing. A "unified containment hierachy language" only uses >> classes (or types/impls), and considers packages to be "singular >> objects", that is a special sort of combined class/object. Therefore >> there is only one mechanism for information hiding rather than two. Ada >> is a mess in this respect. > I wouldn't misuse packages for information hiding. > ... I wasn't implying that. Classes (possibly augmented by shorthands) are used as the only namespace mechanism, rather than there being two sorts. Modules are used as a packaging concept, hence the concepts become more independent. Basically like as follows: Java/Ada Mine Used For File Separation Packages Modules Used For Libraries Packages Classes (Singular Objects) Used For Classes Classes Classes It's kind of a transfer of responsibility. I'll try to read the paper shortly. I remember reading a couple of those papers before. > Oh no! Just display a cross reference for information purposes if > wanted. Let the editor/compiler take care of uses. That's what I'm in preference of at the moment. >> (b) To require the programmer to specify redundant information about >> what they intend to use? > No, too much hassle. What would be gained? Well, the same as any redundant information - to try and prevent errors by catching inconsistent programming. >> (c) To make it readable as to what other elements are used without >> looking at the body? > Can be provided on demand by the editor. Yes. >> (d) If included in types, could be used to restrict what elements a >> defined method can implicitly access. > What should that be good for? It could be used to prevent it from calling certain methods. It's basically like a sandbox, ie a set of policies about what other elements a element can access and in what ways. A sandbox is usually only applied to loaded/generated classes, although it could become a language entity. Whether this would be worthwhile, I don't know. And how sophisticated to make it would also be a question. >> That's a good point - the code may change outside of the editor. If >> it's read-only, it's OK, but if you can write to the code, we could get >> problems. If we have a lock facility to make it read-only if someone >> else is editing it, that would work, but what about if not? >> We probably should attempt to ensure files are not saved if they aren't >> edited, although this might not be easy given my desire to make them >> kind of implicit. Or it might be dead easy. > Every decent editor does it. It's probably quite doable. We just have to make sure that when a change is made through a view, which would usually not care about modules, the editor determines which file this affects and marks it as changed since save. The complication is that a normal editor usually only shows a file per window, whereas I'd prefer it in one window. That does lead me to comment though that a nice view option would be to restrict a view to only showing one module. > I'll try to elaborate a little bit: > ... OK, so this essentially requires you to enter dependencies on a per module basis rather than working them out for themselves. It would certainly be useful to view the used elements/modules in any module, as well as in any language element, e.g. in a method rather than a whole class. Probably not within the main window though for a language element, instead in a dialog. > I'd like to emphasize that the names of all include files are in one place > and are not scattered about like it is in C. > You'll never have to search for things that have been included. > To the user, it looks as if everything is in one big file, which has some > read-only parts. That's a good point. The ability to centralise things is very useful, and we should endeavour to provide means of extracting information into a meaningful view rather than requiring the programmer to hunt and peck for information distributed throughout the program. > Actually, the standard file format (binary) saves a copy of all the included parts > along with the top-level module. Do you mean the code from other modues, or just all the information necessary to generate the code? > This results in extremely fast load/save cycles (and in huge files as well, > but who cares?) and has the added benefit that you need only transfer one > file if you wish to copy a project. If the included files are not present > at the copy location, the load function will simply complain and continue > to use the existing copy. Otherwise it would have checked the file dates to > see whether a refresh was due. Well it seems like it could be useful to be able to work in the absence of the other files, but would you need this often in practice? >> No, nothing as complicated as that. Every detached element will act >> exactly as if it was attached at run-time. You would essentially just >> compile the detached element in the namespace of the other element, then >> later reattach it at linking stage. > How can you attach a feature to a *class* at link time?Isn't that VERY > complicated? You need to recompile all derived classes because > the instance layout may change. It was never intended to get around that problem. But you're right - it is difficult, so it might well be worthwhile just doing something like this with abstract impls and impl inheritance if you want them in different modules, and hoping inheritance optimisations will merge the two impls together if possible. I'm actually not aware of any compilers that do inheritance optimisations, but they seem to me to be a very useful if they can be done. By this I mean things like merging two impls together if the parent impl is only used by one subimpl, doing the same for types, and removing multiple inheritance where it's unneeded. These are based on the premiss that you might have separate entities for good reason, but in one particular program they might not need to be separate. And yes, they would usually need to be inter-module. As an example take the following (implementation) inheritance hierachy. Abstract A Abstract B / \ / Concrete C Concrete D Consider this to be closed, ie we're guaranteed nothing else will extend these implementations. Note the impl MI on D. Since B is only used by D, we know that Bs methods will only be used in D. Hence, any methods not used by D can be eliminated, and anything used by D can be inlined into the body of D, or become Ds methods if they are inherited but not overridden (which is really a simple case of inlining), and then eliminated from B. Once all of the methods of B are eliminated, B can be eliminated. Hence there is one less element in the system, and there is no MI. Types are probably a little more complicated, since they can be used both in variable declarations, impl declarations and type declarations rather than just creations and impl declarations. An alternative system for doing submodules would be more conventional. That is, a particular subtree is specified to be in another module, eg / | Module A | | / | | Module C | \ \ / | Module B \ The modules can nest to arbitrary depths, and there is no "detaching". Again, you would want to modular boundaries to be visible or not according to user preference. It gets a little trickier, since it is no longer a matter of specifying a list of modules, but rather you have to say C goes into A - kind of like mount points in Unix if you're familiar with them. -- Matthew Tuck - Software Developer & All-Round Nice Guy mailto:matty@box.net.au (ICQ #8125618) Check out the Ultra programming language project! http://www.box.net.au/~matty/ultra/ From Hans-Dieter.Dreier@materna.de Tue May 11 08:51:57 1999 From: Hans-Dieter.Dreier@materna.de (Hans-Dieter.Dreier@materna.de) Date: Tue, 11 May 1999 09:51:57 +0200 Subject: A few comments on the archives In-Reply-To: <3736C7A3.5FCA0F69@box.net.au> Message-ID: --SMUdCqNUoWutfgUgLVgRORVrGv8adxR0 Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable >"Peter A. Friend" wrote: > >> I saw a LOT of discussion about outputting bytecodes for the JVM. This >> may be handy in the early stages, but there are a lot of things about >> the JVM that give me a headache. For one, there are NO unsigned integer >> types. >> ... I got the JVM Spec but until now had only a most superficial look into it. My impression was that there are some JVM instructions that are rather high= -level (loading a class, for instance). A major problem might be that they = are assuming certain data structures. It could turn out that, say, implemen= ting MI cannot be done satisfactorily just because Java doesn't support it. >> I have to go back and reread the IDE stuff, but I think that making >> everything GUI is a bad idea. If it is provided it should be an option. >> GUI only slows me down. Well, I don't see any reason why there couldn't be a command-line interface= as well, but I personally like the idea of writing my programs by point'n = click / drag'n drop more. It certainly is a matter of taste (and one's skills). If you got everything= laid out in your head and seldom need an online help, you'd definitely be = faster without GUI. Alas, I often have to consult the online help to look up some specs and I o= ften misspell things when I type them. -- Regards, Hans-Dieter Dreier (Hans-Dieter.Dreier@materna.de)= --SMUdCqNUoWutfgUgLVgRORVrGv8adxR0 Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable IDENTIFIKATIONSANGABEN: a13915a.txt IA5 DX-MAIL X.400 User Agent= --SMUdCqNUoWutfgUgLVgRORVrGv8adxR0-- From octavian@corp.earthlink.net Wed May 12 22:30:29 1999 From: octavian@corp.earthlink.net (Peter A. Friend) Date: Wed, 12 May 1999 14:30:29 -0700 (PDT) Subject: A few comments on the archives In-Reply-To: Message-ID: On Tue, 11 May 1999 Hans-Dieter.Dreier@materna.de wrote: > >"Peter A. Friend" wrote: > > >> I have to go back and reread the IDE stuff, but I think that making > >> everything GUI is a bad idea. If it is provided it should be an option. > >> GUI only slows me down. > > Well, I don't see any reason why there couldn't be a command-line interface as well, but I personally like the idea of writing my programs by point'n click / drag'n drop more. > It certainly is a matter of taste (and one's skills). If you got everything laid out in your head and seldom need an online help, you'd definitely be faster without GUI. > > Alas, I often have to consult the online help to look up some specs and I often misspell things when I type them. Hey I need as much online help as the next guy, if not more. ;-) When using a tool like C++ Builder where you have pre-built components that you drop onto forms it makes a lot of sense. I have no problem with that. My only concern was that everything would only be accessible via the GUI. For me, having to move the mouse and click is much slower than typing "make". More than anything though, I don't like using the GUI code editors. I DO like the syntax highlighting, but I can write code so much faster in vi, the GUI editor becomes frustrating. I also like the ability to pipe my code through indent, lint, etc. I should also admit that I have a dislike of GUIs because I have had to write a number of the things recently. :P Peter --- Software Engineer EarthLink Network From Hans-Dieter.Dreier@materna.de Fri May 14 08:52:16 1999 From: Hans-Dieter.Dreier@materna.de (Hans-Dieter.Dreier@materna.de) Date: Fri, 14 May 1999 09:52:16 +0200 Subject: A few comments on the archives In-Reply-To: Message-ID: --mKKLWCDimG6fDqGEpB0vEBHrYn4Kfttq Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable >When using a tool like C++ Builder where you have pre-built >components that you drop onto forms it makes a lot of sense. I have no >problem with that. My only concern was that everything would only be >accessible via the GUI. For me, having to move the mouse and click is >much slower than typing "make". More than anything though, I don't like >using the GUI code editors. I DO like the syntax highlighting, but I >can write code so much faster in vi, the GUI editor becomes >frustrating. Interesting. In what respect are GUI text editors slower to use than vi? > I also like the ability to pipe my code through indent, >lint, etc. The intention is that you wouldn't need indent, lint, etc. anymore, because e.g. "indentation" already would be done automatically as you enter= the text. >I should also admit that I have a dislike of GUIs because I have had to >write a number of the things recently. :P You're referring to writing GUI applications, not to GUI IDE's, if I unders= tand right. Whereas creating a GUI might be involve a lot of work, actually= using the product *should* save work (at least that was the reasons why GU= I were developed in the first place). I know both worlds (though not vi, which one really needs to get used to) a= nd my opinion is that GUI IDEs indeed can slow you down. Just look at VC++ = (visual studio). Although they put in a lot of work to make it as comfortab= le as possible, IMHO it still is far from optimal, and never can be, becaus= e of the flawed design of the whole thing (expecially C++ with its header f= iles, forward declarations and so on). But I also have seen that a GUI IDE *can* be done much better, and with *le= ss* effort, if the design is done right and the designer is not constrained= by the needs of a language that was not designed for structured storage. I= 'm referring to Centura Builder here, formerly known as Gupta. Had they bet= ter fine-tuned their GUI, it really would have been superior. They simply g= ot the GUI design right. In the lastest version (which I don't have), howev= er, they apparently tried to make it more similar to the competition (and t= hus are messing it up, I'm afraid). Anyhow, if you got an idea of how it should be, let's discuss it. If just using vi is OK for you, well, I don't know a reason why you shouldn= 't do so. We certainly will provide a command line interface, and it will b= e the first one to be implemented, simply because it is easiest to do. I'll give a simple example concerning the keyboard/mouse issue from my pers= onal experience: Once upon a time there was DOS. To copy a file, you typed "copy ". This could be done quite quickly, so I couldn't imagine that I would ever p= refer to use a GUI approach over it. Then came Windows 3.1. You could use file manager to copy files. But it was= so cumbersome to use that I always had a DOS box open just to enter dir an= d copy commands, even at a time where a lot of my collegues would already u= se copy/paste for that purpose. Then came Windows95, path names grew longer (if you're using Unix, you know= what that means...), and drag'n drop of files worked *everwhere*, not just= in file manager. And now I perform almost every copy per drag'n drop, simp= ly because it's faster (and there cannot be typos any more). You see: It all depends... > >Peter > > >--- >Software Engineer >EarthLink Network -- Regards, Hans-Dieter Dreier (Hans-Dieter.Dreier@materna.de)= --mKKLWCDimG6fDqGEpB0vEBHrYn4Kfttq Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable IDENTIFIKATIONSANGABEN: a13931a.txt IA5 DX-MAIL X.400 User Agent= --mKKLWCDimG6fDqGEpB0vEBHrYn4Kfttq-- From octavian@corp.earthlink.net Fri May 14 17:56:27 1999 From: octavian@corp.earthlink.net (Peter A. Friend) Date: Fri, 14 May 1999 09:56:27 -0700 (PDT) Subject: A few comments on the archives In-Reply-To: Message-ID: On Fri, 14 May 1999 Hans-Dieter.Dreier@materna.de wrote: > >can write code so much faster in vi, the GUI editor becomes > >frustrating. > > Interesting. In what respect are GUI text editors slower to use than vi? I think this is only the case when you have been using vi for a while and are used to all of its features. A lot of GUI editors don't have support for regex search and replace. Even fewer allow me to restrict that replace to a range of lines without taking my fingers off of the keys. If I am going to have a lot of similar lines of code, but just part of an argument name is different, I can copy and paste the exact number of lines I need with only 4 keystrokes. Then there all of the options for editing single words, an entire line, etc. I have just gotten to the point where it takes me longer to lift my hand, move the mouse, and select a menu item than it takes to just type in a short command. Again though, most people would disagree with me vehemently on this. Shame on me for bringing up a religious issue (editors). :-) > > I also like the ability to pipe my code through indent, > >lint, etc. > > The intention is that you wouldn't need indent, lint, etc. anymore, > because e.g. "indentation" already would be done automatically as you enter the text. Good point. Any good code editor would have this. Which reminds me of a Windows program called UltraEdit (I think that's it). A buddy showed it to me and I was amazed. I believe it has a "plug in"type of facility which allows you to add support for different languages. > >I should also admit that I have a dislike of GUIs because I have had to > >write a number of the things recently. :P > > You're referring to writing GUI applications, not to GUI IDE's, if I > understand right. Whereas creating a GUI might be involve a lot of > work, actually using the product *should* save work (at least that was > the reasons why GUI were developed in the first place). Yes, I was referring to applications, not IDE's. I was thinking more of our development of the IDE at that moment. I have started using Java a lot because trying to write a multiplatform GUI was going to make me an alcoholic. Ever try to write an X app? Yuck. I agree that a GUI is pretty much pointless if it isn't designed well. > Anyhow, if you got an idea of how it should be, let's discuss it. I'll have to think about that for a while. You have actually seen a good IDE, I haven't yet. I should also point out that I have never worked on a really HUGE software project like the kind tackled at MS. Perhaps in a project with multiple coders and numerous files an IDE would be a lifesaver. I just don't know. My recent fascination with CWEB makes me ask if we want to build in support for "literate programming" with Ultra. Not sure if this has been brought up yet. A more recent example of this idea is Java's javadoc spec. Cheers, Peter --- Software Engineer EarthLink Network From Hans-Dieter.Dreier@materna.de Mon May 17 11:08:21 1999 From: Hans-Dieter.Dreier@materna.de (Hans-Dieter.Dreier@materna.de) Date: Mon, 17 May 1999 12:08:21 +0200 Subject: A few comments on the archives Message-ID: --CCSTqOx4S4eV5M6aN7OJ0JbzuvQMlNRC Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable > >On Fri, 14 May 1999 Hans-Dieter.Dreier@materna.de wrote: > >> >can write code so much faster in vi, the GUI editor becomes >> >frustrating. >> = >> Interesting. In what respect are GUI text editors slower to use than vi? > >I think this is only the case when you have been using vi for a while >and are used to all of its features. A lot of GUI editors don't have >support for regex search and replace. Even fewer allow me to restrict >that replace to a range of lines without taking my fingers off of the >keys. If I am going to have a lot of similar lines of code, but just >part of an argument name is different, I can copy and paste the exact >number of lines I need with only 4 keystrokes. Then there all of the >options for editing single words, an entire line, etc. I have just >gotten to the point where it takes me longer to lift my hand, move the >mouse, and select a menu item than it takes to just type in a short >command. Again though, most people would disagree with me vehemently on >this. Shame on me for bringing up a religious issue (editors). :-) No problem (at least for me). When it eventually comes to designing the edi= tor UI, your experience with the keyboard interface will be most valuable. = If support for the mouse interface doesn't suffer, a good keyboard interfac= e can only be an advantage. >> The intention is that you wouldn't need indent, lint, etc. anymore, >> because e.g. "indentation" already would be done automatically as you en= ter >the text. > >Good point. Any good code editor would have this. Which reminds me of a >Windows program called UltraEdit (I think that's it). A buddy showed it >to me and I was amazed. I believe it has a "plug in"type of facility >which allows you to add support for different languages. We're planning sort-of plug-ins as well, but more fine-grained (on a per-ed= ited class basis) to allow flexible layout & verification of constructs lik= e functions, variables, classes, namespaces... >> >I should also admit that I have a dislike of GUIs because I have had to >> >write a number of the things recently. :P >> = >> You're referring to writing GUI applications, not to GUI IDE's, if I >> understand right. Whereas creating a GUI might be involve a lot of >> work, actually using the product *should* save work (at least that was >> the reasons why GUI were developed in the first place). > >Yes, I was referring to applications, not IDE's. I was thinking more of >our development of the IDE at that moment. I have started using Java a >lot because trying to write a multiplatform GUI was going to make me an >alcoholic. Ever try to write an X app? Yuck. > >I agree that a GUI is pretty much pointless if it isn't designed well. I think we'll try to take as much of the GUI support code from others as is= possible unless someone enjoys writing a new one. I'm considering the GUI = interface as a commodity (like floating point support or file I/O). >I should also point out that I have never worked on a really HUGE >software project like the kind tackled at MS. Perhaps in a project with >multiple coders and numerous files an IDE would be a lifesaver. I just >don't know. No, I think it there would be a difference for ongoing work. Being able to = use a GUI might be more inviting to new project members than a command inte= rface though. >My recent fascination with CWEB makes me ask if we want to build in >support for "literate programming" with Ultra. Not sure if this has >been brought up yet. A more recent example of this idea is Java's >javadoc spec. IMO we definitely should try to include the doc into the source. Docs that = are separated from the source tend to describe a different (mostly older) v= ersion of the software. But I don't like the idea of having yet another man= datory preprocessor run (to generate the compileable source). Tools like Au= toduck also have a (admittedly very limited) parsing capability, which redu= ces the amout of text to be written to generate the doc. >Cheers, > >Peter > > >--- >Software Engineer >EarthLink Network -- Regards, Hans-Dieter Dreier (Hans-Dieter.Dreier@materna.de)= --CCSTqOx4S4eV5M6aN7OJ0JbzuvQMlNRC Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable IDENTIFIKATIONSANGABEN: a14898a.txt IA5 DX-MAIL X.400 User Agent= --CCSTqOx4S4eV5M6aN7OJ0JbzuvQMlNRC-- From Hans-Dieter.Dreier@materna.de Mon May 17 15:01:31 1999 From: Hans-Dieter.Dreier@materna.de (Hans-Dieter.Dreier@materna.de) Date: Mon, 17 May 1999 16:01:31 +0200 Subject: GUI Builders (was: More On Multiple Inheritance) In-Reply-To: <3736D00F.FF513ED2@box.net.au> Message-ID: --wF9BjfqF5aIGMkqIyBTlcsGcxqpDzE31 Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable >Hans-Dieter.Dreier@materna.de wrote: > >> If we use the instance layout of the target class for templates as well,= a >> simple copy constructor can be used as a creation routine. As an additio= nal >> benefit, editor (and debugger) can then be used to view "live" configure= d >> instance items as well as templates. > >This strikes me as basically a prototyping scheme, at least on the >data. You're talking about having templates (prototypes) which can have >the same impl but differ in their state. And these can in turn be used >as a prototype for another template. Yes. >> Methods are almost always class items since all of the instances share t= he >same >> method code. Message handlers are instance items, however. IMO it is a m= ajor >> design flaw to implement message handlers as class items since this >effectively >> prohits reuse of that class. Message handlers often need to access the n= ame >> space of the _instance_ rather than that of the _class_. If all the cont= acts >to >> the instance's environment would have to take place by dynamic dispatch, >such a >> class would be rather cumbersome to use. > >I don't think so. If the widget classes are set up to use observers, >the widgets are reusable and don't need to be written with any >particular message handler in mind. Ideally the widget, handler and the >data are totally separate classes, providing more flexibility. Hence >handlers should never need to be in the widget. Java 1.0 joined them >together - they replaced that model with observers in 1.1. But isn't that a bit heavy for many applications? The model that I have in = mind would allow that, too, but you'd also have the ability to simply speci= fy s.th. like this: PushButton: pkOK ... Mesage Actions On ButtonClicked // ButtonClicked =3D *predefined constant* for = message sUser =3D dfUser.text sPassword =3D dfPassword.text Parent.WindowClose (true) and it possibly would override an inherited message handler for this partic= ular message. You would specify this in the same way you specify a data property. You could use any names in the context of this template definition, especially those of the parent window (the window in which this button is d= isplayed), without any qualification needed. If the programmer wants to see what happens if the button is clicked, he/she simply looks at the buttons definitions, and there it is. No need to= look into any other objects or classes; it all is in one place. BTW, this is an example of a consideration one should bear in mind when pro= gramming OO: OOP sometimes tends to rip aspects of items apart that are bet= ter localized in one place. Message handlers are a good example. If they ar= e highly individual (each instance does it differently), why not specify th= e actions to be taken with each template? = Another example would be an abort button. Usually, every abort button does = the same thing: It simply closes its parent window. Here it is sensible NOT= to specify the message handler with each instance, but rather derive from = a template that already has a message handler with the desired behaviour. T= his is possible because in this case no names of the instantiation namespac= e need to be known; the parent window can be determined by a feature call. This is the way Centura does it; and I can tell from a lot of project work = that I always found it very convenient and way better than how it is done i= n VC++ or Delphi. >> Dynamic creation of identically configured objects by a program is possi= ble >by >> calling the creation routine multiple times for a given template. In thi= s >case >> the instance created by the declaration might be unwanted; we might wan= t to >be >> able to prevent automatic creation due to the declaration. > >If this sort of thing ever happened, I would prefer it to be an >optimisation, I'm not sure I'd want to give it language status, even >though this sort of thing could really happen in any situation. Maybe you're right here - it is rather specific to GUI applications. >> We could do this by >> either adding a key word ("template") to the declaration or by adding a >special >> outline item (folder) for such templates. The latter is better because t= he >> former would either disrupt the instance layout or leave a NULL referenc= e >gaping >> if used in the "instance items" section of a class. > >I'm not sure what you're proposing here. Could you elaborate? Forget it - I found a better solution that makes do with standard features. Look at a normal dialog window. It would look like this: DialogWindow: dlgLogin ... Instance items DataField: dfUser DataField: dfPassword PushButton: pbOk PushButton: pbCancel ... Each instance of dlgLogin creates one instance of each of its children (dfU= ser, dfPasswordc, ...) and adds them to the list of its instance items. The= re is exactly one child item per template, and it is created automatically.= Note that this is analog to the way non-graphical classes operate. Now look at another example: MineSweeper (I'm not sure whether you know tha= t: It's a simple game that comes with Windows; it basically contains a grid= of identical small pushbuttons, each covering a "mine", that are arranged = in a rectangular grid). It would be no fun to specify 400 identical instanc= e items for a 20x20 grid. So my original idea was to have another outline s= ection in the parent window that was meant to contain subitem templates tha= t where NOT to be instantiated automatically like those in the dlgLogin exa= mple, but programmatically to allow for repeated instantiation. But, of course, one could write: Window: dlgMineField ... Instance items: PushButton: pbMine [] ... and simply declare an array of pbMine that would be filled at creation = time. >I assume you're defining properties to be constant here. Hence a copy >is unneeded and you can reuse the same object. If you had properties >that were not constant, eg the text font might change due to a checkbox >somewhere else being chosen, you would not use that for a property but >instead have both fonts as a "initial font" property and "changed font" >property respectively. Or, rather, "Arial" (ie template-specified) / "use ParentClass" (ie inherit= ed from parent class) / "use parent window" (ie "inherited" from surroundin= g window). >Because a copy is unneeded you might keep a prototype repository where >you pass the prototype id and get the prototype back which could be >created lazily if desired or the whole lot could be loaded from a file >or whatever. This wouldn't require any extra language facility. > >You might want to keep the prototypes constant or the ability to change >a lot of widgets at once might be useful. But there is certainly a >distinction between properties like font and transient properties like >widget state. Of course. For widget state, only the initial state would be set from the t= emplate. But it would often be more sensible to set such states programmati= cally, thus allowing to re-initialize them in the middle of the object's li= fe time. >It would be very difficult to merge these into one widget prototype if >you actually had the message handler in the widget too. Regarding message handlers, I should have been more specific: What I'm calling "message handler" actually is just one _case_ inside the m= essage handler (eg the reaction to message 12345). These cases need to be s= pecified individually. MS-VC++ does it by ugly macros in the class that gen= erate code for the message handler, like this: // Message Map BEGIN_MSG_MAP(CExtSnapPPage) MESSAGE_HANDLER( WM_COMMAND, CommandHandler ) MESSAGE_HANDLER( WM_NOTIFY, NotifyHandler) MESSAGE_HANDLER(PSM_QUERYSIBLINGS, QueryHandler) END_MSG_MAP() Such a macro has the disadvantage that it does not support automatic inheri= tance. If you need special code, you either put that into the (surrounding) toplev= el window or derive a whole new class . Furthermore, = it has the inconvenience that each subhandler (eg CommandHandler) needs a n= ame and a declaration, which is unneccessary if it is called only from one = place. In Centura, the message handler body (ie the Big Switch) is completely invi= sible to the programmer; all he sees are the indivudal subhandlers. (I woul= dn't go that far, though, for flexibility reasons). >>> So do these editors allow you to define a control that inherits the >properties >>> of another control? >> Yes. Usually that will be the surrounding window. > >When you say "surrounding window" do you mean "surrounding widget" or do >you mean it literally? Not sure what you are asking here. I'll try to explain: Each non-toplevel w= indow is a child window of some other window. Non-toplevel child windows sh= own inside (on-top) the parent window's client area and are clipped by the = parent window's borders. If the parent window is destroyed, so are all of i= ts child windows. Child windows may be nested; all the conditions noted abo= ve apply in this case as well. Thus, the parent window always is the (geome= tricaly, border-wise) surrounding window of each of its non-toplevel child = windows as well. (Toplevel windows can be children of other toplevel windows, but that's a d= ifferent affair). >And if you could change these templates at run-time, would they be >embedding or delegation based, ie would changes to the parents effect >children that haven't overridden? At the very least you'd need the >ability to create your own templates based on other templates at >run-time. I reckon that changes to the parent should affect children that haven't ove= rridden. Otherwise it could be done by an (automated?) edit-time copy. I'm = not sure whether changes at run time would occur frequently, however. Maybe both options could be present, like: Specify here / Inherit from parent / Copy from parent >> >> Window Position // type 3 item - you couldn't add this comm= ent >> Top: <0 // type 2 item> >> Left: <0> >> Widht: <400> >> Height: <300> >> Window Style >> Border? >> System Menu? >> ... > >I would expect this to be merely one view of the GUI languages of >course. A more graphical dragging and dropping alternative would be >another. Of course. >> I would suggest to keep that editor-related stuff in a separate class to= be >> able to easily strip it for a release version of the program. > >I would consider the "class" to be different in the sense of GUI >Builders and HLLs. GUI builders have an editor element which is >actually a widget defined in the program/language library, whereas a HLL >has an editor element which is a language element. You mean GUI builders have a window painter where non-graphical "builders" = have a text editor? Yes, but having text editing capability for the interna= l (non-graphical) representation of GUI elements' properties is valuable as= well. And, given structured storage with self-description facilities, both= text editors can be unified. The graphical editor remains a separate entit= y. Both are "views" operating on the same "document". >I think this code should never be a part of the editor core since it's >view-oriented. The editor core would: > >o coordinate the shared UI (whatever that might be) >o coordinate adding and removing languages, translations and views >into/from the system >o coordinate translations (ie incremental compilation) >o coordinate views (ie ensuring changes made in one window are >immediately reflected in others) Basically yes. I'd also put in library code for the most common edit behavi= ours and the tree view framework for the outline editor. >> Sure. The editor somehow needs to know which instance items to treat as >> properties. At first glance, I can think of several ways to do this: > >Maybe you could choose all public fields? IMO programm access (public, ...) and being a property are orthogonal (thus= need to be specified independently). There is no point in displaying publi= c items that do not need not have their initial state set at edit time (oth= er than for debug purposes, that is). Displaying all items can be a major waste of valuable screen space. If some= one wants to include/exclude a specific item from the customisation structu= red view, he/she can do so anyway by changing the item's definition. = >> 1. Add a keyword (say, "property") to the instance item's declaration. >> Only usable for simple cases since no specific customisation info can= be >> presented this way. >> ... >> Writing a keyword is much less work than writing a whole class. >> ... > >I wouldn't say that this action is common enough to warrant introducing >a new HLL feature on prototypes. It's certainly useful for widgets and >probably some other classes, but at least for widgets I doubt they're >defined anywhere near as often as they're used. In the meanwhile we got so many "features" or "properties" of *identifiers*= that we should think about having an identifier class. That would would al= low for complete flexibility in defining things like "public", "transparent= ", "property" and it would slim down the *core* language description, expor= ting those things to the definitions of specialized languages (which could = inherit from each other). >> All of the above ways silently include the assumption that there is only= one >> such "customisation set" for each class. This might be sufficient in mos= t >cases, >> but why should we accept that restriction right from the start? > >If you chose them all it wouldn't be a restriction. Sure, but again, displaying all items could be a major waste of valuable sc= reen space. = > Matthew Tuck - Software Developer & All-Round Nice Guy > mailto:matty@box.net.au (ICQ #8125618) > Check out the Ultra programming language project! > http://www.box.net.au/~matty/ultra/ > -- Regards, Hans-Dieter Dreier (Hans-Dieter.Dreier@materna.de)= --wF9BjfqF5aIGMkqIyBTlcsGcxqpDzE31 Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable IDENTIFIKATIONSANGABEN: a19273a.txt IA5 DX-MAIL X.400 User Agent= --wF9BjfqF5aIGMkqIyBTlcsGcxqpDzE31-- From Hans-Dieter.Dreier@materna.de Mon May 17 17:29:04 1999 From: Hans-Dieter.Dreier@materna.de (Hans-Dieter.Dreier@materna.de) Date: Mon, 17 May 1999 18:29:04 +0200 Subject: Parameterised Types In-Reply-To: <3736CA61.5C0395DD@box.net.au> Message-ID: --ks8deCx4ecYBByykPj81c1ph2FEIVrHa Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable >Hans-Dieter Dreier wrote: > >> Conceptually, for me type parameters are instance items. Strictly speaki= ng, >> List and List are actually the same type, but = each >> of them may or may not be used in some context because their different >> parameterization results in different constraints. Those may or may not >> evaluate to true in some context. Example: >> = >> List a ; >> List b; >> b may be used as a data source where a can be used because in this case = the >> contents of a may be substituted by the contents of b. So it is legal to >> write >> a =3D b; >> but it is illegal to write >> b =3D a; > >This is difficult in general because of the following case. > >class A > Field: X > ... > >procedure ... > ... > Variable: A :=3D new A > Variable.Field :=3D new General > >Here Variable.Field gets a General object although it is only allowed a >special object. Generic parameters have to be invariant where they are >used to instantiate read-write variables. Where the X was only used for >read-only variables, the covariant relationship you outlined would >hold. Where the X was only used for write-only variables, it would be >contravariant instead. If it is possible to detect situations like to one shown above (and I belie= ve it is), the compiler may insert a runtime check. Though I don't like thi= s as much as static type checks, it's better than nothing. >> The implementation of our parser may of course *assume* that there is su= ch a >> constraint if a type parameter is of type type because this will most of= ten >> be the case. Then things may probably be simplified by making the value = of >> this type a part of the type name of the parametrized type (similar to n= ame >> decoration in C++). But if we do this, we should keep in mind that it is= a >> mere simplification and not a concept in its own right. > >Hmm, could you elaborate? It would construct a name for internal use from the type and the actual cla= ss parameters, something like @A@@X@ and match those. So "Variable" is of t= ype @A@@General@ and since that is different from @A@@Special@, types would= be different and assignment would be possible only if a conversion were a= vailable. >> The bounds may even be changed at runtime, resulting in a reallocation. = Some >> programming languages allow this. I always found it very convenient to u= se. > >This is possible, but it would invalidate existing references. How is >this usually handled? References to the moved object are fixed up if the object cannot be realloc= ated in-place. No problem if we don't allow pointer-arithmetics <= /shudder>. >Copying GCs already have to handle this sort of >situation. What languages do you know that do this? Centura (IIRC PowerBuilder as well). >This is similar to >being able to change an object's impl, parent impl, etc. at run-time. Not really. The basic structure of an instance doesn't change (there are no= additional "names"); its length was not known at compile time anyway. >I think some object-based inheritance languages allow the addition of >fields at run-time, in parallel to a type downcast. IMO that's quite another thing. > >I'm not sure this would always work easily in general however. The >canonical example of value-driven data is an array but generic value >parameters can be used for typing as well as allocation. Yes. The fact that allocation is dynamic must be made explicitly available = to the compiler, like this: Class X (iItems) Instance items ... Y: x [iItems] Y would need to be the last instance item if we demand instance items' offs= ets to be known at compile time. = >> Contravariance is what I would allow by default. > >That would be the other option I'd take. I haven't really decided >whether contravariance or invariance is better. If we express variance in terms of assertions, the programmer choose which = one he wants, even on a per-instance-item basis. It could be tricky however= to determine in which case to apply the default, since it needs looking at= the semantics of each assertion. Otherwise the "natural" default would be = "no type checking" which would not be good... >> I'd suggest to use normal function syntax, ie write >> AnIntegerArray =3D new Array (Integer); >> instead of >> AnIntegerArray =3D new Array ; > >Possibly. () is usually used for construction parameters, which are >handled differently, so I'd like a way of demonstrating to the reader >that they are a different type of parameter, say by putting the type >parameters first and separating them by a "|" or similar symbol. Since >the type parameter list is defined in a different place to the >construction paremeter list, it would be handy to determine which list >has been passed to incorrectly better, which would be easier if you >separated them. I never liked the C++ way of naming the constructor he same as the class. = Instead, we should choose the Eiffel way and flag methods as "creation feat= ures". Assuming a constructor called "new", we would create a parameterized class = like this: X (MyClassParameter).new (MyCreationParameter) >> The C++ template syntax makes parsing unneccessarily hard because <> are >> used as operators too. > >Well I don't think this would affect a top-down parser. Of course it does. It can cause a lot of backtracking. Just look at the fol= lowing: -------Snip------ template class Test { int operator> (X x) {return true} int operator< (X x) {return false} Test() { Test Test =3D new Test; Test Test; // now is this a comparison or a declaration? // my claim is that it might be either } ~Test (); }; Test A (); ------Snap------- This compiles with VC++ 6.0. You get the point why I don't like C++