Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Chapter: Introduction to Functional Programming #56

Merged
merged 9 commits into from
Apr 22, 2018

Conversation

crphang
Copy link
Contributor

@crphang crphang commented Apr 4, 2018

A high level introduction to Functional Programming.

@crphang
Copy link
Contributor Author

crphang commented Apr 4, 2018

@LiHaoTan Since your chapter on Rust has got to do with Functional Programming, would appreciate if you can take a look at this PR!

@LiHaoTan LiHaoTan self-assigned this Apr 4, 2018
Copy link
Contributor

@tran-tien-dat tran-tien-dat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Chun Rong. Couldn't sleep yet so I read your book chapter. Nice introduction to functional programming. Would be more comprehensive if you can also talk about the disadvantages of functional programming, or when would we not want to use functional programming.

print(length_of_names) # [4,6,4]
```

The function creates a new collection, run the function on each element of the given collection, insert the new values and return the new collection.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This explanation of map is not very clear for a beginner. It doesn't even mention the name map so it may not be obvious to the reader. It also repeats words like function, collection many times, and each instance of the word refers to a different function/collection. I suggest something like: "map takes in 2 parameters, the first one is a function and the second is a collection. map returns a new collection whose elements are the result of applying the given function on the elements of the given collection". Even better, I think you can refer to the example you quoted, e.g. "In the example, map is given a function len and a collection ['Alex', 'Thomas', 'John']. It returns [len('Alex'), len('Thomas'), len('John')]."

@crphang
Copy link
Contributor Author

crphang commented Apr 5, 2018

@tran-tien-dat Thanks a lot for the review! I've added the changes.

Copy link
Contributor

@tran-tien-dat tran-tien-dat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great 👍

Copy link
Contributor

@LiHaoTan LiHaoTan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is an overall very nice introduction to functional programming that addresses the relevant points.

Just mostly some nits and suggestions


Functional Programming is simply a paradigm and needs to be implemented by programming languages. Below are various [languages](https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Functional_languages) that have explicit support for Functional Programming paradigm such as:

- Haskell
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm wondering why these selected languages? Like Haskell is famous, Clojure got more popular, Elixir works on the Erlang VM, Elm translates to Javascript. But it seems the ML family of languages ought to deserve a mention too?


## What is Functional Programming

Functional Programming is a programming paradigm designed based on mathematical functions and avoid mutating state and data. Unlike procedure programming languages like C, Java and Python, Functional Programming languages are [declarative](https://en.wikipedia.org/wiki/Declarative_programming). Even though this demands a shift in mindset from most programmers who are used to imperative form of programming, Functional Programming paradigm is still [increasingly popular](https://blog.appdynamics.com/engineering/the-most-popular-programming-languages-for-2017/) due to its [advantages](#advantages-of-functional-programming).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a nit but I think it should be Functional programming, not capitalized (across the document).

Also, I think Wikipedia's definition reads better:

that treats computation as the evaluation of mathematical functions

designed based on mathematical functions

The second one seems more vague?

Also I think instead of procedural, we should use imperative.


#### Pure Functions

Pure functions is one of concepts in functional programming. To call a function `pure`, it needs to satisfy two conditions:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... one of the ...

Pure functions is one of concepts in functional programming. To call a function `pure`, it needs to satisfy two conditions:

1. [Idempotence](https://en.wikipedia.org/wiki/Idempotence) - The function should return the same output for the same input.
1. No Side Effects - The function should not cause side effects like mutating global state.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just like functional programming, I don't think Side Effects should be capitalized.

1. [Idempotence](https://en.wikipedia.org/wiki/Idempotence) - The function should return the same output for the same input.
1. No Side Effects - The function should not cause side effects like mutating global state.

To illustrate an example of a pure function. Consider this simple example:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should mention ...this simple example in Python:


> Higher Order Functions are functions that take functions as parameters, return functions or both.

Functions are first class citizen in Functional Programming languages, this mean that functions can be passed around like objects and values.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first class citizens

And practically I don't think it makes much difference differentiating higher order and first-class functions but I think a brief note and link they are different will help prevent confusion?

https://en.wikipedia.org/wiki/Functional_programming#First-class_and_higher-order_functions


The common question when learning about Functional Programming is what's the point of having us going through all the trouble of having pure functions, state immutability and absence of loops. Turns out, there are various positive implications of Functional Programming:

- [More Bug-Free Code](https://www.quora.com/Are-software-written-using-Functional-Programming-less-buggy-more-robust-and-stable)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can strengthen this with the infamous Haskell:

More Bug-Free Code, for example famously in Haskell if it compiles it usually works.

- Functional Programming can be [slower](https://www.quora.com/Do-functional-programming-languages-always-run-slower-than-imperative-language) than optimal Imperative Programming for reasons such as data copying due to data immutability.
- And various [other concerns](http://flyingfrogblog.blogspot.sg/2016/05/disadvantages-of-purely-functional.html)

Some of these reasons help explain why 'impure' Functional languages like Scala is much more popular today than Haskell. Scala is a general purpose language that has interoperability with Java and has support for both popular Object Oriented Programming and Functional Programming paradigm. This establishes a [middle ground](https://cacm.acm.org/magazines/2014/4/173220-unifying-functional-and-object-oriented-programming-with-scala/fulltext) for programmers new to Functional Programming.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a nit: ... in part explain...

because Scala's popularity probably also comes from a variety of other factors such as being on the JVM and the pitch as a Java alternative with the built-in rich concurrency support.

On the other hand, Haskell probably has some concerns such as the complicated type system.


Functional Programming can be a very different programming paradigm and it definitely takes time to practice to be an expert at it. To learn more about Functional Programming, I would recommend looking at these amazing guides for a deeper understanding:

- [Introduction to Functional Programming](https://medium.com/@cscalfani/so-you-want-to-be-a-functional-programmer-part-1-1f15e387e536)
Copy link
Contributor

@LiHaoTan LiHaoTan Apr 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these are very high quality curated resources, nice! (I haven't took that course myself though just knew that it is very famous 😆 ). I also could even see clearly the different intentions. I'm suggesting that maybe we make it even better, something like this:

  • An introduction to functional programming, only a three-part series!
  • If you are hungry for more, take the excellent functional programming principles course
  • And to help with the mindset shift for functional programming, take a look at a practical guide on how to translate an imperative to functional style

Also, I think maybe we should include the wikipedia page too because this is one of the times it has an excellent overview of functional programming.

@crphang
Copy link
Contributor Author

crphang commented Apr 12, 2018

@LiHaoTan added the changes. Can I have another review?

Copy link
Contributor

@LiHaoTan LiHaoTan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just some small suggestions


## Functional Programming Languages

Functional programming is simply a paradigm and needs to be implemented by programming languages. Below are various [languages](https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Functional_languages) that have explicit support for Functional programming paradigm such as:
Functional programming is simply a paradigm and needs to be implemented by programming languages. Below are various [languages](https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Functional_languages) that have explicit support for functional programming paradigm such as:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be ...explicit support for the functional programming paradigm...?

@@ -17,7 +17,7 @@ Functional programming is simply a paradigm and needs to be implemented by progr
- Scala
- ML (Meta Language) family of languages

While functional programming can be implemented by languages like Java, the languages listed above encourage Functional programming paradigm such as [pure functions](#pure-functions) or even enforce them in the case of Haskell.
While functional programming can be implemented by languages like Java, the languages listed above encourage functional programming paradigm such as [pure functions](#pure-functions) or even enforce them in the case of Haskell.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be ...explicit support for the functional programming paradigm...?


## Disadvantages of Functional Programming

Functional programming is not a new concept and has been around since the 1950s. Even though it is gaining in popularity today, it is not the predominant programming paradigm used in software applications today. Despite the stated benefits of Functional programming, there are some downsides of it that can help explain why it is not the mainstream programming paradigm:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You missed the capitalization ...stated benefits of Functional programming... here


## Techniques in Functional Programming

#### Recursion

Pure functional languages does not have loop constructs that procedural languages does. This is because `Iteration` usually involves state mutation per iteration. Since Functional programming avoids state changes, `Recursion` is a commonly used [technique](https://www.quora.com/Why-dont-pure-functional-programming-languages-provide-a-loop-construct) to replace `Iteration`.
Pure functional languages does not have loop constructs that procedural languages does. This is because `Iteration` usually involves state mutation per iteration. Since functional programming avoids state changes, `Recursion` is a commonly used [technique](https://www.quora.com/Why-dont-pure-functional-programming-languages-provide-a-loop-construct) to replace `Iteration`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Pure functional languages do not have loop constructs like imperative languages.

@crphang
Copy link
Contributor Author

crphang commented Apr 14, 2018

@damithc Ready for review!

@crphang crphang requested a review from damithc April 14, 2018 06:13
Copy link
Contributor

@damithc damithc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 👍
Some suggestions added. I'll leave you to decide which ones to follow.


## What is Functional Programming

Functional programming is a programming paradigm that treats computation as the evaluation of mathematical function and avoids mutating state and variables. Unlike imperative programming languages like C, Java and Python, functional programming languages are [declarative](https://en.wikipedia.org/wiki/Declarative_programming). Even though this demands a shift in mindset from most programmers who are used to imperative form of programming, functional programming paradigm is still [increasingly popular](https://blog.appdynamics.com/engineering/the-most-popular-programming-languages-for-2017/) due to its [advantages](#advantages-of-functional-programming).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph assumes the reader knows the meaning of imperative and mutating state, but not the meaning of functional programming. That is a bit unrealistic. People may be used to imperative languages but they might not know that they are imperative languages. On a related note, languages like Python support multiple paradigms; it's not correct to present them as of a certain paradigm.


Pure functions is one of the concepts in functional programming. To call a function `pure`, it needs to satisfy two conditions:

1. [Idempotence](https://en.wikipedia.org/wiki/Idempotence) - The function should return the same output for the same input.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This definition need to mention 'multiple invocations' somewhere.


Having immutability built into functional programming languages like Haskell also helps to ensure that functions are `pure` because mutable variables and states can introduce side-effects.

To know more about immutability in functional languages, you can take a look at:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be explain immutability a bit more rather than point to external pages immediately? Reading external links should be optional.


Pure functional languages do not have loop constructs like imperative languages. This is because `Iteration` usually involves state mutation per iteration. Since functional programming avoids state changes, `Recursion` is a commonly used [technique](https://www.quora.com/Why-dont-pure-functional-programming-languages-provide-a-loop-construct) to replace `Iteration`.

Hence, to be able to write functional languages effectively, it means being able to replace Iteration with Recursion. Here are some guides to help you on that:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give an example before pointing to external resources?


#### Higher Order Functions

> Higher Order Functions are functions that take functions as parameters, return functions or both.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This phrasing is a bit unclear. For example, If a function returns a function but does not take a function as a parameter, is it sill a higher order function? Did you mean this?

Higher Order Functions take functions as parameters and/or return functions as the result.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, this need not be given as a quote, especially if you are not citing a source. It can be given as normal text.


- [More Bug-Free Code](https://www.quora.com/Are-software-written-using-Functional-Programming-less-buggy-more-robust-and-stable) for example famously in Haskell, [if it compiles it usually works](https://wiki.haskell.org/Why_Haskell_just_works).
- [Concurrency](https://softwareengineering.stackexchange.com/questions/293851/what-is-it-about-functional-programming-that-makes-it-inherently-adapted-to-para)
- [And Many More](https://alvinalexander.com/scala/fp-book/benefits-of-functional-programming)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too, give a bit more details. Otherwise the reader is forced to go read the external link to understand what you mean.

- And various [other concerns](http://flyingfrogblog.blogspot.sg/2016/05/disadvantages-of-purely-functional.html)

Some of these reasons help in part explain why 'impure' functional languages like Scala is much more popular today than Haskell. Scala is a general purpose language that has interoperability with Java and has support for both object-oriented and functional programming paradigms. This establishes a [middle ground](https://cacm.acm.org/magazines/2014/4/173220-unifying-functional-and-object-oriented-programming-with-scala/fulltext) for programmers new to functional programming.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was no mention of OOP until this point. The reader will wonder how it fits into the whole picture.

@crphang
Copy link
Contributor Author

crphang commented Apr 16, 2018

@damithc Changes are added, ready for another round of review.

@crphang crphang requested a review from damithc April 19, 2018 13:48
Copy link
Contributor

@damithc damithc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Some nits.


## Functional Programming Languages

Functional programming is simply a paradigm and needs to be implemented by programming languages. Below are various [languages](https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Functional_languages) that have explicit support for the functional programming paradigm such as:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

such as is redundant?


#### Pure Functions

Pure functions is one of the concepts in functional programming. To call a function `pure`, it needs to satisfy two conditions:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might help if you use italics here.

Pure functions is one of the concepts ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using code font for pure is not appropriate here. Consider _pure_ or 'pure'

```python
# Mutate state
y=0
def addXToY(x):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a more pythonic name? e.g., add_to_y(x)


#### Immutability

Another concept in functional programming is immutability. Immutability prevents an object's state to be change after it is created. When we assign `x=1`, it does not make mathematical sense to have this expression `x:=x+1`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does not make mathematical sense to have this expression x:=x+1

While this is true, I'm not sure that equates to an explanation or even a justification of immutability. The sentence sounds like this equation doesn't make sense, mathematically. i.e., the syntax is nonsensical

if len(listOfNumbers) == 0:
return 0
return listOfNumbers[0] + getSumOfListRec(listOfNumbers[1:])
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give as two code segments. Otherwise this code will be rejected by Python?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damithc, can you clarify this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant show it like this:


Iterative:

def getSumOfList(listOfNumbers):
    sum = 0
    for number in listOfNumbers:
        sum += number
    return sum

Recursive:

def getSumOfList(listOfNumbers):
    if len(listOfNumbers) == 0:
        return 0
    return listOfNumbers[0] + getSumOfList(listOfNumbers[1:])

At first glance I thought they have the same function name, but on closer inspection they don't. That means the code itself is fine.
But they are alternates --> unlikely to appear in the same code file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran the code and it works. The functions are named differently as well.


#### Higher Order Functions

Higher Order Functions are functions that either take functions as parameters, return a function or both. As functions are first class citizens in functional programming languages, this allows [functions to be passed around like objects and values](https://en.wikipedia.org/wiki/Functional_programming#First-class_and_higher-order_functions).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use oxford comma. xxx, yyy, or zzz.


#### Recursion

Pure functional languages do not have loop constructs like imperative languages. This is because `Iteration` usually involves state mutation per iteration. Since functional programming avoids state changes, `Recursion` is a commonly used [technique](https://www.quora.com/Why-dont-pure-functional-programming-languages-provide-a-loop-construct) to replace `Iteration`. An example of replacing state-mutating iterative code to a pure functional recusive code is shown below:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer Because over Since (latter has two meanings)


The common question when learning about functional programming is what's the point of having us going through all the trouble of having pure functions, state immutability and absence of loops. Turns out, there are various positive implications of functional programming:

- [More Bug-Free Code](https://www.quora.com/Are-software-written-using-Functional-Programming-less-buggy-more-robust-and-stable) for example famously in Haskell, [if it compiles it usually works](https://wiki.haskell.org/Why_Haskell_just_works).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More Bug-Free Code for example famously in Haskell, if it compiles it usually works.

Punctuation missing after More Bug-Free Code?

The common question when learning about functional programming is what's the point of having us going through all the trouble of having pure functions, state immutability and absence of loops. Turns out, there are various positive implications of functional programming:

- [More Bug-Free Code](https://www.quora.com/Are-software-written-using-Functional-Programming-less-buggy-more-robust-and-stable) for example famously in Haskell, [if it compiles it usually works](https://wiki.haskell.org/Why_Haskell_just_works).
- [Concurrency](https://softwareengineering.stackexchange.com/questions/293851/what-is-it-about-functional-programming-that-makes-it-inherently-adapted-to-para). Having state immutability and absence of side effects can allow for bug-free concurrent code with less concerns of race conditions on mutable objects.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't equate fewer bugs with bug-free :-p

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concurrency is not an advantage. Imperative languages can have concurrency too.


## Guides on Functional Programming

Functional programming can be a very different programming paradigm and it definitely takes time to practice to be an expert at it. To learn more about functional programming, I would recommend looking at these amazing guides for a deeper understanding:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid using I. Reason: in future, more authors can be added.

Italicized the words pure. Justified functional programming
with safer concurrency instead of concurrency. Added other
grammar fixes.
Copy link
Contributor

@damithc damithc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like my comment didn't go through earlier.

if len(listOfNumbers) == 0:
return 0
return listOfNumbers[0] + getSumOfListRec(listOfNumbers[1:])
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant show it like this:


Iterative:

def getSumOfList(listOfNumbers):
    sum = 0
    for number in listOfNumbers:
        sum += number
    return sum

Recursive:

def getSumOfList(listOfNumbers):
    if len(listOfNumbers) == 0:
        return 0
    return listOfNumbers[0] + getSumOfList(listOfNumbers[1:])

At first glance I thought they have the same function name, but on closer inspection they don't. That means the code itself is fine.
But they are alternates --> unlikely to appear in the same code file.

@crphang
Copy link
Contributor Author

crphang commented Apr 22, 2018

@damithc Changes are added. Ready for another round of review.

@crphang crphang requested a review from damithc April 22, 2018 02:56
Copy link
Contributor

@damithc damithc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@damithc damithc merged commit bc41abe into se-edu:master Apr 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants