Rendered at 23:40:38 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
pdpi 1 days ago [-]
> Vx is the right language for the thing that must be correct and fast across ten kinds of silicon. It is not the right language for the thing you are still figuring out.
A bit tangential, but I really *really* appreciate them making this distinction, and wish more people did this. Way too many tools try to advertise themselves as all things for all people, catering to all use cases, and that helps nobody.
jack_h 1 days ago [-]
I'm reminded of a number of critiques that have popped up over the years such as "C Is Not a Low-level Language: Your computer is not a fast PDP-11" and others I can't remember at the moment. In essence our "low level" languages are designed to run on an abstract machine that hasn't changed much since the 70s while the actual hardware it's meant to abstract over has become incredibly sophisticated. As a simple example consider how many programming languages have something simple like SIMD support without dropping into compiler intrinsics or relying on the optimizer.
I've actually created some experimental DSL embeddings around this idea before as I find it a fascinating area. Skimming through the Vx docs it seems like it is moving some of the abstract machine into the type system for greater flexibility.
kurthr 8 hours ago [-]
Many CPUs, and most since the PDP-11 were designed were designed around the languages (often C/C++) that they support (eg later x86). For example the introduction of AVX for SIMD with un-aligned memory and load-store cues for unrolling loops with pointers across memory boundaries without penalty. C++ of course also evolved.
It's important to note that there was a huge shift from RISC to CISC to speed decode and then to vectorization and virtualization. The former was driven at first to allow higher single threaded clock speeds, and then when that hit a power wall ~2004 to raise data throughput and allow multi-threading (which required code changes), and then multiple virtual machines.
dreamoffire 1 days ago [-]
“I’d like the best programming language! Look at what people like about Rust, Mojo and Zig and come up with specs for it!
Oh don’t forget we need to think of the future… Make sure we can run on GPUs.
Try not to sound too LLMy.
Don’t mess up.”
I wish you luck I guess
librasteve 15 hours ago [-]
I have come slowly to the view that LLMs are very good at this kind of thing and we can use them very productively. I’m tempted to say that this is optimal human+LLM collaboration.
dreamoffire 10 hours ago [-]
Are you not biased having created another PL in a similar fashion?
This is collaboration in the same fashion as a group project in school. One kid never shows up or does any work and expects to put their name on it.
It’s hard to take you all seriously when your first instinct is to pop open an llm to even name your project. I mean c’mon that’s the funnest part!
That story is buried in a long chat thread between me and Gemini.
librasteve 15 hours ago [-]
fwiw I recently tried this with ChatGPT. The result (https://bil-lang.org) came after I dumped the LLM as a name suggester. As a checker and idea source it was fine. The language name space is quite crowded!
Archit3ch 15 hours ago [-]
> One Language, Every Chip
Every chip? I bet it can't target analog chips, what with the pointer talk and all...
librasteve 15 hours ago [-]
TTL4?
yewenjie 1 days ago [-]
Why is it giving me Vlang vibe
IshKebab 1 days ago [-]
Ugh guys... The front page of your project is the most important thing there is. If you can't even be bothered to write it yourself then I don't have much hope for the rest of your project.
criemen 1 days ago [-]
It doesn't even make sense.
> On Apple's unified memory that transfer compiles to almost nothing. It is still written down, because data locality should be provable by reading the source rather than by profiling the binary.
How does profiling the binary play into this? Elsewhere the hypothesis is "it crashes", whereas profiling is about performance.
> Most languages treat the accelerator as infrastructure: you write math, and a large opaque runtime decides how to ship it. Vx treats it as semantics.
What does that mean? Vx doesn't treat the accelerator as infrastructure? Vx doesn't have a large opaque runtime? "You write math, Vx treats it as semantics". I don't understand that.
lmz 21 hours ago [-]
Can sort of make sense of the transfer and performance bit as: the location is encoded as part of the data type instead of some sort of automatic spillover to main memory that will behave differently based on data size.
Muromec 1 days ago [-]
Right, right? I see the llm smell seeping through the quotes shared here without even visiting
airstrike 1 days ago [-]
They could at least pick a less overused model so it doesn't feel this grating to read
NBJack 1 days ago [-]
And it doesn't seem to render correctly on mobile. I hit this myself trying to vibe up a side project; it looked slick, but it took multiple prompts (and at least an uploaded screenshot or two) just to make it mobile friendly.
1 days ago [-]
nvme0n1p1 1 days ago [-]
It's one of those links you don't even have to open to tell it's AI slop, you can tell from just the title.
ind-igo 18 hours ago [-]
I've seen a lot of hype around this language, but I still haven't found what's the main advantage over using mojo.
amelius 1 days ago [-]
> Vx is the right language for the thing that must be correct and fast across ten kinds of silicon. It is not the right language for the thing you are still figuring out.
Sounds like a great language for an AI to use then :)
Cyan488 1 days ago [-]
> Heterogeneity belongs in the type system, not in the runtime.
Is the intent that applications developed with this are compiled for target hardware on a machine-specific basis?
e.g. I define a machine file for my i5 and GTX3080, and another machine file for my gnarly datacenter rack, and the compiler compiles specifically for each?
That way the same source file is "provable" for different hardware configurations without relying on a runtime to be identicallu implemented?
adityazero 22 hours ago [-]
> Is the intent that applications developed with this are compiled for target hardware on a machine-specific basis?
Vx gives you the power to do so, but one can be conservative by putting all the values in the fleet/*.vx files to extreme values. An analogy to that would be when we compile for X86-64, we can specify `-mcpu` otherwise by default the compiler picks a conservative backend.
Vx allows one to define compute elements(number of cores, etc), memory elements (number of distinct memory elements, hierarchy if any) and their relationship (placement, ownership etc). Together they define the toplogoy of a machine. Toplogy goes into machine description files (see https://github.com/vx-lang/Vx/tree/main/fleet) and the compiler uses them to 'monomorphize' the program based on that topology.
teo_zero 17 hours ago [-]
> One Language, Every Chip [...] CPU, GPU, NPU [...]
Every chip? For example if I target an Intel Meteor Lake (I'm not picking a niche one), does it compile for this CPU, its integrated NPU and its Arc GPU?
heartlights 17 hours ago [-]
IIUC, anything supported by LLVM is fine. The language piggybacks on llvm mlir. So, you should be able to target that.
teo_zero 2 hours ago [-]
But Vx needs a "machine file" for each target hardware, and none is provided for Intel:
> The repository ships machine files for H100, H200, B200, A100, MI300X, Apple M4 and multi-GPU nodes
So it seems it won't work out of the box.
dev_dan_2 1 days ago [-]
Always nice seeing others arriving at similar conclusions! Those two jump out to me:
- "Most compilers hard-code a cost model. Vx reads one. A machine file describes the memory hierarchy and interconnect of a real part, and the compiler admits or rejects placements against it." I also designed it so that the target system is described by a single file that is picked up by the static analysis - cool!
- "Where data lives is part of its type" also doing that - when I got my project to an mvp state; I need to check out how vxlang does what it does: do they use a literal typesystem, or also compile checks outside of that? If its a type system, is it a dependent type system, or another flavor?
Yet another motivation to finally get my side project starting (forth-adjacent, many similar claims with regards to compile-time checks as vxlang; however, I still have to achieve that, while they already seem to have at least those and more in place; kudos to the vxlang team!)
api 1 days ago [-]
Why does this need a new language? Aren't there existing languages where these concepts can be expressed?
librasteve 15 hours ago [-]
even when the underlying language is widely used (in this case, Rust) I think there is a case to coin a new language when (i) there is a bunch of new stuff, (ii) it ain’t gonna be adopted wholesale by the core team and (iii) it has a coherent toolchain and (iv) it makes promises to coders that are stable over time. Disclosure, I am the author of https://bil-lang.org that pulls the same trick as an extension / transpiler targeting golang
paufernandez 1 days ago [-]
Yeah, Mojo.
imtringued 16 hours ago [-]
This language is basically a superset of Rust with a bunch of changes that could perhaps be added in the future.
I think the compiler was written from scratch though.
classified 1 days ago [-]
[dead]
AnimalMuppet 1 days ago [-]
I haven't played with it at all, but the writeup looks promising. Moving a bunch of things into the type system and out of runtime crashes is one of the ways we make progress.
dnautics 1 days ago [-]
I think this is wrong. Type systems should be simpler, and you should design it so that your language is easily and correctly statically checked. Not all invariants necessarily have to be verified at the same cadence (compile time)
treyd 1 days ago [-]
> you should design it so that your language is easily and correctly statically checked.
You do that by making the type system more sophisticated.
If you have a really important invariant that you really don't want to be violated due to run-time behavior/input, it's a huge benefit to have a compiler that can statically check that it actually can't be. That's one of the main benefits of having type systems, not just describing the shape of data structures in memory.
dnautics 1 days ago [-]
You can perform static analysis outside of the compiler without putting things in the type system?
C is a bad language to do this with for various reasons, but as a simple example:
char* buf = malloc(SIZE);
free(buf);
free(buf);
There is absolutely no reason why static analysis should not be able to see what the problem is here.
kfsone 1 days ago [-]
Sure, but what it is that makes you believe the compiler shouldn't be the one doing that analysis? Should it catch
It's been my experience people invested in static analysis think of it like some wholly additive extension.
Compiler-independent static analysis is code applying rules. Someone has to write all the rules, align them with the language and the compiler. The user rarely reads the static analyzer's code or full rule definitions and is blissfully unaware of the full set of disconnects, inconsistences, and gaps between the coverage of the two.
They only notice divergence in the analysis when it generates a false-positive warning or error.
Static analysis adds compilation overhead. Sure, but I'd hazard that re-reading and in to some degree repeating the parsing/translation process that the compiler is going to do also introduces overhead.
There are some languages that demonstrate sta-by-compiler capabilities with heinous compile times, but it doesn't have to be that way. We can engineer better, but at some point it requires a price. Better comments, boilerplate of some kind or another, annotating intent over idiom.
A complex type system isn't ideal; with the right set of primitives you can achieve sophistication without complexity.
```
Freeable buf = malloc(SIZE);
free(buf); // compiler error, you didn't check buf isn't valid.
free(buf); // compiler error still if you fixed the above, free makes buf invalid.
```
"Making the compiler do STA makes it slow". I don't think that's proven one way or the other. There are examples both ways. "complex" type systems frequently have slow compilers, but if you look more closely that's usually because they're trying to compensate for the disconnect between organically emerged complexity in their under-designed type systems.
dnautics 19 hours ago [-]
If it's so great, why does rust not put everything in MIRI into the compiler?
steveklabnik 19 hours ago [-]
Miri is a runtime thing so it can’t be in the compiler.
The compiler could interpret all unsafe via it but then it would be very slow, defeating the point.
dnautics 5 hours ago [-]
"can’t be in the compiler"
Can't is a strong word. You could 100% put it in the compiler. Yet you don't (for the reasonable reasons you give). The line between compiler static analysis and non-compiler static analysis is a design decision. "defeating the point" is a subjective and pragmatic decision, not one rooted in safety absolutism.
0xdeafbeef 1 days ago [-]
uintptr_t x = opaque((uintptr_t)p);
free((void *)x);
free(p);
How will you find such violations if opaque comes from so or some ffi, so compiler can't see through?
you can't. It's heuristics. Sound type system is much stronger
dnautics 19 hours ago [-]
*ffi
Christ. Even rust makes ffi unsafe.
I mean you can annotate it if you want. Just tell the analyzer in a separate file, get the variable at this line on this file has these guarantees.
You could even annotate dependencies that didn't use your static analyzer. You could track custom invariants that your language designer didn't put in the type system.
treyd 19 hours ago [-]
> Even rust makes ffi unsafe.
Which is why every library that wraps C APIs provides safe wrappers that express the implicit expectations within Rust's type system. Yes the low-level calls are unsafe, of course they are, but then we expose them with a safe interface that consumers actually use.
binary132 1 days ago [-]
typesystems can be considered a kind of static analysis
imtringued 16 hours ago [-]
ok but what if you call
buf_create(SIZE)
and
buf_destroy(buf)
now the compiler has to infer that buf_create creates a lifetime and buf_destroy destroys it.
we're back to Rust's Box.
dnautics 3 hours ago [-]
Congratulations, you have hit upon one of the reasons why c is a bad choice. Other languages make this easier.
AnimalMuppet 1 days ago [-]
But what does static analysis work on? The source code. If it's not in the source code, the static analyzer can't check it. So if you want to check something, even with a static analyzer, then you need some way to talk about that thing in the source code, which means it has to be part of the source language.
Now, sure, you could have some kind of annotations in the comments or something, and a static analyzer that checked those, and you could get that to check pretty much anything that can be checked statically. But at that point, it's not really part of the language, is it?
dnautics 19 hours ago [-]
No. Work on the IR.
classified 1 days ago [-]
So you prefer runtime crashes to compiler diagnostics, just so the type system can be "simpler"? I find these priorities backwards.
dnautics 1 days ago [-]
> So you prefer runtime crashes
Do you not understand what static analysis is?
AnimalMuppet 1 days ago [-]
We understand that static analysis is often less bulletproof than a compiler's type system. It doesn't always catch everything. If it does, it often says "may", and then you have to sort out the false positives from the real problems, and there can be a lot of them.
And if you don't take every problem seriously, and do a full investigation, then you are risking a real problem that you don't fix, which can turn into... a runtime crash.
dnautics 19 hours ago [-]
You are describing static analysis as it has been done. Nothing stopping you from doing sa that rejects as strictly as rust for example does.
A bit tangential, but I really *really* appreciate them making this distinction, and wish more people did this. Way too many tools try to advertise themselves as all things for all people, catering to all use cases, and that helps nobody.
I've actually created some experimental DSL embeddings around this idea before as I find it a fascinating area. Skimming through the Vx docs it seems like it is moving some of the abstract machine into the type system for greater flexibility.
It's important to note that there was a huge shift from RISC to CISC to speed decode and then to vectorization and virtualization. The former was driven at first to allow higher single threaded clock speeds, and then when that hit a power wall ~2004 to raise data throughput and allow multi-threading (which required code changes), and then multiple virtual machines.
Oh don’t forget we need to think of the future… Make sure we can run on GPUs.
Try not to sound too LLMy.
Don’t mess up.”
I wish you luck I guess
This is collaboration in the same fashion as a group project in school. One kid never shows up or does any work and expects to put their name on it.
It’s hard to take you all seriously when your first instinct is to pop open an llm to even name your project. I mean c’mon that’s the funnest part!
Every chip? I bet it can't target analog chips, what with the pointer talk and all...
> On Apple's unified memory that transfer compiles to almost nothing. It is still written down, because data locality should be provable by reading the source rather than by profiling the binary.
How does profiling the binary play into this? Elsewhere the hypothesis is "it crashes", whereas profiling is about performance.
> Most languages treat the accelerator as infrastructure: you write math, and a large opaque runtime decides how to ship it. Vx treats it as semantics.
What does that mean? Vx doesn't treat the accelerator as infrastructure? Vx doesn't have a large opaque runtime? "You write math, Vx treats it as semantics". I don't understand that.
Sounds like a great language for an AI to use then :)
Is the intent that applications developed with this are compiled for target hardware on a machine-specific basis?
e.g. I define a machine file for my i5 and GTX3080, and another machine file for my gnarly datacenter rack, and the compiler compiles specifically for each?
That way the same source file is "provable" for different hardware configurations without relying on a runtime to be identicallu implemented?
Vx gives you the power to do so, but one can be conservative by putting all the values in the fleet/*.vx files to extreme values. An analogy to that would be when we compile for X86-64, we can specify `-mcpu` otherwise by default the compiler picks a conservative backend.
Vx allows one to define compute elements(number of cores, etc), memory elements (number of distinct memory elements, hierarchy if any) and their relationship (placement, ownership etc). Together they define the toplogoy of a machine. Toplogy goes into machine description files (see https://github.com/vx-lang/Vx/tree/main/fleet) and the compiler uses them to 'monomorphize' the program based on that topology.
Every chip? For example if I target an Intel Meteor Lake (I'm not picking a niche one), does it compile for this CPU, its integrated NPU and its Arc GPU?
> The repository ships machine files for H100, H200, B200, A100, MI300X, Apple M4 and multi-GPU nodes
So it seems it won't work out of the box.
- "Most compilers hard-code a cost model. Vx reads one. A machine file describes the memory hierarchy and interconnect of a real part, and the compiler admits or rejects placements against it." I also designed it so that the target system is described by a single file that is picked up by the static analysis - cool!
- "Where data lives is part of its type" also doing that - when I got my project to an mvp state; I need to check out how vxlang does what it does: do they use a literal typesystem, or also compile checks outside of that? If its a type system, is it a dependent type system, or another flavor?
Yet another motivation to finally get my side project starting (forth-adjacent, many similar claims with regards to compile-time checks as vxlang; however, I still have to achieve that, while they already seem to have at least those and more in place; kudos to the vxlang team!)
I think the compiler was written from scratch though.
You do that by making the type system more sophisticated.
If you have a really important invariant that you really don't want to be violated due to run-time behavior/input, it's a huge benefit to have a compiler that can statically check that it actually can't be. That's one of the main benefits of having type systems, not just describing the shape of data structures in memory.
C is a bad language to do this with for various reasons, but as a simple example:
There is absolutely no reason why static analysis should not be able to see what the problem is here.``` ((void()(void) free)(buf); ((void()(void) free)(buf); ```
It's been my experience people invested in static analysis think of it like some wholly additive extension.
Compiler-independent static analysis is code applying rules. Someone has to write all the rules, align them with the language and the compiler. The user rarely reads the static analyzer's code or full rule definitions and is blissfully unaware of the full set of disconnects, inconsistences, and gaps between the coverage of the two.
They only notice divergence in the analysis when it generates a false-positive warning or error.
Static analysis adds compilation overhead. Sure, but I'd hazard that re-reading and in to some degree repeating the parsing/translation process that the compiler is going to do also introduces overhead.
There are some languages that demonstrate sta-by-compiler capabilities with heinous compile times, but it doesn't have to be that way. We can engineer better, but at some point it requires a price. Better comments, boilerplate of some kind or another, annotating intent over idiom.
A complex type system isn't ideal; with the right set of primitives you can achieve sophistication without complexity.
``` Freeable buf = malloc(SIZE); free(buf); // compiler error, you didn't check buf isn't valid. free(buf); // compiler error still if you fixed the above, free makes buf invalid. ```
"Making the compiler do STA makes it slow". I don't think that's proven one way or the other. There are examples both ways. "complex" type systems frequently have slow compilers, but if you look more closely that's usually because they're trying to compensate for the disconnect between organically emerged complexity in their under-designed type systems.
The compiler could interpret all unsafe via it but then it would be very slow, defeating the point.
Can't is a strong word. You could 100% put it in the compiler. Yet you don't (for the reasonable reasons you give). The line between compiler static analysis and non-compiler static analysis is a design decision. "defeating the point" is a subjective and pragmatic decision, not one rooted in safety absolutism.
How will you find such violations if opaque comes from so or some ffi, so compiler can't see through? you can't. It's heuristics. Sound type system is much stronger
Christ. Even rust makes ffi unsafe.
I mean you can annotate it if you want. Just tell the analyzer in a separate file, get the variable at this line on this file has these guarantees.
You could even annotate dependencies that didn't use your static analyzer. You could track custom invariants that your language designer didn't put in the type system.
Which is why every library that wraps C APIs provides safe wrappers that express the implicit expectations within Rust's type system. Yes the low-level calls are unsafe, of course they are, but then we expose them with a safe interface that consumers actually use.
buf_create(SIZE)
and
buf_destroy(buf)
now the compiler has to infer that buf_create creates a lifetime and buf_destroy destroys it.
we're back to Rust's Box.
Now, sure, you could have some kind of annotations in the comments or something, and a static analyzer that checked those, and you could get that to check pretty much anything that can be checked statically. But at that point, it's not really part of the language, is it?
Do you not understand what static analysis is?
And if you don't take every problem seriously, and do a full investigation, then you are risking a real problem that you don't fix, which can turn into... a runtime crash.
https://en.wikipedia.org/wiki/Transmeta