5 ms·
I have to plug Ada's rich type system for explicitly encouraging this kind of design. With things like type predicates [1], you can do run-time enforcement or e
by docandrew 4y ago
I have to plug Ada's rich type system for explicitly encouraging this kind of design. With things like type predicates [1], you can do run-time enforcement or even prove at compile-time (to optimize away the runtime checks) that type constraints are met.
As an example of this, in a piece of code I'm working on there's a Base64_String type, where only RFC 4648 characters are permitted to be part of the string, the '=' padding character can only appear at the end of the string, and if the second-to-last padding byte is '=' then the last one must be as well. This is all enforced by the type system without having to call "validate()" or something every time its used.
1. https://learn.adacore.com/courses/intro-to-ada/chapters/contracts.html#predicates https://learn.adacore.com/courses/intro-to-ada/chapters/cont...
- runeks 4y agoThat's definitely cool, but for everyday programming I'd consider this a waste of time.
- pyjarrett 4y agoI agree that it sounds really stupid up front, but it's done when you're just you modeling the constraints of the problem. I've found that it saves a lot of time in debugging and silly mistakes later. For types with invariants, you just add the `Invariant` aspect and then the type invariant gets checked automatically when passed as a parameter. Combined with built-in pre/post conditions, I've found that these sort of automatically inserted checks give me a lot of confidence, and allow significant embedding of conceptual and domain knowledge during development.
- zbentley 4y agoIf you like this style of programming but use Python for your day-to-day, check out typeguard; it provides runtime assertions for parts of the Python type annotation system similar to "Invariant". As with many tools, there are caveats. It's often surprisingly slow (so avoid using it on hot paths, or only turn it on during your testing/pre-production runs) and can't type-check everything (e.g. callables). But it's still pretty nice and requires minimal effort to use! https://pypi.org/project/typeguard/ https://pypi.org/project/typeguard/
- pyjarrett 4y agoNot just that, but it also often does so efficiently and doesn't incur a runtime penalty (for new type and static predicates) and will reuse previous function definitions as well. These are the sorts of cases with function parameters in various languages other language I've dealt with, in which this would have helped: - "dt": delta time of what? Seconds, milliseconds, microseconds, nanoseconds, ticks? Usually, I'd expect seconds if it was a float, though I've seen counter-examples, and I usually have to trace back the flow to know for use if it's a 64-bit (u)int. - "ip_addr" and "port": What's the type of port? If you guessed "int", you'd be right in part of the system. If you guessed "string" you'd be right in a different part of the system. - "path": Does it matter if this is a relative or absolute path? It often isn't apparent this matters and then you find out this path is passed to a different system in which it does matter.
- skrtskrt 4y agoI just got done detangling various ip addrs, ports, and paths being passed from Go to C bindings. Not fun Rust having builtin IP address types (and libraries actually using them) is long overdue for mainstream programming languages
- allisdust 4y agoHow does this get enforced for string content changed at runtime? Or does this apply for only to strings initialised in code.
- pyjarrett 4y agoYou can enforce newtype on strings, or also use a dynamic predicate which checks at runtime. https://ada-lang.io/docs/arm/AA-3/AA-3.2/#324--subtype-predicates https://ada-lang.io/docs/arm/AA-3/AA-3.2/#324--subtype-predi...