Jump to page: 1 2 3
Thread overview
What is nothrow for?
Apr 25, 2008
Janice Caron
Apr 25, 2008
Walter Bright
Apr 25, 2008
Michel Fortin
Apr 25, 2008
janderson
Apr 25, 2008
Walter Bright
Apr 25, 2008
Frank Benoit
Apr 25, 2008
Frits van Bommel
Apr 25, 2008
Walter Bright
Apr 25, 2008
Yigal Chripun
Apr 25, 2008
janderson
Apr 25, 2008
Yigal Chripun
Apr 25, 2008
Walter Bright
Apr 25, 2008
Yigal Chripun
Apr 25, 2008
Janice Caron
Apr 25, 2008
Yigal Chripun
Apr 25, 2008
Janice Caron
Apr 25, 2008
Yigal Chripun
Apr 25, 2008
Walter Bright
Apr 26, 2008
Max Samukha
Apr 26, 2008
Christopher Wright
Apr 26, 2008
Ameer Armaly
Apr 26, 2008
Janice Caron
Apr 27, 2008
Bill Baxter
April 25, 2008
D2.013 just added the "nothrow" keyword, so that one can write, e.g.

    inf f() nothrow
    {
        return 42;
    }

to indicate that f does not throw an exception. My question is, what's the point?

The documentation notes that the semantics are not implemented, but I have to ask, why is this desirable in general?

Like any annotation, "nothrow" indicates a /contract/. Like any annation, there are two rules

(1) if a function is annotated with the nothrowkeyword, then the compiler will emit a compile error within the function body, if the function body of f throws an exception.

(2) if the caller of a function requires that the the called function not throw any exceptions, then the compiler will emit a compile error at the caller site if the callee is not annotated with the nothrow keyword.

Rule one helps the human. Rule two helps the compiler - but positively /hinders/ the human. The problem is one of logical fallacy - given the proposition "all dogs have four legs", one may /not/ assume that if it has four legs, it must be a dog. Likewise, given the proposition "any function decorated with the nothrow keyword will not throw an exception", one may /not/ assume that if it doesn't throw an exception, then it will be decorated with the nothrow keyword. Here's a simple counterexample:

    int f() { return 42; }
    int g() nothrow { return f(); }

Once the semantics of nothrow are implemented, the above code will not compile. This is because, /even though/ f doesn't throw any exceptions, the compiler isn't able to prove that (or at least, can't be bothered to prove that) at the time g is compiled.

Like all annotations, "nothrow" therefore /propogates/ throughout code. In order to get the above to compile, the user must now decorate f.

This is all very well, unless f is in a library, and the user is unable to modify f. In that case, presumably the user must do something like:

    int g() nothrow { return cast(nothrow) f(); }

or perhaps

    int g() nothrow
    {
        try { return f(); }
        catch(Exception e) { return 0; }
    }

Sure - we could decorate /every/ function which does not throw an exception with "nothrow", but are we really going to do that?

So I guess my question is, in what circumstance would "nothrow" be helpful? And is it helpful /enough/ to warrant "polluting" all library code with "nothrow" annotations?
April 25, 2008
Janice Caron wrote:
> So I guess my question is, in what circumstance would "nothrow" be
> helpful? And is it helpful /enough/ to warrant "polluting" all library
> code with "nothrow" annotations?

"nothrow" is, as you say, a contract. It specifies that a function must return normally (unless it aborts, crashes, or hangs). Such annotations:

1. improves the API documentation
2. enables significantly better code generation (if you use a lot of scope statements and struct destructors)
3. nothrow can be very useful in building up transactions, because you know that the components cannot fail
4. destructors cannot throw exceptions (because they are already in one). Andrei has proposed a method to deal with this, but it is as yet unimplemented.

For more info, see http://www.gotw.ca/gotw/082.htm and http://www.boost.org/community/exception_safety.html
April 25, 2008
On 2008-04-25 03:23:39 -0400, Walter Bright <newshound1@digitalmars.com> said:

> Janice Caron wrote:
>> So I guess my question is, in what circumstance would "nothrow" be
>> helpful? And is it helpful /enough/ to warrant "polluting" all library
>> code with "nothrow" annotations?
> 
> "nothrow" is, as you say, a contract. It specifies that a function must return normally (unless it aborts, crashes, or hangs).

I presume "aborts, crashes, or hangs" should also include "asserts". After all, one can't assert in release mode so it doesn't hinder the part about better code generation.


> 4. destructors cannot throw exceptions (because they are already in one). Andrei has proposed a method to deal with this, but it is as yet unimplemented.

Hum, I wonder, can one assert in a destructor?

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

April 25, 2008
Walter Bright wrote:
> Janice Caron wrote:
>> So I guess my question is, in what circumstance would "nothrow" be helpful? And is it helpful /enough/ to warrant "polluting" all library code with "nothrow" annotations?
> 
> "nothrow" is, as you say, a contract. It specifies that a function must return normally (unless it aborts, crashes, or hangs). Such annotations:
> 
> 1. improves the API documentation
> 2. enables significantly better code generation (if you use a lot of
> scope statements and struct destructors)
> 3. nothrow can be very useful in building up transactions, because you
> know that the components cannot fail
> 4. destructors cannot throw exceptions (because they are already in
> one). Andrei has proposed a method to deal with this, but it is as yet
> unimplemented.
> 
> For more info, see http://www.gotw.ca/gotw/082.htm and http://www.boost.org/community/exception_safety.html

I'd like to point out that you both agree that "nothrow" is a _contract_. That immediately begs the question: why implement it as yet another ad hoc feature instead of making it part of D's DBC (which is yet to be implemented...)?

Personally, I don't see the point of constantly adding more annotations
and keywords to D2 since it complicates the syntax and makes D2 much
less attractive from a syntax POV.
D2 will allow the following:
pure invariant invariant(int) func(invariant(int)) nothrow;
Am I the only one that thinks the above is too much?

It's time for a standardized Annotations/Attributes mechanism for D. I'll post my initial suggestion for such a mechanism in a new thread.

--Yigal
April 25, 2008
Michel Fortin wrote:
> On 2008-04-25 03:23:39 -0400, Walter Bright <newshound1@digitalmars.com> said:
> 
>> Janice Caron wrote:
>>> So I guess my question is, in what circumstance would "nothrow" be
>>> helpful? And is it helpful /enough/ to warrant "polluting" all library
>>> code with "nothrow" annotations?
>>
>> "nothrow" is, as you say, a contract. It specifies that a function must return normally (unless it aborts, crashes, or hangs).
> 
> I presume "aborts, crashes, or hangs" should also include "asserts". After all, one can't assert in release mode so it doesn't hinder the part about better code generation.
> 
> 
>> 4. destructors cannot throw exceptions (because they are already in one). Andrei has proposed a method to deal with this, but it is as yet unimplemented.
> 
> Hum, I wonder, can one assert in a destructor?
> 

It shouldn't include asserts.  Asserts can be disabled and don't cause the problems that exceptions do.

-Joel
April 25, 2008
Yigal Chripun wrote:
> Walter Bright wrote:
>> Janice Caron wrote:
>>> So I guess my question is, in what circumstance would "nothrow" be
>>> helpful? And is it helpful /enough/ to warrant "polluting" all library
>>> code with "nothrow" annotations?
>> "nothrow" is, as you say, a contract. It specifies that a function must
>> return normally (unless it aborts, crashes, or hangs). Such annotations:
>>
>> 1. improves the API documentation
>> 2. enables significantly better code generation (if you use a lot of
>> scope statements and struct destructors)
>> 3. nothrow can be very useful in building up transactions, because you
>> know that the components cannot fail
>> 4. destructors cannot throw exceptions (because they are already in
>> one). Andrei has proposed a method to deal with this, but it is as yet
>> unimplemented.
>>
>> For more info, see http://www.gotw.ca/gotw/082.htm and
>> http://www.boost.org/community/exception_safety.html
> 
> I'd like to point out that you both agree that "nothrow" is a
> _contract_. That immediately begs the question: why implement it as yet
> another ad hoc feature instead of making it part of D's DBC (which is
> yet to be implemented...)?
> 
> Personally, I don't see the point of constantly adding more annotations
> and keywords to D2 since it complicates the syntax and makes D2 much
> less attractive from a syntax POV.
> D2 will allow the following:
> pure invariant invariant(int) func(invariant(int)) nothrow;
> Am I the only one that thinks the above is too much?
> 
> It's time for a standardized Annotations/Attributes mechanism for D.
> I'll post my initial suggestion for such a mechanism in a new thread.
> 
> --Yigal


While attributes are a nice idea for somethings; for things like invariants it would make the client syntax more difficult to read.  Also invariant const etc.. could not go into the standard lib because then the compiler would make it much more difficult for the compiler to perform optimizations (Walters point 2).

Also it would be more difficult to extend the concept of invariants; for example, to something like functional programming because of attribute system limitations.

If your moving something like invariants to attributes, don't forget your not actually reducing the complexity to the end user.  Now they have to figure-out what the standard lib is doing also.  The complexity only reduces for the compiler writer.

-Joel
April 25, 2008
janderson wrote:
> 
> While attributes are a nice idea for somethings; for things like invariants it would make the client syntax more difficult to read.  Also invariant const etc.. could not go into the standard lib because then the compiler would make it much more difficult for the compiler to perform optimizations (Walters point 2).
> 
> Also it would be more difficult to extend the concept of invariants; for example, to something like functional programming because of attribute system limitations.
> 
> If your moving something like invariants to attributes, don't forget your not actually reducing the complexity to the end user.  Now they have to figure-out what the standard lib is doing also.  The complexity only reduces for the compiler writer.
> 
> -Joel

Regarding optimizations, I don't know if it would be possible with
attributes - I guess it depends on the compiler APIs exposed to the
attribute writer. I do agree that not _all_things_ should be implemented
as attributes. The invariants are a bad example and I just used that to
illustrate how complex the D syntax has become.
It's like the type system - D provides a a set of built in primitive
types like int,char,long,etc.. and a way to use those to create your own
via classes/unions/structs...
so it may make sense to have a built-in const but IMO nothrow doesn't
deserve the same status. I'm also not sure that pure should be provided
by D.
Look at the link bellow for a Java DBC using annotations. Seems much
better than what D provides (nothing.. since it's not implemented).
Since D is not backed up by a giant like Sun/MS/Google/etc it makes
sense to delegate these features to the community, since it's obvious
not high on Walter's todo list and annotations make perfect sense for that.

Note, you mention "attribute system limitations" - since D does have that system yet, we do not know what limitations D's system would have compared to the .net or Java implementations.

http://en.wikipedia.org/wiki/Java_Modeling_Language
April 25, 2008
Michel Fortin wrote:
> I presume "aborts, crashes, or hangs" should also include "asserts". 

Yes. An assert is an error that is not recoverable, so there is no need for stack unwinding.
April 25, 2008
Yigal Chripun wrote:
> Since D is not backed up by a giant like Sun/MS/Google/etc it makes
> sense to delegate these features to the community, since it's obvious
> not high on Walter's todo list and annotations make perfect sense for that.

If attributes had meaning only in a library or for some special tool, the compiler cannot extract any useful information from them.
April 25, 2008
Walter Bright wrote:
> Yigal Chripun wrote:
>> Since D is not backed up by a giant like Sun/MS/Google/etc it makes sense to delegate these features to the community, since it's obvious not high on Walter's todo list and annotations make perfect sense for that.
> 
> If attributes had meaning only in a library or for some special tool, the compiler cannot extract any useful information from them.

if the compiler provides hooks for the attribute writers than an attribute would have meaning for the compiler.

for example, it should be possible to write a user defined attribute and via a hook, tell the compiler to verify transitivity of it at compile time.

BTW, what information does the compiler extract from an attribute? wouldn't it be enough to use the above approach to tell the compiler what to do for each attribute?

--Yigal
« First   ‹ Prev
1 2 3