HN user

jwatzman

769 karma
Posts9
Comments105
View on HN

There are a few others. “Quite” comes to mind — “I am quite hungry” or “that meal was quite good” can mean opposite things, depending on the speaker region and even voice inflexion if spoken.

My prospective co-founders and I were pitching to a VC firm that was, on paper, a really good fit for what we were trying to do. The partner we were pitching to was, 15 years ago, briefly my manager's manager -- some work relationship there, she remembered me and I her, but we didn't work super closely together and it had been a very long time. She had moved on at that company to more big-shot things and ultimately become a partner at a respectable VC firm.

About 10 minutes into the pitch, she cut us off, and basically said -- as absolutely kindly as something like this can be directly said -- "I am not going to invest in this, and furthermore I don't think what you're trying to do is investible at all". Then she took a bunch of her time to run us through why, help us understand some very fundamental things about the VC world we didn't quite have right, and generally be brutal but extremely useful in us framing what we were trying to do.

She didn't have to do that. She could have nodded along and then given us a polite "no" like everyone else. She could have cut us off and given us a rude "no". But she didn't -- she made sure to use the time we had to help us as much as she could, even if she very adamantly was not going to invest.

Not a big gesture or anything, but kind and helpful. There's a lot of that. But it doesn't make headlines.

In Rust, it's considered a bug for any code which isn't using `unsafe` to encounter a memory error (e.g., to segfault). That bug might be in some underlying library (which is itself using `unsafe`), or more rarely in the compiler, but it's a bug and not how Rust is supposed to work.

Does Haskell have any similar line? What is the property that code must have in order for it to be a bug to segfault? Must not call `unsafePerformIO`? Must not call `unsafeCoerce`? (Must not call any function with the `unsafe` prefix?)

In other words, is the segfault here to be considered a bug in the language -- or is unwrapping IO one of the things that, if you do it, you're own your own and may segfault? (Is part of the point of the article is that it is currently considered safe but should not be? Is that a bug in the language or in peoples' expectations?)

Or is a clear line like this not a notion that Haskell has? It's been a long time since I've done any Haskell, though I don't recall any clear guideline like this!

Can you elaborate on the complexity here for syscall entry on x86_64? (Or link to what you were reading?) Another commenter linked to Linux's own "nolibc" which is similar to, though simpler than, the Google project in the OP. Their x64_64 arch support is here, which looks simple enough, putting things into registers: https://github.com/torvalds/linux/blob/master/tools/include/...

The non-arch-specific callers which use this are here, which also look relatively straightforward: https://github.com/torvalds/linux/blob/master/tools/include/...

I don't see any complex stack alignment or anything which reads to me like it would require "niche C compiler options", so I'm curious if I'm missing something?

Glad you liked it! My co-author and I spent some time trying to find a good spread of questions covering different aspects of LLMs. And we were also surprised by how hard it was to convince GPT-4 that Queen Elizabeth II had died a lot of the time. (We found that specifying she died in 2022 helped a lot.)

(co)-author here. It was really interesting putting this together. We had some idea what LLMs/GPT-4 would and would not do well with, but were still surprised ourselves with a number of things. In particular, we knew it would really struggle with the acrostic, but the degree to which it just completely lost the plot was pretty surprising! It was also surprisingly difficult to convince it that Queen Elizabeth II had died in a lot of cases (it takes it better some times than others).

League of Legends (a similar game) does this -- no booths, only noise-cancelling headphones, for its large tournaments. There have been several major tournaments where the players have complained afterwards that they could not hear anything during big late-game fights due to crowd noise (since the crowd is also super excited at the big fight). Players need to be able to hear not just the game audio but also communication from their teammates and, despite noise-cancelling headphones, the crowd just drowned everything out. I'm honestly not sure why League of Legends hasn't moved to booths like Dota uses.

I'm not sure if you've ever watched one of these tournaments, but they get super noisy, and noise-cancelling all of that is not an easy problem (as the article says).

The article discusses constructors and how to make them work under "Linking the C++ standard library".

I wonder if placement new would run into the same linker problem that the article mentions -- I'll have to try it at some point :)

Indeed his videos are amazing. My recommendation though would be to start with the "beginner" video -- which is completely 2D but at least gets some ideas across. Then watch https://www.youtube.com/watch?v=PGtv-dBi2wE which isn't his but introduces how you get 3D out of fragment shaders. Finally just drink from the firehose -- https://www.youtube.com/watch?v=Cfe5UQ-1L9Q is fantastic, yes it's five hours but worth it. (Definitely come into that familiar with the idea of raymarching though... the first few minutes start off super basic but it goes to eleven real quick.)

if this was your point, the example is terrible.

Yeah, I addressed this in another comment here. I attempted in the last section to separate the ideas of "I heroically dived in" and "I took an opportunity in front of me" -- you shouldn't go looking for heroics. This didn't quite get across, and I totally understand why. Ah well.

The more interesting one though, is that sometimes high-impact work is "just there" to be done, if you're looking.

Author here. Yes, this was exactly my point!

But the best way I've found to detect promising junior engineers who will benefit from mentorship is to find who does bite, and more often respond "what if" instead of "but".

Indeed. I've mentored a bunch of otherwise-competent engineers trying to get to the next level, and my advice is similar: ask yourself "ok, now what's next". After doing the cool thing, there's inevitably half a dozen other things around it, and things might be obvious to you (as the now-expert in the cool thing) but not others.

Author here. For what it's worth, I (mostly) think you're right! IMO heroics were a huge problem at that company, and are a huge problem at the company I work at now too. The gruntwork is really really important.

I tried to get at this in the last section, that it's not about going out trying to be a hero, and it's unfortunate it didn't get across. That was my point that you shouldn't go look for company priorities to fix, to be a hero. Just look around you, see what's going on, and do good shit. Sometimes yeah that does involve heroics, sometimes it's just gruntwork.

I don't want to go back and edit the essay now but I think it could be much clearer indeed!

Imagine the same story but somebody two months earlier had voiced a concern that Jabberwocky and ChaChing wouldn't play well together. Pushing for the APIs to be harmonized so that they could play together and integrate. [...]

Disagree here, though it's maybe not obvious from the bits of the story I told why. ChaChing was one of... maybe three or four dozen experiments like it. All of the others failed. There was no reason to believe ChaChing would be any different, and if it did work, even the best-case expectations were well below what it ended up doing. It really was a lightning strike. So it would have been a huge waste of time to do all of that work, delaying Jabberwocky, for a bunch of things which never ended up shipping.

The concept of an application 'supporting a (specific) file system' sounds slightly ridiculous to me.

This concept is actually way less ridiculous than you might think, for any application which needs any guarantees about data durability, locking, etc (which includes everything from the obvious ones like postgres to things like Dropbox). I found https://danluu.com/deconstruct-files/ a fascinating read diving into this.

I'd not heard about van Emde Boas layout before, and it sounds super cool! I wish the author had included a simple example before focussing on the general case -- I find it hard to get an intuition for the general without a specific example! In particular, after some searching, I found the diagram at the top-left of page 4 of https://www.cs.au.dk/~gerth/papers/soda02.pdf to be immensely helpful in getting my head around the concept.

My Favourite Diff 6 years ago

OP here.

Explicitly-annotated fallthrough was still allowed; I codified a particular annotation that the analysis tool understood and allowed. I removed implicit fallthrough, but explicit fallthrough can be quite useful sometimes.

My Favourite Diff 6 years ago

Author here.

Yeah, you can't just mechanically insert the breaks :) I carefully went through each instance where my rule tripped, looked at the surrounding code, and figured out the right fix. Trying to automate that would indeed have lead to disaster -- and the lack of ability to automate this is why no one had done this in the past, it sounded like too much work. (It wasn't that much work.)

And I agree switch fallthrough can be useful! We just required it be annotated from now on, to convey the intent, as opposed to doing it by accident.

My Favourite Diff 6 years ago

Post author here.

One of the nice advantages we had in using our static analysis tool for this, with real code intelligence, instead of a simpler linter, was that we could do a much more clever check. The actual rule was "every case must be terminal", and we had a rich analysis for "terminal", so stuff like this would be considered legal:

    case blah:
      if (cond) {
        throw blah;
      }
      if (cond2) {
        some_noreturn_function();
      } else {
        return 42;
      }
etc etc. My example is a bit contrived, and the wisdom of doing such complicated things in switch/case is questionable, but it was useful when dealing with an existing codebase.

Another advantage was that our tool was designed for extremely fast analysis over the entire codebase, so errors were given to programmers as they were writing code, immediately. (200ms response time to any change. At that level you can run it on every keystroke, which we did.) Traditional linters can in principle do this, but in practise are often not written with this sort of performance requirements in mind.

(And yes, PHP allowing arbitrary expressions in case labels was... probably not a good idea.)

Back in 2015, I somehow ended up as part of a panel discussion at the end of a conference. The panel was going to include Joe Armstrong, Don Syme (inventor of F#), Tony Hoare (!), and myself (a nobody compared to any of them). During the conference, I wanted to meet each of the other folks on the panel, and ended up in a somewhat lengthy conversation with Joe Armstrong -- mostly about Erlang, but at some point the panel itself came up. I mentioned how nervous I was; me, sitting on a panel with such other esteemed and brilliant folks -- of course referring to all of the other people on the panel, including Joe Armstrong himself. I'll never forget his response: "yeah, me too! Wow, Tony Hoare, seriously?!"

I'm not sure if he deliberately misunderstood me or not, but it definitely put me more at ease, realising that there's always someone bigger, even for the folks you see as bigger than you!

So sad to learn of his passing. RIP.

FB engineer here. We did migrate slowly, to Hack http://hacklang.org/. It's a typed dialect of PHP, notably with full backwards compatibility, so we didn't have to rewrite all of our code as we converted over and added types. I haven't looked at the stats in a while, but last I checked, well over 99% of our files were marked as having some type information, and a very significant proportion of that was becoming fully statically typed. Basically all new code since the end of 2013 has been mostly, if not completely, statically typed.

I'm actually giving a talk at OOPSLA this week about how we went about actually doing the conversion (everything from how we approached designing the system to how we convinced engineers to use it), if you or anyone reading this happenes to be going. http://2015.splashcon.org/event/splash2015-splash-i-josh-wat... I think it will also be recorded.

I don't know the history of threads/NPTL on Linux. However, the distinction between "thread" and "process" in the Linux kernel is mostly a human one, not a technical one. Take a look at the clone() syscall -- spawning a thread vs. forking a process amount just to different flags to that call, to tell it whether to copy pages or not, how to assign a new ID to the new thread/process, etc. (Not sure if that's how fork() and friends are actually implemented under the hood.)