r/ProgrammingLanguages
re-allocating" storage for a local could allow faster code
Rust already knows when a value has been moved, so I think it would make sense for the compiler to also be able to treat the storage behind that local as reusable.
For example:
´´´
let x = big_value();
let y = x; // x is moved
// x can no longer be used here anyway
x = another_value();
´´´
Right now, Rust can be more restrictive than necessary about keeping the same storage associated with `x`.
Issue #61849 proposes allowing the old storage to effectively die after the move. If `x` is initialized again later, the compiler wouldn't necessarily have to put the new value back in the exact same stack slot.
That could give the compiler more freedom to:
- reuse stack space earlier
- reduce stack usage in some functions
- shorten lifetimes of stack allocations
- potentially unlock further optimizations
What I like about the idea is that it matches how moves already feel in Rust: once a value is moved, that value is gone. It seems natural that its storage shouldn't have to remain special either.
There are obviously details around raw pointers and observable addresses that would need proper language semantics, so it isn't just a simple compiler optimization.
But the general rule seems very appealing:
If Rust says the old value no longer exists,
the compiler should be free to stop preserving its storage.
The issue has been open since 2019, and I think it would be interesting to revisit whether this could give modern rustc more optimization freedom. If you agree please react on the GitHub issue with ❤️ or 👍 to show support by the community
How to make a compiler backend?
Hell everyone, i have an question. Im for long trying to make a cool, powerful "kinda" low level language similar to zig and rust, but im struggling to choice llvm as backend, sure i can generate C, but its makes compiler dependent on gcc or clang or other c compiler. LLVM seems hard to me, sure project like QBE exist, but QBE doesnt have C/C++ api like llvm's IRbuilder. So are there other ways? I tried thinking about using GCC infrastructure but GCC has poor api and not very documented api. Maybe just stick to generating C?
Title: Expressions with Word Operators: Which one would you coose?
I was thinking of the ideal expression syntax for the programming language DQ. I started with the (dominating) C syntax.
Operators in C
In C the following operators have shared meanings:
&: bitwise "and" operation OR address of*: multiplication OR pointer dereference/: truncated integer division OR floating point division
Further operators in C:
%: integer division reminder&&orand: logical "and"||oror: logical "or"!ornot: logical "not"~: bitwise "not"^: bitwise "xor"?: ternary operator
Operators in DQ
I think for the good source code readability and clarity every different operation should have a different symbol. Therefore the shared symbols from C are not taken over. These operators are already fixed in DQ:
&: address-of operator (widespread standard)^: pointer dereference (standard in other languages)*: multiplication only/: floating point division only (standard in other languages)or: logical "or" (widespread standard)and: logical "and" (widespread standard)not: logical "not" (widespread standard)
These symbols are already fixed for special purposes:
#: compiler directives (#ifdefetc)$: context local specials (e.g.myarray[0:$end-2])?: inference marker@: namespace designator (e.g.@def.LINUX)
DQ cannot use the C standard &, |, ~, ^ for the bitwise operations, because the & and ^ is used for other (fixed) purposes. But we've run out of the good symbols. The obvious choice, that other existing languages also use, is reserving some words for the remaining operations. In DQ these (all-capital) words are reserved currently as operators:
AND: bitwise "and"OR: bitwise "or"NOT: bitwise "not"XOR: bitwise "xor"IDIV: truncated integer divisionIMOD: integer division reminder
For the modify-assign statements with a word operator a leading = is required, otherwise it looks awkward:
regs.OSPEEDR OR= (1 << pinx2) // invalid
regs.OSPEEDR =OR= (1 << pinx2)
Examples with All-Capital Operators
tmp = RCC.CFGR
tmp =AND= NOT 3
tmp =OR= RCC_CFGR_SW_HSI
RCC.CFGR = tmp
while (RCC.CFGR >> 2) AND 3 <> RCC_CFGR_SW_HSI:
endwhile
RCC.CR =AND= NOT RCC_CR_PLLON
while RCC.CR AND RCC_CR_PLLRDY != 0:
endwhile
var pllm : uint = basespeed IDIV pll_input_freq
var plln : uint = vcospeed IDIV pll_input_freq
var pllq : uint = vcospeed IDIV 48000000
RCC.PLLCFGR = (0
OR (pllsrc << 22)
OR (pllm << 0)
OR (plln << 6)
OR (((pllp >> 1) - 1) << 16)
OR (pllq << 24)
)
regs.MODER =AND= NOT (3 << pinx2)
regs.MODER =OR= (n << pinx2)
if flags AND PINCFG_OPENDRAIN <> 0:
regs.OTYPER =OR= (1 << apinnum)
else:
regs.OTYPER =AND= NOT (1 << apinnum)
endif
regs.PUPDR =AND= NOT (3 << pinx2)
if flags AND PINCFG_PULLUP <> 0:
regs.PUPDR =OR= (1 << pinx2)
elif flags AND PINCFG_PULLDOWN <> 0:
regs.PUPDR =OR= (2 << pinx2)
endif
Prefixed Word Operators
I'm thinking to change the all-capital word operators with a % prefixed lowercase words:
%and: bitwise "and"%or: bitwise "or"%not: bitwise "not"%xor: bitwise "xor"%divor%idiv: truncated integer division%modor%idiv: integer division remainder
The sample code would look like this way:
tmp = RCC.CFGR
tmp %and= %not 3
tmp %or= RCC_CFGR_SW_HSI
RCC.CFGR = tmp
while (RCC.CFGR >> 2) %and 3 <> RCC_CFGR_SW_HSI:
endwhile
RCC.CR %and= %not RCC_CR_PLLON
while RCC.CR %and RCC_CR_PLLRDY != 0:
endwhile
var pllm : uint = basespeed %div pll_input_freq
var plln : uint = vcospeed %div pll_input_freq
var pllq : uint = vcospeed %div 48000000
RCC.PLLCFGR = (0
%or (pllsrc << 22) // select PLL source
%or (pllm << 0)
%or (plln << 6)
%or (((pllp >> 1) - 1) << 16)
%or (pllq << 24)
)
regs.MODER %and= %not (3 << pinx2)
regs.MODER %or= (n << pinx2)
if flags %and PINCFG_OPENDRAIN <> 0:
regs.OTYPER %or= (1 << apinnum)
else:
regs.OTYPER %and= %not (1 << apinnum)
endif
regs.PUPDR %and= %not (3 << pinx2)
if flags %and PINCFG_PULLUP <> 0:
regs.PUPDR %or= (1 << pinx2)
elif flags %and PINCFG_PULLDOWN <> 0:
regs.PUPDR %or= (2 << pinx2)
endif
Which version do you like more?
or
Do you have some other ideas for the operator notation?
EDIT
Version with band / bor etc, as "jason-reddit-public" suggested:
band: bitwise "and"bor: bitwise "or"bnot: bitwise "not"bxor: bitwise "xor"idiv: truncated integer divisionimod: integer division reminder
​
tmp = RCC.CFGR
tmp =band= bnot 3
tmp =bor= RCC_CFGR_SW_HSI
RCC.CFGR = tmp
while (RCC.CFGR >> 2) band 3 <> RCC_CFGR_SW_HSI:
endwhile
RCC.CR =band= bnot RCC_CR_PLLON
while RCC.CR band RCC_CR_PLLRDY != 0:
endwhile
var pllm : uint = basespeed idiv pll_input_freq
var plln : uint = vcospeed idiv pll_input_freq
var pllq : uint = vcospeed idiv 48000000
RCC.PLLCFGR = (0
bor (pllsrc << 22)
bor (pllm << 0)
bor (plln << 6)
bor (((pllp >> 1) - 1) << 16)
bor (pllq << 24)
)
regs.MODER =band= bnot (3 << pinx2)
regs.MODER =band= (n << pinx2)
if flags band PINCFG_OPENDRAIN <> 0:
regs.OTYPER =bor= (1 << apinnum)
else:
regs.OTYPER =bor= bnot (1 << apinnum)
endif
regs.PUPDR =band= bnot (3 << pinx2)
if flags band PINCFG_PULLUP <> 0:
regs.PUPDR =bor= (1 << pinx2)
elif flags AND PINCFG_PULLDOWN <> 0:
regs.PUPDR =bor= (2 << pinx2)
endif
Continuations + preemption vs native fibers: rethinking my embeddable language's concurrency model
posted zym here a while back (embeddable dynamic scripting language, one shot delimited continuations as a primitive, instruction count preemption that host and script can both drive). its at 0.3.2 now with various edges being smoothed over
im now second guessing the concurrency model and wanted to think it through with people who care about this area as i am completely split on where to take this
the current design is continuations and preemption as a pair. it is powerful, you can write whatever scheduler you want in userland. but ive gotten personal reports were people constructing fibers by hand from the raw primitive and hitting capture/resume edge cases. essentially a want for fibers, they just have to build them
the preemption side is exact. it fires at instruction N for both host and script and that requires a counter check on every dispatch, which i measured at ~21% on dispatch heavy code. i tried several ways to make it cheaper (safepoints at back edges and calls, fuel metering with compiler folded costs, dual dispatch tables) and anything that keeps exact firing does not win. back edge safepoints recover 15-17% but overshoot by up to one straight line block
so what im considering is swapping the whole story:
- native cooperative fibers/coroutines as the concurrency model, native scheduling so a switch is cheap and there is nothing to construct
- continuations either kept as an advanced primitive under the fibers or removed from the surface
- preemption becomes host only, a sandbox guard the embedder arms and script cannot observe. once script cannot observe it, bounded firing is acceptable, so the cheaper check is usable and the whole thing can be a compile flag for hosts that do not need it
that gets everyone 15-20% and a model people already know. what it gives up is the primitive being the surface
what i actually dont know:
- do people who use delimited continuations want them exposed, or would they take fibers built on them and not miss it, and the reverse as well would people who use fibers just prefer to use that or would they want flexibility of continuations? i made them one shot delimited for sanity and most languages hide this anyway
- is native yield/resume ever too limiting? effects and handlers people especially, curious whether fibers give up something you would notice, for those that dont use effects would there be a want for them if cooperative scheduling were the baseline
- would you keep the raw primitive as an escape hatch even if almost nobody touches it, or is that surface area for its own sake that would not get used by the vast majority?
happy to go into the measurements or the design, its been a rabbit hole, just has been absolutely bugging me for the past few weeks on that design decision and if people would actually expect or even use this capability over a simpler and more intuitive model but also not as flexible and i am dying for answers to these
language: https://zym-lang.org
github: https://github.com/zym-lang
What if YOU Could Add Your Own Features to a Language?
I made a video explaining a concept I love called macros, which allow you to add your own syntax to a language. Languages like Rust, Lean, and lisp have them. The goal with the video is to make you feel like you could've discovered macros yourself.
I'm new at making educational content like this, but I'm planning on making many more programming language videos like this one on my channel. Any thoughts, constructive criticism, or advice is more than welcome! Hope you all enjoy
How to build a good package manager.
I'm working on a language called threadon. And i don't now how i can properly program a package manager.
My first idea was a central github repo with links to other github repo's which contain the package you're searching for.
There are two main problems with it
If someone deletes his github repo with the package everything build on the package would collapse (like npm)
I think it would be slow when the number of packages grows.
I had an idea to of selfhosting it but i haven't access to the router (My dad owns it i'm 13) and i'm sure downdetector on my package manager site would be worse then github 😄. Like i would probably run sudo rm -rf / --no-preserve-root on the wrong machine.
So my question is how can i build a system that can store up to 20 GB at minimum at packages without the risk of someone nuking his project).
Headache a language that compiles to brainfuck
A few days ago when i was bored i randomly came up with this idea. I made it without AI in about a day so the code is kinda trash but it works.
Using this program you can either:
- Directly run a headache (.ha) file
- Directly run a brainfuck (.bf) file
- Compile a headache file into brainfuck code
Any books similar to SICP Chapter 5?
I loved Chapter 5 of Structure and Interpretation of Computer Programs. Building a virtual register machine with an assembler and compiler in Scheme. Are there any other books/online classes or resources that involve building a computing machine (or any machine) from scratch using code?
Seed7 - Memory Safety and Management • Thomas Mertes • 05/2026
youtube.comDTT Proof Based Languages?
What are people's thoughts on proof-based programming languages based on Dependent Type Theory like Lean, Rocq/Coq, F*/Low*, Agda, etc. It seems like there is some subtle growing hype behind formal verification. Clearly, there is at least some appetite for better behavior guarantees as we can see with Rust.
What do you think, are these languages the future? Will they become more ergonomic over time. Or do you think the average programmer will never be willing to learn or program in such a language for their normal projects?
Lessons from Implementing Functions in My Interpreter (in Rust)
x.comTeaching compiler construction with a tiny self-hosting language
I've just published not-abc, a tiny self-hosting compiler for a deliberately minimal C-like programming language.
https://github.com/michael-lehn/not-abc
The language has only one data type: a 64-bit value, interpreted either as a signed integer or as a pointer. It supports
- functions (the value of the last expression is the return value)
- local and global variables
- pointers (
&,*,#) if/elsewhile- recursion
- dynamic memory allocation (
malloc/free) - integer, character and string literals
The compiler generates LLVM IR rather than assembly. LLVM was chosen simply because it makes the compiler portable across essentially all modern platforms—building programs only requires Clang (or the LLVM toolchain).
The interesting part is probably the background.
not-abc originated from an undergraduate mathematics course called Introduction to High Performance Computing. During one semester, students simultaneously
- build a simple processor from logic gates (bottom-up),
- implement a compiler for a small C-like language (top-down),
until both meet in the middle. At the end of the course, the compiler has two backends: one targeting the custom processor the students built themselves, and one targeting LLVM so the same compiler can generate native executables on real hardware.
The self-hosting compiler in this repository is a distilled version of the compiler developed throughout the course.
I'd be interested in feedback from people interested in language design, compiler construction, or computer architecture.
Update: I finally started building an interpreter from first principles
About a month ago, I made a post asking for resources on building a very small compiler/interpreter before jumping into something larger like Crafting Interpreters.
I decided to stop looking for the perfect resource and just start building the smallest thing I could understand end-to-end.
Today I got the first version of a simple arithmetic interpreter working in Python.
Right now it supports:
- Integer literals
- Addition and subtraction
- Multiplication and division
- Operator precedence
- Parentheses
- Unary minus
- Basic syntax errors
- Division-by-zero handling
- An interactive REPL/CLI
For example:
calc> 2 + 3 * 4
14
calc> (2 + 3) * 4
20
calc> -10 + 5
-5
The structure is currently:
Source text
↓
Lexer
↓
Tokens
↓
Recursive-descent parser
↓
Evaluation
↓
Result
The lexer converts something like:
2 + 3 * 4
into tokens roughly equivalent to:
NUMBER(2)
PLUS
NUMBER(3)
MUL
NUMBER(4)
The parser implements a small grammar along these lines:
expr → term (("+" | "-") term)*
term → factor (("*" | "/") factor)*
factor → NUMBER | "(" expr ")" | "-" factor
One of the most useful things I learned today was how operator precedence can naturally come from the structure of the grammar. I initially assumed I would need to assign explicit precedence values to operators, but with recursive descent, expr, term, and factor already encode that hierarchy.
The parser currently evaluates expressions directly rather than producing an AST, so it is deliberately still very small. My next major step will probably be separating parsing from evaluation by building an AST.
I also spent some time turning it into a proper little Python project instead of keeping everything in one file. It now has separate lexer, parser, interpreter, and CLI modules, a src package layout, pyproject.toml, a command-line entry point, and Ruff for linting/formatting.
So this is obviously nowhere near a real compiler yet, but that was exactly the point of my original post. I wanted something small enough that I could understand every stage instead of immediately disappearing into a much larger implementation.
Building even this tiny version made concepts like tokenization, grammars, recursive descent, precedence, and parsing much less abstract than they were a month ago.
The plan from here is to keep extending it incrementally, probably with an AST, variables, and a few statements before eventually moving toward bytecode or compilation.
The Kal Package Manager
Hey everyone,
A couple of weeks ago, I posted about Kal, my programming language written from scratch.
I am really happy to share a glimpse of Kal's own package manager! Kal v0.1.0 shipped with a package system that lets you add and use third party Kal packages. But, that process was completely manual. You’d have to clone the package, place it in the right directory, clone the package’s entire dependencies all by yourself, one after another. :(
The package manager changes everything. One command automates all!
Instead of being a separate executable, the package manager ships as part of the Kal interpreter itself.
Here’s what it can do:
- Install Kal packages from Github, or any git hosting service.
- Creates/Updates a project.kal file to read and write package information (analogous to package.json).
- Downloads all packages at the same hierarchy in parallel (yup, it’s multi-threaded).
- Resolves sub dependencies of the main package automatically to any depth and installs them too.
- Upgrades/Downgrades packages based on their git tags.
- Auto-resolves cyclic dependencies to prevent an infinite loop.
The Kal Package Manager will officially ship with the next Kal release. Its current source code is available on Github.
Kal: https://kal-lang.vercel.app
Github: https://github.com/KILLinefficiency/Kal
Package Manager: https://github.com/KILLinefficiency/Kal/blob/pkg/pkg.hpp
Kal is completely free & open source. You can show your support by giving the Github Repository a star.
Until the next update!