Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: spec: create builtin interfaces, let builtin types fulfill them #8303

Closed
metakeule opened this issue Jun 30, 2014 · 9 comments
Closed
Labels
FrozenDueToAge LanguageChange v2 A language change or incompatible library change
Milestone

Comments

@metakeule
Copy link

1. Provide a package builtin/interf with interfaces of the kind of

     type Stringer interface {
        String() string
     }

     type Booler interface {
        Bool() bool
     }

for the following builtin types:

bool, byte, complex128, complex64, float32, float64, int, int16, int32, int64, int8,
rune,
string, uint, uint16, uint32, uint64, uint8

2. Have the compiler use the builtin when it is assigned to "its" interface,
as if
each builtin would fulfill its corresponding interface from builtin/interf.

So code like this

     import "builtin/interf"
     
     func a(b interf.Booler) {
       // do something with b.Bool()
     }
     
     func main() {
       a(true)
     }

would compile and optimized, so that the performance and allocation characteristics for
the call
 a(true) would be the same as if a had the signature to receive a bool.
That means assignment of a builtin to "its" interface and call of
"its" interface's method should cost nothing.

WHY and WHAT IS IT FOR?

There are times more often than not, where we want the meantioned builtins to be
optional.
An example would be the use of the json package with structs where there is no easy way
to have optional builtins, like shown in this blog post:

https://willnorris.com/2014/05/go-rest-apis-and-pointers?utm_content=bufferb70ff&;utm_medium=social&utm_source=twitter.com&utm_campaign=buffer

As it turns out, the best solution is to define optional values as interfaces, as shown
here:
http://play.golang.org/p/cIO2yQ4676

The optional aspect is expression via the fact that any interface may be nil.

There are other places where optional builtins make programming with go awkward, e.g. the
Null* types in the database/sql package.

The problem is that every package wanting to have optional builtins will resort to its
own solution. Some of them are type wrappers leading incompatible types and solutions
between packages and a lot of mental and coding boilerplate.

The proposed solution would not only provide a idiomatic and performant solution, but
also allows
some function signatures to relax and accept the new builtin interfaces instead of  the
builtin and
by that be compatible with the builtins without performance digression but also flexible
enough to
be used with custom implementations.

builtin/interf being a package that has to be included in order to be used, means we are
staying compatible and optional.
@davecheney
Copy link
Contributor

Comment 1:

Can you please summarise what you are asking for ? I believe that you are asking for
some kind of interface for builtin types, the example you give is bool. But the reason
for this request is to express a third case, true, false and not set.
How is your proposal materially better than the existing solutions of using a *bool.
This is what you would get, the ability to set this boolean interface type to nil, if I
understand your proposal.

Labels changed: added languagechange.

Status changed to WaitingForReply.

@cznic
Copy link
Contributor

cznic commented Jun 30, 2014

Comment 2:

The topic of having methods on predeclared types had been discussed on the ML several
times. Also, language change proposals are better discussed there.

@metakeule
Copy link
Author

Comment 3:

being not a native speaker I had chosen some wrong wordings:
- "There are times more often than not": remove "more often than not"
- "The optional aspect is expression via the fact": instead: "Since any interface can be
nil, this is a way to express optionality".
- "builtin/interf being a package that has to be included": instead "a package that has
to be imported"
I apologize.

@metakeule
Copy link
Author

Comment 4:

That is right the reason is to express the builtin value and not set (nil).
The solution asked for solves this by providing an interface for each of the mentioned
builtins that could be used instead of the builtin in such cases.
Please have a look at google/go-github#19 to see how hary
the implications are when using pointers to the builtin types.
That simply does not scale well for complex structs and libraries.
The proposal would allow library developers to have 
- a faster implementation, since the builtin->interface->interface method path could
be optimized away by the compiler
- a idiomatic solution with good type signatures and less code
- to make better API for the consumer of the library, that is easier to use, less error
prone and more flexible
What I ask for is, to have a special interface for each of the meantioned builtin
and to have the compiler let each of the meantioned builtin fulfill its interface
without overhead.

@metakeule
Copy link
Author

Comment 5:

Also is it NOT about having methods on predeclared types. In fact there should not be
any method attached to a builtin. You should NOT be able to do e.g. "a".String()
Instead it is only that there are builtin interfaces that
happen to be satisfied and optimized by their corresponding builtin type.
I might sound unusual but it would be a nice fit to go.

@davecheney
Copy link
Contributor

Comment 6:

Please, can you stick to describing the problem which is _currently_ not served by Go as
it stands today.

@metakeule
Copy link
Author

Comment 7:

There are two problems that are not served well by Go is it stands today:
1. Usage of optional builtin types as struct fields and func parameters are cumbersome
leading to hard to maintain incompatible ad hoc solutions in packages (see mentioned
ticket and blog post)
2. There is currently no way to have a type that is an interface and is satisfied by a
builtin without having to create wrapper types that are also ad hoc, package specific
and cumbersome.
The proposal offers a solution to both problems.

@metakeule
Copy link
Author

Comment 8:

Please have a look at this package:
https://github.com/go-on/builtin
here I have implemented it on a package level with wrapper types.
It would be nice to have the above mentioned compiler support which would reduce
overhead to 0.
But if that is considered a too big change for the compiler, please consider integrating
this package into the standard library.
That would be no language change but had still the benefit of having standardized
interfaces for other packages and a recommended way to solve optionality.

@metakeule metakeule changed the title Create buitin interfaces, let builtin types fulfill them Create builtin interfaces, let builtin types fulfill them Dec 14, 2014
@rsc rsc changed the title Create builtin interfaces, let builtin types fulfill them ponies: create builtin interfaces, let builtin types fulfill them Apr 10, 2015
@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@rsc rsc changed the title ponies: create builtin interfaces, let builtin types fulfill them proposal: spec: create builtin interfaces, let builtin types fulfill them Jun 20, 2017
@rsc rsc added the v2 A language change or incompatible library change label Jun 20, 2017
@ianlancetaylor
Copy link
Contributor

This proposal is a way of adding optional types to Go: a type that can hold either a value or an indication that there is no value. I'm going to close this as a dup of #19412, where there is a lot of discussion about optional types as a particular kind of sum type.

@golang golang locked and limited conversation to collaborators Jan 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests

6 participants