Google Cloud Platform and near-perfect documentation



  • @dkf said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    There's also no overhead to error handling

    That's literally impossible (except with really silly definitions of “overhead”). That the error handling is explicit doesn't make it free; the point where a problem occurs and where its resolution is best done are often not coincident and there is always some sort of cost involved in linking the two together. One of the overheads that is forced upon you with Go's design choices in this area is that you have to write more explicit error handling code than you would in some other languages. It might be a reasonable trade-off, but it's definitely not free. (FWIW, languages that use exceptions can do clever things to optimise the error path that make their use not as expensive as you might think; the key trick is in understanding what is actually observed, not just what is potentially observable by some code that could be written but hasn't been in this case.)

    They're trying to fix that: https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md


  • Discourse touched me in a no-no place

    @ben_lubar said in Google Cloud Platform and near-perfect documentation:

    They're trying to fix that: https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md

    The thing that they're going to find awkward is that there's a massive gulf between having too little information to be able to diagnose a problem (🖥 couldn't open file 👨 “But which file and why were you opening it? I didn't know I was asking for a file to be opened…”) and having full information (which is inevitably far too much, and the cost of building the reportable description of what was going on is the single biggest runtime cost of exception handling), and charting a route through is very difficult indeed. What's worse, the right answer to that particular trade-off depends very much on what the overall application is doing and what the error really was. Which isn't always apparent on first glance either.

    Error handling well is harder than it looks. In all languages.


  • Notification Spam Recipient

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @ben_lubar You do realize that wasn't actually the point, right? I'm talking about speed of stack vs heap.

    Could have fooled me, you were talking about methods defining the interface and whether that counts as the same thing or not.


  • Discourse touched me in a no-no place

    @ben_lubar said in Google Cloud Platform and near-perfect documentation:

    I wouldn't worry about garbage collection pause time.

    I would worry about using Go.


  • Considered Harmful

    @dkf said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    There's also no overhead to error handling

    That's literally impossible (except with really silly definitions of “overhead”). That the error handling is explicit doesn't make it free; the point where a problem occurs and where its resolution is best done are often not coincident and there is always some sort of cost involved in linking the two together. One of the overheads that is forced upon you with Go's design choices in this area is that you have to write more explicit error handling code than you would in some other languages. It might be a reasonable trade-off, but it's definitely not free. (FWIW, languages that use exceptions can do clever things to optimise the error path that make their use not as expensive as you might think; the key trick is in understanding what is actually observed, not just what is potentially observable by some code that could be written but hasn't been in this case.)

    In Rust it's free completely. If you're calling a function, and both your function and the called function return Result, and the error types are compatible (which () or Box<Error> are cheap I-don't-care catch-alls), you can add ? at the end of the called function, which will either unwrap the value or return the error. That is what I would call zero-cost error handling, both from a programming perspective and an execution-time perspective.


  • Considered Harmful

    @dkf said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    But the stack and the heap are not simply locations; they have completely different allocation procedures and the latter is far slower.

    Sounds like you've never written an actually intelligent stack allocation system. The trick is knowing where the costs actually are. (Usually it's because heaps have to support multithreaded access whereas stacks as per-thread, which forces the use of locking, and that's very much not free.)

    Does it matter? The stack is fast, the heap is slow, use the heap only if you can't use the stack or using the stack would require giant copies.


  • Considered Harmful

    @ben_lubar said in Google Cloud Platform and near-perfect documentation:

    https://twitter.com/brianhatfield/status/900473287750365184

    I wouldn't worry about garbage collection pause time.

    Yes, we know. They've optimized GC pause time to an insane degree, at the expense of every other stat about a GC.


  • Considered Harmful

    @Tsaukpaetra said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @ben_lubar You do realize that wasn't actually the point, right? I'm talking about speed of stack vs heap.

    Could have fooled me, you were talking about methods defining the interface and whether that counts as the same thing or not.

    If you've got nothing to add except lazy whining, why participate?



  • @pie_flavor

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    If you've got nothing to add except lazy whining, why participate?


  • Considered Harmful

    @ben_lubar

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    Now, can you get back to telling me why using an alternative, slower form of memory without telling the programmer is a good idea?


  • Discourse touched me in a no-no place

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    In Rust it's free completely.

    Except it doesn't compile into no code at all, adds to the complexity of the compiler, and makes code more complex to write. That's not free. It might be cheap, it might possibly be cheaper than other alternatives (a measurable hypothesis) but it is not free.


  • Notification Spam Recipient

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @Tsaukpaetra said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @ben_lubar You do realize that wasn't actually the point, right? I'm talking about speed of stack vs heap.

    Could have fooled me, you were talking about methods defining the interface and whether that counts as the same thing or not.

    If you've got nothing to add except lazy whining, why participate?

    Because fuck you, that's why. Duh. :rolleyes:


  • Considered Harmful

    @dkf said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    In Rust it's free completely.

    Except it doesn't compile into no code at all, adds to the complexity of the compiler, and makes code more complex to write. That's not free. It might be cheap, it might possibly be cheaper than other alternatives (a measurable hypothesis) but it is not free.

    It's an if-check against a one-byte discriminant. There is no form of error handling that's more free. The compiler isn't complex because of it - ? is just a shortcut for the try! macro which is implemented without the compiler's help. And the code is not more complex to write because you literally just add a single character, which has an unambiguous meaning since it isn't used anywhere else, to propagate the error.



  • @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    There is no form of error handling that's more free

    That doesn't mean it is free, and also you are wrong because the cheapest possible error handling is handing the error at the point when the error occurs so it never needs to be re-checked.


  • Considered Harmful

    @ben_lubar No, we're talking about error handling mechanisms, not error handling techniques. The error handling mechanism in Rust is matching against the Result enum, and the ? operator is a macro for doing exactly that. If you wrote

    let x = do_thing()?;
    

    then that would be expanded to

    let x = {
        match do_thing() {
            Ok(val) => val,
            Err(err) => return Err(err.into()),
        }
    };
    


  • @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @ben_lubar No, we're talking about error handling mechanisms, not error handling techniques. The error handling mechanism in Rust is matching against the Result enum, and the ? operator is a macro for doing exactly that. If you wrote

    let x = do_thing()?;
    

    then that would be expanded to

    let x = {
        match do_thing() {
            Ok(val) => val,
            Err(err) => return Err(err.into()),
        }
    };
    

    So you're telling me that the CMP instruction is not followed by any sort of jump?


  • Considered Harmful

    @ben_lubar what?



  • @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @ben_lubar what?

    Your magical innovation in error handling is better known as an "if statement".


  • Considered Harmful

    @ben_lubar said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @ben_lubar what?

    Your magical innovation in error handling is better known as an "if statement".

    No, match is actually more of a switch statement.
    I assume you have a point? I was talking about speed and usability, and now you're complaining 'well your "" abstraction"" is just really an abstraction'



  • @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    I was talking about speed

    You claimed the error handling is free, even though an if statement is probably one of the most expensive instructions in any programming language.


  • Considered Harmful

    @ben_lubar Ah, I see. Now you're :pendant:ing me against 'free', comparing it to doing nothing at all instead of comparing it to every other possible error handling scheme. It is exactly as free as simply returning an unsigned result in a signed data type and returning -1 on error. No error handling scheme that I know of is more free, but you're welcome to come up with an actual example.


  • Notification Spam Recipient

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    free

    It's the definition of this very word that's what half of the conversation has been about, what are you smoking?


  • Considered Harmful

    @Tsaukpaetra There's free as in no checks, there's free as in no useless checks, there's free as in no heap allocations, and there's free as in no useless heap allocations. There's no error handling mechanism possible that has no checks, but the ? operator has no useless checks. However, if you take it as a given that there must be a conditional jump somewhere, and evaluate only the parts of the error handling mechanism that aren't that singular conditional (and other mandatory elements, like moving an error value onto the stack), then Rust's is entirely free.



  • I'm glad the derailed thread is staying on topic. Good job TDWTFers.

    On a 'side' note, gave up on GCP and went back to AWS.



  • @pie_flavor But is it free as in beer, or free as in speech? 🚎


  • Discourse touched me in a no-no place

    @coderpatsy said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor But is it free as in beer, or free as in speech? 🚎

    Free as defined in the parallel universe, which is likely neither in our universe.


  • ♿ (Parody)

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @dkf said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    But the stack and the heap are not simply locations; they have completely different allocation procedures and the latter is far slower.

    Sounds like you've never written an actually intelligent stack allocation system. The trick is knowing where the costs actually are. (Usually it's because heaps have to support multithreaded access whereas stacks as per-thread, which forces the use of locking, and that's very much not free.)

    Does it matter? The stack is fast, the heap is slow, use the heap only if you can't use the stack or using the stack would require giant copies.

    That sounds a lot like what @ben_lubar was saying that Go does.


  • Considered Harmful

    @boomzilla The important thing there is that according to Ben, Go will automatically do it for you without telling you. So if you meant to write it another way, or it was reporting a false positive, then you get a performance hit to your app that you may never find versus a compile error that you could fix in two seconds.


  • ♿ (Parody)

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    The important thing there is that according to Ben, Go will automatically do it for you without telling you. So if you meant to write it another way, or it was reporting a false positive, then you get a performance hit to your app that you may never find versus a compile error that you could fix in two seconds.

    Yes, in your hypothetical ass pull. I find it more likely that you'll decide to do it wrong and introduce either an error or your own performance hit.


  • Considered Harmful

    @boomzilla said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    The important thing there is that according to Ben, Go will automatically do it for you without telling you. So if you meant to write it another way, or it was reporting a false positive, then you get a performance hit to your app that you may never find versus a compile error that you could fix in two seconds.

    Yes, in your hypothetical ass pull. I find it more likely that you'll decide to do it wrong and introduce either an error or your own performance hit.

    what? You're basically saying that people shouldn't be allowed to make decisions about performance since they'll make the wrong ones.


  • ♿ (Parody)

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @boomzilla said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    The important thing there is that according to Ben, Go will automatically do it for you without telling you. So if you meant to write it another way, or it was reporting a false positive, then you get a performance hit to your app that you may never find versus a compile error that you could fix in two seconds.

    Yes, in your hypothetical ass pull. I find it more likely that you'll decide to do it wrong and introduce either an error or your own performance hit.

    what? You're basically saying that people shouldn't be allowed to make decisions about performance since they'll make the wrong ones.

    Yes, absolutely! At this sort of level they're more likely to make a bad decision than a compiler will.

    👨 I once had something bad happen when I put it all on the stack, better just put it on the heap for safety!

    Of course, 99% of the time it won't really matter either way.



  • @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @Tsaukpaetra There's free as in no checks, there's free as in no useless checks, there's free as in no heap allocations, and there's free as in no useless heap allocations. There's no error handling mechanism possible that has no checks, but the ? operator has no useless checks. However, if you take it as a given that there must be a conditional jump somewhere, and evaluate only the parts of the error handling mechanism that aren't that singular conditional (and other mandatory elements, like moving an error value onto the stack), then Rust's is entirely free.

    If you use exceptions, as implemented in most modern c++ compilers, you avoid having an if at every function call at the cost of making the exceptional case more expensive (have to do a bunch of things to find your catch clause, then unwind the stack, etc). So exceptions are more free for the happy path (which should be what gets executed the most) and less free on the exceptional path.

    So your assertion that rust is as free as possible is wrong. It's just uniformly expensive.

    Also, your 1 byte flag is going to cost you at least 4 bytes or more (depending on what you are returning) due to alignment and padding rules.


  • Considered Harmful

    @boomzilla said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @boomzilla said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    The important thing there is that according to Ben, Go will automatically do it for you without telling you. So if you meant to write it another way, or it was reporting a false positive, then you get a performance hit to your app that you may never find versus a compile error that you could fix in two seconds.

    Yes, in your hypothetical ass pull. I find it more likely that you'll decide to do it wrong and introduce either an error or your own performance hit.

    what? You're basically saying that people shouldn't be allowed to make decisions about performance since they'll make the wrong ones.

    Yes, absolutely! At this sort of level they're more likely to make a bad decision than a compiler will.

    👨 I once had something bad happen when I put it all on the stack, better just put it on the heap for safety!

    Of course, 99% of the time it won't really matter either way.

    That's retarded. Stack, the most efficient option, is the default. And it is pointless to try to shelter people from making poor performance decisions at the expense of not being able to make good performance decisions - you make your language underpowered on purpose.
    Which you know. You're just trolling at this point, right?


  • ♿ (Parody)

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @boomzilla said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @boomzilla said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    The important thing there is that according to Ben, Go will automatically do it for you without telling you. So if you meant to write it another way, or it was reporting a false positive, then you get a performance hit to your app that you may never find versus a compile error that you could fix in two seconds.

    Yes, in your hypothetical ass pull. I find it more likely that you'll decide to do it wrong and introduce either an error or your own performance hit.

    what? You're basically saying that people shouldn't be allowed to make decisions about performance since they'll make the wrong ones.

    Yes, absolutely! At this sort of level they're more likely to make a bad decision than a compiler will.

    👨 I once had something bad happen when I put it all on the stack, better just put it on the heap for safety!

    Of course, 99% of the time it won't really matter either way.

    That's retarded. Stack, the most efficient option, is the default. And it is pointless to try to shelter people from making poor performance decisions at the expense of not being able to make good performance decisions - you make your language underpowered on purpose.

    I think you're being ridiculous and imagining things that just aren't so at this point.

    Which you know. You're just trolling at this point, right?

    My honest opinion is that you misunderstood what was said. Next is that I'm being trolled, but I think that's a much lower probability.


  • Considered Harmful

    @Kian said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    @Tsaukpaetra There's free as in no checks, there's free as in no useless checks, there's free as in no heap allocations, and there's free as in no useless heap allocations. There's no error handling mechanism possible that has no checks, but the ? operator has no useless checks. However, if you take it as a given that there must be a conditional jump somewhere, and evaluate only the parts of the error handling mechanism that aren't that singular conditional (and other mandatory elements, like moving an error value onto the stack), then Rust's is entirely free.

    If you use exceptions, as implemented in most modern c++ compilers, you avoid having an if at every function call at the cost of making the exceptional case more expensive (have to do a bunch of things to find your catch clause, then unwind the stack, etc). So exceptions are more free for the happy path (which should be what gets executed the most) and less free on the exceptional path.

    So your assertion that rust is as free as possible is wrong. It's just uniformly expensive.

    Rust actually has a stack unwinding error, called thread panic. If you do not intend that your code will ever run into an error, you can call unwrap() on a Result or Option type which panics if it's Err or None respectively. Additionally, many common operations have variants that panic instead of returning a Result. Lastly, don't quote me on this, but I think that Result checks take advantage of prediction and predict the successful path.

    Also, your 1 byte flag is going to cost you at least 4 bytes or more (depending on what you are returning) due to alignment and padding rules.

    Maybe in C++ land; I don't know how struct packing works there. But in Rust size gets rounded up after adding all the fields together, not before.



  • @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    Rust actually has a stack unwinding error, called thread panic. If you do not intend that your code will ever run into an error, you can call unwrap() on a Result or Option type which panics if it's Err or None respectively.

    What does a panic entail, exactly? Can you catch a panic? Can you create an arbitrary structure holding data at the point of the panic and pass that to wherever it can be addressed, even across threads? Or does it just kill the thread/application at that point? And if you can handle a panic, why didn't they just call it exceptions?

    Maybe in C++ land; I don't know how struct packing works there. But in Rust size gets rounded up after adding all the fields together, not before.

    Presumably rust is putting that flag on the stack next to the data that actually matters, yes? That byte is going to either be at the start of the structure, next to the last thing on the stack, or at the end of the structure, and the next thing that goes on the stack will follow it.
    If it's at the start of the structure, then you are going to need to pad the result so that the result itself is aligned. Suppose the last thing on the stack was a pointer, so the next available spot is already aligned on an 8 byte boundary. You stick your byte there, and now you need to push the result down 1, 3, or 7 bytes to the next boundary (depending on the alignment requirements of your result). If it's at the end of the result, same thing. If the data happened to end at a particular boundary, the byte that tells you if you have a result or an error pushes the next thing that will go on the stack to the next alignment boundary. 1 byte structures are annoying like that, unless you can pack many of them together.



  • @boomzilla said in Google Cloud Platform and near-perfect documentation:

    Yes, in your hypothetical ass pull

    Now I just have to wait for the right moment in a meeting to use this line.


  • Considered Harmful

    @Kian said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    Rust actually has a stack unwinding error, called thread panic. If you do not intend that your code will ever run into an error, you can call unwrap() on a Result or Option type which panics if it's Err or None respectively.

    What does a panic entail, exactly? Can you catch a panic? Can you create an arbitrary structure holding data at the point of the panic and pass that to wherever it can be addressed, even across threads? Or does it just kill the thread/application at that point? And if you can handle a panic, why didn't they just call it exceptions?

    You can, in fact, catch a panic, and retrieve an arbitrary data structure from it. However, this is implementation-defined. If panicking results in stack unwinding, then std::panic::catch_unwind will catch it. But if panicking results in program abort, then you won't catch anything. For this reason it is not recommended to use panics as a general-purpose try/catch mechanism.

    Maybe in C++ land; I don't know how struct packing works there. But in Rust size gets rounded up after adding all the fields together, not before.

    Presumably rust is putting that flag on the stack next to the data that actually matters, yes? That byte is going to either be at the start of the structure, next to the last thing on the stack, or at the end of the structure, and the next thing that goes on the stack will follow it.
    If it's at the start of the structure, then you are going to need to pad the result so that the result itself is aligned. Suppose the last thing on the stack was a pointer, so the next available spot is already aligned on an 8 byte boundary. You stick your byte there, and now you need to push the result down 1, 3, or 7 bytes to the next boundary (depending on the alignment requirements of your result). If it's at the end of the result, same thing. If the data happened to end at a particular boundary, the byte that tells you if you have a result or an error pushes the next thing that will go on the stack to the next alignment boundary. 1 byte structures are annoying like that, unless you can pack many of them together.

    I went and looked up more about packing and I guess you're right. But the padding doesn't affect the size of the processed value, right? When I was saying one byte discriminant, I meant that that's the fastest thing to compare against.



  • @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    You can, in fact, catch a panic, and retrieve an arbitrary data structure from it. However, this is implementation-defined. If panicking results in stack unwinding, then std::panic::catch_unwind will catch it. But if panicking results in program abort, then you won't catch anything. For this reason it is not recommended to use panics as a general-purpose try/catch mechanism.

    So they added exceptions to the language, but specified them to be shitty on purpose ("it's implementation defined whether they're useful"), despite "zero cost" exceptions being a solved problem, so people wouldn't use them? I had given up on Rust when I heard they didn't have exceptions, but they're being actively hostile to the concept.


  • Considered Harmful

    @Kian said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    You can, in fact, catch a panic, and retrieve an arbitrary data structure from it. However, this is implementation-defined. If panicking results in stack unwinding, then std::panic::catch_unwind will catch it. But if panicking results in program abort, then you won't catch anything. For this reason it is not recommended to use panics as a general-purpose try/catch mechanism.

    So they added exceptions to the language, but specified them to be shitty on purpose ("it's implementation defined whether they're useful"),

    C++ does that too. For example, the process will crash if an exception is thrown in a destructor. Rust just makes it explicit: there's a way to trigger a panic, and there's a way to catch a stack unwind, but there isn't any guarantee that a panic causes a stack unwind.

    despite "zero cost" exceptions being a solved problem, so people wouldn't use them? I had given up on Rust when I heard they didn't have exceptions, but they're being actively hostile to the concept.

    I looked it up, and I was right about that branch prediction. Rust actually has an attribute for that, #[cold], which makes sure that that branch is predicted not to happen, and it's used in error handling functions and macros. Most of that stuff will get inlined out anyway, and if you are absolutely 100% sure that it will never error there's a macro to optimize out the if-check and assert the result.



  • @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    C++ does that too. For example, the process will crash if an exception is thrown in a destructor.

    C++ doesn't do what you described, and everything that does happen follows clear rules defined by the spec. It's not up to the implementation.

    Specifically, it is dangerous to allow an exception to escape a destructor (you can throw exceptions within the destructor as long as you also catch them in the destructor perfectly safely) because destructors get called during stack unwinding. If there's an exception calling destructors, and another exception shows up and also tries to unwind the stack, there's no way to resolve which catch clause should be used to handle them and std::terminate is called.

    The same generally happens with any error handling mechanism in any language though. There's no reasonable way to handle errors generated by the error handling code until the first error is handled, and by that time the context of the second error would be gone.

    If your destructor is called during the regular flow of the program, however, it would be just fine to let the exception slip out. Of course, it's hard (rather, a bit of obscure trivia*) to tell whether your destructor was called due to stack unwinding or the object's lifetime ending normally, so it is widely recommended not to let it happen. If you know what you are doing, you could have your destructor throw when called normally and not throw during exception unwinding though.

    • In case you're curious, to tell if your destructor was called due to stack unwinding, you would store the value returned by std::uncaught_exceptions in the constructor, store it in your object, and check it in the destructor. If the value is the same you were called normally, if the value is higher you were called due to an exception. This has very rare uses and can mostly be ignored.

  • Considered Harmful

    @Kian said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    C++ does that too. For example, the process will crash if an exception is thrown in a destructor.

    C++ doesn't do what you described, and everything that does happen follows clear rules defined by the spec. It's not up to the implementation.

    Actually, if there's no handler found, it is implementation-defined in C++ whether it unwinds or not before calling std::terminate(). Meanwhile, in Rust, it's called thread panic because it ends at the thread boundary; calling join on a thread will return a Result representing whether the thread panicked or not.



  • @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    Actually, if there's no handler found, it is implementation-defined in C++ whether it unwinds or not before calling std::terminate().

    Granted, in the specific case of program termination due to an uncaught exception, you can't portably rely on whether destructors were called. Normally you wouldn't care (your program is crashing because you didn't have code in place to handle the error, and you don't need it to remain in a consistent state because the next state of the program is "gone"), but you can force destructors to be called by having a catch all clause in main and rethrowing (or exiting cleanly with a message that you don't know what went wrong). So it's not specified in case you don't care, and you have a way to force consistent behavior if you do

    pie_flavor said in Google Cloud Platform and near-perfect documentation:

    Meanwhile, in Rust, it's called thread panic because it ends at the thread boundary; calling join on a thread will return a Result representing whether the thread panicked or not.

    That's interesting. In c++ using std::async will return a std::future, which can hold the result of the threaded task or an exception. You can even hand the future to another thread, and let that thread deal with the maybe exception, without looking inside.

    This just makes you wonder, why's they called them panics and not exceptions, aside from trying to discourage their use. And why they would want to discourage their use in the first place.


  • kills Dumbledore

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    That's stupid. You should have control over that. Even if it's very simple (e.g. box x to put x on the heap in Rust), it's important to be able to tell where you're allocating something. I want my code to do what I tell it to, when I tell it to.

    In C# it's an implementation detail whether things are allocated on the stack or the heap. For getting shit done it generally doesn't matter


  • kills Dumbledore

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    And the code is not more complex to write because you literally just add a single character

    Official: adding characters does not make code more complex



  • @Jaloopa
    Corollary: we can prove by induction that all code is equally complex, as it can be reached by adding single characters sequentially, which as said does not increase complexity.


  • Discourse touched me in a no-no place

    @Kian said in Google Cloud Platform and near-perfect documentation:

    The same generally happens with any error handling mechanism in any language though. There's no reasonable way to handle errors generated by the error handling code until the first error is handled, and by that time the context of the second error would be gone.

    There are ways, but they require very different approaches to memory management as you end up dynamically changing the lifetime of the primary exception (you end up recording that one exception suppressed another exception, to use Java terminology). It's horribly messy and essentially intractable without a garbage collector, and then you're not really using destructors but are instead using special “official lifetime end marker methods”. I guess the one thing to be said for all this is that you maintain a stack trace of everything that you can eventually log somewhere and hope to try to figure out WTF happened.

    So… don't throw exceptions in those sorts of things anyway if you can possibly help it. Your valium budget will appreciate it.


  • Notification Spam Recipient

    @stillwater said in Google Cloud Platform and near-perfect documentation:

    GCP gives out 300$ free credits for 12 months. That's a lot of credits to do a lot of shit. I was looking at GCP to see if I could use this for my projects and at work.

    Off the bat, the documentation throws random 404's.

    Also, the tutorials are scattered af. There are pages where the search functionality won't work and sometimes the documentation is written like the end user is supposed to know everything already.

    Okay, so

    1. Click on Browse Tutorials and Architectures.

    2. Broken. Search won't work. searching for the term they ask you to try does not fucking work.

    What the fuck is up with this shit? There are so many fuckups here and I need to get some sleep before I implode. Wasted 3 fuckin hours over this.

    How come a company that is so huge cannot throw some money at a motherfucker to write good documentation. The docs are sooooooo bad. AWS and Azure docs seem like heaven after looking at this piece of shit.

    Don't use anything from google. Simple as that.



  • @Kian More than that, since the base case of an empty source file has no complexity, we can prove by induction that all code has no complexity, and is thus trivially simple.


  • Considered Harmful

    @Jaloopa said in Google Cloud Platform and near-perfect documentation:

    @pie_flavor said in Google Cloud Platform and near-perfect documentation:

    That's stupid. You should have control over that. Even if it's very simple (e.g. box x to put x on the heap in Rust), it's important to be able to tell where you're allocating something. I want my code to do what I tell it to, when I tell it to.

    In C# it's an implementation detail whether things are allocated on the stack or the heap. For getting shit done it generally doesn't matter

    A heap alloc may be optimized into a stack alloc, but a stack alloc never gets replaces with a heap alloc. If it did, then it would definitely matter because that hits performance.


Log in to reply