"Recent" language changes and "old" IDE

91 views
Skip to first unread message

Ulrich W.

unread,
May 12, 2020, 2:54:40 AM5/12/20
to Eiffel Users
When I started to learn Eiffel, it was "Eiffel 2" with good arguments why things were as they were.
Then I learned "Eiffel 3" with good arguments why things were changed from"Eiffel 2"...
As an occasional Eiffel user, I find that my old programs don't compile any more with the recent compiler as the language changes over and over.
With the goal of Eiffel to build large stable libraries of software, such continuous change is counter-productive (IMHO).
Today I just want to give the example of the loop variant which formerly was like:
            from
                row := 0
            variant
                3 - row
            until
                row > 2
            loop
                -- ...
                row := row + 1
            end

(Old IDE would add an "end comment" like "end -- loop" while current IDEs actively remove such comments)
The argument was that loop variant and invariant should be placed before "loop" as they have to be valid for every iteration.
Today's compiler wants to have it at the end. The IDE can also do a lot of fancy things, but copying a diagnostic message to the clipboard is still in the far future it seems.

Another thing I'm wondering is that Eiffel has validity rules for a long time, but syntax errors are still very generic "Syntax Errors". Why not mention a concrete syntax production that is violated?

Recently I also did a Java tour with Eclipse, and I wonder when reading a message like "Use the alias form of the infix routine." why Eclipse can suggest and perform a fix while estudio still can't. At that point I would have to lookup some language document to read how today's syntax works..

Another amazing warning is this:
        Warning code: VWMA(1)
...
Explicit array type ARRAY [ANY] may need to be specified.
Computed type of array elements STRING_8 differs from the type ANY of target array elements.

Why wouldn't any array of STINGS conform to an ARRAY[ANY]?

I'm not sure whether this once was legal, but I thought "effecting" was "redefine" in the past (because it's no longer deferred then):
VDRS(4)    Redefine subclause lists feature has, but the class effects it.



Alexander Kogtenkov

unread,
May 12, 2020, 4:05:40 AM5/12/20
to eiffel...@googlegroups.com
VWMA(1) is a safety warning for old projects. In the past, variable `a` after reattachment
 
   a := <<"a", "b", "c">>
 
could be attached to an object of type ARRAY [ANY], ARRAY [COMPARABLE], ARRAY [HASHABLE], etc. depending on the type of the variable itself. And it was the intended behavior. Nowadays, the type of the object does not depend on the type of the target of reattachment, it is the same all the time.
 
So, if in the code you did rely on the old behavior, you can update it to become
 
   a := {ARRAY [ANY]} <<"a", "b", "c">>
 
and, I believe, the code can be updated automatically.
 
If the code does not rely on the old behavior, and you are fine with getting ARRAY [STRING] instead of ARRAY [ANY], in the project setting dialog, turn off "Missing manifest array type" warning.
 
Alexander Kogtenkov
 
 
Ulrich W. <ulrich...@rz.uni-regensburg.de>:

Bertrand Meyer

unread,
May 13, 2020, 9:13:21 AM5/13/20
to eiffel...@googlegroups.com, me...@inf.ethz.ch

First, congratulations for coming back to Eiffel.

 

There will be answers on specific points.

 

One of them: ``I thought "effecting" was "redefine" in the past’’. No change here. The terminology has been the same for as far as I can remember: you “effect” a deferred feature by making it “effective” (no longer deferred, i.e. provided with an implementation). If you want to change the implementation of a routine inherited as effective, you “redefine” it. “Redeclaration” covers both effecting and redefinition. Eiffel uses precise terminology. I realize it may look strange to people groomed in other languages, but I am not aware of any other terminology that is consistent and covers all the cases.

 

Another one, regarding the place of invariant and variant clauses for loops. (Congratulations for using them, by the way; not everyone does. Also by the way, with language changes and particularly compact forms of quantifiers, it becomes ever more realistic to write extensive, powerful loop invariants, such as those of our loop algorithms survey.) The original order seemed obvious but the reasoning behind moving clauses is that the invariant should be next to the exit condition, since their conjunction yields the loop’s effect. The variant, for its part, is there to allay concerns about termination so it is appropriate to have it come last.

 

Regarding backward compatibility: this is an issue to which the team devotes considerable time and discussion. In general the progression is, in successive releases: provide a new facility as an option that programmers have to turn on; turn it on by default, still accepting the old form; start flagging the old form through warnings. Possibly, as a last stage, reject the old form. That last stage may be viewed as a needless nuisance; indeed in many cases we do not bother and continue supporting old idioms. But there are exceptions: when the two variants conflict; and when we fear that supporting both forever would be too much of a nuisance for the compiler (its code should not turn into a living record of the language evolution).

 

Eiffel constructs have always come, as you point out, with justifications of why they are the way they are. In general these justifications remain. The language changes are typically of four kinds: elevation of the level of abstraction (agents); elevation of program reliability (void safety); introduction of more compact synonyms for special cases of constructs in common cases (short forms of quantifiers and loops); integrating technology advances (Unicode). In all those cases the old justifications remain. The fifth kind -- recognizing that something was designed wrongly, and fixing it --  does arise but is rare.

 

We strive to make the evolution path smooth, but it is true that this smoothness assumes that people adapt regularly. From one version to the next the transition is usually not too hard. But if you do a Rip van Winkle, going to sleep then coming back after 20 years or even just 5, you will probably need a few tweaks to make your code work again. I have done this a few times (not going to sleep, but resurrecting old code) found the process very reasonable.

 

We live in a fast-changing world and an even faster-changing industry. It would be surprising that the Eiffel language alone remained unchanged, a monument of perfection.

 

-- BM

--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/eiffel-users/8d3030ce-5e57-4a95-99b1-b73b2921e7ea%40googlegroups.com.

Larry Rix

unread,
May 13, 2020, 10:20:47 AM5/13/20
to Eiffel Users
While being mentored by some very fine folks with Eiffel Software on how to work with Eiffel, we developed a bit of a "coding process" that we used to help ensure we were as complete as possible.

One of these processes was what I referred to (and still do) as—"putting on my contracting hat".

I literally back away from my code in terms of coding and implementing and I focus entirely on writing contracts in all of my "fresh" code. One of the points-of-focus is looking for loops and writing their contracts (invariants). It is an overall assessment of the "health" of each loop, where very critical and direct thought is given to "why-is-this-here" and "how-can-we-ensure-correctness"?

Like Dr. Meyer, I am delighted to become aware of another engineer taking good advantage of the correctness tools available in Eiffel. I merely write this to offer you one way of "baking in" focused and deliberate use of Design by Contract.

Finally—I find that by putting on my "contracting hat" that I end up discovering bugs I did not know were present in the code. It is here that I tend to follow the TDD (Test Driven Development) paradigm (loosely)—where—the added contract exposes the bug and I then write an appropriate "test" (using Auto-test facilities of Eiffel) to expose the error and its correction (until the contract is satisfied, whereby the test is satisfied).

On Wednesday, May 13, 2020 at 9:13:21 AM UTC-4, Bertrand Meyer wrote:

Another one, regarding the place of invariant and variant clauses for loops. (Congratulations for using them, by the way; not everyone does. ...

r...@amalasoft.com

unread,
May 13, 2020, 11:37:57 AM5/13/20
to eiffel...@googlegroups.com
I believe Larry is, if anything, under-selling the value of his process.  The contracting hat, and a contracting eye are hugely valuable and, in the end, save overall development time while ensure higher quality software.

When dealing with any language, I try to follow the 4 I's model (in the spirit of the contracting hat).  Simply put, the 4 'I's are execute in order:

Identify       (good naming; massaging the model, etc.)
Intent         (comment the code first, making clear its INTENT, and NOT paraphrasing its content)
Instrument  (contracts and then in-logic checks)
Implement  (the rest of the coding effort)

I have found this model effective, but especially so when dealing with remote teams and subcontractors.  The latter should come as no surprise.  Having your contracts in place enables you to farm out the implementation and have the necessary checks in place before (and after) implementation.  This helps drive meaningful testing.

Eiffel makes all of this not only possible, but (with practice) almost second nature.

R
--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.

Woland's Cat

unread,
May 13, 2020, 12:05:09 PM5/13/20
to eiffel...@googlegroups.com
Roger,

that is a very nicely stated pedagogic device. The 'intent' is especially important. As an anti-pattern example, the EV2 classes are full of comments that tell one nothing, and only restate what one can see from the code... (I don't say this just to casually criticise; it's worth iusing EV2 for a while to see what the effect of this practice is, and it helps to understand why the intent matters).

- thomas


On 13/05/2020 16:37, r...@amalasoft.com wrote:
I believe Larry is, if anything, under-selling the value of his process.  The contracting hat, and a contracting eye are hugely valuable and, in the end, save overall development time while ensure higher quality software.

Identify       (good naming; massaging the model, etc.)
Intent         (comment the code first, making clear its INTENT, and NOT paraphrasing its content)
Instrument  (contracts and then in-logic checks)
Implement  (the rest of the coding effort)

I have found this model effective, but especially so when dealing with remote teams and subcontractors.  The latter should come as no surprise.  Having your contracts in place enables you to farm out the implementation and have the necessary checks in place before (and after) implementation.  This helps drive meaningful testing.

Eiffel makes all of this not only possible, but (with practice) almost second nature.

Ulrich W.

unread,
May 13, 2020, 3:57:41 PM5/13/20
to Eiffel Users
I don't quite understand: Isn't <<"a", "b", "c">> an ARRAY[STRING] (which conforms to ARRAY[ANY])? So why should I need to "cast" the type?


Am Dienstag, 12. Mai 2020 10:05:40 UTC+2 schrieb Alexander Kogtenkov:
VWMA(1) is a safety warning for old projects. In the past, variable `a` after reattachment
 
   a := <<"a", "b", "c">>
 
could be attached to an object of type ARRAY [ANY], ARRAY [COMPARABLE], ARRAY [HASHABLE], etc. depending on the type of the variable itself. And it was the intended behavior. Nowadays, the type of the object does not depend on the type of the target of reattachment, it is the same all the time.
 
So, if in the code you did rely on the old behavior, you can update it to become
 
   a := {ARRAY [ANY]} <<"a", "b", "c">>
 
and, I believe, the code can be updated automatically.
 
If the code does not rely on the old behavior, and you are fine with getting ARRAY [STRING] instead of ARRAY [ANY], in the project setting dialog, turn off "Missing manifest array type" warning.
 
Alexander Kogtenkov
 
 
Another amazing warning is this:
        Warning code: VWMA(1)
...
Explicit array type ARRAY [ANY] may need to be specified.
Computed type of array elements STRING_8 differs from the type ANY of target array elements.
 
Why wouldn't any array of STRINGS conform to an ARRAY[ANY]?
 

Ulrich W.

unread,
May 13, 2020, 4:38:09 PM5/13/20
to Eiffel Users
Dear BM (I hope it's OK to use that shortcut),

I appreciate the time you took to explain. The thing with VDRS(4) is that my code compiled without problem in Eiffel_18.01, but in Eiffel_19.05 it's an error now. Wouldn't it be much less painful if it were a warning? I mean: The compiler knows quite well what the issue is; why be so picky? (Syntax was set to "transitional")

Specifically the issue is "redefine" of is_less from COMPARABLE...
(Let me apologize if my memory of proper Eiffel terms faded with the years)

On loop variants: It really triggered the syntax anarchist in me reading the suggested article:
1 from
2     Init
3 invariant
4     Inv
5 until
6     Exit
7 variant
8     Var
9 loop
10    Body
11 end

Why not move "variant" inside the body changing the semantics roughly like this:

1 from
2     Init
3 invariant
4     Inv
5 until
6     Exit
7 loop
8     Body
9     variant
10        code_taht_ensures_the_variant
11     ensure
12         Var
13     end
14 end

So "variant ... end" will no longer be optional, but frame the code that ensures the loop variant (which is stated in the "ensure" part that is optional itself). ;-)

On supporting old idioms: Once I wrote a C program, later I converted it to C++. A few years later I wanted to compile that C++ program with a newer compiler and library, finding that some essential library function was no longer available. Since then I avoided C++ very much. I admit that I have programs that are older than 25 years, and some still work. And here's the power of it: Instead of spending your time with keeping the old program running with today's tools, you can spend your time actually improving the code. I guess that was the original idea behind Eiffel, but I find myself spending quite some time getting my older systems compile with recent IDE.

On the "Rip van Winkle": If you are heading for the "absolute truth" (like in the sense of mathematics: What was proven true in the past can't be wrong in the future), there can't be incompatible changes unless the design was wrong anyway.
And obviously wrong designs are a bad starting point... ;-)

Likewise I don't like that "agile hype": If you are in need of constant change, it's just because you did it wrong the last time.
I'm much more a fan of "doing it right, right from the beginning".
Years ago I had an interesting insight visiting an ancient place: The Celts could put stones upon each other some thousand years ago so that rain wouldn't go inside such a building. Today's architects still build "flat roofs" that absolutely fail to keep the water outside the building... (In my school they had marked the places on the floor where to but the buckets when it's raining...) Is that progress?

Enrico Nardelli

unread,
May 14, 2020, 4:18:17 AM5/14/20
to Eiffel Users
I would like to reinforce Ulrich's request on the issue of compiler feedback on "Syntax Errors".

Above at all in a teaching context, where I'm using Eiffel since many years, students could be helped a great lot more.

Not that I do not understand the pedagogical value of discovering on one's own the motivation of errors, but - as Ulrich pointed out - the feeling one gets in the comparison of estudio to other IDEs is not encouraging its use.

Thanks, Enrico

Chris Tillman

unread,
May 14, 2020, 5:11:07 AM5/14/20
to eiffel...@googlegroups.com
It's surprisingly helpful even if just told the syntax error is "near" some part of the source. Often it's missing parens, quotes, or syntax parts, for which the compiler would have an expected location and could relate that.

--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.


--
Chris Tillman
Developer

Larry Rix

unread,
May 14, 2020, 3:50:37 PM5/14/20
to Eiffel Users
Here is such an error—that is—a missing parenthesis.

1 Syntax Error Syntax error at line 45. EL_DATA_SEGMENT (project) 45, 3

Syntax error at line 45 in class EL_DATA_SEGMENT

            segment_as_row (a_data, a_row
        ensure
--------^
            valid_count: segments.count = old segments.count + 1

The syntax error is a missing closing parenthesis. The compiler is indicating the location where its L->R look-ahead parser finally realized it was never going to find a closing parenthesis for the production and it may even have detected it was dealing with a keyword ("ensure") as well. Regardless of the fine detail, the compiler stopped and is pointing at the last location in the parsing stream.

The syntax error is not precisely on line #45, but on line #44, but the compiler finally detected the syntax error as it was parsing on line #45.

I do not think it reasonable for any compiler to be expected to indicate the precise location. In this case—it is near enough.

However—I do wonder if the compiler could actually indicate what it was looking for (e.g. a closing parenthesis). It does seem quite obvious that the compiler did have an unmet expectation but blandly labels the matter with a generic "syntax error".

Nevertheless—in all my years using Eiffel I have NEVER found the syntax errors to be very difficult to read. So, even as I point out the matter in the paragraph above, I find it to be quite trivial and of little value in the grander scheme. As for teaching it—I have now had the privilege of teaching quite a few people and I have NEVER had them complain. This is especially true when I teach them HOW to read the errors and to actually link those errors back to the ECMA specification. The errors presented by the Eiffel compiler and Eiffel Studio are quite good and specific, even offering very truthful advice on how to resolve them. Forgive me if this seems a harsh or hard response, but this is my experience. I find that it is far easier to nit-pick, which is to say—strain at gnats while swallowing camels. I prefer focusing on the camels first and then working my way down the food chain to the gnats and wondering if I will even care when I get there. That just my little ole' opinion and ought not to be considered as guiding or settling to anyone else's conscience in the matter.


Kindest regards,

Larry

Larry Rix

unread,
May 14, 2020, 4:01:29 PM5/14/20
to Eiffel Users
Removing the opening parenthesis from the other side of the feature call is equally revealing, especially in context of the missing closing parenthesis example above.

1 Syntax Error Syntax error at line 44. EL_DATA_SEGMENT (project) 44, 25
Syntax error at line 44 in class EL_DATA_SEGMENT

        do
            segment_as_row a_data, a_row)
---------------------------------^
        ensure

Here—the compiler complains about the proper line number #44 because it is in the middle of parsing that line when its L-R look-ahead parser finally fails.

In this case, the pointer ("^") is actually pointing PRECISELY where the compilers expectations failed to be met. It was looking for NOTHING MORE than the opening parenthesis. It looked ahead to the "a" character, which trigger the "generic" (e.g. "bland") syntax error.

Could the compiler error be more specific and tell you that it was looking for an opening parenthesis? Of course! However, are we so unfamiliar with Eiffel code contracts that we TRULY need or require something beyond "syntax error" and a pointer?

Yes—an utter novice will (at first) perhaps be stymied by this. BUT—that is what learning is all about. I my little old opinion, we clearly have a gnat to strain at for an extreme edge-case of the "blatant novice". How much energy do we really need on such matters? I think there are more than enough camels to give attention to—like good design, expanding the reach of Eiffel through C API wrapping, and a whole host of other very important matters.

Kindest regards,

Larry 

Colin Adams

unread,
May 15, 2020, 1:10:09 AM5/15/20
to Eiffel Users Group
It is very reasonable to expect the compiler to report what it was expecting, and to be more precise at the location. I remember the Rexx language, where the standard prescribed the exact error 
message for each type of syntax error. It is just a matter of writing the grammar accurately.

I have often got stuck for a long time in puzzling out what the syntax error was supposed to be.

--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.

Larry Rix

unread,
May 15, 2020, 9:17:21 AM5/15/20
to Eiffel Users
Hey Collin!


On Friday, May 15, 2020 at 1:10:09 AM UTC-4, colinpauladams wrote:
It is very reasonable to expect the compiler to report what it was expecting, and to be more precise at the location. I remember the Rexx language, where the standard prescribed the exact error 
message for each type of syntax error. It is just a matter of writing the grammar accurately.

I have often got stuck for a long time in puzzling out what the syntax error was supposed to be.

I agree that it is reasonable. I am not sure how to think with this as a compiler-designer with limited resources. I don't know what such changes to the error reporting system of the Eiffel Compiler look like and if in light of that knowledge those changes are still "reasonable" (e.g. we-can-deliver-a-lot-of-bang-with-very-little-effort).

Here is that same "error" but slightly changed:

1 Syntax Error Syntax error at line 47. EL_DATA_SEGMENT (project) 47, 34
 
Syntax error at line 47 in class EL_DATA_SEGMENT


       
do
            segment_as_row
(a_data, a_row b)
 
------------------------------------------^
       
ensure

So—now the expectation with either a "," (comma character), or a closing parenthesis. For me, as a human being with a supercomputer-level brain, this is pretty direct and easy to spot. From my point of view, this activity of identifying the error and the fix is pretty "reasonable". For a relatively stupid computer program (compared to our human brains), the task may or may not be "reasonable". I do understand about getting stuck or stymied on generic syntax error reports where the error is non-obvious. I have encountered them myself. However, as tough as that is—I still lack the knowledge of a compiler designer (more precisely an Eiffel Compiler Designer) to understand what is and is not "reasonable". Kindest regards, Larry
 

Rosivaldo Fernandes Alves

unread,
May 15, 2020, 1:25:58 PM5/15/20
to eiffel...@googlegroups.com
My two cents: I was amazed that ES was not precise about syntax errors.
Every single programming language a had used before had compilers able
to give descriptive syntax errors. As time went by, I found myself being
able to figure out syntax errors with minimal effort. And I stopped
worrying about the matter.

Regards,

Rosivaldo.

Em 15/05/2020 02:09, Colin Adams escreveu:
> It is very reasonable to expect the compiler to report what it was
> expecting, and to be more precise at the location. I remember the Rexx
> language, where the standard prescribed the exact error
> message for each type of syntax error. It is just a matter of writing
> the grammar accurately.
>
> I have often got stuck for a long time in puzzling out what the syntax
> error was supposed to be.
>
> (...)

Anthony W

unread,
May 15, 2020, 6:25:45 PM5/15/20
to eiffel...@googlegroups.com
In my experience, the more often I work in a particular language, the more quickly and easily I can spot syntax (and logical) errors. I don't work with Eiffel on a regular basis - as much as I would love to - and so when I get that opportunity, there's always a re-familiarization period that occurs.

Having more verbose syntax error messages helps to reduce that time. More importantly, it helps to reduce the mental "gear switching effort" that occurs when you transition from trying to solve a domain problem to debugging and then back again.

That being said, there comes a point where I can spot most of the syntax errors without any comments from a compiler. Even so, I *still* think it would be a QOL enhancement to expand the error messages. I'm barely familiar with building a compiler, but to me it seems if the code can be parsed, and the parser logic fails, it can certainly explain what's missing. Just add more descriptive output strings (I know! - I realize there's more work to it than that - that's just my 32k foot design input :) )

Anthony

--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.

Ulrich Windl

unread,
May 18, 2020, 2:06:29 AM5/18/20
to eiffel...@googlegroups.com
>>> Anthony W <awei...@gmail.com> schrieb am 16.05.2020 um 00:25 in Nachricht
<19991_1589581546_5EBF16E9_19991_614_1_CAG+gLBiDVLMw0eGFQDJuPUAbSSm4nnQCBFL1ZmKe
DX_c...@mail.gmail.com>:
> In my experience, the more often I work in a particular language, the more
> quickly and easily I can spot syntax (and logical) errors. I don't work
> with Eiffel on a regular basis - as much as I would love to - and so when I
> get that opportunity, there's always a re-familiarization period that
> occurs.
>
> Having more verbose syntax error messages helps to reduce that time. More
> importantly, it helps to reduce the mental "gear switching effort" that
> occurs when you transition from trying to solve a domain problem to
> debugging and then back again.
>
> That being said, there comes a point where I can spot most of the syntax
> errors without any comments from a compiler. Even so, I *still* think it
> would be a QOL enhancement to expand the error messages. I'm barely
> familiar with building a compiler, but to me it seems if the code can be
> parsed, and the parser logic fails, it can certainly explain what's
> missing. Just add more descriptive output strings (I know! - I realize
> there's more work to it than that - that's just my 32k foot design input :)
> )

Another important aspect is language design, specifically: syntax design. A language designed properly can help the parser a lot to give reasonable hints. Some languages do not have this property. For example a missing semicolon in Perl can trigger tens of odd error messages, but Perl does not stop after the first error being detected...

>
> Anthony
>


Bertrand Meyer

unread,
May 25, 2020, 9:54:19 AM5/25/20
to Bertran...@inf.ethz.ch, eiffel...@googlegroups.com, me...@inf.ethz.ch

Revisiting the point about the order of clauses: I am no longer sure what the fuss was about since this is a case in which we *did* ensure backward compatibility. You can use the old order (variant clause immediately after the invariant) as well as the new one. If you used the old order you will get a syntax warning (only if you enable these warnings – we don’t want by default to overload users with warnings).

 

Did you actually try it?

 

It seems to me that in that case we did exactly the right thing – move forward with a more logical syntax, but maintain compatibility for existing code.

 

-- BM

Reply all
Reply to author
Forward
0 new messages