Colon mystery as prefix or postfix

I have noticed that colons are used quite a lot in sonic pi, not as I understand in the way other languages may use. Sometimes it seems a part of name, like the one “:foo” in “sync: :foo”, sometimes it’s as normal colon, like the one follows the sync previously metioned. And sometimes you don’t need a colon in the name, like "sample_name = :loop_amen
sample sample_name " but sometimes you need, like "in_thread(name: :amen) "
It’s a little confusing. Is it the rule that all the function names, loop, thread names and synth, sample names, and sync names need to be prefixed with a colon? But variables don’t need? Sometimes I can’t figure out their difference.

This is down to the syntax of Ruby.

Symbols start with :, such as :blah. (If you’re not sure what symbols are, it’s worth reading a bit of the Ruby documentation, but essentially they are similar to ordinary text strings, and in most cases can be used interchangeably, unless the code you’re passing it to is specifically designed against this).

Ruby hashes can have keys that are symbols, and in that case they can either start or end with :
Eg { :key => value } or { key: value }.

sync: :foo is an example of the latter style.
(It’s shorthand for { sync: :foo } because you can often omit the braces).

The { :key => value } style is not used a lot in Ruby these days.

You are right that variables don’t need a starting colon. This is because symbols, like ordinary text strings, are just plain data, whereas variables are essentially ‘containers’ that hold data, and therefore cannot start with a colon - otherwise Ruby would think they’re just text.

Hope that helps - and apologies if I was repeating anything you already knew! :slight_smile:

oh thank you so much, I checked with ruby grammar rapidly for the description of colons but didn’t notice too much clue, thank you for the explanation.

by the way, as far as I now understand, the colon prefix is like denoting the string is a “symbol”. But function names in ruby don’t need to be prefixed with colons, in sonic pi function names seem to be all prefixed with colons. So that’s still a little bit different.

Also sonic pi built-in functions don’t have colon prefix. So to me it’s like the syntax rule is not unified.

Well, Sonic Pi ≠ Ruby :slight_smile:
It is perhaps not very well explained to newcomers, but in various ways Sam has tried to explain and make clear that Sonic Pi is its own DSL (domain specific language) only built on top of Ruby (not intended to be fully compatible).

Re ‘in sonic pi function names seem to be all prefixed with colons’ - only the function definition.
When you actually go ahead and call your function later, you drop the colon and refer to it just like the built in functions. This is because when you write

define :foo do
... 
end

What you are actually saying is:

define(:foo) do
 ...
end

Where you are passing the name of the new user defined function as a symbol to the define function, along with attaching the block containing the body of your function. Then you go ahead and use the function like this later:
foo(...)

(Note that Sonic Pi defines user functions this way instead of Ruby’s def blah because it does more stuff behind the scenes to create this user function than what Ruby’s def does).

Wow I like the concept “DSL”, which sets a border and won’t mislead users to mix things together.

Yes define is a function accepting symbols as defined functions’ names explains the myth, but why using function doesn’t need (and even cannot use) the colon? e.g. if I write like this

define :foo do
  play 50
  sleep 1
  play 55
  sleep 0.5
end

:foo

sleep 1

2.times do
  :foo
end

it simply won’t call the function

This can be confusing because in other cases, like use_synth :prophet, set :para, 1, get[:para], thing are just symmetrical

Because it’s treated purely as a hard-coded text string, with no other meaning. (Not a variable, not a function call, etc) :slight_smile: - This is also just a Ruby thing, not a Sonic Pi specific thing…
With use_synth :prophet (again, there the braces are optional - what you are saying is use_synth(:prophet)), :prophet is still basically just a string, but a string being used as a function parameter - the name of the synth.
Same with set :para, 1 - which is really set(:para, 1), and get(:para)

ok… but I still wonder, the function name should be :foo or foo?

Symbol to define, and no symbol to call later (unless you’re doing funky metaprogramming of course, but that’s a whole different kettle of fish :laughing: )

ok, I think I’d just remember and get used to it