Skip to content

Commit

Permalink
lib: add tail function
Browse files Browse the repository at this point in the history
This allows easier accounting free worklist use.
  • Loading branch information
efd6 committed May 28, 2024
1 parent d01c98e commit 1511fff
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 0 deletions.
52 changes: 52 additions & 0 deletions lib/collections.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,25 @@ import (
// [1,2,3,4,5,6,7].min() // return 1
// min([1,2,3,4,5,6,7]) // return 1
//
// # Tail
//
// Returns the elements of a list after the first element:
//
// tail(<list<dyn>>) -> <optional<dyn>>
//
// Examples:
//
// tail([1, 2, 3, 4, 5, 6]) // return [2, 3, 4, 5, 6]
// tail([6]) // return []
// tail([]) // return []
//
// The conjugate of tail, getting the first element, can be achieved
// directly using list indexing, for example if a is [1, 2, 3, 4, 5, 6]
// and b is []:
//
// a[?0] // return 1
// b[?0] // return optional.none
//
// # Values
//
// Returns a list of values from a map:
Expand Down Expand Up @@ -391,6 +410,15 @@ func (collectionsLib) CompileOptions() []cel.EnvOption {
),
),

cel.Function("tail",
cel.Overload(
"tail_list",
[]*cel.Type{listV},
listV,
cel.UnaryBinding(tail),
),
),

cel.Function("values",
cel.MemberOverload(
"map_values",
Expand Down Expand Up @@ -452,6 +480,30 @@ func (collectionsLib) CompileOptions() []cel.EnvOption {

func (collectionsLib) ProgramOptions() []cel.ProgramOption { return nil }

func tail(arg ref.Val) ref.Val {
obj := arg
l, ok := obj.(traits.Lister)
if !ok {
return types.ValOrErr(obj, "no such overload")
}
if l.Size() == types.IntZero {
return arg
}
n := l.Size().(types.Int)
t := make([]ref.Val, 0, n-1)
it := l.Iterator()
head := true
for it.HasNext() == types.True {
if head {
it.Next()
head = false
continue
}
t = append(t, it.Next())
}
return types.NewRefValList(types.DefaultTypeAdapter, t)
}

func flatten(arg ref.Val) ref.Val {
obj := arg
l, ok := obj.(traits.Lister)
Expand Down
83 changes: 83 additions & 0 deletions testdata/want_more_lispy.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
mito -data state.json src.cel
! stderr .
cmp stdout want.txt

-- state.json --
{"list": [1, 2, 3, 4, 5]}
-- src.cel --
{
?"head": state.list[?0], // Pure CEL spelling of (car state.list).
"list": tail(state.list),
"old": state.list,
"want_more": state.list[?0].hasValue(),
}
-- want.txt --
{
"head": 1,
"list": [
2,
3,
4,
5
],
"old": [
1,
2,
3,
4,
5
],
"want_more": true
}
{
"head": 2,
"list": [
3,
4,
5
],
"old": [
2,
3,
4,
5
],
"want_more": true
}
{
"head": 3,
"list": [
4,
5
],
"old": [
3,
4,
5
],
"want_more": true
}
{
"head": 4,
"list": [
5
],
"old": [
4,
5
],
"want_more": true
}
{
"head": 5,
"list": [],
"old": [
5
],
"want_more": true
}
{
"list": [],
"old": [],
"want_more": false
}

0 comments on commit 1511fff

Please sign in to comment.