Live data from Hacker News

Go 1.18

go.dev

571–580 of 614 posts

Re: Go 1.18

#571
post #234

Earlier quoted context omitted.

Not only that, but despite all of the other syntactic sugar Go is lacking (usually sorely, such as a “try” error handler), the switch statement is really just an “if” statement in disguise. var someVar, anotherVar string // ... switch { case someVar == "whatever": fmt.Println("Tell me how, exactly,") case anotherVar == "nope": fmt.Println("this compiles to a jump table?") default: fmt.Println("Spoiler: it doesn't.")…

> the switch statement is really just an “if” statement in disguise If the switch is over a fixed set of strings, then can't the backend generate a perfect hash function ala gperf and then proceed to use the computed hash value to implement a jump table? Also, FWIW, the only compiler backends I've ever seen blindly emit a jump table all died in the '80s. Jump tables aren't always the fastest choice: https://www.cipht…

> can't the backend (...) implement a jump table?

Note that my example “switches” over two independent variables. Even if the Go compiler did generate a table, for this example it would really be generating two tables: and then we're back to the “how is this better than an `if`?” question.

Re: Go 1.18

#572

Earlier quoted context omitted.

It's trivial to store a null pointer in an Option::Some(). struct Foo; fn main() { let option_with_null: Option = Some(std::ptr::null()); dbg!(option_with_null); dbg!(option_with_null.is_none()); } Output: [src/main.rs:6] option_with_null = Some( 0x0000000000000000, ) [src/main.rs:7] option_with_null.is_none() = false https://play.rust-lang.org/?version=stable&mode=debug&editio...

As the creator of the function, you should try to adhere to the conventions and not try to break them.

I don't disagree, but:

> Some(null) is not a valid result.

It is a valid result. Null pointer and Option::None are still different things, is all.

Re: Go 1.18

#573
post #480

Earlier quoted context omitted.

We change the language; people who formerly enjoyed the language now have to put up with a language they rather not. Their only option is to quit programming since there are no programming languages they enjoy left.

Or they become adults and acknowledge programming languages are products like anything else and they either evolve or stagnate. Even COBOL and Fortran keep up with modern times! Yes, including generics.

C has entered the chat

Re: Go 1.18

#574
post #403

Earlier quoted context omitted.

Most critics of Go are well aware of its history and purported design goals. The problem is that the set of features that actually are in Go (like channels) versus those that weren't (like generics) or still aren't (like enums) doesn't really make sense when taking those design goals at face value. For example, generics. Like you say, the original claim was that they didn't want to do them because they thought that m…

> What, exactly, was gained here to justify the productivity lost while waiting? The goal isn't to wait long enough to come up with something novel. That's what research projects are for, and Go is on the exact opposite of the spectrum. If after deliberation, it turns out that a mostly similar solution is the way to go, then that's doing it "right". Also, the lost productivity that keeps getting mentioned is overblow…

It's not boring in a sense of being boring to learn, read, or write. Ada or Java are languages that are "boring" in this sense, but which nevertheless offer far better abstractions than Go.

Go is boring in a sense that it's not innovative. Go's claim to innovation is that the feature set is tuned for new users, but that's not actually the case.

Re: Go 1.18

#575

Earlier quoted context omitted.

Why would Java ever heap-allocate a local, regardless of optimizations? It can decide to heap-allocate or stack-allocate objects (when you new them) based on escape analysis, which is a JIT optimization. But that's very different from heap-allocating variables .

Then I'm not even sure what you're talking about when you say "heap-allocate even a local variable" if you don't actually mean the value of that variable. If you draw that distinction, "variables" are never allocated; spaces for values are. Regardless, whether something is a local or not in Java still varies depending on the JIT's decisions. (Or rather, the JIT does not see local/non-local variables, only lifetimes,…

In Java, the value of the variable of a class type is not an object - it's a reference to the object. Those references are always stack-allocated. Variables of primitive types like ints are also, of course, stack allocated.

In Go, if you have a local of type int, and that local is captured by a closure, it will be allocated on the heap to extend its lifetime. Java doesn't need to do this because it requires captures to be effectively final. On the other hand, C# does the same thing as Go.

Re: Go 1.18

#576

Earlier quoted context omitted.

From my work experience at the time, it was used pretty heavily in new codebases.

I mean the fact that they've been around since 2.0 but you saw it used heavily in new codebases says a lot doesn't it?

You misunderstood - I saw them in codebases that were new back when .NET 2.0 was new.

To be more precise, it was when .NET 3.5 was new (2008). That brought a lot of visibility to Nullable because it was featured prominently in LINQ. But ?. didn't come until C# 6 (2014). I was wrong about ??, though - that one was added along with Nullable itself.

Re: Go 1.18

#578

Earlier quoted context omitted.

I think you underestimate your ability. As a programmer, you've already learned and internalized abstractions that are far more complicated than anything here. `select` is often aliased to `find_all` and that's what it does: finds all elements matching what's passed to it. `take` is sometimes aliased to `first`. Expanded ever so slightly: nums.first(20).find_all { |n| n.odd? }.reduce { |sum, n| sum + n } This reads:…

Perhaps it comes down to a difference in where we spend most of our time? I'll give you an example. I once spent a full day debugging a problem that came down to the implementation details of .zip. The author had assumed that .zip would add extra null elements to the output array if the inputs didn't match in length, which is sadly not the behavior of our programming language. We determined this was the bug after bre…

> We ripped out the .zip and turned it into an explicit for loop because we wanted the behavior for the case of "these arrays are different length" to be extremely obvious to the reader.

This could have been accomplished by just extending the shorter array to the length of the longer one with no loss of clarity (and likely greater clarity, as now I don't have to read your custom implementation of `zip` every time I read this call site).

The broader point is that you found a bug where someone used a function incorrectly and instead of fixing the usage of it, you simply wrote the function inline. This same story could have been with any function call, but for some reason it seems you think that iterator methods are special and different somehow? Any function can be called incorrectly, but the solution isn't to just universally replace function calls with inline equivalents. You had a bad experience with not understanding one of these types of functions, so instead of taking a moment to internalize what they do, you decided to swear off of them entirely? I honestly, genuinely cannot understand this perspective.

> What happens if the length of this array is less than 20?

In 100% of implementations I've ever encountered, it returns fewer than 20 elements. If you want exactly 20, call `take` and then pad its length with whatever-valued elements you need. Explicit.

> What is the default return value if there are no items: None or 0?

Up to you! Pass the default return value as the first argument to the `reduce` method. Explicit.

These aren't deep and particularly confusing semantics around these methods. These are just garden-variety "I instinctively avoid these functions so I don't know the basics of how they work" types of questions. Making the answers to these questions explicit does not require splatting out the entire contents of their function definitions inline. That's not explicit, it's verbose.

> the average function takes a bit longer to parse

Code is read dozens if not hundreds of times more often than it's written. Code must be written to minimize the effort needed to understand it. The entire point of functions is to assist with this. The entire point of these specific iterator functions is that they do a phenomenal job of this, to the point where virtually every single programmer who works in languages with these idioms will understand what you mean when you say you're mapping an array.

You're absolutely capable of the same, but for some reason you've decided that these functions are magic and scary and should be avoided. They're not, and regularly avoiding them actively decreases the clarity of your code and is far more likely to increase your bug count than decrease it.

> if it means that everyone can reason about any given bit of code without trouble.

Where is the floor on this? One engineer decides that `map` or `select` or `all` isn't worth bothering to learn, so nobody gets to use them? What if they decide a `for x := range y` is too much work, does everyone go back to `for x = 0; x These functions are basic. They aren't fancy functional magic that only Haskell wizards will ever hope to comprehend. They are used in an enormous variety of languages where their users overwhelmingly find them to be a net increase in clarity while eliminating the possibility of entire classes of common derpy bugs, no differently than `for x := range y`.

Re: Go 1.18

#579
post #439

Earlier quoted context omitted.

It certainly does for me. It ties into this quote: > Why not use the syntax F like C++ and Java? A great number of us are used to seeing rather than [] for generics. It would seem limitations in Go's parser outrank a popular norm.

If you look at some of the contortions that e.g. C# has to go through when evolving the language, due to numerous ambiguities between used for types and used in expressions, I think it's still a very sensible choice.

Square brackets in go have their own parsing issues (see my original comment). I haven’t found much discussion on how any parsing issues were resolved (presumably any issues needed resolution for backwards compatibility?).

As an outsider it appears to me that the choice for square brackets has been made mostly for stylistic non-technical reasons, but perhaps politically that would be difficult to rationalise to the user-base! Making whitespace significant before comparison/shift operators (matching the gofmt layout) surely solves the stated practical issue of lookahead parsing; although I admit many language geeks would say significant space characters were an ugly solution.

To agree with you: there is a really good discussion on the downsides of here —https://lobste.rs/s/fmcviy/language_designers_stop_using_for — certainly square brackets are used for generics in other languages (Scala, Python, Nim, Eiffel).

Regardless, the point is moot, given that the syntax is now concrete!

> then by the same token is also easy to confuse with comparison operators

Not really, given that comparison/shift operators are not used in types, whereas [] is used in types. Perhaps go-lang wanted to reserve angle brackets for constraint operators a la Scala et al. .

Disclaimer: I have little experience with generics or language design. I am just very curious if there is a divergence between the stated reasons for the design, versus any unstated reasons.

Re: Go 1.18

#580
post #563

Earlier quoted context omitted.

You are posting a criticism of the feature, in response to a comment that is an answer to that criticism . If your code did not use generics, it can continue to not use generics. If you did not interact with any libraries whose need for generics was apparent, you can continue to do that too and the libraries you were using aren't going anywhere. But just because you don't interact with a problem doesn't mean it doesn…

You’ve missed the point. There are trade-offs that you are ignoring. There is no hard science that proves either of our opinions are right. I believe diversity is the better path in the face of such uncertainty, I don’t understand why you are against diversity here, and you continue to not directly answer that question. “ If your code did not use generics, it can continue to not use generics. If you did not interact…

Can't you and yours just freeze at go 1.7? That way, you get your diversity. Pretend every code base that's using go 1.8 is using java or something. A lot of us who write go everyday think generics aren't complicated and are tired or repeating ourselves.
Post reply on HN