Talk:YourLanguageSucks
Contents |
CSS Sucks
- Contrary to your argument given for a lack of transparency, CSS actually does support transparency as of CSS3. This is implemented via the opacity attribute. --Crazy Pothead 23:58, 4 October 2007 (PDT)
- CSS 3 is not an official spec yet and is not supported by all browsers.
- This is not a problem of CSS A71104
- CSS 3 is not an official spec yet and is not supported by all browsers.
Python sucks
- Removed There are strings, and then there are Unicode strings. No justification was given. Python's Unicode strings allow for superior Unicode support than Ruby & PHP, and nothing in Python forces you to use Unicode strings -- you can write an entire application that uses only byte strings and do encoding support the Ruby/PHP way.
- It is not the existence of Unicode strings that is the problem. I would say the bigger problem is that the str strings are used for text at all! Fortunately this is fixed in python 3.0. The sad thing is bytestrings and Unicode strings are not interchangeable. There are very very subtle bugs also, that will kick you hard in the butt, for example b64encode WILL BARF if fed unicode strings AND the 63rd and 64th characters are specified. Just guess which one of these will throw a runtime error: base64.b64decode(u'YQ==', u'+/'), base64.b64decode(u'YQ==', '+/'), base64.b64decode('YQ==', '+/'), base64.b64decode(u'YQ==', u'+/'), base64.b64decode(u'YQ==', u'+/'), base64.b64decode(u'YQ=='), and base64.b64decode('YQ=='). They should all be equivalent, but the first two barf out. As base64 is embedded in text data, the objects might as well be unicode. --Ztane 14:15, 15 July 2011 (PDT)
- Removed The syntax for singleton tuples,
(x,), is confusing, and different from the syntax for singleton lists. Python syntax for tuples uses commas; parenthesis are used to disambiguate when the context requires it (mostly on expressions). For example:
spam = 1, 2, 3 spam = 1, + 2, 3 # spam will be 1, 2, 3 first, second, third = 1, 2, 3 alone = 1,
- Removed:
-1 ** 2 is -1 ???. The unary-operator has lower precedence than**. So-1**2actually means-(1**2).(-1)**2is 1.
- This had popped back on the page. Unary - has never had precedence over ^... not even in my highschool math classes...
- Changed: Added a notice for != and <>
- Removed: there's pow() and **
- well, why did you? isn't that an idiotic duplication? A71104
- Removed: you can do list[1] = x, but you can't do dict['abc'] = 123 (you have to use the unintuitive dict.update({'abc':123}) instead...)
>>> d= {}
>>> d["abc"] = 123
>>> d["abc"]
123
perfectly works
- ...Uh. Well, that's weird. Maybe it wasn't like that in an old version, because I'm sure that didn't work when I tried it ages ago, so I never bothered trying after. But if it worked from the start then I'm just confused. Keiji 09:01, 23 March 2011 (PDT)
Python sucks, but some of these reasons suck worse
Since I am a python fanboy, I'll temporarily recuse myself from editing the python section, and instead make my comments here. I assume that language features that have a greater benefit than cost are not reasons for a language to suck.
- What is bad about having pow() and **? The benefit is straightforward: Having an operator is nice sugar, and the non-operator version allows modular exponentiation (more efficiently than (x**y) % z). Of course it defaults to mod-infinity, which gives it the same semantics as ** in this degenerate case.
- Why is it suckage that you have to implement __len__ to get len() to work? That's also how you get support for other operators and builtins, like __add__, __lt__, __getslice__, __contains__, __abs__, and so on. Whoever wrote this must hate operator overloading in general, which is fine, but the complaint should be changed to "single-dispatch operator overloading and builtin overloading is possible"; it would accurately paint what is going on. Or maybe you're actually sad that builtins are not all operators? Like maybe you'd like len() to be an operator, and then also abs(), and then also 'in'? This is just incoherent.
- I think it's a bit unusual to complain that there are breaking changes from 2 to 3. Isn't that what a major version number change means? But then again, yeah, it sucks, even if it's how every language and every piece of software ought to work.
- Whoever wrote "no tail recursion" doesn't deserve to complain about it, because the thing one might want is tail call _elimination_ (a.k.a. tail call optimization). Tail recursion, that is recursion via a tail call, is a property of functions as-they-are-written, not a property of languages.
--Jholman 23:41, 12 July 2011 (PDT)
PHP
- code must be inserted between
<?phpand?>tags- how can the interpreter know where the html starts and where the php starts without start and end tags? --Alias
- from the caller context --Cesare Di Mauro
- It doesn't need the ?> if the entire file is PHP (in fact, this is preferable). Matt 15:54, 18 June 2009 (UTC)
- how can the interpreter know where the html starts and where the php starts without start and end tags? --Alias
- there's one
is_typefor eachtype:is_int,is_float,is_string, etc. to check for a proper type- so? --Alias
- a single function (or operator) for identity check will be a better solution --Cesare Di Mauro
- so? --Alias
-
++and--cannot be applied to booleans
Object-oriented programming sucks? Perhaps not.
- "Object-oriented programming is an exceptionally bad idea which could only have originated in California." --Edsger Dijkstra.
-
- Well he was dumb. OOP dramatically improves the scalability of programs.
- I agree; remember the "arrogance in computer science is measured in nano-Dijkstra's" thing? A71104
- Suggesting that Dijkstra was dumb, is itself dumb. How many Turing awards have you won? Much of the scalability of OOP comes from adopting Dijkstra's principles of structured programming. Far too many OOP proponents don't seem to realize that many of their techniques come from structured programming. This seems to be because they learned OOP without previously knowing about structured programming, and so they incorrectly think that OOD is the origin of these techniques. Furthermore, Dijkstra's quotes usually need to be understood in the context of where and when they were said. I can't find a reference for where or when he said this. That statement could have easily been made in the early 1970's or even the 1960's. OOP has come a long way since then. One of his famous quotes about BASIC was made in 1975, and made a lot of sense then, but wouldn't be terribly fair in the context of Visual Basic of today. --Bill Davidson
- Dijkstra was brilliant; he was also an asshole. What kind of person makes world-changing contributions to a field and then refuses to use what that field produces? Psychlohexane 08:01, 27 January 2012 (PST)
- Well he was dumb. OOP dramatically improves the scalability of programs.
-
- Object oriented programming has been shown to have no significant difference in productivity than standard procderal programming.
-
- That's actually just not true.
-
- If this "has been shown" then cite the source.
- Done. A71104
- If this "has been shown" then cite the source.
-
C++ sucks? Perhaps not.
The C++ section should be about five times longer than the PHP section. :-) Matt 15:56, 18 June 2009 (UTC)
I think the reasons for why C++ sucks are vague and in some cases debatable. I would like to see more concrete examples.
- C++ doesn't enforce a single paradigm. Neither procedural or object-oriented are enforced resulting in unnecessary complication.
-
- Isn't that a good thing?
-
- None of the languages on this page enforce a single paradigm. How is this problem specific to C++? --Matt Chisholm
- Not true: Java enforces object oriented programming (you can't do procedural programming in Java, there are no functions). A71104
- You absolutely can do procedural programming in Java. Just make all of your methods static. You can even write your entire program in one class. You can be as procedural as you want. Methods that have a return value are really just glorified functions, with the implication that they are attached to an object. However Java's static methods are only attached to a class, not a proper object. Java encourages OOD, but it doesn't really force it. You can write horrible code in Java as easily as with Fortran. -- Bill Davidson
- Not true: Java enforces object oriented programming (you can't do procedural programming in Java, there are no functions). A71104
- None of the languages on this page enforce a single paradigm. How is this problem specific to C++? --Matt Chisholm
-
- It requires a bulky runtime.
-
- That's not true. You don't have to use MFC, and you can program really small programs if you turn off function header generation at the linker.
-
- What does "bulky" mean? C++'s runtime is lightweight compared to every other language on this page. --Matt Chisholm
- You're right, I removed that point. --A71104
- What does "bulky" mean? C++'s runtime is lightweight compared to every other language on this page. --Matt Chisholm
-
- Not practical for low level system development and quickly becomes a mess for user level applications.
-
- That's actually not true. The __asm {} construct allows you to make fairly arbitrary code so long as you tell the compiler to ignore function headers.
- The GNU __asm {} construct is all but practical. Instead, asm blocks using Intel syntax (which can be found on Microsoft compilers) are much better, but if you are programming in C++ you are not supposed to use much assembly, otherwise you are programming in assembly. --A71104
- Exactly: you're not supposed to use __asm/asm constructs that much, so the GNU syntax will not get in your way. About being practical or handy, it's mostly a matter of taste. -- jmc
- The GNU __asm {} construct is all but practical. Instead, asm blocks using Intel syntax (which can be found on Microsoft compilers) are much better, but if you are programming in C++ you are not supposed to use much assembly, otherwise you are programming in assembly. --A71104
- That's actually not true. The __asm {} construct allows you to make fairly arbitrary code so long as you tell the compiler to ignore function headers.
-
- Why is it not practical for low-level system development?
-
- Why does it quickly become a mess for user level applications? --Matt Chisholm
- Because it supports multiple programming paradigms, so a programmer could write object oriented parts and procedural parts, leading to a very heterogeneous and really ugly design, which complicates code maintenance. --A71104
- Why does it quickly become a mess for user level applications? --Matt Chisholm
-
- The standard has no implementation for exception handling and name mangling. This makes cross-compiler object code incompatible.
- Why does the lack of exception handling make cross-compiler object code incompatible? --Matt Chisholm
- Not the lack of exception handling, but the lack of any specification that forces an implementation of exception handling; we are talking about *binary* incompatibility. A71104
- Why does the lack of exception handling make cross-compiler object code incompatible? --Matt Chisholm
- C++ supports 'goto'.
-
- Are we complaining that C++ is too high level or too low level here? Even if it didn't, you could do
-
register int f = *location -
__asm_ volatile ("jmp eax", "a=", f)- Neither of them; we are complaining (as it's widely accepted) that the goto construct brings to really bad designs, and modern languages should just *not* offer such a deadly instrument. A71104
-
- No widely use OS supports the C++ ABI for syscalls.
-
- And why should they? The ABI necessitates an underlying operating system (vtables et. al don't appear by magic ya' know), and if C++ enforced them it would make C++ unable to do low level systems programming. Silly.
-
- An std::string::c_str() call is required to convert an std::string to a char*. From the most powerful language ever we would have all appreciated a goddamn overloaded operator const char* () const.
-
- I think that this is on purpose. Add such an "
operator const char*() const" and the compiler will become confused over the meaning of "str[x]". Is it "str.std::string::operator[](x)" or is it "str.std::string::operator const char*()[x]"? If you desperately need such a thing, just subclassstd::stringand implement your own operator... -- jmc- Keeping both operators would take stupidity to a new level; of course you don't need the [] operator any more when you got the
const char*one! --A71104
- Keeping both operators would take stupidity to a new level; of course you don't need the [] operator any more when you got the
- I think that this is on purpose. Add such an "
-
- There's a moment in every C++ programmer's life where he wonders why, why, switch case fall-through has been invented: it's completely useless, and if you forget a break you introduce a bug silently.
- How is this exactly related to C++? It's a C idiosincrasy, obviously preserved for backwards compatibility with older C code. It's on purpose: if you don't like it, then head for some other language. -- jmc
- You're right, I should correct and just write: "C++ is backward compatible with C." That's a huge sucks. :) --A71104
- How is this exactly related to C++? It's a C idiosincrasy, obviously preserved for backwards compatibility with older C code. It's on purpose: if you don't like it, then head for some other language. -- jmc
- Not to mention a classic: [...]
- Just the same as above, something that should be moved to the "C sucks" section... -- jmc
Java sucks
- The assertion: Nearly everything is wrapped with objects and many things must be buffered, even those things that don't really need to be objects or be buffered
must be adequately explained with examples, because it doesn't make much sense: it is left to the programmer whether to buffer something or not. I think that it should be removed. --A71104
- Exceptions as part of the type system means you have to catch every imaginable exception that might be thrown.
- You could just catch java.lang.Exception and let that same type system gobble up the differences. --G H
- Many standard classes do parameter checking and manually throw unchecked exceptions such as NullPointerException and IllegalArgumentException. No problem; but what are the assertions for, then?
- Assertions are used to test whether assumptions you make about your own code or that of others hold true. This is different from the two mentioned exceptions in that those signal wrong use of code, not wrong code. For example:
- You passed in null as a parameter to a method that clearly states in its documentation that this parameter should not be null. It throws an NPE to signal your wrong use.
- You have an instance field in a class that is not final but should never be null (for example, it must have been set by a container by dependency injection). However, it is. Something isn't doing its work. You catch this abnormality via an assertion.
- You passed in two differently sized arrays as arguments to a method that states the two arrays must be of the same length. It punishes you with an IllegalArgumentException.
- You have a piece of code that uses two arrays which you've created at two different places but that should logically have the same length. You test this with an assert. If it fails, it's clear that your code is faulty or you've made a wrong assumption. --G H
- It's also explained in the official guide: http://docs.oracle.com/javase/1.4.2/docs/guide/lang/assert.html#usage
- catch clauses can contain only one exception, causing a programmer to rewrite the same code N times if he wants to react the same way to N different exceptions.
This is not true as of Java 1.7: http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html I suggest removing this paragraph
- Arrays are objects but don't properly implement .toString() (if you try to print an array, it just prints hash code gibberish) or .equals() (arrays of the same contents don't compare equal, which causes a headache if you try to put arrays into collections)
I agree with .toString(), but I highly doubt that any programmer would expect(or desire) the equal() method to behave like that on arrays. Why would you want to do that? What would you do, when you already have the arrays in the set and then modify one of them? And what if you don't want one of them to disappear? What if those are vectors for the state machine? One of them disappears. Why? Please, remove the second part of the paragraph.
- Enums in Java 1.5 are cool, but to use them you have to prefix the enum type, like MyEnum.SomeValue, because they exist in the enum class's namespace, so they are less convenient than just defining int constants
Then don't use them if you don't like them. Enums as a drawback of a Java? Seriously? Saying that enums are less convenient than integer constants is like saying that writing structured code is less convenient than having one method with thousands of code per program.
- Initialization blocks (both static and non-static) can't throw exceptions
What would that accomplish? See http://stackoverflow.com/questions/2070293/exception-in-static-initialization-block for some explanations on why is that pointless
- No automatic resource cleanup; instead we get have five lines of "allocate; try {...} finally { cleanup; }"
I may not seeing the point in this paragraph. What resources you mean? Orphaned objects? GC is for that. Closing a file? This is very unclear.
- No string join function
It's in the apache commons or you can write those three lines of code yourself. Such trivialities only clutter this list. This should be removed.
- Java has unused keywords, such as goto and const.
I don't see why does it matter. If it's really an issue for some people, then it should be on the bottom of the list.
- There's int types and Integer objects, float types and Float objects. So you can have efficient data types, or object-oriented data types. Wouldn't it be better to make your object-oriented types efficient?
How exactly is Integer inefficient? Is there some language which handles the same "issue" better? If not, the paragraph should be removed.
Ruby sucks
"No real support for arbitrary keyword arguments (key=value pairs in function definitions are positional arguments with default values)"
Not sure what this is supposed to mean. Hashes as the last parameter of a method require no braces:
def foo(options); end; foo(:foo => 'bar', :baz => 'quux')
This requires no order. In 1.9, this can become:
foo(:foo: 'bar', :baz: 'quux')
Matt 15:51, 18 June 2009 (UTC)
XSLT/XPath sucks?
- There is no concept of types whatsoever. Everything is fundamentally a string. This means that even things that are intrinsically typed are treated as strings fundamentally. For example, sorting on the number of child nodes sorts by string order, not numeric order, even though counting is an intrinsically numeric operation.
<xsl:sort select="count(*)"/> <!-- sorts like this: 10, 11, 1, 23, 20, 2, 37, 33, 31, 3, 4, 5, 6, 78, 7, 9 -->
- <xsl:sort> tag has an optional data-type attribute. It's value could be "text" (this is default), "number" or "qname". So if you want to sort numbers you must set this attribute to "number". --Sandh 18:58, 19 June 2011 (PDT)
Python ** comment removed
For instance, in math -2^2 yields 4, while in Python -2**2 yields -4.
I don't know about you, but I've done Further Maths at A-level and Computer Science with Maths at university, and in absolutely every situation where an expression of the form -xy was involved, it means -(xy); parentheses are used explicitly where the (-x)y meaning is desired. Thus, I've removed this "reason" from the Python section. Keiji 09:18, 17 July 2011 (PDT)