関数型プログラミングがついに主流になりつつある
関数型プログラミング関する記事がありました。
原文は英語だったので、自分用に翻訳をメモ。
- Functional programming is finally going mainstream
- いったん関数型プログラミングが私の脳で本当に理解されると、「なぜ他の方法でやるのか?」ということになりました。
Functional programming is finally going mainstream
関数型プログラミングがついに主流になりつつある
ついに主流となった関数型プログラミング
OBJECT-ORIENTED AND IMPERATIVE PROGRAMMING AREN’T GOING AWAY, BUT FUNCTIONAL PROGRAMMING IS FINDING ITS WAY INTO MORE CODEBASES.
オブジェクト指向の命令型プログラミングは廃止されていませんが、関数型プログラミングはより多くのコードベースへの道を見つけています。
オブジェクト指向や命令型プログラミングがなくなるわけではありませんが、関数型プログラミングはより多くのコードベースに入り込んできています。
KLINT FINLEY // JULY 12, 2022
KLINT FINLEY//2022年7月12日
クリント・フィンレー // 2022年7月12日
Paul Louth had a great development team at Meddbase, the healthcare software company he founded in 2005.
Paul Louthは、2005年に設立したヘルスケアソフトウェア会社であるMeddbaseに優れた開発チームを持っていました。
ポール・ラウスが2005年に設立した医療用ソフトウェア会社「Meddbase」には、素晴らしい開発チームがあった。
But as the company grew, so did their bug count.
しかし、会社が成長するにつれて、彼らのバグ数も増えました。
しかし、会社が大きくなるにつれて、バグの数も増えていった。
That’s expected, up to a point.
ある程度までは、それは予想されていました。
それはある程度までは想定内です。
More code and more features mean more defects.
より多くのコードとより多くの機能は、より多くの欠陥を意味します。
コードが増え、機能が増えれば、不具合も増える。
But the defect rate was growing faster than Louth expected.
しかし、欠陥率はラウスの予想よりも速く成長していました。
しかし、不良品率はLouth社の予想以上に伸びていた。
“We were seeing more and more of the same types of bugs,” Louth says.
「同じ種類のバグがどんどん見られました」とLouth氏は言います。
「同じ種類の虫がどんどん増えてきたんです」とLouth氏は言う。
“It was clear that there was an issue, but it wasn’t clear what it was. My instinct told me the problem was complexity.”
「問題があることは明らかでしたが、それが何であるかは明確ではありませんでした。 私の本能は、問題は複雑さだと私に言いました。」
"問題があることは明らかでしたが、それが何であるかは明確ではありませんでした。私の直感では、問題は複雑さだと思いました。
Louth and company used C#, which had just happened to add support for Language Integrated Query (LINQ), an alternate language for querying data sources ranging from databases to objects within codebases.
Louthと会社は、データベースからコードベース内のオブジェクトに至るまでのデータソースをクエリするための代替言語である統合言語クエリ(LINQ)のサポートを追加したばかりのC#を使用しました。
C#は、データベースからコードベース内のオブジェクトまで、さまざまなデータソースを照会するための代替言語であるLINQ(Language Integrated Query)のサポートを偶然にも追加していたのだ。
LINQ introduced ways to apply the programming paradigm known as “functional programming” to C# code, and learning about how LINQ worked led him to learn more about functional programming in general.
LINQは、「関数型プログラミング」と呼ばれるプログラミングパラダイムをC#コードに適用する方法を紹介し、LINQがどのように機能するかを学ぶことで、関数型プログラミング全般について学ぶことができました。
LINQは、「関数型プログラミング」と呼ばれるプログラミングパラダイムをC#のコードに適用する方法を紹介しており、LINQの仕組みを学んだことが、関数型プログラミング全般を学ぶきっかけになった。
Functions—chunks of code that can complete a given task again and again within a program, without the need to re-write the code over and over—are a standard part of programming.
関数(コードを何度も書き直す必要なしに、プログラム内で特定のタスクを何度も完了することができるコードのチャンク)は、プログラミングの標準的な部分です。
関数とは、プログラム内で何度も同じ作業を繰り返すことができるコードの塊で、何度もコードを書き直す必要はありません。
For example, you could write a function that returns the circumference of a circle when given its diameter, or a function that returns an astrological sign based on someone’s date of birth.
たとえば、直径が与えられたときに円の円周を返す関数や、誰かの生年月日に基づいて星座を返す関数を作成できます。
例えば、円の直径を与えると円周率を返す関数や、生年月日から星座を返す関数などがある。
But as Cassidy Williams writes in her guide to functional programming for The ReadME Project, functional programming is about more than just writing functions.
しかし、CassidyWilliamsがReadMEプロジェクトの関数型プログラミングのガイドに書いているように、関数型プログラミングは単なる関数の記述以上のものです。
しかし、Cassidy WilliamsがThe ReadME Projectのための関数型プログラミングのガイドで書いているように、関数型プログラミングは単に関数を書くだけではありません。
It’s a paradigm that emphasizes writing programs using “pure functions”: stateless functions that always return the same value when given the same input and produce no “side effects” when returning their output.
これは、「純粋関数」を使用してプログラムを作成することを強調するパラダイムです。つまり、同じ入力が与えられたときに常に同じ値を返し、出力を返すときに「副作用」を生成しないステートレス関数です。
これは、同じ入力があれば常に同じ値を返し、出力を返す際に「副作用」を発生させないステートレスな関数である「純粋関数」を使ってプログラムを書くことを重視するパラダイムである。
In other words, pure functions don’t change any existing data or modify other parts of an application’s logic.
つまり、純粋関数は、既存のデータを変更したり、アプリケーションのロジックの他の部分を変更したりすることはありません。
言い換えれば、純粋な関数は、既存のデータを変更したり、アプリケーションのロジックの他の部分を変更することはありません。
If our circumference function changed a global variable, for example, it wouldn’t be pure.
たとえば、円周関数がグローバル変数を変更した場合、それは純粋ではありません。
例えば、円周率関数がグローバル変数を変更したとしたら、それは純粋なものではありません。
In functional programming, data is generally treated as immutable.
関数型プログラミングでは、データは一般に不変として扱われます。
関数型プログラミングでは、一般にデータは不変なものとして扱われる。
For example, instead of modifying the contents of an array, a program written in a functional style will produce a copy of the array with the new changes made.
たとえば、配列の内容を変更する代わりに、機能的なスタイルで記述されたプログラムは、新しい変更が加えられた配列のコピーを生成します。
例えば、関数型で書かれたプログラムは、配列の内容を変更するのではなく、新しい変更を加えた配列のコピーを生成します。
Unlike object-oriented programming, where data structures and logic are entwined, functional programming emphasizes a separation of data and logic.
データ構造とロジックが絡み合うオブジェクト指向プログラミングとは異なり、関数型プログラミングはデータとロジックの分離を強調します。
データ構造とロジックが一体化したオブジェクト指向プログラミングとは異なり、関数型プログラミングではデータとロジックの分離が重視される。
“When you think about well-structured software, you might think about software that’s easy to write, easy to debug, and where a lot of it is reusable,” writes Williams, head of developer experience at Remote, a company that uses the functional programming language Elixir for their back-end software.
「適切に構造化されたソフトウェアについて考えるとき、記述しやすく、デバッグしやすく、その多くが再利用可能なソフトウェアについて考えるかもしれません」と、関数型を使用する会社であるRemoteの開発者エクスペリエンスの責任者であるWilliamsは書いています。 バックエンドソフトウェア用のプログラミング言語Elixir。
関数型プログラミング言語Elixirをバックエンドソフトウェアに使用しているRemote社の開発者体験責任者であるWilliams氏は、「よく構造化されたソフトウェアというと、書きやすく、デバッグしやすく、その多くが再利用可能なソフトウェアを想像するかもしれません」と書いています。
“That’s functional programming in a nutshell!”
「それは一言で言えば関数型プログラミングです!」
"これが関数型プログラミングだ!"
Functional programming can be a boon for growing teams working with large codebases.
関数型プログラミングは、大規模なコードベースで作業する成長中のチームにとって恩恵となる可能性があります。
関数型プログラミングは、大規模なコードベースを扱う成長中のチームにとって有益なものです。
By writing code with few side effects and immutable data structures, it’s less likely that a programmer working on one part of a codebase will break a feature another programmer is working on.
副作用がほとんどなく、データ構造が不変のコードを作成することで、コードベースの一部で作業しているプログラマーが、別のプログラマーが作業している機能を壊す可能性が低くなります。
副作用が少なく、不変のデータ構造を持つコードを書くことで、コードベースのある部分を担当しているプログラマーが、他のプログラマーが開発している機能を壊してしまう可能性を低くすることができます。
And it can be easier to track down bugs since, as Williams writes, there are fewer places in the code where changes can take place.
また、Williamsが書いているように、コード内で変更を行うことができる場所が少ないため、バグの追跡が容易になる可能性があります。
また、Williams氏が書いているように、コードに変更を加えられる箇所が少ないので、バグの追跡が容易になる。
As Louth delved deeper into the world of functional programming, he realized the approach could help solve some of the problems that large-scale, object-oriented codebases presented, such as those his team was starting to run into at Meddbase.
Louthが関数型プログラミングの世界を深く掘り下げていくと、彼のチームがMeddbaseで遭遇し始めた問題など、大規模なオブジェクト指向コードベースが提示した問題のいくつかを解決するのにこのアプローチが役立つ可能性があることに気付きました。
ルースは、関数型プログラミングの世界を深く掘り下げるうちに、このアプローチが、Meddbaseで彼のチームが直面し始めたような、大規模なオブジェクト指向のコードベースが抱える問題の解決に役立つと気づいたのだ。
He wasn’t alone.
彼は一人ではありませんでした。
彼は一人じゃなかった。
Interest in functional programming has exploded over the past decade as more and more developers and organizations look for ways to tame complexity and build more secure, robust software.
関数型プログラミングへの関心は、複雑さを抑え、より安全で堅牢なソフトウェアを構築する方法を模索する開発者や組織が増えるにつれて、過去10年間で爆発的に増加しました。
関数型プログラミングへの関心は、過去10年間に爆発的に高まりました。より多くの開発者や組織が、複雑さを緩和し、より安全で堅牢なソフトウェアを構築する方法を探しているからです。
“Once functional programming really clicked in my brain, I was like ‘why do it any other way?’” says Williams, who fell in love with functional programming during a college class that used the LISP programming language dialects Scheme and Racket.
「関数型プログラミングが本当に頭に浮かんだら、「なぜ他の方法でやるのか」と思ったのです」と、LISPプログラミング言語の方言SchemeとRacketを使用した大学の授業中に関数型プログラミングに夢中になったWilliamsは言います。
ウィリアムズさんは、大学でLISP言語の方言であるSchemeとRacketを使った授業で、関数型プログラミングに夢中になったそうです。「関数型プログラミングが頭に入ったら、『なぜ他の方法をとるのか』と思いました。
“Object-oriented programming isn’t bad, it still runs a lot of the world. But a lot of developers become evangelical about functional programming once they start working with it.”
「オブジェクト指向プログラミングは悪くありませんが、それでも多くの世界で実行されています。 しかし、多くの開発者は、関数型プログラミングを使い始めると、関数型プログラミングについて福音主義になります。」
"オブジェクト指向プログラミングは悪くないし、今でも世界の多くを動かしている。しかし、多くの開発者は、ひとたび関数型プログラミングを使い始めると、その伝道師となるのです。"
Sure, object-oriented and imperative programming remain the dominant paradigms for modern software development, and “pure” functional programming languages like Haskell and Elm are relatively rare in production codebases.
確かに、オブジェクト指向で命令型プログラミングは、現代のソフトウェア開発の主要なパラダイムであり続けており、HaskellやElmのような「純粋な」関数型プログラミング言語は本番コードベースでは比較的まれです。
確かに、現代のソフトウェア開発では、オブジェクト指向や命令型プログラミングが依然として主流であり、HaskellやElmのような「純粋な」関数型プログラミング言語は、実運用コードベースでは比較的まれである。
But as programming languages expand support for functional programming methods and new frameworks embrace alternative approaches to software development, functional programming is quickly finding its way into a growing number of codebases through a variety of different avenues.
しかし、プログラミング言語が関数型プログラミング手法のサポートを拡大し、新しいフレームワークがソフトウェア開発への代替アプローチを採用するにつれて、関数型プログラミングはさまざまな方法でますます多くのコードベースに急速に浸透しています。
しかし、プログラミング言語が関数型プログラミングのサポートを拡大し、新しいフレームワークがソフトウェア開発への代替アプローチを採用するにつれ、関数型プログラミングは様々な手段で急速に多くのコードベースに入り込むようになっています。
いったん関数型プログラミングが私の脳で本当に理解されると、「なぜ他の方法でやるのか?」ということになりました。
“Once functional programming really clicked in my brain, I was like ‘why do it any other way?’”
「関数型プログラミングが本当に私の脳の中でクリックされると、私は「なぜそれを他の方法で行うのか」のようでした。」
"ファンクショナル・プログラミングが私の脳で本当に理解されると、"なぜ他の方法をとるのか "ということになったんです」。
主流言語における関数型プログラミングの台頭
Rise of functional programming in mainstream languages
主流言語での関数型プログラミングの台頭
主流言語における関数型プログラミングの台頭
Functional programming’s origins stretch back to the early days of programming languages with the creation of LISP in the late 1950s.
関数型プログラミングの起源は、1950年代後半にLISPが作成されたプログラミング言語の初期にまでさかのぼります。
関数型プログラミングの起源は、1950年代後半のLISPの誕生によるプログラミング言語の黎明期にまでさかのぼる。
But while LISP and its dialects like Common LISP and Scheme retained a devoted following for decades, object-oriented programming eclipsed functional programming in the 1970s and 1980s.
しかし、LISPと、Common LISPやSchemeのようなその方言は、何十年にもわたって熱心な支持者を維持していましたが、オブジェクト指向プログラミングは、1970年代と1980年代に関数型プログラミングを凌駕しました。
しかし、LISPとその方言であるCommon LISPやSchemeが何十年も熱狂的な支持を得たのに対し、オブジェクト指向プログラミングは1970年代から1980年代にかけて関数型プログラミングに取って代わられた。
By 2010, interest in functional programming came roaring back as developers found themselves working with ever-larger codebases, and teams faced the same problems as Louth and his development team.
2010年までに、開発者がますます大きなコードベースで作業していることに気づき、関数型プログラミングへの関心が高まり、チームはLouthと彼の開発チームと同じ問題に直面しました。
2010年になると、関数型プログラミングへの関心が再び高まり、開発者はより大規模なコードベースを扱うようになり、Louth氏と彼の開発チームと同じような問題に直面するようになった。
Scala and Clojure brought functional programming to the Java Virtual Machine, while F# brought the paradigm to .NET.
ScalaとClojureは関数型プログラミングをJava仮想マシンにもたらし、F#はパラダイムを.NETにもたらしました。
ScalaとClojureはJava Virtual Machineに関数型プログラミングをもたらし、F#は.NETにそのパラダイムをもたらした。
Twitter migrated much of their code to Scala, and Facebook deployed venerable functional languages like Haskell and Erlang to solve specific problems.
Twitterはコードの多くをScalaに移行し、Facebookは特定の問題を解決するためにHaskellやErlangなどの由緒ある関数型言語を導入しました。
Twitterはコードの多くをScalaに移行し、Facebookは特定の問題を解決するためにHaskellやErlangといった由緒ある関数型言語を導入しています。
Meanwhile, interest grew in applying functional programming techniques in object-oriented languages like JavaScript, Ruby, and Python.
一方、JavaScript、Ruby、Pythonなどのオブジェクト指向言語で関数型プログラミング手法を適用することへの関心が高まりました。
一方、JavaScript、Ruby、Pythonなどのオブジェクト指向言語において、関数型プログラミングの技術を応用することに関心が高まった。
“All those languages increasingly support features that make it easier to do a functional style,” says Elm in Action author Richard Feldman.
「これらの言語はすべて、機能的なスタイルを簡単に実行できる機能をますますサポートしています」と、ElminActionの著者であるRichardFeldmanは述べています。
Elm in Actionの著者であるRichard Feldman氏は、「これらの言語はすべて、関数型スタイルを容易にする機能をサポートするようになってきています」と述べています。
“Nearly every language is increasingly multi-paradigm.”
「ほぼすべての言語がますますマルチパラダイムになっています。」
"ほぼ全ての言語がマルチパラダイム化している"
In 2014, Apple introduced Swift, a new, multi-paradigm language that includes robust support for functional programming.
2014年、Appleは関数型プログラミングの強力なサポートを含む新しいマルチパラダイム言語であるSwiftを発表しました。
2014年、Appleは関数型プログラミングの強固なサポートを含む、新しいマルチパラダイム言語であるSwiftを発表しました。
The launch proved that functional programming support had become a must-have feature of new programming languages, just as support for object-oriented programming already was.
In a 2019 talk titled “Why Isn’t Functional Programming the Norm?” Feldman concluded that the functional style of programming is indeed becoming the norm.
Or at least part of the norm.
“Something has changed,” he said.
“This style is not something people were considering a positive thing in the 90s, and the idea that it is a positive has become sort of mainstream now.”
The level and nature of support for functional programming vary by language, but one particular feature has become standard. “The thing that has seemingly ‘won,’ so to speak, is higher-order functions—functions that accept or return another function,” says Tobias Pfeiffer, a back-end engineer at Remote. “This lets you create blocks of functions to elegantly solve problems.”
Support for higher-order functions has made it possible for developers to bring functional programming into their codebases without re-architecting existing applications. When Louth and his team decided to shift to a functional programming model, they settled on using F# for new code in existing applications, since it provides robust functional support while maintaining compatibility with the .NET platform. For existing C# code, they employed the language’s own support for functional programming, along with language-ext, Louth’s own open source framework for functional C#.
“A full rewrite wasn’t an option,” Louth says. “So when we add new features to existing code, we write it following a functional programming paradigm.”
For some, using an object-oriented language like Java, JavaScript, or C# for functional programming can feel like swimming upstream. “A language can steer you towards certain solutions or styles of solutions,” says Gabriella Gonzalez, an engineering manager at Arista Networks. “In Haskell, the path of least resistance is functional programming. You can do functional programming in Java, but it’s not the path of least resistance.”
A bigger issue for those mixing paradigms is that you can’t expect the same guarantees you might receive from pure functions if your code includes other programming styles. “If you’re writing code that can have side effects, it’s not functional anymore,” Williams says. “You might be able to rely on parts of that code base. I’ve made various functions that are very modular, so that nothing touches them.”
Working with strictly functional programming languages makes it harder to accidentally introduce side effects into your code. “The key thing about writing functional programming in something like C# is that you have to be careful because you can take shortcuts and then you’ve got the exact sort of mess you would have if you weren’t using functional programming at all,” Louth says. “Haskell enforces the functional style, it encourages you to get it right the first time.” That’s why Louth and his team are using Haskell for some of their entirely new projects.
But purity is often in the eye of the beholder. “LISP is the original functional programming language and it has mutable data structures,” says Pfeiffer. Even if your language is purely functional and uses immutable data structures, impurity is introduced the moment you include user input. While user input is considered an “impure” element, most programs wouldn’t be very useful without it, so purity only goes so far. Haskell manages user input and other unavoidable “impurities” by keeping them clearly labeled and discrete, but different languages have different boundaries.
Expanding the functional mindset
Even though functional programming is now available in most major programming languages, developers aren’t necessarily taking advantage of those features. The functional programming approach requires a substantially different way of thinking about programming than imperative or object-oriented programming. “What blew my mind was that you couldn’t do traditional data structures in functional programming,” Williams says. “I didn’t have to make an object for a tree, I could just do it. It feels like it shouldn’t work, but it does.”
The JavaScript library React is one of the biggest ways that developers are exposed to this new way of thinking today. Because React allows for so much mutability, it’s probably best to think of it as “functional adjacent,” but the ecosystem does enable and promote functional solutions to common programming problems that would traditionally be solved with other methods.
“Even though it looked object-oriented, React provided the first functional-friendly approach to UI programming,” wrote David Nolen, maintainer for ClojureScript, a LISP dialect that compiles to JavaScript, in his story for The ReadME Project.
For example, the recently-introduced React Hooks are a set of functions that help developers manage state and side effects, while Redux—a popular library for managing state often used with React and other front-end libraries—takes a largely functional approach.
“React encourages people to think in a more functional way, even if it isn’t purely functional,” Williams says. “For example, it introduces front-end developers to the idea of using map and reduce functions instead of ‘for’ loops. You can now be a full-time front-end developer and never write a single for loop.” Check out Williams’ guide for an example of how this might work in JavaScript.
Meanwhile, Gonzalez sees functional programming becoming more mainstream through still another avenue: domain-specific languages. Being really good at one thing is often an easier route to adoption. For example, the Nix package management system’s expression language. “It’s even more purely functional than Haskell is, in the sense that it is even harder to write with side effects or mutability,” she says. Nix won’t be useful for, say, building a web server. It’s intended for only one purpose: building packages. But because it’s built for that specific task, developers who need a build tool might use it even if they wouldn’t otherwise try a functional programming language. “I think as time goes on you’ll see fewer general-purpose languages and more specialized languages,” she says. “Many of those will be functional.”
“React encourages people to think in a more functional way, even if it isn’t purely functional."
Building the future of functional programming
Like so much else in software development, functional programming’s future largely depends on the open source communities built around functional languages and concepts. For example, one barrier to pure functional programming adoption is simply that there are far more libraries written for object-oriented or imperative programming. From mathematics and scientific computing packages for Python to web frameworks for Node.js, it makes little sense for individuals to ignore all of this existing code that solves common problems just because it’s not written in a functional style. This is something Louth sometimes experiences with Haskell. “It has a fairly mature ecosystem, but it’s pockmarked by abandoned or unprofessional libraries,” he says.
To overcome that obstacle, the functional programming community will have to come together to create new libraries that make it easier for developers to choose functional programming over more side effect–prone approaches.
From the language-ext library to Redux to Nix, that work is already in progress.