Hi all,
It is logical to expect that if zero_type(X) == zero_type(Y) then X == Y However: 0 == UNDEFINED but zero_type(0) != zero_type(UNDEFINED) this means that checks like some_value == UNDEFINED will never work correctly if some_value is an integer zero. Using zero_type() is not always convenient, at least not for readability... I suspect that this wasn't intended to operate this way, or? Regards, /Al
0 != UNDEFINED. UNDEFINED is 0 with the zero flag set. That is the whole point of it.
/ Peter Bortas
Previous text:
2003-01-22 02:35: Subject: zero_type() & UNDEFINED (bug?)
Hi all,
It is logical to expect that if
zero_type(X) == zero_type(Y)
then X == Y However:
0 == UNDEFINED
but
zero_type(0) != zero_type(UNDEFINED)
this means that checks like some_value == UNDEFINED will never work correctly if some_value is an integer zero.
Using zero_type() is not always convenient, at least not for readability...
I suspect that this wasn't intended to operate this way, or?
Regards, /Al
/ Brevbäraren
It is logical to expect that if zero_type(X) == zero_type(Y) then X == Y.
I am curious as to where you got that idea. That implication never holds; a trivial counter example is zero_type(4) == zero_type(5), whereas 4 != 5. zero_type() tests a a property that `== does not see.
/ Johan Sundström (a hugging punishment!)
Previous text:
2003-01-22 02:35: Subject: zero_type() & UNDEFINED (bug?)
Hi all,
It is logical to expect that if
zero_type(X) == zero_type(Y)
then X == Y However:
0 == UNDEFINED
but
zero_type(0) != zero_type(UNDEFINED)
this means that checks like some_value == UNDEFINED will never work correctly if some_value is an integer zero.
Using zero_type() is not always convenient, at least not for readability...
I suspect that this wasn't intended to operate this way, or?
Regards, /Al
/ Brevbäraren
On Wed, Jan 22, 2003 at 03:00:00AM +0100, Johan Sundström (a hugging punishment!) @ Pike (-) developers forum wrote:
It is logical to expect that if zero_type(X) == zero_type(Y) then X == Y.
I am curious as to where you got that idea. That implication never holds;
i think he just accidentially reversed the examples and meant to say: if X == Y then zero_type(X) == zero_type(Y),
greetings, martin.
i think he just accidentially reversed the examples and meant to say: if X == Y then zero_type(X) == zero_type(Y),
Never the less, this is also not guaranteed since as mentioned before, zero_type checks for an attribute of 'zero' that `== doesn't look at. I.e:
0 == UNDEFINED;
(1) Result: 1
zero_type(0);
(2) Result: 0
zero_type(UNDEFINED);
(3) Result: 1
UNDEFINED is zero but 0 isn't UNDEFINED, unless of course... it is. :-)
/ David Hedbor
Previous text:
2003-01-22 03:09: Subject: Re: zero_type() & UNDEFINED (bug?)
On Wed, Jan 22, 2003 at 03:00:00AM +0100, Johan Sundström (a hugging punishment!) @ Pike (-) developers forum wrote:
It is logical to expect that if zero_type(X) == zero_type(Y) then X == Y.
I am curious as to where you got that idea. That implication never holds;
i think he just accidentially reversed the examples and meant to say: if X == Y then zero_type(X) == zero_type(Y),
greetings, martin.
/ Brevbäraren
On Wed, Jan 22, 2003 at 03:40:00AM +0100, David Hedbor @ Pike developers forum wrote:
zero_type(0);
(2) Result: 0
zero_type(UNDEFINED);
(3) Result: 1
But:
typeof(UNDEFINED);
(27) Result: zero
typeof(0);
(28) Result: zero
sprintf("%t", 0);
(29) Result: "int"
sprintf("%t", UNDEFINED);
(30) Result: "int"
A bit unlogical... :)
Regards, /Al
The whole purpose of UNDEFINED is the ability to get to the special case of zero that UNDEFINED is without using a kludge such as ([])[0]. In general you would on the other hand test for such a value using zero_type().
However you can't use if(variable == UNDEFINED) { ... } since that will match if variable is either 0 or UNDEFINED.
On a related note, I think it would be nice if uninitialized variables ended up being UNDEFINED rather than 0. I.e:
int i; [... do something ...] if(zero_type(i)) { blah }
/ David Hedbor
Previous text:
2003-01-22 07:03: Subject: Re: zero_type() & UNDEFINED (bug?)
On Wed, Jan 22, 2003 at 03:40:00AM +0100, David Hedbor @ Pike developers forum wrote:
zero_type(0);
(2) Result: 0
zero_type(UNDEFINED);
(3) Result: 1
But:
typeof(UNDEFINED);
(27) Result: zero
typeof(0);
(28) Result: zero
sprintf("%t", 0);
(29) Result: "int"
sprintf("%t", UNDEFINED);
(30) Result: "int"
A bit unlogical... :)
Regards, /Al
/ Brevbäraren
Or we might want to invent a new zero type to distinguish between an uninitialized variable and one with the value of a failed indexing operation.
/ Martin Nilsson (Åskblod)
Previous text:
2003-01-22 07:09: Subject: Re: zero_type() & UNDEFINED (bug?)
The whole purpose of UNDEFINED is the ability to get to the special case of zero that UNDEFINED is without using a kludge such as ([])[0]. In general you would on the other hand test for such a value using zero_type().
However you can't use if(variable == UNDEFINED) { ... } since that will match if variable is either 0 or UNDEFINED.
On a related note, I think it would be nice if uninitialized variables ended up being UNDEFINED rather than 0. I.e:
int i; [... do something ...] if(zero_type(i)) { blah }
/ David Hedbor
Some (class-)global variables does not have room for zero-type as it is now. They would have to be converted to svalues.
/ Per Hedbor ()
Previous text:
2003-01-22 11:25: Subject: Re: zero_type() & UNDEFINED (bug?)
Or we might want to invent a new zero type to distinguish between an uninitialized variable and one with the value of a failed indexing operation.
/ Martin Nilsson (Åskblod)
At this point I would like to apologize to everybody for inventing zero_type and all that stuff... :)
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-01-22 11:25: Subject: Re: zero_type() & UNDEFINED (bug?)
Or we might want to invent a new zero type to distinguish between an uninitialized variable and one with the value of a failed indexing operation.
/ Martin Nilsson (Åskblod)
On Wed, Jan 22, 2003 at 03:00:00AM +0100, Johan Sundstr�m (a hugging punishment!) @ Pike (-) developers forum wrote:
whereas 4 != 5. zero_type() tests a a property that `== does not see.
Well... It means that I cannot test something for equality to UNDEFINED and expect correct results (when value is present but is integer zero).
So UNDEFINED by itself is useless, unless tested by zero_type().
It would be nice to have universal "void" value, which would be tested like (value == VOID) where 0 is guaranteed not to be VOID (because it actually isn't).
And "zero_type" is not really meaningful name for such testing (at least out of Pike context)... So I'll alias it to undefined() :)
What is more interesting:
mixed x, y; x = 1;
(16) Result: 1
y = 2;
(17) Result: 2
_typeof(x);
(18) Result: int(1..1)
_typeof(y);
(19) Result: int(2..2)
But:
sprintf("%t", x);
(20) Result: "int"
sprintf("%t", y);
(21) Result: "int"
What a surprise... :) It was just a curiosity, but results are impressive, I didn't expect that two integer values may have different type :)
Regards, /Al
Well... It means that I cannot test something for equality to UNDEFINED and expect correct results (when value is present but is integer zero).
So UNDEFINED by itself is useless, unless tested by zero_type().
It would be nice to have universal "void" value, which would be tested like (value == VOID) where 0 is guaranteed not to be VOID (because it actually isn't).
I don't exactly understand what you want to have - do you want something that means "NULL" but which isn't zero and if you do NULL == <zero or variable with value zero> to always return false?
/ David Hedbor
Previous text:
2003-01-22 06:59: Subject: Re: zero_type() & UNDEFINED and _typeof()
On Wed, Jan 22, 2003 at 03:00:00AM +0100, Johan Sundström (a hugging punishment!) @ Pike (-) developers forum wrote:
whereas 4 != 5. zero_type() tests a a property that `== does not see.
Well... It means that I cannot test something for equality to UNDEFINED and expect correct results (when value is present but is integer zero).
So UNDEFINED by itself is useless, unless tested by zero_type().
It would be nice to have universal "void" value, which would be tested like (value == VOID) where 0 is guaranteed not to be VOID (because it actually isn't).
And "zero_type" is not really meaningful name for such testing (at least out of Pike context)... So I'll alias it to undefined() :)
What is more interesting:
mixed x, y; x = 1;
(16) Result: 1
y = 2;
(17) Result: 2
_typeof(x);
(18) Result: int(1..1)
_typeof(y);
(19) Result: int(2..2)
But:
sprintf("%t", x);
(20) Result: "int"
sprintf("%t", y);
(21) Result: "int"
What a surprise... :) It was just a curiosity, but results are impressive, I didn't expect that two integer values may have different type :)
Regards, /Al
/ Brevbäraren
I think he's asking for a special nil object that is not compatible with integers (nor with other objects).
I.e. x != UNDEFINED for all numbers (and objects), and 17 + UNDEFINED ==> some exception.
/ Niels Möller ()
Previous text:
2003-01-22 07:04: Subject: Re: zero_type() & UNDEFINED and _typeof()
Well... It means that I cannot test something for equality to UNDEFINED and expect correct results (when value is present but is integer zero).
So UNDEFINED by itself is useless, unless tested by zero_type().
It would be nice to have universal "void" value, which would be tested like (value == VOID) where 0 is guaranteed not to be VOID (because it actually isn't).
I don't exactly understand what you want to have - do you want something that means "NULL" but which isn't zero and if you do NULL == <zero or variable with value zero> to always return false?
/ David Hedbor
I think he's asking for a special nil object that is not compatible with integers (nor with other objects).
I.e. x != UNDEFINED for all numbers (and objects), and 17 + UNDEFINED ==> some exception.
Something like this?
object undef = class { int(0..1) `==(mixed a) { return zero_type(a); } int(0..1) `!() { return 1; } }();
undef==0;
(1) Result: 0
undef==UNDEFINED;
(3) Result: 1
:-)
/Mirar
On Wed, Jan 22, 2003 at 07:05:02AM +0100, David Hedbor @ Pike developers forum wrote:
I don't exactly understand what you want to have - do you want something that means "NULL" but which isn't zero and if you do NULL == <zero or variable with value zero> to always return false?
Exactly. A completely "undefined" or "void" value, which is unique and no other value (including integer 0) should give true when comparing to. It will allow to make comparisions like:
somevalue == NULL which will give "true" when somevalue is uninitialized or explicitly set to NULL, but which will give "false" when somevalue assigned something different from NULL.
Without this, any test like:
if (map[key]) ...; would behave incorrectly when map[key] is present but is integer 0.
Name "NULL" isn't good choice for this case, I guess, perhaps "NIL" or "VOID" would be better ("UNDEFINED" is more clear, of course, but a bit long :)
Regards, /Al
Without this, any test like:
if (map[key]) ...;
would behave incorrectly when map[key] is present but is integer 0.
This is EXACTLY what zero_type is there to solve. I.e use:
if(zero_type(map[key])) { key not present in map } else if(map[key]) { key present but value is zero } else { key present with a non-zero value }
/ David Hedbor
Previous text:
2003-01-22 15:26: Subject: Re: zero_type() & UNDEFINED and _typeof()
On Wed, Jan 22, 2003 at 07:05:02AM +0100, David Hedbor @ Pike developers forum wrote:
I don't exactly understand what you want to have - do you want something that means "NULL" but which isn't zero and if you do NULL == <zero or variable with value zero> to always return false?
Exactly. A completely "undefined" or "void" value, which is unique and no other value (including integer 0) should give true when comparing to. It will allow to make comparisions like:
somevalue == NULL
which will give "true" when somevalue is uninitialized or explicitly set to NULL, but which will give "false" when somevalue assigned something different from NULL.
Without this, any test like:
if (map[key]) ...;
would behave incorrectly when map[key] is present but is integer 0.
Name "NULL" isn't good choice for this case, I guess, perhaps "NIL" or "VOID" would be better ("UNDEFINED" is more clear, of course, but a bit long :)
Regards, /Al
/ Brevbäraren
You're missing a ! in the second if.
/ Martin Nilsson (Åskblod)
Previous text:
2003-01-22 16:14: Subject: Re: zero_type() & UNDEFINED and _typeof()
Without this, any test like:
if (map[key]) ...;
would behave incorrectly when map[key] is present but is integer 0.
This is EXACTLY what zero_type is there to solve. I.e use:
if(zero_type(map[key])) { key not present in map } else if(map[key]) { key present but value is zero } else { key present with a non-zero value }
/ David Hedbor
On Wed, Jan 22, 2003 at 04:15:02PM +0100, David Hedbor @ Pike developers forum wrote:
This is EXACTLY what zero_type is there to solve. I.e use:
Except that name zero_type() isn't as clear as undefined(), for instance...
Regards, /Al
But zero_type() doesn't answer the question undefined or not, but returns the type of zero that the argument has. E.g. if zero_type() returns 2 that means that you have a destructed object in your variable. It is very much defined.
/ Martin Nilsson (Åskblod)
Previous text:
2003-01-22 16:22: Subject: Re: zero_type() & UNDEFINED and _typeof()
On Wed, Jan 22, 2003 at 04:15:02PM +0100, David Hedbor @ Pike developers forum wrote:
This is EXACTLY what zero_type is there to solve. I.e use:
Except that name zero_type() isn't as clear as undefined(), for instance...
Regards, /Al
/ Brevbäraren
Well, it isn't that unreasonable to add a new function undefined() that is implemented as (zero_type(x) == 1). It's common that people don't check the exact zero type. That's almost never a problem but it can easily become too much of a habit, which occasionally has led to bugs.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-22 16:25: Subject: Re: zero_type() & UNDEFINED and _typeof()
But zero_type() doesn't answer the question undefined or not, but returns the type of zero that the argument has. E.g. if zero_type() returns 2 that means that you have a destructed object in your variable. It is very much defined.
/ Martin Nilsson (Åskblod)
If it is combined with setting uninitialized variables to zero type 1 it is reasonable.
/ Martin Nilsson (Åskblod)
Previous text:
2003-01-23 01:22: Subject: Re: zero_type() & UNDEFINED and _typeof()
Well, it isn't that unreasonable to add a new function undefined() that is implemented as (zero_type(x) == 1). It's common that people don't check the exact zero type. That's almost never a problem but it can easily become too much of a habit, which occasionally has led to bugs.
/ Martin Stjernholm, Roxen IS
If uninitialized values are given a zero type then it shouldn't be 1 since that'd make it impossible to tell if foo in my_object->foo is a nonexisting identifier or an uninitialized variable. Another zero type and another function uninitialized() or something would be necessary.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 01:24: Subject: Re: zero_type() & UNDEFINED and _typeof()
If it is combined with setting uninitialized variables to zero type 1 it is reasonable.
/ Martin Nilsson (Åskblod)
It's just a compatibility problem, but I agree that your solution is the most preferable one (presented so far).
/ Martin Nilsson (Åskblod)
Previous text:
2003-01-23 01:39: Subject: Re: zero_type() & UNDEFINED and _typeof()
If uninitialized values are given a zero type then it shouldn't be 1 since that'd make it impossible to tell if foo in my_object->foo is a nonexisting identifier or an uninitialized variable. Another zero type and another function uninitialized() or something would be necessary.
/ Martin Stjernholm, Roxen IS
It'd be even better to make the new zero type not equal to zero and add a new constant nil or null or NULL for it. An uninitialized() function wouldn't be necessary.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 01:46: Subject: Re: zero_type() & UNDEFINED and _typeof()
It's just a compatibility problem, but I agree that your solution is the most preferable one (presented so far).
/ Martin Nilsson (Åskblod)
On Thu, Jan 23, 2003 at 02:00:01AM +0100, Martin Stjernholm, Roxen IS @ Pike developers forum wrote:
It'd be even better to make the new zero type not equal to zero and add a new constant nil or null or NULL for it. An uninitialized() function wouldn't be necessary.
Exactly my point. A constant that means that value is not initialized or explicitly deinitialized. This constant must not equals to 0 or anything else but itself. It should be possible to assign this constant to variable of any type, thus "deinitializing" it.
This way, any expression like:
(val = map[key]) != NULL will give correct result when, and only when the element indexed by key has been set to anything but NULL (including integer 0).
Setting an element of mapping, multiset or array to NULL should delete this element (thus eleminating the need of m_delete()). As of me, the code like:
map[key] = NULL; seems logical and I expect that element will be deleted.
NULL by itself should be evaluated as "false" in any logical operation.
Pros: we don't need additional function; we can easily check if the result is defined; we can delete elements in natural way (just by undefining them).
Cons: none yet, or? :)
Regards, /Al
Note that the new NULL value I'm talking about there is distinct from UNDEFINED. That's necessary since, as I've said earlier, it must be possible to tell whether foo in my_object->foo is a nonexisting identifier or a variable that has the value NULL.
So UNDEFINED has to be a transient value that can't be stored in objects etc, or else it looses its function. (I actually find it a little unnerving that it can be stored in local variables inside functions since that makes it a bit "blurry" conceptually. It's also a bit of a problem when it comes to unification classes and functions, which I think is a very neat idea from a language design standpoint.)
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 03:00: Subject: Re: zero_type() & UNDEFINED and _typeof()
On Thu, Jan 23, 2003 at 02:00:01AM +0100, Martin Stjernholm, Roxen IS @ Pike developers forum wrote:
It'd be even better to make the new zero type not equal to zero and add a new constant nil or null or NULL for it. An uninitialized() function wouldn't be necessary.
Exactly my point. A constant that means that value is not initialized or explicitly deinitialized. This constant must not equals to 0 or anything else but itself. It should be possible to assign this constant to variable of any type, thus "deinitializing" it.
This way, any expression like:
(val = map[key]) != NULL
will give correct result when, and only when the element indexed by key has been set to anything but NULL (including integer 0).
Setting an element of mapping, multiset or array to NULL should delete this element (thus eleminating the need of m_delete()). As of me, the code like:
map[key] = NULL;
seems logical and I expect that element will be deleted.
NULL by itself should be evaluated as "false" in any logical operation.
Pros: we don't need additional function; we can easily check if the result is defined; we can delete elements in natural way (just by undefining them).
Cons: none yet, or? :)
Regards, /Al
/ Brevbäraren
Why? Those two proposals are orthogonal.
What's the problem with variables being automatically initialized to zero? You just have to stop thinking of them as "undefined" (like C stack variables) and instead think of them as automatically initalized to zero (like C static variables).
If you start making string foo; equivalent to string foo = UNDEFINED_STRING; would you also want to make foo = 0; (where foo is a string variable) equivalent to foo = UNDEFINED_STRING?
To me, having more than one "null value" for strings seems utterly useless.
/ Niels Möller ()
Previous text:
2003-01-23 01:24: Subject: Re: zero_type() & UNDEFINED and _typeof()
If it is combined with setting uninitialized variables to zero type 1 it is reasonable.
/ Martin Nilsson (Åskblod)
On Thu, Jan 23, 2003 at 10:05:02AM +0100, Niels Möller () @ Pike (-) developers forum wrote:
What's the problem with variables being automatically initialized to zero?
that it's only ints that are actually initialized to value of their own type, while everything else is clearly distinguishable from a real value. (if that is a problem :-)
To me, having more than one "null value" for strings seems utterly useless.
i agree with that, if 0 looses its special meaning, then a string (or any non int variable) should never get the value 0.
things that irritate are:
string foo; sprintf("%s", foo);
Sprintf: Wrong type for argument 2: expected string, got int.
where i'd rather read:
Sprintf: Wrong type for argument 2: string is UNDEFINED.
which more clearly indicates that foo has an unacceptable value, but not an unacceptable type.
or:
foo+="bar";
(1) Result: "0bar"
the automatic cast of strings with value 0 to "0" in many string operations is an equal irritation where i'd rather get an exception.
compare this to:
array bar; bar+=({ "baz" });
Bad argument 2 to `+(). Expected int
which does raise an exception. although the errormessage seems rather odd too:
Bad argument 1 to `+(). array is undefined.
is, what one would like to read here.
however all things said, the compatibility issues involved may make the whole discussion moot...
greetings, martin.
I think of zero as a real and valid value for a string variable. Perhaps I've gotten too used to C's NULL value.
For your other comments, I agree that printf could display a better error message, and I really hate the automatic int->string conversion. But that doesn't mean that I don't think initialization to zero is ok.
As for arrays, automatic initialization to an empty array would be useful, but it's no big deal to have to write array bar = ({}); when that's what you want.
/ Niels Möller ()
Previous text:
2003-01-23 10:49: Subject: Re: zero_type() & UNDEFINED and _typeof()
On Thu, Jan 23, 2003 at 10:05:02AM +0100, Niels Möller () @ Pike (-) developers forum wrote:
What's the problem with variables being automatically initialized to zero?
that it's only ints that are actually initialized to value of their own type, while everything else is clearly distinguishable from a real value. (if that is a problem :-)
To me, having more than one "null value" for strings seems utterly useless.
i agree with that, if 0 looses its special meaning, then a string (or any non int variable) should never get the value 0.
things that irritate are:
string foo; sprintf("%s", foo);
Sprintf: Wrong type for argument 2: expected string, got int.
where i'd rather read:
Sprintf: Wrong type for argument 2: string is UNDEFINED.
which more clearly indicates that foo has an unacceptable value, but not an unacceptable type.
or:
foo+="bar";
(1) Result: "0bar"
the automatic cast of strings with value 0 to "0" in many string operations is an equal irritation where i'd rather get an exception.
compare this to:
array bar; bar+=({ "baz" });
Bad argument 2 to `+(). Expected int
which does raise an exception. although the errormessage seems rather odd too:
Bad argument 1 to `+(). array is undefined.
is, what one would like to read here.
however all things said, the compatibility issues involved may make the whole discussion moot...
greetings, martin.
/ Brevbäraren
Much of this is due to that the type system doesn't completely correspond to the actual value sets. E.g. the string type includes zero and all "real" strings, but the value zero has almost completely different properties than the other string values. It's very common with functions that take string arguments and still don't accept zero, and then they complain that zero isn't a string.
I'd like this to be fixed in the long run, perhaps for Pike 8, so that the reference types don't include zero in their value sets. If you want to allow zero then be explicit about it and use string|zero.
The initial value problem could be fixed by
1. defaulting to "", ({}) etc as appropriate (but that gives an ambiguity problem for variables of type string|array etc),
2. always requiring an initialization, or
3. add rules to make it possible to check at compile time that a variable always is initialized before its first use. That could be tricky due to the dynamic nature of Pike, though.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 10:49: Subject: Re: zero_type() & UNDEFINED and _typeof()
On Thu, Jan 23, 2003 at 10:05:02AM +0100, Niels Möller () @ Pike (-) developers forum wrote:
What's the problem with variables being automatically initialized to zero?
that it's only ints that are actually initialized to value of their own type, while everything else is clearly distinguishable from a real value. (if that is a problem :-)
To me, having more than one "null value" for strings seems utterly useless.
i agree with that, if 0 looses its special meaning, then a string (or any non int variable) should never get the value 0.
things that irritate are:
string foo; sprintf("%s", foo);
Sprintf: Wrong type for argument 2: expected string, got int.
where i'd rather read:
Sprintf: Wrong type for argument 2: string is UNDEFINED.
which more clearly indicates that foo has an unacceptable value, but not an unacceptable type.
or:
foo+="bar";
(1) Result: "0bar"
the automatic cast of strings with value 0 to "0" in many string operations is an equal irritation where i'd rather get an exception.
compare this to:
array bar; bar+=({ "baz" });
Bad argument 2 to `+(). Expected int
which does raise an exception. although the errormessage seems rather odd too:
Bad argument 1 to `+(). array is undefined.
is, what one would like to read here.
however all things said, the compatibility issues involved may make the whole discussion moot...
greetings, martin.
/ Brevbäraren
UNDEFINED is not useless. It's very useful to e.g. use as a return value from a function.
The real problem is that there is no operation "check the existence of the index foo" that is separate from "get the value of index foo". Instead there is this kludge by overloading the value zero with different subtypes. I think the good solution is to add a check for existence operation and then let a zero just be a zero. (The other zero types are fairly obscure and could probably be done away with easily or simply ignored.)
There was a discussion a while back about adding new operators for insert and delete operations, foo+[bar]=gnu and foo-[bar] (something I intend to do when I get the time, unless someone beats me to it). In the same vein an operator for this could be added. The logical choice would be foo?[bar] but unfortunately there was some grammatic problem with that, if I remember correctly.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-22 06:59: Subject: Re: zero_type() & UNDEFINED and _typeof()
On Wed, Jan 22, 2003 at 03:00:00AM +0100, Johan Sundström (a hugging punishment!) @ Pike (-) developers forum wrote:
whereas 4 != 5. zero_type() tests a a property that `== does not see.
Well... It means that I cannot test something for equality to UNDEFINED and expect correct results (when value is present but is integer zero).
So UNDEFINED by itself is useless, unless tested by zero_type().
It would be nice to have universal "void" value, which would be tested like (value == VOID) where 0 is guaranteed not to be VOID (because it actually isn't).
And "zero_type" is not really meaningful name for such testing (at least out of Pike context)... So I'll alias it to undefined() :)
What is more interesting:
mixed x, y; x = 1;
(16) Result: 1
y = 2;
(17) Result: 2
_typeof(x);
(18) Result: int(1..1)
_typeof(y);
(19) Result: int(2..2)
But:
sprintf("%t", x);
(20) Result: "int"
sprintf("%t", y);
(21) Result: "int"
What a surprise... :) It was just a curiosity, but results are impressive, I didn't expect that two integer values may have different type :)
Regards, /Al
/ Brevbäraren
It sounds like you are contradicting yourself. On one hand you say that it is useful to return zerotypes from functions, but on the other hand you say that zerotypes are not useful as long as there is another way to check membership of indices.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-01-23 00:13: Subject: Re: zero_type() & UNDEFINED and _typeof()
UNDEFINED is not useless. It's very useful to e.g. use as a return value from a function.
The real problem is that there is no operation "check the existence of the index foo" that is separate from "get the value of index foo". Instead there is this kludge by overloading the value zero with different subtypes. I think the good solution is to add a check for existence operation and then let a zero just be a zero. (The other zero types are fairly obscure and could probably be done away with easily or simply ignored.)
There was a discussion a while back about adding new operators for insert and delete operations, foo+[bar]=gnu and foo-[bar] (something I intend to do when I get the time, unless someone beats me to it). In the same vein an operator for this could be added. The logical choice would be foo?[bar] but unfortunately there was some grammatic problem with that, if I remember correctly.
/ Martin Stjernholm, Roxen IS
I said that UNDEFINED is useful considering the current situation when this kludge exists. The kludge itself is unfortunate, though, and UNDEFINED (and the other zero types) could be removed if a new existence operator is added.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 00:16: Subject: Re: zero_type() & UNDEFINED and _typeof()
It sounds like you are contradicting yourself. On one hand you say that it is useful to return zerotypes from functions, but on the other hand you say that zerotypes are not useful as long as there is another way to check membership of indices.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Personally I think that the suggested new operators are more ugly than UNDEFINED and zero_type squared.
/ Per Hedbor ()
Previous text:
2003-01-23 00:34: Subject: Re: zero_type() & UNDEFINED and _typeof()
I said that UNDEFINED is useful considering the current situation when this kludge exists. The kludge itself is unfortunate, though, and UNDEFINED (and the other zero types) could be removed if a new existence operator is added.
/ Martin Stjernholm, Roxen IS
What would you return from a function that currently returns UNDEFINED if UNDEFINED is removed then? If there is another value that works just as well, why is UNDEFINED useful in the current situation? If there is no such value, why is UNDEFINED not useful in a situation with an existence test operator?
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-01-23 00:34: Subject: Re: zero_type() & UNDEFINED and _typeof()
I said that UNDEFINED is useful considering the current situation when this kludge exists. The kludge itself is unfortunate, though, and UNDEFINED (and the other zero types) could be removed if a new existence operator is added.
/ Martin Stjernholm, Roxen IS
With that operator there would be two different functions and no need for a special value. But anyway, it wouldn't be wise to remove the value for the reason in 9629831. Not to mention functions like resolv() etc.
Adding an existence operation could still be useful though, since it'd give a standardized way for a collection class to implement a check for existence without at the same time calculating the value.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 00:39: Subject: Re: zero_type() & UNDEFINED and _typeof()
What would you return from a function that currently returns UNDEFINED if UNDEFINED is removed then? If there is another value that works just as well, why is UNDEFINED useful in the current situation? If there is no such value, why is UNDEFINED not useful in a situation with an existence test operator?
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Eh? "There would be"? The code would hardly rewrite itself. Let's say I have a large function called "do_heavy_database_query()" which can return a value, or UNDEFINED if the database doesn't know the answer. Are you suggesting I should duplicate the code and create two functions "do_heavy_database_query_ok()" and "do_heavy_database_query_value()", and then call first the first one to check if the database knows the answer and then the second one to actually get the value? Besides the fact that the database operation would have to be done twice, there is also the problem of atomicity. The database might forget the value between the call to "do_heavy_database_query_ok()" and "do_heavy_database_query_value()".
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-01-23 00:58: Subject: Re: zero_type() & UNDEFINED and _typeof()
With that operator there would be two different functions and no need for a special value. But anyway, it wouldn't be wise to remove the value for the reason in 9629831. Not to mention functions like resolv() etc.
Adding an existence operation could still be useful though, since it'd give a standardized way for a collection class to implement a check for existence without at the same time calculating the value.
/ Martin Stjernholm, Roxen IS
That sounds more common than masts problem.
/ Martin Nilsson (Åskblod)
Previous text:
2003-01-23 01:23: Subject: Re: zero_type() & UNDEFINED and _typeof()
Eh? "There would be"? The code would hardly rewrite itself. Let's say I have a large function called "do_heavy_database_query()" which can return a value, or UNDEFINED if the database doesn't know the answer. Are you suggesting I should duplicate the code and create two functions "do_heavy_database_query_ok()" and "do_heavy_database_query_value()", and then call first the first one to check if the database knows the answer and then the second one to actually get the value? Besides the fact that the database operation would have to be done twice, there is also the problem of atomicity. The database might forget the value between the call to "do_heavy_database_query_ok()" and "do_heavy_database_query_value()".
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
No, I'm no longer suggesting that if you read the text you commented more carefully. But thanks anyway for a more verbose description of the drawbacks than I gave.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 01:23: Subject: Re: zero_type() & UNDEFINED and _typeof()
Eh? "There would be"? The code would hardly rewrite itself. Let's say I have a large function called "do_heavy_database_query()" which can return a value, or UNDEFINED if the database doesn't know the answer. Are you suggesting I should duplicate the code and create two functions "do_heavy_database_query_ok()" and "do_heavy_database_query_value()", and then call first the first one to check if the database knows the answer and then the second one to actually get the value? Besides the fact that the database operation would have to be done twice, there is also the problem of atomicity. The database might forget the value between the call to "do_heavy_database_query_ok()" and "do_heavy_database_query_value()".
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
If there's no special UNDEFINED value, I think the only natural way to say that there's no answer, is to raise an exception.
To me, the basic uglyness with the zerotype solution is that it's not really possible to store the value in mapping. And that it is sometimes automatically degraded to an ordinary zero (say, when stored in a certain global variables?).
/ Niels Möller ()
Previous text:
2003-01-23 01:23: Subject: Re: zero_type() & UNDEFINED and _typeof()
Eh? "There would be"? The code would hardly rewrite itself. Let's say I have a large function called "do_heavy_database_query()" which can return a value, or UNDEFINED if the database doesn't know the answer. Are you suggesting I should duplicate the code and create two functions "do_heavy_database_query_ok()" and "do_heavy_database_query_value()", and then call first the first one to check if the database knows the answer and then the second one to actually get the value? Besides the fact that the database operation would have to be done twice, there is also the problem of atomicity. The database might forget the value between the call to "do_heavy_database_query_ok()" and "do_heavy_database_query_value()".
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
If there's no special UNDEFINED value, I think the only natural way to say that there's no answer, is to raise an exception.
With the current exception system, that's not really practical though. Trying to use excpetions for anything other than errors becomes quite messy.
To me, the basic uglyness with the zerotype solution is that it's not really possible to store the value in mapping. And that it is sometimes automatically degraded to an ordinary zero (say, when stored in a certain global variables?).
This is interresting. masts main gripe against UNDEFINED is that it _can_ be stored under certain circumstances, and yours is that it _can't_ under the remaining. :-)
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-01-23 09:54: Subject: Re: zero_type() & UNDEFINED and _typeof()
If there's no special UNDEFINED value, I think the only natural way to say that there's no answer, is to raise an exception.
To me, the basic uglyness with the zerotype solution is that it's not really possible to store the value in mapping. And that it is sometimes automatically degraded to an ordinary zero (say, when stored in a certain global variables?).
/ Niels Möller ()
On Thu, Jan 23, 2003 at 01:05:04PM +0100, Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum wrote:
This is interresting. masts main gripe against UNDEFINED is that it _can_ be stored under certain circumstances, and yours is that it _can't_ under the remaining. :-)
well, both have in common that currently this is not consistent :-)
greetings, martin.
Well, I think too that UNDEFINED is basically ugly, much on the same ground. The ugliness gets worse since it's inconsistent. I'd like a solution where there was no need for such a value at all, but so far noone has come up with an alternative that is good enough.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 13:03: Subject: Re: zero_type() & UNDEFINED and _typeof()
If there's no special UNDEFINED value, I think the only natural way to say that there's no answer, is to raise an exception.
With the current exception system, that's not really practical though. Trying to use excpetions for anything other than errors becomes quite messy.
To me, the basic uglyness with the zerotype solution is that it's not really possible to store the value in mapping. And that it is sometimes automatically degraded to an ordinary zero (say, when stored in a certain global variables?).
This is interresting. masts main gripe against UNDEFINED is that it _can_ be stored under certain circumstances, and yours is that it _can't_ under the remaining. :-)
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
I think that
mixed x = foo(); if(zero_type(x)) { werror("No value\n"); } else { werror("The value is %O\n", x); }
is much better than
mixed x; mixed y = catch(x = foo()); if(!y) { werror("The value is %O\n", x); } else if(!arrayp(y) && !(objectp(y) && y->is_generic_error)) { werror("No value\n"); } else { throw(y); }
though.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-01-23 16:47: Subject: Re: zero_type() & UNDEFINED and _typeof()
Well, I think too that UNDEFINED is basically ugly, much on the same ground. The ugliness gets worse since it's inconsistent. I'd like a solution where there was no need for such a value at all, but so far noone has come up with an alternative that is good enough.
/ Martin Stjernholm, Roxen IS
I think the exception thing would work if there was some syntax sugar and a decent exception hierarchy.
try { mixed x = foo(); werror("The value is %O\n", x); } except { no_value: werror("No value\n"); }
One would also want some syntax sugar to make m[foo] | "bar" work (and do the right thing, with "bar" used iff m[foo] doesn't exist). It's hard to cook up a good syntax. Perhaps a trinary or n-ary !: could work (by a stretch analogy with trinary ?):
m[foo] ! no_value : "bar"
/ Niels Möller ()
Previous text:
2003-01-23 17:06: Subject: Re: zero_type() & UNDEFINED and _typeof()
I think that
mixed x = foo(); if(zero_type(x)) { werror("No value\n"); } else { werror("The value is %O\n", x); }
is much better than
mixed x; mixed y = catch(x = foo()); if(!y) { werror("The value is %O\n", x); } else if(!arrayp(y) && !(objectp(y) && y->is_generic_error)) { werror("No value\n"); } else { throw(y); }
though.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Sorry, but that last bit feels more like syntactic dung than syntatic sugar...
/ Leif Stensson, Lysator
Previous text:
2003-01-23 17:42: Subject: Re: zero_type() & UNDEFINED and _typeof()
I think the exception thing would work if there was some syntax sugar and a decent exception hierarchy.
try { mixed x = foo(); werror("The value is %O\n", x); } except { no_value: werror("No value\n"); }
One would also want some syntax sugar to make m[foo] | "bar" work (and do the right thing, with "bar" used iff m[foo] doesn't exist). It's hard to cook up a good syntax. Perhaps a trinary or n-ary !: could work (by a stretch analogy with trinary ?):
m[foo] ! no_value : "bar"
/ Niels Möller ()
Any better suggestions for some exception-conditional that can be used as an expression?
/ Niels Möller ()
Previous text:
2003-01-23 17:59: Subject: Re: zero_type() & UNDEFINED and _typeof()
Sorry, but that last bit feels more like syntactic dung than syntatic sugar...
/ Leif Stensson, Lysator
I'm not at all sure it's the right approach, but assuming it is, I suppose a special function or operator that extracts an exception result object could do. E.g.
exceptionset(m)->no_value ? "bar" : m->foo
That concentrates the exception magic into an ordinary function, and uses the plain "?" operator for the actual selection.
/ Leif Stensson, Lysator
Previous text:
2003-01-23 18:18: Subject: Re: zero_type() & UNDEFINED and _typeof()
Any better suggestions for some exception-conditional that can be used as an expression?
/ Niels Möller ()
I'm afraid I don't understand how that's supposed to work.
Looks reasonably nice, though.
/ Niels Möller ()
Previous text:
2003-01-24 16:22: Subject: Re: zero_type() & UNDEFINED and _typeof()
I'm not at all sure it's the right approach, but assuming it is, I suppose a special function or operator that extracts an exception result object could do. E.g.
exceptionset(m)->no_value ? "bar" : m->foo
That concentrates the exception magic into an ordinary function, and uses the plain "?" operator for the actual selection.
/ Leif Stensson, Lysator
Ah, a typo. I meant:
exceptionset(m->foo)->no_value ? "bar" : m->foo
/ Leif Stensson, Lysator
Previous text:
2003-01-24 23:29: Subject: Re: zero_type() & UNDEFINED and _typeof()
I'm afraid I don't understand how that's supposed to work.
Looks reasonably nice, though.
/ Niels Möller ()
I'd like a construktion where the actual m->foo lookup is done only once (and preferably, also occurs only once in the source code).
/ Niels Möller ()
Previous text:
2003-01-28 10:51: Subject: Re: zero_type() & UNDEFINED and _typeof()
Ah, a typo. I meant:
exceptionset(m->foo)->no_value ? "bar" : m->foo
/ Leif Stensson, Lysator
Define a utility function when you need it? :-)
mixed value_with_default(mixed value, mixed default) { return exceptionset(value)->no_value ? default : value; }
/ Leif Stensson, Lysator
Previous text:
2003-01-28 12:11: Subject: Re: zero_type() & UNDEFINED and _typeof()
I'd like a construktion where the actual m->foo lookup is done only once (and preferably, also occurs only once in the source code).
/ Niels Möller ()
Huh?
value_with_default(m->foo, "bar");
You're asuming that the exception is stored together with the value? That's not how exceptions work in any language I'm familiar with, it would be raised when the value is computed, terminate the normal flow of control, and the helper function would never be called.
I'm afraid I'm totally lost here, even if storing arbitrary exceptions with a value would be a creative extension of the zero_type hack.
/ Niels Möller ()
Previous text:
2003-01-28 13:56: Subject: Re: zero_type() & UNDEFINED and _typeof()
Define a utility function when you need it? :-)
mixed value_with_default(mixed value, mixed default) { return exceptionset(value)->no_value ? default : value; }
/ Leif Stensson, Lysator
You're asuming that the exception is stored together with the value?
1. Well, I wouldn't call it "assuming", I'm just sketching a possibility. We already have something like this, except that no real information about the nature of the exception is included.
2. I said from the start that I'm not sure this whole kind of approach -- trapping exceptions as values implicitly, by any means, as in your example, my example, or the existing zero_type hack -- is a good idea. But you asked me for suggestions, and I gave one I thought was reasonable, assuming we wanted to try the trap-exception-as-value approach.
3. It's not the exception itself that is stored, it's a "hidden record" (or whatever we might want to call it) of the exception. I meant that things that use the zero_type hack today could be extended to use this kind of system, instead of throwing exceptions. Then real exceptions could perhaps be thrown as objects, behaving like traditional "backtrace" arrays when indexed with integers, and behaving in the new way when indexed with other values.
4. It's not exactly stored "together" with the value, since the value and the exception record are mutually exclusive. If the evaluation went alright, without exceptions, there is no exception record, and if the evaluation was interrupted by an exception, there is no value, just an exception record.
That's not how exceptions work in any language I'm familiar with,
It's a bit like how conditionals work in PL/1, I think. :-) But I didn't mean for us to change "thrown" exceptions to work that way, just to merge the zero_type hack with an enhanced exception system. I mean, a new exception system is desirable anyway, and unifying the zero_type hack with it would be nice, especially if it could be done in a way that doesn't break existing code (or at least doesn't break normal existing code; unusually zero_type-aware code might run the risk of being broken, but I don't think that kind of code is particularly common, if it exists at all outside of test cases).
/ Leif Stensson, Lysator
Previous text:
2003-01-28 14:19: Subject: Re: zero_type() & UNDEFINED and _typeof()
Huh?
value_with_default(m->foo, "bar");
You're asuming that the exception is stored together with the value? That's not how exceptions work in any language I'm familiar with, it would be raised when the value is computed, terminate the normal flow of control, and the helper function would never be called.
I'm afraid I'm totally lost here, even if storing arbitrary exceptions with a value would be a creative extension of the zero_type hack.
/ Niels Möller ()
The best I can come up with is a variant of ? : that checks for existence instead of truth:
a[b] ?? "exists" : "does not exist"
One could extend it by making the middle expression optional. If it's left out then the value of the expression is the value of the test. E.g.
a[b] ??: "does not exist"
would either produce the result from the lookup of b in a or the string "does not exist".
But it seems a bit ad hoc to me to introduce another operator for this case, i.e. one that would either catch a very specific exception or look for the UNDEFINED value.
The Icon language has taken an interesting approach to this. It implements a sort of lightweight exceptions based on that every expression can either produce a value or fail. Such a failure is propagated much like an exception but only out of the expression. Then it simply becomes the value false for it. E.g. what in Pike would be written
mixed x; if (zero_type (x = a[b])) return -1; else return sizeof (x);
could be condensed to
return sizeof (a[b]) || -1;
If the lookup succeeds, its result would be fed to sizeof(), which always would succeed (given the type is correct). The || operator would then have a successful evaluation in its first operand and would return the its value. But if the lookup fails then sizeof() would never be called since a function with a failed argument will fail itself. || would then have failure in its first operand and continue to its second instead, and -1 would be returned.
It's apparent that this allows considerably more compact code. Many "silly" variables such as x above can be avoided. Perhaps it gets too compact; some experience is probably required to say whether programs become hard to understand or not.
See http://www.cs.arizona.edu/icon/ for info about Icon. The Overview page explains the idea about expression failure pretty well. Maybe it's possible to use this idea in Pike 8 or so. I suspect it'd take the language quite a bit from the current C-like operator behavior, but that's not necessarily a bad thing in my view.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 17:42: Subject: Re: zero_type() & UNDEFINED and _typeof()
I think the exception thing would work if there was some syntax sugar and a decent exception hierarchy.
try { mixed x = foo(); werror("The value is %O\n", x); } except { no_value: werror("No value\n"); }
One would also want some syntax sugar to make m[foo] | "bar" work (and do the right thing, with "bar" used iff m[foo] doesn't exist). It's hard to cook up a good syntax. Perhaps a trinary or n-ary !: could work (by a stretch analogy with trinary ?):
m[foo] ! no_value : "bar"
/ Niels Möller ()
Sounds reasonably nice, but hard to extend to catch specific exceptions.
/ Niels Möller ()
Previous text:
2003-01-24 02:19: Subject: Re: zero_type() & UNDEFINED and _typeof()
The best I can come up with is a variant of ? : that checks for existence instead of truth:
a[b] ?? "exists" : "does not exist"
One could extend it by making the middle expression optional. If it's left out then the value of the expression is the value of the test. E.g.
a[b] ??: "does not exist"
would either produce the result from the lookup of b in a or the string "does not exist".
But it seems a bit ad hoc to me to introduce another operator for this case, i.e. one that would either catch a very specific exception or look for the UNDEFINED value.
The Icon language has taken an interesting approach to this. It implements a sort of lightweight exceptions based on that every expression can either produce a value or fail. Such a failure is propagated much like an exception but only out of the expression. Then it simply becomes the value false for it. E.g. what in Pike would be written
mixed x; if (zero_type (x = a[b])) return -1; else return sizeof (x);
could be condensed to
return sizeof (a[b]) || -1;
If the lookup succeeds, its result would be fed to sizeof(), which always would succeed (given the type is correct). The || operator would then have a successful evaluation in its first operand and would return the its value. But if the lookup fails then sizeof() would never be called since a function with a failed argument will fail itself. || would then have failure in its first operand and continue to its second instead, and -1 would be returned.
It's apparent that this allows considerably more compact code. Many "silly" variables such as x above can be avoided. Perhaps it gets too compact; some experience is probably required to say whether programs become hard to understand or not.
See http://www.cs.arizona.edu/icon/ for info about Icon. The Overview page explains the idea about expression failure pretty well. Maybe it's possible to use this idea in Pike 8 or so. I suspect it'd take the language quite a bit from the current C-like operator behavior, but that's not necessarily a bad thing in my view.
/ Martin Stjernholm, Roxen IS
These expression failures shouldn't be confused with exceptions, I think. They would probably not even be implemented that way since exceptions aren't entirely cheap and these failures would be very common.
For instance, I think that sizeof() in my example should still throw a normal exception (handled just like it is today) instead of reporting failure if it was fed zero or some other invalid type.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-24 09:38: Subject: Re: zero_type() & UNDEFINED and _typeof()
Sounds reasonably nice, but hard to extend to catch specific exceptions.
/ Niels Möller ()
I think about as a special kind of exception. I guess one could think about it in other ways.
/ Niels Möller ()
Previous text:
2003-01-24 16:18: Subject: Re: zero_type() & UNDEFINED and _typeof()
These expression failures shouldn't be confused with exceptions, I think. They would probably not even be implemented that way since exceptions aren't entirely cheap and these failures would be very common.
For instance, I think that sizeof() in my example should still throw a normal exception (handled just like it is today) instead of reporting failure if it was fed zero or some other invalid type.
/ Martin Stjernholm, Roxen IS
Of course, but in either case there's no use considering several variants of it. The current exception system would not change.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-24 23:28: Subject: Re: zero_type() & UNDEFINED and _typeof()
I think about as a special kind of exception. I guess one could think about it in other ways.
/ Niels Möller ()
Hmm, exceptional operators, funky...
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-01-23 17:42: Subject: Re: zero_type() & UNDEFINED and _typeof()
I think the exception thing would work if there was some syntax sugar and a decent exception hierarchy.
try { mixed x = foo(); werror("The value is %O\n", x); } except { no_value: werror("No value\n"); }
One would also want some syntax sugar to make m[foo] | "bar" work (and do the right thing, with "bar" used iff m[foo] doesn't exist). It's hard to cook up a good syntax. Perhaps a trinary or n-ary !: could work (by a stretch analogy with trinary ?):
m[foo] ! no_value : "bar"
/ Niels Möller ()
On Thu, Jan 23, 2003 at 05:10:05PM +0100, Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum wrote:
I think that
mixed x = foo(); if(zero_type(x)) { werror("No value\n"); } else { werror("The value is %O\n", x); }
I think that:
if(x == VOID) { werror("No value\n"); } else { werror("The value is %O\n", x); }
is even better :)
Regards, /Al
Hmm, I just came to realize a clear advantage with UNDEFINED wrt an existence operator: It makes it possible to combine the existence operation and the lookup.
It's a pity that it's equal to zero though. Compatibility aspects aside, it would be better if 0 != UNDEFINED (but both would still be false).
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 00:34: Subject: Re: zero_type() & UNDEFINED and _typeof()
I said that UNDEFINED is useful considering the current situation when this kludge exists. The kludge itself is unfortunate, though, and UNDEFINED (and the other zero types) could be removed if a new existence operator is added.
/ Martin Stjernholm, Roxen IS
It would be quite unpikish to introduce values that are "false" but != 0. Three seconds after you implement that, someone will suggest that empty strings, mappings and arrays should also be "false".
/ Niels Möller ()
Previous text:
2003-01-23 00:40: Subject: Re: zero_type() & UNDEFINED and _typeof()
Hmm, I just came to realize a clear advantage with UNDEFINED wrt an existence operator: It makes it possible to combine the existence operation and the lookup.
It's a pity that it's equal to zero though. Compatibility aspects aside, it would be better if 0 != UNDEFINED (but both would still be false).
/ Martin Stjernholm, Roxen IS
Why would someone suggest that? There's a big difference between UNDEFINED and "", ({}) etc. Someone could otoh argue that the integer 0 should be true for symmetry with those values. But that'd require that a nil value is added, for starters. Even then, I'm a bit too damaged by C to like that.
/ Martin Stjernholm, Roxen IS
Previous text:
2003-01-23 00:48: Subject: Re: zero_type() & UNDEFINED and _typeof()
It would be quite unpikish to introduce values that are "false" but != 0. Three seconds after you implement that, someone will suggest that empty strings, mappings and arrays should also be "false".
/ Niels Möller ()
pike-devel@lists.lysator.liu.se