I'm thinking in sending the following proposal to the ARG, but I'd
like to present it here first to have more opinions about it
usefulness, and probably to refine it a bit with your comments...
It is based on a 2004 paper of Tony Hoare (from the book 'From Object-
orientation To Formal Methods') where he describes different types of
assertions used by (C/C++) developers in production code, including
this one:
SYMPLIFYING_ASSUMPTION (strlen(input) > MAX_PATH, "not yet checking
for overflow");
'SYMPLIFYING_ASSUMPTION' is a macro very similar to the C 'assert',
also checking at run-time a boolean condition and aborting the program
if it evaluates to false. But if an 'assert' is valid during the whole
life of the application, the 'SYMPLIFYING_ASSUMPTION' is used by the
programmer just *during the coding phase* to document those cases that
aren't coded yet (probably edge cases). The difference is when
compiling the program _not_ in debug mode (NDEBUG defined): the
'assert' macros are eliminated by the preprocessor whereas it is a
compilation error if any 'SYMPLIFYING_ASSUMPTION' remains in the
sources.
That is, a SYMPLIFYING_ASSUMPTION is like those 'TODO:' or 'FIXME:'
annotations used to remind the programmer what should be modified in
the code, but it is recognized by the compiler instead of being just a
comment, and therefore cannot be ignored by accident.
So the proposal whould be adding to the next Ada revision two new
pragmas:
pragma Assumption ([Check =>] boolean_expression[, [Message =>]
string_expression]);
pragma Assumption_Policy (policy_identifier); -- Error, Check
Which behave exactly like Assert and Assertion_Policy (also raising
Assertion_Error, but with a different message), except that by default
it is a compilation error to find any pragma Assumption in the sources
unless when explicitly allowed using a compilation flag or the 'Check'
policy.
Probably better names can be chosen for those pragmas, so feel free to
propose more adequate identifiers. Also, maybe in this case the
Message string should be required, anyway it is a documentation pragma
(in pragma Assert the second parameter is optional).
IMHO this pragma is not a complete replacement for the TODO or FIXME
comments, and in many cases it is better to code the whole
functionality at once than just the more common cases. However,
sometimes it will be a good approach to code just some cases
documenting the assumptions, run the testsuite (raising an exception
if any of those missing cases are triggered), and to code the rest in
the future. But now, even if you forget to add that code, the compiler
will remind you about those missing cases when trying to compile the
final executable (following the "programmers make faults" Ada
philosophy).
Do you think it is an useful addition to Ada 2015? Would you use this
feature? Do you know of any means to achieve the same effect in Ada
2005? Thanks
Cheers,
--
Santiago Urueña-Pascual
Technical University of Madrid (UPM)
This sounds much like pragma Debug together with the language
defined restriction No_Implementation_Pragmas to me.
-- Georg
Although in theory it is possible to achieve the same effects of
pragma Assumption using pragma Debug, it would be very awkward: it
doesn't receive a boolean condition but a subprogram call (the first
parameter is just to enable/disable it at run-time), so a new
procedure should be created to evaluate the desired condition, and
then raise an exception explicitly when false. This pragma is more
focused for execution logs.
Furthermore, pragma Debug is very similar to pragma Assert in the
sense that it can be left on production code during the whole life of
the application. So even if a programmer is willing to add so much
code for each assumption, she won't be able to use pragma Debug for
any other uses (probably she shouldn't use any other implementation
defined pragma at all).
Best regards,
http://www.adacore.com/wp-content/files/auto_update/gnat-unw-docs/html/gnat_rm_2.html
Currently GNAT has the following related pragmas, but none is close to
pragma Fixme or Assumption:
pragma Assert (boolean_EXPRESSION [, string_EXPRESSION]);
pragma Check (
[Name =>] Identifier,
[Check =>] Boolean_EXPRESSION
[, [Message =>] string_EXPRESSION] );
pragma Check_Name (check_name_IDENTIFIER);
pragma Check_Policy ([Name =>] Identifier, CHECK|IGNORE);
pragma Compile_Time_Error
(boolean_EXPRESSION, static_string_EXPRESSION);
pragma Compile_Time_Warning
(boolean_EXPRESSION, static_string_EXPRESSION);
pragma Debug ([CONDITION, ]PROCEDURE_CALL_WITHOUT_SEMICOLON);
pragma Debug_Policy (CHECK | IGNORE);
pragma Postcondition (
[Check =>] Boolean_Expression
[,[Message =>] String_Expression]);
pragma Precondition (
[Check =>] Boolean_Expression
[,[Message =>] String_Expression]);
Pragma Assert, Check (generalization of Assert), Debug, Postcondition
and Postcondition are evaluated at run-time, but are intended for the
whole life of the application. In contrast, pragma Compile_Time_Error
and Compile_Time_Warning are evaluated at compilation time (mainly to
detect assertion errors when instantiating a generic), so cannot be
equivalent to pragma Assumption.
Regards,
>> I've been using pragma Fixme; for this -- OK, won't fail in production
>> (unless you use GNAT & -gnatwe, treat warnings as errors, or your
>> compiler's equivalent).
>>
> Interesting, that's very close to this type of assertions (except
> that it doesn't document much, and it won't fail if any test tries
> to exercise the unimplemented code). Which compiler has that pragma?
It's a pragma that I made up and that the compiler ignores with a
warning .. while refactoring some code recently, I found myself using
pragma I_Dont_Believe_It (see British TV program "One Foot In The
Grave").
Just look at any C or C++ compilers except for a few simple "conditional
statement" every version has it own "conditional statements". Which makes
most of these older language compilers less desirable to use. That is one
reason we like and use Ada.
Second, the "Ada Language Maintainers" would have to agree to create
a simple "conditional compilation". And would it use "pragma"
statement or another new statement. At the earliest that would be included
in 2015 or better yet 2025.
Third, macros are apart of an advance "conditional compilation" which would
be added in 2025 or 2035. Which means is statement is too far into the
future for most people.
> pragma Assumption ([Check =3D>] boolean_expression[, [Message =3D>]
>Santiago Urue=F1a-Pascual
Cheers,
--
Santiago Urueña-Pascual
:-)
Interesting addition. But which one is more useful in your opinion,
pragma Fixme or Assumption (or both)?
'SYMPLIFYING_ASSUMPTION' is a macro very similar to the C 'assert', ...
In conpilers a "MACRO" is consider to be a "conditional compiling"
statement! This make what you were talking about, a matter for a
"conditional compiling" decision. Which allows Ada to lose it concept
of true portability. A bad idea for all.
In <68a2d09d-c49c-4a61...@t54g2000hsg.googlegroups.com>, =?ISO-8859-1?Q?Santiago_Urue=F1a?= <sur...@gmail.com> writes:
>> First, conditional compiling does not exist in the Ada Language and
>> should never exist because of the purpose of Ada to be portable.
>>
>Thanks for your interest in the topic, but this proposal has nothing
>to do with conditional compilation. Please, read again the original
>post. Thanks
>
>Cheers,
>
>--
>Santiago Urue=F1a-Pascual
> In conpilers a "MACRO" is consider to be a "conditional compiling"
> statement!
What makes you think so?
> In conpilers a "MACRO" is consider to be a "conditional compiling"
> statement!
>
Although macros and conditional compilation are done by the
preprocessor, they are very different (and orthogonal) concepts.
You can compare pragma Assumption with pragma Assert, which is
standard in Ada 2005. Do you think pragma Assert reduces Ada
portability?
--
Santiago Urueña-Pascual
>> It's a pragma that I made up and that the compiler ignores with a
>> warning .. while refactoring some code recently, I found myself
>> using pragma I_Dont_Believe_It (see British TV program "One Foot In
>> The Grave").
>
> :-)
>
> Interesting addition. But which one is more useful in your opinion,
> pragma Fixme or Assumption (or both)?
I'd certainly use Assumption is it was available. The other is just a
crude workround, of course, but has the advantage of being here now.
Does Ada need "pragma Assumption". No!
For GNAT Ada: You can use the
"pragma unimplemented_unit;"
or adding a routine to a package like the routine used in GNAT
Ada System.Interrupts Dummy package ("s-interr-dummy.adb")
-------------------
-- Unimplemented; --
-------------------
procedure Unimplemented is
begin
Ada.Exceptions.Raise_Exception
(Program_Error'Identity, "interrupts/signals not implemented");
raise Program_Error;
end Unimplemented;
Then call "Unimplemented;" where needed. and remove the call when
routine is corrected.
Or a simple way is to use specification and body packages. Compiling
works but binding and linking will cause and error. That can be
fixed by creating the routines that are used in the program. Once
routine works rename package or move routine to another file.
An example
--
-- Specification Package: TODO
--
package ToDo is
--
-- List of functions and procedures specification that need to
-- be written.
--
end ToDo ;
--
-- Procedure Test -- Main program procedure
--
with ToDo ;
use ToDo ;
procedure Test is
begin
--
-- Use routines that are in "ToDo" package where and when needed.
--
end Test ;
These examples shows simple reason why this concept was not inserted
in 2005 specification. Check the list of rejected Ada 2005 updates.
>Santiago Urue=F1a-Pascual
> -------------------
> -- Unimplemented; --
> -------------------
>
> procedure Unimplemented is
> begin
> Ada.Exceptions.Raise_Exception
> (Program_Error'Identity, "interrupts/signals not implemented");
> raise Program_Error;
> end Unimplemented;
>
> Then call "Unimplemented;" where needed. and remove the call when
> routine is corrected.
>
I also considered this approach (but of course the procedure was
called "Asumption" and it received a boolean parameter :-), but when
compiling the final binary you are again at risk of forgetting to
search for any remaining calls to that procedure or to remove its body
(people make that kind of mistakes all the time). Instead, with pragma
Assumption the compiler will warn you, anyway it is common practice to
have different compilations options for each development phase, and
unless that option is explicitly added the compiler will reject any
occurrence of that pragma.
> --
> -- Specification Package: TODO
> --
> package ToDo is
>
> --
> -- List of functions and procedures specification that need to
> -- be written.
> --
>
> end ToDo ;
>
I didn't considered that, but has the same problems as the procedure
Unimplemented
> Check the list of rejected Ada 2005 updates.
>
I did, and I was unable to find any related proposal
Cheers,
--
Santiago Urueña-Pascual
And maybe the pragma Assumption_Policy is a bad idea for the same
reasons: this pragma has preference over the compiler switches (at
least for gnat in the case of pragma Assert_Policy), so it is very
easy to forget to change the policy from "Check" to "Error"...
--
---------------------------------------------------------
J-P. Rosen (ro...@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr
Wouldn't a compilation configuration be a good place
for a partition-wide configuration pragma?
Project files typically have a Debug target and a
Production target.
And as for compiler allowing "--allow-unimplemented-units" this is
against the Ada RM. It might be possible to compile Ada without the
body for all routines But you must provide either a link (pragma Import)
or the body to all routines before binding and linking.
In <13aa4422-c478-478e...@k30g2000hse.googlegroups.com>, =?ISO-8859-1?Q?Santiago_Urue=F1a?= <sur...@gmail.com> writes:
>> So the proposal would be adding to the next Ada revision two new
>> pragmas:
>>
>> pragma Assumption ([Check =3D>] boolean_expression[,
>> [Message =3D>] string_expression]);
>> pragma Assumption_Policy (policy_identifier); -- Error, Check
>>
>I've been thinking more about it, and probably the compilers should be
>encouraged to choose a long switch name to reduce the chance of
>forgetting to remove that it in the final binary. For example, instead
>of (say) "-gnatap", choose something like "--allow-unimplemented-
>units".
>
>And maybe the pragma Assumption_Policy is a bad idea for the same
>reasons: this pragma has preference over the compiler switches (at
>least for gnat in the case of pragma Assert_Policy), so it is very
>easy to forget to change the policy from "Check" to "Error"...
>
>--
>Santiago Urue=F1a-Pascual
That's true. So the idea would have the compiler to reject any pragma
Assumption occurrence in the production target (the "final binary" I
said before), and explicitly ask for it using a compiler switch in the
debug target during coding and testing.
I don't get it. If you remove the package containing Unimplemented from the
program (as you should do in this case), any remaining references will be
caught by the compiler as undefined. I don't see how that is different from
some sort of compiler switch -- it's just as easy to forget changing that.
Anything that requires a change is a bad thing!
These days, "production" systems and "debugging" systems often are the
same -- computers are fast enough that there is rarely a need to remove the
debugging code. (And leaving it in can help technical support a lot,
especially when customers can't send a code sample for one reason or
another.) So anything that depends on a difference in building a system is
dubious in my view.
Moreover, I don't see anything that this feature would provide that is
really helpful. Our coding standard includes a structured comment:
-- **Temp: <explanation>
for anything that requires later work. I personally usually use "raise
Program_Error;" or a call to a routine defined for that purpose (the
Janus/Ada optimizer has a routine "Die(<reason>)" for instance) if code is
left out for any significant period. The structured comment allows future
finding of these areas if desired. But it isn't uncommon to decide to not
bother with implementing such things: if the case never happens, it's
probably a waste of time to implement it. In which case the comment and
"Die" may live for a long time.
Finally, as a pragma, there is nothing preventing an implementer from adding
it if it is found useful. There doesn't seem to be any compelling reason to
add it to the language in order to get it implemented. As such, I'd
recommend that such a proposal be filed as an AC (received no action).
If you can convince some implementers to implement it, *and* it proves
useful, *then* it might be considered for future standardization. But not
without something that cannot currently be done.
Randy Brukardt.
> I don't get it. If you remove the package containing Unimplemented from the
> program (as you should do in this case), any remaining references will be
> caught by the compiler as undefined.
I thought that, too, but then considered programmers
who wouldn't mind a "workaround":
"If that Simplifying_Assumption package is gone away,
stupid big IT organization, I'll roll my own.
I don't want their configuration handling to affect
my coding right now!"
This is not possible to do with a language defined pragma.
Once a pragma is used to express "preliminary implementation",
its language defined semantics will ensure that there is no
simple way to work around finishing your work.
No reference to HR, to quality control, performance control or
team leadership competence is needed.
With a pragma, language semantics can improve work semantics
and quality control, in line with Ada culture maybe.
(Programming discipline for free?)
I can remember too many IFs without completed ELSE, too many
notes about cases to be handled later that would inevitably
make a program confront Murphy's law.
Tools are helpful; if Simplifying_Assumption, a variation of
Assert, becomes language defined, there is a one button
solution to most of these problems.
It's iPhone usability at the development level .-)
> These days, "production" systems and "debugging" systems often are the
> same -- computers are fast enough that there is rarely a need to remove the
> debugging code. (And leaving it in can help technical support a lot,
> especially when customers can't send a code sample for one reason or
> another.) So anything that depends on a difference in building a system is
> dubious in my view.
>
I agree, and that's fine. In that case pragma Assumption would only
document that: whereas an Assert is (in theory) always true, a pragma
Assumption highlights that that code is not completely finished, and
that it is known that in some cases it will fail.
In both cases, when any Assertion exception is raised, that data
should be sent to the technical support (in fact, that's exactly what
Tony Hoare explains in the article). Probably there is no need to add
another exception when triggering a bad assumption, but it could be
added if somebody thinks that those cases should be handled
separately.
> Moreover, I don't see anything that this feature would provide that is
> really helpful. Our coding standard includes a structured comment:
> -- **Temp: <explanation>
> for anything that requires later work. I personally usually use "raise
> Program_Error;" or a call to a routine defined for that purpose (the
> Janus/Ada optimizer has a routine "Die(<reason>)" for instance) if code is
> left out for any significant period. The structured comment allows future
> finding of these areas if desired. But it isn't uncommon to decide to not
> bother with implementing such things: if the case never happens, it's
> probably a waste of time to implement it. In which case the comment and
> "Die" may live for a long time.
>
This pragma just reflects common software development processes,
adding support to the language to the incremental and iterative
schemes.
(BTW, they are not the same! see: http://www.stsc.hill.af.mil/crosstalk/2008/05/0805Cockburn.html
)
> Finally, as a pragma, there is nothing preventing an implementer from adding
> it if it is found useful. There doesn't seem to be any compelling reason to
> add it to the language in order to get it implemented. As such, I'd
> recommend that such a proposal be filed as an AC (received no action).
>
> If you can convince some implementers to implement it, *and* it proves
> useful, *then* it might be considered for future standardization. But not
> without something that cannot currently be done.
>
Thanks for the advice, I think that's the way to go!
--
Santiago Urueña Pascual
Totally agree ;-)
> Randy Brukardt wrote:
>
>> I don't get it. If you remove the package containing Unimplemented from the
>> program (as you should do in this case), any remaining references will be
>> caught by the compiler as undefined.
>
> I thought that, too, but then considered programmers
> who wouldn't mind a "workaround":
> "If that Simplifying_Assumption package is gone away,
> stupid big IT organization, I'll roll my own.
> I don't want their configuration handling to affect
> my coding right now!"
> This is not possible to do with a language defined pragma.
Yes, it is; just change the build script to pass the right compiler
option.
The only "fix" for actively malicious programmers is firing them.
--
-- Stephe
I can change the integration build script in SCM only in case I have
writing permissions.
OTOH, I can't invent, overload, or override a language
defined pragma; sure, a malicious programmer (MP?) can still replace
anything with something different. But let's assume programmers who
are interested in doing programming work and who would not work as
moles or as machinators, or as minimum effort maximum garbage coders.
Simplifying_Assumption is a concept. How is it best represented?
I think it is somewhat akin to Ada's case coverage rules. Maybe
going over the top, I could suggest
assume
Facts(Information);
begin
Machine.Run(Information);
end assume;
This should express that for the time being, Information covers
many cases, but some cases may not be Facts, expect an exception.
Thus Simplifying_Assumption is promoted to a new reserved word.
However, the purpose of Simplifying_Assumptions is really pragmatic,
geared towards program development by completing the cases, and
instructing the compiler. So a pragma might be fine.
So, should it be added to Ada? I don't know, that's why I'm asking
here: first to the Ada community, to know whether programmers think it
is useful, and after that to the ARG who will decide if it should be
added or not to the language. The first step wasn't bad: nobody of the
(few) people who replied said that he wouldn't use it (but a lot of
answers were more focused on achieving the same effects without adding
more features to the language). But I think I will follow Randy's
advice, creating a patch for the future GNAT GPL 2008 (let's see if it
is really easy to implement or not... :-) and distributing it here.
For Ada, there is very little in the form of trade-offs. This is
stated in the RM and the programmers that primarily use Ada likes
it that way, actually we wish it had no trade-offs, but that hard
to make it reality. But the "Ravenscar" concept does helps a great
deal.
Now, there are a lot of "C/C++" people who come to Ada and complain
that Ada wont let them create code their way, they want to dirty Ada
up like other languages, why should we or the Ada's RM let them.
Plus, the concepts of "Portability", "Compatibility" and others are
built into Ada and are stated in the RM. So, any change or patch that
destroys this should be looked as an attempt to "Kill Ada". Because
your patch to the compiler would allow people to violate the RM it
should be abandon. One reason is your patch could cause students in
classes to fail the course, causing the colleges to complain and stop
using Ada. Which will inturn make it harder for companies to use
Ada. Aka the "DEATH OF ADA" but that's what "C/C++"
programmers wants, the "DEATH OF ADA!"
All because you want to modify the language instead of learning and
use an alternative way. that the RM and Ada requires you to learn
and use.
And as for the
>> The only "fix" for actively malicious programmers is firing them.
I say that too nice. Put that programmer in JAIL for LIFE without
access to a computer or the internet!
>Santiago Urue=F1a-Pascual