@property

Timon Gehr timon.gehr at gmx.ch
Tue Aug 7 15:16:17 PDT 2012


On 08/07/2012 10:52 PM, José Armando García Sancio wrote:
> On Tue, Aug 7, 2012 at 12:27 PM, Timon Gehr<timon.gehr at gmx.ch>  wrote:
>> On 08/07/2012 08:37 PM, José Armando García Sancio wrote:
>>>
>>> On Tue, Aug 7, 2012 at 10:39 AM, Timon Gehr<timon.gehr at gmx.ch>   wrote:
>>>>
>>>> On 08/07/2012 07:59 AM, José Armando García Sancio wrote:
>>>>
>>>>>
>>>>> On Sun, Aug 5, 2012 at 2:32 PM, Kapps<opantm2+spam at gmail.com>    wrote:
>>>>>>
>>>>>>
>>>>>> On Sunday, 5 August 2012 at 14:32:50 UTC, Adam D. Ruppe wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Sunday, 5 August 2012 at 04:12:23 UTC, Jonathan M Davis wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> I'd be very surprised if all that many people compile with -property.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Indeed. Sometimes I try it just to see what happens, and always the
>>>>>>> same
>>>>>>> results: it doesn't solve problems and complains about code.
>>>>>>>
>>>>>>> Some examples of things that break:
>>>>>>>
>>>>>>> import std.algorithm;
>>>>>>> foreach(i; [1,2,3].map!"a+1") {
>>>>>>>
>>>>>>> }
>>>>>>> prophate.d(5): Error: not a property [1,2,3].map!("a+1")
>>>>>>>
>>>>>>>
>>>>>>> Of course, this is relatively new, using ufcs in 2.059, so the
>>>>>>> breakage
>>>>>>> probably isn't too bad, but I'm not the only one who writes it this
>>>>>>> way
>>>>>>> -
>>>>>>> I've seen a number of reddit and newsgroup comments do this too,
>>>>>>> especially
>>>>>>> when chaining it.
>>>>>>> [snip]
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> I completely agree, particularl with the UFCS part. UFCS is designed to
>>>>>> get
>>>>>> rid of the horrible mess of (), and now we want to arbitrarily force a
>>>>>> ()
>>>>>> anyways? Seems like it defeats the purpose. To me, when comparing
>>>>>> range.filter!"a>    2".map!"a*a".countUntil(3)
>>>>>> to
>>>>>> range.filter!"a>    2"().map!"a*a"().countUntil(3)
>>>>>> Those extra paranthesis just don't do anything, they don't give extra
>>>>>> meaning, they don't accomplish anything useful but distract from the
>>>>>> actual
>>>>>> expression.
>>>>>>
>>>>>
>>>>> Just a small comment. I have been following this thread a little and
>>>>> was somewhat surprise that the argument against enforcing parenthesis
>>>>> on non-properties is that a call like [1,2,3].map!"a+1" would look
>>>>> ugly as [1,2,3].map!"a+1"(). To me that is a issue of the
>>>>> std.algorithm module and not so much of the language.
>>>>>
>>>>>
>>>>> Personally I am not a huge fan of using strings as a way to pass a
>>>>> function into a high-order function. I suspect that this string stuff
>>>>> became popular because D didn't have lambda declarations and type
>>>>> inference when the module was designed and implemented.
>>>>
>>>>
>>>>
>>>> String lambdas would quite certainly have been left out.
>>>> Anyway, string lambdas are unrelated to the discussion of std.algorithm
>>>> idioms in this context.
>>>>
>>>> [1,2,3].map!(a=>a+1)
>>>>
>>>> [1,2,3].map!(a=>a+1)()
>>>
>>>
>>> Yep. The "problem" is not string lambda but that the mapping function
>>> is passed a template argument (which you need for string lambda to
>>> work).
>>
>>
>> It is also a matter of execution speed and GC pressure. None of the D
>> compilers is able to inline delegate parameters at least as well as
>> alias template parameters afaik.
>>
>> Furthermore, only the current form can _guarantee_ that no hidden GC
>> allocations take place due to parameter passing to map.
>>
>
> Interesting. I can't speak for the GC and allocation you mention since
> I never tried to implement this myself but I should point out that C++
> STL's algorithm "module" (transform, for_each, etc) works this way.
> Having said that, if D can't infer the type of lambda parameters
> (which I thought the current version of D could) and create a
> function/delegate based on the body then this is a no go.
>
> Thanks for you insight.
> -Jose

The reason it works in C++ for transform, for_each etc. is because
those functions are eager.

Allocation-free transform with runtime delegate in D:

import std.algorithm, std.range;
void transform(IR,OR,I,O)(IR input, OR output, scope O delegate(I) dg)
     if(is(typeof(input.map!dg.copy(output))))
{
     input.map!dg.copy(output);
}

void main(){
     int[3] result;
     int	b = 1;
     [1,2,3].transform(result[], (int a)=>a+b);
     assert(result[] == [2,3,4]);
}

Note that parameter type deduction is lost for the delegate. I'd like
type deduction to work if the signature of 'transform' is changed to:

void transform(IR,OR,I=ElementType!IR,O)(IR input, OR output, scope O 
delegate(I) dg);

[1,2,3].transform(result[], a=>a+b);

Lazy map with runtime delegate would have to remember the delegate,
therefore it could not be a scope delegate.



More information about the Digitalmars-d mailing list