Ask Slashdot: What Are the Strangest Features of Various Programming Languages?
itwbennett writes: Every programming language has its own unique quirks, such as weird syntax, unusual functionality or non-standard implementations -- things that can cause developers new to the language, or even seasoned pros, to scratch their heads in wonder (or throw their hands up in despair). Phil Johnson has rounded up some of the strangest — from the + operator in JavaScript to the trigraphs in C and C++ and indentation level in Python. What programming language oddities cause you the most grief?"
-eq as the equality operator in Powershell is pretty odd.
Posting a slideshow on Slashdot? Lame. What, was Buzzfeed not available?
It's outdated database security models that cause me the most grief. I don't want jsmith logging in from gatech.edu to be considered a DIFFERENT HUMAN BEING that jsmith logging in from whitehouse.gov. I want to say, there's ONE PERSON, John Smith, username jsmith, who is allowed to login from BOTH domains with the SAME PASSWORD and GRANTS. Nope. Can't do it. Newer versions MIGHT allow you to swap in your own authentication module instead, but NOT the authorization piece, so I'm still screwed!
"Love heals scars love left." -- Henry Rollins
I envision an add filled slideshow with almost no content, and what content is there to be boring and well known so I’ll skip the article.
To answer the question, most of perl seems to be built around bizarre unintuitive constructs that you just have to kinda know about, so pointing out any of that would seem unfair.
In C, the first time I saw the size of elements of a struct specified (i.e. int something : 3) it threw me (and that’s a hard problem to google). It was being used to essentially overlay a struct onto a chunk of memory being received via an interface and extract values, which was actually kinda a cool use of the feature (though a comment woulda been nice unknown dev!).
Some of the type erasure mechanics of Java can be a bit confusing the first time you hit up against them.
The way javascript does dates, and timezones
I dunno, most languages have their weird bits, but I can’t think of anything that is egregiously terrible.
As far as tools, I'd say pacman (Arch's package manager) and git (yes, I'm an SVN fanboy) have the highest concentration of "the hell were they smoking" flags and usage instructions. Pacman seemed to pick it's arguments randomly, and git seems to go straight off the deep end if you want to do anything non-trivial.
Lua's standard is, for things like arrays, to start counting from 1. The unlearning of old habits made this a hard adjustment.
Requiring a graphics card and special character set to program in the language:
Because of the unusual character set, many programmers use special keyboards with APL keytops for authoring APL code. Although there are various ways to write APL code using only ASCII characters, in practice, it is almost never done.
http://en.wikipedia.org/wiki/APL_%28programming_language%29
Since this operator exists in C/C++, Java and Perl at least, it's hardly obscure
I used to think that Perl's feature of "There's More Than One Way To Do It" was great until I had to start modifying and maintaining the code of other developers, (several over the years). 20+ years I've been with Perl and I gotta say that through the years this has probably caused me more frustration than anything. Python, comparatively speaking, is a dominatrix and I'm starting to enjoy "There's Only One Way To Do It".
The "var" in C# is not a variant. It's simply a syntactic shortcut to allow the developer to not repeat the type in the declaration if the type can be inferred from the initialization expression. The behavior is identical to C++ "auto".
var x = 1; // x is an int // compiler error, x is an int and cannot be set to a string
x = "1";
var y; // compiler error, the type cannot be inferred // compiler error, the type cannot be inferred
var y = null;
Namely, the >> symbol. Because templates use angle brackets for template parameters, if you had a nested template such as T<int, T1<double> >, you HAD to put the space between the two closing angle brackets. Otherwise the lexer would interpret the two angle brackets as the shift operator.
General Relativity: Space-time tells matter where to go; Matter tells space-time what shape to be.
That pesky ";" statement terminator... I guess you had to uses something, but it causes me the most trouble..
C, C++, Pascal, Perl, Java, C#, bash/sh, ksh, JavaScript..... The list goes on..
"File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
I can tell you why C# has it.
The normal way intellisense works, you often have to do the end of your line of code then go back to the beginning to type out what type of variable the method you're calling returns now that you know. Var obviates this task by going "oh, of course, it's the type returned by this method".
As usual with language features, it comes from us developers being very very very lazy people.
I realize that but its seems a waste. My point was that you should already know your data types. I like the readability of strongly typed code. You also make you compiler and debugger work extra. On small stuff no big deal. But on large projects those extra compiling seconds can become minutes easily. Also I've had a few cases where when I've done compares on C# compiled code the strongly typed program usually came out smaller.
You say things that offend me and I can deal with it. Can you?
How is that a language quirk for JavaScript? The + operator has been used for string concatenation in a number of programming languages (C++, Java, Python...) long before JavaScript. It is still implemented as such in newer programming languages like C#.
Goodbye Slashdot. You've changed.
I started with Ruby about 1 year ago. And until now, work with strings and the symbols is not natural yet to me. I mean, most of the languages I handled until now have only strings.
PHP's list of oddities is never-ending. From "catchable fatal error" to "unexpected T_PAAMAYIM_NEKUDOTAYIM".
There are some nice collections at http://eev.ee/blog/2012/04/09/... http://phpmanualmasterpieces.t... and http://www.phpwtf.org/
Many of us have read the PHP is a fractal of bad design article and a commonly cited rebuttal. I tried to reconcile the two and ended up with about a half dozen legit complaints.
Heh, all of Intercal is strange.... but COMEFROM is just.... elegant.
It's been implemented for Python, of all things.....
See: https://en.wikipedia.org/wiki/...
Assigning a number or a list in Python and many other languages (Julia) is a different operation. Such as
>>> a = 2
>>> b = a
>>> a = 1
>>> b
2
>>> a = [2]
>>> b = a
>>> a[0] = 1
>>> b
[1]
Octave (Matlab) is more consistent on this point, every assignement is a memory copy.
False and True are variables and you can assign one to the other. False = True print False Not that anyone sane would do this in real code, but the thought is still scary.
use whitespace. Be warned, several problems have been reported when posting source code to the internet.
Odd integers are true; even integers are false.
Arrays can be indexed with () or []. This leads to namespace problems with functions which are also called with (). For example:
x=a(1,2)
error: undefined variable a.
If you want to call function a, you have to forward declare it for this reason.
There's a different syntax for procedures (which don't have a return value) and functions (which do).
It is required to assign the result of a function to something. You have to write
dummy = foo(1,2,3)
as writing
foo(1,2,3)
will give an error.
Most of the time, a single element array is treated the same as a scalar. But not always, and not being very careful will lead to weird errors.
There are no zero length arrays.
An array can be length 1; a multidimensional array can be length [1,2,2], but a multidimensional array cannot be length [2,1,1]. If the last dimension has length 1, it simply vanishes to a smaller dimension, unless already 1 dimensional. Example:
a = make_array(1,2,2)
; a has dimensions [1,2,2]
a = make_array(2,1,1)
; a has dimensions [2]
This means special code must be written to handle any array operations that might end with last dimension 1.
Array slices are weird.
b = a[3,*,2]
means to take a slice of a along the second dimension. I'd expect the answer to be 1 dimensional, since there's only 1 scan in the slice. But the result has dimensions [1,3]
On the other hand, a[3,2,*] has dimensions [1,1,3], and a[*,3,2] has dimensions [3]. It makes sense in a convoluted way, but it sucks.
Ok, someone has to mention lisp.
Item from 15 or so years ago: a guy posted online that he'd broken into the Pentagon's computers, and found the code for SDI, and it was written in lisp. He didn't want to break US security, but he did post the last five lines of the code.... (stupid slashdot edit filter - 5 lines of ) was not junk... at least, not in lisp....)
mark
http://stackoverflow.com/quest...
That's a list of very strange language features. Unsurprisingly, Javascript makes many, many appearances.
-- "So they told me that using the download page to download something was not something they anticipated." - Bill Gates
if (a = b) assigns the contents of b to a and executes the code following if b 0. Who the hell thought that would be a good idea?
If b is an expression that returns a reference to a newly allocated resource, such as fopen or malloc, this if statement represents trying to allocate a resource and then skipping the following compound statement if the allocation failed. It's what they had before exceptions, and it's what they still have on microcontrollers too small to have the overhead of a full-featured exception handler.
strings terminated by a binary zero rather than their physical size. Who the hell thought that would be a good idea?
Probably the same way that most popular operating systems store text files as a list of lines separated by newline characters, encoded as 0x0A on UNIX or Windows but 0x0D on Apple II or classic Mac OS. VMS is an exception in that its "non-stream" text files have each line prefixed by its length.
By now, the only strange thing about the ternary operator condition ? value_if_true : value_if_false is how PHP has the operator's associativity backwards from everything else. Everything else interprets a?b:c?d:e as a?b:(c?d:e), where a chain of ternary operators means use the value associated with the first true condition. It's equivalent to SQL's case when a then b when c then d else e end. PHP, on the other hand, interprets a?b:c?d:e as (a?b:c)?d:e, which means using one condition to select which other condition shall apply. In my opinion, PHP's interpretation is less useful.
Not any more with lambdas:
button.setOnActionEvent(e -> doSomethingWith(e));
I always liked the target-first approach of Intel. Like strcpy(dst, src). I know I'm mucking with (dst) string, and not doing anything with (src). The same with (MOV %eax, 0xdeadbeef).
Imagine strcpy(src,dst), which many people would say is more logical because you're saying "Perform a string copy from (src) to (dst)." We say "Copy from source to destination" all the time--it's how we think, right? And then: strncpy(src,dst,32). So with strcpy(), the last argument is the thing we mess with; while strncpy() it's some argument in the middle.
This is why strcpy(dst,src) and strncpy(dst,src,len) are set: the first argument is the target. These calls immediately tell you what they actually change. printf() changes nothing, but uses the first argument as its format--it emits a modified content of the first argument based on subsequent arguments; sprintf() changes the first argument to a modified copy of the second argument using all further arguments. If something is changed, it's the first things that are changed.
In Intel assembly, a glance down the left side of the screen rapidly tells you what's roughly going on. You don't need to read the whole line; you just look at opcodes and targets, quickly recognizing which opcodes modify their targets. This immediately tells you flow; and attaching the source data for the modification provides you with logic. This is less decoding than trying to interpret an individual opcode, rearrange it in your head, extract its behavior, extract its logic, and build incrementally with that.
Support my political activism on Patreon.
def mkCounter():
c = 0
def counter():
c = c + 1
return c
return counter
count = mkCounter()
print str(count())
print str(count())
print str(count())
You'd expect "1", "2" and "3", right? Wrong!
$ python test.py
Traceback (most recent call last):
File "test.py", line 9, in
print str(count())
File "test.py", line 4, in counter
c = c + 1
UnboundLocalError: local variable 'c' referenced before assignment
When Python parses the definition of "counter", it sees the assignment "c = ..." and assumes that we must be defining a local variable "c", so it creates a slot in "counter" to contain "c". This local slot shadows the "c" inherited from "mkCounter", so when we get to evaluating "c + 1" we get this "referenced before assignment" error.
Note that it's perfectly fine to *use* inherited variables, just not to *assign* them:
def mkPrinter(s):
def printer():
print s
return printer
p = mkPrinter("hello world")
p()
This prints "hello world" as we'd expect.
This was a stunner for me when I first encountered it. When you mix double and int types in Matlab, it demotes the double to an int! Same with float and int.
Of course, you must create the int explicitly as such (double is the default) but I mean, WTF Matlab??
If it weren't for deadlines, nothing would be late.
I'm pretty sure null-terminated strings come from the days of punch cards/punch tape where an unpunched area is read as null (binary zero). Wherever the data-entry clerk stopped typing was the end of the string and the string could be appended to latter (impossible with a non-zero end-of-string symbol or a string length in the header which can't be rewritten on card/tape).
Support Right To Repair Legislation.
The C pre-processor. The whole thing. The CPP is without a doubt the biggest WTF in language design. Hey, this C language is neat and all, but how about if we make it so that before you compile it you have to run it through a whole separate language processor with different syntax designed to do string substitution? And let's use that language to implement comments. And hey, how about using it to import common files? But since it's really just a string substitution, the import really just dumps a verbatim copy of the common file into the one being processed. If you have two identical include lines you get two copies of the common file inserted. Wouldn't that be *great*!?
Okay, I understand the historical context and why it made sense at the time. I really do. But from a modern perspective it's definitely not in any way the sane way to do it.
And for an honorable mention, how about the use of leading whitespace in Makefiles? Not only is leading whitespace significant, starting a line with spaces has a different meaning than starting a line with tabs!
Chelloveck
I give up on debugging. From now on, SIGSEGV is a feature.
I actually like Perl statement modifiers; they can make code more readable if used judiciously. Something like:
return unless $DEBUGGING;
can be pretty useful. Obviously, something like:
$a += $b * complex_function($c, $d, $e) unless ($x > 100.7 && pre_condition($d, $c, $e));
is not good.
I love the various different parsers MSSQL uses, and how very wrong things can go. Run this in SQL management studio and it will work fine... run it from the command line and it will give the below error. It will find \r\nGO\r\n and treat it as a block terminator... even if it appears in comments. This is the only command that it will find and execute within comments.
/*
declare @var as int
set @var = 10
print @var
this is totally in the comments
GO
*/
print @var
------------
output -
------------
10
Msg 137, Level 15, State 2, Line 1 Must declare the scalar variable "@var".
First, Metapost is implemented as a macro language, so it is similar to C shell languages in the way it is evaluated. The symbols x, y, and z are predefined macros. For a location x the construct 3x is three times x. There are built in lengths, so 2cm and 1in are lengths. You can extend the language by defining you own macros for prefix or uinary and binary operations, which is the way that many of the operators are implemented.
The if and loop syntax
There are four levels of precedence. This is why multiplication by a constant can be expressed by putting a number in front of a value.
These are just some of the syntax features. The data types include splines, transforms, colors and numeric pairs for points. Built in operations can find points where two curves intersect and sub-curve sections between intersections.
It's fun in a strange fashion, and you can make some interesting geometrical pictures.
Why is Snark Required?
: CELEBRATE FORTH LOVE IF HONK THEN ; and remember that : ? . ! ; is a straightforward part of the language definition.
"When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
Platform lock-in is the strangest feature of some languages that purposely defeat all the progress we made since Assembler. This is why I will never C#
Elxsi Fortran had it long ago.
Richard Maine in FORTRAN IV program illustrating assigned GO TO on web site
The Elxsi compiler in the mid 80's actually implemented the comefrom
statement (and several variants) as a continuation of this spoof. It
wasn't documented, but I found out about it when Ralph Merkle (one of
the developers) suggested that I might be amused by looking at a certain
area in the compiler executable file. When I did so, I found a list of
strings containing mostly familliar Fortran keywords. Amidst those, I
spotted comefrom. A quick check verified that the statement actually
compiled and worked as "expected".
I later heard that the statement was pulled from the compiler after a
customer submitted a bug report (I think it was a
performance/optimization issue) related to the comefrom statement
implementation. The joke wasn't worth actually investing scarce support
resources on.
much of left-wing thought is a kind of playing with fire by people who don't even know that fire is hot - George Orwell