I would offer that there is no shame in doing something a bit more advanced, as long as there are test cases and documentation proportional to the advanced nature of the technique available.
Linus Torvalds' good taste argument for linked lists, explained
21–30 of 339 posts
Re: Linus Torvalds' good taste argument for linked lists, explained
#22What I do not understand is why one should use an "IntList" struct in the first place? As the explanation of the second method suggests, a List is the same thing as a pointer to its first element, so why not do this?:
typedef struct IntListItem* IntList;
Also, could it be that both methods fail terribly (infinite loops?) when they are given wrong input such as elements not in the list at all?
Re: Linus Torvalds' good taste argument for linked lists, explained
#23I 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…
Re: Linus Torvalds' good taste argument for linked lists, explained
#24I 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…
I totally agree, it’s about proving you’re clever rather than communicating ideas. Maybe for something hard like Linux kernel development this is a good thing but in most cases it just leads to messy code that people can’t understand or follow.
Re: Linus Torvalds' good taste argument for linked lists, explained
#25 IntListItem -> IntListItem -> IntListItem
and then draw the position of the list head: IntList -> IntListItem -> IntListItem -> IntListItem
You can see that the if-branch in the cs101 answer comes because there is a ('virtual') element of the list (the IntList head) that is different from the other elements of the list.If we were to make them the same (C# code):
interface IListItem
{
IntListItem Next {get;set;}
}
class IntListItem : IListItem
{
int Value {get; set;}
IntListItem Next {get; set;}
}
class IntList : IListItem
{
IntListItem Head {get; set;}
IntListItem Next
{
get { return Head; }
set { Head = value; }
}
}
then our cs101 code simplifies itself, folding into a prettier algorithm: void remove_cs102(IntList l, IntListItem target)
{
IListItem p = (IListItem) l;
while (p.Next != target)
{
p = (IListItem) p.Next;
}
p.Next = p.Next.Next;
}
the use of indirect pointers was masking the real issue: some algorithms look better if you add a virtual head (or a virtual tail) to your linked list. Emphasis on look though -- they work almost the same.Re: Linus Torvalds' good taste argument for linked lists, explained
#26I 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…
I think Linus is correct on this one.
Re: Linus Torvalds' good taste argument for linked lists, explained
#27The second version seems more elegant but will scare non-C people away with all those pointers ;-) What I do not understand is why one should use an "IntList" struct in the first place? As the explanation of the second method suggests, a List is the same thing as a pointer to its first element, so why not do this?: typedef struct IntListItem* IntList; Also, could it be that both methods fail terribly (infinite loops?…
You could just say "has undefined behavior unless target is an element of the list".
Whatever your choice though - this is slide code. It should be obvious that it's not production ready.
Re: Linus Torvalds' good taste argument for linked lists, explained
#28I 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…
They are expensive! Your code maintained years in the future, every developer has to potentially read every damn line.
The alternative to "clever" code isn't Java and FactoryFactoryFactories, it's short clear code, which is different from short codegolfed code. The main difference is nicely designed libraries and abstractions.
Re: Linus Torvalds' good taste argument for linked lists, explained
#29So I think the image with the blue boxes is misleading and it should be
->[4->[12->[3->[6->[2->[]]]]]]
It is now obvious that you can always point -> to a different [...]
And as it turns out, that is basically the Cons/Nil view of a list from functional programming or lisp, if you're so inclined. And in those languages you would pattern match on the constructor once and do the tail-recursive call.
Re: Linus Torvalds' good taste argument for linked lists, explained
#30I don't think this is really about taste. It's about "common ground" between programmers. If you've seen and used the second pattern many times before, it becomes part of your vocabulary. You're then able to express yourself more succinctly. It is then obviously a better solution to you.
If you see another programmer use the same pattern, it is common ground between you, and you like it. As long as every or most programmers on the team share the same common ground, you are more effective for using it. If you don't share it, you're less effective.
Everyone here commenting that they like the first solution better probably doesn't share the necessary common ground with Linus.
The big question is: what common grounds should you expect when writing your code?