--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/CAOyqgcUOsyW9ozzvSOcXi8T0ajgxQF0Dcx6m7aJGLHofQ8Eetg%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/CAOyqgcVreoq0979VTfWNqEuMSWX1Qxu9sb4pfF_pgK2sT7ksRA%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/9720CF67-954E-4DB6-8D39-47ED790A2A4F%40gmail.com.
We experimented with other syntaxes, such as using a colon to separate the type arguments from the regular arguments. The current design seems to be the nicest, but perhaps something better is possible.
When parsing code within a function, such asv := F<T>
, at the point of seeing the<
it's ambiguous whether we are seeing a type instantiation or an expression using the<
operator. Resolving that requires effectively unbounded lookahead. In general we strive to keep the Go parser simple.
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/CAEkBMfEeMzNrmbOsPbKVEjQo6N0U9Wyy%2BVbnv2id3nuivxPBPQ%40mail.gmail.com.
> example: func (r *Receiver(T)) Strings(type T setter)(s []string) ([]T, error)
Well, I hope they aren't going to be exponentially harder to read. We
are adding an additional optional parameter list to functions, and
marking it with a new keyword. They may well be somewhat harder to
read, but I'm not persuaded that they will be exponentially harder.
func MapAndPrint(type E, M stringer(M))(s []E, f(E) M) []string {...}
func MapAndPrint(s []E, f(E) M) type E, M stringer(M) return []string {...}
With that you could then have gofmt format like so::
func MapAndPrint(s []E, f(E) M)type E, M stringer(M)return []string {...}
Adopting this multi-line keyword-based approach would:
- Allow longer function declarations to be written so they do not run off the right side of the editor window and/or the code review page,
- Be easier to read, especially for newer Go programmers or for programmers whose eyesight is not perfect,
- Resolve the "Lots of irritating silly parentheses" issue in the proposal (at least for the declaration of the func),
- Feel lot more Go-like (IMO), and
- Resolve one of the very few laments I have about the proposal. :-)
#fwiw -Mike
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/CAFm1DRGiCdq7864aAsWiyi_CA22uN%2BHHKHnMiadMA%3DNp1UogFQ%40mail.gmail.com.
As to this specific proposal, I'm concerned about scoping. Here you
are introducing type parameter after they are being used. ...
Programmers, and tools, will need to look ahead in the code to see the
definition of the identifier. That seems potentially confusing. It
is unlike any other scoping in the language: currently you can always
tell immediately the set of scopes in which to look for an identifier.
func MapAndPrint()
type E, M stringer(M)
params s []E, f(E) M
return []string {
...
I would like to try seeing some real code with the current suggested
syntax. That is the only way that we'll discover whether this really is
a problem or not.
I'm skeptical that there is any objective metric for these sort of
syntactic issues. If there is one, that would solve a lot of
problems. The closest we can get is something like "how many people
are confused" and "how often do people misunderstand the code" and
"how many mistakes do people make."
So it's going to be a matter of reading and writing code and seeing
how it feels. That is how the Go language has been designed since the
beginning.
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/3d31fdf7-0fc4-4590-ac8d-7f735ea0bc82%40googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/119b2a5c-9095-4fa1-a760-ca5ad5bf94c2%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/119b2a5c-9095-4fa1-a760-ca5ad5bf94c2%40googlegroups.com.
The updated generics design that I mentioned in my talk at Gophercon
(live blog at https://about.sourcegraph.com/go/gophercon-2019-generics-in-go)
can now be seen at
https://go.googlesource.com/proposal/+/master/design/go2draft-contracts.md
.
Ian
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/85a1c28b-fd18-41e2-aa74-7f457670f962%40googlegroups.com.
AIUI that research considers prose, not code, so I wouldn't transfer its findings to this discussion.
It is subjective to dismiss this research simply because of code vs. prose.
That said, it is not appropriate for this one concern to dominate the discussion of this thread. Let us both please end this topic on this thread, out of consideration for others.
-Mike
// Stream is a continuous sequence of values. type Stream(type E) interface { // Get the next value in the stream. // When done, io.EOF signals termination of the stream. Next() (E, error) }
type Sub(type E) interface { Stream(E) SubStream(uint) (Stream(E), error) }
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/89cc6262-7eb4-445e-81c1-3a3fcd442c13%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/6e56ce9d-ed02-41c8-acbf-d0c4310b0fae%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/99d1441c-7584-4020-a6bf-583c8fc78a33%40googlegroups.com.
The grammar should allow disambiguating by encasing in parentheses:type Sub(type E) interface {
(Stream(E))
SubStream(uint) (Stream(E), error)
}
On Tue, Jul 30, 2019 at 4:56 PM Joshua Boelter <joshua....@gmail.com> wrote:
>
> Kudos again to the latest proposal. Spent a bit of time reading and re-reading the contracts.
>
> Apologies if I missed it in the spec, but was there a rationale to not allow a contract to specify that a type conform to an interface? This would make it easier to declare a contract against interfaces developers are already familiar with or part of existing package.
>
> The example in the spec could be written:
>
> contract IOCloser(S) {
> S io.Reader, io.Writer
> S io.Closer
> }
The question is whether that means that S must have an underlying type
of io.Reader, or whether S must implement io.Reader. And in
particular how should we handle the builtin error interface. It may
be that what you suggest--that we treat an interface type as meaning
that the type argument must implement the interface, rather than that
the type argument must be the interface--makes the most sense.
More generally, there is clearly some degree of overlap between a
contract with one type parameter that only lists methods that do not
mention the type parameter, and an interface type. Of course, they
are different, too: you can't have a value of a contract "type". But
we could in principle decide that you can use an interface as a
contract. I don't know how often that would be useful. But if we
decide to go in that direction, it might affect the case you describe
above.
> Which then led me to below; thoughts on utilizing a boolean syntax to allow a more expressive contract?
Let's see if there is any real use for that first.
int Foo(T)(T t) if (isAddable!(T) && isMultipliable!(T))
The updated generics design that I mentioned in my talk at Gophercon
(live blog at https://about.sourcegraph.com/go/gophercon-2019-generics-in-go)
can now be seen at
https://go.googlesource.com/proposal/+/master/design/go2draft-contracts.md
+contract setter(T) {
+ *T Set(string)
+}
+```
Do you think something like this could be done for ensuring an argument is a pointer?what would be the proposed contract to make sure "decoder"-like methods could be more compile-time safe?cheers,-s
.
Ian
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/CAOyqgcUOsyW9ozzvSOcXi8T0ajgxQF0Dcx6m7aJGLHofQ8Eetg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/CAAV3P_AgO9NLo_%3DsT5j8MCKaiRnWri0iaa8ycz6ZW2pvi9vqpg%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/b95404f0-63cf-4873-961b-dfc6a75cea71%40googlegroups.com.
In cases where type inference won't work, say for:
May I suggest that we don't bikeshed this part of the design at this point - there's bigger fish to fry. This part we can always revisit once everything else is solid. Otherwise we're just going in circles.
contract IOCloser(S) {
io.Reader(S), io.Writer(S)
io.Closer(S)
}
contract IOCloser1(T) {
T io.Reader, io.Writer
T io.Closer
}
contract IOCloser2(T) {
T interface {
Read([]byte) (int, error)
Close() error
}, interface {
Write([]byte) (int, error)
Close() error
}
}
contract IOCloser3(T) {
T io.Reader, interface {
Write([]byte) (int, error)
}
T interface {
Close() error
}
T []byte, string // non-sensical, just to show that T must also be []byte or string
}
LookupAsString(MyInt)(m, 0)
func Ranger(type T)() (*Sender(type T), *Receiver(type T)) {
c := make(chan T)
d := make(chan bool)
s := &Sender(type T){values: c, done: d}
r := &Receiver(type T){values: c, done: d}
runtime.SetFinalizer(r, r.finalize)
return s, r
}
type Sender(type T) struct {
values chan<- T
done <-chan bool
}
func (s *Sender(type T)) Send(v T) bool {
select {
case s.values <- v:
return true
case <-s.done:
return false
}
}
func (s *Sender(type T)) Close() {
close(s.values)
}
type Receiver(type T) struct {
values <-chan T
done chan<- bool
}
func (r *Receiver(type T)) Next() (T, bool) {
v, ok := <-r.values
return v, ok
}
func (r *Receiver(type T)) finalize() {
close(r.done)
}
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/ae78f550-71b4-4b74-867a-c3fbca617f76%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/CAEpSaE0wzH60RjFK78FEJRWAYAih7a%3Dow6%3DVjDcdB2uBUXOM%3DQ%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-dev/e6d47288-52f9-4375-a878-80b054c1b2ba%40googlegroups.com.
https://gist.github.com/urandom/40ea1b3fa41be88fdbd4fd81c044e02d
Unfortunately, the following example had no need of a specific contact, though it does heavily rely on parametric types, at least for the implementation. And if I understood the draft correctly, a user would not need to specify the types, since they would be inferred from the function arguments. All in all, the user might not even be aware of any additional complexity under the hood, while still reaping the benefits of compile time safety and a bit faster runtime.
I understand and accept that your judgement on this issue is
different. I have no intention of stopping you from discussing
complex numbers with anybody else who is interested. And likely that
will lead to something that we can incorporate in the design draft if
it still makes sense as we move forward. But I don't see why it is a
discussion that needs my voice. I'm not saying "no." I'm saying
that, as far as I'm concerned, "we can discuss this later."
Ian