E

Evan Ovadia

verdagon.dev · Personal blog · on HN since 2022

Evan Ovadia, creator of the Vale language, writes about memory safety, generational references, regions, and language design.

What HN saysCommenters follow Vale closely and are interested in its approach to memory safety, with predictable latency and easier iteration than borrow checking.
60HN people shared it
29linked it in comments
54stories submitted
1.4Kstory points
4 months agolast shared
2022people per year2026

Most-shared posts

  1. 1
  2. 2
    Vale's Hybrid-Generational Memory
    6 people · 1 points · first shared 2022 · discussion on HN
  3. 3
  4. 4
  5. 5
  6. 6
    Zero-Cost Memory Safety with Vale Regions (Preview)
    4 people · 4 points · first shared 2022 · discussion on HN
  7. 7
    Chasing the Myth of Zero-Overhead Memory Safety
    4 people · 3 points · first shared 2023 · discussion on HN
  8. 8
  9. 9
    Accidentally making a language, for an engine, for a game
    3 people · 356 points · first shared 2022 · 221 comments on HN
  10. 10
    On removing let and let mut
    3 people · 33 points · first shared 2022 · 20 comments on HN
  11. 11
    Vale's First Prototype for Immutable Region Borrowing
    3 people · 30 points · first shared 2023 · 1 comments on HN
  12. 12
  13. 13
  14. 14
  15. 15
    Higher RAII and the seven arcane uses of linear types
    2 people · 109 points · first shared 2024 · 46 comments on HN

What HN people wrote when they linked it

verdagon · 2025-08-28
Big fan of Verona, I love their memory safety approach as well. I wrote a bit about it in the Grimoire [0] too. IIRC they plan for the user to specify whether a region is backed by an arena allocator or GC, which sounds pretty nice. It's kind of hard to track down details though, most of my knowledge comes from reading David Chisnall's comments on lobste.rs. [0] https://verdagon.dev/grimoire/grimoire
pxeger1 · 2024-03-06
I think there isn't enough research into languages with affine/linear typing (the property of some types that they can't be copied - which is partly what the borrow checker ensures in Rust). I'm super sold on it for enhancing safety. Vale with its "Higher RAII"[0] is the only other example I was aware of until seeing this. Rust is great but being an early adopter has made its usability imperfect in places. Combining substructural typing with gradual typing and OOP is interesting here. Others in this thread have also mentioned wanting a higher-level Rust, like Go. I'd like to see a purely functional Rust. Haskell has experimental support for linear typing[1], but I suspect a language built with it from the ground up would be very different. [0]: https://verdagon.dev/blog/higher-raii-7drl [1]: https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/linear_types.h…
hu3 · 2023-07-12
...more predictable latency than tracing garbage collection. ...better performance and cache friendliness than reference counting. ...prototype and iterate more easily than with borrow checking. Ok, you had my curiosity, but now you have my attention. Just started following your RSS feed: https://verdagon.dev/rss.xml
rom-antics · 2023-03-09
> I've been wondering lately whether a new spatial approach can yet again simplify matters. I've been closely following the development of Vale since I first saw it here. Though their approach is slightly higher-level than Rust and requires (some) runtime safety checks (though to be fair, so does GC). https://vale.dev/ https://verdagon.dev/blog/zero-cost-memory-safety-regions-overview I think it would be tough to change the spatial model in a language as low-level as Rust, because that spatial model is just reflecting how your CPU actually works under the hood. If you try to hide that away, the programmer is going to end up losing some control.
kitd · 2022-06-18
Interesting to read about variable mutability here: https://verdagon.dev/blog/on-removing-let-let-mut Originally there was let and let mut like Rust. But that was changed to simple assignments, followed by the compiler checking for subsequent reassignment with set. While I can see that might make for cleaner code while still allowing the compiler to get on with its job, surely one of the benefits of explicitly immutability is to stop the coder accidentally letting off foot guns. If simply setting a variable after declaration makes it mutable, it feels like it could open the door to data in a code block being allowed to change behind the scenes when the assumption in that block is that it is fixed. I'd be interested to know how this works in every day practice and possible unintended effects.
samsquire · 2023-02-06
Thank you for this. If you found this interesting then you shall like the following pages: The Vale language blog post on seamless structured concurrency https://verdagon.dev/blog/seamless-fearless-structured-concurrency The rust book on concurrency https://doc.rust-lang.org/book/ch16-00-concurrency.html I've been working on implementing Java async/await state machine with switch statements and a scheduling loop. If the user doesn't await the async task handle, then the task's returnvalue is never handled. This is similar to the Go problem with the go statement. https://github.com/samsquire/multiversion-concurrency-control/blob/mai… If your async call returns a handle and the handle is linked to a scope then in theory the async/await could be used as primitive to structured concurrency. I journal about asynchrony and parallelism everyday in ideas4 (see my HN profile)
cyber_kinetist · 2023-01-17
Throwing exceptions might not be acceptable in your use-case, with many codebases disabling it for concerns of performance or executable bloat. And factory functions cannot really help the initialization problem anyway, since your field is still in an uninitialized state before calling the factory function. And also, returning std::optional or std::expected can sometimes lead to slower code (copy constructor being called) because of NRVO not working when the compiler “feels like it”. So an init() method/function that returns an error code is the best you can get. I think the best way to really solve the invalid object problem in C++, is to always put sensible default values inside your struct/class definitions, so your code will at least fail without UB (in addition to using asserts liberally to check for index overflow problems, especially in your own containers even in. Release mode.) Zero-initialization is good for most cases, but sometimes you might need to default-initialize your indices to -1. weak_ptr is really slow, because of the lock instruction generated for each lock(). Once you use them all over the place to fix reference cycles, the overhead of using these becomes hard to ignore. Generational indices/references remove all the ref-counting and gives programmers the semantics of weak_ptr without the performance cost (see https://verdagon.dev/blog/generational-references, the details are mostly language-agnostic).
bmacho · 2025-07-18
Verdagon has this linear types/higher-RAII article: https://verdagon.dev/blog/higher-raii-7drl It is about types that can't be copied and can't go out of scope, and the only way to destroy them is to call one of their destructors. This is compile time checkable. In theory they can solve a lot of problems easily, mainly resource management. Also it generalizes C++'s RAII, and similar to Rust's ownership. In practice they haven't got support in any mainstream programming language yet.
alexisread · 2024-06-15
This looks the same as in Vale? I like this technique, and Vale tries to go further with index elision to remove the memory and checking overhead. https://verdagon.dev/grimoire/grimoire
jitl · 2024-01-23
I'm not a language author, so I'm not getting any lightbulbs about why its nice to build regions into the VM rather than the compiler. I see the appeal of the region thing which reminds me of Vale (https://verdagon.dev/blog/zero-cost-borrowing-regions-overview). I didn't really get the exceptions thing. What's some stuff you'd like to see in a higher level language that would fit the design nicely? Are those things really hard to implement on top of WebAssembly?
dash2 · 2023-10-25
Another relevant language might be Vale (https://vale.dev), which is aiming for "perfect replayability": https://verdagon.dev/blog/perfect-replayability-prototyped
n2d4 · 2023-07-29
The GIL does very little to protect unexperienced users. It's still really easy to run into race conditions, for example, if your thread gets scheduled out in any multi-instruction operation (this is more common than you think [1]). In general, Python code still has to be thread-safe; you get the risks without the benefits. If you don't care about CPU performance, instead of threads you should go for an event-loop approach (see asyncio in Python). As soon as you have threads (on a language-level, not implementation-level), there is some notion of implicit switching, and you run into issues. So, the language you're looking for is JavaScript, which is single-threaded and every context switch is explicit (in form of `await` or `yield`). [1] https://verdagon.dev/blog/python-data-races
satvikpendem · 2023-07-17
Have you seen Vale? They're working on a new type of analyzer for memory errors, that apparently is simply and safer than Rust's [0]. [0] https://verdagon.dev/blog/first-regions-prototype
JonChesterfield · 2023-07-12
Generational references leak if a counter reaches int_max and involve an increment on alloc and on free. Seems pretty close to reference counting to me. https://verdagon.dev/blog/generational-references Statically eliminating memory operations does seem to be a win though.
LLyaudet · 2023-06-29
Yep not even a random display in JS. I looked at the source code of the webpage. There is nothing curious. Custom JS is here: https://verdagon.dev/components/annotated.js and does only trivial things. Not a real easter egg for the client part. Maybe the easter egg is in server part that sends the HTML with or without it depending on hour or something. No need to waste more time on it, there is no funny code behind :)
pizza234 · 2023-01-03
> So my understanding is that both Rust and Val are providing the same guarantee to the program (exactly one writer or any number of readers to values) but choose to do it in very different ways. The interesting thing from the PL design side is that both implementations leak into the semantics of the language (Rust through explicit lifetime annotation, Val through implicit references) Interesting. Can't Val references (based on my reading of https://verdagon.dev/blog/generational-references) be implemented in Rust as smart pointers? It seems that the requirement from the language is ownership (to detect when the reference needs to be freed), besides the error handling.
unsignednoop · 2022-08-24
I really like how the side notes and references line up on the right. https://verdagon.dev/blog/hybrid-generational-memory
azakai · 2022-06-18
The key mechanism for memory safety, generational references, is described here: https://verdagon.dev/blog/generational-references IIUC it's basically a form of memory tagging in userspace, but designed to be safe (64 bits, very low risk of collision) and fast (language is designed to avoid tagging whenever possible: owning refs don't need them; inline objects reuse the gen of the parent; static analysis). I buy that this can be almost as safe as reference counting or GC, and as easy to use, but faster. But not sure I understand how inline objects work, and how effective static analysis will be is important. Comparisons to other languages (C++/Rust/JS) are here: https://vale.dev/comparisons
e4m2 · 2022-06-18
Vale compares its safety to Rust's on a few occasions[0][1] and the exact opposite claim is made, i.e. Vale is safer than Rust. [0] https://verdagon.dev/blog/hybrid-generational-memory#afterword-how-mig… [1] https://vale.dev/comparisons#safe
ashish_negi_ · 2022-06-18
@verdagon Can you please explain https://verdagon.dev/blog/generational-references comment that: "programs dereference less than they alias and dealias" ? Does deference means accessing a field of object ? Does alias/dealias mean creating/destroying another variable reference ? If answer of above is true, isn't programs deference more than alias/dealias ? i mean, in: var alias = shared_ptr_of_some_object; for (int i = 0; i < 1000; ++i) { alias.foo += bar_fn(alias.baz) } is just creating 1 alias but defrences 1k times and above looks like very typical code.
riffraff · 2022-06-18
For anyone that was confused like me, this is unrelated to the Vala programming language [0] which is a more traditional OO based on GLib. E vs A. Looks very interesting, and the blog has very nice writeups, I found the article on mutable/constant variables syntax[1] particularly clever. Tho I'm unconvinced of the final decision it's certainly a breath of fresh air. [0] https://en.m.wikipedia.org/wiki/Vala_(programming_language) [1] https://verdagon.dev/blog/on-removing-let-let-mut
EdwardDiego · 2022-04-05
Is this blog entry out of date? Or is this still a WIP? > Note that hybrid-generational-memory is not implemented yet, it's still just a design. From https://verdagon.dev/blog/hybrid-generational-memory
mijoharas · 2022-04-05
fyi, your links on that page to hybrid generational memory seem incorrect (i.e. 7 in the sidebar, but I think there was another). I'd not heard of vale, but after reading around a little looks very interesting. Nice job! [0] https://verdagon.dev/blog/hybrid-generational-memory
vaughan · 2023-06-25
Something that gives me hope is that I haven't seen anyone prioritize debuggability in a modern programming language or even a framework. Vale is maybe the first getting close: https://verdagon.dev/blog/perfect-replayability-prototyped. I think there is a new era yet to come. > probably too complex to visualize in a usable way You can always abstract the complexity. A simplification of the control flow graph at the function level. As an example, I want to understand the Postgres codebase better...there are a lot of very visualizable things going on there. If you look at lecture slides on relational DBMS, there are lots of diagrams...so why can't be view those animating diagrams as the code executes. I was thinking of instrumenting the code to get a trace of every function call and its arguments, and then filter that and visualize it. The key to this approach working though is a think ultimately we need to write our code and organize our code such that it can be easily visualizable. The purpose of code is for humans to understand it, otherwise we are writing assembly.
comex · 2023-01-17
> In an average Google Earth quarter, only 3-5% of bug reports were traceable to memory safety problems, and Address Sanitizer made them trivial to reproduce in development mode. Bug reports, sure. But as for security vulnerabilities, both Microsoft and Google have reported that roughly 70% of them were memory safety issues. Personally, as a Rust fan, I fully agree that the borrow checker limits developer velocity, and I'd be happy to toss it if I could. But verdagon has been promising memory safety with no overhead for years; I'll believe it when I see it. Edit: Okay, that was unfair to say without further context, so let me add two things. First, although Vale is open source, the design has changed over time and the implementation was described as a "work-in-progress" as of two months ago. [1] Second, a month before that, verdagon described the design as providing "statistical safety", meaning use-after-frees may fail to be caught but are caught "99.9999999999996% of the time". Now, stochastic exploit mitigations such as ASLR and PAC are valid defenses, as long as that 99...% also applies in the presence of an active attacker. But the specific design described (allowing generation counters to wrap) sounds like, in many scenarios, an attacker could manipulate it to provide no protection at all. There may be ways to mitigate this, but in context it does sound like it's designed under the assumption that memory safety violations will occur at random, rather than…
modernerd · 2022-12-08
Language-level guarantees of memory safety are not critical to all low-level programmers, and sometimes this is fine! Developers of games, compilers, digital audio workstations, video editors, and live performance software (such as openFrameworks) likely don't rank memory safety as their top concern. Zig is already an attractive choice for those domains because it offers: - Great compile times compared to C++/Rust, and future plans to implement hot reloading as a core part of the tooling: https://www.jakubkonka.com/2022/03/16/hcs-zig.html - The ability to reason about where data exists in memory: https://ziglang.org/documentation/master/#Where-are-the-bytes - Good readability and learnability, especially if you have a C/C++ background. - Comptime that enables clean generics, compile-time reflection and general metaprogramming as a happy side-effect: https://kristoff.it/blog/what-is-zig-comptime/ - Better tooling than C/C++. The ability to cross-compile Zig and C/C++ from one machine lets you set up much more stable and reproducible build environments already. You can clone zig-gamedev and have the demos working with just three commands on Windows/macOS/Linux, for example, and two of those three are cloning the repo and changing to the directory: https://github.com/michal-z/zig-gamedev (to build the examples you will need the latest copy of Zig from the 'master' section for your platform at https://ziglang.org/download/ ) We should all be careful about insinuating…
nyanpasu64 · 2022-04-25
Not staticassertion, but I'm a hobbyist in real-time audio. I like Rust as a vocabulary for describing/teaching safe programming (&/&mut/Send/Sync). I find that multithreaded programs written in Rust are usually correct while multithreaded programs written in C++ are usually wrong, because Rust encodes the rules of shared-memory threading in its type system (&T: Sync objects are thread-shared, but are either immutable or atomic or requires locking to acquire a &mut T). I also appreciate guiding users towards exclusive references (&mut) to make it easier to reason about code. However I find it makes it too difficult to mutate through shared references or write unsafe code (passing Stacked Borrows while lending out &mut is more like solving puzzles than writing imperative code, and writing code that never touches & and &mut is a quagmire of addr_of_mut!() and unsafe blocks on every pointer dereference), and the Rust community appears uninterested in making unsafe programming more ergonomic. Personally I'm a fan of C++'s unique_ptr/& as an unsafe escape hatch from Rust's single ownership or runtime refcounting overhead. It's at least as safe as Rust's unsafe pointers, and far more pleasant to use. Qt's QObject ownership system is reasonably ergonomic and QPointer is fun (though dangerous since it can turn into null unexpectedly), but Qt uses it pervasively (rather than only when safe memory management fails), relies on prose documentation to describe which pointers transfer…
sargstuff · 2022-04-06
Warning: Bit of a 'Hitch hikers guide to the galaxy"/conway game of life yak shave for a reply. Nice start to providing a simple way to visually interact/experiment/manipulate different multiple Neural network concepts by loading/transforming any traditional code (working or not) & reshuffling/tesselating the structual representation of the code to generate a turing tape path via color execution paths. Switching to pi calculus could provide the theory to support coroutine/coprossing/ threading" multiple interacting tape paths/color combinations/path diffs/scaled recusion to perform assembly language instructions. Raster graphics without the yak ( https://verdagon.dev/blog/yak-shave-language-engine-game ) Feed back between tape & "traditional code" as neural network layer(s)! Flexiable code (via tessilations) without changing the actual imported source code! So, complete svg (tape interactions) web page as code source on how to interact with web page, ( https://www.youtube.com/watch?v=r6sGWTCMz2k ) what's displayed/played, documentation & usage manual included within code structure! Unicode permits implied piping rich kern font without all the tech fluff. Unicode fails because allows infinate multics and is there for k&r incomplete. But, this approach is way more dimensional/colorful than unicode/tech stuff. ?? can one's code unintentially provide a wordle problem & solution in one package ?? (https://www.youtube.com/watch?v=v68zYyaEmEA ) ?? turing complete fourier…

Keyboard shortcuts

/Search
j kNext / previous blog
EnterOpen selected blog
vVisit the blog site
fFollow / unfollow
lSwitch grid / list view
dSwitch dark mode
g hHome
g pTop posts
g tTopics
g fFollowing
g lLiked
g yHistory
g qFAQ
EscBack / close