Live data from Hacker News

What's wrong with this code, really?

cvmountain.com

81–90 of 217 posts

Re: What's wrong with this code, really?

#81

Earlier quoted context omitted.

For the record, the second way is typically better: It is usually more (sometimes much more) efficient to remove from the end of a list/array than to remove from the beginning.

I'm genuinely curious -- why? The last time I coded my own linked-list, it was doubly-linked, so deleting either the head or the tail was exactly the same.

Linked lists aren't used very often in languages that have easy (memory managed, or resizable) access to arrays, unless the specific characteristics of linked lists are desired. Arrays are faster for almost all operations for most collection lengths that come up in human-provided data (i.e. less than 10, almost certainly less than 100 - and in this case, tab pages, very probably only 3 or 4). And on the flipside, if the idiom of the language is to prefer arrays over linked lists, it naturally follows that you tend to want to clear such collections from the end rather than the start.

In terms of performance, another consideration may be important here: invalidation and redrawing of the UI. Controls like tab pages may update the UI for every modification of the tab collection (unless updates have been suspended). Removing from the end will look slightly more pleasant than removal from the start in this case.

Re: What's wrong with this code, really?

#82

That chart of development costs ignores the fact that only successful projects get maintained. Many projects simply get abandoned before they ever gain traction and at that point code quality becomes meaningless.

That's a good point. And if the project consists of mainly bad code, it probably contributes to the project being abandoned, as it gets harder and harder to fix bugs and add new features in a code base like that.

Re: What's wrong with this code, really?

#83
So what's the "correct" way to do this?

Clearing the entire array can usually be accomplished easily, but what if you want to remove only items matching some condition?

Looping backwards, perhaps?

    for ( int i=this.MyControl.TabPages.Count-1 ; i >= 0 ; i-- )
    {
       this.MyControl.TabPages.Remove ( this.MyControl.TabPages[i] );
    }

Re: What's wrong with this code, really?

#84
post #27

About the McConnell quote: "Inefficient programmers tend to experiment randomly until they find a combination that seems to work." The essence of this quote is being passed around quite often these days. When you first start programming, you generally have no idea what the hell you are doing. You learn all these strange, abstract concepts best, by experimenting. It's easy to dismiss people "jiggling things around unt…

I blame JavaSchools for this.

Computing education should be started in Scheme or Python, without all that accidental complexity-- "public static void main(String[] args)"-- littered around the first program. To absorb all of that requires more than should be expected before people can write a first program. JavaSchools get people used to magic incantations that create a culture where inadequate knowledge is the norm.

After learning the essentials, one can move on to languages with powerful type systems (Ocaml, Scala, Haskell) and the discussion of OOP and when it's appropriate and when not.

People should be starting with simple programs and knowing exactly what they do, rather than creating classes without a clue what a class is and why the concept is important (much less where not to use object-oriented programming).

The argument for starting CS in Java is that it makes grads more employable. Frankly, I would never hire (for a programming position) someone who took one CS course and stopped taking more. The whole raison d'etre for starting CS education in Java is bogus, and I think the practice is actually harmful. As much as I hate the factory metaphor in education, let's "produce" 20 programmers who actually understand what they are doing instead of 200 who don't have a clue.

Re: What's wrong with this code, really?

#86

As soon as I saw that snippet I could see what's wrong. In C# / .Net you can't remove an element from an enumerator while you're enumerating through it. You can remove the last element however, as it's the final loop the enumerator isn't used again so it won't throw an error. The original developer probably tried to remove it forward only first, encountered an error and wrote the code to loop through it backwards, us…

I've also found it depressing that you can't remove an element fron an enumerator while you're enumerating through it

Why? I like to think library developers have my back. What's the point in an iterator, it its broken on the 1st thing I try? (Ok the 2nd thing; 1st I code a search through the list, then the teardown)

Iterators are also pretty much broken when 1) inserting into a list, 2) merging a list into a list, 3) deleting an item from a list.

Ok, they're pretty much broken for absolutely everything BUT searching lists.

I remember the profound disappointment I felt when Java 1 came out, and its iterators were this same lame junk.

So I never use them. They are born to create bugs like this one.

Re: What's wrong with this code, really?

#87
post #7

Deleting from a container while you are iterating over it should always raise red flags.

Isn't clear() itself a "while (not empty) delete element"?

A while loop isn't in itself an iterator. There's a difference between

  while(collection.Count > 0) 
  {
   collection.Delete(0);
  }
.. which is a working implementation of clear, though probably superfluous.

and...

  int i = 0;
  while(i 
which does try to walk along the list and is broken.

Also, .Net has a specific exception to stop you modifying a collection while an enumerator is walking along it. Google for "Collection was modified; enumeration operation may not execute"

Re: What's wrong with this code, really?

#88
post #62
post #7

Deleting from a container while you are iterating over it should always raise red flags.

Depends on what you want to accomplish and what your container and iterators support. If your Iterator offers a delete method, I think it's a very elegant and clear way to filter a container. for (Iterator it = container.iterator(); it.hasNext(); ) if (!predicate(it.next())( it.remove(); It's more ugly and error prone if you've got to juggle an index, though.

Even with plain C, you can just iterate backwards:

    for (i = ctr_size(container); i > 0; i--)
        if (!predicate(container, i - 1))
            ctr_remove(container, i - 1);

Re: What's wrong with this code, really?

#89
I find this a lot with HTML guys I work with. They add a few px of padding to the top of something to get it vertically centered on Chrome and then it's broken on IE. Then I tell them to fix IE and then it's broken on Chrome.

Then it's two more hours of screwing around until they get it right. Then I show it to them on a notebook with a different DPI setting...

Re: What's wrong with this code, really?

#90

Earlier quoted context omitted.

I prefer: for (int i=this.MyControl.TabPages.Count - 1; i >= 0; i--) { this.MyControl.TabPages.Remove(this.MyControl.TabPages[i]); } Though a simple while loop is much easier to follow, even if its less efficient than removing the elements in reverse.

Although your point on efficiency stands (at least with data structures that have to reshuffle contents on deletion), the type of loop that you use has nothing to do with the order that you delete the elements. You could easily do something like: while (MyControl.TabPages.Count > 0) { MyControl.TabPages.RemoveAt(MyControl.TabPages.Count-1); } For loop are nothing more than while loops with: (1) an assignment (int i =…

Sure. Though if we're talking about efficiency, I would imagine that counting backwards would be slightly faster than getting the current count each time. Though in reality this depends on way too many factors - I imagine TabPages would be stored in cache and getting the count is just as fast as counting backwards. Micro-optimization and all that.

Regarding for vs while, I find the choice is important only in the intent they emphasize: while puts emphasis on the condition, whereas for puts the emphasis on the iteration. I think in this case the condition (that the list is not empty) is deserves more emphasis than the iteration through the elements of said list - hence why I find the while version to be more readable. YMMV and all that :)

Post reply on HN