Version 2 of Til-lang

Updated 2022-06-04 20:47:04 by cleberz

Til

https://til-lang.github.io/til/

Discussion on Hacker News

Til is a command language written in D whose syntax is inspired by Tcl. It aims to be:

  • easy to understand: you can read the source code and easily grasp what is going on;
  • easy to use: Til have syntax, specially where it makes things more comfortable;
  • easy to extend: D is very practical and easy to learn.

An example

proc list_joiner (separator list) {
    length $list | as n
    set counter 0
    list | as receiving
    range $list | foreach item {
        set counter $($counter + 1)
        push $receiving $item
        if $($counter < $n) {
            push $receiving $separator
        }
    }
    set s ""
    range $receiving | foreach item {
        set s "$s$item"
    }
    return $s
}

scope "test list_joiner" {
    set target_list (a b c d e)
    set separator ", "
    # Compare our function's result with the built-in `join` method:
    assert $([list_joiner $separator $target_list] == [join $separator $target_list])
}

In the example we can see that:

  • You can create a list using both the () syntax and the command list;
  • You can set variables with set, Tcl-style, or using a pipe to as, like list a b c | as my_list;
  • Conditions are not "delegational" by default: if receives a boolean as first argument. The $() syntax takes care of turning $($a < $b) into < $a $b;
  • You iterate over "streams" using foreach; there is also a transform command that allows changing the items from the sequence in the middle of a pipeline;
  • Commands can be methods: length, when called with a list as first argument, actually calls SimpleList.commands["lenght"]. If you call, for instance, length $queue, it's going to look for a Queue's method, so you don't need to name commands different for each type.

til-tcl

With this package you can create Tcl interpreters and run commands in them:

scope "load Tk, just because" {
    tcl | autoclose | as t
    run $t {{ package require Tk }}
    print "Tk loaded!"
}

scope "interpret a String as Tcl code" {
    tcl | autoclose | as t
    run $t "set x 123"
    print "x in Tcl is " <$t x>
    assert $(<$t x> == "123")
}
scope "interpret Til code as Tcl" {
    tcl | autoclose | as t
    run $t {{
        set x 123
        puts "x (from inside Tcl) is $x"
    }}
    assert $(<$t x> == "123")
}
scope "get values from Tcl" {
    tcl | autoclose | as t
    run $t "set x 321"
    set value <$t x>
    assert $($value == "321")
    print "x in Tcl is $value"
}

Notice that it implements extraction of values from the interpreter (that is: getting the value from a variable) with proper syntax (<$interpreter $variable_name>).