# Chapter 1: Getting Started Deimos can be run both interactively via a read-eval-print loop (REPL) or by compiling and running a given source file. ## REPL The REPL allows interactive programming similar to classic functional languages as well as Ruby. To start the REPL, run: ``` dm repl ``` ### Basics All statements and expressions in the REPL are scoped under a synthetic function; in other words, variables persist through each input: ``` > let x = 2 > x 2 > let y = 3 > x + y 5 ``` In addition to statements and expressions, functions can be defined in scope: ``` > fn double(x: Int) x * 2 end > double(4) 8 ``` Note that variables in the "top" scope are not available inside defined functions: ``` > let x = 7 > fn doubleX() x * 2 end Error: Symbol x could not be found. ``` This requires the use of closures, which can "capture" variables in their containing scope: ``` > let x = 42 > let doubleX = { x * 2 } > doubleX() 84 ``` Note the difference in syntax between function declarations and closure declarations. As we will later see, closures are powerful constructs. ### Introduction to Classes Classes can also be defined in the REPL: ``` > class Dog \ pub name: String \ pub ctor(name: String) \ self.name = name \ end \ end ``` A few things are going on here. First, note the use the backslash to indicate that we are not done with our input (normally, a newline without a preceding backslash will cause the interpreter to consume everything input so far). Next, note our syntax for declaring a class, with hints of Rust and Ruby: - `class` keyword: the usual meaning - `pub` keyword: makes a property or method available outside the class (i.e., non-private) - `: Type` annotations: indicates the type of a property, parameter, or variable. - `ctor` keyword: marks a constructor. *Note: Classes can only have **one** constructor*. - `self` keyword, followed by property name: like the usual construct in OOP languages. Once we've defined our class, we can use it: ``` > let bear = Dog("Bear") > let skye = Dog("Skye") > bear.name Bear > skye.name Skye ``` Note above how we construct instances of the class by "calling" the class, exactly like we do in Kotlin. #### Class Declaration Short Form The above class example is a bit verbose; Deimos offers the following equivalent, inspired by Kotlin: ``` class Dog(pub name: String) end ``` This is especially useful in the REPL, where we may just want to declare a data type for doing some data processing. ``` > class Point(pub x: Int, pub y: Int) end > fn double(p: Point) Point(p.x * 2, p.y * 2) end > let a = Point(3, 4) > double(a) Point(6, 8) > let b = Point(5, 6) > double(double(b)) Point(20, 24) ``` ## Compiling and Running Files To compile and run a file, do: ``` dm run .dm ``` Note that the `.dm` extension is required in the command name (unlike `java`). The above command will compile and immediately run the file. In order for a Deimos file to be executable, it must contain a `main` function like the following: ``` fn main() println("Hello, Deimos!") end ``` Unlike the REPL, statements and expressions are not allowed in the top-level scope; they must be contained in a function or method: ``` let x = 10 // ERROR! Will not parse. ``` However, functions, classes, and other top-level constructs are allowed: ``` fn double(p: Point) -> Point Point(p.x * 2, p.y * 2) end class Point(x: Int, y: Int) end fn main() let a = Point(1, 2) let b = Point(3, 4) println(double(a)) // Point(2, 4) println(double(b)) // Point(6, 8) end ``` ``` let f = { a, b -> a + b } << 4 let x = f(5) println(x) // 9 ```