September 02, 2012
On Saturday, 1 September 2012 at 21:50:33 UTC, Dmitry Olshansky wrote:
> On 02-Sep-12 01:13, foobar wrote:
> [snip]
> >
> > I skipped the details but I do agree with the general
> sentiment.
> > This long post begs the question - Why a general annotation
> > mechanism isn't enough to justify adding so much complexity to
> > the language?
>
> It's quite short compared to all of the features it replaces and it had to allow for backwards compatibility. And it had to leave place for other @annotations as I felt restricting blocks of code is not the only use case for annotations.
>
> Also sadly it reiterates a lot of trivia around how tagged functions and pointers interact with each another.
>
> About general annotation mechanism. Nobody yet put together a proper proposal (if any at all), all I see is people that keep saying: "it's simple - just add the general annotation mechanism!".
>

This basically reiterates the original post without answering my question.
Regarding the general mechanism - Why do we have to re-invent the wheel?
There already is a very successful model used by Java, C# and even C++11 (with slight variations). My "proper proposal" would than to simply look at the C# documentation!

>
> > Me thinks that simply tagging malloc/alloca/GC.allocate/etc..
> > with a _user defined_ annotation should be sufficient without
> the
> > need to introduce all of the above syntax to the language.
>
> Simple tags have no much use on their own - need syntax to use them.
> The compiler can deduce their meaning so you also need a way tell the compiler: this function can only use "yellow" and "green" functions. Then some tags need to be compatible (or convertible with others), then there is a need to bundle tags together and so on.
>
> I agree that simply tagging functions with red/green is attractive and simple concept but to implement things like say @safe you need more then that. You need to tweak what compiler puts in there for you (and forbid/allow as it suits your needs).
>

We already have at least part of the syntax in D.
There is no need to "tweak the compiler", everything can be implemented in user code as shown in the link I provided. Including a proof of concept implementation in D, thanks to Bartosz.

>  In
> > fact, I have a vague memory of reading about green/red
> marking of
> > code via templates in plain old c++. No extra syntax required.
> >
> But xxtra works obviously :)
> The method entails carrying around tag arguments apparently. It could be labeled as creative but a very backward way to do something simple. More specifically it shows that this has to be a language feature so that developers can focus on using it instead of being busy implementing it by hand.
>
> > Here's the link:
> > http://www.artima.com/cppsource/codefeaturesP.html

Again, this is a proof of concept that shows that even current D is sufficient to implement this sort of restrictions. Add annotations to the mix and you could implement this with a better syntax without the need to add extra parameters to functions (which is quite an elegant solution imo)
No need for developers to implement this "by hand". Any language with a meta-data facility also provides standard annotations in its stdlib. If such restrictions are general purpose and useful enough they'll end up in Phobos anyway, allowing developers to concentrate on using them.

September 02, 2012
On 09/02/2012 12:08 PM, foobar wrote:
>
> This basically reiterates the original post without answering my question.
> Regarding the general mechanism - Why do we have to re-invent the wheel?

No need to re-invent the wheel, but it needs to be tweaked because the
vehicle it should be attached to has different features than other cars.

September 02, 2012
2012/9/1 Dmitry Olshansky <dmitry.olsh@gmail.com>:
> On 01-Sep-12 17:01, Adam D. Ruppe wrote:
>>
>> On Saturday, 1 September 2012 at 12:39:41 UTC, Dmitry Olshansky wrote:
>>>
>>> I'd say
>>> @nogc:
>>> at the top and deal is sealed.
>>
>>
>> BTW don't forget a @yesgc would be good to counter it. We need a way to turn off each attribute to use this pattern best.
>
>
> What I see with this @nogc proposal is that that problem it tries to solve (and tool used to do so) is far more interesting and general.
>

This reminds me custom attributes discussion which can be found in NG archive.
Requested language additions relevant to attributes may be divided
into three groups:

1 (tags). We want to tag some (likely function) declarations like
@nogc. This addition has several issues:
- can tags carry additional information (for e.x @tag(atrr1=opened))?
- are they part of type or not (similar problems with default arguments)?
- are they user-defined or entirely built in the language?
- how to distinguish between restricted and permissive semantic (when
tagged function care about
whether they call non-tagged functions or not)?

In this case possible solutions are to link user-defined enumeration
types to existing @syntax
or to create entirely new syntax for purpose of holding additional
information (@tag(atrr1=opened)
where @attr1 refers to enum attr1{} ). Simply tagged functions
(@tag(name)) would have restrictive
semantics. Another possible solution would be that construction
"@tag(attr1=value) type symbol;" is rewritten as
struct __name {type symbol; enum att1 = value; alias type this; } -
just not to add brand new features
which are hard to implement and easy to introduce bugs.

2 (extending type). We want to define type (likely classes) and then
extend its functionality.
AFAIK C# attributes belong to this camp (correct me if I am wrong). In
this case (likely class) type implicitly derives
from attribute class. Obviously this also related to compile time
because D being static typed language and has no
way to be aware at run time that type functionality was extended. I
think that it is not worth embedding in the language, because
it is already possible to derive from base class, or interface, or
instantiated template or to use mixin.

3 (extending instance). We want to make some instance of (extremely
likely class) type to extend functionality
while still remaining in original type without affecting type.
Obviously this can be done only in run-time
where actual instance of type is created.

In this case possible solutions are to put associative array or some
container in druntime (object.Object) which export
attributes for e.x. through .attributeof property.

I offer simple solutions because I estimate probability of introducing
complex addition to the language now as
extremely low.
September 02, 2012
On Saturday, 1 September 2012 at 02:52:23 UTC, bearophile wrote:
> One more comment, a quotation from the DIP18:
>
>>Currently, all functions can use garbage collected memory. Threads that call those functions must be managed by the garbage collector, which may occasionally suspend them to perform collection. This can lead to unwanted pauses, that are not acceptable in some situations, mainly real-time audio/video processing, gaming, and others.<
>
> C heap functions like malloc(), calloc(), realloc() have the same problem, their run-time is not deterministic, so if you don't want pauses a @noheap is useful.
>
> @noheap is not meant to forbid calling low-level system-specific memory allocation functions.
>
> Bye,
> bearophile

It looks very much that several annotations are actually directed at the compiler or the runtime for specific optimisations.
The @ could be used (or are used) as local compiler switches or runtime hints.
September 02, 2012
On Saturday, 1 September 2012 at 16:08:08 UTC, Dmitry Olshansky wrote:

> In fact if pure @safe nothrow could be combined in a user defined tag:
>
> alias pure @safe nothrow nogc nice_func;
>
> nice_func int mul(int x, int y);
>

That would be awesome.
September 02, 2012
On Saturday, 1 September 2012 at 16:20:14 UTC, Dmitry Olshansky wrote:
....
> 6. Probably we need a way to alias a list of restictions to ease the use of frequent combinations. (No idea, but any sane syntax around alias will do)

So you can tailor precisely the language to your own requirements, by basically inserting compiler switches in the code.
That is a very smart idea, but I don't see how this could play well with most of the std lib.

September 03, 2012
On Sunday, 2 September 2012 at 16:59:19 UTC, Maxim Fomin wrote:

> This reminds me custom attributes discussion which can be found in NG archive.
> Requested language additions relevant to attributes may be divided
> into three groups:
>
> 1 (tags). We want to tag some (likely function) declarations like @nogc.

IMO, this is a poor choice.

> 2 (extending type). We want to define type (likely classes) and then
> extend its functionality.
> AFAIK C# attributes belong to this camp (correct me if I am wrong). In
> this case (likely class) type implicitly derives
> from attribute class. Obviously this also related to compile time
> because D being static typed language and has no
> way to be aware at run time that type functionality was extended. I
> think that it is not worth embedding in the language, because
> it is already possible to derive from base class, or interface, or
> instantiated template or to use mixin.

This is my preferred solution. This is also similar to Java. In fact there are only small differences between C# and Java semantics. This also includes other languages on the matching platforms, E.g. Nemerle is a .net language and provides the same attributes mechanism as C#. I assume that Scala does the same with Java annotations.

The C# way (which I slightly prefer over the Java one):
class Whatever : Annotation { // user defined annotation type
}

Java uses @interface to define a user defined annotation.
@interface whatever { // user defined annotation type
}

I don't get your last point at all regarding inheritance - in both Java and C# it should be possible to use polymorphism with annotations. No need to add a new mechanism for it.
class Foo : whatever {} // inheritance

Really, the main things that are needed inside the compiler are a mechanism to attach custom attributes to various lingual parts, a way to mark such custom attributes by e.g. deriving from a special class (not unlike the IUnknown interface in D for COM) and standard compiler APIs for usage inside such an attribute.
One extra step is defining an execution model for custom attributes:
Java way is multi-pass - compiler executes the annotations which generate new version of the code, which is run through the compiler again, and so forth.
Nemerle way - attributes can be macros which in turn can manipulate the AST.
etc..

>
> 3 (extending instance). We want to make some instance of (extremely likely class) type to extend functionality
> while still remaining in original type without affecting type.

I don't get this at all. What's the purpose of having a single type?

>
> I offer simple solutions because I estimate probability of introducing
> complex addition to the language now as
> extremely low.


September 03, 2012
On 1 September 2012 19:08, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:

> On 01-Sep-12 19:58, Peter Alexander wrote:
>
>> C:
>>
>> int mul(int x, int y);
>>
>>
>> Future D:
>>
>> pure @safe nothrow nogc commutative associative distributive @forceinline mayoverflow int mul(int x, int y);
>>
>>
> No it's GNU C++ of today just replace 'pure' with __attribute__((pure))
> and you are done :)
> And don't even get me started at MS extensions...
>
> Either way this is a kind of thing that only some users need but std library have to use all of them just so that those 'some users' can use it.
>
> In fact if pure @safe nothrow could be combined in a user defined tag:
>
> alias pure @safe nothrow nogc nice_func;
>
> nice_func int mul(int x, int y);
>
> and even C has it via macros, damn...


Aside the context of this thread, this would actually be REALLY useful. I
think I've asked about it a few times before.
There is already a fairly annoying problem where GDC supports GNU
attributes that DMD doesn't know about, which are basically impossible to
use; there's no nice way to use compiler-specific attributes without some
sort of alias like this.
I think the only current way is to duplicate the definitions in different
version blocks.
An attribute alias would be super handy, particularly when abstracting
support for multiple compilers.


September 03, 2012
Dmitry Olshansky wrote:
> On 01-Sep-12 19:58, Peter Alexander wrote:
>> C:
>>
>> int mul(int x, int y);
>>
>>
>> Future D:
>>
>> pure @safe nothrow nogc commutative associative distributive
>> @forceinline mayoverflow int mul(int x, int y);
>>
>
> Either way this is a kind of thing that only some users need but std
> library have to use all of them just so that those 'some users' can use it.

The DIP states that nogc should be inferred by the compiler to avoid marking all existing functions.

But, I know there are some problems with inferring non templated methods: http://www.digitalmars.com/d/archives/digitalmars/D/Why_isn_t_purity_co._inferred_for_all_functions_166946.html.
September 03, 2012
Dmitry Olshansky wrote:
> On 01-Sep-12 17:01, Adam D. Ruppe wrote:
>> On Saturday, 1 September 2012 at 12:39:41 UTC, Dmitry Olshansky wrote:
>>> I'd say
>>> @nogc:
>>> at the top and deal is sealed.
>>
>> BTW don't forget a @yesgc would be good to counter it. We need
>> a way to turn off each attribute to use this pattern best.
>
> What I see with this @nogc proposal is that that problem it tries to
> solve (and tool used to do so) is far more interesting and general.
>
> Namely the problem is to specify that some functions can call only
> specific subset of functions and able to use only specific subset of
> language features. It's more far reaching then just gc, one may want to
> get @noblocking  or @async attribute to statically check e.g. that GUI
> thread can't ever block.
> (it would however require to identify API calls that don't block, not
> possible on every OS, might entail some wrappers etc. but is very
> desirable)

[snip]

> The idea in a nutshell:

[snip]

How the attribute inferring works in this proposal?