HackerTube
HomeLongsLikedHistoryWatch laterCategoriesPlaylistsSettings

Ruby Conf 12 - Boundaries by Gary Bernhardt

Confreaks8 HN recommenders · recommended in 9 months, 2015-2024
YouTube
58K views · 13 years ago · talk · evergreen

Gary Bernhardt's RubyConf 2012 talk on testing in isolation without mocking everything. It goes through behavior versus data, mutation versus immutability, and how a functional core with an imperative shell yields natural isolation and parallelism.

HN recommends it as the canonical presentation of 'functional core, imperative shell' and a practical answer to unit versus integration testing.

Testing, debugging & developer toolsSoftware architecture & designFunctional programming#functionalcoreimperativeshell#garybernhardt#testing#immutability#sideeffects

12 comments from Hacker News

@maxbond2024 · in “The two factions of C++”

You've got the gist of it. By decoupling your function from the state of your application, you can test that function in isolation. For instance, you might be tempted to write a function that opens an HTTP connection, performs an API call, parses the result, and returns it. But you'll have a really hard time testing that function. If you decompose it into several tiny functions (one that opens a connection, one that accepts an open connection and performs the call, and one that parses the result), you'll have a much easier time testing it. (This clicked for me when I wrote code as I've described, wrote tests for it, and later found several bugs. I realized my tests did nothing and failed to catch my bugs, because the code I'd written was impossible to test. In general, side effects and global state are the enemies of testability.) You end up with functions that take a lot of arguments (10+), which can feel wrong at first, but it's worth it, and IDEs help enormously. This pattern is called dependency injection. link See also, the "functional core, imperative shell" pattern. ▶ this video

CitesView on HN
@jrvarela562024 · in “Total Functional Programming (2004) [pdf]”

This talk [1] made me conclude something along these lines. You need side-effects to make anything useful, just make sure they're segregated in a specific place in your program. This makes it easier to make most of the program pure and make it clear where the dangerous stuff happens. [1] Boundaries by Gary B. from Destroy All Software ▶ this video

CitesView on HN
@dnautics2021 · in “Onboarding to Elixir”

> Jose has really thread a needle with Elixir I feel. There was kind of something in the zeitgeist ready for this... This was a video by Gary Bernhardt in 2012 (that's like, Elixir -2 years?). I've queued it up to where he talks about basically wanting to go live on a cruise ship, fork rubinius, and rebuild ruby on top of erlang. The main chunk of the talk is about the software pattern that Phoenix and Elixir really tries to get you to adopt. ▶ this video

RecommendsView on HN
@AaronFriel2020 · in “A Theory of Software Architecture”

A few years ago I was on a team and the dev lead had a practice of sharing Gary Bernhardt's Boundaries talk every time there was some degree of rotation or churn on the team. Almost part of the onboarding. As a functional programming aficionado, I didn't need the sales pitch, but it was the presentation that was gripping. Keep in mind, Ruby isn't a functional language, but here was this presenter describing essentially how you write good Haskell code, but in Ruby! A language that makes it so easy to mutate in place that it's known for libraries that "monkey patch" base classes and can change the definition of operators and functions at runtime! Fantastic talk, fantastic presentation. I now share it with my new engineering colleagues too. Here's the talk where he talks about imperative shell, functional core, "Boundaries": ▶ this video

Strongly recommendsView on HN
@aszen2020 · in “Prefer Fakes over Mocks”

I have been researching into several testing approaches and so far in my experience yes fakes are better than mocks. But what is even better is not having to fake or mock stuff especially for testing business logic. One of the problems we get ourselves into is abstracting service io code into functions and calling them from our business logic code. This forces us to mock all the io calls, instead we should be doing the opposite i.e abstracting business logic into discrete functions of pure data in and out and then calling those functions from our io code. This way we can test the business logic independently of the io code. Testing the business logic now becomes quite simple and one can leverage property testing to further boost our confidence in such tests. Many times the ramaining io code is just calling other functions and doesn't need to be tested. Several other ideas that relate to this are hexagonal architecture, Domain Driver Design, clean architecture and functional core with an imperative shell. Some resources to further explore these ideas: Clean Architecture in Python - link Why integrated tests are a scam - link Boundaries - ▶ this video

RecommendsView on HN
@magicpat20102020 · in “Ask HN: Organization of Layered Software?”

This isn't an article but reading your post reminds me of the presentation by Gary Bernhardt titled "Boundaries", ▶ this video I would be interested in looking at the article(s) if you can find them again.

RecommendsView on HN
@dnautics2020 · in “I Don't Use Classes”

> I find some problems are solved better in an OO way such as interacting with a relational database. I've switched to functional interactions with a database, (Elixir/Ecto) and really, it's much better. In particular the explicit and declarative nature of the database interactions combines the convenience of an ORM with "not hiding important gotchas from you". I'm not arguing for pure functional systems (which I can see going very poorly with relational databases). There are some things that objects are good at like caching state as a model. But even here the FP systems typically do it better via FP actors and (again, impure) message passing, which enforces no-shared memory, and at least in erlang virtual machine systems, couples segregated state with limiting blast radius for your systems failure domains, which is 150% the "right thing to do". Of course if we're getting pedantic, this is even close to OO the way that Alan Kay imagined it, than what the OP and GP talk about, and I don't consider that to be OO in the contemporary, colloquial sense of "everything that happened after Bjarne Soustroup invented C++" I highly recommend this video for a more philosophical take on how to do "impure FP" without OO that is informed by a decade of industry experience: ▶ this video which is by Gary Bernhardt (of WAT fame) > I look for the right tool for the job rather than some idealistic purity This is all about right tool for the job. IMO, FP code is easier to read, easier to reason about,

Strongly recommendsView on HN
@dnautics2020 · in “Elixir v1.10”

if you are a rubyist, I can't more strongly recommend watching this video, which has nothing to do directly with Elixir (in fact it precedes elixir by a couple of years) but if the topics that Bernhart (of wat fame) brings up resonate with you, then you will really like Elixir. ▶ this video

Strongly recommendsView on HN
@pmarreck2016 · in “Have Software Developers Given Up?”

Here is the infamous Nagappan TDD paper from Microsoft Research link Also discussed in this infoq article link Here's someone's thesis paper on it, with data: link There's also interesting discussions like this link "it is my experience that the value proposition for TDD grows exponentially as the time and resources involved in a project grows linearly." This has also been my own experience. This person's comment also is interesting and has data link Some of the above is empirical (read: scientific, no-bullshit) data. My opinion on it has grown to the point that I think TDD should literally be inseparable from programming, and the two together should simply be called, "programming." Lacking any unit tests whatsoever (TDD or otherwise) should be called, "taking stupid, extremely hazardous risks to save a little time, like reading your phone while driving" I've not found a programming task in at least 5 years that wasn't waaaay better-written when done via TDD. Some things, like IO, can be a challenge to unit-test, but that's why we have great ideas to solve that like Gary Bernhardt's awesome "Boundaries" talk ▶ this video

Strongly recommendsView on HN
@itsmemattchung2016 · in “How to avoid brittle code”

I recommend watching this talk: ▶ this video Both, unit and integration tests, are imperative. Integration tests point in the general direction of where an issue might be but unit tests are more precise.

RecommendsView on HN
@lectrick2015 · in “The microservices cargo cult”

Many of the advantages of microservices can be achieved by refactoring your monolith code to be less monolithic. I would suggest using functional styles wherever possible, plenty of isolated unit testable code, and a hexagonal architecture link that pushes all the I/O, mutation, side effects, etc. to the very boundary of your code. Also see Gary Bernhardt's "Boundaries" talk for more interesting thought in that vein ▶ this video

RecommendsView on HN
@zachrose2015 · in “Ask HN: Front-end “design patterns”?”

Forgive me for being vague and brief, but I've been trying to test my UIs for the last year or so and this is what I've come up with. I've found the ideas in Gary Bernhardt's talk, Boundaries (1), to be very helpful in figuring out how to test interactive web UIs. The basic idea is that DOM manipulation can be an "imperative shell" with as little logic and as few conditionals as possible. Derive the state of your UI component with separate functions and methods that return plain values (a "functional core"), and write tests for those because testing for values is easy. So no, don't test for the presence of classes and IDs. Test your imperative shell once, maybe even manually or with an integration test, and that's probably enough. Angular and React both encourage something like this approach, but you don't need those technologies to do it this way. In Backbone, for instance, just try to avoid conditionals and logic in your templates and render methods. If you think your UI piece needs to render with conditionals because it can be in different states, ask yourself if those states are just appearances that can be programmed declaratively with classes and CSS. Also, testing is so much easier when you limit API surface areas. So if you're using a library like Backbone, where models and views both have many methods with many ways they can be called and used, don't give them direct references to each other. I've had some success in having models and views communicate only with a gl

RecommendsView on HN
Rails Conf 2013 The Magic Tricks of Testing by Sandi Metz32:23

Rails Conf 2013 The Magic Tricks of Testing by Sandi Metz

Confreaks
144K views • 13 years ago
The Clean Architecture in Python49:54

The Clean Architecture in Python

Next Day Video
114K views • 12 years ago
"Outperforming Imperative with Pure Functional Languages" by Richard Feldman34:55

"Outperforming Imperative with Pure Functional Languages" by Richard Feldman

Strange Loop Conference
98K views • 5 years ago
RailsConf 2015 - Nothing is Something35:53

RailsConf 2015 - Nothing is Something

Confreaks
84K views • 11 years ago
Domain Modeling Made Functional - Scott Wlaschin51:40

Domain Modeling Made Functional - Scott Wlaschin

NDC Conferences
71K views • 9 years ago
RailsConf 2014 - All the Little Things by Sandi Metz38:47

RailsConf 2014 - All the Little Things by Sandi Metz

Confreaks
190K views • 12 years ago
Solving Problems the Clojure Way - Rafal Dittwald1:02:26

Solving Problems the Clojure Way - Rafal Dittwald

Clojure/north
87K views • 7 years ago
Functional architecture - The pits of success - Mark Seemann1:00:10

Functional architecture - The pits of success - Mark Seemann

NDC Conferences
152K views • 10 years ago
Stuart Sierra - Components Just Enough Structure41:19

Stuart Sierra - Components Just Enough Structure

ClojureTV
36K views • 12 years ago
Ruby Conf 12 - Y Not- Adventures in Functional Programming by Jim Weirich53:22

Ruby Conf 12 - Y Not- Adventures in Functional Programming by Jim Weirich

Confreaks
65K views • 14 years ago
"Agility & Robustness: Clojure spec" by Stuart Halloway40:00

"Agility & Robustness: Clojure spec" by Stuart Halloway

Strange Loop Conference
25K views • 10 years ago
October CincyRb - Jim Weirich on Decoupling from Rails1:15:58

October CincyRb - Jim Weirich on Decoupling from Rails

Launch Scout
48K views • 13 years ago
Domain Modeling Made Functional - Scott Wlaschin - KanDDDinsky 201950:49

Domain Modeling Made Functional - Scott Wlaschin - KanDDDinsky 2019

KanDDDinsky
74K views • 6 years ago
Mountain West Ruby 2012 Capability vs. Suitability by Gary Bernhardt19:44

Mountain West Ruby 2012 Capability vs. Suitability by Gary Bernhardt

Confreaks
22K views • 14 years ago
Spec-ulation Keynote - Rich Hickey1:16:14

Spec-ulation Keynote - Rich Hickey

ClojureTV
135K views • 9 years ago
Cheng Lou - On the Spectrum of Abstraction at react-europe 201635:32

Cheng Lou - On the Spectrum of Abstraction at react-europe 2016

ReactEurope
63K views • 10 years ago
Analyzing Programs with Z343:31

Analyzing Programs with Z3

Compose Conference
24K views • 10 years ago
Ruby Manor 3 - Programming with Nothing by Tom Stuart40:50

Ruby Manor 3 - Programming with Nothing by Tom Stuart

Confreaks
13K views • 14 years ago
Cory Benfield - Building Protocol Libraries The Right Way - PyCon 201631:38

Cory Benfield - Building Protocol Libraries The Right Way - PyCon 2016

PyCon 2016
15K views • 10 years ago
MountainWest RubyConf 2014 - But Really, You Should Learn Smalltalk28:06

MountainWest RubyConf 2014 - But Really, You Should Learn Smalltalk

Confreaks
27K views • 12 years ago