Basic Syntax

Basic syntax

Collection of basic code snippets to get a quick start!

Note: '//' is used for comments

Program entry point

Part of code from where the execution begins! In Eia, the entry point is the main function.

fn main() {
  println("Hello, World!")
}

This is optional! Just like Python, you can directly write down the codes without necessarily having a main function. But when this source file is imported, it may evaluate code located outside main that you may not require!

Standard I/O operations

println and print prints its argument to the standard output.

print("Meow\n")
println("Thank you", " Hackclub!")

Similarly, readln function reads an entire line from the standard input.

// Requests the user to enter a name
println("Enter a name: ")
 
// Reads and stores the name
let name = readln()
 
// Hello $name
println("Hello ", name)

Variables

Inspired by Swift! Declare a variable using either let or var.

Use the let keyword to create immutable constant that cannot be reassigned.
To create a mutable variable with re-assignable property, use the var keyword.

let name = "Hackclub!"
// 'name' is a constant that can only be accessed!
// Creates a variable 'count' with initial value of 7
var count = 7
// Increment the count by 2
count += 2
; 9

Eia supports declaring many variables in a single statement:

// declaring two variables of ints
let a = 1, b = 2

// declaring two different typed variables
let c: Int = 2, d: String = "meow"

Eia has an automated type resolution system, you don't need to explicitly specify data types, it is auto-detected.

Variable Modifiers

You can use modifiers visible or private to expose variable to outer classes or to keep them private.
Local scope variables are always private, since external classes only have access to scope 0 of the current class.

// variable is accessable to other classes
visible let name = "Meow"
 
// default or private variables
let age = 16
// or
private let age = 16
(they both are the same)

Primitive types

Primitive classes in Eia are Bool, Int, Char, Float, generic Num, String, Array/Array<N>, Type, (that holds signatures), Unit, Nil, Any
An example of few:

println(
  "Meow World",   // a string
  'H',            // a character
  true,           // boolean type
  123,            // an integer
  2.8,            // a float
  nil,            // null type
 
  { println("Meow") }            // a Unit, anonymous lambda that can be invoked using `<unit>(args..)`
  arrayOf("meow", "world"),      // implicit array declaration (type is auto resolved)
  arrayOf<Any>(2, "hello"),      // an array containing mixed data types
  makeArray<Int>(5, 8)           // create an array of integer of size 5 with default value 8
)

This outputs the following:

Meow World
H
true
123
2.8
EArray(meow, world)
EArray(2, hello)
EArray(8, 8, 8, 8, 8)

Conditional Expressions

Eia lang's behaviour of If expressions is very identical to that of Kotlin.

let x = 5
let y = 8
 
if (x > y) {
  println("X is greater")
} else {
  println("Y is greater")
}

You may use if not just for flow control, but also as an expression:

let x = 5
let y = 8
 
println(if (x > y) "X is greater" else "Y is greater")

Branches of an if expression can be blocks. In this case, the last expression is the value of a block:

let a = 10
let b = 20
 
let max = if (a > b) {
    print("Choose a")
    a
} else {
    print("Choose b")
    b
}
 
println(max)
// Choose b
// 20

If you're using if as an expression, for example, for returning its value or assigning it to a variable, the else branch is mandatory.

For loop

let places = arrayOf("India", "Japan", "Germany")
for (place in places) {
  println(place)
}

or the classical way:

let places = arrayOf("India", "Japan", "Germany")
for (var i = 0; i < len(places); i++) {
  println(places[i])
}

Until loop

let places = arrayOf("India", "Japan", "Germany")
var index = 0
until (index < len(places)) {
  println("Item at index " + index + " is " + places[index])
  index++
}

Special loop

It's one of the special features offered by Eia!

Iterating backwards from 5 to 1:

each (x: 5 to 1) {
  println(x)
}

Iteration from 2 to 10 by increment of 2:

each (y: 2 to 10 by 2) {
  println(x)
}

Type checks and casting

Like Kotlin, the is checks if an expression belongs to a certain type.

let a = "Meow!"
println(a is String)            // true
println("Meow" + 8 is Int)      // false
println(arrayOf("Hack", "Club!") is Array<String>)      // true

To cast values, for example from Any to Int or generic Array to Array<Int> we use the cast operator :: followed by a type:

// casting from Any to String
let name: Any = "Meow"
let reName: String = name::String
 
// casting from generic Array to Array<Int>
let gArray = arrayOf(7::Any, 8::Any)        // gArray has signature Array<Any>
let eArray = gArray::Array<Int>             // eArray has signature Array<Int>