View mode: basic / threaded / horizontal-split · Log in · Help
March 21, 2012
Re: What about putting array.empty in object.d?
On Wednesday, March 21, 2012 15:54:51 Daniel Murphy wrote:
> FWIW, I would rather see `if (array)` translated to `if (array.length)` and
> this become the recomended way to check if an array is empty. Wouldn't that
> remove the dependency on std.array for most of the cases?

The problem with checking whether length == 0 is that it's inefficient for some 
containers, so it's generally good practice to use empty rather than length. 
And while length == 0 is fine for arrays, it promotes bad habits in general, so 
I'm against it and think that code should pretty much always use empty rather 
than length == 0.

if(array)

is a bit different, because you're not specifically checking the length, but

if(container)

doesn't work in the general case, and stuff like

if(array || cond)

doesn't work. So, making

if(array)

be equivalent to

if(array.length != 0)

and

if(!array.empty)

rather than

if(array !is null)

may be a good idea, but it doesn't work in the general case. In the general 
case, you're still going to have to choose between length == 0 and empty, and 
I definitely think that empty is the correct choice, because it promotes good 
habits, whereas length == 0 promotes bad habits. So, there's value in putting 
empty in _object.d regardless of what happens with if.

Now, I find that I use enough other stuff in std.array, that it always gets 
imported anyway, but I don't think that putting empty in _object.d is a bad 
idea.

- Jonathan M Davis
March 21, 2012
Re: What about putting array.empty in object.d?
On Wed, 21 Mar 2012 14:33:58 -0400, Jonathan M Davis <jmdavisProg@gmx.com>  
wrote:

> On Wednesday, March 21, 2012 15:54:51 Daniel Murphy wrote:
>> FWIW, I would rather see `if (array)` translated to `if (array.length)`  
>> and
>> this become the recomended way to check if an array is empty. Wouldn't  
>> that
>> remove the dependency on std.array for most of the cases?
>
> The problem with checking whether length == 0 is that it's inefficient  
> for some
> containers, so it's generally good practice to use empty rather than  
> length.

But we are specifically talking about arrays, not containers in general.   
Containers in general are not defined by the language.

> And while length == 0 is fine for arrays, it promotes bad habits in  
> general, so
> I'm against it and think that code should pretty much always use empty  
> rather
> than length == 0.

I think you may misunderstand the proposal.  if(array) translating to  
if(array.length) is *only* for arrays, not for general types.

I don't see why defining empty in object.d is necessary for things that  
don't involve ranges at all.

Any time you import a container, it's going to import std.range, which  
publicly imports std.array.

Bottom line: if you don't care about ranges, if(array) works just fine  
(checks if length != 0).  If you care about ranges, you are going to be  
importing std.range and therefore std.array, and array.empty works just as  
well.

As an bonus this gets rid of the controversial behavior of if(array)  
translating to if(array.ptr).

-Steve
March 21, 2012
Re: What about putting array.empty in object.d?
"Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message 
news:op.wbjc7au8eav7ka@localhost.localdomain...
>
> I don't see why defining empty in object.d is necessary for things that 
> don't involve ranges at all.
>

But arrays *are* ranges. Or at least they're supposed to be.

> Any time you import a container, it's going to import std.range, which 
> publicly imports std.array.
>

Arrays and AAs *are* containers, but you *don't* import them.

> Bottom line: if you don't care about ranges, if(array) works just fine 
> (checks if length != 0).  If you care about ranges, you are going to be 
> importing std.range and therefore std.array, and array.empty works just as 
> well.
>

Yes, but a better bottom line would be:

If you want to check if something has no elements, use "empty". Period. 
Done.

Why should it even matter whether it's an array vs some other range? Why 
can't checking for empty be standardized and consistent? It's a simple and 
fundamental enough concept.

> As an bonus this gets rid of the controversial behavior of if(array) 
> translating to if(array.ptr).
>

Yea, I'm not *necessarily* opposed to "if(array)" translating to 
"if(array.length != 0)" (athough it would break code that relies on the 
"null vs empty" distinction), but I don't think it's an adequate substitute 
for array's range-style interface being available whenever arrays are 
available (ie, always).
March 21, 2012
Re: What about putting array.empty in object.d?
On Wed, 21 Mar 2012 16:21:21 -0400, Nick Sabalausky <a@a.a> wrote:

> "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message
> news:op.wbjc7au8eav7ka@localhost.localdomain...
>>
>> I don't see why defining empty in object.d is necessary for things that
>> don't involve ranges at all.
>>
>
> But arrays *are* ranges. Or at least they're supposed to be.

They can be.  But the language doesn't define them as ranges, phobos  
does.  In order to use arrays as ranges, I have to import std.range or  
std.array.

>
>> Any time you import a container, it's going to import std.range, which
>> publicly imports std.array.
>>
>
> Arrays and AAs *are* containers, but you *don't* import them.

What I meant is any container that defines ranges.  In other words, any  
time you are going to be using ranges, you import std.range.  Which makes  
array.empty work.

>> Bottom line: if you don't care about ranges, if(array) works just fine
>> (checks if length != 0).  If you care about ranges, you are going to be
>> importing std.range and therefore std.array, and array.empty works just  
>> as
>> well.
>>
>
> Yes, but a better bottom line would be:
>
> If you want to check if something has no elements, use "empty". Period.
> Done.

We have defined range interface requirements.  If we want to define .empty  
for everything other than ranges which can contain things, we can, but  
it's not done already.  If we wanted to do that, then I agree array.empty  
should go into object.d.

>> As an bonus this gets rid of the controversial behavior of if(array)
>> translating to if(array.ptr).
>>
>
> Yea, I'm not *necessarily* opposed to "if(array)" translating to
> "if(array.length != 0)" (athough it would break code that relies on the
> "null vs empty" distinction)

We have discussed ways of introducing this in the least painful way.  I  
think it should happen, no matter what the pain, since it's the least  
obvious choice.

> but I don't think it's an adequate substitute
> for array's range-style interface being available whenever arrays are
> available (ie, always).

This goes a step further, saying all the range-style interfaces for arrays  
should go into object.  I certainly don't agree with that.

-Steve
March 21, 2012
Re: What about putting array.empty in object.d?
On Wed, 21 Mar 2012 16:43:28 -0400, Steven Schveighoffer  
<schveiguy@yahoo.com> wrote:

> On Wed, 21 Mar 2012 16:21:21 -0400, Nick Sabalausky <a@a.a> wrote:
>
>> "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message
>> news:op.wbjc7au8eav7ka@localhost.localdomain...
>>>
>>> As an bonus this gets rid of the controversial behavior of if(array)
>>> translating to if(array.ptr).
>>>
>>
>> Yea, I'm not *necessarily* opposed to "if(array)" translating to
>> "if(array.length != 0)" (athough it would break code that relies on the
>> "null vs empty" distinction)
>
> We have discussed ways of introducing this in the least painful way.  I  
> think it should happen, no matter what the pain, since it's the least  
> obvious choice.

What I mean is the *current behavior* is the least obvious choice :D

-Steve
March 21, 2012
Re: What about putting array.empty in object.d?
On Wednesday, March 21, 2012 10:17:08 Jacob Carlborg wrote:
> On 2012-03-21 09:42, Nick Sabalausky wrote:
> > "Jacob Carlborg"<doob@me.com> wrote in message
> > 
> >> Sure, why not. Do we want an "any" function as well, that is the
> >> opposite?
> > 
> > I think "!array.empty" is plenty sufficient. Besides, there are other good
> > uses of "any" that have been brought up before.
> 
> Actually I was thinking something like "any?" in Ruby:
> 
> http://www.ruby-doc.org/core-1.8.7/Enumerable.html#method-i-any-3F

So, std.algorithm.canFind then? There has been some discussion of renaming it 
to any (or at least the overload that just takes the predicate and the range), 
but canFind gives you the behavior regardless.

- Jonathan M Davis
March 21, 2012
Re: What about putting array.empty in object.d?
On Wednesday, March 21, 2012 15:46:12 Steven Schveighoffer wrote:
> On Wed, 21 Mar 2012 14:33:58 -0400, Jonathan M Davis <jmdavisProg@gmx.com>
> 
> wrote:
> > On Wednesday, March 21, 2012 15:54:51 Daniel Murphy wrote:
> >> FWIW, I would rather see `if (array)` translated to `if (array.length)`
> >> and
> >> this become the recomended way to check if an array is empty. Wouldn't
> >> that
> >> remove the dependency on std.array for most of the cases?
> > 
> > The problem with checking whether length == 0 is that it's inefficient
> > for some
> > containers, so it's generally good practice to use empty rather than
> > length.
> 
> But we are specifically talking about arrays, not containers in general.
> Containers in general are not defined by the language.

I know that. Much point is that length == 0 is a bad thing to do in general, 
because it's ineffecient with some containers. The language itself is pretty 
much irrelevant as far as that goes. As such, I'd argue in pretty much _any_ 
language that using length == 0 instead of empty is _not_ a good habit to be 
in. Doing it with arrays will make it much more likely that you'll end up 
doing it with containers without thinking about it. On the other hand, if 
you're in the habit of _always_ using empty rather than length == 0, then you 
don't have the problem.

> > And while length == 0 is fine for arrays, it promotes bad habits in
> > general, so
> > I'm against it and think that code should pretty much always use empty
> > rather
> > than length == 0.
> 
> I think you may misunderstand the proposal. if(array) translating to
> if(array.length) is *only* for arrays, not for general types.

No. I understand just fine. My point is that doing length == 0 for _any_ type 
of container is bad, because it promotes bad habits and leads to inefficient 
code for containers where it _does_ matter. So, I'd argue that if you should 
always be using empty rather than length == 0 - even with arrays - which 
currently means that you're almost always importing std.array. Having empty in 
object.d certainly isn't necessary, but it mitigates the problem, because then 
you don't have to import it if all you care about is empty.

if(array) is a special case. If we want to change it to translate to 
if(array.length) then fine. That's all tied up in the insanity of an empty 
array and a null array being considered equal. But even if you want to use 
that syntax, it only mitigates the length == 0 vs empty issue for arrays 
rather than eliminating, because it only works directly in if statements and 
the like. The issue of choosing length == 0 vs empty still remains in many 
cases.

And actually, I'd personally shy away from the if(array) syntax regardless 
simply because of the inherent ambiguity. Even if the language clearly defines 
it, I believe that it's the sort of thing that programmers are likely to 
misunderstand - particularly since if(var) checks for null with all of the 
other reference types. Experienced D programmers will know, but since newbies 
probably won't I'd consider it a code smell.

I think that muddling null and empty was D's largest mistake with arrays and 
tend to think that any code that isn't explicit about it is asking for trouble 
if nothing else because the odds aren't low that the programmer did one thing 
when they meant another, because they didn't understand how null and empty 
arrays interact (e.g. arr == null is _always_ a bad sign IMHO).

> I don't see why defining empty in object.d is necessary for things that
> don't involve ranges at all.

It's not necessary, but it would be nice. empty isn't just a range thing. 
Containers in general use it (across many languages whether ranges are 
involved or not), and for the reasons that I've already given, I don't think 
that length == 0 should ever be used in code. So I'd argue that you should 
always be using empty, which means importing std.array all the time if empty 
isn't in object.d, even if you _aren't_ doing range-based operations.

Now, range-based operations are so common that you pretty much have to import 
std.range in most code anyway, so it really isn't all that much of a burden to 
have to import std.array or std.range to get at empty, but putting it in 
object.d definitely provides some benefit.

So, I'm not sure that I care all that much whether std.array.empty gets moved 
to object.d or not, but I'd strongly argue that code should import std.array 
and use it rather than checking length == 0 as long as empty is in std.array 
rather than in object.d. So, if putting empty in object.d promotes the use of 
empty over length == 0, I'm all for it.

- Jonathan M Davis
March 21, 2012
Re: What about putting array.empty in object.d?
On 2012-03-21 21:49, Jonathan M Davis wrote:
> On Wednesday, March 21, 2012 10:17:08 Jacob Carlborg wrote:
>> http://www.ruby-doc.org/core-1.8.7/Enumerable.html#method-i-any-3F
>
> So, std.algorithm.canFind then? There has been some discussion of renaming it
> to any (or at least the overload that just takes the predicate and the range),
> but canFind gives you the behavior regardless.
>
> - Jonathan M Davis

Yes, I didn't see the overload. But the Ruby version has a default 
predicate, that does this:

canFind!("a")([3, 4, 5]);

I'm usually using "any?" to check if an array contains any values.

-- 
/Jacob Carlborg
March 21, 2012
Re: What about putting array.empty in object.d?
On Wed, 21 Mar 2012 22:30:17 +0100, Jacob Carlborg <doob@me.com> wrote:

> On 2012-03-21 21:49, Jonathan M Davis wrote:
>> On Wednesday, March 21, 2012 10:17:08 Jacob Carlborg wrote:
>>> http://www.ruby-doc.org/core-1.8.7/Enumerable.html#method-i-any-3F
>>
>> So, std.algorithm.canFind then? There has been some discussion of  
>> renaming it
>> to any (or at least the overload that just takes the predicate and the  
>> range),
>> but canFind gives you the behavior regardless.
>>
>> - Jonathan M Davis
>
> Yes, I didn't see the overload. But the Ruby version has a default  
> predicate, that does this:
>
> canFind!("a")([3, 4, 5]);
>
> I'm usually using "any?" to check if an array contains any values.
>

I hope you mean canFind!("true")([3, 4, 5]);. canFind!"a" fails for
arrays where all elements are 0.
March 21, 2012
Re: What about putting array.empty in object.d?
"Jonathan M Davis" <jmdavisProg@gmx.com> wrote in message 
news:mailman.985.1332364578.4860.digitalmars-d@puremagic.com...
> I know that. Much point is that length == 0 is a bad thing to do in 
> general,
> because it's ineffecient with some containers. The language itself is 
> pretty
> much irrelevant as far as that goes. As such, I'd argue in pretty much 
> _any_
> language that using length == 0 instead of empty is _not_ a good habit to 
> be
> in. Doing it with arrays will make it much more likely that you'll end up
> doing it with containers without thinking about it. On the other hand, if
> you're in the habit of _always_ using empty rather than length == 0, then 
> you
> don't have the problem.

Yes, .length is inefficient on some containers... but so is indexing.  That 
doesn't mean using indexing on arrays is a bad habit.

If you're writing general code for ranges, you are going to have to use the 
range interface.  But when you're writing code for arrays only, you can take 
advantage of the fact that indexing is O(1), length is O(1), slicing is O(1) 
etc.

I'm not even advocating using arr.length == 0 to check for empty.  Just use 
`if (!arr)`.
1 2 3
Top | Discussion index | About this forum | D home