Live data from Hacker News

Linus Torvalds' good taste argument for linked lists, explained

github.com

171–180 of 339 posts

Re: Linus Torvalds' good taste argument for linked lists, explained

#171

I understand the general point (and value) of reframing the problem or the solution in a way that removes special cases ... but in this case I would actually prefer the first solution over the second. The second solutions reminds me of the old-school perl culture, and JavaScript culture, where 'cleverness' (which always manifests itself as terseness as if lines of code were expensive), takes precedence over maintaina…

On the other hand, "clever code" repeated enough times is a "design pattern."

Re: Linus Torvalds' good taste argument for linked lists, explained

#173
post #167

Earlier quoted context omitted.

Yeah that's true, but the problem with your version is it loses the homogeny because an empty list can't simply be a Node, it has to be represented in some other way (as an Option or something), so we're back to square one. Maybe I was wrong and this can't be done perfectly even with union types.

In that case wouldn't you just: struct List { head: Option } struct Node { value: i32, next: Option > }

Yep, but this replicates the original inelegancy (from the article): Option and Option> are not the same type, and so they can't be treated the same way.

Re: Linus Torvalds' good taste argument for linked lists, explained

#174

I'm not sure why the article removed comments from the code and replaced variable names like "indirect" with "p". Here are the two code samples verbatim from Linus's presentation: remove_list_entry(entry) { prev = NULL; walk = head; // Walk the list while (walk != entry) { prev = walk; walk = walk->next; } // Remove the entry by updating the // head or the previous entry if (!prev) head = entry->next; else prev->next…

I'm kinda confused on how this will behave if we want to remove `head`—if `head` is in the stack frame (assuming it's a parameter to `remove_list_entry`), wouldn't `*(&head) = entry->next;` be a no-op as far as the caller is concerned? (Sorry for the n00b question.)

Then you will escape from while((* indirect) != entry) check in the first place and ignore * (&head) = entry->next;.

Re: Linus Torvalds' good taste argument for linked lists, explained

#175

Earlier quoted context omitted.

As the other person said, it's not really about complexity. Complexity isn't all that different here; personally I'd find something like the following to be simpler (I imagine others might disagree): remove_list_entry(entry) { for (p = &head; *p; p = &(*p)->next) { if (*p == entry) { *p = entry->next; break; } } } However, what the choice does objectively impact is performance. Being able to assume the object exists…

Not just an instruction, but a branching instruction. Branch predictors will probably do pretty well on this, but still.

With linked lists, memory latency dominates, since you're chasing pointers all over the heap. I guess the null check costs nothing most of the time. On the other hand, removing random objects from lists that you don't know are actually in those lists is a smell.

Re: Linus Torvalds' good taste argument for linked lists, explained

#176

I'm not sure why the article removed comments from the code and replaced variable names like "indirect" with "p". Here are the two code samples verbatim from Linus's presentation: remove_list_entry(entry) { prev = NULL; walk = head; // Walk the list while (walk != entry) { prev = walk; walk = walk->next; } // Remove the entry by updating the // head or the previous entry if (!prev) head = entry->next; else prev->next…

I'm kinda confused on how this will behave if we want to remove `head`—if `head` is in the stack frame (assuming it's a parameter to `remove_list_entry`), wouldn't `*(&head) = entry->next;` be a no-op as far as the caller is concerned? (Sorry for the n00b question.)

No, this copies the value from next into the memory occupied by head.

For example if the linked list was:

&next: (100, 0xFFFF)

0xFFFF: (101, 0xDEFF)

0XDEFF: (102, 0)

Then calling remove on head would leave us with:

&next: (101, 0xDEFF)

0xFFFF: (101, 0xDEFF)

0XDEFF: (102, 0)

(It would be on the caller to free the memory address 0XFFFF)

Re: Linus Torvalds' good taste argument for linked lists, explained

#177

I'm not sure why the article removed comments from the code and replaced variable names like "indirect" with "p". Here are the two code samples verbatim from Linus's presentation: remove_list_entry(entry) { prev = NULL; walk = head; // Walk the list while (walk != entry) { prev = walk; walk = walk->next; } // Remove the entry by updating the // head or the previous entry if (!prev) head = entry->next; else prev->next…

The author also misunderstands what "head" of a list is, adding more bad clutter to the code. (Granted, the code in the original TED talk is broken, as it doesn't define "head".) A linked list in C isn't a struct with a "head"; "head" is just a pointer pointing to the head element. The OP article should be retracted.

I don't see what you're saying.. the OP added that bit (the IntList struct) himself but it doesn't really change the scenario or take away from what he is trying to explain.

But it should be retracted? Really?

Re: Linus Torvalds' good taste argument for linked lists, explained

#180

I'm not sure why the article removed comments from the code and replaced variable names like "indirect" with "p". Here are the two code samples verbatim from Linus's presentation: remove_list_entry(entry) { prev = NULL; walk = head; // Walk the list while (walk != entry) { prev = walk; walk = walk->next; } // Remove the entry by updating the // head or the previous entry if (!prev) head = entry->next; else prev->next…

This comment seems wrong to me:

      // The "indirect" pointer points to the
      // *address* of the thing we'll update
The "indirect" pointer points to the thing we'll update. See at the bottom, it's updating *indirect, so "indirect" points to the thing being updated. On the other hand, "indirect" points to the address of the thing we'll remove. There's a specific item being removed, and there's a specific thing that will be updated; the thing being updated comes immediately before the thing being removed; they're not the same thing.
Post reply on HN