Skip to content

Commit

Permalink
doc: document call argument evaluation order (#118)
Browse files Browse the repository at this point in the history
..now that the spec is resolved.
  • Loading branch information
adonovan authored Jan 18, 2019
1 parent d5c553a commit 7b3aad4
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 14 deletions.
7 changes: 7 additions & 0 deletions doc/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,13 @@ same name, such as `f(x=1, x=2)`. A call that provides a `**kwargs`
argument may yet have two values for the same name, such as
`f(x=1, **dict(x=2))`. This results in a dynamic error.

Function arguments are evaluated in the order they appear in the call.
<!-- see https://github.com/bazelbuild/starlark/issues/13 -->

Unlike Python, Starlark does not allow more than one `*args` argument in a
call, and if a `*args` argument is present it must appear after all
positional and named arguments.

A function call completes normally after the execution of either a
`return` statement, or of the last statement in the function body.
The result of the function call is the value of the return statement's
Expand Down
24 changes: 10 additions & 14 deletions internal/compile/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -1567,27 +1567,23 @@ func (fcomp *fcomp) args(call *syntax.CallExpr) (op Opcode, arg uint32) {
p++
}

// Python2, Python3, and Starlark-in-Java all permit named arguments
// Python2 and Python3 both permit named arguments
// to appear both before and after a *args argument:
// f(1, 2, x=3, *[4], y=5, **dict(z=6))
//
// However all three implement different argument evaluation orders:
// They also differ in their evaluation order:
// Python2: 1 2 3 5 4 6 (*args and **kwargs evaluated last)
// Python3: 1 2 4 3 5 6 (positional args evaluated before named args)
// Starlark-in-Java: 1 2 3 4 5 6 (lexical order)
// Starlark-in-Java historically used a third order:
// Lexical: 1 2 3 4 5 6 (all args evaluated left-to-right)
//
// The Starlark-in-Java semantics are clean but hostile to a
// compiler-based implementation because they require that the
// compiler emit code for positional, named, *args, more named,
// and *kwargs arguments and provide the callee with a map of
// the terrain.
// After discussion in github.com/bazelbuild/starlark#13, the
// spec now requires Starlark to statically reject named
// arguments after *args (e.g. y=5), and to use Python2-style
// evaluation order. This is both easy to implement and
// consistent with lexical order:
//
// For now we implement the Python2 semantics, but
// the spec needs to clarify the correct approach.
// Perhaps it would be best if we statically rejected
// named arguments after *args (e.g. y=5) so that the
// Python2 implementation strategy matches lexical order.
// Discussion in github.com/bazelbuild/starlark#13.
// f(1, 2, x=3, *[4], **dict(z=6)) # 1 2 3 4 6

// *args
if varargs != nil {
Expand Down

0 comments on commit 7b3aad4

Please sign in to comment.