December 02, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sunday, 2 December 2012 at 06:58:12 UTC, Jonathan M Davis wrote:
> On Sunday, December 02, 2012 07:49:52 deadalnix wrote:
>> And what do you think about map!(x => x * x) = generator(x, y, z)
>> ?
>
> What's that even supposed to mean? map has been given no function argument
> either as UFCS or with a normal function call, so it's not being called. And
> even if it were, it wouldn't result in an lvalue, so putting it on the left of
> an assignment makes no sense. I have no idea what you're trying to do here.
>
I want to express that regular function are really different than regular function calls. If map had to behave like a property, then the code above would be correct, and 100% equivalent to Andrei's snippet.
|
December 02, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
On 12/02/12 07:57, Jonathan M Davis wrote:
> On Sunday, December 02, 2012 07:49:52 deadalnix wrote:
>> And what do you think about map!(x => x * x) = generator(x, y, z)
>> ?
>
> What's that even supposed to mean? map has been given no function argument either as UFCS or with a normal function call, so it's not being called. And even if it were, it wouldn't result in an lvalue, so putting it on the left of an assignment makes no sense. I have no idea what you're trying to do here.
void main() {
import std.stdio;
writeln!string = "Hello World!";
}
// The explicit "!string" is only needed because of no IFTI, if 'writeln' was
// a function instead of a template you could just call it like "writeln = "blah".
Allowing that /by default/ does much more harm than good, proper property enforcement is necessary. Function calls go via '()'. Programmer can override when he knows better. UFCS doesn't change things. [1]
artur
[1] If you think the required '()' in UFCS chains look ugly, you're right, but the
right fix isn't to butcher the language. '()' carry important information. Having
a mode where function calls are made w/o the parens would be a good idea, but it
should be limited to an explicit scope. ie something like
"auto r = function {generator(x, y, z).map!(x => x * x)};", except 'function' keyword
can't be overloaded like that, it's too long, and ()-less calls isn't the only change
that could be done.
|
December 02, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 12/2/12, deadalnix <deadalnix@gmail.com> wrote: > BTW, I can't edit in the wiki? When I try to do so, it says me that deadalnix is an invalid username. If I need to register, I didn't found out how. It requires a silly CamelCase style username. You can try and edit the new wiki though: http://dwiki.kimsufi.thecybershadow.net/Main_Page |
December 02, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
On Sunday, December 02, 2012 12:36:53 Artur Skawina wrote:
> [1] If you think the required '()' in UFCS chains look ugly, you're right, but the right fix isn't to butcher the language.
I agree, but those who think that seem to be outnumbered by those who don't want to have to use the parens - particularly with functions which already require a template argument.
- Jonathan M Davis
|
December 02, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | There's more than just @property that operate like variables. Should we restrict this as well? struct stdio { void opAssign(T)( T a_arg ) { writeln( a_arg ); } } main() { stdio writeln; writeln = "hellow world"; } Conceptually, I don't see why we have to impose a difference between how variables are assigned and how functions are called. A variable "=" assignment is simply a special case of a function call that is written for you by the compiler. The example of opAssign shows that for some time now, there's been pressure to eliminate the difference in at least some cases, and allow the programmer to implement their own version of the assignment function call. If you want to remove inconsistencies, then the way functions and variables are manipulated should be unified. If someone can honestly demonstrate a non-subjective reason why there must be a difference between function call and variable assignments, please show it. So far I've only seen arguments that boil down to "I don't like it". --rt |
December 02, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | There's more than just @property that operate like variables. Should we restrict this as well? struct stdio { void opAssign(T)( T a_arg ) { writeln( a_arg ); } } main() { stdio writeln; writeln = "hellow world"; } Conceptually, I don't see why we have to impose a difference between how variables are assigned and how functions are called. A variable "=" assignment is simply a special case of a function call that is written for you by the compiler. The example of opAssign shows that for some time now, there's been pressure to eliminate the difference in at least some cases, and allow the programmer to implement their own version of the assignment function call. If you want to remove inconsistencies, then the way functions and variables are manipulated should be unified. If someone can honestly demonstrate a non-subjective reason why there must be a difference between function call and variable assignments, please show it. So far I've only seen arguments that boil down to "I don't like it". --rt |
December 02, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rob T | On Sun, 02 Dec 2012 18:47:26 -0000, Rob T <rob@ucora.com> wrote: > If someone can honestly demonstrate a non-subjective reason why there must be a difference between function call and variable assignments, please show it. So far I've only seen arguments that boil down to "I don't like it". A variable assignment is in 99% of cases a simple operation. A function call is in 99% of cases a more complex operation. Being able to immediately "see" those costs is useful. A language which allows you to make variable assignments costly will be inherently harder to understand in terms of cost, than a language which does not. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/ |
December 02, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rob T | On 12/02/12 19:48, Rob T wrote:
> There's more than just @property that operate like variables.
>
> Should we restrict this as well?
>
> struct stdio
> {
> void opAssign(T)( T a_arg )
> {
> writeln( a_arg );
> }
> }
>
> main()
> {
> stdio writeln;
> writeln = "hellow world";
> }
>
> Conceptually, I don't see why we have to impose a difference between how variables are assigned and how functions are called.
>
> A variable "=" assignment is simply a special case of a function call that is written for you by the compiler.
>
> The example of opAssign shows that for some time now, there's been pressure to eliminate the difference in at least some cases, and allow the programmer to implement their own version of the assignment function call.
>
> If you want to remove inconsistencies, then the way functions and variables are manipulated should be unified.
>
> If someone can honestly demonstrate a non-subjective reason why there must be a difference between function call and variable assignments, please show it. So far I've only seen arguments that boil down to "I don't like it".
Do you seriously think that there is no difference and would like to have to decypher code like
void main() {
import std.stdio, std.math;
writeln(sqrt=81);
}
?
Having assignments act as calls for every random function is insane.
It can be done and is ok where the programmers decides this makes sense.
Your above stdio example is not such a case. [1]
artur
[1] But thanks for sharing it, I would have probably never thought of
using a static opAssign otherwise...
struct stdout {
static void opAssign(T...)(T args) {
import std.stdio;
writeln(args);
}
}
void main() {
stdout = "It's a strange world";
}
|
December 03, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rob T Attachments:
| I had been trying to advance the phase to the next. Now, an experimental pull request is here. https://github.com/D-Programming-Language/dmd/pull/1311 ---- This change can distinguish almost usages between property and non-property syntax int func() { return 1; } void func(int n) { } @property int prop() { return 2; } @property void prop(int n) { } void main() { // Without -property switch, all lines can compile. // With -property switch: func(); // OK -> OK func(1); // OK -> OK func; // OK -> OK [*] func = 1; // OK -> NG (fixed!) prop(); // OK -> NG (fixed!) prop(1); // OK -> NG (fixed!) prop; // OK -> OK prop = 1; // OK -> OK } First exception is [*], keeping the line is necessary to allow UFCS chain without redundant parentheses (e.g. r.map!(a=>a*2).array). It is acceptable to me, at least. ---- I also implemented that calling function pointer which returned by property function. @property foo(){ return (int n) => n * 2; } auto n = foo(10); // `foo` is resolved to property function call in advance assert(n == 20); But, we cannot support it immediately, because it will *always* introduce breaking of existing code. - If enable always this feature, propfunc() is implicitly translated to (propfunc())(), then much existing correct code without "-property" switch will break. - If enable this only when -property switch is specified, a code propfunc() will have _two_ meanings. When propfunc returns a function pointer, * If -property is on, propfunc() is translated to propfunc()(), then call returned function pointer and returns its result. * If -property is off, propfunc() is jsut call property function, then returns function pointer. Changing compilation behavior by compile switch is bad. Then it is the second exception. ---- The third exception is in AddressExpression (&exp). In current, both &func and &propfunc return their function pointers. Some peoples argues that the latter should return an address of the returned value of propfunc after implementing more property enforcement, but I'm difficult to accept that. The root cause is: AddressExpression is just only one built-in feature for getting an exact type of property function (Note that typeof(propfunc) returns the type of propfunc result). If compiler will always translate the code &propfunc to &(propfunc()), we will lost a way to get an exact type of propfunc, and then std.traits.FunctionTypeOf will never work for propfunc. To resolve the issue, I have proposed a small enhancement for AddressExpression. http://d.puremagic.com/issues/show_bug.cgi?id=9062 It will distinguish &propfunc and &(propfunc), the former returns a function poiinter of propfunc, and the latter returns an address of propfunc result. The real example about that is here. https://github.com/D-Programming-Language/phobos/pull/968/files#L0L1136 ---- How about that? Kenji Hara |
December 03, 2012 Re: @property needed or not needed? | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 12/2/12 1:49 AM, deadalnix wrote:
> On Tuesday, 20 November 2012 at 04:12:54 UTC, Andrei Alexandrescu wrote:
>> On 11/19/12 5:23 PM, Rob T wrote:
>>> I don't have an answer, but there may be more to the picture than we
>>> think.
>>
>> I agree. In particular I find it a specious argument to insist on
>> religiously associating "()" with function calling and the lack
>> thereof with variable access. I don't see myself, when seeing an
>> expression like "generator(x, y, z).map!(x => x * x)()", going like
>> "holy cow, good I saw those trailing parens, otherwise I would've
>> sworn it was a variable". Trailing parens in UFCS chains are just
>> warts, this is the reality. Let's deal with it.
>>
>>
>> Andrei
>
> And what do you think about map!(x => x * x) = generator(x, y, z) ?
I think that ought to be disallowed.
Andrei
|
Copyright © 1999-2021 by the D Language Foundation