# Coding in the style of Arvo Pärt and... some questions!

**URL:** <https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441>\
**Category:** Creations & Ideas\
**Created:** [April 20, 2021, 4:00pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441 "2021-04-20T16:00:20Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ChrisLTIR](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/chrisltir/32/1725_2.png) [@ChrisLTIR](https://in-thread.sonic-pi.net/u/ChrisLTIR)\
**Post date:** [April 20, 2021, 4:00pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/1 "2021-04-20T16:00:20Z")

</div>

Hi everyone. I’m Chris, french musician and new to sonic pi.  
The first thing I tried is a generative version of Fur Alina, the famous piece by Arvo Pärt.

I created functions that corresponds to the “cells” of the piece, and by that I mean the little “parts” of two or more notes that shows little by little the principle of tintinnabuli : m-voice + t-voice.

If you don’t know how Pärt writes music, I highly recommend the Paul Hiller book about the composer’s style, it’s really interesting.

Anyway, here is my code. I’m sure it’s full of inelegant errors (and the commentaries are in french) but it’s a work in progress so …

Also, after I post this, I have a question for you people, about the use of functions 😉

> #code arvo pÃ¤rt  
> #fonctions tintinnabuli inspirÃ©e de fur alina  
> #version polyphonique play
> 
> define :drone do  
> play :B2, release: 5, amp: rrand(0.50, 1)  
> play :B0, release: 5, amp: rrand(0.50, 1)  
> sleep choose([2, 3, 4, 5])  
> end
> 
> define :a do  
> play :B3, release: 5, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :Fs2, release: 5, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :b do  
> play choose([:Cs4,:D4]), attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :B2, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :c do  
> play choose([:E4,:Fs4]), attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :D3, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :d do  
> play choose([:G4,:A4,:B4]), attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :Fs3, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :e do  
> play choose([:Cs4,:D4]), attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :B3, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :f do  
> play choose([:E5,:Fs5]), attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :D4, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :g do  
> play choose([:G5,:A5,:B5]), attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :Fs4, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :h do  
> play choose([:Cs6,:D6]), attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :B4, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :flower do  
> play :Fs5, attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :Cs4, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :bfa do  
> play :D4, attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :B2, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> define :dfa do  
> play :B4, attack: choose([0.2,0.5]), release: 3, amp: rrand(0.50, 1)  
> sleep choose([0, 1])  
> play :Fs3, attack: choose([0.2,0.5]), release: 4, amp: rrand(0.50, 1)  
> sleep choose([0.5, 1, 2, 3, 4, 5])  
> end
> 
> #structure
> 
> in\_thread(name: :arvopart) do  
> #uncomment to use one or another  
> #use\_play\_defaults port: ‘focusrite\_usb\_play’  
> #use\_play\_defaults port: ‘arturia\_minibrute\_2’
> 
> with\_fx :reverb, room: 0.9 do
> 
> ```
> loop do
>   
> use_synth :hollow
> drone
>   
> 14.times do
> choose ([a, b, c, d, e, f, g, h, flower])
> end
>   
> end
> 
> ```
> 
> end  
> end

---

<div class="post-metadata">

**Author:** ![ChrisLTIR](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/chrisltir/32/1725_2.png) [@ChrisLTIR](https://in-thread.sonic-pi.net/u/ChrisLTIR)\
**Post date:** [April 20, 2021, 4:03pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/2 "2021-04-20T16:03:21Z")

</div>

So, here is my question :

maybe you noticed that

> choose ([a, b, c, d, e, f, g, h, flower])

I discovered that sonic pi just plays the functions in that order, but I guess you understand what I tried there ^^  
Is there anyway to do it ?  
Help is really welcome.  
I’ll be posting the new versions here as soon as I can work on it.

Thanks a lot !

---

<div class="post-metadata">

**Author:** ![Nechoj](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/nechoj/32/1814_2.png) [@Nechoj](https://in-thread.sonic-pi.net/u/Nechoj)\
**Post date:** [April 20, 2021, 6:00pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/3 "2021-04-20T18:00:06Z")

</div>

Hi @ChrisLTIR  
welcome to the forum!  
If I understand your question correctly you are wondering why the `choose` command always produces the same sequence? If yes, that’s by design. As long as the random seed is the same, the result is deterministic.

If you use

```ruby
use_random_seed 7
d = choose([1, 2, 3, 4, 5, 6])
print(d)

```

you can influence the sequence of random elements.

Just a note: when posting code, put it inside 3 backticks ```. Then you’ll get color formating.

---

<div class="post-metadata">

**Author:** ![manu55](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/manu55/32/1728_2.png) [@manu55](https://in-thread.sonic-pi.net/u/manu55)\
**Post date:** [April 20, 2021, 7:05pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/4 "2021-04-20T19:05:14Z")

</div>

Hi ChrisLTIR.  
Nice code.

Maybe, we could use rrand\_i? in some place?

---

<div class="post-metadata">

**Author:** ![ChrisLTIR](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/chrisltir/32/1725_2.png) [@ChrisLTIR](https://in-thread.sonic-pi.net/u/ChrisLTIR)\
**Post date:** [April 20, 2021, 7:29pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/5 "2021-04-20T19:29:16Z")

</div>

Hi, thanks for the quick answer !

I came to understand how the \> choose command does the same sequence everytime, by reading the tutorial (which is really great !), thank you for the advice on the “use\_random\_seed” I completely forgot about that.

Actually through my tests this idea came : is that even possible to use that “choose” command to go through a list of functions ? Because actually sometime I really am under the impression that sonic pi just read the order in which I put the functions, ignoring the “choose” command… but I only did a few tests so I’m not sure.

But I guess my question is more about that : is it possible to treat functions like that, like if they were basic elements like notes of music ?

Thanks a lot again 🙂

---

<div class="post-metadata">

**Author:** ![ChrisLTIR](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/chrisltir/32/1725_2.png) [@ChrisLTIR](https://in-thread.sonic-pi.net/u/ChrisLTIR)\
**Post date:** [April 20, 2021, 7:30pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/6 "2021-04-20T19:30:24Z")

</div>

Hey !

Thanks, I’ll look into that !

---

<div class="post-metadata">

**Author:** ![Nechoj](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/nechoj/32/1814_2.png) [@Nechoj](https://in-thread.sonic-pi.net/u/Nechoj)\
**Post date:** [April 20, 2021, 7:37pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/7 "2021-04-20T19:37:51Z")

</div>

I see, you’re looking for something like this

```ruby
aa = ->{a}
bb = ->{b}
cc = ->{c}
dd = ->{d}

live_loop :foo do
  fun = [aa, bb, cc, dd].choose
  fun.call
end

```

The syntax `aa = ->{...}` assigns a lambda function to symbol `aa` which then can be called using `aa.call`. Within the body `{...}` you can have executable expressions, such as calling another function `a`.

---

<div class="post-metadata">

**Author:** ![ChrisLTIR](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/chrisltir/32/1725_2.png) [@ChrisLTIR](https://in-thread.sonic-pi.net/u/ChrisLTIR)\
**Post date:** [April 20, 2021, 7:49pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/8 "2021-04-20T19:49:23Z")

</div>

Wow, that really looks like the solution I’m looking for !

Thanks a lot, I’ll try it as soon as I can

---

<div class="post-metadata">

**Author:** ![ChrisLTIR](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/chrisltir/32/1725_2.png) [@ChrisLTIR](https://in-thread.sonic-pi.net/u/ChrisLTIR)\
**Post date:** [April 20, 2021, 7:50pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/9 "2021-04-20T19:50:37Z")

</div>

By the way, is that syntax anywhere talked about in the tutorial that’s within the software ?

---

<div class="post-metadata">

**Author:** ![Nechoj](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/nechoj/32/1814_2.png) [@Nechoj](https://in-thread.sonic-pi.net/u/Nechoj)\
**Post date:** [April 20, 2021, 7:51pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/10 "2021-04-20T19:51:58Z")

</div>

That’s pure Ruby stuff, see [Ruby Lambdas](https://www.rubyguides.com/2016/02/ruby-procs-and-lambdas/#What_is_a_Lambda).

---

<div class="post-metadata">

**Author:** ![ChrisLTIR](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/chrisltir/32/1725_2.png) [@ChrisLTIR](https://in-thread.sonic-pi.net/u/ChrisLTIR)\
**Post date:** [April 20, 2021, 7:54pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/11 "2021-04-20T19:54:11Z")

</div>

Nice ! Going to investigate further.

Thanks !

---

<div class="post-metadata">

**Author:** ![ethancrawford](https://avatars.discourse-cdn.com/v4/letter/e/a88e4f/32.png) [@ethancrawford](https://in-thread.sonic-pi.net/u/ethancrawford)\
**Post date:** [April 21, 2021, 12:08am UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/12 "2021-04-21T00:08:15Z")

</div>

> [@ChrisLTIR](#):
>
> Wow, that really looks like the solution I’m looking for !

That’s definitely one way of doing it, sure. 🙂 There are others, such as using Ruby’s `method()`.

One thing to remember is that as usual, any code which is not specifically from Sonic Pi’s language (ie, plain Ruby for example) is not officially supported and may stop working at any time as we make changes.

---

<div class="post-metadata">

**Author:** ![blipson](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/blipson/32/1772_2.png) [@blipson](https://in-thread.sonic-pi.net/u/blipson)\
**Post date:** [April 21, 2021, 6:42am UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/13 "2021-04-21T06:42:49Z")

</div>

Any examples of when a lambda would be particularly desirable when using SPI?

---

<div class="post-metadata">

**Author:** ![ethancrawford](https://avatars.discourse-cdn.com/v4/letter/e/a88e4f/32.png) [@ethancrawford](https://in-thread.sonic-pi.net/u/ethancrawford)\
**Post date:** [April 21, 2021, 7:03am UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/14 "2021-04-21T07:03:18Z")

</div>

They’re already mentioned sneakily as part of the ‘official’ language, but in very specific usage cases: as a way to filter sample packs for example: [Sonic Pi - Tutorial](https://sonic-pi.net/tutorial#section-3-7) 🙂  
(There may have been one or two other places, but I can’t quite remember off the top of my head).

---

<div class="post-metadata">

**Author:** ![Nechoj](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/nechoj/32/1814_2.png) [@Nechoj](https://in-thread.sonic-pi.net/u/Nechoj)\
**Post date:** [April 21, 2021, 7:46am UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/15 "2021-04-21T07:46:39Z")

</div>

It has been used also in this post: [Self-modifying algorithms](https://in-thread.sonic-pi.net/t/self-modifying-algorithms/5360/25). @amiika came up with the idea to have lambda functions as part of the rules system (= hash map).

---

<div class="post-metadata">

**Author:** ![samaaron](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/samaaron/32/7_2.png) [@samaaron](https://in-thread.sonic-pi.net/u/samaaron)\
**Post date:** [April 21, 2021, 8:30am UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/16 "2021-04-21T08:30:14Z")

</div>

Hi @Nechoj and @ChrisLTIR

> [@Nechoj](#):
>
> If yes, that’s by design. As long as the random seed is the same, the result is deterministic.

Just to clear matters, although this is generally accurate in terms of lists/rings of existing elements it’s not actually what’s causing the observed behaviour in this case.

What we have here is a case of non-lazy lists being constructed _before_ any randomisation happens.

It’s a tricky thing to wrap your head around, so give it a few tries after I’ve explained - and I hope I can be clear enough.

Consider this list:

```ruby
[1, 2, 3]

```

When the code (text) is read by the computer it constructs an equivalent list in memory that can then be used. This is an implicit action that happens automatically at the time the list is encountered by the language runtime. You can think of it as a “step”.

The following code has two steps:

```ruby
[1, 2, 3].choose

```

The steps are:

1. Construct a list containing the numbers 1, 2 and 3.
2. Choose a random element from that list.

Hopefully this makes some sense so far.

Now, let’s complicate things by adding functions:

```ruby
define :a do
  1
end

define :b do
  2
end

define :c do
  3
end

[a, b, c]

```

So, what happens here? Well first, we define 3 functions called `a, b` and `c`. Then we do something we’ve seen earlier which is to “construct a list”. What are the elements of the list? Well, actually we don’t know, we just know that they are the results of the functions `a, b` and `c` respectively. So the language runtime calls these functions in turn and uses their results to construct the list `[1, 2, 3`].

It’s this behaviour of having to construct the list which is what is being observed by the original question.

We can make this really obvious:

```ruby
define :a do
   puts "hello"
   1
end

[a]

```

When we run this code, we see that `"hello"` is printed to the log. This is because the function `a` had to be called when the list is constructed.

So, to bring it all together, let’s look at all the steps in the following code:

```ruby
define :a do
  1
end

define :b do
  2
end

define :c do
  3
end

[a, b, c].choose

```

1. Define functions `a`, `b` and `c`.
2. Construct the list `[a, b, c]` which in turn requires us to…
  1. Call function `a` which returns 1
  2. Call function `b` which returns 2
  3. Call function `c` which returns 3

3. Put our new list `[1, 2, 3]` into memory
4. Choose a random element from the list

Notice that we have to call all the functions _in order_ as part of the list construction.

The solution that uses lambdas avoids the need to call the functions because the lambdas are actually values like numbers, so they can be constructed in memory just fine and calling `.choose` will just return a random lambda. Only when you _call_ the lambda will its code be executed - so you get to choose when that happens explicitly.

I do hope that this helps in some way. 🙂

---

<div class="post-metadata">

**Author:** ![ChrisLTIR](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/chrisltir/32/1725_2.png) [@ChrisLTIR](https://in-thread.sonic-pi.net/u/ChrisLTIR)\
**Post date:** [April 21, 2021, 1:16pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/17 "2021-04-21T13:16:57Z")

</div>

Thank you very much !

I’ll look into all of it soon, thanks for the reply ! And congrats Sam on that wonderful software.

---

<div class="post-metadata">

**Author:** ![samaaron](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/samaaron/32/7_2.png) [@samaaron](https://in-thread.sonic-pi.net/u/samaaron)\
**Post date:** [April 21, 2021, 1:29pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/18 "2021-04-21T13:29:23Z")

</div>

Thanks @ChrisLTIR and welcome to our community - it’s so lovely to have you here 🙂

---

<div class="post-metadata">

**Author:** ![Nechoj](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/nechoj/32/1814_2.png) [@Nechoj](https://in-thread.sonic-pi.net/u/Nechoj)\
**Post date:** [April 21, 2021, 2:31pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/19 "2021-04-21T14:31:28Z")

</div>

Very precise and clear, thanks!

---

<div class="post-metadata">

**Author:** ![pashultz](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/pashultz/32/1964_2.png) [@pashultz](https://in-thread.sonic-pi.net/u/pashultz)\
**Post date:** [April 25, 2021, 8:11pm UTC](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441/20 "2021-04-25T20:11:34Z")

</div>

I love this project! It’s a perfect (to my ear) imitation of Pärt’s style, and that combination of synth and effects sounds great. So impressive.

I’ve done a few similar projects that generate “infinite” versions of a familiar piece of music. It’s such a satisfying exercise—for this semi-lapsed music theorist, it scratches that analytical itch while also being fun to listen to and play with. I keep meaning to clean up and post my efforts—would any of you be interested in contributing to an “album” along these lines?

[Next page](https://in-thread.sonic-pi.net/t/coding-in-the-style-of-arvo-part-and-some-questions/5441.md?page=2)
