Flow - Now with Lottie & Animated SVGs - Ship beautiful UI Animations. | Product Hunt Embed


Tags icon

Flood Language Guide

Flood is a new programming language for creating templates (i.e. export options) that can be used with Flow. It is a domain-specific language that possesses many of the features and fundamental types that you know well.

If you haven’t already, we emphatically suggest you read the Introduction to Flood.

Overview

The Flood language is a domain specific scripting language used to create Templates for Flood. The language posses many of the fundamental programming types similar to types found in other languages like JS, C, or Python. These types include, Double, Bool, and String.

Flood also provides access to two primary collection types, Array and Dictionary.

Like many other languages Flood uses variables to store and refer to values by an identifying name. Flood also features two control flow elements, if and switch statements, as well as the ability to create callable sections of code called functions.

Input / Output

We actually use a Flood template to generate this document. Below you’ll see code blocks preceded by the headings INPUT or OUTPUT. The input blocks are actual Flood code, and the output blocks are the result processing the input.

INPUT:
<% var v = "Flood is great" -%>
<%= v %>
OUTPUT:
Flood is great

Verbatim text

We use the term verbatim text to denote text that will be output exactly as it is written. Typically, this text is found in a .flt file, but exists outside of a code block.

INPUT:
This is verbatim text<% " whereas this is not" -%>.
OUTPUT:
This is verbatim text.

The beauty of verbatim text is that it allows you to structure your files, and coding style, while allowing only the insertion of variables to complete your exports.

Here’s an example of how a CSS block might be written:

INPUT:
<% 
var className = "full-width" 
var widthValue = "100"
-%>
div.<%= className -%> {
  width: <%= widthValue -%>%;
}
OUTPUT:
div.full-width {
  width: 100%;
}

Control Sequence

A key factor in Flood’s templating is the control sequence system used to define what type of text Flood is currently interpreting. Flood uses a combination of verbatim text and Flood code blocks to generate documents. Verbatim text is text that is copied directly from the template into the generated document. Flood code blocks are pieces of code mixed into verbatim text that has to be compiled before being injected into the generated document. The contents of these code blocks can range from a reference to a varaible, to the definition of a function.

Code Blocks

Opening (<%) and closing (%>) tags define the begining and end of a Flood code block. A Flood code block is any code that is not verbatim. Any code that can be written using the Flood programming language can be written inside a Flood code block.

Flood variables can be displayed by adding a = to the opening tag. This is written as: <%=.

INPUT:
<%
var floodVariable = "AND I AM THE VARIABLE"
-%>
I am verbatim text, <%= floodVariable %>.
OUTPUT:
I am verbatim text, AND I AM THE VARIABLE.

By default a new line is appended to the end of a Flood code block. If you don’t want to have a new line at the end of a Flood code block you can add a - to the closing tag. This is written as: -%>.

INPUT:
<%
var floodVariable = "Flood! "
-%>
<%= floodVariable %>
<%= floodVariable -%>
<%= floodVariable -%>
<%= floodVariable -%>
OUTPUT:
Flood! 
Flood! Flood! Flood! 

You can easily execute control flow statements. You can use print() or println() inside a code block when you want to immediately write the value of a varible to the current output file.

INPUT:
<%
if 1 + 2 > 3 
    print("Math is hard")
else
    print("Math makes sense!")
end
-%>
OUTPUT:
Math makes sense!

You can also insert code between verbatim text.

INPUT:
You can also do things like loops in between varbatim text. For example.

<% 
for index in 1...5
    print("\(index) potato ")
end
%>

Isn't that nice?
OUTPUT:
You can also do things like loops in between varbatim text. For example.

1 potato 2 potato 3 potato 4 potato 5 potato 

Isn't that nice?

Variables and Types

Variables and their types are used to store values by a name that can be refered to at other points of the program.

Variables

Variables can be initialized by prefacing the variable name with the var keyword. The initial value of a variable is set vy writing = value after the variable name.

INPUT:
<%
var name = "Bannana"
var type = "fruit"
var tasty = true
var price = 2
-%>
<%= "\(name)s are a \(tasty)ly tasty \(type), and so affordable at only $\(price)."-%>

OUTPUT:
Bannanas are a truely tasty fruit, and so affordable at only $2.

The value of the variable can then be changed by writing variableName = newValue. Variables in Flood are type agnostic, meaning that a variables value can change type without causing an error.

INPUT:
<%
var name = "Banana"
var type = "fruit"
var tasty = true
var price = 2
-%>
<%= "\(name)s are a \(tasty)ly tasty \(type), and so affordable at only $\(price)."%>
<% price = 4 -%>
Unless you buy organic, where...
<%= "\(name)s are a \(tasty)ly tasty \(type), and not so affordable at $\(price)."-%>
OUTPUT:
Bananas are a truely tasty fruit, and so affordable at only $2.
Unless you buy organic, where...
Bananas are a truely tasty fruit, and not so affordable at $4.

For example, if a variable’s initial value is of type String it is possible to then change that variable to a value of type Double, or type Bool.

INPUT:
<%
var name = "Banana"
-%>
<%= "\(name)s are tasty."-%>
<% name = 1 -%>
<%= "...and only cost $\(name+name)" -%>
OUTPUT:
Bananas are tasty....and only cost $2

Double

Currently, all numbers used in Flood are floating-point variables of type Double. For example: 1, -2, 35.67, -2.0, 0.5154, … are all Double values.

You can perform math functions on these values.

INPUT:
<%
var ten = 10
var pointFive = 0.5

for i in 1...5 
    ten = ten + pointFive
end

print(ten)
-%>
OUTPUT:
12.5

String

A string is a series of characters, such as:

"Hey mom, there's something in the backroom hope it's not the creatures from above."

Any object can have methods. For example, String has a variety of methods that you’d expect. Here’s an example of using the appending() method to concatenate two strings:

INPUT:
<% var sentence = "You used to read me stories"
sentence = sentence.appending(" as if my dreams were boring.")
print(sentence)
-%>
OUTPUT:
You used to read me stories as if my dreams were boring.

String Subscripts

You can use subscripts are used to access character values of a string between a pair of indeces.

INPUT:
<%
var str = "abcd"
println(str[2])
println("abcd"[0])
print("abcd"[0...2])
-%>
OUTPUT:
c
a
abc

Bool

Flood provides two Boolean constant values, true and false.

INPUT:
<% 
var nope = false
var yep = true

if 1 < 2
  print(yep)
else
  print(nope)
end
-%>
OUTPUT:
true

Comment

A comment is a block of text that will not be executed by the compiler. In Flood, comments are preceded by a double-slash: //

The interpreter will omit any comment that is in an flp file, or that is within a code block.

Comments in .flt files, that are not inside code blocks will be treated as verbatim text.

INPUT:
What did you say?
// This comment is actually verbatim text, and will be included in the output
<%= 
1 
// The interpreter will skip over comments that lie inside of code blocks
%>
<%= 2 %>
OUTPUT:
What did you say?
// This comment is actually verbatim text, and will be included in the output
1
2

Range

A Range is a way to define a series of numbers between two points. For example, the range with a starting index of 1 and an ending index of 5 would contain the numbers 1, 2, 3, 4, and 5.

Ranges can be used in many different ways. In the example below a range used for iterating a for loop as well as subscripting a string.

INPUT:
<%
var range = 0...3
var str = "ranger danger, "

for i in range
    println(str)
end

println("\(str[range])")
print("\(str[7...9]) \(str[0...2]) \(str[8...9])\(str[7]) \(str[0...2])")
-%>
OUTPUT:
ranger danger, 
ranger danger, 
ranger danger, 
ranger danger, 
rang
dan ran and ran

Conditional Statements

Conditional statements are used to run different pieces of code based on certain conditions. You may want to run a specific piece of code if a certain button is clicked or if it’s someones birthday and you want to send them a special message.

Conditional Statements can be created using if statements or switch statements.

if

The simplest way to use an if statement is to run a piece of code only if a certain condition is true.

INPUT:
<%
var moneyInBank = 100
var richBenchMark = 75

if(moneyInBank >= richBenchMark)
    print("Donate!")
end
-%>
OUTPUT:
Donate!

Another way to use an alternative set of statements known as the else clause.

The else clause runs if the if condition is false.

INPUT:
<%
var moneyInBank = 50
var richBenchMark = 75

if(moneyInBank >= richBenchMark)
    print("Donate!")
else
    print("Save up!")
end
%>
OUTPUT:
Save up!

The else if adds a second case that gets evaluted when first condition is false, but before falling through to the default condition.

INPUT:
<%
var moneyInBank = 75
var richBenchMark = 75

if(moneyInBank > richBenchMark)
  print("Donate!")
else if (moneyInBank == richBenchMark)
  print("Ooooooh!")
else
  print("Save up!")
end
%>
OUTPUT:
Ooooooh!

switch

A switch statement uses a single value as an argument to compare against several possible matching patterns. It then executes an appropriate block of code based on the first matching pattern. If no matching pattern is found, an optional default case is executed if one is specified.

INPUT:
<% 
var today = "Friday"
switch today
case "Monday":
    print("Coffee and an early lunch")
case "Friday":
    print("TGI\(today)!")
default:
    print("Some day")
end 
-%>
OUTPUT:
TGIFriday!

Collections

Swift provides two primary collection types for storing collections of values: arrays and dictionaries. Arrays are ordered collections of values. Dictionaries are unordered collections of key-value associations.

Array

A heterogeneous array which can store values of differing types. The same value can appear repeatedly within an array.

INPUT:
<%
var list = ["lettuce", 32, false, 123.321]

for item in list 
  println(item)
end 
-%>
OUTPUT:
lettuce
32
false
123.321

Dictionary

A heterogeneous dictionary which stores associations between keys of the different types and values of the different types in a collection with no defined ordering. Each value is associated with a unique key, which acts as an identifier for that value within the dictionary.

Unlike items in an array, items in a dictionary do not have a specified order.

You use a dictionary when you need to look up values based on their identifier, in much the same way that a real-world dictionary is used to look up the definition for a particular word.

INPUT:
<% var dict = [
"Paul": "bass player", 
"Ringo": "drummer", 
"John": "singer", 
"George": "guitar player"]
for (k,v) in dict 
 println("\(k) is a \(v)")
end 
-%>
OUTPUT:
John is a singer
Paul is a bass player
George is a guitar player
Ringo is a drummer

Loops

Flood provides two control flow statements that allow you to perform a task multiple times: for and while loops.

for-in

A for-in loop is used to iterate over a sequence, such as items in an array, ranges of numbers, or characters in a string.

INPUT:
<% 
var title = "number "
for index in 1...3
  println("\(title) \(index)")
end
-%>
OUTPUT:
number  1
number  2
number  3

while

A while loop performs a set of statements until a condition becomes false.

INPUT:
<% 
var timeLeft = 5
while timeLeft > 0
  print("\(timeLeft)...")
  timeLeft = timeLeft - 1
end 
println("")
print("BOOM!")
%>
OUTPUT:
5...4...3...2...1...
BOOM!

Functions and Closures

Functions are self-contained chunks of code that perform a specific task. You give a function a name that identifies what it does, and this name is used to “call” the function to perform its task when needed.

INPUT:
<% func f(a, b, c)
print("A: \(a), ")
print("B: \(b), ")
print("C: \(c).")
end
f(a: 1, b: 2, c: 3)
-%>
OUTPUT:
A: 1, B: 2, C: 3.

You can also return values from functions.

INPUT:
<% 
func f(a, b, c)
  return "A: \(a), B: \(b), C: \(c)."
end
print(f(a: 1, b: 2, c: 3))
-%>
OUTPUT:
A: 1, B: 2, C: 3.

Closures

Closures are self contained blocks of code that can be passed around and used in different places throughout your code.

INPUT:
<% 
func makeCounter()
  var i = 0
  func count()
    i = i + 1
    println("count: \(i)")
  end
  return count
end

var counter = makeCounter()
counter()
counter()
counter()
-%>
OUTPUT:
count: 1
count: 2
count: 3

Basic Operators

An operator is a special symbol or phrase that you use to check, change, or combine values. For example, the multiplication operator (*) multiplies two numbers, as in let i = 2 * 3.

Assignment

The assignment operator (a = b) initializes or updates the value of a with the value of b.

INPUT:
<%
var a = 0
print(a)
-%>
OUTPUT:
0

Arithmetic

Flood supports the four standard arithmetic operators:

  • Addition (+)
  • Subtraction (-)
  • Multiplication (*)
  • Division (/)
INPUT:
<%
println(0 + 1)
println(2.3 - 4.5)
println(5 * 6)
print(7.8 / 9)
-%>
OUTPUT:
1
-2.2
30
0.866667

You can not use the + to concatenate strings.

Compounding Values

Flow does not provide compounding assignment operators. So, you cannot do the following:

var a = 0
a += 1

However, you can reference a variable while assigning it a new value.

INPUT:
<%
var a = 0
a = a + 1
print(a)
-%>
OUTPUT:
1

Comparison

Flood supports all standard C comparison operators:

  • Equal to (==)
  • Not equal to (!=)
  • Greater than (>)
  • Less than (<)
  • Greater than or equal to (>=)
  • Less than or equal to (<=)
INPUT:
<%
var a = 0
var b = 1
println(a == b)
println(a != b)
println(a > b)
println(a < b)
println(a >= b)
print(a <= b)
-%>
OUTPUT:
false
true
false
true
false
true

Logical Operators

Logical operators modify or combine the Boolean logic values true and false. Flood supports the three standard logical operators found in C-based languages:

  • Logical NOT (!)
  • Logical AND (&&)
  • Logical OR (||)
INPUT:
<%
var t = true
var f = false

println(!t)
println(t && f)
print(t || f)
-%>

OUTPUT:
false
false
true

Type Checking

The is operator is used to check if a variable “is” a specific type.

INPUT:
<%
println(1 is Double)
println(1.0 is Double)
println(true is Double)
println("string" is Double)
println([0, 1] is Array)
println([0: "a"] is Dictionary)
println(0..<1 is Range)
print(0...1 is ClosedRange)
%>
OUTPUT:
true
true
false
false
true
true
true
true

That’s it! If you actually read this whole document, give me a High Five

background Made with Flow.
underscore Made with Flow.
line2 Made with Flow.
line1 Made with Flow.
circle Made with Flow.
hit Made with Flow.

result(s) found for “”.