12 ms·
Strangest Programming Language Feature?
- adamnemecek 13y agoFun fact, this is also the reason why 'i' is commonly used as a name for the loop counter variable.
- BlackDeath3 13y agoSource?
- adamnemecek 13y agoI mean google around. It's not "it's definitely from Fortran" more like "it has been repeatedly suggested that...".
- tsm 13y agoWhat about as an abbreviation for "index"?
- kps 13y agoNo, it's the other way around; i, j, ... have a long history in mathematics as indices for matrices, summations, etc., with m, n likewise being traditional for the dimensions of a matrix. In early FORTRAN, integers were present primarily to be used as array subscripts. The INteger mnemonic doesn't appear in any of the early papers or manuals. As a side note, on the topic of features that would currently seem ‘strange’, some early languages that were intended to be programmed using teletypewriters rather than FORTRAN's Hollerith cards used half-line motions to write array subscripts as actual subscripts.
- antirez 13y agoSmalltalk's "become" is a pretty interesting one... http://gbracha.blogspot.it/2009/07/miracle-of-become.html http://gbracha.blogspot.it/2009/07/miracle-of-become.html
- saryant 13y agoAkka actors have a very similar feature, same name. It doesn't swap identities though. It's actually pretty cool if you think of it as a way to track state without having a mutable variable. One example is this implementation of the dining philosophers problem: https://github.com/akka/akka/blob/master/akka-samples/akka-sample-fsm/src/main/scala/DiningHakkersOnBecome.scala https://github.com/akka/akka/blob/master/akka-samples/akka-s... You can also use "unbecome" and effectively treat an actor's behavior as a stack, popping and pushing receive functions. One cool trick is to bind a value to your receive function: def receive(foo: Foo): Receive = { ... } Then you can bind immutable data to a given receive function but think of it as mutable by replacing the current receive function with become().
- BrandonY 13y agoSmalltalk also is rather famous for giving developers enough freedom to more or less destroy the environment with the terrifying looking command "Smalltalk := nil"
- rbanffy 13y agoI once crashed Squeak by making true := false. It was an interesting experience.
- Crito 13y agoIt logically follows from how arrays in C works, so I don't really know if it qualifies for weird/suprising, but the old array[i] / i[array] thing is fun to show to people who haven't seen it before. The most amusingly weird thing I can think of is INTERCAL's COMEFROM: http://en.wikipedia.org/wiki/COMEFROM http://en.wikipedia.org/wiki/COMEFROM
- ThatOtherPerson 13y agoCan you explain your array[i] / i[array] reference? I can't find it on Google.
- sootzoo 13y agoThere's an answer [1] on the linked SO thread (flip to the first page) but basically, the following two lines are equivalent in C: a[10] 10[a] This is because a[10] is equivalent to (a + 10), and 10[a] is equivalent to (10 + a), as the first comment on this answer explains. [1] http://stackoverflow.com/questions/1995113/strangest-language-feature/1995156#199515 http://stackoverflow.com/questions/1995113/strangest-languag...
- deleted 13y ago[deleted]
- rodrodrod 13y agoFrom the c standard[0]: > The definition of the subscript operator [] is that E1[E2] is identical to (* ((E1)+(E2))). Since * (E1 + E2) is commutative, E1[E2] == E2[E1]. [0] http://c0x.coding-guidelines.com/6.5.2.1.html http://c0x.coding-guidelines.com/6.5.2.1.html
- kidb 13y agoI think the trick is that array[i] and i[array] will always be the same value in C. It's confusing because array[i] makes sense but i[array] doesn't (how the hell can you use an array as an index on an integer?) It works because array is a pointer to a memory address and i (or index) is an offset. array[i] will add the index to the memory address and return the value there, where as i[array] will add the memory address to the index. Since array+index == index+array, they point to the same memory and return the same value.
- Someone 13y agoNo mention of "ALTER" (http://en.wikipedia.org/wiki/COBOL#Self-modifying_code http://en.wikipedia.org/wiki/COBOL#Self-modifying_code) on the first page? Self-modifying code was fairly common at the time COBOL was developed, but incorporating it in a high-level business language was, IMO, a very weird decision. I also miss call by name (http://en.wikipedia.org/wiki/Man_or_boy_test http://en.wikipedia.org/wiki/Man_or_boy_test) on the first page. In general, one should read the Intercal (http://en.wikipedia.org/wiki/INTERCAL http://en.wikipedia.org/wiki/INTERCAL) paper, and figure out from which language each of its features came.
- EvanAnderson 13y agoYour mentioning "ALTER" made me think about a dialect of BASIC that I once used (STARDOS BASIC on a "Micro V" computer, back in the late 1980s). This BASIC dialect had an "XEQ" function that would pass a string to the tokenizer and execute it as an immediate-mode command. If you started the string with a line number you could create self-modifying BASIC code. It was dizzying to my young mind.
- Zenst 13y agoYou mention COBOL, I was aught COBOL the JSP (Jackson) method and did lovely code. My first job they used GOTO and I was like argh, COBOL has a GOTO verb. Performance and the like, much less cleaner code but effecient :\ and with that the first steps from the academic world into the real world open your eyes up to many weird programing ways and features. But I did always liked the COBOL, OCCURS DEPENDING ON ( http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.aix.cbl.doc%2Ftptbl27.htm http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/inde... ) and how you could use it to write variable length records to files, saving space on tape or DISC and with that faster and cheaper. it is after all effeciency and getting that extra drop of performance that drives the weird and wonderful quirks and usage and practices that this topic aspires to highlight.
- al2o3cr 13y ago/me drops the MUMPS reference manual on the table That whole language is one long-running WTF.
- roywiggins 13y agoThis line in MUMPS is not only valid, it also actually does something potentially useful: s:foo'="" foo(foo)=foo It's actually a bit tricky to explain what it does. Everything in MUMPS is effectively a tree. Each tree has a value in the "root node" and you can set it like this: set foo="hello" You can also put data deeper into the tree: set foo("fizz")="buzz" So if something is passed to you and you want to know if you can treat it as a string, you test to see if it's a null string: if foo'="" do [something] ('= means !=) Two more features: 1) Almost every directive can be reduced to one letter. 2) If I want to quit based on a condition, I can do either if condition quit or quit:condition So the line above is more legibly written as if foo'="" set foo(foo)=foo So if foo="bar", it's equivalent to: set foo("bar")="bar"
- perturbation 13y agof p=2,3:2 s q=1 x "f f=3:2 q:f(asterisk)f>p!'q s q=p#f" w:q p,?$x\8+18 (Not sure if this is going to mess up the formatting, so apologies in advance). This (shamelessly stolen from a usenet sig) will print out a table of primes with formatting. Adding a quit based on max prime size is left as exercise to the reader. Explanation: f = for, but basically used as a while loop since we don't have a terminate condition ('p' is used as the counter variable and we would normally have an upper limit, but since we don't it will keep iterating until something breaks) We're setting the variable 'p' to 2 on first iteration of the loop, 3 on the next, and then going up by 2 on subsequent. Then, we're setting the variable 'q' to 1. 'x' is short for XECUTE. It looks at the string following it and executes it as code. "f f=3:2 q:f(asterisk)f>p!'q s q=p#f" This is another loop, with the variable 'f' used as the counter, starting at 3 and incrementing by 2. Each loop iteration, it checks if f^2 is greater than p or if q == 0. If not, it proceeds to set q to p modulo f. To sum things up: We quit the loop if either we've checked all candidates (excluding evens) up to ~sqrt(p) or if one of these evenly divides p (that is, modulo 0). The tricky bit: w:q p,?$x\8+18 w:q == WRITE, using the value of 'q' as a post-conditional, only to be executed for non-zero values of q. If we write, we will write 'p', setting the position of the cursor with '?' (syntax particular to write) using the '$x' variable (built-in for the current cursor position). Note: $x\8+18 evaluates to (($x INTEGER DIV 8)+1)8 First line: GTM>f p=2,3:2 s q=1 x "f f=3:2 q:ff>p!'q s q=p#f" w:q p,?$x\8+18 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 Edit: Formatting is messed up. (asterisk == '* '). I could have escaped, but didn't want to add whitespace.
- BlackDeath3 13y ago>GOD is REAL, unless declared INTEGER. I'm stealing the hell out of this.
- kabdib 13y ago: 2 3 ; ... redefines the constant 2 as 3. FORTH. Go figure :-)
- marcosdumay 13y agoTaking about constants, the scad format (for 3D design) allows for defining and redefining constants, but they always have the last defined values... That is, unless you import a module within redeclariations, in what case the module will inherit the values of the last declarations above the line it's imported on (not the last one of the file). And yep, that'll replace any declarations within that module. The biggest surprise is that this is useful.
- bodyfour 13y agoCertain ancient FORTRAN compilers would let you do that as well. If the target CPU didn't have a "move immediate" instruction, the compiler would just stash the number into memory. The quickest way to implement it is to just add the number into the symbol table... that way an often-used constant will only need one spot in core. Of course when your whole compiler has to run in 8 Kwords or whatever, syntax checking isn't a high priority. So if you do "1234 = 0" it would allow it (since '1234' is just a variable in the symbol table) and it actually would change all of the meaning of 1234 everywhere else in the program!
- kps 13y agoI haven't heard of that, and it would be great if you could remember where you found it. It sounds to me like it might be an apocryphal corruption of the following: Fortran passes arguments by reference. If the compiler uses a constant pool, and (lazily or efficiently, depending on your point of view) passes the constant pool location as an argument, a subroutine could inadvertently modify a constant. FORTRAN 66 (the first ANSI standard) and FORTRAN 77 forbid passing a constant or expression as an argument that will be modified†‡, thereby blessing this implementation. (Fortran 90 and later are tl;dr.) † http://www.fh-jena.de/~kleine/history/languages/ansi-x3dot9-1966-Fortran66.pdf http://www.fh-jena.de/~kleine/history/languages/ansi-x3dot9-... §8.4 p26 ‡ http://www.fortran.com/fortran/F77_std/rjcnf-15.html#sh-15.9.2 http://www.fortran.com/fortran/F77_std/rjcnf-15.html#sh-15.9...
- runn1ng 13y ago"not really a question. closed."
- kps 13y agoHere is a route to interesting reading (or HN karma, if you're into that): https://www.google.com/search?q="This+question+exists+because+it+has+historical+significance"++site%3Astackoverflow.com+-meta.stackoverflow.com https://www.google.com/search?q="This+question+exists+becaus...
- cratermoon 13y agoThe COBOL MOVE-CORRESPONDING verb. I'm not going to try to explain exactly how it works here, but imagine, if you will, copying the contents of one table to another table with a different column structure, but sort of the same names.
- rst 13y agoThis is one of the COBOL features that makes a lot more sense if you think of COBOL as SQL for tape drives than as something that is trying to be, say, Pascal or Ada and failing. (Along with, say, pretty much the entire DATA DIVISION...)
- analog31 13y agoLine numbers in BASIC
- ahoge 13y agoIt kinda made sense, because there wasn't anything fancy like Notepad. If you wanted to read some section, you had to specify the range. If you wanted to change a line, you overwrote it by using the same line number. If you wanted to insert a line, you had to pick a line number which lies between those other two line numbers. That's why you used an increment of 10 (or whatever) instead of 1.
- rbanffy 13y agoYou obviously never dropped a deck of punchcards, did you? Line numbers are a wonderful thing in that situation.
- rbanffy 13y agoYou obviously never dropped a deck of punchcards, did you? Line numbers are a wonderful thing in that situation.
- protomyth 13y agoThe control structures in Icon are not quite what you would expect and qualify as strange: http://en.wikipedia.org/wiki/Icon_(programming_language) http://en.wikipedia.org/wiki/Icon_(programming_language)
- raldi 13y agoI don't see what you mean; could you spell it out?
- protomyth 13y agoI thought the wikipedia article could explain it better than I, but here are some more references: http://blogs.kde.org/2006/10/21/ralph-griswold-icon-language-designer-passes-away http://blogs.kde.org/2006/10/21/ralph-griswold-icon-language... http://dl.acm.org/citation.cfm?id=104659 http://dl.acm.org/citation.cfm?id=104659 http://research.microsoft.com/pubs/69724/tr-99-64.ps http://research.microsoft.com/pubs/69724/tr-99-64.ps look at Goal-directed evaluation of icon
- dj-wonk 13y agoI heart what should be called a "truth injection attack" in Python: http://stackoverflow.com/a/2021553/109618 http://stackoverflow.com/a/2021553/109618
- userbinator 13y agoYou can do a similar thing with Java, although it's a bit harder... http://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection http://stackoverflow.com/questions/3301635/change-private-st... I think you can do something like this in C# too (not surprisingly).
- Thiz 13y agoFor…else in python. Weird. or dutch.
- valtron 13y agoCool!
- jejones3141 13y agoSomeone's already mentioned COBOL's ALTER X TO PROCEED TO Y, so I'll mention a programming language called COMAL. A friend with a C64 showed it to me, and it was very respectable for its time and the available resources; reminded me of BASIC09. Apparently it was written by someone from Denmark, and there were commands to switch back and forth between English and Danish. I don't remember whether it was just for error messages or for those and for the language keywords as well; I want to say the latter.
- mck- 13y agoIn CoffeeScript I discovered the other day that: 0 <= "" <= 0 # True "" is 0 # False
- shoo 13y agoI guess that is because coffeescript's <= operator is just javascript's <= operator, which does implicit type conversion. but coffeescript's "is", aka ==, aka === in javascript, doesn't. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... having "==" be semantically quite different to "<=" doesn't seem a particularly nice choice of notation. arguably coffeescript has made things worse in this case compared to plain javascript, where you're probably not going to expect === to behave similarly to <=. not obvious how you'd improve this to make it consistent, without say redefining how "==" and "<=" work to make them raise type errors or evaluate to something undefined if the types of the arguments don't match.
- runlevel1 13y agoIt's because equality comparisons in CoffeeScript (==, !=, is, isnt) are always compiled into strict (non-type-converting) comparisons (===, !==). [1] JavaScript doesn't have strict relational operators (>, <, >=, <=), so all relational comparisons undergo type-conversion. [2] CoffeeScript: 0 <= "" <= 0 # True JavaScript: (0 <= "" && "" <= 0); // True CoffeeScript: "" is 0 # False JavaScript: "" === 0; // False [1]: http://coffeescript.org/#operators http://coffeescript.org/#operators [2]: http://www.ecma-international.org/ecma-262/5.1/#sec-11.8 http://www.ecma-international.org/ecma-262/5.1/#sec-11.8 EDIT: Forgot to include 'is' and 'isnt' operators.
- Fasebook 13y agoJavascript's DOM
- eps 13y agoDuff's device is certainly a very strange construct. http://www.lysator.liu.se/c/duffs-device.html#duffs-device http://www.lysator.liu.se/c/duffs-device.html#duffs-device
- spc476 13y agoINRAC, the langauge RACTER (http://en.wikipedia.org/wiki/Racter http://en.wikipedia.org/wiki/Racter) has the most bizarre flow control I've ever seen in any computer language, ever. It can best be described as "a random, pattern matched GOTO/GOSUB" which is the most succinct description I can come up with. I have a blog entry about it (http://boston.conman.org/2008/06/18.2 http://boston.conman.org/2008/06/18.2) but in short, each line of an INRAC program (unless it ends with a '#' mark in which case execution continues to the next line) is a subroutine, each with a label. The label does not need be unique, but when you "call" a subroutine, INRAC will just pick one line with that label at random to execute. The pattern matching comes in because you can select the label with wildcard characters (which just picks a line that matches the pattern at random). There isn't much about the language on the Internet. In fact, the only other page aside from my blog entry (which I wrote as I went through the existing source code I found for Racter) is the Racter FAQ (https://groups.google.com/forum/#!topic/rec.arts.int-fiction/RTV5CUkJ8fs https://groups.google.com/forum/#!topic/rec.arts.int-fiction...) which has a few inaccuracies (or perhaps was looking at a version of the code before processing).
- zokier 13y agoC++ has all sorts of fun stuff. One example is std::vector<bool>, which is not implemented as a simple array of booleans like every other std::vector, but instead it is a bitmap. Afaik this behavior is required by standard. One fun side-effect is that you can't take the address of individual elements of the vector. Compare these two: http://ideone.com/qC9yOp http://ideone.com/qC9yOp http://ideone.com/jF4krp http://ideone.com/jF4krp
- eli_gottlieb 13y agoI'm the only person thinking of the way MATLAB passes everything by value, including compound objects and structs?
- Pxtl 13y agoC switch fallthrough. I know it's old and everybody's used to it and I get why it's there, but it's freaking weird. I love c#'s response that you must use goto <case> instead to make fallthrough explicit.
- Pxtl 13y agoin vb.net: off-by-one array sizes so people who do one-based arrays don't get hurt. Also, two sets of boolean operators, the simpler ones don't short-circuit (or vs orelse, and vs andalso).
- kyberias 13y agoThis question is a beautiful invitation for everyone to defend their favorite languages! :)
- julian_t 13y agoSnobol... where patterns are first class constructs, and every line can end with a GOTO. That definitely lets you write some very, er, compact code. But it was superb to program in. And how about the assigned GOTO in older versions of Fortran? "GOTO N" where N is an integer variable whose value will be known at runtime. Happy days...
- knome 13y agoI'm sure you'll be pleased to find that gcc has kept the assigned goto alive as a c extension. #include <stdio.h> int main( int argc, char ** argv ){ void * p = && lol ; bounce: goto *p ; lol: printf("lol %p\n", p); p = && wtf; goto bounce; wtf: printf("wtf %p\n", p); p = && lol; goto bounce; }