# Declaring one-line Live-Loops

**URL:** <https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113>\
**Category:** Support, Help & Resources\
**Created:** [March 12, 2019, 3:54pm UTC](https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113 "2019-03-12T15:54:59Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bubo](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bubo/32/786_2.png) [@Bubo](https://in-thread.sonic-pi.net/u/Bubo)\
**Post date:** [March 12, 2019, 3:55pm UTC](https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113/1 "2019-03-12T15:55:00Z")

</div>

Hey,

Is there a way to create a more dense version of the live\_loop and other loop structures? One may be tempted to do something like this:

```
live_loop :test do ; play 50 ; sleep 1 ; end

```

What I would like to do is to define a type of loop that is limited to one line only and that can accept any number of arguments and things nested inside. Something like this:

```
ll :test play 50 ; sleep 1 

```

The idea behind this would be to quickly create a large number of loops synchronised to each other, like this:

```
ll :test play 50 ; sleep 1
ll :test2, sync: :test ; play 50 ; sleep 0.5
ll :test3, sync:: test ; et caetera

```

It may not be the best idea for what concerns code organization and language design, but I would still enjoy to play with something like this.

---

<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:** [March 13, 2019, 8:43am UTC](https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113/2 "2019-03-13T08:43:08Z")

</div>

I think that this is where a more dense pattern language like Ixi Lang makes sense…

I’m working on just that 🙂

---

<div class="post-metadata">

**Author:** ![bradgonesurfing](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bradgonesurfing/32/889_2.png) [@bradgonesurfing](https://in-thread.sonic-pi.net/u/bradgonesurfing)\
**Post date:** [March 13, 2019, 12:39pm UTC](https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113/3 "2019-03-13T12:39:24Z")

</div>

Given that sonic pi is just ruby under the hood you can create your own functions. For example

```
use_bpm 120

def lsample(name, sample_name, sleep_time)
  live_loop name do
    sync :zync
    sample sample_name, beat_stretch:sleep_time
    sleep sleep_time-0.001
  end
end

lsample :a, :loop_amen, 2
lsample :b, :ambi_piano, 2
lsample :c, :ambi_piano, 4
lsample :d, :ambi_piano, 8
lsample :e, :bass_woodsy_c, 16

live_loop :zync do
  sleep 0.5
end

```

But you do lose the intellisense of the sonic pi editor. That is you will have to remember all the sample names rather than get that little popup menu

---

<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:** [March 13, 2019, 12:50pm UTC](https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113/4 "2019-03-13T12:50:08Z")

</div>

For the record, the Sonic Pi way of defining functions is using `define`.

```ruby
define :lsample |name, sample_name, sleep_time| do
  live_loop name do
    sync :zync
    sample sample_name, beat_stretch:sleep_time
    sleep sleep_time-0.001
  end
end

```

Whilst `def` does currently work, it’s not supported and may break in a future version without warning.

---

<div class="post-metadata">

**Author:** ![Bubo](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bubo/32/786_2.png) [@Bubo](https://in-thread.sonic-pi.net/u/Bubo)\
**Post date:** [March 13, 2019, 1:04pm UTC](https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113/5 "2019-03-13T13:04:00Z")

</div>

@bradgonesurfing : yes but you lost the possibility of adding more parameters than those that you defined when writing the function in the first place.

@samaaron : Cool! I just have to wait then! Thanks!

---

<div class="post-metadata">

**Author:** ![bradgonesurfing](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bradgonesurfing/32/889_2.png) [@bradgonesurfing](https://in-thread.sonic-pi.net/u/bradgonesurfing)\
**Post date:** [March 13, 2019, 1:41pm UTC](https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113/6 "2019-03-13T13:41:49Z")

</div>

@bubo Within live\_loop you can do pretty much anything so if you want a more compact DSL you have to decide on what you want. However you can pass through abitrary keyword value maps using splats to the inner code making it more flexible. @samaaron thanks for the headsup on def vs define.

```
use_bpm 120

define :lsample do |name, sample_name, sleep_time, fx_name, **fx_parts|
  live_loop name do
    sync :zync
    with_fx fx_name, fx_parts do
      sample sample_name, beat_stretch:sleep_time
    end
    
    sleep sleep_time-0.001
  end
end

lsample :a, :loop_amen, 2, :wobble, mix:0.1
lsample :b, :ambi_piano, 20, :wobble
lsample :c, :ambi_piano, 4, :flanger, decay:0.5, amp: 2
lsample :d, :ambi_piano, 8, :none
lsample :e, :bass_woodsy_c, 8, :none
lsample :e, :bass_woodsy_c, 12, :none

live_loop :zync do
  sleep 0.5
end
```

---

<div class="post-metadata">

**Author:** ![binarysweets](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/binarysweets/32/2683_2.png) [@binarysweets](https://in-thread.sonic-pi.net/u/binarysweets)\
**Post date:** [March 13, 2019, 2:02pm UTC](https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113/7 "2019-03-13T14:02:52Z")

</div>

Can the same be done for threads?

I’d assume the following would play both parts at the same time, but it doesn’t.

```
use_bpm 130

define :run do |parts|
  parts.each { |part|
    in_thread do
      part
    end
  }
end

define :one do
  notes = (ring :a2, :a3, :a4, :a5)
  
  8.times do
    play notes.tick
    sleep 1
  end
end

define :two do
  notes = (ring :a2, :a3, :a4, :a5).reverse
  
  8.times do
    play notes.tick
    sleep 1
  end
end

run [one, two]
```

---

<div class="post-metadata">

**Author:** ![bradgonesurfing](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bradgonesurfing/32/889_2.png) [@bradgonesurfing](https://in-thread.sonic-pi.net/u/bradgonesurfing)\
**Post date:** [March 13, 2019, 2:33pm UTC](https://in-thread.sonic-pi.net/t/declaring-one-line-live-loops/2113/9 "2019-03-13T14:33:24Z")

</div>

The problem is that you can’t pass the method via

```
run [one, two]

```

when you type

```
  one

```

or

```
  two

```

you actually are evaluating the functions rather than passing the method pointer. Ruby evaluates functions without brackets. Easy mistake to make. You could solve it by passing **procs**

```
use_bpm 130

define :run do |parts|
  parts.each { |part|
    in_thread do
      part.call
    end
  }
end

define :one do
  notes = (ring :a2, :a3, :a4, :a5)
  
  8.times do
    play notes.tick
    sleep 1
  end
end

define :two do
  notes = (ring :a2, :a3, :a4, :a5).reverse
  
  8.times do
    play notes.tick
    sleep 1
  end
end

run [->() {one}, ->(){two}]

```

or by passing **symbols** and using **send** to evaluate them

```
use_bpm 130

define :run do |parts|
  parts.each { |part|
    in_thread do
      send part
    end
  }
end

define :one do
  notes = (ring :a2, :a3, :a4, :a5)
  
  8.times do
    play notes.tick
    sleep 1
  end
end

define :two do
  notes = (ring :a2, :a3, :a4, :a5).reverse
  
  8.times do
    play notes.tick
    sleep 1
  end
end

run [:one, :two]
```
