www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What does func!thing mean?

reply "ProgrammingGhost" <dsioafiseghvfawklncfskzdcf sdifjsdiovgfdisjcisj.com> writes:
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
Nov 07 2013
next sibling parent reply "qznc" <qznc web.de> writes:
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".
Nov 07 2013
parent reply "ProgrammingGhost" <dsioafiseghvfawklncfskzdcf sdifjsdiovgfdisjcisj.com> writes:
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.
Nov 08 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Nov 08 2013
prev sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
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"
Nov 08 2013
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
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.
Nov 07 2013
prev sibling parent reply "Gary Willoughby" <dev nomad.so> writes:
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/
Nov 08 2013
parent "Gary Willoughby" <dev nomad.so> writes:
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/
Nov 08 2013