Classic Utilities
There is a strong focus in glue to offer a basic toolset of powerful methods rather than a ton of very specific methods.
It is left up to library providers or endusers to craft specific utilities as needed. Here are some example of classic utilities you would expect to find in most languages and how you can achieve them with the core methods in glue.
Push/Unshift/Offer/...
These methods revolve around adding elements at the back or front of a series, they can be achieved using the merge() functionality:
series = series(1, 2, 3)
# push at the end
series = merge(series, 4, 5)
# unshift at the beginning
series = merge(0, series)
echo(series)
[0, 1, 2, 3, 4, 5]
In fact merge will allow you to merge a combination of collections and standalone values.
Pop/Shift/Pull/...
These methods revolve around removing elements at the back or the front of a series, this can be achieved with offset():
series = series(0, 1, 2, 3, 4, 5)
# remove at front
series = offset(1, series)
# remove at back
series = offset(-2, series)
echo(series)
[1, 2, 3]
If we want to write a reusable pop utility, the question becomes what the best return value is. Both the modified list and the removed element are of interest.
Glue supports inherent multiple return, so we could do something like this:
pop = lambda
[] series ?= null
@return
popped = last(series)
@return
series = offset(-1, series)
echo(pop(1, 2, 3, 4))
{popped=4, series=[1, 2, 3]}
Where lambdas are unable to affect the original captured context, methods are allowed to do this so we could actually change the series:
series = series(0, 1, 2, 3, 4, 5)
pop = method
@return
popped = last(series)
@persist
series = offset(-1, series)
echo(pop())
echo(series)
5
[0, 1, 2, 3, 4]
In this case however we are modifying the actual "series" variable in the scope which is not always ideal. We could capture the series in a context though where we expose additional functions:
series = series(1, 2, 3, 4)
managed = lambda
[] series ?= null
pop = method
@return
popped = last(series)
@persist
series = offset(-1, series)
a = managed(series)
echo(a/pop())
echo(a/series)
# print the original series to check that it wasn't altered
echo(series)
4
[1, 2, 3]
[1, 2, 3, 4]
Slice/Sublist/...
The slice functionality in general allows you to take a part of a list, you can do this with a combination of offset() and limit():
series = series(0, 1, 2, 3, 4, 5)
# base it on an initial offset and a number of items
first = limit(3, offset(1, series))
# base it on an initial offset and an end offset
# in this particular case we remove the first and last items of the series
second = offset(-1, offset(1, series))
Splice
The splice functionality allows you to remove parts of a list and/or replace them with some other elements, this can be achieved with a combination of offset(), limit() and merge():
series = series(0, 1, 3, 4)
series = merge(
limit(2, series),
2,
offset(2, series))
At this point the list contains: [0, 1, 2, 3, 4]
Combine it all
You can combine all of the above into a single managed instance:
series = series(1, 2, 3, 4)
managed = lambda
[] series ?= null
pop = method
@return
popped = last(series)
@persist
series = offset(-1, series)
push = method
[] values ?= null
@persist
series = merge(series, values)
@return
value = $this
slice = method
from ?= 0
to ?= size(series)
@return
sliced = merge(limit(to - from, offset(from, series)))
splice = method
from ?= 0
to ?= size(series)
[] elements ?= null
@return
sliced = slice(from, to)
@persist
series = merge(limit(from, series), elements, offset(to, series))
a = managed(series)
echo("Popped: " + a/pop())
echo(a/push(5, 6)/slice(3, 5))
echo(a/series)
echo(a/splice(1, 3, 7, 8))
echo(a/series)
Popped: 4
[5, 6]
[1, 2, 3, 5, 6]
[2, 3]
[1, 7, 8, 5, 6]
Zip
The python zip() method is a special case of derive():
series1 = series(1, 2, 3)
series2 = series(5, 4, 3)
zip = lambda(x, y, series(x, y))
echo(derive(zip, series1, series2))
[[1, 5], [2, 4], [3, 3]]
You could also implement your own zip() method as follows:
zip = lambda
[] series ?= null
helper = sequence
[] input ?= null
@return
result = series(unwrap(input))
@return
result = derive(helper, unwrap(series))
echo(zip(series(1, 2, 3),
series(5, 4, 3)))
echo(zip(series(1, 2, 3),
series(5, 4, 3),
series(10, 9, 8)))
[[1, 5], [2, 4], [3, 3]]
[[1, 5, 10], [2, 4, 9], [3, 3, 8]]
Any/All
Given a series of booleans, you can check whether any boolean is true or all booleans are true. For example:
regexes = series("a.*", "b.*")
## Generate a series of booleans
echo("aa" ~ regexes)
## Check if the boolean "true" is in that series (= any)
echo(true ? ("aa" ~ regexes))
## Check that the boolean "false" is not in that series (= all)
echo(false !? ("aa" ~ regexes))
This prints out:
[true, false]
true
false