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: Go 2: remove map from keywords #36508

Closed
minkofski opened this issue Jan 11, 2020 · 11 comments
Closed

proposal: Go 2: remove map from keywords #36508

minkofski opened this issue Jan 11, 2020 · 11 comments
Labels
Milestone

Comments

@minkofski
Copy link

Motivation

Go 1 is tightly designed with 25 keywords:

// dependency management
package import

// values
const var

// flow controls
if else break continue 
switch case default 
for range 
goto fallthrough

// function calls
func return defer

// data structures
type struct map interface

// concurrencies
go chan select

All keywords have their value and orthogonal except the map which dedicated to a hash table data structure but also share similarities array and slice, according to the language specification:

ArrayType   =       "[" ArrayLength "]" ElementType .
SliceType   =       "["             "]" ElementType .
MapType     = "map" "["   KeyType   "]" ElementType .

Comparing to these three definitions, map prefix is redundant because "[" XXX "]" ElementType . is rich enough to represent various meanings depends on the difference of XXX.

Proposal

I propose to remove map from keywords, where a Go 2 map type is:

Go2MapType = "["   KeyType   "]" ElementType .

Compatability

go fix can walk the whole program and drop all parsed map keyword from the program.

@gopherbot gopherbot added this to the Proposal milestone Jan 11, 2020
@mvdan
Copy link
Member

mvdan commented Jan 11, 2020

I don't agree with this proposal. When I read [foo]string, right now it's unambiguous; foo must be a constant like const foo = 10; var _ [foo]string, thus meaning an array.

But with your proposal. it would be ambiguous to the reader, as it could also be type foo int; var _ [foo]string, thus meaning a map.

@ALTree ALTree added the v2 A language change or incompatible library change label Jan 11, 2020
@maj-o
Copy link

maj-o commented Jan 20, 2020

I am the one who gave thumb up, so I have do argue why. Because I love what Mr. Griesemer showed 2006. If we can declare our Indexes on our own, surely we can remove map from the core, like complex numbers. And yes, go fix can and should fix this.
This would reduce the size of applications not using map. This would also open a door for SSE optimizations, 'cause data (ElementType) and index (KeyType) and all of its methods are known.
For me this is a thumb up, though it is strange at first look.

@ianlancetaylor
Copy link
Contributor

For language change proposals, please fill out the template at https://go.googlesource.com/proposal/+/bd3ac287ccbebb2d12a386f1f1447876dd74b54d/go2-language-changes.md .

When you are done, please reply to the issue with @gopherbot please remove label WaitingForInfo.

Thanks!

@ianlancetaylor ianlancetaylor added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jan 21, 2020
@gopherbot gopherbot removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jan 21, 2020
@ianlancetaylor ianlancetaylor added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jan 21, 2020
@henvic
Copy link
Contributor

henvic commented Jan 29, 2020

@maj-o, can you explain why we can't achieve the same level of optimization at compile time, please?

@nirui
Copy link

nirui commented Jan 29, 2020

Hey, just wondering, maybe when generic became a thing, map can then be supported through a package rather than a builtin keyword? (Move first-class map to a package?)

@ianlancetaylor
Copy link
Contributor

@niruix Yes, a good generics implementation would support writing map as a package. That could be done with the current design draft, for example.

But the keyword version is still going to be more convenient to use.

@minkofski
Copy link
Author

minkofski commented Feb 7, 2020

Would you consider yourself a novice, intermediate, or experienced Go programmer?

Experienced.

What other languages do you have experience with?

C/C++

Would this change make Go easier or harder to learn, and why?

Easier. I consider this makes Go with fewer keywords, compact.

Has this idea, or one like it, been proposed before?

No, to my knowledge.

If so, how does this proposal differ?

Not applicable

Who does this proposal help, and why?

All Go users. Type less, and more apparent to the meaning of the data type.

Take this example:

map[string]map[string]map[string]map[string]string

=>

[string][string][string][string]string

and this

// this remains to be an array.
const foo = 10; var _ [foo]string

// changing the meaning of foo, of course, will change the meaning of var.
type foo int;   var _ [foo]string 

Hash table can be considered as a "Multidimensional Array".

Is this change backward compatible?

No. But Yes, with go fix.

Breaking the (Go 1 compatibility guarantee)[https://golang.org/doc/go1compat] is a large cost and ## requires a large benefit.

Not breaking. go fix quickly fix everything.

Or we do not do anything with a deprecated way of writing map:
map[string]string continues to work, but will be removed in the future.
[string]string is recommended.

Show example code before and after the change.

It is illustrated before.

What is the cost of this proposal? (Every language change has a cost).

Developer need slightly reconsider

How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected?

go fix easily fix everything.

What is the compile time cost?

Faster since map can be considered as a multidimensional array.

What is the run time cost?

No change.

Can you describe a possible implementation?

Yes. Production rule:

ArrayType = "[" ArrayLength "]" ElementType .
SliceType = "["             "]" ElementType .
MapType   = "["   KeyType   "]" ElementType .

Do you have a prototype? (This is not required.)

No.

How would the language spec change?

Again:

ArrayType = "[" ArrayLength "]" ElementType .
SliceType = "["             "]" ElementType .
MapType   = "["   KeyType   "]" ElementType .

Orthogonality: how does this change interact or overlap with existing features?

No changes.

Is the goal of this change a performance improvement?

It might be in the future for compiler optimization.

If so, what quantifiable improvement should we expect?

Less binary size, less compile time, etc.

How would we measure it?

The measurement already exists in the current Go source.

Does this affect error handling?

No.

If so, how does this differ from previous error handling proposals?

No.

Is this about generics?

Might be related, because generics can implement a map package.
In this case, the proposal can be remove map from Go data types.
But this is not the intention of this proposal and should be in a separate issue.

If so, how does this differ from the the current design draft and the previous generics proposals?

No.

@minkofski
Copy link
Author

@gopherbot please remove label WaitingForInfo

@gopherbot gopherbot removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Feb 7, 2020
@dotaheor
Copy link

dotaheor commented Feb 9, 2020

The proposal is some interesting, so I would expand it a little. I have no opinions on the proposal though.

OP said:

All keywords have their value and orthogonal except the map which dedicated to a hash table data structure but also share similarities array and slice, according to the language specification:

ArrayType   =                    "[" ArrayLength "]" ElementType .
SliceType   =                    "["             "]" ElementType .
MapType     =              "map" "["   KeyType   "]" ElementType .

I would expand it to the chan keyword too:

ArrayType   =                    "[" ArrayLength "]" ElementType .
SliceType   =                    "["             "]" ElementType .
MapType     =              "map" "["   KeyType   "]" ElementType .
ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .

If we can think it as there were originally the array and slice keywords,
the above will be denoted as:

ArrayType   =            "array" "[" ArrayLength "]" ElementType .
SliceType   =            "slice" "["             "]" ElementType .
MapType     =              "map" "["   KeyType   "]" ElementType .
ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .

So, the donations are quite consistent:

  • the last generic type is not enclosed in [].
  • the next to last generic type, if it exists, is enclosed in [].

It looks Go authers had considered the extension for future custom generics.

@ianlancetaylor
Copy link
Contributor

This change would break essentially all existing Go code, and would invalidate essentially all existing documentation. We can automatically fix the code, but not the documentation. That is a heavy cost. The benefit of removing a keyword doesn't seem worth it.

The resulting code is generally less readable, as it becomes less clear whether a type is a map or an array.

This proposal does not have much support based on emoji voting.

For these reasons, this is a likely decline. Leaving open for four weeks for final comments.

@ianlancetaylor
Copy link
Contributor

No further comments, so closing.

@golang golang locked and limited conversation to collaborators Mar 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

10 participants