# Motivating examples for (squeeze)Join

**URL:** <https://uzu.lurk.org/t/motivating-examples-for-squeeze-join/6213>\
**Category:** TidalCycles\
**Tags:** resources\
**Created:** [2 September 2026 11:17 UTC](https://uzu.lurk.org/t/motivating-examples-for-squeeze-join/6213 "2026-09-02T11:17:21Z")\
**Posts on this page:** 3\
**Page:** 1

<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:** [2 September 2026 11:17 UTC](https://uzu.lurk.org/t/motivating-examples-for-squeeze-join/6213/1 "2026-09-02T11:17:21Z")

</div>

A _join_ function has type `Pattern (Pattern a) -> Pattern a`.

There are several joins (innerJoin, outerJoin, unwrap, squeezeJoin) in the tidalcycles library, and they are used to implement other functions. Looking at tidalcycles performances, it is my impression that joins rarely occur visibly in applications.

Here are two examples that show why joins might be useful:  
[https://www.imn.htwk-leipzig.de/~waldmann/etc/untutorial/tc/join/](https://www.imn.htwk-leipzig.de/~waldmann/etc/untutorial/tc/join/)

If you have more examples, or questions, regarding joins, bring them to the workshop [https://www.imn.htwk-leipzig.de/LFUNK2026/](https://www.imn.htwk-leipzig.de/LFUNK2026/) (September 29), or/and post them here beforehand.

---

<div class="post-metadata">

**Author:** ![mrreason](https://uzu.lurk.org/user_avatar/uzu.lurk.org/mrreason/32/3203_2.png) [@mrreason](https://uzu.lurk.org/u/mrreason)\
**Post date:** [2 September 2026 18:06 UTC](https://uzu.lurk.org/t/motivating-examples-for-squeeze-join/6213/2 "2026-09-02T18:06:56Z")

</div>

I am a huge fan of `squeezeJoin`. Naturally it is used with the `inhabit` function. I use this to create progressions and drum beats. It means, that you can control a pattern with a pattern like this:

```haskell
do
let drum pt f = inhabit [
      ("1", f $ s "[bd(3,8), hh*4]" )
      ,("2", f $ s "[bd*4, ~ sn, hh*4 hh*8]" )
      ,("f1",f $ s "sn!2 bd!4 sn!2 tom:1! tom:0!" )
      ] pt
    bubu = (fast "<1 1 2 1>" . ply "<1!3 1>" ) 
d1 $ drum "<1 2 1 f1>" (bubu) 

```

And then you can decide whether you want to apply a function on the outer or the inner pattern. I have a custom implementation for this but basically I use it like in the code snippet above, i.e.

```haskell
drums (inner_pattern_function "1") outer_pattern_function

```

For a live coding performance I use numbers to control a pattern, because it is really easy to change the numbers with a simple shortcut in NeoVim.

---

<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:** [2 September 2026 19:53 UTC](https://uzu.lurk.org/t/motivating-examples-for-squeeze-join/6213/3 "2026-09-02T19:53:20Z")

</div>

Ah, I didn't know about `inhabit`. I just looked it up [https://hackage-content.haskell.org/package/tidal-core-1.10.2/docs/src/Sound.Tidal.UI.html#inhabit](https://hackage-content.haskell.org/package/tidal-core-1.10.2/docs/src/Sound.Tidal.UI.html#inhabit) and it's basically doing what I did in my first example (replace string with pattern)? Ok, then we (and the library authors) agree that it's a useful application of `join`.

(end of statement, begin of opinion)

Where we might disagree is whether `inhabit` is above the [https://wiki.haskell.org/Fairbairn\_threshold](https://wiki.haskell.org/Fairbairn_threshold). Their example is: you wouldn't need a function `fooBar` if the implementation is just `foo . bar`. Well, if you know what the dot means (function composition). The point is, "join" is very much similar (basic and thus, important) as it allows for composing functions `a -> Pattern b` (cf. [https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Monad.html#v:-62--61--62-](https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Monad.html#v:-62--61--62-) )
