Parallel to Procedural Programming
, and at the same level of observation about software architecture from sub-program
is the Functional Programming
paradigm. At that time, we have reviewed and compared some features of Procedural
and Functional
side-by-side.
However, within the framework of a short introduction, there are still many details that I cannot bring in to introduce these programming models. And in particular, after going through the Sub-Series Ada
, it becomes even more obvious that the programming tools and related concepts, provided by a language designed with a focus on Procedural
, have many parts. cannot be listed in one article.
And now is the right time to dive into the details of the tools and related concepts that a language designed with a focus on Functional
has to offer. In fact, to learn about Functional Programming
seriously and use the advantages of Functional
, the most favorable environment right now is the Haskell
language. However, in order to maintain the appropriate amount of memory-memory syntax, I chose the reference learning method from Haskell
and implemented it in Elm
with all the capabilities that Elm
has.
Although it is also a purely Functional
language, compared to Haskell
, Elm
supports less code representation syntax and only comes with just enough basic architectural tools. Some of the concepts about the Functional
code generation tools that are already supported by Haskell
such as Type Class
, Functor
, Monad
, etc.. when we want to use it in Elm
, we will have to define the simulation ourselves. However, it will also allow us to better understand these tools and better grasp functional programming thinking.
Functional Aspects
In Elm
‘s previous Sub-Series, we talked about Declarative Programming
– one of the two basic paradigms for writing a piece of code that describes the logic that needs to be performed by the computer. However, Declarative
is like Imperative
, only talking about expressing logic at the detail level, not at the program architecture level. And then, when we start to care about the design and organization of sub-program
, we have Procedural
and Functional
.
That means that a Procedural
language can also be designed with a syntax used in a Declarative
form, such as SQL
; And a Functional
language can also be designed with syntax used in the Imperative
form, such as F-sharp
. However, it is true that purely Functional
languages use Declarative
syntax, and the vast majority of Procedural
languages use Imperative
syntax.
In this Sub-Series, we will only cover the Functional
aspect expressed in Elm
to learn and be able to implement in Imperative
languages like JavaScript
if desired.
first-class function & function composition
higher-order function & currying function
type variable & type class
functor & applicative
monad & monoid
The above is a list of some features and concepts related to Functional Programming
that we will learn in this Sub-Series with reference from Haskell
. And in this introductory article we will talk about the concepts of First-Class Function
and Function Composition
.
First-Class Function
This is the most basic and most important feature for any language to be considered as supporting Functional Programming
. The concept of First-Class Function
is a short way of saying the sentence Function is First-Class Citizen
– which can be roughly understood as Function
are classified as the most important components of the software, equivalent to the Type Data Type
. . And the expression to be supported is a Function that can be viewed as a Value
, can be assigned to variables, can be used as operands of an expression between Functions, can be passed into another Function call, and possibly the return result of a certain Function call.
A Function can be assigned to a variable for storage and later use.
It is for this reason that although you may not touch purely Functional
languages, when you walk around some popular programming languages to refer to features and syntax, there is a great chance that you will encounter many the case of a function definition in some languages that support writing in the form of an expression with the assignment =
to a certain identifier name. This type of syntax is exactly what comes from Functional Programming
.
module Main exposing ( main )
import Html exposing ( Html , text )
main : Html message
main = text ( greet "Elm" )
greet : String -> String
greet name = "Hello " ++ name ++ " again !"
And in JavaScript
as we know it from the First Web Programming Series:
// -- greet : String -> String
const greet = ( name ) => "Hello" + name + "again !"
Hmm… the location of the =
assignment seems to be somewhat different. In Elm
‘s example code, we are describing the mathematical function f(x) = ... x ...
, and where the position of f
is greet
and the position of x
is name
; In the JS
example code, the position adjective (name) => ...
has the same meaning as the definition in Elm
and creates an anonymous function f
to assign to the greet
constant.
However, we can also modify Elm
‘s main
code to show more clearly that – Function
is a Value
just like any other data type. Try assigning the greet
function to a variable in main
, then calling the function using this variable name.
-- module ...
main : Html message
main =
let make = greet
in text ( make "Elm" )
-- greet : ...
Function Composition
The concept of Function Composition
appeared concurrently with First-Class Function
, because the purpose of seeing a Function Function
as a Value
and the requirement to design a language that supports storing Functions in variables is for them to we can do math on functions and then get an all-in-one
summation function and store it in a variable. Then apply this function on the input
data and get the output
result.
This idea is also borrowed from Mathematics. When we have the expression h(x) = f(g(x))
then we can also write h = f . g
to denote that the function h
is the result obtained by combining the function f
and the function g
.
main : Html message
main =
let make = text << greet
in make "Elm"
Here we have the code Hello, Elm !
rewritten with main
defined as the result obtained after calling make
with the string "Elm"
, and make
now defined as the combined function generated from the text
function and the greet
function. This form of writing code will be used a lot in the Main Functions that control the main operation logic of the program, equivalent to the role of Procedures in the Procedural
environment; Because as we all know, in the Procedural
environment, function
only play the role of a sub-program
to support the main procedure
that control the main operation logic just below the level of main
.
Regarding the division of roles between Main Functions and Utility Functions that support computational operations, there is no convention in the Functional
environment. It is all completely the choice of the coder when designing the Functions and having to take notes or give the naming convention
to arrange themselves. However, a common feature of Functional
languages is to be very careful in separating the side-effect
code that affects the external environment from the code that handles the main logic, so we will soon learn the pattern
implementation is applied to this.
A small note about the operation of combining the <<
function that we just used, that is, in case we want to write a list of functions in the opposite direction according to Imperative
thinking, we can use the notation. sign >>
.
main : Html message
main =
let make = greet >> text
in make "Elm"
In an earlier Sub-Series Declartive
, we used the <|
implementation or |>
to pass the result of a function call into another function on the left or right side. However, it is not a Function Composition
but is still a stacked function call, and the call priority is adjusted thanks to alternative implementations of parentheses ()
.
The purpose of the <<
and >>
combined implementations is to provide another method for structuring the program. Chances are, if you build a complex enough application, in your program in addition to the data-flow
there will also be the flow of functions across the execution points of the combination of functions.