joeshaw | 1 year ago | on: Don't defer Close() on writable files (2017)
joeshaw's comments
joeshaw | 1 year ago | on: Don't defer Close() on writable files (2017)
joeshaw | 1 year ago | on: Don't defer Close() on writable files (2017)
The core issue here is that you want to deal with errors as soon as possible. The async nature of writes to files makes this more challenging. Part of the purpose of this post was to inform people that you don't necessarily always see write errors at write-time, sometimes you see them at close-time and should handle them there. (And sometimes you don't see them at all without fsync.)
Even if you do handle errors in your deferred close, you may be taking other actions that you'd rather not have until the file i/o is completed, and this could leave your program in an inconsistent state. Side effects in Go are common, so this is a practical concern and it is hard to spot and debug.
joeshaw | 1 year ago | on: Don't defer Close() on writable files (2017)
`defer` is really not well-suited for error handling, its benefit is mainly in resource cleanup where failure is impossible or doesn't matter. (This makes it fine for `Close` on read-only file I/O operations, and not so great for writes.)
joeshaw | 8 years ago | on: Go += Package Versioning
I like Go's distributed package imports (even if everyone just uses Github), but it means you're distributing single points of failure all over the place. Vendoring (whether source or modules) solves this problem.
joeshaw | 8 years ago | on: Understanding Go panic output
The encoding/json package is interesting because it uses both panic() and recover() internally in a way more reminiscent to how exceptions are used in other languages (that is, for control flow).
For example, https://github.com/golang/go/blob/2596a0c075aeddec571cd658f7... panics, and https://github.com/golang/go/blob/2596a0c075aeddec571cd658f7... recovers it.
Both uses are quite uncommon, though.
joeshaw | 8 years ago | on: Understanding Go panic output
There was a nascent project inside the Go team a couple of years ago (called ergo I think?) but I believe it was shelved in favor of Delve, which was much further along.
It's probably safe at this point to consider Delve the de facto standard Go debugger.
joeshaw | 8 years ago | on: Understanding Go panic output
> If a function could fail, the function must return an error as its last return value. The caller should immediately check for errors from that function.
In practice, in idiomatic code it is quite rare for a function that returns a `(* Something, error)` to return `(nil, nil)`, which are the cases where a nil pointer dereference would most often happen. The other case is not _immediately_ checking errors. I would say both of these cases are not idiomatic Go. (Yes, there are exceptions.)
The other cases where I've seen nil dereferences pop up most often:
(1) the zero value for maps is nil, and a nil map is mostly not usable. `m[50] = "foo"` will panic with a nil dereference if you've not initialized `m`. This is one of the most annoying things about Go.
(2) not checking for presence when pulling out of a map. If you have `map[string]* Something` and do `x := m["nonexistent"]` and try to use `x`, it'll blow up. Always use the `x, ok := m["nonexistent"]` form instead, and deal with stuff when `ok == false`.
(3) nil receivers. `var x *Something`, then `x.Method()` -- the `Method()` method _can_ deal when `x == nil`, but most code does not.
My reasons for citing C and Java:
C doesn't have multiple return values, and kinds of C code deals with errors differently. Lots of stuff just returns `NULL` and all too often things don't check for it. (`malloc()` is a perfect example of this -- it rarely fails but a _lot_ of code doesn't check for errors. Now extrapolate that to everything :)
For Java, it's because the try-catch control structure complicates program flow. If you have a large block of code in a try-catch, it is very easy for a different line of code to throw an exception than you expected, and as a result an object you attempt to dereference later is null and you get an NPE. There are ways to deal with this, of course, but in my experience most people are pretty lazy about the non-happy path.
EDIT: formatting. how can a site about programming have such terrible support for typing in code
joeshaw | 9 years ago | on: GlobalSign experiencing issues – Certificates showing as revoked
joeshaw | 10 years ago | on: Mono Relicensed as MIT
The Novell-owned IP was either sold or licensed to Xamarin later.
joeshaw | 10 years ago | on: Mainframes connected to the Internet
Most of them seem to be interfaces to network switches.
joeshaw | 10 years ago | on: Resize.ly – Images resized, responsive, and retina ready
We clearly need to update the copyright info on the page and make some new blog posts!
joeshaw | 10 years ago | on: Show HN: “Who is hiring?” Map
If you zoom in on the east coast of the US, for instance, jobs are grouped between NYC and Boston and the location of the bubble doesn't make much sense until you zoom in further and see them separated.
joeshaw | 11 years ago | on: Graph of Foursquare's Popularity After Removing Check-Ins
I lament the loss of the app too. Checking in and becoming the mayor was the fun of the old app, and Swarm just doesn't do it for me. At this point I use it mostly as a log of new places I've been to so I can visit them again in the future, particularly while traveling.
joeshaw | 11 years ago | on: Graph of Foursquare's Popularity After Removing Check-Ins
Twitter's incorporation of the POI will give them much more "check-in" data than their own apps ever could.
https://medium.com/@dens/six-years-in-a-few-thoughts-on-four...
joeshaw | 11 years ago | on: Graph of Foursquare's Popularity After Removing Check-Ins
I am as disappointed in the pivot of the app as everyone else, but it's hardly the sign of impending death the post (and many of these comments) make it out to be. 4sq built up an incredible points-of-interest database, and that is their real product.
By providing that POI data to other providers -- most notably Twitter -- they get much of the same data that checkins in their own app gave them. And Twitter is massively more popular than the Foursquare/Swarm apps ever was or ever will be.
joeshaw | 11 years ago | on: Ask HN: I got let go this morning. What should I do next?
joeshaw | 11 years ago | on: Building Web Apps with Go
Other than the occasional need to fix up an ambiguous import that it guessed incorrectly, I haven't touched import lines in my code in a year.
joeshaw | 11 years ago | on: Bash 'shellshock' scan of the Internet
joeshaw | 11 years ago | on: ITerm2 2.0
Details on the protocol are here: https://docs.google.com/document/d/1ABI0kqUUxoAjxhWW3AsWFis6...
The core problem is that the error checking is not done soon enough, either because Go programmers are conditioned to `defer f.Close()` from nearly all example code -- most of it demonstrating reads, not writes -- or because they are handling the error, but only in a deferred function, not earlier.
A more correct way to do this would be:
`Sync()` flushes the data to disk, and `Close()` gives a "last-chance" opportunity to return an error. The `defer f.Close()` exists as a way to ensure resource cleanup if an error occurs before the explicit `f.Close()` toward the end of the function. As I mentioned in an update to the post, double `Close()` is fine.