July 01, 2004
Regan Heath wrote:
> On Wed, 30 Jun 2004 22:40:28 -0700, Andy Friesen <andy@ikagames.com> wrote:
>> How on Earth ""!=null ever comes about is beyond me.
> 
> _adEq is..
> 
> extern (C) int _adCmp(Array a1, Array a2, TypeInfo ti)
> {
>     [....]
> }
> 
> which would return 0 if both lengths were 0. "" and null both have a length of 0.

Right, but Cmp functions return 0 to indicate equality, which would be the right thing in this case.

My money says the cause is in that inline-assembly-optimized _adCmpChar. (line 360)  I freely admit that I blame it on the inline assembly because me and assembly have not been on speaking terms for some time now.  (one too many hand-coded alpha-blits that lost to MSVC's optimizing compiler)

 -- andy
July 01, 2004
Sean Kelly <sean@f4.ca> wrote in news:cc04eh$2l5e$1@digitaldaemon.com:

> In article <Xns95199C928F73itsFarmer@63.105.9.61>, Farmer says...
>>
>>How do I know? Well the function in the phobos file internal\gc.d
>>         byte[] _d_arraysetlength(uint newlength, uint sizeelem, Array
>>         *p)
>>contains this assertion
>>         assert(!p.length || p.data);
>>
>>Ironically, this assertion permits, that the data pointer is null, but the length is greater than 0.
Rubbish.

> 
> I read it that the assertion requires either the length to be zero or
> the length to be nonzero and the data to be non-null.
> This seems to
> correspond to my assumption that D allows for zero length arrays to
> retain allocated memory.
> 
> Sean
> 

I blush for shame, this is too embarrassing. What a whimp I am, I can't do simple boolean algebra. What must years of Java(TM) programming hav done to me?

On the upside, it means that I was wrong. No assertion discourages null or empty-arrays.

Yes, memory for zero length arrays is retained, if the array is sliced.





July 01, 2004
Sorry, I've posted rubbish.

Farmer.
July 01, 2004
"Bent Rasmussen" <exo@bent-rasmussen.info> wrote in news:cbvk1g$1r9b$1@digitaldaemon.com:

> I hope you're not referring to the quick hack I posted. It was meant to express the *conceptual* problem of returning a null value for a value type -- *not* a practical one. It was mentioned in the context of the ML option type.
> 
> ps. Both links are broken.
> 
> 
You suggested none's for int's but you don't use the term naive in your posts. So no f(l)ame(s) for you, either.


Try these: http://www.digitalmars.com/drn-bin/wwwnews?D/29213 http://www.digitalmars.com/drn-bin/wwwnews?D/23120



Farmer.
July 03, 2004
Regan Heath <regan@netwin.co.nz> wrote in news:opsafmvd1m5a2sq9@digitalmars.com:

[snip]

> Arrays in D act just like reference types (except for the inconsitencies you have shown) even tho they aren't technically, what I want to know is, what effect will changes to those inconsistencies actually have to people who do not need to be able to tell a null array from an empty one?

The impact for code that doesn't need to distinguish between null arrays and
empty arrays depends on
1) the semantic of null arrays regarding the .length property and the opCat
operator.
2) whether null arrays are disallowed by a function interface contract.
3) whether a function should treat null arrays and empty arrays in the
sameway.


Regarding item 1) I assume these semantics:
- Reading and writing of the length property is allowed. Write access to the
length property always returns an array of the given size. So
   nullarray.length=0
turns the null array 'nullarray' into an empty array
- The opCat operators allows null arrays for both arguments. So
   nullarray.opcat(nullarray2)
creates an empty array.


Regarding item 2):
Non-local arrays should be initialized to an empty array.
Local arrays should be initialized to an empty array instead of a null array.

Note that local arrays that are not explicitly initialized are not permitted, anyway (see section 'Local Variables' in function.htm of the D spec). (But as DMD doesn't enforce this, yet, such illegal D code might be quite common.)


As with all reference types that are passed to a function, putting an assertion to check for the disallowed null-case is a good idea.

If the D language permits that different objects that are physically never changed, are allocated only once, then there is almost no performance penalty for using empty arrays instead of null.



Regarding item 3):
Code need the same changed as described for item 2. Additionally any array
parameters must be checked against null and eventually converted to empty
arrays. E.g.
   if (array is null)
      array=new char[0];
Of course, a templated function could do that.

For many "low-level" functions null arrays can be treated as empty arrays, without any additional checks, since the length property can still be accessed. But 'high-level' functions typically have to deal with null arrays explicitly, because they would depend on functions that disallow null-arrays.




Farmer.







July 07, 2004
In article <opsafg63rh5a2sq9@digitalmars.com>, Regan Heath says...
>
>On Wed, 30 Jun 2004 07:27:33 +0000 (UTC), Arcane Jill <Arcane_member@pathlink.com> wrote:
>
>> In article <opsadsu8f75a2sq9@digitalmars.com>, Regan Heath says...
>>
>>> s = p.getValue("foo");
>>> if (s) ..
>>> s = p.getValue("bar");
>>> if (s) ..
>>>
>>> Right...
>>>
>>> If I cannot return null, then (using the code above) I cannot tell the difference between whether foo or bar was passed or had an empty value.
>>
>>
>> And indeed that very situation is ALSO true with integer parameters. How
>> can
>> tell the difference between an integer parameter being present and zero,
>> and no
>> integer parameter being present at all?
>
>Yep. As another poster noted he had the same problem with integers, resulting in him using a value of -1 to represent null. Yuck.
>
>> But of course, there are various solutions to this problem, many much
>> simpler
>> than you propose. For a start, you could return an int* instead of an
>> int, or
>> indeed a char[]* instead of a char[]. Then you could explicitly test for
>> ===null
>> in both cases.
>
>This is the C solution. For int I cannot think of a good D solution. For char[] (or any array) we already have one, the array emulates/acts like a reference type, it's just inconsistent.

The D equivalent might be to return int[] or char[][] y.  Test if the length is zero.  If it's not, then the data is "present".  Otherwise it is missing.

# char[][] result = GetHtmlTag(html_object, "SOME_HTML_FLAG");
#
# if (result.length) {
#     if (result[0].length == 0) {
#         // present but empty
#     } else {
#         // has a nonempty value
#     }
# } else {
#     // not present
# }

For the HTML parsing example given in this thread, this may be even better because sometimes HTML has multiple values with the same tag.

Another data point: I've also used the technique listed below (pair<bool, T>), albeit wrapped in a template class.  The code is very readable.

Kevin

>> In C++, I'd just return a std::pair<bool, T>. I'm sure that once we have
>> a good
>> supply of standard templates in D we'll be able to do much the same
>> thing. (Even
>> without templates, you could define a struct and return it).
>
>You're emulating a reference type, why not just have one. This may be the best soln for int and other strict value types.
>
>> Anything wrong with either of these approaches?
>
>Yep. Neither is as simple, elegant or clean as a reference type, which we already have in D arrays albeit inconsistently.
>
>Regan.
>
>-- 
>Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/


July 09, 2004
Kevin Bealer <Kevin_member@pathlink.com> wrote in news:cci0tl$2dnl$1@digitaldaemon.com:

> In article <opsafg63rh5a2sq9@digitalmars.com>, Regan Heath says...
>>
>>On Wed, 30 Jun 2004 07:27:33 +0000 (UTC), Arcane Jill <Arcane_member@pathlink.com> wrote:
>>
>>> In article <opsadsu8f75a2sq9@digitalmars.com>, Regan Heath says...
>>>
>>>> s = p.getValue("foo");
>>>> if (s) ..
>>>> s = p.getValue("bar");
>>>> if (s) ..
>>>>
>>>> Right...
>>>>
>>>> If I cannot return null, then (using the code above) I cannot tell the difference between whether foo or bar was passed or had an empty value.
>>>
>>>
>>> And indeed that very situation is ALSO true with integer parameters.
>>> How can
>>> tell the difference between an integer parameter being present and
>>> zero, and no
>>> integer parameter being present at all?
>>
>>Yep. As another poster noted he had the same problem with integers, resulting in him using a value of -1 to represent null. Yuck.
>>
>>> But of course, there are various solutions to this problem, many much
>>> simpler
>>> than you propose. For a start, you could return an int* instead of an
>>> int, or
>>> indeed a char[]* instead of a char[]. Then you could explicitly test
>>> for ===null
>>> in both cases.
>>
>>This is the C solution. For int I cannot think of a good D solution. For char[] (or any array) we already have one, the array emulates/acts like a reference type, it's just inconsistent.
> 
> The D equivalent might be to return int[] or char[][] y.  Test if the length is zero.  If it's not, then the data is "present".  Otherwise it is missing.

Disagree. Returning an array for a single value confuses a programmer that
didn't bother to fully read the function's documentation. (Don't blame the
programmer, in most cases the documentation doesn't exist, anyway.)


> # char[][] result = GetHtmlTag(html_object, "SOME_HTML_FLAG");
> #
> # if (result.length) {
> #     if (result[0].length == 0) {
> #         // present but empty
> #     } else {
> #         // has a nonempty value
> #     }
> # } else {
> #     // not present
> # }
> 
> For the HTML parsing example given in this thread, this may be even better because sometimes HTML has multiple values with the same tag.
> 
> Another data point: I've also used the technique listed below (pair<bool, T>), albeit wrapped in a template class.  The code is very readable.

Since the code is very readable, why do you argue that the D-way would be something different, then? [No need to answer this, I already know one good answer.]

What do you mean by 'albeit wrapped in a template class'? Do you wrap 'pair<bool, T>' into your own templated class to provide an  isNull() method?


I like the  pair<bool, T>  solution best. It expresses the meaning of the
returned value precisely and can be generically applied to all types.
Still, in some cases using reference typec (e.g.null-arrays) is a simpler and
faster solution.


Farmer.



> 
> Kevin
> 
>>> In C++, I'd just return a std::pair<bool, T>. I'm sure that once we
>>> have a good
>>> supply of standard templates in D we'll be able to do much the same
>>> thing. (Even
>>> without templates, you could define a struct and return it).
>>
>>You're emulating a reference type, why not just have one. This may be the best soln for int and other strict value types.
>>
>>> Anything wrong with either of these approaches?
>>
>>Yep. Neither is as simple, elegant or clean as a reference type, which we already have in D arrays albeit inconsistently.
>>
>>Regan.
>>
>>-- 
>>Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
> 
> 

1 2 3 4 5 6 7 8 9 10 11
Next ›   Last »