Skip to content

Commit

Permalink
spec: allow nested def statements and lambda expressions
Browse files Browse the repository at this point in the history
Change-Id: Ife0a71909aea14b4bae7d24f324ab28b78471e81
  • Loading branch information
adonovan committed Dec 11, 2020
1 parent 653cadd commit d3546a5
Showing 1 changed file with 53 additions and 8 deletions.
61 changes: 53 additions & 8 deletions spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ and else load
break for not
continue if or
def in pass
elif return
elif lambda return
```

The tokens below also may not be used as identifiers although they do not
Expand All @@ -251,15 +251,14 @@ appear in the grammar; they are reserved as possible future keywords:
<!-- and to remain a syntactic subset of Python -->

```text
as is
assert lambda
as import
assert is
class nonlocal
del raise
except try
finally while
from with
global yield
import
```

*Identifiers*: an identifier is a sequence of Unicode letters, decimal
Expand Down Expand Up @@ -933,7 +932,11 @@ A function value represents a function defined in Starlark.
Its [type](#type) is `"function"`.
A function value used in a Boolean context is always considered true.

Function definitions may not be nested.
Functions defined by a [`def` statement](#function-definitions) are named;
functions defined by a [`lambda` expression](#lambda-expressions) are anonymous.

Function definitions may be nested, and an inner function may refer
to a local variable of an outer function.

A function definition defines zero or more named parameters.
Starlark has a rich mechanism for passing arguments to functions.
Expand Down Expand Up @@ -1133,6 +1136,7 @@ allowing unbounded recursion.

A built-in function is a function or method implemented by the interpreter
or the application into which the interpreter is embedded.
Its [type](#type) is `"builtin_function_or_method"`.

A built-in function value used in a Boolean context is always considered true.

Expand Down Expand Up @@ -1431,7 +1435,7 @@ hashable, unless they have become immutable due to _freezing_.
A `tuple` value is hashable only if all its elements are hashable.
Thus `("localhost", 80)` is hashable but `([127, 0, 0, 1], 80)` is not.

Values of type `function` are also hashable.
Values of the types `function` and `builtin_function_or_method` are also hashable.
Although functions are not necessarily immutable, as they may be
closures that refer to mutable variables, instances of these types
are compared by reference identity (see [Comparisons](#comparisons)),
Expand Down Expand Up @@ -1572,7 +1576,7 @@ and `Test` where it accepts an expression of only a single component.
```text
Expression = Test {',' Test} .
Test = IfExpr | PrimaryExpr | UnaryExpr | BinaryExpr .
Test = IfExpr | PrimaryExpr | UnaryExpr | BinaryExpr | LambdaExpr .
PrimaryExpr = Operand
| PrimaryExpr DotSuffix
Expand Down Expand Up @@ -1653,10 +1657,11 @@ for x in 1, 2:
```

Starlark (like Python 3) does not accept an unparenthesized tuple
expression as the operand of a list comprehension:
or lambda expression as the operand of a `for`-clause in a comprehension:

```python
[2*x for x in 1, 2, 3] # parse error: unexpected ','
[2*x for x in lambda: 0] # parse error: unexpected 'lambda'
```

### Dictionary expressions
Expand Down Expand Up @@ -2316,6 +2321,46 @@ operand (when the stride is 1). By contrast, slicing a list requires
the creation of a new list and copying of the necessary elements.


### Lambda expressions

A `lambda` expression yields a new function value.

```grammar {.good}
LambdaExpr = 'lambda' [Parameters] ':' Test .
```

Syntactically, a lambda expression consists of the keyword `lambda`,
followed by a parameter list like that of a `def` statement but
unparenthesized, then a colon `:`, and a single expression, the
_function body_.

Example:

```python
def map(f, list):
return [f(x) for x in list]

map(lambda x: 2*x, range(3)) # [2, 4, 6]
```

As with functions created by a `def` statement, a lambda function
captures the syntax of its body, the default values of any optional
parameters, the value of each free variable appearing in its body, and
the global dictionary of the current module.

The name of a function created by a lambda expression is `"lambda"`.

The two statements below are essentially equivalent, but the
function created by the `def` statement is named `twice` and the
function created by the lambda expression is named `lambda`.

```python
def twice(x):
return x * 2

twice = lambda x: x * 2
```

## Statements

```text
Expand Down

0 comments on commit d3546a5

Please sign in to comment.