3 ms·
It's more of a design issue here. You could do away from classes while keeping types by using 2 lines: Expr = Callable[[str]], Callable[..., Iterable[str]]
by BiteCode_dev 6y ago
It's more of a design issue here. You could do away from classes while keeping types by using 2 lines:
Expr = Callable[[str]], Callable[..., Iterable[str]]]
AstNode = Expr | Callable[... ], Callable[..., Iterable[str]]]
You then don't event need to call representation() , as each node is callable. No classes needed.
But my instinct tells me a node will eventually have more attributes and methods. Stuff to get parents, children, siblings, filtering and so on.
So it's probably a good call to use a class for later. Also you want to keep AstNode as a node could be an expression, a statement or a comment.
- mumblemumble 6y ago> But my instinct tells me a node will eventually have more attributes and methods. I couldn't agree more with Jack Diederich's thoughts on that sentiment, at 5:40 in the video linked above: https://youtu.be/o9pEzgHorH0?t=340 https://youtu.be/o9pEzgHorH0?t=340 > Lots of times people think they might need something later. You don't. Or, you can just do it later.
- BiteCode_dev 6y agohttps://docs.python.org/3/library/ast.html https://docs.python.org/3/library/ast.html Experience helps with this. It's a middle path as usual: naive approaches waste as much time as overenginering.
- nerdponx 6y agoYAGNI is a double-edged sword. It's almost no additional overhead to write a class now if you think you might need to add methods and internal state later. But it's quite a bit of refactoring work if you decide not to write a class and then realize you need one after the fact. Maybe this is an indictment of Python as a language, but I think it's a case of not taking anything too literally. YAGNI fetishism is like DRY fetishism all over again.
- mumblemumble 6y agoI guess? At the same time, working in some languages (Racket and C come to mind), it's surprising how long I can go without anything ever becoming a class, ever. Seemingly indefinitely. My sense is that many of us are taught to think in terms of classes and methods instead of data structures and functions, so it's very easy to slip into thinking you need objects in order to manage state, even when that's not the simplest way to do it. Strictly speaking, though, I think that the only time in Python that you really have no workable alternative to classes is when you also need dynamic dispatch.
- Groxx 6y agoPersonally: it's much easier to YAGNI in languages with relatively-strong compile-time checks and relatively-sophisticated tooling. If you lose either of those, a little bit of preventative work goes a loooooong way. The friction (largely due to risk) of correcting things later is so large that it just starts snowballing unless your team is extremely attentive. In that sense, Python is... middle of the road, with an extremely broad spread. Tooling is an odd blend of surprisingly good vs incapable of doing simple inference / detecting all calls, and type safety depends heavily on how you write things (some tactics are fairly strong, many are so weak as to be useless or make things much worse).
- mumblemumble 6y agoPersonally: Python has a great type checker. Several, actually. They're not compile time, because Python doesn't exactly have a compile time, but still. 11/10, use everywhere, spend less time on unit tests, be happy. Second, to me, these sorts of concerns about refactoring are. . . maybe not a smell, but worrisome, all the same. They suggest poorly-modularized designs with no internal component boundaries that might have limited the scope of impact of such a change. That said, even if you do find yourself needing to do a far-reaching refactor like that, refactoring in a dynamic codebase isn't necessarily harder, it's just different. Not being able to lean on the compiler to help you boil the ocean, for example, is fine, because boiling the ocean wasn't necessarily the best approach in the first place. The strangler pattern will help here, not just with type errors, but also with other problems the compiler might not have been able to help with, and will also be friendlier to the people who do your code reviews.
- rkangel 6y agoTo echo the sibling - I believe the most important skill a developer can have is reworking* code, and doing it readily and continuously. If you can do that, then you don't ever have to worry about what code MIGHT do in the future, you just design it for what it DOES do and then rework it later if necessary. It's quicker and the result is cleaner. Also, even if you tried your hardest to predict what was going to be needed, there are always things you can't predict and at that point you either rework your code or have bad code. * I could have said refactoring, but some people have very specific definitions attached to that word so I use something more general here