1# Customization
2
3I like the idea of "prototype oriented programming" proposed by OpenSCAD2.
4
5A new shape can be constructed in two ways:
6 * Using the "high level api", by composing existing shapes using high level
7   shape operators.
8 * Using the "low level api", constructing a new shape using the "shape
9   protocol", currently by invoking the `make_shape` constructor.
10
11You can write a function that returns a shape with either of the above
122 kinds of shape expression as the body.
13
14I want the ability to define customizable shapes using either API.
15
16 1. OpenSCAD2 has "geometric objects", similar to Curv modules,
17    which can be customized using function call notation.
18    This generalizes the idea that an OpenSCAD script denotes a shape.
19 2. Parameterized_Shape proposes `defshape` as a special definitional form
20    for defining shape constructors that preserve the constructor name when
21    the constructed shape is serialized. So we can "export the CSG tree".
22    It is proposed that if the constructor isn't curried, and all arguments
23    have defaults, then the shape is customizable.
24
25So I have proposed multiple ways to define a customizable shape.
26
27[1] `lollipop.curv` contains:
28```
29param radius   = 10; // candy
30param diameter = 3;  // stick
31param height   = 50; // stick
32
33translate([0,0,height]) sphere(r=radius);
34cylinder(d=diameter,h=height);
35```
36Then, `lollipop = file("lollipop.curv");`.
37
38[2]
39```
40lollipop = {
41    param radius   = 10; // candy
42    param diameter = 3;  // stick
43    param height   = 50; // stick
44
45    translate([0,0,height]) sphere(r=radius);
46    cylinder(d=diameter,h=height);
47};
48```
49
50[3]
51```
52// automatically supports customization, due to no currying and all
53// parameters having defaults.
54defshape lollipop(
55    radius   = 10, // candy
56    diameter = 3,  // stick
57    height   = 50) // stick
58= union [
59    translate([0,0,height]) sphere(r=radius),
60    cylinder(d=diameter,h=height),
61];
62```
63
64[4]
65```
66defshape lollipop = {
67    param radius   = 10; // candy
68    param diameter = 3;  // stick
69    param height   = 50; // stick
70
71    translate([0,0,height]) sphere(r=radius);
72    cylinder(d=diameter,h=height);
73};
74```
75This illustrates that `defshape` need not have any special powers of
76customization if modules are customizable and modules are shapes.
77