Live data from Hacker News

Toward Go 2

blog.golang.org

461–470 of 670 posts

Re: Toward Go 2

#461
post #76

Earlier quoted context omitted.

Java has "had" anonymous functions for ages with anonymous inner classes, they just sucked as an implementation.

Absolutely correct. Lambdas are just shorthand for anonymous inner classes which implement an interface with only one method -- aka single abstract method (SAM) types. For instance, you have two functions. One takes `Function ` and the other takes `UnaryOperator `. Giving the "same" lambda to both functions will result in two anonymous inner types, one implementing both interfaces.

Lambdas are also more aggressively optimized. If possible, the compiler will sometimes turn a lambda into a static method.

Re: Toward Go 2

#462
post #426
post #291

Earlier quoted context omitted.

I'm not even a Go developer, I just played with it a bit a couple of years ago and used it for a small one-off internal API thing, and I can think of a dozen real-world use cases for generics off the top of my head. * type-safe containers (linked lists, trees, etc.) * higher order functions (map, reduce, filter, etc.) * database adapters (i.e. something like `sql.NullColumn ` instead of half a dozen variations on `sq…

It's generally the opinion of the Go community that map, reduce and filter are bad ideas due to how easily they are abused. A for loop gets the job done easily enough. If you've ever worked with data scientists working with Python, you'll quite often see them all chained together, probably with some other list comprehensions thrown in until it becomes one incomprehensible line.

If that's the case, then the Go community is wrong.

For loops do not get the job done easily enough. I've lost count of the number of times I've had to do contortions in order to count backwards inclusive down to zero with an unsigned int. With a proper iterator API, it's trivial.

Furthermore, for loops are a pain to optimize. They encourage use of indices everywhere, which results in heroic efforts needed to eliminate bounds checks, effort that is largely unnecessary with higher level iterators. Detecting the loop trip count is a pain, because the loop test is reevaluated over and over, and the syntax encourages complicated loop tests (for example, fetching the length of a vector over and over instead of caching it). For loop trip count detection is one of the major reasons why signed overflow is undefined in C, and it's a completely self-inflicted wound.

I'm generally of the opinion nowadays that adding a C-style for loop to a language is a design mistake.

Re: Toward Go 2

#463
post #425

Earlier quoted context omitted.

What? Manage it the way you'd manage any other environment variables, like AWS_SECRET_ACCESS_KEY. That's exactly what a bash environment is for.

You want to manage GOPATH as if it were a secret key!? Not ever storing it in repos, having weird dotfiles storing them locally, having to set up a keystore cluster like consul in production? Yuck.

The point is it's a per-project config. And yeah, there's no reason to store "/home/artur/go" in my git repo - that wouldn't work for my coworkers whose names are not Artur.

Re: Toward Go 2

#464

Earlier quoted context omitted.

I've described Go programs as often looking like a listing of things that could go wrong.

Which is exactly what software engineers should spend most of their time doing.

It really doesn't have to be that way. See http://fsharpforfunandprofit.com/posts/recipe-part2

Re: Toward Go 2

#465
post #442

I should send this to rsc, but it's fairly easy to find examples where the lack of generics caused an opportunity cost. (1) I started porting our high-performance, concurrent cuckoo hashing code to Go about 4 years ago. I quit. You can probably guess why from the comments at the top of the file about boxing things with interface{}. It just got slow and gross, to the point where libcuckoo-go was slower and more bloate…

> fundamental containers like this really benefit from being type-safe

Note that, at least in its current form, the native concurrent map type uses interface{} for all keys and values, and therefore offers no type safety:

https://github.com/golang/go/blob/master/src/sync/map.go

See also: https://github.com/golang/go/issues/18177

All of Go's built-in pseudo-generic types (e.g. maps) require special support from the parser. I'm not sure if they plan on doing that for sync.Map as well, but this is clearly an area that could benefit from generics.

Re: Toward Go 2

#466

Earlier quoted context omitted.

Calling those languages screw ups is one of the funnier things I've seen in awhile.

I know that both Java and C++ have a lot more issues than Golang ever will. I've used all three languages. Java has mile long class hierarchies, massive try-catch blocks, indentation as thick as my neck, and runs in a JVM. It's so bad there are already other implementations that people would much rather use. I also really don't like the file/project naming conventions. C++ is a whole other animal. The whole system of…

> know that both Java and C++ have a lot more issues than Golang ever will.

No you don't. But even if I granted that Golang has a bright future (I don't think it does) by any objective measure C++ and Java are more successful than Golang. LOC, number of devs, performance, install base, etc. Pick a measure other than current hype (not even peak hype) and either Java or C++ trounces Golang.

> I've used all three languages.

I have too. I program golang full time and have for 3 years. I'd switch tomorrow to either of the other languages if I could wave a magic wand (and I'm a fair hater of both).

> and runs in a JVM

I desperately miss the JVM (any of the ones I've used). The amount of sophistication and polish in comparison to the Golang runtime is embarrassing. Debugger support, operational sophistication, IDES, tooling, basically everything is better on any of the JVMs I've used in comparison to the golang runtime.

>Java has mile long class hierarchies, massive try-catch blocks, indentation as thick as my neck

And go has ridiculous copy/paste libraries, horrendous concurrency edge cases, terrible error handling, worse third party libraries and no story around packages.

> There are lots of cross compilation and static linking problems that don't arise with Go.

Because dependency management is not possible in golang. It is literally the worst story in any language I've used in 20 years. You have 2 choice in golang half baked vendoring or a monorepo where you have all of your code in one place.

> Compared to them Go is a very well thought out and elegant language

No, compared to them Go is a young language. There aren't any big projects in Golang yet. We shall see if there ever will be. My theory is that either none will ever happen as some other language will be a better choice, or golang will adapt and all the things people claim are benefits (simplicity, default tooling) will go away, crushed under the reality of complex projects being complex.

Re: Toward Go 2

#467
post #426
post #291

Earlier quoted context omitted.

I'm not even a Go developer, I just played with it a bit a couple of years ago and used it for a small one-off internal API thing, and I can think of a dozen real-world use cases for generics off the top of my head. * type-safe containers (linked lists, trees, etc.) * higher order functions (map, reduce, filter, etc.) * database adapters (i.e. something like `sql.NullColumn ` instead of half a dozen variations on `sq…

It's generally the opinion of the Go community that map, reduce and filter are bad ideas due to how easily they are abused. A for loop gets the job done easily enough. If you've ever worked with data scientists working with Python, you'll quite often see them all chained together, probably with some other list comprehensions thrown in until it becomes one incomprehensible line.

Yes, people can get crazy with inline anonymous function chaining/composition, and that can quickly get out of hand in terms of maintainability and readability, but deeply nested imperative loops is often much, much worse to debug and understand, because the intermediate steps are not nearly as explicit as in a functional chain/composition that simply takes data and returns data at every step.

Regardless, these are simply cases of people writing bad code, and nobody is claiming map/reduce/filter is a panacea for bad code.

Functional composition/chaining works best with small, well-named single purpose functions that compose/chain together into more complex functionality (with appropriate names at every non-trivial level of chaining/composition). You can't easily compose/chain imperative loops this way (at least not without wrapping them in functions that take data, and returns transformed data, by which point you might as well use map/reduce/filter to transform the data to begin with to get rid of the impedance mismatch).

Re: Toward Go 2

#468
post #308

Earlier quoted context omitted.

Nearly every item on your list is available with OCaml.

I really enjoy writing OCaml but I hate all the tooling around it. It lacks a good package management and build system à la Cargo.

The build system is a bit funky but the opam package manager is actually one of the nicest I have used.

Re: Toward Go 2

#469

Earlier quoted context omitted.

In my specific case it was the fact that i could not have one insert function or one update function. I would need one for each and every struct(table). These days there is a tool that can generate all those struct methods: https://github.com/vattle/sqlboiler So from the ORM perspective we (as the community) have worked around it.

I guess I don't see how generics would help you reduce the number of insert/update functions. The basic problem of an ORM is to map struct fields to columns; I don't see how generics would help you here. Can you write the generic pseudocode you want to write?

I would guess something like:

    class Collection {
        void insert(T entity) {
            String vals = entity.props.map(escapeSql).join(",");
            String qs = entity.props.map(x => "?").join(",");
            PreparedStatement p = db.prepare("insert into %s (%s) values (%s);", this.tableName, qs, vals);
            db.submit(p);
        }
    }

Re: Toward Go 2

#470
post #86
post #12

Earlier quoted context omitted.

> no longer even bother participating in Go-related discussions, because they've believe it will never happen /raises hand I like when tools are good, but I've basically written off Go as a tool for generating unsustainable code right now (and a big part of it is the odious options, either type-unsafety or code generation, for things that are trivially handled by parametricity). If things change, I'll be happy to rev…

I kind of think the same way, but thanks to Docker and K8s success, it means we might have to deal with Go code regardless how we think about it.

Maybe. My intuition is that k8s is going to lose its luster once people actually have to do a little math related to its costs; while I think there are real reasons for something like it in on-prem environments, I think the cloud-in-your-cloud-so-you-can-cloud-while-you-cloud approach currently being rolled out is profoundly unwise. (Which is to say: k8s is functionally something to weld together to make an OpenStack alternative--such as it is--rather than a layer to plop on top of one.)

Docker...yeah. We're stuck with it there. And their historical security posture doesn't make me super excited, but...yeah.

I hate when you're right. But you usually are.

Post reply on HN