The Easiest Language to Learn Functional Programming
By: Abinand Sivakumar
Tags: Programming Languages, Functional Programming, Programming, Scheme

The Easiest Language to Learn Functional Programming

Even if you are a beginner to programming

Photo by James Harrison on Unsplash

All the cool kids know functional programming. When object-oriented programmers try to explore or learn it, functional concepts might seem impractical, especially if they never incorporated functional concepts in their day-to-day programming.

When curiosity and fear-of-missing-out eventually override practicality, object-oriented programmers look to either:

learn a new functional programming language from scratch or learn from functional constructs in languages they are comfortable with.

Each path has its limitations. The first choice puts emphasis on the language rather than concepts and the second choice is messy due to the short-comings and caveats of loosely implemented functional features in general purpose languages.

There is no bad choice to get started on learning. However, there is a reprieve for you folks who are thinking of option 1 — Scheme

What is Scheme?

Scheme, according to wikipedia, is “a minimalist dialect of the Lisp family of programming languages”. Lisp is an expression oriented language that existed decades before the first object oriented languages were invented. The Scheme dialect distills Lisp into the most basic constructs needed to execute a program.

Constructs and keywords

Here is an example of a Scheme expression to add two numbers:

(+ 2 3) Output: 5

This will seem absurd at first. You would have expected the operation to look like 2 + 3 but this absurdity is also the simplicity of Scheme. You see, the “+” is not an operator, it is a function. The “+” function adds the inputs given to it. For you CompSci savvy people, this is the prefix notation as opposed to the infix “2+3” notation used commonly in modern languages.

These basic functional expressions can be nested within each other, forming new expressions. Here is another example:

(/ (* 10 2) (+ 2 3)) Output:4 - divide the result of (* 10 2) with result of (+ 2 3) which is 20 divided by 5

With these expressions, we are already using function composition and first-order functions! Imagine the code you write to express a concept like this in JavaScript.

Scheme has keywords, like all languages do. Here are some of the common ones used in the majority of the Scheme programs. The following examples don’t go into the finer details but they just highlight how it is used.

define — for naming values; what one might call “user-defined functions”.

(define (square x) (* x x))

(square 5) Output: 25

- creates a function named "square" and calls it with value 5

lambda — does the same thing as above but without it giving a name. Why we need such a feature will become apparent in a later example. Incidentally, this is where the lambda of Python, C# and other languages came from.

((lambda (x) (* x x)) 5) Output: 25

cond, if, and, or, not, else — conditional branching stuff

(if (> 5 6) 4 (+ 7 1)) Output: 8

- if 5 is greater than 6 then give 4 otherwise give (+ 7 1)

cons, car, cdr, list, ‘ (single quote) — these are used to create and produce lists. Lisp stands for List Processor after all, so lists are heavily used.

(list 1 2 3 4)

Output: (1 2 3 4) '(1 2 3 4)

Output: (1 2 3 4)

- the single quote is a lisp shorthand for list

do, map, filter — looping and recursion. Note that functional languages don’t really use loops like iterative languages do. Recursion is preferred instead.

(map (lambda (x) (* x x)) '(1 2 3 4 5)) Output: (1 4 9 16 25)

- the lambda from before, executed on every item in (1 2 3 4 5)

There are more subtle lexicons, but as we see here, the minimalism of the language is quite evident. The examples specifically avoided iterative programming concepts like variable assignments because they are rarely used.

Also, these programs tend to include a lot of parenthesis (). For some, it makes the program look ugly but with the right IDE, it won’t be a problem. Which lead us to ..

Development Setup

Playing with a language involves writing code and that code has to run somewhere. Where do you get IDE and compilers for it?

The simplest way to get started is Dr Racket. Racket is a language of its own (another dialect of Lisp) but it supports the Scheme compiler as a subset and provides rich auto-formatting, static code analysis, and debugging features out-of-the-box.

In order to set Scheme as the preferred language, type the following in the workspace and either click on Run from the options bar or press Ctrl+r.

#lang scheme

Setup to run Scheme programs in DrRacket

Et Violà! You have an IDE to run Scheme. Let’s test this by running the last example from above to see the output. If you choose to type the code, pressing enter after keywords would neatly auto-indent the program.

A working example code executed in DrRacket

Sample Program

Let’s expand on what we know so far and write a simple program to calculate the factorial of a given number.

The factorial of a number N is defined by this mathematical expression below:

Factorial(N) = N * (N-1) * (N-2) * …. * 1

Expressed in a different mathematical formula, we can say

Factorial(N) = N * Factorial(N-1) ; when N is not 1

= 1 ; when N is 1

Here is the code to calculate the factorial in Scheme. The program defines a factorial function and uses it to calculate the factorial of number 5.

#lang scheme (define (factorial N)

(if (= N 1)

1

(* N (factorial (- N 1))))) (factorial 5)

Notice similarity of the mathematical expression and the corresponding expression in Scheme.

Next Steps

If you are sold on using Scheme to learn functional programming, I encourage you to get the book “Structure and Implementation of Computer Programs”, otherwise known as the SICP book, to continue learning. Another popular recommendation is “How to Design Programs”.

Dev tip — it would be sufficient to go over the first three sections of the SICP book to learn 90% of practical functional programming including mutability, higher order functions, streams (which is what Observables in RxJS are about), lambdas, closures, and much more. Personally, I found the last two sections of SICP to be a bit arcane for a web applications programmer like myself, but it might interest other species of programmers.

Scheme is great for students to get comfortable with functional programming but due to its minimal nature, it doesn’t scale for very large projects. However, learning Scheme will open the doors to more advanced Lisp dialects that come with pre-implemented libraries for common utilities. The DrRacket IDE supports Racket and Common Lisp, which are other powerful dialects of Lisp. The macros in Common Lisp for instance, are impossible to imitate with other languages. Java programmers could leverage learning Clojure to integrate functional programming into existing projects.