June 27, 2002
> Burton,
>
> I've been thinking about your approach for generic functions.  How would your syntax handle this C++ template:
>
> template <int a, int b>
> float[b][a] Inverse(float matrix[a][b]) { ... }
>
> Perhaps you have a radically new idea that can handle this.
>
> Craig

I am going to answer my own question.

void Invert(in $M matrix, out &I inverse)
in
{
   assert(constant(matrix.rows == inverse.cols));
   assert(constant(matrix.cols == inverse.rows));
}
body { ... }

Given that there are row and column properties for the matrix, or some way of getting that information at compile time.



June 27, 2002
"Craig Black" <cblack@ara.com> wrote in message news:affqjc$2kbf$1@digitaldaemon.com...

> > Burton,
> >
> > I've been thinking about your approach for generic functions.  How would your syntax handle this C++ template:
> >
> > template <int a, int b>
> > float[b][a] Inverse(float matrix[a][b]) { ... }
> >
> > Perhaps you have a radically new idea that can handle this.
> >
> > Craig
>
> I am going to answer my own question.
>
> void Invert(in $M matrix, out &I inverse)
> in
> {
>    assert(constant(matrix.rows == inverse.cols));
>    assert(constant(matrix.cols == inverse.rows));
> }
> body { ... }
>
> Given that there are row and column properties for the matrix, or some way of getting that information at compile time.

   Still, in order to make this work completely at compile time, the
function's contract should be part of the official interface of the
function.

   The "template<>" (or, in LX, "generic[]", or Haskell's class assertions
and contexts) construct is more robust in the general case. It's like
saying... "assuming we have a and b which are integer values, this is a
generic matrix-inverting function". It's clean, it's non-ambiguous.

   Of course, using angle brackets IS ambiguous for parsing (eek!), but
that's besides the point.

Salutaciones,
                         JCAB



June 27, 2002
On Thu, 27 Jun 2002 10:21:12 -0500 "Craig Black" <cblack@ara.com> wrote:

> matter of personal preference.  A(n)(n) or A<n>(n)?  Then again, D might not
> even allow the creation of temporaries this way.  I dunno.

It doesn't. You always have to use operator new to create an object. There is no such thing as "temporary" in D.
June 27, 2002
On Thu, 27 Jun 2002 16:15:56 +0000 (UTC) Patrick Down <pat@codemoon.com> wrote:

> Yes but they caused an equall number of problems in C++ with the >> operator.

Well, then, use something else =)
Maybe backticks?

	template `type T` class tree { ... }
	template `type T` class deque { ... }

	tree`deque`int`` foo;
June 27, 2002
Craig Black wrote:

> I've been thinking about your approach for generic functions.  How would
> your syntax handle this C++ template:
> 
> template <int a, int b>
> float[b][a] Inverse(float matrix[a][b]) { ... }


    float[$b][$a] Inverse (float matrix[$a][$b]) { ... }

They're generic values of type int.  But this is your one and only chance to have a generic function of this name and number of arguments in this scope, so a method is a much better solution.  Before it comes up:

    foo (int [TypeInfo $type] bar)

For associated arrays.


> Perhaps you have a radically new idea that can handle this.

No, just an undescribed part of the syntax.  I meant to describe it but forgot.

June 28, 2002
"Craig Black" <cblack@ara.com> wrote in message news:affa1j$1qdt$1@digitaldaemon.com...

> I suppose the compiler could assume that the first set of parens refers to the template, and the second to the constructor.

   Actually, if the name references a template class, using the first set of
parens as constructor parameters wouldn't be an option, anyway.

   The problem would still exist with template functions, though.

   I see no harm in using something unambiguous and visible, like [[...]]:

struct Array[[type T, int size]] {
  T theArray[size];
};

generic[[type T]] T Min(T v0, T v1);

Salutaciones,
                         JCAB



June 28, 2002
>      float[$b][$a] Inverse (float matrix[$a][$b]) { ... }

So in a generic function the $symbol can be a type, or an integer, or anything else?  I could see where this ambiguity might be too much for the compiler to handle.  That is why C++ uses "template<>" for functions.  For classes I think its unnecessary, but for functions the compiler has to infer what the type or value is, so it is best to give the compiler as many hints as possible to reduce ambiguity.  It would be different if we assumed that all $symbol's were types.  How about preceding each $symbol with a type where the value is to be deduced?  Not only will this specify what the type is, but it will tell the compiler which parameter to get the value from.  I admit I've never designed a compiler, but I assume these kinds of generic functions are difficult to implement.  Let's keep in mind that somebody is going to have to implement this stuff if it's ever going to work.

 float[$b][$a] Inverse (float matrix[int $a][int $b]) { ... }




June 28, 2002
We could use $ for types and # for values.
Array subscripts are always integral (and unsigned!) so one could leave out
the "int" there, it's implicitly uint.

$f[#b][#a] Inverse ($f matrix[#a][#b]) { ... }

Sean

"Craig Black" <cblack@ara.com> wrote in message news:afhrmp$1v65$1@digitaldaemon.com...
> >      float[$b][$a] Inverse (float matrix[$a][$b]) { ... }
>
> So in a generic function the $symbol can be a type, or an integer, or anything else?  I could see where this ambiguity might be too much for the compiler to handle.  That is why C++ uses "template<>" for functions.  For classes I think its unnecessary, but for functions the compiler has to
infer
> what the type or value is, so it is best to give the compiler as many
hints
> as possible to reduce ambiguity.  It would be different if we assumed that all $symbol's were types.  How about preceding each $symbol with a type where the value is to be deduced?  Not only will this specify what the
type
> is, but it will tell the compiler which parameter to get the value from.
I
> admit I've never designed a compiler, but I assume these kinds of generic functions are difficult to implement.  Let's keep in mind that somebody is going to have to implement this stuff if it's ever going to work.
>
>  float[$b][$a] Inverse (float matrix[int $a][int $b]) { ... }



June 29, 2002
> We could use $ for types and # for values.
> Array subscripts are always integral (and unsigned!) so one could leave
out
> the "int" there, it's implicitly uint.
>
> $f[#b][#a] Inverse ($f matrix[#a][#b]) { ... }
>
> Sean

This would work if we assumed that all #symbol's were unsigned integers. But what about associative arrays?  With an associative array, the subscript can be char[] or potentially any other type.  We would need another symbol for every kind of type.

Craig



June 29, 2002
I was thinking that # would be "a value of any type".  However I guess I was wrong about its ability to use uint implicitly in the array index situation.

So I'd have to modify my example thusly:

$f[#b][#a] Inverse ($f matrix[uint #a][uint #b]) { ... }

any #value would have to have a type specified for it at least once (and all such declarations would have to match).  If the compiler can figure out the type implicitly that's great, if not, it has to be specified.

Sean

"cblack01" <cblack01@cox.net> wrote in message news:afj697$9eo$1@digitaldaemon.com...
> > We could use $ for types and # for values.
> > Array subscripts are always integral (and unsigned!) so one could leave
> out
> > the "int" there, it's implicitly uint.
> >
> > $f[#b][#a] Inverse ($f matrix[#a][#b]) { ... }
> >
> > Sean
>
> This would work if we assumed that all #symbol's were unsigned integers. But what about associative arrays?  With an associative array, the
subscript
> can be char[] or potentially any other type.  We would need another symbol for every kind of type.
>
> Craig