www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Positive

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Hello,


(Background: Walter has kindly allowed ".()" as an alternative to the 
ugly "!()" for template argument specifications.)

Just a quick question - I am feeling an increasing desire to add a 
template called Positive to std.typecons. Then Positive.(real) would 
restrict its values to only positive real numbers etc.

The implementation would accept conversion from its base type, e.g. 
Positive.(real) can be constructed from a real. The constructor enforces 
dynamically the condition. Also, Positive.(real) accepts implicit 
conversion to real (no checking necessary).

There are many places in which Positive can be useful, most notably 
specifications of interfaces. For example:

Positive.(real) sqrt(Positive.(real) x);

These specifications are also efficient because checking for positivity 
is done outside sqrt; if you had a Positive.(real) to start with, there 
is no cascading checking necessary so there's one test less to do.

However, there is also the risk that Positive has the same fate the many 
SafeInt implementation have had in C++: many defined them, nobody used 
them. What do you think? If you had Positive in std and felt like 
crunching some numbers, would you use it?

In order to get things really started, there's already been an exchange 
with Walter on the matter. His reply was (I haven't asked for 
permission, but I'm pretty sure he'd agree making it public):

==============
Honestly, I wouldn't use it. I'd rather have an in contract for sqrt 
that asserts the argument is positive. Also, this opens the door to 
Negative, NegativeOrZero, ZeroOrInfinity, Odd, Even, Prime, 
SixOrFifteen, etc.
==============

My answer to that was:

==============
About contracts: Let me explain how I think that's inferior to Positive 
in two ways.

1. Enough functions are defined on positive numbers only, to justify 
factoring that contract out of the functions themselves.

2. The efficiency perk is that when using several such functions 
together, there's only one check; once in Positive-land, no more checks 
are necessary.

About proliferation of types: I don't think that follows at all. Math 
found positive numbers special enough to dedicate them a special 
notation (|R with subscript "+"). There's also a special notation for 
nonzero real numbers (|R with superscript "*"). There is no special 
notation for any of the sets you mentioned. That is bound to mean something.
==============

I'm interesting in further arguments. This feature is a numbers issue 
(pun not intended), meaning it will be any good only if enough people 
find it useful enough to actually use it in their own code and 
libraries, therefore building momentum behind it.


Andrei
Oct 04 2008
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Andrei Alexandrescu" wrote
 (Background: Walter has kindly allowed ".()" as an alternative to the ugly 
 "!()" for template argument specifications.)

:( Another case of multiple syntax possibilities. What was wrong with !() ? I didn't consider it ugly at all. In fact, I prefer it. It's very alarming to me that something like this just has no problem getting in the language without community feedback.
 Just a quick question - I am feeling an increasing desire to add a 
 template called Positive to std.typecons. Then Positive.(real) would 
 restrict its values to only positive real numbers etc.

I wouldn't use it, if that helps at all. Even if it was in Tango (i.e. not just because I don't use Phobos). -Steve
Oct 04 2008
next sibling parent =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Steven Schveighoffer wrote:
 "Andrei Alexandrescu" wrote
 (Background: Walter has kindly allowed ".()" as an alternative to the ugly 
 "!()" for template argument specifications.)

:( Another case of multiple syntax possibilities. What was wrong with !() ? I didn't consider it ugly at all. In fact, I prefer it. It's very alarming to me that something like this just has no problem getting in the language without community feedback.
 Just a quick question - I am feeling an increasing desire to add a 
 template called Positive to std.typecons. Then Positive.(real) would 
 restrict its values to only positive real numbers etc.

I wouldn't use it, if that helps at all. Even if it was in Tango (i.e. not just because I don't use Phobos).

Seconded.
Oct 04 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Sat, Oct 4, 2008 at 10:55 PM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 "Andrei Alexandrescu" wrote
 (Background: Walter has kindly allowed ".()" as an alternative to the ugly
 "!()" for template argument specifications.)

:( Another case of multiple syntax possibilities. What was wrong with !() ? I didn't consider it ugly at all. In fact, I prefer it. It's very alarming to me that something like this just has no problem getting in the language without community feedback.

Heartily agree. Not that it means anything.
Oct 04 2008
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Steven Schveighoffer wrote:
 It's very alarming to me that something like this just has no problem 
 getting in the language without community feedback.

It's there at the moment so we can look at it and see if we like it. I know Andrei likes it. Anyhow, this is the opportunity for community feedback.
Oct 04 2008
next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Walter Bright wrote:
 Steven Schveighoffer wrote:
 It's very alarming to me that something like this just has no problem 
 getting in the language without community feedback.

It's there at the moment so we can look at it and see if we like it. I know Andrei likes it. Anyhow, this is the opportunity for community feedback.

To me, the !() syntax has always clearly communicated what's happening. The exclamation mark signifies an assertion of sorts (using the English meaning of 'assertion', not the programming meaning). With the dot syntax I'd always be wondering whether there was a function call taking place that I didn't know about. Is there anything this change in syntax gives us over what we currently have? If not, I don't want it. Sean
Oct 04 2008
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Sean Kelly wrote:
 Is there anything this change in syntax 
 gives us over what we currently have?  If not, I don't want it.

It's purely aesthetic. There are no technical advantages of one over the other.
Oct 04 2008
next sibling parent reply =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Walter Bright wrote:
 Sean Kelly wrote:
 Is there anything this change in syntax gives us over what we 
 currently have?  If not, I don't want it.

It's purely aesthetic. There are no technical advantages of one over the other.

“T!()” just works. There’s no other meaning to it than template instantiation, whereas ”.” is heavily used as member accessor. I don’t see any technical or even aesthetical advantages here that might help understanding code. I just don’t get it.
Oct 04 2008
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Oct 04 2008
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== 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.
Oct 04 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Oct 04 2008
next sibling parent reply superdan <super dan.org> writes:
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.
Oct 04 2008
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

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.

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 guess this still counts as a vote! No? :o) Andrei
Oct 04 2008
prev sibling parent reply "Chris R. Miller" <lordsauronthegreat gmail.com> writes:
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

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.

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.
Oct 05 2008
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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

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.

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
Oct 05 2008
parent Lutger <lutger.blijdestijn gmail.com> writes:
Andrei Alexandrescu wrote:

...
 No go due to #line. :o(
 
 Andrei

Perhaps this is silly, but if #line is the sole blocker, then why not change #line? That feature seems so small in comparison to template instantiation, it isn't fair to get the nicer symbol.
Oct 06 2008
prev sibling parent KennyTM~ <kennytm gmail.com> writes:
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

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.

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.

Sorry, ` is not possible because of `string like = this.toString();`.
Oct 05 2008
prev sibling parent reply Janderson <ask me.com> writes:
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

I guess if you want to make template look like normal code your could look at extending that static syntax to accept things like alias: void FooTemplate(alias T, alias T2, static T x, T2 f) { ... } //call int value; FooTemplate(int, int, 10, value); //And with induction T2 can be solved so (Note: I'm considering induction either all that can be solved, or nothing) FooTemplate(int, 10, value); -Joel
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Janderson 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

I guess if you want to make template look like normal code your could look at extending that static syntax to accept things like alias: void FooTemplate(alias T, alias T2, static T x, T2 f) { ... } //call int value; FooTemplate(int, int, 10, value); //And with induction T2 can be solved so (Note: I'm considering induction either all that can be solved, or nothing) FooTemplate(int, 10, value); -Joel

Walter actually went out implementing this for days and reached irreconcilable issues. Andrei
Oct 05 2008
parent Janderson <ask me.com> writes:
Andrei Alexandrescu wrote:
 Janderson 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

I guess if you want to make template look like normal code your could look at extending that static syntax to accept things like alias: void FooTemplate(alias T, alias T2, static T x, T2 f) { ... } //call int value; FooTemplate(int, int, 10, value); //And with induction T2 can be solved so (Note: I'm considering induction either all that can be solved, or nothing) FooTemplate(int, 10, value); -Joel

Walter actually went out implementing this for days and reached irreconcilable issues. Andrei

That's a shame :(
Oct 05 2008
prev sibling next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
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. Can't {} be used for that? For example: List{int} someList; void foo{T}(T val) { } It seems more quiet. :-) The only thing is, I don't know if this can lead to ambiguos parsing. I thought about it a little, and it seems it's ok. Another thing is that maybe { and ( look alike, so it can lead to confusion... Oh, mmm... does it conflict with struct initializers?
Oct 04 2008
parent reply "Chris R. Miller" <lordsauronthegreat gmail.com> writes:
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).
Oct 05 2008
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2008-10-05 20:57:31 -0400, "Chris R. Miller" 
<lordsauronthegreat gmail.com> said:

 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).

Well, not so sure about that: I'm pretty sure it's needed for disambiguation too. Let's say you have: void foo(int x)(); void foo(T)(T x); foo(5); Is foo(5) a the same as foo!(5), or does it call foo!(int).foo(5) ? Under the current rules, it's the second (you can write foo!(5) to call the first). If you allow templates to be instanciated without the "!", then I guess both will match and you'll have ambiguity. If you could avoid having sets of parameters, one for the function and one for the template, then you could get rid of the "!" in a snap... Well, maybe not. You'll still have to resolve the same issues for constructors: class A(int x) { this() {} } class A() { this(int x) {} } auto a = new A(5); Perhaps this is not a problem however: the only two valid ways to create an instance of one or the other are "new A!(5)" or "new A!()(5)", which would translate in non-"!" syntax as: "new A(5)" and "new A()(5)". Unfortunately, we don't have this "luck" with functions. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Oct 05 2008
next sibling parent reply Vincent Richomme <forumer smartmobili.com> writes:
Michel Fortin a crit :
 On 2008-10-05 20:57:31 -0400, "Chris R. Miller" 
 <lordsauronthegreat gmail.com> said:
 
 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).


What about the ^ ? I think it's not worst than ! foo^(int)(bar) but maybe this symbol is already used by D ? Personally I would prefer to keep the C++, Java, C# syntax with <> because people are used to it even if in some cases it looks like a bit shift op.
Oct 05 2008
next sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
Vincent Richomme wrote:
 Michel Fortin a crit :
 On 2008-10-05 20:57:31 -0400, "Chris R. Miller" 
 <lordsauronthegreat gmail.com> said:

 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).


What about the ^ ? I think it's not worst than ! foo^(int)(bar) but maybe this symbol is already used by D ? Personally I would prefer to keep the C++, Java, C# syntax with <> because people are used to it even if in some cases it looks like a bit shift op.

The problem isn't what it looks like to people -- people will generally be able to discern a template instantiation/declaration from a bitshift. The problem is what it looks like to the compiler. If we had this in the compiler, the compiler would need to resolve symbols before it was able to produce a full parse tree, which leads to slower compilation times, more difficult tool creation, and a whole slew of other problems.
Oct 05 2008
prev sibling parent reply KennyTM~ <kennytm gmail.com> writes:
Vincent Richomme wrote:
 Michel Fortin a écrit :
 On 2008-10-05 20:57:31 -0400, "Chris R. Miller" 
 <lordsauronthegreat gmail.com> said:

 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).


What about the ^ ? I think it's not worst than ! foo^(int)(bar) but maybe this symbol is already used by D ? Personally I would prefer to keep the C++, Java, C# syntax with <> because people are used to it even if in some cases it looks like a bit shift op.

^ is for bitwise XOR! Unless you use ^^ foo^^(int)(bar) Not my cup of tea though.
Oct 05 2008
parent reply Vincent Richomme <forumer smartmobili.com> writes:
KennyTM~ a écrit :
 Vincent Richomme wrote:
 Michel Fortin a écrit :
 On 2008-10-05 20:57:31 -0400, "Chris R. Miller" 
 <lordsauronthegreat gmail.com> said:

 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).


What about the ^ ? I think it's not worst than ! foo^(int)(bar) but maybe this symbol is already used by D ? Personally I would prefer to keep the C++, Java, C# syntax with <> because people are used to it even if in some cases it looks like a bit shift op.

^ is for bitwise XOR!

Just look at managed c++ in .NET and tell me if ^ is always a bitwise XOR.
 Unless you use ^^
 
   foo^^(int)(bar)
 
 Not my cup of tea though.

Oct 05 2008
parent KennyTM~ <kennytm gmail.com> writes:
Vincent Richomme wrote:
 KennyTM~ a écrit :
 Vincent Richomme wrote:
 Michel Fortin a écrit :
 On 2008-10-05 20:57:31 -0400, "Chris R. Miller" 
 <lordsauronthegreat gmail.com> said:

 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).


What about the ^ ? I think it's not worst than ! foo^(int)(bar) but maybe this symbol is already used by D ? Personally I would prefer to keep the C++, Java, C# syntax with <> because people are used to it even if in some cases it looks like a bit shift op.

^ is for bitwise XOR!

Just look at managed c++ in .NET and tell me if ^ is always a bitwise XOR.

OK. The *binary* operator ^ is for bitwise XOR! And the ^ in foo^(int) acts as a *binary* operator also. And in C++/CLI the ^ in int^ and ^x acts as a *unary* operator, so no problem in this case. AFAIK one of the reason ! was chosen because a!b doesn't make sense in C, so D is free to use ! as a *binary* operator.
 
 Unless you use ^^

   foo^^(int)(bar)

 Not my cup of tea though.


Oct 05 2008
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2008-10-05 22:23:16 -0400, Michel Fortin <michel.fortin michelf.com> said:

 Well, not so sure about that: I'm pretty sure it's needed for 
 disambiguation too. Let's say you have:
 
 	void foo(int x)();
 	void foo(T)(T x);
 
 	foo(5);
 
 Is foo(5) a the same as foo!(5), or does it call foo!(int).foo(5) ? 
 Under the current rules, it's the second (you can write foo!(5) to call 
 the first). If you allow templates to be instanciated without the "!", 
 then I guess both will match and you'll have ambiguity.
 
 If you could avoid having sets of parameters, one for the function and 
 one for the template, then you could get rid of the "!" in a snap...

Or... we could just disallow having both at the same time, just like you can't have two functions with the same arguments. A call to foo(5) would be ambigous in the above situation, plain and simple. Is this reasonable? We could still disambiguate using: foo!(5); and: foo(int)(5); In this context, the ! becomes the "force this to be template arguments" operator, or the "do not deduce template arguments, I'll provide them" operator. Or we could just forget ! completely and leave the first one impossible to disambiguate. Which makes me think that it's sad we can't write the second as: foo(int, 5); I'd be much nicer to the eye. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Oct 06 2008
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Mon, Oct 6, 2008 at 9:16 AM, Denis Koroskin <2korden gmail.com> wrote:
 On Mon, 06 Oct 2008 16:42:51 +0400, Jarrett Billingsley
 <jarrett.billingsley gmail.com> wrote:

 On Mon, Oct 6, 2008 at 6:59 AM, Denis Koroskin <2korden gmail.com> wrote:

 If we don't omit parenthesises, the ambiguity goes away:

 foo()(5)
 foo(5)()

Stdout("foo")("bar!").newline;

paranthesises.

The point is that something like "foo()(5)" could then be either a template instantiation or a chained call.

I think there is ambiguity, and another problem is that we wanted to make things "better"; under these circumstances, terser would be better. Andrei
Oct 06 2008
prev sibling parent reply Benji Smith <dlanguage benjismith.net> writes:
Jarrett Billingsley wrote:
 On Mon, Oct 6, 2008 at 6:59 AM, Denis Koroskin <2korden gmail.com> wrote:
 
 If we don't omit parenthesises, the ambiguity goes away:

 foo()(5)
 foo(5)()

No it doesn't. Stdout("foo")("bar!").newline;

This is one of the main reasons I dislike opCall. Combined with optional-parentheses for function invocation, opCall is a poison-pill that creates a lot of potential ambiguities and prevents the implementation of more compelling features. --benji
Oct 07 2008
parent Benji Smith <dlanguage benjismith.net> writes:
Simen Kjaeraas wrote:
 On Tue, 07 Oct 2008 16:27:00 +0200, Benji Smith 
 <dlanguage benjismith.net> wrote:
 
 Jarrett Billingsley wrote:
 On Mon, Oct 6, 2008 at 6:59 AM, Denis Koroskin <2korden gmail.com> 
 wrote:

 If we don't omit parenthesises, the ambiguity goes away:

 foo()(5)
 foo(5)()

Stdout("foo")("bar!").newline;

This is one of the main reasons I dislike opCall. Combined with optional-parentheses for function invocation, opCall is a poison-pill that creates a lot of potential ambiguities and prevents the implementation of more compelling features. --benji

void delegate() foo() { return delegate void() {);}; } ?

Is that supposed to be legal code? I'll assume this is what you meant to write: void delegate() foo() { return delegate void() { }; } ...and that you're making the point that opCall introduces no more ambiguities than delegate-call syntax. And I suppose you're right. But people use opCall *everywhere* for all sorts of crazy crap, and I think it makes the code far less readable. When the call syntax is used for actual delegates, I don't really mind. But I think call-chaining with opCall is a huge eye-sore: object(x)("hello")(); I guess my ambiguity argument is invalidated by wanting to keep the delegate-call syntax. I just hate when it's applied to non-delegates. --benji
Oct 08 2008
prev sibling parent reply Benji Smith <dlanguage benjismith.net> writes:
Jarrett Billingsley wrote:
 On Sun, Oct 5, 2008 at 8:57 PM, Chris R. Miller
 <lordsauronthegreat gmail.com> wrote:
 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).

Unambiguous grammar, you fail it. foo(bar)(baz); // template instantiation or a chained call? This _can_ be _made_ to work, but it would mean that the parse tree would be dependent upon semantic analysis, and that just makes things slow and awful. I.e. C++.

I'd be happy to get rid of OpCall, which I've always found confusing and pointless. --benji
Oct 06 2008
parent reply KennyTM~ <kennytm gmail.com> writes:
Benji Smith wrote:
 Jarrett Billingsley wrote:
 On Sun, Oct 5, 2008 at 8:57 PM, Chris R. Miller
 <lordsauronthegreat gmail.com> wrote:
 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).

Unambiguous grammar, you fail it. foo(bar)(baz); // template instantiation or a chained call? This _can_ be _made_ to work, but it would mean that the parse tree would be dependent upon semantic analysis, and that just makes things slow and awful. I.e. C++.

I'd be happy to get rid of OpCall, which I've always found confusing and pointless. --benji

That's going to break a lot of struct constructors using static opCalls.
Oct 06 2008
parent reply Benji Smith <dlanguage benjismith.net> writes:
KennyTM~ wrote:
 Benji Smith wrote:
 Jarrett Billingsley wrote:
 On Sun, Oct 5, 2008 at 8:57 PM, Chris R. Miller
 <lordsauronthegreat gmail.com> wrote:
 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).

Unambiguous grammar, you fail it. foo(bar)(baz); // template instantiation or a chained call? This _can_ be _made_ to work, but it would mean that the parse tree would be dependent upon semantic analysis, and that just makes things slow and awful. I.e. C++.

I'd be happy to get rid of OpCall, which I've always found confusing and pointless. --benji

That's going to break a lot of struct constructors using static opCalls.

Only because structs should have had constructors from the start. Using opCall was always a hack around the lack of constructors on structs. opCall is a source of numerous language ambiguities that make other features more difficult to implement. For example, template instantiation could be done with bare parentheses ("Template(args)" instead of "Template!(args)" or "Template{args}") if opCall was eliminated. --benji
Oct 07 2008
parent reply KennyTM~ <kennytm gmail.com> writes:
Benji Smith wrote:
 KennyTM~ wrote:
 Benji Smith wrote:
 Jarrett Billingsley wrote:
 On Sun, Oct 5, 2008 at 8:57 PM, Chris R. Miller
 <lordsauronthegreat gmail.com> wrote:
 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).

Unambiguous grammar, you fail it. foo(bar)(baz); // template instantiation or a chained call? This _can_ be _made_ to work, but it would mean that the parse tree would be dependent upon semantic analysis, and that just makes things slow and awful. I.e. C++.

I'd be happy to get rid of OpCall, which I've always found confusing and pointless. --benji

That's going to break a lot of struct constructors using static opCalls.

Only because structs should have had constructors from the start. Using opCall was always a hack around the lack of constructors on structs. opCall is a source of numerous language ambiguities that make other features more difficult to implement. For example, template instantiation could be done with bare parentheses ("Template(args)" instead of "Template!(args)" or "Template{args}") if opCall was eliminated. --benji

But what about a method that returns a delegate?
Oct 07 2008
parent reply Benji Smith <dlanguage benjismith.net> writes:
KennyTM~ wrote:
 Benji Smith wrote:
 KennyTM~ wrote:
 Benji Smith wrote:
 Jarrett Billingsley wrote:
 On Sun, Oct 5, 2008 at 8:57 PM, Chris R. Miller
 <lordsauronthegreat gmail.com> wrote:
 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).

Unambiguous grammar, you fail it. foo(bar)(baz); // template instantiation or a chained call? This _can_ be _made_ to work, but it would mean that the parse tree would be dependent upon semantic analysis, and that just makes things slow and awful. I.e. C++.

I'd be happy to get rid of OpCall, which I've always found confusing and pointless. --benji

That's going to break a lot of struct constructors using static opCalls.

Only because structs should have had constructors from the start. Using opCall was always a hack around the lack of constructors on structs. opCall is a source of numerous language ambiguities that make other features more difficult to implement. For example, template instantiation could be done with bare parentheses ("Template(args)" instead of "Template!(args)" or "Template{args}") if opCall was eliminated. --benji

But what about a method that returns a delegate?

Damn. You win. Hmmmmmm... I still hate opCall, though :) --benji
Oct 07 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Benji Smith wrote:
 Hmmmmmm... I still hate opCall, though :)

One context in which I found opCall very valuable is parameterized functions: functions that take, say, 1 argument but are parameterized by another. An example is a Gaussian kernel of parameterized bandwidth: double gaussianKernel(double d) { return exp(-d * d / alpha * alpha); } We'd like to be able to configure alpha properly (not via a global, because there could be several Gaussian kernels around). A solution would be to use delegates, but that's inefficient and a kernel is evaluated so often it's not even funny. So a good solution is to make the function a struct with state: struct GaussianKernel { private double alpha2InvNeg = -1; double opCall(double d) const { return exp(d * d * alpha2InvNeg); } void alpha(double a) { enforce(a > 0); alpha2InvNeg = -1 / (a * a); } double alpha() const { return sqrt(-1 / alpha2InvNeg); } } Andrei
Oct 07 2008
parent Benji Smith <dlanguage benjismith.net> writes:
Andrei Alexandrescu wrote:
 Benji Smith wrote:
 Hmmmmmm... I still hate opCall, though :)

One context in which I found opCall very valuable is parameterized functions: functions that take, say, 1 argument but are parameterized by another. An example is a Gaussian kernel of parameterized bandwidth: double gaussianKernel(double d) { return exp(-d * d / alpha * alpha); } We'd like to be able to configure alpha properly (not via a global, because there could be several Gaussian kernels around). A solution would be to use delegates, but that's inefficient and a kernel is evaluated so often it's not even funny. So a good solution is to make the function a struct with state: struct GaussianKernel { private double alpha2InvNeg = -1; double opCall(double d) const { return exp(d * d * alpha2InvNeg); } void alpha(double a) { enforce(a > 0); alpha2InvNeg = -1 / (a * a); } double alpha() const { return sqrt(-1 / alpha2InvNeg); } } Andrei

Great example! I've actually implemented the same thing (in Java). I have a KernelDensityEstimator class, for estimating the shape of a distribution, based on sample values from that distribution. The KDE constructor takes a Function object to define the kernel. (Rather than defining a "Kernel" as an interface or an abstract class, I define a more general "Function" interface, and let the caller make his own choice about whether his function makes an appropriate kernel.) So the code looks like this: interface Function { public double project(double value); } class GaussianFunction implements Function { private double height; private double mean; private double stdev; private double denominator; public GaussianFunction(double height, double mean, double stdev) { enforce(height > 0); enforce(!Double.isInfinite(height)); enforce(!Double.isNaN(height)); enforce(!Double.isInfinite(mean)); enforce(!Double.isNaN(mean)); enforce(stdev > 0); enforce(!Double.isInfinite(stdev)); enforce(!Double.isNaN(stdev)); this.height = height; this.mean = mean; this.stdev = stdev; // Pre-calculate the denominator of the exponent // (since it won't vary from call to call). this.denominator = 2 * stdev * stdev; } public double project(double value) { double difference = x - mean; double numerator = difference * difference; return height * Math.exp(- (numerator / denominator)); } } class KernelDensityEstimator { private Function kernel; private List<Double> samples; public KernelDensityEstimator(Function kernel) { this.kernel = kernel; this.samples = new ArrayList<Double>(); } public double addSample(double sample) { samples.add(sample); } public estimatedProbabilityOf(double value) { double sum = 0; for (double sample : samples) { sum += kernel.project(sample); } return sum / samples.size(); } } Anyhoo... maybe that's a little too much code to dump, but I wanted to show the definition of the concept of a "Function", separated from the definition of a particular function class, separated from the instantiation of that class, and separated from the invocation of the function. In my mind, opCall would encourage code like this: foreach (double x; values) { GaussianKernel(alpha)(x); } In this code, the alpha gets set... over and over and over again. If the construction of the parametric function is distinct from the calling of it, the user is encouraged to write code more like this: auto kernel = new GuassianKernel(alpha); foreach (double x; values) { auto result = kernel.valueOf(x); } It can be convincingly argued that a Function object shouldn't have a *named* method. Or at least, if it does have a named method, the name should be the same at the name of the function. But then that makes it hard to use functions polymorphically. What you and I are doing is pretty much the same, except that I call my function "project" (since a function is a projection from an x value to a corresponding y value), whereas you use opCall. The nice thing about using a named function, though, is that it allows me to pass functions around polymorphically, and since Java doesn't have function pointers, this is the best solution to the problem. I totally agree with you, though, that this is the best possible use for opCall. --benji
Oct 07 2008
prev sibling next sibling parent reply =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Andrei Alexandrescu wrote:
 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.

Sean has a point. Templates are not runtime constructs. So a clear distinction between instantiating a function with a given type and just calling a function that has fixed argument types and a fixed return type is necessary. The exclamation mark gives us this clear distinction and has served well in terms of readability for me, especially because it jumps out — not because it’s an exclamation mark, thus having a meaning in natural language, but rather just because of its form. A straight vertical line with a dot underneath it. That just works perfectly well as seperator between identifier/type and type argument. Also, you might want to consider changing your font if exclamation marks jump at you so intensively. ;)
Oct 04 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Alexander Pánek wrote:
 Andrei Alexandrescu wrote:
 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.

Sean has a point. Templates are not runtime constructs. So a clear distinction between instantiating a function with a given type and just calling a function that has fixed argument types and a fixed return type is necessary.

Why? This sounds objective, so you better back it up. Au contraire, I see absolutely, but absolutely no need for a distinction. If it weren't for syntactic difficulties, to me using straight parentheses for template instantiation would have been the perfect choice. (How many times did you just forget the "!"? I know I often do. Why? Because most of the time it's not even needed.)
 The exclamation mark gives us this clear distinction and 
 has served well in terms of readability for me, especially because it 
 jumps out — not because it’s an exclamation mark, thus having a meaning 
 in natural language, but rather just because of its form. A straight 
 vertical line with a dot underneath it. That just works perfectly well 
 as seperator between identifier/type and type argument.

I believe the clear distinction is not only unnecessary, but undesirable. We should actively fight against it.
 Also, you might want to consider changing your font if exclamation marks 
 jump at you so intensively. ;)

I use Vera, probably the best code font I've ever had. Andrei
Oct 04 2008
next sibling parent reply =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Andrei Alexandrescu wrote:
 Alexander Pánek wrote:
 Andrei Alexandrescu wrote:
 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.

Sean has a point. Templates are not runtime constructs. So a clear distinction between instantiating a function with a given type and just calling a function that has fixed argument types and a fixed return type is necessary.

Why? This sounds objective, so you better back it up. Au contraire, I see absolutely, but absolutely no need for a distinction. If it weren't for syntactic difficulties, to me using straight parentheses for template instantiation would have been the perfect choice. (How many times did you just forget the "!"? I know I often do. Why? Because most of the time it's not even needed.)
 The exclamation mark gives us this clear distinction and has served 
 well in terms of readability for me, especially because it jumps out — 
 not because it’s an exclamation mark, thus having a meaning in natural 
 language, but rather just because of its form. A straight vertical 
 line with a dot underneath it. That just works perfectly well as 
 seperator between identifier/type and type argument.

I believe the clear distinction is not only unnecessary, but undesirable. We should actively fight against it.

IMHO — I forgot that before, so that’s why it might have sounded a bit too objective —, the clear distinction is important to keep the code self-documenting. It might not be so important in terms of freestanding templated functions that might even be simple enough that the argument types can be infered, but as soon as something heavily alters the way the code and the binary looks like afterwards (CTFE, multiple templated class/struct/function instantiates, string mixins created by CTFE functions, etc.), it (again, in my truly subjective opinion) deserves to be marked as such. I see this distinction as feature, not as flaw.
Oct 04 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Alexander Pánek wrote:
 Andrei Alexandrescu wrote:
 Alexander Pánek wrote:
 Andrei Alexandrescu wrote:
 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.

Sean has a point. Templates are not runtime constructs. So a clear distinction between instantiating a function with a given type and just calling a function that has fixed argument types and a fixed return type is necessary.

Why? This sounds objective, so you better back it up. Au contraire, I see absolutely, but absolutely no need for a distinction. If it weren't for syntactic difficulties, to me using straight parentheses for template instantiation would have been the perfect choice. (How many times did you just forget the "!"? I know I often do. Why? Because most of the time it's not even needed.)
 The exclamation mark gives us this clear distinction and has served 
 well in terms of readability for me, especially because it jumps out 
 — not because it’s an exclamation mark, thus having a meaning in 
 natural language, but rather just because of its form. A straight 
 vertical line with a dot underneath it. That just works perfectly 
 well as seperator between identifier/type and type argument.

I believe the clear distinction is not only unnecessary, but undesirable. We should actively fight against it.

IMHO — I forgot that before, so that’s why it might have sounded a bit too objective —, the clear distinction is important to keep the code self-documenting. It might not be so important in terms of freestanding templated functions that might even be simple enough that the argument types can be infered, but as soon as something heavily alters the way the code and the binary looks like afterwards (CTFE, multiple templated class/struct/function instantiates, string mixins created by CTFE functions, etc.), it (again, in my truly subjective opinion) deserves to be marked as such. I see this distinction as feature, not as flaw.

I don't understand this argument. For one thing, argument type deduction for template functions is not simple at all and we're glad that it's taken care of. Andrei
Oct 04 2008
prev sibling next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Andrei Alexandrescu wrote:
 Alexander Pánek wrote:
 Andrei Alexandrescu wrote:
 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.

Sean has a point. Templates are not runtime constructs. So a clear distinction between instantiating a function with a given type and just calling a function that has fixed argument types and a fixed return type is necessary.

Why? This sounds objective, so you better back it up.

I like being able to distinguish between the function signature and the parameter list and to tell at a glance what's actually happening. Since the dot already has a function in this context, I don't think it should be given another. Also, if we get the option to override opDot, things could get really weird if it's also a template signifier.
 The exclamation mark gives us this clear distinction and has served 
 well in terms of readability for me, especially because it jumps out — 
 not because it’s an exclamation mark, thus having a meaning in natural 
 language, but rather just because of its form. A straight vertical 
 line with a dot underneath it. That just works perfectly well as 
 seperator between identifier/type and type argument.

I believe the clear distinction is not only unnecessary, but undesirable. We should actively fight against it.

Why is it undesirable? I like the idea of static parameters as described at the conference last year, but I don't think that has any bearing on this particular issue. Sean
Oct 04 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Sean Kelly wrote:
 Andrei Alexandrescu wrote:
 I believe the clear distinction is not only unnecessary, but 
 undesirable. We should actively fight against it.

Why is it undesirable? I like the idea of static parameters as described at the conference last year, but I don't think that has any bearing on this particular issue.

Time and again, both Walter and myself have met people who experience a mental block whenever templates come within a mile. The fact that they come with the sign Here! This! Is! A! Template! doesn't help any. Andrei
Oct 05 2008
parent "Chris R. Miller" <lordsauronthegreat gmail.com> writes:
Andrei Alexandrescu wrote:
 Sean Kelly wrote:
 Andrei Alexandrescu wrote:
 I believe the clear distinction is not only unnecessary, but 
 undesirable. We should actively fight against it.

Why is it undesirable? I like the idea of static parameters as described at the conference last year, but I don't think that has any bearing on this particular issue.

Time and again, both Walter and myself have met people who experience a mental block whenever templates come within a mile. The fact that they come with the sign Here! This! Is! A! Template! doesn't help any.

Are we discussing better template syntax of a magical injection that will cure the common fear of template code? ;-)
Oct 05 2008
prev sibling parent Sergey Gromov <snake.scaly gmail.com> writes:
Sat, 04 Oct 2008 23:50:47 -0500,
Andrei Alexandrescu wrote:
 Alexander Panek wrote:
 Andrei Alexandrescu wrote:
 The problem I see with "!" as a template instantiation is not=20
 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=20
 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=20
 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=20
 natural language "!". In D, binary "!" _always_ follows a word, a=20
 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=20
 believe that using .() can make templates more palatable. I tried=20
 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=20
 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,=20
 and still is, made in D to avoid shell-shocking people about use of=20
 templates, and I think ".()" would be a good step in that direction.

Sean has a point. Templates are not runtime constructs. So a clear=20 distinction between instantiating a function with a given type and just=


 calling a function that has fixed argument types and a fixed return typ=


  is necessary.

Why? This sounds objective, so you better back it up. Au contraire, I=20 see absolutely, but absolutely no need for a distinction. If it weren't=

 for syntactic difficulties, to me using straight parentheses for=20
 template instantiation would have been the perfect choice. (How many=20
 times did you just forget the "!"? I know I often do. Why? Because most=

 of the time it's not even needed.)
=20
 The exclamation mark gives us this clear distinction and=20
 has served well in terms of readability for me, especially because it=


 jumps out ? not because it?s an exclamation mark, thus having a meaning=


 in natural language, but rather just because of its form. A straight=20
 vertical line with a dot underneath it. That just works perfectly well=


 as seperator between identifier/type and type argument.

I believe the clear distinction is not only unnecessary, but=20 undesirable. We should actively fight against it.

You have a problem with shouting. Not everyone has. The distinction is important IMHO because the choice between template=20 and runtime is a speed/size tradeoff choice. It's better to make it=20 explicitly.
Oct 06 2008
prev sibling next sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Andrei Alexandrescu wrote:
 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.

Not only that, but typing it is annoying. First you need to put the right pinky on the shift key, which is a long reach; then you need to put the left pinky on the 1 key, which is a long reach. Then you need to move your left pinky all the way back to the left shift key, which is a short reach, and move your right ring finger up to the 9 key. It's a lot of reaching and back and forth. But I don't favor '.' since it's already used.
Oct 04 2008
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Christopher Wright wrote:
 Andrei Alexandrescu wrote:
 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.

Not only that, but typing it is annoying. First you need to put the right pinky on the shift key, which is a long reach; then you need to put the left pinky on the 1 key, which is a long reach. Then you need to move your left pinky all the way back to the left shift key, which is a short reach, and move your right ring finger up to the 9 key. It's a lot of reaching and back and forth. But I don't favor '.' since it's already used.

I don't favor "." any more than the next guy, but I am glad there is awareness of how unfit a choice "!" is. If you have any ideas, please post them! Ah! I! Exclaimed! Again! Andrei!
Oct 04 2008
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 I don't favor "." any more than the next guy, but I am glad there is 
 awareness of how unfit a choice "!" is. If you have any ideas, please 
 post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke); Anything else I forgot? Or we could use special delimiter characters: Positive<real>(joke); Positive“real”(joke); Positive«real»(joke); Positive#real (joke); Each having its own problem though. My preference still goes to "!(". - - - The ".(" syntax makes me think more of something like this: void func(T, alias methodOfT, A...)(T obj, A args) { obj.(methodOfT)(args); } which I which I could do. If methodOfT was a string, I suppose I could use string mixins, but it pushes diagnostics about misnamed methods further in the template and requires adding quotes to the template parameter when instanciating. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Oct 05 2008
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:
 
 I don't favor "." any more than the next guy, but I am glad there is 
 awareness of how unfit a choice "!" is. If you have any ideas, please 
 post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke); Anything else I forgot? Or we could use special delimiter characters: Positive<real>(joke); Positive“real”(joke); Positive«real»(joke); Positive#real (joke); Each having its own problem though. My preference still goes to "!(". - - - The ".(" syntax makes me think more of something like this: void func(T, alias methodOfT, A...)(T obj, A args) { obj.(methodOfT)(args); } which I which I could do. If methodOfT was a string, I suppose I could use string mixins, but it pushes diagnostics about misnamed methods further in the template and requires adding quotes to the template parameter when instanciating.

Argh, actually I once have a strong desire making f«T»(x); a valid construct, and to workaround that « and » can't be easily typed you could substitute it with f\<T\>(x); --- Anyway, I think the .() syntax is not as good as !() because the . is pretty hideous before another punctuation mark (which may be a good thing, I don't know), and one could easily miss it. And even if .() is allowed, please don't remove !() -- it will break significantly many code, and it doesn't cause any ambiguity either (unlike .func() vs .prop).
Oct 05 2008
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
KennyTM~ wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 I don't favor "." any more than the next guy, but I am glad there is 
 awareness of how unfit a choice "!" is. If you have any ideas, please 
 post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke); Anything else I forgot? Or we could use special delimiter characters: Positive<real>(joke); Positive“real”(joke); Positive«real»(joke); Positive#real (joke); Each having its own problem though. My preference still goes to "!(". - - - The ".(" syntax makes me think more of something like this: void func(T, alias methodOfT, A...)(T obj, A args) { obj.(methodOfT)(args); } which I which I could do. If methodOfT was a string, I suppose I could use string mixins, but it pushes diagnostics about misnamed methods further in the template and requires adding quotes to the template parameter when instanciating.

Argh, actually I once have a strong desire making f«T»(x); a valid construct, and to workaround that « and » can't be easily typed you could substitute it with f\<T\>(x); ---

Yah I would've like French quotes too.
 Anyway, I think the .() syntax is not as good as !() because the . is 
 pretty hideous before another punctuation mark (which may be a good 
 thing, I don't know), and one could easily miss it.
 
 And even if .() is allowed, please don't remove !() -- it will break 
 significantly many code, and it doesn't cause any ambiguity either 
 (unlike .func() vs .prop).

Many languages have successfully dealt with similar situations by simply allowing both but promoting only one in books and other documentation. Speaking of which, I'm on verge of signing with Addison Wesley Longman for delivering TDPL in April. Andrei
Oct 05 2008
prev sibling parent reply Gregor Richards <Richards codu.org> writes:
KennyTM~ wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 I don't favor "." any more than the next guy, but I am glad there is 
 awareness of how unfit a choice "!" is. If you have any ideas, please 
 post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke); Anything else I forgot? Or we could use special delimiter characters: Positive<real>(joke); Positive“real”(joke); Positive«real»(joke); Positive#real (joke); Each having its own problem though. My preference still goes to "!(". - - - The ".(" syntax makes me think more of something like this: void func(T, alias methodOfT, A...)(T obj, A args) { obj.(methodOfT)(args); } which I which I could do. If methodOfT was a string, I suppose I could use string mixins, but it pushes diagnostics about misnamed methods further in the template and requires adding quotes to the template parameter when instanciating.

Argh, actually I once have a strong desire making f«T»(x); a valid construct, and to workaround that « and » can't be easily typed you could substitute it with f\<T\>(x);

Yes. Trigraphs were such a good idea in C, let's bring them to D X_X - Gregor Richards
Oct 05 2008
parent KennyTM~ <kennytm gmail.com> writes:
Gregor Richards wrote:
 KennyTM~ wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 I don't favor "." any more than the next guy, but I am glad there is 
 awareness of how unfit a choice "!" is. If you have any ideas, 
 please post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke); Anything else I forgot? Or we could use special delimiter characters: Positive<real>(joke); Positive“real”(joke); Positive«real»(joke); Positive#real (joke); Each having its own problem though. My preference still goes to "!(". - - - The ".(" syntax makes me think more of something like this: void func(T, alias methodOfT, A...)(T obj, A args) { obj.(methodOfT)(args); } which I which I could do. If methodOfT was a string, I suppose I could use string mixins, but it pushes diagnostics about misnamed methods further in the template and requires adding quotes to the template parameter when instanciating.

Argh, actually I once have a strong desire making f«T»(x); a valid construct, and to workaround that « and » can't be easily typed you could substitute it with f\<T\>(x);

Yes. Trigraphs were such a good idea in C, let's bring them to D X_X - Gregor Richards

It has been done with Pascal ( {comment} = (*comment*) } already. And the \ character is used to escape stuffs already, so no problem like writing "what??!" in C. And technically it's just a digraph, so at most it is only 67% as evil as trigraphs <g>. OK I'm just joking :p.
Oct 05 2008
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:
 
 I don't favor "." any more than the next guy, but I am glad there is 
 awareness of how unfit a choice "!" is. If you have any ideas, please 
 post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke); Anything else I forgot? Or we could use special delimiter characters: Positive<real>(joke); Positive“real”(joke); Positive«real»(joke); Positive#real (joke); Each having its own problem though. My preference still goes to "!(".

There was also Positive{real}(joke), with which I couldn't find an ambiguity.
 - - -
 
 The ".(" syntax makes me think more of something like this:
 
     void func(T, alias methodOfT, A...)(T obj, A args)
     {
         obj.(methodOfT)(args);
     }
 
 which I which I could do. If methodOfT was a string, I suppose I could 
 use string mixins, but it pushes diagnostics about misnamed methods 
 further in the template and requires adding quotes to the template 
 parameter when instanciating.

Given that methodOfT is an alias, there is no need for the parens. Andrei
Oct 05 2008
parent reply KennyTM~ <kennytm gmail.com> writes:
Andrei Alexandrescu wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 -- snip --

 Or we could use special delimiter characters:

     Positive<real>(joke);
     Positive“real”(joke);
     Positive«real»(joke);
     Positive#real (joke);

 Each having its own problem though.

 My preference still goes to "!(".

There was also Positive{real}(joke), with which I couldn't find an ambiguity.

Ohhhh. Why isn't it considered then? (Suppose we already knew Positive is not a keyword and not preceded by the keywords struct, class, etc.)
 
 -- snip --

Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 -- snip --

 Or we could use special delimiter characters:

     Positive<real>(joke);
     Positive“real”(joke);
     Positive«real»(joke);
     Positive#real (joke);

 Each having its own problem though.

 My preference still goes to "!(".

There was also Positive{real}(joke), with which I couldn't find an ambiguity.

Ohhhh. Why isn't it considered then? (Suppose we already knew Positive is not a keyword and not preceded by the keywords struct, class, etc.)

I believe it should be considered. At some point there was discussion on accepting a last parameter of delegate type outside the function parens. The idea was to allow user-defined code to define constructs similar to e.g. if and foreach. But I think that has many other problems (one of which is that the delegate can't reasonably specify parameters), so we can safely discount that as a problem. I'd want to give it a try. How do others feel about Template{arguments}? Andrei
Oct 05 2008
next sibling parent =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Andrei Alexandrescu wrote:
 I'd want to give it a try. How do others feel about Template{arguments}?

I’m not sure. It looks somehow better when nesting template arguments, but {} doesn’t quite fit in as some kind of argument in a C-style language like D, I think. Template{int}(); // Looks awkward.
Oct 05 2008
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Andrei Alexandrescu" wrote
 KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 -- snip --

 Or we could use special delimiter characters:

     Positive<real>(joke);
     Positive"real"(joke);
     Positivereal(joke);
     Positive#real (joke);

 Each having its own problem though.

 My preference still goes to "!(".

There was also Positive{real}(joke), with which I couldn't find an ambiguity.

Ohhhh. Why isn't it considered then? (Suppose we already knew Positive is not a keyword and not preceded by the keywords struct, class, etc.)

I believe it should be considered. At some point there was discussion on accepting a last parameter of delegate type outside the function parens. The idea was to allow user-defined code to define constructs similar to e.g. if and foreach. But I think that has many other problems (one of which is that the delegate can't reasonably specify parameters), so we can safely discount that as a problem. I'd want to give it a try. How do others feel about Template{arguments}?

I like it much better than .() But I'd still vote for keeping !(), as I have no problems with it. -Steve
Oct 05 2008
prev sibling next sibling parent KennyTM~ <kennytm gmail.com> writes:
Andrei Alexandrescu wrote:
 KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 -- snip --

 Or we could use special delimiter characters:

     Positive<real>(joke);
     Positive“real”(joke);
     Positive«real»(joke);
     Positive#real (joke);

 Each having its own problem though.

 My preference still goes to "!(".

There was also Positive{real}(joke), with which I couldn't find an ambiguity.

Ohhhh. Why isn't it considered then? (Suppose we already knew Positive is not a keyword and not preceded by the keywords struct, class, etc.)

I believe it should be considered. At some point there was discussion on accepting a last parameter of delegate type outside the function parens. The idea was to allow user-defined code to define constructs similar to e.g. if and foreach.

Probably use func () { // some delegates } ? Just like what has been done to class invariants. But this may cause ambiguity if the 1st parameter of func is optional...
 But I think that has many other problems (one of which is that the 
 delegate can't reasonably specify parameters), so we can safely discount 
 that as a problem.
 
 I'd want to give it a try. How do others feel about Template{arguments}?
 
 
 Andrei

Oct 05 2008
prev sibling next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Andrei Alexandrescu escribió:
 KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 -- snip --

 Or we could use special delimiter characters:

     Positive<real>(joke);
     Positive“real”(joke);
     Positive«real»(joke);
     Positive#real (joke);

 Each having its own problem though.

 My preference still goes to "!(".

There was also Positive{real}(joke), with which I couldn't find an ambiguity.

Ohhhh. Why isn't it considered then? (Suppose we already knew Positive is not a keyword and not preceded by the keywords struct, class, etc.)

I believe it should be considered. At some point there was discussion on accepting a last parameter of delegate type outside the function parens. The idea was to allow user-defined code to define constructs similar to e.g. if and foreach. But I think that has many other problems (one of which is that the delegate can't reasonably specify parameters), so we can safely discount that as a problem. I'd want to give it a try. How do others feel about Template{arguments}?

I thought no one read my post, now I see you are discussing it in another thread. :-P After I posted, I also remembered the possibility of allowing delegate invocation in a nicer way, and that conflicts with Foo{T}. :-(
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Ary Borenszweig wrote:
 Andrei Alexandrescu escribió:
 KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 -- snip --

 Or we could use special delimiter characters:

     Positive<real>(joke);
     Positive“real”(joke);
     Positive«real»(joke);
     Positive#real (joke);

 Each having its own problem though.

 My preference still goes to "!(".

There was also Positive{real}(joke), with which I couldn't find an ambiguity.

Ohhhh. Why isn't it considered then? (Suppose we already knew Positive is not a keyword and not preceded by the keywords struct, class, etc.)

I believe it should be considered. At some point there was discussion on accepting a last parameter of delegate type outside the function parens. The idea was to allow user-defined code to define constructs similar to e.g. if and foreach. But I think that has many other problems (one of which is that the delegate can't reasonably specify parameters), so we can safely discount that as a problem. I'd want to give it a try. How do others feel about Template{arguments}?

I thought no one read my post, now I see you are discussing it in another thread. :-P After I posted, I also remembered the possibility of allowing delegate invocation in a nicer way, and that conflicts with Foo{T}. :-(

I think we can drop that. Even if we allow that, there will be parens needed before the delegate body, at least for passing it arguments. Andrei
Oct 05 2008
prev sibling next sibling parent Derek Parnell <derek psych.ward> writes:
On Sun, 05 Oct 2008 09:41:28 -0500, Andrei Alexandrescu wrote:


 I'd want to give it a try. How do others feel about Template{arguments}?

Not too shabby at all, really. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Oct 05 2008
prev sibling next sibling parent Leandro Lucarella <llucax gmail.com> writes:
Andrei Alexandrescu, el  5 de octubre a las 09:41 me escribiste:
 I'd want to give it a try. How do others feel about Template{arguments}?

I feel is unnecessary to change the template instantiation syntax. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- "CIRILO" Y "SIRACUSA" DE "SEÑORITA MAESTRA": UNO MUERTO Y OTRO PRESO -- Crónica TV
Oct 05 2008
prev sibling next sibling parent "Chris R. Miller" <lordsauronthegreat gmail.com> writes:
Andrei Alexandrescu wrote:
 KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 -- snip --

 Or we could use special delimiter characters:

     Positive<real>(joke);
     Positive“real”(joke);
     Positive«real»(joke);
     Positive#real (joke);

 Each having its own problem though.

 My preference still goes to "!(".

There was also Positive{real}(joke), with which I couldn't find an ambiguity.

Ohhhh. Why isn't it considered then? (Suppose we already knew Positive is not a keyword and not preceded by the keywords struct, class, etc.)

I believe it should be considered. At some point there was discussion on accepting a last parameter of delegate type outside the function parens. The idea was to allow user-defined code to define constructs similar to e.g. if and foreach. But I think that has many other problems (one of which is that the delegate can't reasonably specify parameters), so we can safely discount that as a problem. I'd want to give it a try. How do others feel about Template{arguments}?

I distrust it greatly. Too similar to a code block. I still have a lot of contact with kids still being educated in programming, and that'd probably just confuse the heck out of 'em. No on {}! Keep the code block sacred! ;-)
Oct 05 2008
prev sibling parent reply Benji Smith <dlanguage benjismith.net> writes:
Andrei Alexandrescu wrote:
 I'd want to give it a try. How do others feel about Template{arguments}?

At first glance, I like it better than !(), especially since it saves a character, making nested templates much nicer: auto map = new Map{T[], List{MyType}}(); // not too bad auto map = new Map!(T[], List!(MyType))(); // not too good auto map = new Map<T[], List<MyType>>(); // still my favorite It's too bad the shift operators can't be changed. Personally, I think the angle brackets are more valuable as a matched pair of enclosures. We could redefine the shift operators to be: --> RIGHT SHIFT <-- LEFT SHIFT -->> SIGNED RIGHT SHIFT And then the angle brackets could be coopted for templates. Of course, like I said before, I think it'd be especially cool if templates, as such, didn't exist. Instead, what if an ordinary function could return a Type, which could be used in a Type Constructor? Templates would vanish! It'd be CTFE, but for types instead of just for values. --benji
Oct 06 2008
next sibling parent KennyTM~ <kennytm gmail.com> writes:
Benji Smith wrote:
 Andrei Alexandrescu wrote:
 I'd want to give it a try. How do others feel about Template{arguments}?

At first glance, I like it better than !(), especially since it saves a character, making nested templates much nicer: auto map = new Map{T[], List{MyType}}(); // not too bad auto map = new Map!(T[], List!(MyType))(); // not too good auto map = new Map<T[], List<MyType>>(); // still my favorite It's too bad the shift operators can't be changed. Personally, I think the angle brackets are more valuable as a matched pair of enclosures. We could redefine the shift operators to be: --> RIGHT SHIFT <-- LEFT SHIFT -->> SIGNED RIGHT SHIFT And then the angle brackets could be coopted for templates. Of course, like I said before, I think it'd be especially cool if templates, as such, didn't exist. Instead, what if an ordinary function could return a Type, which could be used in a Type Constructor? Templates would vanish! It'd be CTFE, but for types instead of just for values. --benji

Another problem with < is that, if you're not confident that Map is really a template identifier, you'll have the ambiguity whether < is an open bracket or a less than sign. int x, y, w, z; writefln(x<y,w>(z)); // currently compiles.
Oct 06 2008
prev sibling parent reply =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Benji Smith wrote:
 Andrei Alexandrescu wrote:
 I'd want to give it a try. How do others feel about Template{arguments}?

At first glance, I like it better than !(), especially since it saves a character, making nested templates much nicer: auto map = new Map{T[], List{MyType}}(); // not too bad auto map = new Map!(T[], List!(MyType))(); // not too good auto map = new Map<T[], List<MyType>>(); // still my favorite It's too bad the shift operators can't be changed. Personally, I think the angle brackets are more valuable as a matched pair of enclosures. We could redefine the shift operators to be: --> RIGHT SHIFT <-- LEFT SHIFT -->> SIGNED RIGHT SHIFT And then the angle brackets could be coopted for templates.

No way! :( ’em pointed brackets are way too pointy. I like having parenthesis for templates.
Oct 06 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Alexander Pnek wrote:
 Benji Smith wrote:
 Andrei Alexandrescu wrote:
 I'd want to give it a try. How do others feel about Template{arguments}?

At first glance, I like it better than !(), especially since it saves a character, making nested templates much nicer: auto map = new Map{T[], List{MyType}}(); // not too bad auto map = new Map!(T[], List!(MyType))(); // not too good auto map = new Map<T[], List<MyType>>(); // still my favorite It's too bad the shift operators can't be changed. Personally, I think the angle brackets are more valuable as a matched pair of enclosures. We could redefine the shift operators to be: --> RIGHT SHIFT <-- LEFT SHIFT -->> SIGNED RIGHT SHIFT And then the angle brackets could be coopted for templates.

No way! :( em pointed brackets are way too pointy. I like having parenthesis for templates.

Well another problem is we'd need to redefine the less-than and greater-than operators too. Andrei
Oct 06 2008
parent Benji Smith <dlanguage benjismith.net> writes:
Andrei Alexandrescu wrote:
 Alexander Pnek wrote:
 Benji Smith wrote:
 Andrei Alexandrescu wrote:
 I'd want to give it a try. How do others feel about 
 Template{arguments}?

At first glance, I like it better than !(), especially since it saves a character, making nested templates much nicer: auto map = new Map{T[], List{MyType}}(); // not too bad auto map = new Map!(T[], List!(MyType))(); // not too good auto map = new Map<T[], List<MyType>>(); // still my favorite It's too bad the shift operators can't be changed. Personally, I think the angle brackets are more valuable as a matched pair of enclosures. We could redefine the shift operators to be: --> RIGHT SHIFT <-- LEFT SHIFT -->> SIGNED RIGHT SHIFT And then the angle brackets could be coopted for templates.

No way! :( em pointed brackets are way too pointy. I like having parenthesis for templates.

Well another problem is we'd need to redefine the less-than and greater-than operators too. Andrei

Oh yeah. I don't know how I missed that. <smacks forehead> --benji
Oct 07 2008
prev sibling next sibling parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:
 
 I don't favor "." any more than the next guy, but I am glad there is 
 awareness of how unfit a choice "!" is. If you have any ideas, please 
 post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke);

Positive$(real)(joke); Does D have a use for # at the moment? I'm surprised it wasn't used for array length instead of $. L.
Oct 05 2008
next sibling parent KennyTM~ <kennytm gmail.com> writes:
Lionello Lunesu wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 I don't favor "." any more than the next guy, but I am glad there is 
 awareness of how unfit a choice "!" is. If you have any ideas, please 
 post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke);

Positive$(real)(joke); Does D have a use for # at the moment? I'm surprised it wasn't used for array length instead of $. L.

Yes. #line. I think $ makes sense because in RegExp $ matches the end of string (or end of line).
Oct 05 2008
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lionello Lunesu wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 I don't favor "." any more than the next guy, but I am glad there is 
 awareness of how unfit a choice "!" is. If you have any ideas, please 
 post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke);

Positive$(real)(joke); Does D have a use for # at the moment? I'm surprised it wasn't used for array length instead of $.

I considered # too. It's a bit "fat", but you know what, I'd rather deal with a fella with a slight weight problem than one who's shouting all the time. Andrei
Oct 05 2008
prev sibling parent reply Leandro Lucarella <llucax gmail.com> writes:
Michel Fortin, el  5 de octubre a las 03:53 me escribiste:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> said:
 
I don't favor "." any more than the next guy, but I am glad there is awareness
of how unfit a choice "!" is. If you have any ideas, please post them! Ah! I! 
Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke); Anything else I forgot? Or we could use special delimiter characters: Positive<real>(joke); Positive“real”(joke); Positive«real»(joke); Positive#real (joke); Each having its own problem though. My preference still goes to "!(".

I think this is exactly the point. ".(" don't look that much better than "!(" (if better at all), so why should a new syntax variation should be introduced to the language with that small (and arguable) benefit? "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. And if it's introduced, you'll have to read a lot of "!(" anyways, is not that you will be solving any problems, because all D1-ported code (and code of people who like "!(" better) will use it instead of ".(" (unless "!(" stops working, in which case it's really dumb to make D1 incompatible with D2 for this such a small aesthetic issue). So you'll just make things whorse. -1 for ".(" PS: I wont use Positive!() either ;) -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Es mas posible, que un elefante maneje un cero km a que un camello habite un departamento de un ambiente. -- Peperino Pómoro
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Leandro Lucarella wrote:
 Michel Fortin, el  5 de octubre a las 03:53 me escribiste:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> said:

 I don't favor "." any more than the next guy, but I am glad there is awareness
of how unfit a choice "!" is. If you have any ideas, please post them! Ah! I! 
 Exclaimed! Again!

Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke); Anything else I forgot? Or we could use special delimiter characters: Positive<real>(joke); Positive“real”(joke); Positive«real»(joke); Positive#real (joke); Each having its own problem though. My preference still goes to "!(".

I think this is exactly the point. ".(" don't look that much better than "!(" (if better at all), so why should a new syntax variation should be introduced to the language with that small (and arguable) benefit?

I think it's reasonable to say that The Sad Pirate won't make it. I hope a different fate awaits for unparenthesized instantiations.
 "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.
 And if it's introduced, you'll have to read a lot of "!(" anyways, is not
 that you will be solving any problems, because all D1-ported code (and
 code of people who like "!(" better) will use it instead of ".(" (unless
 "!(" stops working, in which case it's really dumb to make D1 incompatible
 with D2 for this such a small aesthetic issue). So you'll just make things
 whorse.
 
 -1 for ".("
 
 
 PS: I wont use Positive!() either ;)

Would you use Bounded? It takes a type, a minimum, and a maximum. Andrei
Oct 05 2008
next sibling parent reply Jason House <jason.james.house gmail.com> writes:
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.
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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.

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} enum deviceStatusMask = 3; ... 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
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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.

That's kinda hard to argue against because it's a sheer fact.

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} enum deviceStatusMask = 3; ... 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
Oct 05 2008
prev sibling next sibling parent Leandro Lucarella <llucax gmail.com> writes:
Andrei Alexandrescu, el  5 de octubre a las 17:45 me escribiste:
"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 [...]

But this thread started about uglyness, and enum SOMETHING = 1 is plain ugly =)
And if it's introduced, you'll have to read a lot of "!(" anyways, is not
that you will be solving any problems, because all D1-ported code (and
code of people who like "!(" better) will use it instead of ".(" (unless
"!(" stops working, in which case it's really dumb to make D1 incompatible
with D2 for this such a small aesthetic issue). So you'll just make things
whorse.
-1 for ".("
PS: I wont use Positive!() either ;)

Would you use Bounded? It takes a type, a minimum, and a maximum.

I don't make much numeric/math programming, but it sounds much more useful than Positive. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- You look so tired-unhappy, bring down the government, they don't, they don't speak for us.
Oct 06 2008
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Simen Kjaeraas wrote:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> 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.

All bears are animals, so lets call all animals bears. See where this is wrong?

The correct reasoning to apply is, if you see a white bear, would you call it a different way? Andrei
Oct 08 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Simen Kjaeraas wrote:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 
 Simen Kjaeraas wrote:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> 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.

All bears are animals, so lets call all animals bears. See where this is wrong?

The correct reasoning to apply is, if you see a white bear, would you call it a different way? Andrei

Mayhaps. But to me, a manifest constant is not just a bear of a different color, but possibly one with six legs, a prehensile tail, bat wings, and riding a helicopter. And I'm pretty sure I would not classify that as a bear, even if it still had fur and powerful jaws, and would make for a fun teddy.

But you just agreed that enum is a manifest constant. Andrei
Oct 08 2008
prev sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Andrei Alexandrescu wrote:
 Christopher Wright wrote:
 Andrei Alexandrescu wrote:
 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.

Not only that, but typing it is annoying. First you need to put the right pinky on the shift key, which is a long reach; then you need to put the left pinky on the 1 key, which is a long reach. Then you need to move your left pinky all the way back to the left shift key, which is a short reach, and move your right ring finger up to the 9 key. It's a lot of reaching and back and forth. But I don't favor '.' since it's already used.

I don't favor "." any more than the next guy, but I am glad there is awareness of how unfit a choice "!" is. If you have any ideas, please post them! Ah! I! Exclaimed! Again! Andrei!

I agree with Mr. Martin II: colon might be an unambiguous option, and for qwerty keyboards, you don't have to switch shift keys. (I use dvorak, so it'd be slightly more awkward, but still a fair bit more easier than a bang.) Also, colon's taller than dot, so it's easier to see.
Oct 05 2008
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
Christopher Wright wrote:
 Andrei Alexandrescu wrote:
 Christopher Wright wrote:
 Andrei Alexandrescu wrote:
 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.

Not only that, but typing it is annoying. First you need to put the right pinky on the shift key, which is a long reach; then you need to put the left pinky on the 1 key, which is a long reach. Then you need to move your left pinky all the way back to the left shift key, which is a short reach, and move your right ring finger up to the 9 key. It's a lot of reaching and back and forth. But I don't favor '.' since it's already used.

I don't favor "." any more than the next guy, but I am glad there is awareness of how unfit a choice "!" is. If you have any ideas, please post them! Ah! I! Exclaimed! Again! Andrei!

I agree with Mr. Martin II: colon might be an unambiguous option, and for qwerty keyboards, you don't have to switch shift keys. (I use dvorak, so it'd be slightly more awkward, but still a fair bit more easier than a bang.) Also, colon's taller than dot, so it's easier to see.

How to distinguish a label from a template then? Should I print X or Y in the following code? import std.stdio; class X { static void print () { writeln("Y"); } } template T (x) { void print () { writeln("X"); } } void main () { T:(X).print(); }
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
KennyTM~ wrote:
 Christopher Wright wrote:
 Andrei Alexandrescu wrote:
 Christopher Wright wrote:
 Andrei Alexandrescu wrote:
 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.

Not only that, but typing it is annoying. First you need to put the right pinky on the shift key, which is a long reach; then you need to put the left pinky on the 1 key, which is a long reach. Then you need to move your left pinky all the way back to the left shift key, which is a short reach, and move your right ring finger up to the 9 key. It's a lot of reaching and back and forth. But I don't favor '.' since it's already used.

I don't favor "." any more than the next guy, but I am glad there is awareness of how unfit a choice "!" is. If you have any ideas, please post them! Ah! I! Exclaimed! Again! Andrei!

I agree with Mr. Martin II: colon might be an unambiguous option, and for qwerty keyboards, you don't have to switch shift keys. (I use dvorak, so it'd be slightly more awkward, but still a fair bit more easier than a bang.) Also, colon's taller than dot, so it's easier to see.

How to distinguish a label from a template then? Should I print X or Y in the following code? import std.stdio; class X { static void print () { writeln("Y"); } } template T (x) { void print () { writeln("X"); } } void main () { T:(X).print(); }

Heh. So this change should come together with abolishing goto :o). Andrei
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Adam D. Ruppe wrote:
 On Sun, Oct 05, 2008 at 09:29:37AM -0500, Andrei Alexandrescu wrote:
 Heh. So this change should come together with abolishing goto :o).

Noooooooooooooooooooooooooo!

No worries. Goto to Walter is what money is to Swiss banks. :o) Andrei P.S. I have one goto in my code too.
Oct 05 2008
parent Sergey Gromov <snake.scaly gmail.com> writes:
Sun, 05 Oct 2008 09:44:39 -0500,
Andrei Alexandrescu wrote:
 Adam D. Ruppe wrote:
 On Sun, Oct 05, 2008 at 09:29:37AM -0500, Andrei Alexandrescu wrote:
 Heh. So this change should come together with abolishing goto :o).

Noooooooooooooooooooooooooo!

No worries. Goto to Walter is what money is to Swiss banks. :o) Andrei P.S. I have one goto in my code too.

Maybe not gotos, but labelled breaks and continues might come in very handy sometimes.
Oct 06 2008
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Christopher Wright wrote:
 Andrei Alexandrescu wrote:
 Christopher Wright wrote:
 Andrei Alexandrescu wrote:
 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.

Not only that, but typing it is annoying. First you need to put the right pinky on the shift key, which is a long reach; then you need to put the left pinky on the 1 key, which is a long reach. Then you need to move your left pinky all the way back to the left shift key, which is a short reach, and move your right ring finger up to the 9 key. It's a lot of reaching and back and forth. But I don't favor '.' since it's already used.

I don't favor "." any more than the next guy, but I am glad there is awareness of how unfit a choice "!" is. If you have any ideas, please post them! Ah! I! Exclaimed! Again! Andrei!

I agree with Mr. Martin II: colon might be an unambiguous option, and for qwerty keyboards, you don't have to switch shift keys. (I use dvorak, so it'd be slightly more awkward, but still a fair bit more easier than a bang.) Also, colon's taller than dot, so it's easier to see.

I love the colon. It would be my first preference in fact. Walter wants to do parsing without symbol tables, and I think that's a worthy goal. How to parse this? a = b?c?d:(e):f:(g); Hmmmm... Andrei
Oct 05 2008
prev sibling parent reply Lester L. Martin II <lestermartin92 gmail.com> writes:
Christopher Wright Wrote:

 Andrei Alexandrescu wrote:
 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.

Not only that, but typing it is annoying. First you need to put the right pinky on the shift key, which is a long reach; then you need to put the left pinky on the 1 key, which is a long reach. Then you need to move your left pinky all the way back to the left shift key, which is a short reach, and move your right ring finger up to the 9 key. It's a lot of reaching and back and forth. But I don't favor '.' since it's already used.

I don't like the idea of '.' either. I currently like the '!'. I am not the best at templates and making templates similar to function call (looks like each other) would make templating so much harder. It should have something that lets you know right off that it's a template. Do you really want a template looking like a function. That has potential to get confusing as your brain argues just at a glance over if a function is called and supplied parameters most functions wouldn't accept or is it a template and the list afterwards is the stuff supplied to the function (I don't remember ever passing to a function (real, real) so looking at that and having my brain think about "OH!" that's why the function call isn't working and the code won't compile, it's because you were dumb enough to supply types instead of values is not very intuitive). I like the '!' and don't look forward to seeing it changed but if it was to be changed, I'd prefer it not to be a '.' but maybe something along the line of a colon (':') because it doesn't show a function call. I can't remember ever using a ':' in my code except for that import this : function2 type stuff so I think this would be a good idea versus the '.' Lester L. Martin II
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lester L. Martin II wrote:
 Christopher Wright Wrote:
 
 Andrei Alexandrescu wrote:
 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.

right pinky on the shift key, which is a long reach; then you need to put the left pinky on the 1 key, which is a long reach. Then you need to move your left pinky all the way back to the left shift key, which is a short reach, and move your right ring finger up to the 9 key. It's a lot of reaching and back and forth. But I don't favor '.' since it's already used.

I don't like the idea of '.' either. I currently like the '!'. I am not the best at templates and making templates similar to function call (looks like each other) would make templating so much harder. It should have something that lets you know right off that it's a template. Do you really want a template looking like a function.

You already have a template looking like a function. It works so well you don't even care, and consequently are not put off by it.
 That
 has potential to get confusing as your brain argues just at a glance
 over if a function is called and supplied parameters most functions
 wouldn't accept or is it a template and the list afterwards is the
 stuff supplied to the function (I don't remember ever passing to a
 function (real, real) so looking at that and having my brain think
 about "OH!" that's why the function call isn't working and the code
 won't compile, it's because you were dumb enough to supply types
 instead of values is not very intuitive).
 
 I like the '!' and don't look forward to seeing it changed but if it
 was to be changed, I'd prefer it not to be a '.' but maybe something
 along the line of a colon (':') because it doesn't show a function
 call. I can't remember ever using a ':' in my code except for that
 import this : function2 type stuff so I think this would be a good
 idea versus the '.'

I prefer the colon too, if ambiguity with ?: can be taken care of. Andrei
Oct 05 2008
parent Walter Bright <newshound1 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 I prefer the colon too, if ambiguity with ?: can be taken care of.

There's also an ambiguity with statement labels: L1: (*foo)();
Oct 05 2008
prev sibling next sibling parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
I don't like using "." for template instantiation. The tokenizer in my 
eyes clearly separates constructs at ".". On the other hand, "!" as a 
graphical character is more 'filled', thus doesn't separate the 
identifier and arguments that much visually.

foo.bar          <-  obviously member access
foo.(bar, baz)   <-  multiple member access?

... It looks like it should yield a tuple containing bar and baz :P


foo!(bar, baz)   <-  distinct, no issue.


As for the other queries, I like how template instantiation stands out 
right now with the exclamation mark. I would not like to have 
compile-time and run-time merged visually in code. And I don't forget to 
put the exclamation mark there when programming templates.

Let's also keep in mind what Ary said, that using "." will cause 
problems for IDEs.

What's the point in pretending that run-time is the same as 
compile-time? You can't instantiate compile-time constructs with 
run-time arguments, the costs are very different, too. Heck, when I see 
too many "!" in the code, it indicates that there may be a design issue 
and some massive bloat involved. I would not like this additional 
insight into the code removed from my eyes.


-- 
Tomasz Stachowiak
http://h3.team0xf.com/
h3/h3r3tic on #D freenode
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Tom S wrote:
 I don't like using "." for template instantiation. The tokenizer in my 
 eyes clearly separates constructs at ".". On the other hand, "!" as a 
 graphical character is more 'filled', thus doesn't separate the 
 identifier and arguments that much visually.
 
 foo.bar          <-  obviously member access
 foo.(bar, baz)   <-  multiple member access?

I hear you. I would have chosen the colon if it wasn't ambiguous.
 ... It looks like it should yield a tuple containing bar and baz :P
 
 
 foo!(bar, baz)   <-  distinct, no issue.

Looks great until you have twenty or thirty of these on a code screen. Then you're like, boy this is one ugly language. Believe me, I *tried* to put up with it.
 As for the other queries, I like how template instantiation stands out 
 right now with the exclamation mark.

I wouldn't mind it either if I only had few of those.
 I would not like to have 
 compile-time and run-time merged visually in code.

You already do in template argument deduction. Compile-time evaluation erodes the distinction further. The times go against the style of coding that separates compile-time stuff from run-time stuff.
 And I don't forget to 
 put the exclamation mark there when programming templates.

Ok.
 Let's also keep in mind what Ary said, that using "." will cause 
 problems for IDEs.

No it won't.
 What's the point in pretending that run-time is the same as 
 compile-time?

Because you shouldn't care.
 You can't instantiate compile-time constructs with 
 run-time arguments, the costs are very different, too. Heck, when I see 
 too many "!" in the code, it indicates that there may be a design issue 
 and some massive bloat involved. I would not like this additional 
 insight into the code removed from my eyes.

Conversely, if you have too few of those, I come and say you're doing too much manual work. Andrei
Oct 05 2008
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Andrei Alexandrescu wrote:
 ... It looks like it should yield a tuple containing bar and baz :P


 foo!(bar, baz)   <-  distinct, no issue.

Looks great until you have twenty or thirty of these on a code screen. Then you're like, boy this is one ugly language. Believe me, I *tried* to put up with it.

Hm, I didn't think so when working on ctrace or Bind... I could similarly say that parentheses look bad and we should change them to something else because a screenful of them looks ugly when calling lots of functions.
 I would not like to have compile-time and run-time merged visually in 
 code.


a bad thing that some functions will be running at compile-time 'behind my back'. I just wouldn't like the visual distinction between normal function calls and template evaluations to go away as long as they are fundamentally different.
 You already do in template argument deduction.

Point. But for a different purpose - eliminating a lot of redundant code and making some meta programming feasible. It's a bit different from pretending template evaluation is like function calls.
 The times go against the style of coding 
 that separates compile-time stuff from run-time stuff.

The times? I'd say that these times have already been ;) You may not have this distinction e.g. in Lisp. But if you consider that D only has one 'compile time', while you could freely operate on anything at any time in Lisp, it makes more sense to have the compile-time phase stand out a bit. Especially because template code is still very different than normal D code (it's functional and memoized, after all). I'd be tempted to change my mind here if D had more meta-facilities, but at the current state of things, I'd say that the 'times' are pretty stagnant for D.
 Let's also keep in mind what Ary said, that using "." will cause 
 problems for IDEs.

No it won't.

Would you elaborate on this? I'd rather believe Ary if nothing else is provided to your point. Ary is the creator of the most advanced IDE for D as far as I know.
 What's the point in pretending that run-time is the same as compile-time?

Because you shouldn't care.

I wish I could! But then, I can't process types at run-time.
 You can't instantiate compile-time constructs with run-time arguments, 
 the costs are very different, too. Heck, when I see too many "!" in 
 the code, it indicates that there may be a design issue and some 
 massive bloat involved. I would not like this additional insight into 
 the code removed from my eyes.

Conversely, if you have too few of those, I come and say you're doing too much manual work.

Or the code is a 'normal' module that mixes some meta constructs and standard non-parametrized stuff. The "!" may be very common in modules such as std.algorithm, but you won't see as many in the usual stuff, like, most of Tango. -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Oct 05 2008
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Tom S wrote:
 Andrei Alexandrescu wrote:
 ... It looks like it should yield a tuple containing bar and baz :P


 foo!(bar, baz)   <-  distinct, no issue.

Looks great until you have twenty or thirty of these on a code screen. Then you're like, boy this is one ugly language. Believe me, I *tried* to put up with it.

Hm, I didn't think so when working on ctrace or Bind... I could similarly say that parentheses look bad and we should change them to something else because a screenful of them looks ugly when calling lots of functions.

You couldn't because f(a, b) is already used in math for function invocation. "Word!" is already used. For shouting that is.
 I would not like to have compile-time and run-time merged visually in 
 code.


a bad thing that some functions will be running at compile-time 'behind my back'. I just wouldn't like the visual distinction between normal function calls and template evaluations to go away as long as they are fundamentally different.

They are and they stay different. One oughtn't be shouting at you though.
 You already do in template argument deduction.

Point. But for a different purpose - eliminating a lot of redundant code and making some meta programming feasible. It's a bit different from pretending template evaluation is like function calls.

Well parens are already used for more than function calls and nobody seems to mind.
 The times go against the style of coding that separates compile-time 
 stuff from run-time stuff.

The times? I'd say that these times have already been ;) You may not have this distinction e.g. in Lisp. But if you consider that D only has one 'compile time', while you could freely operate on anything at any time in Lisp, it makes more sense to have the compile-time phase stand out a bit. Especially because template code is still very different than normal D code (it's functional and memoized, after all). I'd be tempted to change my mind here if D had more meta-facilities, but at the current state of things, I'd say that the 'times' are pretty stagnant for D.

More meta-facilities are coming D's way, not less. As far as Lisp is concerned, at least in Scheme (I forgot how you do it in Lisp) macro invocation isn't distinguished in any way. For example "and" in (and a b c) is a macro.
 Let's also keep in mind what Ary said, that using "." will cause 
 problems for IDEs.

No it won't.

Would you elaborate on this? I'd rather believe Ary if nothing else is provided to your point. Ary is the creator of the most advanced IDE for D as far as I know.

A template name without arguments has no members, except inside the very template definition, when you'd rarely use it.
 What's the point in pretending that run-time is the same as 
 compile-time?

Because you shouldn't care.

I wish I could! But then, I can't process types at run-time.

Well then here's the distinction that you wanted :o).
 You can't instantiate compile-time constructs with run-time 
 arguments, the costs are very different, too. Heck, when I see too 
 many "!" in the code, it indicates that there may be a design issue 
 and some massive bloat involved. I would not like this additional 
 insight into the code removed from my eyes.

Conversely, if you have too few of those, I come and say you're doing too much manual work.

Or the code is a 'normal' module that mixes some meta constructs and standard non-parametrized stuff. The "!" may be very common in modules such as std.algorithm, but you won't see as many in the usual stuff, like, most of Tango.

By and large we'd want seamless and smooth integration of various styles and techniques, wouldn't we? Shouting doesn't fit into this. Andrei
Oct 05 2008
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Andrei Alexandrescu escribió:
 Tom S wrote:
 Andrei Alexandrescu wrote:
 ... It looks like it should yield a tuple containing bar and baz :P


 foo!(bar, baz)   <-  distinct, no issue.

Looks great until you have twenty or thirty of these on a code screen. Then you're like, boy this is one ugly language. Believe me, I *tried* to put up with it.

Hm, I didn't think so when working on ctrace or Bind... I could similarly say that parentheses look bad and we should change them to something else because a screenful of them looks ugly when calling lots of functions.

You couldn't because f(a, b) is already used in math for function invocation. "Word!" is already used. For shouting that is.
 I would not like to have compile-time and run-time merged visually 
 in code.


as a bad thing that some functions will be running at compile-time 'behind my back'. I just wouldn't like the visual distinction between normal function calls and template evaluations to go away as long as they are fundamentally different.

They are and they stay different. One oughtn't be shouting at you though.
 You already do in template argument deduction.

Point. But for a different purpose - eliminating a lot of redundant code and making some meta programming feasible. It's a bit different from pretending template evaluation is like function calls.

Well parens are already used for more than function calls and nobody seems to mind.
 The times go against the style of coding that separates compile-time 
 stuff from run-time stuff.

The times? I'd say that these times have already been ;) You may not have this distinction e.g. in Lisp. But if you consider that D only has one 'compile time', while you could freely operate on anything at any time in Lisp, it makes more sense to have the compile-time phase stand out a bit. Especially because template code is still very different than normal D code (it's functional and memoized, after all). I'd be tempted to change my mind here if D had more meta-facilities, but at the current state of things, I'd say that the 'times' are pretty stagnant for D.

More meta-facilities are coming D's way, not less. As far as Lisp is concerned, at least in Scheme (I forgot how you do it in Lisp) macro invocation isn't distinguished in any way. For example "and" in (and a b c) is a macro.
 Let's also keep in mind what Ary said, that using "." will cause 
 problems for IDEs.

No it won't.

Would you elaborate on this? I'd rather believe Ary if nothing else is provided to your point. Ary is the creator of the most advanced IDE for D as far as I know.

A template name without arguments has no members, except inside the very template definition, when you'd rarely use it.

I don't think it's because of that, but the IDE could check that if what's before the "." is a template, suggest instantiation. So after thinking about it again, I agree with you that it won't be problematic. Anyway, I don't like the .() syntax. :-P
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Ary Borenszweig wrote:
 Andrei Alexandrescu escribió:
 Tom S wrote:
 Andrei Alexandrescu wrote:
 ... It looks like it should yield a tuple containing bar and baz :P


 foo!(bar, baz)   <-  distinct, no issue.

Looks great until you have twenty or thirty of these on a code screen. Then you're like, boy this is one ugly language. Believe me, I *tried* to put up with it.

Hm, I didn't think so when working on ctrace or Bind... I could similarly say that parentheses look bad and we should change them to something else because a screenful of them looks ugly when calling lots of functions.

You couldn't because f(a, b) is already used in math for function invocation. "Word!" is already used. For shouting that is.
 I would not like to have compile-time and run-time merged visually 
 in code.


as a bad thing that some functions will be running at compile-time 'behind my back'. I just wouldn't like the visual distinction between normal function calls and template evaluations to go away as long as they are fundamentally different.

They are and they stay different. One oughtn't be shouting at you though.
 You already do in template argument deduction.

Point. But for a different purpose - eliminating a lot of redundant code and making some meta programming feasible. It's a bit different from pretending template evaluation is like function calls.

Well parens are already used for more than function calls and nobody seems to mind.
 The times go against the style of coding that separates compile-time 
 stuff from run-time stuff.

The times? I'd say that these times have already been ;) You may not have this distinction e.g. in Lisp. But if you consider that D only has one 'compile time', while you could freely operate on anything at any time in Lisp, it makes more sense to have the compile-time phase stand out a bit. Especially because template code is still very different than normal D code (it's functional and memoized, after all). I'd be tempted to change my mind here if D had more meta-facilities, but at the current state of things, I'd say that the 'times' are pretty stagnant for D.

More meta-facilities are coming D's way, not less. As far as Lisp is concerned, at least in Scheme (I forgot how you do it in Lisp) macro invocation isn't distinguished in any way. For example "and" in (and a b c) is a macro.
 Let's also keep in mind what Ary said, that using "." will cause 
 problems for IDEs.

No it won't.

Would you elaborate on this? I'd rather believe Ary if nothing else is provided to your point. Ary is the creator of the most advanced IDE for D as far as I know.

A template name without arguments has no members, except inside the very template definition, when you'd rarely use it.

I don't think it's because of that, but the IDE could check that if what's before the "." is a template, suggest instantiation. So after thinking about it again, I agree with you that it won't be problematic. Anyway, I don't like the .() syntax. :-P

And why should I care? I got superdan's drunken vote! :oD Andrei
Oct 05 2008
prev sibling parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Andrei Alexandrescu wrote:
 By and large we'd want seamless and smooth integration of various styles
 and techniques, wouldn't we? Shouting doesn't fit into this.

Is that a phobia? :P -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Oct 05 2008
prev sibling parent Benji Smith <dlanguage benjismith.net> writes:
Tom S wrote:
 The "!" may be very common in modules 
 such as std.algorithm, but you won't see as many in the usual stuff, 
 like, most of Tango.

Unfortunately, any code that uses strings (and wants to correctly handle all three character types) is required to use templates. So there's a lot more template code out there than there ought to be. --benji
Oct 06 2008
prev sibling next sibling parent reply downs <default_357-line yahoo.de> writes:
Andrei Alexandrescu wrote:
 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.
 

FWIW: I write large volumes of template code and I like the ! just fine.
 
 Andrei
 

Oct 05 2008
next sibling parent Peter Modzelewski <peter.modzelewski gmail.com> writes:
downs pisze:
 Andrei Alexandrescu wrote:
 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.

FWIW: I write large volumes of template code and I like the ! just fine.

Same here! Piotr Modzelewski keyer team0xf.com
Oct 05 2008
prev sibling parent reply Gregor Richards <Richards codu.org> writes:
downs wrote:
 Andrei Alexandrescu wrote:
 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.

FWIW: I write large volumes of template code and I like the ! just fine.

Don't take this endorsement lightly. When downs says he writes large volumes of template code, he means volumes in the literary sense: You could fill a fairly-large bookshelf with his tomes of template code. - Gregor Richards
Oct 05 2008
parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
Gregor Richards wrote:

 downs wrote:
 Andrei Alexandrescu wrote:
 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.

FWIW: I write large volumes of template code and I like the ! just fine.

Don't take this endorsement lightly. When downs says he writes large volumes of template code, he means volumes in the literary sense: You could fill a fairly-large bookshelf with his tomes of template code.

I'm sure you mean not so large tomes, but with very long lines? -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Oct 05 2008
next sibling parent downs <default_357-line yahoo.de> writes:
Lars Ivar Igesund wrote:
 Gregor Richards wrote:
 
 downs wrote:
 Andrei Alexandrescu wrote:
 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.


volumes of template code, he means volumes in the literary sense: You could fill a fairly-large bookshelf with his tomes of template code.

I'm sure you mean not so large tomes, but with very long lines?

That's why you need the bookshelf. It's not so much the length of the tomes, it's the width :)
Oct 05 2008
prev sibling parent KennyTM~ <kennytm gmail.com> writes:
Lars Ivar Igesund wrote:
 Gregor Richards wrote:
 
 downs wrote:
 Andrei Alexandrescu wrote:
 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.


volumes of template code, he means volumes in the literary sense: You could fill a fairly-large bookshelf with his tomes of template code.

I'm sure you mean not so large tomes, but with very long lines?

If you strip all the \n's you'll get a very long line. /joke (unless you've used a #line)
Oct 05 2008
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Sun, Oct 5, 2008 at 12:06 AM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 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.

Long argument short: I don't mind !() at all, and changing it to .() seems like a pointless pedanticism. But since you're the one suggesting it, there's a very good chance of it getting into the language (if it hasn't already), so there's not much use arguing against it.

It won't make it unless others try it and find it palatable too. But please let's try it first. Also, I'm much less keen on introducing .() than on ousting !(), which I believe was a very poor choice. So I suggest we all explore other syntax choices until we find something that we can show to the world with a straight face. Andrei
Oct 05 2008
prev sibling next sibling parent Lars Ivar Igesund <larsivar igesund.net> writes:
Andrei Alexandrescu wrote:

 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.

I don't dislike !() and don't want .() -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Oct 05 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
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.
Oct 05 2008
prev sibling next sibling parent reply Benji Smith <dlanguage benjismith.net> writes:
Andrei Alexandrescu wrote:
 One morning I woke up with the sudden realization of what the problem 
 was: the shouting.

Here's my (nutty) opinion: Neither the "!" nor the "." really want to be there. I think the language really *wants* to be using a bare set of parens for templates. Because the language actually wants templates and functions to converge. Instead of a special-case syntax for templates, and a set of special rules for CTFE, and a whole set of parallel "static" statements (if, else, foreach) and a special compile-type-only type construct (tuples), just let D be D, either at runtime or compile type. If a function could return a Type, and if that type could be used in a Type Constructor, then you'd have all the magic template sauce you'd need, and templates could happily converge themselves with regular functions. Hey! I told you it was going to be nutty!!! <g> --benji
Oct 06 2008
parent reply Benji Smith <dlanguage benjismith.net> writes:
Simen Kjaeraas wrote:
 On Wed, 08 Oct 2008 22:02:18 +0200, Simen Kjaeraas 
 <simen.kjaras gmail.com> wrote:
 
 On Mon, 06 Oct 2008 12:39:29 +0200, Benji Smith 
 <dlanguage benjismith.net> wrote:

 Andrei Alexandrescu wrote:
 One morning I woke up with the sudden realization of what the 
 problem was: the shouting.

Here's my (nutty) opinion: Neither the "!" nor the "." really want to be there. I think the language really *wants* to be using a bare set of parens for templates. Because the language actually wants templates and functions to converge. Instead of a special-case syntax for templates, and a set of special rules for CTFE, and a whole set of parallel "static" statements (if, else, foreach) and a special compile-type-only type construct (tuples), just let D be D, either at runtime or compile type. If a function could return a Type, and if that type could be used in a Type Constructor, then you'd have all the magic template sauce you'd need, and templates could happily converge themselves with regular functions. Hey! I told you it was going to be nutty!!! <g> --benji

That would only work for templated functions, though. What about templated types?

Forget I ever let my ass do the thinking. I'd really like to see how this would look, but I feel it'd make for uglier syntax.

I don't really know how it would work, but the syntax is easy to imagine: Type Dictionary = HashMap(char[], char[]); Dictionary d = new Dictionary(); In this case, HashMap is just a function (executable at compile-time through CTFE), which returns a type. Once the type has been returned, objects of that type can be instantiated. This idea first occurred to me when CTFE was introduced. I thought to myself "if we can have compile-time function exectuion", why can't we also have "runtime template instantiation"? Why is it only possible to define a new type (or to choose which type) at compile time? In languages like Ruby, you can attach new methods to an object at runtime. In .NET, you can generate, compile, and load new bytecode instructions on the fly. It's hard to think of cases where you'd really want to construct a new type at runtime. But maybe....automatically generating a library of types by querying a database schema? --benji
Oct 08 2008
next sibling parent Benji Smith <dlanguage benjismith.net> writes:
Simen Kjaeraas wrote:
 Benji Smith <dlanguage benjismith.net> wrote:
 
 This idea first occurred to me when CTFE was introduced. I thought to 
 myself "if we can have compile-time function exectuion", why can't we 
 also have "runtime template instantiation"? Why is it only possible to 
 define a new type (or to choose which type) at compile time?

 In languages like Ruby, you can attach new methods to an object at 
 runtime. In .NET, you can generate, compile, and load new bytecode 
 instructions on the fly.

 It's hard to think of cases where you'd really want to construct a new 
 type at runtime. But maybe....automatically generating a library of 
 types by querying a database schema?

 --benji

The reasons for such things are to be found in the compiler. Optimizing an expression whose types you do not know, and allocating space for a type that may change its size under your feet - sounds to me like tricky business.

Yep. I totally understand why it's not currently possible. You'd have to have an instance of the compiler always available at runtime; compiling, loading, and linking on the fly. Tricky stuff. But it'd be cool. It wasn't a real suggestion. Just a musing. --benji
Oct 08 2008
prev sibling parent Don <nospam nospam.com.au> writes:
Benji Smith wrote:
 Simen Kjaeraas wrote:
 On Wed, 08 Oct 2008 22:02:18 +0200, Simen Kjaeraas 
 <simen.kjaras gmail.com> wrote:

 On Mon, 06 Oct 2008 12:39:29 +0200, Benji Smith 
 <dlanguage benjismith.net> wrote:

 Andrei Alexandrescu wrote:
 One morning I woke up with the sudden realization of what the 
 problem was: the shouting.

Here's my (nutty) opinion: Neither the "!" nor the "." really want to be there. I think the language really *wants* to be using a bare set of parens for templates. Because the language actually wants templates and functions to converge. Instead of a special-case syntax for templates, and a set of special rules for CTFE, and a whole set of parallel "static" statements (if, else, foreach) and a special compile-type-only type construct (tuples), just let D be D, either at runtime or compile type. If a function could return a Type, and if that type could be used in a Type Constructor, then you'd have all the magic template sauce you'd need, and templates could happily converge themselves with regular functions. Hey! I told you it was going to be nutty!!! <g> --benji

That would only work for templated functions, though. What about templated types?

Forget I ever let my ass do the thinking. I'd really like to see how this would look, but I feel it'd make for uglier syntax.

I don't really know how it would work, but the syntax is easy to imagine: Type Dictionary = HashMap(char[], char[]); Dictionary d = new Dictionary(); In this case, HashMap is just a function (executable at compile-time through CTFE), which returns a type. Once the type has been returned, objects of that type can be instantiated. This idea first occurred to me when CTFE was introduced. I thought to myself "if we can have compile-time function exectuion", why can't we also have "runtime template instantiation"? Why is it only possible to define a new type (or to choose which type) at compile time? In languages like Ruby, you can attach new methods to an object at runtime. In .NET, you can generate, compile, and load new bytecode instructions on the fly. It's hard to think of cases where you'd really want to construct a new type at runtime. But maybe....automatically generating a library of types by querying a database schema?

It makes sense to construct a new type in CTFE code, though. That would allow a template to be instantiated inside a CTFE function. Currently, a template can pass its arguments into a CTFE function, but a CTFE function cannot pass its arguments to a template.
Oct 09 2008
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Bill Baxter wrote:
 On Sun, Oct 5, 2008 at 1:06 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 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'm joining this discussion late, but I just wanted to say the !() doesn't bother me so much. What Walter said to you was pretty much how it went for me. Seemed weird for a while, but I got used to it. I had to do several double-takes reading this thread thinking people were suggesting to use plain "()" because the little dot is just so easy to miss. I find !() to at least be easier on the eyes than greater-than less-than everywhere in C++. I wouldn't be adamantly opposed to a different syntax, but it would have to be better by leaps and bounds for me to think it was worth the headache. And .() doesn't seem leaps and bounds better to me. I suggest, though, that if you think it looks a lot better you should at least post some example code showing "before" and "after" to try to convince us. Seems like not many here see a lot of point in making the change, so rather than pleading with everyone to try it out on their own, why not just save us the effort and show us how it improves the code you're looking at?

Well part of the problem is that many people made up their mind just by imagining how it would look like, and it would be hard to sway them. Since you asked, here are some examples copied verbatim from a source file I found handy: alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; For functions: sort.("a._0 == b._0 ? a._1 < b._1 : a._0 < b._0")(all); result.id = std.conv.parse.(uint)(line); I was even more pleased while actually using The Sad Pirate than while imagining how it would be like, probably because typing is also easier (something that's not self-evident when just looking at the code). It looks like The Sad Pirate won't make it. People just don't see it as bringing enough improvement. But I think it is worth pursuing a number of alternatives. The two that to me are the most appealing are: a) Template{Args} Experience with Perl has shown that using {} as parens in addition to blocks is easy to pick up and easy on the eyes. Another argument in favor is that {} are "the right thing" - meaning they are parens that pair properly, as opposed to "<>". Also, they make today's "!()" look like a contraption that creates a new kind of parens from an existing (and ambiguous) kind of parens by prefixing it with a marker. b) Template Arg and Template (Args) This approach not only accepts the need for a contraption, it actually leverages it by allowing you to drop the parens if you only have one argument. That way " " becomes a true operator, the template instantiation operator. Note that this can be done with the current "!" as well, except that Template!Arg does not look to me like anything enticing. Andrei
Oct 06 2008
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Andrei Alexandrescu wrote:
 Bill Baxter wrote:
 On Sun, Oct 5, 2008 at 1:06 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 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'm joining this discussion late, but I just wanted to say the !() doesn't bother me so much. What Walter said to you was pretty much how it went for me. Seemed weird for a while, but I got used to it. I had to do several double-takes reading this thread thinking people were suggesting to use plain "()" because the little dot is just so easy to miss. I find !() to at least be easier on the eyes than greater-than less-than everywhere in C++. I wouldn't be adamantly opposed to a different syntax, but it would have to be better by leaps and bounds for me to think it was worth the headache. And .() doesn't seem leaps and bounds better to me. I suggest, though, that if you think it looks a lot better you should at least post some example code showing "before" and "after" to try to convince us. Seems like not many here see a lot of point in making the change, so rather than pleading with everyone to try it out on their own, why not just save us the effort and show us how it improves the code you're looking at?

Well part of the problem is that many people made up their mind just by imagining how it would look like, and it would be hard to sway them. Since you asked, here are some examples copied verbatim from a source file I found handy: alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; For functions: sort.("a._0 == b._0 ? a._1 < b._1 : a._0 < b._0")(all); result.id = std.conv.parse.(uint)(line); I was even more pleased while actually using The Sad Pirate than while imagining how it would be like, probably because typing is also easier (something that's not self-evident when just looking at the code). It looks like The Sad Pirate won't make it. People just don't see it as bringing enough improvement. But I think it is worth pursuing a number of alternatives. The two that to me are the most appealing are: a) Template{Args} Experience with Perl has shown that using {} as parens in addition to blocks is easy to pick up and easy on the eyes. Another argument in favor is that {} are "the right thing" - meaning they are parens that pair properly, as opposed to "<>". Also, they make today's "!()" look like a contraption that creates a new kind of parens from an existing (and ambiguous) kind of parens by prefixing it with a marker. b) Template Arg and Template (Args) This approach not only accepts the need for a contraption, it actually leverages it by allowing you to drop the parens if you only have one argument. That way " " becomes a true operator, the template instantiation operator. Note that this can be done with the current "!" as well, except that Template!Arg does not look to me like anything enticing.

So let's have them written down to be able to compare them easier: The sad pirate ---------------- alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; The curly braces ---------------- alias DenseMatrix{num} PulType; alias SparseRowsMatrix{num, HashSparseVector} PuuType; alias BiMap{uint, Tuple{uint, uint}, BiMapOptions.lhDense} DicType; The at ---------------- alias DenseMatrix num PulType; alias SparseRowsMatrix (num, HashSparseVector) PuuType; alias BiMap (uint, Tuple (uint, uint), BiMapOptions.lhDense) DicType; --- Personally, I find the {} easier to understand, and it's less typing, but it doesn't allow to omit the closing } for one argument.
 
 
 Andrei

Oct 06 2008
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Ary Borenszweig" wrote
 Andrei Alexandrescu wrote:
 Bill Baxter wrote:
 On Sun, Oct 5, 2008 at 1:06 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 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'm joining this discussion late, but I just wanted to say the !() doesn't bother me so much. What Walter said to you was pretty much how it went for me. Seemed weird for a while, but I got used to it. I had to do several double-takes reading this thread thinking people were suggesting to use plain "()" because the little dot is just so easy to miss. I find !() to at least be easier on the eyes than greater-than less-than everywhere in C++. I wouldn't be adamantly opposed to a different syntax, but it would have to be better by leaps and bounds for me to think it was worth the headache. And .() doesn't seem leaps and bounds better to me. I suggest, though, that if you think it looks a lot better you should at least post some example code showing "before" and "after" to try to convince us. Seems like not many here see a lot of point in making the change, so rather than pleading with everyone to try it out on their own, why not just save us the effort and show us how it improves the code you're looking at?

Well part of the problem is that many people made up their mind just by imagining how it would look like, and it would be hard to sway them. Since you asked, here are some examples copied verbatim from a source file I found handy: alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; For functions: sort.("a._0 == b._0 ? a._1 < b._1 : a._0 < b._0")(all); result.id = std.conv.parse.(uint)(line); I was even more pleased while actually using The Sad Pirate than while imagining how it would be like, probably because typing is also easier (something that's not self-evident when just looking at the code). It looks like The Sad Pirate won't make it. People just don't see it as bringing enough improvement. But I think it is worth pursuing a number of alternatives. The two that to me are the most appealing are: a) Template{Args} Experience with Perl has shown that using {} as parens in addition to blocks is easy to pick up and easy on the eyes. Another argument in favor is that {} are "the right thing" - meaning they are parens that pair properly, as opposed to "<>". Also, they make today's "!()" look like a contraption that creates a new kind of parens from an existing (and ambiguous) kind of parens by prefixing it with a marker. b) Template Arg and Template (Args) This approach not only accepts the need for a contraption, it actually leverages it by allowing you to drop the parens if you only have one argument. That way " " becomes a true operator, the template instantiation operator. Note that this can be done with the current "!" as well, except that Template!Arg does not look to me like anything enticing.

So let's have them written down to be able to compare them easier: The sad pirate ---------------- alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; The curly braces ---------------- alias DenseMatrix{num} PulType; alias SparseRowsMatrix{num, HashSparseVector} PuuType; alias BiMap{uint, Tuple{uint, uint}, BiMapOptions.lhDense} DicType; The at ---------------- alias DenseMatrix num PulType; alias SparseRowsMatrix (num, HashSparseVector) PuuType; alias BiMap (uint, Tuple (uint, uint), BiMapOptions.lhDense) DicType; --- Personally, I find the {} easier to understand, and it's less typing, but it doesn't allow to omit the closing } for one argument.

I find the {} much easier to read than the . syntax. The omitting of the braces is not a huge savings. You are sacrificing a couple characters, actually only one if you are comparing with {}, at the expense of clarity. I think it's a special case that is not really worth the trouble. Besides, it's not hard to type {} when you are so used to it anyways, and if you are interested in saving characters, aliasing is a much better approach. One thing I should mention, since this is all about asthetics, my news reader keeps treating the name param as a linked email address. Somthing that will be very annoying if we adopt the syntax and end up discussing templates on the NG. I still vote to keep ! as it's the easiest solution, and I never have found it annoying ;) -Steve
Oct 06 2008
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 "Ary Borenszweig" wrote
 Andrei Alexandrescu wrote:
 Bill Baxter wrote:
 On Sun, Oct 5, 2008 at 1:06 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 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.

doesn't bother me so much. What Walter said to you was pretty much how it went for me. Seemed weird for a while, but I got used to it. I had to do several double-takes reading this thread thinking people were suggesting to use plain "()" because the little dot is just so easy to miss. I find !() to at least be easier on the eyes than greater-than less-than everywhere in C++. I wouldn't be adamantly opposed to a different syntax, but it would have to be better by leaps and bounds for me to think it was worth the headache. And .() doesn't seem leaps and bounds better to me. I suggest, though, that if you think it looks a lot better you should at least post some example code showing "before" and "after" to try to convince us. Seems like not many here see a lot of point in making the change, so rather than pleading with everyone to try it out on their own, why not just save us the effort and show us how it improves the code you're looking at?

imagining how it would look like, and it would be hard to sway them. Since you asked, here are some examples copied verbatim from a source file I found handy: alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; For functions: sort.("a._0 == b._0 ? a._1 < b._1 : a._0 < b._0")(all); result.id = std.conv.parse.(uint)(line); I was even more pleased while actually using The Sad Pirate than while imagining how it would be like, probably because typing is also easier (something that's not self-evident when just looking at the code). It looks like The Sad Pirate won't make it. People just don't see it as bringing enough improvement. But I think it is worth pursuing a number of alternatives. The two that to me are the most appealing are: a) Template{Args} Experience with Perl has shown that using {} as parens in addition to blocks is easy to pick up and easy on the eyes. Another argument in favor is that {} are "the right thing" - meaning they are parens that pair properly, as opposed to "<>". Also, they make today's "!()" look like a contraption that creates a new kind of parens from an existing (and ambiguous) kind of parens by prefixing it with a marker. b) Template Arg and Template (Args) This approach not only accepts the need for a contraption, it actually leverages it by allowing you to drop the parens if you only have one argument. That way " " becomes a true operator, the template instantiation operator. Note that this can be done with the current "!" as well, except that Template!Arg does not look to me like anything enticing.

The sad pirate ---------------- alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; The curly braces ---------------- alias DenseMatrix{num} PulType; alias SparseRowsMatrix{num, HashSparseVector} PuuType; alias BiMap{uint, Tuple{uint, uint}, BiMapOptions.lhDense} DicType; The at ---------------- alias DenseMatrix num PulType; alias SparseRowsMatrix (num, HashSparseVector) PuuType; alias BiMap (uint, Tuple (uint, uint), BiMapOptions.lhDense) DicType; --- Personally, I find the {} easier to understand, and it's less typing, but it doesn't allow to omit the closing } for one argument.

I find the {} much easier to read than the . syntax.

To me too.
 The omitting of the braces is not a huge savings.  You are sacrificing a 
 couple characters, actually only one if you are comparing   with {}, at the 
 expense of clarity.  I think it's a special case that is not really worth 
 the trouble.  Besides, it's not hard to type {} when you are so used to it 
 anyways, and if you are interested in saving characters, aliasing is a much 
 better approach.

One thing I kinda dislike about Template Arg is that adding a second arg also asks for the parens. This is a problem present with single- vs. multi-statement blocks as well: if (a) b; If you want to add another statement, you need to add the curls as well: if (a) { b; c; } But then if you want to remove one of the statement you'd want to remove the curls too to stay consistent: if (a) c; This becomes tenuous enough that many people and some coding standards actually prefer to use full block statements to start with, even when they only contain one statement.
 One thing I should mention, since this is all about asthetics, my news 
 reader keeps treating the name param as a linked email address.  Somthing 
 that will be very annoying if we adopt the   syntax and end up discussing 
 templates on the NG.

Walter made another point, namely that " " has "a lot of ink" in it. I know what he means. I guess people who wanted templates to be distinguished will find that an advantage :o).
 I still vote to keep ! as it's the easiest solution, and I never have found 
 it annoying ;)

Well would you go on a strike if there was a little experimentation with the curls? Andrei
Oct 06 2008
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Andrei Alexandrescu" wrote
 Steven Schveighoffer wrote:
 I find the {} much easier to read than the . syntax.

To me too.
 The omitting of the braces is not a huge savings.  You are sacrificing a 
 couple characters, actually only one if you are comparing   with {}, at 
 the expense of clarity.  I think it's a special case that is not really 
 worth the trouble.  Besides, it's not hard to type {} when you are so 
 used to it anyways, and if you are interested in saving characters, 
 aliasing is a much better approach.

One thing I kinda dislike about Template Arg is that adding a second arg also asks for the parens. This is a problem present with single- vs. multi-statement blocks as well: if (a) b; If you want to add another statement, you need to add the curls as well: if (a) { b; c; } But then if you want to remove one of the statement you'd want to remove the curls too to stay consistent: if (a) c; This becomes tenuous enough that many people and some coding standards actually prefer to use full block statements to start with, even when they only contain one statement.

Yeah, I find myself doing that also, removing the {} braces when possible, but that can't apply here for technical reasons. Conversely, I don't think anyone is complaining that they always have to use braces for one-line functions.
 One thing I should mention, since this is all about asthetics, my news 
 reader keeps treating the name param as a linked email address.  Somthing 
 that will be very annoying if we adopt the   syntax and end up discussing 
 templates on the NG.

Walter made another point, namely that " " has "a lot of ink" in it. I know what he means. I guess people who wanted templates to be distinguished will find that an advantage :o).

Yeah, but ! is just as good then, and we don't have to change thousands of lines of code ;)
 I still vote to keep ! as it's the easiest solution, and I never have 
 found it annoying ;)

Well would you go on a strike if there was a little experimentation with the curls?

I like D too much to give it up based on this one thing. But I would be cursing you profusely as I changed all my existing D code when I move to support D2. I don't think I'd ever feel that it was an improvement, but if it means so much to everyone to abolish the ! syntax, I'd just do the updates and move on. Like I said, it's a bicycle shed color. BTW, this would be another notch in the D1/D2 incompatibility belt (perhaps an insurmountable one), but that ship may have already sailed. -Steve
Oct 06 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 "Andrei Alexandrescu" wrote
 Well would you go on a strike if there was a little experimentation with 
 the curls?

I like D too much to give it up based on this one thing. But I would be cursing you profusely as I changed all my existing D code when I move to support D2. I don't think I'd ever feel that it was an improvement, but if it means so much to everyone to abolish the ! syntax, I'd just do the updates and move on. Like I said, it's a bicycle shed color. BTW, this would be another notch in the D1/D2 incompatibility belt (perhaps an insurmountable one), but that ship may have already sailed.

There's no need to worry about it at all. The !() syntax can stay for a long time in vigor as an alternative that gets used less and less, then mentioned less and less, until essentially disabling it becomes a non-event. PL history has many examples of such changes that were successful, and I'll give a few: 1. The K&R function declaration syntax: int foo(a) int a; { return a; } Before trying: do you believe gcc would accept it? How many of us wrote one like that? 2. C++'s member function definition: class A { void foo(); } void A.foo() {} 3. Perl, having a very experimental attitude towards syntax, has effectively "forgot" quite a few syntaxes that weren't successful, but remained harmless. For example, "?pattern?" is equivalent with the well-known "/pattern/", and still accepted - yet hardly anyone uses it anymore. (There was IIRC an odd operator for accessing a package member that also fell into obsolescence, incidentally it might have been "!", does anyone know?) Of course it's ineffective to allow a lot of things and then leave them hanging around, but it is possible to operate a syntax change without too much disruption. Andrei
Oct 06 2008
prev sibling parent KennyTM~ <kennytm gmail.com> writes:
Andrei Alexandrescu wrote:
 Steven Schveighoffer wrote:
 "Ary Borenszweig" wrote
 Andrei Alexandrescu wrote:
 Bill Baxter wrote:
 On Sun, Oct 5, 2008 at 1:06 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 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.

doesn't bother me so much. What Walter said to you was pretty much how it went for me. Seemed weird for a while, but I got used to it. I had to do several double-takes reading this thread thinking people were suggesting to use plain "()" because the little dot is just so easy to miss. I find !() to at least be easier on the eyes than greater-than less-than everywhere in C++. I wouldn't be adamantly opposed to a different syntax, but it would have to be better by leaps and bounds for me to think it was worth the headache. And .() doesn't seem leaps and bounds better to me. I suggest, though, that if you think it looks a lot better you should at least post some example code showing "before" and "after" to try to convince us. Seems like not many here see a lot of point in making the change, so rather than pleading with everyone to try it out on their own, why not just save us the effort and show us how it improves the code you're looking at?

by imagining how it would look like, and it would be hard to sway them. Since you asked, here are some examples copied verbatim from a source file I found handy: alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; For functions: sort.("a._0 == b._0 ? a._1 < b._1 : a._0 < b._0")(all); result.id = std.conv.parse.(uint)(line); I was even more pleased while actually using The Sad Pirate than while imagining how it would be like, probably because typing is also easier (something that's not self-evident when just looking at the code). It looks like The Sad Pirate won't make it. People just don't see it as bringing enough improvement. But I think it is worth pursuing a number of alternatives. The two that to me are the most appealing are: a) Template{Args} Experience with Perl has shown that using {} as parens in addition to blocks is easy to pick up and easy on the eyes. Another argument in favor is that {} are "the right thing" - meaning they are parens that pair properly, as opposed to "<>". Also, they make today's "!()" look like a contraption that creates a new kind of parens from an existing (and ambiguous) kind of parens by prefixing it with a marker. b) Template Arg and Template (Args) This approach not only accepts the need for a contraption, it actually leverages it by allowing you to drop the parens if you only have one argument. That way " " becomes a true operator, the template instantiation operator. Note that this can be done with the current "!" as well, except that Template!Arg does not look to me like anything enticing.

The sad pirate ---------------- alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; The curly braces ---------------- alias DenseMatrix{num} PulType; alias SparseRowsMatrix{num, HashSparseVector} PuuType; alias BiMap{uint, Tuple{uint, uint}, BiMapOptions.lhDense} DicType; The at ---------------- alias DenseMatrix num PulType; alias SparseRowsMatrix (num, HashSparseVector) PuuType; alias BiMap (uint, Tuple (uint, uint), BiMapOptions.lhDense) DicType; --- Personally, I find the {} easier to understand, and it's less typing, but it doesn't allow to omit the closing } for one argument.

I find the {} much easier to read than the . syntax.

To me too.
 The omitting of the braces is not a huge savings.  You are sacrificing 
 a couple characters, actually only one if you are comparing   with {}, 
 at the expense of clarity.  I think it's a special case that is not 
 really worth the trouble.  Besides, it's not hard to type {} when you 
 are so used to it anyways, and if you are interested in saving 
 characters, aliasing is a much better approach.

One thing I kinda dislike about Template Arg is that adding a second arg also asks for the parens. This is a problem present with single- vs. multi-statement blocks as well: if (a) b; If you want to add another statement, you need to add the curls as well: if (a) { b; c; } But then if you want to remove one of the statement you'd want to remove the curls too to stay consistent: if (a) c; This becomes tenuous enough that many people and some coding standards actually prefer to use full block statements to start with, even when they only contain one statement.
 One thing I should mention, since this is all about asthetics, my news 
 reader keeps treating the name param as a linked email address.  
 Somthing that will be very annoying if we adopt the   syntax and end 
 up discussing templates on the NG.

Walter made another point, namely that " " has "a lot of ink" in it. I know what he means. I guess people who wanted templates to be distinguished will find that an advantage :o).
 I still vote to keep ! as it's the easiest solution, and I never have 
 found it annoying ;)

Well would you go on a strike if there was a little experimentation with the curls? Andrei

Frankly speaking one disadvantage of {} is that it is more difficult to refactor it (unlike .() where you just do a s/!\(/.(/g.) If this is gonna effective, I suggest still keeping !() for a while, but make it deprecated, like what has been done to the === operator (the grace period from 0.72 (introduction of "is") to 0.126 (=== deprecated) to 0.174 (=== illegal)).
Oct 06 2008
prev sibling parent reply superdan <super dan.org> writes:
Bill Baxter Wrote:

 On Mon, Oct 6, 2008 at 11:58 PM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 "Ary Borenszweig" wrote

 I still vote to keep ! as it's the easiest solution, and I never have found
 it annoying ;)

Yeh, me too. The (and #) also take up too much width in a small mono-space font like the Proggy font I use. And so they run into the previous and following chars making them less readable. ! is nice and thin so it doesn't have that problem. { } vs ( ) is also a fairly subtle distinction in a small font. Usually the context and usage is different enough that that doesn't matter. But of course you may just tell me I should change my font in that case.

spoken like a true prodigy. yeah. change yer font.
  But I still say ! stands out better.

it stands out. unsure about the `better' part.
 And honestly, my eyes totally just see !(...) as a symbolic string
 now, devoid of any meaning beyond "this is a template".  Mentions of
 it looking like shouting or negation or anything else brought back a
 vague recollection of a time long ago when I still could see that.
 But I can only make it look like shouting in my mind now if I
 purposefully pretend the parentheses are part of a different word, or
 pretend to myself that I'm not looking at D code.

i'm sober now eh. thing is that's important. i don't mind !() much myself. like a mole on an otherwise fine piece of ass. got used to it. but like u i also remember in the beginning i was like, what's wrong with walt did he run out of ideas or what. to some1 coming anew to d stuff like what!(the!(hell!())) is freakin' weird. no two ways about it. you just keep starin' at that mole like austin powers. if there's a way to get rid of it then whynot. helps attract newcomerz eh. parallel with perl is good. much stuff i thot and still think is plain weird in perl. but hash access was never one. looks good & works like a charm.
Oct 06 2008
parent reply Don <nospam nospam.com.au> writes:
Bill Baxter wrote:
 On Tue, Oct 7, 2008 at 2:25 AM, superdan <super dan.org> wrote:
 Bill Baxter Wrote:

 On Mon, Oct 6, 2008 at 11:58 PM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 "Ary Borenszweig" wrote
 I still vote to keep ! as it's the easiest solution, and I never have found
 it annoying ;)

The (and #) also take up too much width in a small mono-space font like the Proggy font I use. And so they run into the previous and following chars making them less readable. ! is nice and thin so it doesn't have that problem. { } vs ( ) is also a fairly subtle distinction in a small font. Usually the context and usage is different enough that that doesn't matter. But of course you may just tell me I should change my font in that case.


Well, I think it's more a matter of the size than the particular font, though. So the remedy would probably be to switch to a font that takes up more screen real-estate, meaning I'll get fewer lines of D to the page. But there *is* a difference between { and ( even with Proggy at 6x10 -- 2 pixels are shifted one position. I suppose it's not any more subtle than the difference between . and , which is seen everywhere. I'm sure I could get used to it if it's what the D community thinks is best. Anyway I think foo{} is more readable than foo.().
 thing is that's important. i don't mind !() much myself. like a mole on an
otherwise fine piece of ass. got used to it. but like u i also remember in the
beginning i was like, what's wrong with walt did he run out of ideas or what.

 to some1 coming anew to d stuff like what!(the!(hell!())) is freakin' weird.
no two ways about it. you just keep starin' at that mole like austin powers. if
there's a way to get rid of it then whynot. helps attract newcomerz eh.

I thought it was bizarre till I read the justification here http://www.digitalmars.com/d/1.0/templates-revisited.html. Then I thought, OK. Not a bad idea. It's better than parsing ambiguities, and being forced to insert spaces between punctuation to avoid them. But I agree that as an utter newbie to D, foo{bar} would probably have seemed more elegant and obvious as a template syntax than re-purposing the unary NOT operator. The newbie's response to "foo{bar} is a template instantiation" would probably be "ok, sure." instead of "Why??" Still it seems like a big bike shed issue. And it's bizarre coming from the guy who's usually the first one to call "bike shed" anytime anyone else makes a suggestion to improve aesthetics.

I agree with all these. There's a lot of other things I wish Andrei were working on instead. I'd hope for a colossal benefit, from something which would break almost all my code... (BTW Putting template parameters inside normal parens would be an adequate benefit).
Oct 07 2008
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Don wrote:
 Bill Baxter wrote:
 On Tue, Oct 7, 2008 at 2:25 AM, superdan <super dan.org> wrote:
 Bill Baxter Wrote:

 On Mon, Oct 6, 2008 at 11:58 PM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 "Ary Borenszweig" wrote
 I still vote to keep ! as it's the easiest solution, and I never 
 have found
 it annoying ;)

The (and #) also take up too much width in a small mono-space font like the Proggy font I use. And so they run into the previous and following chars making them less readable. ! is nice and thin so it doesn't have that problem. { } vs ( ) is also a fairly subtle distinction in a small font. Usually the context and usage is different enough that that doesn't matter. But of course you may just tell me I should change my font in that case.


Well, I think it's more a matter of the size than the particular font, though. So the remedy would probably be to switch to a font that takes up more screen real-estate, meaning I'll get fewer lines of D to the page. But there *is* a difference between { and ( even with Proggy at 6x10 -- 2 pixels are shifted one position. I suppose it's not any more subtle than the difference between . and , which is seen everywhere. I'm sure I could get used to it if it's what the D community thinks is best. Anyway I think foo{} is more readable than foo.().
 thing is that's important. i don't mind !() much myself. like a mole 
 on an otherwise fine piece of ass. got used to it. but like u i also 
 remember in the beginning i was like, what's wrong with walt did he 
 run out of ideas or what.

 to some1 coming anew to d stuff like what!(the!(hell!())) is freakin' 
 weird. no two ways about it. you just keep starin' at that mole like 
 austin powers. if there's a way to get rid of it then whynot. helps 
 attract newcomerz eh.

I thought it was bizarre till I read the justification here http://www.digitalmars.com/d/1.0/templates-revisited.html. Then I thought, OK. Not a bad idea. It's better than parsing ambiguities, and being forced to insert spaces between punctuation to avoid them. But I agree that as an utter newbie to D, foo{bar} would probably have seemed more elegant and obvious as a template syntax than re-purposing the unary NOT operator. The newbie's response to "foo{bar} is a template instantiation" would probably be "ok, sure." instead of "Why??" Still it seems like a big bike shed issue. And it's bizarre coming from the guy who's usually the first one to call "bike shed" anytime anyone else makes a suggestion to improve aesthetics.

I agree with all these. There's a lot of other things I wish Andrei were working on instead.

I am, I am. Soon as Walter fixes a few bugs, I'll rewrite std.algorithm (and add some more to it) in terms of ranges. Map and reduce will likely be lazyfied. Also std.random will define ranges instead of the current ad-hoc interface that works but is not integrated with anything in particular. But bear with me; I have a paper deadline staring me in the face and a thesis to finish.
 I'd hope for a colossal benefit, from something which would break almost 
 all my code...

Not going to break anything, as I explained.
 (BTW Putting template parameters inside normal parens would be an 
 adequate benefit).

I agree. Andrei
Oct 07 2008
prev sibling parent reply Aarti_pl <aarti interia.pl> writes:
Don pisze:
 Bill Baxter wrote:
 On Tue, Oct 7, 2008 at 2:25 AM, superdan <super dan.org> wrote:
 Bill Baxter Wrote:

 On Mon, Oct 6, 2008 at 11:58 PM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 "Ary Borenszweig" wrote
 I still vote to keep ! as it's the easiest solution, and I never 
 have found
 it annoying ;)

The (and #) also take up too much width in a small mono-space font like the Proggy font I use. And so they run into the previous and following chars making them less readable. ! is nice and thin so it doesn't have that problem. { } vs ( ) is also a fairly subtle distinction in a small font. Usually the context and usage is different enough that that doesn't matter. But of course you may just tell me I should change my font in that case.


Well, I think it's more a matter of the size than the particular font, though. So the remedy would probably be to switch to a font that takes up more screen real-estate, meaning I'll get fewer lines of D to the page. But there *is* a difference between { and ( even with Proggy at 6x10 -- 2 pixels are shifted one position. I suppose it's not any more subtle than the difference between . and , which is seen everywhere. I'm sure I could get used to it if it's what the D community thinks is best. Anyway I think foo{} is more readable than foo.().
 thing is that's important. i don't mind !() much myself. like a mole 
 on an otherwise fine piece of ass. got used to it. but like u i also 
 remember in the beginning i was like, what's wrong with walt did he 
 run out of ideas or what.

 to some1 coming anew to d stuff like what!(the!(hell!())) is freakin' 
 weird. no two ways about it. you just keep starin' at that mole like 
 austin powers. if there's a way to get rid of it then whynot. helps 
 attract newcomerz eh.

I thought it was bizarre till I read the justification here http://www.digitalmars.com/d/1.0/templates-revisited.html. Then I thought, OK. Not a bad idea. It's better than parsing ambiguities, and being forced to insert spaces between punctuation to avoid them. But I agree that as an utter newbie to D, foo{bar} would probably have seemed more elegant and obvious as a template syntax than re-purposing the unary NOT operator. The newbie's response to "foo{bar} is a template instantiation" would probably be "ok, sure." instead of "Why??" Still it seems like a big bike shed issue. And it's bizarre coming from the guy who's usually the first one to call "bike shed" anytime anyone else makes a suggestion to improve aesthetics.

I agree with all these. There's a lot of other things I wish Andrei were working on instead. I'd hope for a colossal benefit, from something which would break almost all my code... (BTW Putting template parameters inside normal parens would be an adequate benefit).

Well, I want just say "I agree" to all written above by Bill, Don and others who like current syntax. I wanted to write a bit more today morning but I stopped myself as I would probably write too much :-P ------ I would be much more happy with implementation of my proposal: http://d.puremagic.com/issues/show_bug.cgi?id=1827 I mean here especially syntax for "is expression" for templates. http://digitalmars.com/d/1.0/expression.html#IsExpression As it occurred on Tango conference in talk of Rafał Bocian (who lead the D course for students) syntax for "is expression" and specification (among few other things) is especially difficult for newbies in D. Unfortunately answer from Walter, why he didn't decide to change current syntax was.... guess what? --- It doesn't look nice in code... Bad luck, said sad pirate .( BR Marcin Kuszczak (aarti_pl)
Oct 07 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Aarti_pl wrote:
 Don pisze:
 Bill Baxter wrote:
 On Tue, Oct 7, 2008 at 2:25 AM, superdan <super dan.org> wrote:
 Bill Baxter Wrote:

 On Mon, Oct 6, 2008 at 11:58 PM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 "Ary Borenszweig" wrote
 I still vote to keep ! as it's the easiest solution, and I never 
 have found
 it annoying ;)

The (and #) also take up too much width in a small mono-space font like the Proggy font I use. And so they run into the previous and following chars making them less readable. ! is nice and thin so it doesn't have that problem. { } vs ( ) is also a fairly subtle distinction in a small font. Usually the context and usage is different enough that that doesn't matter. But of course you may just tell me I should change my font in that case.


Well, I think it's more a matter of the size than the particular font, though. So the remedy would probably be to switch to a font that takes up more screen real-estate, meaning I'll get fewer lines of D to the page. But there *is* a difference between { and ( even with Proggy at 6x10 -- 2 pixels are shifted one position. I suppose it's not any more subtle than the difference between . and , which is seen everywhere. I'm sure I could get used to it if it's what the D community thinks is best. Anyway I think foo{} is more readable than foo.().
 thing is that's important. i don't mind !() much myself. like a mole 
 on an otherwise fine piece of ass. got used to it. but like u i also 
 remember in the beginning i was like, what's wrong with walt did he 
 run out of ideas or what.

 to some1 coming anew to d stuff like what!(the!(hell!())) is 
 freakin' weird. no two ways about it. you just keep starin' at that 
 mole like austin powers. if there's a way to get rid of it then 
 whynot. helps attract newcomerz eh.

I thought it was bizarre till I read the justification here http://www.digitalmars.com/d/1.0/templates-revisited.html. Then I thought, OK. Not a bad idea. It's better than parsing ambiguities, and being forced to insert spaces between punctuation to avoid them. But I agree that as an utter newbie to D, foo{bar} would probably have seemed more elegant and obvious as a template syntax than re-purposing the unary NOT operator. The newbie's response to "foo{bar} is a template instantiation" would probably be "ok, sure." instead of "Why??" Still it seems like a big bike shed issue. And it's bizarre coming from the guy who's usually the first one to call "bike shed" anytime anyone else makes a suggestion to improve aesthetics.

I agree with all these. There's a lot of other things I wish Andrei were working on instead. I'd hope for a colossal benefit, from something which would break almost all my code... (BTW Putting template parameters inside normal parens would be an adequate benefit).

Well, I want just say "I agree" to all written above by Bill, Don and others who like current syntax. I wanted to write a bit more today morning but I stopped myself as I would probably write too much :-P ------ I would be much more happy with implementation of my proposal: http://d.puremagic.com/issues/show_bug.cgi?id=1827 I mean here especially syntax for "is expression" for templates. http://digitalmars.com/d/1.0/expression.html#IsExpression As it occurred on Tango conference in talk of Rafał Bocian (who lead the D course for students) syntax for "is expression" and specification (among few other things) is especially difficult for newbies in D. Unfortunately answer from Walter, why he didn't decide to change current syntax was.... guess what? --- It doesn't look nice in code... Bad luck, said sad pirate .( BR Marcin Kuszczak (aarti_pl)

Your proposal should be reevaluated in wake of the conditional templates, which Walter has implemented a couple of releases ago. Andrei
Oct 07 2008
parent reply Marcin Kuszczak <aarti_please_no spam_interia.pl> writes:
Andrei Alexandrescu wrote:

 Aarti_pl wrote:
 I would be much more happy with implementation of my proposal:
 http://d.puremagic.com/issues/show_bug.cgi?id=1827
 
 I mean here especially syntax for "is expression" for templates.
 
 http://digitalmars.com/d/1.0/expression.html#IsExpression
 
 As it occurred on Tango conference in talk of Rafał Bocian (who lead the
 D course for students) syntax for "is expression" and specification
 (among few other things) is especially difficult for newbies in D.
 
 Unfortunately answer from Walter, why he didn't decide to change current
  syntax was.... guess what? --- It doesn't look nice in code...
 
 Bad luck, said sad pirate .(
 
 BR
 Marcin Kuszczak
 (aarti_pl)

Your proposal should be reevaluated in wake of the conditional templates, which Walter has implemented a couple of releases ago. Andrei

Yes, I am aware of that. They are just small part of the whole proposal, but currently implemented in such a way that it is not possible to use it in e.g. static asserts and aliases like it was proposed. I still think that proposal is good (no one pointed out problems with it). It could be implemented as kind of compile time expression once, and then used in other places. It allows also more expressiveness and predictable syntax e.g. void call(T : class)(T instance) {} I hope that above mentioned issues with current design of IsExpression will be eventually fixed somehow, sometime... The strange think here is how minor issues (as most of community doesn't have problem with it) suddenly emerges from deeps and good ideas (which solve real problems) are sunken in the water... Well, I can give more examples if you want :-) -- Regards Marcin Kuszczak (Aarti_pl) ------------------------------------- Ask me why I believe in Jesus - http://www.zapytajmnie.com (en/pl) Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/ -------------------------------------
Oct 07 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Marcin Kuszczak wrote:
 Andrei Alexandrescu wrote:
 
 Aarti_pl wrote:
 I would be much more happy with implementation of my proposal:
 http://d.puremagic.com/issues/show_bug.cgi?id=1827

 I mean here especially syntax for "is expression" for templates.

 http://digitalmars.com/d/1.0/expression.html#IsExpression

 As it occurred on Tango conference in talk of Rafał Bocian (who lead the
 D course for students) syntax for "is expression" and specification
 (among few other things) is especially difficult for newbies in D.

 Unfortunately answer from Walter, why he didn't decide to change current
  syntax was.... guess what? --- It doesn't look nice in code...

 Bad luck, said sad pirate .(

 BR
 Marcin Kuszczak
 (aarti_pl)

templates, which Walter has implemented a couple of releases ago. Andrei

Yes, I am aware of that. They are just small part of the whole proposal, but currently implemented in such a way that it is not possible to use it in e.g. static asserts and aliases like it was proposed. I still think that proposal is good (no one pointed out problems with it). It could be implemented as kind of compile time expression once, and then used in other places. It allows also more expressiveness and predictable syntax e.g. void call(T : class)(T instance) {} I hope that above mentioned issues with current design of IsExpression will be eventually fixed somehow, sometime...

I agree that pattern matching on type trees will have to make it into the language in one form or another. In fact, syntactically it is already there, but compiler bugs/limitations prevent it from happening. One thing with the notation you suggest is that it doesn't quite look like the rest of the language, and perhaps a few simple steps could be taken to make it more integrated.
 The strange think here is how minor issues (as most of community doesn't
 have problem with it) suddenly emerges from deeps and good ideas (which
 solve real problems) are sunken in the water... Well, I can give more
 examples if you want :-)

This is pointing at some being born into royalty while others' good work is under-compensated. Well in a way I'm glad you bring this up. One thing that has caused and is causing an amount of stir and occasional irritation is the perception that I came out of nowhere and captured Walter's attention effortlessly. The reality is that being neighbors with Walter was part of the mix, but the prosaic bulk of it is that Walter cared only because of my previous and ongoing 99% transpiration. For better or worse, this state of affairs makes it that whatever I say is perceived as much more intense, imposing, controversial, quirky, or arrogant, than it is, and therefore much more scrutinized and criticized. This reaction is entirely understandable, and I'm still thinking of ways to assuage it. In the meantime it's costing me time because I feel obligated to answer the many replies to my posts. That being said, it is always great if you can bring to the fore more outstanding problems that you think have good solutions thought of by you or others. Just please consider the above when you compare and contrast them against the petty issue of "!()". Andrei
Oct 07 2008
next sibling parent reply Aarti_pl <aarti interia.pl> writes:
Andrei Alexandrescu pisze:
 Marcin Kuszczak wrote:
 Andrei Alexandrescu wrote:

 Aarti_pl wrote:
 I would be much more happy with implementation of my proposal:
 http://d.puremagic.com/issues/show_bug.cgi?id=1827

 I mean here especially syntax for "is expression" for templates.

 http://digitalmars.com/d/1.0/expression.html#IsExpression

 As it occurred on Tango conference in talk of Rafał Bocian (who lead 
 the
 D course for students) syntax for "is expression" and specification
 (among few other things) is especially difficult for newbies in D.

 Unfortunately answer from Walter, why he didn't decide to change 
 current
  syntax was.... guess what? --- It doesn't look nice in code...

 Bad luck, said sad pirate .(

 BR
 Marcin Kuszczak
 (aarti_pl)

templates, which Walter has implemented a couple of releases ago. Andrei

Yes, I am aware of that. They are just small part of the whole proposal, but currently implemented in such a way that it is not possible to use it in e.g. static asserts and aliases like it was proposed. I still think that proposal is good (no one pointed out problems with it). It could be implemented as kind of compile time expression once, and then used in other places. It allows also more expressiveness and predictable syntax e.g. void call(T : class)(T instance) {} I hope that above mentioned issues with current design of IsExpression will be eventually fixed somehow, sometime...

I agree that pattern matching on type trees will have to make it into the language in one form or another. In fact, syntactically it is already there, but compiler bugs/limitations prevent it from happening. One thing with the notation you suggest is that it doesn't quite look like the rest of the language,

Really? I got in my code a lot of similarly looking code. My proposal is in fact generalization and "uniformization" of existing syntaxes of template parameters and is expression. In most common cases you get same syntax as now.
 and perhaps a few simple steps could be 
 taken to make it more integrated.
 

I have nothing against improving this syntax. But I would be happy to get one uniform syntax for: template parameters, IsExpression, static assert, static if. And to dismiss this ugly: T : T[] creature ;-) With my proposal you got only one universal syntax and few design mistakes fixed. With current implementation state we probably lost opportunity for uniform syntax.
 The strange think here is how minor issues (as most of community doesn't
 have problem with it) suddenly emerges from deeps and good ideas (which
 solve real problems) are sunken in the water... Well, I can give more
 examples if you want :-)

This is pointing at some being born into royalty while others' good work is under-compensated. Well in a way I'm glad you bring this up. One thing that has caused and is causing an amount of stir and occasional irritation is the perception that I came out of nowhere and captured Walter's attention effortlessly. The reality is that being neighbors with Walter was part of the mix, but the prosaic bulk of it is that Walter cared only because of my previous and ongoing 99% transpiration. For better or worse, this state of affairs makes it that whatever I say is perceived as much more intense, imposing, controversial, quirky, or arrogant, than it is, and therefore much more scrutinized and criticized. This reaction is entirely understandable, and I'm still thinking of ways to assuage it. In the meantime it's costing me time because I feel obligated to answer the many replies to my posts.

Great that you see this issue. And even greater that you think rationally how to solve it. Currently I think that it would be good to ask community about top 5 problematic issues with D (not features, nor bugs because it would be better to get more general knowledge). And after sorting out final top 5 list, commit to improve situation or solve problem in these areas in reasonable, defined time. I think that people could post here proposed features, most annoying bugs, D design mistakes, problems with processes, problems with web pages etc. Just one restriction: only 5, single, well defined issues in decreasing priority. Well, I think that it might help to know what community really needs.
 That being said, it is always great if you can bring to the fore more 
 outstanding problems that you think have good solutions thought of by 
 you or others. Just please consider the above when you compare and 
 contrast them against the petty issue of "!()".
 
 
 Andrei

I think that asking people about "top 5 issues" (see above) will bring a lot of such a things. I will certainly contribute with my 5 groszy (Polish "cents"). Best Regards Marcin Kuszczak (aarti_pl)
Oct 08 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Aarti_pl wrote:
 Andrei Alexandrescu pisze:
 I agree that pattern matching on type trees will have to make it into 
 the language in one form or another. In fact, syntactically it is 
 already there, but compiler bugs/limitations prevent it from 
 happening. One thing with the notation you suggest is that it doesn't 
 quite look like the rest of the language, 

Really? I got in my code a lot of similarly looking code. My proposal is in fact generalization and "uniformization" of existing syntaxes of template parameters and is expression. In most common cases you get same syntax as now.

Probably I misread the samples you posted with that bug report. Could you please point me to a more thorough description?
 and perhaps a few simple steps could be taken to make it more integrated.

I have nothing against improving this syntax. But I would be happy to get one uniform syntax for: template parameters, IsExpression, static assert, static if. And to dismiss this ugly: T : T[] creature ;-)

Oh how I wish Walter let that go.
 With my proposal you got only one universal syntax and few design 
 mistakes fixed. With current implementation state we probably lost 
 opportunity for uniform syntax.

Then I guess it's of interest. Again, need to build some more understanding.
 The strange think here is how minor issues (as most of community doesn't
 have problem with it) suddenly emerges from deeps and good ideas (which
 solve real problems) are sunken in the water... Well, I can give more
 examples if you want :-)

This is pointing at some being born into royalty while others' good work is under-compensated. Well in a way I'm glad you bring this up. One thing that has caused and is causing an amount of stir and occasional irritation is the perception that I came out of nowhere and captured Walter's attention effortlessly. The reality is that being neighbors with Walter was part of the mix, but the prosaic bulk of it is that Walter cared only because of my previous and ongoing 99% transpiration. For better or worse, this state of affairs makes it that whatever I say is perceived as much more intense, imposing, controversial, quirky, or arrogant, than it is, and therefore much more scrutinized and criticized. This reaction is entirely understandable, and I'm still thinking of ways to assuage it. In the meantime it's costing me time because I feel obligated to answer the many replies to my posts.

Great that you see this issue. And even greater that you think rationally how to solve it. Currently I think that it would be good to ask community about top 5 problematic issues with D (not features, nor bugs because it would be better to get more general knowledge). And after sorting out final top 5 list, commit to improve situation or solve problem in these areas in reasonable, defined time. I think that people could post here proposed features, most annoying bugs, D design mistakes, problems with processes, problems with web pages etc. Just one restriction: only 5, single, well defined issues in decreasing priority. Well, I think that it might help to know what community really needs.

I think that's a good idea. For now, I'm waiting on the results of the Tango conference to percolate. I understand there was some discussion about mistakes in D's design.
 That being said, it is always great if you can bring to the fore more 
 outstanding problems that you think have good solutions thought of by 
 you or others. Just please consider the above when you compare and 
 contrast them against the petty issue of "!()".


 Andrei

I think that asking people about "top 5 issues" (see above) will bring a lot of such a things. I will certainly contribute with my 5 groszy (Polish "cents").

Ok. Andrei
Oct 08 2008
prev sibling parent reply John Reimer <terminal.node gmail.com> writes:
Hello Andrei,

<snip>

 This is pointing at some being born into royalty while others' good
 work is under-compensated. Well in a way I'm glad you bring this up.
 One thing that has caused and is causing an amount of stir and
 occasional irritation is the perception that I came out of nowhere and
 captured Walter's attention effortlessly. The reality is that being
 neighbors with Walter was part of the mix, but the prosaic bulk of it
 is that Walter cared only because of my previous and ongoing 99%
 transpiration. For better or worse, this state of affairs makes it
 that whatever I say is perceived as much more intense, imposing,
 controversial, quirky, or arrogant, than it is, and therefore much
 more scrutinized and criticized. This reaction is entirely
 understandable, and I'm still thinking of ways to assuage it. In the
 meantime it's costing me time because I feel obligated to answer the
 many replies to my posts.

Anderi, I think you have a good grasp of the complexity of the situation here, and I think (or is it believe ;) ) you are doing a fine job, if not being a little too accomodating (in terms of trying to respond to everyone): I would have collapsed of exhaustion long ago if I were in your shoes. Anyway, keep up the good work. I think the general D/Walter relationship picture will become clearer the longer your participate. It does seem that D is taking a turn for the better again. -JJR
Oct 08 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
John Reimer wrote:
 Hello Andrei,
 
 <snip>
 
 This is pointing at some being born into royalty while others' good
 work is under-compensated. Well in a way I'm glad you bring this up.
 One thing that has caused and is causing an amount of stir and
 occasional irritation is the perception that I came out of nowhere and
 captured Walter's attention effortlessly. The reality is that being
 neighbors with Walter was part of the mix, but the prosaic bulk of it
 is that Walter cared only because of my previous and ongoing 99%
 transpiration. For better or worse, this state of affairs makes it
 that whatever I say is perceived as much more intense, imposing,
 controversial, quirky, or arrogant, than it is, and therefore much
 more scrutinized and criticized. This reaction is entirely
 understandable, and I'm still thinking of ways to assuage it. In the
 meantime it's costing me time because I feel obligated to answer the
 many replies to my posts.

Anderi, I think you have a good grasp of the complexity of the situation here, and I think (or is it believe ;) ) you are doing a fine job, if not being a little too accomodating (in terms of trying to respond to everyone): I would have collapsed of exhaustion long ago if I were in your shoes. Anyway, keep up the good work. I think the general D/Walter relationship picture will become clearer the longer your participate. It does seem that D is taking a turn for the better again. -JJR

Thank you! Andrei
Oct 09 2008
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Andrei Alexandrescu" wrote
 John Reimer wrote:
 Hello Andrei,

 <snip>

 This is pointing at some being born into royalty while others' good
 work is under-compensated. Well in a way I'm glad you bring this up.
 One thing that has caused and is causing an amount of stir and
 occasional irritation is the perception that I came out of nowhere and
 captured Walter's attention effortlessly. The reality is that being
 neighbors with Walter was part of the mix, but the prosaic bulk of it
 is that Walter cared only because of my previous and ongoing 99%
 transpiration. For better or worse, this state of affairs makes it
 that whatever I say is perceived as much more intense, imposing,
 controversial, quirky, or arrogant, than it is, and therefore much
 more scrutinized and criticized. This reaction is entirely
 understandable, and I'm still thinking of ways to assuage it. In the
 meantime it's costing me time because I feel obligated to answer the
 many replies to my posts.

Anderi, I think you have a good grasp of the complexity of the situation here, and I think (or is it believe ;) ) you are doing a fine job, if not being a little too accomodating (in terms of trying to respond to everyone): I would have collapsed of exhaustion long ago if I were in your shoes. Anyway, keep up the good work. I think the general D/Walter relationship picture will become clearer the longer your participate. It does seem that D is taking a turn for the better again. -JJR

Thank you! Andrei

I'd also like to thank you Andrei. Although we don't see eye to eye on every issue, I think what you have brought to the table in many areas is very good. That gets overlooked, especially by me, because your ideas are mostly in Phobos, which I don't use. But I agree with most of your ideas. If I disagree with you it's mostly because I really do disagree, not because I perceive that your ideas automatically make it into D without question from Walter. Just some constructive criticism, it would have been a lot less agitating if you had stated in your original post: Background: Walter has allowed ".()" as an alternative to "!()" for template argument specifications in the next version of D2 as a trial to see if people like it better. Your original statement implied that it was a fact everyone hated !(), and implied that Walter had already blessed the change for D2. This was the point I think that set me off at least. -Steve
Oct 09 2008
prev sibling parent KennyTM~ <kennytm gmail.com> writes:
Ary Borenszweig wrote:
Ary Borenszweig wrote:
 Andrei Alexandrescu wrote:
 Bill Baxter wrote:
 On Sun, Oct 5, 2008 at 1:06 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 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'm joining this discussion late, but I just wanted to say the !() doesn't bother me so much. What Walter said to you was pretty much how it went for me. Seemed weird for a while, but I got used to it. I had to do several double-takes reading this thread thinking people were suggesting to use plain "()" because the little dot is just so easy to miss. I find !() to at least be easier on the eyes than greater-than less-than everywhere in C++. I wouldn't be adamantly opposed to a different syntax, but it would have to be better by leaps and bounds for me to think it was worth the headache. And .() doesn't seem leaps and bounds better to me. I suggest, though, that if you think it looks a lot better you should at least post some example code showing "before" and "after" to try to convince us. Seems like not many here see a lot of point in making the change, so rather than pleading with everyone to try it out on their own, why not just save us the effort and show us how it improves the code you're looking at?

Well part of the problem is that many people made up their mind just by imagining how it would look like, and it would be hard to sway them. Since you asked, here are some examples copied verbatim from a source file I found handy: alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; For functions: sort.("a._0 == b._0 ? a._1 < b._1 : a._0 < b._0")(all); result.id = std.conv.parse.(uint)(line); I was even more pleased while actually using The Sad Pirate than while imagining how it would be like, probably because typing is also easier (something that's not self-evident when just looking at the code). It looks like The Sad Pirate won't make it. People just don't see it as bringing enough improvement. But I think it is worth pursuing a number of alternatives. The two that to me are the most appealing are: a) Template{Args} Experience with Perl has shown that using {} as parens in addition to blocks is easy to pick up and easy on the eyes. Another argument in favor is that {} are "the right thing" - meaning they are parens that pair properly, as opposed to "<>". Also, they make today's "!()" look like a contraption that creates a new kind of parens from an existing (and ambiguous) kind of parens by prefixing it with a marker. b) Template Arg and Template (Args) This approach not only accepts the need for a contraption, it actually leverages it by allowing you to drop the parens if you only have one argument. That way " " becomes a true operator, the template instantiation operator. Note that this can be done with the current "!" as well, except that Template!Arg does not look to me like anything enticing.

So let's have them written down to be able to compare them easier: The sad pirate ---------------- alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; The curly braces ---------------- alias DenseMatrix{num} PulType; alias SparseRowsMatrix{num, HashSparseVector} PuuType; alias BiMap{uint, Tuple{uint, uint}, BiMapOptions.lhDense} DicType; The at ---------------- alias DenseMatrix num PulType; alias SparseRowsMatrix (num, HashSparseVector) PuuType; alias BiMap (uint, Tuple (uint, uint), BiMapOptions.lhDense) DicType; --- Personally, I find the {} easier to understand, and it's less typing, but it doesn't allow to omit the closing } for one argument.
 Andrei


 Andrei Alexandrescu wrote:
 Bill Baxter wrote:
 On Sun, Oct 5, 2008 at 1:06 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 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'm joining this discussion late, but I just wanted to say the !() doesn't bother me so much. What Walter said to you was pretty much how it went for me. Seemed weird for a while, but I got used to it. I had to do several double-takes reading this thread thinking people were suggesting to use plain "()" because the little dot is just so easy to miss. I find !() to at least be easier on the eyes than greater-than less-than everywhere in C++. I wouldn't be adamantly opposed to a different syntax, but it would have to be better by leaps and bounds for me to think it was worth the headache. And .() doesn't seem leaps and bounds better to me. I suggest, though, that if you think it looks a lot better you should at least post some example code showing "before" and "after" to try to convince us. Seems like not many here see a lot of point in making the change, so rather than pleading with everyone to try it out on their own, why not just save us the effort and show us how it improves the code you're looking at?

Well part of the problem is that many people made up their mind just by imagining how it would look like, and it would be hard to sway them. Since you asked, here are some examples copied verbatim from a source file I found handy: alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; For functions: sort.("a._0 == b._0 ? a._1 < b._1 : a._0 < b._0")(all); result.id = std.conv.parse.(uint)(line); I was even more pleased while actually using The Sad Pirate than while imagining how it would be like, probably because typing is also easier (something that's not self-evident when just looking at the code). It looks like The Sad Pirate won't make it. People just don't see it as bringing enough improvement. But I think it is worth pursuing a number of alternatives. The two that to me are the most appealing are: a) Template{Args} Experience with Perl has shown that using {} as parens in addition to blocks is easy to pick up and easy on the eyes. Another argument in favor is that {} are "the right thing" - meaning they are parens that pair properly, as opposed to "<>". Also, they make today's "!()" look like a contraption that creates a new kind of parens from an existing (and ambiguous) kind of parens by prefixing it with a marker. b) Template Arg and Template (Args) This approach not only accepts the need for a contraption, it actually leverages it by allowing you to drop the parens if you only have one argument. That way " " becomes a true operator, the template instantiation operator. Note that this can be done with the current "!" as well, except that Template!Arg does not look to me like anything enticing.

So let's have them written down to be able to compare them easier: The sad pirate ---------------- alias DenseMatrix.(num) PulType; alias SparseRowsMatrix.(num, HashSparseVector) PuuType; alias BiMap.(uint, Tuple.(uint, uint), BiMapOptions.lhDense) DicType; The curly braces ---------------- alias DenseMatrix{num} PulType; alias SparseRowsMatrix{num, HashSparseVector} PuuType; alias BiMap{uint, Tuple{uint, uint}, BiMapOptions.lhDense} DicType; The at ---------------- alias DenseMatrix num PulType; alias SparseRowsMatrix (num, HashSparseVector) PuuType; alias BiMap (uint, Tuple (uint, uint), BiMapOptions.lhDense) DicType; --- Personally, I find the {} easier to understand, and it's less typing, but it doesn't allow to omit the closing } for one argument.
 Andrei


I don't think being able to omit {} is a big problem. Well, we used f(x) in a function with 1 parameter so long without complaining anyway. (Some mathematicians use f`1 to indicate f(1) to avoid confusion with multiplication; and many cases the ( ) are even omitted, e.g. sin 1. So f(x) is not "the" norm.)
Oct 06 2008
prev sibling parent reply Benji Smith <dlanguage benjismith.net> writes:
Andrei Alexandrescu wrote:
 b) Template Arg and Template (Args)
 
 This approach not only accepts the need for a contraption, it actually 
 leverages it by allowing you to drop the parens if you only have one 
 argument. That way " " becomes a true operator, the template 
 instantiation operator. Note that this can be done with the current "!" 
 as well, except that Template!Arg does not look to me like anything 
 enticing.

Interesting. // If this is possible....... auto myTemplate = Template (1, 2, 3, uint); // ......shouldn't this be possible too? auto args = (1, 2, 3, uint); auto myTemplate = Template args; All other binary operators can operate on either a literal or on an expression, and I'd expect a template instantiation operator to do the same. What do you think? --benji
Oct 07 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Benji Smith wrote:
 Andrei Alexandrescu wrote:
 b) Template Arg and Template (Args)

 This approach not only accepts the need for a contraption, it actually 
 leverages it by allowing you to drop the parens if you only have one 
 argument. That way " " becomes a true operator, the template 
 instantiation operator. Note that this can be done with the current 
 "!" as well, except that Template!Arg does not look to me like 
 anything enticing.

Interesting. // If this is possible....... auto myTemplate = Template (1, 2, 3, uint); // ......shouldn't this be possible too? auto args = (1, 2, 3, uint); auto myTemplate = Template args; All other binary operators can operate on either a literal or on an expression, and I'd expect a template instantiation operator to do the same. What do you think?

I think you will have a hard time (re)using parentheses and commas to define literals. Andrei
Oct 07 2008
parent Benji Smith <dlanguage benjismith.net> writes:
Andrei Alexandrescu wrote:
 Benji Smith wrote:
 Andrei Alexandrescu wrote:
 b) Template Arg and Template (Args)

 This approach not only accepts the need for a contraption, it 
 actually leverages it by allowing you to drop the parens if you only 
 have one argument. That way " " becomes a true operator, the template 
 instantiation operator. Note that this can be done with the current 
 "!" as well, except that Template!Arg does not look to me like 
 anything enticing.

Interesting. // If this is possible....... auto myTemplate = Template (1, 2, 3, uint); // ......shouldn't this be possible too? auto args = (1, 2, 3, uint); auto myTemplate = Template args; All other binary operators can operate on either a literal or on an expression, and I'd expect a template instantiation operator to do the same. What do you think?

I think you will have a hard time (re)using parentheses and commas to define literals. Andrei

The actual syntax I used isn't important. That's not what I was talking about. It was the idea that template instantiation is the result of a binary operator. Which, to me, implies that the operands could be either literals or other types of expressions. I suppose the real syntax would be more like this: auto args = Tuple (1, 2, 3, real); auto myTemplate = Template args; So, if " " is a binary operator, it has two operands: a template name and an argument list. But, currently, there's no way to express either of those constructs symbolically. Only literally. It seems to me that, in your proposal, " " is not really an operator. It might act a little bit like an operator, but since its operands can't exist by themselves, then they're not really operands. And " " is not an operator. It'd be cool if template instantiation really was the result of an operator, with all of the necessary implications regarding the operands. Of course, I'm not actually *proposing* that implementation. I'm just drawing a fine line in the sand delineating what it actually means to be an "operator" rather than "template syntax". --benji
Oct 07 2008
prev sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Mon, Oct 6, 2008 at 9:16 AM, Denis Koroskin <2korden gmail.com> wrote:
 On Mon, 06 Oct 2008 16:42:51 +0400, Jarrett Billingsley
 <jarrett.billingsley gmail.com> wrote:

 On Mon, Oct 6, 2008 at 6:59 AM, Denis Koroskin <2korden gmail.com> wrote:

 If we don't omit parenthesises, the ambiguity goes away:

 foo()(5)
 foo(5)()

No it doesn't. Stdout("foo")("bar!").newline;

And what causes ambiguity here? I mean, imagine you can't drop empty paranthesises.

The point is that something like "foo()(5)" could then be either a template instantiation or a chained call.
Oct 06 2008
prev sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
On Tue, Oct 7, 2008 at 2:25 AM, superdan <super dan.org> wrote:
 Bill Baxter Wrote:

 On Mon, Oct 6, 2008 at 11:58 PM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 "Ary Borenszweig" wrote

 I still vote to keep ! as it's the easiest solution, and I never have found
 it annoying ;)

Yeh, me too. The (and #) also take up too much width in a small mono-space font like the Proggy font I use. And so they run into the previous and following chars making them less readable. ! is nice and thin so it doesn't have that problem. { } vs ( ) is also a fairly subtle distinction in a small font. Usually the context and usage is different enough that that doesn't matter. But of course you may just tell me I should change my font in that case.

spoken like a true prodigy. yeah. change yer font.

Well, I think it's more a matter of the size than the particular font, though. So the remedy would probably be to switch to a font that takes up more screen real-estate, meaning I'll get fewer lines of D to the page. But there *is* a difference between { and ( even with Proggy at 6x10 -- 2 pixels are shifted one position. I suppose it's not any more subtle than the difference between . and , which is seen everywhere. I'm sure I could get used to it if it's what the D community thinks is best. Anyway I think foo{} is more readable than foo.().
 thing is that's important. i don't mind !() much myself. like a mole on an
otherwise fine piece of ass. got used to it. but like u i also remember in the
beginning i was like, what's wrong with walt did he run out of ideas or what.

 to some1 coming anew to d stuff like what!(the!(hell!())) is freakin' weird.
no two ways about it. you just keep starin' at that mole like austin powers. if
there's a way to get rid of it then whynot. helps attract newcomerz eh.

I thought it was bizarre till I read the justification here http://www.digitalmars.com/d/1.0/templates-revisited.html. Then I thought, OK. Not a bad idea. It's better than parsing ambiguities, and being forced to insert spaces between punctuation to avoid them. But I agree that as an utter newbie to D, foo{bar} would probably have seemed more elegant and obvious as a template syntax than re-purposing the unary NOT operator. The newbie's response to "foo{bar} is a template instantiation" would probably be "ok, sure." instead of "Why??" Still it seems like a big bike shed issue. And it's bizarre coming from the guy who's usually the first one to call "bike shed" anytime anyone else makes a suggestion to improve aesthetics. --bb
Oct 06 2008
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sun, Oct 05, 2008 at 09:29:37AM -0500, Andrei Alexandrescu wrote:
 Heh. So this change should come together with abolishing goto :o).

Noooooooooooooooooooooooooo!
 
 Andrei

-- Adam D. Ruppe http://arsdnet.net
Oct 05 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Mon, Oct 6, 2008 at 6:59 AM, Denis Koroskin <2korden gmail.com> wrote:

 If we don't omit parenthesises, the ambiguity goes away:

 foo()(5)
 foo(5)()

No it doesn't. Stdout("foo")("bar!").newline;
Oct 06 2008
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 06 Oct 2008 16:42:51 +0400, Jarrett Billingsley  
<jarrett.billingsley gmail.com> wrote:

 On Mon, Oct 6, 2008 at 6:59 AM, Denis Koroskin <2korden gmail.com> wrote:

 If we don't omit parenthesises, the ambiguity goes away:

 foo()(5)
 foo(5)()

No it doesn't. Stdout("foo")("bar!").newline;

And what causes ambiguity here? I mean, imagine you can't drop empty paranthesises.
Oct 06 2008
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Tue, 07 Oct 2008 16:27:00 +0200, Benji Smith <dlanguage benjismith.net>  
wrote:

 Jarrett Billingsley wrote:
 On Mon, Oct 6, 2008 at 6:59 AM, Denis Koroskin <2korden gmail.com>  
 wrote:

 If we don't omit parenthesises, the ambiguity goes away:

 foo()(5)
 foo(5)()

Stdout("foo")("bar!").newline;

This is one of the main reasons I dislike opCall. Combined with optional-parentheses for function invocation, opCall is a poison-pill that creates a lot of potential ambiguities and prevents the implementation of more compelling features. --benji

void delegate() foo() { return delegate void() {);}; } ? -- Simen
Oct 08 2008
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Walter Bright" wrote
 Steven Schveighoffer wrote:
 It's very alarming to me that something like this just has no problem 
 getting in the language without community feedback.

It's there at the moment so we can look at it and see if we like it. I know Andrei likes it. Anyhow, this is the opportunity for community feedback.

Well, here is my feedback. First, I hate it when D has two ways of doing something. For example, C style array declarations, or function pointers. But those have good reasons. We want the new style because it's unambiguous and context-free, but we want the old style to allow easy porting of C code. But this change has no qualities I can see except that Andrei thinks it looks better (at least, that's the only reason he's given). There are not compatibility issues with C or some other language, it's just a new syntax that looks different. Are there problems with the original !()? Please give a reason for this addition besides asthetics, and then we can discuss the merits. Or if the community overwhelmingly loves this new syntax, I guess that's a good reason. Otherwise, I think it should be rejected on the simple principle of not fixing things that aren't broken. -Steve
Oct 04 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 "Walter Bright" wrote
 Steven Schveighoffer wrote:
 It's very alarming to me that something like this just has no problem 
 getting in the language without community feedback.

know Andrei likes it. Anyhow, this is the opportunity for community feedback.

Well, here is my feedback. First, I hate it when D has two ways of doing something. For example, C style array declarations, or function pointers. But those have good reasons. We want the new style because it's unambiguous and context-free, but we want the old style to allow easy porting of C code.

I agree that D should not gratuitously define two ways of doing something.
 But this change has no qualities I can see except that Andrei thinks it 
 looks better (at least, that's the only reason he's given).

Believes, not thinks :o).
 There are not 
 compatibility issues with C or some other language, it's just a new syntax 
 that looks different.  Are there problems with the original !()?  Please 
 give a reason for this addition besides asthetics, and then we can discuss 
 the merits.  Or if the community overwhelmingly loves this new syntax, I 
 guess that's a good reason.  Otherwise, I think it should be rejected on the 
 simple principle of not fixing things that aren't broken.

There are no objective differences, only the subjective arguments I brought based on linguistic conotations of "!". And actually I didn't come up with that argument - it literally came to me. Word followed by exclamation mark. Our brains are wired to interpret that as an exclamation. If it's frequent enough in code, it becomes really jarring. The one way to figure whether you'd aesthetically like something or not is to try it on some code. Unfortunately, that's not yet possible until the next release (Walter was kind enough to send me an alpha for a test drive). So my only request is kindly please hold off judgment until you can play with the notation and see how you feel. Andrei
Oct 04 2008
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Andrei Alexandrescu" wrote
 Steven Schveighoffer wrote:
 "Walter Bright" wrote
 Steven Schveighoffer wrote:
 It's very alarming to me that something like this just has no problem 
 getting in the language without community feedback.

know Andrei likes it. Anyhow, this is the opportunity for community feedback.

Well, here is my feedback. First, I hate it when D has two ways of doing something. For example, C style array declarations, or function pointers. But those have good reasons. We want the new style because it's unambiguous and context-free, but we want the old style to allow easy porting of C code.

I agree that D should not gratuitously define two ways of doing something.
 But this change has no qualities I can see except that Andrei thinks it 
 looks better (at least, that's the only reason he's given).

Believes, not thinks :o).

yes, of course, my bad.
 There are not compatibility issues with C or some other language, it's 
 just a new syntax that looks different.  Are there problems with the 
 original !()?  Please give a reason for this addition besides asthetics, 
 and then we can discuss the merits.  Or if the community overwhelmingly 
 loves this new syntax, I guess that's a good reason.  Otherwise, I think 
 it should be rejected on the simple principle of not fixing things that 
 aren't broken.

There are no objective differences, only the subjective arguments I brought based on linguistic conotations of "!". And actually I didn't come up with that argument - it literally came to me. Word followed by exclamation mark. Our brains are wired to interpret that as an exclamation. If it's frequent enough in code, it becomes really jarring.

For what it's worth, I never had a 'jarring' experience with the ! syntax. It reads perfectly fine to me, and I actually like it.
 The one way to figure whether you'd aesthetically like something or not is 
 to try it on some code. Unfortunately, that's not yet possible until the 
 next release (Walter was kind enough to send me an alpha for a test 
 drive). So my only request is kindly please hold off judgment until you 
 can play with the notation and see how you feel.

Firstly, I won't be playing with it unless it's released for D1 (which I doubt), and secondly, I don't think it's worth the effort to have something like this changed for minor annoyance. Since it's completely engrained on our brains already and we get along fine with !, there should have to be a really good reason to change it. 'looking better' doesn't strike me as a really good reason, especially when it is subjective (and especially when I disagree with the opinion). This seems like a bicycle shed issue to me. Please note, I'm not arguing for ! because of some technical reason, I probably would have been fine with ., but since it's already !, I think we should keep it that way unless a good technical reason comes up. The reasons you have put forth don't make it worth it in my mind. If this change is implemented, Walter is going to have a hard time arguing that it's not worth changing invariant to immutable... -Steve
Oct 04 2008
next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Steven Schveighoffer wrote:
 "Andrei Alexandrescu" wrote
 Steven Schveighoffer wrote:
 "Walter Bright" wrote
 Steven Schveighoffer wrote:
 It's very alarming to me that something like this just has no problem 
 getting in the language without community feedback.

know Andrei likes it. Anyhow, this is the opportunity for community feedback.

First, I hate it when D has two ways of doing something. For example, C style array declarations, or function pointers. But those have good reasons. We want the new style because it's unambiguous and context-free, but we want the old style to allow easy porting of C code.

 But this change has no qualities I can see except that Andrei thinks it 
 looks better (at least, that's the only reason he's given).


yes, of course, my bad.
 There are not compatibility issues with C or some other language, it's 
 just a new syntax that looks different.  Are there problems with the 
 original !()?  Please give a reason for this addition besides asthetics, 
 and then we can discuss the merits.  Or if the community overwhelmingly 
 loves this new syntax, I guess that's a good reason.  Otherwise, I think 
 it should be rejected on the simple principle of not fixing things that 
 aren't broken.

brought based on linguistic conotations of "!". And actually I didn't come up with that argument - it literally came to me. Word followed by exclamation mark. Our brains are wired to interpret that as an exclamation. If it's frequent enough in code, it becomes really jarring.

For what it's worth, I never had a 'jarring' experience with the ! syntax. It reads perfectly fine to me, and I actually like it.
 The one way to figure whether you'd aesthetically like something or not is 
 to try it on some code. Unfortunately, that's not yet possible until the 
 next release (Walter was kind enough to send me an alpha for a test 
 drive). So my only request is kindly please hold off judgment until you 
 can play with the notation and see how you feel.

Firstly, I won't be playing with it unless it's released for D1 (which I doubt), and secondly, I don't think it's worth the effort to have something like this changed for minor annoyance. Since it's completely engrained on our brains already and we get along fine with !, there should have to be a really good reason to change it. 'looking better' doesn't strike me as a really good reason, especially when it is subjective (and especially when I disagree with the opinion). This seems like a bicycle shed issue to me.

hehe... how about we swap '!' for '.' and in exchange we get to use something other than 'enum' for manifest constants ;-) Sean
Oct 04 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Sean Kelly wrote:
 hehe... how about we swap '!' for '.' and in exchange we get to use 
 something other than 'enum' for manifest constants ;-)

You know what, I believe "." is such an improvement, I'd join the movement. Andrei
Oct 05 2008
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 If this change is implemented, Walter is going to have a hard time arguing 
 that it's not worth changing invariant to immutable...

Speaking of which... guess what he just did :o). Andrei
Oct 05 2008
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Denis Koroskin wrote:
 On Sun, 05 Oct 2008 17:31:14 +0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Steven Schveighoffer wrote:
 If this change is implemented, Walter is going to have a hard time 
 arguing that it's not worth changing invariant to immutable...

Speaking of which... guess what he just did :o). Andrei

Oh, come on... did he? :D

His initiative. Can I use this as a bargaining chip? :o) Andrei
Oct 05 2008
prev sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Andrei Alexandrescu wrote:
 Steven Schveighoffer wrote:
 If this change is implemented, Walter is going to have a hard time 
 arguing that it's not worth changing invariant to immutable...

Speaking of which... guess what he just did :o).

*dances for joy* Sean
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Sean Kelly wrote:
 Andrei Alexandrescu wrote:
 Steven Schveighoffer wrote:
 If this change is implemented, Walter is going to have a hard time 
 arguing that it's not worth changing invariant to immutable...

Speaking of which... guess what he just did :o).

*dances for joy*

Well are you greased properly for giving .() a shot? :o) Andrei
Oct 05 2008
parent Sean Kelly <sean invisibleduck.org> writes:
Andrei Alexandrescu wrote:
 Sean Kelly wrote:
 Andrei Alexandrescu wrote:
 Steven Schveighoffer wrote:
 If this change is implemented, Walter is going to have a hard time 
 arguing that it's not worth changing invariant to immutable...

Speaking of which... guess what he just did :o).

*dances for joy*

Well are you greased properly for giving .() a shot? :o)

I'll certainly try it. Sean
Oct 05 2008
prev sibling next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Andrei Alexandrescu wrote:
 Steven Schveighoffer wrote:
 "Walter Bright" wrote
 Steven Schveighoffer wrote:
 It's very alarming to me that something like this just has no 
 problem getting in the language without community feedback.

I know Andrei likes it. Anyhow, this is the opportunity for community feedback.

Well, here is my feedback. First, I hate it when D has two ways of doing something. For example, C style array declarations, or function pointers. But those have good reasons. We want the new style because it's unambiguous and context-free, but we want the old style to allow easy porting of C code.

I agree that D should not gratuitously define two ways of doing something.
 But this change has no qualities I can see except that Andrei thinks 
 it looks better (at least, that's the only reason he's given).

Believes, not thinks :o).
 There are not compatibility issues with C or some other language, it's 
 just a new syntax that looks different.  Are there problems with the 
 original !()?  Please give a reason for this addition besides 
 asthetics, and then we can discuss the merits.  Or if the community 
 overwhelmingly loves this new syntax, I guess that's a good reason.  
 Otherwise, I think it should be rejected on the simple principle of 
 not fixing things that aren't broken.

There are no objective differences, only the subjective arguments I brought based on linguistic conotations of "!". And actually I didn't come up with that argument - it literally came to me. Word followed by exclamation mark. Our brains are wired to interpret that as an exclamation. If it's frequent enough in code, it becomes really jarring.

I like the use of '!' specifically for its linguistic connotation. It communicates to me that what's happening isn't normal run-time stuff.
 The one way to figure whether you'd aesthetically like something or not 
 is to try it on some code. Unfortunately, that's not yet possible until 
 the next release (Walter was kind enough to send me an alpha for a test 
 drive). So my only request is kindly please hold off judgment until you 
 can play with the notation and see how you feel.

Will do. It's easy enough to search-replace '!' with '.' Sean
Oct 04 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Sean Kelly wrote:
 I like the use of '!' specifically for its linguistic connotation.  It 
 communicates to me that what's happening isn't normal run-time stuff.

But I'm sure you don't have a beef with function template argument deduction, and normal run-time stuff that ain't.
 The one way to figure whether you'd aesthetically like something or 
 not is to try it on some code. Unfortunately, that's not yet possible 
 until the next release (Walter was kind enough to send me an alpha for 
 a test drive). So my only request is kindly please hold off judgment 
 until you can play with the notation and see how you feel.

Will do. It's easy enough to search-replace '!' with '.'

You'll need a sed expression to not catch unary ! and != as well. Andrei
Oct 05 2008
parent reply Sean Kelly <sean invisibleduck.org> writes:
Andrei Alexandrescu wrote:
 Sean Kelly wrote:
 Will do.  It's easy enough to search-replace '!' with '.'

You'll need a sed expression to not catch unary ! and != as well.

Nah, just replace "!(" with ".(" I basically never use "!(exp)" in conditions so there should be no problems. Sean
Oct 05 2008
next sibling parent KennyTM~ <kennytm gmail.com> writes:
Sean Kelly wrote:
 Andrei Alexandrescu wrote:
 Sean Kelly wrote:
 Will do.  It's easy enough to search-replace '!' with '.'

You'll need a sed expression to not catch unary ! and != as well.

Nah, just replace "!(" with ".(" I basically never use "!(exp)" in conditions so there should be no problems. Sean

auto reply = "Oh I didn't know that!(sarcasm)"; And for some unknown reason I decided to write templateName! (templateParameter).etc; I believe we require a lexer unless you know you won't write these bad (but valid) code.
Oct 05 2008
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Sean Kelly wrote:
 Andrei Alexandrescu wrote:
 Sean Kelly wrote:
 Will do.  It's easy enough to search-replace '!' with '.'

You'll need a sed expression to not catch unary ! and != as well.

Nah, just replace "!(" with ".(" I basically never use "!(exp)" in conditions so there should be no problems.

Well well laziness never helps. sed --in-place -e 's/\([a-zA-Z0-9_]\)\(\s*\)!\(\s*\)(/\1\2.\3(/' *.d Preserves whitespace used around !, too. The major problem is it will transform insides of strings too. Also, won't transform instantiations across lines, and won't work with Unicode symbols... Andrei
Oct 05 2008
parent Sean Kelly <sean invisibleduck.org> writes:
Andrei Alexandrescu wrote:
 Sean Kelly wrote:
 Andrei Alexandrescu wrote:
 Sean Kelly wrote:
 Will do.  It's easy enough to search-replace '!' with '.'

You'll need a sed expression to not catch unary ! and != as well.

Nah, just replace "!(" with ".(" I basically never use "!(exp)" in conditions so there should be no problems.

Well well laziness never helps. sed --in-place -e 's/\([a-zA-Z0-9_]\)\(\s*\)!\(\s*\)(/\1\2.\3(/' *.d Preserves whitespace used around !, too. The major problem is it will transform insides of strings too. Also, won't transform instantiations across lines, and won't work with Unicode symbols...

I'm just talking about my own code here, not a universal conversion tool. Sean
Oct 05 2008
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Sun, 05 Oct 2008 00:12:06 -0500, Andrei Alexandrescu wrote:

 Word followed by exclamation mark. Our brains are wired to interpret that as
an 
 exclamation. If it's frequent enough in code, it becomes really jarring.

I too find the form ... Template!(arg1, arg2, arg3) a bit uncomfortable. If we need to visually distinguish templates (compile-time constructs) from run-time constructs, I would advocate a totally different style all together. Maybe something more along the lines of the DDoc style ... (Template arg1 arg2 arg3) Nested it would look like ... (This (That (TheOther crap))) But I'm being too left-field, I suspect. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Oct 05 2008
parent reply Christopher Wright <dhasenan gmail.com> writes:
Derek Parnell wrote:
 On Sun, 05 Oct 2008 00:12:06 -0500, Andrei Alexandrescu wrote:
 
 Word followed by exclamation mark. Our brains are wired to interpret that as
an 
 exclamation. If it's frequent enough in code, it becomes really jarring.

I too find the form ... Template!(arg1, arg2, arg3) a bit uncomfortable. If we need to visually distinguish templates (compile-time constructs) from run-time constructs, I would advocate a totally different style all together. Maybe something more along the lines of the DDoc style ... (Template arg1 arg2 arg3) Nested it would look like ... (This (That (TheOther crap))) But I'm being too left-field, I suspect.

It's actually a lot quicker to type ( than !( -- it's reasonable for me to use the same shift key for the and the (. So I wouldn't much complain about this, except for the ugliness. And !( is also ugly.
Oct 05 2008
parent =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Christopher Wright wrote:
 Derek Parnell wrote:
 On Sun, 05 Oct 2008 00:12:06 -0500, Andrei Alexandrescu wrote:

 Word followed by exclamation mark. Our brains are wired to interpret 
 that as an exclamation. If it's frequent enough in code, it becomes 
 really jarring.

I too find the form ... Template!(arg1, arg2, arg3) a bit uncomfortable. If we need to visually distinguish templates (compile-time constructs) from run-time constructs, I would advocate a totally different style all together. Maybe something more along the lines of the DDoc style ... (Template arg1 arg2 arg3) Nested it would look like ... (This (That (TheOther crap))) But I'm being too left-field, I suspect.

It's actually a lot quicker to type ( than !( -- it's reasonable for me to use the same shift key for the and the (. So I wouldn't much complain about this, except for the ugliness. And !( is also ugly.

Since I only use the left shift key, it’s equally quick to type for me. I don’t see much point in basing syntax on how fast you can type. Also, on German keyboard layouts (and I think lots of other non-us based, European layouts), the is at Compose + q, which is pretty uncomfortable.
Oct 05 2008
prev sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
On Mon, Oct 6, 2008 at 11:58 PM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 "Ary Borenszweig" wrote

 I still vote to keep ! as it's the easiest solution, and I never have found
 it annoying ;)

Yeh, me too. The (and #) also take up too much width in a small mono-space font like the Proggy font I use. And so they run into the previous and following chars making them less readable. ! is nice and thin so it doesn't have that problem. { } vs ( ) is also a fairly subtle distinction in a small font. Usually the context and usage is different enough that that doesn't matter. But of course you may just tell me I should change my font in that case. But I still say ! stands out better. And honestly, my eyes totally just see !(...) as a symbolic string now, devoid of any meaning beyond "this is a template". Mentions of it looking like shouting or negation or anything else brought back a vague recollection of a time long ago when I still could see that. But I can only make it look like shouting in my mind now if I purposefully pretend the parentheses are part of a different word, or pretend to myself that I'm not looking at D code. --bb
Oct 06 2008
prev sibling next sibling parent "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Sun, 05 Oct 2008 11:48:35 +0100, Tom S  
<h3r3tic remove.mat.uni.torun.pl> wrote:

 I don't like using "." for template instantiation. The tokenizer in my  
 eyes clearly separates constructs at ".". On the other hand, "!" as a  
 graphical character is more 'filled', thus doesn't separate the  
 identifier and arguments that much visually.

 foo.bar          <-  obviously member access
 foo.(bar, baz)   <-  multiple member access?

 ... It looks like it should yield a tuple containing bar and baz :P

Oct 05 2008
prev sibling next sibling parent Moritz Warning <moritzwarning web.de> writes:
On Sat, 04 Oct 2008 23:50:47 -0500, Andrei Alexandrescu wrote:

 Alexander Pánek wrote:
 Andrei Alexandrescu wrote:


 I believe the clear distinction is not only unnecessary, but
 undesirable. We should actively fight against it.
 
 Andrei

I also believe the distinction is unnecessary. About the exclamation mark vs dot. I believe the dot would be worse: - code completion in IDEs get confused - '!' may be an unary operator, but '.' is also some kind of operator that is often used otherwise. - changing the syntax always hurts, even if it might be easy to do so. The justification should be strong.
Oct 05 2008
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 05 Oct 2008 17:31:14 +0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Steven Schveighoffer wrote:
 If this change is implemented, Walter is going to have a hard time  
 arguing that it's not worth changing invariant to immutable...

Speaking of which... guess what he just did :o). Andrei

Oh, come on... did he? :D
Oct 05 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Sun, Oct 5, 2008 at 12:06 AM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 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.

Long argument short: I don't mind !() at all, and changing it to .() seems like a pointless pedanticism. But since you're the one suggesting it, there's a very good chance of it getting into the language (if it hasn't already), so there's not much use arguing against it.
Oct 05 2008
prev sibling next sibling parent reply "Bent Rasmussen" <IncredibleShrinkingSphere Gmail.com> writes:
Somewhere there is the dream of a pure function call syntax

    abs(real) sqrt(abs(real) x);

Total unification. And possibly total impossibility.

Looks beautiful tho.

- Bent

"Steven Schveighoffer" <schveiguy yahoo.com> skrev i meddelelsen 
news:gc9ab4$1ai4$1 digitalmars.com...
 "Andrei Alexandrescu" wrote
 (Background: Walter has kindly allowed ".()" as an alternative to the 
 ugly "!()" for template argument specifications.)

:( Another case of multiple syntax possibilities. What was wrong with !() ? I didn't consider it ugly at all. In fact, I prefer it. It's very alarming to me that something like this just has no problem getting in the language without community feedback.
 Just a quick question - I am feeling an increasing desire to add a 
 template called Positive to std.typecons. Then Positive.(real) would 
 restrict its values to only positive real numbers etc.

I wouldn't use it, if that helps at all. Even if it was in Tango (i.e. not just because I don't use Phobos). -Steve

Oct 05 2008
next sibling parent KennyTM~ <kennytm gmail.com> writes:
Bent Rasmussen wrote:
 Somewhere there is the dream of a pure function call syntax
 
    abs(real) sqrt(abs(real) x);
 
 Total unification. And possibly total impossibility.
 
 Looks beautiful tho.
 
 - Bent
 

But how to check 0 ∉ gamma(ℝ)? This notation is simple for invertible functions and sets with finite elements, but won't be applicable for more complicated functions and types.
 "Steven Schveighoffer" <schveiguy yahoo.com> skrev i meddelelsen 
 news:gc9ab4$1ai4$1 digitalmars.com...
 "Andrei Alexandrescu" wrote
 (Background: Walter has kindly allowed ".()" as an alternative to the 
 ugly "!()" for template argument specifications.)

:( Another case of multiple syntax possibilities. What was wrong with !() ? I didn't consider it ugly at all. In fact, I prefer it. It's very alarming to me that something like this just has no problem getting in the language without community feedback.
 Just a quick question - I am feeling an increasing desire to add a 
 template called Positive to std.typecons. Then Positive.(real) would 
 restrict its values to only positive real numbers etc.

I wouldn't use it, if that helps at all. Even if it was in Tango (i.e. not just because I don't use Phobos). -Steve


Oct 05 2008
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Bent Rasmussen wrote:
 Somewhere there is the dream of a pure function call syntax
 
    abs(real) sqrt(abs(real) x);
 
 Total unification. And possibly total impossibility.
 
 Looks beautiful tho.

It does look beautiful. It won't as soon as "!" enters the picture. Andrei
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Denis Koroskin wrote:
 On Sun, 05 Oct 2008 20:09:25 +0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Bent Rasmussen wrote:
 Somewhere there is the dream of a pure function call syntax
     abs(real) sqrt(abs(real) x);
  Total unification. And possibly total impossibility.
  Looks beautiful tho.

It does look beautiful. It won't as soon as "!" enters the picture. Andrei

I second that. It also brings templates and functions closer: int x = sqrt(42); // what is sqrt - a CT-function or a template? I don't care!

So in the "me" vs. "we" argument there's actually five "me"s or so. This has Agent Smith written all over it! :o) Andrei
Oct 05 2008
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 05 Oct 2008 17:49:48 +0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 KennyTM~ wrote:
 Michel Fortin wrote:
 On 2008-10-05 01:14:17 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> said:

 I don't favor "." any more than the next guy, but I am glad there is  
 awareness of how unfit a choice "!" is. If you have any ideas, please  
 post them! Ah! I! Exclaimed! Again!

Hum, I don't think we have much choice, it'll have to be something in this lot: Positive!(real)(joke); Positive.(real)(joke); Positive#(real)(joke); Positive (real)(joke); Positive&(real)(joke); Positive`(real)(joke); Positive´(real)(joke); Positive^(real)(joke); Positive¨(real)(joke); Positive\(real)(joke); Anything else I forgot? Or we could use special delimiter characters: Positive<real>(joke); Positive“real”(joke); Positive«real»(joke); Positive#real (joke); Each having its own problem though. My preference still goes to "!(". - - - The ".(" syntax makes me think more of something like this: void func(T, alias methodOfT, A...)(T obj, A args) { obj.(methodOfT)(args); } which I which I could do. If methodOfT was a string, I suppose I could use string mixins, but it pushes diagnostics about misnamed methods further in the template and requires adding quotes to the template parameter when instanciating.

f«T»(x); a valid construct, and to workaround that « and » can't be easily typed you could substitute it with f\<T\>(x); ---

Yah I would've like French quotes too.
 Anyway, I think the .() syntax is not as good as !() because the . is  
 pretty hideous before another punctuation mark (which may be a good  
 thing, I don't know), and one could easily miss it.
  And even if .() is allowed, please don't remove !() -- it will break  
 significantly many code, and it doesn't cause any ambiguity either  
 (unlike .func() vs .prop).

Many languages have successfully dealt with similar situations by simply allowing both but promoting only one in books and other documentation. Speaking of which, I'm on verge of signing with Addison Wesley Longman for delivering TDPL in April. Andrei

Great news! Your site still says it appears in October, though.
Oct 05 2008
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 05 Oct 2008 20:09:25 +0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Bent Rasmussen wrote:
 Somewhere there is the dream of a pure function call syntax
     abs(real) sqrt(abs(real) x);
  Total unification. And possibly total impossibility.
  Looks beautiful tho.

It does look beautiful. It won't as soon as "!" enters the picture. Andrei

I second that. It also brings templates and functions together: int x = sqrt(42); // what is sqrt - a CT-function of a template? I don't care!
Oct 05 2008
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 05 Oct 2008 20:09:25 +0400, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

 Bent Rasmussen wrote:
 Somewhere there is the dream of a pure function call syntax
     abs(real) sqrt(abs(real) x);
  Total unification. And possibly total impossibility.
  Looks beautiful tho.

It does look beautiful. It won't as soon as "!" enters the picture. Andrei

I second that. It also brings templates and functions closer: int x = sqrt(42); // what is sqrt - a CT-function or a template? I don't care!
Oct 05 2008
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
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.

That's kinda hard to argue against because it's a sheer fact.

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} enum deviceStatusMask = 3; ... 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?
Oct 05 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Sun, Oct 5, 2008 at 8:57 PM, Chris R. Miller
<lordsauronthegreat gmail.com> wrote:
 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).

Unambiguous grammar, you fail it. foo(bar)(baz); // template instantiation or a chained call? This _can_ be _made_ to work, but it would mean that the parse tree would be dependent upon semantic analysis, and that just makes things slow and awful. I.e. C++.
Oct 05 2008
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 06 Oct 2008 14:56:43 +0400, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2008-10-05 22:23:16 -0400, Michel Fortin <michel.fortin michelf.com>  
 said:

 Well, not so sure about that: I'm pretty sure it's needed for  
 disambiguation too. Let's say you have:
  	void foo(int x)();
 	void foo(T)(T x);
  	foo(5);
  Is foo(5) a the same as foo!(5), or does it call foo!(int).foo(5) ?  
 Under the current rules, it's the second (you can write foo!(5) to call  
 the first). If you allow templates to be instanciated without the "!",  
 then I guess both will match and you'll have ambiguity.
  If you could avoid having sets of parameters, one for the function and  
 one for the template, then you could get rid of the "!" in a snap...

Or... we could just disallow having both at the same time, just like you can't have two functions with the same arguments. A call to foo(5) would be ambigous in the above situation, plain and simple. Is this reasonable? We could still disambiguate using: foo!(5); and: foo(int)(5); In this context, the ! becomes the "force this to be template arguments" operator, or the "do not deduce template arguments, I'll provide them" operator. Or we could just forget ! completely and leave the first one impossible to disambiguate. Which makes me think that it's sad we can't write the second as: foo(int, 5); I'd be much nicer to the eye.

If we don't omit parenthesises, the ambiguity goes away: foo()(5) foo(5)()
Oct 06 2008
prev sibling next sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
On Sun, Oct 5, 2008 at 1:06 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 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'm joining this discussion late, but I just wanted to say the !() doesn't bother me so much. What Walter said to you was pretty much how it went for me. Seemed weird for a while, but I got used to it. I had to do several double-takes reading this thread thinking people were suggesting to use plain "()" because the little dot is just so easy to miss. I find !() to at least be easier on the eyes than greater-than less-than everywhere in C++. I wouldn't be adamantly opposed to a different syntax, but it would have to be better by leaps and bounds for me to think it was worth the headache. And .() doesn't seem leaps and bounds better to me. I suggest, though, that if you think it looks a lot better you should at least post some example code showing "before" and "after" to try to convince us. Seems like not many here see a lot of point in making the change, so rather than pleading with everyone to try it out on their own, why not just save us the effort and show us how it improves the code you're looking at? --bb
Oct 06 2008
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Tue, 07 Oct 2008 20:05:28 +0400, Benji Smith <dlanguage benjismith.net>  
wrote:

 Andrei Alexandrescu wrote:
 Benji Smith wrote:
 Andrei Alexandrescu wrote:
 b) Template Arg and Template (Args)

 This approach not only accepts the need for a contraption, it  
 actually leverages it by allowing you to drop the parens if you only  
 have one argument. That way " " becomes a true operator, the template  
 instantiation operator. Note that this can be done with the current  
 "!" as well, except that Template!Arg does not look to me like  
 anything enticing.

Interesting. // If this is possible....... auto myTemplate = Template (1, 2, 3, uint); // ......shouldn't this be possible too? auto args = (1, 2, 3, uint); auto myTemplate = Template args; All other binary operators can operate on either a literal or on an expression, and I'd expect a template instantiation operator to do the same. What do you think?

define literals. Andrei

The actual syntax I used isn't important. That's not what I was talking about. It was the idea that template instantiation is the result of a binary operator. Which, to me, implies that the operands could be either literals or other types of expressions. I suppose the real syntax would be more like this: auto args = Tuple (1, 2, 3, real); auto myTemplate = Template args; So, if " " is a binary operator, it has two operands: a template name and an argument list. But, currently, there's no way to express either of those constructs symbolically. Only literally. It seems to me that, in your proposal, " " is not really an operator. It might act a little bit like an operator, but since its operands can't exist by themselves, then they're not really operands. And " " is not an operator. It'd be cool if template instantiation really was the result of an operator, with all of the necessary implications regarding the operands. Of course, I'm not actually *proposing* that implementation. I'm just drawing a fine line in the sand delineating what it actually means to be an "operator" rather than "template syntax". --benji

You could do it this way: alias Tuple (1,2,3,real) Args; alias Template Args MyTemplate;
Oct 07 2008
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Mon, 06 Oct 2008 12:39:29 +0200, Benji Smith <dlanguage benjismith.net>  
wrote:

 Andrei Alexandrescu wrote:
 One morning I woke up with the sudden realization of what the problem  
 was: the shouting.

Here's my (nutty) opinion: Neither the "!" nor the "." really want to be there. I think the language really *wants* to be using a bare set of parens for templates. Because the language actually wants templates and functions to converge. Instead of a special-case syntax for templates, and a set of special rules for CTFE, and a whole set of parallel "static" statements (if, else, foreach) and a special compile-type-only type construct (tuples), just let D be D, either at runtime or compile type. If a function could return a Type, and if that type could be used in a Type Constructor, then you'd have all the magic template sauce you'd need, and templates could happily converge themselves with regular functions. Hey! I told you it was going to be nutty!!! <g> --benji

That would only work for templated functions, though. What about templated types? -- Simen
Oct 08 2008
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> 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.

All bears are animals, so lets call all animals bears. See where this is wrong? -- Simen
Oct 08 2008
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 08 Oct 2008 22:02:18 +0200, Simen Kjaeraas  
<simen.kjaras gmail.com> wrote:

 On Mon, 06 Oct 2008 12:39:29 +0200, Benji Smith  
 <dlanguage benjismith.net> wrote:

 Andrei Alexandrescu wrote:
 One morning I woke up with the sudden realization of what the problem  
 was: the shouting.

Here's my (nutty) opinion: Neither the "!" nor the "." really want to be there. I think the language really *wants* to be using a bare set of parens for templates. Because the language actually wants templates and functions to converge. Instead of a special-case syntax for templates, and a set of special rules for CTFE, and a whole set of parallel "static" statements (if, else, foreach) and a special compile-type-only type construct (tuples), just let D be D, either at runtime or compile type. If a function could return a Type, and if that type could be used in a Type Constructor, then you'd have all the magic template sauce you'd need, and templates could happily converge themselves with regular functions. Hey! I told you it was going to be nutty!!! <g> --benji

That would only work for templated functions, though. What about templated types?

Forget I ever let my ass do the thinking. I'd really like to see how this would look, but I feel it'd make for uglier syntax. -- Simen
Oct 08 2008
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
Benji Smith <dlanguage benjismith.net> wrote:

 This idea first occurred to me when CTFE was introduced. I thought to  
 myself "if we can have compile-time function exectuion", why can't we  
 also have "runtime template instantiation"? Why is it only possible to  
 define a new type (or to choose which type) at compile time?

 In languages like Ruby, you can attach new methods to an object at  
 runtime. In .NET, you can generate, compile, and load new bytecode  
 instructions on the fly.

 It's hard to think of cases where you'd really want to construct a new  
 type at runtime. But maybe....automatically generating a library of  
 types by querying a database schema?

 --benji

The reasons for such things are to be found in the compiler. Optimizing an expression whose types you do not know, and allocating space for a type that may change its size under your feet - sounds to me like tricky business. -- Simen
Oct 08 2008
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:

 Simen Kjaeraas wrote:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> 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.

All bears are animals, so lets call all animals bears. See where this is wrong?

The correct reasoning to apply is, if you see a white bear, would you call it a different way? Andrei

Mayhaps. But to me, a manifest constant is not just a bear of a different color, but possibly one with six legs, a prehensile tail, bat wings, and riding a helicopter. And I'm pretty sure I would not classify that as a bear, even if it still had fur and powerful jaws, and would make for a fun teddy. -- Simen
Oct 08 2008
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 08 Oct 2008 23:11:14 +0200, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Simen Kjaeraas wrote:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:

 Simen Kjaeraas wrote:
 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> 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.

All bears are animals, so lets call all animals bears. See where this is wrong?

The correct reasoning to apply is, if you see a white bear, would you call it a different way? Andrei

different color, but possibly one with six legs, a prehensile tail, bat wings, and riding a helicopter. And I'm pretty sure I would not classify that as a bear, even if it still had fur and powerful jaws, and would make for a fun teddy.

But you just agreed that enum is a manifest constant. Andrei

Indeed. But my point is that not all manifest constants are enumerations, as the name enum seems to suggest. That is my gripe with the choice. And I fear it will continue like that. -- Simen
Oct 08 2008
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 About proliferation of types: I don't think that follows at all. Math 
 found positive numbers special enough to dedicate them a special 
 notation (|R with subscript "+"). There's also a special notation for 
 nonzero real numbers (|R with superscript "*"). There is no special 
 notation for any of the sets you mentioned. That is bound to mean 
 something.

I'm not a math major. But in college I took 4 years of math, up through integration in the complex plane and branch cuts (which I never did properly understand <g>). Every engineering/physics class was a math class. I never saw this notation. I am not suggesting it doesn't exist, just that it became commonplace fairly recently, or that it isn't commonplace at least at the undergraduate level. This plays into the numbers issue you mentioned.
Oct 04 2008
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
Walter Bright wrote:
 Andrei Alexandrescu wrote:
 About proliferation of types: I don't think that follows at all. Math 
 found positive numbers special enough to dedicate them a special 
 notation (|R with subscript "+"). There's also a special notation for 
 nonzero real numbers (|R with superscript "*"). There is no special 
 notation for any of the sets you mentioned. That is bound to mean 
 something.

I'm not a math major. But in college I took 4 years of math, up through integration in the complex plane and branch cuts (which I never did properly understand <g>). Every engineering/physics class was a math class. I never saw this notation. I am not suggesting it doesn't exist, just that it became commonplace fairly recently, or that it isn't commonplace at least at the undergraduate level. This plays into the numbers issue you mentioned.

Probably they'd used (0, +∞) and [0, +∞) instead. --- BTW, negative real numbers can also be indicated as ℝ⁻ (R^- if Unicode is not supported). Is it now special enough to deserve a Negative!() template? :p I think these sign checking should be done through contracts or "conditional template" (? whatever it's called; I haven't used one of these yet) instead. Unless you can runtime check that Positive!(double) x = 6; Positive!(double) y = 12; Positive!(double) z = void; z = x - y; // raises error. Positive!(double) w; din.readf("%g", &w); // raises error if user enters negative number. But I don't think uint, etc now even do these checks.
Oct 05 2008
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
Bruce Adams wrote:
 On Sun, 05 Oct 2008 11:18:24 +0100, KennyTM~ <kennytm gmail.com> wrote:
 Probably they'd used (0, +∞) and [0, +∞) instead.

 ---

 BTW, negative real numbers can also be indicated as ℝ⁻ (R^- if Unicode 
 is not supported). Is it now special enough to deserve a Negative!() 
 template? :p

Nice use of unicode.
 I think these sign checking should be done through contracts or 
 "conditional template" (? whatever it's called; I haven't used one of 
 these yet) instead. Unless you can runtime check that

    Positive!(double) x = 6;
    Positive!(double) y = 12;

Compile time check
    Positive!(double) z = void;

This must be an syntax error surely?

type x = void; means don't initialize x. Or have I missed something?
 
    z = x - y;  // raises error.

The return type of subtraction goes outside the postive domain: i.e. if it needed to exist (which it probably doesn't) the function spec would be: double opMinus(Positive!(double) y, Positive!(double) y); So this is actually: z = cast(Positive!(double))(x - y) Hence there is the necessary check which could be either run-time or compile time.

Most of the time it can't be compile time because if I've initialized x and y to be some runtime-dependent function (e.g. sin(current time)) then you can't be sure of the sign of x-y. So the check must be made into runtime unless the expression can be CTFE-ed.
 
    Positive!(double) w;
    din.readf("%g", &w);  // raises error if user enters negative number.

 But I don't think uint, etc now even do these checks.

This would ideally work as above but I see your problem. The contract of readf is not tight enough. You should rewrite as: double wtemp; din.read("%g", &wtemp); Positive!(double) w = wtemp; // type check applied here

But this is getting ugly :)
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
KennyTM~ wrote:
 Bruce Adams wrote:
 On Sun, 05 Oct 2008 11:18:24 +0100, KennyTM~ <kennytm gmail.com> wrote:
 Probably they'd used (0, +∞) and [0, +∞) instead.

 ---

 BTW, negative real numbers can also be indicated as ℝ⁻ (R^- if 
 Unicode is not supported). Is it now special enough to deserve a 
 Negative!() template? :p

Nice use of unicode.
 I think these sign checking should be done through contracts or 
 "conditional template" (? whatever it's called; I haven't used one of 
 these yet) instead. Unless you can runtime check that

    Positive!(double) x = 6;
    Positive!(double) y = 12;

Compile time check
    Positive!(double) z = void;

This must be an syntax error surely?

type x = void; means don't initialize x. Or have I missed something?
    z = x - y;  // raises error.

The return type of subtraction goes outside the postive domain: i.e. if it needed to exist (which it probably doesn't) the function spec would be: double opMinus(Positive!(double) y, Positive!(double) y); So this is actually: z = cast(Positive!(double))(x - y) Hence there is the necessary check which could be either run-time or compile time.

Most of the time it can't be compile time because if I've initialized x and y to be some runtime-dependent function (e.g. sin(current time)) then you can't be sure of the sign of x-y. So the check must be made into runtime unless the expression can be CTFE-ed.
    Positive!(double) w;
    din.readf("%g", &w);  // raises error if user enters negative number.

 But I don't think uint, etc now even do these checks.

This would ideally work as above but I see your problem. The contract of readf is not tight enough. You should rewrite as: double wtemp; din.read("%g", &wtemp); Positive!(double) w = wtemp; // type check applied here

But this is getting ugly :)

Of course. It's because it uses the "!". :o) Andrei
Oct 05 2008
parent KennyTM~ <kennytm gmail.com> writes:
Andrei Alexandrescu wrote:
 KennyTM~ wrote:
 Bruce Adams wrote:
 On Sun, 05 Oct 2008 11:18:24 +0100, KennyTM~ <kennytm gmail.com> wrote:
 Probably they'd used (0, +∞) and [0, +∞) instead.

 ---

 BTW, negative real numbers can also be indicated as ℝ⁻ (R^- if 
 Unicode is not supported). Is it now special enough to deserve a 
 Negative!() template? :p

Nice use of unicode.
 I think these sign checking should be done through contracts or 
 "conditional template" (? whatever it's called; I haven't used one 
 of these yet) instead. Unless you can runtime check that

    Positive!(double) x = 6;
    Positive!(double) y = 12;

Compile time check
    Positive!(double) z = void;

This must be an syntax error surely?

type x = void; means don't initialize x. Or have I missed something?
    z = x - y;  // raises error.

The return type of subtraction goes outside the postive domain: i.e. if it needed to exist (which it probably doesn't) the function spec would be: double opMinus(Positive!(double) y, Positive!(double) y); So this is actually: z = cast(Positive!(double))(x - y) Hence there is the necessary check which could be either run-time or compile time.

Most of the time it can't be compile time because if I've initialized x and y to be some runtime-dependent function (e.g. sin(current time)) then you can't be sure of the sign of x-y. So the check must be made into runtime unless the expression can be CTFE-ed.
    Positive!(double) w;
    din.readf("%g", &w);  // raises error if user enters negative 
 number.

 But I don't think uint, etc now even do these checks.

This would ideally work as above but I see your problem. The contract of readf is not tight enough. You should rewrite as: double wtemp; din.read("%g", &wtemp); Positive!(double) w = wtemp; // type check applied here

But this is getting ugly :)

Of course. It's because it uses the "!". :o) Andrei

I mean using temporary variable explicitly is ugly -_-
Oct 05 2008
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
KennyTM~ wrote:
 Walter Bright wrote:
 Andrei Alexandrescu wrote:
 About proliferation of types: I don't think that follows at all. Math 
 found positive numbers special enough to dedicate them a special 
 notation (|R with subscript "+"). There's also a special notation for 
 nonzero real numbers (|R with superscript "*"). There is no special 
 notation for any of the sets you mentioned. That is bound to mean 
 something.

I'm not a math major. But in college I took 4 years of math, up through integration in the complex plane and branch cuts (which I never did properly understand <g>). Every engineering/physics class was a math class. I never saw this notation. I am not suggesting it doesn't exist, just that it became commonplace fairly recently, or that it isn't commonplace at least at the undergraduate level. This plays into the numbers issue you mentioned.

Probably they'd used (0, +∞) and [0, +∞) instead.

Depends on the field. The problem is, either notation is hard to google for.
 BTW, negative real numbers can also be indicated as ℝ⁻ (R^- if Unicode 
 is not supported). Is it now special enough to deserve a Negative!() 
 template? :p

Where I grew up I think the sign came as a subscript. This is because the nonzero "*" sign could then be added as a superscript. The notations I know of are (in TeX notation): non-negative real numbers: R_+ non-zero real numbers: R^* positive numbers: R_+^* Rarely used (I never saw them, actually): non-positive real numbers: R_- negative numbers: R_-^* Oh, I just realized that bounded numbers can't express nonzero real numbers.
 I think these sign checking should be done through contracts or 
 "conditional template" (? whatever it's called; I haven't used one of 
 these yet) instead. Unless you can runtime check that
 
   Positive!(double) x = 6;
   Positive!(double) y = 12;
   Positive!(double) z = void;
   z = x - y;  // raises error.
   Positive!(double) w;
   din.readf("%g", &w);  // raises error if user enters negative number.
 
 But I don't think uint, etc now even do these checks.

They don't because they have a slightly different purpose and charter. Andrei
Oct 05 2008
prev sibling parent "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Sun, 05 Oct 2008 11:18:24 +0100, KennyTM~ <kennytm gmail.com> wrote:
 Probably they'd used (0, +∞) and [0, +∞) instead.

 ---

 BTW, negative real numbers can also be indicated as ℝ⁻ (R^- if Unicode  
 is not supported). Is it now special enough to deserve a Negative!()  
 template? :p

Nice use of unicode.
 I think these sign checking should be done through contracts or  
 "conditional template" (? whatever it's called; I haven't used one of  
 these yet) instead. Unless you can runtime check that

    Positive!(double) x = 6;
    Positive!(double) y = 12;

Compile time check
    Positive!(double) z = void;

This must be an syntax error surely?
    z = x - y;  // raises error.

The return type of subtraction goes outside the postive domain: i.e. if it needed to exist (which it probably doesn't) the function spec would be: double opMinus(Positive!(double) y, Positive!(double) y); So this is actually: z = cast(Positive!(double))(x - y) Hence there is the necessary check which could be either run-time or compile time.
    Positive!(double) w;
    din.readf("%g", &w);  // raises error if user enters negative number.

 But I don't think uint, etc now even do these checks.

This would ideally work as above but I see your problem. The contract of readf is not tight enough. You should rewrite as: double wtemp; din.read("%g", &wtemp); Positive!(double) w = wtemp; // type check applied here -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Oct 05 2008
prev sibling next sibling parent Sean Kelly <sean invisibleduck.org> writes:
Andrei Alexandrescu wrote:
 Hello,
 
 
 (Background: Walter has kindly allowed ".()" as an alternative to the 
 ugly "!()" for template argument specifications.)
 
 Just a quick question - I am feeling an increasing desire to add a 
 template called Positive to std.typecons. Then Positive.(real) would 
 restrict its values to only positive real numbers etc.

Sounds like range-restricted values, which people have been asking for as a language feature for ages. The idea has merit.
 However, there is also the risk that Positive has the same fate the many 
 SafeInt implementation have had in C++: many defined them, nobody used 
 them. What do you think? If you had Positive in std and felt like 
 crunching some numbers, would you use it?

See below.
 In order to get things really started, there's already been an exchange 
 with Walter on the matter. His reply was (I haven't asked for 
 permission, but I'm pretty sure he'd agree making it public):
 
 ==============
 Honestly, I wouldn't use it. I'd rather have an in contract for sqrt 
 that asserts the argument is positive. Also, this opens the door to 
 Negative, NegativeOrZero, ZeroOrInfinity, Odd, Even, Prime, 
 SixOrFifteen, etc.
 ==============
 
 My answer to that was:
 
 ==============
 About contracts: Let me explain how I think that's inferior to Positive 
 in two ways.
 
 1. Enough functions are defined on positive numbers only, to justify 
 factoring that contract out of the functions themselves.

So you're saying the problem with contracts here is code duplication? I'm not sure I follow.
 2. The efficiency perk is that when using several such functions 
 together, there's only one check; once in Positive-land, no more checks 
 are necessary.

To be fair, there's one check for each time such a value is constructed or altered. So you're simply assuming that the checked value will be constructed and then never altered. But how is this different from using contracts? I like the idea of checked values for safety, but I think efficiency concerns would prevent me from using them for actual work. For example, let's say that I'm performing a bunch of computations. I only really want to check whether the result is in range--I don't care about the intermediate values. So I'd be inclined to forgo the use of checked values for the actual work and simply return a checked type at the end. But this is exactly how contracts work! Why would I bother with checked values if I can do the same checking in in/out clauses?
 About proliferation of types: I don't think that follows at all. Math 
 found positive numbers special enough to dedicate them a special 
 notation (|R with subscript "+"). There's also a special notation for 
 nonzero real numbers (|R with superscript "*"). There is no special 
 notation for any of the sets you mentioned. That is bound to mean 
 something.

It's clearly as important to describe the attributes of a variable in math as it is in programming. So mathematicians settled on the notation you mention, and programmers have largely settled on the use of contracts. There may still be some value in more math-like notation in programming, but I don't personally see much of a need for it in this case. Like Walter, I'd continue to use contracts unless some compelling reason can be provided for using this notation instead. Sean
Oct 04 2008
prev sibling next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Andrei Alexandrescu escribi:
 (Background: Walter has kindly allowed ".()" as an alternative to the 
 ugly "!()" for template argument specifications.)
 
 For example:
 
 Positive.(real) sqrt(Positive.(real) x);

I can't read that. I see a bunch of calls and casts. !() was a little hard at first, but this is impossible. Of course, this is just my opinion, I don't know what the others think about it... Another problem, from an IDE perspective: "Positive." will trigger autocomplete of Positive's members, ugh.
Oct 04 2008
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 05 Oct 2008 07:36:58 +0400, Ary Borenszweig <ary esperanto.org.ar>  
wrote:
 Another problem, from an IDE perspective: "Positive." will trigger  
 autocomplete of Positive's members, ugh.

Thumbs up! That's you all over :)
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Denis Koroskin wrote:
 On Sun, 05 Oct 2008 07:36:58 +0400, Ary Borenszweig 
 <ary esperanto.org.ar> wrote:
 Another problem, from an IDE perspective: "Positive." will trigger 
 autocomplete of Positive's members, ugh.

Thumbs up! That's you all over :)

Uninstantiated templates don't have members, except inside the template itself. This is a non-issue. Andrei
Oct 05 2008
prev sibling next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Andrei Alexandrescu Wrote:

 Hello,
 
 
 (Background: Walter has kindly allowed ".()" as an alternative to the 
 ugly "!()" for template argument specifications.)

I don't think .() is visually distinct enough, especially when property syntax can be used.
 
 Just a quick question - I am feeling an increasing desire to add a 
 template called Positive to std.typecons. Then Positive.(real) would 
 restrict its values to only positive real numbers etc.

It's interesting, but I'd use contracts instead. I'd use an ultra short notation with no perceptible user impact (to save me typing). A not null type is more interesting to me.
 
 The implementation would accept conversion from its base type, e.g. 
 Positive.(real) can be constructed from a real. The constructor enforces 
 dynamically the condition. Also, Positive.(real) accepts implicit 
 conversion to real (no checking necessary).
 
 There are many places in which Positive can be useful, most notably 
 specifications of interfaces. For example:
 
 Positive.(real) sqrt(Positive.(real) x);

Ummm... That's not even the correct signature for square root. It should accept non negative numbers.
 
 These specifications are also efficient because checking for positivity 
 is done outside sqrt; if you had a Positive.(real) to start with, there 
 is no cascading checking necessary so there's one test less to do.
 
 However, there is also the risk that Positive has the same fate the many 
 SafeInt implementation have had in C++: many defined them, nobody used 
 them. What do you think? If you had Positive in std and felt like 
 crunching some numbers, would you use it?
 
 In order to get things really started, there's already been an exchange 
 with Walter on the matter. His reply was (I haven't asked for 
 permission, but I'm pretty sure he'd agree making it public):
 
 ==============
 Honestly, I wouldn't use it. I'd rather have an in contract for sqrt 
 that asserts the argument is positive. Also, this opens the door to 
 Negative, NegativeOrZero, ZeroOrInfinity, Odd, Even, Prime, 
 SixOrFifteen, etc.
 ==============
 
 My answer to that was:
 
 ==============
 About contracts: Let me explain how I think that's inferior to Positive 
 in two ways.
 
 1. Enough functions are defined on positive numbers only, to justify 
 factoring that contract out of the functions themselves.
 
 2. The efficiency perk is that when using several such functions 
 together, there's only one check; once in Positive-land, no more checks 
 are necessary.
 
 About proliferation of types: I don't think that follows at all. Math 
 found positive numbers special enough to dedicate them a special 
 notation (|R with subscript "+"). There's also a special notation for 
 nonzero real numbers (|R with superscript "*"). There is no special 
 notation for any of the sets you mentioned. That is bound to mean something.
 ==============
 
 I'm interesting in further arguments. This feature is a numbers issue 
 (pun not intended), meaning it will be any good only if enough people 
 find it useful enough to actually use it in their own code and 
 libraries, therefore building momentum behind it.
 
 
 Andrei

Oct 04 2008
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jason House wrote:
 Andrei Alexandrescu Wrote:
 Positive.(real) sqrt(Positive.(real) x);

Ummm... That's not even the correct signature for square root. It should accept non negative numbers.

Rats. I was thinking positive means >= 0 and strictly positive means > 0. According to Wikipedia, positive really means strictly positive and the longer-to-type NonNegative should be used instead :o|. For such a simple concept, a short and sweet name is pivotal. If there are any ideas for a better choice, please make them known. Andrei
Oct 04 2008
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Jason House wrote:
 Andrei Alexandrescu Wrote:
 Positive.(real) sqrt(Positive.(real) x);

Ummm... That's not even the correct signature for square root. It should accept non negative numbers.

0. According to Wikipedia, positive really means strictly positive and the longer-to-type NonNegative should be used instead :o|. For such a simple concept, a short and sweet name is pivotal. If there are any ideas for a better choice, please make them known. Andrei

Maybe create the templates as a back end using whatever name, and then create typedefs/aliases for ufloat, udouble, ureal? This would definitely be consistent with ints and easy to remember.
Oct 04 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Jason House wrote:
 Andrei Alexandrescu Wrote:
 Positive.(real) sqrt(Positive.(real) x);

should accept non negative numbers.

0. According to Wikipedia, positive really means strictly positive and the longer-to-type NonNegative should be used instead :o|. For such a simple concept, a short and sweet name is pivotal. If there are any ideas for a better choice, please make them known. Andrei

Maybe create the templates as a back end using whatever name, and then create typedefs/aliases for ufloat, udouble, ureal? This would definitely be consistent with ints and easy to remember.

I think that's a great idea. So, the question becomes: how do people feel about using ufloat, udouble, and ureal? Andrei
Oct 04 2008
next sibling parent =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Andrei Alexandrescu wrote:
 dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s 
 article
 Jason House wrote:
 Andrei Alexandrescu Wrote:
 Positive.(real) sqrt(Positive.(real) x);

should accept non negative numbers.

0. According to Wikipedia, positive really means strictly positive and the longer-to-type NonNegative should be used instead :o|. For such a simple concept, a short and sweet name is pivotal. If there are any ideas for a better choice, please make them known. Andrei

Maybe create the templates as a back end using whatever name, and then create typedefs/aliases for ufloat, udouble, ureal? This would definitely be consistent with ints and easy to remember.

I think that's a great idea. So, the question becomes: how do people feel about using ufloat, udouble, and ureal?

I’d even suggest putting those into the language as primitive types — I just figured out they are not. Puzzled me a bit.
Oct 04 2008
prev sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Andrei Alexandrescu wrote:

 Maybe create the templates as a back end using whatever name, and then 
 create
 typedefs/aliases for ufloat, udouble, ureal?  This would definitely be 
 consistent
 with ints and easy to remember.

I think that's a great idea. So, the question becomes: how do people feel about using ufloat, udouble, and ureal?

I'll just insert my usual "real is not a type, but an alias"... At least udouble is easier to understand than Positive.(double) --anders
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Anders F Bjrklund wrote:
 Andrei Alexandrescu wrote:
 
 Maybe create the templates as a back end using whatever name, and 
 then create
 typedefs/aliases for ufloat, udouble, ureal?  This would definitely 
 be consistent
 with ints and easy to remember.

I think that's a great idea. So, the question becomes: how do people feel about using ufloat, udouble, and ureal?

I'll just insert my usual "real is not a type, but an alias"...

I thought it's a real type. No?
 At least udouble is easier to understand than Positive.(double)

The comparison was with Positive!(double). I'm Positive! Andrei
Oct 05 2008
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Andrei Alexandrescu wrote:

 I'll just insert my usual "real is not a type, but an alias"...

I thought it's a real type. No?

No, "real" is an alias for "largest hardware implemented floating point size". So it can be anything from 64 to 80 to 96 to 128 bits in size... I dubbed the two underlying IEEE types "extended" (80) and "quad" (128), as in "*** precision" (just like single precision and double precision)
 At least udouble is easier to understand than Positive.(double)

The comparison was with Positive!(double). I'm Positive!

:-) --anders
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Anders F Bjrklund wrote:
 Andrei Alexandrescu wrote:
 
 I'll just insert my usual "real is not a type, but an alias"...

I thought it's a real type. No?

No, "real" is an alias for "largest hardware implemented floating point size". So it can be anything from 64 to 80 to 96 to 128 bits in size...

Yes, it's a type of unknown width. But it's a distinct type nontheless for all I know. For example, even on a system that had 64-bit math, real would be a distinct type from double even if they had the same size and behavior. Andrei
Oct 05 2008
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Andrei Alexandrescu wrote:

 No, "real" is an alias for "largest hardware implemented floating point
 size". So it can be anything from 64 to 80 to 96 to 128 bits in size...

Yes, it's a type of unknown width. But it's a distinct type nontheless for all I know. For example, even on a system that had 64-bit math, real would be a distinct type from double even if they had the same size and behavior.

Right, for all practical purposes it maps straight to C's "long double". --anders
Oct 05 2008
prev sibling parent reply "Peter C. Chapin" <pcc482719 gmail.com> writes:
Andrei Alexandrescu wrote:

 Rats. I was thinking positive means >= 0 and strictly positive means >
 0. According to Wikipedia, positive really means strictly positive and
 the longer-to-type NonNegative should be used instead :o|. For such a
 simple concept, a short and sweet name is pivotal. If there are any
 ideas for a better choice, please make them known.

Ada supports the ability to create new types from the primitive numeric types by adding range constraints to the primitive. The Ada community finds this useful and would appreciate the sort of feature you are talking about. In Ada there are even two predefined subtypes of Integer subtype Positive is Integer range 1 .. Integer'Last; subtype Natural is Integer range 0 .. Integer'Last; So for non-negative integers... what about "natural"? Peter
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Peter C. Chapin wrote:
 Andrei Alexandrescu wrote:
 
 Rats. I was thinking positive means >= 0 and strictly positive means >
 0. According to Wikipedia, positive really means strictly positive and
 the longer-to-type NonNegative should be used instead :o|. For such a
 simple concept, a short and sweet name is pivotal. If there are any
 ideas for a better choice, please make them known.

Ada supports the ability to create new types from the primitive numeric types by adding range constraints to the primitive. The Ada community finds this useful and would appreciate the sort of feature you are talking about. In Ada there are even two predefined subtypes of Integer subtype Positive is Integer range 1 .. Integer'Last; subtype Natural is Integer range 0 .. Integer'Last; So for non-negative integers... what about "natural"?

Well uint kinda occupied that space, although as we all know it's not exactly a natural number. I think the comparison with experience in Ada is sensible. I wished there was a predefined subtipe of Real too... Andrei
Oct 05 2008
prev sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 05 Oct 2008 08:41:50 +0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s  
 article
 Jason House wrote:
 Andrei Alexandrescu Wrote:
 Positive.(real) sqrt(Positive.(real) x);

should accept non negative numbers.

0. According to Wikipedia, positive really means strictly positive and the longer-to-type NonNegative should be used instead :o|. For such a simple concept, a short and sweet name is pivotal. If there are any ideas for a better choice, please make them known. Andrei

create typedefs/aliases for ufloat, udouble, ureal? This would definitely be consistent with ints and easy to remember.

I think that's a great idea. So, the question becomes: how do people feel about using ufloat, udouble, and ureal? Andrei

much, Much, MUCH better! Especially once overflows would trigger exceptions I believe these would become very valuable.
Oct 05 2008
prev sibling next sibling parent reply =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Andrei Alexandrescu wrote:
 There are many places in which Positive can be useful, most notably 
 specifications of interfaces. For example:
 
 Positive.(real) sqrt(Positive.(real) x);

I think such restrictions/contracts are up to the implementation of an interface. There’s no point in defining them with interfaces, besides specific mathematical functions, which don’t play such big role in the “real world” as far as I can tell.
 These specifications are also efficient because checking for positivity 
 is done outside sqrt; if you had a Positive.(real) to start with, there 
 is no cascading checking necessary so there's one test less to do.

Same goes for contracts. It basically happens outside the body of the function, already.
 However, there is also the risk that Positive has the same fate the many 
 SafeInt implementation have had in C++: many defined them, nobody used 
 them. What do you think? If you had Positive in std and felt like 
 crunching some numbers, would you use it?

I wouldn’t, since I can’t seem to see the point of it — well, besides trying to express mathematical notations in D, which in turn I find pretty pointless..
 About contracts: Let me explain how I think that's inferior to Positive 
 in two ways.
 
 1. Enough functions are defined on positive numbers only, to justify 
 factoring that contract out of the functions themselves.

I don’t think that the amount of functions defined as such really justify such a kind of (additional) restriction option. Positivity can be asserted by only accepting positive (unsigned) primitive types and a null argument is asserted in a contract. Adding another layer of restriction doesn’t make it any better. Especially not if you only need it in a very specific set of functions.
 2. The efficiency perk is that when using several such functions 
 together, there's only one check; once in Positive-land, no more checks 
 are necessary.

Speaking mathematically correct, you can’t really let sqrt return a signed, positive value, since every sqrt has two results — positive and negative. There’s no point in restricting the return type to positive and especially not signed values.
Oct 04 2008
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Alexander Pánek wrote:
 Andrei Alexandrescu wrote:
 There are many places in which Positive can be useful, most notably 
 specifications of interfaces. For example:

 Positive.(real) sqrt(Positive.(real) x);

I think such restrictions/contracts are up to the implementation of an interface. There’s no point in defining them with interfaces, besides specific mathematical functions, which don’t play such big role in the “real world” as far as I can tell.

Well we do use uint in the real world and we hope (partially in vain, sigh) that it models natural numbers. Positive gives ufloat, udouble, or ureal, as truly checked positive numbers. I mean nonnegative. Damn.
 These specifications are also efficient because checking for 
 positivity is done outside sqrt; if you had a Positive.(real) to start 
 with, there is no cascading checking necessary so there's one test 
 less to do.

Same goes for contracts. It basically happens outside the body of the function, already.

No. Contracts are not foldable. Folding them could be in theory done by the compiler, but requires nonscalable interprocedural analysis.
 However, there is also the risk that Positive has the same fate the 
 many SafeInt implementation have had in C++: many defined them, nobody 
 used them. What do you think? If you had Positive in std and felt like 
 crunching some numbers, would you use it?

I wouldn’t, since I can’t seem to see the point of it — well, besides trying to express mathematical notations in D, which in turn I find pretty pointless..

Why is that pointless? To the extent it's doable, it would only help.
 About contracts: Let me explain how I think that's inferior to 
 Positive in two ways.

 1. Enough functions are defined on positive numbers only, to justify 
 factoring that contract out of the functions themselves.

I don’t think that the amount of functions defined as such really justify such a kind of (additional) restriction option. Positivity can be asserted by only accepting positive (unsigned) primitive types and a null argument is asserted in a contract. Adding another layer of restriction doesn’t make it any better. Especially not if you only need it in a very specific set of functions.

No, this is a misunderstanding. There's no more need for sqrt to check its argument - it's guaranteed to be nonnegative. That's the whole point of the whole shtick.
 2. The efficiency perk is that when using several such functions 
 together, there's only one check; once in Positive-land, no more 
 checks are necessary.

Speaking mathematically correct, you can’t really let sqrt return a signed, positive value, since every sqrt has two results — positive and negative. There’s no point in restricting the return type to positive and especially not signed values.

I think this is off. In pretty much all languages I know, sqrt for real numbers never returns both roots. It returns the positive square root. Andrei
Oct 04 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Graham St Jack wrote:
 I prefer your suggestion of ufloat/udouble/ureal to Positive, and I
 would definitely use these. I already use unsigned integer types a
 LOT, even more than signed ones.
 
 Have you thought how (and if) auto-casting would work?

I did, and it would work. The problem is there's no precedent for it. double x; ... auto y = sqrt(x); That will do a runtime check and throw if x is negative. That's unprecedented for an implicit cast, so I was thinking of defining a universal "unsigned" template function that does the check: auto y = sqrt(unsigned(x));
 As far as template instantiation goes, my feeling is that the "." is
 too easily confused with method invocation. I know you are trying to
 make them look more similar, but for we mere mortals that don't do
 much template programming, we need something that stand out more.
 Something less alarming than "!" would be ok, so long as there was
 ONLY ONE way.

I agree that in the end there should be only one man standing. And the reference to mere mortals makes me think we should bring the mountain to them instead of them to the mountain. I know, lame metaphor. Andrei
Oct 04 2008
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2008-10-05 01:55:43 -0400, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 That will do a runtime check and throw if x is negative. That's 
 unprecedented for an implicit cast, so I was thinking of defining a
 universal "unsigned" template function that does the check:
 
 auto y = sqrt(unsigned(x));

Well, at this point I would prefer if it was a contract. Having to explicitly convert to unsigned just makes it harder than necessary. Throwing may be unprecedented for implict casts, but it is standard for contracts using assertions. So I think it would be okay to implicit cast and assert the value is non-negative (which would be equivalent to enforcing a contract). But then, shouldn't sqrt(-1) give you NaN, or i? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michel Fortin wrote:
 On 2008-10-05 01:55:43 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:
 
 That will do a runtime check and throw if x is negative. That's 
 unprecedented for an implicit cast, so I was thinking of defining a
 universal "unsigned" template function that does the check:

 auto y = sqrt(unsigned(x));

Well, at this point I would prefer if it was a contract. Having to explicitly convert to unsigned just makes it harder than necessary.

But the point is that often you already traffic in nonnegatives, so you have them handy. Only passing the first time is difficult. But I hear you. We can make the conversion implicit.
 Throwing may be unprecedented for implict casts, but it is standard for 
 contracts using assertions. So I think it would be okay to implicit cast 
 and assert the value is non-negative (which would be equivalent to 
 enforcing a contract).
 
 But then, shouldn't sqrt(-1) give you NaN, or i?

It can't yield i because i has a different type. It gives NaN now, and believe me, that doesn't help any. Andrei
Oct 05 2008
prev sibling next sibling parent Graham St Jack <graham.stjack internode.on.net> writes:
I prefer your suggestion of ufloat/udouble/ureal to Positive,
and I would definitely use these. I already use unsigned integer
types a LOT, even more than signed ones.

Have you thought how (and if) auto-casting would work?

As far as template instantiation goes, my feeling is that
the "." is too easily confused with method invocation. I
know you are trying to make them look more similar, but
for we mere mortals that don't do much template programming,
we need something that stand out more. Something less alarming
than "!" would be ok, so long as there was ONLY ONE way.

Graham.
Oct 04 2008
prev sibling parent "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Sun, 05 Oct 2008 09:04:37 +0100, Michel Fortin  
<michel.fortin michelf.com> wrote:

 On 2008-10-05 01:55:43 -0400, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> said:

 That will do a runtime check and throw if x is negative. That's  
 unprecedented for an implicit cast, so I was thinking of defining a
 universal "unsigned" template function that does the check:
  auto y = sqrt(unsigned(x));

Well, at this point I would prefer if it was a contract. Having to explicitly convert to unsigned just makes it harder than necessary. Throwing may be unprecedented for implict casts, but it is standard for contracts using assertions. So I think it would be okay to implicit cast and assert the value is non-negative (which would be equivalent to enforcing a contract). But then, shouldn't sqrt(-1) give you NaN, or i?

Depends on the type of argument. For normal integers it should balk at compile time if possible and assert/throw if necessary For complex types i would make sense. For IEEE real numbers the specification probably mandates some behaviour such as NaN. Anyone read it recently?
Oct 05 2008
prev sibling next sibling parent reply Janderson <ask me.com> writes:
Andrei Alexandrescu wrote:
 Hello,
 
 
 (Background: Walter has kindly allowed ".()" as an alternative to the 
 ugly "!()" for template argument specifications.)
 
 Just a quick question - I am feeling an increasing desire to add a 
 template called Positive to std.typecons. Then Positive.(real) would 
 restrict its values to only positive real numbers etc.
 
 The implementation would accept conversion from its base type, e.g. 
 Positive.(real) can be constructed from a real. The constructor enforces 
 dynamically the condition. Also, Positive.(real) accepts implicit 
 conversion to real (no checking necessary).
 
 There are many places in which Positive can be useful, most notably 
 specifications of interfaces. For example:
 
 Positive.(real) sqrt(Positive.(real) x);
 
 These specifications are also efficient because checking for positivity 
 is done outside sqrt; if you had a Positive.(real) to start with, there 
 is no cascading checking necessary so there's one test less to do.
 
 However, there is also the risk that Positive has the same fate the many 
 SafeInt implementation have had in C++: many defined them, nobody used 
 them. What do you think? If you had Positive in std and felt like 
 crunching some numbers, would you use it?
 
 In order to get things really started, there's already been an exchange 
 with Walter on the matter. His reply was (I haven't asked for 
 permission, but I'm pretty sure he'd agree making it public):
 
 ==============
 Honestly, I wouldn't use it. I'd rather have an in contract for sqrt 
 that asserts the argument is positive. Also, this opens the door to 
 Negative, NegativeOrZero, ZeroOrInfinity, Odd, Even, Prime, 
 SixOrFifteen, etc.
 ==============
 
 My answer to that was:
 
 ==============
 About contracts: Let me explain how I think that's inferior to Positive 
 in two ways.
 
 1. Enough functions are defined on positive numbers only, to justify 
 factoring that contract out of the functions themselves.
 
 2. The efficiency perk is that when using several such functions 
 together, there's only one check; once in Positive-land, no more checks 
 are necessary.
 
 About proliferation of types: I don't think that follows at all. Math 
 found positive numbers special enough to dedicate them a special 
 notation (|R with subscript "+"). There's also a special notation for 
 nonzero real numbers (|R with superscript "*"). There is no special 
 notation for any of the sets you mentioned. That is bound to mean 
 something.
 ==============
 
 I'm interesting in further arguments. This feature is a numbers issue 
 (pun not intended), meaning it will be any good only if enough people 
 find it useful enough to actually use it in their own code and 
 libraries, therefore building momentum behind it.
 
 
 Andrei

As others have mentioned. Why a second class form of range restriction? Why not a first class implementation like ADA's with ranges and subranges as specific typedefs? I know it would be more work for the compiler writer to implement (if it can't be done in templates) however I prefer more generic solutions then having many once-off solutions that crudely fit together. Being able to simply pick a type that is within the range needed would save having to write contracts and static contracts all over the place. It also a great form of documentation. I would find that useful, particularly when working with algorithms that traverse arrays in specific sequences such as spacial data structures but need to maintain certain constraints. -Joel
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Janderson wrote:
 Andrei Alexandrescu wrote:
 Hello,


 (Background: Walter has kindly allowed ".()" as an alternative to the 
 ugly "!()" for template argument specifications.)

 Just a quick question - I am feeling an increasing desire to add a 
 template called Positive to std.typecons. Then Positive.(real) would 
 restrict its values to only positive real numbers etc.

 The implementation would accept conversion from its base type, e.g. 
 Positive.(real) can be constructed from a real. The constructor 
 enforces dynamically the condition. Also, Positive.(real) accepts 
 implicit conversion to real (no checking necessary).

 There are many places in which Positive can be useful, most notably 
 specifications of interfaces. For example:

 Positive.(real) sqrt(Positive.(real) x);

 These specifications are also efficient because checking for 
 positivity is done outside sqrt; if you had a Positive.(real) to start 
 with, there is no cascading checking necessary so there's one test 
 less to do.

 However, there is also the risk that Positive has the same fate the 
 many SafeInt implementation have had in C++: many defined them, nobody 
 used them. What do you think? If you had Positive in std and felt like 
 crunching some numbers, would you use it?

 In order to get things really started, there's already been an 
 exchange with Walter on the matter. His reply was (I haven't asked for 
 permission, but I'm pretty sure he'd agree making it public):

 ==============
 Honestly, I wouldn't use it. I'd rather have an in contract for sqrt 
 that asserts the argument is positive. Also, this opens the door to 
 Negative, NegativeOrZero, ZeroOrInfinity, Odd, Even, Prime, 
 SixOrFifteen, etc.
 ==============

 My answer to that was:

 ==============
 About contracts: Let me explain how I think that's inferior to 
 Positive in two ways.

 1. Enough functions are defined on positive numbers only, to justify 
 factoring that contract out of the functions themselves.

 2. The efficiency perk is that when using several such functions 
 together, there's only one check; once in Positive-land, no more 
 checks are necessary.

 About proliferation of types: I don't think that follows at all. Math 
 found positive numbers special enough to dedicate them a special 
 notation (|R with subscript "+"). There's also a special notation for 
 nonzero real numbers (|R with superscript "*"). There is no special 
 notation for any of the sets you mentioned. That is bound to mean 
 something.
 ==============

 I'm interesting in further arguments. This feature is a numbers issue 
 (pun not intended), meaning it will be any good only if enough people 
 find it useful enough to actually use it in their own code and 
 libraries, therefore building momentum behind it.


 Andrei

As others have mentioned. Why a second class form of range restriction? Why not a first class implementation like ADA's with ranges and subranges as specific typedefs? I know it would be more work for the compiler writer to implement (if it can't be done in templates) however I prefer more generic solutions then having many once-off solutions that crudely fit together. Being able to simply pick a type that is within the range needed would save having to write contracts and static contracts all over the place. It also a great form of documentation. I would find that useful, particularly when working with algorithms that traverse arrays in specific sequences such as spacial data structures but need to maintain certain constraints.

Making ufloat, udouble, ureal as instantiations of Bounded.(low, high) is a great idea! Andrei
Oct 05 2008
prev sibling next sibling parent reply BLS <nanali nospam-wanadoo.fr> writes:
I would prefer a more general, ADA like, solution.

// ADA
SUBTYPE Natural IS Integer RANGE 0 .. Integer'Last;
SUBTYPE NonNegFloat IS Float RANGE 0.0 .. Float'Last;
and also :
SUBTYPE CapitalLetter IS Character RANGE 'A' .. 'Z';


just my 2 euro cents;
Bjoern
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
BLS wrote:
 I would prefer a more general, ADA like, solution.
 
 // ADA
 SUBTYPE Natural IS Integer RANGE 0 .. Integer'Last;
 SUBTYPE NonNegFloat IS Float RANGE 0.0 .. Float'Last;
 and also :
 SUBTYPE CapitalLetter IS Character RANGE 'A' .. 'Z';
 
 
 just my 2 euro cents;
 Bjoern

I think that's cool, particularly thinking that it can be done entirely at library level. Andrei
Oct 05 2008
prev sibling next sibling parent reply "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Sun, 05 Oct 2008 03:35:57 +0100, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Hello,


 (Background: Walter has kindly allowed ".()" as an alternative to the  
 ugly "!()" for template argument specifications.)

the positive template to be the focus of attention. As soon as I saw it, I anticipated the usual 'enflamed discussion'. Didn't you? or was that part of the plan? Anyway, I am glad some people did eventually get back to your main question. [snip]
 In order to get things really started, there's already been an exchange  
 with Walter on the matter. His reply was (I haven't asked for  
 permission, but I'm pretty sure he'd agree making it public):

 ==============
 Honestly, I wouldn't use it. I'd rather have an in contract for sqrt  
 that asserts the argument is positive. Also, this opens the door to  
 Negative, NegativeOrZero, ZeroOrInfinity, Odd, Even, Prime,  
 SixOrFifteen, etc.
 ==============

 My answer to that was:

 ==============
 About contracts: Let me explain how I think that's inferior to Positive  
 in two ways.

 1. Enough functions are defined on positive numbers only, to justify  
 factoring that contract out of the functions themselves.

 2. The efficiency perk is that when using several such functions  
 together, there's only one check; once in Positive-land, no more checks  
 are necessary.

 About proliferation of types: I don't think that follows at all. Math  
 found positive numbers special enough to dedicate them a special  
 notation (|R with subscript "+"). There's also a special notation for  
 nonzero real numbers (|R with superscript "*"). There is no special  
 notation for any of the sets you mentioned. That is bound to mean  
 something.
 ==============

 I'm interesting in further arguments. This feature is a numbers issue  
 (pun not intended), meaning it will be any good only if enough people  
 find it useful enough to actually use it in their own code and  
 libraries, therefore building momentum behind it.


 Andrei

As at least one other pointed out. * means x >= 0 i.e. non negative + means x > 0 i.e. strictly positive I think it is useful to support sub-typing as you suggest. Moreover, I would like to see more subtypes. Including things like Negative NegativeOrZero, and Odd or Even but not six of fifteen. Prime will be too expensive to check but it might still be useful. Its probably better to leave that to people to create when they find it useful. Generalised range restricted sub-types would be a real boon. I don't see what the problem is with proliferating types. If you have a function that works on a restricted range then declaring that makes sense. Regarding the name I have no good suggestions. There is "Unsigned" which is a C-ism that is out of kilter with the mathematical intent. There is "Cardinal" which is under rated outside of Modula derived languages but includes only whole numbers. Actually I think "Cardinal" would be a useful addition in its own right. I think subtyping is orthogonal to declaring a contract. Contracts apply to functions whereas this is a type declaration. Also you can use it to be more concise in your contracts. To declare that two non-negative numbers are greater than each other you could just write: NonNegative!(x) > NonNegative!(y) If this is going to end up in a std library why is it a problem if few people use it? It is better that it is there and that people are aware of it than that people go down separate paths in solving the same problem at a later stage. Perhaps a more interesting question is how will you be using it? A second use I can see is selecting two different implementations at compile time. A (possibly faster) one for when the contract is supported and a slower or just different one when the type contract is not met. Going back to the sqrt example. Do you propose to change the library declaration to NonNegative!(numberType) sqrt( NonNegative!(numberType) X, NonNegative!(numberType) Y); Presumably changes like this are the real reason you want more feedback? My understanding of what you propose is: This is slightly less readable than using contracts but it is a more precise definition of the interface. Implicit type conversion would test the positivity in calls at compile time if possible but otherwise at runtime when necessary. The internal implementation of square root would not use the type constructor as it knows it answer will be positive. It could end with a cast to NonNegative to avoid the unnecessary test or more likely always be using NonNegative numbers inside. 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. 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. Regards, Bruce.
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Bruce Adams wrote:
 On Sun, 05 Oct 2008 03:35:57 +0100, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Hello,


 (Background: Walter has kindly allowed ".()" as an alternative to the 
 ugly "!()" for template argument specifications.)

about the positive template to be the focus of attention. As soon as I saw it, I anticipated the usual 'enflamed discussion'. Didn't you? or was that part of the plan? Anyway, I am glad some people did eventually get back to your main question.

I didn't expect that much hubbub.
 In order to get things really started, there's already been an 
 exchange with Walter on the matter. His reply was (I haven't asked for 
 permission, but I'm pretty sure he'd agree making it public):

 ==============
 Honestly, I wouldn't use it. I'd rather have an in contract for sqrt 
 that asserts the argument is positive. Also, this opens the door to 
 Negative, NegativeOrZero, ZeroOrInfinity, Odd, Even, Prime, 
 SixOrFifteen, etc.
 ==============

 My answer to that was:

 ==============
 About contracts: Let me explain how I think that's inferior to 
 Positive in two ways.

 1. Enough functions are defined on positive numbers only, to justify 
 factoring that contract out of the functions themselves.

 2. The efficiency perk is that when using several such functions 
 together, there's only one check; once in Positive-land, no more 
 checks are necessary.

 About proliferation of types: I don't think that follows at all. Math 
 found positive numbers special enough to dedicate them a special 
 notation (|R with subscript "+"). There's also a special notation for 
 nonzero real numbers (|R with superscript "*"). There is no special 
 notation for any of the sets you mentioned. That is bound to mean 
 something.
 ==============

 I'm interesting in further arguments. This feature is a numbers issue 
 (pun not intended), meaning it will be any good only if enough people 
 find it useful enough to actually use it in their own code and 
 libraries, therefore building momentum behind it.


 Andrei

As at least one other pointed out. * means x >= 0 i.e. non negative + means x > 0 i.e. strictly positive

Ok.
 I think it is useful to support sub-typing as you suggest. Moreover, I 
 would
 like to see more subtypes. Including things like Negative 
 NegativeOrZero, and Odd
 or Even but not six of fifteen. Prime will be too expensive to check but 
 it might
 still be useful. Its probably better to leave that to people to create 
 when they
 find it useful.
 
 Generalised range restricted sub-types would be a real boon.
 
 I don't see what the problem is with proliferating types. If you have a 
 function
 that works on a restricted range then declaring that makes sense.
 
 Regarding the name I have no good suggestions. There is "Unsigned" which 
 is a C-ism
 that is out of kilter with the mathematical intent. There is "Cardinal" 
 which is
 under rated outside of Modula derived languages but includes only whole 
 numbers.
 Actually I think "Cardinal" would be a useful addition in its own right.
 
 I think subtyping is orthogonal to declaring a contract. Contracts apply to
 functions whereas this is a type declaration.
 Also you can use it to be more concise in your contracts. To declare 
 that two non-negative
 numbers are greater than each other you could just write:
 
   NonNegative!(x) > NonNegative!(y)
 
 If this is going to end up in a std library why is it a problem if few 
 people use it?
 It is better that it is there and that people are aware of it than that 
 people go down
 separate paths in solving the same problem at a later stage. Perhaps a more
 interesting question is how will you be using it?
 
 A second use I can see is selecting two different implementations at 
 compile time.
 A (possibly faster) one for when the contract is supported and a slower 
 or just different
 one when the type contract is not met.

These are excellent insights, thanks!
 Going back to the sqrt example. Do you propose to change the library 
 declaration to
 
  NonNegative!(numberType) sqrt( NonNegative!(numberType) X, 
 NonNegative!(numberType) Y);
 
 Presumably changes like this are the real reason you want more feedback?

Yah. But what is the second argument for?
 My understanding of what you propose is:
 
 This is slightly less readable than using contracts but it is a more 
 precise definition
 of the interface.

Yes. The contract goes out of the bowels of the function and from the documentation, straight in the interface of the function.
 Implicit type conversion would test the positivity in calls at compile 
 time if possible
 but otherwise at runtime when necessary.

Yes.
 The internal implementation of square root would not use the type 
 constructor as it knows it answer
 will be positive.

Yes. (Wow I didn't think of that one!)
 It could end with a cast to NonNegative to avoid the 
 unnecessary test or
 more likely always be using NonNegative numbers inside.

Correct.
 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.
 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
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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.

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
Oct 05 2008
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Bruce Adams wrote:
 On Mon, 06 Oct 2008 00:55:33 +0100, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 Andrei

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.

even the simple cases is a start. I agree that D won't have this (any time soon) but mainly because there are several hundred things higher up the priority list.
 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

Is it? I think your example needs to be expanded or we may be talking at cross purposes. Firstly I would rearrange things a little, though in principle it makes no difference. pre { static assert(foreach (e; vec) assert(e >= 0)); } void normalize(double[] vec) { auto sum = reduce "a + b"(vec, 0); assert(sum > 0); foreach (ref e; vec) e /= sum; } double[] vec; static assert(foreach (e; vec) assert(e >= 0)); // line X // now we know vec is all nonnegatives normalize(vec); // line Y Imagine I have a prolog style symbolic unification engine to hand inside my compiler. At line X the static assertion is evaluated. The logical property e>=0 is asserted on the vec symbol. The compiler reaches line Y. Vec has not been modified so still has this property associated with it. We now unify the symbol representing vec with the contract on normalise. The unification succeeds and everything is fine. Now imagine we have a stupid analyser. double[] vec; static assert(foreach (e; vec) assert(e >= 0)); // line X vec[0] -= 1; // line Z // now we know vec is all nonnegatives normalize(vec); // line Y when the compile time analyser reaches line Z it can't work out whether or not the contract still applies, so it removes the assertion that vec is e>=0 for all elements, or rather asserts that it is not provably true. Now when we reach Y the unification fails. We don't throw a compile time contraint violation error. We haven't proved it to have failed. We throw a compile time constraint unprovable error or warning. Its like a lint warning. Your code may not be wrong but you might want to consider altering it in a way that makes it provably correct. We would really like to be able to assert that certain properties always hold for a variable through its life-time. That is a harder problem. I see something like this as a basis on which more advanced analysis can be built gradually. Actually re-using static assert above was probably misleading. It would be better to have something that says talk to the compile time theorem prover (a prolog interpreter would do). I have been meaning to write something along these lines for years but so far I haven't got around to it so I might as well stop keeping it under my hat. Regards, Bruce.

I think it's terrific to try your hand at it. I for one know am not equipped for such a pursuit. I have no idea how to perform unification over loops, particularly when they may have myriads of little differences while still having the same semantics; how to do that cross-procedurally in reasonable time; how to take control flow sensitivity into account; and why exactly people who've worked hard at it haven't gotten very far. But I am equipped to define a type that enforces all that simply and clearly, today. Andrei
Oct 05 2008
prev sibling parent Brad Roberts <braddr puremagic.com> writes:
Andrei Alexandrescu wrote:
 Bruce Adams wrote:
 On Mon, 06 Oct 2008 00:55:33 +0100, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Andrei

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.

even the simple cases is a start. I agree that D won't have this (any time soon) but mainly because there are several hundred things higher up the priority list.
 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

Is it? I think your example needs to be expanded or we may be talking at cross purposes. Firstly I would rearrange things a little, though in principle it makes no difference. pre { static assert(foreach (e; vec) assert(e >= 0)); } void normalize(double[] vec) { auto sum = reduce "a + b"(vec, 0); assert(sum > 0); foreach (ref e; vec) e /= sum; } double[] vec; static assert(foreach (e; vec) assert(e >= 0)); // line X // now we know vec is all nonnegatives normalize(vec); // line Y Imagine I have a prolog style symbolic unification engine to hand inside my compiler. At line X the static assertion is evaluated. The logical property e>=0 is asserted on the vec symbol. The compiler reaches line Y. Vec has not been modified so still has this property associated with it. We now unify the symbol representing vec with the contract on normalise. The unification succeeds and everything is fine. Now imagine we have a stupid analyser. double[] vec; static assert(foreach (e; vec) assert(e >= 0)); // line X vec[0] -= 1; // line Z // now we know vec is all nonnegatives normalize(vec); // line Y when the compile time analyser reaches line Z it can't work out whether or not the contract still applies, so it removes the assertion that vec is e>=0 for all elements, or rather asserts that it is not provably true. Now when we reach Y the unification fails. We don't throw a compile time contraint violation error. We haven't proved it to have failed. We throw a compile time constraint unprovable error or warning. Its like a lint warning. Your code may not be wrong but you might want to consider altering it in a way that makes it provably correct. We would really like to be able to assert that certain properties always hold for a variable through its life-time. That is a harder problem. I see something like this as a basis on which more advanced analysis can be built gradually. Actually re-using static assert above was probably misleading. It would be better to have something that says talk to the compile time theorem prover (a prolog interpreter would do). I have been meaning to write something along these lines for years but so far I haven't got around to it so I might as well stop keeping it under my hat. Regards, Bruce.

I think it's terrific to try your hand at it. I for one know am not equipped for such a pursuit. I have no idea how to perform unification over loops, particularly when they may have myriads of little differences while still having the same semantics; how to do that cross-procedurally in reasonable time; how to take control flow sensitivity into account; and why exactly people who've worked hard at it haven't gotten very far. But I am equipped to define a type that enforces all that simply and clearly, today. Andrei

I'm not an expert at optimizers, but I do read a whole lot. This type of analysis is often call 'value range propagation'. Tracking the possible values for data as it flows around and eliminating checks based on prior events. Most modern compilers do some amount of it. The question is how much and under what circumstances. I'm not sure how many combine that with static value analysis to create multiple function versions. IE, 'enough' callers to justify emitting two different forms of the function, each with different base assumptions about the incoming data and adjusting call sites. I know that some compilers do that for known constant values. I guess it's something halfway to inlining. I can guess at what dmd's backend does.. or rather doesn't do. :) Later, Brad
Oct 05 2008
prev sibling next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Andrei,

 Hello,
 
 (Background: Walter has kindly allowed ".()" as an alternative to the
 ugly "!()" for template argument specifications.)
 

Just adding more gas to the fire... Please, Oh Please NO!!! 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).
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
BCS wrote:
 Reply to Andrei,
 
 Hello,

 (Background: Walter has kindly allowed ".()" as an alternative to the
 ugly "!()" for template argument specifications.)

Just adding more gas to the fire... Please, Oh Please NO!!! 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
Oct 05 2008
parent reply BCS <ao pathlink.com> writes:
Reply to Andrei,

 BCS wrote:
 
 Reply to Andrei,
 
 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).

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.
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
BCS wrote:
 Reply to Andrei,
 
 BCS wrote:

 Reply to Andrei,

 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).

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
Oct 05 2008
parent BCS <ao pathlink.com> writes:
Reply to Andrei,

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

Easier is better. I'd rather spend my time and effort on other things.
Oct 06 2008
prev sibling next sibling parent "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Sun, 05 Oct 2008 15:12:13 +0100, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Bruce Adams wrote:
 On Sun, 05 Oct 2008 03:35:57 +0100, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 Hello,


 (Background: Walter has kindly allowed ".()" as an alternative to the  
 ugly "!()" for template argument specifications.)

about the positive template to be the focus of attention. As soon as I saw it, I anticipated the usual 'enflamed discussion'. Didn't you? or was that part of the plan? Anyway, I am glad some people did eventually get back to your main question.

I didn't expect that much hubbub.

 Going back to the sqrt example. Do you propose to change the library  
 declaration to
   NonNegative!(numberType) sqrt( NonNegative!(numberType) X,  
 NonNegative!(numberType) Y);
  Presumably changes like this are the real reason you want more  
 feedback?

Yah. But what is the second argument for?

thoroughly. :)
 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.

Positive!(int) x = 1;
 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. 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. Regards, Bruce.
Oct 05 2008
prev sibling next sibling parent "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Mon, 06 Oct 2008 00:55:33 +0100, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:
 Andrei

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.

the simple cases is a start. I agree that D won't have this (any time soon) but mainly because there are several hundred things higher up the priority list.
 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

Is it? I think your example needs to be expanded or we may be talking at cross purposes. Firstly I would rearrange things a little, though in principle it makes no difference. pre { static assert(foreach (e; vec) assert(e >= 0)); } void normalize(double[] vec) { auto sum = reduce "a + b"(vec, 0); assert(sum > 0); foreach (ref e; vec) e /= sum; } double[] vec; static assert(foreach (e; vec) assert(e >= 0)); // line X // now we know vec is all nonnegatives normalize(vec); // line Y Imagine I have a prolog style symbolic unification engine to hand inside my compiler. At line X the static assertion is evaluated. The logical property e>=0 is asserted on the vec symbol. The compiler reaches line Y. Vec has not been modified so still has this property associated with it. We now unify the symbol representing vec with the contract on normalise. The unification succeeds and everything is fine. Now imagine we have a stupid analyser. double[] vec; static assert(foreach (e; vec) assert(e >= 0)); // line X vec[0] -= 1; // line Z // now we know vec is all nonnegatives normalize(vec); // line Y when the compile time analyser reaches line Z it can't work out whether or not the contract still applies, so it removes the assertion that vec is e>=0 for all elements, or rather asserts that it is not provably true. Now when we reach Y the unification fails. We don't throw a compile time contraint violation error. We haven't proved it to have failed. We throw a compile time constraint unprovable error or warning. Its like a lint warning. Your code may not be wrong but you might want to consider altering it in a way that makes it provably correct. We would really like to be able to assert that certain properties always hold for a variable through its life-time. That is a harder problem. I see something like this as a basis on which more advanced analysis can be built gradually. Actually re-using static assert above was probably misleading. It would be better to have something that says talk to the compile time theorem prover (a prolog interpreter would do). I have been meaning to write something along these lines for years but so far I haven't got around to it so I might as well stop keeping it under my hat. Regards, Bruce.
Oct 05 2008
prev sibling next sibling parent "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Mon, 06 Oct 2008 06:17:44 +0100, Brad Roberts <braddr puremagic.com>  
wrote:

 Andrei Alexandrescu wrote:
 Bruce Adams wrote:
 On Mon, 06 Oct 2008 00:55:33 +0100, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Andrei

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.

even the simple cases is a start. I agree that D won't have this (any time soon) but mainly because there are several hundred things higher up the priority list.
 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

Is it? I think your example needs to be expanded or we may be talking at cross purposes. Firstly I would rearrange things a little, though in principle it makes no difference. pre { static assert(foreach (e; vec) assert(e >= 0)); } void normalize(double[] vec) { auto sum = reduce "a + b"(vec, 0); assert(sum > 0); foreach (ref e; vec) e /= sum; } double[] vec; static assert(foreach (e; vec) assert(e >= 0)); // line X // now we know vec is all nonnegatives normalize(vec); // line Y Imagine I have a prolog style symbolic unification engine to hand inside my compiler. At line X the static assertion is evaluated. The logical property e>=0 is asserted on the vec symbol. The compiler reaches line Y. Vec has not been modified so still has this property associated with it. We now unify the symbol representing vec with the contract on normalise. The unification succeeds and everything is fine. Now imagine we have a stupid analyser. double[] vec; static assert(foreach (e; vec) assert(e >= 0)); // line X vec[0] -= 1; // line Z // now we know vec is all nonnegatives normalize(vec); // line Y when the compile time analyser reaches line Z it can't work out whether or not the contract still applies, so it removes the assertion that vec is e>=0 for all elements, or rather asserts that it is not provably true. Now when we reach Y the unification fails. We don't throw a compile time contraint violation error. We haven't proved it to have failed. We throw a compile time constraint unprovable error or warning. Its like a lint warning. Your code may not be wrong but you might want to consider altering it in a way that makes it provably correct. We would really like to be able to assert that certain properties always hold for a variable through its life-time. That is a harder problem. I see something like this as a basis on which more advanced analysis can be built gradually. Actually re-using static assert above was probably misleading. It would be better to have something that says talk to the compile time theorem prover (a prolog interpreter would do). I have been meaning to write something along these lines for years but so far I haven't got around to it so I might as well stop keeping it under my hat. Regards, Bruce.

I think it's terrific to try your hand at it. I for one know am not equipped for such a pursuit. I have no idea how to perform unification over loops, particularly when they may have myriads of little differences while still having the same semantics; how to do that cross-procedurally in reasonable time; how to take control flow sensitivity into account; and why exactly people who've worked hard at it haven't gotten very far. But I am equipped to define a type that enforces all that simply and clearly, today. Andrei

I'm not an expert at optimizers, but I do read a whole lot. This type of analysis is often call 'value range propagation'. Tracking the possible values for data as it flows around and eliminating checks based on prior events. Most modern compilers do some amount of it. The question is how much and under what circumstances. I'm not sure how many combine that with static value analysis to create multiple function versions. IE, 'enough' callers to justify emitting two different forms of the function, each with different base assumptions about the incoming data and adjusting call sites. I know that some compilers do that for known constant values. I guess it's something halfway to inlining. I can guess at what dmd's backend does.. or rather doesn't do. :) Later, Brad

Perhaps more can be done with LLVM. I was actually suggesting something more radical than this. Having a turing complete interpreter available at compile time with access to the data structures used to represent the data flow analysis. This is what I mean by rope enough to hang yourself by. This isn't done currently for many reasons. 1. its a sledgehammer to crack a nut (though it is more general purpose) - as Andrei points out he can do myriad useful things today without this 2. compiler authors are rightly uneasy about exposing internal data-structures at compile time 3. compiler authors are rightly uneasy permitting activities that can potential result in longer compile times and especially infinitely long compile times (though templates make this possible) 4. many programmers are uneasy about marrying different programming styles. One of D's successes is actually in making template meta-programming more like regular procedural/functional OO programming and less like pattern matching / logical / declarative programming. That makes it more comprehendable to the masses which is a good thing. But it also hides the possibility of slipping a constraint solver in there. Though I don't think the CTFE system and templates are powerful enough to write an interpreter in. You don't have access to state information except through arguments that are constant expressions. It would be unnecessarily challenging to make this state mutable from different places in the program, if its even possible. This is where a multi-level language might win. I like the idea of possibly generating two different function implementations internally for the internal optimizer. However, I was suggesting the analysis is focused on contracts at interface boundaries. Regards, Bruce.
Oct 06 2008
prev sibling next sibling parent Don <nospam nospam.com.au> writes:
Andrei Alexandrescu wrote:
 Hello,
 
 
 (Background: Walter has kindly allowed ".()" as an alternative to the 
 ugly "!()" for template argument specifications.)
 
 Just a quick question - I am feeling an increasing desire to add a 
 template called Positive to std.typecons. Then Positive.(real) would 
 restrict its values to only positive real numbers etc.
 
 The implementation would accept conversion from its base type, e.g. 
 Positive.(real) can be constructed from a real. The constructor enforces 
 dynamically the condition. Also, Positive.(real) accepts implicit 
 conversion to real (no checking necessary).
 
 There are many places in which Positive can be useful, most notably 
 specifications of interfaces. For example:
 
 Positive.(real) sqrt(Positive.(real) x);

From the IEEE definition of sqrt(x), x can be >=0, which includes -0. For negative zero, the return result is -0. However, not all positive-valued functions will accept -0 as an argument. They also vary in whether or not they will accept an infinity or a NaN. So there's an annoying bit of complication.
 These specifications are also efficient because checking for positivity 
 is done outside sqrt; if you had a Positive.(real) to start with, there 
 is no cascading checking necessary so there's one test less to do.
 
 However, there is also the risk that Positive has the same fate the many 
 SafeInt implementation have had in C++: many defined them, nobody used 
 them. What do you think? If you had Positive in std and felt like 
 crunching some numbers, would you use it?

I think it probably is similar to SafeInt in C++. It just doesn't add enough value. Essentially, it allows you to drop some trivial contracts. But I don't think it scales particularly well. As math functions gain more arguments, the relationships in the 'in' contracts tend to get more complicated. Much more useful would be positive int. Meaning, the top bit of the int is always 0, which is a completely different concept to uint. Then we could have implicit conversion from posint -> int and posint -> uint, and disallow conversions between int <-> uint. But really I'd like to see polysemous types first...
Oct 06 2008
prev sibling parent e-t172 <e-t172 akegroup.org> writes:
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Andrei Alexandrescu a =C3=A9crit :
 "enum" as the way to declare manifest constants were much more ugly th=


 "!(", and most of the people were against it. I don't see why ".(" sho=


 be introduced.

Ugly or not, enumerated symbols were manifest constants to begin with. =

Sure. However manifest constants weren't enumerated symbols to begin with= =2E --=20 Etienne Dechamps / e-t172 - AKE Group Website: http://www.e-t172.net/ Contact: e-t172 akegroup.org Phone: +33547414942
Oct 06 2008