Skip to content

Releases: abs-lang/abs

v1.11.3

22 Mar 20:05
Compare
Choose a tag to compare

This is a patch release that fixes a nasty scenario with string interpolation (#330). You can now interpolate variables both with $var and ${var} so that variables can be embedded within other strings "string${var}string" (#331).

v1.11.2

26 Feb 18:38
Compare
Choose a tag to compare

This is a patch release that upgrades ABS to be built through Go 1.14. Ther are no changes to the language besides the improvements brought by this new release of Go.

https://golang.org/doc/go1.14

v1.11.1

24 Feb 19:20
Compare
Choose a tag to compare

This is a bugfix release that fixes a regression introduced in 1.10.1: early returns from within for and for in loops were enabled for all return values, not just explicit ones.

An explicit return is defined as using the return keyword:

for x in 1..10 {
  return x
}

but the early return feature was enabled also for implicit returns:

for x in 1..10 {
  x <-- this loop only runs one, and return the first value of x
}

which would make code such as this fail:

list = []
for x in 1..10 {
  list.push(x) <-- this will be considered an implicit return, and only run once
}

This was fixed with #325.

Please note that the 1.10.x branch will not see a backport of this fix.

v1.11.0

16 Feb 16:16
Compare
Choose a tag to compare

A new minor release of ABS: always be shipping! 🚢

Named functions

Functions can now be "named":

f my_func(x) {
  return x**2
}

Earlier, you would have had to assign
the function to a variable:

my_func = f(x) {
  return x**2
}

while right now function names are first-class
citizens. For example, the string representation
of a function will actualy include its name (to be
included in stacktraces as well):

⧐  f test() {echo(1)}
f test() {echo(1)}

Decorators

A decorator is a plain-old function that
accepts 1 + N arguments, where 1 is the
function being wrapped, and returns a new
function that wraps the original one:

f log_if_slow(original_fn, treshold_ms) {
    return f() {
        start = `date +%s%3N`.int()
        res = original_fn(...)
        end = `date +%s%3N`.int()

        if end - start > treshold_ms {
            echo("mmm, we were pretty slow...")
        }

        return res
    }
}

That's as simple as that: a named function
that returns a new function that executes the
decorated one (original_fn) and returns its
result, while logging if it takes longer than
a few milliseconds.

Now that we've declared our decorator, it's time
to use it, through the @ notation:

@log_if_slow(500)
f return_random_number_after_sleeping(seconds) {
    `sleep $seconds`
    return rand(1000)
}

and we can test our decorator has takn the stage:

⧐  return_random_number_after_sleeping(0)
493
⧐  return_random_number_after_sleeping(1)
mmm, we were pretty slow...
371

Accessing a function's arguments

Functions can receive a dynamic number of arguments,
and arguments can be "packed" through the special
... variable:

f sum_numbers() {
    s = 0
    for x in ... {
        s += x
    }

    return s
}

sum_numbers(1) # 1
sum_numbers(1, 2, 3) # 6

... is a special variables that acts
like an array, so you can loop and slice
it however you want:

f first_arg() {
    if ....len() > 0 {
        return ...[0]
    }

    return "No first arg"
}

first_arg() # "No first arg"
first_arg(1) # 1

When you pass ... directly to a function,
it will be unpacked:

f echo_wrapper() {
    echo(...)
}

echo_wrapper("hello %s", "root") # "hello root"

and you can add additional arguments as well:

f echo_wrapper() {
    echo(..., "root")
}

echo_wrapper("hello %s %s", "sir") # "hello sir root"

Call a function with an array of arguments

call calls a function "spreading" the array of arguments into the function's arguments:

multiplier = f(x, y) { x * y }
multiplier.call([10, 2]) # 20

v1.10.1

11 Feb 17:55
Compare
Choose a tag to compare

This patch release fixes 2 issues with backports from the 1.11.x development branch.

The issues fixed are:

  • hash property / array index assignment did not support ending with a semicolon, such as x.key = val; (#315)
  • you couldn't return "early" from for / for-in loops (for x in 1..10 { return x }) (#303)

v1.10.0

02 Jan 16:25
Compare
Choose a tag to compare

A new minor release of ABS: always be shipping! 🚢

New features

  • you can now reverse strings with str.reverse() (#310)
  • arrays' join method glue argument now defaults to an empty character: [1,2,3].join() # 123 (#310)
  • strings' split method separator argument now defaults to a space: "a b c".split() # ["a", "b", "c"] (#310)

Misc

  • the ABS package installer will now remove archives downloaded from github after extracting them (#292)

Thank yous!

A big thank you to @mingwho and @sysread for their contributions!

v1.9.0

07 Dec 13:09
Compare
Choose a tag to compare

A new minor release of ABS: always be shipping! 🚢

Optional chaining

You can now access objects' properties that don't exist safely (#297):

a?.b?.c?.d?.e()

Earlier, you needed to make sure all the properties in the chain existed, and simply using a.b.c.d.e() could lead to an error.

env() improvements

We've added an optional argument to env() that allows setting an environment variable (#305):

$ TEST=1 abs
Hello user, welcome to the ABS (1.9.0) programming language!
Type 'quit' when you're done, 'help' if you get lost!
⧐  env("TEST")
1
⧐  env("TEST", "123")
123
⧐  env("TEST")
123

Thanks @sysread!

Installed modules don't have the -master suffix anymore

Earlier, modules were saved under /vendor/github.com/$REPO-master directory.
Now they are saved under /vendor/github.com/$REPO directory.

Thanks @mingwho!

v1.8.3

16 Nov 10:46
Compare
Choose a tag to compare

This release adds a new builtin function: args(), implemented in #300. It returns a list of arguments the abs script has been called with (eg. ["abs", "script.abs", "--flag", "val"]).

v1.8.2

09 Nov 13:35
Compare
Choose a tag to compare

This release fixes a panic in the arg function (#299), fixed through #302. If a negative number is passed, now arg(...) will return an empty string.

# the command we're running is abs index.abs
arg(0) # "abs"
arg(1) # "index.abs"
arg(2) # ""
arg(-1) # ""

v1.8.1

31 Oct 11:49
Compare
Choose a tag to compare

This is a bugfix release which fixes #284 through #294.

To call a function "attached" to an hash you can simply:

hash = {"fn": f(){}}
hash.fn()

Earlier you had to "dereference" the function "out" of the hash due to a minor bug in ABS' evaluator:

hash = {"fn": f(){}}
fn = hash.fn
fn()