Recent submissions

Comment · 12 years ago
One of the rats achieved a 53.5% success rate (the author did not specify whether this was over the entire 800 data points or only the last 100).

When tested on 800 data points, a purely random strategy would have a > 53.5% success rate about 2% of the time.

Comment · 12 years ago
Honest question: what are the benefits of using environment variables over having an actual configuration file (that is obviously not added to version control) ?
Comment · 12 years ago
> structure = json.loads(json_string)

Not quite. Let's say your JSON data contains the following attribute:

    "access" : [ "view", "edit", "admin" ],
This field should be represented (in the language) as a set of values from an "access-levels" enumeration.

In C#, you'd have the following boilerplate:

    [DataMember(Name = "access")]
    public HashSet<AccessLevels> Access { get; private set; }
In OCaml, it would be:

    access : Access.Set.t ;
The simple "json.loads" solution would return a list of strings instead. What's the Python code for turning it into a set of enumeration values, and failing if one of the values does not match ?
Comment · 12 years ago
Easy language interoperability as a reason to choose Protobuf over JSON ? Mainstream languages support both JSON and Protobuf equally well, and the others tend to support JSON more often than Protobuf.

Free backwards compatibility ? No. Numbered fields are a good thing, but they only help in the narrow situation where your "breaking change" consists in adding a new, optional piece of data (a situation that JSON handles as well). New required fields ? New representation of old data ? You'll need to write code to handle these cases anyway.

As for the other points, they are a matter of libraries (things that the Protobuf gems support and the JSON gems don't) instead of protocol --- the OCaml-JSON parser I use certainly has benefits #1 (schemas), #3 (less boilerplate) and #4 (validation) from the article.

There is, of course, the matter of bandwidth. I personally believe there are few cases where it is worth sacrificing human-readability over, especially for HTTP-based APIs, and especially for those that are accessed from a browser.

I would recommend gzipped msgpack as an alternative to JSON if reducing the memory footprint is what you want: encoding JSON as msgpack is trivial by design.

Comment · 12 years ago
https://kdp.amazon.com/help?topicId=A301WJ6XCJ8KW0

If your list price is above $9.99, you get 35% royalties instead of 70%.

Comment · 12 years ago
"... on GitHub."
Comment · 12 years ago
Many companies offer production-grade hosting for open source applications. The fact that you are keeping your source closed tells me that you are afraid a competitor (or your clients themselves) could achieve an equivalent quality of hosting for less than they would pay you. To a customer like me, this is bad news.
Comment · 12 years ago
I'm curious: with HTTPS, how does the firewall know that it's an OPTIONS request ?
Comment · 12 years ago
At RunOrg, we've encountered this a few times with our CORS-only API.

It is against our philosophy to leave users behind only because they are locked in by outdated infrastructure. We still want to support them.

It is against our philosophy to bend the purity of our API to accommodate wrinkles in how outdated infrastructure declines to support standards. There will be no JSONP alternative to CORS in RunOrg.

The solution we propose each and every time is to mount a proxy to our API on the same domain as the site it is used on. Users on modern infrastructure reach us directly at api.runorg.com, users on CORS-hostile infrastructure reach us through the proxy and still get their data (albeit with decreased performance). It's a fairly simple technical solution that leavers our API clean and supports non-CORS modes of access.

Comment · 12 years ago
This was just as easy in the previous generation :)

OCaml has had this feature since 1996.

Comment · 12 years ago
I have a hard time thinking of a situation where proper objects-and-functions code becomes easier to understand by removing the functions. Do you have any examples ?
Comment · 12 years ago
The only difficulty is naming the abstraction :)
Comment · 12 years ago
I would argue that functions have no business performing global side-effects in the first place --- these things are better expressed as state encapsulators (such as objects) anyway.
Comment · 12 years ago
The Single Responsibility Principle is like Body Mass Index for code: it's easy to measure (humans have an innate sense of what "reponsibility" means) but outside of extreme situations it is not precise enough to base serious decisions on: there is a huge grey area where people do not agree on what responsibilities are.

It's the same as EDD: it's fairly subjective, but it weeds out the extreme cases.

The benefits of SRP are usually a side-effect of applying more objective rules to the code.

DRY is the primary driving force. It pulls shared responsibilities out of modules and leaves no doubt that those responsibilities were shared. It detects recurring concepts and gives them a representation, thereby increasing coupling.

The second force is to reduce access to private code: out of 100 lines of code in your module, how many actually need to access that private concept on line 42 ? If the answer is "30", then what are those other 70 lines doing in this module ?

Apply both forces to a code base, and the SRP will appear out of nowhere.

Comment · 12 years ago
The most important rule about the future is that You Aren't Gonna Need It. If the future is known then it is called "requirements". Design is for protecting you from the unknown future: allowing code to be changed in arbitrary, unforeseen ways.

As for coupling and cohesion: if modules are too small, they usually lack cohesion ; if module are too big, they usually have high internal coupling. The sweet spot is in the middle. And you can create low-cohesion, high-coupling modules if you want :-)

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton