HNHacker News
TopNewBestAskShowJobs

dcreager

859 karma · joined March 26, 2018

[ my public key: https://keybase.io/dcreager; my proof: https://keybase.io/dcreager/sigs/qAdDFd-q6TDjesY0__JJ6GnOrnO0mRcDVpvmhC1958M ]
submissionscomments
dcreager··on Ty: A fast Python type checker and language server
Wait wait wait

Carl, you did not tell me that the errors we emit need to be correct!!

I think I need to go revisit some of my PRs...

dcreager··on Ty: A fast Python type checker and language server
At least for the moment, we aren't planning on a plugin architecture. We do recognize that there are some popular libraries and code patterns that aren't easily (or at all) typeable with the current state of the typing spec. We feel it would be more useful to help drive changes to the typing spec where we can, so that other type checkers can also benefit; and/or implement workarounds for the most popular libraries directly in ty, so that a library author doesn't have to rely on their downstream consumers installing a particular set of plugins to get good type-checker results.

(It's also more difficult to support plugins effectively in a type checker like ty, than in a linter like ruff, since any non-trivial use case would likely require deep changes to how we represent types and how we implement type inference. That's not something that lends itself to a couple of simple hook extension points.)

dcreager··on Ty: A fast Python type checker and language server
Well, it is a joke...but that said, we're hosting a happy hour which is kinda similar!

https://partiful.com/e/Dcrv6XA8PjWTK5Zhw8yr

dcreager··on Ty: A fast Python type checker and language server
We do plan to provide an LSP server and VS Code plugin, which will support GTD etc. Though as several others have pointed out (e.g. https://news.ycombinator.com/item?id=43919354), it's still very early days for ty, so we don't have concrete release announcements for that yet.
dcreager··on Ty: A fast Python type checker and language server
There is a formal grammar defined in the CPython repo, implemented in a language called ASDL:

https://github.com/python/cpython/blob/main/Parser/Python.as...

ty uses the same AST and parser as ruff. We don't use the ASDL grammar directly, because we store a few syntax nodes differently internally than how they're represented upstream. Our parser is hand-written in Rust. At first, our AST was also entirely hand-written, though we're moving in the direction of auto-generating more of it from a declarative grammar.

https://github.com/astral-sh/ruff/issues/15655

https://github.com/astral-sh/ruff/tree/main/crates/ruff_pyth...

https://github.com/astral-sh/ruff/blob/main/crates/ruff_pyth...

dcreager··on Ty: A fast Python type checker and language server
We're going to set up a lemonade stand in the main hall at PyCon next week
dcreager··on Ty: A fast Python type checker and language server
> such as claiming `datetime.UTC` doesn't exist)

This is a known issue — we're currently defaulting to a conservative Python version, and `datetime.UTC` really doesn't exist until Python 3.11!

https://docs.python.org/3/library/datetime.html#datetime.UTC

We will probably change the default to "most recent supported Python version", but as mentioned elsewhere, this is very early and we're still working out these kinds of kinks!

dcreager··on "We're building a new static type checker for Python"
> it uses salsa from rust for incremental type checking

This is true! We're also contributing salsa features upstream where we can, e.g. https://github.com/salsa-rs/salsa/pull/603

dcreager··on "We're building a new static type checker for Python"
The aim is to support both incremental ongoing type checking via something like an LSP server, and also batch type checking for use in e.g. CI.

> The entire system is designed to be highly incremental so that it can eventually power a language server (e.g., only re-analyze affected files on code change).

https://bsky.app/profile/crmarsh.com/post/3lgvhzeawuc26

dcreager··on "We're building a new static type checker for Python"
np! I also posted a link to Charlie's Bluesky cross-post, which you can read without logging in to anything: https://news.ycombinator.com/item?id=42870359
dcreager··on "We're building a new static type checker for Python"
> does it actually exist? is this currently a closed-source codebase, or is "we're building" future tense?

From the thread:

> We haven't publicized it to-date, but all of this work has been happening in the open, in the Ruff repository.

dcreager··on "We're building a new static type checker for Python"
Bluesky cross-post for those who don't want to read the thread on X: https://bsky.app/profile/crmarsh.com/post/3lgvhzdfrps26
dcreager··on Deprecating outdated issues on the GitHub public roadmap
> "Precise code navigation" also already exists for TypeScript

We had conflated JS and TS support into a single release issue. JS support never landed, but TS did: https://github.blog/changelog/2024-03-14-precise-code-naviga...

When we first created the release issue, the thinking was that we wanted to launch support for those two languages at the same time, and for that support to be compatible with each other. (So we could correctly follow e.g. a TS library referencing a definition in an upstream JS library.)

Unfortunately we never got JS support to the point where we could GA it. Largely for scaling reasons — there is a HUGE amount of JS on GitHub, and JS is a dynamic enough language that we have to do more per-file processing on it than for TS or Python. We decided not to wait for JS to be GA-ready before releasing TS, but then never corrected the release issue to account for that.

dcreager··on Let's create a Tree-sitter grammar
This is exactly right. You either end up with something very low-level (on the level of LLVM IR, for instance)—which means you aren't constructing and analyzing high-level language constructs anymore—or with something high-level but with many language-specific special cases grafted on.

Where we've found success is in stepping back and creating formalisms that are language-agnostic to begin with, and then using tree-sitter to manage the language-specific translations into that formalism. A good example is how we use stack graphs for precise code navigation [1], which uses a graph structure to encode a language's name binding semantics, and which we build up for several languages from tree-sitter parse trees [2].

[1] https://dcreager.net/talks/stack-graphs/

[2] https://github.com/github/stack-graphs/tree/main/languages

dcreager··on Stem, a stack-based language with metaprogramming and a C FLI
This is very cool, well done! I love seeing people get interested in other programming paradigms, like concatenative languages. I gave a talk about them at Strange Loop / PWL last year: https://dcreager.net/talks/concatenative-languages/
dcreager··on My review of the C standard library in practice
There are many libraries available that you can use as a libc replacement instead of CCAN, if that’s what you prefer [1-3]. Taking on a beefy dependency like that can be overkill, though, if all you need is a linked list or dynamic array implementation.

[1] http://library.gnome.org/devel/glib/

[2] http://apr.apache.org/

[3] https://libcork.io/

dcreager··on My review of the C standard library in practice
Please note that the above link has been claimed by squatters and isn’t the right link for CCAN anymore! The maintainer suggests [1] just using the GitHub repo [2] instead.

[1] https://lists.ozlabs.org/pipermail/ccan/2022-September/00141...

[2] https://github.com/rustyrussell/ccan/

dcreager··on My review of the C standard library in practice
For those who haven't seen it, CCAN [1] is a great collection of reusable C code, much of which specifically exists to work around the kinds of issues mentioned in OP. It turns “oh crap I should probably roll my own” into “wait I bet someone has already re-rolled this”.

[1] https://ccodearchive.net/

dcreager··on The technology behind GitHub’s new code search
This sounds like Cross-Repo Code Navigation [1], which we do support, though only for Python at the moment. And you're right that it does not use the same search index under the covers — OP is specifically describing the index for "search box"-style code search across a large set of repositories (org-scoped, global-scoped, me-scoped, etc). For Code Navigation, we have a _different_ set of interesting and bespoke indexers and storage formats. I've posted some links here if you want to learn more: [2]

[1] https://docs.github.com/en/repositories/working-with-files/u...

[2] https://news.ycombinator.com/item?id=34693181

dcreager··on The technology behind GitHub’s new code search
It sounds like you are navigating in a language where we currently only support "fuzzy" or "search-based" Code Navigation, which only uses the _unqualified_ symbol name as the search target. As you point out, this can be very imprecise when there are particular symbol names that are used a lot. (Think `render` in a Rails codebase, for instance.)

We also have Precise Code Navigation — still currently only for Python [1], but we're working on other languages as fast as we can. As mentioned down-thread, that is built on our new stack graphs framework [2]. We're often asked why we're not leaning on something LSP-shaped for this. I go into a built of detail about that in a FOSDEM talk from a couple years back [3], and also in the Related Work section of a paper that we just published [4].

[1] https://docs.github.com/en/repositories/working-with-files/u...

[2] https://dcreager.net/talks/stack-graphs/

[3] https://dcreager.net/talks/2020-fosdem/

[4] https://dcreager.net/publications/016-stack-graphs/

dcreager··on The technology behind GitHub’s new code search
> But this could be tied into CI, especially for projects utilizing runners for building the code.

One often overlooked drawback of generating this data during CI is that you, the project owner, are now paying for the compute. Of course, maybe you qualify for a free tier. And if not, if you're already running a CI job for testing/linting/etc, the marginal cost of also generating code nav symbols might not be too bad. But one benefit of the stack graphs approach mentioned up-thread (and the code search indexing described in OP) is that all of the analysis and extraction work is done in dedicated server-side jobs that GitHub is footing the bill for.

dcreager··on Remote startups will win the war for top talent
> having "face to face" chitchat, builds up a small buffer of rapport that significantly improves empathy and perceived intent

On my team we have a weekly 30-minute meeting for non-work-related updates. A chance to talk about whatever you did in the past week outside of work, or about anything else that currently interests you. It typically prompts a lot of follow-on conversations in Slack afterwards.

It might be nicer if this happened organically, and didn't require an explicitly scheduled meeting. But we consider it important enough that we carve out the time to make it clear that it's a team norm.

dcreager··on Static analysis at GitHub
In short, yes, very much so! Tree-sitter is what we're using under the covers to parse all of the languages that we support. The ctags-like symbol extraction described in the paper comes straight from tree-sitter, too. [1]

[1] https://tree-sitter.github.io/tree-sitter/code-navigation-sy...

dcreager··on Static analysis at GitHub
Parsing is definitely a big part of it, and it's a fair point that for search-based Code Navigation, we don't have to do any real heavy lifting on the analysis side. That said, I think the article describes our non-functional requirements well (zero-config, incremental, language-agnostic). It's those non-functional requirements which are most important for the “at scale” part. I'd go so far as to suggest that any static analysis implementation that can't meet those requirements would be nigh impossible for us to roll out across the entire GitHub corpus.
dcreager··on Static analysis at GitHub
Note that this article describes our implementation of “search-based” or “ctags-like” Code Navigation, which definitely has the imprecision that you describe. We've also been working over the previous ~year on a framework called Stack Graphs [1,2,3], which lets us tackle “precise” Code Navigation while still having the zero-config and incremental aspects that are described in the paper.

The build-based approach that you describe is also used by the Language Server Protocol (LSP) ecosystem. You've summarized the tradeoffs quite well! I've described a bit more about why we decided against a build-based/LSP approach here [4]. One of the biggest deciding factors is that at our scale, incremental processing is an absolute necessity, not a nice-to-have.

[1] https://github.blog/2021-12-09-introducing-stack-graphs/

[2] https://dcreager.net/talks/2021-strange-loop/

[3] https://news.ycombinator.com/item?id=29500602

[4] https://news.ycombinator.com/item?id=29501824

dcreager··on How to write a linter using tree-sitter in an hour
Many folks have often (correctly!) pointed out that each language's existing parsing packages will be more guaranteed to keep up with language changes. Our hope is that if we can get a critical mass of useful tools that all use tree-sitter under the covers, there will _also_ be incentives to ensure that the tree-sitter parser for each language stays up-to-date. And because of how tree-sitter grammars typically live in dedicated repos, that work might be done by external volunteers, and not by the core language developers.

Another benefit to our approach is that it should be much easier to adapt OP's linter to work with other languages, since in a sense it's “parameterized” by the language grammar and queries. If you use Python's `ast` module, you can't easily adapt that code to work on Go programs, for instance.

dcreager··on How to write a linter using tree-sitter in an hour
The generated parsers are implemented in C, and so currently the only way to use them is via FFI. (Unless you're writing your analysis tool itself in C!)

The `tree-sitter generate` command also produces a full description of the grammar itself (typically written to src/grammar.json). In theory you could use this to generate each grammar implementation in other languages, as well. No one has tackled this yet, though, because in practice it has worked well enough to FFI in the C parser implementations.

Also, depending on what language you're trying to consume tree-sitter parsers in, we're trying to leverage the language's package ecosystem as much as we can to simplify this process. If you're using Rust, for instance, we publish crates for tree-sitter itself [1] and for various language grammars [2,3,4]. So you can often just add some dependencies to your Cargo.toml and the Rust build system takes care of everything for you. (Note that these crates also provide a more Rust-idiomatic API, instead of making you call the FFI'ed C functions directly.)

[1] https://crates.io/crates/tree-sitter

[2] https://crates.io/crates/tree-sitter-python

[3] https://crates.io/crates/tree-sitter-javascript

[4] https://crates.io/crates/tree-sitter-ruby

dcreager··on Improving GitHub Code Search
It's not quite what you're asking, but it you want to limit your searches to a particular repo, you can just type that into the URL bar (and then bookmark that): https://cs.github.com/$OWNER/$REPO, just like how the repo's primary site on GitHub is https://github.com/$OWNER/$REPO
dcreager··on Stack Graphs
Unfortunately not yet — we have working stack rules for Python, but they use an older internal version of the graph DSL. We’re actively working on porting it to the open source tree-sitter-graph DSL and adding it to the public tree-sitter-python grammar repo. But it’s not there yet.
dcreager··on Stack Graphs
Right now code nav on GitHub only works within a repository, and so every link you follow keeps you within the commit that you’re already viewing. As we move to cross-repo code nav, you’re right that it will be difficult to determine the right commit to take you to when following a cross-repo link.
← PreviousPage 2 of 4Next →