Future of string lambda functions/string predicate functions
Jakob Ovrum
jakobovrum at gmail.com
Tue Aug 6 02:05:56 PDT 2013
In Phobos pull request #1453 (Implement chunkBy.)[1], the topic
of string lambda functions has again cropped up. I think we
should clearly decide on some things regarding them. Questions
such as; are they a worthwhile alternative in the present
language? Should they be deprecated? Should they be supported in
new additions to Phobos?
Some background: string lambda functions are a feature of
std.functional/std.range/std.algorithm, where strings can be
passed in lieu of functions as template alias arguments to
various public functions in these modules. The string becomes the
return expression of an anonymous function which implicitly has
one or two arguments, named "a" and "b", like the string "a < 3"
in the following example expression:
arr.filter!"a < 3"
When this feature was developed, there were no lambda function
literals in the language. There were anonymous functions, but
their syntactical overhead means they fare poorly as a
replacement for lambda functions:
arr.filter!((a) { return a < 3; })
The effect is particularly jarring in bigger compositions:
assert([ 1, 2, 3, 4, 5 ].filter!((a) { return a < 3;
}).equal([1, 2]));
Since then, a first-class lambda syntax has been introduced, with
significantly less syntactic overhead:
arr.filter!(a => a < 3)
The issue is then: is the old string lambda syntax obsolete in
the face of the new lambda literals?
----------
My opinion on the matter is that the *only* advantage of string
lambdas is that they are (even) shorter than the new lambda
syntax. However, I don't think that comes even close to making up
for its many disadvantages; here are the ones I think are the
biggest:
* The number one reason string lambdas are shorter is because
they implicitly introduce their parameters. However, this means
that you're always stuck with the generic, uninformative
parameter names "a" and "b".
* To the uninitiated, they may not look like code. They
certainly aren't highlighted as D code in your average code
editor (the q{} literal deserves a mention, but then some of the
succinctness advantage is lost and it's not just for D code), and
the magically, implicitly introduced variables "a" and "b" is
something you plain just have to know beforehand to understand.
* Apart from "a" and "b", they can only access symbols that are
visible in the scope of the std.functional module.
In light of the above points, I just find them excessively arcane
- something new D programmers shouldn't have to learn and thus
none of us should continue to use or promote. The symbols you can
access in a string lambda are determined by the implementation
details of std.functional and thus, may change at any time. It is
then only reasonable to recommend that the programmer should not
depend on any symbols except for "a" and "b", severely limiting
the utility of string lambdas. Also, they only exist in unary and
binary forms at present, which means new functions with different
requirements cannot leverage them. And then comes the point about
consistency; if the utility of string lambdas is so limited in
the face of the general lambda literal syntax, foregoing string
lambdas in favour of lambda literals helps code consistency.
I can also think of some relatively minor disadvantages of string
lambdas, such as the compile-time performance cost they incur.
I think string lambdas were a valiant effort to fill a glaring
hole in the language at the time, but are now superseded by an
overall superior alternative. The cognitive and maintenance load
on programmers is not worth their marginal utility. I think we
should deprecate string lambdas altogether.
Specifically, I suggest the following deprecation path:
* Add deprecation notes to std.functional's unaryFun and
binaryFun so users are dissuaded from using them in new code. In
time, we would remove their documentation.
* Leave support for string lambdas in existing Phobos functions
for the foreseeable future, for backwards-compatibility purposes.
* Change all documentation so that it doesn't mention string
lambdas, whether in prose or code. Phobos pull request #707
(Switch std.algorithm/.range to lambda syntax)[2] attempted this
and was approved and merged, but subsequently reverted due to
bugs.
* New functions would not support string lambdas.
----------
To be honest, I thought this was a foregone conclusion, but
comments on Github indicate otherwise, hence this thread.
What does everyone think?
[1] https://github.com/D-Programming-Language/phobos/pull/1453
[2] https://github.com/D-Programming-Language/phobos/pull/707
More information about the Digitalmars-d
mailing list