Discussion:
The Eiffel Compiler tecomp version 0.24 released
(too old to reply)
Helmut
2010-10-10 22:19:45 UTC
Permalink
http://tecomp.sourceforge.net
http://www.sourceforge.net/projects/tecomp

== New features ==

=== Simplified void safety syntax implemented ===

A simplified syntax for void safety has been implemented which
replaces the more verbose old syntax

exp: detachable E
anc_exp: detachable E_ANCESTOR -- conformant

-- old syntax
check attached exp as x then
x.some_feature
end
check attached {E} anc_exp as x then
x.some_feature
end

-- new syntax
exp.attached.some_feature
anc_exp.attached{E}.some_feature


If `exp' is not attached to an object or `anc_exp' is not
attached to an object of type E, an exception is thrown, i.e. the
semantics is the same as with the old syntax, the syntax is more
concise.

For more details see the white paper at
[[http://tecomp.sourceforge.net]] -> white papers -> language
discussion -> improved void safety.
Emmanuel Stapf [ES]
2010-10-11 19:10:58 UTC
Permalink
Post by Helmut
-- new syntax
exp.attached.some_feature
anc_exp.attached{E}.some_feature
If `exp' is not attached to an object or `anc_exp' is not
attached to an object of type E, an exception is thrown, i.e. the
semantics is the same as with the old syntax, the syntax is more
concise.
This goes against void-safety. We added `attached' in ANY at the very
beginning of Void-safety in EiffelStudio. The type of attached is
"attached like Current". It was thought it would help in the transition
to void-safety but we quickly abandoned it. Because really you are just
hiding the fact that `exp' is not attached and you are not better off
than Eiffel without void-safety which already raised an exception.

The fact that you are hiding the check part is really bad when reading
the code because if I read a check I know that the author of the code
thought about it, not that it just wrote `a.attached' just to please the
type system which will happen a lot if you offer this possibility.

Manu
Helmut
2010-10-12 17:58:45 UTC
Permalink
On Oct 11, 2:10 pm, "Emmanuel Stapf [ES]"
Post by Emmanuel Stapf [ES]
     -- new syntax
     exp.attached.some_feature
     anc_exp.attached{E}.some_feature
If `exp' is not attached to an object or `anc_exp' is not
attached to an object of type E, an exception is thrown, i.e. the
semantics is the same as with the old syntax, the syntax is more
concise.
This goes against void-safety. We added `attached' in ANY at the very
beginning of Void-safety in EiffelStudio. The type of attached is
"attached like Current". It was thought it would help in the transition
to void-safety but we quickly abandoned it. Because really you are just
hiding the fact that `exp' is not attached and you are not better off
than Eiffel without void-safety which already raised an exception.
The fact that you are hiding the check part is really bad when reading
the code because if I read a check I know that the author of the code
thought about it, not that it just wrote `a.attached' just to please the
type system which will happen a lot if you offer this possibility.
Clearly, there are always pros and cons. But I am not sure whether you
have read the change completely. There is no --- I repeat -- no change
of semantics. The long and clumsy form you are proposing and the more
concise form are semantically identical.

I.e.

a.attached.do_something

and

check
attached a as att_a
then
att_a.do_something
end

should be read in the same way. I.e. both are assertions which need to
be checked at runtime or proved at compile time. If the programer is
wrong and the assertion does not hold, he is wrong in both cases. If
the developer tries to `cheat' the type system, he can cheat it in
both ways. The only reasonable argument you can raise: In the new
form, the developer has less keys to type to make an error. But is
less keystrokes really a reason to generate more errors? I doubt it.
Emmanuel Stapf [ES]
2010-10-13 04:09:10 UTC
Permalink
Post by Helmut
Clearly, there are always pros and cons. But I am not sure whether you
have read the change completely. There is no --- I repeat -- no change
of semantics. The long and clumsy form you are proposing and the more
concise form are semantically identical.
I'm sorry but reading a.b does not read as a check to me. It reads as a
normal feature call thus in a void-safe system I would associate it with
a call on an attached target, not a check.
Post by Helmut
should be read in the same way. I.e. both are assertions which need to
be checked at runtime or proved at compile time. If the programer is
wrong and the assertion does not hold, he is wrong in both cases. If
Yes but there is a big difference. In one case he made a wrong
assumption (check is violated) and I can see that from the code. On the
other hand without the check I'm very doubtful of the programmer's code
quality because he did not put anything in the code to show that it was
never void, he just assumed so by working around the type system.

My point of view is not of the one writing the code, but of someone
reviewing the code and trying to make sure that the code written is
really covering all the possible cases. What I mean by that is that if I
read (in non void-safe Eiffel)

f (s: STRING)
do
s.to_lower
end

I can right away tell to the programmer that his code is wrong, he is
either missing a precondition or an if statement.

The reviewer reading a.attached.f will most likely miss it because it
does not emphasize the fact that one has to check for the non-voidness
of `a'. It encourages quick and dirty fix of the error reported by the
compiler.

I think that before adding a new language construct one should actually
have some strong arguments. There is so little code using void-safe and
the new `check' instruction at the moment that it is a little bit early
to propose yet a new syntax.

Regards,
Manu
Georg Bauhaus
2010-10-13 09:44:16 UTC
Permalink
Post by Emmanuel Stapf [ES]
Post by Helmut
Clearly, there are always pros and cons. But I am not sure whether you
have read the change completely. There is no --- I repeat -- no change
of semantics. The long and clumsy form you are proposing and the more
concise form are semantically identical.
I'm sorry but reading a.b does not read as a check to me.
2nd
Post by Emmanuel Stapf [ES]
I can see that from the code.
Very important. The clever abbreviation

clutter.attached.more_clutter

is (again emphasizing Manu's remark) "hiding" the check. Specifically, the
syntax is mixing an outstanding construct (check ... then ... end) of specific
semantic implications with that of regular feature call at the syntax level.
A sin, in my book. This is "overloading" constructs at the language design level,
requiring the reader to disambiguate.

If

a.attached.do_something
a.attach(b)
a.attached_nodes.count

appear in the same program, surely confusion will be imposed on the reader?


For illustration, assume that explicitness is a "long and clumsy
form". Let this motivate a similar want of terseness applied to the
"feature" keyword. Semantically harmless, the example only involves
comments, the programmer thinks. No language change is involved.
Nevertheless, harm is done:

There is no change of meaning if I rewrite

feature -- department abc
foo ...
bar ...
feature -- department xyz
baz ...

as

feature -- departments abc and xyz
foo ...
bar ...
baz ...

The second alternative removes very important information
from the program source text. Important to the human reader,
not to the mechanical translator. But programming is a human
activity. Language designs and translators are supposed to
help with that...


On the whole, the time I spend in writing syntactical construct seems
little in comparison to the time spent in writing algorithms,
getting them right, adapting them to changes in the environment,
and be guided by clear, unique, if not-so-terse notation.



Georg
Helmut
2010-10-13 19:24:14 UTC
Permalink
On Oct 12, 11:09 pm, "Emmanuel Stapf [ES]"
Post by Emmanuel Stapf [ES]
Post by Helmut
Clearly, there are always pros and cons. But I am not sure whether you
have read the change completely. There is no --- I repeat -- no change
of semantics. The long and clumsy form you are proposing and the more
concise form are semantically identical.
I'm sorry but reading a.b does not read as a check to me.
But a.attached.do_something reads as a check. But if you prefer the
long form, just use the long form.
Post by Emmanuel Stapf [ES]
It reads as a
normal feature call thus in a void-safe system I would associate it with
a call on an attached target, not a check.
Post by Helmut
should be read in the same way. I.e. both are assertions which need to
be checked at runtime or proved at compile time. If the programer is
wrong and the assertion does not hold, he is wrong in both cases. If
Yes but there is a big difference. In one case he made a wrong
assumption (check is violated) and I can see that from the code.
In both cases he made a wrong assumption and you can see that from the
code. Remember that `attached' is a keyword and is usually
highlighted.
Post by Emmanuel Stapf [ES]
On the
other hand without the check I'm very doubtful of the programmer's code
quality because he did not put anything in the code to show that it was
never void,
he put the keyword `attached' and signalled with that, that he assumes
it will never be void.
Post by Emmanuel Stapf [ES]
he just assumed so by working around the type system.
You can work around the type system with the check instruction as
well.
Post by Emmanuel Stapf [ES]
My point of view is not of the one writing the code, but of someone
reviewing the code and trying to make sure that the code written is
really covering all the possible cases.
Me too. Try to compare the readability of

check attached exp as att_exp then
att_exp.do_something
end

with

exp.attached.do_something

The keyword attached immediately signals an assumption which needs to
be verified.
Post by Emmanuel Stapf [ES]
The reviewer reading a.attached.f will most likely miss it because it
does not emphasize the fact that one has to check for the non-voidness
of `a'.
Before making such a claim you should compare. Eiffelbase is already
voidsafe. Just pick some examples of how it is written today with the
check instruction and compare it to the proposed syntax. And then case
by case we could examine your argument. If you find more some good
examples where the proposed new syntax is worse, I certainly will say:
"you are right".
Post by Emmanuel Stapf [ES]
I think that before adding a new language construct one should actually
have some strong arguments. There is so little code using void-safe and
the new `check' instruction at the moment that it is a little bit early
to propose yet a new syntax.
I thought all you Eiffelstudio libaries are void safe now. A lot of
material to study!!

By the way: Do you have an idea, why so few Eiffel users have already
switched to void safe mode (it is available for more than one year
now!!). And don't worry, it certainly is not only because of the check
instruction.
Georg Bauhaus
2010-10-14 12:20:17 UTC
Permalink
On Oct 12, 11:09 pm, "Emmanuel Stapf [ES]"
Post by Emmanuel Stapf [ES]
Post by Helmut
Clearly, there are always pros and cons. But I am not sure whether you
have read the change completely. There is no --- I repeat -- no change
of semantics. The long and clumsy form you are proposing and the more
concise form are semantically identical.
I'm sorry but reading a.b does not read as a check to me.
But a.attached.do_something reads as a check.
Empirical research regarding programmer behavior will tell
that, no, it doesn't read as a check. Studies of this kind have
been performed both formally and less formally; they have
influenced language design. I trust that Emmanuel Stapf
is among the people with a tremendous amount of insight here,
both directly and indirectly.

I also trust that since you want this style of expression,
there is no point in discussing it.


But anyway, a utility function of a language feature (utility function
as in economy or related sciences) needs to take into account
important variables. These, I think, include:

- Will the persons who decide on language choice vote Eiffel
up or down because of the feature?

For example, if might calculate that a 24/7 Eiffel programmer knows
how to distinguish
a.attached.do_something
and
a.untouch.do_something. *But* future personnel, or multi-
language personnel might not. So which economic feature cost will
they compute? Will their feature cost calculation make them lean
towards Eiffel?
Assign the feature a degree of influence on the decision.


- How will the feature affect tools?

Assign a vendor effort cost factor, maybe negative if you are a
customer (IFF you have to pay for increased effort of to
implement the feature), or positive if you are a vendor (IFF
you (want to) get payed for the increased effort, and consider it
a business asset).


- Will "reads-as check magic" attract programmers in the long run?

Take, for example, MS's LINQ feature. It seem to attract people.
Is it much different from FUNCTION, TUPLE etc? Is it more attractive?
Why?
Assign a degree of attraction.

- Will the feature make analyzing and restructuring software
any easier?

As this is usually called refactoring, assign a degree of increased/
decreased feasibility of refactoring, with existing tools and
processes in mind.

So far, then,

utility = f (c(skills), c(tools), c(attraction), c(maintenance))
where c stands for cost and f is a utility function.

Without much more thinking, I'm not sure these four are the variables
already or independent variables, or indeed functions of yet
something else. I only wanted to emphasize that a language feature
has implications beyond syntax and semantics. The implications
should in turn influence decisions on syntax and semantics.

Eiffel's co- vs contra-variant type hierarchy decision
provides us with one example.
Seemingly non-technical factors have influenced language design:
Eiffel has covariant hierarchies because ... and not because
contra-variance has certain technical benefits. Again, syntax
and semantics are not enough to make a choice.


Georg
Simon Willcocks
2010-10-14 22:13:40 UTC
Permalink
Post by Georg Bauhaus
On Oct 12, 11:09 pm, "Emmanuel Stapf [ES]"
Post by Emmanuel Stapf [ES]
Post by Helmut
Clearly, there are always pros and cons. But I am not sure whether you
have read the change completely. There is no --- I repeat -- no change
of semantics. The long and clumsy form you are proposing and the more
concise form are semantically identical.
I'm sorry but reading a.b does not read as a check to me.
But a.attached.do_something reads as a check.
I would agree with this; it's something you can quickly search for, or have
highlighted in an editor. (I don't think it's a good place for a keyword,
though; the feature in ANY seems reasonable, to me. I prefer my ? though.)
Post by Georg Bauhaus
Empirical research regarding programmer behavior will tell
that, no, it doesn't read as a check. Studies of this kind have
been performed both formally and less formally; they have
influenced language design. I trust that Emmanuel Stapf
is among the people with a tremendous amount of insight here,
both directly and indirectly.
Do you have any references to these studies?
Post by Georg Bauhaus
I also trust that since you want this style of expression,
there is no point in discussing it.
I don't think it's helpful to dismiss someone in that way; it's too easily
used by someone who has already made up their own mind.
Post by Georg Bauhaus
But anyway, a utility function of a language feature (utility function
as in economy or related sciences) needs to take into account
- Will the persons who decide on language choice vote Eiffel
up or down because of the feature?
For example, if might calculate that a 24/7 Eiffel programmer knows
how to distinguish
a.attached.do_something
and
a.untouch.do_something. *But* future personnel, or multi-
language personnel might not. So which economic feature cost will
they compute? Will their feature cost calculation make them lean
towards Eiffel?
Assign the feature a degree of influence on the decision.
I think that Helmut's approach could probably be incorporated into existing
Eiffel programs with a relatively simple sed command, leaving the programs
no more prone to error than they were before. Looking through the program
for places it's not needed would be a reasonably straight forward task.

I would suggest that "multi- language personnel" may have more problems with
a check statement (essentially an assertion, until recently) becoming both
an essential part of the program and a variable declaration!

(Please forgive me if I've misunderstood the examples Helmut gave:

exp: detachable E
anc_exp: detachable E_ANCESTOR -- conformant

-- old syntax
check attached exp as x then
x.some_feature
end
check attached {E} anc_exp as x then
x.some_feature
end

In it, it looks like x has appeared from nowhere (and presumably needs yet
another name that doesn't clash with a feature, local or parameter?) and
disabling runtime checks is no longer an option.)

There was a rather nice construct suggested a while ago, where you could
select an object by type, something like:

select o -- an instance of some superclass of E
when E
o.some_e_function -- you get to use the same name!
when NULL
-- o = Void, now what?
end

I liked that!
Post by Georg Bauhaus
- How will the feature affect tools?
Assign a vendor effort cost factor, maybe negative if you are a
customer (IFF you have to pay for increased effort of to
implement the feature), or positive if you are a vendor (IFF
you (want to) get payed for the increased effort, and consider it
a business asset).
So, a commercial vendor would prefer the more complex solution. What if the
tool is to be free? Then both the customer and developer would want the
quickest, sufficient, solution. It also depends on the number of customers;
it's worth spending more time on something to be used by thousands than one
to be used by just a few.
Post by Georg Bauhaus
- Will "reads-as check magic" attract programmers in the long run?
Take, for example, MS's LINQ feature. It seem to attract people.
I'd not come across that before. Wasn't there something similar by Oracle
(PL/SQL, or something)?
Post by Georg Bauhaus
Is it much different from FUNCTION, TUPLE etc? Is it more attractive?
Probably. I always thought that there were simpler ways of dealing with
those problems, anyway.
Post by Georg Bauhaus
Why?
Because Microsoft told (tens of?) thousands of developers that it was a good
thing, and lots of people believe them (they might even be right).
Post by Georg Bauhaus
Assign a degree of attraction.
- Will the feature make analyzing and restructuring software
any easier?
As this is usually called refactoring, assign a degree of increased/
decreased feasibility of refactoring, with existing tools and
processes in mind.
Since both approaches are easily interchangable, I doubt this is a major
factor.
Post by Georg Bauhaus
So far, then,
utility = f (c(skills), c(tools), c(attraction), c(maintenance))
where c stands for cost and f is a utility function.
Without much more thinking, I'm not sure these four are the variables
already or independent variables, or indeed functions of yet
something else. I only wanted to emphasize that a language feature
has implications beyond syntax and semantics. The implications
should in turn influence decisions on syntax and semantics.
Eiffel's co- vs contra-variant type hierarchy decision
provides us with one example.
Eiffel has covariant hierarchies because ... and not because
contra-variance has certain technical benefits. Again, syntax
and semantics are not enough to make a choice.
Isn't covariance semantics? And aren't CAT calls still a concern?

I never understood why ISE's Eiffel checked preconditions on the attached
object instead of the interface the call was being made through. If your
code needs weaker preconditions, you should check to see if you've got an
object that will accept them first!

Simon
--
ROLF - The RISC OS Look and Feel on Linux.
http://ro-lookandfeel.blogspot.com/
http://sourceforge.net/projects/ro-lf/
Georg Bauhaus
2010-10-15 11:06:27 UTC
Permalink
Post by Simon Willcocks
On Oct 12, 11:09 pm, "Emmanuel Stapf [ES]"
Post by Emmanuel Stapf [ES]
Post by Helmut
Clearly, there are always pros and cons. But I am not sure whether you
have read the change completely. There is no --- I repeat -- no change
of semantics. The long and clumsy form you are proposing and the more
concise form are semantically identical.
I'm sorry but reading a.b does not read as a check to me.
But a.attached.do_something reads as a check.
I would agree with this; it's something you can quickly search for, or have
highlighted in an editor. (I don't think it's a good place for a keyword,
though; the feature in ANY seems reasonable, to me. I prefer my ? though.)
Indeed, the placing of a keyword is part of the argument.
It is in the same position as a called feature and, perhaps
unintentionally, subverts the usual Eiffel grammatical habits.

I'm deliberately exaggerating in the following example,
to illustrate the point: by the same token, one might rewrite

if a.query then
foo.bar
end

as

a.query.if.foo.bar

The "if" is quickly searched for, or highlighted in an editor,
and we can use sed for refactoring. I suggest many would find
my placement of "if" absurd. Not so with "attached", it seems.
Why is that?

I'd also count the placement issue as going against what is called
"natural target of quality assurance efforts" in [1, p.12], even
though the argument there is not the same. The emphasis would be
on "natural", a notion to be kept in mind with advantage when making
language decisions,I believe.

On the positive side, a clearly visible infix symbol can invalidate
some of the arguments, though. To avoid overloading at the syntax
level, the symbol should perhaps have no other uses. (I have picked
this one (CHECK MARK, U+2713) for the sake of an example.)

b.foo(bar)
a ✓ do_something
c.d

A compiler can then still try to show that a is always attached
or else generate code raising a meaningful exception. But with
the brevity the opportunity to add a note has vanished...
Post by Simon Willcocks
Empirical research regarding programmer behavior ...
Do you have any references to these studies?
Yes, some recent, some old; lengthy elaboration and some
conclusive arguing might be needed, and reference to other languages.
Since doing so might entail loosing focus or even incite language
wars, I'll try to send them via email.
Post by Simon Willcocks
I also trust that since you want this style of expression,
there is no point in discussing it.
I don't think it's helpful to dismiss someone in that way; it's too easily
used by someone who has already made up their own mind.
Agree, but I think the issue always needs to be on the table:
a new language feature is to be defended, exhibit all motives.
Risk some impoliteness.
Post by Simon Willcocks
I would suggest that "multi- language personnel" may have more problems with
a check statement (essentially an assertion, until recently) becoming both
an essential part of the program and a variable declaration!
exp: detachable E
anc_exp: detachable E_ANCESTOR -- conformant
-- old syntax
check attached exp as x then
x.some_feature
end
check attached {E} anc_exp as x then
x.some_feature
end
In it, it looks like x has appeared from nowhere (and presumably needs yet
another name that doesn't clash with a feature, local or parameter?) and
disabling runtime checks is no longer an option.)
The order of symbols in the declaration has changed, yes.
Object test syntax aside, if symmetry seems desirable then

check
x : attached exp
then
x.some_feature
end

looks like it has fewer syntactical rearrangements?

But x appeared from nowhere in attached exp as x?

I'd assume that language savvy programmers (or indeed anyone having
read a math text) have seen an expression of the kind
x op y where y = f(t1, t2)
Finding x standing on the right would not seem to be
an unusual expectation to me.

(AFAIU, the semantics of check may have changed a bit, but the
spirit, too? Assume the thing to be attached, and have quality
assurance fix the error otherwise; "check" still is not "if"
and can be turned off, once you trust your attachments. Correct?)
Post by Simon Willcocks
There was a rather nice construct suggested a while ago, where you could
select o -- an instance of some superclass of E
when E
o.some_e_function -- you get to use the same name!
when NULL
-- o = Void, now what?
end
I liked that!
Note how this does not have the placement issue! ;-)
Post by Simon Willcocks
As this is usually called refactoring, assign a degree of increased/
decreased feasibility of refactoring, with existing tools and
processes in mind.
Since both approaches are easily interchangable, I doubt this is a major
factor.
Ideally, any unambiguous syntax can be transformed into another.
But in real life, programmers struggle with regular expressions,
for a start. Even for Eiffel a good, general tool might not be
trivial to write and use if there is older source, too, written
using an older, different grammar.
Post by Simon Willcocks
Eiffel's co- vs contra-variant type hierarchy decision
provides us with one example.
Eiffel has covariant hierarchies because ... and not because
contra-variance has certain technical benefits. Again, syntax
and semantics are not enough to make a choice.
Isn't covariance semantics? And aren't CAT calls still a concern?
Exactly, OOSC2 does not hesitate to use what, upon closer
inspection, appears to be persuasive rhetoric to defend
covariance, in the presence of CAT calls.
I'm sure others will be able to provide equally compelling
examples of why contravariance would have been preferable.
But the point is, both language design decisions (co or contra)
have implications that could not have be deduced from syntax and
semantics alone. Examples, or use cases, were needed.

Georg
__
[1] Avoid a Void: The eradication of null dereferencing
http://docs.eiffel.com/sites/docs.eiffel.com/files/void-safe-eiffel.pdf
Georg Bauhaus
2010-10-15 11:21:43 UTC
Permalink
Post by Georg Bauhaus
I'd assume that language savvy programmers (or indeed anyone having
read a math text) have seen an expression of the kind
x op y where y = f(t1, t2)
Finding x standing on the right would not seem to be
an unusual expectation to me.
I should have used different letters, sorry.
Simon Willcocks
2010-10-18 12:33:39 UTC
Permalink
Post by Georg Bauhaus
Post by Simon Willcocks
On Oct 12, 11:09 pm, "Emmanuel Stapf [ES]"
Post by Emmanuel Stapf [ES]
I'm sorry but reading a.b does not read as a check to me.
But a.attached.do_something reads as a check.
I would agree with this; it's something you can quickly search for, or have
highlighted in an editor. (I don't think it's a good place for a keyword,
though; the feature in ANY seems reasonable, to me. I prefer my ? though.)
Indeed, the placing of a keyword is part of the argument.
It is in the same position as a called feature and, perhaps
unintentionally, subverts the usual Eiffel grammatical habits.
I'm deliberately exaggerating in the following example,
to illustrate the point: by the same token, one might rewrite
if a.query then
foo.bar
end
as
a.query.if.foo.bar
I understand what you are saying, but they're not equivalent. "attached"
could be implemented as a simple function returning the attached type, so
having it in the same position as a feature isn't such a problem.

The magic of the check form is to do with multi-threading.
Post by Georg Bauhaus
On the positive side, a clearly visible infix symbol can invalidate
some of the arguments, though. To avoid overloading at the syntax
level, the symbol should perhaps have no other uses. (I have picked
this one (CHECK MARK, U+2713) for the sake of an example.)
b.foo(bar)
a ✓ do_something
c.d
My e-mail client didn't like that much!

I'd still be inclined to use the question mark, it even implies uncertaincy
in natural language, don't you think?

d?do_something.foo( bar )

a ?= d -- throws exception iff d = Void and a's type is attached
Post by Georg Bauhaus
A compiler can then still try to show that a is always attached
or else generate code raising a meaningful exception. But with
the brevity the opportunity to add a note has vanished...
There are still comments, and you can always assign it to a local attached
entity.
Post by Georg Bauhaus
Post by Simon Willcocks
Empirical research regarding programmer behavior ...
Do you have any references to these studies?
Yes, some recent, some old; lengthy elaboration and some
conclusive arguing might be needed, and reference to other languages.
Since doing so might entail loosing focus or even incite language
wars, I'll try to send them via email.
I got them, thanks.
Post by Georg Bauhaus
Post by Simon Willcocks
I also trust that since you want this style of expression,
there is no point in discussing it.
I don't think it's helpful to dismiss someone in that way; it's too easily
used by someone who has already made up their own mind.
a new language feature is to be defended, exhibit all motives.
Risk some impoliteness.
OK, and reading the document you referenced below (I wish I could write so
clearly) it seems to me that a large proportion of the syntax decision is
due to (non-Scoop) multi- threading matters, which I hadn't been
considering.

Ignoring void safety, for the moment, it doesn't appear to be all that much
of a step forwards, though:

lock exp as o then
-- o is always the same object, OK.
if o.x = 4 then
if o.x = 12 then
-- This could still happen, I think
end
end
end

[snip the syntax; I get it, I prefer your syntax]
Post by Georg Bauhaus
(AFAIU, the semantics of check may have changed a bit, but the
spirit, too? Assume the thing to be attached, and have quality
assurance fix the error otherwise; "check" still is not "if"
and can be turned off, once you trust your attachments. Correct?)
I suppose so; it used to be that nothing would happen between the "check"
and the "end", if checks were turned off, now you've still got a compound
statement that will be run. OK, so check-then is more of a shorthand for
if-then-else-raise.

To me, it feels a lot like when Scoop started making preconditions into
control flow constructs. It doesn't quite fit.
Post by Georg Bauhaus
Post by Simon Willcocks
There was a rather nice construct suggested a while ago, where you could
select o -- an instance of some superclass of E
when E
o.some_e_function -- you get to use the same name!
when NULL
-- o = Void, now what?
end
I liked that!
Note how this does not have the placement issue! ;-)
It's quite clearly a language construct rather than a function, though.
Incidentally, it could include multiple when-parts and an else part.

(What if you could and the types?

when NUMERIC and COMPARABLE ...).
Post by Georg Bauhaus
[1] Avoid a Void: The eradication of null dereferencing
http://docs.eiffel.com/sites/docs.eiffel.com/files/void-safe-eiffel.pdf
--
ROLF - The RISC OS Look and Feel on Linux.
http://ro-lookandfeel.blogspot.com/
http://sourceforge.net/projects/ro-lf/
Helmut
2010-10-18 15:20:46 UTC
Permalink
Let me try to summarize the points raised with respect to void safety:

The currently proposed syntax (1) is

check
attached a as a_att
then
a_att.do_something
end

The new proposal (2) to do exactly the same is

a.attached.do_something


In non void safe Eiffel you would write (3)

a.do_something

The syntax (2) has been proposed, because (1) introduces a new
variable and is a little bit clumsy just to express the fact that the
programmer wants to assert that entity `a' is attached and features
can be called on it without any risk of a void target call.

The syntax (2) has been critized for not highlighting enough the fact
that the programmer is making an assertion. The main line of the
critique is that `a.attached' reads like a normal feature call unless
you have a syntax highlighter (or the reader has his syntax
highlighter hardwirded in his eyes :-) ). Even if I proposed syntax
(2) and my role is to defend it (as Georg said) I must admit that
there is a point here.

Simon has made the proposal (4)

a?do_something

and Georg used a check mark to better highlight the difference between
the implicit assertion and a normal feature call. The disadavantage of
these operator symbols: It is not easy to express the equivalent of
`a.attached{T}.do_something' and it is not in the usual keyword driven
Eiffel style which does not or nearly not use operator symbols to
express other things as unary or binary operations.

In order to make the syntax more different from a normal feature call
I could imagine to write

a.is attached.do_something -- (5)
a.is attached{T}.do_something

or

a.check attached.do_something -- (6)
a.check attached{T}.do_something

or

attached(a).do_something -- (7)
attached{T}(a).do_something

However I think the alternatives are not very pleasing to the eye.
Maybe somebody can come up with a more elegant syntax which avoids the
extra variable.

But in my opinion the change from non void safe Eiffel

a.do_something

to the ISE proposed construct

check
attached a as a_att
then
a_att.do_something
end

does more to obscure matters (because it introduces a lot of clutter)
than making it clearer. Recall that we discuss the situation where the
programmer wants to express that he is sure that the expression `a' is
attached or is attached to an object of type `T'.

Regards
Helmut
Simon Willcocks
2010-10-18 21:02:07 UTC
Permalink
In message <a768af06-fc83-4653-b80f-***@d17g2000yqm.googlegroups.com>
Helmut <***@gmx.net> wrote:

[snip summary]
Post by Helmut
The syntax (2) has been critized for not highlighting enough the fact
that the programmer is making an assertion.
Having read the void-safety document, we should note that there is
additional functionality in the check-then (as well as the if-then)
construct to do with threading, although I think it's flawed.
Post by Helmut
The main line of the
critique is that `a.attached' reads like a normal feature call unless
you have a syntax highlighter (or the reader has his syntax
highlighter hardwirded in his eyes :-) ). Even if I proposed syntax
(2) and my role is to defend it (as Georg said) I must admit that
there is a point here.
Simon has made the proposal (4)
a?do_something
and Georg used a check mark to better highlight the difference between
the implicit assertion and a normal feature call. The disadavantage of
these operator symbols: It is not easy to express the equivalent of
`a.attached{T}.do_something' and it is not in the usual keyword driven
Eiffel style which does not or nearly not use operator symbols to
express other things as unary or binary operations.
The Eiffel style used not to have the array access operator, either, but now
array[i] is used instead of array.item(i).

Could you keep the verbose version for downcasts (and making local copies of
attributes)?
Post by Helmut
In order to make the syntax more different from a normal feature call
I could imagine to write
a.is attached.do_something -- (5)
a.is attached{T}.do_something
or
a.check attached.do_something -- (6)
a.check attached{T}.do_something
or
attached(a).do_something -- (7)
attached{T}(a).do_something
However I think the alternatives are not very pleasing to the eye.
I don't like the way the spaces in 5 & 6 separate the target from the call.
I can't see any advantage of number 7 over the original suggestion (which
looked neater).
Post by Helmut
Maybe somebody can come up with a more elegant syntax which avoids the
extra variable.
Well, to avoid the extra variable /name/, the select by type construct could
be used to:

* perform downcasts,
* void checking (don't include a NULL check/else part and it should raise an
exception if it is Void), and
* keep a copy of any reference to an attribute.

One downside is it can only be used to select the type of an object
reference, not an expression, although I suppose the 'as' overloading could
work:

select mailbox.current as object
when BILL
object.bill_thing
when MAGAZINE
object.remove_loose_adverts
when NULL
raise ...
else
raise ...
end

The other, and potentially trickier, problem is that if the object's type
multiply inherits from both BILL and MAGAZINE...

Or, how about simply:

attach a -- only this line can raise an exception

-- from this point on in this block, a can be used as attached type
-- (and possibly not re-read, if it's an attribute)
x := a.attribute
a.frozen_feature( 10 )
a.do_something_else

Also, "attach exp as a", "attach {T} exp as a"...?

OK, it's a lot like the check statement, without an end, but there's one
clear point where an exception could occur. I guess there are potentially
several with a Void reference; it might not fail on an attribute read, or a
call to a frozen feature but only fail on a polymorphic call (or, worse, on
a call on x, much later on).
Post by Helmut
But in my opinion the change from non void safe Eiffel
a.do_something
to the ISE proposed construct
check
attached a as a_att
then
a_att.do_something
end
does more to obscure matters (because it introduces a lot of clutter)
than making it clearer. Recall that we discuss the situation where the
programmer wants to express that he is sure that the expression `a' is
attached or is attached to an object of type `T'.
I think your original solution (which could simply be a feature of ANY) is a
reasonable shortcut for this simple case, and it wouldn't involve making any
language change. Maybe you should wait and see how frequently it's actually
needed.

Cheers,
Simon
--
ROLF - The RISC OS Look and Feel on Linux.
http://ro-lookandfeel.blogspot.com/
http://sourceforge.net/projects/ro-lf/
Georg Bauhaus
2010-10-19 09:27:47 UTC
Permalink
Post by Helmut
In order to make the syntax more different from a normal feature call
I could imagine to write
a.is attached.do_something -- (5)
a.is attached{T}.do_something
or
a.check attached.do_something -- (6)
a.check attached{T}.do_something
or
attached(a).do_something -- (7)
attached{T}(a).do_something
However I think the alternatives are not very pleasing to the eye.
Maybe somebody can come up with a more elegant syntax which avoids the
extra variable.
I'd like to throw in another possible requirement: multiplicity,
first of variables (r1), then of tests (r2). Multiplicity might
make syntax appear in a different light.

(r1) Programs may have, in whichever syntax,

a <attached...> do_something
b <attached...> do_something_else

So <attached...> will pile up when there are many variables.
Doesn't seem terrible to me, but it seems possible to say that
many occurrences of "attached inline" defeats the purpose. The
"clutter" of explicit scope bracketing is replaced with multiple
occurrences of "attached" so that a growing number of the latter
will reduce the "savings" when avoiding a full check ... then ...
end (since the proportion of these three words in the total
text decreases).

In addition, is it possible for `b' and `a' to occur in
`do_something' and `do_something_else', respectively?
(Which reminds me of MLs "and-ed" function definitions.)

Again, then, scoping rules are needed. What is the extent of
<attached...>? When is it evaluated/determined/called?
I guess this is the scope of object tests, then.
(Or similar to Java's rule for final variables.)


(r2) What is the likelihood of a sequence of statements
such as these:

a <attached ...> do_something
blah
a <attached ...> do_something -- or do_something_else

(Assuming `a' is `some_object.some_feature', maybe.)

One issue is that some setter in `blah' can have an
effect on `a'. (Can it?).

Another issue is that concurrent objects can change the
status of `a'.

Will "total locking" (like Simon's lock) be good enough? The
programmer might actually want `a' to be modifiable between the
first and third line of the above example. (`a' is not stable,
then, IIUC.)

When there are two objects, `a' and `b', and only one should
be locked, will common scoping achieve this?


I'm not sure yet that any of this is elegant, or can be made
elegant. The whole language theory has too many ifs and whens
for my taste. "Check" or any variation thereof seems to spoil
simplicity, for a start.

Maybe we should try to avoid the billion-dollar mistake by
trying for an Eiffel that has no Void in the first place?


Arguments similar to the above will, I think, apply to Simon's
select construct. What is it going to look like if there are
two variables that need to be checked?


Georg

Martin Piskernig
2010-10-15 10:45:56 UTC
Permalink
Post by Georg Bauhaus
Eiffel has covariant hierarchies because ...
... 25 years ago the implications for type safety and subtyping
were not understood very well. It was only later that the
object-oriented community recognized that covariant routine
arguments, covariant genericity (and covariant export
restrictions) violate subtyping.
Post by Georg Bauhaus
and not because contra-variance has certain technical benefits.
I wouldn't call statical type safety "certain technical benefits".
It is a crucial property of statically typed programming languages,
which Eiffel is lacking.

Martin
Loading...