Live data from Hacker News

Why I’m not leaving Python for Go

uberpython.wordpress.com

171–180 of 245 posts

Re: Why I’m not leaving Python for Go

#171
post #102

Earlier quoted context omitted.

I respectfully disagree: http://golang.org/src/pkg/net/timeout_test.go#L39 edit: You should note that the above test code is actually far less verbose than the analogous end-user code, given that the timeout_test.go clearly expects the 'err' var to be a net.Error. Now consider the case of a network subsystem, with funcs having in args of type 'bufio.Reader' and/or 'bufio.Writer'. At some prior point you may have set…

Not sure what buffer overruns you are referring to, or why this case requires reflection at all. err := readMessage(reader) if n, ok := err.(net.Error); ok && n.Timeout() { // handle timeout } else if err != nil { // handle other errors } You can see an example of exactly this pattern here: http://golang.org/src/pkg/net/http/server.go?s=29962:30008#L...

You did not carefully read the GP.

IO read/write functions are not limited to the net package. net.Conn supports a subset of these (interface types) and it is entirely idiomatic and possible for a net.Conn flavor to endup at some deep layer of your code in a function accepting generic io in args.

Functions taking non-net "in args" returning "error" can not be assumed to always return "net.Error". You will need to test the type (reflectively) and then safely cast.

For example : http://golang.org/pkg/io/#ReadFull

Is it "non-idiomatic" to wrap net.Conn as another non-net package type and then use it?

http://golang.org/src/pkg/net/net.go#L22

Re: Why I’m not leaving Python for Go

#172
What happens in Go if there is an exception (division by zero or whatnot)? Does it just exit, no stack trace? I am so used to exceptions that I don't even know how it used to work without them. I think getting a stack trace for debugging is really important...

Re: Why I’m not leaving Python for Go

#173
post #151

Earlier quoted context omitted.

I agree that exceptions can be cumbersome at times. And I do prefer the Go parsing float example to the try/catch one if my entire program is only one line. But in order to live in peace you have to either: * Force every programmer to always check all the error values. or * Allow errors to pass silently. So either you accept Go as a heavy-duty, heavy boilerplate error handling laden language. Or you accept it as a fl…

So, I rarely see eg Java code that actually handles the exceptions it receives. Usually its just "Oh, I got an exception, so I'll print an error (or silently fail) and blindly keep going". Given this, I don't see how Go is any worse with respect to sloppy programmers. They'll Always Find A Way. Also, why couldn't your second example be nested? It seems like either of those two examples could be structured identically…

I think this is not what you're actually seeing. When you get an exception there is rarely much you can do other than log the error or alert the user. It is much more important what you do not do in such a case - you do not let bad data flow into your program, and exceptions are great at preventing that.

Re: Why I’m not leaving Python for Go

#174
post #138

Earlier quoted context omitted.

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?

When I just do a simple hello world app, I get this error ghc helloworld.hs -o helloworld ./helloworld ./helloworld: error while loading shared libraries: libgmp.so.10: cannot open shared object file: No such file or directory However if I compile statically, I get a different error ghc helloworld.hs --make -optc-static -optl-static -optl-pthread -static -o helloworld ./helloworld FATAL: kernel too old Segmentation f…

Amusingly enough, I'm pretty sure "FATAL: kernel too old" is a problem with glibc, so it's actually the C standard library that's preventing you from running your staticly-linked Haskell binary on your server.

Re: Why I’m not leaving Python for Go

#175
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…

>try: >> f = float(someText) >> catch ValueError: >> # I just parsed you, this is crazy, >> # here's an exception, throw it maybe? No, you have it exactly backwards. It's with return values that you have to check after every call to be safe. With exceptions you can truly say: if I don't know what to do if this fails then I don't do anything. You can let the exception bubble up higher, all the way up to crashing the p…

    try:
       f = float(someText)
    catch ValueError:
       # I just parsed you, this is crazy,
       # here's an exception, throw it maybe?
Formatted That For You

Re: Why I’m not leaving Python for Go

#176
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…

>try: >> f = float(someText) >> catch ValueError: >> # I just parsed you, this is crazy, >> # here's an exception, throw it maybe? No, you have it exactly backwards. It's with return values that you have to check after every call to be safe. With exceptions you can truly say: if I don't know what to do if this fails then I don't do anything. You can let the exception bubble up higher, all the way up to crashing the p…

[deleted]

Re: Why I’m not leaving Python for Go

#177
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…

Ad your last Python example - the preferred method of doing resource cleanup in Python is the 'with' mechanism: with open("x.txt") as f: #do stuff with f That's it. Obviously, compared to 'defer', it hides stuff - the actual magic happens in special methods __enter__ and __exit__ of the object passed to 'with'.

> Obviously, compared to 'defer', it hides stuff - the actual magic happens in special methods __enter__ and __exit__ of the object passed to 'with'.

Then again, `f.Close()` could hide any "magic" you want as well.

Re: Why I’m not leaving Python for Go

#178
post #174

Earlier quoted context omitted.

When I just do a simple hello world app, I get this error ghc helloworld.hs -o helloworld ./helloworld ./helloworld: error while loading shared libraries: libgmp.so.10: cannot open shared object file: No such file or directory However if I compile statically, I get a different error ghc helloworld.hs --make -optc-static -optl-static -optl-pthread -static -o helloworld ./helloworld FATAL: kernel too old Segmentation f…

Amusingly enough, I'm pretty sure "FATAL: kernel too old" is a problem with glibc, so it's actually the C standard library that's preventing you from running your staticly-linked Haskell binary on your server.

So the haskell RTS requires the same version of glibc on both machines to make it work?

This wouldn't be too much of a problem but I don't have administrative privileges to these servers. So when I want to write throwaway scripts or programs, I find myself turning to Go or D and they work without any quibbles.

Re: Why I’m not leaving Python for Go

#179
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…

One problem with Go is that is uses multiple return values to indicate errors instead of alternative return values. When you call strconv.ParseFloat, you always get back two values, the error code and... wait, what float do you get back when there's an error? If you're going to use return values to indicate errors (and certainly I feel that there are reasons to use them, exceptions vs error codes is not an either/or…

> One problem with Go is that is uses multiple return values to indicate errors instead of alternative return values. When you call strconv.ParseFloat, you always get back two values, the error code and... wait, what float do you get back when there's an error?

Why would you even be interested in the float when there's an error?

Re: Why I’m not leaving Python for Go

#180
post #162

Earlier quoted context omitted.

Ad your last Python example - the preferred method of doing resource cleanup in Python is the 'with' mechanism: with open("x.txt") as f: #do stuff with f That's it. Obviously, compared to 'defer', it hides stuff - the actual magic happens in special methods __enter__ and __exit__ of the object passed to 'with'.

Ruby by convention uses blocks for the same situation: def withSomeResource handle = acquireSomeResource yield handle ensure freeSomeResource(handle) if handle end withSomeResource do |h| h.whatever end File.open and other parts of the standard library does that by default. I imagine the Python implementation of "with" is pretty similar, given that it can be implemented pretty much like this in Ruby, and "(begin) ..…

> given that it can be implemented pretty much like this in Ruby, and "(begin) .. ensure .." is pretty much equivalent to "try ... finally ..":

Note that there's a difference in the handling of exceptions: if an exception is triggered from the `with` block, it is intercepted, provided to __exit__ and can be silenced if needed or desired (by returning a truthy value). So a closer approximation would be:

    def with r
        r.__enter__
        begin
            yield(r)
        rescue Exception => e
            raise unless r.__exit__(e)
        else
            r.__exit__(nil)
        end
    end
Post reply on HN