Live data from Hacker News

Why I’m not leaving Python for Go

uberpython.wordpress.com

131–140 of 245 posts

Re: Why I’m not leaving Python for Go

#131

Earlier quoted context omitted.

I imagine that this is to keep compatibility with C. And also, this ensures that when a Left value is accidentally read as a Right one, you don't get a "random" bit pattern due to type punning, but a correct (albeit meaningless) value such as NULL.

I'm not sure how, C doesn't have multiple return values either. I also don't really understand the second part. How is that any worse than the current situation of not checking the error side and reading an undefined (or whatever it is?) value?

>> when a Left value is accidentally read as a Right one, you don't get a "random" bit pattern due to type punning, but a correct (albeit meaningless) value such as NULL

> How is that any worse than the current situation of not checking the error side and reading an undefined (or whatever it is?) value?

You get deterministic failure modes instead of dragons flying out of your nose.

Also assigning error in a variable ignoring it sticks out a lot more. The single-return value C version doesn't tell you if it can return failure or not.

edit: fixed quoting

Re: Why I’m not leaving Python for Go

#132
post #73
post #61

Earlier quoted context omitted.

Um... errors ARE normal operation. Consult historical output from your C++ compiler, if you don't believe me! (If anything, that should probably be "errors", quotes included, because what people usually mean by the term is "easily-forseeable occurrence that I couldn't be bothered to write the code for".)

Compiler errors aren't usually implemented as exceptions because compilers these days don't stop at the first error. Exceptions are ideal for things that require aborting and unwinding to a point - usually a loop, like a server request handler or UI event dispatcher - high up on the stack. If the general behaviour is not to abort and unwind, it's not a good fit for an exception. It's also why exception handlers shoul…

> Error codes that need checking and aborting by hand at every function call boundary are a poor fit for replacing exceptions, because they optimize for the case where the error can be handled, rather than the usual case for exceptions, where the error cannot be handled.

From what I understand, the Go language team wanted to write robust servers, thus they wanted to "optimize for the case where the error can be handled."

Re: Why I’m not leaving Python for Go

#133
post #120

I have mixed feelings about errors as return codes. Then again, I have mixed feelings about exceptions. There are two general use cases for exceptions: 1. Unexpected (typically fatal) problems; 2. As an alternative to multiple return values. (1) is things like out of memory errors. (2) is things like you're trying to parse a user input into a number and it fails. I despise (2) for exceptions. It means writing code li…

Java 7 has AutoCloseables for resource cleanup:

  try (FileInputStream f = new FileInputStream(path)) {
      // do stuff
  }

Re: Why I’m not leaving Python for Go

#134
post #115

Earlier quoted context omitted.

This kind of comment kinda misses the point. Haskell (IMHO) won't ever be mainstream for much the same reasons Lisp never was (or will be?): it has an incredibly high learning curve (eg [1]). This is really the problem of the "pure" functional languages. Functional programming is suited to some tasks. With others the fit is almost tortuous. Imperative programming is well-suited to how we think and how we break down t…

This kind of comment kind of misses the point. The monadic style of threading error values is perfectly compatible with imperative programming if only language designers knew about it.

Problem is that you then have to explain monads to average programmers who'll be using the language.

I love monads (I love arrows more, but that's another issue). I'm a language design geek. My level of expertise is different from someone who has just been hired into a new job and wants to get things done.

I suspect that most language designers know about monads - I'm not sure Rob Pike did, but it's pretty common knowledge among folks who do this stuff. Until you can explain them to the folks who'll be using the language in a way that doesn't make them seem like arcane black magic, though, you'll find programmers will just say "I don't get this" and use what they're familiar with.

Re: Why I’m not leaving Python for Go

#135

Earlier quoted context omitted.

I imagine that this is to keep compatibility with C. And also, this ensures that when a Left value is accidentally read as a Right one, you don't get a "random" bit pattern due to type punning, but a correct (albeit meaningless) value such as NULL.

I'm not sure how, C doesn't have multiple return values either. I also don't really understand the second part. How is that any worse than the current situation of not checking the error side and reading an undefined (or whatever it is?) value?

Well, the choice is between structures or tagged unions.

I'm not a Go user, but if I understand correctly ("It's like an Either that always has Left and Right."), functions return a structure with both an error code and a value.

To wrap a C function into a Go function with this signature, you can initialize a structure with { code: success; value:f() }; and then of course error checking has to be done C-style (errno, lib_last_error(), etc).

The problem with tagged unions is that when you access the wrong field (when it's not enforced by the language), everything can happen : you can build ill-formed values, jump to random places, etc. Having an explicit NULL in that cases is better.

In a nutshell, unsafe tagged unions < explicit NULLs < safe tagged unions.

Re: Why I’m not leaving Python for Go

#136
post #133
post #120

I have mixed feelings about errors as return codes. Then again, I have mixed feelings about exceptions. There are two general use cases for exceptions: 1. Unexpected (typically fatal) problems; 2. As an alternative to multiple return values. (1) is things like out of memory errors. (2) is things like you're trying to parse a user input into a number and it fails. I despise (2) for exceptions. It means writing code li…

Java 7 has AutoCloseables for resource cleanup: try (FileInputStream f = new FileInputStream(path)) { // do stuff }

About fucking time

Re: Why I’m not leaving Python for Go

#137

I'll agree that this is perhaps the single thing that I don't like about Go. Now, you can argue it helps with "explicit error handling" and all that, but in that case you might as well have must-be-caught exceptions. Anyone want to fork Go?

Only if we call it Goto

Or perhaps GoTwo.

Re: Why I’m not leaving Python for Go

#138
post #80

As usual in these threads about Go, I really wish people would consider Haskell as a nice alternative. A lot of people write Haskell off as "academic" or "impractical", which I feel is not an entirely fair assessment. Particularly: Haskell is fast, concurrent by design (whatever that means, I'm sure Haskell is :P), typed but not cumbersome or ugly (less cumbersome and ugly than Go's types, even) and--most importantly…

I love Haskell too, but I always run into problems with distributing my compiled haskell binaries to other systems that don't have a GHC compiler available to them. For example, if I compile a binary on my Ubuntu machine and SCP it to a server running centOS Linux, the binary just fails to run because of shared lib issues. Even if you try and compile the binary statically I still run into similar problems. This is in…

That'd kind of defeat the whole point of linking a binary. Were you using cabal to build executables? What shared libs were missing on remote machines?

Re: Why I’m not leaving Python for Go

#139

If you use a language that uses error codes, then you're forced to explicitly think about what to do in every single error case (or not, and accept the consequences). This can add a lot of mental overhead, but can result in a much more robust and well-thought-out program. But because more logic is involved period (to handle the robustness), the program is necessarily more complex. If you use exception handling, then…

I basically agree with you. I think return codes are simpler, and exceptions appear simpler because we're used to them. In reality they are a magical, out-of-band mechanism compared to plain old return. I contend that local and explicit is more strongly correlated with simplicity than remote and implicit. Put another way, verbose code can be simpler if it is direct and explicit — what happens is what's on the page —…

Say you need to migrate a database to a new schema. You need 10 SQL statements to do this. Each statement may fail, in which case you want to write stuff in a log and abort the transaction. In this case, wouldn't you agree that writing your statements in a try/catch/finally block would result in clean, easy to understand code, as opposed to adding explicit error handling after each statement?

Re: Why I’m not leaving Python for Go

#140
post #71

Exceptions are like garbage collection. Garbage collection relieves you from the drudgery, accounting and bureaucracy of manual memory management and indirectly leads to more expressive forms of programming once function boundaries are freed from having to specify who owns the data being passed back and forth. But you still need to be aware of space vs time usage, you still need to know where memory is being allocate…

>In the hands of someone who knows what's going on, programs get much simpler I never really got this argument. With RAII types that have value semantics (ala shared_ptr) what is so difficult about memory management in C++? I guess there are reference cycles, but weak_ptr can help there. Manual ref-counting (like a COM AddRef/Release pattern) can be tricky, but that is where attention to detail, code reviews and basi…

The problem with shared_ptr is that you can't use it for fine grained stuff because it's terribly inefficient. It also has problematic concurrency implications.

But more importantly, what makes C++ memory management difficult is that different libraries do it in completely different ways. Bridging that mess is error prone and a huge mental burden.

Post reply on HN