Exit Full View

Feather / src / dist / documentation / Basic Syntax.md

Package definition and imports

Package specification should be at the top of the source file:

package my.demo

import my.package.*
import my.package.MyClass

Comments

// This is an end-of-line comment

/*
    This is a block comment
    on multiple lines.
*/

Variables

val bar = 1
var baz = 2

bar is a final (its value cannot be changed), whereas baz is mutable. The types haven't been explicitly stated, so Feather uses the initial value to determine the type. In this case the type is int.

Explicit Types :

var bar : double = 1

Here bar is explicitly declared as a double. (Note the value 1 is automatically converted from an int to a double).

Strings

Use double quotes to create string literals :

"Hello"

Using """, we can make the string straddle multiple lines :

"""Hello
How are you?""" 

Smart Strings (aka String Templates)

Variables/field can be embedding into strings :

"Hello $name"

Or expressions of any kind :

"Hello ${person.firstName()}"

If you want a literal $ character, you can escape it like so :

"Give me \$5" // Give me $5

If Expression

if (booleanExpression) doSomething()

if (booleanExpression) {
    doSomething()
}

if (booleanExpression) doSomething() else somethingElse()

if (booleanExpression) {
    doSomething()
} else {
    somethingElse()
}

At the moment, the parentheses are optional, but this may change, so always include them!

if...else... can be used as an expression for example :

val foo = if (a) 1 else 2 

The value of foo will either be 1, or 2, depending on 'a'.

We can also use curly braces :

val foo = if (a) {
    1
} else {
    2
}

And the braces can contain any block of code:

val foo = if (a) {
    println( "a was true" )
    1 // The result of each branch is the last expression.
} else {
    println( "b was false" )
    2 // Again, the last expression is the result of this branch
}

For Loops

for ( c in "Hello" ) { ... }
for ( i in 1 .. 10 ) { ... } // Includes 10
for ( i in 1 until 10 ) { ... } // Excludes 10

for ( item in myCollection ) { ... }

Note that the types for the loop variables 'c', 'i', 'item' are not explicitly stated. The compiler can work them out.

While Loops

while ( booleanExpression ) { ... }

do { ... } while ( booleanExpression )

A do ... while loop will always go into the block at least ONCE.

A while... loop will not enter the block at all, if the expression is false.

With

In this example, exists and deleteOnExit are methods of the File object. The result of with is the last item in the block, which in this case is a String (from File.getPath())

val path = with( File( "temp.txt" ) ){
    if (exists()) {
        deleteOnExit()
    }
    getPath()
}

Note that getPath() can also be written as just path. See Don't get it? below ;-)

Apply

In this example, exists and deleteOnExit are methods of File. The result of an apply is the object it was applied to, which in this case is the File.

val file = File( "temp.TXT" ).apply {
    if (exists()) {
        deleteOnExit()
    }
}

Try ... Catch ... Finally

The usual Java-like syntax for exception handling :

try {
    ...
} catch ( e : Exception ) {
    ...
}

try {
    ...
} catch ( e : Exception ) {
    ...
} finally {
    ...
}


try {
    ...
} finally {
    ...
}

Note, you can have multiple catch (...) { ... } each catching a different type of exception.

Don't get it? (or set it)

Java code is peppered with lots of methods named get... and set.... Feather detects (and detests;-) such methods, and allows them to appear as fields, rather than method calls.

For example, Java' File class has a method getPath(), which returns a String. These two lines are functionally identical :

val foo = myFile.getPath()
val foo = myFile.path

Similarly, for set... methods, these two are functionally the same :

myObject.setBlah(1)
myObjec.blah = 1