Search
Andrei Alexandrescu wrote:

> Leandro Lucarella wrote:
>> "enum" as the way to declare manifest constants were much more ugly than "!(", and most of the people were against it. I don't see why ".(" should be introduced.
>
> Ugly or not, enumerated symbols were manifest constants to begin with. That's kinda hard to argue against because it's a sheer fact.

Even before we expanded enums, I hated how there was no toString() for enum types.  Walter explained this was because bit masks made it difficult. I like using enums for a restricted set of options.  That'd allow the compiler to provide toString and catch misuse in switch statements... Including when I add or remove allowed values.

BCS wrote:
>
>> BCS wrote:
>>
>>>
>>>> Hello,
>>>>
>>>> (Background: Walter has kindly allowed ".()" as an alternative to
>>>> the ugly "!()" for template argument specifications.)
>>>>
>>>
>>> I think the runtime/compiletime distinction is important, sort of for
>>> the same reason that cast(T) is used (make things stand out, but Re
>>> '!' not as a bad thing).
>>>
>> This has been discussed. Implicit function template instantiation and
>> compile-time function evaluation have been successful partly because
>> they unify the run-time and the compile-time realms.
>>
>> Andrei
>>
>
> Yes they are good because they unify the implementation of RT&CT but that's not what I'm referring to. What I am liking is the disjunction between the use of them. I want to be able to look at a block of code and see at a glance that it will collapse to nothing in the executable or get put in as code to get executed.

Well I guess it all depends on how hard the glance is and how sharp your eye is... :o)

Andrei

Bruce Adams wrote:
> On Sun, 05 Oct 2008 15:12:13 +0100, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>> Internal temporaries would be checked at compile time (when initialised to a compile time constant value)
>>> so there would be no added cost to implementing sqrt only using it with values that might
>>> be negative.
>>
>> That can't be done in the current language, sigh.
>>
> It can't? That surprises me. Doesn't CTFE apply to:
>
> Positive!(int) x = 1;

Not currently.

>>> If my understanding is correct you are proposing this mainly because unlike contracts,
>>> templates are checked by the compiler at compile time.
>>> I suspect that is the real problem. I and others have previously tried to argue for compile
>>> time checkable contracts.
>>> Another advantage of compile time contracts is that you can design and test arbitrary new
>>> categories of type without having to add new type specifiers to the language. I'm thinking about
>>> const and pure here. Though pure would require functions to have visible compile time attributes
>>> (as opposed to the purely invisible ones which must exist internally) which is another kettle of fish.
>>
>> I'd love compile-time-checked contracts, but they're simply not doable with current compiler technology.
>>
>> Andrei
>
> I disagree. I'm not saying its easy but it could be done. We would have to start
> with something relatively simple and work our way up but it could be done.

I, too, think it can be done in the same way supersonic mass
transportation can be done, but having done research in the area I can
tell you you are grossly underestimating the difficulties. It is a
project of gargantuan size. Today the most advanced systems only managed
to automatically prove facts that look rather trivial to the casual
reader. There is absolutely no hope for D to embark on this.

> Compiler's already do all kinds of clever analyses behind the scenes but each one
> is often hard coded. I suspect the main difficulty is giving users too much rope
> by which to hang themselves, or rather hang the compiler trying to prove something
> it doesn't realise it can't. Marrying declarative / constraint based programming
> at compile time is creeping in via templates. I wish it was less well hidden.

I discussed the problem this morning with Walter and he also started
rather cocky: if you assert something early on, you can from then on
assume the assertion is true (assuming no assignment took place, which
is not hard if you have CFA in place). He got an arrow in a molar with
the following example:

double[] vec;
foreach (e; vec) assert(e >= 0);
// now we know vec is all nonnegatives
normalize(vec);

The definition of normalize is:

void normalize(double[] vec)
{
foreach (e; vec) assert(e >= 0);
auto sum = reduce@"a + b"(vec, 0);
assert(sum > 0);
foreach (ref e; vec) e /= sum;
}

If normalize takes udouble[] and you have one of those, there's no need to recheck. Automated elimination of the checking loop above is really hard.

Andrei

Jason House wrote:
> Andrei Alexandrescu wrote:
>
>> Leandro Lucarella wrote:
>>> "enum" as the way to declare manifest constants were much more ugly than
>>> "!(", and most of the people were against it. I don't see why ".(" should
>>> be introduced.
>> Ugly or not, enumerated symbols were manifest constants to begin with.
>> That's kinda hard to argue against because it's a sheer fact.
>
> Even before we expanded enums, I hated how there was no toString() for enum
> types.

defineEnum in std.typecons provides that (and parsing too).

> Walter explained this was because bit masks made it difficult. I
> like using enums for a restricted set of options.  That'd allow the
> compiler to provide toString and catch misuse in switch statements...
> Including when I add or remove allowed values.

Walter hasn't gotten around to implementing the final switch statement, which does exactly as you mention. For the interested I paste the relevant section in TDPL - hot off the oven:

\section{The \protect\cc{final switch} Statement}

It is  often the case  that @switch@ is  meant to handle  all possible
cases,  such as  all values  of a  small integer  or of  an enumerated
type. If, during maintenance, the  number of cases is changing, all of
the dependent @switch@  statements suddenly fall out of  sync and must
be  manually searched  for  and modified.   For  such situations,  the
\cc{final switch} statement comes in handy:

\begin{D}
...
void Handle(uint x) {
final switch (x & deviceStatusMask) {
case 0: ...
case 1: ...
case 2: ...
case 3: ...
}
}
\end{D}

Should  the value of  @mask@ change  later to,  say, 7,  attempting to
recompile @Handle@ is met with refusal on the following grounds:

\begin{lstlisting}[language=sys]
Error: final switch statement must handle all values
\end{lstlisting}

The \cc{final switch} statement looks  at the shape of its controlling
expression to figure out the bounds, as follows:

\begin{itemize*}
\item  If \meta{expression}  is \metai{e}  @&@ \metaii{e}  and  one of
\metai{e} and \metaii{e} evaluates  to a positive compile-time value
@c@, then the range is determined as @0@ up to (and including) @c@.
\item  If  \meta{expression}   is  \metai{e}  \cc{\%}  \metaii{e}  and
\metaii{e} evaluates to a  positive compile-time value @c@, then the
range is determined as @0@ up to (and not including) \cc{c}.
\item  If  \meta{expression}  is   an  unsigned  right  shift  (either
\metai{e}  \cc{>>}  \metaii{e}  operating  on unsigned  numbers,  or
\metai{e}  \cc{>>>} \metaii{e}),  and if  \metaii{e} evaluates  to a
compile-time value  @c@, then the range  is determined as  @0@ up to
(and not including) \cc{1 << (8 *} \metai{e}\cc{.sizeof - c)}.%>>
\item If  \meta{expression} is  the assignment variant  of one  of the
above  (@&=@, \cc{\%=}  etc.) then  the range  the same  as  for the
non-assignment variant.
\item If  \meta{expression} is  an enumerated type,  the range  is the
entire set of values of the enumerated type.
\item   Otherwise,  the  range   is  @e.min@   up  to   and  including
@e.max@. (The @min@ and @max@  constants are defined for all numeric
types.)
\end{itemize*}

There are quite a few other  cases in which the range of an expression
could be  effectively determined,  but \cc{final switch}  only handles
the  usual ones.   A @default@  label  is allowed  inside a  \cc{final
switch} statement  and practically turns  off all checks  because it
ensures \emph{de facto} that all values are handled.

Andrei

superdan wrote:
> Andrei Alexandrescu Wrote:
>
>> dsimcha wrote:
>>> == Quote from Andrei Alexandrescu (SeeWebsiteForEmail@erdani.org)'s article
>>>> The problem I see with "!" as a template instantiation is not technical.
>>>> I write a fair amount of templated code and over years the "!" did not
>>>> grow on me at all. I was time and again consoled by Walter than one day
>>>> that will happen, but it never did. I also realized that Walter didn't
>>>> see a problem with it because he writes only little template code.
>>>> I didn't have much beef with other oddities unique to D. For example, I
>>>> found no problem accommodating binary "~" and I was wondering what makes
>>>> "!" different. I was just looking at a page full of templates and it
>>>> looked like crap.
>>>> One morning I woke up with the sudden realization of what the problem
>>>> was: the shouting.
>>>> In C, "!" is used as a unary operator. That may seem odd at first, but
>>>> it nevers follows a word so it's tenuous to associate it with the
>>>> natural language "!". In D, binary "!" _always_ follows a word, a name,
>>>> something coming from natural language. So the conotation with
>>>> exclamation jumps at you.
>>>> That's why I find the choice of "!" poor. I believe it can impede to
>>>> some extent acquisition of templates by newcomers, and conversely I
>>>> believe that using .() can make templates more palatable. I tried using
>>>> ".()" in my code and in only a couple of days it looked and felt way
>>>> better to me. Based on that experience, I suggest that "!()" is dropped
>>>> in favor of ".()" for template instantiation for D2.
>>>> Sean's argument that "The exclamation mark signifies an assertion of
>>>> sorts" is exactly where I'd want templates not to be: they should be
>>>> blended in, not a hiccup from normal code. Serious effort has been, and
>>>> still is, made in D to avoid shell-shocking people about use of
>>>> templates, and I think ".()" would be a good step in that direction.
>>>> Andrei
>>> Personally, I think that ".()" looks a little too much like a normal
>>> function/method call.  The "!()" syntax looks just different enough to make it
>>> easy to keep straight in my head that stuff with the "!" is a compile-time
>>> construct and stuff without it can be evaluated at runtime.
>> I'm arguing we _should_ make template code look like "normal" code, whatever "normal" is :o). We _should_ strive for "quiet" templates.
>>
>> You know what annoys the living heebiejeebies out of me? Nested template instantiations.
>>
>> This!(That!(TheOther!(crap)))
>>
>> I have a ton + change of those. In superdan's words: intercourse that.
>>
>>
>> Andrei
>
> im a bit drunk. but im much obliged since my name was mentioned n all.
>
> ! pisses me off too. i have an opinion. walter looked at unary ops that can be binary ops. first tilde. pulled tat off. ten he wanted the template thing. only 1 left was !. so he put that at work. right walt?
> now i never like ! because of nother reason. i always forget to put it. and yes it's not needed. i look @ code its unambig. then wtf do i need that crap !
>
> anyhoo would be great if ! goes away. to hell with it. need to try asdad.(asdasd) to see how it feels. and yeah they all jump andreis neck whever he posts any. or walts. its funny. hold them guns folks. can i delete this later i wonder.

I live in California.  Legally I cannot own any gun that could conceivably hurt someone when misused under the proper situations.  =/

I was never particularly annoyed by the !() syntax, but then again I have not written much template code.  I can count the number of template classes I have written on one hand.

I am deeply concerned about the proposed .() syntax, however, since (to me) it's too similar to a function call.  This lack of finding some kind of counterproposal left me studying my keyboard for any unused characters that could become a symbol.  I saw these symbols that I could remember no existing use for:

@, #, $,  I'm favorable to the # symbol. So a template would look like foo#(int)(bar). To me the # symbol looks like it could be two Latin 't' characters (not to be confused with the Greek Tau 'T', which is different). Thus one could remember the mnemonic "template" with two t's for the # symbol. Just a countersuggestion, I haven't really looked through specifications or anything to verify the unused status of any of those symbols.  Chris R. Miller wrote: > superdan wrote: >> Andrei Alexandrescu Wrote: >> >>> dsimcha wrote: >>>> == Quote from Andrei Alexandrescu (SeeWebsiteForEmail@erdani.org)'s article >>>>> The problem I see with "!" as a template instantiation is not technical. >>>>> I write a fair amount of templated code and over years the "!" did not >>>>> grow on me at all. I was time and again consoled by Walter than one day >>>>> that will happen, but it never did. I also realized that Walter didn't >>>>> see a problem with it because he writes only little template code. >>>>> I didn't have much beef with other oddities unique to D. For example, I >>>>> found no problem accommodating binary "~" and I was wondering what makes >>>>> "!" different. I was just looking at a page full of templates and it >>>>> looked like crap. >>>>> One morning I woke up with the sudden realization of what the problem >>>>> was: the shouting. >>>>> In C, "!" is used as a unary operator. That may seem odd at first, but >>>>> it nevers follows a word so it's tenuous to associate it with the >>>>> natural language "!". In D, binary "!" _always_ follows a word, a name, >>>>> something coming from natural language. So the conotation with >>>>> exclamation jumps at you. >>>>> That's why I find the choice of "!" poor. I believe it can impede to >>>>> some extent acquisition of templates by newcomers, and conversely I >>>>> believe that using .() can make templates more palatable. I tried using >>>>> ".()" in my code and in only a couple of days it looked and felt way >>>>> better to me. Based on that experience, I suggest that "!()" is dropped >>>>> in favor of ".()" for template instantiation for D2. >>>>> Sean's argument that "The exclamation mark signifies an assertion of >>>>> sorts" is exactly where I'd want templates not to be: they should be >>>>> blended in, not a hiccup from normal code. Serious effort has been, and >>>>> still is, made in D to avoid shell-shocking people about use of >>>>> templates, and I think ".()" would be a good step in that direction. >>>>> Andrei >>>> Personally, I think that ".()" looks a little too much like a normal >>>> function/method call. The "!()" syntax looks just different enough to make it >>>> easy to keep straight in my head that stuff with the "!" is a compile-time >>>> construct and stuff without it can be evaluated at runtime. >>> I'm arguing we _should_ make template code look like "normal" code, whatever "normal" is :o). We _should_ strive for "quiet" templates. >>> >>> You know what annoys the living heebiejeebies out of me? Nested template instantiations. >>> >>> This!(That!(TheOther!(crap))) >>> >>> I have a ton + change of those. In superdan's words: intercourse that. >>> >>> >>> Andrei >> >> im a bit drunk. but im much obliged since my name was mentioned n all. >> >> ! pisses me off too. i have an opinion. walter looked at unary ops that can be binary ops. first tilde. pulled tat off. ten he wanted the template thing. only 1 left was !. so he put that at work. right walt? >> now i never like ! because of nother reason. i always forget to put it. and yes it's not needed. i look @ code its unambig. then wtf do i need that crap ! >> >> anyhoo would be great if ! goes away. to hell with it. need to try asdad.(asdasd) to see how it feels. and yeah they all jump andreis neck whever he posts any. or walts. its funny. hold them guns folks. can i delete this later i wonder. > > I live in California. Legally I cannot own any gun that could conceivably hurt someone when misused under the proper situations. =/ > > I was never particularly annoyed by the !() syntax, but then again I have not written much template code. I can count the number of template classes I have written on one hand. > > I am deeply concerned about the proposed .() syntax, however, since (to me) it's too similar to a function call. This lack of finding some kind of counterproposal left me studying my keyboard for any unused characters that could become a symbol. I saw these symbols that I could remember no existing use for: > > @, #,$, 
>
> I'm favorable to the # symbol.  So a template would look like foo#(int)(bar).
>
> To me the # symbol looks like it could be two Latin 't' characters (not to be confused with the Greek Tau 'T', which is different).  Thus one could remember the mnemonic "template" with two t's for the # symbol.
>
> Just a countersuggestion, I haven't really looked through specifications or anything to verify the unused status of any of those symbols.

No go due to #line. :o(

Andrei

On Mon, 06 Oct 2008 04:03:08 +0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Jason House wrote:
>> Andrei Alexandrescu wrote:
>>
>>> Leandro Lucarella wrote:
>>>> "enum" as the way to declare manifest constants were much more ugly than
>>>> "!(", and most of the people were against it. I don't see why ".(" should
>>>> be introduced.
>>> Ugly or not, enumerated symbols were manifest constants to begin with.
>>> That's kinda hard to argue against because it's a sheer fact.
>>  Even before we expanded enums, I hated how there was no toString() for enum
>> types.
>
> defineEnum in std.typecons provides that (and parsing too).
>
>> Walter explained this was because bit masks made it difficult. I
>> like using enums for a restricted set of options.  That'd allow the
>> compiler to provide toString and catch misuse in switch statements...
>> Including when I add or remove allowed values.
>
> Walter hasn't gotten around to implementing the final switch statement, which does exactly as you mention. For the interested I paste the relevant section in TDPL - hot off the oven:
>
> \section{The \protect\cc{final switch} Statement}
>
> It is  often the case  that @switch@ is  meant to handle  all possible
> cases,  such as  all values  of a  small integer  or of  an enumerated
> type. If, during maintenance, the  number of cases is changing, all of
> the dependent @switch@  statements suddenly fall out of  sync and must
> be  manually searched  for  and modified.   For  such situations,  the
> \cc{final switch} statement comes in handy:
>
> \begin{D}
> ...
> void Handle(uint x) {
>    final switch (x & deviceStatusMask) {
>    case 0: ...
>    case 1: ...
>    case 2: ...
>    case 3: ...
>    }
> }
> \end{D}
>
> Should  the value of  @mask@ change  later to,  say, 7,  attempting to
> recompile @Handle@ is met with refusal on the following grounds:
>
> \begin{lstlisting}[language=sys]
> Error: final switch statement must handle all values
> \end{lstlisting}
>
> The \cc{final switch} statement looks  at the shape of its controlling
> expression to figure out the bounds, as follows:
>
> \begin{itemize*}
> \item  If \meta{expression}  is \metai{e}  @&@ \metaii{e}  and  one of
>    \metai{e} and \metaii{e} evaluates  to a positive compile-time value
>    @c@, then the range is determined as @0@ up to (and including) @c@.
> \item  If  \meta{expression}   is  \metai{e}  \cc{\%}  \metaii{e}  and
>    \metaii{e} evaluates to a  positive compile-time value @c@, then the
>    range is determined as @0@ up to (and not including) \cc{c}.
> \item  If  \meta{expression}  is   an  unsigned  right  shift  (either
>    \metai{e}  \cc{>>}  \metaii{e}  operating  on unsigned  numbers,  or
>    \metai{e}  \cc{>>>} \metaii{e}),  and if  \metaii{e} evaluates  to a
>    compile-time value  @c@, then the range  is determined as  @0@ up to
>    (and not including) \cc{1 << (8 *} \metai{e}\cc{.sizeof - c)}.%>>
> \item If  \meta{expression} is  the assignment variant  of one  of the
>    above  (@&=@, \cc{\%=}  etc.) then  the range  the same  as  for the
>    non-assignment variant.
> \item If  \meta{expression} is  an enumerated type,  the range  is the
>    entire set of values of the enumerated type.
> \item   Otherwise,  the  range   is  @e.min@   up  to   and  including
>    @e.max@. (The @min@ and @max@  constants are defined for all numeric
>    types.)
> \end{itemize*}
>
> There are quite a few other  cases in which the range of an expression
> could be  effectively determined,  but \cc{final switch}  only handles
> the  usual ones.   A @default@  label  is allowed  inside a  \cc{final
>    switch} statement  and practically turns  off all checks  because it
> ensures \emph{de facto} that all values are handled.
>
>
> Andrei

Final switch is great, but why allow default case in it? Putting the default case into the final switch effectively transforms it into a regular one discarding all of its benefits. What's the point?

Denis Koroskin wrote:
> On Mon, 06 Oct 2008 04:03:08 +0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>
>> Jason House wrote:
>>> Andrei Alexandrescu wrote:
>>>
>>>> Leandro Lucarella wrote:
>>>>> "enum" as the way to declare manifest constants were much more ugly than
>>>>> "!(", and most of the people were against it. I don't see why ".(" should
>>>>> be introduced.
>>>> Ugly or not, enumerated symbols were manifest constants to begin with.
>>>> That's kinda hard to argue against because it's a sheer fact.
>>>  Even before we expanded enums, I hated how there was no toString() for enum
>>> types.
>>
>> defineEnum in std.typecons provides that (and parsing too).
>>
>>> Walter explained this was because bit masks made it difficult. I
>>> like using enums for a restricted set of options.  That'd allow the
>>> compiler to provide toString and catch misuse in switch statements...
>>> Including when I add or remove allowed values.
>>
>> Walter hasn't gotten around to implementing the final switch statement, which does exactly as you mention. For the interested I paste the relevant section in TDPL - hot off the oven:
>>
>> \section{The \protect\cc{final switch} Statement}
>>
>> It is  often the case  that @switch@ is  meant to handle  all possible
>> cases,  such as  all values  of a  small integer  or of  an enumerated
>> type. If, during maintenance, the  number of cases is changing, all of
>> the dependent @switch@  statements suddenly fall out of  sync and must
>> be  manually searched  for  and modified.   For  such situations,  the
>> \cc{final switch} statement comes in handy:
>>
>> \begin{D}
>> ...
>> void Handle(uint x) {
>>    final switch (x & deviceStatusMask) {
>>    case 0: ...
>>    case 1: ...
>>    case 2: ...
>>    case 3: ...
>>    }
>> }
>> \end{D}
>>
>> Should  the value of  @mask@ change  later to,  say, 7,  attempting to
>> recompile @Handle@ is met with refusal on the following grounds:
>>
>> \begin{lstlisting}[language=sys]
>> Error: final switch statement must handle all values
>> \end{lstlisting}
>>
>> The \cc{final switch} statement looks  at the shape of its controlling
>> expression to figure out the bounds, as follows:
>>
>> \begin{itemize*}
>> \item  If \meta{expression}  is \metai{e}  @&@ \metaii{e}  and  one of
>>    \metai{e} and \metaii{e} evaluates  to a positive compile-time value
>>    @c@, then the range is determined as @0@ up to (and including) @c@.
>> \item  If  \meta{expression}   is  \metai{e}  \cc{\%}  \metaii{e}  and
>>    \metaii{e} evaluates to a  positive compile-time value @c@, then the
>>    range is determined as @0@ up to (and not including) \cc{c}.
>> \item  If  \meta{expression}  is   an  unsigned  right  shift  (either
>>    \metai{e}  \cc{>>}  \metaii{e}  operating  on unsigned  numbers,  or
>>    \metai{e}  \cc{>>>} \metaii{e}),  and if  \metaii{e} evaluates  to a
>>    compile-time value  @c@, then the range  is determined as  @0@ up to
>>    (and not including) \cc{1 << (8 *} \metai{e}\cc{.sizeof - c)}.%>>
>> \item If  \meta{expression} is  the assignment variant  of one  of the
>>    above  (@&=@, \cc{\%=}  etc.) then  the range  the same  as  for the
>>    non-assignment variant.
>> \item If  \meta{expression} is  an enumerated type,  the range  is the
>>    entire set of values of the enumerated type.
>> \item   Otherwise,  the  range   is  @e.min@   up  to   and  including
>>    @e.max@. (The @min@ and @max@  constants are defined for all numeric
>>    types.)
>> \end{itemize*}
>>
>> There are quite a few other  cases in which the range of an expression
>> could be  effectively determined,  but \cc{final switch}  only handles
>> the  usual ones.   A @default@  label  is allowed  inside a  \cc{final
>>    switch} statement  and practically turns  off all checks  because it
>> ensures \emph{de facto} that all values are handled.
>>
>>
>> Andrei
>
> Final switch is great, but why allow default case in it? Putting the default case into the final switch effectively transforms it into a regular one discarding all of its benefits. What's the point?

Good point. I was thinking of making maintenance easier: sometimes you decide to insert a default. Then you'd need to wipe the "final" too. Then you comment out the default. You'd need to add the "final" back (and you may forget). And so on.

Andrei

On Sun, Oct 5, 2008 at 8:13 PM, Denis Koroskin <2korden@gmail.com> wrote:

> Final switch is great, but why allow default case in it? Putting the default case into the final switch effectively transforms it into a regular one discarding all of its benefits. What's the point?
>

I was going to ask the same thing.

Ary Borenszweig wrote:
> Andrei Alexandrescu escribió:
>> The problem I see with "!" as a template instantiation is not technical. I write a fair amount of templated code and over years the "!" did not grow on me at all. I was time and again consoled by Walter than one day that will happen, but it never did. I also realized that Walter didn't see a problem with it because he writes only little template code.
>>
>> I didn't have much beef with other oddities unique to D. For example, I found no problem accommodating binary "~" and I was wondering what makes "!" different. I was just looking at a page full of templates and it looked like crap.
>>
>> One morning I woke up with the sudden realization of what the problem was: the shouting.
>>
>> In C, "!" is used as a unary operator. That may seem odd at first, but it nevers follows a word so it's tenuous to associate it with the natural language "!". In D, binary "!" _always_ follows a word, a name, something coming from natural language. So the conotation with exclamation jumps at you.
>
> I was thinking about in which other way templates could be specified... Most of the other symbols already have a meaning as binary operator. And it also would be nice to have an opening and closing symbols, like <> in Java, C++, etc.

I remember reading that Walter specifically rejected that idea because it became ambiguous with bitshift operations.  In my time with Java, I saw many of these:

public class Foo<Bar<o extends ArrayList>> { ... }

When instantiated in code the >> at the end of the template declaration does become very ambiguous with a bitshift.

> Can't {} be used for that? For example:
>
> List{int} someList;
>
> void foo{T}(T val) {
> }
>
> It seems more quiet. :-)

I rejected that idea when I was searching for counterproposals because it conflicts with the code-block syntax.  The existing () is much less ambiguous, since when you encounter two sets of parenthesis it must be a template.  If it were multiplication it would require the explicit * binary operator.

The !() syntax seems to serve only as a heads up that it's a template. Otherwise (as far as I can tell) a simple foo(int)(bar, baaz) would work just as well as foo!(int)(bar, baaz).