Summary#
A helper that belongs to one body, declared in it:
string Report(int count) {
int margin = 2;
var line = Label(count); // called before it is declared, as C# allows
string Label(int n) => $"#{n + margin}"; // reads `margin` from the code around it
int Fact(int n) => n <= 1 ? 1 : n * Fact(n - 1); // calls itself
return $"{line}|{Fact(count)}";
}
[Test]
void Local_Functions_Work_Like_Methods() {
Assert.Equal("#6|24", Report(4));
}Signature#
<Return> Name(<params>) { … }
<Return> Name(<params>) => <expression>;
static <Return> Name(<params>) => <expression>; // reads nothing from the code around itDescription#
What can a local function read?#
The parameters of the function it is in, and the locals declared there with their TYPE spelled out — int margin = 2;,
not var margin = 2;. A local function receives what it reads as a value, so a var local it reads is refused with a
message asking for the type. Inside a class method it also reads the class's own fields, exactly as the method does:
class Invoice {
public decimal Rate = 0.25m;
public decimal Gross(decimal net) {
decimal WithTax(decimal v) => v * (1m + Rate);
return WithTax(net);
}
}
[Test]
void A_Method_Local_Reads_The_Object() {
Assert.Equal(125m, new Invoice().Gross(100m));
}Can it change a variable of the code around it?#
Yes, as in C#: the local function and the body around it share the variable. What it reads is read when it is CALLED, and what it assigns is the variable itself — also when one local function calls another, or calls itself:
[Test]
void A_Local_Function_Shares_What_It_Writes() {
int seen = 0;
int step = 1;
void Note() { seen += step; }
int NoteTwice() { Note(); Note(); return seen; }
step = 5;
Note();
Assert.Equal(15, NoteTwice());
Assert.Equal(15, seen);
}Such a local function is called by NAME in the body that declares it. Used as a value — Action a = Note;, handed on
or stored — it could run where the variable is not, so that is refused by name; and it cannot wait inside itself for
the other side or a durable timer. In either case, have it return the new value and assign it where the variable
lives.
What does static add?#
A promise that the local function reads nothing from around it — C#'s static local function. One that does is
refused, as C# refuses it.
See also#
- function — functions declared at the top level of a file
- x => … — lambdas, with or without parameter types — an inline function as a value
- class methods — functions that belong to a class