Interview with David Barri

My name's David Barri. I fell in love with programming at the age of 8 (I'm now 40) and been programming ever since. I've worked on all kinds of projects in a number of different languages. These days I'm primarily focused on two startups that I founded, but I also do short-term contracts occasionally, and a lot of open-source work.

What is your functional programming background?

I discovered both FP and Scala back in early 2013 and it's changed my life. It took years of study and thought to learn FP, and years of experience to learn how to apply it properly in "the real-world". The practical benefit is profound and hard to understate. I love learning new techniques and concepts but I'm personally pretty strict to draw a line between "fun and interesting to learn" vs "provides real value in a real project with real human (and imperfect) team mates". Thankfully most things I learned in FP do indeed provide real value, and so while it doesn't excite me as much as it used to, I still use it every day because it's just so effective. The differences in code quality, reliability and basically just how much confidence you can have in your software, are huge now with FP vs in my past without FP. I like to write code, get it working, then just completely forget about it. In terms of devops I want to just know that if it compiles and tests pass, I can push it into production and just forget about it. Of course things do go wrong but it's extremely, extremely rare now compared to my non-FP days.

I'm lucky I started ShipReq at around the same time I started learning FP. One of the reasons that ShipReq has been very slow in its development, was that I decided I wasn't going to rush a quick MVP out the door. The whole project started as a response to the status quo in the programming industry which was this growing culture of just getting half-working half-considered shit released, frustrating and disrespecting your user-base, and then constantly just reacting to all the biggest fires. Obviously not all software is created in those circumstances but I was personally affected for years by a lot of software made with that attitude, and so I rebelled and set out to test (and bet on) my belief that going slow at the beginning lets you go really fast in the future. I started learning FP a few months after I started building ShipReq and so as I was learning FP, I would slowly start introducing it into the ShipReq codebase, sometimes because what I'd just learned would immediately solve a real problem I had, sometimes just because a new technique had promise and so I'd give it a try. Usually it worked out very well, sometimes I worked my ass off to end up with something that technically worked very well but was so complex and confusing that it was way too hard to use or understand. Through those experiences I learned to come back down to Earth and consider the bigger picture: just because you're using a cool FP technique doesn't mean it's good for you or the project. I later ended up replacing those crazy complex FP sections with simple FP sections and a little more boilerplate. Much better and a very valuable lesson. But yeah, pretty much all of the code written in the first 6 months was eventually replaced with superior, simple FP. The fact that I had the freedom to not rush, but instead focus on codebase quality, and learning to apply FP practically, changed my life. I consider myself very proficient at FP now, and yet I usually write simple FP code these days, because the trick I learned through experience is that the perfect solution is usually pretty simple but it takes time to recognise which simple solution is required for each situation. Some of my friends knew all of the FP theory and could pass any technical interview, but when I worked with them they struggled to use FP effectively. Theory itself isn't enough. It's great to see more people learning FP than ever before, but I think we also need to start teaching more practical application in addition to just theory. If employers would grant their teams some time and freedom to experiment with FP on their real work projects, then sure, productivity will decrease in the short-term but in the long-term it rises to be way higher, which I think is a very good investment.

What is your current project you work on?

I'm working on

  • ShipReq (which is a very large and ambitious project)
  • a yet-undisclosed smaller-scale project
  • I'm just about to take 2 months or so to focus full-time on a big batch of improvements to all of my OSS, with scalajs-react getting the majority of the attention

What software do you use for functional programming?

In my opinion the best two languages in the world for writing serious apps with FP are Scala and Haskell. Haskell's awesome but I prefer Scala for a number of reasons. The tools I rely on most are:

  • Scala itself - very strong and expressive types; allows for very powerful FP but also allows mutable OO. In my case pretty much all of the code I write is pure FP with OO for organisation. Being able to write very low-level mutable code is a very valuable tool when you have code on the hot-path that you want to be as fast as possible. Beginners might think mutability and FP are mutually-exclusive but that's not the case. It's a useful strategy to write a referentially-transparent FP function that uses non-leaky mutability under-the-hood to be lightning fast.
  • Scala.JS - I can write normal fully-powered Scala and compile to JS. This allows me to share huge amounts of code between client and server; very valuable. The JS output executes very fast. Unfortunately the JS size is a bit big -- not so big that it's unacceptable -- but still bigger than I'd like. It's an acceptable trade-off to me as I can mitigate it by pre-compressing before serving, using a CDN, and using effective client-side caching.
  • scalajs-react - this is my #1 tool for writing FP UIs. With scalajs-react I'm able to write large and very complex webapps (usually SPAs) and have all of the code be pure FP.
  • any optics library (I use Monocle https://www.optics.dev/Monocle/) - If you don't know what I mean by "optics", I basically mean constructs like lens, prisms, traversals, etc. For non FP practitioners, they're basically classes that allow you to read and/or write some kind of nested or encapsulated data. A lens for example, is the combination of a getter and a setter, that is coupled to a data type but decoupled from any data value; that you can then use with any compatible data instance.
    Not only is it a highly useful tool in any programmers repertoire, but in the context of an FP UI it's crucial to writing your UI code and having it be decoupled and modular. This makes parts of your UI more reusable, more resilient to changes elsewhere in the codebase, and very easy to test. I've got two online scalajs-react demos that I hope demonstrate this:
  • https://japgolly.github.io/scalajs-react/#examples/state-snapshot-1 <-- small and trivial demo
  • https://japgolly.github.io/scalajs-react/#examples/state-snapshot-2 <-- larger example demonstrating FP + full decoupling/modularity
  • a general FP library like Cats (or the older Scalaz) brings in what is basically the FP stdlib. So Monad, Monoid, blah blah blah.
  • for DB interaction I love doobie (https://github.com/tpolecat/doobie)
  • an effects library is a must in any FP app - an app that doesn't interact with any external endpoints (network, screen, keyboard) is effectively just a calculator, nearly all apps interface with the outside world. Effects libraries give you a bunch of tools to do this in an FP way. Not only does that keep your code nice and predictable, but it also makes it easier (than imperative code). Error handling, retries, timeboxing, rate-limiting, caching safely, parallelising - these are all important and effects libraries make these easy to do. The big two Scala effects libraries are Zio and cats-effect.
  • There's a library of mine called ClearConfig (https://github.com/japgolly/clear-config). You define all of your config in an FP way and then at runtime you can get reports telling you exactly what config was used, and where it came from. The value of FP allows mechanical introspection so you get those reports for free! Those reports have regularly saved both myself and teams I've worked with, by making it very very clear why certain config is being applied or not being applied. Even simple typos like "blah.recieve.limit = 3" not working because it was supposed to be "blah.receive.limit = 3" become really obvious when looking at the report.
  • Property testing - invaluable
  • Separately to property testing is the ability to generate random data. Very useful for performance testing. In my case I use my own Nyaya library. Unlike other property testing libraries, it's more modular: the random data generation is decoupled from properties which are decoupled from property testing. Also (as far as I know) the random data generation is the fastest (by a long shot) in the Scala/JVM ecosystem.
  • There's a library of mine called Scala Test-State (https://github.com/japgolly/test-state) Not many people know about it but it's a fantastically useful tool for testing my FP UI. I write (FP) Scala for my Scala.JS UI unit tests and it executes directly in a JS environment (so Node or the now-deprecated Phantom.JS) without any external dependencies. Much faster than launching a real service and a real browser, and communicating via Selenium. That being said, you can run the same test-state test through Selenium too! test-state supports external web testing with Selenium. So you keep the same test code and just change the configuration. In fact, it's even better than Selenium because it can (optionally) use a combination of Selenium and Jsoup under-the-hood to be something like 10x faster and it's all just config changes for test-state end-users.
  • TLA+ - this one's a bit unexpected, in that it's not a tool that you use directly from your software. It's software that allows you to write very abstract code, specify certain properties, and then check that those properties always hold. You don't just model the code that you're going to write for your app, you also model everything relevant in your little universe: for example, you might model the network itself, and the servers that exist in production. Everything is super abstract so we're not talking about days of work, it's much faster. In one case I forgot to model a type of server in my system, and I managed to add it in 15min, and then start seeing how this type of server going down will effect everything else in my ecosystem. The TLA+ model checker can then test every possible combination of events in your abstract universe and find crazy bugs that you'd never catch without it. Stuff like if a user clicks submit, and then worker #1 goes down just as worker #2 is starting up then the user gets the wrong kind of response and their account gets into a broken state. That's a very simple example. The models your write in TLA+ are all immutable data that can change with each event, which is basically FP. Sometimes TLA+ can be useful just to find an FP-way of modelling something difficult. The biggest use case I can think of is proving eventual consistency - it's fantastic for that.

Who are the audience you would recommend to use ShipReq?

I'd recommend ShipReq to any kind of team or individual that works on a creative endeavour. Anyone who needs to record requirements, or user feedback, or tracks bugs, or even wants somewhere to store design documents. It's a replacement for storing markdown files locally, or writing docs in MS Word, or tracking things in MS Excel, or using JIRA. It currently has quite a lot of functionality, but because the vision is so large there are still many features it doesn't have yet. As such some JIRA users would be very happy to use it already, some others would probably want to hold off until certain other features are included.

Also it's all a little bit moot because we're currently operating under a closed beta, and not accepting new beta users for a while longer. Realistically the doors probably won't open to the public until sometime in the later half of the year. There are a few reasons for this. One is that some of the innovations aren't strong enough yet to stand up to real-world usage, and so we're working to evolve those fundamentals to handle more real-world complexity and nuances, which can be quite disruptive.

Once the doors are open to the public and the peripheral stuff like help guides and tutorials are in place, I hope it's something that will bring happiness to anyone interested. My original motivation was to improve the state of the industry and improve the lives of all of us who work in the industry (I consider myself user #1). In a perfect world it would just be free and everyone interested could use it right now but unfortunately, it literally costs money to develop and maintain ShipReq, and we need to scale slowly at the beginning and walk a balance. This isn't a promise but I'm hoping in the future we'll be able to offer free use to individuals, small businesses, students, non-for-profits, and OSS projects.

In summary I can't recommend it to any audience at the moment because the doors are closed, and I don't want to waste anyone's patience. Even though we have real users and real functionality already in production, I worry that sitting in a mailing list for months without any public activity would ultimately give the impression of vapourware and lead to disappointment. If anyone is ok with that and happy to receive updates as we get closer to onboarding new beta users and/or allowing public access, they feel free to subscribe to the mailing list on shipreq.com.

Добавить комментарий

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Помогла вам эта статья?

Не нашли ответ на свой вопрос? Возможно, вы найдете решение проблемы на нашем канале в Youtube! Здесь мы собрали небольшие, но эффективные инструкции. Смотрите и подписывайтесь на наш youtube-канал!

Смотреть на Youtube