API deprecate marking

548 views
Skip to first unread message

Henry Adi Sumarto

unread,
Apr 28, 2015, 12:24:37 AM4/28/15
to golan...@googlegroups.com
Hi,
I wonder whether the Go Team has considered adding a feature to the language that allows developers to deprecate functions that are no longer supported. In C#, you can just mark a method as obsolete. Existing code can still use the deprecated method, but the compiler will throw a warning. Going through the package documentation and manually check existing code for obsolete APIs is quite a manual labor. If the compiler can help with this one it would be a blast. Perhaps it can be implemented with a special form of comment that the compiler can recognize?

Thanks.

Henry

Ian Lance Taylor

unread,
Apr 28, 2015, 12:32:23 AM4/28/15
to Henry Adi Sumarto, golang-nuts
On Mon, Apr 27, 2015 at 7:30 PM, Henry Adi Sumarto
<henry.ad...@gmail.com> wrote:
>
> I wonder whether the Go Team has considered adding a feature to the language that allows developers to deprecate functions that are no longer supported. In C#, you can just mark a method as obsolete. Existing code can still use the deprecated method, but the compiler will throw a warning. Going through the package documentation and manually check existing code for obsolete APIs is quite a manual labor. If the compiler can help with this one it would be a blast. Perhaps it can be implemented with a special form of comment that the compiler can recognize?

I think that Go would be more likely to implement that via an external
tool, not the compiler. If there is a clear consensus that this is
desirable, and on how it should be implemented, it's possible that it
could become a go vet warning.

Personally, it's not clear to me how useful this would be. What does
it mean to deprecate a function? In the Go world the existing
function ought to keep working. So my best guess is that deprecating
a function means that calls to that function should call some other
function instead, with additional options. That could perhaps be done
by providing input for the eg tool. Is that what we might want?

Do you have any examples in mind?

Ian

andrewc...@gmail.com

unread,
Apr 28, 2015, 12:55:13 AM4/28/15
to golan...@googlegroups.com
If it was going to be done, I think tag in the doc string and a go vet warning would be a pretty decent approach. Just don't deprecate anything that works until the alternative is done and dusted :).

Henry Adi Sumarto

unread,
Apr 28, 2015, 5:09:57 AM4/28/15
to golan...@googlegroups.com, henry.ad...@gmail.com
Let's consider the following situation:
  • Let's say Team A writes a library. The code written by Team A is consumed by Team B. Team B writes other part of the program that makes use of the component written by Team A. Team B does not need to know anything about how Team A's library works. Team B just uses it, like a black box.
  • Later, Team A decides to extend the library. While doing so, Team A realizes that there is no way to squeeze additional functionality into the existing APIs. New APIs have to be added to supersede the old ones. Team A wants the library users (Team B) to no longer use the older APIs for future development, but the old APIs are still there for backward compatibility purposes. Team A marks the older APIs as obsolete (or deprecated in Java).
  • Team B updates the component written by Team A. Team B has no clue what has changed in the component and they don't need to know. When they try to compile, Team B's code still work (because the older APIs are still there) but they receive warning from the compiler that they use obsolete types/functions that the library writer (Team A) has discouraged to use. It would be better if the message also includes reference to the new APIs that Team A recommends. Team B can choose to ignore it and use the new APIs for future development, or refactor existing codes to adopt the new APIs.
  • Over time, when everybody has moved to the new APIs and Team A is sure that nobody no longer refers to the old APIs, Team A may even remove the old APIs from the library. 
I think this is a very common scenario. As the code evolves, APIs too will change. Java has deprecated hundreds of APIs in its standard library. The same goes with C#. If we are talking about one dependency, then it may not be much of a problem. Imagine if you are in Team B's position and Team B's code relies on many libraries written by other people whom they haven't even met. Going through all the library documentation to see what has changed and checking existing code for obsolete APIs one by one is quite a masochistic activity.

In C#, you can just do this:
[Obsolete]
public static string FormatAddress(string address){ //Old method. It supports format for local address only. Use the new method instead
 
...
}

public static string FormatAddress(string address, CountryCode country){//New method. It supports internationalization.
 
...
}

Sorry for the lengthy post. I hope the example is clear. 

Henry

Dave Cheney

unread,
Apr 28, 2015, 5:39:06 AM4/28/15
to golan...@googlegroups.com
> Imagine if you are in Team B's position and Team B's code relies on many libraries written by other people whom they haven't even met. Going through all the library documentation to see what has changed and checking existing code for obsolete APIs one by one is quite a masochistic activity.

Not at all, I believe this is part of delivering a product. Just because team B may have built their solution on components that they have outsourced does not mean team B are excused from knowing what goes into the solution they provide. If team B consume so many dependencies without knowing why or what they provide in detail it would seam that that is the root of the problem.

Dave

Henry Adi Sumarto

unread,
Apr 28, 2015, 6:10:44 AM4/28/15
to golan...@googlegroups.com
Hi Dave,

It wasn't my intention to say that Team B does not need to know anything at all about the libraries they use. They still need to know what the library does and how to use it. The details on how it gets implemented is what they don't need to know.  

Anyhow, what I propose isn't exactly a new invention. Java, C#, and possibly other languages have had it for years. If there isn't any merit in it, they would not have adopted it. Sure, if you want to stick to extreme minimalism, you can still do it manually without any tool, which is fine for small projects. However, I believe the obsolete / deprecate feature helps communicate what the library designers have in mind on how the library is supposed to be used. Not everybody writes great documentation though. 

Paul Borman

unread,
Apr 28, 2015, 1:08:44 PM4/28/15
to Henry Adi Sumarto, golang-nuts
I like what Ian said about using an external tool.  Team B, being a thoughtful team and wanting to provide long term viability for their product, probably would making using that external tool be part of their normal development and testing environment.  This would not require a language change, just a trigger.  Probably something as simple as, at the bottom of the doc comment for the function, variable, or package:

//
// DEPRECATED: a nice meaningful warning message about using NewFoo instead
func OldFoo() {

Even without running the tool, as Dave mentions, team B would hopefully notice the DEPRECATED comment in the generated documentation.


I guess my concern would be going down the slippery slope.  Someone is going to want DEPRECATED to mean one thing and OBSOLETE to mean something stronger, then someone will want the ability to add bold faced important notices and perhaps italics or font change or ... 

    -Paul

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chris Hines

unread,
Apr 28, 2015, 1:10:55 PM4/28/15
to golan...@googlegroups.com, henry.ad...@gmail.com
Team A could version their APIs and change the version when breaking changes are made. (See e.g. http://gopkg.in as an implementation of this idea). Perhaps another tool can scan a project and report imports of older APIs.

Chris

Ian Lance Taylor

unread,
Apr 28, 2015, 1:41:46 PM4/28/15
to Henry Adi Sumarto, golang-nuts
On Tue, Apr 28, 2015 at 2:09 AM, Henry Adi Sumarto <henry.ad...@gmail.com> wrote:

  • Later, Team A decides to extend the library. While doing so, Team A realizes that there is no way to squeeze additional functionality into the existing APIs. New APIs have to be added to supersede the old ones. Team A wants the library users (Team B) to no longer use the older APIs for future development, but the old APIs are still there for backward compatibility purposes. Team A marks the older APIs as obsolete (or deprecated in Java).

As part of deprecating the old API, team A writes input for the eg tool (golang.org/x/tools/cmd/eg) to convert the old API to the new one.
 
  • Team B updates the component written by Team A. Team B has no clue what has changed in the component and they don't need to know. When they try to compile, Team B's code still work (because the older APIs are still there) but they receive warning from the compiler that they use obsolete types/functions that the library writer (Team A) has discouraged to use. It would be better if the message also includes reference to the new APIs that Team A recommends. Team B can choose to ignore it and use the new APIs for future development, or refactor existing codes to adopt the new APIs.

When team B updates the component, they see the release notes and run the eg tool input.  Their code is updated.

I have no idea if this would work in general but it seems like a better approach than marking a function as deprecated.  I would prefer to consider that approach first.

Ian

Joubin Houshyar

unread,
Apr 28, 2015, 6:03:12 PM4/28/15
to golan...@googlegroups.com, henry.ad...@gmail.com

On Tuesday, April 28, 2015 at 1:41:46 PM UTC-4, Ian Lance Taylor wrote:
On Tue, Apr 28, 2015 at 2:09 AM, Henry Adi Sumarto <henry.ad...@gmail.com> wrote:

  • Later, Team A decides to extend the library. While doing so, Team A realizes that there is no way to squeeze additional functionality into the existing APIs. New APIs have to be added to supersede the old ones. Team A wants the library users (Team B) to no longer use the older APIs for future development, but the old APIs are still there for backward compatibility purposes. Team A marks the older APIs as obsolete (or deprecated in Java).

As part of deprecating the old API, team A writes input for the eg tool (golang.org/x/tools/cmd/eg) to convert the old API to the new one.

Typically API deprecation is not an atomic transition. 
 
 
  • Team B updates the component written by Team A. Team B has no clue what has changed in the component and they don't need to know. When they try to compile, Team B's code still work (because the older APIs are still there) but they receive warning from the compiler that they use obsolete types/functions that the library writer (Team A) has discouraged to use. It would be better if the message also includes reference to the new APIs that Team A recommends. Team B can choose to ignore it and use the new APIs for future development, or refactor existing codes to adopt the new APIs.

When team B updates the component, they see the release notes and run the eg tool input.  Their code is updated. 

I have no idea if this would work in general but it seems like a better approach than marking a function as deprecated.  I would prefer to consider that approach first.

Doesn't seem very general. Also note that 2 actions in your prop -- updated release notes & read the darn thing -- are out of band actions.

I liked Andrew's suggestion. 

Ideally the godoc tool should also surface this bit of meta-info about the API to the devs. It could even emit the itemized list of deprecated funcs for you to manually put in the release notes.


Ian

Matt Silverlock

unread,
Apr 28, 2015, 8:36:38 PM4/28/15
to golan...@googlegroups.com
  • If the consumer (Team B) is just updating/pulling their dependencies from master day-after-day, I think there's an expectation that there may be breaking changes.
  • If Team B is NOT updating their dependencies, then they'll never know what's deprecated (in a world where they aren't keeping tabs on critical deps)
  • If Team B cares about re-producible builds, then vendoring dependencies (godep, gb, etc.) makes the need to "deprecate" things a non-issue. You would (should!) pull any new deps into branches, refactor/update as needed, and then merge in.
My issue with some kind of DEPRECATED tag (ala TODO, or BUG) is that there's a solution: vendoring. 



On Tuesday, April 28, 2015 at 4:24:37 PM UTC+12, Henry Adi Sumarto wrote:

Henry Adi Sumarto

unread,
May 5, 2015, 7:35:58 AM5/5/15
to golan...@googlegroups.com
Hi,

I have just realized that there is a go tool called "gofix" that automatically update references to the old APIs to the new ones. I can't find further documentation how this gofix works. For example, how do you mark deprecated APIs so that gofix would understand? If there is any code example, it would be great.

Thanks. 

Henry

Ian Lance Taylor

unread,
May 5, 2015, 2:05:27 PM5/5/15
to Henry Adi Sumarto, golang-nuts
On Tue, May 5, 2015 at 4:35 AM, Henry Adi Sumarto
<henry.ad...@gmail.com> wrote:
>
> I have just realized that there is a go tool called "gofix" that
> automatically update references to the old APIs to the new ones. I can't
> find further documentation how this gofix works. For example, how do you
> mark deprecated APIs so that gofix would understand? If there is any code
> example, it would be great.

gofix is itself somewhat deprecated, since although it's quite
powerful it's quite hard to use. For most cases,
golang.org/x/tools/cmd/eg is a lot better.

Ian

Andrew Chambers

unread,
May 5, 2015, 6:22:10 PM5/5/15
to Ian Lance Taylor, Henry Adi Sumarto, golang-nuts
Hadn't heard of the eg tool before, is there any sort of blog post or good description of all the refactoring tools that are available and how to use them?


--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/aRhTutV27SI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.

Dave Cheney

unread,
May 5, 2015, 6:39:46 PM5/5/15
to golan...@googlegroups.com, andrewc...@gmail.com, henry.ad...@gmail.com, ia...@golang.org
Not a blog post per se, but there is this presentation by the eg author, Alan Donovan from Gotham Go last year, https://vimeo.com/114736889 

old...@google.com

unread,
Dec 10, 2015, 5:29:41 PM12/10/15
to golang-nuts
Is there a supported way to mark a flag (command-line option) as deprecated?

Tyler Compton

unread,
Dec 11, 2015, 3:45:27 PM12/11/15
to golang-nuts
Vendoring does not get rid of the need for a way to communicate about the evolution of an API in the real world. Security fixes and other critical bug fixes may sometimes need to be brought into a very large program as quickly as possible, and it may not be realistic to refactor all uses of a library that's integral to the program at that time. Ideally, a program should be able to benefit from fixes like these easily and without breaking API changes. The API may still need to evolve, however, so there should be a way to signal to developers that they need to go prune out calls to deprecated parts of the API in favor of the new, better way to do it.

Deprecation tags are to help with a full upgrade process. Of course, if you never upgrade, you won't need them, but in practice, upgrades will need to happen.
Reply all
Reply to author
Forward
0 new messages