Sorry about the ad, Reddit hugs are too expensive without something to cover the hosting costs.

Functional programming
is cool. I like functional programming. I can write out programs as equations and somehow my computer makes sense of it. Some people call some programming
executable mathematics,
which makes me feel like I'm doing complicated number processing.
Unfortunately, you can't always use your favourite tool all the time. In exams, you'd probably get more than a few frowns for taking GHC or MIT/GNU Scheme to your cardboard-walled cell for nearly two hours. Therefore, it'd be much nicer to get the really important features of your favourite language on the calculator. These are

```
map
```

and
```
filter
```

for me, but you might disagree. It's very easy to write equations and functions the way you would on your favourite REPL after defining a few primitives in an alien language.
This post targets the TI-Nspire CX CAS, but any calculator with conditionals and function definitions will suffice. I'll also show Scheme and Haskell equivalents of any interesting functions used.

f(*x*) = x × x

Should a function need to span several lines, the end result becomes terrible:
Define f(*x*) = Func

If**evenp**(*x*) Then

Return*x/2*

Else

Return 2 ×*x* + 1

EndIf

EndFunc

This approach screams BASIC to me. (At least I don't need MathJax to typeset it, nonetheless.)
If

Return

Else

Return 2 ×

EndIf

EndFunc

Here's an application:

f(5)
(→ 25)

A few typographic conventions will be seen in this document. Variables will be in
love(*fire*) = **building**(*on*, *fire*)
(→ 1977.2)

Being able to join lists is important in functional programming. Haskell uses
```
a : b
```

, where the item a is being placed in front of the list b. Scheme uses
```
(cons a b)
```

. The CAS does not expose its lists as linked, so we must resort to slow list joins, like
```
[a] ++ b
```

and
```
(append (list a) b)
```

. This is written as:
augment({*a*}, *b*)

```
apply
```

, which can be defined as:
apply(*f*, *x*) = *f*(*x*)

If only that would work on my calculator. It doesn't support first-class functions, where you can pass a definition as a variable. There is a hack to achieve what we want though, which is using expr().
It's not pretty, but it does work. Here's the function in action:
apply(*f*, *x*) = **expr**(*f*)

The function (f) has to be passed in as a string in terms of x, such as
```
"x / 3"
```

which works well enough. x is bound to our variable, so x is substituted automagically. We won't need to touch this function very much after defining the higher order functions.
```
head
```

function, and Scheme's
```
car
```

first(*l*) = *l*[1]

This only works for lists, which are written as
```
{item1, item2, item3, ...}
```

in the CAS. Matrix support is an excercise to the reader, or can be examined further with the downloadable CAS file at the end of this document.
```
car
```

and
```
cdr
```

are supposedly remnants of the IBM mainframes Lisps were originally written on. Scheme should have adopted the first/rest notation usable in Common Lisp, and presented here.
```
tail
```

, and Scheme's
```
cdr
```

.
This needs some more work to implement, as lists are presented as a whole entity, and not linked items. The CAS uses a similar solution to Python's list comprehensions:
rest(*l*) = **seq**(*l*[*x*], *x*, 2, **dim**(*l*))

seq tells the CAS to evaluate the first argument (l[x]) for each value of the second argument (x) bound from the third (2) to the fourth (dim(l)). dim gets the length of a list. The CAS is one-indexed, by the way.
```
null
```

or Scheme's
```
null?
```

. (The CAS doesn't support question marks in names, so we settle for "nullp" like the Common Lisp function.)
We've already seen dim in action, and we can use it to check emptiness.
nullp(*l*) = (**dim**(*l*) = 0)

```
map' f x = if null x then [] else (f (head x)) : (map' f (tail x))
```

The Scheme way may be more familiar:

(define (map* f x) (cond ((null? x) '()) (else (cons (f (car x)) (map* f (cdr x))))))This can be read as "if the list is null, return an empty list, otherwise join the first item passed through the function with the mapping of the rest of the list."

Our map will be our first function with conditionals. Here goes.

Define **map**(*f*,*l*)=

Func

If**nullp**(*l*) Then

Return*l*

Else

Return augment({**apply**(*f*,**first**(*l*))}, **map**(*f*, **rest**(*l*)))

EndIf

EndFunc

Welcome to CAS programming. It's awful.
Func

If

Return

Else

Return augment({

EndIf

EndFunc

This is a simple recursive function. It can be run like:

map("3 × x", {1, 2, 3})
(→ {3, 6, 9})

Let's step through this. The first thing the CAS does is check if our list is empty. It's not, so let's move to the Else clause:
Return augment({**apply**(*f*, **first**(*l*))}, **map**(*f*, **rest**(*l*)))

Yuck. Let's start with the first argument to augment. We're making a list from the result of applying f to the first item of l. Let's substitute that in.
Return augment({**apply**("3 × *x*", 1)}, **map**(*f*, **rest**(*l*)))

Using our logic for apply, we can also evaluate that side.
Return augment({3}, **map**(*f*, **rest**(*l*)))

The second argument is simpler.
Return augment({3}, **map**("3 × *x*", {2, 3}))

Now, we can continue with the rest of the applications, remembering when the list is empty.
Return augment({3}, augment({6}, **map**("3 × *x*", {3})))

Return augment({3}, augment({6}, augment({9},**map**("3 × *x*", {}))))

Return augment({3}, augment({6}, augment({9}, {})))

Return {3,6,9}

Almost all functional programming can be analysed through this method. Our function's only weakness is its many calls to augment and itself. The CAS only supports 256 recursive calls, so presumably it will fail after 254 items have been processed.
Return augment({3}, augment({6}, augment({9},

Return augment({3}, augment({6}, augment({9}, {})))

Return {3,6,9}

```
filter even [1, 2, 3, 4]
```

(→ [2, 4])
This is similar in Scheme:

```
(filter even? '(1 2 3 4)
```

(→ (2 4))
This has the same messiness as map when written in CAS speak, unfortunately:

Define **filter**(*p*, *l*)=

Func

If**nullp**(*l*) Then

Return*l*

ElseIf**apply**(*p*, **first**(*l*)) Then

Return augment({**first**(*l*)}, **filter**(*p*, **rest**(*l*)))

Else

Return**filter**(*p*, **rest**(*l*))

EndIf

EndFunc

This function doesn't return the applied values, and doesn't add items to the list when the predicate is false. You should be able to analyse a call like this now:
Func

If

Return

ElseIf

Return augment({

Else

Return

EndIf

EndFunc

That was a lot. You can download an extended TNS library for this (with an assoc implementation and matrix support)
here
if you just want code.
(→ You lazy little solve user.)