View mode: basic / threaded / horizontal-split · Log in · Help
July 24, 2005
Re: [Suggestion] Make if(array) illegal.
Regan Heath wrote:

>> What do you mean by can't be null?
> 
> char[] p = null;
> if (p.length == 0) { //does not crash, p itself is never 'null' }

Okay... I obviously don't get D strings because this seems wildly 
counter-intuitive to me. Sure if p CANNOT be null, the line

char[] p = null; // Surely this means: set p to null

should fail to compile or throw an exception or something?

If D strings truly couldn't be null I would expect something like:

// Declare p
// p is initialized to empty (not null - it can never be null)
char[] p;

// Test for empty
// A test for null makes no sense - p can never be null
if (!p) {}

What am I missing?

James McComb
July 24, 2005
Re: [Suggestion] Make if(array) illegal.
On Mon, 25 Jul 2005 08:55:09 +1000, James McComb <ned@jamesmccomb.id.au>  
wrote:
> Regan Heath wrote:
>
>>> What do you mean by can't be null?
>>  char[] p = null;
>> if (p.length == 0) { //does not crash, p itself is never 'null' }
>
> Okay... I obviously don't get D strings because this seems wildly  
> counter-intuitive to me. Sure if p CANNOT be null, the line
>
> char[] p = null; // Surely this means: set p to null
>
> should fail to compile or throw an exception or something?

I understand where you're going with this, the important fact here is that  
though an array reference itself cannot be null it still behaves like any  
other reference set to null(*). eg.

char[] p = null;
if (p is null) { //true }

(*) with the exception that you can de-reference an array that has been  
set to null, eg.

char[] p = null;
if (p.length == 0) { //does not crash }

Try that with another reference type, eg a class with a length member.
Try that with a struct (value type), you'll find you cannot assign null.

The problem is perhaps trying to think of an array as "strictly" a  
reference type or "strictly" a value type. It's not, it's a mix of the  
two, an attempt by Walter (successful IMO) to get the best performance  
possible, passed by reference, stored on the stack, nice syntax, etc.

I believe you should think of arrays as references with special abilities  
like overloaded = and [] operators, for example. If we had the ability to  
define an opEquals for classes I believe we could emulate arrays with  
classes. (I admit, I haven't tried, nor considered it thoughroughly)

That said, you could perhaps equally argue that you should think of them  
as structs which are passed by reference, can be set to null, can be  
compared to null, .. I think of them as references, it makes more sense to  
me.

> If D strings truly couldn't be null I would expect something like:
>
> // Declare p
> // p is initialized to empty (not null - it can never be null)
> char[] p;
>
> // Test for empty
> // A test for null makes no sense - p can never be null
> if (!p) {}

The distinction is perhaps fine: "strings" can be non-existant.  
non-existant is typically represented with null. "array references" cannot  
be null. Yet, arrays can represent non-existant. A contradiction? No,  
those statements are not directly contradictory because:
 - null is not the only way to represent non-existance (beside the point  
in this case)
 - the object (arrays) need not be null in all situations.

In our case point 2 is the relevant one. Arrays are null only when they  
need to be in order to behave like other reference types. Arrays are not  
null when you try to dereference them.

> What am I missing?

Maybe nothing, maybe something, who am I to say. I can only offer my  
opinion above.

Regan
July 24, 2005
Re: [Suggestion] Make if(array) illegal.
Hi,

In article <dc1689$h1q$1@digitaldaemon.com>, James McComb says...
>
>Regan Heath wrote:
>
>>> What do you mean by can't be null?
>> 
>> char[] p = null;
>> if (p.length == 0) { //does not crash, p itself is never 'null' }
>
>Okay... I obviously don't get D strings because this seems wildly 
>counter-intuitive to me. Sure if p CANNOT be null, the line
>
>char[] p = null; // Surely this means: set p to null
>
>should fail to compile or throw an exception or something?

You are right, it is a little counter-intuitive. Then you say array = null you
are sort of talking about the array's pointer, not the reference itself. I
suspect one of two things happens internally:

1) The " = null" is simply ignored by the compiler (for efficiency). So
char[] p = null;
becomes:
char[] p;

2) A *new* reference (null pointer, 0-length) is created, in the style of
function parameters, and assigned. In other words, it does whatever it does when
you pass "null" to a function expecting an array.

>If D strings truly couldn't be null I would expect something like:
>
>// Declare p
>// p is initialized to empty (not null - it can never be null)
>char[] p;
>
>// Test for empty
>// A test for null makes no sense - p can never be null
>if (!p) {}
>
>What am I missing?

That's one of the original points of this thread. I wanted D to outlaw that test
precisely because of the confusion. It didn't make sense to me either. You can
think of "if (!p)" as "if (!p.ptr)". It is _not_ a test for emptiness.
Therefore, I'm against this automatic conversion, for what it's worth.

Cheers,
--AJG.
July 25, 2005
Re: [Suggestion] Make if(array) illegal.
Regan Heath wrote:

> ... the important fact here is 
> that  though an array reference itself cannot be null it still behaves 
> like any  other reference set to null ...
> with the exception that you can de-reference an array that has been  
> set to null ...

Thanks for the examples. I understand what you mean, now.

Considering that these lines are valid:

char[] p = null;
if (p is null) { //true }

...it confused me that you say p cannot be null.

I know what you mean now, though. :)

James McComb
July 25, 2005
Re: [Suggestion] Make if(array) illegal.
On Mon, 25 Jul 2005 11:33:58 +1000, James McComb wrote:

> Regan Heath wrote:
> 
>> ... the important fact here is 
>> that  though an array reference itself cannot be null it still behaves 
>> like any  other reference set to null ...
>> with the exception that you can de-reference an array that has been  
>> set to null ...
> 
> Thanks for the examples. I understand what you mean, now.
> 
> Considering that these lines are valid:
> 
> char[] p = null;
> if (p is null) { //true }
> 
> ...it confused me that you say p cannot be null.
> 
> I know what you mean now, though. :)

These lines are equivalent to ...

 char[] p;
 p.ptr = null;
 p.length = 0;
 if (p.ptr == null or p.length == 0) { //true }

I know Regan talks about an 'array reference' as an abstract concept but I
just find it easier to think of it in terms of how it is actually
implemented, namely a two field struct. To me, I keep thinking of a
'reference' as the address of a pointer - but that's just me ;-)

For example, '&p' returns the address of the array reference (struct) and
you can manipulate it directly (at your peril, of course).

-- 
Derek
Melbourne, Australia
25/07/2005 12:56:21 PM
July 27, 2005
Re: [Suggestion] Make if(array) illegal.
AJG schrieb:
> You are right, it is a little counter-intuitive. Then you say array =
>  null you are sort of talking about the array's pointer, not the 
> reference itself. I suspect one of two things happens internally:

> 2) A *new* reference (null pointer, 0-length) is created, in the 
> style of function parameters, and assigned. In other words, it does 
> whatever it does when you pass "null" to a function expecting an 
> array.

You cannot say "new" because the array (slice) does not have the
reference sematics by itself, and does not get allocated. It is stored
inline - that is, wherever you mention it - on stack, within a class,
etc, as a *value*.

The statement "char[]p = null" declares an array slice on the stack (the
LHS), and at the same time assigns null to its pointer field, and 0 to
its length field.

The slice has a reference semantics with respect to its referred
elements, i.e. you can manipulate the elements directly and the changes 
propagate outside. However, it does not have a reference semantics in 
respect to its fields:

void manipulate(char[] blah) {
	assert(blah.length > 1);
	blah[0] = 'x'; //This change propagates
	blah.length = blah.length-1;
	//Above change does not propagate
	blah[0] = 'y'; //This change propagates
	blah~="z";
	//Above statement decouples completely
	//Now no changes will ever propagate,
	//whatever you do to the poor array!
}

I happen to like the strange semantics, but this is in strong contrast
to a string& or vector<blah>& in C++ or the Java array.

> 1) The " = null" is simply ignored by the compiler (for efficiency). 
> So char[] p = null; becomes: char[] p;

I don't see any special provision for efficiency, just that an array
slice has a default value tuple (null,0), and the same gets assigned to
it by an assignment of null.

-eye
July 27, 2005
Re: [Suggestion] Make if(array) illegal.
In article <dc86pk$2rta$1@digitaldaemon.com>, Ilya Minkov says...
>
>AJG schrieb:
>> You are right, it is a little counter-intuitive. Then you say array =
>>  null you are sort of talking about the array's pointer, not the 
>> reference itself. I suspect one of two things happens internally:
>
>> 2) A *new* reference (null pointer, 0-length) is created, in the 
>> style of function parameters, and assigned. In other words, it does 
>> whatever it does when you pass "null" to a function expecting an 
>> array.
>
>You cannot say "new" because the array (slice) does not have the
>reference sematics by itself, and does not get allocated. It is stored
>inline - that is, wherever you mention it - on stack, within a class,
>etc, as a *value*.

I meant at compile-time, not in the "new int[5]" sense. 

>The slice has a reference semantics with respect to its referred
>elements, i.e. you can manipulate the elements directly and the changes 
>propagate outside. However, it does not have a reference semantics in 
>respect to its fields:

I had been wondering how to define reference semantics for a while, and I think
your definition is spot-on.

>I happen to like the strange semantics, but this is in strong contrast
>to a string& or vector<blah>& in C++ or the Java array.

I don't like the strange array field semantics. I ran into a particularly nasty
length problem a couple of days ago, and life would have been much simpler if
fields worked just like contents.

My solution was to use an array-reference pointer. E.g.

# alias char[] string;
# string original; // = whatever.
# string* trueReference = &original;
# trueReference.length = 5; // This does work properly.

>> 1) The " = null" is simply ignored by the compiler (for efficiency). 
>> So char[] p = null; becomes: char[] p;
>
>I don't see any special provision for efficiency, just that an array
>slice has a default value tuple (null,0), and the same gets assigned to
>it by an assignment of null.

What I meant is that char[] p; is already initialized to null. Doing an
additional = null is redundant and thus eliminating it would be a small
efficiency gain (again, to the compiler, not the runtime).

----

While we are on this topic, is this legal? (and safe?):

# void Foo (string s) {
#     assert(s.length == 3);
#     s[0] = 'F';
#     s[1] = 'o';
#     s[2] = 'o';
# }
#
# void Bar () {
#     string s = "Bar"; // Static data?
#     writefln(s);
#     Foo(s);
#     writefln(s);
# }

I think it should be, for consistency and simplicity, but I don't know about the
safety of it. I don't have DMD handy to test it, either.

Thanks,
--AJG.
Next ›   Last »
3 4 5 6 7
Top | Discussion index | About this forum | D home