Mixed stuff

Hans-Dieter.Dreier@materna.de Hans-Dieter.Dreier@materna.de
Tue, 23 Feb 1999 13:03:08 +0100


--C7TZvrWrhWWukaGikfHHIuaK5MZzHo3B
Content-type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable

>Hans-Dieter Dreier wrote:

>> But in this Eiffel page I looked at,
>> the author stated that a parameterless function
>> can actually be viewed as some form of a (read-only) member variable.
>
>Actually, not necessarily read-only.  For example, look at C++'s
>reference return values.  You could write a statement like:
>
>hello(a) =3D 0

You're right, of course. If it returned a reference, it could be used as an=
 assignment target.

>A more general alternative to this would be to define "get" and "set"
>methods to emulate a variable, like many languages are doing now.

If there is a function returning the feature itself, that would be the "get=
",
and the function returning a reference to the feature would be the "set" (w=
hich could also be used as a "get", after automatic dereferencing). Right? =
It would involve polymorphic use of the feature's name, however, which I pe=
rsonally do not like very much because it adds some ambiguity to the source=
 code (ambiguous not to the compiler, of course, but to the forgetful progr=
ammer).

>> This has the advantage that you can change
>> the implementation of that "feature" (Eiffel speak for instance item)
>> if you see that some compilation is needed
>
>Not sure what you mean by "some compilation is needed".

Sorry, I meant "computation".

>> or want to write-protect the member variable,
>
>I wouldn't favour this as a way of write protecting the variable.  A far
>nicer way is to specify access mode in the type's method signature.  It
>is not something the implementation should choose.

If you mean the interface definition by "method signature", I agree.

>> Q: How do you revent execution if you actually
>> want a reference to the feature?
>> A: Have the appropriate type (ref <type of the feature>)
>> as a required type.
>
>Normally in OOPs you can't take references to methods, if you want to do
>that you get an object reference.  C++ is an exception and I don't think
>there's a necessity to follow it's lead here.

Maybe it's not needed very often, but if I can get it for free, I'll take i=
t,
since I don't consider it harmful. There may be cases where this sort of dy=
namism allows for shorter programs (avoiding the switch statement).

>> Q: Do you need to recompile clients?
>> A: Yes, except when the VM would be able
>> to insert the necessary dereferencing
>> (which sounds rather messy to me).
>
>A problem is that all variable accesses turn into method calls with this
>system.

Why _all_? I'd rather think, just those that really are method calls. Of co=
urse, a "normal" variable access may be seen as an inlined method call, if =
you like; but then again there wouldn't be any difference in performance.

>  These are less efficient, and hence method inlining is
>essential.  Since this is a inter-class optimisation, it make the
>program more fragile and subject to recompilation.  During development
>these inlines can be disabled if desired.

If the method calls can be inlined, all the better. But inlining wouldn't a=
void the inter-class optimisation either, since the inlined code would be u=
sed to *implement* the base class's feature. It would need recompilation wh=
enever the implementation of that feature changes.

>> This is a little disadvantage, but recompilation
>> may be required anyway most the time when an implementation
>> of a client class changes (because method addresses change).

Sorry, I meant _base class_ (instead of client class).

>I don't see this as true.  This is because I see this implementated as
>having a get and set method in the class whether it is implemented as a
>variable or real methods.  The type would not change, only the
>implementation, and hence the server class would not change.  Only
>inlining would force recompiles.
>
>> aClass::aMethod (int p1) vs. aFunction (aClass this, int p1)
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>> IMHO the *compiled* code for those examples
>> may actually be *identical*.
>
>A call to the first may well involve a method dispatch, the second, at
>least in a single dispatch language, would not.

You mean in case of virtual functions? That's true. I would like to use sta=
tic "dispatch" (actually an ordinary direct call) wherever possible, becaus=
e of better performance, combined with less memory usage (due to shorter v =
table). In this case they would be the same. =


>Languages which use multiple dispatch (choosing the method based on the
>type of more than one parameter) do things this way.

Do you mean the formal (declared) or the actual type (which may well be a d=
erived class)?

>> I'm thinking of automatic conversions, for example.
>> Remember the old problem of dyadic operators
>> which are commutative and
>> take parameters of *different* types.
>
>No, I've never been very comfortable with this either.  This as far as I
>can see is the reason why C++ has the friend keyword.  In this way, it's
>put in neither class but still has access to private members.  I and
>most people I know don't really like friend, but it does its job.

I didn't mention access to private features to the class. If that is needed=
 and the function is not part of the class, surely there must be a friend d=
eclaration. But IMO most conversions should be able to do without if there =
is a suitable public constructor available.

Anyhow, to allow the compiler to use a given method for automatic conversio=
ns should explicitly granted by the programmer. Otherwise the weirdest thin=
gs can happen.
 =

>> into account), but guess what happens if I hit
>> Alt+F8 to pretty-format my source?
>> Two lines become different just because of layout.
>> I have to view them all,
>> just to make sure not to miss a real change.
>
>I'm not sure what you're getting at here.  If there's a problem, it
>indicates the implementation should be tweaked rather than abandoned. =

>It should be simple to tell you if the file has been updated.

In plain words, I was just trying to say: "Not having an automatic, mandato=
ry layout has its problems, especially in a text file".

>> 2. Use of special characters.
>> ...
>
>This all sounds reasonable, but the fact is that people have widely
>ranging opinions on things like this.  Everyone has different screens,
>different fonts, different international conventions, different
>mathematical and programming backgrounds, etc.
>
>There really is no reason to enforce this sort of thing onto anyone.  As
>long as it works with the underlying language (e.g. identifier
>construction could affect the allowable grammar), it should be allowable
>if its useful to the programmer.
>
>No one is going to create a perfect syntax.  Choosing your own allows
>you to tailor it for your own specific needs, and experiment to create
>better syntaxes.  It's never been done before to my knowledge, so the
>effects will be interesting.

Sure. May everybody do it his way and get what his deserves. I don't mind ;=
)
That is, after all, a point that should make Ultra stand out amongst other =
languages. As you said, we should try to keep those representations transfo=
rmable, however.

>> 3. A language should be designed to make
>> it easy on the compiler, even if this means
>> that the programmer has to write a little more.
>
>While it's impossible to comment in general on a general comment like
>this, I have to disagree.  The compiler is there to save the programmer
>time.  That's why it was invented, and that's still what it's for.

But if you take that to an extreme, you end up with PL/1 or Ada or C++. Cer=
tainly there must be some balance.

>Functional complexity is not a bad thing - without it we would not be
>where we are today.  Arbitrary complexity is the problem, and often it
>can be removed, making things better for everyone.

Just compare a space shuttle with a russian rocket: The US did it the compl=
icated way and ended up with a complex, expensive thing, while the russians=
 did it as simple as possible, yet powerful enough and *cheap*. All I'm try=
ing to say is: At some point it is good enough; the extra effort of making =
it better will simply not justify the benefit gained.

>> If you look at C++ error messages,
>> you see what happens if this is not the case:
>> Forget one { and you get *lots* of messages
>> which are quite unrelated to the real error.
>
>This is a problem with error recovery in all parsers, not C++.  There is
>a tradeoff between reporting false errors and trying to report multiple
>true errors.  I don't see it as a major problem - although perhaps a
>"possible errors" comment could be useful, below which the status of the
>error is not known.

See, this is exactly what I would want to avoid: Introducing a new feature =
"possible error report" just because of a (IMHO) design flaw of the underly=
ing syntax which does not provide for robust error recovery. Why not rework=
 the syntax instead: You get only benefits (simpler parser, syntax that is =
easier to understand, better error messages, most likely shorter runtime ..=
.).

>> An (admittedly extreme) counterexample is Centura's 4GL,
>> where you got to write "Set X =3D Y" for an assignment.
>> At first I found that annoying, but I quickly got used to it.
>> And it has the advantage that you *always* get
>> ...
>
>If you change to a structure editor I would imagine you wouldn't get
>parse errors.  If we use a text based editor, the situation is really up
>in the air.  The view writer would have to worry about such things as
>error recovery.

An outline editor simply wouldn't allow you to make most errors in the firs=
t place. You could only enter syntactically correct items. You can make oth=
er errors, of course, like name clashes; but even these can be found much e=
asier in an outline than in plain text.

If people insist on using a plain text editor, they have to live with the c=
onsequences, as you said. (It's not _that_ bad, after all; zillions of prog=
rammers are stuck with stuff like this ;)

>> It's just that the compiler knows all it takes
>> for a really intelligent guess: The name is known;
>> the type can (usually) be inferred from the usage;
>> access properties can be guessed as "local variable".
>> I would like the compiler to insert that definition,
>> flag it as "compiler generated" (shown in some other color, perhaps)
>> and (optionally) issue a warning.
>
>I don't know I'd go as far as making the compiler put it there, but what
>we could do is to make it easier to manually generate declarations.  So
>for example you might right-click on one or more unhooked variables and
>choose "Generate Declaration(s)" from the popup menu.  Then you'll see
>them and can change them.
>
>Alternatively, you could right-click on error messages.  If there is a
>known solution to the problem, such as "Generate Declaration", you could
>choose it.  This could be applied to all manner of situations.  This
>sort of thing is view-independent too, which is good.

view independent? Well, I actually wanted the *compiler* to insert missing =
declarations, not the editor. That's because the programmer must explicitly=
 say "Now it's ready to give it a try", otherwise some confusion about prem=
ature actions taken by the editor might occur. You can see this nicely in V=
isual Studio: Quite often it starts updating some internal tables (or somet=
hing similar, I really dunno) on some innocent mouse click and there is an =
annoying delay. The compiler also has most of the neccessary functionality =
already built in, so it need not be duplicated.

If you drag'n drop a class definition into the "parameters" section of your=
 function's outline (thereby requesting a parameter of that type to be decl=
ared), the situation is reversed: Now the *editor* may (or may not, if you =
choose) propose some default name or default prefix for the item's name. Th=
is is OK because here the context is quite clear, the action is quickly per=
formed and is confined to the immediate neighborhood of the cursor.

>> If the compiler finds a declaration that is no longer used,
>> it should comment it out and mark that as "compiler generated";
>> if the declaration was compiler generated in the first place,
>> it should be removed completely instead.
>
>This really seems like a lot of hassle to go to to avoid a small hassle.

Shouldn't be much hassle, inserting, deleting and identifying items in a st=
ructure is easier than in a plain text. If such options are not present in =
the plain text based solution because it was too much hassle, so be it. IMO=
 the actual user interface with which the programmer is working every day s=
hould be as comfortable as possible. Every hour spent enhaceing the develop=
ment environment will in the long run save much more time (and nerves) spen=
t dealing with a less-than-perfect solution otherwise.

>> If the compiler generated items no longer apply due to a code change,
>> they should be removed automatically during compilation.
>> That would be a great auto-comment utility.
>> If the programmer cares to read those items,
>> he may even find logical errors in his program
>> that would otherwise only show up during testing.
>
>Is this any different than a "variable unreferenced" warning message?

Yes, it adds customising capabilities to the compiler, since it is then abl=
e to actively add info to the source code. Example: Unless you specify else=
, you won't be bothered with the same warning messages over and over again,=
 because the compiler knows (from the comment it left in the source) that y=
ou already recognised that warning. You do not need to change the code your=
self to explicitly disable that warning.

If this feature is done in a sensible way, I think many people will appreci=
ate the enhanced ease of use. Of course, all this is just an option; you ma=
y as well perfer not to have the compiler change your code in any way.

--

Regards,

Hans-Dieter Dreier
(Hans-Dieter.Dreier@materna.de)>Hans-Dieter Dreier wrote:
>
>> I got a new nice language link on Haskell for the link collection:
>> http://www-i2.informatik.rwth-aachen.de/Haskell/
>
>Yes.  I'll add that.  I really have to improve on the paltry number of
>language links there at the moment.
>
>> But in this Eiffel page I looked at,
>> the author stated that a parameterless function
>> can actually be viewed as some form of a (read-only) member variable.
>
>Actually, not necessarily read-only.  For example, look at C++'s
>reference return values.  You could write a statement like:
>
>hello(a) =3D 0
>
>A more general alternative to this would be to define "get" and "set"
>methods to emulate a variable, like many languages are doing now.
>
>> This has the advantage that you can change
>> the implementation of that "feature" (Eiffel speak for instance item)
>> if you see that some compilation is needed
>
>Not sure what you mean by "some compilation is needed".
>
>> or want to write-protect the member variable,
>
>I wouldn't favour this as a way of write protecting the variable.  A far
>nicer way is to specify access mode in the type's method signature.  It
>is not something the implementation should choose.
>
>> without having to rewrite the classes' clients.
>
>Swapping functions and variables is an important feature, since it
>allows various changes in implementation.  You could calculate or
>redundantly store some piece of information, for example the count of
>members in a linked list.  Does it matter whether it's redundantly
>stored (as a variable that is updated), or calculated (as a function)? =

>No, and you should be able to change between them.  As another example,
>you might to somehow compress the field to take less space.
>
>> Q: How do you revent execution if you actually
>> want a reference to the feature?
>> A: Have the appropriate type (ref <type of the feature>)
>> as a required type.
>
>Normally in OOPs you can't take references to methods, if you want to do
>that you get an object reference.  C++ is an exception and I don't think
>there's a necessity to follow it's lead here.
> =

>> Q: Do you need to recompile clients?
>> A: Yes, except when the VM would be able
>> to insert the necessary dereferencing
>> (which sounds rather messy to me).
>
>A problem is that all variable accesses turn into method calls with this
>system.  These are less efficient, and hence method inlining is
>essential.  Since this is a inter-class optimisation, it make the
>program more fragile and subject to recompilation.  During development
>these inlines can be disabled if desired.
>
>> This is a little disadvantage, but recompilation
>> may be required anyway most the time when an implementation
>> of a client class changes (because method addresses change).
>
>I don't see this as true.  This is because I see this implementated as
>having a get and set method in the class whether it is implemented as a
>variable or real methods.  The type would not change, only the
>implementation, and hence the server class would not change.  Only
>inlining would force recompiles.
>
>> aClass::aMethod (int p1) vs. aFunction (aClass this, int p1)
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>> IMHO the *compiled* code for those examples
>> may actually be *identical*.
>
>A call to the first may well involve a method dispatch, the second, at
>least in a single dispatch language, would not.
>
>Languages which use multiple dispatch (choosing the method based on the
>type of more than one parameter) do things this way.
> =

>> I'm thinking of automatic conversions, for example.
>> Remember the old problem of dyadic operators
>> which are commutative and
>> take parameters of *different* types.
>
>No, I've never been very comfortable with this either.  This as far as I
>can see is the reason why C++ has the friend keyword.  In this way, it's
>put in neither class but still has access to private members.  I and
>most people I know don't really like friend, but it does its job.
> =

>> into account), but guess what happens if I hit
>> Alt+F8 to pretty-format my source?
>> Two lines become different just because of layout.
>> I have to view them all,
>> just to make sure not to miss a real change.
>
>I'm not sure what you're getting at here.  If there's a problem, it
>indicates the implementation should be tweaked rather than abandoned. =

>It should be simple to tell you if the file has been updated.
> =

>> 2. Use of special characters.
>> ...
>
>This all sounds reasonable, but the fact is that people have widely
>ranging opinions on things like this.  Everyone has different screens,
>different fonts, different international conventions, different
>mathematical and programming backgrounds, etc.
>
>There really is no reason to enforce this sort of thing onto anyone.  As
>long as it works with the underlying language (e.g. identifier
>construction could affect the allowable grammar), it should be allowable
>if its useful to the programmer.
>
>No one is going to create a perfect syntax.  Choosing your own allows
>you to tailor it for your own specific needs, and experiment to create
>better syntaxes.  It's never been done before to my knowledge, so the
>effects will be interesting.
>
>> 3. A language should be designed to make
>> it easy on the compiler, even if this means
>> that the programmer has to write a little more.
>
>While it's impossible to comment in general on a general comment like
>this, I have to disagree.  The compiler is there to save the programmer
>time.  That's why it was invented, and that's still what it's for.
>
>Functional complexity is not a bad thing - without it we would not be
>where we are today.  Arbitrary complexity is the problem, and often it
>can be removed, making things better for everyone.
>
>> If you look at C++ error messages,
>> you see what happens if this is not the case:
>> Forget one { and you get *lots* of messages
>> which are quite unrelated to the real error.
>
>This is a problem with error recovery in all parsers, not C++.  There is
>a tradeoff between reporting false errors and trying to report multiple
>true errors.  I don't see it as a major problem - although perhaps a
>"possible errors" comment could be useful, below which the status of the
>error is not known.
>
>> An (admittedly extreme) counterexample is Centura's 4GL,
>> where you got to write "Set X =3D Y" for an assignment.
>> At first I found that annoying, but I quickly got used to it.
>> And it has the advantage that you *always* get
>> ...
>
>If you change to a structure editor I would imagine you wouldn't get
>parse errors.  If we use a text based editor, the situation is really up
>in the air.  The view writer would have to worry about such things as
>error recovery.
>
>> It's just that the compiler knows all it takes
>> for a really intelligent guess: The name is known;
>> the type can (usually) be inferred from the usage;
>> access properties can be guessed as "local variable".
>> I would like the compiler to insert that definition,
>> flag it as "compiler generated" (shown in some other color, perhaps)
>> and (optionally) issue a warning.
>
>I don't know I'd go as far as making the compiler put it there, but what
>we could do is to make it easier to manually generate declarations.  So
>for example you might right-click on one or more unhooked variables and
>choose "Generate Declaration(s)" from the popup menu.  Then you'll see
>them and can change them.
>
>Alternatively, you could right-click on error messages.  If there is a
>known solution to the problem, such as "Generate Declaration", you could
>choose it.  This could be applied to all manner of situations.  This
>sort of thing is view-independent too, which is good.
>
>> If the compiler finds a declaration that is no longer used,
>> it should comment it out and mark that as "compiler generated";
>> if the declaration was compiler generated in the first place,
>> it should be removed completely instead.
>
>This really seems like a lot of hassle to go to to avoid a small hassle.
>
>> If the compiler generated items no longer apply due to a code change,
>> they should be removed automatically during compilation.
>> That would be a great auto-comment utility.
>> If the programmer cares to read those items,
>> he may even find logical errors in his program
>> that would otherwise only show up during testing.
>
>Is this any different than a "variable unreferenced" warning message?
>
>-- =

>     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)=

--C7TZvrWrhWWukaGikfHHIuaK5MZzHo3B
Content-type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable

IDENTIFIKATIONSANGABEN:
a16167a.txt IA5 DX-MAIL X.400 User Agent=

--C7TZvrWrhWWukaGikfHHIuaK5MZzHo3B--