www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Polysemous Values Qustion

reply Robert Frser <fraserofthenight gmail.com> writes:
Can someone giv me an example where polysemous values could apply to a class
(given the class has (multiple) opImplicitCastTo/From)
Sep 24 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Robert Frser wrote:
 Can someone giv me an example where polysemous values could apply to a class
(given the class has (multiple) opImplicitCastTo/From)

Maybe a class with opImplicitCastTo - char[] opImplicitCastTo - wchar[] opImplicitCastTo - dchar[] ? --bb
Sep 24 2007
prev sibling next sibling parent davidl <davidl 126.com> writes:
在 Tue, 25 Sep 2007 08:40:40 +0800,Robert Frser  
<fraserofthenight gmail.com> 写道:

 Can someone giv me an example where polysemous values could apply to a  
 class (given the class has (multiple) opImplicitCastTo/From)

I don't understand what you mean by that. Since the lvalue type , and rvalue type is known. If I understand you correctly, there won't be such a problem for assignment expression. Only happens if there're void funcoverload(Can_Cast_From_ObjectB_1 A) void funcoverload(Can_Cast_From_ObjectB_2 C) funcoverload(ObjectB); <-- this calling is ambiguous. Cause it can cast to either A or C. and similar situation is ObjectB gets the opImplicitTo ObjectC ObjectA gets the opImplicitFrom ObjectB so a calling of void funcoverload(ObjectC c) void funcoverload(ObjectA a) funcoverload(ObjectB); <-- this would run into the same problem as the previous example -- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
Sep 24 2007
prev sibling next sibling parent reply "Janice Caron" <caron800 googlemail.com> writes:
In another thread, Christopher Wright said that polysemous meant "A
variable that can have several types depending on how it is assigned
or casted is polysemous. Walter wants to use this especially for
string literals -- should it be fixed length or not, should it be
char, wchar,
dchar?"

And then Don Clugston said "For example, the literal number 1. Could
be a short, int, uint, float, complex number,..."

Both of those examples are LITERALS. I get that. Literal can be
interpreted as either one type or another. It makes sense that you'd
want to delay nailing down the decision until you really have to.

But CW said: "A /variable/..." (my emphasis). Can you have a
polysemous variable (as opposed to literal)? I don't get how that
would work.
Sep 25 2007
next sibling parent reply Reiner Pope <some address.com> writes:
Janice Caron wrote:
 In another thread, Christopher Wright said that polysemous meant "A
 variable that can have several types depending on how it is assigned
 or casted is polysemous. Walter wants to use this especially for
 string literals -- should it be fixed length or not, should it be
 char, wchar,
 dchar?"
 
 And then Don Clugston said "For example, the literal number 1. Could
 be a short, int, uint, float, complex number,..."
 
 Both of those examples are LITERALS. I get that. Literal can be
 interpreted as either one type or another. It makes sense that you'd
 want to delay nailing down the decision until you really have to.
 
 But CW said: "A /variable/..." (my emphasis). Can you have a
 polysemous variable (as opposed to literal)? I don't get how that
 would work.

Not sure of this, but perhaps it is to allow overloading by return value? int foo() { ... } long foo() { ... } auto x = foo(); // x is polysemous, perhaps? -- Reiner
Sep 25 2007
parent Matti Niemenmaa <see_signature for.real.address> writes:
Disclaimer: I don't know anything. My thoughts in any case:

Janice Caron wrote:
 auto x = 7;
 
 means that x is polysemous? (any type capable of being initialised
 with 7)? And if we then say
 
 ulong y = x;
 
 would that retrospectively establish that typeof(x) is ulong?

I don't think so, because couldn't you still do: short z = x; If you couldn't, this would be a huge problem. Imagine the following: auto x = 5; // ... short y = x; Then somebody adds "ulong z = x;" to somewhere within the "...", between the initializations of x and y. Suddenly, the line "short y = x" doesn't compile because of something which should be unrelated. I think typeof(x) remains { byte, ubyte, short, /+ ... +/ } no matter what you do with it. I'm not sure how thinking about the typeof(x) would play with opImplicitCast (assuming such a thing will come). typeof(x) could change depending on what classes are visible from where x is declared. Maybe there's just an "any class with an opImplicitCast to any of my other types" type.
 ...I'm still very confused. However, it would also make sense if
 polysemous was a compile-time type, whose interpretation (at compile
 time) is "the type of this value is one of { T, U, V, ... }, and then
 you narrow down the list as you evaluate the expression in which it
 occurs. For example
 
 auto z = 0x10000 * 0x10000;
 
 Here the compiler must multiply one polysemous type by another. Both
 values are known at compile time, and both could be { int, uint, long,
 ulong } but the result (0x100000000) is too big to fit into an int or
 uint, and so must be constrained to one of { long, ulong }.

That's how I see it. typeof(z) == [ long, ulong, class with opImplicitCast to long or ulong ]. And cent and ucent of course, they might be around by the time this is implemented. ;-) -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Sep 25 2007
prev sibling next sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Janice Caron wrote:
 In another thread, Christopher Wright said that polysemous meant "A
 variable that can have several types depending on how it is assigned
 or casted is polysemous. Walter wants to use this especially for
 string literals -- should it be fixed length or not, should it be
 char, wchar,
 dchar?"
 
 And then Don Clugston said "For example, the literal number 1. Could
 be a short, int, uint, float, complex number,..."
 
 Both of those examples are LITERALS. I get that. Literal can be
 interpreted as either one type or another. It makes sense that you'd
 want to delay nailing down the decision until you really have to.
 
 But CW said: "A /variable/..." (my emphasis). Can you have a
 polysemous variable (as opposed to literal)? I don't get how that
 would work.

I believe polysemy will have to be resolved at compile time. Walter would know better. So, if your variable is subjected to constant expansion, *maybe* Walter will allow it to be polysemous via the auto keyword. But that would likely be a fair bit harder than forcing typing at first use -- the assignment. If Walter's reading this, he's probably thinking that it's a bad idea to allow any type to be unresolved for very long, given the problems people have mentioned. And if not, well, that might be reason enough for me to stick with D2 rather than going with D3. (I hate, hate, HATE languages where it's nontrivial to tell the effective type of something.) Chris Wright.
Sep 25 2007
parent Jari-Matti =?ISO-8859-1?Q?M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
Christopher Wright wrote:

 If Walter's reading this, he's probably thinking that it's a bad idea to
 allow any type to be unresolved for very long, given the problems people
 have mentioned. And if not, well, that might be reason enough for me to
 stick with D2 rather than going with D3. (I hate, hate, HATE languages
 where it's nontrivial to tell the effective type of something.)

Well AFAICS the polysemous type is an extension to the current type system. So if you want to explicitly declare all types, you're still free to do so. It's like the new constness, but in this case types are still backwards compatible. Btw, a modern IDE can easily determine the inferred type by doing on the fly semantic analysis and visualize the set of possible types. In case you haven't noticed, even D 1.x allows you to write long functions without binding any concrete types, for example: T fun(T, U, ...)(T t, U u, ...) { // some code auto foo = t.children; auto bar = foo.first; foreach(c; foo) { if (bar < c) bar = c; } // more code }
Sep 26 2007
prev sibling parent Don Clugston <dac nospam.com.au> writes:
Janice Caron wrote:
 In another thread, Christopher Wright said that polysemous meant "A
 variable that can have several types depending on how it is assigned
 or casted is polysemous. Walter wants to use this especially for
 string literals -- should it be fixed length or not, should it be
 char, wchar,
 dchar?"
 
 And then Don Clugston said "For example, the literal number 1. Could
 be a short, int, uint, float, complex number,..."
 
 Both of those examples are LITERALS. I get that. Literal can be
 interpreted as either one type or another. It makes sense that you'd
 want to delay nailing down the decision until you really have to.
 
 But CW said: "A /variable/..." (my emphasis). Can you have a
 polysemous variable (as opposed to literal)? I don't get how that
 would work.

AFAIK, it only applies to rvalues (which is a bit broader than simply literals).
Sep 25 2007
prev sibling next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 9/25/07, Reiner Pope <some address.com> wrote:
 Not sure of this, but perhaps it is to allow overloading by return value?

 int foo() { ... }
 long foo() { ... }

 auto x = foo();
 // x is polysemous, perhaps?

Or maybe auto x = 7; means that x is polysemous? (any type capable of being initialised with 7)? And if we then say ulong y = x; would that retrospectively establish that typeof(x) is ulong? ...I'm still very confused. However, it would also make sense if polysemous was a compile-time type, whose interpretation (at compile time) is "the type of this value is one of { T, U, V, ... }, and then you narrow down the list as you evaluate the expression in which it occurs. For example auto z = 0x10000 * 0x10000; Here the compiler must multiply one polysemous type by another. Both values are known at compile time, and both could be { int, uint, long, ulong } but the result (0x100000000) is too big to fit into an int or uint, and so must be constrained to one of { long, ulong }. In C++, on a 32-bit platform, the expression "0x10000 * 0x10000" will yield zero. You have to explicitly make at least one them 64-bits wide, e.g. "0x10000 * 0x10000LL", to stop the expression overflowing. This would obviously be a huge boon to D. Maybe that's what Walter means? I still don't get the notion of runtime polysemousness.
Sep 25 2007
prev sibling parent reply Nathan Reed <nathaniel.reed gmail.com> writes:
Robert Frser wrote:
 Can someone giv me an example where polysemous values could apply to a class
(given the class has (multiple) opImplicitCastTo/From)

Here's another example where polysemous values could come in handy: interface A { ... } interface B { ... } class Foo : A, B { ... } class Bar : A, B { ... } void main (string[] args) { bool flag = ... auto whatsMyType = flag ? new Foo : new Bar; } Here, Foo and Bar both implement A and B, so the variable 'whatsMyType' could have either type A or type B. If you do this in D now, it will fail with a compile error, since Foo and Bar have no least upper bound...but with polysemous values, whatsMyType could have type "A or B". Thanks, Nathan Reed
Sep 25 2007
parent reply downs <default_357-line yahoo.de> writes:
Nathan Reed wrote:
 Robert Frser wrote:
 Can someone giv me an example where polysemous values could apply to a
 class (given the class has (multiple) opImplicitCastTo/From)

Here's another example where polysemous values could come in handy: interface A { ... } interface B { ... } class Foo : A, B { ... } class Bar : A, B { ... } void main (string[] args) { bool flag = ... auto whatsMyType = flag ? new Foo : new Bar; } Here, Foo and Bar both implement A and B, so the variable 'whatsMyType' could have either type A or type B. If you do this in D now, it will fail with a compile error, since Foo and Bar have no least upper bound...but with polysemous values, whatsMyType could have type "A or B". Thanks, Nathan Reed

I don't think it can. Polysemous values are values that can be interpreted as more than one type simultaneously. whatsMyType can be interpreted as either Foo or Bar, but not both at the same time - whichever one is correct at runtime, the other one isn't. The proper thing to do here is to cast them to Object and figure it out via dynamic casts. :) --downs
Sep 25 2007
parent reply Jari-Matti =?ISO-8859-1?Q?M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
downs wrote:

 Nathan Reed wrote:
 Robert Frser wrote:
 Can someone giv me an example where polysemous values could apply to a
 class (given the class has (multiple) opImplicitCastTo/From)

Here's another example where polysemous values could come in handy: interface A { ... } interface B { ... } class Foo : A, B { ... } class Bar : A, B { ... } void main (string[] args) { bool flag = ... auto whatsMyType = flag ? new Foo : new Bar; } Here, Foo and Bar both implement A and B, so the variable 'whatsMyType' could have either type A or type B. If you do this in D now, it will fail with a compile error, since Foo and Bar have no least upper bound...but with polysemous values, whatsMyType could have type "A or B". Thanks, Nathan Reed

I don't think it can. Polysemous values are values that can be interpreted as more than one type simultaneously. whatsMyType can be interpreted as either Foo or Bar, but not both at the same time - whichever one is correct at runtime, the other one isn't.

Types of "new Foo" and "new Bar" can be [Foo, Object, A, B]. (ok, maybe also void*) If in the type world ?: is a function (x,y) -> (z) where z belongs to both x and y, "flag ? new Foo : new Bar" can very well be [Object, A, B], and by the same logic so can also "whatsMyType", because typewise = is probably a function (x) -> (x).
Sep 26 2007
parent Jari-Matti =?ISO-8859-1?Q?M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
Jari-Matti Mkel wrote:

 Types of "new Foo" and "new Bar" can be [Foo, Object, A, B]. (ok, maybe
 also void*)

Heh, I optimized away something. Type of "new Bar" is more likely a subset of these [Bar, Object, A, B]. :)
Sep 26 2007