1--- 2title: Strudel vs Tidal 3layout: ../../layouts/MainLayout.astro 4--- 5 6import { MiniRepl } from '../../docs/MiniRepl'; 7import { JsDoc } from '../../docs/JsDoc'; 8 9# Comparing Strudel and Tidal 10 11This page is dedicated to exisiting tidal users, giving an overview of all the differences between Strudel and Tidal. 12 13## Language 14 15Strudel is written in JavaScript, while Tidal is written in Haskell. 16 17### Example 18 19This difference is most obvious when looking at the syntax: 20 21```haskell 22iter 4 $ every 3 (||+ n "10 20") $ (n "0 1 3") # s "triangle" # crush 4 23``` 24 25One _could_ express that pattern to Strudel like so: 26 27``` 28iter(4, every(3, add.squeeze("10 20"), n("0 1 3").s("triangle").crush(4))) 29``` 30 31- The `$` operator does not exist, so the `iter` function has to wrap everything in parens. 32- Custom operators like `||+` are explicit function calls, `add.squeeze` in this case 33- The `#` operator is replaced with a chained function call `# crush 4` => `.crush(4)` 34 35Unlike Haskell, JavaScript lacks the ability to define custom infix 36operators, or change the meaning of existing ones. 37 38Before you discard Strudel as an unwieldy paren monster, look at this alternative way to write the above: 39 40``` 41n("0 1 3").every(3, add.squeeze("10 20")).iter(4).s("triangle").crush(4) 42``` 43 44By reordering calls, the parens are much less nested. 45As a general rule by thumb, you could say that everything Tidal does with `$` is reversed in Strudel: 46 47`iter 4 $ every 3 (||+ n "10 20") $ (n "0 1 3")` 48 49becomes 50 51`n("0 1 3").every(3, add.squeeze("10 20")).iter(4)` 52 53Simply put, `foo x $ bar x` becomes `bar(x).foo(x)`. 54 55### Operators 56 57The [custom operators of tidal](https://tidalcycles.org/docs/reference/pattern_structure/#all-the-operators) are normal functions in strudel: 58 59| function | tidal | strudel | 60| ----------- | ------ | ------- | 61| add | \|+ n | .add(n) | 62| subtract | \|- n | .sub(n) | 63| multiply | \|\* n | .mul(n) | 64| divide | \|\/ n | .div(n) | 65| modulo | \|\% n | .mod(n) | 66| left values | \|\< n | .set(n) | 67 68The above list only displays the operators taking the structure comes from the `left`. 69For each of those, a `right` and `both` variant also exists. 70As this directional thinking only works with code, strudel calls these `in` / `out` / `mix`: 71 72| direction | tidal | strudel | 73| --------- | ------- | ----------- | 74| left | \|+ n | .add.in(n) | 75| right | +\| n | .add.out(n) | 76| both | \|+\| n | .add.mix(n) | 77 78Instead of `+` / `add`, you can use any of the available operators of the first list. 79 80## Function Compatibility 81 82[This issue](https://codeberg.org/uzu/strudel/issues/31) tracks which Tidal functions are implemented in Strudel. 83The list might not be 100% up to date and probably also misses some functions completely.. 84Feel encouraged to search the source code for a function you're looking for. 85If you find a function that's not on the list, please tell! 86 87## Control Params 88 89As seen in the example, the `#` operator (shorthand for `|>`) is also just a function call in strudel. 90So `note "c5" # s "gtr"` becomes `note("c5").s('gtr')`. 91 92[This file](https://codeberg.org/uzu/strudel/src/branch/main/packages/core/controls.mjs) lists all available control params. 93Note that not all of those work in the Webaudio Output of Strudel. 94If you find a tidal control that's not on the list, please tell! 95 96## Sound 97 98Tidal is commonly paired with Superdirt / Supercollider for sound generation. 99While Strudel also has a way of [communicating with Superdirt](/learn/input-output/), 100it aims to provide a standalone live coding environment that runs entirely in the browser. 101 102### Audio Effects 103 104Many of SuperDirt's effects have been reimplemented in Strudel, using the Web Audio API. 105You can find a [list of available effects here](/learn/effects/). 106 107### Sampler 108 109Strudel's sampler supports [a subset](/learn/samples) of Superdirt's sampler. 110Also, samples are always loaded from a URL rather than from the disk, although [that might be possible in the future](https://codeberg.org/uzu/strudel/issues/118). 111 112## Evaluation 113 114The Strudel REPL does not support [block based evaluation](https://codeberg.org/uzu/strudel/issues/34) yet. 115You can use labeled statements and `_` to mute: 116 117<MiniRepl 118 client:visible 119tune={`$: n("[0 .. 8]*8/9").scale("C:minor:pentatonic") 120 121\_$: s("bd\*4").bank('RolandTR909')`} 122/> 123 124## Tempo 125 126Strudels tempo is 1 cycle per second, while tidal defaults to `0.5625`. 127You can get the same tempo as tidal with: 128 129``` 130note("c a f e").fast(.5625); 131``` 132 133Next up: the [REPL](/technical-manual/repl)