JaroslavTulach at 16:22, 5 April 2009 - 2009-04-05 16:22:35

←Older revision Revision as of 16:22, 5 April 2009
Line 6: Line 6:
{{:API has to be Correct}}
{{:API has to be Correct}}
-
== Mercurial vs. Subversion ==
+
{{:Mercurial vs. Subversion}}
-
 
+
-
One side note in the [[Extreme_Advice_Considered_Harmful|chapter 13]] compares behaviour of [[Mercurial]] and [[Subversion]]. A curious reader sent a comment:
+
-
 
+
-
: Page 241: In the scenario described [[Subversion]] behaves the same way as [[Mercurial]],
+
-
: so it would not be possible to checkin changes without first synchronizing against
+
-
: the HEAD revision (assuming checking goes to HEAD). See, for instance,
+
-
: [http://subversion.tigris.org/faq.html Subversion FAQ], question
+
-
: '''I'm trying to commit, but Subversion says my working copy is out of date?''', answer 3.
+
-
 
+
-
Looks like sometimes the '''svn up''' is needed. However not in regular workflow. I've just tried:
+
-
<source lang="bash">
+
-
# create a new file as user A:
+
-
svn co file:///home/jarda/tmp/svn/r/
+
-
echo Hi. >readme.txt
+
-
svn add readme.txt
+
-
svn ci -m "adding readme.txt by user A"
+
-
 
+
-
# create another new file as user B:
+
-
svn co file:///home/jarda/tmp/svn/r/
+
-
echo >b.txt
+
-
svn add b.txt
+
-
svn ci -m "Adding file b.txt from user B"
+
-
 
+
-
# now, as user A change the readme file, without updating
+
-
# e.g. without knowing that there is the b.txt file:
+
-
echo Hello >readme.txt
+
-
svn diff
+
-
svn ci -m "Changing content of file readme.txt as A, without updating to B's latest version"
+
-
</source>
+
-
 
+
-
This is a significant difference between [[Subversion]] and [[Mercurial]]. [[Subversion]] lets the user A integrate changes without knowing what the final state after the integration will be. Seen from rationalistic point of view, this is not ''correct''. [[Mercurial]] would refuse such integration asking the user A to '''svn update''' to latest version of the repository first. This is the correct behaviour. However it is not really [[cluelessness|clueless]] and enormous majority of developers I know is complaining about such [[Mercurial]] restrictions. This is another example of ''correct but complex'' behaviour.
+

JaroslavTulach: /* Mercurial vs. Subversion */ - 2009-04-05 16:19:21

Mercurial vs. Subversion

←Older revision Revision as of 16:19, 5 April 2009
Line 8: Line 8:
== Mercurial vs. Subversion ==
== Mercurial vs. Subversion ==
-
One side note in this chapter compares behaviour of mercurial and subversion. A curious reader sent a comment:
+
One side note in the [[Extreme_Advice_Considered_Harmful|chapter 13]] compares behaviour of [[Mercurial]] and [[Subversion]]. A curious reader sent a comment:
-
: Page 241: In the scenario described Subversion behaves the same way as Mercurial,
+
: Page 241: In the scenario described [[Subversion]] behaves the same way as [[Mercurial]],
: so it would not be possible to checkin changes without first synchronizing against
: so it would not be possible to checkin changes without first synchronizing against
: the HEAD revision (assuming checking goes to HEAD). See, for instance,
: the HEAD revision (assuming checking goes to HEAD). See, for instance,
Line 37: Line 37:
</source>
</source>
-
This is a significant difference between [[Subversion]] and [[Mercurial]]. [[Subversion]] let the user A to integrate changes without knowing what the final state after the integration will be. Seen from rationalistic point of view, this is not ''correct''. [[Mercurial]] would refuse such integration asking the user A to '''svn update''' to latest version of the repository first. This is the correct behaviour. However it is not really [[cluelessness|clueless]] and enormous majority of developers I know is complaining about the [[Mercurial]] restrictions.
+
This is a significant difference between [[Subversion]] and [[Mercurial]]. [[Subversion]] lets the user A integrate changes without knowing what the final state after the integration will be. Seen from rationalistic point of view, this is not ''correct''. [[Mercurial]] would refuse such integration asking the user A to '''svn update''' to latest version of the repository first. This is the correct behaviour. However it is not really [[cluelessness|clueless]] and enormous majority of developers I know is complaining about such [[Mercurial]] restrictions. This is another example of ''correct but complex'' behaviour.

JaroslavTulach at 15:51, 5 April 2009 - 2009-04-05 15:51:49

←Older revision Revision as of 15:51, 5 April 2009
Line 5: Line 5:
{{:API has to be Correct}}
{{:API has to be Correct}}
 +
 +
== Mercurial vs. Subversion ==
 +
 +
One side note in this chapter compares behaviour of mercurial and subversion. A curious reader sent a comment:
 +
 +
: Page 241: In the scenario described Subversion behaves the same way as Mercurial,
 +
: so it would not be possible to checkin changes without first synchronizing against
 +
: the HEAD revision (assuming checking goes to HEAD). See, for instance,
 +
: [http://subversion.tigris.org/faq.html Subversion FAQ], question
 +
: '''I'm trying to commit, but Subversion says my working copy is out of date?''', answer 3.
 +
 +
Looks like sometimes the '''svn up''' is needed. However not in regular workflow. I've just tried:
 +
<source lang="bash">
 +
# create a new file as user A:
 +
svn co file:///home/jarda/tmp/svn/r/
 +
echo Hi. >readme.txt
 +
svn add readme.txt
 +
svn ci -m "adding readme.txt by user A"
 +
 +
# create another new file as user B:
 +
svn co file:///home/jarda/tmp/svn/r/
 +
echo >b.txt
 +
svn add b.txt
 +
svn ci -m "Adding file b.txt from user B"
 +
 +
# now, as user A change the readme file, without updating
 +
# e.g. without knowing that there is the b.txt file:
 +
echo Hello >readme.txt
 +
svn diff
 +
svn ci -m "Changing content of file readme.txt as A, without updating to B's latest version"
 +
</source>
 +
 +
This is a significant difference between [[Subversion]] and [[Mercurial]]. [[Subversion]] let the user A to integrate changes without knowing what the final state after the integration will be. Seen from rationalistic point of view, this is not ''correct''. [[Mercurial]] would refuse such integration asking the user A to '''svn update''' to latest version of the repository first. This is the correct behaviour. However it is not really [[cluelessness|clueless]] and enormous majority of developers I know is complaining about the [[Mercurial]] restrictions.

JaroslavTulach at 15:42, 23 January 2009 - 2009-01-23 15:42:54

←Older revision Revision as of 15:42, 23 January 2009
Line 4: Line 4:
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.
-
=== API has to be Correct: Prehistoric I/O ===
+
{{:API has to be Correct}}
-
 
+
-
One of the advices that can often cause more harm than be useful, is the attempt to make an [[API]] fully correct. Well, nothing about correctness, correct version of an [[API]] is better than incorrect one, in case all other features of those two versions are on par. But often, in the search for correctness one sacrifices simplicity.
+
-
 
+
-
An example of this can be found in [[Java]]'s '''java.io.File'''. Have you ever tried to read a content of a file in [[Java]]? Painful, isn't it? Instead of having a single method to load file's content into a '''String''', one needs to allocate an array, write a loop to populate it and only than convert it into so desired '''String'''. I wrote that code many times, especially as a utility method in a unit test, so I at least know how to do it. However imagine a newcomer, a refugee from [[Perl]], trying to rewrite a single line of such I/O [[Perl]] code to [[Java]]. How can such trivial task be so complex!? Why we cannot have simple methods like:
+
-
 
+
-
<source lang="java">
+
-
File f = new File("config.txt");
+
-
String text = f.asText();
+
-
byte[] arr = f.asBytes();
+
-
for (String line : f.asLines()) {
+
-
...
+
-
}
+
-
</source>
+
-
 
+
-
I explain this unnecessary complexity as a result of an ''extreme search for correctness''. Plus a little bit of ''copy based design''. Reading done in the [[Java]] way almost completely mimics the [[C]] style. E.g. ''malloc'' a bit of memory, read data into it, process them, read additional data, etc. This [[C]] way is known to be correct, never exhaust available memory and be robust even for use in operating systems. As such the designers of the [[Java]] I/O libraries just copied this correct and well-working principle.
+
-
 
+
-
Nobody of its designers considered it too complicated, as they were familiar with it from their [[C]] days. In fact it is not that complex compared to other [[C]] constructs. Just try to concatenate two [[C]] strings and you'll find out how verbose that code is. The [[C]] libraries leave the memory manipulation up to the programmer. However [[Java]] is different, concatenating strings is a matter of single ''+''. Memory is allocated and freed automatically as needed. [[API]] users usually do not need to care. And they like it. As such the [[Java]] I/O [[API]] for reading from a file seems like a relict of [[wikipedia::Stone Age|stone age]]. So complex and hard to use (but correct).
+
-
 
+
-
For a while I was advocating the [[Java]] I/O library to be enhanced with simple reading utility methods. However that takes time. But a few weeks later I realized that we do not need to wait! The [[NetBeans]] project has own ''virtual filesystem'' library and we can add the methods there! Today I started an [[APIReview|API review]] to provide simple I/O reading [[API]] (see issue [http://openide.netbeans.org/issues/show_bug.cgi?id=157362 157362]) in the '''FileObject''' class.
+
-
 
+
-
Users of [[NetBeans]] 7.0 [[API]]s, say farewell to painful reading of files! And please accept my apology for using ''copy based design'' and realizing only recently that our users could benefit from our own simple '''asText()''', '''asBytes()''', and '''asLines''' utility methods.
+

JaroslavTulach: /* API has to be Correct: Prehistory I/O */ - 2009-01-23 15:26:29

API has to be Correct: Prehistory I/O

←Older revision Revision as of 15:26, 23 January 2009
Line 4: Line 4:
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.
-
=== API has to be Correct: Prehistory I/O ===
+
=== API has to be Correct: Prehistoric I/O ===
One of the advices that can often cause more harm than be useful, is the attempt to make an [[API]] fully correct. Well, nothing about correctness, correct version of an [[API]] is better than incorrect one, in case all other features of those two versions are on par. But often, in the search for correctness one sacrifices simplicity.
One of the advices that can often cause more harm than be useful, is the attempt to make an [[API]] fully correct. Well, nothing about correctness, correct version of an [[API]] is better than incorrect one, in case all other features of those two versions are on par. But often, in the search for correctness one sacrifices simplicity.

JaroslavTulach: /* API has to be Correct */ - 2009-01-23 15:26:19

API has to be Correct

←Older revision Revision as of 15:26, 23 January 2009
Line 4: Line 4:
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.
-
=== API has to be Correct ===
+
=== API has to be Correct: Prehistory I/O ===
One of the advices that can often cause more harm than be useful, is the attempt to make an [[API]] fully correct. Well, nothing about correctness, correct version of an [[API]] is better than incorrect one, in case all other features of those two versions are on par. But often, in the search for correctness one sacrifices simplicity.
One of the advices that can often cause more harm than be useful, is the attempt to make an [[API]] fully correct. Well, nothing about correctness, correct version of an [[API]] is better than incorrect one, in case all other features of those two versions are on par. But often, in the search for correctness one sacrifices simplicity.

JaroslavTulach: /* API has to be Correct */ - 2009-01-23 15:21:23

API has to be Correct

←Older revision Revision as of 15:21, 23 January 2009
Line 23: Line 23:
Nobody of its designers considered it too complicated, as they were familiar with it from their [[C]] days. In fact it is not that complex compared to other [[C]] constructs. Just try to concatenate two [[C]] strings and you'll find out how verbose that code is. The [[C]] libraries leave the memory manipulation up to the programmer. However [[Java]] is different, concatenating strings is a matter of single ''+''. Memory is allocated and freed automatically as needed. [[API]] users usually do not need to care. And they like it. As such the [[Java]] I/O [[API]] for reading from a file seems like a relict of [[wikipedia::Stone Age|stone age]]. So complex and hard to use (but correct).
Nobody of its designers considered it too complicated, as they were familiar with it from their [[C]] days. In fact it is not that complex compared to other [[C]] constructs. Just try to concatenate two [[C]] strings and you'll find out how verbose that code is. The [[C]] libraries leave the memory manipulation up to the programmer. However [[Java]] is different, concatenating strings is a matter of single ''+''. Memory is allocated and freed automatically as needed. [[API]] users usually do not need to care. And they like it. As such the [[Java]] I/O [[API]] for reading from a file seems like a relict of [[wikipedia::Stone Age|stone age]]. So complex and hard to use (but correct).
-
For a while I was advocating the [[Java]] I/O library to be enhanced with simple reading utility methods. However that takes time. But a few weeks later I realized that we do not need to wait! The [[NetBeans]] project has own ''virtual filesystem'' library and we can add the methods there! Today I started an [[API Review]] to provide simple I/O reading [[API]] (see issue [http://openide.netbeans.org/issues/show_bug.cgi?id=157362 157362]).
+
For a while I was advocating the [[Java]] I/O library to be enhanced with simple reading utility methods. However that takes time. But a few weeks later I realized that we do not need to wait! The [[NetBeans]] project has own ''virtual filesystem'' library and we can add the methods there! Today I started an [[APIReview|API review]] to provide simple I/O reading [[API]] (see issue [http://openide.netbeans.org/issues/show_bug.cgi?id=157362 157362]) in the '''FileObject''' class.
-
Users of [[NetBeans]] 7.0 [[API]]s, say farewell to painful reading of files! And please accept my apology for using ''copy based design'' and realizing only recently that our users could benefit from our own '''asText()''', '''asBytes()''', and '''asLines''' methods.
+
Users of [[NetBeans]] 7.0 [[API]]s, say farewell to painful reading of files! And please accept my apology for using ''copy based design'' and realizing only recently that our users could benefit from our own simple '''asText()''', '''asBytes()''', and '''asLines''' utility methods.

JaroslavTulach: /* API has to be Correct */ - 2009-01-23 15:18:56

API has to be Correct

←Older revision Revision as of 15:18, 23 January 2009
Line 8: Line 8:
One of the advices that can often cause more harm than be useful, is the attempt to make an [[API]] fully correct. Well, nothing about correctness, correct version of an [[API]] is better than incorrect one, in case all other features of those two versions are on par. But often, in the search for correctness one sacrifices simplicity.
One of the advices that can often cause more harm than be useful, is the attempt to make an [[API]] fully correct. Well, nothing about correctness, correct version of an [[API]] is better than incorrect one, in case all other features of those two versions are on par. But often, in the search for correctness one sacrifices simplicity.
-
An example of this can be seen in [[Java]]'s '''java.io.File'''. Have you ever tried to read a content of a file in [[Java]]? Painful, isn't it? I have when I have to write that code as instead of loading a file content into a '''String''', one needs to allocate an array, write a loop to populate it and only than convert it into so desired string. I wrote that code many times, especially as a utility method in a unit test, so I at least know how to do it. However imagine a newcomer, a refugee from [[Perl]], trying to rewrite a single line of [[Perl]] code to [[Java]]. One needs to allocate the array, understand concept of '''FileInputStream''', etc. How can such trivial task be so complex!? Why we cannot have simple methods like:
+
An example of this can be found in [[Java]]'s '''java.io.File'''. Have you ever tried to read a content of a file in [[Java]]? Painful, isn't it? Instead of having a single method to load file's content into a '''String''', one needs to allocate an array, write a loop to populate it and only than convert it into so desired '''String'''. I wrote that code many times, especially as a utility method in a unit test, so I at least know how to do it. However imagine a newcomer, a refugee from [[Perl]], trying to rewrite a single line of such I/O [[Perl]] code to [[Java]]. How can such trivial task be so complex!? Why we cannot have simple methods like:
<source lang="java">
<source lang="java">
Line 19: Line 19:
</source>
</source>
-
I explanation this unnecessary complexity is as an extreme search for correctness. Plus little bit of ''copy based design''. The way reading is done in [[Java]] is the same as it is in [[C]]. E.g. ''malloc'' a bit of memory, read data into it, process them, read additional data, etc. This [[C]] way is know to be correct, never exhaust available memory and be robust even for design of operating systems. As such the designers of the [[Java]] I/O libraries just copied this correct and well-working principle.
+
I explain this unnecessary complexity as a result of an ''extreme search for correctness''. Plus a little bit of ''copy based design''. Reading done in the [[Java]] way almost completely mimics the [[C]] style. E.g. ''malloc'' a bit of memory, read data into it, process them, read additional data, etc. This [[C]] way is known to be correct, never exhaust available memory and be robust even for use in operating systems. As such the designers of the [[Java]] I/O libraries just copied this correct and well-working principle.
-
Nobody of its designers considered it too complicated, as they were familiar with it from their [[C]] days. In fact it is not that complex compared to other [[C]] constructs. Just try to concatenate two strings and you'll find out how verbose that code is. The [[C]] libraries leave the memory manipulation up to the programmer. However [[Java]] is different, concatenating strings is a matter of single ''+''. Memory is allocated and freed automatically as needed. [[API]] users usually do not need to care. And they like it. As such the [[Java]] I/O [[API]] for reading from a file seems like a relict of [[wikipedia::Stone Age|stone age]]. So complex and hard to use (but correct).
+
Nobody of its designers considered it too complicated, as they were familiar with it from their [[C]] days. In fact it is not that complex compared to other [[C]] constructs. Just try to concatenate two [[C]] strings and you'll find out how verbose that code is. The [[C]] libraries leave the memory manipulation up to the programmer. However [[Java]] is different, concatenating strings is a matter of single ''+''. Memory is allocated and freed automatically as needed. [[API]] users usually do not need to care. And they like it. As such the [[Java]] I/O [[API]] for reading from a file seems like a relict of [[wikipedia::Stone Age|stone age]]. So complex and hard to use (but correct).
-
For a while I was advocating the [[Java]] library to be enhanced with simple reading utility methods. However only few weeks later I realized that in fact, we do not need to wait! The [[NetBeans]] project has own ''virtual filesystem'' library and we can add the methods there! Today I am proud to announce that I started an [[API]] review to do that (see issue [http://openide.netbeans.org/issues/show_bug.cgi?id=157362 157362]).
+
For a while I was advocating the [[Java]] I/O library to be enhanced with simple reading utility methods. However that takes time. But a few weeks later I realized that we do not need to wait! The [[NetBeans]] project has own ''virtual filesystem'' library and we can add the methods there! Today I started an [[API Review]] to provide simple I/O reading [[API]] (see issue [http://openide.netbeans.org/issues/show_bug.cgi?id=157362 157362]).
-
Users of [[NetBeans]] 7.0 [[API]]s, say farewell to painful reading of files! And please accept my apology for using copy based design and realizing only so late that our users might use those '''asText()''', '''asBytes()''', and '''asLines''' methods.
+
Users of [[NetBeans]] 7.0 [[API]]s, say farewell to painful reading of files! And please accept my apology for using ''copy based design'' and realizing only recently that our users could benefit from our own '''asText()''', '''asBytes()''', and '''asLines''' methods.

JaroslavTulach: /* Have You Ever Wondered...? */ - 2009-01-23 14:58:42

Have You Ever Wondered...?

←Older revision Revision as of 14:58, 23 January 2009
Line 3: Line 3:
I've just finished reading the theoretical and practical parts of your book, are you saying me that I have to apply all your advices to be successful? No, not at all.
I've just finished reading the theoretical and practical parts of your book, are you saying me that I have to apply all your advices to be successful? No, not at all.
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.
 +
 +
=== API has to be Correct ===
 +
 +
One of the advices that can often cause more harm than be useful, is the attempt to make an [[API]] fully correct. Well, nothing about correctness, correct version of an [[API]] is better than incorrect one, in case all other features of those two versions are on par. But often, in the search for correctness one sacrifices simplicity.
 +
 +
An example of this can be seen in [[Java]]'s '''java.io.File'''. Have you ever tried to read a content of a file in [[Java]]? Painful, isn't it? I have when I have to write that code as instead of loading a file content into a '''String''', one needs to allocate an array, write a loop to populate it and only than convert it into so desired string. I wrote that code many times, especially as a utility method in a unit test, so I at least know how to do it. However imagine a newcomer, a refugee from [[Perl]], trying to rewrite a single line of [[Perl]] code to [[Java]]. One needs to allocate the array, understand concept of '''FileInputStream''', etc. How can such trivial task be so complex!? Why we cannot have simple methods like:
 +
 +
<source lang="java">
 +
File f = new File("config.txt");
 +
String text = f.asText();
 +
byte[] arr = f.asBytes();
 +
for (String line : f.asLines()) {
 +
...
 +
}
 +
</source>
 +
 +
I explanation this unnecessary complexity is as an extreme search for correctness. Plus little bit of ''copy based design''. The way reading is done in [[Java]] is the same as it is in [[C]]. E.g. ''malloc'' a bit of memory, read data into it, process them, read additional data, etc. This [[C]] way is know to be correct, never exhaust available memory and be robust even for design of operating systems. As such the designers of the [[Java]] I/O libraries just copied this correct and well-working principle.
 +
 +
Nobody of its designers considered it too complicated, as they were familiar with it from their [[C]] days. In fact it is not that complex compared to other [[C]] constructs. Just try to concatenate two strings and you'll find out how verbose that code is. The [[C]] libraries leave the memory manipulation up to the programmer. However [[Java]] is different, concatenating strings is a matter of single ''+''. Memory is allocated and freed automatically as needed. [[API]] users usually do not need to care. And they like it. As such the [[Java]] I/O [[API]] for reading from a file seems like a relict of [[wikipedia::Stone Age|stone age]]. So complex and hard to use (but correct).
 +
 +
For a while I was advocating the [[Java]] library to be enhanced with simple reading utility methods. However only few weeks later I realized that in fact, we do not need to wait! The [[NetBeans]] project has own ''virtual filesystem'' library and we can add the methods there! Today I am proud to announce that I started an [[API]] review to do that (see issue [http://openide.netbeans.org/issues/show_bug.cgi?id=157362 157362]).
 +
 +
Users of [[NetBeans]] 7.0 [[API]]s, say farewell to painful reading of files! And please accept my apology for using copy based design and realizing only so late that our users might use those '''asText()''', '''asBytes()''', and '''asLines''' methods.

JaroslavTulach: /* Have You Ever Wondered...? */ - 2008-08-17 19:42:39

Have You Ever Wondered...?

←Older revision Revision as of 19:42, 17 August 2008
Line 1: Line 1:
== Have You Ever Wondered...? ==
== Have You Ever Wondered...? ==
-
I've just finished the theoretical and practical parts of your book, are you saying me that I have to apply all your advices to be successful? No, not at all.
+
I've just finished reading the theoretical and practical parts of your book, are you saying me that I have to apply all your advices to be successful? No, not at all.
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.
One of the the worst things to do is to follow advice completely, to the extreme. The [[Extreme Advice Considered Harmful|chapter 13]] builds on the [[wikipedia::Considered_harmful|Considered harmful]] phrase and expands it meaning into the world of API Design.