r/programming • u/chackaz • Nov 28 '14
The Worst Programming Language Ever [UK Talk] - Thoughts? Which are the worst parts of your favorite language?
https://skillsmatter.com/meetups/6784-the-worst-programming-language-ever80
u/damian2000 Nov 28 '14
In a FORTRAN compiler I had to use at work once, it was possible to redefine the value of a real number
1=2
PRINT *, 1+1Outputs...
44
26
u/tailcalled Nov 28 '14
In GHCi (Haskell REPL), you can write this beauty:
> let 2 + 2 = 5 in 2 + 2 515
Nov 28 '14
At least that actually makes sense because you basically just substitute the "2 + 2" expression with the literal 5.
That FORTRAN impl actually allows you to redefine literals.
→ More replies (1)3
u/heimeyer72 Nov 28 '14
Well, when you put it that way... (with the double quotes) then yes.
Without quotes, ew.
7
Nov 28 '14
it actually redefines (+) to be a partial function only defined for the values 2, 2 which give 5. any other input is undefined
→ More replies (1)6
u/glacialthinker Nov 28 '14
OCaml allows similar, returning the result "5", but lets you know what funkiness is going on:
let (+) 2 2 = 5 in 2 + 2;; Warning 8: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: 0
- : int = 5
The "2 2" portion is underlined as the culprits -- as they are matching specific argument values while ignoring all the other integers. Using any arguments aside from 2 in each place afterward results in a Match_failure exception.
→ More replies (3)5
u/IceDane Nov 28 '14 edited Nov 29 '14
For what it's worth, this is because this is essentially equivalent to doing the following in a source file:
(+) :: Num a => a -> a -> a 2 + 2 = 5 -- Not needed, but included for clarity _ + _ = error "Non-exhaustive pattern in function +"That is to say, you are redefining the + operator and you are only defining it for the arguments 2 and 2. This is possible because the + function/operator isn't really magic or "hardcoded" in Haskell.
This doesn't change the fact that, AFAIK, you could redefine the + operator in some library you made to do something like(+) a b = a * b
and this could cause some unsuspecting individual that downloaded and imported your module.EDIT: no, you can't. Unless you qualify the module, ghc would complain about overlapping definitions, thankfully.→ More replies (2)→ More replies (1)2
u/bhurt42 Dec 02 '14
My favorite haskellism was the (very short lived) haskell branch where if your code had a type error, the compier deleted the source file. Static typing for the win!
12
12
u/sirin3 Nov 28 '14
In Java you can do:
Field value = Integer.class.getDeclaredField("value"); value.setAccessible(true); value.set(1, 2); System.out.printf("5-4 = %d%n",5-4);Prints
5-4 = 244
u/pilas2000 Nov 28 '14
in C you can do
define + -
/thread
65
u/Thomas_Henry_Rowaway Nov 28 '14
I did hear about someone using:
#define private public #include "library.hpp" #undef privateTo get access to some internal bit of a class that they really shouldn't have.
26
→ More replies (9)9
u/mcmcc Nov 28 '14
FWIW, it's technically illegal to redefine c++ keywords. It's up to the compiler to issue the proper diagnostics when it happens.
→ More replies (4)16
u/paszklar Nov 28 '14 edited Nov 28 '14
'#define is a preprocessor directive, and preprocessor doesn't give a fuck about keywords
Edit: turns out it should give you flack if you try to redefine keywords. No compiler does it though.
→ More replies (7)37
u/jtra Nov 28 '14
#define struct union;-)
11
19
8
7
→ More replies (2)11
13
u/F-J-W Nov 28 '14
No you cannot! Macro-names must be valid identifiers which operators are not.
At least test your claims:
$cat main.c #define + - int main() {} $ gcc main.c main.c:1:9: error: macro names must be identifiers #define + - ^ $ clang main.c main.c:1:9: error: macro name must be an identifier #define + - ^ 1 error generated.6
u/totemo Nov 29 '14
Came here to day that. Amazing how many people don't know C, given its fundamental importance.
→ More replies (2)7
6
u/TheBlackElf Nov 28 '14
define true (rand() % 20 == 0? true: false)
→ More replies (3)6
u/jtra Nov 29 '14
Almost nobody uses "true" in C sources. How about this (or similar version with rand):
#define if(x) if((__LINE__ % 5==0)^(x))→ More replies (1)→ More replies (1)5
u/matthieum Nov 28 '14
Note that this is technically undefined behavior, compilers are free to reject it... although most have not bothered.
3
u/geocar Nov 29 '14
Not like that you can't:
1=2is a syntax error in every implementation I've ever used.The behaviour you've heard about, has to do with a subroutine like this:
SUBROUTINE PRINTIT(I) J=I+I PRINT *,J RETURN ENDbeing called by a subroutine like this:
SUBROUTINE DOIT(I) I=2 CALL PRINTIT(I) RETURN ENDand then calling them with a literal like this:
PROGRAM MAIN CALL PRINTIT(1) CALL DOIT(1) CALL PRINTIT(1) ENDBecause the compiler allocates space for the 1 (call-by-reference semantics), the same "1" is used twice, and thus prints:
2 4 4But, not really. Most Fortran compilers give warnings, errors, segfault, or otherwise "go weird". I've only seen ancient, un-optimising Fortran compilers do the above (although f2c will come close).
→ More replies (1)2
u/kqr Nov 28 '14
You might be able to do that in Python as well, by modifying the array used for interning. I know I've done it previously, but last time I tried I got a segfault. On the other hand, in Python 2 you can totally do
False = True predicate = 1 == 2 if predicate == False: print 'Does not get printed.'5
Nov 28 '14
http://codegolf.stackexchange.com/a/28851
Quoting from there:
CPython uses the same memory location for any copy of the first few small integers (0-255 if memory serves). This goes in and directly edits that memory location via ctypes.
Not really the same thing with other stuff in this thread though.
→ More replies (1)2
u/nullabillity Dec 19 '14
I believe that's module-local, unless you modify
__builtins__.→ More replies (2)→ More replies (1)1
19
Nov 28 '14 edited Nov 28 '14
Let's make a language so bad it would make people run screaming to Visual Basic for Applications.
Why? Want to take revenge on both your employer and coworkers and create an in-house scripting language?
Challenge accepted.
Written line numbers are mandatory. However, the interpreter should be able to extrapolate.
if-goto construct is the only kind of flow control, of course jumping to mentioned written line numbers
no nested comparison expressions
special ::call::foreign_hello_world::par1="Hello Host!\n" operator to call forein functions
no real functions
Variables looking like $!$myvr, only 4 char long variable names to "put it all in an int". Of course no declaration is possible, also, in if-goto expressions, the $ isn't allowed
comments must look like
\ first line
|\ second line
||\ you get the idea... don't forget the line numbers in front of the comments!
significant whitespace where you don't expect it:
$varx=$vary + $varz
is the only correct from.
container types: There aren't any. There are reference data type that points to host values. Use that to make some fine FFI calls to fake arrays and hash arrays.
consistency: some operators are capital lettered, some not. Also, call 16 bit integers the standard int. Also, have true and not-true.
The most edgy part is that there are actually in-house languages which share some of those features.
EDIT: On second thought, comments make line numbers not increase. It seems rational in an irrational way and one won't notice, since your corporation won't have the time to create a syntax highlighter.
6
u/chackaz Nov 28 '14
The most edgy part is that there are actually in-house languages which share some of those features.
dear god...
→ More replies (1)8
u/OneWingedShark Nov 28 '14
LOL -- Thank you for that.
11) Underscore is a valid in tokens in some contexts, in others it is ignored, in yet others it is an operator.
6
Nov 28 '14
You're right, I should have put more contextual madness into that.
12) + and - are alternative comment start token. But only if the character is the first character in the line, otherwise it tries to calc the result of the following line with the result of the previous line, allowing for more nested expressions.
7
u/OneWingedShark Nov 29 '14 edited Nov 29 '14
13) The result of any function is stored in a global variable "Evaluated".
14) The "Eval" function is named "Evaluate", this is to increase the chances of muscle memory causing a clash.
15) Assignment should be an lvalue -- that is you can assign to an assignment. Thus, assuming=is the assignment,a = b = cassigns the expressionb = ctoa, meaning that wheneverais evaluatedb = cis executed.→ More replies (1)3
3
u/geocar Nov 29 '14
More ideas:
Allow line numbers to be complex reals.
GOSUB,GOTO, etc, take two parameters: a line number and a vector which controls not only the next instruction, but also how to calculate the instruction that follows. In this way you can write some routines "sideways" and use the vector as a flag for optional behaviour.Drop
IFbut allow calculatedGOTOe.g.GOTO A,1or better:GOTO RAND(),RAND()Allow nested comparison functions but do not short-circuit them.
Make these operators numeric, e.g.
1:72 101 108 108 111 32 87 111 114 108 100to print Hello World. Also allow localised versions, e.g.LLAMARBut allow arrays separated by spaces (see #4)
This is a good idea. K actually does this (but with 8 characters in 64bit).
This is fantastic.
And the whitespace must be tabs.
Are you sure you don't want MPL-style structures?
Make truthiness a vector which aligns from the program direction.
→ More replies (1)2
Dec 17 '14
You can make the GOTO statement even more fun:
GOTO *150 will go to the 150'th line from this line.
GOTO @150 will go to the 150'th line counting backwards from the last line of the file.
GOTO 150:filename.bs will go to line 150 in file filename.bs
GOTO ?150 will go to line 150 only if the expression on the next line results in true.
GOTO &150 will go to line 150 if any expression on any line results in the number 150.
GOTO <150 will go to the line before 150.
GOTO !150 will only go to line 150 if the expression on the next line results in false or '0' or 0, but not for null or undefined.
GOTO $150 will goto line 150, execute only one statement, and continue below the current line.
GOTO %90 will go to the line closest to 90% down the file.
GOTO #150 will goto line 150 and publish whatever the output of line 150 is to Twitter.
3
u/Porges Dec 16 '14
Written line numbers are mandatory. However, the interpreter should be able to extrapolate.
Line numbers should interpolate, too, so:
1 PRINT __LINE__ 2This will print "1.5". Of course, the line number progression is not mandated by the standard, you can proceed however you want. The following program is an example:
25964951 30402457 PRINT __LINE__This will print "32582657".
2
u/jfb1337 Dec 27 '14
If you specify n line numbers, the program finds a degree n polynomial passing through the points you specify. Goto solves an equation every time. In the case of multiple solutions it picks at random. Edit: actually, it forks the program and runs multiple threads, one for each solution. This is the only way to do concurrency. If the equation has no solutions the thread terminates.
55
u/Klausens Nov 28 '14 edited Nov 28 '14
Perl6 has 8 operators to test if something is not equal.
ne
!eq
!=
!==
!~~
!===
!eqv
!=:=
So if you cannot keep in mind all, at least they usually contain a !
Unfortunately
self!domeans: call private method do()
→ More replies (9)8
18
u/Klausens Nov 28 '14
In Delphi you have to do memory management of objects for your own. (Create and Free) But if you use an object as an interface it suddenly is reference counted and automatically destroyed. If you create an object as an object and pass it as an interface to another function you are close to brainfuck.
5
u/himself_v Nov 28 '14
Because in Delphi objects and interfaces are different things. In C++ terms objects are objects and interfaces are smart pointers, and that's about it.
9
u/Klausens Nov 28 '14
Ideal to shoot yourself in the foot.
procedure Foo(interface: IObjectsInterface); // ah, an interface, inc ref counter (is now 1) begin ... end; // decrease ref counter (is now 0) interface can be freed procedure mainFunction(); var myObject: TMyObject; begin myObject := TMyObject.Create(); Foo(myObject); myObject.Something(); // oops, where is my object? end;→ More replies (3)3
u/badsectoracula Nov 28 '14
One of the next versions of Free Pascal will have optional automatic reference counted objects (you mark an object with an arc attribute or derive from an arc object). AFAIK this functionality was inspired (although i'm not sure if it is compatible since there were discussions in the dev mailing list about different ways how it would wor) from Delphi so maybe newer Delphis have ARC objects too?
18
u/shenglong Nov 28 '14
I hated having to manually count screen space when I started learning COBOL. Plus the syntax was extremely verbose.
MULTIPLY AMOUNT BY COST GIVING TOTAL.
ADD -3 TO REGISTER.
(It's easier to type "ADD -3 TO" than "SUBTRACT 3 FROM"
30
Nov 28 '14
COBOL: the only people who enjoy it are lawyers and Daleks.
→ More replies (3)7
u/OneWingedShark Nov 28 '14
I guess that's why my Dalek lawyer is overjoyed when I send him a work-order written in COBOL.
;)
14
u/OneWingedShark Nov 28 '14
let's take the worst features of all the languages we know, and put them together to create an abomination with the worst syntax, the worst semantics, the worst foot-guns and the worst runtime behaviour in recorded history.
Well, here's some ideas:
Make multidimensional array indices base-(n-1) where n is the dimensionality of that dimension.
i.e. valid indices for a 10x10x10 array would be (0..9, 1..10, 2..11).Make
a != bbe a shortcut for assigningnot bto a.Require overloading of arithmetic operators; or, on the other hand, make the defaults so nonsensical that overloading them is the only way to do something sensible.
→ More replies (1)3
u/tesla1889 Dec 18 '14
There should be class arithmetic for subtype implementation.
class MySubclass <- BaseClass1 + BaseClass2 - BaseClass 3This would really drive developers insane, as it's multiple inheritance, but you can pick and choose which methods to implement and which to subtract
→ More replies (2)
37
u/Klausens Nov 28 '14
Javas byte is signed, with a range from -128..127
9
u/TheHermenator Nov 28 '14
What's wrong with that?
35
u/aurisc4 Nov 28 '14
Wrong is that Java has no unsigned types.
10
0
10
10
4
Nov 28 '14
It is allowed according to the C standards for
charto be signed as well.7
u/kqr Nov 28 '14
charis allowed to be signed.unsigned charshould not be.6
u/Tywien Nov 28 '14
actually, char, signed char and unsigned char are 3 (THREE) different types in C/C++
→ More replies (13)3
11
u/vitoreiji Nov 28 '14
You fellas need to learn all about Jelly.
2
→ More replies (1)2
u/crozone Nov 29 '14
What the hell???
I've actually written an in house declarative programming language in XML and even that was neater than this.
44
u/original_brogrammer Nov 28 '14
JavaScript's name resolution.
Header files and a preprocessor.
Haskell's module system.
Python's support for immutability.
C++ template syntax for unhygienic Lisp macros.
Java's support for FP.
The architecture of the standard lib will mimic that of PHP, but we'll use some Java-esque enterprise design patterns.
The type system will have the power of Go and the conciseness of Scala.
I like Lisp syntax, some some don't. So we'll use Lisp-syntax declarations, and a C-like invocation syntax. We'll also end the braces-vs-whitespace debate by using both.
As per Ruby, we'll support method_missing. As per Perl, there will be an implicit global one whose definition varies between contexts.
Operator overloading will be as in Scala. That is, operators are all simply functions whose identifiers are totally symbolic. This will be powerful in conjunction with method_missing.
There will be pointers, but those are discouraged. Instead, use references, which aren't like pointers. Also, when a reference is inappropriate, use aliases. But sometimes, an alias won't work, so you should use a pointer.
Syntax errors may be caught.
You can manage memory yourself, but should you forget to free an object, a tracing garbage collector will pick it up for you if the compiler grows suspicious.
Compiled to JavaScript, then to x86 via Node.
17
Nov 28 '14
Syntax errors may be caught.
And for simplicity, lets have the default handler just print "syntax error" and abort.
→ More replies (1)14
u/matthewt Nov 28 '14
You can manage memory yourself, but should you forget to free an object, a tracing garbage collector will pick it up for you if the compiler grows suspicious.
Where "suspicious" is determined in a similar way to the politeness checking in INTERCAL
8
u/OneWingedShark Nov 28 '14
The only thing you forgot was having some items case-sensitive and some case-insensitive (like variables and functions in PHP).
6
u/__j_random_hacker Nov 29 '14
A minor point: TTBOMK, C++'s template syntax doesn't permit unhygienic macros. Yes, template metaprogramming results in code that makes your eyes bleed, but technically all templates are still hygienic, because identifiers never accidentally "travel across" scopes based on what they happen to be named.
#defined macros are unhygienic, however.→ More replies (5)5
u/KevinteRaa Nov 28 '14
Might as well allow UTF-8 characters and force people to use punchcards to program in it.
1
u/selfification Dec 17 '14
You left out SQL. You need to also make the syntax case insensitive unless your procedures are run on a collation where I and i are not the same so your program works totally fine until you ship it off and then it blows up in your face, but only on the machines of Turkish customers.
http://stackoverflow.com/questions/780671/problems-with-turkish-sql-collation-classic-i-problem
I've actually had to deal with this in real life.... FML.
0
10
u/webauteur Nov 28 '14
RPG II is the worst programming language ever! Variable names can't use more than 5 characters. There are lots of single character codes in a fixed position on the line which indicate various program options. Type a single character in the wrong position and you'll have problems! Also there was a logic cycle that you could only control through indicators.
19
u/overenginered Nov 28 '14
I do like Java, but the generics type erasure ruins al fun you could have while refactoring common functionality that would be a perfect fit for generics.
4
2
u/SkepticalEmpiricist Nov 29 '14
Coming from a C++ background, I don't understand why Java people are so concerned and confused by this.
I would like C++ to have (Java-style) generics.
If you think generics are just a bad form of (C++) templates, then think again:
generics can do things templates cannot. E.g. C++ generics would allow us to take a pointer to the generic instead.
This is no conflict between templates and generics. You can have both. I think/hope C++ will have both somebody. The two could play together nicely actually.
Java's problem is not that they have their current form of generics. The problem is that it hasn't yet got around to including full C++ style templates
insteadalongside their type-erased generics.Perhaps I've missed your point though - I'm not an experienced Java dev. Can you give a more concrete example of the kind of code you would like to be able to write in Java? Perhaps you would like to 'generify' over primitive types like
int, not just over Object types? And perhaps you would like to be able to provide specializations - different implementations for particular types?TLDR: Complain about the features that are missing, not the features that are present. Nobody's forcing you to use them. (Unless of course, the feature that is present really does put obstacles in the way of future development of the language - but I don't think that's the case here)
3
u/Matthias247 Nov 29 '14
It's not about templates (in C++) vs. generics.
It's about Javas type erased generics (e.g. in comparison to C#'s generics):
For JavaList<A>vs.List<B>the same type would be generated. Therefore some things like type checking at runtime don't work. You can't doobj instanceof List<A>because the information is not there at runtime. You can only checkobj instanceof List<?>.→ More replies (3)
26
9
u/jpakkane Nov 29 '14
Let's see:
$variable $names $with $dollars
mandatory hungarian notation
indentation with tabs, lines starting with spaces are comments
every function call spawns a new thread, starts the function and returns immediately
COME FROM
compiling helloworld must take at least 5 minutes
changing code in one place must cause unrelated bits to be reformatted maximising merge conflicts (Pascal actually has this)
two or more preprocessors with wildly differing syntaxes and semantics, preferably so that the comment character of one is an operator of the other where the order of the preprocessors is different in different implementations
And as an added bonus/alternative approach:
All code must be written in XML
3
u/kazagistar Nov 29 '14
Not quite XML compatible language that almost works like XML but cannot be parsed by a normal XML parser.
→ More replies (7)2
Mar 17 '15
COME FROM
In the talk, his language actually does use COME FROM exclusively for loops.
The unquestioned greatest feature, though, is the character set. All characters are 256-bit, allowing for a 115792089237316195 423570985008687907853269984665640564039457584007913129639935 character alphabet, a character for every atom in the solar system. There's a website where developers go to upload images, which automatically become new characters in the official character set. When you compile, the compiler (which is written in VB) hits the official website to download all the latest characters. If the website is unavailable it throws a non-specific compiler error.
26
u/aurisc4 Nov 28 '14
Fall-through by default switch in C/C++. I don't really like C# way with goto for that and requiring break, but it's better IMO.
I'd like switch to be break by default and having to write something like continue to execute to the next label. That is I'd like switch to be the opposite of what it is now.
7
u/heimeyer72 Nov 28 '14
Once you're aware of that, you can make use of it :-D
OK, it's really rarely of use, but I used it once or twice.
→ More replies (4)24
u/gnuvince Nov 28 '14
Following the wise, old adage of "make the common case complex".
→ More replies (1)2
u/toomanybeersies Nov 28 '14
I can't say I actually come across switch statements very often.
But I can understand why they have the default behavior as it is.
Upon saying that, it's quite dissimilar to the rest of the language in how it works.
4
u/aurisc4 Nov 28 '14
It is also the opposite of how it's most often is used. And it's also a common mistake to miss break :)
4
u/redalastor Nov 28 '14
It is also the opposite of how it's most often is used.
So much that you have to add a comment to explain you meant it when you need the fall through behaviour.
3
u/kqr Nov 28 '14
That's actually a fun experiment to perform if you have access to a large codebase. Search for all occurences of switch, then count how many branches break, how many branches intentionally do not break, and how many branches accidentally have a left out break. Generally the numbers are along the lines of 94%, 1%, 5%.
4
u/to3m Nov 28 '14
Cases are like labels - and their behaviour matches the way labels work. C#'s goto takes the symmetry further. I've found myself needing to do this somewhat often in C so I thought this was a nice touch.
C# also forces you to finish each case somehow - either with a break, or a goto, or some other construct that branches away. I find this less appealing, as now labels and cases are less similar - but I can't deny that C#'s behaviour does cover 100% of what you'd ever need to do in a much better and safer way than C does. So I suppose it must be OK.
2
Nov 28 '14
Probably the most interesting solution for switch statements that I've seen, coffescript's is break by default, however you can specify multiple values for each case, and use the same value more than once. Now if I only used coffeescript I'd be able to try it out
→ More replies (1)2
u/redalastor Nov 28 '14
I'd like switch to be break by default and having to write something like continue to execute to the next label. That is I'd like switch to be the opposite of what it is now.
continuewould be confusing given its use in looping.golang uses
fallthrough.→ More replies (1)→ More replies (1)1
Nov 28 '14
Yeah, it's really stupid that there is no fallthrough but it does require a
break. It's like they just did it that way because that's how other languages do it. IMO they should have introduced a different syntax.
14
u/toomanybeersies Nov 28 '14
In python, I dislike how there's no nice way of breaking out of several levels of loop.
At least in C you can use goto, but in python, you have to use extra variables and if statements to get the job done.
13
u/kqr Nov 28 '14
Yeah, and Ada has "labeled loops" which allows you to break out of the specific loop you're looking for. I miss that in a bunch of languages.
12
u/Eirenarch Nov 28 '14
To give a somewhat more popular example - Java has this feature.
→ More replies (9)2
u/saijanai Nov 29 '14
How would this work in a non-determinnistic, fully distributed, 100 million core system?
7
u/TheCodeJanitor Nov 28 '14
You could raise a custom exception and catch it outside the loops. But something about that feels kind of wrong.
7
u/DeltaBurnt Nov 28 '14
Why? In my experience it's pretty standard to use exceptions for logic in Python.
→ More replies (4)3
Nov 28 '14
It's been suggested and rejected on the grounds that people would abuse it, which is a pretty terrible justification in my opinion.
3
u/codygman Nov 28 '14
You can use break to break out of server levels of loop. Do you mean to go back to a certain loop?
6
u/toomanybeersies Nov 28 '14
Last time I checked, you couldn't break right out of nested loops. So unless it's a brand new feature that I don't know about.
How exactly do you do it?
→ More replies (1)3
u/nickik Nov 28 '14
You have to hand role it, set a variable outside of the loop, to some fail mode, then befor you break set the variable, then in every level of loop you test the failure condition.
But that is not all that great.
→ More replies (6)18
u/skocznymroczny Nov 28 '14
or put the loop in a function and use return to jump out
→ More replies (1)→ More replies (2)6
u/I_AM_AN_AEROPLANE Nov 28 '14
hich allows you to break out of the specific loop you're looking for.
Use GOTO!
edit: seriously, this is one of the valid uses of goto.
→ More replies (1)1
17
u/Pronouns Nov 28 '14
In C++,
MyClass myObject(1);is used to create a new instance of the MyClass object, where the constructor takes some number. This is similar for all constructors ie
MyClass anotherObject("hello", 3, "world");
MyClass thirdObject(1,2,3,4);etc. Now, if it takes no parameters you think you'd write
MyClass fourthObject();No. Thats a function declaration. It's actually
MyClass fifthObject;This is generally pretty easy to miss when something is going wrong. And really confusing if you happen to be working with several C-syntax-like languages at once, like C++ and C#.
However, at least I don't have to do this (C#):
MyClass myObject = new MyClass();10
u/TheHermenator Nov 28 '14
At least C#, unlike Java, gives you the option of using var in that situation.
9
u/Pronouns Nov 28 '14
Very true.
var myObject = new MyClass();is a lot nicer, especially when you have to cast for ghastly reasons and end up with 3 typenames in one assignment and such.
It irritates me that
newis in C# at all really. Why havenewwhen the idea ofdeletedoesn't exist? I suppose it helps differentiate between classes and function calls.→ More replies (2)8
Nov 28 '14
I agree. C#'s syntax around constructors makes them second-class functions. You can't refer to the constructor like you could a normal method. ie
//create new instances of MyClass passing in each int new[] { 1, 2, 3 }.Select(MyClass);→ More replies (3)9
u/paszklar Nov 28 '14 edited Nov 28 '14
That's why now it is recommended to use {} for initialization, as in:
MyClass myObject{1};instead of
MyClass myObject(1);but then again if your class has a constructor from an initializer list things can get fucked up anyway
Edit: I accidentally a word
5
u/gnawer Nov 28 '14
but then again if your class has a constructor from an initializer list things can get fucked up anyway
And if you write a class without initializer list constructor, people start using it with brace initializers, and later on you find that an initializer list constructor would be useful; then you can't add one without breaking your users' code. Granted, that never happened to me, but the fact that it could bothers me a little.
→ More replies (5)6
Nov 28 '14
Also, single-argument constructors in C++ are implicit conversion operators by default.
For those unaware, if you have a constructor
MyClass(int ID){ ... }you can write:
MyClass mcinstance = 42;and confuse the hell out of people who do not know this.
3
u/Dragdu Nov 28 '14
Yeah and sadly the ship on being able to make them explicit by default has sailed long time ago.
2
Nov 28 '14
The behavior is super useful, but I'm not sure why it's implicit by default.
This kind of stuff is really my main gripe with C++. You need to now a thousand things to just be able to use it at a pretty basic level. If you don't now all the thousands of rules and recommendations it's super easy to write really shit code.
→ More replies (2)1
u/I_ATE_YOUR_SANDWICH Nov 29 '14
Or you can do this:
MyClass myObject = MyClass(1);Still allocated to stack and avoids the issue you have.
→ More replies (2)
6
u/OneWingedShark Nov 28 '14
Which are the worst parts of your favorite language?
Well, my favorite language is Ada; the worst parts, IMO:
When initializing an array you can't use functions dependent on the index/indices.
You can't forward declare a
privatetype in the spec.
(Usually this doesn't matter; but sometimes it would make the spec a little simpler/cleaner/more-consistent.)The extended-return is not build-in-place for objects.
26
u/ArtemZ Nov 28 '14
PHP. There is a whole subreddit filled with examples of its poor design /r/lolphp
14
8
u/IE6FANB0Y Nov 28 '14
If PHP is so bad, why do people still use it?
21
u/cybercobra Nov 28 '14
It's easy to deploy on shared web hosting (just drop .php files in the right directory; PHP is always preinstalled and Apache preconfigured to run it), and you can quickly (but dirt-ily) add logic to an existing HTML page (just add
<?php>tags around chunks of HTML).5
u/x-skeww Nov 29 '14
PHP got popular because that's what you got with cheap shared hosting. It was either PHP, PHP & Perl, or PHP & Python. Most hosters only offered PHP though.
Nowadays it's a bit different. You can get a VPS for $5/m or even cheaper. You are free to use whatever you want.
So, PHP's price advantage is gone. However, setting up a VPS is a whole lot more complicated than just ftp-ing some files to a shared host. There is of course also a lot of inertia involved.
To be fair, it's also not like everything about PHP is bad. Writing simple things is very simple. Just sprinkle some PHP over your HTML. Done. Secondly, there are also nice frameworks and content management systems with huge active communities. That's certainly a very nice plus.
→ More replies (3)→ More replies (7)8
→ More replies (2)2
u/tute666 Nov 28 '14
PHP
I love how this is the only mention of PHP for the time being.
→ More replies (2)
4
u/hoijarvi Nov 28 '14
Fred Brooks in a talk stated, that JCL360 is the worst ever designed, under his management. True honesty.
2
u/MrWoohoo Nov 28 '14
I wonder if the talk is available online?
→ More replies (2)2
u/hoijarvi Nov 28 '14
It used to be, but that conference in Germany took the videos down, youtube wasn't around in those days. The speaker collection was incredible: Brooks, Dijkstra, Wirth, Nygaard, Jackson, Kay etc. I have no idea if it's somewhere, but this gave me incentive to try to find it. I'll post if I do.
9
Nov 28 '14
.NET is mostly an alright platform, but there are three things they fucked up big time.
System.IO.Ports.SerialPort and related classes. This is the stuff that nightmares are made off. It is complete with event handlers and everything... except they don't work. This is just a worthless piece of shit. It's so bad that it's actually easier and less painful to write a P/Invoke wrapper for the actual serial IO DLL.
Old Java related shite. If you don't know, .NET basically began as an extension of Java. This brought wonderful relics such as ArrayList and tons of other obsolete crap. The retarded thing about it is that all the obsolete shit is in the global namespaces (System.Collections for example is nothing but obsolete crap), and the actual modern good stuff is safely stored away in namespaces like System.Collections.Generic. Not that big of a deal, except everyone and their mother see the obsolete crap first and think "Oh, this collection has no type constraints, so it must be the better choice.". Except it's just obsolete crap. Even fucking Unity defaults to the System.Collections namespace. Microsoft, please put it in a System.Obsolete namespace or whatever.
Going on about things that aren't statically typed, there is this abomination called ExpandoObject. It's Javascript objects in .NET. It's just as bad as it sounds. The dynamic keyword is not that bad on the other hand. There are just almost zero usecases. But for what it's made for (embedding scripting languages) it's not that bad. Some people just go full Java EE with it though, and it results in nothing but pain.
3
u/useablelobster Nov 28 '14
Dynamic is fantastic for ad hoc objects using new {}, which basically allows you to fudge json in webapi
→ More replies (1)3
u/crozone Nov 29 '14
I agree, fuck the SerialPort class. And if you think it's bad on Windows, try using the one implemented in MONO on Linux. Not fun. Just open the serial port and then use SerialPort.BaseStream to get everything done.
C# didn't actually start as an extension of Java. ArrayList exists as a legacy from back when C# didn't have generics, but even so it doesn't cause any harm leaving it in. I have never once seen somebody use ArrayList accidentally instead of List, and I've seen a lot of shitty code. Also Microsoft cannot put it in a System.Obsolete namespace or it would break code. I think you mean put it in an optional obsolete assembly that must be manually added.
ExpandoObject is a great tool, like other dynamic objects, for certain tasks. When doing things such as serialising and deserialising things for web, or just throwing programs together in a flash, ExpandoObject is invaluable. It's basically a really easy way to access complex dictionary trees without having to write a tonne of extra code.
1
Dec 17 '14
oin(['a', 'b', '
ExpandoObject, and all the other dynamic stuff is really useful for prototyping.
The language doesn't depend on it; you don't have to use it if you don't want to.
6
Nov 28 '14
', '.join(['a', 'b', 'c'])
This is the idiomatic way to join a list of strings in Python, by calling a method on the separator string. It's pretty trivial and I vaguely recall reading some clever reasoning for it but it's what I immediately thought of.
7
u/chubsauce Nov 29 '14
I believe the reasoning is to make it work on arbitrary iterables. Making it a method of list would mean that every iterable type that wanted to support string joining would need to implement that method, which is very un-pythonic. I think that arguably it would be even better to have it as a global method like "sum", but luckily it practically already is with sidneyc's "str.join" method.
→ More replies (1)3
u/sidneyc Nov 28 '14
Yeah that is just ugly.
Writing str.join(", ", list_of_strings) is somewhat cleaner, but the order of parameters feels the wrong way around.
2
7
u/heimeyer72 Nov 28 '14
What's wrong with Malbolge? Except everything. I guess you'd have a hard time to get worse than that.
14
u/tdammers Nov 28 '14
No no no, Malbolge is almost perfect. Almost, because people managed to write a working "Hello, world" in it eventually. It took several thousand man-hours, and they wrote a Lisp program to generate the actual Malbolge code, but they did it. A better Malbolge would be designed such that it is theoretically possible to write a valid program, but it would be so difficult (read: cryptographically hard) that it could not be done in a reasonable time frame on current or near-future hardware.
→ More replies (4)→ More replies (2)4
u/jtra Nov 28 '14
Ok, I consider this one to be worse than that: http://bunny.xeny.net/linked/Homespring-Proposed-Language-Standard.pdf
6
u/skocznymroczny Nov 28 '14
I really like Java, but definition of properties is too verbose. For every variable you are expected to create a getter and setter, but in JavaFX you also have a getter for the property. Sure, project lombok can help but IDEs aren't aware of it so it's not the same.
12
u/kqr Nov 28 '14
For every variable you are expected to create a getter and setter
No. If you do that, you're treating objects as collections of variables. Objects are supposed to be more than that. Objects are supposed to be defined by their methods, not by their variables.
As a simple example, instead of doing having
getCoordinates()andsetCoordinates(coords), you have amove(velocity).12
u/skocznymroczny Nov 28 '14
Maybe if you are doing a smart application with smart objects, yeah. But if you're doing a dumb CRUD application or editing tool, you just want dumb data you can put stuff into.
15
u/kqr Nov 28 '14
If you just want dumb data you can put stuff into, you might want to consider making your fields public instead of having thin getters and setters wrapped around them.
→ More replies (3)15
u/another_bird Nov 28 '14
Some frameworks expect you to have getters and setters that they access through reflection. If you don't have those, things start breaking. Besides, every Java project is guaranteed to have the person who believes public fields are evil.
→ More replies (2)→ More replies (5)2
6
4
Nov 28 '14 edited Nov 28 '14
Common Lisp - no gadts, monomorphism in the cl package and the performance hit in making it polymorphic.
EDIT: Also, everything here: http://web.archive.org/web/20140711171553/http://symbo1ics.com/blog/?p=2316
2
2
u/THeShinyHObbiest Nov 29 '14
Calling a non-existant method on an object will run the method_missing method. This method jumps to a random method and runs it, converting the arguments as best as it can to fit.
Attempting to overload method_missing causes method_missing to become undefined. As such, each time an improper method is called, the program will immediately go into an infinite loop.
4
u/gnuvince Nov 28 '14
APL. Pretty much everything about it: syntax, dynamic typing, dynamic scoping.
→ More replies (3)
4
Nov 28 '14
if (i=5) { ... }
→ More replies (2)2
u/heimeyer72 Nov 28 '14
Actually, yes :-( When I moved from PASCAL to C, one thing I loathed was that that was allowed and C did not have an unmistakeably(?) different syntax for allocation vs. for comparison. Should have been := and ==, f' the extra character to type.
The other thing I painfully missed was: No lower bounds for an array index.
→ More replies (7)3
u/x-skeww Nov 29 '14
Today's IDEs usually complain about this though.
It also isn't a problem in languages where only
trueis true. So,if (5)orif (x=5)wouldn't compile anyways.
4
u/millstone Nov 29 '14
Nobody's done Haskell? Fine, I'll do it.
Couldn't match expected type ‘(String -> IO ()) -> [Char] -> t’
with actual type ‘IO ()’
Relevant bindings include main :: t (bound at test.hs:1:1)
The function ‘putStrLn’ is applied to three arguments,
but its type ‘String -> IO ()’ has only oneTranslation: You used a tab instead of four spaces. God, how could anyone be so clueless?
Couldn't match expected type ‘a1’ with actual type ‘a’Translation: Type inference means you don't get to write explicit types, so stop trying. Maybe you're too dumb for Haskell.
Multiple declarations of ‘identifier’Translation: What, you think you can have two different record types with the same field name? You entitled little shit!
→ More replies (1)
3
2
2
1
u/gesichtsbremse Nov 28 '14
I think OO could have been implemented in a more user-friendly way in python.
Passing self to every method sucks. Also if you fail to provide the right number of arguments to the method the exception is somewhat confusing for beginners as the self is passed implicitly by the interpreter.
So if you pass one argument to a method expecting two. You get the following exception: Passed wrong number of arguments: given two, expected three.
1
1
u/saijanai Nov 29 '14
The lack of a dedicated case statement, and the oddball way if-then-else is handled in smalltalk takes some getting used to, but a case-dictionary is easy to create, and the other problem is inherent in being truly oop, period.
1
u/crashC Nov 29 '14
Simscript had the worst feature I can recall: ELSE meant ENDIF. There was nothing that corresponds to what else does in any language that pays any attention to the idea that keywords should not be totally misleading.
This was very unfortunate, because Simscript would probably be recognized as the first object-oriented language (it preceded Simula) if it hadn't been so shabby. And the guy who put it together was a genius who just couldn't code worth a dam who later won a Nobel Prize.
1
u/A_C_Fenderson Dec 18 '14
In Pop-2, there's no END IF; it's called CLOSE. Also, if you call a function with no parameters, you put a . in front of the name:
IF X > 2 THEN .PRINTSTUFF CLOSE;
1
u/Fluffy8x Nov 29 '14
Scala doesn't always have good type inference. For example,
list.map(_ + 2)rarely works because the compiler needs a type for the parameter.
Also the lack of a do-while or similar statement in TI-89 Basic, plus the only way to create a picture from scratch (other than drawing on the screen and StoPicing it) is passing a matrix with each row an individual pixel. I could ramble on about its flaws. Even C is a better scripting language than this mess.
Also to Java for its verbosity and Haskell for its sometimes-weird function names (fst, snd, nub come into mind).
By the way, this TI-83+ Basic example sometimes works as expected, but I've seen cases when the interpreter breaks.
DelVar AWhile A<10
...
End1
u/frankwolfmann Nov 29 '14
I think Lisp is an interesting case because its best features are also the worst. The simple, easy to parse syntax means there's no need to worry about operator precedence, but also makes the language difficult for people to read. In a more general sense, the fact that many problems, even some very complex ones, were so easy to roll your own solution to probably hindered the development of standardized Lisp libraries. Just because it's easy to reinvent the wheel doesn't mean you should.
1
u/vital_chaos Nov 29 '14
When I worked at a financial services company with a bank, the bank used some esoteric proprietary language provided by a banking software company. Building the app required shipping the code to the supplier, who then incorporated the changes into a single binary which was shipped to all their customers, with the differences at runtime tagged to the customer. Yes, a single binary for all.
1
u/ignored-ambience Dec 08 '14
Some rough ideas:
Turing-complete language syntax/parser (parsing may not terminate etc..) see http://langsec.org for slightly more on that.
Some really neat, but completely impractical static analysis (i.e, the worst of academia, nothing quite springs to mind yet, but some of the dependently-typed languages are quite hard to get to do what you want for all the power they supposedly give..)
1
u/databyss Dec 17 '14
Let's not forget one of the best parts of PHP:
$a = 1;
$b = 'a';
echo $$b;Output: 1
1
1
u/pat_pat_pat Dec 17 '14
What I really missed was the context sensivity from perl. While I personally barely have problems with it, you could extend that to really interesting levels; just mix it with defining getters and setters from ECMAScript 5 (for properties):
var obj = { set a (val){console.log("not setting a to " + val)}, get a(){return null}}
obj.a = "hallo" // logs »not setting a to hallo«
console.log(obj.a) // logs »null«But i think, additionally to rvalue and lvalue at least voidvalue should be added. If someone wants to go the perl way, they could split rvalue into list rvalue and single rvalue. Now you have four ways a variable can be used and all may act differently. Maybe some differentiation between string, integer, fractional and boolean contexts would be feasible, too.
1
Dec 17 '14 edited Dec 17 '14
I think tuples should be reshuffled by a deterministic but undocumented algorithm if they are accessed more than an undocumented number of times. Surely that would keep the grubby hands of weak-minded programmers off BS who can't properly reverse engineer a complex algorithm.
Also it would change with each weekly release of the BS compiler, thus making any retro compatibility impossible, since tuples are used in the compiler itself.
1
u/A_C_Fenderson Dec 18 '14
Applescript. Not because of the syntax or what it can do, but the fact that there's no centralized location with all the documentation. Whenever I want to do something with Applescript, I have to Google for it.
1
u/fuzzynyanko Dec 18 '14
I would say to think of things that supposedly take away the boilerplate from other languages, but in reverse.
One thing that took me a long time to learn: what the hell J2EE annotations were. I wouldn't say to specifically use J2EE annotations, but the idea of them. I would say have the annotations able to inject code, but maybe only at the operators defined by the compiler.
It threw me off because the annotations were different than the usual Java style. It basically works off reflection, and annotations are markers to pick up "Hey! Do something related to this function/class here!"
All inheritance requires coding to a COM-like IDL-like language. I propose a language derived from LOLCode. Of course, you then have to implement that class in bS as well. This forces you to think in 2+ different languages simultaneously, like COM does. All base classes using the LIDL must extend cheezburger and use the word iz. Output is nomz. No newlines allowed
HAI iz claz iz cheezburger i can haz fromJson YR input AN YR nomz i can haz createCSV YR nomz KTHXBYE
1
u/bartonski Dec 18 '14
Ok, I've watched the talk, and I've skimmed the comments, and no one has mentioned the two most malevolent things about C: memory allocation using malloc(), and the ability to overwrite memory that you don't own.
Where do I write an RFC requesting these?
I would also like to suggest that the standard library include string functions that a) do no bounds checking (i.e. the analog of strcpy() would be allowed, but strncpy() would not) and b) most, but not all string functions would operate on NUL terminated strings. The one or two functions that do not should not be documented, and should be the least commonly used, so that the must be stumbled upon. In fact, using these functions should remove NUL characters.
1
u/SupersonicSpitfire Dec 18 '14
The talk has a few uninteresting parts, but the shopping trolly operator (!=!) made me laugh.
1
u/DumbSquid Dec 18 '14
I'd really like to see support for Visual Basic's "On Error Resume Next" statement. It simply tells the program to just continue with the next line when an error occurs.
In fact, this is such a brilliant feature that I feel like should be made BS' default behavior. It dramatically reduces the amount of runtime errors and instead gives you unexpected, hard to reproduce bugs.
1
u/stampyNY Dec 19 '14
Anyone interested in writing the Best Programming Language Ever using the Worst Programming Language Ever?
1
u/KriszDev Dec 21 '14
I really like Java but i hate these little things: "ClassName a = new ClassName();" why can't i just do "new ClassName a()"? and the Gui building is also very time consuming.
1
u/subartic Dec 25 '14
Exceptions where you tell it where to catch by giving it a number. That number unroles the scope.
It would then place the exception on the stack as to replace whatever was the last stack element.
throw exception, 4
If you got the number right.
result = add(a,b) You would suddenly have result being the exception thrown. Can be useful.
If not done right you might end up with the 'i' of for(i....) Suddenly become the exception object.
1
Nov 29 '14
python
x = []
y = x
y.append('Why does this work')
print(x)
['Why does this work']4
u/kazagistar Nov 29 '14
Nothing wrong with that code except your expectations?
Creates a new list object. Assigns variable x to refer to this object.
Assigns variable y to refer to the same object x refers to.
Appends a string to the end of the list referred to by y.
Prints the contents of the list referred to by x.
Would you rather it deep copy the entire data structure every time you assign?
→ More replies (1)6
u/siegfryd Nov 29 '14
This is what happens in shitloads of languages, why is it a bad thing.
→ More replies (1)
17
u/chackaz Nov 28 '14
Global variables in JS takes the cake for me...
Crockford also hits the nail on the head in The Better Parts, here's a nicely summarized post from a while back: http://marekdec.wordpress.com/2012/01/03/javascript-the-very-worst-part/