HN user

mbucc

115 karma

[ my public key: https://keybase.io/markb; my proof: https://keybase.io/markb/sigs/_-K6c-b3WQilNGvwBO38SSbGSMH5NyQKrv9TIb8TsIk ]

Posts1
Comments26
View on HN

Draft Unix manual written by Dennis Ritchie circa 1971---at a time when Unix had been running for a "few months" on the PDP-11.

Here's a great blog post on insurance and healthcare: https://healthcareinamerica.us/how-to-ask-good-questions-abo...

I think insurance is not an accurate word for the health care industry. I, like you, think of that word as coverage for risk, and in fact that is how the industry started in sixteenth century Netherlands (mentioned in that blog post).

But the business of insurance is about defining and measuring risk, and putting people into pools so that you can charge the riskier people more.

I don't think that maps well to health care, especially when you consider how good DNA testing will be in a matter of years. "Yup, your kid is in a high-risk pool for leukemia. You get to pay $50,000 a year for family insurance instead of the normal $19,000." [The first number is made up.]

Also, if you run an insurance business and someone with a pre-existing condition knocks on your door, their "market" rates will be their cost of treatment as their risk has become a certainty.

If you don't think charging people based on your best knowledge of the risk is fair, then it is a government program, a forced redistribution of risk across a larger pool; not insurance.

I hear a lot about OTP and the "let it crash" mantra, but I just don't quite understand what's so great about it.

The top two for me are:

(1) you start to just program the sunny path. It's faster and more fun to code in this mode. And with pattern matching of function arguments and return values (as well as guards) and you get pre- and post-condition asserts all while programming the sunny path.

(2) What are you supposed to do when your system raises an run-time error anyway? I think in practice, in the majority of cases simply restarting your process in some known state is the best you can do.

And that "start in some known state" is non-trivial for a system that handles concurrent inputs. OTP helps you do that correctly.

Edit: Formating. Add note pattern matching of function args and guards.

By default, the erl interpreter starts up the otp app, which loads lots of modules (50+?) and multiple (5?) different processes. It takes a second. To get things running faster, you can use the -boot argument to erl. There is a appendix in Joe Armstrong's book that steps you through it.

I don't hate it, but I do question if it is the best use of funds. The U.S. doesn't have the density required to support the transit systems we have built. Fare box revenue only covers 44% of operating costs in Boston; in Austin, the CMTA only covers 12.4%. And operating costs do not include the cost of capital, which must be massive [ref: https://en.wikipedia.org/wiki/Farebox_recovery_ratio].

-- Edit 's/costs do not cover/costs do not include/'

The benefit I see is that (at least in Erlang) pattern matching combines pre-condition asserts with programming the sunny path. For example,

   "/" ++ X = HttpRequest:get(path).
will crash if PATH_INFO doesn't include leading slash. Writing just the sunny path and getting asserts "for free" (without any clutter) is a fun way to program.

I also find that statement very readable.

BTW, here's some Java code that does the same thing:

  String Path;
  if (HttpRequest.getPathInfo().startsWith("/")) {
     Path = HttpRequest.getPathInfo().substring[1:];
  } else {
     String emsg = "no match of right hand side value \"%s \"";
     throw new IllegalStateException(emsg.format(HttpRequest.getPathInfo());
  }

Nice. Here's an Erlang version of your code, which I think reads even more like math:

  gcd(A, B) when B == 0 -> A;
  gcd(A, B) when A < B  -> gcd(B, A);
  gcd(A, B)             -> gcd(B, A rem B).
I also really appreciated the posting of more of Dijkstra's thoughts (from rer0tsaz) above, in particular this line struck a chord:
  When programming languages emerged, the "dynamic" nature of
  the assignment statement did not seem to fit too well into the
  "static" nature of traditional mathematics.
  
(Along those lines, Erlang's recasting of the equals sign as a pattern matching operator felt so natural when I learned how it worked.)

[Edit: zap redundant sentence.]

I do hold the belief that Spotify is putting a good-faith effort towards paying musicians and "rights holders" day in and day out.

The NPR piece said they asked a copyright laywer to look up the copyright for that song, and it took ten minutes (the copyright holder had filed a copyright). Based on that piece, if I was the judge and jury, I would expect a company valued at over $8B to have done a better job, especially given how the penalties are structured.

His song was played over 20,000 times, for which he received no compensation. IIRC, the NPR piece said the max penalty is $150k per infringement. Ouch.

Nokia 635, $40

I don't understand why these low cost Nokia's get so little love here in the U.S. My 520 was $50 a few years ago and is a rock solid piece of hardware. I guess it's the missing apps on Windows mobile?

They created a ton. Transistors, solar cells, lasers, satellites, cell phones, LEDs, UNIX and C all came out of that monopoly. That's an unparalleled track record of technical innovation.

Actually, discovered ledger-cli here last week (thanks HN). It's amazing. Abstracting currency to the concept of commodity + price files makes it trivial to track your shares in 401k, and have the current market value print on the balance report. Handles lots. Recurring transactions support period specifications like "every two weeks starting on 2013/10/01". Maps payee's to accounts, and supports payee aliases. Pretty much anywhere you type a string you can also use a regex. State is a text file and the program does not alter state; just reads it and prints out a report. Finally, it provides a CSV convert which makes it easy to convert an export from your bank to a list of double entry transactions (./convert bk_download.csv >> trx.dat).

I found it interesting how radically different his teaching premise is from the current U.S. public school approach. From the preface:

I thought to address them to the most intelligent in the class and to make sure, if possible, that even the most intelligent student was unable to completely encompass everything that was in the lectures.

The models certainly contributed. (Note: I have read this far in the book.)

The modeling error in question was independence; that is, if you have five mortgages, each with a 5% change of default, then these can be packaged up as an AAA security as follows: you only lose your money if all five default. A bit riskier package is that you lose if 4/5 default. And so on, each with different returns.

If they are independent, the p(default) = 1/20^5. If they are dependent, it is 1/20. Now multiple mortgage pool size by a 100 or 1,000 or 10,000 (?) and see how far off the estimated risk is. :)

Now combine this with a 30-to-1 leverage when buying these "AAA" securities.

(This was quite a good problem to work through with my daughter to see what that little "independence" assumption means. :)

His main point here was that modeling failures are typically due to out-of-sample conditions; when the housing bubble broke, the markets were might more tightly coupled across the country than the modelers assumed. While they could have seen this kind of dependence if they looked to Japan, there was no such precedence in the US in recent history.

So, if the method was commented, would you:

(A) assume the comments are correct and skip reading what the code does?

(B) use comments as guidance and read code anyway?

The first seems awfully risky to me and poor advice to any programmer trying to write solid code.

This talk is very informative.

The historical bit about NASA using event-sourced design for the Apollo Program (1969) was pretty interesting. He gives IBM big props for hitting 2,300 transactions/second in the mid-60's (with IMS aka DB1).

@17:15 "We've forgetting a lot of this good stuff in our modern designs."

@17:34 "Transaction queues, pulling things off, uncontended, and processing them."

@17:50 "Some of the systems we have today are woeful and can't even get close to that, considering the hardware we have today, and it's ... how we are writing contended designs"

Last month Forbes reported that Netflix said 75% of what it's customers watch are from recommendations. Definitely some bang there.

Also, note that 10% improvement was far from linear: year 1: +8.43%, year2 +1% and year3 +0.6% (!!).

Keeping variable names short is a natural brake on routine length. Like wrapping at 80 columns and using tabs is a natural brake on deeply nested conditionals.

If I need a longer variable name to clarify the intent of the code, it's a signal from the code that maybe I should break the routine into smaller pieces.

I also find that smaller variable names makes it way faster to scan and thus understand.

YMMV ...

blocking / non-blocking has nothing to do with language; for e.g., see tornado for async request handling in python.

I have been using event-based persistence, and while performance is definitely a bonus, the win for me is the ability to replay the transaction log.

For example, let's say you log each page view and include the referer in that transaction. Initially, the only state you maintain (in memory) is the count of page views.

Three months after your system is on-line, you decide you want to take a closer look at who is sending you traffic. So, you update the business logic that processes the pageview_transaction to count page views by referer, perhaps a count of domains by day (for up to 365 days). Replay the log and you will now have that state for the entire history of your app.

I expect there will be benefits for debugging as well, since I can replay the transaction log with a local, annotated version of the app to figure out specific sequence of real-world transactions that surfaced the bug.

And you can use SQL if you like. You just have to keep your transaction processing fast (e.g., by using an in-memory db).

If you are interested, here's a Python implementation: https://github.com/PetrGlad/python-prevayler.