It's very nice to see a small type checker in Python, for Python! This became much easier in the last 10 years, since the MyPy team basically "upstreamed" the typed_ast library they were using into the stdlib. I found that there are not enough good teaching materials on type checkers -- e.g. the second edition of the Dragon Book lacks a type checker, which is a glaring hole IMO - https://news.ycombinator.com/item?id=…
once you get used to it, visitors are a very pleasant way to write ast walking code in python. they are essentially generating your case statement for you, so instead of `case ast.Expr: handle_expr(node)` you just write a `self.visit_expr` method and have the visitor match the node type to the method name and call it.
Baby's first type checker
11–20 of 22 posts
Re: Baby's first type checker
#12Earlier quoted context omitted.
once you get used to it, visitors are a very pleasant way to write ast walking code in python. they are essentially generating your case statement for you, so instead of `case ast.Expr: handle_expr(node)` you just write a `self.visit_expr` method and have the visitor match the node type to the method name and call it.
No it's not pleasant at all. It's boilerplate heavy, non-local and indirect. It's presumably a large part of why pattern matching is arriving in Python.
Re: Baby's first type checker
#13It's very nice to see a small type checker in Python, for Python! This became much easier in the last 10 years, since the MyPy team basically "upstreamed" the typed_ast library they were using into the stdlib. I found that there are not enough good teaching materials on type checkers -- e.g. the second edition of the Dragon Book lacks a type checker, which is a glaring hole IMO - https://news.ycombinator.com/item?id=…
> I found that there are not enough good teaching materials on type checkers -- e.g. the second edition of the Dragon Book lacks a type checker, which is a glaring hole IMO Pierce’s Types and Programming Languages [1] is excellent. It starts with very little (if you understand basic set-theory notation, you’re probably OK), gets you to a pretty reasonable point, and just generally makes for very pleasant reading. You…
Re: Baby's first type checker
#14Earlier quoted context omitted.
once you get used to it, visitors are a very pleasant way to write ast walking code in python. they are essentially generating your case statement for you, so instead of `case ast.Expr: handle_expr(node)` you just write a `self.visit_expr` method and have the visitor match the node type to the method name and call it.
No it's not pleasant at all. It's boilerplate heavy, non-local and indirect. It's presumably a large part of why pattern matching is arriving in Python.
Re: Baby's first type checker
#15It's amazing to me that a python program can be written to make sure another python program is pythoning properly.
Just curious. Isn't that how development tools generally work? Would you be surprised if it was in and for a compiled language? (This isn't a dismissal. I'm curious about the aspect of this specific case that amuses you.)
EDIT: escaped censorship
Re: Baby's first type checker
#16It's amazing to me that a python program can be written to make sure another python program is pythoning properly.
Re: Baby's first type checker
#17It's amazing to me that a python program can be written to make sure another python program is pythoning properly.
Just curious. Isn't that how development tools generally work? Would you be surprised if it was in and for a compiled language? (This isn't a dismissal. I'm curious about the aspect of this specific case that amuses you.)
Python is probably the apex of the "slow + doesn't work without a magic environment" problem
Re: Baby's first type checker
#18Earlier quoted context omitted.
No it's not pleasant at all. It's boilerplate heavy, non-local and indirect. It's presumably a large part of why pattern matching is arriving in Python.
That's a lot of buzzwords to say that you enjoy shoving everything in one function. :)
Re: Baby's first type checker
#19It's very nice to see a small type checker in Python, for Python! This became much easier in the last 10 years, since the MyPy team basically "upstreamed" the typed_ast library they were using into the stdlib. I found that there are not enough good teaching materials on type checkers -- e.g. the second edition of the Dragon Book lacks a type checker, which is a glaring hole IMO - https://news.ycombinator.com/item?id=…
once you get used to it, visitors are a very pleasant way to write ast walking code in python. they are essentially generating your case statement for you, so instead of `case ast.Expr: handle_expr(node)` you just write a `self.visit_expr` method and have the visitor match the node type to the method name and call it.
Your language will have a number of phases/passes to carry out. Let's say LambdaLifting, TypeChecking and Inlining.
All the code for lambda lifting belongs in one module, all the code for type-checking in another module, etc.
If you instead use visitor pattern, you will be looking at all the code related to Variable, Function, Literal in those files respectively.
So when you're working on Function.typecheck(), it will sit in source code just under Function.lambdalift() and just above Function.inline() - things which you don't want to consider together. Meanwhile, you'll need to switch between source files to work on Variable.typecheck() and Literal.typecheck().
Re: Baby's first type checker
#20Earlier quoted context omitted.
once you get used to it, visitors are a very pleasant way to write ast walking code in python. they are essentially generating your case statement for you, so instead of `case ast.Expr: handle_expr(node)` you just write a `self.visit_expr` method and have the visitor match the node type to the method name and call it.
Doing it this way maxes coupling and minimises cohesion. Your language will have a number of phases/passes to carry out. Let's say LambdaLifting, TypeChecking and Inlining. All the code for lambda lifting belongs in one module, all the code for type-checking in another module, etc. If you instead use visitor pattern, you will be looking at all the code related to Variable, Function, Literal in those files respectivel…
I've never organized visitor pattern code that way. Usually it's something like:
TypeChecker
visitFunction
visitVariable
visitLiteral
PrettyPrinter
visitFunction
visitVariable
visitLiteral
So related functions (across the types you're visiting) are kept together, you're not revisiting the Function module to add a new visitor there. That would almost defeat the purpose of the pattern.https://en.wikipedia.org/wiki/Visitor_pattern - See the UML diagram here.