Skip to content

Commit

Permalink
Merge pull request #240 from 9rnsr/fix_funclit
Browse files Browse the repository at this point in the history
Improve function literal documentation
  • Loading branch information
alexrp committed Jan 21, 2013
2 parents 53086b3 + f29fdf4 commit d30b904
Showing 1 changed file with 81 additions and 60 deletions.
141 changes: 81 additions & 60 deletions expression.dd
Expand Up @@ -65,20 +65,20 @@ c = a + (a = b);
of errors is a quality of implementation issue.
)

$(P The evaluation order of function arguments is defined to be left to
right. This is similar to Java but different to C/C++ where the evaluation
order is unspecified. Thus, the following code is valid and well defined.
)
$(P The evaluation order of function arguments is defined to be left to
right. This is similar to Java but different to C/C++ where the evaluation
order is unspecified. Thus, the following code is valid and well defined.
)
-------------
import std.conv;
int i = 0;
assert(text(++i, ++i) == "12"); // left to right evaluation of arguments
-------------

$(P But even though the order of evaluation is well defined writing code that
depends on it is rarely recommended.
$(B Note that dmd currently does not comply with left to right evaluation of
function arguments.))
$(P But even though the order of evaluation is well defined writing code that
depends on it is rarely recommended.
$(B Note that dmd currently does not comply with left to right evaluation of
function arguments.))

<h2><a name="Expression">Expressions</a></h2>

Expand Down Expand Up @@ -141,11 +141,11 @@ a = cast(typeof(a))(a $(I op) b)

$(P except that:)

$(UL
$(LI operand $(D a) is only evaluated once)
$(LI overloading $(I op) uses a different function than overloading $(I op)= does)
$(LI the left operand of $(D >>>=) does not undergo integral promotions before shifting)
)
$(UL
$(LI operand $(D a) is only evaluated once)
$(LI overloading $(I op) uses a different function than overloading $(I op)= does)
$(LI the left operand of $(D >>>=) does not undergo integral promotions before shifting)
)

<h2>Conditional Expressions</h2>

Expand Down Expand Up @@ -601,7 +601,7 @@ $(GNAME ShiftExpression):

$(P It's illegal to shift by the same or more bits than the size of the
quantity being shifted:
)
)

-------------
int c;
Expand Down Expand Up @@ -732,24 +732,24 @@ $(GNAME ComplementExpression):
$(B ~) $(I UnaryExpression)
)

$(P $(I ComplementExpression)s work on integral types (except bool).
All the bits in the value are complemented.)
$(P $(I ComplementExpression)s work on integral types (except bool).
All the bits in the value are complemented.)

$(P Note: unlike in C and C++, the usual integral promotions are not performed
prior to the complement operation.
)
$(P Note: unlike in C and C++, the usual integral promotions are not performed
prior to the complement operation.
)

<h3>New Expressions</h3>

$(GRAMMAR
$(GNAME NewExpression):
$(B new) $(I AllocatorArguments)$(OPT) $(GLINK2 declaration, Type) $(B [) $(GLINK AssignExpression) $(B ])
$(B new) $(I AllocatorArguments)$(OPT) $(GLINK2 declaration, Type) $(B $(LPAREN)) $(GLINK ArgumentList) $(B $(RPAREN))
$(B new) $(I AllocatorArguments)$(OPT) $(GLINK2 declaration, Type)
$(GLINK2 class, NewAnonClassExpression)
$(B new) $(I AllocatorArguments)$(OPT) $(GLINK2 declaration, Type) $(B [) $(GLINK AssignExpression) $(B ])
$(B new) $(I AllocatorArguments)$(OPT) $(GLINK2 declaration, Type) $(B $(LPAREN)) $(GLINK ArgumentList) $(B $(RPAREN))
$(B new) $(I AllocatorArguments)$(OPT) $(GLINK2 declaration, Type)
$(GLINK2 class, NewAnonClassExpression)

$(GNAME AllocatorArguments):
$(B $(LPAREN)) $(GLINK ArgumentList)$(OPT) $(B $(RPAREN))
$(B $(LPAREN)) $(GLINK ArgumentList)$(OPT) $(B $(RPAREN))

$(GNAME ArgumentList):
$(GLINK AssignExpression)
Expand Down Expand Up @@ -802,7 +802,7 @@ foreach (ref a; bar)
$(P If there is a $(B new $(LPAREN)) $(GLINK ArgumentList) $(B $(RPAREN)),
then
those arguments are passed to the class or struct specific
$(LINK2 class.html#allocators, allocator function) after the size argument.
$(LINK2 class.html#allocators, allocator function) after the size argument.
)

$(P If a $(I NewExpression) is used as an initializer for
Expand Down Expand Up @@ -844,8 +844,8 @@ $(GNAME DeleteExpression):

$(P The pointer, dynamic array, or reference is set to $(B null)
after the delete is performed.
Any attempt to reference the data after the deletion via another
reference to it will result in undefined behavior.
Any attempt to reference the data after the deletion via another
reference to it will result in undefined behavior.
)

$(P If $(I UnaryExpression) is a variable allocated
Expand Down Expand Up @@ -916,13 +916,13 @@ else
}
-------------

$(P Casting a pointer type to and from a class type is done as a type paint
(i.e. a reinterpret cast).)
$(P Casting a pointer type to and from a class type is done as a type paint
(i.e. a reinterpret cast).)

$(P Casting a dynamic array to another dynamic array is done only if the
array lengths multiplied by the element sizes match. The cast is done
as a type paint, with the array length adjusted to match any change in
element size. If there's not a match, a runtime error is generated.)
$(P Casting a dynamic array to another dynamic array is done only if the
array lengths multiplied by the element sizes match. The cast is done
as a type paint, with the array length adjusted to match any change in
element size. If there's not a match, a runtime error is generated.)

$(V1
---
Expand Down Expand Up @@ -997,7 +997,7 @@ assert(is(typeof(cast(const)x) == const int));

$(P Casting with no $(GLINK Type) or $(GLINK CastQual) removes
any top level $(B const), $(B immutable), $(B shared) or $(B inout)
type modifiers from the type
type modifiers from the type
of the $(GLINK UnaryExpression).)

---
Expand Down Expand Up @@ -1102,7 +1102,7 @@ $(GNAME SliceExpression):
type of the $(I PostfixExpression).
)

$(P A $(I SliceExpression) is not a modifiable lvalue.)
$(P A $(I SliceExpression) is not a modifiable lvalue.)

$(P If $(I PostfixExpression) is an $(I ExpressionTuple), then
the result of the slice is a new $(I ExpressionTuple) formed
Expand Down Expand Up @@ -1182,7 +1182,7 @@ void main() {
}
-------------

$(P Assignment to $(B this) is not allowed.)
$(P Assignment to $(B this) is not allowed.)

<h3>$(LNAME2 super, super)</h3>

Expand All @@ -1195,7 +1195,7 @@ void main() {
to $(B super), a non-virtual call is made.
)

$(P Assignment to $(B super) is not allowed.)
$(P Assignment to $(B super) is not allowed.)

<h3>$(LNAME2 null, null)</h3>

Expand Down Expand Up @@ -1377,30 +1377,30 @@ $(GNAME Lambda):
$(GLINK ParameterAttributes) $(B =&gt;) $(GLINK AssignExpression)
)

$(P $(I Lambda)s are a shorthand syntax for $(GLINK FunctionLiteral)s.
The first form is equivalent to:
)
$(P $(I Lambda)s are a shorthand syntax for $(GLINK FunctionLiteral)s.
The first form is equivalent to:
)
---
delegate ( $(IDENTIFIER) ) { return $(I AssignExpression); }
( $(IDENTIFIER) ) { return $(I AssignExpression); }
---

$(P And the second:)
$(P And the second:)

---
delegate $(I ParameterAttributes) { return $(I AssignExpression); }
$(I ParameterAttributes) { return $(I AssignExpression); }
---

Example usage:
---
import std.stdio;

void main() {
auto i=3;
auto square = (int x) => x*x;
auto twice = (int x) => x*2;
auto i=3;
auto square = (int x) => x*x;
auto twice = (int x) => x*2;

writeln(square(i)); // prints 9
writeln(twice(i)); // prints 6
writeln(square(i)); // prints 9
writeln(twice(i)); // prints 6
}
---

Expand Down Expand Up @@ -1431,7 +1431,8 @@ $(V2 $(GLINK2 declaration, Parameters) $(GLINK2 declaration, FunctionAttrib
The type of a function literal is pointer to function or
pointer to delegate.
If the keywords $(B function) or $(B delegate) are omitted,
it defaults to being a delegate.)
it is inferred from whether $(I FunctionBody) is actually
accessing to the outer context.)

$(P For example:)

Expand Down Expand Up @@ -1480,16 +1481,36 @@ void test() {
}
-------------

$(P and the following where the return type $(B int) is
inferred:)
$(P and the following where the return type $(B int) and
$(B function)/$(B delegate) are inferred:)

-------------
int abc(int delegate(long i));
int def(int function(long s));

void test() {
int b = 3;

abc( $(B (long c) { return 6 + b; }) );
abc( $(B (long c) { return 6 + b; }) ); // inferred to $(B delegate)
def( $(B (long c) { return c * 2; }) ); // inferred to $(B function)
//def( $(B (long c) { return c * b; }) ); // error!
// Because the FunctionBody accesses b, then the function literal type
// is inferred to delegate. But def cannot receive delegate.
}
-------------

If the type of a function literal can be uniquely determined from its context,
the parameter type inference is possible.

-------------
void foo(int function(int) fp);

void test() {
int function(int) fp = (n) { return n * 2; };
// The type of parameter n is inferred to $(B int).

foo((n) { return n * 2; });
// The type of parameter n is inferred to $(B int).
}
-------------

Expand All @@ -1515,7 +1536,7 @@ double test() {
-------------

When comparing with $(DDSUBLINK function, nested, nested functions),
the $(B function) form is analogous to static
the $(B function) form is analogous to static
or non-nested functions, and the $(B delegate) form is
analogous to non-static nested functions. In other words,
a delegate literal can access stack variables in its enclosing
Expand All @@ -1531,9 +1552,9 @@ $(GNAME AssertExpression):
)

$(P Asserts evaluate the $(I AssignExpression).
If it evaluates to a non-null class reference, the class invariant is run.
Otherwise, if it evaluates to a non-null pointer to a struct, the struct invariant is run.
Otherwise, if the result is false,
If it evaluates to a non-null class reference, the class invariant is run.
Otherwise, if it evaluates to a non-null pointer to a struct, the struct invariant is run.
Otherwise, if the result is false,
an $(B AssertError) is thrown. If the result is true, then no
exception is thrown.
It is an error if the $(I expression) contains any side effects
Expand Down Expand Up @@ -1920,9 +1941,9 @@ $(V1 $(TR
$(TR
$(TD $(CODE function))
$(TD $(I TypeTuple) of the function parameter types.
For C- and D-style variadic functions,
only the non-variadic parameters are included.
For typesafe variadic functions, the ... is ignored.)
For C- and D-style variadic functions,
only the non-variadic parameters are included.
For typesafe variadic functions, the ... is ignored.)
)
$(TR
$(TD $(CODE delegate))
Expand Down Expand Up @@ -2043,7 +2064,7 @@ void main() {
Macros:
TITLE=Expressions
WIKI=Expression
IDENTIFIER=$(GLINK2 lex, Identifier)
IDENTIFIER=$(GLINK2 lex, Identifier)
CATEGORY_SPEC=$0
FOO=

0 comments on commit d30b904

Please sign in to comment.