News for hackers. Stuff that matters.
Re:Generics enabled by default in Go tip by theshrike79 on Saturday August 21, 2021 @01:05AM (#28254371)
You say "verbose and repetitive", I say "easy to read without any surprises".

The verbose patterns (if err!= nil for example) make the code predictable to read, you notice the code smell of missing error handling really fast.

Re:Generics enabled by default in Go tip by takeda on Saturday August 21, 2021 @01:39AM (#28254516)
I think readability has multiple dimensions, and it really depends what you are looking for.

For example here's a code in Go to look for a Prime:

    func IsPrime(n int) bool {
        if n < 0 {
                n = -n
        }
        switch {
        case n < 2:
                return false
        default:
                for i := 2; i < n; i++ {
                        if n%i == 0 {
                                return false
                        }
                }
        }
        return true
    }
It's readable as it is simple to understand what each line does.

Here for example is a code that does the same thing in Rust:

    fn is_prime(n: u64) -> bool {
        match n {
            0...1 => false,
            _ => !(2..n).any(|d| n % d == 0),
        }
    }
It's might seem more complex at first (what does match do, what 0...1 means, !(2..n) what is any() doing. But if you understand the language it actually this seem much simpler and you can quickly look at it and know exactly what it is doing. And because it is less verbose it is easier to grasp the bigger code.

I also noticed that while individual functions in Go are simple to understand and follow, you can still create complex, hard to follow and understand programs in Go.

Re:Generics enabled by default in Go tip by vips7L on Saturday August 21, 2021 @03:43PM (#28259919)
Go is crazy verbose. Even Java can do it much more simply:

    static boolean isPrime(int n) {

        return switch (n) {
            case 0, 1 -> false,
            default -> !IntStream.range(2, n).anyMatch(i -> n % i == 0)
        }
    }
Re:Generics enabled by default in Go tip by bopbeepboop on Saturday August 21, 2021 @01:55AM (#28254582)
You changed function signatures from int->bool to uint->bool, which changes how long the functions are.

That seems unfair when comparing:

Removing negatives from the Go implementation removes 6 out of 16 lines, bring it from 3x Rust to 2x Rust in line length.

Re:Generics enabled by default in Go tip by takeda on Saturday August 21, 2021 @02:24AM (#28254730)
I used code from: https://endler.dev/2017/go-vs-rust/ good point, I overlooked that.

Anyway in Go (ironically because of lack of generics) if you use any numeric type other than int, int64, float64 you will be in the word of hurt. Rust doesn't have that issue.

So in practice you will likely use int, and I suppose you can add an assertion.

BTW: I only see that it would remove 3 lines though, where are the other 3?

Re:Generics enabled by default in Go tip by tptacek on Saturday August 21, 2021 @02:28AM (#28254749)
I don't follow. I use unsigned ints in Go all the time. I've never been in a world of hurt with them. Mandatory explicit integer conversions (and the way Go consts work) are something Go gets right.
Re:Generics enabled by default in Go tip by takeda on Saturday August 21, 2021 @02:34AM (#28254777)
Ok, so you like that. I myself really hated when I used float32 and had to do this when I was doing calculations:

    result = (float32)Max((float64)a, (float64)b)
I ended up switching the type to float64, and wonder why they even offer float32 if it's practically unusable. I had similar experience when I needed to use int8 or int16 etc.

An alternative was to make own version of Max/Min and other math functions, but this is what generics would solve.

Re:Generics enabled by default in Go tip by tptacek on Saturday August 21, 2021 @03:19AM (#28254962)
I'm not sure I follow, because Rust is also (thankfully) fussy about integer types.
Re:Generics enabled by default in Go tip by masklinn on Saturday August 21, 2021 @03:28AM (#28254998)
I think what they mean is utility functions (e.g. min/max here) tend to only be implemented for one type, so if you’re using an other you keep casting back and forth.

Rust is very fussy about types and some operations are bound to a single one (e.g. stdlib sequences only index with usize) but utility functions tend to either be genetic or be mass-implemented using macros (or by hand probably for f32::min and f64::min though I did not check).

Re:Generics enabled by default in Go tip by takeda on Saturday August 21, 2021 @05:20AM (#28255487)
I don't have problem with being strong typed, I like that as well. The problem is that the stdlib doesn't really support other types and that's mostly due to lack of generics, so using uncommon types becomes quite annoying.
Re:Generics enabled by default in Go tip by masklinn on Saturday August 21, 2021 @06:57AM (#28255926)
TBF the float Min/Max issue has nothing to do with generics, there isn't a "floating-point" generic class, and the entire reason why Go has an f64 Min/Max in the first place is that floats are not fully ordered[0], so you "can't" use regular comparisons (which you'd be told to do for integers) and thus you could not have a generic min/max relying on that even if there was one (e.g. in Rust `f32` and `f64` are not `Ord`, which `std::cmp::{min, max}` require, hence both `f32` and `f64` having their own inherent min/max methods).

So what your issue comes down to is Go's designers couldn't be arsed to duplicate the entire `math` package to also work on `float32`. Some members of the community did rise to the challenge[1] tho.

[0] well recent revisions of IEEE-754 have a total ordering predicate but I wouldn't say that it's really useful for such a situation as it positions NaNs on "outside" of the numbers, so a negative NaN is smaller than a negative number and a positive NaN larger than a positive number

[1] https://github.com/chewxy/math32

Re:Generics enabled by default in Go tip by takeda on Saturday August 21, 2021 @04:32PM (#28260331)
I'm aware of it, in the example given I used float32. Anyway Max/Min was just example I used other functions from math as well.

Anyway my point was that with generics, they wouldn't need to copy anything, the math package would work with both float32 and float64 and many functions likely would also work on all integers.

Re:Generics enabled by default in Go tip by theshrike79 on Saturday August 21, 2021 @07:10AM (#28255986)
The difference here is that I can hand off the first code to any random freshly hired CS grad or cheapest outsourced coder and they can grok the code quickly. This is the advantage Go has to all other languages.

The Rust code needs maintenance coders of way higher caliber, not something you'd usually find. It's super fun for the top-tier developers who love to be expressive and concise with their code, but all code is pushed down to maintenance mode eventually when the hotshots move on to the new shiny project.

Go has removed pretty much every footgun by sticking to the basics. You have one way to do a loop, one way to do comparisons etc. There are very few ways to hide non-obvious functionality.

It _is_ possible to create complex programs, that are hard to follow but that's a larger design problem. Not something the language can force on developers.

Re:Generics enabled by default in Go tip by pjmlp on Sunday August 22, 2021 @06:03AM (#28264205)
That was one of the points from Java 1.0.

Thing is, care with what you wish for when easy to outsource is a goal, a welcomed feature mostly relevant to IT managers that don't care about the final quality of delivery, nor what consequences it makes to the home job market.

So yeah to all Wipros, Infosys, TCS, .....

Re:Generics enabled by default in Go tip by andy_ppp on Saturday August 21, 2021 @03:34AM (#28255019)
Personally I find code with generics just as easy to read as (largely duplicated) implementations for each type. I might consider Golang again when this drops and there are things to be like about how low level it is…
Re:Generics enabled by default in Go tip by coryrc on Saturday August 21, 2021 @01:14AM (#28254412)
Or use Option or Result, so your error handling is small and forcibly correct.
Re:Generics enabled by default in Go tip by tptacek on Saturday August 21, 2021 @01:18AM (#28254436)
Error handling in Rust isn't always small or straightforward. I miss both options and match expressions when I switch back to Go from Rust, but there's also tangles of or_else's and maps and the fact that everyone uses third-party libraries to work out the types for errors. There's tradeoffs everywhere you look.
Re:Generics enabled by default in Go tip by int_19h on Saturday August 21, 2021 @04:47AM (#28255331)
Zig is probably a better comparison for this:

https://ziglang.org/documentation/master/#Errors

Re:Generics enabled by default in Go tip by the_gipsy on Saturday August 21, 2021 @07:59AM (#28256268)
In rust you have to swallow an error quite explicitly. In go it’s extremely easy to swallow one "err”, by assigning to some previous one which was already checked.
Re:Generics enabled by default in Go tip by anothernewdude on Saturday August 21, 2021 @02:42AM (#28254815)
You're right that a templating language would reduce the code and make it easier to read.