Devlog: is Checks
v1.4.5 added is checks, mostly so code like this can work:
if maybe_ptr is @int:
real_ptr: @int = maybe_ptr
end
The idea is (fairly) simple: if the condition proves maybe_ptr is an @int, the inside of the branch should be allowed to treat it like one.
Flower did not know how to do that before. It knew what a variable was declared as, but it did not really learn anything from control flow yet. Now it can, at least for the pointer/nullable-ish cases I care about first.
This touched the parser, AST, typechecker, narrowing logic, and codegen. So, naturally, the “small feature” went everywhere.
I’d actually consider this one of the bigger refactors so far, mostly because it added a new TypeAtom structure. Before this, types were still a bit too attached to the places they appeared, and all fell under the TypeInfo. That worked for simpler declarations, but is checks needed type syntax to have something the compiler could pass around to use for comparisons, validations, and narrowing.
The parser had to recognize the new expression shape. The AST had to store the left side and the tested type. The typechecker had to make sure the test was allowed and not totally garbage. Then the narrowing logic had to say, “inside this branch, this variable has the proven type of x and therefore we won’t flag you for being an idiot.”
That last part was where the bug goblin lived. I’m calling them a goblin because they were sneaky (and I also think it’s quite a funny and cute name).
For a while, Flower had applied narrowing from the if body instead of the if condition, which meant the compiler saw this:
if maybe_ptr is @int:
real_ptr: @int = maybe_ptr
end
and somehow still failed on the assignment inside the branch.
Very helpful. Thank you, compiler. EVen though it’s obviously 100% my fault, I made the compiler, but oh well!!
Once I changed the narrowing step to inspect the actual condition expression, it started behaving like it should. The typechecker could see maybe_ptr is @int, attach that narrowed type to the branch scope, and allow maybe_ptr to be used as @int inside the guarded block. For now this explicitness is how I want it. There may come a time in the near future where I decide some implicity is ok, but we’ll see ;)
is checks are the first real step towards control-flow-aware typing in Flower. Not full union support yet, but definitely the beginning of that road soon to come.
Right now it mostly helps with nullable and pointer-like cases. Later, the same idea can support richer unions, better narrowing, and more type-driven control flow without making the programmer manually restate everything the compiler should already know.
Also, it bootstrapped cleanly twice — which.. is obviously the bare minimum, but still!!
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.