Hacker Newsnew | past | comments | ask | show | jobs | submit | Mond_'s commentslogin

This is begging the question. Yes, but why did they do that over dedicated syntax?

(My personal theory is that early go had a somewhat misguided idea of simplicity, and preferred overloading existing concepts with special cases over introducing new keywords. Capitalization for visibility is another example of that.)


//go:xyz is dedicated syntax that is compatible with both the language spec and other toolchains that don't know about it.


It's an overloaded comment. I am personally quite fine with it, I don't think it's bad. but it is an overloaded comment.


I'm no longer sure what you're saying. You asked why they didn't go with dedicated syntax, I listed two advantageous aspects of the chosen syntax. We know it's an overloaded comment: that's literally one of the advantages.


Well, I've been unable to follow you as well, then. Obviously if they'd used a different type of syntax (e.g. using # for annotations), those would also be compatible with the language spec, and other implementations would still be just as capable of ignoring all unknown annotations.

(Though for the record, talking about alternative implementations when discussing Go is kind of a funny joke.)


Is gccgo a joke to you?


Maybe? It's stuck at 1.18 without generics and no one has replaced its maintainer, Ian Lance Taylor, who seems to have moved on after leaving Google.

But to be fair to alternative toolchains, TinyGo and TamaGo are also a thing.


Ian Lance Taylor is in the recent commit history for the main Go implementation. He's not working at Google any more but he's still active.


I meant gccgo specifically, I don't doubt he's still active with Go in general.

Good luck compiling on a toolchain that doesn't know about //go:embed or /* */import "C" comments.


This is such a silly response when "You've gotten better at using them and know how to work around their flaws now." is right there and seems a lot more plausible.


I used Manjaro for a few years.

That's how I learned a pretty important lesson about software engineering that still informs how I work to this day.

"A layer of abstraction on top of a stateful legacy system often doesn't result in a simpler system, it just introduces exciting new failure possibilities. This especially applies when the owners of the legacy system have no responsibility over the abstraction layer."


This comment made a lot more sense to me once I realized we weren't talking about an aggressively marketed weight loss drug.


It's still true. Your metabolic system is probably not simpler after taking terzepatide. Although, just because it's not simpler doesn't mean it can't be better. I'm very glad for the C++ abstraction layer over assembly, even if the stack is more complicated than if it were just assembly


The word "legacy" doesn't seem needed there.


Can you explain it for those out of the loop?


Manjaro sells itself as "Arch, but more approachable". In reality, you'll often end up with "Arch, but with additional weird package management upgrade issues that are a byproduct of Manjaro's own repositories interacting with the arch on your system."

Instead of just having to track the arch repos, you suddenly have those and Manjaro's own stuff (and own package manager tool etc.), which is another point of failure. Every new bit of technology is another part that can fail.


I think a lot of the really old school people don't care, but a lot of the younger people (especially those disillusioned with C++ and not fully enamored with Rust) are in fact quite happy for C to evolve and improve in conservative, simple ways (such as this one).


The tradeoff Go made is that certain code just cannot be written in it.

Its STD exists because Go is a language built around a "good enough" philosophy, and it gets painful once you leave that path.


> The tradeoff Go made is that certain code just cannot be written in it.

Uh... yeah? That's true of basically all platforms, and anyone who says otherwise is selling something.

> it gets painful once you leave that path

Still less painful than being zero-day'd by a supply chain attack.


> > The tradeoff Go made is that certain code just cannot be written in it.

> Uh... yeah? That's true of basically all platforms, and anyone who says otherwise is selling something.

What code can you not write in C?

Might be painful for some(many) cases, but there is nothing you can't write in C.


SIMD code.

And if you are going to point out compiler extensions, they are extensions exactly because ISO C cannot do it.


> What code can you not write in C?

This falls under the "selling somthing" angle I mentioned. Yes yes yes, generality and abstraction are tradeoffs and higher level platforms lack primitives for things the lower levels can do.

That is, at best, a ridiculous and specious way to interpret the upthread argument (again c.f. "selling something").

The actual point is that all real systems involve tradeoffs, and one of the core ones for a programming language is "what problems are best solved in this language?". That's not the same question as "what problems CAN be solved in this language", and trying to conflate the two tells me (again) that you're selling something. The applicability of C to problem areas it "can" solve has its own tradeoffs, obviously.


not really in-topic but constant-time crypto primitives are considered hard for any compiled language with a lot of optimizations


Bad news, John Google told me they already quantized it immediately after the benchmarks were done and it sucks now.

I miss when Gemini 3.1 was good. :(


OpenAI has a whole history of trying to scoop other providers. This was a whole thing for Google launches, where OpenAI regularly launched something just before Google to grab the media attention.


Some recent examples:

GPT-4o vs. Google I/O (May 2024): OpenAI scheduled its "Spring Update" exactly 24 hours before Google’s biggest event of the year, Google I/O. They launched GPT-4o voice mode.

Sora vs. Gemini 1.5 Pro (Feb 2024): Just two hours after Google announced its breakthrough Gemini 1.5 Pro model, Sam Altman tweeted the reveal of Sora (text-to-video).

ChatGPT Enterprise vs. Google Cloud Next (Aug 2023): As Google began its major conference focused on selling AI to businesses, OpenAI announced ChatGPT Enterprise.


why call him that when "saltman" is right there


The Dr Seuss reference was more appealing to me at the time


I can't get over Scam Altman.


It's worth pointing out that the two examples that you're writing are actually strictly different, and not just "better syntax for the same thing". (This is assuming `String | Int` works as in Python, and the second example works as in Rust.)

To understand the difference, `String | String` is just `String`. It's a union, not a sum type. There's no tag or identifier, so you cannot distinguish whether it's the first or the second string.

If this sounds pedantic, this has pretty important ramifications, especially once generics get involved.


To provide a concrete example, this bit me in a typescript codebase:

    type Option<T> = T | undefined

    function f<T>(value: T): Option<T> { ... }

    let thing: string | undefined = undefined;
    let result = f(thing);
Now imagine the definition of Option is in some library or other file and you don't realize how it works. You are thinking of the Option as its own structure and expect f to return Option<string | undefined>. But Option<string | undefined> = string | undefined | undefined = string | undefined = Option<string>.

The mistake here is in how Option is defined, but it's a footgun you need to be aware of.


The mistake here is that you assume that Option is a struct. For TypeScript, this is an idiomatic definition of something that is optional though.


I guess I just want to be able to do something like this in Swift:

    let x: String | Int
    
    switch x {
        case let value as String:
            // handle String value here
        case let value as Int:
            // handle Int value here
    }
There's one more thing about TypeScript-style union types: string literals. I think it's great to be able to do

    type Options = "option_1" | "option_2" ... "option_n"
And subsequently I could use

    let t: Options
    switch t {
        case "option_1":
            // handle `"option_1"` case here
        ...
        case "option_n":
            // handle `"option_n"` case here
    }
I think this is more programmer friendly than requiring an out-of-line definition of a new `enum`. Sometimes you just want to write some code, you know?


Hijacking your comment because this is a common point that's made on the superiority of Swift syntax against the union syntax.

At least with |, you're attempting to model the state space. You're saying "this is one of these things." You might get the exhaustiveness wrong, but you're in the right ballpark. As it's normally done right now, the Swift developer with five optional properties is modeling state as "maybe this, maybe that, maybe both, who knows, good luck." which is just worse than a bar. If you need to discriminate explicitly, add a `__kind` field!


So long as you have structurally typed structs (as TypeScript does), you can do stuff like {foo: string} | {bar: string} to the same effect as type constructors if and when you actually need it.

At the same time, how often do you really need (Just (Just (Just ...)))?


Sounds like it might be an issue with your setup, considering that other people have no problems running it. Hard to tell what the problem is, but definitely a frustrating situation.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: