# Jupyter kernels

# Jupyter kernels#

A Jupyter Notebook can utilise any program kernel that implements the Jupyter messaging protocol for executing code. There are kernels available for Python, Julia, Ruby, Haskell and many other languages.

In this notebook we demonstrate executing code with the Coconut Programming Language, a variant of Python built for *simple, elegant, Pythonic functional programming*.

In the first example we will define a recursive `factorial`

function, a fundamentally functional approach that doesn’t involve any state changes or loops:

```
def factorial(n):
"""Compute n! where n is an integer >= 0."""
case n:
match 0:
return 1
match x is int if x > 0:
return x * factorial(x-1)
else:
raise TypeError("the argument to factorial must be an integer >= 0")
3 |> factorial |> print
```

```
6
```

Although this example is very basic, pattern-matching is both one of Coconut’s most powerful and most complicated features.

In the second example, we implement the quick sort algorithm. This quick_sort algorithm works using a bunch of new constructs:

```
def quick_sort(l):
"""Sort the input iterator using the quick sort algorithm."""
match [head] :: tail in l:
tail = reiterable(tail)
yield from quick_sort(left) :: [head] :: quick_sort(right) where:
left = (x for x in tail if x < head)
right = (x for x in tail if x >= head)
# By yielding nothing if the match falls through, we implicitly return an empty iterator.
[3,0,4,2,1] |> quick_sort |> list |> print
```

```
[0, 1, 2, 3, 4]
```

Finally, we see that exceptions are raised as one would expect:

```
x
```

```
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-3-151148cf3fd5> in <module>
----> 1 x # line 1: x
NameError: name 'x' is not defined
```