Skip to content

new syntax for user operator declarations and invocations#6181

Merged
mccanne merged 2 commits intomainfrom
call-op
Sep 3, 2025
Merged

new syntax for user operator declarations and invocations#6181
mccanne merged 2 commits intomainfrom
call-op

Conversation

@mccanne
Copy link
Collaborator

@mccanne mccanne commented Sep 3, 2025

This commit improves the syntax for user operators to better align with built-in operators and distinguish their syntax from user functions.

The new syntax for op declarations is:

 op name arg, arg, ... : ( ... )

and invoking an operator is now:

call name arg, arg, ...

with a short-cut where you can drop the "call" as a shortcut:

name arg, arg, ...

(as long as the shortcut is not a single operator with no arguments inside of a subquery)

Updated documentation is coming in a subsequent PR from the book branch.

This commit improves the syntax for user operators to better align
with built-in operators and distinguish their syntax from user
functions.

The new syntax for op declarations is:

     op name arg, arg, ... : ( ... )

and invoking an operator is now:

    call name arg, arg, ...

with a short-cut where you can drop the "call" as a shortcut:

    name arg, arg, ...

(as long as the shortcut is not a single operator with no arguments
inside of a subquery)

Updated documentation is coming in a subsequent PR from the book branch.
Comment on lines +90 to +94
/ !CallIDGuard id:Identifier _ !CallExprGuard args:Exprs {
return &ast.CallOp{Kind:"CallOp", Name: id.(*ast.ID), Args:sliceOf[ast.Expr](args), Loc:loc(c)}, nil
}
/ !CallIDGuard id:Identifier &EndOfOp {
return &ast.CallOp{Kind:"CallOp", Name: id.(*ast.ID), Loc:loc(c)}, nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We usually name these for the field they initialize rather than their rule.

Suggested change
/ !CallIDGuard id:Identifier _ !CallExprGuard args:Exprs {
return &ast.CallOp{Kind:"CallOp", Name: id.(*ast.ID), Args:sliceOf[ast.Expr](args), Loc:loc(c)}, nil
}
/ !CallIDGuard id:Identifier &EndOfOp {
return &ast.CallOp{Kind:"CallOp", Name: id.(*ast.ID), Loc:loc(c)}, nil
/ !CallIDGuard name:Identifier _ !CallExprGuard args:Exprs {
return &ast.CallOp{Kind: "CallOp", Name: name.(*ast.ID), Args: sliceOf[ast.Expr](args), Loc: loc(c)}, nil
}
/ !CallIDGuard name:Identifier &EndOfOp {
return &ast.CallOp{Kind: "CallOp", Name: name.(*ast.ID), Loc: loc(c)}, nil

Comment on lines +423 to +428
= CALL _ id:Identifier args:((_ args:Exprs) { return args, nil })? {
op := &ast.CallOp{Kind:"CallOp", Name: id.(*ast.ID), Loc:loc(c)}
if args != nil {
op.Args = sliceOf[ast.Expr](args)
}
return op, nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nits: Name the Identifier label for the field it initializes. And passing nil to sliceOf is safe.

Suggested change
= CALL _ id:Identifier args:((_ args:Exprs) { return args, nil })? {
op := &ast.CallOp{Kind:"CallOp", Name: id.(*ast.ID), Loc:loc(c)}
if args != nil {
op.Args = sliceOf[ast.Expr](args)
}
return op, nil
= CALL _ name:Identifier args:((_ args:Exprs) { return args, nil })? {
return &ast.CallOp{
Kind: "CallOp",
Name: name.(*ast.ID),
Args: sliceOf[ast.Expr](args),
Loc: loc(c)
}, nil
}

// or an expression that is either an implied "values" (non-boolean) or an implied
// "where" (boolean).
// one of four shortcuts: a shortcut assignment for "put", a shortcut "aggregate",
// a shortcut "call" operator, or an expression that is either an implied "values"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: For consistency with the other items in this list.

Suggested change
// a shortcut "call" operator, or an expression that is either an implied "values"
// a shortcut "call", or an expression that is either an implied "values"

@nwt
Copy link
Member

nwt commented Sep 3, 2025

I think this new syntax looks really good!

Co-authored-by: Noah Treuhaft <noah.treuhaft@gmail.com>
@mccanne mccanne merged commit a90585f into main Sep 3, 2025
5 checks passed
@mccanne mccanne deleted the call-op branch September 3, 2025 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants