I’d like to write a post to try to understand liquidsoap’s own scripting
language. Liquidsoap is a functional language, which you may find confusing if
you have not programmed much before. In functional languages you can’t do things you
might be used to doing in other languages like mutating values, changing state, etc.
types
The basic types in liquidsoap are integers, floats, strings and booleans.
integers 42
floats 3.33
strings "foo"
booleans true or false
You probably are quite familar with these if you have programmed before. There are other types specific to liquidosoap,
these are
source (produces a stream)
request (something that a stream will play, like a file)
format (for different audio/video encodings)
and a few others.
no changing variables
Since liquidsoap is a functional language, there are no variables, only
definitions. So in this example, I’m not really changing the value of the
source variable, I’m simply creating new ones and using the same name.
no unused variables
You aren’t allowed to declare a variable and then not use it, liquidsoap will
complain:
static typing
Liquidsoap is statically typed, but the types are inferred. This means you won’t
have to write types like in C or Java.
function notation in the API docs
The function notation used in the liquidsoap api
documentation may be a
bit daunting at first. For example here is the documentation for input.harbor:
All the question marks are simply optional named arguments and usually described
in the function’s documentation. Required arguments are marked with a ~
instead of a question mark.
?id:string
This is a optional parameter called id that is a type string.
?on_disconnect:(()->unit)
This is an optional parameter called on_disconnect that takes a function that is
of type ()->unit, which is a function that takes no arguments and returns
unit. What’s a unit, you ask? From the wikipedia page
In simple terms, a unit is returned when you don’t care about the return value.
In other languages, you could simply not return anything. However, in functional
languages, all functions must return a value, so we denote the return value as
unit when we don’t care about the return value.
[t] are lists and (t*t) are ‘pairs’ (or ‘tuples’ if you come from another
language like Python).
([(string*string)])->unit
This is a function that takes a list of (string*string) (such as ("a","b")) tuples and returns a
unit.
Finally you can see what this function returns by looking at the arrow(->) at
the end.
->source('a)
This means the function returns a source type.
defining functions
We can define a function with def and end to mark the end of a function.
like so:
The return type of the function is simply the last line of the body of the
function. So in the case of the function above, it would be string.
refs
Liquidsoap is a functional language, however it is not a pure functional language. You can use mutatable variables if
you want to. Liquidsoap borrows a concept from ocaml known as ref:
When assigning values to a ref, you use := instead of =.
If you want to print a ref, you should use the ! operator.
Modern Online Radio with Liquidsoap Book - Free Sample
Need more help with liquidsoap?
Can’t get your script to work?
I wrote a book to help you learn Liquidsoap. The book covers all aspects of liquidsoap, from getting started, to making dynamic streams, audio processing, video, customizing metadata, authentication, and more. The book is available for purchase now here!
You can get a free sample chapter of my book! Just enter your email address to subscribe to my mailing list and I'll send you a free PDF sample of the book in return.