What advantage does the end if statement in Ada provide over other languages
Asked Answered
C

3

5

Most other programming languages don't have an end if statement required at the end of conditional statements.

if boolean_expression then statement else statement

What advantage does including an end if provide Ada that other languages don't have?

if boolean_expression then statement else statement end if

I think it has something to do with branch prediction if the condition is true (skips the else portion of the code), but I'm not sure.

Correctitude answered 12/10, 2017 at 5:16 Comment(3)
As you can check on Rosetta code, all languages either use indentation to delimit if blocks, use characters (such as { and }) to delimit blocks, or have something equivalent to end if.Poignant
Branch prediction has nothing to do with it, it's just the Ada way to terminate a block.Anticlerical
In other languages where they use braces, for instance, if there are multiple nesting levels, you end up with a load of }'s and you might not be able to tell which brace ends which block, the top may be off screen. In Ada, "end if;" or "end if Label_Name;" you can easily tell by looking at what is being ended. Ada is all about readability.Silkaline
S
10

Consider a nested if, like this: if boolean_expression then if another_boolean_expression then statement else statement

Now, to which if statement does the else part belong?

end if resolves the issue (indented for clarity):

if boolean_expression then 
   if another_boolean_expression then
      statement 
   end if;
else
  statement 
end if;

or:

if boolean_expression then 
   if another_boolean_expression then
      statement
   else
      statement
   end if;
end if;
Statvolt answered 12/10, 2017 at 6:50 Comment(1)
Wikipedia on this problemSubtotal
E
4

TL;DR:

It carries no special advantage, but it is a necessary part of any language that allows block declarations.

Ada's method of block termination is very explicit, but that does not convey any particular advantage.

Discussion

As the others are indicating, it is simply Ada's method of block termination. The syntactic detail is not very important, but the semantics are critical.

Consider a few examples of how block termination is expressed in other languages:

  • Erlang and Prolog: The keyword end for lambdas and conditionals, the full-stop character . for function definitions, and , and ; for phrase segregation.
  • Python, YAML, "indented-mode" Haskell and RyuQ: Block termination is expressed with indentation (semantic whitespace).
  • Ruby and Elixir: Block termination is expressed with the keyword end. Very similar to Ada.
  • Algol and sh/Bash/Dash: Express block termination with a matching reversal of the initiating keyword. So if is terminated with fi, and case terminates with esac.
  • Rust, C, C++, D, Java, JavaScript/ECMA Script, etc.: All open using a keyword and an opening bracket { and close all blocks with a closing } which allows the block's closing token to be easily identified (by a relatively naive parser, not necessarily a human reader).
  • Lisp and friends: Generally speaking, everything is a list-form semantic expression and all evaluation blocks are opened with a ( (which essentially means "begin evaluation") while lists are opened with a '( (which essentially means "I'm a list, but skip evaluating me") and all are closed with a closing paren ).
  • XML, HTML, SGML, XSLT, and other waking nightmares: Each (possibly arbitrary) opening tag like <foo> is terminated by a matching tag with a closing slash indicator like </foo> (or sometimes just </>, which is slightly better for important reasons). Most variants of angle-bracket madness now support "self-closing" tags as well, where the closing slash can exist at the end of the opening tag as a shorthand, so an empty tag that is its own phrase like <foo></foo> can be shortened to <foo /> or sometimes <foo/> depending on what flavor of insanity it happens to be. (Obviously there are a few semantic black holes one can be sucked into with this sort of ambiguity.)

Etc...

As we can see, Ada's block termination expression isn't in any way odd -- it is just more explicit than the brackety languages (and slightly more explicit than Erlang and Prolog). Regardless, without resorting to GOTOs or other forms of explicit jump expression it is absolutely necessary to be able to define logical blocks and that means also having a clear way of terminating them. This is just Ada's way.

Addendum: A note on "blocks"

As flyx has kindly pointed out, there is an interesting distinction among statements, blocks, expressions, procedures, subroutines, and functions. Some languages have all of these, some have only functions and expressions, some have any arbitrary mix.

C (and its descendants) make a distinction between "statements" and "expressions", and in the case of a C-style block delimited by {} braces the language treats that "block" as a single statement. Meaning, it is not expected to return a value the way an expression would, it is expected that execution of the procedure represented by the statement itself will have some meaningful effect on the program.

So what does that mean in terms of syntax?

In Ada the if explicitly opens a block.

In C, however, an if doesn't open or declare anything at all -- it simply guards the next statement. So a one-line if in C is perfectly normal to see -- no brackets need be closed at all because none were opened. If, however, the statement following the if needs to be a multi-line statement (note that it is a bit unidiomatic in C to define functions for every multi-line statement).

if (x) {do_something();}

is the same as

if (x) do_something();

Look, Ma, no brackets!

The former is more common as most conditional branches are more than a single line.

This particular issue becomes a bit more cloudy (and now you actually do get into branch prediction issues) with the C ternary operator:

int opening_time = (day == SUNDAY) ? 12 : 9;

or Python's somewhat recently added ternary operator:

opening_time = 12 if day == 'sunday' else 9

An equivalent (in somewhat unidiomatic C):

int opening_time = 9;
if (day == SUNDAY) opening_time = 12;

And so on.

Here is where we get into understanding both some of the very early utility of un-named blocks of code, and how in some (but not all) languages they are treated as compound statements.

Etch answered 14/10, 2017 at 11:18 Comment(3)
Not the one who downvoted, but if you explain blocks, you should mention that in most languages that use {} for blocks, the if statement is defined as treating the (one) succeeding statement as the code that gets executed only when the condition is met. So when you want to execute multiple statements conditionally, you use a block as the statement following the if because a block is a statement. That's pretty different to Ada where the if statement automatically starts a block.Subtotal
@Subtotal Good point. There are no brackets involved in a one-line if in C and C-like languages at all -- and that indeed demands some explanation.Etch
Misses the point that qualifying end with the block type if, and/or a label, can help the compiler decide where a block terminator is missing. This isn't always decidable with curly brackets.Neuron
T
3

Ada language has been designed with concern to readability and to code defect prevention. So scope closing constructs are mandatory and correspond to scope opening constructs. When you have a long piece of code it would be easier to figure out what that closing entry does actually close.

procedure Foo is
begin
    if condition then 
    -------------------
    -- a lot of code...
    -------------------
    end if;
end Foo;

In contrast some other languages with different syntax may leave it up to developers whether to write additional comments to clarify closing entry purpose or whether to write closing entry at all (C++ example):

void
Foo(void)
{
    if(condition)
    {
    ///////////////////
    // a lot of code...
    ///////////////////
    } // if
} // Foo

Such code turns to be either less readable and potentially prone to scoping issues or requires extra efforts from the developer.

Thirza answered 15/10, 2017 at 14:45 Comment(1)
Yup, what I wrote above. Also, as you point out here, a lot other languages use comments after the } to explain what is being closed, what if you forget to put that in or your IDE doesn't do it for you? Ada enforces it.Silkaline

© 2022 - 2024 — McMap. All rights reserved.