Comment #0 by bearophile_hugs — 2012-03-18T05:51:03Z
I suggest to turn filter and map into @properties, so thanks to UFCS you are allowed to use them like this, that is quite handy:
[1, 2, -3, 4].filter!(x => x > 0).map!(x => x ^^ 0.2).writeln();
See also Bug 7722
Comment #1 by issues.dlang — 2012-03-20T15:28:47Z
But then that would _force_ you to use UFCS, which would be very bad IMHO. Allowing it is one thing. Forcing it is another thing entirely.
Also, conceptually speaking, filter and map aren't properties at all. They wouldn't make any sense whatsoever as fields on a class or struct. They're definitely functions. And so they shouldn't be marked with @property.
Comment #2 by bearophile_hugs — 2012-03-20T17:26:48Z
(In reply to comment #1)
Thank you for your answers. As it often happens with design matters, this topic asks for judgements. I don't have definitive answers.
> But then that would _force_ you to use UFCS,
Are you sure?
Even when Bug 7722 will be fixed, I think the following code will be valid:
@property T head(T)(T[] a) { return a[0]; }
void main() {
int r1 = head([1, 2, 3]);
int r2 = [1, 2, 3].head();
int r3 = [1, 2, 3].head;
}
In the second part of this post I have asked for the enforcement of proprieties the other way, as you say, but I am not sure it will happen:
http://forum.dlang.org/thread/[email protected]
> They wouldn't make any sense whatsoever as fields on a class or struct.
> They're definitely functions.
I agree.
> And so they shouldn't be marked with @property.
In this line of code filter and map look as built-in property of iterables, where if you see them as functions the template argument looks like their argument:
[1, 2, -3, 4].filter!(x => x > 0).map!(x => x ^^ 0.2)
There the () doesn't add clarity, because their true argument is on their left:
[1, 2, -3, 4].filter!(x => x > 0)().map!(x => x ^^ 0.2)()
So I have used a different conceptual definition of property, coming from syntactical aesthetics :-)
So it's an exception of the general "what's a @property" rule, that may (or may not) be justified on the base of practicality: map/filter functions are meant to be used very often in code, and Python shows how much list comprehensions (even the lazy ones, that have a different name) are handy. Reducing the syntax noise of very commonly used idioms is positive.
Comment #3 by bearophile_hugs — 2012-03-20T17:31:10Z
(In reply to comment #2)
> In this line of code filter and map look as built-in property of iterables,
I meant:
In this line of code filter and map look as built-in methods of iterables,
Comment #4 by issues.dlang — 2012-03-20T18:14:59Z
It seems to me that you're not looking for a property. You just think that the empty parens are annoying and don't want to have to use them, and property syntax is the only way to do that. Personally, I'm completely against using @property on anything that could conceptually be a field of a class. filter and map are very much functions and are staples of functional languages, so I'm completely against marking them as properties, regardless of what syntactic benefits there may be in doing so.
> Are you sure?
> Even when Bug 7722 will be fixed, I think the following code will be valid:
> @property T head(T)(T[] a) { return a[0]; }
> void main() {
> int r1 = head([1, 2, 3]);
> int r2 = [1, 2, 3].head();
> int r3 = [1, 2, 3].head;
> }
Strong property enforcement would mean that @property functions can _never_ be called with parens, and functions which aren't marked with @property must _always_ be called with parens. That's what TDPL describes. And as such, r3 would be the only legal option. I don't know what the current implementation is doing though.
Comment #5 by destructionator — 2012-03-20T18:18:59Z
This issue is another piece of evidence that -property is a mistake and should never be enforced.
Comment #6 by issues.dlang — 2012-03-20T18:29:13Z
> This issue is another piece of evidence that -property is a mistake and should
> never be enforced.
I disagree. It's more an issue of what @property is for. Is it simply to try and enable a syntax where you don't need parens if you don't feel like it, or is it a means of providing functions that act like variables?
Normally, properties are intended as a means of replacing variables with functions that act like the variable but do something more (e.g. enforce invariants). But since D originally took the approach of being lax and letting any function be called without parens if it didn't have any parameters (or be used with = if it only had one), people got used to being lax about the their parens with functions that had nothing to do with properties at all.
And as long as properties are intended to mimic variables rather than simply be a means of being lax with parens, it makes no sense to use @property simply so that you don't need to use parens.
Personally, I suspect that @property is as disputed as it is simply because D took the lax approach initially rather than providing a way to define whether a particular function was a property function or not. If we'd one @property originally or done something like what C# did with get and set, it probably would never have been an issue at all.
Regardless, I'm firmly in the camp of folks in favor of strict enforcement of @property, and I think that this proposal goes against the concept of properties.
Comment #7 by destructionator — 2012-03-20T18:53:22Z
(In reply to comment #6)
> I disagree. It's more an issue of what @property is for. Is it simply to try
> and enable a syntax where you don't need parens if you don't feel like it, or
> is it a means of providing functions that act like variables?
@property and "property syntax" aren't the same thing, and
shouldn't be confused.
D's property syntax is orthogonal to the concept of properties.
Yes, it is useful for them, but it also useful for chaining,
like seen here, and other things in the wild.
@property is to help functions act like variables, which
only relates to syntax when there's ambiguity.
The mistake with -property enforcement is it combines these
two items, while ignoring other uses like function chaining
or property/function hybrids (ones with default arguments,
e.g. if(empty) or if(empty(true)) given bool empty(bool deep = false)).
"Property syntax" should be renamed to "optional parenthesis
syntax" to help cure this confusion. Then, it would be clear
that -property's enforcement is wrong, and issues like this
would resolve themselves.
The legitimate uses work, the ambiguous properties use,
and best of all, it won't break any existing code.
Everybody wins.
Comment #8 by bearophile_hugs — 2012-03-20T19:22:16Z
(In reply to comment #7)
> "Property syntax" should be renamed to "optional parenthesis
> syntax" to help cure this confusion. Then, it would be clear
> that -property's enforcement is wrong, and issues like this
> would resolve themselves.
In this bug report I ask if it's a good idea to add @property to map/filter to gain a better usage syntax.
I am for strong enforcement of propriety syntax (both ways), as Jonathan. I can't see how thinking of @property as "optional parenthesis syntax" makes its enforcement useless :)
Comment #9 by bearophile_hugs — 2012-03-20T19:26:57Z
(In reply to comment #4)
> Strong property enforcement would mean that @property functions can _never_ be
> called with parens, and functions which aren't marked with @property must
> _always_ be called with parens. That's what TDPL describes.
That's good because if you define a property, you use it with () and later you replace the property with a normal field, the code stops compiling. So I agree it's important to enforce property in both directions.
I didn't remember this detail of TDPL, thank you for your answer.
If your note about TDPL is correct, then the value of this enhancement request decreases, because you are forced to use map/filter with a property syntax.
I don't know if always using map/filter with a property syntax is a good idea. Maybe not.
Comment #10 by destructionator — 2012-03-20T19:29:26Z
(In reply to comment #8)
> In this bug report I ask if it's a good idea to add @property to map/filter to
> gain a better usage syntax.
That's definitely wrong. map and filter aren't @properties.
> I am for strong enforcement of propriety syntax (both ways), as Jonathan. I
> can't see how thinking of @property as "optional parenthesis syntax" makes its
> enforcement useless :)
My point is that @property != "property syntax". They are
completely separate concepts.
Comment #11 by bearophile_hugs — 2012-03-20T20:53:44Z
(In reply to comment #10)
> That's definitely wrong. map and filter aren't @properties.
They are, with a different definition of property :)