Hi,

On 4/21/06, Bram Moolenaar <[EMAIL PROTECTED]> wrote:
>
> Srinath Avadhanula wrote:
>
> > a[M:N] does truncate when N > len(a). However, this still gives an
> > error when len(a) = 0. Can this be changed as well to return just an
> > empty list? I appreciate your changing the previous behavior. It made
> > things a lot simpler... I am presently aiming to release a beta
> > version of vim-latex for vim7 around the same time you release vim7.
> > The code has reduce about 30% (!!!) using the list/dictionaries and
> > expanded functions of vim7.
>
> I think trying to get items from an empty list should produce an error
> message.

I thought a little bit more rigorously about this. This is what I feel:

a[M:N] should _never_ produce errors because returning an empty (or
truncated) list for a[M:N] unambiguously conveys to the programmer that
M > len(a) (or N > len(a)). Note that trying to get a single element
using a[M] _has_ to be an error when M > len(a) because there is no
unambiguous way of conveying to the programmer that M > len(a) without
producing an error. For example, returning an empty list will not work
because we can have an empty list as a legal element of a list.

What I want to get at is that the principle of "do not get in the way"
is best upheld when a[M:N] doesn't produce an error. Basically, when
some information can be conveyed the programmer via a return value, then
producing an error is a needless intrusion.

< IMPORTANT
Can you think of a use-case when returning an empty list will cause the
programmer to do the "wrong thing"?
/>

Moreover as Sean said, if a[M:N] is an error when M > len(a), then
a[M:N] should be an error when N > len(a) for the sake of consistency.
Right now, things are inconsistent and the advantage that the rule
    a[M:N] = a[M:] when N > len(a)
offers is completely lost. One will still have to have an if statement
before every slice operation.

The most common use-case for the slice operation I can think of is:

for item in somelist[M:N]
    " do something
endfor

Having a[M:N] never be an error makes the above work flawlessly. Note
that this and all succeeding examples are for cases when somelist is
created dynamically, so we do not have an apriori idea of how long
somelist is.

Right now I will have to always have:

if len(somelist) > M
    for item in somelist[M:N]
        " do something
    endfor
endif

Infact, if as Georg suggests, a[M:N] is an error in the case when any
number in range(M:N) is > len(a), then this becomes

if len(somelist) > M
    if len(somelist) < N
        smallerlist = somelist[M:]
    else
        smallerlist = somelist[M:N]
    endif
    for item in smallerlist
        " do something
    endfor
endif

Before someone else points it out,

if len(somelist) > M
    for i in range(M, min([N, len(a)-1]))
        let item = somelist[i]
        " do something
    endfor
endif

will work, but it introduces a new variable called i which is used for
nothing else and will persist after the loop. Besides the expression
range(M, min([N, len(a)-1])) is just plain ugly IMHO.

IMHO python does exactly the right thing by not producing errors when
returning a value can unambiguously convey the same information to the
user. This principle has been extended in python to things like
range(0,-1) returning an empty list instead of producing an error like
vim does[1]. Infact, MATLAB which also uses extensive list and matrix
manipulations never produces errors when you use list slicing. I think
that the makers of these languages are onto something.

Thanks,
Srinath

[1] range(M,N) never produces an error in python. Once again, the
    len(range(M,N)) can unambiguously convey information to the
    programmer.

Reply via email to