October 01, 2008
Yigal Chripun wrote:
> Andrei Alexandrescu wrote:
>> Yigal Chripun wrote:
>>> Andrei Alexandrescu wrote:
>>>> Yigal Chripun wrote:
>>>>> Benji Smith wrote:
>>>>>> Andrei Alexandrescu wrote:
>>>>>>> I stated two principles of language design. They could be true or
>>>>>>> false. They are up there for debate. They are subjective, because
>>>>>>> aside from some basics, language design is subjective.
>>>>>>>
>>>>>>> The principles are:
>>>>>>>
>>>>>>> 1) A language should minimize the number of syntactic constructs that
>>>>>>> are semantically and/or pragmatically meaningless.
>>>>>>>
>>>>>>> 2) The more frequently-used constructs should be given syntactic
>>>>>>> priority over the less-used constructs, particularly when the latter
>>>>>>> are also at risk of breaking the first principle.
>>>>>> I'd like to propose another principle of language design:
>>>>>>
>>>>>> 3) Consistency -- The expression of a semantic construct should always
>>>>>> use the same syntax. Likewise, multiple uses of the same syntactic
>>>>>> constructs should always result in the same semantics.
>>>>>>
>>>>>> Based on that principle, I'd argue that function-calling should either
>>>>>> always use parentheses, or it should never use parentheses.
>>>>>>
>>>>>> Requiring parentheses for some function calls, but not for others
>>>>>> violates the principle of consistency.
>>>>>>
>>>>>> In my prioritization of language-design principles, consistency is
>>>>>> more
>>>>>> important then syntactic economy.
>>>>>>
>>>>>> Based on those principles, I believe that the parentheses should be
>>>>>> mandatory for all function calls.
>>>>>>
>>>>>> --benji
>>>>> I was about to post a very similar post (it's still in my drafts
>>>>> folder)
>>>>> besides fully agreeing with the above, I'll add the following:
>>>>> operator & in D is not consistent.
>>>>>
>>>>> int x;
>>>>> auto y = &x; // y is int* (i.e pointer to int)
>>>>>
>>>>> int func(int);
>>>>> auto f = &func; // consistent with the above:
>>>>> // f's type is - int function(int); i.e function pointer.
>>>>>
>>>>> let's try a class:
>>>>> class Test {
>>>>>   int x;
>>>>>   int func(int);
>>>>> }
>>>>>
>>>>> auto test = new Test();
>>>>> auto y = &test.x; // consistent with the above
>>>>> auto g = &test.func; // this is inconsistent!
>>>>> in the above g is a delegate which is not a function pointer.
>>>>> just as int* is different from int[]. you wouldn't expect to get an
>>>>> int[] in the above, would you?
>>>>>
>>>>> a more consistent approach would be to have:
>>>>> - func and obj.method to be treated as delegates, of course for
>>>>> function
>>>>> pointers there should be an implicit cast to delegate.
>>>>> - &func and &obj.method would be strictly function pointers.
>>>>> - using parentheses is mandatory for function calls.
>>>> A delegate /is/ a function pointer, more precisely, a pointer to
>>>> function packed with a pointer to a value.
>>>>
>>>> This also seems to reveal a lack of understanding of how class methods
>>>> work. What function would you make &obj.method point to?
>>>>
>>>>
>>>> Andrei
>>> I understand a delegate as a struct of two pointers as you said so
>>> yourself, above. an int[] != int* and so does a delegate != [C like]
>>> function pointer.
>>>
>>> I'd make &obj.method to be the function pointer stored in the delegate.
>> What is the signature of that function?
>>
>> Andrei
>>
> 
> say we have:
> class Test {
>   int method(int);
> }
> 
> auto obj = new Test();
> auto fPtr = &obj.method;
> 
> type of fPtr would be: int function(int); or in C syntax: int (*)(int);

That doesn't stay glued. What is "this" inside the function?

> are you asking because of C++ pointer-to-member-function types?
> in C++: int (Test::*)(int); ?
> 
> You know C++ much better than most of us here (certainly better than
> me), in your experience, is that distinction useful?

C++ pointers to member functions aren't that well designed. But at least they work :o|.


Andrei
October 01, 2008
Andrei Alexandrescu wrote:
> Yigal Chripun wrote:
>> Andrei Alexandrescu wrote:
>>> Yigal Chripun wrote:
>>>> Andrei Alexandrescu wrote:
>>>>> Yigal Chripun wrote:
>>>>>> Benji Smith wrote:
>>>>>>> Andrei Alexandrescu wrote:
>>>>>>>> I stated two principles of language design. They could be true or false. They are up there for debate. They are subjective, because aside from some basics, language design is subjective.
>>>>>>>>
>>>>>>>> The principles are:
>>>>>>>>
>>>>>>>> 1) A language should minimize the number of syntactic constructs
>>>>>>>> that
>>>>>>>> are semantically and/or pragmatically meaningless.
>>>>>>>>
>>>>>>>> 2) The more frequently-used constructs should be given syntactic
>>>>>>>> priority over the less-used constructs, particularly when the
>>>>>>>> latter
>>>>>>>> are also at risk of breaking the first principle.
>>>>>>> I'd like to propose another principle of language design:
>>>>>>>
>>>>>>> 3) Consistency -- The expression of a semantic construct should
>>>>>>> always
>>>>>>> use the same syntax. Likewise, multiple uses of the same syntactic
>>>>>>> constructs should always result in the same semantics.
>>>>>>>
>>>>>>> Based on that principle, I'd argue that function-calling should
>>>>>>> either
>>>>>>> always use parentheses, or it should never use parentheses.
>>>>>>>
>>>>>>> Requiring parentheses for some function calls, but not for others violates the principle of consistency.
>>>>>>>
>>>>>>> In my prioritization of language-design principles, consistency is
>>>>>>> more
>>>>>>> important then syntactic economy.
>>>>>>>
>>>>>>> Based on those principles, I believe that the parentheses should be mandatory for all function calls.
>>>>>>>
>>>>>>> --benji
>>>>>> I was about to post a very similar post (it's still in my drafts
>>>>>> folder)
>>>>>> besides fully agreeing with the above, I'll add the following:
>>>>>> operator & in D is not consistent.
>>>>>>
>>>>>> int x;
>>>>>> auto y = &x; // y is int* (i.e pointer to int)
>>>>>>
>>>>>> int func(int);
>>>>>> auto f = &func; // consistent with the above:
>>>>>> // f's type is - int function(int); i.e function pointer.
>>>>>>
>>>>>> let's try a class:
>>>>>> class Test {
>>>>>>   int x;
>>>>>>   int func(int);
>>>>>> }
>>>>>>
>>>>>> auto test = new Test();
>>>>>> auto y = &test.x; // consistent with the above
>>>>>> auto g = &test.func; // this is inconsistent!
>>>>>> in the above g is a delegate which is not a function pointer.
>>>>>> just as int* is different from int[]. you wouldn't expect to get an
>>>>>> int[] in the above, would you?
>>>>>>
>>>>>> a more consistent approach would be to have:
>>>>>> - func and obj.method to be treated as delegates, of course for
>>>>>> function
>>>>>> pointers there should be an implicit cast to delegate.
>>>>>> - &func and &obj.method would be strictly function pointers.
>>>>>> - using parentheses is mandatory for function calls.
>>>>> A delegate /is/ a function pointer, more precisely, a pointer to function packed with a pointer to a value.
>>>>>
>>>>> This also seems to reveal a lack of understanding of how class methods work. What function would you make &obj.method point to?
>>>>>
>>>>>
>>>>> Andrei
>>>> I understand a delegate as a struct of two pointers as you said so yourself, above. an int[] != int* and so does a delegate != [C like] function pointer.
>>>>
>>>> I'd make &obj.method to be the function pointer stored in the delegate.
>>> What is the signature of that function?
>>>
>>> Andrei
>>>
>>
>> say we have:
>> class Test {
>>   int method(int);
>> }
>>
>> auto obj = new Test();
>> auto fPtr = &obj.method;
>>
>> type of fPtr would be: int function(int); or in C syntax: int (*)(int);
> 
> That doesn't stay glued. What is "this" inside the function?
> 
>> are you asking because of C++ pointer-to-member-function types?
>> in C++: int (Test::*)(int); ?
>>
>> You know C++ much better than most of us here (certainly better than me), in your experience, is that distinction useful?
> 
> C++ pointers to member functions aren't that well designed. But at least they work :o|.
> 
> 
> Andrei

if I understand it correctly, in C++ the type of this is encoded in the
signature (as above) and you use obj.*pointer(..); to call the function.
this is a possible solution (using the C++ pointer to member function).
however, maybe we should use a more python like solution:
the signature becomes: int function(Test, int);
and this refers to the first argument (just like you pass the "self" in
Python).

I think i prefer the second option more [ int function(Test, int) ] and
it will be easier to use in C.
-- Yigal
October 01, 2008
Yigal Chripun wrote:
> Andrei Alexandrescu wrote:
>> Yigal Chripun wrote:
>>> Andrei Alexandrescu wrote:
>>>> Yigal Chripun wrote:
>>>>> Andrei Alexandrescu wrote:
>>>>>> Yigal Chripun wrote:
>>>>>>> Benji Smith wrote:
>>>>>>>> Andrei Alexandrescu wrote:
>>>>>>>>> I stated two principles of language design. They could be true or
>>>>>>>>> false. They are up there for debate. They are subjective, because
>>>>>>>>> aside from some basics, language design is subjective.
>>>>>>>>>
>>>>>>>>> The principles are:
>>>>>>>>>
>>>>>>>>> 1) A language should minimize the number of syntactic constructs
>>>>>>>>> that
>>>>>>>>> are semantically and/or pragmatically meaningless.
>>>>>>>>>
>>>>>>>>> 2) The more frequently-used constructs should be given syntactic
>>>>>>>>> priority over the less-used constructs, particularly when the
>>>>>>>>> latter
>>>>>>>>> are also at risk of breaking the first principle.
>>>>>>>> I'd like to propose another principle of language design:
>>>>>>>>
>>>>>>>> 3) Consistency -- The expression of a semantic construct should
>>>>>>>> always
>>>>>>>> use the same syntax. Likewise, multiple uses of the same syntactic
>>>>>>>> constructs should always result in the same semantics.
>>>>>>>>
>>>>>>>> Based on that principle, I'd argue that function-calling should
>>>>>>>> either
>>>>>>>> always use parentheses, or it should never use parentheses.
>>>>>>>>
>>>>>>>> Requiring parentheses for some function calls, but not for others
>>>>>>>> violates the principle of consistency.
>>>>>>>>
>>>>>>>> In my prioritization of language-design principles, consistency is
>>>>>>>> more
>>>>>>>> important then syntactic economy.
>>>>>>>>
>>>>>>>> Based on those principles, I believe that the parentheses should be
>>>>>>>> mandatory for all function calls.
>>>>>>>>
>>>>>>>> --benji
>>>>>>> I was about to post a very similar post (it's still in my drafts
>>>>>>> folder)
>>>>>>> besides fully agreeing with the above, I'll add the following:
>>>>>>> operator & in D is not consistent.
>>>>>>>
>>>>>>> int x;
>>>>>>> auto y = &x; // y is int* (i.e pointer to int)
>>>>>>>
>>>>>>> int func(int);
>>>>>>> auto f = &func; // consistent with the above:
>>>>>>> // f's type is - int function(int); i.e function pointer.
>>>>>>>
>>>>>>> let's try a class:
>>>>>>> class Test {
>>>>>>>   int x;
>>>>>>>   int func(int);
>>>>>>> }
>>>>>>>
>>>>>>> auto test = new Test();
>>>>>>> auto y = &test.x; // consistent with the above
>>>>>>> auto g = &test.func; // this is inconsistent!
>>>>>>> in the above g is a delegate which is not a function pointer.
>>>>>>> just as int* is different from int[]. you wouldn't expect to get an
>>>>>>> int[] in the above, would you?
>>>>>>>
>>>>>>> a more consistent approach would be to have:
>>>>>>> - func and obj.method to be treated as delegates, of course for
>>>>>>> function
>>>>>>> pointers there should be an implicit cast to delegate.
>>>>>>> - &func and &obj.method would be strictly function pointers.
>>>>>>> - using parentheses is mandatory for function calls.
>>>>>> A delegate /is/ a function pointer, more precisely, a pointer to
>>>>>> function packed with a pointer to a value.
>>>>>>
>>>>>> This also seems to reveal a lack of understanding of how class methods
>>>>>> work. What function would you make &obj.method point to?
>>>>>>
>>>>>>
>>>>>> Andrei
>>>>> I understand a delegate as a struct of two pointers as you said so
>>>>> yourself, above. an int[] != int* and so does a delegate != [C like]
>>>>> function pointer.
>>>>>
>>>>> I'd make &obj.method to be the function pointer stored in the delegate.
>>>> What is the signature of that function?
>>>>
>>>> Andrei
>>>>
>>> say we have:
>>> class Test {
>>>   int method(int);
>>> }
>>>
>>> auto obj = new Test();
>>> auto fPtr = &obj.method;
>>>
>>> type of fPtr would be: int function(int); or in C syntax: int (*)(int);
>> That doesn't stay glued. What is "this" inside the function?
>>
>>> are you asking because of C++ pointer-to-member-function types?
>>> in C++: int (Test::*)(int); ?
>>>
>>> You know C++ much better than most of us here (certainly better than
>>> me), in your experience, is that distinction useful?
>> C++ pointers to member functions aren't that well designed. But at least
>> they work :o|.
>>
>>
>> Andrei
> 
> if I understand it correctly, in C++ the type of this is encoded in the
> signature (as above) and you use obj.*pointer(..); to call the function.
> this is a possible solution (using the C++ pointer to member function).
> however, maybe we should use a more python like solution:
> the signature becomes: int function(Test, int);
> and this refers to the first argument (just like you pass the "self" in
> Python).
> 
> I think i prefer the second option more [ int function(Test, int) ] and
> it will be easier to use in C.

It's great that you are now equipped to appreciate the advantages and disadvantages of various tradeoffs. Maybe a reevaluation of the existing solution would be useful.

Andrei
October 01, 2008
Andrei Alexandrescu wrote:
> Yigal Chripun wrote:
>> Andrei Alexandrescu wrote:
>>> Yigal Chripun wrote:
>>>> Andrei Alexandrescu wrote:
>>>>> Yigal Chripun wrote:
>>>>>> Andrei Alexandrescu wrote:
>>>>>>> Yigal Chripun wrote:
>>>>>>>> Benji Smith wrote:
>>>>>>>>> Andrei Alexandrescu wrote:
>>>>>>>>>> I stated two principles of language design. They could be true or false. They are up there for debate. They are subjective, because aside from some basics, language design is subjective.
>>>>>>>>>>
>>>>>>>>>> The principles are:
>>>>>>>>>>
>>>>>>>>>> 1) A language should minimize the number of syntactic constructs
>>>>>>>>>> that
>>>>>>>>>> are semantically and/or pragmatically meaningless.
>>>>>>>>>>
>>>>>>>>>> 2) The more frequently-used constructs should be given syntactic
>>>>>>>>>> priority over the less-used constructs, particularly when the
>>>>>>>>>> latter
>>>>>>>>>> are also at risk of breaking the first principle.
>>>>>>>>> I'd like to propose another principle of language design:
>>>>>>>>>
>>>>>>>>> 3) Consistency -- The expression of a semantic construct should
>>>>>>>>> always
>>>>>>>>> use the same syntax. Likewise, multiple uses of the same syntactic
>>>>>>>>> constructs should always result in the same semantics.
>>>>>>>>>
>>>>>>>>> Based on that principle, I'd argue that function-calling should
>>>>>>>>> either
>>>>>>>>> always use parentheses, or it should never use parentheses.
>>>>>>>>>
>>>>>>>>> Requiring parentheses for some function calls, but not for others violates the principle of consistency.
>>>>>>>>>
>>>>>>>>> In my prioritization of language-design principles, consistency is
>>>>>>>>> more
>>>>>>>>> important then syntactic economy.
>>>>>>>>>
>>>>>>>>> Based on those principles, I believe that the parentheses
>>>>>>>>> should be
>>>>>>>>> mandatory for all function calls.
>>>>>>>>>
>>>>>>>>> --benji
>>>>>>>> I was about to post a very similar post (it's still in my drafts
>>>>>>>> folder)
>>>>>>>> besides fully agreeing with the above, I'll add the following:
>>>>>>>> operator & in D is not consistent.
>>>>>>>>
>>>>>>>> int x;
>>>>>>>> auto y = &x; // y is int* (i.e pointer to int)
>>>>>>>>
>>>>>>>> int func(int);
>>>>>>>> auto f = &func; // consistent with the above:
>>>>>>>> // f's type is - int function(int); i.e function pointer.
>>>>>>>>
>>>>>>>> let's try a class:
>>>>>>>> class Test {
>>>>>>>>   int x;
>>>>>>>>   int func(int);
>>>>>>>> }
>>>>>>>>
>>>>>>>> auto test = new Test();
>>>>>>>> auto y = &test.x; // consistent with the above
>>>>>>>> auto g = &test.func; // this is inconsistent!
>>>>>>>> in the above g is a delegate which is not a function pointer.
>>>>>>>> just as int* is different from int[]. you wouldn't expect to get an
>>>>>>>> int[] in the above, would you?
>>>>>>>>
>>>>>>>> a more consistent approach would be to have:
>>>>>>>> - func and obj.method to be treated as delegates, of course for
>>>>>>>> function
>>>>>>>> pointers there should be an implicit cast to delegate.
>>>>>>>> - &func and &obj.method would be strictly function pointers.
>>>>>>>> - using parentheses is mandatory for function calls.
>>>>>>> A delegate /is/ a function pointer, more precisely, a pointer to function packed with a pointer to a value.
>>>>>>>
>>>>>>> This also seems to reveal a lack of understanding of how class
>>>>>>> methods
>>>>>>> work. What function would you make &obj.method point to?
>>>>>>>
>>>>>>>
>>>>>>> Andrei
>>>>>> I understand a delegate as a struct of two pointers as you said so yourself, above. an int[] != int* and so does a delegate != [C like] function pointer.
>>>>>>
>>>>>> I'd make &obj.method to be the function pointer stored in the delegate.
>>>>> What is the signature of that function?
>>>>>
>>>>> Andrei
>>>>>
>>>> say we have:
>>>> class Test {
>>>>   int method(int);
>>>> }
>>>>
>>>> auto obj = new Test();
>>>> auto fPtr = &obj.method;
>>>>
>>>> type of fPtr would be: int function(int); or in C syntax: int (*)(int);
>>> That doesn't stay glued. What is "this" inside the function?
>>>
>>>> are you asking because of C++ pointer-to-member-function types?
>>>> in C++: int (Test::*)(int); ?
>>>>
>>>> You know C++ much better than most of us here (certainly better than me), in your experience, is that distinction useful?
>>> C++ pointers to member functions aren't that well designed. But at least they work :o|.
>>>
>>>
>>> Andrei
>>
>> if I understand it correctly, in C++ the type of this is encoded in the
>> signature (as above) and you use obj.*pointer(..); to call the function.
>> this is a possible solution (using the C++ pointer to member function).
>> however, maybe we should use a more python like solution:
>> the signature becomes: int function(Test, int);
>> and this refers to the first argument (just like you pass the "self" in
>> Python).
>>
>> I think i prefer the second option more [ int function(Test, int) ] and it will be easier to use in C.
> 
> It's great that you are now equipped to appreciate the advantages and disadvantages of various tradeoffs. Maybe a reevaluation of the existing solution would be useful.
> 
> Andrei

my main issue was with the syntax. and I still think it's inconsistent. the only drawback I see with my suggestion is the need to implement this additional feature with method pointers.

it adds consistency for the common case (delegates) without limiting any
of the current uses.

What other cons do you see for my suggestion besides the difficulty to implement?
October 01, 2008
Yigal Chripun wrote:
> Andrei Alexandrescu wrote:
>> Yigal Chripun wrote:
>>> Andrei Alexandrescu wrote:
>>>> Yigal Chripun wrote:
>>>>> Andrei Alexandrescu wrote:
>>>>>> Yigal Chripun wrote:
>>>>>>> Andrei Alexandrescu wrote:
>>>>>>>> Yigal Chripun wrote:
>>>>>>>>> Benji Smith wrote:
>>>>>>>>>> Andrei Alexandrescu wrote:
>>>>>>>>>>> I stated two principles of language design. They could be true or
>>>>>>>>>>> false. They are up there for debate. They are subjective, because
>>>>>>>>>>> aside from some basics, language design is subjective.
>>>>>>>>>>>
>>>>>>>>>>> The principles are:
>>>>>>>>>>>
>>>>>>>>>>> 1) A language should minimize the number of syntactic constructs
>>>>>>>>>>> that
>>>>>>>>>>> are semantically and/or pragmatically meaningless.
>>>>>>>>>>>
>>>>>>>>>>> 2) The more frequently-used constructs should be given syntactic
>>>>>>>>>>> priority over the less-used constructs, particularly when the
>>>>>>>>>>> latter
>>>>>>>>>>> are also at risk of breaking the first principle.
>>>>>>>>>> I'd like to propose another principle of language design:
>>>>>>>>>>
>>>>>>>>>> 3) Consistency -- The expression of a semantic construct should
>>>>>>>>>> always
>>>>>>>>>> use the same syntax. Likewise, multiple uses of the same syntactic
>>>>>>>>>> constructs should always result in the same semantics.
>>>>>>>>>>
>>>>>>>>>> Based on that principle, I'd argue that function-calling should
>>>>>>>>>> either
>>>>>>>>>> always use parentheses, or it should never use parentheses.
>>>>>>>>>>
>>>>>>>>>> Requiring parentheses for some function calls, but not for others
>>>>>>>>>> violates the principle of consistency.
>>>>>>>>>>
>>>>>>>>>> In my prioritization of language-design principles, consistency is
>>>>>>>>>> more
>>>>>>>>>> important then syntactic economy.
>>>>>>>>>>
>>>>>>>>>> Based on those principles, I believe that the parentheses
>>>>>>>>>> should be
>>>>>>>>>> mandatory for all function calls.
>>>>>>>>>>
>>>>>>>>>> --benji
>>>>>>>>> I was about to post a very similar post (it's still in my drafts
>>>>>>>>> folder)
>>>>>>>>> besides fully agreeing with the above, I'll add the following:
>>>>>>>>> operator & in D is not consistent.
>>>>>>>>>
>>>>>>>>> int x;
>>>>>>>>> auto y = &x; // y is int* (i.e pointer to int)
>>>>>>>>>
>>>>>>>>> int func(int);
>>>>>>>>> auto f = &func; // consistent with the above:
>>>>>>>>> // f's type is - int function(int); i.e function pointer.
>>>>>>>>>
>>>>>>>>> let's try a class:
>>>>>>>>> class Test {
>>>>>>>>>   int x;
>>>>>>>>>   int func(int);
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> auto test = new Test();
>>>>>>>>> auto y = &test.x; // consistent with the above
>>>>>>>>> auto g = &test.func; // this is inconsistent!
>>>>>>>>> in the above g is a delegate which is not a function pointer.
>>>>>>>>> just as int* is different from int[]. you wouldn't expect to get an
>>>>>>>>> int[] in the above, would you?
>>>>>>>>>
>>>>>>>>> a more consistent approach would be to have:
>>>>>>>>> - func and obj.method to be treated as delegates, of course for
>>>>>>>>> function
>>>>>>>>> pointers there should be an implicit cast to delegate.
>>>>>>>>> - &func and &obj.method would be strictly function pointers.
>>>>>>>>> - using parentheses is mandatory for function calls.
>>>>>>>> A delegate /is/ a function pointer, more precisely, a pointer to
>>>>>>>> function packed with a pointer to a value.
>>>>>>>>
>>>>>>>> This also seems to reveal a lack of understanding of how class
>>>>>>>> methods
>>>>>>>> work. What function would you make &obj.method point to?
>>>>>>>>
>>>>>>>>
>>>>>>>> Andrei
>>>>>>> I understand a delegate as a struct of two pointers as you said so
>>>>>>> yourself, above. an int[] != int* and so does a delegate != [C like]
>>>>>>> function pointer.
>>>>>>>
>>>>>>> I'd make &obj.method to be the function pointer stored in the
>>>>>>> delegate.
>>>>>> What is the signature of that function?
>>>>>>
>>>>>> Andrei
>>>>>>
>>>>> say we have:
>>>>> class Test {
>>>>>   int method(int);
>>>>> }
>>>>>
>>>>> auto obj = new Test();
>>>>> auto fPtr = &obj.method;
>>>>>
>>>>> type of fPtr would be: int function(int); or in C syntax: int (*)(int);
>>>> That doesn't stay glued. What is "this" inside the function?
>>>>
>>>>> are you asking because of C++ pointer-to-member-function types?
>>>>> in C++: int (Test::*)(int); ?
>>>>>
>>>>> You know C++ much better than most of us here (certainly better than
>>>>> me), in your experience, is that distinction useful?
>>>> C++ pointers to member functions aren't that well designed. But at least
>>>> they work :o|.
>>>>
>>>>
>>>> Andrei
>>> if I understand it correctly, in C++ the type of this is encoded in the
>>> signature (as above) and you use obj.*pointer(..); to call the function.
>>> this is a possible solution (using the C++ pointer to member function).
>>> however, maybe we should use a more python like solution:
>>> the signature becomes: int function(Test, int);
>>> and this refers to the first argument (just like you pass the "self" in
>>> Python).
>>>
>>> I think i prefer the second option more [ int function(Test, int) ] and
>>> it will be easier to use in C.
>> It's great that you are now equipped to appreciate the advantages and
>> disadvantages of various tradeoffs. Maybe a reevaluation of the existing
>> solution would be useful.
>>
>> Andrei
> 
> my main issue was with the syntax. and I still think it's inconsistent.
>
> the only drawback I see with my suggestion is the need to implement this
> additional feature with method pointers.
> 
> it adds consistency for the common case (delegates) without limiting any
> of the current uses.
> 
> What other cons do you see for my suggestion besides the difficulty to
> implement?

I think we're better off with the current state of affairs.

Andrei
October 01, 2008
Andrei Alexandrescu wrote:
> Yigal Chripun wrote:
>> Andrei Alexandrescu wrote:
>>> Yigal Chripun wrote:
>>>> Andrei Alexandrescu wrote:
>>>>> Yigal Chripun wrote:
>>>>>> Andrei Alexandrescu wrote:
>>>>>>> Yigal Chripun wrote:
>>>>>>>> Andrei Alexandrescu wrote:
>>>>>>>>> Yigal Chripun wrote:
>>>>>>>>>> Benji Smith wrote:
>>>>>>>>>>> Andrei Alexandrescu wrote:
>>>>>>>>>>>> I stated two principles of language design. They could be
>>>>>>>>>>>> true or
>>>>>>>>>>>> false. They are up there for debate. They are subjective,
>>>>>>>>>>>> because
>>>>>>>>>>>> aside from some basics, language design is subjective.
>>>>>>>>>>>>
>>>>>>>>>>>> The principles are:
>>>>>>>>>>>>
>>>>>>>>>>>> 1) A language should minimize the number of syntactic
>>>>>>>>>>>> constructs
>>>>>>>>>>>> that
>>>>>>>>>>>> are semantically and/or pragmatically meaningless.
>>>>>>>>>>>>
>>>>>>>>>>>> 2) The more frequently-used constructs should be given
>>>>>>>>>>>> syntactic
>>>>>>>>>>>> priority over the less-used constructs, particularly when the
>>>>>>>>>>>> latter
>>>>>>>>>>>> are also at risk of breaking the first principle.
>>>>>>>>>>> I'd like to propose another principle of language design:
>>>>>>>>>>>
>>>>>>>>>>> 3) Consistency -- The expression of a semantic construct should
>>>>>>>>>>> always
>>>>>>>>>>> use the same syntax. Likewise, multiple uses of the same
>>>>>>>>>>> syntactic
>>>>>>>>>>> constructs should always result in the same semantics.
>>>>>>>>>>>
>>>>>>>>>>> Based on that principle, I'd argue that function-calling should
>>>>>>>>>>> either
>>>>>>>>>>> always use parentheses, or it should never use parentheses.
>>>>>>>>>>>
>>>>>>>>>>> Requiring parentheses for some function calls, but not for
>>>>>>>>>>> others
>>>>>>>>>>> violates the principle of consistency.
>>>>>>>>>>>
>>>>>>>>>>> In my prioritization of language-design principles,
>>>>>>>>>>> consistency is
>>>>>>>>>>> more
>>>>>>>>>>> important then syntactic economy.
>>>>>>>>>>>
>>>>>>>>>>> Based on those principles, I believe that the parentheses
>>>>>>>>>>> should be
>>>>>>>>>>> mandatory for all function calls.
>>>>>>>>>>>
>>>>>>>>>>> --benji
>>>>>>>>>> I was about to post a very similar post (it's still in my drafts
>>>>>>>>>> folder)
>>>>>>>>>> besides fully agreeing with the above, I'll add the following:
>>>>>>>>>> operator & in D is not consistent.
>>>>>>>>>>
>>>>>>>>>> int x;
>>>>>>>>>> auto y = &x; // y is int* (i.e pointer to int)
>>>>>>>>>>
>>>>>>>>>> int func(int);
>>>>>>>>>> auto f = &func; // consistent with the above:
>>>>>>>>>> // f's type is - int function(int); i.e function pointer.
>>>>>>>>>>
>>>>>>>>>> let's try a class:
>>>>>>>>>> class Test {
>>>>>>>>>>   int x;
>>>>>>>>>>   int func(int);
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> auto test = new Test();
>>>>>>>>>> auto y = &test.x; // consistent with the above
>>>>>>>>>> auto g = &test.func; // this is inconsistent!
>>>>>>>>>> in the above g is a delegate which is not a function pointer.
>>>>>>>>>> just as int* is different from int[]. you wouldn't expect to
>>>>>>>>>> get an
>>>>>>>>>> int[] in the above, would you?
>>>>>>>>>>
>>>>>>>>>> a more consistent approach would be to have:
>>>>>>>>>> - func and obj.method to be treated as delegates, of course for
>>>>>>>>>> function
>>>>>>>>>> pointers there should be an implicit cast to delegate.
>>>>>>>>>> - &func and &obj.method would be strictly function pointers.
>>>>>>>>>> - using parentheses is mandatory for function calls.
>>>>>>>>> A delegate /is/ a function pointer, more precisely, a pointer to function packed with a pointer to a value.
>>>>>>>>>
>>>>>>>>> This also seems to reveal a lack of understanding of how class
>>>>>>>>> methods
>>>>>>>>> work. What function would you make &obj.method point to?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Andrei
>>>>>>>> I understand a delegate as a struct of two pointers as you said so
>>>>>>>> yourself, above. an int[] != int* and so does a delegate != [C
>>>>>>>> like]
>>>>>>>> function pointer.
>>>>>>>>
>>>>>>>> I'd make &obj.method to be the function pointer stored in the delegate.
>>>>>>> What is the signature of that function?
>>>>>>>
>>>>>>> Andrei
>>>>>>>
>>>>>> say we have:
>>>>>> class Test {
>>>>>>   int method(int);
>>>>>> }
>>>>>>
>>>>>> auto obj = new Test();
>>>>>> auto fPtr = &obj.method;
>>>>>>
>>>>>> type of fPtr would be: int function(int); or in C syntax: int
>>>>>> (*)(int);
>>>>> That doesn't stay glued. What is "this" inside the function?
>>>>>
>>>>>> are you asking because of C++ pointer-to-member-function types?
>>>>>> in C++: int (Test::*)(int); ?
>>>>>>
>>>>>> You know C++ much better than most of us here (certainly better than me), in your experience, is that distinction useful?
>>>>> C++ pointers to member functions aren't that well designed. But at
>>>>> least
>>>>> they work :o|.
>>>>>
>>>>>
>>>>> Andrei
>>>> if I understand it correctly, in C++ the type of this is encoded in the
>>>> signature (as above) and you use obj.*pointer(..); to call the
>>>> function.
>>>> this is a possible solution (using the C++ pointer to member function).
>>>> however, maybe we should use a more python like solution:
>>>> the signature becomes: int function(Test, int);
>>>> and this refers to the first argument (just like you pass the "self" in
>>>> Python).
>>>>
>>>> I think i prefer the second option more [ int function(Test, int) ] and it will be easier to use in C.
>>> It's great that you are now equipped to appreciate the advantages and disadvantages of various tradeoffs. Maybe a reevaluation of the existing solution would be useful.
>>>
>>> Andrei
>>
>> my main issue was with the syntax. and I still think it's inconsistent.
>>
>> the only drawback I see with my suggestion is the need to implement this additional feature with method pointers.
>>
>> it adds consistency for the common case (delegates) without limiting any
>> of the current uses.
>>
>> What other cons do you see for my suggestion besides the difficulty to implement?
> 
> I think we're better off with the current state of affairs.
> 
> Andrei

so if I understand you correctly, you don't see any other disadvantages. so it all comes to whether it's worth the time to implement this, on which we appear to disagree.

since I'm unable to convince you that [from my POV as a user] it's worth it, I won't write more about it.

Thank you for your time discussing this issue.
Yigal
October 01, 2008
On Wed, Oct 1, 2008 at 10:58 PM, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> "KennyTM~" wrote
>> You cannot return a double& when calling .minutes because it simply does not exist. Therefore, the interpreter have to clever enough to convert
>>
>>   t.minutes += 2;
>>
>> into
>>
>>   t.minutes = t.minutes + 2;
>>
>> i.e.
>>
>>   t.minutes(t.minutes() + 2);
>>
>> if .minutes does not return a reference. A similar problem also exist with .opIndexAssign and .opSliceAssign.
>
> Yes yes!
>
> vote++
>
> -Steve

Me too++


--bb
October 01, 2008
Yigal Chripun Wrote:

> Andrei Alexandrescu wrote:
> > Yigal Chripun wrote:
> >> Andrei Alexandrescu wrote:
> >>> Yigal Chripun wrote:
> >>>> Andrei Alexandrescu wrote:
> >>>>> Yigal Chripun wrote:
> >>>>>> Andrei Alexandrescu wrote:
> >>>>>>> Yigal Chripun wrote:
> >>>>>>>> Andrei Alexandrescu wrote:
> >>>>>>>>> Yigal Chripun wrote:
> >>>>>>>>>> Benji Smith wrote:
> >>>>>>>>>>> Andrei Alexandrescu wrote:
> >>>>>>>>>>>> I stated two principles of language design. They could be
> >>>>>>>>>>>> true or
> >>>>>>>>>>>> false. They are up there for debate. They are subjective,
> >>>>>>>>>>>> because
> >>>>>>>>>>>> aside from some basics, language design is subjective.
> >>>>>>>>>>>>
> >>>>>>>>>>>> The principles are:
> >>>>>>>>>>>>
> >>>>>>>>>>>> 1) A language should minimize the number of syntactic
> >>>>>>>>>>>> constructs
> >>>>>>>>>>>> that
> >>>>>>>>>>>> are semantically and/or pragmatically meaningless.
> >>>>>>>>>>>>
> >>>>>>>>>>>> 2) The more frequently-used constructs should be given
> >>>>>>>>>>>> syntactic
> >>>>>>>>>>>> priority over the less-used constructs, particularly when the
> >>>>>>>>>>>> latter
> >>>>>>>>>>>> are also at risk of breaking the first principle.
> >>>>>>>>>>> I'd like to propose another principle of language design:
> >>>>>>>>>>>
> >>>>>>>>>>> 3) Consistency -- The expression of a semantic construct should
> >>>>>>>>>>> always
> >>>>>>>>>>> use the same syntax. Likewise, multiple uses of the same
> >>>>>>>>>>> syntactic
> >>>>>>>>>>> constructs should always result in the same semantics.
> >>>>>>>>>>>
> >>>>>>>>>>> Based on that principle, I'd argue that function-calling should
> >>>>>>>>>>> either
> >>>>>>>>>>> always use parentheses, or it should never use parentheses.
> >>>>>>>>>>>
> >>>>>>>>>>> Requiring parentheses for some function calls, but not for
> >>>>>>>>>>> others
> >>>>>>>>>>> violates the principle of consistency.
> >>>>>>>>>>>
> >>>>>>>>>>> In my prioritization of language-design principles,
> >>>>>>>>>>> consistency is
> >>>>>>>>>>> more
> >>>>>>>>>>> important then syntactic economy.
> >>>>>>>>>>>
> >>>>>>>>>>> Based on those principles, I believe that the parentheses
> >>>>>>>>>>> should be
> >>>>>>>>>>> mandatory for all function calls.
> >>>>>>>>>>>
> >>>>>>>>>>> --benji
> >>>>>>>>>> I was about to post a very similar post (it's still in my drafts
> >>>>>>>>>> folder)
> >>>>>>>>>> besides fully agreeing with the above, I'll add the following:
> >>>>>>>>>> operator & in D is not consistent.
> >>>>>>>>>>
> >>>>>>>>>> int x;
> >>>>>>>>>> auto y = &x; // y is int* (i.e pointer to int)
> >>>>>>>>>>
> >>>>>>>>>> int func(int);
> >>>>>>>>>> auto f = &func; // consistent with the above:
> >>>>>>>>>> // f's type is - int function(int); i.e function pointer.
> >>>>>>>>>>
> >>>>>>>>>> let's try a class:
> >>>>>>>>>> class Test {
> >>>>>>>>>>   int x;
> >>>>>>>>>>   int func(int);
> >>>>>>>>>> }
> >>>>>>>>>>
> >>>>>>>>>> auto test = new Test();
> >>>>>>>>>> auto y = &test.x; // consistent with the above
> >>>>>>>>>> auto g = &test.func; // this is inconsistent!
> >>>>>>>>>> in the above g is a delegate which is not a function pointer.
> >>>>>>>>>> just as int* is different from int[]. you wouldn't expect to
> >>>>>>>>>> get an
> >>>>>>>>>> int[] in the above, would you?
> >>>>>>>>>>
> >>>>>>>>>> a more consistent approach would be to have:
> >>>>>>>>>> - func and obj.method to be treated as delegates, of course for
> >>>>>>>>>> function
> >>>>>>>>>> pointers there should be an implicit cast to delegate.
> >>>>>>>>>> - &func and &obj.method would be strictly function pointers.
> >>>>>>>>>> - using parentheses is mandatory for function calls.
> >>>>>>>>> A delegate /is/ a function pointer, more precisely, a pointer to function packed with a pointer to a value.
> >>>>>>>>>
> >>>>>>>>> This also seems to reveal a lack of understanding of how class
> >>>>>>>>> methods
> >>>>>>>>> work. What function would you make &obj.method point to?
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Andrei
> >>>>>>>> I understand a delegate as a struct of two pointers as you said so
> >>>>>>>> yourself, above. an int[] != int* and so does a delegate != [C
> >>>>>>>> like]
> >>>>>>>> function pointer.
> >>>>>>>>
> >>>>>>>> I'd make &obj.method to be the function pointer stored in the delegate.
> >>>>>>> What is the signature of that function?
> >>>>>>>
> >>>>>>> Andrei
> >>>>>>>
> >>>>>> say we have:
> >>>>>> class Test {
> >>>>>>   int method(int);
> >>>>>> }
> >>>>>>
> >>>>>> auto obj = new Test();
> >>>>>> auto fPtr = &obj.method;
> >>>>>>
> >>>>>> type of fPtr would be: int function(int); or in C syntax: int
> >>>>>> (*)(int);
> >>>>> That doesn't stay glued. What is "this" inside the function?
> >>>>>
> >>>>>> are you asking because of C++ pointer-to-member-function types?
> >>>>>> in C++: int (Test::*)(int); ?
> >>>>>>
> >>>>>> You know C++ much better than most of us here (certainly better than me), in your experience, is that distinction useful?
> >>>>> C++ pointers to member functions aren't that well designed. But at
> >>>>> least
> >>>>> they work :o|.
> >>>>>
> >>>>>
> >>>>> Andrei
> >>>> if I understand it correctly, in C++ the type of this is encoded in the
> >>>> signature (as above) and you use obj.*pointer(..); to call the
> >>>> function.
> >>>> this is a possible solution (using the C++ pointer to member function).
> >>>> however, maybe we should use a more python like solution:
> >>>> the signature becomes: int function(Test, int);
> >>>> and this refers to the first argument (just like you pass the "self" in
> >>>> Python).
> >>>>
> >>>> I think i prefer the second option more [ int function(Test, int) ] and it will be easier to use in C.
> >>> It's great that you are now equipped to appreciate the advantages and disadvantages of various tradeoffs. Maybe a reevaluation of the existing solution would be useful.
> >>>
> >>> Andrei
> >>
> >> my main issue was with the syntax. and I still think it's inconsistent.
> >>
> >> the only drawback I see with my suggestion is the need to implement this additional feature with method pointers.
> >>
> >> it adds consistency for the common case (delegates) without limiting any
> >> of the current uses.
> >>
> >> What other cons do you see for my suggestion besides the difficulty to implement?
> > 
> > I think we're better off with the current state of affairs.
> > 
> > Andrei
> 
> so if I understand you correctly, you don't see any other disadvantages. so it all comes to whether it's worth the time to implement this, on which we appear to disagree.
> 
> since I'm unable to convince you that [from my POV as a user] it's worth it, I won't write more about it.
> 
> Thank you for your time discussing this issue.
> Yigal

way i read it he was tryin' to save you face, but of course you missed that too. just continued making a fool of urself. nothing personal dood. but really u r in a mismatch here. first u make a "proposal" that makes no sense. you can't as much put two and two together in a function sig. the man is patient kind enuff to explain. here you're wrong here you don't make sense here you're talking outta your ass. did you my friend miss a beat. hell no. no ``thank you i'll go study some more'' no ``sorry you was right i was wrong'' no ``let me correct myself'' not even effin' ``oh ok''. wtf man. r u really only mouth and no brain. then who's cocky and holding his tail up. ``so if I understand you correctly, you don't see any other disadvantages''. oxpoop. there are no advantages, that's the problem. poop.
October 02, 2008
Andrei Alexandrescu wrote:
> In neither case is it possible for x and &x to mean the same thing. For functions some really weird stuff happens:

One flag that something wacky is going is to look at the compiler code needed to implement it. In DMC, there's the nutty function arraytoptr() which is called from about 30 places in the semantic analysis. It's clearly a special case:

/**************************
 * If e is <array of>, convert it to <pointer to>.
 * If e is <function>, convert it to <pointer to><function>.
 */

elem *arraytoptr(elem *e)
{   type *t;

    t = e->ET;
    if (t)
    {
        switch (tybasic(t->Tty))
        {   case TYarray:
                if (e->Eoper == OPvar && type_isvla(t))
                {
                    // It already is a pointer, so just change the type
                    type_settype(&e->ET, newpointer(t->Tnext));
                }
                else if (CPP || !(e->PEFflags & PEFnotlvalue))  // ANSI C 3.2.2
                {   type *tp = type_ptr(e,t->Tnext);

                    tp->Talternate = t;
                    t->Tcount++;
                    e = el_unat(OPaddr,tp,e);
                }
                break;
#if TX86
            case TYnfunc:
            case TYnpfunc:
            case TYnsfunc:
            case TYnsysfunc:
            case TYfsysfunc:
            case TYf16func:
            case TYfsfunc:
            case TYifunc:
            case TYjfunc:
#endif
            case TYffunc:
            case TYfpfunc:
                e = exp2_addr(e);
                break;
        }
    }
    return e;
}
October 02, 2008
On Wed, 01 Oct 2008 15:28:36 +0200, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Simen Kjaeraas wrote:
>>  It seems we will soon get reference return values, in which case this would
>> no longer be a problem. I have also written a property template that enables
>> things such as that, but it would also benefit immensely from reference
>> return values.
>
> Not quite. Sorry, I woke up all negative this morning :o).
>
> Consider the .length property for built-in arrays. Better yet, consider you implement your own array and want to define a .length property.
>
> You don't want it to return a reference! You want to have control over the assignment so that you execute the actual array change.
>
> What I'd proposed to Walter for a long time is to allow a.b @= c to work if a.b = a.b @ c works. I'm sure people around here will find reasons to dislike that :o).
>
>
> Andrei

Ah, of course. So that leaves us with the property template. I've got a
fairly nice implementation running, but I dislike the syntax.

class foo
{
  int _bar;
  myStruct _baz;

  mixin property!(_bar, properties.readwrite, barChanged) bar; // This is ugly.
  mixin property!(_baz, properties.read) baz;

  void barChanged(int value)
  {
    //...
  }
}

This supports all manners of operator overloading at the moment.

-- 
Simen