View mode: basic / threaded / horizontal-split · Log in · Help
October 05, 2008
Re: Positive
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.
October 05, 2008
Re: Positive
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.
October 05, 2008
Re: Positive
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
October 05, 2008
shouting versus dotting
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
October 05, 2008
Re: Positive
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
October 05, 2008
Re: shouting versus dotting
== 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.
October 05, 2008
Re: shouting versus dotting
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?
October 05, 2008
Re: Positive
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.
October 05, 2008
Re: Positive
== 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.
> 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

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.
October 05, 2008
Re: Positive
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
1 2 3 4 5 6
Top | Discussion index | About this forum | D home