Types in Lime

Lime is a strongly, strictly typed language.

Default Types

The default atomic types in Lime are:

  • bool (binary truth value, true or false)
  • int (integer, e.g., -12)
  • float (floating-point number, e.g., 2.0)
  • str (string, e.g., "abc")

Lists can be made out of any type, even lists themselves, by appending a $ token. For example, a list of int`s have the signature :code:`int$, and a list of int$`s will have the signature :code:`int$$.

Custom Types

Defining a struct

To define a struct, use the struct directive at the top level of a program.

(struct person first_name:str last_name:str age:int)

This will also define a new type, person.

Initializing a struct

To initialize a struct, use the new keyword, which will initialize and return a new instance of the struct specified.

(new person first_name "Liam" last_name "Schumm" age 17)

You can specify only a subset of the attributes when initializing, by not including the keys for those items:

(new person first_name "Liam" age 17)

Getting values of a struct

To get the values of a struct, use the get command. For example,

(get example_person first_name)

would return the first_name attribute of example_person.

Setting values of a struct

To set the values of a struct, use the set command. For example,

(set example_person (first_name 2))

would set the first_name attribute of example_person to 2, and return a reference to the object.

Type Signatures

In Lime, all functions must have a type specified for their return value and for their inputs. The type signature BNF is as following:

type           ::= (int|float|str...)
                 | type$
function_name  ::= [A-z]+
type_signature ::= function_name:type (type*)

Polymorphism

Lime has polymorphism, aka "overriding". This allows you to define a single function with different behavior when it is passed different types. For example,

(defun increment:float (x:float) (fadd x 1.0))
(defun increment:int   (x:int)   (iadd x 1))

would define the increment function for ints and floats. This can also be used for optional arguments, like so:

(defun sinput:str () (sinput ":"))
(defun sinput:str (prompt:str) (...c implementation...))

if a prompt is not explicitly defined, it will default to ":".

The any type

The any type allows methods to be specified that take arbitrary combinations of arguments that match a specific expression. For example, the lget command is defined to operate on lists of any and return a singular element of type any. The type signature looks like:

lget:any (arr:any$)