There was a hang/performance bug [1, 2] that was reported just after the beta release, which we've since fixed [3]. You might try seeing if we get through your entire project now?
(And as an aside, there _is_ a verbose mode: if you add `-vv` you'll get DEBUG-level log messages printing out the name of each file as we start to check it, and you can set TY_MAX_PARALLELISM=1 in your env to make it very clear which file is causing the hang. That's how we debug these kinds of issues when they're reported to us.)
Yes, we love TypeForm! We plan to support it as soon as the PEP for it lands. Under the covers, we already support much of what's needed, and use it for some of our special-cased functions like `ty_extensions.is_equivalent_to` [1,2]. TypeForm proper has been lower on the priority list mostly because we have a large enough backlog as it is, and that lets us wait to make sure there aren't any last-minute changes to the syntax.
Stepping away from Forth in particular, one of the benefits of a stack-based / concatenative language is that it's easy to implement on constrained hardware. uxn [1] is a great example of that.
And shameless self-promotion, if you're interested in how these kinds of languages compare with more traditional named-based languages, with more theoretical constructs like the lambda calculus and combinatory logic, and with gadgets like a PyBadge — well you're in luck! I gave a talk about exactly that at the final Strange Loop [2].
This is long winded, but maybe you have some thoughts here.
I've been building a DOM-builder API recently in Rust. The existing options (there are many) tend to use textual templating, which can't reason well about anything, or basic macros, which never support indentation. I wanted something that was just code, where I'd be in full control on the indentation (or lack thereof) programmatically. The closest equivalent is Python's Dominate [1], though its indentation mechanisms are buggy.
So I built a system using the traditional tree where Nodes own other Nodes at random addresses, and I built a renderer that renders those nodes and concatenates their strings recursively. It ended up working but it was hacky and very slow for the large inputs. In release mode, it was taking almost a minute to render 70 files, and I want about two orders of magnitude lower.
I ran it through profilers and optimized it a bit, but wanted to see if I could simplify the architecture and reduce the amount of work the computer could do. I read about flattening ASTs [2] and how through optimizing that format, you can end up with a sort of bytecode [3]. I also looked into Data-Oriented Design, watching Mike Acton's famous talk [4], Andrew Kelley's talk about DoD in Zig [5], and reading through the DoD book by Richard Fabian [6].
I ended up with something that works quite well for traversing and rendering, which is a stack that can be traversed and rendered in O(n), but I lost my nice Dominate-like API. As in, I can build these beautiful, flat trees, but to embed those trees in my code, I need to either materialize a tree in the traditional style first and then push it onto these stacks, or do some sort of macro magic to make these stack pushes.
I wonder if this is a common issue with stack-based programming. It is, in my case, quite simple for the computer, but hard to fit into an API without building up the stack manually!
pyx doesn't compete with PyPI; it's a private registry that companies can use e.g. to host internal-only packages, or to provide curated views of things like PyPI for compliance reasons.
> making changes which seemingly require their client (uv) be used
That's an explicit non-goal: "You won't need to use pyx to use uv, and you won't need to use uv to use pyx."
The Open Firmware bootloader also used a Forth as its command-line interface. That was used on PowerPC Macs before Apple switched over to Intel. (So, you know, two processor architectures ago.)
A common theme is that Forth-likes are very easy to implement on constrained hardware. I have a Strange Loop talk a couple of years ago where I go into this at the end, calling out uxn from the Hundred Rabbits folks. You might consider that more "hobbyist" than "production", but people are deriving real joy making apps and games in that ecosystem.
ty is definitely not ready to be a pyright replacement yet. But it is usable as an LSP for simple things like go to definition, and deeper LSP features are on the roadmap for the eventual beta and GA releases.
The current plan is that they will remain separate tools, but will work together nicely if you are using both. For instance, we want to add type-aware and multi-file lints to ruff at some point down the line.
> Gradual typing means that an implicit "any" (unknown type) anywhere in your code base is not an error or even a warning. Even in critical code you thought was fully typed. Where you mistakenly introduce a type bug and due to some syntax or inference limits the type checker unexpectedly loses the plot and tells you confidently "no problems in this file!"
This is a good point, and one that we are taking into account when developing ty.
The benefit of the gradual guarantee is that it makes the onboarding process less fraught when you want to start (gradually) adding types to an untyped codebase. No one wants a wall of false positive errors when you first start invoking your type checker.
The downside is exactly what you point out. For this, we want to leverage that ty is part of a suite of tools that we're developing. One goal in developing ty is to create the infrastructure that would let ruff support multi-file and type-aware linter rules. That's a bit hand-wavy atm, since we're still working out the details of how the two tools would work together.
So we do want to provide more opinionated feedback about your code — for instance, highlighting when implicit `Any`s show up in an otherwise fully type-annotated function. But we view that as being a linter rule, which will likely be handled by ruff.
This makes sense to me and is exactly what TypeScript does. Implicit `any`s do not raise TypeScript errors (which, by definition, is expected), but obviously that means if there is an `any`, it's potentially unsafe. To deal with this, you can turn on `noImplicitAny` or strict mode (which 99% of projects probably have enabled anyway).
Difference here that strict mode is a tsc option vs. having this kind of rule in the linter (ruff), but the end result is the same.
Anyway, that was a long winded way of saying that ty or ruff definitely needs its own version of a "strict" mode for type checking. :)
(And as an aside, there _is_ a verbose mode: if you add `-vv` you'll get DEBUG-level log messages printing out the name of each file as we start to check it, and you can set TY_MAX_PARALLELISM=1 in your env to make it very clear which file is causing the hang. That's how we debug these kinds of issues when they're reported to us.)
[1] https://github.com/astral-sh/ty/issues/1968
[2] https://github.com/astral-sh/ty/issues/1993
[3] https://github.com/astral-sh/ruff/pull/22030