HNHacker News
TopNewBestAskShowJobs

ben509

4,046 karma · joined December 7, 2017

I'm an engineer presently working for Capital One Investing, prior work at AWS for the CloudHSM team, before that Novetta, and before that I did 6 years in the army.

I'm also working on the Tenet language; see https://tenet-lang.org/

Also at https://keybase.io/ben509

YdRK9Q3mIBRWsRBonHhJCsgLnurwJk9eHbw1Jg4wz9M

submissionscomments
ben509··on Show HN: QuikPub – Write, Publish and Share rich text via short URLs
Allow audio uploads and you can deal with slander, too!
ben509··on Amazon shortchanged drivers $61.7M in tips
Tips are fundamentally broken. If you didn't know about tips, and someone offered you a job and said, "I'll pay you crap wages, but you can ask the customers for more money. Don't worry, they'll pay or their friends won't like them," you'd think it was a scam because it's such an obviously terrible deal.

Tips are an awful way to incentivize good service.

I'm neither qualified to judge my server's performance, and I've got very limited and potentially misleading information about what a reasonable expectation is. I've got no idea what small crises my server had to deal with, or how other customers are treating him.

And because tips are everywhere now, nobody knows the going rate for most tips. Obviously tourists have no idea how much to tip.

If I reduce the tip, the waiter is only finding out that I was unsatisfied after it's too late to fix anything. But tipping up front makes the exercise entirely pointless.

And the moralizing of tips is stupid.

Many moral arguments paint people in the service industry as paupers or victims, but a basic level of respsect has to assume they're competent professionals who chose this line of work.

A tip is not an act of generosity, either, you're paying a fee for a service rendered. And that's why, as a system, the morality of tipping is entirely backwards: it rewards people who rip off their servers.

The thing that really bothers me are the awful motivations behind tipping: being control freaks, conspicuous consumption and all the slimy business incentives to push their payroll onto their customers.

ben509··on F# is gaining independence from .NET
All DI libraries can be ripped out and replaced with a bog standard main method, and it doesn't even require much skill. Most of what it's doing for you is stuff like "foo = new Foo(); bar = new Bar(foo, 33);" So there's no strict "need" for them, they help with (and enable) complexity.

What F#'s aversion to cyclic dependencies does forces you to break cycles of types referring to types referring to types. The way you do that is by writing a generic function that avoids referring to a concrete type. Because it's generic, such a function is inherently easier to test by means of a simple stub value.

ben509··on Robinhood Play Store listing went from 329K reviews to 180K in few hours
Reasons Google would not want the financial status quo:

1. It tends to retard technical progress.

2. They have to make deals with entrenched incumbents to do finance.

3. There's nothing stopping a hedge fund manipulating Alphabet's stock.

ben509··on Discord bans r/WallStreetBets server, subreddit went private for a while
Of course you're censoring them.

You would also be censoring people if you ran an upscale restaurant with a dress code and standards of behavior, or if you didn't let them post ads on the walls.

As long as you make your rules clear and enforce them fairly, censorship and standards of behavior are completely fine.

The very large social media platforms all market themselves as being neutral. They got to be the largest by providing a space for everyone.

So the ask here is "please enforce the rules fairly the way you have always promised you would." Asking a business to deliver on the promises they've made and continue to make is not an entitled attitude.

After all, all these businesses are in complete control of what they promise. If they don't like the old promise, they have a first amendment right to make a new promise that suits them better.

ben509··on OO in Python is mostly pointless
I'd argue that's not object-oriented programming.

You are using Python's class mechanism, but that's where the OOness ends. The types themselves are immutable value types, carrying no state and reacting to no messages, and they don't exploit a class hierarchy beyond having a common "Number" class. The "methods" don't even behave like methods, e.g. __add__(self, other) has special wiring so it obscures which side of the addition is "self".

That's very different than a classic OO scheme like a UI toolkit.

ben509··on OO in Python is mostly pointless
I think OO caught on because it encourages people to organize their thoughts, and good structure alone brings a tremendous improvement in code.

I think the reaction to it is more the "everything is mutable" approach most OO languages took, which led to things that looked organized but that were a hot mess of side-effects.

With dataclasses (or attrs) you can cut back on that by freezing everything, and still get the clarity of methods that lay out the essential functionality of a type.

In their own example, "get_items" and "save_items" make a bit more sense if they're stashed away in the Client namespace, and you can see that they're essential to what a Client does.

And while Oil's conjecture is probably right, I'm not sure it survives if you add the caveat, "in that same language."

For instance, Python doesn't have a native way of expressing sum types outside of inheritance. That's not to say inheritance, especially an always open style, is a good way of working with a sum type, it's just the only native way.

ben509··on Firefox 85 cracks down on supercookies
I don't see how that helps you persist a tracking ID.

If you generate a random URL, you'll always get a cache miss.

If you use a static URL, you'll know if you have a new session or not, but that doesn't tell you what the tracking ID was.

The only thing I can imagine is the server serve several images /byte1.png /byte2.png etc. and make them all X by 1 pixels, encoding a random value in the dimensions, assuming that's available to Javascript.

But if you encode the tracking ID in the image somehow, you don't care much whether it was cached or not, it's inherently persistent. It'd mainly be useful if you're trying to reconstruct a super cookie.

ben509··on Postgres scaling advice
Predictably bad won't result in a sudden spike in IO usage that brings down a production system. This is why Oracle has SQL profiles.
ben509··on We rendered a million web pages to find out what makes the web slow
Sticky Ducky is a nice plugin for that.
ben509··on We rendered a million web pages to find out what makes the web slow
I run Wipr on Safari. It's quite cheap, and since I don't use Safari as my main browser, the fact that there's nothing to configure is a bonus.

It was also easier to install it on my parents' computers than to convince them to change browsers.

ben509··on Get notified when a file on GitHub has changed
Fair point re webhooks, though you could ask the owners for it. The atom solution is nicer, and I'd probably do it even if I owned the project, but it's still just polling.

It always bugs me that everything distributed inevitably devolves into polling...

ben509··on Get notified when a file on GitHub has changed
Good call out, though I'd put it under the umbrella of expensive, since someone banning or throttling you is a symptom of it.
ben509··on Get notified when a file on GitHub has changed
Yes, it uses polling. The only problem is the standard one for polling: it's either expensive or slow.

> The function app hosts the scheduled process that at the specified time retrieves the list of files from the storage account (1), iterates through them, for each (2) one checks if it changed and sends a notification if it did (3). If the file has changed, the function app also updates the file hash in the storage account (4).

The cheaper way to do it would be to set up a webhook listening for push events [1]. You do have to handle missed webhook notifications, but you can usually just do that by polling very infrequently.

[1]: https://docs.github.com/en/developers/webhooks-and-events/gi...

ben509··on On the complexity of JSON serialization (2020)
I mean that fundamentally the deserializer has lookup function and it's going to lookup anything it's told to.

You're right, some languages are worse about this, e.g. Python's pickle will perform arbitrary code executions.

But it's easy enough to restrict it to a set of known good constructors. You still have the classic late-binding dilemma: it's flexibility we don't actually want. Why should my find_matching_socks function ever have to worry that it might be passed basketballs?

The usual answer is, "it's fine, it'll just crash if they do that."

It might crash, or it might hang, or silently corrupt something. An attacker can stick the wrong kind of object into your code anywhere they like.

ben509··on CondensationDB: A general-purpose distributed database with end-to-end security
What's the story for deletion? Is that done through something like merge(record, delete_token) -> delete_token?
ben509··on On the complexity of JSON serialization (2020)
If JSON is transported through any intermediate processor, you have to assume they're translating them to floats and back again. If you treat them as arbitrary decimals, you have to expect that data is being silently corrupted.

And this includes intermediate processors that are invoked manually, so if someone uses a command like jq to simply test something, numbers are being truncated and they're baffled as to why they're getting different results.

ben509··on On the complexity of JSON serialization (2020)
I've tried this approach, and it's not great. You either have to pack a lot of noisy information in the JSON for the deserializer to work reliably, or you kludge it to try and guess, and then you find yourself designing your data structures around all the kludges.

You inevitably run the risk that your deserializer can, effectively, make arbitrary function calls. And your data is tied not only to your language, but also needs to find classes in specific modules.

ben509··on On the complexity of JSON serialization (2020)
The author understates the problem. Many half-baked solutions handle serializing, but don't consider how you're going to deserialize data. And if you do anything with numbers, you may need to guard against intermediate processors that truncate all numbers to 64-bit float accuracy.

I took a shot at it with https://pypi.org/project/json-syntax/ after doing some ad hoc solutions.

My approach was:

1. Don't serialize directly to JSON, but convert to the "jsonic" types. 2. Allow users to pick the rules they need, and make it reasonably easy to create new rules. 3. Generate picklable encoding and decoding functions.

It's worked pretty well for a project that has a very complex set of objects that need to be transmitted via JSON. The main difficulty is that it depends on interrogating Python's type annotations, which were pretty sketchy in earlier versions.

ben509··on Pip has dropped support for Python 2
Because nobody wants it.

You probably could run GraalPython, which is Python 3 and Jython, which is 2.7, since they both run inside a JVM.[1]

There'd be no interop between the languages, though. To get that in Graal, you'd have to reimplement python 2 using Truffle.

That's a massive effort compared to simply running 2to3 to migrate your old code to Python 3.

[1]: https://www.graalvm.org/reference-manual/python/Jython/

ben509··on Facebook Disabled My Account After I Criticized Them
But they may not be able to do it well enough that it will be notably better than an AI. Scaling manual labor can't work indefinitely due to the scarcity of talent.

Keep in mind that while a human being is very good at categorizing things, they're terrible at doing it over and over again, so the scarce talents are likely consistency and conscientiousness.

You should expect that, overall, the (n+1)th person you hire is marginally less talented than the nth. And while people are constantly entering and exiting the labor pool, this is negated by the fact that you're trying to expand your share of it.

So while there's a lot of randomness in recruiting, if you enforce any kind of standard, you'll hit a point where not enough candidates meet that standard, so you have to drop it. Once it is below the threshold of "better than AI" you have no reason to hire more people.

And you'll try to expand your eligible pool by raising wages, but everyone else wants consistent, conscientious people, too, so you're liable to run into the economic constraint: the amount you have to pay someone will exceed the value they're adding as a moderator.

ben509··on Judge refuses to reinstate Parler after Amazon shut it down
All the partisan boards I've seen, left and right, all plainly labeled themselves as such. If you're going to be a place for like-minded people, that's a selling point.

It doesn't make a lot of business sense to say, "we invite everyone in" and then plan on kicking out a lot of users.

There are loads of simpler reasons why lefties thought they were getting booted, especially incompetence on Parler's part.

ben509··on Judge refuses to reinstate Parler after Amazon shut it down
The entire premise of a republic is that power is checked and balanced. The aim is not to represent the "will of the people", because the will of a majority is frequently to oppress a minority.

The EC was more than a compromise, it was an integral part of a system that prevents too much power being handed to any one institution or demographic. And forcing national candidates to appeal to a multitude of states rather than a handful of cities has a moderating effect.

If anything, what's outdated about the EC is we need more checks on the political influence that is centralized in cities because the founders didn't anticipate urbanization.

ben509··on Judge refuses to reinstate Parler after Amazon shut it down
The real problem is that Parler sincerely wanted to start a free speech platform, and this is another data point that the idea, while well intentioned, doesn't work. It's a just-world fallacy: because free speech is a good and just thing, a business model predicated on free speech will be successful.

The first trouble is that you are opening the doors to all sorts of extremists. Whether they're far left, far right or simply personally unhinged, they are as predatory as spammers. They have no qualms about abusing your good will and s**ing in the punch bowl.

Same thing happened with Gab and Minds, but also smaller bulletin boards I've seen over the years. You set up a free speech site, and next thing you have a bunch of Nazis festooning it with swastikas. They're just like spammers, except they're spamming ideology instead of work from home scams.

The second trouble is that Parler is a competitor to established media corporations, who have a strong incentive to shut them down. That's a reality that every new business needs to face: established firms do not want competition.

All the people running amok provide the established firms with plenty of ammo to tar the upstart's reputation. And while they are biased by their incentives, they feel they are acting justly because they see all the extremist lunatics there. AWS didn't fabricate those incidents on Parler, all those were real posts.

ben509··on Judge refuses to reinstate Parler after Amazon shut it down
Barnes and Frey didn't read the contract closely.

Uncivil Law is a friend of theirs and he goes over the contract here: https://www.youtube.com/watch?v=PhWDKx9myI0&t=6187s

He's a conservative lawyer, so he doesn't have a political bias against Parler. They just don't have a case. I think Parler's lawyers misread the contract and thought the 30-day notice applied to termination for cause.

ben509··on AWS announces forks of Elasticsearch and Kibana
> Amazon can easily fund developers, they just didn't because they didn't have to.

Disclaimer: worked at AWS.

Yes, Amazon has a vast number of engineers. They also have a vast need for engineers.

So they have to make a business case to continue to fund engineers, and I don't think one exists for the type of development we're wanting.

To be clear, there is some development they could justify.

If they are replicating new features that Elastic releases, so they're not falling behind the market, the business case is retaining customers. But that's playing catch up.

If new features optimize the service, the business case is being able to advertise lower TCO, which attracts customers. That could be quite beneficial, but there's usually not a ton of optimization you can do.

There is a business case for new features that increase integration with other AWS services. That increases customer usage of AWS. But AWS is so proprietary this would likely be useless outside AWS.

So none of that, I think, is the development people are looking for.

What we'd want are features a software business develops to differentiate their product in the market. If the features go into the open source version, however, then by definition they aren't differentiating.

This is the key business contradiction in AWS trying to fund open source development.

Maybe I'm missing something and they can make the business case for continued differentiating feature development. So, I'd say I'm wrong if after two years we're seeing such features being released to the commnuity.

ben509··on RAM is the new disk – and how to measure its performance (2015)
Well, all memory operations must be translated by an MMU. So can the MMU be a distributed beast that lives in the CPU, the memory and the IO?
ben509··on Super-expressive – Write regex in natural language
I'd want something like this and the more compact language.

Classic regex syntax has a similar problem as purely expression-based languages: it's hard to clearly delineate between smaller and larger scale structures.

Sometimes, brevity is clarity. It's bad to write matchDigit().times(2).match('-').matchDigit().times(2) instead of simply '\d\d-\d\d'. So even with the problems with metacharacters, I don't think you want to lose that.

But more complex regexes are clearest when the individual parts are assigned to meaningful names and they're then composed into the final expression.

Most regex implementations require that you're doing string-munging to compose regular expressions, and developers and maintainers must be aware of the semantics of that string-munging to the regex compiler.

Allowing the dev to compose regular expressions from parts, then, seems like the greatest opportunity here for improving regex syntax. It'd be especially helpful for any dynamically generated regular expression, and you could have facilities like a "quote" operator.

ben509··on When parties reverse their stance, supporters immediately switch their opinions
Thanks!
ben509··on Again on 0-based vs. 1-based indexing
0-based indexing is preferable because the mathematics of half-open intervals make composing ranges far simpler. It becomes a bit more obvious as soon as you do any kind of non-integer ranges, because you find that only integers have a reliable "subtract one" operation.

For instance, suppose you're doing a lot of date arithmetic, and you might include times. If I have a range:

    [2005-05-05, 2007-07-07)
This unambiguously includes all times. If I compose it:

    [2005-05-05, 2007-07-07) [2007-07-07, 2008-08-08)
If I shift all of them forward 10 days:

    [2005-05-15, 2007-07-17) [2007-07-17, 2008-08-18)
Every possible time within the new range is accounted for. Transformations on the ranges are obviously correct. If we can't agree on whether time resolves to seconds, milliseconds or nanoseconds, it doesn't matter.

That's because you can find the beginning and end of a range without knowing how to subtract by one. If you later decide to add times, it will just work because, conceptually, you already handle every possible value in the range.

If you want to construct a series of ranges of floats, it's a bad idea to do [3.457, 6.799999], [6.8, 12.47699999]. If you use half-open intervals, it just works, without mucking with the end of the range.

This is the reason that "indices are offsets" is powerful: it's not circular reasoning, but a simplification because we're removing an unnecessary primitive (subtracct 1) that only reliably works with integers.

And to bring this back to integer offsets, even when you're working strictly with integers, you may want to conceptually work with rational numbers.

When you're working out your math for buffered IO, you need to map byte indices to chunk indices. You need to assign every byte written to a chunk.

In a 0-based world, your chunk offset is simply your byte offset / chunk length. Because there is no distinction between indices and offsets, it's a clean mapping between one offset scheme and the other.

It means you can work out on paper when a new chunk should be started, and then translate that into integer arithmetic. And your code directly reflects the math, rather than having to stick "- 1" and "+ 1" in here and there.

← PreviousPage 5 of 34Next →