about const and immutable (again)

Gor Gyolchanyan gor.f.gyolchanyan at gmail.com
Thu Oct 6 09:27:16 PDT 2011


I see. Thanks for the detailed answer.
I love D's support for functional programming. Everything about it,
except the readability of function and delegate literals:
    * Function and delegate literals are way too long because of the
"function" and "delegate" keywords being too long to be used inside
expressions.
    * One-liners introduce extra braces and a "return" keyword, which
further litters the supposedly small expression, containing a literal.
    * Parameter types are always required, despite the fact, that if
the literal is being assigned somewhere they can be inferred from the
assignee's type.

The best way to avoid this is making the delegate take 0 arguments, in
which case the whole thing can be reduced to a single expression via a
lazy parameter.
The second best way (when lazy parameters are not accessible) is to
wrap the expression into a single return-statement in braces.
But that's as good as it can get with readability. Adding parameters
is a huge pain particularly because often you really don't want to
specify their types and storage classes, since those are known from
the type of variable, that is being initialized by the literal.

I just looked up Wikipedia for lambdas in different languages and
found out, that C# has an awesome syntax for that:

x => x * x
(x, y) => x == y
(int x, string s) => s.Length > x
() => SomeMethod()
n => { string s = n + " " + "World"; Console.WriteLine(s); }

The fat arrow operator (=>) isn't used in D and cannot be confused
with anything (there's no way to write that and not get an error).
The fat arrow operator looks confusing (especially with equality
operators in the lambda's body), so the arrow operator (->) can be
used instead (which is also unused and unambiguous).
Specifying the literal type is easily accomplished by adding the
appropriate keyword in front of the expression (as it's done now).
The only remaining problem are the keywords being too long, which is
not gonna change, since even adding new keywords is a breaking change.
In the future, though, it would be great to shorten them to something
like "fn" and "dg" or something.
Nonetheless, this would be a great-looking D code:

alias int function(int, int) Fn;
alias int delegate(int, int) Dg;

Fn a0 = function (a, b) -> a + b;
Dg a1 = delegate (a, b) -> a + b;
Dg a2 = (c, f) -> a + b;

On Thu, Oct 6, 2011 at 7:32 PM, Steven Schveighoffer
<schveiguy at yahoo.com> wrote:
> On Thu, 06 Oct 2011 10:56:43 -0400, Gor Gyolchanyan
> <gor.f.gyolchanyan at gmail.com> wrote:
>
>> Hi, guys.
>>
>> I just made my handy parsing struct take an arbitrary range, instead
>> of a dstring and immediately rain head-first into a brick wall of
>> errors.
>>
>> There's this function:
>>    bool next(bool function(ElementType!InputType) pred)
>>
>> , where InputType is bound to be dstring and which gets called like this:
>>    parser.next(&isAlpha)
>>
>> , where isAlpha is from std.uni.
>> When i do that, i get this error:
>>    Error: cannot implicitly convert expression (& isAlpha) of type
>> bool function(dchar c) pure nothrow @safe to bool
>> function(immutable(dchar))
>>
>> Yes, I understand why do i get this error.
>> What i don't understand is: does the dchar being immutable really
>> change anything?
>
> What it does is make it so during the function, the parameter cannot be
> changed.  It technically has no effect on what you can pass to the function,
> since as you rightly point out, ints implicitly cast between const,
> immutable, and mutable.
>
> Why did someone do it?  To ensure they didn't accidentally write code that
> changed the value inside the function.  The compiler might also use that
> information to do some optimization (i.e. avoid reloading into a register),
> but I doubt it's necessary for that.
>
> To answer your underlying question, why doesn't the delegate "just work"?
> It's because D does not allow implicit casting of delegates or functions at
> all.  I assume this will get better at some point, because implicit casting
> of delegates would make things just so much smoother in generic programming.
>
> -Steve
>


More information about the Digitalmars-d mailing list