HNHacker News
TopNewBestAskShowJobs

alex_smart

1,323 karma · joined April 30, 2014

submissionscomments
alex_smart··on What P vs. NP is about
To whatever extent the shortest route question is not in NP, it is also not NP-hard.

Both NP and NP-hard are defined for the class of decision problems.

alex_smart··on A Burrito Is a Monad
>Some people call futures monads.

Well that's because they are. And it is one of my favorite examples to explain the power of monads actually.

Most humans prefer programming in the async/await style compared to using promises/futures with callbacks (commonly called "callback hell"). In most languages, you need explicit language support to enable async/await by adding new keywords into the language. (And you are completely at the mercy of your language designers. Looking at you Java.)

Haskellers, because they grok monads and futures are just monads, are able to code in an async/await style without any special syntax specifically for async/await. They just use the same notation they use for other monads.

alex_smart··on gRPC: The Ugly Parts
Haha the good old circular dependency problem. I am still surprised there are people in the industry that can’t recognise and solve these problems. It is such a classic pattern and its use arises in the wild all the time.
alex_smart··on Swift is a more convenient Rust
Sure, but use of those patterns is not idiomatic in Python.
alex_smart··on gRPC: The Ugly Parts
>They eventually added a ServeHTTP() interface to grpc-go as an experimental way to use the HTTP server from the Go standard library but using that method results in a significant loss of performance.

I don't quite see how that is possible. ServeHTTP() seems like a most general HTTP interface. How could implementing that interface for a protocol built on top of HTTP result in a performance degradation!? If that is indeed the case, that seems like it would imply a flaw in go's standard http library, not grpc.

alex_smart··on Swift is a more convenient Rust
> The languages that dominated the 2000s (Ruby, Python, Javscript, PHP) were all more or less derived from Smalltalk

One of these is not like the others. Javascript derives from Lisp (first-class functions, lambdas, closures), not Smalltalk.

alex_smart··on Llama 3.1 in C
The Hindi output is garbage.
alex_smart··on Inline previous result in Emacs Lisp
THIS right here is why I use emacs. Not that something like this is not possible with other open-source software, but the number of steps required to compile, debug, identify change required, compile, rerun, it is usually not worth your time to investigate minor inconveniences. So there is learned helplessness and you compromise and learn to just live with the annoyance.

With Emacs you truly feel to be in control.

alex_smart··on What everyone gets wrong about the 2015 Ashley Madison scandal
The majority of users are men on all dating sites and apps.
alex_smart··on The Death of the Junior Developer
Today: Don’t hire or train junior developers.

Five years later: Why can’t I find any senior developers? Shocked pikachu face.

alex_smart··on A breakthrough towards the Riemann hypothesis
Not according to constructivists.
alex_smart··on Don't DRY Your Code Prematurely
>You lose absolutely nothing. If you later want to handle the two cases differently, most IDEs allow you to inline the set_deadline method in a single key stroke.

Problem with unintentional coupling isn't that you can't undo it. It is that someday someone from some other team is going to change the method to add behaviour they need for their own use case that is different from your own and you won't even notice until there is a regression.

alex_smart··on Don't DRY Your Code Prematurely
>It's not like webpage space is expensive.

It is not the webpage space. It is people's limited attention spans and ability to focus. A complex example is needed to properly motivate certain concepts, but too complex an example also contains too many other details that the reader gets bogged down/distracted from the main concept being discussed.

At least that is my hypothesis for why almost all programming books and tutorials have terrible examples. I am happy to be proven wrong.

Coming back to the article, I looked at some of the previous articles from the same series, and to me it feels like a very conscious decision to only include 3-4 line code examples.

alex_smart··on Don't DRY Your Code Prematurely
Almost all programming tutorials and even books to a certain extent suffer with the problem of terrible examples. Properly motivating most design patterns requires context of a sufficiently complex codebase that tutorials and books simply do not have the space of getting into. This particular case is especially bad, probably because they had the goal of having the whole article fit in one page. ("You can download a printer-friendly version to display in your office.")

> There is no guidance whatsoever (ie: Martin Fowler's Rule of Three).

That is completely unfair imo. Although not properly motivated, the advice is all there. "When designing abstractions, do not prematurely couple behaviors that may evolve separately in the longer term." "When in doubt, keep behaviors separate until enough common patterns emerge over time that justify the coupling."

Simplified maxims like "Rule of Three" do more harm than good. Don't couple unrelated concerns is a much higher programming virtue than DRY.

alex_smart··on Tmux is worse-is-better
On mac, iterm2 has excellent tmux integration. You start tmux in control mode (tmux -CC) and it opens a new window for that session with all the multiplexing handled by the terminal instead. You get to use all of your normal terminal keyboard shortcuts and terminal interface.

It is the best of both worlds. And, yes, of course it works with a remote ssh session.

alex_smart··on Why SQLite Uses Bytecode
> Branching on "expression type" and column type in your first example is also unnecessary

It’s not?

alex_smart··on Why SQLite Uses Bytecode
Consider evaluating an expression like "col1 + col2 == col3"

A tree based evaluator has to do something like -

    for (int i = 0; i < df.size(); i++) {
        // switch on expression type (column, binary operator, unary operator etc)
        // switch on expression operator type (add, subtract, equals etc)
        // switch on column type (int, long, float etc)
        // actual evaluation
    }
whereas a bytecode based evaluator is able to run something equivalent to -

    for (int i = 0; i < df.size(); i++) {
        result[i] = df.getLong(column1Index, i) + df.getLong(column2Index, i)) == df.getLong(column3Index, i)
    }
alex_smart··on Why SQLite Uses Bytecode
I found this by looking at spark source code to figure out what they were doing under the hood to deal solve this problem. :)
alex_smart··on Why SQLite Uses Bytecode
I recently implemented my own expression evaluator in java for in-memory data frames, and once you think about doing that deeply, you very quickly understand the need for bytecode. If you directly evaluate the expression using a tree representation, you basically have to do a whole lot of branching (either via switch statements or polymorphism) for every single line of useful operation. Yes, the branch predictor kicks in and it means that your code wouldn’t be as slow as if it didn’t, but it is still measurably slower than if you converted the expression into bytecode once and just ran that on all rows instead.
alex_smart··on The Performance Impact of C++'s `final` Keyword
One thing that wasn't mentioned in the article that I wished it did was the size of the compiled binary with and without final. Only reason I would expect the final version to be slower is that we are emitting more code because of inlining and that is resulting in a larger portion of instruction cache misses.

Also, now that I think of it, they should have run the code under perf and compared the stats.

alex_smart··on Programming Is Mostly Thinking (2014)
In case you didn’t know, doesn’t delete the commit. You can use `git reflog` to find the commits you were recently on and recover your code.
alex_smart··on What John von Neumann did at Los Alamos (2020)
Not sure if you’re being facetious? There were not 100 people of the same calibre as JvN in the US or even the world surely.
alex_smart··on What John von Neumann did at Los Alamos (2020)
Probably not. The figure is the right order of magnitude.
alex_smart··on Guess my RGB
I meant 3 tries in total, not just the random guesses.
alex_smart··on Guess my RGB
Excellent work!

We can also probably prove that 3 guesses are not enough by some sort of adversarial argument. That is, instead of having the color be fixed at the start, imagine that the game picks the colors adversarially to try to make the job of the guesser as difficult as possible, while remaining consistent with the answers it has already given. If we can pick a function for the adversary that does not fully disambiguate the color completely for any sequence of three guesses, we will be done.

alex_smart··on Guess my RGB
Assuming the score is 100-Euclidean distance, you should be able to triangulate to the correct answer after three random guesses. Triangulation will give you two candidates for the correct colour, so if you choose between them randomly you should get the correct colour in 4.5 tries on average.
alex_smart··on The window for great-grandmothers is closing
Great-grandparents? The window for grandparents might be closing! If you have your kids at 35, and your kids have their kids 35, you are 75 by the time the grandchild turns 5. The amount of quality time you might have to spend with your grandchild could be approximately zero (depends of course on your health).
alex_smart··on Jeff Dean: Trends in Machine Learning [video]
IMHO, the good old method of skimming through the table of contents, reading the preface and perhaps the first couple of chapters is going to be a much higher fidelity indicator of whether a book is worth your time than reading an AI generated summary.
alex_smart··on Zed Editor: All Occurrences Search from 1s to 4ms
To check what the actual zero-abstraction version of the select_all_matches function would run in, I created a simple c++ function that accepts the string buffer and the simply calls buffer.find until it finds all matches and pushes the match results into a vector. Result: with the same file and search string, it runs in all of 0.2 ms. So we are still off by a factor of at least 10 before we get to call it a "zero-cost" abstraction.
alex_smart··on I Ended Up with Just 0.15% of My Own Startup
It matters if the pre-money valuation at which the new shares are issued is inaccurate.

You own 10% of a company that was valued in the last round of funding at 10 million dollars. You have put in significant amount of work since and company has raised a lot more revenue. The fair market value is now at a 100 million dollars, but the existing shareholders put in another 90 million dollars at the same pre-money valuation as last round, diluting every existing share down by 90%. Congrats you now own only 1% of the company and just got robbed of over 8 million dollars. (Fair value of your stock went from 10% of 100 million = 10 million to 1% of 190 million = 1.9 million).

← PreviousPage 4 of 19Next →