What's New in Punctual
New in Punctual 0.5.1.1
Reintroduced list expansions, which were removed in Punctual 0.5.
There are two types of list expansions:
[x, y .. z]
expands to a list of numbers starting atx
, incrementing byy-x
, and ending atz
.
For example: [0, 0.25 .. 1]
expands to [0, 0.25, 0.5, 0.75, 1]
.
[x ... z]
expands to a list of numbers starting atx
, incrementing by 1 (or -1), and ending atz
.
For example: [0 ... 5]
expands to [0, 1, 2, 3, 4, 5]
. [5 ... 0]
expands to [5, 4, 3, 2, 1, 0]
.
New in Punctual 0.5.1
New functions pan
, panp
and splay
pan
(combinatorial) and panp
(pairwise) do equal-power panning over any number of output channels. Although their use is obvious in the audio domain, they can also be used to pan signals in the visual domain.
In this example, the pan
function is used to pan a line between the three channels of the add
output:
l << hline 0 0.01;
pan 3 (osc 0.13) l >> add;
The oscillator controls the speed of the panning, which is perceived as a color change in the line.
splay
spreads n channels over m outputs (again, with the same equal-power algorithm).
xs << [-0.5,-0.25,0,0.25,0.5];
splay 3 $ circle [xs,0] 0.1 >> add;
In this example, the splay
function spreads the five circles over three channels. Note that the first circle is sent to the first channel (red), the second between the first and second channels (yellow), and so on.
New in Punctual 0.5
If you’ve used Punctual before, you might be interested in the new features included in the recently released version 0.5. Below is a summary of the key updates.
Output Notations
Punctual 0.5 introduces new output notations, focusing on how patterns are combined rather than on the channels used.
While the old rgb
and rgba
notations still exist, they now have slightly different meanings.
The most commonly used output notations are now add
and blend
, with add
being the equivalent of rgb
in version 0.4, and blend
equivalent to rgba
. The mul
notation completes the set of available outputs.
All deprecated output notations have been removed, including red
, green
, blue
, hue
, saturation
, value
, hsv
, alpha
, and fdbk
.
For more details, see the output notations section.
Functions with Fewer Arguments
None of the texture-creating functions (fb
, fft
, ifft
) require arguments anymore.
For example, where you previously wrote fb fxy
, you now simply write fb
. Other expressions can be adapted similarly: for example, fb frt
can be replaced with setfxy frt fb
. This update aligns these functions with img
, vid
, and cam
, which already worked this way.
The fft
function is now equivalent to the 0.4 expression fft fx
.
Removed Functions
step
: useseq
,spr
orsprp
instead.zip
: not removed but deprecated. Use{}
instead.
Functions with Different Meaning
tile
andzoom
: see the details below.
Reimplementation in PureScript
Punctual 0.5 has been completely rewritten in PureScript, a functional programming language that compiles directly to JavaScript. Prior to version 0.5, Punctual was written in Haskell.
This switch simplifies the process of generating the final JavaScript version from Punctual’s source code, making it easier to develop new features. Additionally, it opens up possibilities for users to create their own modified versions of Punctual more easily.
Exolang
Punctual is now an exolang in Estuary. Essentially, this means that the Punctual code can be modified and these changes can be applied in Estuary without needing to alter any of Estuary’s code. As a result, bug fixes and new features can be implemented more quickly.
Since exolangs can be imported dynamically into Estuary, you can now use different versions of Punctual or even your own customized versions seamlessly. Different Estuary cells can even run different versions of Punctual simultaneously.
User-Defined Functions
You can now define your own functions and add them to Punctual!
User-defined functions are written in Punctual itself, accept arguments, and can contain any Punctual expression. The only limitation is that user functions must be written as one-liners.
For example, the user-defined pixelate
function implements a pixelation effect:
pixelate xy = setfxy $ (0.5+floor (fxy*:(xy/2)))/:(xy/2);
i << img "https://upload.wikimedia.org/wikipedia/commons/6/69/A_smiling_member_of_the_Ramnami_Samaj_%28edited%29.jpg";
pixelate [100,1000] i >> add;
External Script import
In addition to creating your own functions, you can now dynamically import Punctual code files using import
.
Any variables or functions defined in an imported file are immediately available to the rest of your Punctual code.
Files to be imported must be hosted on a CORS-enabled server, just like any other resource (such as images or videos). See Using your own images and videos for ideas on how to set this up.
Time Shifting Functions
Time functions are a new category in Punctual that allow you to control when changes in patterns occur.
This set includes four functions: slow
, fast
, late
, and early
.
Here’s an example of how they work:
l << hline (saw 0.1) 0.01;
[1,1,1]*l >> add;
[1,0,0]*slow 2 l >> add;
[0,1,0]*fast 2 l >> add;
[0,0,1]*late 2 l >> add;
[1,1,0]*early 2 l >> add;
Sequences
Punctual now allows you to create sequences of expressions using the new seq
function, which serves as a more flexible replacement for the removed step
function.
seq
overcomes the main limitation of step
, which could only handle a single number in each step.
For example:
s << seq [osc 0.2, 0];
hline s 0.01 >> add;
This will draw a horizontal line at height 0 half the time, and move it up and down according to the oscillator during the other half.
You can also use signals with different numbers of channels (all signals will be adjusted to the maximum number of channels present):
hline (seq [osc 0.3, saw [0.1,0.2,0.3]]) 0.01 >> add
By default, seq
completes one full iteration per cycle. You can control the speed and phase of the sequence using the time-shifting functions mentioned earlier.
Note, however, that this only covers cases where step was used with a saw
oscillator.
For more complex cases, you can use spr
(short for spread, combinatorial) or sprp
(pairwise). They are like the old step
function, but they work with multichannel semantics.
For example:
l << hline 0 0.01;
s << step [0.1, 0.5, 0, 0.8, 1.3] fx;
fit 1 $ spin s l >> add;
can be rewritten as:
l << hline 0 0.01;
s << spr [0.1, 0.5, 0, 0.8, 1.3] fx;
fit 1 $ spin s l >> add;
Additionally, you can use signals with different numbers of channels:
l << hline 0 0.01;
s << spr [0.1, -0.2, 0, {0.1, -0.1}, 0.2] fx;
fit 1 $ spin s l >> add;
Changes in Geometric Transformation Functions
In version 0.4, tile [1,4]
would repeat a pattern once on the horizontal axis and four times on the vertical axis. This behavior is now achieved using tilexy
.
In version 0.5, tile [1,4]
repeats the pattern once and four times, creating two versions of the pattern. In 0.4, this would have been written as tile [1,1,4,4]
.
There are two additional functions: tilex
, which only tiles patterns horizontally, and tiley
, which only tiles them vertically.
The same changes apply to the zoom
function, with corresponding zoomxy
, zoomx
, and zoomy
options.
New Operator {}
In Punctual 0.5, []
combines lists combinatorially, whereas {}
combines them pairwise.
In the following example, all nine circles are created by the []
expression, but only the three yellow ones appear when using {}
:
x << [-0.5, 0.2, 0.8];
y << [-0.8, 0, 0.5];
[1,0,0]*(mono $ circle [x,y] 0.1) >> add;
[0,1,0]*(mono $ circle {x,y} 0.1) >> add;
In version 0.4, this result could be achieved using circle (zip x y) 0.1
.
pxy
The new pxy
shortcut has been added, which is equivalent to [px, py]
.
Not yet implemented
The unrep
function, that worked in version 0.4, is not yet implemented in version 0.5.X.