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?
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
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.
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.
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.
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/...
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.
Well, whether ';' is a statement terminator (like in C) or a statement separator is one thing.
But Javascript takes it to a whole new level. You can decide not to put them in, and if you break your lines a certain way, you may get the effect of a semicolon where you didn't expect one. And this is part of the language specification.
#naabhaprzrag, #sverubfr-000, #agi-fcbafberq, negvpyr[pynff*=' negvpyr-ary-'] { qvfcynl: abar !vzcbegnag; }
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.
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.
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.
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".
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#