# Syntax tips for stitching Tidal functions together

**URL:** <https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728>\
**Category:** TidalCycles\
**Tags:** questions\
**Created:** [10 January 2021 17:58 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728 "2021-01-10T17:58:17Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![mbutz](https://uzu.lurk.org/user_avatar/uzu.lurk.org/mbutz/32/1085_2.png) [@mbutz](https://uzu.lurk.org/u/mbutz)\
**Post date:** [10 January 2021 17:58 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728/1 "2021-01-10T17:58:17Z")

</div>

Before I am asking for more let me say that the help I got from this forum is excellent and very friendly. Alex's weekly course videos and his other videos as well as the recorded frequently faq sessions (also with Lucy) are great. And last but not least I really appreciate the userbase and all its help documents; finally Hoogle can be of help even if this can be much to digest for a beginner. Many, many thanks for that!

In another posting I did mention that I also found [Carsten Heisterkamp's introduction](https://medium.com/@heisterkamp/tidal-adventures-ab627f05ef7c) quite helpful. Especially the list of guidelines to explore and first and foremost to combine Tidal functions is something which for me - and I suppose any beginner - is potentially fruitful. Under the heading "Composing functions the right way" he writes:

> Tidal really gets fun when you learn how to write your patterns and manipulate and alter them by intuitively sticking functions together without being interrupted by the compiler and searching for bugs in your code. This is most of the time the case, either because of typos and most of the time because we tried to combine functions with signatures which do not fit.

I am quite aware that the internals of type signatures and related language internals are not everyone's cup of tea but I really like to dive in and found Heisterkamp's argument quite convincing (for me). This is where I started a few months ago. Besides the mentioned article there are some resources about expressions like `$` and `#` and I guess I meanwhile have consumed all of it (which obviously does _not_ mean: _understood_ all of it). I think I now can interpret type signatures and I have an idea about how these can help to find out how to combine Tidal functions.

On the other hand I still have a lot of questions, am confused especially about syntax and find myself using trial-an-error-methods (interesting to explore a programming language solely with empirical methods like it was nature 😉 ), which is not wrong but I'd appreciate also a logically guided and systematic way.

So here are some very helpful yet also confusing hints from the mentioned article (see the chapter titled "Composing functions the right way"); this is step 4 and 5 he provides with reference to a reasonably complex example:

"4. If you want to use a function that returns a pattern inside a function that takes a pattern of type ControlMap, you need to evaluate it first with the bracket () notation, like juxcut (# speed 2)"

"5. Vice versa if you want to use a function which can not be used with the # because they don´t take but return pattern inside a function that takes a pattern you also need to evaluate them first with the bracket notation ().For example # pan (slow 4 $ sine ) or # gain(choose [0.5 0.75 1])

The example code is:

```haskell
d1 $ slow 4
   $ spaceOut (map (1/) [1, 1.2 .. 10])
   $ sometimesBy 0.66 (rev)
   $ rarely (juxcut(# speed (choose[0.33, 0.5, 0.66, 0.75, 1.5, 2]))) 
   $ sound “bd*4”
   # n (choose[1, 3, 5, 7])
   # pan (slow 4 $ sine )
   # orbit 0

```

Now looking at the type signatures tells me:

`juxcut :: (Pattern ControlMap -> Pattern ControlMap) -> Pattern ControlMap -> Pattern ControlMap`

and

`speed :: Pattern Double -> ControlPattern`

In this respect hint #4 makes some sense (leaving also some darkness):

As far as I have understood a `ControlMap` [is or can be a subunit of a control pattern](http://www.imn.htwk-leipzig.de/~waldmann/etc/untutorial/tc/types/) and serves to directly control sound resp. Supercollider (pardon me if this is very simplistic but it is what I have grasped so far). In really simple words: As `speed` supplies a pattern and `juxcut` expects one, the `#` function is necessary to combine both (which does not really seem to be the correct explanation now that I am reading my text again...).

There are other similar cases such as `every` I e. g. found in an example from a Kindohm interview:

```haskell
d1
  $ every 3 (0.5 <~)
  $ every 4 (chop 4)
  $ every 5 (# speed "1.5 -1 0.5")
  $ every 6 (# crush 2)
  $ every 7 (rev)
  $ stack [sound "bd(3,8)", sound "cp*2"]

```

```haskell
speed :: Pattern Double -> ControlPattern
crush :: Pattern Double -> ControlPattern
pan :: Pattern Double -> ControlPattern

```

The type signature of `every` is:

```haskell
every :: Pattern Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a

```

So this is obviously a case where the Heisterkamp rule #4 applies but this rule does not seem to be defined as general as it should or could: `every` does not expect a 'ControlPattern' but - patterns of type int and a and a function.

There are other functions where the `#` is not necessary such as

```haskell
$ every 7 (rev)

rev :: Pattern a -> Pattern a

```

and

```haskell
$ every 2 (chop 4)

chop :: Pattern Int -> ControlPattern -> ControlPattern

```

So I am sure this is all explainable in a very logic way. It is just that I can't see it with the knowledge I have been able to gain so far.

Finally I am not really sure how the rule #5 fits into the image. Actually I see the reference within the code example but I can't really map the rule with the type signatures:

```haskell
# pan (slow 4 $ sine )

slow :: Pattern Time -> Pattern a -> Pattern a
pan :: Pattern Double -> ControlPattern

```

It might be, that my lack of understanding rises from the fact that I don't really understand the conceptual differences between `ControlMap`, `ControlPattern` and some other `Pattern`.

I really do hope that I was able not only sound like I am complaing about my confusion but also to somehow give it a form that someone more experienced can pick up the tread and help to clear this up. It is somehow quite difficult to come up with clear questions (usually once you have a clear question the answer is not far away).

I guess my main question is, whether it is possible to extend the already awesome resources that exist with a document titled something like "Syntax tips for stitching Tidal functions together" (sorry, English is not my first lanuage).

I reckon this would not only help me but also other beginners.

Anyway, if you have come to this point: Thanks for reading these lengthy notes!

---

<div class="post-metadata">

**Author:** ![jwaldmann](https://uzu.lurk.org/letter_avatar_proxy/v4/letter/j/977dab/32.png) [@jwaldmann](https://uzu.lurk.org/u/jwaldmann)\
**Post date:** [11 January 2021 12:56 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728/2 "2021-01-11T12:56:00Z")

</div>

Hi.

You took great care, and length, to describe the situtation. Much appreciated.

You ask about (concrete) syntax (= what you write/see), but a discussion of abstract syntax (= the tree shape that is described by concrete syntax), and static semantics (= types) should be helpful.

This is about expressions built from operators (I am showing a `ghci` session)

```haskell
:i ($)
($) :: (a -> b) -> a -> b -- Defined in ‘GHC.Base’
infixr 0 $

```

and

```haskell
:i (#)
(#) :: Unionable b => Pattern b -> Pattern b -> Pattern b
  	-- Defined in ‘Sound.Tidal.Core’

```

Since `#` has no explicit "fixity", the declaration `infixl 9 #` is assumed ([4 Declarations and Bindings](https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-820004.4.2))

This "fixity" is important to know who is applied to whom. It contains this information:

- right associativity (of `$`): `f $ g $ h $ x` means `f $ (g $ (h $ x))` - if you draw the abstract syntax tree (AST) where `$` nodes are binary, you get a list-like tree, hanging to the right
- left associativity (of `#`): `a # b # c # d` means `((a # b) # c) # d` - tree hanging to the left
- precedence (that of `#` is higher than that of `$`): `f $ a # b` means `f $ (a # b)`.

Once we have the AST, we can insert type information at each node.

- The left child of `$` must be a function (of type `t1 -> t2`, for some types `t1, t2`), the right child must be of type `t1`, and the root (where `$` is) has type `t2`. Often, `t1` and `t2` are patterns. The dynamic semantics of `f $ x` is "apply f to x"
- For `#`, both children must be patterns, with a `Unionable` event type, and the root has the same pattern type. The semantics of `a # b` is "combine events of a and b"

The relation between the types you mention is

```haskell
:i ControlPattern
type ControlPattern :: *
type ControlPattern = Pattern ControlMap
:i ControlMap
type ControlMap :: *
type ControlMap = Data.Map.Internal.Map String Value
:i Value
type Value :: *
data Value
  = VS {svalue :: String, vbus :: Maybe Int}
 | ...

```

A `ControlPattern` is what you can send to the back-end (with `d1`, etc.), but patterns with other event types might be used in construction.

* * *

About "extend the already awesome resources that exist with ..."

If someone wants to use the above, go ahead. But -

I'm afraid there's no short-cut here to the classical approach in programming languages:

- concrete syntax (ASCII representation)
- abstract syxtax (tree representation)
- static semantics (types)
- dynamic semantics (execution, evaluation) \<== that's where you hear the music

but you might say I'm "biased" as I am getting paid for researching and teaching these things.

Now music (also, graphics) can be used in introductions to programming: students can start to do something audible/visible/creative immediately, while learning aspects of programming, and of a concrete language, along the way. E.g., [Home Page](https://www.cs.yale.edu/homes/hudak/SOE/index.htm) , [Haskell School of Music – Euterpea](http://www.euterpea.com/haskell-school-of-music/) Also, see this recent thread about teaching Haskell [[Haskell-cafe] Teaching High-School one-semester FP (using Haskell)](https://mail.haskell.org/pipermail/haskell-cafe/2020-December/133125.html)

But Tidal's goal is not "learning Haskell", it's "making music". The (hypothetical) claim "you can make music, without worring about Haskell" is risky. It somehow works as long as you stay in the mini language, and have a fixed expression on the outside, but it breaks down as soon as you 1) want to know why it's working, or 2) leave that fixed shape.

It is also risky (by me) preaching the one true Haskell way here - one possible outcome being "we don't need static semantics anyway" and switch (music) programming to Python or Javascript - an error that many universities are currently proudly making... But the fact is that types (type constructors like `Pattern`, type classes like `Applicative`) are not just nice for software correctness - they are also essential for effective programming (writing, and maintaining, less code - because that code can be much more expressive). Recent example: [Ply and chords - #7 by yaxu](https://club.tidalcycles.org/t/ply-and-chords/2724/7)

There are lots of instances of this in Tidal's source , but they rarely become visible in performances. Perfectly understandable - there's a difference between changing some number (hardware synthesizer: turning a knob) and re-wiring the innards (soldering iron).

---

<div class="post-metadata">

**Author:** ![mbutz](https://uzu.lurk.org/user_avatar/uzu.lurk.org/mbutz/32/1085_2.png) [@mbutz](https://uzu.lurk.org/u/mbutz)\
**Post date:** [11 January 2021 20:24 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728/3 "2021-01-11T20:24:11Z")

</div>

Thanks a lot for taking the time to read and answer. I will have to process this. I really have to make my way and understand concepts which probably are basic stuff for you (_static semantics_ as only one of many examples). Nevertheless I feel like this is mental workout. I actually enjoy watching talks about functional programming aso. understanding only ... well ... maybe 10 or 20 percent (to be fair to myself: Sometimes I do understand more than that;) )? It is probably my way to slowly get acquainted with ways of thinking which are somehow alien to me.

So yes, I want to make music with Tidal/Haskell which is what I am already doing. I don't really care too much about the code in these moments and more about the aesthetic outcome. Main criteria: is this interesting?

And also yes: I am very keen on understanding why and how this works. And there are practical reasons for that: Mainly I am eager to gain some kind of freedom in using Tidal because then it becomes easier to invent when you not always hounded by syntax errors. (There are also more pure or theoretical reasons which have to do with the mentioned 'mental workout'.)

The good thing: I am not in a hurry. So I when I have time and energy I will crawl down the rabbit whole and be glad if I can ask more or hopefully less silly questions here and get some answers also from time to time.

So again, I need some time to try and understand what you have written. Thanks!

---

<div class="post-metadata">

**Author:** ![yaxu](https://uzu.lurk.org/user_avatar/uzu.lurk.org/yaxu/32/2_2.png) [@yaxu](https://uzu.lurk.org/u/yaxu)\
**Post date:** [11 January 2021 21:05 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728/4 "2021-01-11T21:05:31Z")

</div>

`ControlPattern` is defined like this:

```haskell
type ControlPattern = Pattern ControlMap

```

So it's a pattern of controlmaps, in the same way as a `Pattern Int` is a pattern of integer numbers.

What's a controlmap? Actually just a dictionary (aka associative array, hash map, lookup table etc), of keys and values, to represent a message to send to superdirt. Each key is the name of a parameter, like 'speed', with a value, like `1.5`.

You say `every` doesn't seem to expect a `ControlPattern`:

```haskell
every :: Pattern Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a

```

The reason it works is you can replace the `a`s with _any_ other type, including `ControlMap`.. and `ControlPattern` is really just an alias for `Pattern ControlMap`.

The same for `rev`, it works on `Pattern a`, where `a` is unconstrained.. So it will work on `ControlPattern`s too.

```haskell
speed :: Pattern Double -> ControlPattern

```

Is maybe clearer like this:

```haskell
speed :: Pattern Double -> Pattern ControlMap

```

In that speed takes all the numbers in the pattern (with are of type `Double`) and replaces each one with a dictionary, each of which has only one entry, for `speed`, with the number as the value.

I don't understand what Carsten Heisterkamp is getting at with rule #4. I think it is not really true. In terms of syntax there are not really any special rules for using `ControlMap` or `#`, just very general Haskell rules for how to use operators, functions and parenthesis.

Looking at an example:

```haskell
jux (# speed 2) $ sound "bd sn"

```

`jux` wants a function for its first parameter, which gets applied to the ControlPattern (aka `Pattern ControlMap`) in its second parameter. It could be something like `rev` of type `Pattern a -> Pattern a`, because 'a' can stand for a controlmap - rev doesn't care what kind of pattern its working on.

This _wouldn't_ work, because `speed 2` doesn't have the right type signature - it isn't even a function.

```haskell
jux (speed 2) $ sound "bd sn"

```

`#` is a function, but it's one that takes _two_ patterns as arguments. This working version works because it uses `#`, but with one of its arguments 'filled in'.. Which turns it into a new function that accepts the remaining argument.

```haskell
jux (# speed 2) $ sound "bd sn"

```

In case it surprises you - `#` is a function, just like `every`. The only difference between operators like `#` and functions like `#` is that operators always have two arguments, and the first of its arguments appears on its left.

Hope that helps, please keep asking questions until it's clear!

---

<div class="post-metadata">

**Author:** ![mbutz](https://uzu.lurk.org/user_avatar/uzu.lurk.org/mbutz/32/1085_2.png) [@mbutz](https://uzu.lurk.org/u/mbutz)\
**Post date:** [12 January 2021 20:58 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728/5 "2021-01-12T20:58:33Z")

</div>

Thanks a lot for this detailed response, very helpful indeed! I need some time to process as work is overwhelming right now.

> [@yaxu](#):
>
> ... because `speed 2` doesn't have the right type signature - it isn't even a function.

This is especially insightful for me.

---

<div class="post-metadata">

**Author:** ![yaxu](https://uzu.lurk.org/user_avatar/uzu.lurk.org/yaxu/32/2_2.png) [@yaxu](https://uzu.lurk.org/u/yaxu)\
**Post date:** [12 January 2021 22:07 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728/6 "2021-01-12T22:07:33Z")

</div>

To be clear `speed` is a function, but `speed 2` isn't, because it has all its inputs.

---

<div class="post-metadata">

**Author:** ![mbutz](https://uzu.lurk.org/user_avatar/uzu.lurk.org/mbutz/32/1085_2.png) [@mbutz](https://uzu.lurk.org/u/mbutz)\
**Post date:** [12 January 2021 22:20 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728/7 "2021-01-12T22:20:08Z")

</div>

So if it is evaluated it is an applied function returning a value?

---

<div class="post-metadata">

**Author:** ![yaxu](https://uzu.lurk.org/user_avatar/uzu.lurk.org/yaxu/32/2_2.png) [@yaxu](https://uzu.lurk.org/u/yaxu)\
**Post date:** [12 January 2021 22:25 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728/8 "2021-01-12T22:25:27Z")

</div>

Yes that's right.

```haskell
:t speed
speed :: Pattern Double -> ControlPattern
:t speed 2
speed 2 :: ControlPattern

```

Strictly speaking, a function is a special kind of value, that takes an input.

---

<div class="post-metadata">

**Author:** ![mbutz](https://uzu.lurk.org/user_avatar/uzu.lurk.org/mbutz/32/1085_2.png) [@mbutz](https://uzu.lurk.org/u/mbutz)\
**Post date:** [16 January 2021 19:58 UTC](https://uzu.lurk.org/t/syntax-tips-for-stitching-tidal-functions-together/2728/9 "2021-01-16T19:58:18Z")

</div>

Thank you both, much appreciated advice. The fog is clearing. Slowly but surely.
