Skip to content

Lua code - the gory details

Background

Lua is an embeddable scripting language created by the Pontifical Catholic University of Rio de Janeiro in Brazil. Its syntax is extremely light-weight and easy to read, which makes it ideal for the simple task of performing the maths necessary to calculate zmanim. For the official Lua reference manual, see Lua 5.5 reference.

why not Javascript?

At the time Zmanim Advanced was originally written (2009!), iOS (or iPhoneOS, as it was called then) did not offer a practical way to access a Javascript environment for running embedded scripts. For the kinds of code needed for a typical zman calculation, the syntax is virtually identical anyway.


Anatomy of code

A line of code typically consists of one or more of the following:

feature description examples
keyword A keyword is a word that is claimed by the language itself. Keywords cannot be used as variable or function names. return, local
variable A variable is a name given to some value. In calculations, the value is usually a number, but it doesn't have to be. zman_sunset, degrees
literal A value that is written in the code directly, instead of using a variable. 90, 10.75
function call A function call invokes some other piece of code and returns a value. It can be passed parameters, which are variables or values, that affect the result of the function. sunrise(90 + 50/60, true)
+, -, *, / Mathematical operators. They are, in the order listed: addition, substraction, multiplication, division. minutes * 60, 90 + degrees

Keywords

Keywords are words that are reserved for the use of the language itself. They provide structure and instruction that describes what you want the code to do for you. The one keyword you will see in every calculation is return. It is instructing Lua to return the value of the function, which is often stored into a variable or passed directly to another function.

Variables

Variables are names for values. They act as placeholders such that when the code is evaluated, the variables are replaced with their values.

Lua supports two kinds of variables: local and global. In the context of Zmanim Advanced, a global variable is accessible from any calculation. Local variables are only accessible from the calculation that defines them.

  • the result of a calculation is stored in a global variable. This is what allows one calculation to use the result of another.
  • the variables defined in the code editor are local to the calculation that defines them.
  • Zmanim Advanced provides several other global variables to calculations. They are detailed below.

constructing variable names from calculations

The template for the name of the global variable into which a calculation's result is stored is: zman_<name>, where <name> is the name given to a calculation. These variables are created by Zmanim Advanced.

Example

For a calculation with the name sunset, the variable name will be zman_sunset. To use this value in another calculation, use the calculation picker to insert the appropriate variable.

why use locals?

Why use local variables when their value can just be written in the code in the first place? Wouldn't that be quicker?

The answer is three-fold:

  1. variables with well-chosen names are self-documenting.
  2. several calculations for common zmanim are essentially identical, with the only difference being the number of minutes or the number of degrees. By using a local, the code itself can be identical across calculations.
  3. there are calculations whose correct value depends on differing legal opinions or practice. To make it easier to customize, a variable is used as a placeholder for the point of disagreement.

Another reason to use local variables is dynamic titles.

Literals

Literals are values that are entered into the code directly. Literals can be numbers, strings (text), as well as some other types that are not of particular interest for zmanim (see the official reference manual for details). In the code examples below, some literals are: 60, 90, 10.75.

Functions

The table above lists function call as one of the features often found in a calculation expression. To understand function calls, one must understand functions.

A function in Lua is conceptually similar to a mathematical function, 𝒇(𝓍). Functions take zero or more parameters, and they return a value. In calculations, due to their inherently mathematical nature, the similarities are particularly striking.

For each calculation, Zmanim Advanced creates a function that wraps the variables and code, and assigns this to a variable which acts as the name of the function.

Example

Given:

variable degrees 16.1
code return sunrise(90 + degrees)

Zmanim Advanced will construct an expression like so:

calc_alot_degrees = function ()
    local degrees = 16.1
    return sunrise(90 + degrees)
end

This defines a function and stores it in a variable called calc_alot_degrees. This function is then invoked (called) as follows: zman_alot_degrees = calc_alot_degrees()

  • A function has a name(1): calc_alot_degrees.
  • A function has a beginning: function ()
  • A function has a body: local degrees = 16.1, return sunrise(90 + degrees)
  • A function has an end: end
  1. Technically, the function itself is anonymous and it's the variable which has a name. But who wants to get technical at a time like this?

Calling

To call this function, you write its name, followed by parantheses: calc_alot_degrees().

Zmanim Advanced provides two functions that any calculation may use: sunrise() and sunset(). They are described in detail below. Because most zmanim are calculated as offsets from one or the other, they provide a basis for calculating any zman. As such, they appear in the code of many zmanim.

Expressions

An expression is a fragment of code that is evaluated to obtain a value. For example, 5 + 5 is an expression that returns the value 10. In Lua, variables, literals and functions can be combined using operators to form expressions. Each of the examples below contain the keyword return, followed by an expression.

Examples

# code
1 return zman_sunset + minutes * 60
2 return sunrise(90 + 50/60, true)
3 return zman_sunrise + 10.75 * zman_hour_standard

1 - global, local, literal

The first example shows the usage of 3 of the sources for values used in calculations. zman_sunset is a global, minutes is a local, and 60 is a literal. As one can see, the expression is written in the form of a mathematical statement: the calculation being defined is some number of minutes after sunset. (It is, of course, the specific number of minutes that makes the calculation significant.)

2 - function call, nested expression

This example shows a function call being made. The function has two parameters (equivalent to a mathematical function 𝒇(𝓍,𝑦)), but one of them is a number and one is a boolean (true/false value). The first parameter is itself an expression, 90 + 50/60. Lua evaluates this expression first, and the result becomes the first parameter to the function.

3 - more global variables

The final example is similar to the first, but uses multiple global variables. This exemplifies how a single calculation can depend on the results of multiple other calculations. See Dependencies for more details.

"Builtin" functions and variables

Zmanim Advanced provides a number of (global) variables and functions which are available to any calculation. While there is generallt no need for the variables to be used, the two functions, sunrise and sunset, are used extensively.

variables

Aside from the global variables created to hold the results of calculations, the following variables are available:

Name Meaning
longitude, latitude Location in degrees
altitude Height above the sea-level in meters (from the saved location)
date Unix timestamp (timeIntervalSince1970) for the calendar day being evaluated. The time expressed by this value is midnight for the selected date.

Functions

Zmanim Advanced provides two functions: sunrise and sunset. To use them correctly, we must understand what they are calculating. Both functions operate the same way, and the difference between them is the direction of their focus. sunrise calculates a moment in time when the (middle of the) sun will reach a certain angle in the eastern sky. sunset does the same for the western sky.

For each function, 90° is the horizon. Values above 90 are below the horizon and values below 90 are above the horizon.

Note

The previous sentence may seem unintuitive and/or confusing. The sunrise and sunset functions consider 0° to be straight over head, and moving away from that position towards the horizon increases the number of degrees.

In addition to the number of degrees, each function takes a boolean (true/false) value as a second parameter. This parameter controls whether altitude (elevation) is taken into account. Elevation increases the distance to the horizon. This causes someone at a greater elevation to see the sun rise before someone at ground level, and to see the sun set after someone at ground level. In other words, elevation causes sunrise to be earlier and sunset to be later.

Because there are various opinions as to whether elevation should be considered when calculating zmanim, as well as for which zmanim, Zmanim Advanced gives the option to consider or ignore elevation, as needed.

50/60

Why does Zmanim Advanced add 50/60 when calculating sunrise and sunset?

Short answer: atmospheric refraction

Sunrise is calculated as the moment the top of the sun's disk appears on the horizon. Due to standard atmospheric refraction at the horizon, this happens when the sun is approximately 1/6th of a degree below the horizon. By adding 5/6 to 90, we are calculating the position of the sun when it is 6/6 - 1/6 = 5/6 degrees below the horizon. This works because the sunrise function calculates the moment when the sun's center reaches the specified number of degrees.

The same applies for sunset.

For a more complete treatment, ask google "why do we calculate sunrise as 90 + 5/6 degrees?".

Summary

function call what it does
sunrise(degrees, true) calculate when the sun will reach degrees number of degrees towards (or below) the eastern horizon. Elevation is taken into account.
sunrise(degrees, false) calculate when the sun will reach degrees number of degrees towards (or below) the eastern horizon. Elevation is ignored.
sunset(degrees, true) calculate when the sun will reach degrees number of degrees towards (or below) the western horizon. Elevation is taken into account.
sunset(degrees, false) calculate when the sun will reach degrees number of degrees towards (or below) the western horizon. Elevation is ignored.

If the parameter for considering elevation is omitted (e.g. sunrise(90)), it is the same as passing false.