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.
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
.
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.
<% var v = "Flood is great" -%>
<%= v %>
Flood is great
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.
This is verbatim text<% " whereas this is not" -%>.
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:
<%
var className = "full-width"
var widthValue = "100"
-%>
div.<%= className -%> {
width: <%= widthValue -%>%;
}
div.full-width {
width: 100%;
}
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.
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: <%=
.
<%
var floodVariable = "AND I AM THE VARIABLE"
-%>
I am verbatim text, <%= floodVariable %>.
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: -%>
.
<%
var floodVariable = "Flood! "
-%>
<%= floodVariable %>
<%= floodVariable -%>
<%= floodVariable -%>
<%= floodVariable -%>
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.
<%
if 1 + 2 > 3
print("Math is hard")
else
print("Math makes sense!")
end
-%>
Math makes sense!
You can also insert code between verbatim text.
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?
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 their types are used to store values by a name that can be refered to at other points of the program.
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.
<%
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)."-%>
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.
<%
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)."-%>
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
.
<%
var name = "Banana"
-%>
<%= "\(name)s are tasty."-%>
<% name = 1 -%>
<%= "...and only cost $\(name+name)" -%>
Bananas are tasty....and only cost $2
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.
<%
var ten = 10
var pointFive = 0.5
for i in 1...5
ten = ten + pointFive
end
print(ten)
-%>
12.5
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:
<% var sentence = "You used to read me stories"
sentence = sentence.appending(" as if my dreams were boring.")
print(sentence)
-%>
You used to read me stories as if my dreams were boring.
You can use subscripts are used to access character values of a string between a pair of indeces.
<%
var str = "abcd"
println(str[2])
println("abcd"[0])
print("abcd"[0...2])
-%>
c
a
abc
Flood provides two Boolean
constant values, true
and false
.
<%
var nope = false
var yep = true
if 1 < 2
print(yep)
else
print(nope)
end
-%>
true
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.
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 %>
What did you say?
// This comment is actually verbatim text, and will be included in the output
1
2
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.
<%
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])")
-%>
ranger danger,
ranger danger,
ranger danger,
ranger danger,
rang
dan ran and ran
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.
The simplest way to use an if
statement is to run a piece of code only if a certain condition is true
.
<%
var moneyInBank = 100
var richBenchMark = 75
if(moneyInBank >= richBenchMark)
print("Donate!")
end
-%>
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
.
<%
var moneyInBank = 50
var richBenchMark = 75
if(moneyInBank >= richBenchMark)
print("Donate!")
else
print("Save up!")
end
%>
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.
<%
var moneyInBank = 75
var richBenchMark = 75
if(moneyInBank > richBenchMark)
print("Donate!")
else if (moneyInBank == richBenchMark)
print("Ooooooh!")
else
print("Save up!")
end
%>
Ooooooh!
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.
<%
var today = "Friday"
switch today
case "Monday":
print("Coffee and an early lunch")
case "Friday":
print("TGI\(today)!")
default:
print("Some day")
end
-%>
TGIFriday!
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.
A heterogeneous array which can store values of differing types. The same value can appear repeatedly within an array.
<%
var list = ["lettuce", 32, false, 123.321]
for item in list
println(item)
end
-%>
lettuce
32
false
123.321
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.
<% var dict = [
"Paul": "bass player",
"Ringo": "drummer",
"John": "singer",
"George": "guitar player"]
for (k,v) in dict
println("\(k) is a \(v)")
end
-%>
John is a singer
Paul is a bass player
George is a guitar player
Ringo is a drummer
Flood provides two control flow statements that allow you to perform a task multiple times: for
and while
loops.
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.
<%
var title = "number "
for index in 1...3
println("\(title) \(index)")
end
-%>
number 1
number 2
number 3
A while
loop performs a set of statements until a condition becomes false.
<%
var timeLeft = 5
while timeLeft > 0
print("\(timeLeft)...")
timeLeft = timeLeft - 1
end
println("")
print("BOOM!")
%>
5...4...3...2...1...
BOOM!
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.
<% func f(a, b, c)
print("A: \(a), ")
print("B: \(b), ")
print("C: \(c).")
end
f(a: 1, b: 2, c: 3)
-%>
A: 1, B: 2, C: 3.
You can also return values from functions.
<%
func f(a, b, c)
return "A: \(a), B: \(b), C: \(c)."
end
print(f(a: 1, b: 2, c: 3))
-%>
A: 1, B: 2, C: 3.
Closures are self contained blocks of code that can be passed around and used in different places throughout your code.
<%
func makeCounter()
var i = 0
func count()
i = i + 1
println("count: \(i)")
end
return count
end
var counter = makeCounter()
counter()
counter()
counter()
-%>
count: 1
count: 2
count: 3
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.
The assignment operator (a = b
) initializes or updates the value of a
with the value of b
.
<%
var a = 0
print(a)
-%>
0
Flood supports the four standard arithmetic operators:
+
)-
)*
)/
)<%
println(0 + 1)
println(2.3 - 4.5)
println(5 * 6)
print(7.8 / 9)
-%>
1
-2.2
30
0.866667
You can not use the +
to concatenate strings.
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.
<%
var a = 0
a = a + 1
print(a)
-%>
1
Flood supports all standard C comparison operators:
==
)!=
)>
)<
)>=
)<=
)<%
var a = 0
var b = 1
println(a == b)
println(a != b)
println(a > b)
println(a < b)
println(a >= b)
print(a <= b)
-%>
false
true
false
true
false
true
Logical operators modify or combine the Boolean logic values true and false. Flood supports the three standard logical operators found in C-based languages:
!
)&&
)||
)<%
var t = true
var f = false
println(!t)
println(t && f)
print(t || f)
-%>
false
false
true
The is
operator is used to check if a variable “is” a specific type.
<%
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)
%>
true
true
false
false
true
true
true
true
That’s it! If you actually read this whole document, give me a High Five
result(s) found for “”.