Functional Aspects

Tram Ho

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.

Share the news now

Source : Viblo