What is Functional Programming

Firstly, we should know what is a programming paradigm means.
Programming paradigm is a way to classify programming languages.

Let’s see the common programming paradigms include

* imperative in which the programmer instructs the machine how to change its state,
* procedural which groups instructions into procedures,
* object-oriented which groups instructions together with the part of the state they operate on,
* declarative in which the programmer merely declares properties of the desired result, but not how to compute it
* functional in which the desired result is declared as the value of a series of function applications, <- We will learn this
* logic in which the desired result is declared as the answer to a question about a system of facts and rules,
* mathematical in which the desired result is declared as the solution of an optimization problem
// https://en.wikipedia.org/wiki/Programming_paradigm
* imperative in which the programmer instructs the machine how to change its state,
  * procedural which groups instructions into procedures,
  * object-oriented which groups instructions together with the part of the state they operate on,

* declarative in which the programmer merely declares properties of the desired result, but not how to compute it
  * functional in which the desired result is declared as the value of a series of function applications, <- We will learn this
  * logic in which the desired result is declared as the answer to a question about a system of facts and rules,
  * mathematical in which the desired result is declared as the solution of an optimization problem

// https://en.wikipedia.org/wiki/Programming_paradigm
* imperative in which the programmer instructs the machine how to change its state, * procedural which groups instructions into procedures, * object-oriented which groups instructions together with the part of the state they operate on, * declarative in which the programmer merely declares properties of the desired result, but not how to compute it * functional in which the desired result is declared as the value of a series of function applications, <- We will learn this * logic in which the desired result is declared as the answer to a question about a system of facts and rules, * mathematical in which the desired result is declared as the solution of an optimization problem // https://en.wikipedia.org/wiki/Programming_paradigm

When we will functional in any language you should accept these rules:

  • DO NOT mutate your data
    • You should not change the value of data, or change the data to another variable.
    • Use only constants

That means you should disallow side-effects!

<span>// This is not allowed!</span>
<span>let</span> <span>mut</span> <span>something</span> <span>=</span> <span>20</span><span>;</span>
<span>something</span> <span>+=</span> <span>7</span><span>;</span>
<span>// This is allowed.</span>
<span>let</span> <span>something</span> <span>=</span> <span>20</span><span>;</span>
<span>let</span> <span>something_else</span> <span>=</span> <span>something</span> <span>+</span> <span>7</span><span>;</span>
<span>// This is not allowed!</span>
<span>let</span> <span>mut</span> <span>something</span> <span>=</span> <span>20</span><span>;</span>
<span>something</span> <span>+=</span> <span>7</span><span>;</span>

<span>// This is allowed.</span>
<span>let</span> <span>something</span> <span>=</span> <span>20</span><span>;</span>
<span>let</span> <span>something_else</span> <span>=</span> <span>something</span> <span>+</span> <span>7</span><span>;</span>
// This is not allowed! let mut something = 20; something += 7; // This is allowed. let something = 20; let something_else = something + 7;
  • Each function should return value(s).
<span>// This is not allowed!</span>
<span>fn</span> <span>something</span><span>()</span> <span>{</span>
<span>println!</span><span>(</span><span>"27"</span><span>);</span>
<span>}</span>
<span>// This is allowed.</span>
<span>fn</span> <span>something</span><span>()</span> <span>-></span> <span>i32</span> <span>{</span>
<span>return</span> <span>5</span>
<span>}</span>
<span>// This is not allowed!</span>
<span>fn</span> <span>something</span><span>()</span> <span>{</span>
  <span>println!</span><span>(</span><span>"27"</span><span>);</span>
<span>}</span>

<span>// This is allowed.</span>
<span>fn</span> <span>something</span><span>()</span> <span>-></span> <span>i32</span> <span>{</span>
  <span>return</span> <span>5</span>
<span>}</span>
// This is not allowed! fn something() { println!("27"); } // This is allowed. fn something() -> i32 { return 5 }

What will can you use when you purely functional:

  • Shadowing
    • Having 2 different constants in different scopes
<span>let</span> <span>a</span> <span>=</span> <span>20</span><span>;</span>
<span>{</span>
<span>let</span> <span>a</span> <span>=</span> <span>7</span><span>;</span>
<span>println!</span><span>(</span><span>"{}"</span><span>,</span> <span>a</span><span>);</span>
<span>}</span>
<span>println</span><span>(</span><span>"{}"</span><span>,</span> <span>a</span><span>);</span>
<span>/* Output: 7 20 */</span>
<span>let</span> <span>a</span> <span>=</span> <span>20</span><span>;</span>
<span>{</span>
  <span>let</span> <span>a</span> <span>=</span> <span>7</span><span>;</span>
  <span>println!</span><span>(</span><span>"{}"</span><span>,</span> <span>a</span><span>);</span>
<span>}</span>
<span>println</span><span>(</span><span>"{}"</span><span>,</span> <span>a</span><span>);</span>

<span>/* Output: 7 20 */</span>
let a = 20; { let a = 7; println!("{}", a); } println("{}", a); /* Output: 7 20 */
  • Recursion
    • You can’t use for or foreach loops when you purely functional. Because you’re just changing the single variables value. This is not allowed because of immutability. Factorial example
<span>fn</span> <span>fact</span><span>(</span><span>n</span><span>:</span> <span>i32</span><span>)</span> <span>-></span> <span>i32</span> <span>{</span>
<span>if</span> <span>n</span> <span>==</span> <span>1</span> <span>{</span>
<span>1</span>
<span>}</span>
<span>else</span> <span>{</span>
<span>n</span> <span>*</span> <span>fact</span><span>(</span><span>n</span> <span>-</span> <span>1</span><span>)</span>
<span>}</span>
<span>}</span>
<span>/* fact(5); 5 * fact(4) 5 * 4 * fact(3) 5 * 4 * 3 * fact(2) 5 * 4 * 3 * 2 * fact(1) -> It's 1! Return 1 and stop recursion. 5 * 4 * 3 * 2 * 1 5 * 4 * 3 * 2 5 * 4 * 6 5 * 24 120 */</span>
<span>fn</span> <span>fact</span><span>(</span><span>n</span><span>:</span> <span>i32</span><span>)</span> <span>-></span> <span>i32</span> <span>{</span>
  <span>if</span> <span>n</span> <span>==</span> <span>1</span> <span>{</span>
    <span>1</span>
  <span>}</span>
  <span>else</span> <span>{</span>
    <span>n</span> <span>*</span> <span>fact</span><span>(</span><span>n</span> <span>-</span> <span>1</span><span>)</span>
  <span>}</span>
<span>}</span>

<span>/* fact(5); 5 * fact(4) 5 * 4 * fact(3) 5 * 4 * 3 * fact(2) 5 * 4 * 3 * 2 * fact(1) -> It's 1! Return 1 and stop recursion. 5 * 4 * 3 * 2 * 1 5 * 4 * 3 * 2 5 * 4 * 6 5 * 24 120 */</span>
fn fact(n: i32) -> i32 { if n == 1 { 1 } else { n * fact(n - 1) } } /* fact(5); 5 * fact(4) 5 * 4 * fact(3) 5 * 4 * 3 * fact(2) 5 * 4 * 3 * 2 * fact(1) -> It's 1! Return 1 and stop recursion. 5 * 4 * 3 * 2 * 1 5 * 4 * 3 * 2 5 * 4 * 6 5 * 24 120 */

Foreach-like example (python example :p)

<span>def</span> <span>double_each</span><span>(</span><span>arr</span><span>):</span>
<span>if</span> <span>arr</span> <span>==</span> <span>[]:</span>
<span>return</span> <span>[]</span>
<span>return</span> <span>[</span><span>arr</span><span>[</span><span>0</span><span>]</span> <span>*</span> <span>2</span><span>]</span> <span>+</span> <span>double_each</span><span>(</span><span>arr</span><span>[</span><span>1</span><span>:])</span>
<span>print</span><span>(</span><span>double_each</span><span>([</span><span>2</span><span>,</span> <span>7</span><span>,</span> <span>8</span><span>]))</span>
<span>""" double_each([2, 7, 8]) [4] + double_each([7, 8])) [4] + [14] + double_each([8]) [4] + [14] + [16] + double_each([]) -> Got empty list! Return empty list and stop recursion. [4] + [14] + [16] + [] [4] + [14] + [16] [4] + [14, 16] [4, 14, 16] """</span>
<span>def</span> <span>double_each</span><span>(</span><span>arr</span><span>):</span>
  <span>if</span> <span>arr</span> <span>==</span> <span>[]:</span>
    <span>return</span> <span>[]</span>
  <span>return</span> <span>[</span><span>arr</span><span>[</span><span>0</span><span>]</span> <span>*</span> <span>2</span><span>]</span> <span>+</span> <span>double_each</span><span>(</span><span>arr</span><span>[</span><span>1</span><span>:])</span>

<span>print</span><span>(</span><span>double_each</span><span>([</span><span>2</span><span>,</span> <span>7</span><span>,</span> <span>8</span><span>]))</span>

<span>""" double_each([2, 7, 8]) [4] + double_each([7, 8])) [4] + [14] + double_each([8]) [4] + [14] + [16] + double_each([]) -> Got empty list! Return empty list and stop recursion. [4] + [14] + [16] + [] [4] + [14] + [16] [4] + [14, 16] [4, 14, 16] """</span>
def double_each(arr): if arr == []: return [] return [arr[0] * 2] + double_each(arr[1:]) print(double_each([2, 7, 8])) """ double_each([2, 7, 8]) [4] + double_each([7, 8])) [4] + [14] + double_each([8]) [4] + [14] + [16] + double_each([]) -> Got empty list! Return empty list and stop recursion. [4] + [14] + [16] + [] [4] + [14] + [16] [4] + [14, 16] [4, 14, 16] """
  • Map, Reduce and Filter
    • Map: apply function f on each item in list and return a new list.
    • Reduce: apply function f to first two items in list and continue like this.
    • Filter: Add to new list if f returns true.

Map

<span>>>></span> <span>list</span><span>(</span><span>map</span><span>(</span><span>lambda</span> <span>n</span><span>:</span> <span>n</span> <span>*</span> <span>2</span><span>,</span> <span>[</span><span>2</span><span>,</span> <span>7</span><span>,</span> <span>8</span><span>])</span>
<span>[</span><span>4</span><span>,</span> <span>14</span><span>,</span> <span>16</span><span>]</span>
<span>>>></span> <span>list</span><span>(</span><span>map</span><span>(</span><span>lambda</span> <span>n</span><span>:</span> <span>n</span> <span>*</span> <span>2</span><span>,</span> <span>[</span><span>2</span><span>,</span> <span>7</span><span>,</span> <span>8</span><span>])</span>
<span>[</span><span>4</span><span>,</span> <span>14</span><span>,</span> <span>16</span><span>]</span>
>>> list(map(lambda n: n * 2, [2, 7, 8]) [4, 14, 16]

Reduce

<span>>>></span> <span>from</span> <span>functools</span> <span>import</span> <span>reduce</span>
<span>>>></span> <span>reduce</span><span>(</span><span>lambda</span> <span>a</span><span>,</span> <span>b</span><span>:</span> <span>a</span> <span>+</span> <span>b</span><span>,</span> <span>[</span><span>2</span><span>,</span> <span>7</span><span>,</span> <span>8</span><span>])</span>
<span>17</span>
<span>>>></span> <span>from</span> <span>functools</span> <span>import</span> <span>reduce</span>
<span>>>></span> <span>reduce</span><span>(</span><span>lambda</span> <span>a</span><span>,</span> <span>b</span><span>:</span> <span>a</span> <span>+</span> <span>b</span><span>,</span> <span>[</span><span>2</span><span>,</span> <span>7</span><span>,</span> <span>8</span><span>])</span>
<span>17</span>
>>> from functools import reduce >>> reduce(lambda a, b: a + b, [2, 7, 8]) 17

Filter

<span>>>></span> <span>list</span><span>(</span><span>filter</span><span>(</span><span>lambda</span> <span>n</span><span>:</span> <span>n</span> <span>%</span> <span>2</span> <span>==</span> <span>0</span><span>,</span> <span>[</span><span>2</span><span>,</span> <span>7</span><span>,</span> <span>8</span><span>]))</span>
<span>[</span><span>2</span><span>,</span> <span>8</span><span>]</span>
<span>>>></span> <span>list</span><span>(</span><span>filter</span><span>(</span><span>lambda</span> <span>n</span><span>:</span> <span>n</span> <span>%</span> <span>2</span> <span>==</span> <span>0</span><span>,</span> <span>[</span><span>2</span><span>,</span> <span>7</span><span>,</span> <span>8</span><span>]))</span>
<span>[</span><span>2</span><span>,</span> <span>8</span><span>]</span>
>>> list(filter(lambda n: n % 2 == 0, [2, 7, 8])) [2, 8]

Questions

  • What is lambda calculus?
    Simply, lambda calculus is a theorical framework for describing functions and their evaluation. It forms the basis of almost all current functional programming languages!
    Wikipedia

  • What is the first functional programming language?
    LISP! The oldest (after FORTRAN (FORmula TRANslation)) and it’s still in usage (For example Clojure). It’s based on s-expressions.

  • What is Purely Functional?
    Purely functional means ONLY ALLOW FUNCTIONAL PROGRAMMING RULES. However, you can Purely functional in many languages. Just accept the rules.

Made while listening MU40PROJ.KDM by BUILD Engine creator Ken Silverman

This is my first post, so it’s possible to make BIG MISTAKES.

原文链接:What is Functional Programming

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
Don’t let a bad day make you feel lke you have a bad lfe.
不要让糟糕的一天让你误以为有个糟糕的人生
评论 抢沙发

请登录后发表评论

    暂无评论内容