OK, good replies.  Cool.  So the two places I thought I'd need to use explicit types are in parameter and return types.  Say, a function returns the result of map, and another consumes it to print it.  The consuming function seems to work with templating:<div>

<br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>void printSquares(T)(T squares) {</div></div><div><div>  writeln(squares);</div></div><div><div>}</div>
</div><div><div><br></div></div><div><div>void main() {</div></div><div><div>  int[] start = [1,2,3,4,5];</div></div><div><div>  auto squares = map!((a) { return a * a; })(start);</div></div><div><div>  printSquares(squares);</div>

</div><div><div>}</div></div></blockquote><div><br></div><div>However, returning the result of map doesn't seem to work so well with the same method:</div><div><br></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;">
<div><div><div><div><div>T getSquares(T)() {</div></div></div></div></div><div><div><div><div><div>  int[] start = [1,2,3,4,5];</div></div></div></div></div><div><div><div><div><div>  return map!((a) { return a * a; })(start);</div>
</div></div></div></div><div><div><div><div><div>}</div></div></div></div></div><div><div><div><div><div><br></div></div></div></div></div><div><div><div><div><div>void main() {</div></div></div></div></div><div><div><div>
<div><div>  auto squares = getSquares();</div></div></div></div></div><div><div><div><div><div>  writeln(squares);</div></div></div></div></div><div><div><div><div><div>}</div></div></div></div></div></blockquote><div><div>
<div><div><div><br></div><div>Gives the errors:</div><div><br></div></div></div></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><div><div><div><div><div><div>
test.d(11): Error: template test.getSquares(T) does not match any function template declaration</div></div></div></div></div></div><div><div><div><div><div><div>test.d(11): Error: template test.getSquares(T) cannot deduce template function from argument types !()()</div>
</div></div></div></div></div></blockquote><div><div><div><div><div><br></div><div>But this does work with auto return type inference:</div><div><br></div></div></div></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;">
<div><div><div><div><div><div>auto getSquares() {</div></div></div></div></div></div><div><div><div><div><div><div>  int[] start = [1,2,3,4,5];</div></div></div></div></div></div><div><div><div><div><div><div>  return map!((a) { return a * a; })(start);</div>
</div></div></div></div></div><div><div><div><div><div><div>}</div></div></div></div></div></div><div><div><div><div><div><div><br></div></div></div></div></div></div><div><div><div><div><div><div>void main() {</div></div>
</div></div></div></div><div><div><div><div><div><div>  auto squares = getSquares();</div></div></div></div></div></div><div><div><div><div><div><div>  writeln(squares);</div></div></div></div></div></div><div><div><div><div>
<div><div>}</div></div></div></div></div></div></blockquote><div><br></div>So ... stuff works, but I'm not really sure why one uses function templating and the other uses return type inference.  Any answers?<br><div><div>
<div><div><br><div class="gmail_quote">On Thu, Jul 7, 2011 at 7:31 PM, Steven Schveighoffer <span dir="ltr"><<a href="mailto:schveiguy@yahoo.com" target="_blank">schveiguy@yahoo.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>On Thu, 07 Jul 2011 10:00:48 -0400, James Fisher <<a href="mailto:jameshfisher@gmail.com" target="_blank">jameshfisher@gmail.com</a>> wrote:<br>


<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
To date, I've been using D in much the same way I used C++, without heavy<br>
use of templates.  Now I'm trying out a more functional style using<br>
std.algorithm.  However I'm pretty much stuck at the first hurdle: map.<br></div><div>
 With type inference, this works:<br>
<br>
import std.algorithm;<br>
import std.stdio;<br>
<br>
void main() {<br>
  auto start = [1,2,3,4,5];<br>
  auto squares = map!((a) { return a * a; })(start);<br>
  writeln(squares);<br>
}<br>
<br>
<br>
Without type inference (obviously necessary beyond trivial examples),<br>
</div></blockquote>
<br>
Type inference is useful everywhere, at any level of complexity.<br>
<br>
Where it's not useful is declarations, for example, declaring the type of a struct or class member.  However, typeof should work to use type inference there.<div><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
it'd<br>
be nice to do:<br>
<br>
import std.algorithm;<br>
import std.stdio;<br>
<br>
void main() {<br>
  int[] start = [1,2,3,4,5];<br>
  int[] squares = map!((a) { return a * a; })(start);<br>
  writeln(squares);<br>
}<br>
<br>
<br>
but this gives "Error: cannot implicitly convert expression (map(start)) of<br>
type Result to int[]".  That opaque type "Result" is weird (not<br>
parameterized on "int"?), but OK, let's try that:<br>
<br>
import std.algorithm;<br>
import std.stdio;<br>
<br>
void main() {<br>
  int[] start = [1,2,3,4,5];<br>
  Result squares = map!((a) { return a * a; })(start);<br>
  writeln(squares);<br>
}<br>
<br>
<br>
gives "undefined identifier Result".  Not sure why, but OK.  I can't see<br>
examples in the docs of explicit type declarations -- annoyingly they all<br>
use "auto".<br>
</blockquote>
<br></div>
OK, so this is kind of a weird case.  std.algorithm.map returns an inner struct, which means, it has no public name.  But then how can you even use it?  Well, it just doesn't have a public *name*, but it still can be used outside the function.  It's definitely an oddball.  However, what's nice about it is that you can encapsulate the struct inside the one place it is used.<br>


<br>
You can see the definition of map here: <a href="https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d#L366" target="_blank">https://github.com/D-<u></u>Programming-Language/phobos/<u></u>blob/master/std/algorithm.d#<u></u>L366</a><br>


<br>
And a few lines down, the declaration of Result.<br>
<br>
You can use typeof if you want to get the type, but again, auto is much better unless you are declaring something.<div><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
However, they do tell me that map "returns a range".  Assuming all<br>
definitions of ranges are in std.range, there's no such thing as a "Range"<br>
interface, so it's not that.  The most general interfaces I can see are<br>
InputRange(E) and OutputRange(E).  It certainly can't be an OutputRange, so<br>
I guess it must satisfy InputRange, presumably type-parameterized with<br>
"int".<br>
</blockquote>
<br></div>
No, a range is a concept, meaning it is a compile-time interface.  Any type which satisfies the requirements of the input range can be a range, even non-polymorphic types.  Even an array is a range.<div><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 So this should work:<br>
<br>
import std.algorithm;<br>
import std.stdio;<br>
import std.range;<br>
<br>
void main() {<br>
  int[] start = [1,2,3,4,5];<br>
  InputRange!int squares = map!((a) { return a * a; })(start);<br>
  writeln(squares);<br>
}<br>
<br>
<br>
But the compiler complains "cannot implicitly convert expression<br>
(map(start)) of type Result to std.range.InputRange!(int).<u></u>InputRange".<br>
</blockquote>
<br></div>
Right, because it's not a derivative of that interface, it's its own type, defined only inside the function.  Yeah, I know it's confusing :)<div><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 That's weird, because "std.range.InputRange!(int).<u></u>InputRange" doesn't even<br>
look like a type.<br>
</blockquote>
<br></div>
std.range is the module, but I assume you already know that.<br>
<br>
But one of the coolest things about D templates is the eponymous rule.  That is, if you declare a template, and that template has exactly one member, and that one member is named the same as the template, then x!(y) becomes the equivalent of x!(y).x.<br>


<br>
For example:<br>
<br>
template t(T)<br>
{<br>
   class t<br>
   {<br>
      T val;<br>
   }<br>
}<br>
<br>
t!(int) is equivalent to t!(int).t<br>
<br>
In other words, a template is a *namespace* for declarations using the template parameters.  And in this special case, you can omit the member of the namespace you are accessing.<br>
<br>
Then what follows is that:<br>
<br>
class t(T)<br>
{<br>
   T val;<br>
}<br>
<br>
is shorthand for the above.<br>
<br>
But the compiler maintains the namespace.member nomenclature, which is why you see that in the error message.<br>
<br>
-Steve<br>
</blockquote></div><br></div></div></div></div>