Thread overview
"deprecated" Attribute
Apr 21, 2004
James Widman
Apr 21, 2004
Matthew
Apr 22, 2004
James Widman
Apr 22, 2004
Stewart Gordon
Apr 22, 2004
Stewart Gordon
Apr 23, 2004
James Widman
Apr 23, 2004
James Widman
April 21, 2004
First of all, thanks to all who contribute to D. I've never been so thoroughly inspired by a programming language spec before.  But maybe part of that comes from reading the ISO C++ standard on an almost daily basis. :-)

One thing about "deprecated" though:  I don't see anything in the syntax to suggest where the library writer can insert an explanation or suggest alternative functions. E.g.:

deprecated (r"[insert informative URL here]", newmod1, newmod2)
    {
    void oldF() reason ("Cuts mustard poorly", newmod1.F1, newmod2.F2)
        {}
    void oldB() {}
    }

upon use of oldF and oldB, compiler reports: Warning: oldF has been deprecated. Reason: Cuts mustard poorly. Use newmod1.F1 or newmod2.F2 instead.

Warning: oldB has been deprecated. Reason:[insert informative URL here]. Refer to the documentation for modules 'newmod1' or 'newmod2'.

Admittedly, the syntax in this example may not be the best. :-)

Can we expect something like this for 2.0?

Thanks,

James
April 21, 2004
If you can come up with a good syntax, and solid reasoning, I don't see why it can't slip in earlier.

"James Widman" <james@jwidman.dot.com> wrote in message news:james-AE6F62.01285221042004@news.digitalmars.com...
> First of all, thanks to all who contribute to D. I've never been so thoroughly inspired by a programming language spec before.  But maybe part of that comes from reading the ISO C++ standard on an almost daily basis. :-)
>
> One thing about "deprecated" though:  I don't see anything in the syntax to suggest where the library writer can insert an explanation or suggest alternative functions. E.g.:
>
> deprecated (r"[insert informative URL here]", newmod1, newmod2)
>     {
>     void oldF() reason ("Cuts mustard poorly", newmod1.F1, newmod2.F2)
>         {}
>     void oldB() {}
>     }
>
> upon use of oldF and oldB, compiler reports:
> Warning: oldF has been deprecated. Reason: Cuts mustard poorly. Use
> newmod1.F1 or newmod2.F2 instead.
>
> Warning: oldB has been deprecated. Reason:[insert informative URL here]. Refer to the documentation for modules 'newmod1' or 'newmod2'.
>
> Admittedly, the syntax in this example may not be the best. :-)
>
> Can we expect something like this for 2.0?
>
> Thanks,
>
> James


April 22, 2004
In article <c65145$2b9b$1@digitaldaemon.com>,
 "Matthew" <matthew.hat@stlsoft.dot.org> wrote:
> If you can come up with a good syntax, and solid reasoning, I don't see why it can't slip in earlier.

[apologies in advance for the length of this message]

Reasoning:
==========
Here's a real-world example.  When compiling a C project on my linux box
with gcc, I get this at link time:

foo.o(.text+0x1096): In function `bar':

/home/james/src/proj/foo.c:1933: warning: the use of `tmpnam' is dangerous , better use `mkstemp'

Which tells me:
1) I'm doing something wrong (tmpnam is deprecated).
2) Why it's wrong (tmpnam is dangerous).
3) A recommended course of action (replace it with mkstemp).

This is a feature that users of C and C++ have had for a long time, so it behooves us to provide it in D.   Besides, (2) and (3):

- help the library writer to get the word out about deprecated symbols. - motivate the lib user to make the fix and allow him/her to make it faster by virtue of (3).

I can see two ways to support this.  One is to extend the existing "deprecated" syntax (if the following looks like too much cruft to you, skip to the bottom):

*DeprecatedAttribute*:
   *DeprecatedAttributeBlock*
   *DeprecatedAttributeDecl*

*DeprecatedAttributeDecl*:
   deprecated *DeprecatedDeclDef*

*DeprecatedAttributeBlock*:
   deprecated { *DeprecatedDeclDefs* }

DeprecatedDeclDefs*:
   *ReasonBlock* *ReasonedDeclDefs*
   *ReasonedDeclDefs*

*ReasonBlock*:
   why *ReasonParams* *DeclDefBlock*  [symbols to use instead]
   [nothing]

*ReasonParams*:
   ()
   ( *String* )   [Human-readable explanation, URL pointing to same,
etc.]

*ReasonedDeclDefs*:
   *ReasonedDeclDef*
   *ReasonedDeclDef* *ReasonedDeclDefs*

*ReasonedDeclDef*:
   *BasicType* *Declarators* *ReasonBlock* ;
   *BasicType* Declarator* *ReasonBlock* *FunctionBody*

If it looks like sucky syntax, that's because this is the first time I've written syntax for a language. :-)

Note the introduction of keyword "why".  I'm not sure this is necessary.




The presumption is that a library writer may want to use a single ReasonBlock to refer to several symbols, or one ReasonBlock for each symbol.

The second way to do it is as a pragma:

pragma(deprecated, *String* *NewIdentifierList*) *DeprecatedSymbols*

*NewIdentifierList*:
   [nothing]
   , *Identifier*
   , *Identifier* , *IdentifierList*

*DeprecatedSymbols*:
   *Declaration*
   *DeclarationBlock*
   : *Declarations*

I think I like it better this way because it does the same thing with a lot less syntax. :-)
April 22, 2004
James Widman wrote:

<snip>
> One thing about "deprecated" though:  I don't see anything in the syntax to suggest where the library writer can insert an explanation or suggest alternative functions. E.g.:
> 
> deprecated (r"[insert informative URL here]", newmod1, newmod2)
>     {     void oldF() reason ("Cuts mustard poorly", newmod1.F1, newmod2.F2)
>         {}
>     void oldB() {}
>     }
<snip>

Why have the extra complexity of the 'reason' syntax at all?  This would suffice for your purpose:

deprecated ("Cuts mustard poorly", newmod1.F1, newmod2.F2)
void oldF() {}

deprecated ("[insert informative URL here]", newmod1, newmod2)
void oldB() {}

FWIW, even simpler would be to have the whole message in the string, rather than build it up like this.  The only real advantage is that a documentation tool can easily linkify the alternative functions.  I guess it's a matter of debate whether such detail should be left to the documentation comments....

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
April 22, 2004
Stewart Gordon wrote:

<snip>
> FWIW, even simpler would be to have the whole message in the string, rather than build it up like this.  The only real advantage is that a documentation tool can easily linkify the alternative functions. 

Oops, I meant the only real advantage of having the string, functionname, functionname syntax....

> I guess it's a matter of debate whether such detail should be left to the documentation comments....
> 
> Stewart.
> 


-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
April 23, 2004
In article <c68ega$237i$1@digitaldaemon.com>,
 Stewart Gordon <smjg_1998@yahoo.com> wrote:
> Why have the extra complexity of the 'reason' syntax at all?

Yep.  I see now that 'reason' is totally unnecessary.

I was trying to avoid more complexity in the parser in the case where a return type is parenthesized---but that won't happen (somehow I mixed up the grammar for return types and declarators).

I should have checked the grammar earlier.  Thanks. :-)

Ok, so the alternatives are:
1)  "deprecated" extension:

*Attribute*:
   *DeprecatedAttribute*
*DeprecatedAttribute*:
   deprecated
   deprecated ( *ReasonExpr* )
*ReasonExpr*:
   *String*
   *IdentifierList*
   *StringLiteral* , *NewIdentifiers*
*NewIdentifiers*:
   *IdentifierList*
   *IdentifierList* , *NewIdentifiers*

2) Make it a pragma.  (Benefit (or so I think):  it fits cleanly into the existing pragma grammar, so *presumably* it's less work for the implementor.)

pragma(deprecated, *ReasonExpr* ) *DeclDefBlock*
pragma(deprecated, *ReasonExpr* ) : *Decls*

I really don't know which of these is better.  Anyone?

> FWIW, even simpler would be to have the whole message in the string, rather than build it up like this.

Yes.

> The only real advantage is that a documentation tool can easily linkify the alternative functions.

Yes. And an IDE wise to it can also let the lib user click on that alternative and go straight to its declaration or documentation.  Us Vim (or Emacs) users will probably be using a D-Tags plugin though. :-)

> I guess it's a matter of debate whether such detail should be left to the documentation comments....

Well, in addition to the above, note that tyops are a PITA. ;-)

Under the assumption that people's plates are already full with fixes and enhancements to do, I'd like to start implementing this as soon as someone authoritative gives the go-ahead.
April 23, 2004
In article <james-49412E.21183222042004@digitalmars.com>,
 James Widman <james@jwidman.com> wrote:
> *ReasonExpr*:
>    *String*
>    *IdentifierList*
>    *StringLiteral* , *NewIdentifiers*

Oops. That should be:

*ReasonExpr*:
   *StringLiteral*
   *NewIdentifiers*
   *StringLiteral* , *NewIdentifiers*

Once more:
*Attribute*:
   *DeprecatedAttribute*
*DeprecatedAttribute*:
   deprecated
   deprecated ( *ReasonExpr* )
 *ReasonExpr*:
    *StringLiteral*
    *NewIdentifiers*
    *StringLiteral* , *NewIdentifiers*
*NewIdentifiers*:
    *IdentifierList*
    *IdentifierList* , *NewIdentifiers*

Attribute, StringLiteral, and IdentifierList have the same meaning here as in the spec.