Re: @api: One attribute to rule them All

2015-01-11 Thread Dicebot via Digitalmars-d

On Friday, 9 January 2015 at 16:14:01 UTC, Zach the Mystic wrote:
To sum up: All .di function signatures will now be generated 
with both explicit and inferred attributes. The keyword 
'export' will be overloaded with a new meaning, toggled on and 
off by a compiler flag which generates .di files based on that 
meaning. Correct?


It is not truly overloading with new meaning. One can argue that 
existing meaning of export can already be interpreted that way, 
it is simply not implemented in full power. See DIP45 for some 
more stuff on topic.


As for the rest - I'd better try answering those questions if I 
ever sit down and actually write it carefully, right now it is 
more like bunch of vague ideas rolling around with no solid 
structure.


Re: @api: One attribute to rule them All

2015-01-11 Thread Dicebot via Digitalmars-d

On Saturday, 10 January 2015 at 10:47:04 UTC, Marc Schütz wrote:
On Friday, 9 January 2015 at 16:14:01 UTC, Zach the Mystic 
wrote:
If solving the problem at the level of the command line with 
the help of the existing 'export' attribute is more flexible 
and robust, then I'm all for it. The first thing to find out 
is if anyone will have a problem overloading the meaning of 
'export' for this purpose. I can't think of a reason they 
would, unless people are currently using 'export' in some 
niche way which would be ruined by the new flag.


This DIP is of relevance:
http://wiki.dlang.org/DIP45


Yes, it was partly what started me thinking in this direction, 
DIP45 is very wise.


Re: @api: One attribute to rule them All

2015-01-10 Thread via Digitalmars-d

On Friday, 9 January 2015 at 16:14:01 UTC, Zach the Mystic wrote:
If solving the problem at the level of the command line with 
the help of the existing 'export' attribute is more flexible 
and robust, then I'm all for it. The first thing to find out is 
if anyone will have a problem overloading the meaning of 
'export' for this purpose. I can't think of a reason they 
would, unless people are currently using 'export' in some niche 
way which would be ruined by the new flag.


This DIP is of relevance:
http://wiki.dlang.org/DIP45


Re: @api: One attribute to rule them All

2015-01-10 Thread Atila Neves via Digitalmars-d

Very interesting, looking forward to reading the DIP.

Atila

On Friday, 9 January 2015 at 11:40:28 UTC, Dicebot wrote:
I think that push for more inference / WPO is an important goal 
for D. However I had somewhat more radical and generic changes 
in mind, ones that don't add new keywords or semantics but 
rather strictly define what existing ones mean. This was 
supposed to be turned into a DIP at some point (possibly after 
consulting with Walter) but here is the draft outline:


- separate compilation in basic C sense becomes illegal
- minimal legal unit of separate compilation is defined as 
static library
- any time library gets built, it _must_ be distributed with 
matching .di interfaces. If there are original .d files 
imported, one must not try to link prebuilt library.

- .di generation is split in two modes:
1) 'minimal' (API) which only writes exported symbols and 
ignores even public ones. All inferred attributes gets written 
explicitly there. This is what gets recommended for public 
distribution (even if it is source-only distribution) and what 
defines stable API.
2) 'full' mode which is similar to existing .di generation 
but with all attributes explicitly written to all functions. It 
is approach recommended for creating intermediate built 
artifacts (such as dub building of dependencies).


Stability of (1) headers can be validated mechanically by 
compiler / external tool in such scenario. As you may notice no 
new keywords / language concepts are proposed, it is only about 
more strict definition of standard development flow. It also 
opens well-defined borderline for any WPO.


Needs a lot of work before any serious destruction of course 
but should give some overall feeling of what I am going at.




Re: @api: One attribute to rule them All

2015-01-09 Thread Zach the Mystic via Digitalmars-d

On Friday, 9 January 2015 at 11:40:28 UTC, Dicebot wrote:
I think that push for more inference / WPO is an important goal 
for D. However I had somewhat more radical and generic changes 
in mind, ones that don't add new keywords or semantics but 
rather strictly define what existing ones mean. This was 
supposed to be turned into a DIP at some point (possibly after 
consulting with Walter) but here is the draft outline:


- separate compilation in basic C sense becomes illegal
- minimal legal unit of separate compilation is defined as 
static library
- any time library gets built, it _must_ be distributed with 
matching .di interfaces. If there are original .d files 
imported, one must not try to link prebuilt library.


This last one is where all the threats from bad linking seem to 
come from.



- .di generation is split in two modes:
1) 'minimal' (API) which only writes exported symbols and 
ignores even public ones. All inferred attributes gets written 
explicitly there. This is what gets recommended for public 
distribution (even if it is source-only distribution) and what 
defines stable API.
2) 'full' mode which is similar to existing .di generation 
but with all attributes explicitly written to all functions. It 
is approach recommended for creating intermediate built 
artifacts (such as dub building of dependencies).


To sum up: All .di function signatures will now be generated with 
both explicit and inferred attributes. The keyword 'export' will 
be overloaded with a new meaning, toggled on and off by a 
compiler flag which generates .di files based on that meaning. 
Correct?


Stability of (1) headers can be validated mechanically by 
compiler / external tool in such scenario. As you may notice no 
new keywords / language concepts are proposed, it is only about 
more strict definition of standard development flow. It also 
opens well-defined borderline for any WPO.


If solving the problem at the level of the command line with the 
help of the existing 'export' attribute is more flexible and 
robust, then I'm all for it. The first thing to find out is if 
anyone will have a problem overloading the meaning of 'export' 
for this purpose. I can't think of a reason they would, unless 
people are currently using 'export' in some niche way which would 
be ruined by the new flag.


Needs a lot of work before any serious destruction of course 
but should give some overall feeling of what I am going at.


We both agree that full covariant inference should be the 
default. It seems like the first step is to introduce it using an 
opt-in compiler flag (e.g. -infer). I'm not sure how .di files 
and mangled names should be generated using this flag though. The 
goal is to get the kinks out of the inference process before 
making it the default. What's step two, though?


Re: @api: One attribute to rule them All

2015-01-09 Thread Dicebot via Digitalmars-d
I think that push for more inference / WPO is an important goal 
for D. However I had somewhat more radical and generic changes in 
mind, ones that don't add new keywords or semantics but rather 
strictly define what existing ones mean. This was supposed to be 
turned into a DIP at some point (possibly after consulting with 
Walter) but here is the draft outline:


- separate compilation in basic C sense becomes illegal
- minimal legal unit of separate compilation is defined as static 
library
- any time library gets built, it _must_ be distributed with 
matching .di interfaces. If there are original .d files imported, 
one must not try to link prebuilt library.

- .di generation is split in two modes:
1) 'minimal' (API) which only writes exported symbols and 
ignores even public ones. All inferred attributes gets written 
explicitly there. This is what gets recommended for public 
distribution (even if it is source-only distribution) and what 
defines stable API.
2) 'full' mode which is similar to existing .di generation 
but with all attributes explicitly written to all functions. It 
is approach recommended for creating intermediate built artifacts 
(such as dub building of dependencies).


Stability of (1) headers can be validated mechanically by 
compiler / external tool in such scenario. As you may notice no 
new keywords / language concepts are proposed, it is only about 
more strict definition of standard development flow. It also 
opens well-defined borderline for any WPO.


Needs a lot of work before any serious destruction of course but 
should give some overall feeling of what I am going at.


Re: @api: One attribute to rule them All

2015-01-07 Thread Zach the Mystic via Digitalmars-d

On Monday, 5 January 2015 at 21:15:00 UTC, Zach the Mystic wrote:

https://github.com/D-Programming-Language/dmd/pull/1877


Deep into the discussion on the above pull, Walter responds to 
this comment of Kenji's:


I think this kind of optimization should be hidden after the 
semantic phase - as like inlining and backend optimizations.


...with this:

The trouble with doing this is that it is extremely dangerous in 
a language that supports separate compilation. It means that a 
function can be treated as pure, but its mangled signature says 
its impure. Then, the build system swaps in another version of 
that function, with the same signature, but is impure. Now the 
code that calls it is silently broken - the worst kind of runtime 
error.
This is why attribute inference is limited to those functions 
where the definitions are guaranteed to be available - templates, 
lambdas, nesteds and autos - then there can be no runtime 
mismatch.


What bothers me about this is that the compiler could *know* that 
a function is pure any time it has the function body available to 
it, regardless of what kind of function it is. The above quote 
suggests, however, that it's just completely impossible for the 
compiler to know if the function which will be called is the one 
that it has just compiled, or if it will be swapped in by a 
linker with another function with the same name from somewhere 
else. I honestly don't know enough about how linking works to 
know if this cancels my proposal. Wouldn't it cause an error if 
the linker found two of the exact same function?


My naive assumption about it is that when the compiler has the 
body, it can treat it as pure from within, even if it gets 
expressed by 'extern(noinfer)' as impure. That is, from within 
the singly compiled program, it can be treated as if it *is* 
pure, being one-hundred percent certain that the function it 
compiles will be the one that gets called at binary time, but for 
anyone reading the expressed interface, it can only be compiled 
as if it's *not* pure, since that's all the information the 
interface tells them.


Re: @api: One attribute to rule them All

2015-01-07 Thread Zach the Mystic via Digitalmars-d
Martin Nowak is the one who created the issue for this 
enhancement request:


https://issues.dlang.org/show_bug.cgi?id=10979

He proposes a different solution though - creating two mangled 
names for each function. The advantage, as far as I can see it, 
is that you wouldn't even have to add @api or extern(noinfer) 
to link properly. I see two disadvantages: the binary would 
suffer bloat, and the generated .di signatures would have to 
default to the conservative explicit signature, since is could 
not include both signatures without causing a duplicate 
definition.


Re: @api: One attribute to rule them All

2015-01-07 Thread Zach the Mystic via Digitalmars-d
On Thursday, 8 January 2015 at 04:43:50 UTC, Zach the Mystic 
wrote:

https://issues.dlang.org/show_bug.cgi?id=10979


Whoops! The link is:
https://issues.dlang.org/show_bug.cgi?id=10924


Re: @api: One attribute to rule them All

2015-01-06 Thread John Colvin via Digitalmars-d

On Tuesday, 6 January 2015 at 09:12:43 UTC, John Colvin wrote:
On Monday, 5 January 2015 at 21:15:00 UTC, Zach the Mystic 
wrote:
Hello everybody. My name is Zach, and I have a suggestion for 
the improvement of D. I've been looking at the following 
stalled pull request for a while now:


https://github.com/D-Programming-Language/dmd/pull/1877

...in which Walter Bright wants to introduce 
built-in-attribute inference for a relatively small set of 
functions. It seems like the most obvious thing in the world 
to me to desire this, and not even just for 'auto' and 
templated functions, but for *every* function. And there's no 
reason it can't be done. So long as the compiler has 
everything it needs to determine which attributes can be 
applied, there's no reason to demand anything from the 
programmer. Look how simple this function is:


int plusOne(int a) { return a+1; }

Let's say I later want to call it, however, from a fully 
attributed function:


int plusTwo(int a) pure nothrow @safe @nogc  {
 return plusOne(plusOne(a));
}

I get a compiler error. The only way to stop it is to add 
unnecessary visual noise to the first function. All of these 
attributes should be something that you *want* to add, not 
something that you *need*. The compiler can obviously figure 
out if the function throws or not. Just keep an additional 
internal flag for each of the attributes. When any attribute 
is violated, flip the bit and boom, you have your implicit 
function signature.


I think this is how it always should have been. It's important 
to remember that the above attributes have the 'covariant' 
property, which means they can always be called by any 
function without that property. Therefore no existing code 
will start failing to compile. Only certain things which would 
have *errored* before will stop. Plus new optimizations can be 
done.


So what's the problem? As you can read in the vehement 
opposition to pull 1877 above, the big fear is that function 
signatures will start changing willy-nilly, causing the 
exposed interface of the function to destabilize, which will 
cause linker errors or require code intended to be kept 
separate in large projects to be recompiled at every little 
change.


I find this depressing! That something so good should be 
ruined by something so remote as the need for separate 
compilation in very large projects? I mean, most projects 
aren't even very large. Also, because D compiles so much 
faster than its predecessors, is it even such a big deal to 
have to recompile everything?


But let's admit the point may be valid. Yes, under attribute 
inference, the function signatures in the exposed API will 
indeed find themselves changing every time one so much as adds 
a 'printf' or calls something that throws.


But they don't *have* to change. The compiler doesn't need to 
include the inferred attributes when it generates the mangled 
name and the .di signature, only the explicit ones. From 
within the program, all the opportunities for inference and 
optimization could be left intact, while outside programs 
accessing the code in precompiled form could only access the 
functions as explicitly indicated.


This makes no change to the language, except that it allows 
new things to compile. The only hitch is this: What if you 
want the full advantages of optimization and inference from 
across compilation boundaries? You'd have to add each of the 
covariant function attributes manually to every function you 
exposed. From my perspective, this is still a chore.


I suggest a new attribute, @api, which does nothing more than 
to tell the compiler to generate the function signature and 
mangle the name only with its explicit attributes, and not 
with its inferred ones. Inside the program, there's no reason 
the compiler can't continue to use inference, but with @api, 
the exposed interface will be stabilized, should the 
programmer want that. Simple.


I anticipate a couple of objections to my proposal:

The first is that we would now demand that the programmer 
decide whether he wants his exposed functions stabilized or 
not. For a large library used by different people, this choice 
might pose some difficulty. But it's not that bad. You just 
choose: do you want to improve compilation times and/or 
closed-source consistency by ensuring a stable interface, or 
do you want to speed up runtime performance without having to 
clutter your code? Most projects would choose the latter. @api 
is made available for the those who don't. The opposition to 
attribute inference put forth in pull 1877 is thereby appeased.


A second objection to this proposal: Another attribute? 
Really? Well, yeah.


But it's not a problem, I say, for these reasons:

1. This one little attribute allows you to excise gajillions 
of unnecessary little attributes which are currently forced on 
the programmer by the lack of inference, simply by appeasing 
the opponents of inference and allowing it to be 

Re: @api: One attribute to rule them All

2015-01-06 Thread John Colvin via Digitalmars-d

On Monday, 5 January 2015 at 21:15:00 UTC, Zach the Mystic wrote:
Hello everybody. My name is Zach, and I have a suggestion for 
the improvement of D. I've been looking at the following 
stalled pull request for a while now:


https://github.com/D-Programming-Language/dmd/pull/1877

...in which Walter Bright wants to introduce built-in-attribute 
inference for a relatively small set of functions. It seems 
like the most obvious thing in the world to me to desire this, 
and not even just for 'auto' and templated functions, but for 
*every* function. And there's no reason it can't be done. So 
long as the compiler has everything it needs to determine which 
attributes can be applied, there's no reason to demand anything 
from the programmer. Look how simple this function is:


int plusOne(int a) { return a+1; }

Let's say I later want to call it, however, from a fully 
attributed function:


int plusTwo(int a) pure nothrow @safe @nogc  {
  return plusOne(plusOne(a));
}

I get a compiler error. The only way to stop it is to add 
unnecessary visual noise to the first function. All of these 
attributes should be something that you *want* to add, not 
something that you *need*. The compiler can obviously figure 
out if the function throws or not. Just keep an additional 
internal flag for each of the attributes. When any attribute is 
violated, flip the bit and boom, you have your implicit 
function signature.


I think this is how it always should have been. It's important 
to remember that the above attributes have the 'covariant' 
property, which means they can always be called by any function 
without that property. Therefore no existing code will start 
failing to compile. Only certain things which would have 
*errored* before will stop. Plus new optimizations can be done.


So what's the problem? As you can read in the vehement 
opposition to pull 1877 above, the big fear is that function 
signatures will start changing willy-nilly, causing the exposed 
interface of the function to destabilize, which will cause 
linker errors or require code intended to be kept separate in 
large projects to be recompiled at every little change.


I find this depressing! That something so good should be ruined 
by something so remote as the need for separate compilation in 
very large projects? I mean, most projects aren't even very 
large. Also, because D compiles so much faster than its 
predecessors, is it even such a big deal to have to recompile 
everything?


But let's admit the point may be valid. Yes, under attribute 
inference, the function signatures in the exposed API will 
indeed find themselves changing every time one so much as adds 
a 'printf' or calls something that throws.


But they don't *have* to change. The compiler doesn't need to 
include the inferred attributes when it generates the mangled 
name and the .di signature, only the explicit ones. From within 
the program, all the opportunities for inference and 
optimization could be left intact, while outside programs 
accessing the code in precompiled form could only access the 
functions as explicitly indicated.


This makes no change to the language, except that it allows new 
things to compile. The only hitch is this: What if you want the 
full advantages of optimization and inference from across 
compilation boundaries? You'd have to add each of the covariant 
function attributes manually to every function you exposed. 
From my perspective, this is still a chore.


I suggest a new attribute, @api, which does nothing more than 
to tell the compiler to generate the function signature and 
mangle the name only with its explicit attributes, and not with 
its inferred ones. Inside the program, there's no reason the 
compiler can't continue to use inference, but with @api, the 
exposed interface will be stabilized, should the programmer 
want that. Simple.


I anticipate a couple of objections to my proposal:

The first is that we would now demand that the programmer 
decide whether he wants his exposed functions stabilized or 
not. For a large library used by different people, this choice 
might pose some difficulty. But it's not that bad. You just 
choose: do you want to improve compilation times and/or 
closed-source consistency by ensuring a stable interface, or do 
you want to speed up runtime performance without having to 
clutter your code? Most projects would choose the latter. @api 
is made available for the those who don't. The opposition to 
attribute inference put forth in pull 1877 is thereby appeased.


A second objection to this proposal: Another attribute? Really? 
Well, yeah.


But it's not a problem, I say, for these reasons:

1. This one little attribute allows you to excise gajillions of 
unnecessary little attributes which are currently forced on the 
programmer by the lack of inference, simply by appeasing the 
opponents of inference and allowing it to be implemented.


2. It seems like most people will be okay just recompiling 

Re: @api: One attribute to rule them All

2015-01-06 Thread ketmar via Digitalmars-d
On Mon, 05 Jan 2015 21:14:58 +
Zach the Mystic via Digitalmars-d digitalmars-d@puremagic.com wrote:

 Hello everybody. My name is Zach, and I have a suggestion for the 
 improvement of D. I've been looking at the following stalled pull 
 request for a while now:
 
 https://github.com/D-Programming-Language/dmd/pull/1877

heh. i did a little hack based on this patch: autoinference is turned
on only for `private auto`. i also added a bunch of UDAs to control the
process: `@inferattr` (can be applied to any function), `@notinferattr`,
`@canthrow`, `@impure` and `@gc` (to control inference).

any explicit attribute on function will block inference too.

as druntime and phobos has no `private auto` which is not templated or
without explicit attribues, it compiles fine. and for my code i have
some control.

this feature can be poorly designed, but as it doesn't conflict with
most of the existing code, i'm happy with it. one should be carefull
with templates calling private functions with inferred attributes (it
breaks linking -- for obvious reason), but it's ok for me. `private
auto` is so ugly that it will rise my alarm level anyway. i mean
function returning 'auto' is suspicious.


signature.asc
Description: PGP signature


Re: @api: One attribute to rule them All

2015-01-06 Thread Joseph Rushton Wakeling via Digitalmars-d

On Tuesday, 6 January 2015 at 03:29:39 UTC, Zach the Mystic wrote:
A more likely scenario is that your library starts small enough 
not to need the @api attribute, then at some point it gets 
really, really huge. Then in one fell swoop you decide to 
@api: your whole file so that the public interface won't 
change so often. I'm picking the most extreme case I can think 
of, in order to argue the point from a different perspective.


Note that if you want auto-inferred attributes during the alpha 
phase of library development, it's just as trivial to put a 
general @autoinfer: or @noapi: or whatever you like, and that in 
turn is a pretty nice signifier to the user this function's 
attributes are not guaranteed to be stable.



Attribute inference provides convenience, not guarantees.


Indeed.  But any publicly-available API is a guarantee of sorts.  
From the moment people are using something, you can no longer 
vicariously break things.


If a user was relying on the purity of a function which was 
never marked 'pure', it's only convenience which allows him to 
do it, both on the part of the user, for adding 'pure', and the 
library writer, for *not* adding it.


Nevertheless, if a user relies on that inferred purity (which 
they will do), and you tweak things so the function is no longer 
pure, you have broken that downstream user's code.  Worse, you'll 
have done it in a way which flies under the radar until someone 
actually tries to build against your updated library.  You, as 
the library developer, won't get any automatic warning that 
you've broken backwards compatibility with your earlier 
implementation; the downstream user won't get any 
automatically-documented warnings of this breaking change.


If instead you have an explicit please auto-infer attributes for 
this function marker, then at least the user has a very clear 
warning that any attributes possessed by this function cannot be 
relied on.  (Absence of a guarantee != presence of a statement 
that there is NO guarantee:-)


Adding @api (or 'extern (noinfer)') cancels that convenience 
for the sake of modularity. It's a tradeoff. The problem  
itself is solved either by the library writer marking the 
function 'pure', or the user removing 'pure' from his own 
function.


As a library writer, I don't think you can responsibly expect 
users to bear the burden of fixing undocumented breaking change.



Without @api,  the problem only arises when the library writer
actually does something impure, which makes perfect sense.
It's @api (and D's existing default, by the way) which adds
the artificiality to the process, not my suggested default.


I'm not sure what exactly you mean when you talk about D's 
existing default, but one aspect that I think is important is: 
D's default position is that a function has no guarantees, and 
you _add_ guarantees to it via attributes.


This whole discussion would be quite different if the default was 
that a function is expected to be @safe, pure, nothrow, etc., and 
the developer is expected to use attributes to indicate 
_weakening_ of those guarantees.


It's quite analogous in this respect to the argument about 
final vs. virtual by default for class methods.


I don't think so, because of so-called covariance. Final and 
virtual each have their own advantages and disadvantages, 
whereas inferring attributes only goes one way. There is no 
cost to inferring in the general case.


I think you have missed the point I was making.

If you have final-by-default for classes, and you accidentally 
forget to tag a public method as 'virtual', then you can fix that 
without breaking any downstream user's code.  If by contrast you 
have virtual-by-default and you accidentally forget to tag a 
public method as 'final', then you can't fix that without the 
risk of breaking downstream; _someone_ may have relied on that 
function being virtual.


The situation is very similar here.  If your function has no 
attributes, and then later you add one (say, 'pure'), then you 
don't do any downstream user any harm.  If on the other hand your 
function _does_ have attributes -- whether explicit or inferred 
-- and then you remove them, you risk breaking downstream code.


If you don't auto-infer, this is not really an issue, because you 
have to manually add and remove attributes, and so you can never 
unintentionally or unknowingly remove an attribute.  But if you 
_do_ auto-infer, then it's very easy indeed to accidentally 
remove attributes that your downstream may have relied on.



My suggestion, (I now prefer 'extern(noinfer)'), does absolutely
nothing except to restore D's existing default, for what I think
are the rare cases it is needed. I could be wrong about just how
rare using extern(noinfer) will actually be, but consider that
phobos, for example, just doesn't need it, because it's too 
small

a library to cause trouble if all of a sudden one of its
non-templated functions becomes impure.


I don't think you 

Re: @api: One attribute to rule them All

2015-01-06 Thread Atila Neves via Digitalmars-d

tldr: I like what you're thinking, please can we have this.


+1

Atila



Re: @api: One attribute to rule them All

2015-01-06 Thread via Digitalmars-d
On Tuesday, 6 January 2015 at 12:07:21 UTC, Joseph Rushton 
Wakeling wrote:
As a library writer, I don't think you can responsibly expect 
users to bear the burden of fixing undocumented breaking change.


I agree, maybe just replace module with library. Also make 
module mandatory. It takes no extra keyword if it always is the 
first token.


Then the compiler can be more lax with module files and more 
strict with library files.


Re: @api: One attribute to rule them All

2015-01-06 Thread Elie Morisse via Digitalmars-d
On Tuesday, 6 January 2015 at 12:07:21 UTC, Joseph Rushton 
Wakeling wrote:

I think you have missed the point I was making.

If you have final-by-default for classes, and you accidentally 
forget to tag a public method as 'virtual', then you can fix 
that without breaking any downstream user's code.  If by 
contrast you have virtual-by-default and you accidentally 
forget to tag a public method as 'final', then you can't fix 
that without the risk of breaking downstream; _someone_ may 
have relied on that function being virtual.



For people making libraries which really need to keep ABI 
compatibility there should be some quick trick to tell the 
compiler to build those ABI-stable interfaces like:


  class {
  final @api:
...

  virtual @api:
...
  }

It's imho a small price to pay for not having to always write 
explicit attributes for most D functions.


Re: @api: One attribute to rule them All

2015-01-06 Thread Zach the Mystic via Digitalmars-d
On Tuesday, 6 January 2015 at 12:07:21 UTC, Joseph Rushton 
Wakeling wrote:
If you have final-by-default for classes, and you accidentally 
forget to tag a public method as 'virtual', then you can fix 
that without breaking any downstream user's code.  If by 
contrast you have virtual-by-default and you accidentally 
forget to tag a public method as 'final', then you can't fix 
that without the risk of breaking downstream; _someone_ may 
have relied on that function being virtual.


That's a much bigger problem than what you get with inferred 
attributes. If you have whole class hierarchy built around a 
function which isn't even supposed to be virtual, you'll have a 
lot of refactoring to do when it's marked final.


The only way in which downstream code will ever break is when 
the called function is longer expressed by the interface as 
'pure'. Under the new default, this will only happen when the 
function *actually stops being pure*. This is good! The only code 
which will then break is code which is itself marked 'pure'. The 
solution is either to remove 'pure' from the user's function, or 
to stop calling the impure function. It's not the end of the 
world if a user function stops being pure (@safe, nothrow, etc.). 
Since the called function was never marked 'pure', and thus never 
guaranteed to be pure to begin with, it was only luck and 
convenience which allowed the user to tag his code 'pure' in the 
first place. And, as John Colvin just pointed out, with the new 
defaults, the user most likely won't even bother to tag his code 
'pure', because he knows he will get all the optimization 
benefits without the hassle. The only reason to tag 'pure' from 
now on will be to *guarantee* it. At that point, you *want* your 
code to break, but only when your function actually stops being 
pure.


With D's existing default (and with code marked with the 
suggested new attribute 'extern(noinfer)'), you have another 
reason why your 'pure' function won't compile. Indeed, it's 
already broken. I ask you, why should a user have to wait until 
someone marks a function 'pure' to get the advantages of its 
purity, when the compiler already has everything it needs in 
order to grant those advantages? In the rare case where you 
actually want to revert to the way D is now, then you simply have 
to pay the price, which is the *same* price that everyone is 
already paying now.


Re: @api: One attribute to rule them All

2015-01-06 Thread Zach the Mystic via Digitalmars-d

On Tuesday, 6 January 2015 at 09:12:43 UTC, John Colvin wrote:
It's worth noting that with full inference then much less code 
would be explicitly annotated, which goes some way towards 
ameliorating the stability problem as more client code will be 
flexible w.r.t. changing attributes on library boundaries.


That's a great point. Explicit attributes will only be for larger 
projects which really want those guarantees. Everyone else gets 
all the optimizations for free... pretty cool!


Re: @api: One attribute to rule them All

2015-01-06 Thread Zach the Mystic via Digitalmars-d

On Tuesday, 6 January 2015 at 09:14:00 UTC, John Colvin wrote:

tldr: I like what you're thinking, please can we have this.


Hey thanks, John.


Re: @api: One attribute to rule them All

2015-01-05 Thread Zach the Mystic via Digitalmars-d

On Monday, 5 January 2015 at 21:25:01 UTC, Daniel N wrote:

An alternative could be to use the already existing 'export'.


'extern'. Yeah, something like 'extern (noinfer):'.


Re: @api: One attribute to rule them All

2015-01-05 Thread Zach the Mystic via Digitalmars-d

On Monday, 5 January 2015 at 22:00:40 UTC, Zach the Mystic wrote:

On Monday, 5 January 2015 at 21:25:01 UTC, Daniel N wrote:

An alternative could be to use the already existing 'export'.


'extern'. Yeah, something like 'extern (noinfer):'.


Err, yeah, whatever works!


Re: @api: One attribute to rule them All

2015-01-05 Thread Joseph Rushton Wakeling via Digitalmars-d

On 05/01/15 22:14, Zach the Mystic via Digitalmars-d wrote:

I get a compiler error. The only way to stop it is to add unnecessary visual
noise to the first function. All of these attributes should be something that
you *want* to add, not something that you *need*. The compiler can obviously
figure out if the function throws or not. Just keep an additional internal flag
for each of the attributes. When any attribute is violated, flip the bit and
boom, you have your implicit function signature.


Bear in mind one quite important factor -- all that alleged noise isn't simply 
about getting stuff to work, it's about promises that the function makes to 
downstream users.  You do touch on this yourself, but I think you have missed 
how your @api flag could go wrong.



I suggest a new attribute, @api, which does nothing more than to tell the
compiler to generate the function signature and mangle the name only with its
explicit attributes, and not with its inferred ones. Inside the program, there's
no reason the compiler can't continue to use inference, but with @api, the
exposed interface will be stabilized, should the programmer want that. Simple.


IMHO if anything like this is to be implemented, the extra flag should be to 
indicate that a function is _not_ intended to be part of the API and that 
therefore it is OK to infer its attributes.


Here's the rationale.  Suppose that I have a bunch of functions that are all 
intended to be part of the public API of my project.  I accidentally forget to 
tag one of them with the @api attribute, so its attributes will be 
auto-inferred, but the function is still public, so downstream users will wind 
up using it.


3 months later, I realize my mistake, and add the @api attribute -- at which 
point downstream users' code will break if their code was relying on the 
unintended inferred attributes.


If on the other hand you take the assumption that attributes should by default 
_not_ be auto-inferred, and you accidentally forget to tag a function to 
auto-infer its attributes, that can be fixed without breaking downstream.


It's quite analogous in this respect to the argument about final vs. virtual by 
default for class methods.


Re: @api: One attribute to rule them All

2015-01-05 Thread Joseph Rushton Wakeling via Digitalmars-d

On 06/01/15 00:48, Joseph Rushton Wakeling via Digitalmars-d wrote:

IMHO if anything like this is to be implemented, the extra flag should be to
indicate that a function is _not_ intended to be part of the API and that
therefore it is OK to infer its attributes.


Hmm.  On thinking about this some more, it occurs to me that this might be 
fundamentally about protection.  If it were forbidden to auto-infer attributes 
for a non-templated public function, then quite a few of my objections above 
might go away.


Re: @api: One attribute to rule them All

2015-01-05 Thread Zach the Mystic via Digitalmars-d
On Monday, 5 January 2015 at 23:48:17 UTC, Joseph Rushton 
Wakeling via Digitalmars-d wrote:
Here's the rationale.  Suppose that I have a bunch of functions 
that are all intended to be part of the public API of my 
project.  I accidentally forget to tag one of them with the 
@api attribute,


A more likely scenario is that your library starts small enough 
not to need the @api attribute, then at some point it gets 
really, really huge. Then in one fell swoop you decide to @api: 
your whole file so that the public interface won't change so 
often. I'm picking the most extreme case I can think of, in order 
to argue the point from a different perspective.


so its attributes will be auto-inferred, but the function is 
still public, so downstream users will wind up using it.


3 months later, I realize my mistake, and add the @api 
attribute -- at which point downstream users' code will break 
if their code was relying on the unintended inferred attributes.


Attribute inference provides convenience, not guarantees. If a 
user was relying on the purity of a function which was never 
marked 'pure', it's only convenience which allows him to do it, 
both on the part of the user, for adding 'pure', and the library 
writer, for *not* adding it. Adding @api (or 'extern (noinfer)') 
cancels that convenience for the sake of modularity. It's a 
tradeoff. The problem  itself is solved either by the library 
writer marking the function 'pure', or the user removing 'pure' 
from his own function. Without @api, the problem only arises when 
the library writer actually does something impure, which makes 
perfect sense. It's @api (and D's existing default, by the way) 
which adds the artificiality to the process, not my suggested 
default.


It's quite analogous in this respect to the argument about 
final vs. virtual by default for class methods.


I don't think so, because of so-called covariance. Final and 
virtual each have their own advantages and disadvantages, whereas 
inferring attributes only goes one way. There is no cost to 
inferring in the general case. My suggestion, (I now prefer 
'extern(noinfer)'), does absolutely nothing except to restore D's 
existing default, for what I think are the rare cases it is 
needed. I could be wrong about just how rare using 
extern(noinfer) will actually be, but consider that phobos, for 
example, just doesn't need it, because it's too small a library 
to cause trouble if all of a sudden one of its non-templated 
functions becomes impure. A quick recompile, a new interface 
file, and now everyone's using the new thing. Even today, it's 
not even marked up with attributes completely, thus indicating 
that you never even *could* have used it for all it's worth.


Have I convinced you?


@api: One attribute to rule them All

2015-01-05 Thread Zach the Mystic via Digitalmars-d
Hello everybody. My name is Zach, and I have a suggestion for the 
improvement of D. I've been looking at the following stalled pull 
request for a while now:


https://github.com/D-Programming-Language/dmd/pull/1877

...in which Walter Bright wants to introduce built-in-attribute 
inference for a relatively small set of functions. It seems like 
the most obvious thing in the world to me to desire this, and not 
even just for 'auto' and templated functions, but for *every* 
function. And there's no reason it can't be done. So long as the 
compiler has everything it needs to determine which attributes 
can be applied, there's no reason to demand anything from the 
programmer. Look how simple this function is:


int plusOne(int a) { return a+1; }

Let's say I later want to call it, however, from a fully 
attributed function:


int plusTwo(int a) pure nothrow @safe @nogc  {
  return plusOne(plusOne(a));
}

I get a compiler error. The only way to stop it is to add 
unnecessary visual noise to the first function. All of these 
attributes should be something that you *want* to add, not 
something that you *need*. The compiler can obviously figure out 
if the function throws or not. Just keep an additional internal 
flag for each of the attributes. When any attribute is violated, 
flip the bit and boom, you have your implicit function signature.


I think this is how it always should have been. It's important to 
remember that the above attributes have the 'covariant' property, 
which means they can always be called by any function without 
that property. Therefore no existing code will start failing to 
compile. Only certain things which would have *errored* before 
will stop. Plus new optimizations can be done.


So what's the problem? As you can read in the vehement opposition 
to pull 1877 above, the big fear is that function signatures will 
start changing willy-nilly, causing the exposed interface of the 
function to destabilize, which will cause linker errors or 
require code intended to be kept separate in large projects to be 
recompiled at every little change.


I find this depressing! That something so good should be ruined 
by something so remote as the need for separate compilation in 
very large projects? I mean, most projects aren't even very 
large. Also, because D compiles so much faster than its 
predecessors, is it even such a big deal to have to recompile 
everything?


But let's admit the point may be valid. Yes, under attribute 
inference, the function signatures in the exposed API will indeed 
find themselves changing every time one so much as adds a 
'printf' or calls something that throws.


But they don't *have* to change. The compiler doesn't need to 
include the inferred attributes when it generates the mangled 
name and the .di signature, only the explicit ones. From within 
the program, all the opportunities for inference and optimization 
could be left intact, while outside programs accessing the code 
in precompiled form could only access the functions as explicitly 
indicated.


This makes no change to the language, except that it allows new 
things to compile. The only hitch is this: What if you want the 
full advantages of optimization and inference from across 
compilation boundaries? You'd have to add each of the covariant 
function attributes manually to every function you exposed. From 
my perspective, this is still a chore.


I suggest a new attribute, @api, which does nothing more than to 
tell the compiler to generate the function signature and mangle 
the name only with its explicit attributes, and not with its 
inferred ones. Inside the program, there's no reason the compiler 
can't continue to use inference, but with @api, the exposed 
interface will be stabilized, should the programmer want that. 
Simple.


I anticipate a couple of objections to my proposal:

The first is that we would now demand that the programmer decide 
whether he wants his exposed functions stabilized or not. For a 
large library used by different people, this choice might pose 
some difficulty. But it's not that bad. You just choose: do you 
want to improve compilation times and/or closed-source 
consistency by ensuring a stable interface, or do you want to 
speed up runtime performance without having to clutter your code? 
Most projects would choose the latter. @api is made available for 
the those who don't. The opposition to attribute inference put 
forth in pull 1877 is thereby appeased.


A second objection to this proposal: Another attribute? Really? 
Well, yeah.


But it's not a problem, I say, for these reasons:

1. This one little attribute allows you to excise gajillions of 
unnecessary little attributes which are currently forced on the 
programmer by the lack of inference, simply by appeasing the 
opponents of inference and allowing it to be implemented.


2. It seems like most people will be okay just recompiling 
projects instead of preferring to stabilize their apis. Thus, 
@api 

Re: @api: One attribute to rule them All

2015-01-05 Thread Daniel N via Digitalmars-d

On Monday, 5 January 2015 at 21:15:00 UTC, Zach the Mystic wrote:

Now, Bombard with your gunships.



An alternative could be to use the already existing 'export'.

http://dlang.org/attribute.html
Export means that any code outside the executable can access the 
member. Export is analogous to exporting definitions from a DLL.