June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Saturday, 29 June 2013 at 01:31:13 UTC, Walter Bright wrote:
> On 6/28/2013 5:00 PM, JS wrote:
>> Is variant useful? If not then you have a point. I'm not proposing anything that
>> variant can't already do except add compile time performance. I do not think the
>> complexity is much more than what is already done.
>>
>> D already checks for time mismatch. With such a variant or auto the check simply
>> is more intelligent.
>>
>> e.g.,
>>
>> auto x; // x's type is undefined or possibly variant.
>> x = 3; // x's type is set temporarily to an int
>> ...
>> x = 3.0; // ****
>>
>>
>> at **** we have several possibilities.
>>
>> 1. Throw an error, this makes auto more useful and avoids many pitfalls.
>> 2. Set x's type to a variant. [possibly goto 3 if castable to new type]
>> 3. Set x's type to a double.
>>
>> Both 2 and 3 require an extra pass to convert the code because it uses forward
>> inference.
>>
>> auto looks only at the immediate assignment expression to determine the type. I
>> am talking about generalizing it to look in the scope with possible fallback to
>> a variant type with optional warning, an error, or type enlargement.
>
>
> Again, I need a compelling use case. It's not enough to say it's the same as variant, and it's not enough to say it can be implemented.
>
> A compelling use case would be a pattern that is commonplace, and for which the workarounds are ugly, unsafe, error prone, unportable, etc.
What was the use case for auto that got in into the language?
|
June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On Saturday, 29 June 2013 at 01:49:01 UTC, JS wrote:
> On Saturday, 29 June 2013 at 01:31:13 UTC, Walter Bright wrote:
>> On 6/28/2013 5:00 PM, JS wrote:
>>> Is variant useful? If not then you have a point. I'm not proposing anything that
>>> variant can't already do except add compile time performance. I do not think the
>>> complexity is much more than what is already done.
>>>
>>> D already checks for time mismatch. With such a variant or auto the check simply
>>> is more intelligent.
>>>
>>> e.g.,
>>>
>>> auto x; // x's type is undefined or possibly variant.
>>> x = 3; // x's type is set temporarily to an int
>>> ...
>>> x = 3.0; // ****
>>>
>>>
>>> at **** we have several possibilities.
>>>
>>> 1. Throw an error, this makes auto more useful and avoids many pitfalls.
>>> 2. Set x's type to a variant. [possibly goto 3 if castable to new type]
>>> 3. Set x's type to a double.
>>>
>>> Both 2 and 3 require an extra pass to convert the code because it uses forward
>>> inference.
>>>
>>> auto looks only at the immediate assignment expression to determine the type. I
>>> am talking about generalizing it to look in the scope with possible fallback to
>>> a variant type with optional warning, an error, or type enlargement.
>>
>>
>> Again, I need a compelling use case. It's not enough to say it's the same as variant, and it's not enough to say it can be implemented.
>>
>> A compelling use case would be a pattern that is commonplace, and for which the workarounds are ugly, unsafe, error prone, unportable, etc.
>
> What was the use case for auto that got in into the language?
A quick look at any heavily templated c++ (pre c++11) is all you need to justify it.
auto cuts code clutter by huge amounts all over the place.
|
June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On 6/28/2013 6:48 PM, JS wrote:
> What was the use case for auto that got in into the language?
In code where the type of the initializer would change, and if the type of the variable was fixed, then there would be an unintended implicit conversion. The other use case was voldemort types. Such patterns are commonplace, and a source of error and inconvenience without auto. auto appears in various forms in other languages, and is almost universally lauded as worthwhile.
These cases don't apply to this proposal, nor do I know of its successful adoption in another language.
It's not a matter of finding reasons not to implement it. It's finding reasons TO implement it. Language features do not have zero cost - some benefit has to offset it.
|
June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Saturday, 29 June 2013 at 02:05:35 UTC, Walter Bright wrote:
> On 6/28/2013 6:48 PM, JS wrote:
>> What was the use case for auto that got in into the language?
>
> In code where the type of the initializer would change, and if the type of the variable was fixed, then there would be an unintended implicit conversion. The other use case was voldemort types. Such patterns are commonplace, and a source of error and inconvenience without auto. auto appears in various forms in other languages, and is almost universally lauded as worthwhile.
>
> These cases don't apply to this proposal, nor do I know of its successful adoption in another language.
>
> It's not a matter of finding reasons not to implement it. It's finding reasons TO implement it. Language features do not have zero cost - some benefit has to offset it.
I don't disagree with you and I'm not saying auto is not useful. IMO though, auto is almost all convenience and very little to do with solving errors.
A very simple use case is:
auto x = 0;
...
x = complex(1, 1) + x;
which obviously is an error.
By having auto use forward inferencing we can avoid such errors. It's obvious that x was intended to be a complex variable. Having auto look forward(or using a different keyword) reduces code refactoring and improves on the power of auto.
for example suppose we use instead
auto x = pow(2, 10);
where pow returns a real. In this case x is still the wrong type. So we always have to know the "final" supertype anyways... I'm just proposing we let the compiler figure it out for us if we want.
But because some types are supertypes of others it is entirely logical that they be extended when it is obvious the are being used as such.
To see why this is even more useful, suppose we had such code above but now want to refactor to use quaternions. In this case, the line x = complex(1,1) + x is becomes invalid too and requires fixing(or the auto x line has to be fixed). If we allowed auto x; to easily see that it is suppose to be a quaternion then that line does not have to be fixed and everything would work as expected.
So the real question is, is it error prone to allow the compiler to deduce what supertype a variable really is? I do not think it is a problem because ambiguity results in an error and warnings could be given when a variable type was upgraded to a super type.
At some point, if flow analysis is ever added, auto would be a natural bridge to it.
another useless case is
auto someflag;
static if (__cpu == 3)
someflag = "amdx64"
else
someflag = false;
which allows a sort of static variant type. (which could be gotten around if a static if conditional expression, e.g.,
static auto someflag = (__cpu == 3) ?? "amdx64" : false; )
The above may make it easier in some cases for configuration code.
The biggest benefit I can immediately see comes from using mixins. In this case we can always have a variable select the appropriate type.
e.g.,
mixin template Foo() { ((...) ?? int : float) func() { } } // func is of type int or float depending on the condition ...
class Bar {
auto x; // possibly auto x = default(typeof(func)); but possibly error prone due to refactoring if line order matters
mixin Foo;
static Bar() { x = default(typeof(func)); }
}
note that x's type is deduced at compile time to be the appropriate type corresponding to the mixin used. Because x's type does not have to be immediately known we can specify it implicitly later on without ever having to know the return types of the mixins.
In this case Bar acts like a templated class but isn't(or is a sort of statically templated class so to speak)
Such classes would be useful for versioning where the user of the class is oblivious to the types used in the class and does not need to specify a type parameter.
e.g., The Bar class above could use int for a more performant version of the program and float for a more precise version. The use of auto would completely or near completely eliminate having to deal with which one is being used.
In any case I can't specify any super duper use case because I don't know any.
|
June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On Fri, 28 Jun 2013 18:00:54 -0400, JS <js.mdnq@gmail.com> wrote:
> On Friday, 28 June 2013 at 14:02:07 UTC, Steven Schveighoffer wrote:
>> On Fri, 28 Jun 2013 02:51:39 -0400, JS <js.mdnq@gmail.com> My argument is that auto should be left the way it is. I don't want it to change. And variant already does what you want with less confusing semantics, no reason to add another feature.
>>
>> -Steve
>
> Using the auto keyword was just an example. My argument does not depend the specific keyword used. My "idea" is simply generalizing auto to use forward inferencing.
>
> variant is NOT what I am talking about. It is not a performant time but a union of types. I am talking about the compiler finding the best choice for the type by looking ahead of the definition of the time.
There is a possible way to solve this -- auto return types. If you can fit your initialization of the variable into a function (even an inner function) that returns auto, then the compiler should be able to figure out the best type.
Example:
import std.stdio;
void main(string[] args)
{
auto foo() {
if(args.length > 1 && args[1] == "1")
return 1;
else
return 2.5;
}
auto x = foo();
writeln(typeof(x).stringof);
}
this outputs "double".
Granted, it doesn't solve the "general" case, where you want to use x before it's initialized a second time, but I think that really is just a programming error -- use a different variable.
-Steve
|
June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On 6/27/13 9:34 PM, JS wrote: > Would it be possible for a language(specifically d) to have the ability > to automatically type a variable by looking at its use cases without > adding too much complexity? It seems to me that most compilers already > can infer type mismatchs which would allow them to handle stuff like: > > main() > { > auto x; > auto y; > x = 3; // x is an int, same as auto x = 3; > y = f(); // y is the same type as what f() returns > x = 3.9; // x is really a float, no mismatch with previous type(int) > } > > in this case x and y's type is inferred from future use. The compiler > essentially just lazily infers the variable type. Obviously ambiguity > will generate an error. What you are asking is essentially what Crystal does for all variables (and types): https://github.com/manastech/crystal/wiki/Introduction#type-inference Your example would be written like this: x = 3 y = f() x = 3.9 But since Crystal transforms your code to SSA (http://en.wikipedia.org/wiki/Static_single_assignment_form) you actually have *two* "x" variables in your code. The first one is of type Int32, the second of type Float64. The above solves the problem mentioned by Steven Schveighoffer, where you didn't know what overloaded version you was calling: x = 3 f(x) # always calls f(Int32), because at run-time # x will always be an Int32 at this point x = 3.9 But to have this in a language you need some things: 1. Don't have a different syntax for declaring and updating variables 2. Transform your code to SSA (maybe more?) So this is not possible in D right now, and I don't think it will ever be because it requires a huge change to the whole language. |
June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | On 6/29/2013 12:18 PM, Ary Borenszweig wrote:
> What you are asking is essentially what Crystal does for all variables (and types):
>
> https://github.com/manastech/crystal/wiki/Introduction#type-inference
>
> Your example would be written like this:
>
> x = 3
> y = f()
> x = 3.9
>
> But since Crystal transforms your code to SSA
> (http://en.wikipedia.org/wiki/Static_single_assignment_form) you actually have
> *two* "x" variables in your code. The first one is of type Int32, the second of
> type Float64.
Sorry, but that seems like a solution in search of a problem.
And besides, yuk. Imagine the bugs caused by "hey, it doesn't implicitly convert, so instead of letting the user know he goofed, let's just silently create a new variable!"
|
June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 6/29/13 6:01 PM, Walter Bright wrote:
> On 6/29/2013 12:18 PM, Ary Borenszweig wrote:
>> What you are asking is essentially what Crystal does for all variables
>> (and types):
>>
>> https://github.com/manastech/crystal/wiki/Introduction#type-inference
>>
>> Your example would be written like this:
>>
>> x = 3
>> y = f()
>> x = 3.9
>>
>> But since Crystal transforms your code to SSA
>> (http://en.wikipedia.org/wiki/Static_single_assignment_form) you
>> actually have
>> *two* "x" variables in your code. The first one is of type Int32, the
>> second of
>> type Float64.
>
> Sorry, but that seems like a solution in search of a problem.
>
> And besides, yuk. Imagine the bugs caused by "hey, it doesn't implicitly
> convert, so instead of letting the user know he goofed, let's just
> silently create a new variable!"
Sorry, but I can't imagine those bugs. Can you show me an example?
|
June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Borenszweig | On 6/29/2013 2:53 PM, Ary Borenszweig wrote:
> On 6/29/13 6:01 PM, Walter Bright wrote:
>> On 6/29/2013 12:18 PM, Ary Borenszweig wrote:
>>> What you are asking is essentially what Crystal does for all variables
>>> (and types):
>>>
>>> https://github.com/manastech/crystal/wiki/Introduction#type-inference
>>>
>>> Your example would be written like this:
>>>
>>> x = 3
>>> y = f()
>>> x = 3.9
>>>
>>> But since Crystal transforms your code to SSA
>>> (http://en.wikipedia.org/wiki/Static_single_assignment_form) you
>>> actually have
>>> *two* "x" variables in your code. The first one is of type Int32, the
>>> second of
>>> type Float64.
>>
>> Sorry, but that seems like a solution in search of a problem.
>>
>> And besides, yuk. Imagine the bugs caused by "hey, it doesn't implicitly
>> convert, so instead of letting the user know he goofed, let's just
>> silently create a new variable!"
>
> Sorry, but I can't imagine those bugs. Can you show me an example?
Sure:
x = 3
px = &x
y = f()
x = 3.9
// uh-oh, *px points to a different x, and wasn't updated!
printf("%d\n", x); // uh-oh, I thought x was an int!
|
June 29, 2013 Re: Automatic typing | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Sat, 29 Jun 2013 17:01:54 -0400, Walter Bright <newshound2@digitalmars.com> wrote:
> On 6/29/2013 12:18 PM, Ary Borenszweig wrote:
>> What you are asking is essentially what Crystal does for all variables (and types):
>>
>> https://github.com/manastech/crystal/wiki/Introduction#type-inference
>>
>> Your example would be written like this:
>>
>> x = 3
>> y = f()
>> x = 3.9
>>
>> But since Crystal transforms your code to SSA
>> (http://en.wikipedia.org/wiki/Static_single_assignment_form) you actually have
>> *two* "x" variables in your code. The first one is of type Int32, the second of
>> type Float64.
>
> Sorry, but that seems like a solution in search of a problem.
>
> And besides, yuk. Imagine the bugs caused by "hey, it doesn't implicitly convert, so instead of letting the user know he goofed, let's just silently create a new variable!"
x is a variant that is compile-time optimized to be an int or a float. Where would the bug be? If x could possibly change types depending on runtime data, then x is given a type of a union between int or float.
It would be somewhat like the compiler optimizing this:
{
Variant v = 1;
v = 3.5;
}
to:
{
int v = 1;
}
{
float v = 3.5;
}
because it sees that during the optimized scopes, v is only used as that specific type.
It seems like the compiler is generating variants that can hold exactly the types that are used for that variable. Interesting concept.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation