HNHacker News
TopNewBestAskShowJobs

lobster_johnson

10,160 karma · joined September 9, 2010

Norwegian developer in NYC.

Email: hackernews@purefiction.net

Github: https://github.com/atombender

submissionscomments
lobster_johnson··on An Analysis of vgo
git may have become successful, but that doesn't mean it's right. I'd argue that most developers still don't really understand git. I know seasoned, senior developers who struggle when git gets into an unfamiliar state, or who are completely mystified as to how it actually works. And don't forget that git spent years improving its initially horrific UI to make it easier and more palatable to people who aren't kernel developers.

If you compare git to rival tools such as Mercurial and Fossil or even Darcs, it's pretty evident that git didn't really win on technical merit, user friendliness or indeed hardly any other metric. It was fast, and it had the dubious advantage of being better than a lot of crappy alternatives at the time, and of being the product of a famous developer. But if technical merit was how we chose software, we might all be using Mercurial today. It's quite possible we'd be better off, too.

git's punting of "certain of the hard theoretical problems" lead to major shortcomings in its design. For example, git does not track branching histories. Once you merge your changes back into a branch and delete the origin branch, the path that your commits took are lost. Another example: Since git's data model works entirely on repository snapshots (there are no "patches" or logical operations, only snapshots), it doesn't know about file renames. Some commands, like log and diff, do understand how to detect renames (but not out of the box!), but it's fundamentally a fuzzy-matching operation that can only work perfectly if you separate your rename commits from modification commits, which is rarely feasible.

Don't get me wrong, git has overall been a force for good, but I think it's a pretty terrible example in this particular case. In fact, I'm not sure I can think of many cases where the "worse is better" philosophy was ultimately a good idea. In every instance that comes to mind (MySQL, MongoDB, PHP), the fast-and-loose attitude ultimately came back to hurt everyone, and years were spent paying for those mistakes, plugging one hole at a time.

The original decision by the Go team to build package management into the language ("go get") was made without really understanding the problem, and this decision has been haunting us pretty much since day one, with developers having to chase unofficial package management tools of the week in order to get their work done. I really want it to be done right, even if takes a bit longer. It's a problem worth solving well.

lobster_johnson··on An Analysis of vgo
Thanks for the correction; I worded that unclearly. My point is that with MVS, the solver will favour the oldest package that is allowed by the semver version constraint; given transitive dependencies on multiple packages, it will conservatively pick the oldest that satisfies all the constraint. You can bump the version you want by updating the version constraint, but unlike other tools (e.g. Cargo [1]), it will always favour the oldest allowed version.

[1] https://research.swtch.com/cargo-newest.html

lobster_johnson··on An Analysis of vgo
I don't disagree — dep has been a huge improvement on Go's package management story. Until dep was stable, we were using Glide, which is extremely buggy.

That said, if you ignore the doubts and arguments about the sanity of its dependency resolution algorithm, I think vgo's introduction of modules is its real contribution.

Go packages have been problematic since the start since their design, naively, conflates a bunch of concepts that most developers keep separate: File location, file structure and source repository. That is, when you do 'import "github.com/foo/bar"', there's a whole bunch of conventions at play that dictate where it can be fetched from and where it should be in the file system. Aside from the fact that the $GOPATH convention is maddeningly annoying to many developers, the design has several issues, such as that an entire git repository has to be fetched in order to use a nested package, or that a package can have multiple import paths. But getting rid of $GOPATH is in itself a huge deal.

I'm personally less concerned with the new MVS algorithm (though I personally prefer the more traditional lock file approach such as that used by dep, Cargo, Bundler, NPM, etc.), as long as I can get modules. While getting modules retrofitted into depwithout all the other stuff in the proposal would be lovely, I don't know if the module design is too dependent (heh) on the rest of vgo's versioning thesis to be separated out.

lobster_johnson··on An Analysis of vgo
The article is about vgo, a proposal (with working prototype) to build package management into Go itself.

vgo bundles several improvements, a major one being the introduction of "modules", which are versioned collections of packages. Modules, among other features, will let us decouple the import path from the file system structure and source repository, making the awkward and much-maligned $GOPATH finally obsolete.

vgo also introduces a new dependency resolution algorithm, minimal version selection (MVS), which is different from traditional dependency resolution algorithms in that it will at any time choose the oldest allowed version that satisfy the minimum version constraints specified in the list of imported packages, where other systems will choose the newest. As MVS does not require (as with dep) a complex boolean SAT solver with potentially pathological, NP-complete cases, it is much simpler and faster to compute. However, it also has downsides. (Edited, thanks to pa7ch for correction.)

The author likes pretty much everything about vgo except the MVS algorithm, which has been deeply controversial since the proposal was first published. The author goes into explanations of why he thinks MVS is a bad fit, but this is a complicated topic, so you really have read both the vgo proposal and this rebuttal to understand what it's all about.

The article was written by Sam Boyer, one of the designers/authors of dep. While he has been courteous about it, there are obviously emotions at play; during its development, dep seemed to have the blessing of the official Go team, and this proposal came out of the blue and probably felt like an ambush.

lobster_johnson··on GHC Parser Principles
Ruby is actually an ISO standard. Admittedly, it's frozen at Ruby 1.8 and it doesn't count for much.
lobster_johnson··on Apple Faces Class Action Lawsuit Over 'Defective' Keyboards
Dupe (of same news event, not same article): https://news.ycombinator.com/item?id=17054710
lobster_johnson··on Apple faces class action lawsuit over failing MacBook butterfly keyboards
Similar story here. I managed to spill coffee on my MacBook Pro 2015, which I had been really happy with -- great performance (max out with CPU, RAM and 1TB SSD).

I got the new 2017 model, and really hated the keyboard, but also really disliked the Touch Bar and lack of Escape button. I'm not at all concerned with the lack of USB or SD card reader, though I was disappointed with the lack of performance improvements over the 2015 model.

So I returned it, and bought a brand new 2015 model. Except it turns out they changed it! It no longer has a dedicated AMD graphics card. It's an integrated Intel Iris Pro with less VRAM, and it seems really underpowered compared to the old AMD Radeon on my previous model.

The lower graphics performance is especially noticeable if you turn the Retina setting to scaled (like 1.5x, which I prefer). It's not just that apps render a bit more slowly -- I get the sense that there's some GPU memory transfer bottleneck that's happening that causes sudden pauses in UI rendering across the entire OS. And it's something that makes the whole computer slow down with use; rebooting (or restarting Safari) speeds things up again. Typing in Slack or VSCode has noticeable lag, and switching between Spaces results in a significant pause, and the switching animation stutters something fierce. I would go so far as to say that scaled Retina is unusable on this model.

I looked the model ID, and it's "MacBookPro11,4". The model that has a dedicated GPU is "MacBookPro11,5" and was discontinued in October 2016. So it looks like it's impossible to get a 2015 MBP with a dedicated graphics card right now. You can't plug in an external GPU, either; while High Sierra now supports it, it's only supported on the newer models via Thunderbolt 3.

This is really frustrating. I've been using Apple laptops since 2006, and this is the first time when I can genuinely say that none of their products are good enough. I've even looked at the possibility of switching to a Linux laptop, but Linux distros are nowhere near macOS in terms of cohesiveness and UI, and while the laptop models I've looked at (ThinkPad T480S, Dell XPS 15, System76 Oryx Pro) admittedly have much better specs than Apple, none of them stand out as being particularly good.

I'm now hoping that Apple will see sense this year and offer a non-Touch-Bar model with some kind of non-butterfly keyboard. But I'm not hopeful.

lobster_johnson··on Seaweed in Cow Feed Reduces Methane Emissions Almost Entirely
It says right there in the article -- a coastal farmer discovered that the cows grazing on nearby seaweed were healthier and had more active periods of heat. A subsequent study found that it also had an effect on methane production.
lobster_johnson··on How 2 M.T.A. Decisions Pushed the Subway into Crisis
I found an answer here [1], via a Reddit thread [2] (where the answers are apparently gone):

    I won't go into details, but if the conductor wants to exit
    the train and leave the doors open at the terminal, he needs 
    to walk to the next car at the last stop in order to open
    the doors, which is why there's a short delay before they
    open. If the doors open immediately at the last stop, then
    it means the train is either going to go to the yard, or the
    crew is going to manually key open one door per car (which
    is only done if the train is going to sit there for at least
    10 minutes, and helps the air comfort system).
[1] http://www.ibtimes.com/mta-worker-goes-underground-share-sub...

[2] https://www.reddit.com/r/IAmA/comments/kx5fa/iama_new_york_c...

lobster_johnson··on How 2 M.T.A. Decisions Pushed the Subway into Crisis
I've never been bothered by that (and as others point out, the L is automated, anyway). What I'd like to know is why, when the L reaches the 8th Ave stop in Manhattan, the operator waits 10 seconds after coming to a full stop before opening the doors. The train has already stopped, so this seems unnecessary.

There's also this weird thing where, while the train is sitting there waiting to return the opposite way back to Brooklyn, they close all the subway doors except one in each carriage. It doesn't prevent people from getting on.

lobster_johnson··on Kubernetes Ingress Controller for Kong
I'm referring to Cloud CDN [1], which is per-backend setting that is disabled by default.

Unlike some other offerings (like AWS CloudFront), the CDN is transparent and built into the GLBC. Just by turning on the CDN, your load balancer automatically gets a globally distributed cache.

[1] https://cloud.google.com/cdn/

lobster_johnson··on Kubernetes Ingress Controller for Kong
Do we know what the Kubernetes' team's official plan for fixing the ingress situation is?

My opinion is that ingress portability isn't really that useful in practice. You want implementation lock-in at the ingress level, since the implementation matters. If I need to target platforms in a generic way (e.g. make something that works on both AWS and GKE), I can use Helm or some other templating solution to generate the right manifests with the right settings.

So "KongIngress" isn't a problem for me, and rather than struggle with today's situation on GKE, I'd much rather have a "GoogleIngress" with all the GLBC bells and whistles (well, there aren't many, but at least timeouts and a CDN toggle!) and not care about it being portable.

lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
I did describe both (Google could do a much better job with the integration on GCP/GKE), but by "Kubernetes first" I meant the latter.

Databases run fine on Kubernetes and have been doing fine since 1.7, and the meme that Docker is bad for stateful apps is a getting a bit old. The challenges are mostly the same as with running databases on a VM or bare metal. In particular, you need to know how to manage HA.

The weakest point is perhaps that Kubernetes's scheduler completely ignores disk I/O, so you have to bare careful to avoid sharing a node with multiple disk-heavy apps that will compete for resources. This is includes the file system cache; for example, PostgreSQL works best when it can rely on the OS to cache pages, so you don't want other apps (including Docker and Kubernetes themselves) to compete there.

That said, I wasn't saying that a hosted solution shouldn't also offer VMs. Just that Kubernetes should be the main entrypoint and control plane. And someone figured out a way to run VMs via Kubernetes [1], which is a neat example of a solution to the lack of integration I was complaining about earlier.

[1] https://www.mirantis.com/blog/virtlet-run-vms-as-kubernetes-...

lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
Private clusters are in open beta: https://cloud.google.com/kubernetes-engine/docs/how-to/priva....
lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
We were talking about openshift.com, though. I didn't realize there were more than one site. Since you're going there:

- I didn't even know it was called "OpenShift Origin"!

- I don't understand what the differentiation is between the various things called "OpenShift", from having visited the Google links briefly.

- Third Google hit (https://www.redhat.com/en/technologies/cloud-computing/opens...) does not even mention Origin anywhere, but describes it as "a container application platform that brings Docker and Kubernetes to the enterprise". With that copy, you already lost me. That IBM-type business site that makes my skin crawl.

- The Github site actually introduces it as "Enterprise Kubernetes for Developers", which... I don't even know what that means! What does "Enterprise Kubernetes" even mean? The actual readme's introduction ("a distribution of Kubernetes optimized for continuous application development and multi-tenant deployment") does make sense, and the readme itself is fine. However, still no explanation of what "Origin" is compared to other things named "OpenShift".

- Openshift.org (5th link on Google) is good. That's exactly the kind of site I'd want to see as a developer/CTO. However, still no explanation of "Origin". From Openshift.org it seems like Origin is the only product.

- I go back to openshift.com and click on "Products" out of curiosity, and it's clear that there's a bunch of other OpenShifts. What are they? Why should I care? The site isn't inviting me to find out, so I leave.

Why are there are so many sites? Github is one thing, but so far we have three, and none of them really give a cohesive story.

I understand that the marketing department is targeting different people, but do they realize that people google this stuff, and will likely end up on the wrong site, with no signposts to the right thing? The fuzzy messaging leaves the impression that the company is messy and disorganized, and also pretty lost in a fog of enterprise buzzwords.

Anyway, in my original comment, what I was seeking was Kubernetes a cloud service. After sniffing around on openshift.com, I suspect the product I want is called OpenShift Online, but I'm not actually sure. Because there's also something called OpenShift Container Platform, which is also Kubernetes, but apparently in the cloud of your choice? Unfortunately, the site doesn't explain what the relationship is between this and Origin, and of course there is no pricing for Container Platform, probably because it has the label "ENTERPRISE" next to it. Figures.

lobster_johnson··on Conversations with a six-year-old on functional programming
Einstein never said that, though: https://skeptics.stackexchange.com/questions/8742/did-einste....
lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
We used Drone [1] from a while. It's almost exactly what I want in a CI/CD system, and it runs pretty well on Kubernetes.

On the minus side, the development has been slow, with major breaking changes happening along the way. And in the latest version, the open-source version has been a bit hobbled. In particular, it doesn't support global secrets, so every project to be built has to be created and managed separately. This is not just if it needs build secrets (such as to access private Go packages, NPM modules, Ruby gems, etc.), but it's obviously also required to authenticate with a container registry. We decided to skip that since it means duplicating the same secrets for every single application. We actually reached out to the Drone guys to ask about enterprise pricing, but they didn't respond (!).

(At the moment we're back to building with Semaphore, which is a hosted solution similar to Travis. It's an old-hat CI system that spins up VMs, so it's slow and awkward to work with when it comes to Docker. But it's working okay at the moment.)

I've heard good things about GoCD [2], though. It's next on my list to investigate.

[1] https://drone.io

[2] https://www.gocd.org

lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
Google does use GCP/GKE internally. And Google's internal Kubernetes team is basically the GCP team, according to googlers on HN.
lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
Hence my skepticism. Someone who doesn't know how to engage with engineers is someone I don't have any interest in engaging with, either.
lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
That's what I mean by "Kubernetes first".

Why not use Kubernetes to declaratively define nodes, disks, load balancers, firewall rules, DNS rules...? If you look at Terraform, for example, it's just an "object store" (the state file) that you modify in order to "converge" your infrastructure.

If you're already using Kubernetes via GKE or a similar IaaS, then of course Kubernetes has underlying primitives (GCE disks, GLBCs, etc.) that are exposed. But those primitives are exposed because GKE runs on top of GCP.

What I'm proposing is a "KaaS" where Kubernetes is the control plane, without the baggage of an additional API.

lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
See my reply here: https://news.ycombinator.com/item?id=17015475.
lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
Last I checked, he's working on Azure's Kubernetes solution.
lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
Many of the founders (e.g. Brendan Burns) are still working on Kubernetes, so I don't see how that's relevant. Google is heavily invested in Kubernetes, and so is a bunch of other companies.

According to googlers here on HN, Google does use Kubernetes internally via GCP/GKE. But clearly those apps are in the minority, given Google's huge investment in Borg.

lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
I don't think that's true. If you believe the team that designed Kubernetes, Kubernetes is an attempt to improve on Borg.

Borg is an accumulation of a decade's work with containers at Google, and has been described by googlers as a rich but a little messy, having been designed incrementally over many years as needs have surfaced. Borg could never be open-sourced because it's so specific to Google; for example, it uses Google's own cgroups-based container tech, not Docker/OCI/etc. Omega, as I understand, was an effort to clean up Borg and modernizing it, but apparently it was never put into production; instead, some of the innovations ended up being backported to Borg [1].

More importantly, Kubernetes is based roughly on the same design as Borg: A declarative, consistent object store, with controllers, schedulers and other bits and pieces orchestrating changes to the store, mediated by a node-local controller (Borglet/Kubelet). A major difference between Borg and Kubernetes is that with Borg, the object store is exposed to clients, whereas Kubernetes hides it behind an API. Another difference is the structure of containers; Borg's "allocs" are coarser-grained than pods and Borg is less strict about where things go, which googlers have described as a shortcoming compared to Kubernetes' strict pod/container structure. Another difference, also seen as a shortcoming, is that Borg lacks Kubernetes' one-IP-per-pod system; all apps on Borg apparently share the host's network interface. Kubernetes also innovates on Borg in several ways; for example, Borg doesn't have labels [2].

Borg, from what I gather, scales much further than Kubernetes at this point, but it's really not related to the design. The design is fundamentally the same.

Yegge's criticisms are too handwavy ("overcomplicated") to counter, but I don't think Yegge knows what he's talking about here. As for "benefit": Not sure what you mean by this, but Kubernetes arguably comes with benefits — declarative ops, platform abstractions, container isolation — even if you're just running a single node. The notion that you only need Kubernetes if you have "Google-scale problems" is just nonsense.

PS. What's "Grab"?

[1] https://ai.google/research/pubs/pub44843 (I recommend reading this paper)

[2] https://kubernetes.io/blog/2015/04/borg-predecessor-to-kuber...

lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
That's not what I meant, though. A Kubernetes PV is an abstraction that causes a controller allocate a GCE disk (which of course is another abstraction), but if you create a GCE disk through the CLI/UI/API, then you don't get a PV.
lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
Thanks, I know about service brokers. My point was that there's an opportunity for a vendor to do this better out of the box.
lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
Maybe. I'm skeptical of Red Hat. The openshift.com web site, which is definitely not geared toward engineers, doesn't give me any confidence that this is what I'm after.

Not that Google is better here, but I already know what GCP provides; something that wants to compete with GCP/GKE really needs to explain why they're a viable competitor.

(And to people who design these things: If you need to have a "Products" dropdown filled with unexplained product names, you're doing something wrong.)

lobster_johnson··on As Kubernetes grows, a startup ecosystem develops in its wake
We were on DigitalOcean before GCP. They're okay. They're cheap, but can't really compare to GCP in terms of performance, stability, networking, object storage, etc. Their Kubernetes offering is also a GKE competitor, not a "Kubernetes first" cloud.
lobster_johnson··on Monads for functional programming (1995) [pdf]
Right, IO does not collect the results this way. putStr for strings is declared like so:

    putStr :: String -> IO ()
Here, () is the unit type, which is similar to null/nil in other languages. In other words, I/O functions like putStr etc. don't return anything. putStr internally calls lower-level functions that actually write to a file descriptor.

Some people get into Haskell thinking that functions can't have side effects because Haskell is "pure", but that's not right. Rather, as the parent commenter say, they can have all the side effects they want, and the consistency and purity of the program's execution is preserved through the use of monads.

Haskell is considered a pure functional language where everything is immutable, but that's not true, either. A lot of the GHC standard library uses mutation (e.g. with IORefs) for performance reasons. For example, putStr ends up writing to an internal byte buffer that is modified directly.

lobster_johnson··on Monads for functional programming (1995) [pdf]
It's my understanding that the IO monad is largely a type system thing. The IO monad doesn't "do" anything -- a call to the print function actually does write to a file descriptor right there and then.

In a lazy, pure language like Haskell, there's the problem that since a print function doesn't actually compute anything, it doesn't return anything that makes sense functionally; it's not a function in the mathematical sense. In Haskell, a function is only evaluated when it needs to be (i.e. potentially out of order), and functions called with the same arguments can be memoized, and functions that don't return anything can conceptually be eliminated entirely. So the challenge is to somehow tag the print function as being unmemoizable.

To do this, as far as I recall (it's been a while), the GHC's implementation of IO says that the monad wraps a value of a type "RealWorld". Every time you bind/return an IO function, you are sending the current RealWorld and then getting a new RealWorld back. This is hidden from the caller since it's a detail of the monad that you don't need to see. As far as I know, the world value is just a dummy value that is optimized away and doesn't exist at run time. But by forcing every IO to depend on the previous result, the "computations" will be chained in the right order.

Edit: Haskell wiki has more: https://wiki.haskell.org/IO_inside

← PreviousPage 2 of 34Next →