6,887 karma · joined June 7, 2011
evan.martin@gmail.com
My posts on HN: https://news.ycombinator.com/from?site=neugierig.org
---
If you're on HN it's plausible you're advanced relative to your peers, either in your education or in your career. Don't use that to rush your way into adulthood! You have the rest of your life to do adult things, but you only get ~730 more days of being a teenager in your whole life.
Concretely: if you're ahead in your education, don't skip college, but instead use your aheadness to make time to learn more things. If you're ahead in your employability, don't jump into maximizing your $$$ but instead look for interesting personal growth opportunities.
The maybe too subtle point I was trying to make is that, even though the TypeChecker object literally provides an EmitResolver (I think? something like that?), in terms of the conceptual layout of the compiler, if you have a box labelled "Type Checker" it's natural for the reader to think it's where type checking happens.
In other words, the graph is something like
TypeChecker object -> EmitResolver -> js files
|
v
type checkingImportantly, types do not affect TypeScript emit[1]: you can take a TS program, replace every type with Banana and the compiler will have the same output.
(I am not sure, but I think the TypeScript emitter does use a "type checker" object for type-adjacent things like resolving scopes. But it does not use such an object for checking types during emit. Another way of saying this is that type checking can be done during emit but conceptually it's a an optional segue on the side, not the box immediately leading to .js files.)
[1]: http://neugierig.org/software/blog/2016/04/typescript-types....
I think they help, but ultimately I expect you need a compiler solve the absolute madness of the totality of C++. For example I think getting argument-dependent lookup right in the presence of 'auto' requires type information? And there are other categories of things (like header search paths) where I think you are forced to involve the build system too.
As this article describes, doing this requires per-language integrations and also effectively being able to "run the build" for any given code (because e.g. the C++ header search path can vary on a per-source-file basis), which is untenable for a codebase as large and varied as GitHub's. However, if you can make it work, you get the benefit of having the compiler's understanding of the semantics of the code, which is especially finicky in complex languages like C++ or, say, Rust.
For example, if you look at this[1] method call it refers to a symbol generated by a chain of macros, but the browser is still able to point you at the definition of it.
It's an interesting tradeoff to make: the GitHub approach likely doesn't handle corner cases like the above but it makes up for it in broad applicability and performance. I recall an IDE developer once telling me they made a similar tradeoff in code completion, in that it's better DX to pop up completions quickly even if they're "only" 99% correct.
(To be clear, I absolutely think the approach taken in the article was the right one for the domain they're working in, I was just contrasting it against my experience in a similar problem where we took a very different approach.)
[1] https://source.chromium.org/chromium/chromium/src/+/main:v8/...
https://github.com/ninja-build/ninja/commit/89587196705f54af...
If you've completed enough of the base game, I can recommend Seablock (which includes AngelBob) and Space Exploration as two mods that make the game dramatically larger. I played some of Pyanodon (which is also sometimes mentioned as a big mod) but I found it kind of gratuitously complex.
Further, I have the impression that Figma has pretty specific and complex graphics needs. For one example of the sort of thing I mean, we decode image data in JS and put it into GL textures without the Wasm side ever seeing the pixel data, so that the browser can (potentially) decode on a background thread and uncompressed pixel data doesn't contribute to Wasm heap memory usage. However, I don't know Skia well, so it's possible Skia has some mechanism to composite GL textures it's not responsible for too.
This is not quite right. The bulk of Figma rendering is Figma-custom GPU code. It's true that Figma uses Skia, but only for some specific graphics algorithms in Skia, not as a general purpose rendering library.
Source: I work on this code.
(But upon writing that I'm not sure where I got that impression from, and I can't find a citation for it right now, so treat the claim with skepticism.)
Overall the net effect is a kind of death by a million cuts, but each of these cuts individually is a decent amount of work to clean up and fix that doesn't itself move any needles.
My latest perspective on this is that the only renewing force is the also the one found in nature, which is that you occasionally need to burn the whole forest down or have the organism die, so that you can start again afresh. In a business setting this means using a new stack in a new app.
I previously worked on JS infra at Google. Google uses a lot of shared JS libraries that date back over a decade, and those libraries have accumulated lots of workarounds for browsers that nobody cares about anymore. (One especially crazy seeming one from today's perspective is that there's a separate implementation of event propagation, I believe because because it dates back to browsers that only implemented one half of event bubbling/capture!)
It's very difficult to remove an old workaround because
1. it's hard to be completely sure nobody actually depends on the workaround (especially given the wide variety of apps and environments Google supports -- Firefox aside, Google JS runs on a lot of abandonware TVs), and
2. it's hard to prioritize doing such work, because it's low value (a few less bytes of JS) and nonzero risk (see point 1) without meaningfully moving any metrics you care about.
In all, how to eliminate accumulated cruft like is a fascinating problem to me in that I can't see how it ever gets done. And it's not a Google thing. Even the newer cooler startup I now work at has similar "work around old Safari bug, not sure if it's safe to remove" codepaths that I can imagine will stick around forever, for similar reasons.
http://neugierig.org/software/blog/2012/03/heap-profiling.ht...
* The one exception was when I was on a team where we had a rotating pager duty for our stuff in production, and I would periodically be on duty. As I recall we got paid extra for those time blocks.
(Disclaimer: no affiliation, I just enjoyed my visits there. I also have done no research into whether the animals are mistreated or anything.)
With more perspective on the problem, I think the way we implemented it at the time was wrong, with the XML processing done in unsandboxed C++. At the time, Chrome didn't use any HTML for its UI like the new tab page, so only web content was sandboxed, but with today's perspective it's obvious to me you want to process XML content with the same sandboxing indirection you use for other untrusted data formats. So in retrospect I'm glad the feature didn't launch as it was, because it would've been a security disaster.
Also my recollection is that the code wasn't great. (I feel allowed to say that because I authored it -- I'm not slagging on my coworkers.)
I highly recommend it to anyone else like me, who is generally cranky about new things. They did a really great job with Arch. This policy you mention is a great example of what I like about it.
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1679430