Quail

Overview

Quail is easy-to-use scripting language with simple yet powerful syntax, embeddable in Java applications and supporting a plenty of different approaches for designing code and writing it.

#:alias "SAYHELLO" out("Hello")

SAYHELLO

Preprocessor

Simple regex-based preprocessor opens possibilites to widely customize the syntax

Dynamic typing

Dynamic typing opens wide possibilities when writing code

a = 10
a = "Hello"
out(a)
class Person {
 string name

 method hello(this)
  out("Hello from " + this.name)
}

# Add methods to class on the way
Person.someMethod = (this, args...) -> {}

Prototype-based object-oriented programming

Prototype-oriented programming is the best in scripting, especially dynamic typed languages.
You can add methods and fields to the class at the runtime or modify existing, easily inherit via standart tools or make your own inheritance system

Everything is an object

You can use every value in Quail as an object, add, remove, change fields and methods, invoke them.

Number.sum = (this, a) -> {
 return this + a
}
refreshtypes()


out(15.sum(37))
class N {
 num value
 object builder(this, n) this.value = n
 override + (this, other) return this.value * 2 + other
}

out(N(1) + 2)

Operator overloading

Ability to overload operators combined with previously described features makes you able to write easy-to-understand and easy-to-write code

Many variants of syntax

Yes, these three pieces of code will run without any errors one-by-one even without necessity to do something to the interpreter.

num a = 1;
through 0:10 as i {
 a += i;
}

a = 1
through 0:10 as i do
 a += i
end

A should be 1
through 0:10 as i
 A should now be A plus 1
through 0:10 as x {
 through 0:10 as y {
  through 0:10 as z {
   if z == 5
    # Breaks only 2 loops - z and y, x will remain untouched
    strike 2
   out(tostring(x) + " " + tostring(y) + " " + tostring(z))
  }
 }
}

Breaking nested loops and other unique features

Quail has so many tiny little unique features that make writing code easy. E.g. the strike operator that breaks nested loops

Built-in event system

Not a lot of languages have this. But Quail has. A built-in event system with ability to "deaf" (cancel) events, assign multiple handlers and migrate handlers from libraries

on "birthday" (event) {
 out("Happy Birthday, " + event.person)
}

newevent("birthday", {person="Mark"})
dynamic = 10
dynamic = "Hello"
dynamic = [1, 2, 3]

num clarified1 = 10
clarified1 = "Hello" # causes an error

anyof num | string clarified2 = 10
clarified2 = "Hello" # Ok
clarified2 = [1, 2, 3] # causes an error

Strong static typing (if you want)

You can probably say:

What the? You just said Quail is dynamically typed, didn't you?

Yes i did, but strong static typing is also available. By default, all variables are dynamic, but you can clarify the type and the variable becomes statically typed

Importing jars

You can create jar-packed libraries for Quail

usejar("lib.jar", "com.example.lib")