Am 17.02.2012, 05:10 Uhr, schrieb H. S. Teoh <hst...@quickfur.ath.cx>:
On Thu, Feb 16, 2012 at 07:41:00PM -0800, Walter Bright wrote:
On 2/16/2012 7:23 PM, Jonathan M Davis wrote:
>No. Absolutely not. I hate the fact that C++ does this with virtual.
>It makes it so that you have to constantly look at the base classes
>to figure out what's virtual and what isn't. It harms maintenance and
>code understandability. And now you want to do that with @safe, pure,
>nothrow, and const? Yuck.
It's probably the same reason I brought up: looking at a function's
definition will no longer tell you which modifiers are actually in
effect. So you have to trace the overrides up the inheritance hierarchy
in order to know exactly what modifiers it has.
On that note, though, one thing I've always wanted in a programming
language is to be able to ask the compiler to expand all templates,
deduce all types, etc., for a given function/declaration, and print out
what it actually understands the declaration to be (as opposed to what I
*think* the declaration would expand to).
Depending on how people approach the language
- editor or IDE
- looking up documentation or relying on intuitive code
- prefer explicit or implicit declarations (see 'auto' return as well)
- trust in the compiler catching their errors or trying to keep compilers
out of their understanding of the source code
we come to different strong opinions.
If @safe, pure, nothrow, and const were inherited and optional now I would try
that system, but still wonder if it actually makes me use these attributes more
than before. I tend to just put @safe: at the top of my module and mark trivial
I/O functions @trusted. Frankly I don't mind the typing as much as I minded to
have to remove these attributes later, because after a few nested function
calls I ended up calling a throwing function (and don't want to catch). I think
similar things happened with pure and const. It helps that I wouldn't have to
go through all of the class hierarchy if this happens, but I wonder what the
benefit of pure and nothrow is. @safe and const help me detect bugs or design
mistakes. If there were performance benefits to using strongly pure functions,
I'd be far more tempted to use them than with automatic inheritance. Also the
case for Phobos was mentioned, but that are mostly free functions that wouldn't
benefit from inheritance either.
My utopical IDE would deduce all the attributes from looking at the source code
and actually place them in the code like this:
uint foo() /*deduced:*/ pure const nothrow @safe
{
return 42;
}
This way I see what the method currently evaluates to, but I am free to add a "throw
new Exception(...);" with the IDE changing the signature on the fly:
uint foo() /*deduced:*/ pure const @safe
{
throw new Exception("abc");
}
If the attributes could be displayed as some sort of tri-state buttons in the
code view and I would decide that this method *has to be* const, I would click
on 'const' to move the keyword left:
uint foo() const /*deduced:*/ pure @safe
{
throw new Exception("abc");
}
And at this point no user of that IDE could be too lazy to add "pure const
nothrow", because it would be deduced from the code and also put in the signature to
document it. Editor purists will hate this idea and it doesn't solve anything right
*now*, but I wanted to share it anyway. Maybe it inspires others to come up with better
ideas.
-- Marco