Pages

Friday, September 15, 2017

OpenSCAD Essentials: Functional Programming

Functional programming

OpenSCAD is a 3D CAD program where the 3D model is created with a script. Although the basics are very simple there is a point on the learning curve where the OpenSCAD programming language can become confusing. OpenSCAD is a Functional Programming Language and behaves differently than most people, used to the Imperative Programming Paradigm, expect. With Imperative Programming a value can be assigned to a variable and later another value can be assigned to same variable later in the program. This changes the state of the program. This approach will not work in OpenSCAD.

Sierpinski triangle in OpenSCAD. A program I made earlier that demonstrates recursion in OpenSCAD.

An example

The easiest way to explain this is with a simple example. In this example we want the program to add the numbers 1 to 10 (1+2+3+4+5+6+7+8+9+10).

total = 0;

module count(number) {
    for (i = [1:number]) {
        total=total+i;
    }
    echo(total);
}

count(10);

You might expect that the answer is 55 however to your horror you'll find in OpenSCAD that it actually is 0. What happened? Instead of assigning a new value to the variable total for every interation, total keeps it's initial value. The program written in OpenSCAD is a mathematical expression that is evaluated by pressing F5. OpenSCAD supports powerful functional constructs to support these expressions. In the case of the example above we write.

function sum(number) = (number == 0 ? 0 : number + sum(number-1));

echo(sum(10));

The result of this program is 55 as intended but how does it work. We define a function (hence the name Functional Language) sum with a parameter number. On the right side of the function there is an evaluation, in pseudocode: if n == 0 then 0 else number + sum(number-1). Notice that the function is recursive so for example for number is 3 the function evaluates as follows

sum(3) = 3 + sum(2) = 3 + 2 + sum(1) = 3 + 2 + 1 = 6

Iteration in OpenSCAD is usually accomplished via recursion. If you are not used to recursion it's takes effort and practice to understand but it's often simple and elegant. Now let's do a somewhat more complicated example, the greatest common devisor (gcd). When we look at gcd algorithms on wikipedia we find the recursive Euclidian algorithm which is described as follows:

gcd(a,0) = a
gcd(a,b) = gcd(b, a mod b)

Even if we would not understand the algorithm it's easy to translate it to OpenSCAD

function gcd(a,b) = b == 0 ? a : gcd(b,a%b);

Where a%b means a modulo b (BTW: the syntax used in the functions above is similar to the programming language C). It's worthwhile as a training to find recursive algorithms and try to implement them in OpenSCAD.

Further reading

If you want to advance in OpenSCAD it is necessary to read the manual at some point. This discloses valuable information that is hard to find by just using the Cheatsheet or the watching YouTube videos. The user manual can be found here: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language

No comments:

Post a Comment