Thread overview
What does func!thing mean?
Nov 08, 2013
ProgrammingGhost
Nov 08, 2013
qznc
Nov 08, 2013
ProgrammingGhost
Nov 08, 2013
bearophile
Nov 09, 2013
Jesse Phillips
Nov 08, 2013
Philippe Sigaud
Nov 08, 2013
Gary Willoughby
Nov 08, 2013
Gary Willoughby
November 08, 2013
I'm a D noob. ".map!(a => a.length)" seems like the lambda is passed into the  template. ".map!split" just confuses me. What is split? I thought only types can be after "!". I would guess split is a standard function but then shouldn't it be map!(split)?

    const wordCount = file.byLine()                  // Read lines
                          .map!split                 // Split into words
                          .map!(a => a.length)       // Count words per line
                          .reduce!((a, b) => a + b); // Total word count
November 08, 2013
On Friday, 8 November 2013 at 05:46:29 UTC, ProgrammingGhost wrote:
> I'm a D noob. ".map!(a => a.length)" seems like the lambda is passed into the  template. ".map!split" just confuses me. What is split? I thought only types can be after "!". I would guess split is a standard function but then shouldn't it be map!(split)?
>
>     const wordCount = file.byLine()                  // Read lines
>                           .map!split                 // Split into words
>                           .map!(a => a.length)       // Count words per line
>                           .reduce!((a, b) => a + b); // Total word count

Do you know C++ templates? C++ func<thing> == D func!(thing).

You can pass anything into a template, not just types. So you are right, "map!split" gives the "split" function into the "map" template and "map!(split)" is the canonical form. D allows you to remove the parens for simple cases, hence "map!split".
November 08, 2013
When a template argument is only one token long (ie: one number, one type, one string, one name), the parenthesis are optional and can be omitted.


November 08, 2013
On Friday, 8 November 2013 at 05:46:29 UTC, ProgrammingGhost wrote:
> I'm a D noob. ".map!(a => a.length)" seems like the lambda is passed into the  template. ".map!split" just confuses me. What is split? I thought only types can be after "!". I would guess split is a standard function but then shouldn't it be map!(split)?
>
>     const wordCount = file.byLine()                  // Read lines
>                           .map!split                 // Split into words
>                           .map!(a => a.length)       // Count words per line
>                           .reduce!((a, b) => a + b); // Total word count

For a friendly introduction to D template system please take a look at this: http://nomad.so/2013/07/templates-in-d-explained/
November 08, 2013
On Friday, 8 November 2013 at 08:59:17 UTC, Gary Willoughby wrote:
> For a friendly introduction to D template system please take a look at this: http://nomad.so/2013/07/templates-in-d-explained/

Then to understand why parens are optional take a look at this: http://nomad.so/2013/08/alternative-function-syntax-in-d/
November 08, 2013
On Friday, 8 November 2013 at 06:25:15 UTC, qznc wrote:
> On Friday, 8 November 2013 at 05:46:29 UTC, ProgrammingGhost wrote:
>> I'm a D noob. ".map!(a => a.length)" seems like the lambda is passed into the  template. ".map!split" just confuses me. What is split? I thought only types can be after "!". I would guess split is a standard function but then shouldn't it be map!(split)?
>>
>>    const wordCount = file.byLine()                  // Read lines
>>                          .map!split                 // Split into words
>>                          .map!(a => a.length)       // Count words per line
>>                          .reduce!((a, b) => a + b); // Total word count
>
> Do you know C++ templates? C++ func<thing> == D func!(thing).
>
> You can pass anything into a template, not just types. So you are right, "map!split" gives the "split" function into the "map" template and "map!(split)" is the canonical form. D allows you to remove the parens for simple cases, hence "map!split".

Oh I see. Yes I understand C++ templates which is how I guessed that. This FEELS UNUSUAL. Because it seems like it is .map(!split.map(!(...))).reduce...

As if split.map was the template parameter. How does it know if split isn't a class (or if d has them, namespace) and map is a static function? Thats why it confused me.
November 08, 2013
ProgrammingGhost:

> As if split.map was the template parameter. How does it know if split isn't a class (or if d has them, namespace) and map is a static function? Thats why it confused me.

D doesn't have namespaces, it has modules and packages. map is a higher order function that returns a lazy templated range, a templated struct.

My suggestion is to start from simpler things (simpler syntax) and go up on from there. If you start from the end, you will be confused :-)

Bye,
bearophile
November 09, 2013
On Friday, 8 November 2013 at 20:15:14 UTC, ProgrammingGhost
wrote:
> Oh I see. Yes I understand C++ templates which is how I guessed that. This FEELS UNUSUAL. Because it seems like it is .map(!split.map(!(...))).reduce...

Simply put, anything more complex than a single name requires !()

     to!char[]("fish");

"test.d(5): Error: cannot resolve type for to!char"