Re: [go-nuts] Appreciating Go
> That's why I've used *time.Time, not time.Time - if you try to use it when > t.Err is set you'll get panic because of nil value. > > > Runtime checks doesn't count :) Compiler still allowed you to use value, when error was set. -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Appreciating Go
Hi! On Sun, Feb 25, 2018 at 01:51:08AM -0800, Maxim Ivanov wrote: > > type Time struct { > > Err error > > *time.Time > > } > Problem is that it continues to be product type, nothing really enforces > that you can't use t as a time.Time when t.Err is set. That's why I've used *time.Time, not time.Time - if you try to use it when t.Err is set you'll get panic because of nil value. -- WBR, Alex. -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Appreciating Go
On 24 February 2018 at 22:02, Bakul Shah wrote: > r := os.Open(filename) > if isError(r) { return r.(error) } > f := r.(*os.File) // or better: var f *os.File; f = r I don't think the "or better" alternative would be possible. The of r is still `*os.File|error`, not *os.File, and this not assignable to a *os.File without some kind of type assertion. Unless somehow isError is a special language builtin that manages to change the type of r after calling it. I can't see how that would work though. So here we've got two type assertions, both of which can potentially panic. At least, I always look very carefully at type assertions without a `, ok` clause because the consequences are so bad if you get them wrong. > Error checking being a common pattern, isError() can be added as a builtin > or trivially in errors pkg. Likely the enclosing function also returns an > error > so the return in the second line above can be just return r but with the > current product type approach you’d have return nil, err. That's only the case if you're returning exactly the same type. > You are only looking at code after returning. Code within a function benefits > more (gets simplified). > > func f(s string) (int|error) { // instead of (int,error) > ... > return err // instead of return 0,err > ... > return 1 // instead of return 1,nil > // and return n, err case disappears > > Having to return an extra thing that gets discarded right away is annoying. It's perhaps a little annoying (although it would be less annoying if we had a standard identifier for "zero value - see https://github.com/golang/go/issues/19642), but AFAICS using sum types instead would end up more annoying in practice. Also, it's not *that* uncommon to need to return both a valid value and an error. cheers, rog. -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Appreciating Go
> Short version to just get a taste: > > type Time struct { > Err error > *time.Time > } > > func now(pass bool) Time { > if !pass { > return Time{Err: errors.New("not now")} > } > now := time.Now() > return Time{Time: &now} > } > > t := now(…) > f t.Err != nil { > return t.Err > } > > Problem is that it continues to be product type, nothing really enforces that you can't use t as a time.Time when t.Err is set. -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Appreciating Go
Hi! On Sat, Feb 24, 2018 at 02:02:37PM -0800, Bakul Shah wrote: > r := os.Open(filename) > if isError(r) { return r.(error) } > f := r.(*os.File) // or better: var f *os.File; f = r > > Error checking being a common pattern, isError() can be added as a builtin > or trivially in errors pkg. Likely the enclosing function also returns an > error > so the return in the second line above can be just return r but with the > current product type approach you’d have return nil, err. > > You are only looking at code after returning. Code within a function benefits > more (gets simplified). > > func f(s string) (int|error) { // instead of (int,error) > ... > return err // instead of return 0,err > ... > return 1 // instead of return 1,nil > // and return n, err case disappears Actually you can have such a sum type right now, without any changes to syntax or stdlib, and with much more pleasant usage syntax. Full example: https://play.golang.org/p/tVSAqRprmKI Short version to just get a taste: type Time struct { Err error *time.Time } func now(pass bool) Time { if !pass { return Time{Err: errors.New("not now")} } now := time.Now() return Time{Time: &now} } t := now(…) f t.Err != nil { return t.Err } // Use t just like time.Time. -- WBR, Alex. -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Appreciating Go
On Sat, Feb 24, 2018 at 11:04 PM Bakul Shah wrote: > r := os.Open(filename) > if isError(r) { return r.(error) } > f := r.(*os.File) // or better: var f *os.File; f = r > This still does not seem meaningfully different to me, though. * You are writing isError(r), instead of err != nil * You are writing r.(error) instead of err * You are writing f := r.(*os.File), but is that so different from just using f? Yes, the compiler will prevent you from using the result without a type-assertion. That's a real benefit. But given that you are not really meaningfully change the amount of boilerplate and the benefit of detecting a possible bug can also be achieved using errcheck, I agree with Roger that this doesn't seem that meaningful an improvement to justify adding a new language feature. > > Error checking being a common pattern, isError() can be added as a builtin > or trivially in errors pkg. Likely the enclosing function also returns an > error > so the return in the second line above can be just return r but with the > current product type approach you’d have return nil, err. > > You are only looking at code after returning. Code within a function > benefits > more (gets simplified). > > func f(s string) (int|error) { // instead of (int,error) > ... > return err // instead of return 0,err > ... > return 1 // instead of return 1,nil > // and return n, err case disappears > > Having to return an extra thing that gets discarded right away is annoying. > Early on this was a common mistake for me. We are used to it now but the > current idiom came about because of a lack of sum types. People can use > object{} as a return type today but that more or less defeats type checking > which may be why returning an extra thing was perhaps seen as acceptable. > So yes, I do think sum types benefit here. May be not enough for people to > want a change but net benefit nonetheless. > > The bigger benefit is their use where people currently end up using > object{} > or product type. With sum types you get better documentation and checking. > If you think of sum types as just restricted object{} types, they are > simple to > explain and implement. Simpler than what you guys were discussing on issue > 19412 thread. I will add a comment there. > > On Feb 24, 2018, at 12:03 PM, roger peppe wrote: > > >> I once counted there were about 8000 uses of ,error as > >> return types for functions in $GOROOT/src which could benefit > >> from sum types. > > > > I'm not entirely convinced that sum types are a net win as a > > substitute for (T, error) return values. > > > > Where currently we have: > > > > f, err := os.Open(filename) > > if err != nil { > > return err > > } > > // use f > > > > we'd have to do something like: > > > > fOrError := os.Open(filename) > > if err, ok := fOrError.(error); ok { > > // ... but what happens if we want to return a distinct > > // value that implements error? > > return err > > } > > f := fOrError.(*os.File) > > // use f > > > > or perhaps: > > > > var f *os.File > > switch fOrError := os.Open(filename).(type) { > > case *os.File: > > f = fOrError > > case error: > > return fOrError > > } > > // use f > > > > or even, defensively (perhaps os.Open's type might change to admit > > more possibilities: > > > > var f *os.File > > switch fOrError := os.Open(filename).(type) { > > case *os.File: > > f = fOrError > > case error: > > return fOrError > > default: > > panic("unexpected type %T returned from os.Open", fOrError) > > // or return error > > } > > // use f > > > > I don't know about you, but I wouldn't consider any of those a > > particular improvement on the current idiom. They're all more verbose > > and not actually that much more type-safe. > > > > That doesn't mean that I don't think sum types are a decent idea, but > > just that I'm not sure that they're as clear a win for this (a > > commonly cited use case) as one might think. > > > > cheers, > >rog. > > > > > >> On 24 February 2018 at 01:23, Bakul Shah wrote: > >>> On Thu, 22 Feb 2018 12:55:01 + Jesper Louis Andersen < > jesper.louis.ander...@gmail.com> wrote: > >>> > >>> For sums, in Go, I have to return a pair, > >>> > >>> x, err := someOperation(..) > >>> > >>> but this is slightly inconsistent, insofar I can return "nil, nil", > which > >>> might not be a valid value, or I can return "3, Error(..)" but in that > case > >>> the 3 is not to be used. Only one "side" is valid at a given point in > time. > >>> If you have sum-types in the usual sense, you can define something > along > >>> the lines of (OCaml follows): > >>> > >>> type ('a, 'b) result = Ok of 'a | Error of 'b > >> > >> I once worked out some details of adding sum types to Go and I > >> think it is quite doable and easy to implement. For example, > >>
Re: [go-nuts] Appreciating Go
r := os.Open(filename) if isError(r) { return r.(error) } f := r.(*os.File) // or better: var f *os.File; f = r Error checking being a common pattern, isError() can be added as a builtin or trivially in errors pkg. Likely the enclosing function also returns an error so the return in the second line above can be just return r but with the current product type approach you’d have return nil, err. You are only looking at code after returning. Code within a function benefits more (gets simplified). func f(s string) (int|error) { // instead of (int,error) ... return err // instead of return 0,err ... return 1 // instead of return 1,nil // and return n, err case disappears Having to return an extra thing that gets discarded right away is annoying. Early on this was a common mistake for me. We are used to it now but the current idiom came about because of a lack of sum types. People can use object{} as a return type today but that more or less defeats type checking which may be why returning an extra thing was perhaps seen as acceptable. So yes, I do think sum types benefit here. May be not enough for people to want a change but net benefit nonetheless. The bigger benefit is their use where people currently end up using object{} or product type. With sum types you get better documentation and checking. If you think of sum types as just restricted object{} types, they are simple to explain and implement. Simpler than what you guys were discussing on issue 19412 thread. I will add a comment there. On Feb 24, 2018, at 12:03 PM, roger peppe wrote: >> I once counted there were about 8000 uses of ,error as >> return types for functions in $GOROOT/src which could benefit >> from sum types. > > I'm not entirely convinced that sum types are a net win as a > substitute for (T, error) return values. > > Where currently we have: > > f, err := os.Open(filename) > if err != nil { > return err > } > // use f > > we'd have to do something like: > > fOrError := os.Open(filename) > if err, ok := fOrError.(error); ok { > // ... but what happens if we want to return a distinct > // value that implements error? > return err > } > f := fOrError.(*os.File) > // use f > > or perhaps: > > var f *os.File > switch fOrError := os.Open(filename).(type) { > case *os.File: > f = fOrError > case error: > return fOrError > } > // use f > > or even, defensively (perhaps os.Open's type might change to admit > more possibilities: > > var f *os.File > switch fOrError := os.Open(filename).(type) { > case *os.File: > f = fOrError > case error: > return fOrError > default: > panic("unexpected type %T returned from os.Open", fOrError) > // or return error > } > // use f > > I don't know about you, but I wouldn't consider any of those a > particular improvement on the current idiom. They're all more verbose > and not actually that much more type-safe. > > That doesn't mean that I don't think sum types are a decent idea, but > just that I'm not sure that they're as clear a win for this (a > commonly cited use case) as one might think. > > cheers, >rog. > > >> On 24 February 2018 at 01:23, Bakul Shah wrote: >>> On Thu, 22 Feb 2018 12:55:01 + Jesper Louis Andersen >>> wrote: >>> >>> For sums, in Go, I have to return a pair, >>> >>> x, err := someOperation(..) >>> >>> but this is slightly inconsistent, insofar I can return "nil, nil", which >>> might not be a valid value, or I can return "3, Error(..)" but in that case >>> the 3 is not to be used. Only one "side" is valid at a given point in time. >>> If you have sum-types in the usual sense, you can define something along >>> the lines of (OCaml follows): >>> >>> type ('a, 'b) result = Ok of 'a | Error of 'b >> >> I once worked out some details of adding sum types to Go and I >> think it is quite doable and easy to implement. For example, >> >>func f(i int) float64|error { >>if i == 0 { return errors.New("not zero") } >>return 1./float64(i) >>} >> >> As in OCaml "|" is used for sum types and it binds less >> tightly than existing type "expressions". >> >>> And then you can discriminate on this value via pattern matching >>> >>> match res with >>> | Ok value -> ... >>> | Error err -> ... >> >> Not quite the same but something similar is doable with >> type switch. >> >>res := f(j) >>switch res.(type) { >>case error: ... >>case string: ... >>} >> >> This use is identical with f returning interface{} (even the f >> body remains exactly the same). This makes sense since >> interface{} is in a sense the sum of all other types. >> >> But by allowing sum type, we can do better checking within f >> (e.g. return "string" will fail to compile). And by using a >> sum type instead of a product type to return a value or
Re: [go-nuts] Appreciating Go
> I once counted there were about 8000 uses of ,error as > return types for functions in $GOROOT/src which could benefit > from sum types. I'm not entirely convinced that sum types are a net win as a substitute for (T, error) return values. Where currently we have: f, err := os.Open(filename) if err != nil { return err } // use f we'd have to do something like: fOrError := os.Open(filename) if err, ok := fOrError.(error); ok { // ... but what happens if we want to return a distinct // value that implements error? return err } f := fOrError.(*os.File) // use f or perhaps: var f *os.File switch fOrError := os.Open(filename).(type) { case *os.File: f = fOrError case error: return fOrError } // use f or even, defensively (perhaps os.Open's type might change to admit more possibilities: var f *os.File switch fOrError := os.Open(filename).(type) { case *os.File: f = fOrError case error: return fOrError default: panic("unexpected type %T returned from os.Open", fOrError) // or return error } // use f I don't know about you, but I wouldn't consider any of those a particular improvement on the current idiom. They're all more verbose and not actually that much more type-safe. That doesn't mean that I don't think sum types are a decent idea, but just that I'm not sure that they're as clear a win for this (a commonly cited use case) as one might think. cheers, rog. On 24 February 2018 at 01:23, Bakul Shah wrote: > On Thu, 22 Feb 2018 12:55:01 + Jesper Louis Andersen > wrote: >> >> For sums, in Go, I have to return a pair, >> >> x, err := someOperation(..) >> >> but this is slightly inconsistent, insofar I can return "nil, nil", which >> might not be a valid value, or I can return "3, Error(..)" but in that case >> the 3 is not to be used. Only one "side" is valid at a given point in time. >> If you have sum-types in the usual sense, you can define something along >> the lines of (OCaml follows): >> >> type ('a, 'b) result = Ok of 'a | Error of 'b > > I once worked out some details of adding sum types to Go and I > think it is quite doable and easy to implement. For example, > > func f(i int) float64|error { > if i == 0 { return errors.New("not zero") } > return 1./float64(i) > } > > As in OCaml "|" is used for sum types and it binds less > tightly than existing type "expressions". > >> And then you can discriminate on this value via pattern matching >> >> match res with >> | Ok value -> ... >> | Error err -> ... > > Not quite the same but something similar is doable with > type switch. > > res := f(j) > switch res.(type) { > case error: ... > case string: ... > } > > This use is identical with f returning interface{} (even the f > body remains exactly the same). This makes sense since > interface{} is in a sense the sum of all other types. > > But by allowing sum type, we can do better checking within f > (e.g. return "string" will fail to compile). And by using a > sum type instead of a product type to return a value or error > also makes the code clearer. > > I once counted there were about 8000 uses of ,error as > return types for functions in $GOROOT/src which could benefit > from sum types. Now there seem to be about 4253 instances > (found using a crude regexp). > > I think I worked out the semantics of T1|T2 where T1 and T2 > are both interface types themselves. It all seem to fit > together, at least on paper! I need to find my notes > >> The other matching construction is a switch-statement, but such a statement >> doesn't allow for matching deeply into an AST structure, which a >> traditional pattern matcher does. > > Deeper matching also binds names to matched parts. e.g. > > sumsqr [] = 0 > sumsqr (x:xs) = x*x + sumsqr xs > > This sort of binding may be difficult to shoehorn into Go. > There may be no real benefit of binding head, tail of a slide > but consider an AST. If you are already cracking it open for > matching it with a pattern, you may as well bind variables to > interesting parts. > > match stmt { > case If1stmt(test:, thenstmt:): ... > case If2stmt(test:, thenstmt:, elsestmt:): ... > ... > } > > Hard to come up with an intuitive syntax here. Also probably > impossible to add func level patterns. > >> Coincidentally, given sum-types, you can write a regexp matching engine in >> very few lines of code. See Bob Harper's "Programming in Standard ML" [2] >> for example; it is the introductory example to get a feel for the language. >> The solution uses sum types to define the AST for regular expressions, and >> then uses pattern matching to build a matcher on regular expressions. I >> can't remember how far Bob takes the exposition however. > > This should be doabl
Re: [go-nuts] Appreciating Go
On Fri, 23 Feb 2018 17:39:16 -0800 Ian Lance Taylor wrote: Ian Lance Taylor writes: > On Fri, Feb 23, 2018 at 5:23 PM, Bakul Shah wrote: > > > > I once worked out some details of adding sum types to Go and I > > think it is quite doable and easy to implement. > > There is an extensive discussion of sum types in Go over at > https://golang.org/issue/19412. Thanks! Looks like Roger's ideas is similar. Not at all surprising. Will check it out further. -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Appreciating Go
On Fri, Feb 23, 2018 at 5:23 PM, Bakul Shah wrote: > > I once worked out some details of adding sum types to Go and I > think it is quite doable and easy to implement. There is an extensive discussion of sum types in Go over at https://golang.org/issue/19412. Ian -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Appreciating Go
On Thu, 22 Feb 2018 12:55:01 + Jesper Louis Andersen wrote: > > For sums, in Go, I have to return a pair, > > x, err := someOperation(..) > > but this is slightly inconsistent, insofar I can return "nil, nil", which > might not be a valid value, or I can return "3, Error(..)" but in that case > the 3 is not to be used. Only one "side" is valid at a given point in time. > If you have sum-types in the usual sense, you can define something along > the lines of (OCaml follows): > > type ('a, 'b) result = Ok of 'a | Error of 'b I once worked out some details of adding sum types to Go and I think it is quite doable and easy to implement. For example, func f(i int) float64|error { if i == 0 { return errors.New("not zero") } return 1./float64(i) } As in OCaml "|" is used for sum types and it binds less tightly than existing type "expressions". > And then you can discriminate on this value via pattern matching > > match res with > | Ok value -> ... > | Error err -> ... Not quite the same but something similar is doable with type switch. res := f(j) switch res.(type) { case error: ... case string: ... } This use is identical with f returning interface{} (even the f body remains exactly the same). This makes sense since interface{} is in a sense the sum of all other types. But by allowing sum type, we can do better checking within f (e.g. return "string" will fail to compile). And by using a sum type instead of a product type to return a value or error also makes the code clearer. I once counted there were about 8000 uses of ,error as return types for functions in $GOROOT/src which could benefit from sum types. Now there seem to be about 4253 instances (found using a crude regexp). I think I worked out the semantics of T1|T2 where T1 and T2 are both interface types themselves. It all seem to fit together, at least on paper! I need to find my notes > The other matching construction is a switch-statement, but such a statement > doesn't allow for matching deeply into an AST structure, which a > traditional pattern matcher does. Deeper matching also binds names to matched parts. e.g. sumsqr [] = 0 sumsqr (x:xs) = x*x + sumsqr xs This sort of binding may be difficult to shoehorn into Go. There may be no real benefit of binding head, tail of a slide but consider an AST. If you are already cracking it open for matching it with a pattern, you may as well bind variables to interesting parts. match stmt { case If1stmt(test:, thenstmt:): ... case If2stmt(test:, thenstmt:, elsestmt:): ... ... } Hard to come up with an intuitive syntax here. Also probably impossible to add func level patterns. > Coincidentally, given sum-types, you can write a regexp matching engine in > very few lines of code. See Bob Harper's "Programming in Standard ML" [2] > for example; it is the introductory example to get a feel for the language. > The solution uses sum types to define the AST for regular expressions, and > then uses pattern matching to build a matcher on regular expressions. I > can't remember how far Bob takes the exposition however. This should be doable given my sum-type proposal sketch above?! > [0] They are really the same in the right setting. In a boolean algebra, > for instance, + is OR and * is AND. If you look at them from the Category > Theory branch of mathematics they are related: they are duals of each other > which means that if you "invert" one you get the other and vice versa. > > [1] Obviously, Go, being a descendant of Algol has two syntactic classes: > statements and expressions, whereas OCaml is descendant from either Lisp or > the Lambda Calculus depending on view. Those languages only have > expressions as a syntactic class. sum-types (which are easy to implement) and pattern matching (may be not so easy) can be added to Go even if it has non-expression syntatic classes. > [2] http://www.cs.cmu.edu/~rwh/isml/book.pdf > > [3] > https://www.microsoft.com/en-us/research/wp-content/uploads/1987/01/slpj-book-1987-small.pdf SLPJ's book was quite an eye opener for me back in the '80s! -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Appreciating Go
Usually, the type theoretic basis is what is called a sum-type. They are corresponding to a logical OR or a '+' addition operation in algebra. A "struct" is rightfully a variant of a product-type, or a logical AND or a '*' multiplication operation in algebra[0]. Most (commonly used) programming languages can "multiply" in the type system, but they can't "add", and this creates a lot of serious problems since you have to simulate sums through products. If we write type point struct { x int y int } you could argue that a value of type point contains "a value X" AND "a value Y", which is why they are often called product types. Forming a point point{x,y} mandates you supply both at the same time. For sums, in Go, I have to return a pair, x, err := someOperation(..) but this is slightly inconsistent, insofar I can return "nil, nil", which might not be a valid value, or I can return "3, Error(..)" but in that case the 3 is not to be used. Only one "side" is valid at a given point in time. If you have sum-types in the usual sense, you can define something along the lines of (OCaml follows): type ('a, 'b) result = Ok of 'a | Error of 'b And then you can discriminate on this value via pattern matching match res with | Ok value -> ... | Error err -> ... This means that the inconsistent state cannot be represented. An ('a, 'b) result is either "Ok ..." OR "Error ..." but it can't be both. Go does have matching constructions which are special cases of the general variant above. In particular, in OCaml we can have match x with | true -> ExprT | false -> ExprF (where ExprT/ExprF are arbitrary expressions) but this is same as (in fact, syntactic sugar for): if x then ExprT else ExprF which is roughly equivalent to the following in Go[1] if x { ExprT } else { ExprF } The other matching construction is a switch-statement, but such a statement doesn't allow for matching deeply into an AST structure, which a traditional pattern matcher does. In practice, a programming language will contain a "pattern match compiler" which compiles a pattern match into an if-maze, a jump table, binary search and so on. This means they are efficient to execute in practice because you can use positive and negative match information to skip match clauses when needed. Two good references are Simon Peyton Jones compiler book[3] and Peter Sestofts pattern match compiler[4] Coincidentally, given sum-types, you can write a regexp matching engine in very few lines of code. See Bob Harper's "Programming in Standard ML" [2] for example; it is the introductory example to get a feel for the language. The solution uses sum types to define the AST for regular expressions, and then uses pattern matching to build a matcher on regular expressions. I can't remember how far Bob takes the exposition however. Rust calls them "enums" but they are more than just an enumeration in e.g., Java, because each variant also binds values. Scala calls them sealed classes, and I guess it has to do with the language being heavely based on Java and thus needs the concept to coexist with subtyping, but I may be wrong in my guess. [0] They are really the same in the right setting. In a boolean algebra, for instance, + is OR and * is AND. If you look at them from the Category Theory branch of mathematics they are related: they are duals of each other which means that if you "invert" one you get the other and vice versa. [1] Obviously, Go, being a descendant of Algol has two syntactic classes: statements and expressions, whereas OCaml is descendant from either Lisp or the Lambda Calculus depending on view. Those languages only have expressions as a syntactic class. [2] http://www.cs.cmu.edu/~rwh/isml/book.pdf [3] https://www.microsoft.com/en-us/research/wp-content/uploads/1987/01/slpj-book-1987-small.pdf [4] http://dotat.at/tmp/match.pdf On Thu, Feb 22, 2018 at 1:14 PM Josh Humphries wrote: > On Thu, Feb 22, 2018 at 4:56 AM, Steven Hartland > wrote: > >> On 22/02/2018 09:46, andrewchambe...@gmail.com wrote: >> >> Just a list of things I like about Go, thanks everyone for the hard work: >> >> snip... >> >> Minor things that could be improved in order of importance: >> >> - Ways to express immutability ... as a concurrent language it can still >> be easy to make mistakes and share a buffer or slice by accident. >> - More advanced static analysis tools that can prove properties of your >> code (perhaps linked with the above). >> >> Have you seen: https://github.com/alecthomas/gometalinter >> >> - Generics. >> - Some sort of slightly more sophisticated pattern matching . >> >> Not sure what you mean here but have you seen: >> https://golang.org/pkg/regexp/ >> > > I'm pretty sure Andrew was referring to pattern matching like in Scala and > Rust. It's a very slick feature. Related: Rust's enum types are slick -- > they are like a combination of enums (such as in Java, and Scala) and > Scala's sealed classes. > https://docs.scala-lang.org/tour/
Re: [go-nuts] Appreciating Go
On Thu, Feb 22, 2018 at 4:56 AM, Steven Hartland wrote: > On 22/02/2018 09:46, andrewchambe...@gmail.com wrote: > > Just a list of things I like about Go, thanks everyone for the hard work: > > snip... > > Minor things that could be improved in order of importance: > > - Ways to express immutability ... as a concurrent language it can still > be easy to make mistakes and share a buffer or slice by accident. > - More advanced static analysis tools that can prove properties of your > code (perhaps linked with the above). > > Have you seen: https://github.com/alecthomas/gometalinter > > - Generics. > - Some sort of slightly more sophisticated pattern matching . > > Not sure what you mean here but have you seen: > https://golang.org/pkg/regexp/ > I'm pretty sure Andrew was referring to pattern matching like in Scala and Rust. It's a very slick feature. Related: Rust's enum types are slick -- they are like a combination of enums (such as in Java, and Scala) and Scala's sealed classes. https://docs.scala-lang.org/tour/pattern-matching.html https://doc.rust-lang.org/1.6.0/book/match.html > > -- > 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+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Appreciating Go
On 22/02/2018 09:46, andrewchambe...@gmail.com wrote: Just a list of things I like about Go, thanks everyone for the hard work: snip... Minor things that could be improved in order of importance: - Ways to express immutability ... as a concurrent language it can still be easy to make mistakes and share a buffer or slice by accident. - More advanced static analysis tools that can prove properties of your code (perhaps linked with the above). Have you seen: https://github.com/alecthomas/gometalinter - Generics. - Some sort of slightly more sophisticated pattern matching . Not sure what you mean here but have you seen: https://golang.org/pkg/regexp/ -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] Appreciating Go
Just a list of things I like about Go, thanks everyone for the hard work: Good things go has: - Go has an extremely useful std library. - Go has the best backwards compatibility I have seen (I'm pretty sure code from go version 1.0 still works today.). - Go has the nicest code manipulation tools I have seen. - The best race condition detector tool around. - An incredibly useful in practice interface system. (I once tunneled http and ssh connections over a serial port because net.Listener and net.Conn are easy interfaces) - The fastest compiler to use, and to build from source. - Probably the best cross compilation story of any language, with uniformity across platforms, including ones you haven't heard of. - One of the easiest to distribute binaries across platforms (this is why hashicorp, cockroachdb, ngrok etc choose go, it makes on boarding customers so much easier.). - A very sophisticated garbage collector with low pause times. - One of the best runtime performance to ease of use ratios around. - One of the easier to learn languages around. - A compiler that produces byte for byte identical binaries. - incredibly useful libraries maintained by google: (e.g. Heres a complete ssh client and server anyone can use: https://godoc.org/golang.org/x/crypto/ssh) - Lots of money invested in keeping it working well from many companies: cloud flare, google, uber, hashicorp and more. - *FINALLY* A fresh and bold take on package management that isn't a cargo cult :) - https://research.swtch.com/vgo (I especially like how well this tackles verifiable builds). Minor things that could be improved in order of importance: - Ways to express immutability ... as a concurrent language it can still be easy to make mistakes and share a buffer or slice by accident. - More advanced static analysis tools that can prove properties of your code (perhaps linked with the above). - Generics. - Some sort of slightly more sophisticated pattern matching . Let me know if I missed anything, thanks again. -- 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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.