What are the unused but useful feature you know in D?

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Sun Jun 25 21:31:33 PDT 2017


On Mon, Jun 26, 2017 at 12:38:21AM +0000, Mike via Digitalmars-d wrote:
> On Sunday, 25 June 2017 at 23:21:25 UTC, aberba wrote:
> > Can you share feature(s) in D people are not talking about which
> > you've found very useful?
> 
> In my experience, using appropriate attributes for functions,
> variables, etc... doesn't happen like it should.  This includes
> attributes like `@safe`, `immutable`, `pure`, `const`, and others.
> 
> I recently watched of video where Andrei acknowledged this when
> talking about the `pure` attribute
> (https://youtu.be/WsgW4HJXEAg?t=3052).  It was also acknowledged
> somewhat by Walter in his talk at DConf 2017
> (https://youtu.be/iDFhvCkCLb4?t=2531).  As I understand it, though,
> the D compiler has some logic to automatically infer some of these
> attributes, but because its *invisible* to the user it's difficult to
> predict what those inferences are, and there's no documentation that
> I'm aware of that defines how/where/where this happens.

It happens for template functions, member functions of templated
aggregates (structs/classes), and auto functions.  One of the reasons
it's undocumented or underdocumented is because it's a moving target:
the goal is to apply automatic inference as widely as possible.
Requiring users to manually write attributes is ultimately an
impractical plan, especially when the number of attributes increase.

You can always use pragma(msg, typeof(...)) to find out exactly what was
inferred.

To ensure that a particular template function *must* have some attribute
as long as none of its arguments break it, use an attributed unittest.
E.g.:

	auto myTemplateFunc(Range)(Range r)
		if (isInputRange!Range)
	{
	}

	pure unittest
	{
		auto r = [1,2,3].myTemplateFunc();
	}

The reason you don't want to stick the attribute on the function itself
is because then it will preclude using it with a range that happens to
have impure methods, whereas what you want is that the function is pure
if the range is also pure, but if the range is impure, it's OK for the
function to be impure.  This is achieved by putting the attribute on the
unittest: since [1,2,3] is a range known to be pure, any source of
impurity must have come from the function; the pure attribute on the
unittest would force a compile error in that case.


> IMO, part of the problem is that D has the wrong defaults (e.g.
> `immutable` by default, `@safe` by default, `final` by default,
> etc...), so users have to opt in to these things when they should
> really only be opting out of them.  Unfortunately, changing this would
> be disruptive and will probably never happen without a fork.
[...]

Yes, the wrong defaults were a historical accident.  It was inherited
from before D had attributes, so when the attributes were added, the
only way was to add attributes that negate the status quo rather than
change the default setting, otherwise it would have completely broken
everyone's code.  Pretty much everyone here agrees that if we could
start over, we would have pure by default, nothrow by default, @safe by
default, etc., and only require marking when something is impure,
throwing, @system, etc.. But as they say, hindsight is always 20/20...
it was not obvious back when D was first designed.


T

-- 
Only boring people get bored. -- JM


More information about the Digitalmars-d mailing list