Astmaker – A DSL in Rust for programming language designers
david-delassus.medium.com
david-delassus.medium.com
I reckon other languages could replicate this combination, it’s not very hard. Dart added this feature recently. I just don’t know why it’s taken so long for tagged unions + exhaustive match to become widely adopted.
I need to come up with a haskell "new project" template thing
Thx for expositing my remark :)
But for a high performance compiler, manually managed arena allocation will beat out a generational GC.
Not only the type system is quite nice, the ecosystem is full of nice crates:
- lexing: logos
- parsers: rust-peg / lalrpop / nom
- utilities: string-interner / linecol / snailquote
I also wrote about this here: https://david-delassus.medium.com/writing-a-simple-lisp-inte... (friend link, no paywall)Though personally I think writing LISP interpreters with parser libraries should be considered sacrilege
Agreed, though the point of the article was to explore the Rust ecosystem. When learning, a little bit of blasphemy isn't a bad thing :)
Also, I find the whole visitor pattern abstraction a little pointless in Rust. I can't help but feel that applying a visitor pattern is taking an idiosyncrasy of object oriented programming and forcing it into Rust. Basically abstraction for abstraction's sake. I'd much rather write a bunch of `visit_expr`, `visit_stmt` (really `type_check_expr`, `type_check_stmt`) functions that pattern match on the data. It's much more searchable, and condenses the information at the pass level and not the data structure level. I care much more about having all of my type checking methods in one place, than I care about having all of the transformations of `Expr` in one place. I suppose if you're doing a lot of passes over the same representation and you need to schedule them in an efficient way, a visitor pattern could work. But how often are you doing that? Maybe if you're writing an optimizer but more often than not I'm doing a transformation pass from one IR to another.
With that said I can sympathize with ASTs being a lot of boilerplate. It took a lot of typing to thread location data through my AST.
Though, I should try to use `quote_spanned!` instead of `quote!`, but I'm kind of a newbie with proc-macros.
As for your take on the visitor pattern. In my previous code, I had the `visit_expr`, `visit_stmt`, etc... And it's a lot of boilerplate, I wanted to reduce the amount of copy/paste and facilitate refactoring, hence my DSL.
I do have multiple phases during compilation where I walk the AST and the "only" difference is the return value of those `visit_*` functions and their body. Here, I just have to use a `model!{}` macro for each "phase", which is less boilerplate code.
In the end, it's just static dispatch through the use of a trait that I called "Visitable".
Rather than
pub node Expression =
| BinOp -> Node<BinaryOperation>
| UnOp -> Node<UnaryOperation>
| Num -> Node<Number>
;
pub node BinaryOperation = {
lhs: Node<Expression>,
op: BinOp,
rhs: Node<Expression>,
}
write pub enum Expression {
BinOp(Node<BinaryOperation>),
Node(Node<UnaryOperation>),
Num(Node<Number>),
}
pub struct BinaryOperation {
lhs: Node<Expression>,
op: BinOp,
rhs: Node<Expression>,
}
[0]: https://rust-lang.github.io/api-guidelines/macros.html#input...courtesy of a Show HN project from a while ago
I'll keep publishing on Medium though :)
I use Medium because I can monetize easily the articles I write, though it's not much (currently around 10-15$/month).
I'm not doing it for the money, but it's still nice.
But if you try to invent your own language (like Tolkien did), you are not "expressing an idea" (aka: speaking), you are creating a framework to express ideas.
When you write a program, you follow a grammar to express an idea (the solution to the problem you are tackling). When you design a programming language, you are creating that grammar (using another language to implement it afterwards).
Also, here "programming language designers" designates "people who are working on their own programming language". Those are the people I'm talking to when writing this Rust crate and blog article. The webdev doing CRUD microservices could not care less about astmaker.
Though, this is fine by me. I don't mind people bypassing the paywall, but it's a source of (rather small) income for me :)
"My blog but secret" is a very, very strange promotion strategy IMHO
For "member-only" articles, you get a remuneration proportional to the "member reading time". For members who subscribed via your "onboarding" page (I don't have one I think, I don't know, I should look into it), you get a remuneration proportional to their reading time on any articles, not just yours.
The friend-tag on an article's link removes the paywall, allowing you to increase views when sharing the article. The more views your article has, the more Medium will promote it. But many platforms removes it as it may have trackers associated to it (I haven't looked into that to confirm or infirm).
EDIT: Fun fact, the Javascript subreddit even forbids medium links because they consider the content to be spammy 99% of the time.
For Medium, they want to incite people to buy a subscription, hence the paywall. But they also want writers to generate the content for them, hence the friend-link and remuneration model.
The remuneration is quite small, so I don't think they are loosing money. But short clickbaity articles about how console.log works can generate a LOT of views, and writers spamming those can earn up to 300$/month (or maybe more), hence the bad reputation of Medium. I'm not interested in doing that, I mainly write to share about my work and just enjoy the small remuneration as a reward for my open-source work: it's not entirely useless if I can get a meal per month out of it ^^
EDIT: Out of transparency, by writing an average of 1-2 articles/month on topics I enjoy, I managed to make an average of 10-15$/month. The ones about Rust are the more profitable ones, go figure :P