Hacker News new | past | comments | ask | show | jobs | submit | KRAKRISMOTT's comments login

The Japanese and Koreans aren't dying early though.


Somebody probably wants more defense contracts


Extracting book titles from comments used to be an excellent exercise in named entity recognition, but with ChatGPT and transformer, it's now trivial.


Are there any solid PHP WebSockets and WebRTC setups outside of Laravel?


Symfony? Or is this a case where Laravel has actually built out their own packages for support in these two instances?



swoole makes websockets extremely easy and fast.

webRTC is a beast with the STUN server needs better handled elsewhere.


Go has typed errors, it just didn't use it in this case.


In principle. In practice, most Go code, and even significant parts of the Go standard library, return arbitrary error strings. And error returning functions never return anything more specific than `error` (you could count the exceptions in the top 20 Go codebases on your fingers, most likely).

Returning non-specific exceptions is virtually encouraged by the standard library (if you return an error struct, you run into major issues with the ubiquitous `if err != nil` "error handling" logic). You have both errors.New() and fmt.Errorf() for returning stringly-typed errors. errors.Is and errors.As only work easily if you return error constants, not error types (they can support error types, but then you have to do more work to manually implement Is() and As() in your custom error type) - so you can't easily both have a specific error, but also include extra information with that error.

For the example in the OP, you have to do a lot of extra work to return an error that can be checked without string comparisons, but also tells you what was the actual limit. So much work that this was only introduced in Go 1.19, despite MaxBytesReader existing since go 1.0 . Before that, it simply returned errors.New("http: request body too large") [0].

And this is true throughout the standard library. Despite all of their talk about the importance of handling errors, Go's standard library was full of stringly-typed errors for most of its lifetime, and while it's getting better, it's still a common occurrence. And even when they were at least using sentinel errors, they rarely included any kind of machine-readable context you could use for taking a decision based on the error value.

[0] https://cs.opensource.google/go/go/+/refs/tags/go1:src/pkg/n...


You do not have to do more work to use errors.Is or errors.As. They work out of the box in most cases just fine. For example:

    package example

    var ErrValue = errors.New("stringly")

    type ErrType struct {
        Code    int
        Message string
    }
    func (e ErrType) Error() string {
        return fmt.Sprintf("%s (%d)", e.Message, e.Code)
    }
You can now use errors.Is with a target of ErrValue and errors.As with a target of *ErrType. No extra methods are needed.

However, you can't compare ErrValue to another errors.New("stringly") by design (under the hood, errors.New returns a pointer, and errors.Is uses simple equality). If you want pure value semantics, use your own type instead.

There are Is and As interfaces that you can implement, but you rarely need to implement them. You can use the type system (subtyping, value vs. pointer method receivers) to control comparability in most cases instead. The only time to break out custom implementations of Is or As is when you want semantic equality to differ from ==, such as making two ErrType values match if just their Code fields match.

The one special case that the average developer should be aware of is unwrapping the cause of custom errors. If you do your own error wrapping (which is itself rarely necessary, thanks to the %w specifier on fmt.Errorf), then you need to provide an Unwrap method (returning either an error or a slice of errors).


Your example is half right, I had misread the documentation of errors.As [0].

errors.As does work as you describe, but errors.Is doesn't: that only compares the error argument for equality, unless it implements Is() itself to do something different. So `var e error ErrType{Code: 1, Message: "Good"} = errors.Is(e, ErrType{})` will return false. But indeed Errors.As will work for this case and allow you to check if an error is an instance of ErrType.

[0] https://play.golang.com/p/qXj3SMiBE2K


As I said, errors.Is works with ErrValue and errors.As works with ErrType. I guess the word "Is" is doing too much work here, because I wouldn't expect ErrType{Code:1} and ErrType{Code:0} to match under errors.Is, though ErrType{Code:1} and ErrType{Code:1} would, but yes you could implement an Is method to override that default behavior.


If you want errors to behave more like value types, you can also implement `Is`. For example, you could have your `ErrType`'s `Is` implementation return true if the other error `As` an `ErrType` also has the same code.


If you have a value type, you don't need to implement Is. It's just that errors.New (and fmt.Errorf) doesn't return a value type, so such errors only match under errors.Is if they have the same identity, hence why you typically see them defined with package-level sentinel variables.


Probably worth noting that errors.As uses assignability to match errors, while errors.Is is what uses simple equality. Either way, both work well without custom implementations in the usual cases.


Go errors cannot be string-typed, since they need to implement the error interface. The reason testing error types sometimes won't work is that the error types themselves may be private to the package where they are defined or that the error is just a generic error created by errors.New().

In this case the Error has an easy-to-check public type (*MaxBytesError) and the documentation clearly indicates that. But that has not always been the case. The original sin is that the API returned a generic error and the only way to test that error was to use a string comparison.

This is an important context to have when you need to make balanced decisions about Hyrum's law. As some commentators already mentioned, you should be wary of taking the extreme version of the law, which suggest that every single observable behavior of the API becomes part of the API itself and needs to be preserved. If you follow this extreme version, every error or exception message in every language must be left be left unchanged forever. But most client code doesn't just go around happily comparing exception messages to strings if there is another method to detect the exception.


They didn't have them when they implemented this code.

Back then, error was a glorified string. Then it started having more smart errors, mostly due to a popular third party packages, and then the logic of those popular packages was more or less* put back to go.

* except for stacktraces in native errors. I understand that they are not there for speed reasons but dang it would be nice to have them sometimes


Nobody teaches people to use them. There is no analog to "catch most specific exceptions" culture in other languages.


It has typed errors, except every function that returns an error returns the 'error' interface, which gives you no information on the set of errors you might have.

In other statically typed languages, you can do things like 'match err' and have the compiler tell you if you handled all the variants. In java you can `try { x } catch (SomeTypedException)` and have the compiler tell you if you missed any checked exceptions.

In go, you have to read the recursive call stack of the entire function you called to know if a certain error type is returned.

Can 'pgx.Connect' return an `io.EOF` error? Can it return a "tls: unknown certificate authority" (unexported string only error)?

The only way to know is to recursively read every line of code `pgx.Connect` calls and take note of every returned error.

In other languages, it's part of the type-signature.

Go doesn't have _useful_ typed errors since idiomatically they're type-erased into 'error' the second they're returned up from any method.


You actually should never return a specific error pointer because you can eventually break nil checks. I caused a production outage because interfaces are tuples of type and pointer and the literal nil turns to [nil, nil] when getting passed to a comparator whereas your struct return value will be [nil, *Type]


It's really hard to reconcile behavior like this with people's seemingly unshakeable love for golang's error handling.


People who rave about Go's error handling, in my experience, are people who haven't used rust or haskell, and instead have experience with javascript, python, and/or C.

https://paulgraham.com/avg.html


Exceptions in Python and C are the same. The idea with these is, either you know exactly what error to expect to handle and recover it, or you just treat it as a general error and retry, drop the result, propagate the error up, or log and abort. None of those require understanding the error.

Should an unexpected error propagate from deep down in your call stack to your current call site, do you really think that error should be handled at this specific call-site?


Nope, exceptions in Python are not the same. There are a lot of standard exceptions

https://docs.python.org/3/library/exceptions.html#concrete-e...

and standard about exception type hierarchy

https://github.com/psycopg/psycopg/blob/d38cf7798b0c602ff43d...

https://peps.python.org/pep-0249/#exceptions

Also in most languages "catch Exception:" (or similar expression) is considered a bad style. People are taught to catch specific exceptions. Nothing like that happens in Go.


Sure, there is a hierarchy. But the hierarchy is open. You still need to recurse down the entire call stack to figure out which exceptions might be raised.


C also doesn’t have exceptions and C++ similarly can distinguish between exception types (unless you just throws a generic std::exception everywhere).


Yes, python and C also do not have properly statically typed errors.

In python, well, python's a dynamically typed language so of course it doesn't have statically typed exceptions.

"a better type system than C" is a really low bar.

Go should be held to a higher bar than that.


The consumer didn't, but the error in the example is typed, it's called `MaxBytesError`.


Matching the underlying type when using an interface never feels natural and is definitely the more foreign part of Go's syntax to people who are not super proficient with it. Thus, they fall back on what they know - string comparison.


Only since go 1.19. It was a stringy error since go 1.0 until then.


Go didn't have them at the time.

Pessimistically this is yet another example of the language's authors relearning why other languages have the features they do one problem at a time.


Let's pray he can do the same for general aviation, we sorely need cheaper and better alternatives to century old Cessnas.


As soon as the government develops the technology then gets forced to bring in the oligarchs Musk will be able to take credit for it.

The issue is literally sonic booms over people's homes and businesses.


Why?


General aviation has been on the decline primarily because of the way US liability law is structured and the cost of FAA airworthiness certification. A quirk of legislation made it such that old models of planes are shielded from lawsuits, among other issues. If you are a manufacturer, why bother designing a new plane when you can keep selling the same world war 2 era stock? It's not like you will have any competition. The cost of certification is also why Boeing tried to avoid certifying the 737 max as a new plane.

https://en.wikipedia.org/wiki/General_Aviation_Revitalizatio...

https://worksinprogress.co/issue/planes-claims-and-automobil...

Fewer people are learning to fly except to go work for the airlines. Most of the small aviation manufacturers and engine producers have been snapped up by China. It's so expensive to certify an engine for flight that most of general aviation is using engines where you burn leaded fuel and manually control the carburetors and fuel injectors. In aviation, a 1940s era airframe is considered perfectly safe, and it is completely acceptable to use vacuum pneumatic instruments despite them being significantly less reliable than MEMS or solid state ring laser (or fibre optic) gyros. Even something as simple as a radar altimeter would cost well into the 5-6 figures. It's a very backwards industry similar to medicine and pharmacy. The doctors believe in hazing new grads through residency, while biotech legislators holds the view that right to try and loosening clinical trials lead to moral hazard; better ten people die from disease than for one to be accidentally killed during drug testing. It is the same in aviation, safety is written in blood and all that so the best way to stay safe is to make it too expensive to fly. Many flight schools preach training with old airframes and technology. A lot of pilots refuse to admit the real reason is because of cost, and instead come up with all sort of post-hoc fantastic explanations that students learn better when they are flying rickety vehicles with century old technology. If you want to learn to fly, find a school that offers the DA-20/DA-40 (or even better, the DA-40NG with push button start) manufactured in the past ten years. Avoid the Cessna-only places.

The FAA is trying to improved the situation with the new MOSAIC light sports aircraft policy (that's mostly half baked) and certifying more engines for unleaded fuels. But unless the White House comes down hard on them for their inaction, they are going to drag out the issue for another decade (and hopefully kill off the general aviation industry all together). Regulators don't like general aviation, especially post 911. Between drones and climate change, and the fact that general aviation pilots are mostly Midwestern farmers and upper middle class people curious about aerospace, the industry doesn't have any real advocates. Not enough nouveau riche tech bros fly, and the ones that do are often rich enough to buy their own legislators and presidents that the costs don't matter. It's the aviation version of the middle class being squeezed from both ends.

https://www.faa.gov/newsroom/faa-proposes-rule-enhance-safet...

https://www.faa.gov/unleaded

If general aviation continues to decline, it's going to become a national security issue. It's not a good world where aviation becomes a professional luxury, where aviation manufacturers cater primarily to foreign clients, and where most aerospace engineers would never have the opportunity to actually fly what they build.


Yeah and not having to breathe leaded fuel fumes and getting that stuff on our hands when checking the tanks.


Nitrile gloves + better fuel sump is a good stop gap.

https://www.aircraftspruce.com/catalog/pnpages/05-04237.php


This area doesn't seem too bad if you own a plane. It's perfect for a Skyhawk.


Do you mind removing the Segment requirement for usage? I think many users would be fine with just a standard http endpoint.


Hey KRAKRISMOTT, we have SDKs and a REST API which can be found at https://docs.dittofeed.com/integrations/sources

Open to expanding our SDK selection though.


Ah okay, it's mostly that your getting started guide specifically requires a Segment account for some reason.


Noted! I'll make sure to edit that. Thank you for the feedback.


The thing about RISC-V is that they indirectly have the R&D coffers of the Chinese government backing them for strategic reasons. They are the hardware equivalent of Uber's scale-first-make-money later strategy. This is not a competition that ARM can win purely relying on their existing market dominance.


The Elon and Thiel gang, they are not pro "SV" insomuch as being pro Thiel/Elon oligopolies. If open source AI one day threatens their livelihoods and career, the tune from the WH will change overnight. Right now the SV conservatives are playing catch up on AI so they are happy to push for laissez-faire instead of regulatory capture. I won't be suprised that should the cost of running and finetuning FB Llama models become so cheap that they start to eat into x.ai's business, all of a sudden AI is a massive national security issue and AI safety academics will go back to regurgitating talking points about imaginatory AGI terminator bots.


Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: