Closed lachlanhardy closed 4 years ago
If all the routine’s preconditions are met by the caller, the routine shall guarantee that all postconditions and invariants will be true when it completes
@tomdalling: felt like he could write perfect code in the early years but that wore off pretty quickly. @lachlanhardy: earlier in his career, he was a lot more defensive about his code because he knew it wasn't perfect. @lachlanhardy: framing feedback as questions (i.e. in pull requests) helps you absorb the feedback because it creates a conversation. @saramic and @tomdalling have used exercism.io and found the mentors to be friendly and provide valuable feedback. @saramic is taking a course-by-proxy on being a decent human being.
The group has little experience programming in languages that employ DBC.
@mcgain: types are a form of contract and, as such, using the Sorbet type checker for Ruby is a form of DBC. Pattern matching in Elixir could also be considered DBC. @lachlanhardy: reading about topics like this is great but cognitively demanding.
@mcgain: a good semantic invariant in e-commerce software is the user should never be charged twice. Having this as a semantic invariant would create discussions on areas such as transaction integrity and third-party integrations (e.g. Stripe) and how errors would create adherence to the invariant.
@elle: this chapter brought to mind the Liskov substitution principle (the "L" in SOLID) which says that a subclass should be substitutable for its parent class.
@tomdalling: thoughts on why languages like Eiffel aren't more popular? @lachlanhard (aka, Mr Eloquent): "sounds like mathematical, nerdery, bullshit to me". @elle: it's not designed for developer happiness. @tomdalling: Rich Hickey, creator of Clojure said "Programmers know the benefits of everything and the tradeoffs of nothing"
@HashNotAdam: what was missed in this book was a nuanced discussion about when a contract is more valuable than developer happiness. He uses Sorbet in places of high risk (e.g. when dealing with monetary transactions that involve an API) but never in lower-risk components.
@elle: prefers to use input validation only when dealing with user input since she controls the other inputs.
@mcgain: recommends Confident Ruby which digs into this topic.
@tomdalling: the suggestion of defensive coding seems to run counter to so much of the advice.
@mcgain: Confident Ruby suggests programming defensively where your app connects to users and then transform the inputs so they do not need to be handled defensively in the lower levels of your app. This includes removing nil
inputs so you don't need to consider those values deeper in the app.
@tomdalling: after working on an application that attempted to never crash and seeing how that lead to incorrect values, he now believes in the value of using assertions and crashing.
@lachlanhard: name drops Jeremy Keith who says "you bring the problems as close to you as you can; don't push the problems to your users". This means you want to see errors in development/tests so you see the errors rather than the user getting in in production.
@mcgain: writes bad code and so likes to use assertions, crash the app, and then marshal the application state into a file. In a long-running process, this allows him to go back to just before the crash and continue one the bug is fixed.
@lachlanhard: when it comes to intermittent issues, sometimes you can deprioritise fixing them and simply retry.
@tomdalling: generally only raises an exception for something that can not be recovered (i.e. an actual bug). He has a blog post detailing his views and Piotr Solnica of dry-rb was recently discussing this
Toms' post: Raise On Developer Mistake Tom's post: Result Objects - Errors Without Exceptions
Piotr Solnica's tweet Article by Igor Morozov referenced in the tweet (Should I really use monads?)
@tomdalling: doesn't really use assertions in Ruby; occasionally will raise
that something went wrong but generally prefers to let the app crash and then fix the issue
@mcgain: went on a tangent on this topic raging about the concept of a Maintenance Programmer. It suggests there are Greenfield Programmers who do the architectural work and then leave the "shitty" rest of the job to Maintenance Programmers. @tomdalling: assumes the term comes from very large organisations who hire consultants build apps and then use staff programmers to maintain them. @elle: people forget that "maintenance" is the bulk of work that needs to be done. @mcgain: you have to be a better programmer to be a Maintenance Programmer. @saramic: Dave Thomas of YOW! believes that Maintenance Programmers can have a lot more business impact than Greenfield Programmers.
@tomdalling: references The Teeth by Kelly Sutton that describes the idea of taking small steps as teeth. The bigger your steps are the bigger the teeth of the monster and they are going to hurt you more.
@elle: it can be difficult sometimes to not do too much when experience tells you the longer path is "better" but often you will find that work wasn't required. @mcgain: used a tool called Jumpstart to create a new Rails app. Within a few days, it became clear that this came along with far too many tools that he would never need. @elle (aka thoughtbot shill): recommends taking a look at the suspenders gem which brings in core tools without any features (e.g. authentication or admin).
https://pragprog.com/book/tpp20/the-pragmatic-programmer-20th-anniversary-edition
Aiming to cover:
MC: @tomdalling
Notes: @HashNotAdam
See you 12 pm Tuesday, April 7th @ https://whereby.com/blackmill
Ping gday@blackmill.co if you want a calendar invite and access to the low-volume Slack beforehand.