Enums in Turbine: More Than Just Constants
In my previous post, I introduced Turbine, a lightweight scripting language with a Markdown-like syntax. This time, I’d like to dive into a feature that stands out from conventional programming languages: Enums. Moving Beyond Integer-Based Enums In many languages, enums are used to represent states or flags by assigning consecutive integers or bit values (using things like iota() or auto()). A typical usage would be something like this in C++: #include int main() { enum class Color { red, green = 20, blue }; Color r = Color::blue; switch(r) { case Color::red : std::cout

In my previous post, I introduced Turbine, a lightweight scripting language with a Markdown-like syntax. This time, I’d like to dive into a feature that stands out from conventional programming languages: Enums.
Moving Beyond Integer-Based Enums
In many languages, enums are used to represent states or flags by assigning consecutive integers or bit values (using things like iota()
or auto()
). A typical usage would be something like this in C++:
#include
int main()
{
enum class Color { red, green = 20, blue };
Color r = Color::blue;
switch(r)
{
case Color::red : std::cout << "red\n"; break;
case Color::green: std::cout << "green\n"; break;
case Color::blue : std::cout << "blue\n"; break;
}
}
Bit-shifting (like 1 << 0
, 1 << 1
, etc.) is often used for flag enums too, especially when working with combinations.
Turbine, however, takes a different approach: it removes the need to think about assigning specific numeric values altogether. Instead, you can directly associate meaningful data fields with each enum entry. That makes your enums more expressive and structured.
Here’s what it looks like in Turbine:
## Color enum
: symbol , name , rgba_index, bgra_index
- R , "red" , 0 , 2
- G , "green" , 1 , 1
- B , "blue" , 2 , 0
- A , "alpha" , 3 , 3
# main() int
- r = Color.B
print(r.name)
- idx = r.bgra_index
return 0
This format allows you to work with richer data—like color channels for different formats—without writing extra logic or switch
statements. In essence, Turbine enums act like 2D tables where each row is a named data record.
Why Not Just Call It a Table?
Early in development, I originally called this feature a "table" instead of an "enum". The syntax even resembled Markdown tables. But several issues came up:
- The
|
character conflicted with bitwise OR when writing constant expressions. - Explaining the feature took more effort than just calling it an "enum".
- The term "table" was easily confused with "table types" in other languages.
Eventually, I chose to stick with the more familiar term: Enum. Describing it as a “2D enum” turns out to be surprisingly intuitive for most developers.
Looping Over Enum Entries
Sometimes, you need to loop over all enum values—like when building dropdown menus or defining configurable options. Turbine makes this very straightforward:
## Month enum
: symbol , name , num
- Jan , "January" , 1
- Feb , "February" , 2
- Mar , "March" , 3
- Apr , "April" , 4
- May , "May" , 5
- Jun , "June" , 6
- Jul , "July" , 7
- Aug , "August" , 8
- Sep , "September" , 9
- Oct , "October" , 10
- Nov , "November" , 11
- Dec , "December" , 12
# main(args vec{string}) int
- month_menu = vec{"Select Month"}
for m in Month
vecpush(month_menu, m.name)
// Use month_menu as the dropdown options
// ...
return 0
By treating enums as iterable collections, you can keep your UI and logic in sync without redundancy.
Enum Loops: A Syntax Exception
In Turbine, for
loops normally expect an expression after in
, like a range or a collection. But there's a special exception: Enums.
Instead of writing something like in Enum.all()
or a built-in .values
, Turbine allows you to simply write for val in Month
. This improves readability and matches real-world use cases like UI building.
Yes, it bends the consistency of the syntax a bit, but the trade-off is worthwhile. In all other contexts, using just an enum type like Month
without a field (e.g., Month.Jan
) would result in a syntax error—so the parser treats this for loop form as a special case.
Summary
Turbine enums are more than just symbolic constants. They’re essentially collections of named records, shaped by their origin in table-based syntax. If you ever wanted to manage small tables of structured data inside a script, Turbine enums might be just what you’re looking for.
Learn More
Turbine is still under active development, and the syntax and features are evolving. You can follow along here: