HN Theater @HNTheaterMonth

The best talks and videos of Hacker News.

Hacker News Comments on
Ruby Conf 12 - Boundaries by Gary Bernhardt

Confreaks · Youtube · 1 HN points · 12 HN comments
HN Theater has aggregated all Hacker News stories and comments that mention Confreaks's video "Ruby Conf 12 - Boundaries by Gary Bernhardt".
Youtube Summary
Some people test in isolation, mocking everything except the class under test. We'll start with that idea, quickly examine the drawbacks, and ask how we might fix them without losing the benefits. This will send us on a trip through behavior vs. data, mutation vs. immutability, interface vs. data dependencies, how data shape affords parallelism, and what a system optimizing each of these for natural isolation might look like.

Help us caption & translate this video!

http://amara.org/v/FGeb/
HN Theater Rankings

Hacker News Stories and Comments

All the comments and stories posted to Hacker News that reference this video.
https://www.youtube.com/watch?v=yTkzNHF6rMs

Of course this approach requires an impure functional language (so you can have side-effect calls).

Jun 22, 2021 · dnautics on 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.

https://www.youtube.com/watch?v=yTkzNHF6rMs&t=2400s

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": https://www.youtube.com/watch?v=yTkzNHF6rMs

barrkel
What is a functional language - something that encourages programming in a functional style, or actively outlaws imperative programming?

IMO it's pleasant to use Ruby in a functional style, much more pleasant than Python owing to the ease of chaining calls that take lambda arguments (blocks). Every time I try to do something similar to a big chained Enumerator stream in Ruby in Python using a list comprehension, I have to invert my thinking - as far as I'm concerned, those things are written backwards and inside out.

Huggernaut
I think Gary shared a Twitter related project that was written in this way, but do you have any examples of other projects by any chance?
dnautics
"most projects in elixir". Some good open-source examples are oban, hex.pm, papercups.io
AaronFriel
Ah, I am blocked by Gary on Twitter and there is some irony that his Boundaries talk culminates in a Twitter client. (Gary if you're reading this I enjoyed your feed!)

I'm not aware of any good OSS examples, either.

I think React and Redux are in a way an implementation of these concepts. React is a view layer that sends messages and each component is (ideally) a pure function of state, and sometimes its own history. It's so, so easy to unit test the interactions.

Hooks make it a little harder to reason about, and it's unfortunately easy to write hooks that perform IO and you suddenly end up in a miasma of difficult-to-test code where you have to return to using a mocking library to "replace" IO functions with fake versions, and then you're on a slippery slope again toward mixing interaction and mutation in one layer.

dnautics
The talk is fantastic. The interesting thing about that talk is that he advocates using a functional style in ruby and quietly suggests that in the end the coder should 'probably use erlang'. It turned out that jose valim was working on elixir at that time, which basically became exactly what gary was asking for (a rubyish erlang). It's a shame that gary doesn't use elixir.
Oct 14, 2020 · aszen on 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 - https://youtu.be/DJtef410XaM

Why integrated tests are a scam - https://youtu.be/VDfX44fZoMc

Boundaries - https://youtu.be/yTkzNHF6rMs

A classic worth watching if any of you haven't seen it! https://www.youtube.com/watch?v=yTkzNHF6rMs
This isn't an article but reading your post reminds me of the presentation by Gary Bernhardt titled "Boundaries", https://youtu.be/yTkzNHF6rMs

I would be interested in looking at the article(s) if you can find them again.

konradb
Thanks, yes the area I think is relevant to Gary Bernhardt's presentations. Thanks for the link.

If I find the article I will reply again to your message.

Mar 12, 2020 · dnautics on 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: https://www.youtube.com/watch?v=yTkzNHF6rMs 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, easier to maintain. I think it's a shame that FP gets this reputation for being 'about ideological purity'. I like using "working programmer's FP", and the FP that I use are built on designs that are driven by real, customer-use-case driven concerns and real-world constraints, and how to make life easier for programmers and operators.

jbjohns
>I'm not arguing for pure functional systems (which I can see going very poorly with relational databases).

Why? The very best "OO" interactions I have with a database are via Linq which is a monad [1]. What it actually does is simply build the plan for what to do in the database and actually do the query at the last possible opportunity. Exactly how it would work in a purely functional setting.

[1 ]https://github.com/louthy/language-ext/wiki/Thinking-Functio...

dnautics
Yes, ecto is basically a monad too (it's based on linq), but at the edges it will violate functional purity.

Linq is functional, but functional-impure.

sojournerc
I largely use the OO patterns to collect related functionality based on the domain.

Many of the methods on those organizational classes are implemented in a functional manner.

I rely on the class/instance pattern for working with a database. static class methods for actions that work on multiple rows, instance methods for single row interactions.

This works especially well in typescript where I can set private/protected/public

That said, I rarely use inheritance except when it's obvious - no nested class hierarchies or other such traps.

Thanks for the video, I'll give it a watch.

Jan 27, 2020 · dnautics on 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.

https://www.youtube.com/watch?v=yTkzNHF6rMs&t=2252s

Here is the infamous Nagappan TDD paper from Microsoft Research

http://research.microsoft.com/en-us/groups/ese/nagappan_tdd....

Also discussed in this infoq article

http://www.infoq.com/news/2009/03/TDD-Improves-Quality

Here's someone's thesis paper on it, with data:

http://www.nomachetejuggling.com/files/tdd_thesis.pdf

There's also interesting discussions like this

http://programmers.stackexchange.com/questions/206355/the-re...

"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

http://programmers.stackexchange.com/a/210756

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 https://www.youtube.com/watch?v=yTkzNHF6rMs

I recommend watching this talk: https://www.youtube.com/watch?v=yTkzNHF6rMs

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.

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 http://alistair.cockburn.us/Hexagonal+architecture 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 https://www.youtube.com/watch?v=yTkzNHF6rMs

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 global event bus, which means my objects don't even know about each other. This makes them easier to specify, which makes them easier to test, which usually results in more focused interfaces and responsibilities.

(1) https://www.youtube.com/watch?v=yTkzNHF6rMs

Chris_Newton
I often plan large-scale UI code as three fundamental levels:

1. Model data

2. View data

3. Rendered data

The model data comes from whatever underlying data store and business rules you are working with.

The view data contains every value you need to render your UI. This typically includes a lot of data taken straight from the model. However, it can also include derived data, perhaps the result of some arithmetic calculation or the outcome of some conditional logic. This is also the level where any view metadata that isn’t persisted in the model lives, for example if you need to keep track of a cursor position, zoom level, contents of a clipboard/kill ring, etc.

The rendered data level only applies if you’re creating your UI using a descriptive/declarative system rather than by calling some sort of API. For example, for a web app, the rendered data would be HTML ready to put into the DOM. At this level, I try to keep the logic trivial; you might need some basic conditional or loop logic in the rendering, but the view data is where anything complicated happens, and the rendering logic in something like an HTML template shouldn’t be more complicated than “if (simple boolean value provided by view data) then (version A) else (version B)” or “for each item in (list provided by view data) do (render individual item)”.

Ideally, the conversions from model data to view data and from view data to rendered data are pure (as in without side-effects) functions, and therefore in principle they are amenable to automated testing techniques in isolation. For example, it is straightforward to add unit tests that calculated view data do have the expected values for sample model data.

In practice, I find automated testing of the view data to rendered data stage has very little value, for two reasons. Firstly, if your rendering stage is basically just filling out templates using view data and the logic is trivial, errors tend to be obvious: a table has no contents, for example, or an entire part of the page disappears. Secondly, my experience is that most of the bugs I find at the rendering level don’t actually originate in the rendering logic. Rather, they tend to be in some accompanying data, such as a CSS stylesheet that didn’t include the right prefixes or got the media queries wrong, or as a bug in the rendering engine itself that is out of your immediate control, such as a browser layout engine bug.

Edit: Of course, the above only describes data going one way through the system. Depending on the application, you might also have interactions that update view meta-data, and in anything beyond pure visualisation code you’ll surely have interactions that need to update the model data. This is also amendable to automated testing, as long as you have reasonable separation between (a) the code that does things like validation, constraint checks and eventually state modification at the model and view levels, and (b) whatever event-handling or other code starts the process. In this case, it’s that event-handling or other trigger code that is the part where bugs tend to be either obvious or outside of your immediate control, and you can have unit test suites for everything below. You can also use tools like Selenium to simulate those initial interactions and test in a more end-to-end fashion in real browsers.

Aug 04, 2013 · 1 points, 0 comments · submitted by tmlee
HN Theater is an independent project and is not operated by Y Combinator or any of the video hosting platforms linked to on this site.
~ yaj@
;laksdfhjdhksalkfj more things
yahnd.com ~ Privacy Policy ~
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.