Hacker News new | past | comments | ask | show | jobs | submit login

Some people here seem to not like the similarity to interfaces, but I think, it should be even more like interfaces. In fact, I like the interface syntax even better than the contract syntax. And the type parameter list pollutes the otherwise very clean syntax in my opinion.

So you might ask what I am suggesting. AFAIK there are two major problems preventing interfaces to be used as generics:

1. There is no way to require the methods of builtin types aka operators.

2. Compile-time type safety is very limited

The reason why interfaces have no access to operators and other language features is that the language is kinda rough around the edges. And I really don't want to hurt anybody with this statement. I love the language, but I think there are some things that aren't perfect.

For example, just imagine every array/slice would have a method (e.g. Position(int)) that would be the equivalent of the square brackets and the square brackets would be just some syntactic sugar like

  arrayA[0] == arrayA.Position(0)
Same thing for operators like +

  x := 1
  x + 2 == x.Addition(2)
It would eliminate a lot of cases that make contracts necessary. In essence, it would mean that you could actually address built-in types in interfaces.

The second problem is related to the type parameter list. In my opinion, it would be better to simply put those types on extra lines like:

  type T Generic
  func Print(s []T) {
    // function body
  }
I mean, there should be no problem in making them available for more than one function and it would definitely clean up the function signature and look more Go-like.



Agreed, though I think the syntax problem (too many parens) could be made more readable and Go-like by emphasizing the generic aspect and making it stand out visually -- leaving no doubt that you're in a section that's generic, and perhaps dissuading overuse by making it noisy. Perhaps something like:

  generic func(T, U) Map(slice []T, mapper func(T) U) []U
For "contracts":

  type Set generic interface(T comparable) {
    Push(T)
    Pop() T
  }
Every time you want to refer to a generic type you'd have to use the generic keyword, which encourages use of concrete types:

  type IntSet generic Set(int)
This is more or less how Modula-3 does it. Generics have dedicated syntax with a "generic" keyword.


Agree & Voted.

Another alternative that I would like is to have angle brackets < > for better readability, so that definition and call would look as follows:

  // 1
  func Print2<type T1, T2>(s1 []T1, s2 []T2) { ... }
  Print2<int,int>( ... )
  
  // 2
  var v Vector<int>
  
  // 3
  func (v *Vector<Element>) Push(x Element) { *v = append(*v, x) }
Sorry, if it gives you C++ nightmares.


That looks much better! Somewhat like associated types of rust.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: