10 ms·
Strangest language feature
- profquail 16y agoAwesome comment on trigraphs in C: These let you use the "WTF operator": (foo() != ERROR)??!??! cerr << "Error occurred" << endl;
- tome 16y ago[Language pedant: although it's legal C, the use of cerr and endl and << is more likely to occur in C++!]
- senki 16y ago<< is C++ only.
- mahmud 16y ago"Goddamn operator overloading" -- Rev Wright
- senki 16y agoStrangest language feature...
- tome 16y ago<< is the left-shift operator in C, so the OP's code is syntactically valid C. It ought not to compile though, since it's trying to shift cerr by a string!
- senki 16y agoThanks. Sorry. I'm stupid...
- protomyth 16y agoIcon conditions were pretty interesting.
- deleted 16y ago[deleted]
- ratsbane 16y agoDynamic scope. Not really very strange but very unusual; not supported by many languages. AFAIK Perl and Lisp(ish) languages are the only ones. For example: sub foo {my $x='fish'; local $y='chips'; &bar;} sub bar {print "\$x is >$x< and \$y is >$y<\n";} This will output $x is >< and $y is >chips< It's quite handy - saves passing around a "context" object, for example. The remarkable thing is how few languages implement some form of it.
- btilly 16y agoDynamic scope is supported in older Lisps (eLisp is the only widely used variant with it), and a variety of scripting languages including PHP, Perl, TCL and vimsh (that's vim's internal scripting language). It is rarish because it has been recognized as a bad design, but it still turns up because it is easy to implement.
- bretthoerner 16y ago> eLisp is the only widely used variant with it I think you mean it's the only widely used variant where it's the default. It's available in CL and Clojure when you want (need?) it.
- ratsbane 16y agoIt is often recognized as bad design - though I don't think that's always fair. I thought of this because I was just reading some Java code that passed around a context object with all kinds of random things stuffed into it. It was, in effect, a way of simulating dynamic scope. There's a time and a place for everything. I'm sure dynamic scope can be horribly abused, but it's also nice to have in the toolbox for when you actually need to do what it does.
- btilly 16y agoMy favorite examples from Perl. The reset function. The dump function. And the fact that pos($x) = pos($x) is NOT a no-op. (It clears an internal flag allowing a zero-length regular expression to match again. Yes, I've used this.) Another fun one is that in Perl that local can operate on data structures. As in local $foo{bar}. (I use this every so often in recursion sanity checks. But it is still an odd feature.)
- famousactress 16y agoI can't say I'm surprised that three of the top 5 features on the post are Javascript :|
- deleted 16y ago[deleted]
- vog 16y agoIt is because the ECMAScript type system is a real WTF. I always found the type system of PHP questionable, especially the useless and bug provoking unity between arrays and hash tables. However, ECMAScript provides such mis-design at an even lower level of the language. Nevertheless, I still like working with ECMAScript because at least it has proper closures.
- deleted 16y ago[deleted]
- lectrick 16y agoI am happy to not see Ruby represented here.
- judofyr 16y agoJust on the top of my head: 1. The flip-flop >> s = true >> (1..10).reject { true if (s = !s) .. (s) } => [1, 3, 5, 7, 9] 2. A snake in my Ruby?!? # Works in both Python and Ruby print """Hello World""" 3. END vs at_exit END { puts "Ruby has END ..." } at_exit do puts "... and at_exit" end puts "Do you know the difference?" 4. BEGIN/END wtf? # Have you ever seen these in production code? BEGIN {} END {} 5. The wonders of a single space # Returns the position where the regexp matches "foobar", # or nil if no match. def get(regexp = /bar/) regexp =~ "foobar" end get /1#/ # => nil get / 1#/ # => 3 <- WTF? 6. Local variable tables; don't we all love them? def get(regexp = /bar/) regexp =~ "foobar" end get /1#/ # => nil get = 5 get /1#/ # => 5 get / 1#/ # => 5
- derefr 16y agoJust guessing that your #4, BEGIN and END, are for using Ruby like awk (that is, from the shell—you should never see them in a script.) Try this (and cringe): cat /usr/share/dict/words | ruby -lne 'puts $_.reverse; n = (n || 0) + 1; END{ puts "total: #{ n }" }'
- deleted 16y ago[deleted]
- arethuza 16y agoThe video of implementing Conway's Game of Life in APL is awesome: http://www.youtube.com/watch?v=a9xAKttWgP4 http://www.youtube.com/watch?v=a9xAKttWgP4
- ww520 16y agoI'm curious. How come no one claim APL being expressive?
- lukev 16y agoTo be usefully expressive, a language must not only be compact, but easy to read. From what I've seen, APL is pretty much a write-only language. Code can't be read, only deciphered.
- vorg 16y agoThe reason people can't read APL easily is it's one of many languages programmers know. If APL was the ONLY programming language any ever used anywhere, then all programmers would be able to read it easily after a little programming experience. Natural languages have the tersest syntax around, and people understand them easily because it's the ONLY language they learn, or one of only a handful if they're polylingual. It would be the same with a programming language.
- tkahn6 16y agoJust because you understand a language does not mean you understand or recognize all algorithms that can be expressed in that language.
- silentbicycle 16y agoYeah, but that's hardly limited to APL.
- 16y ago
- samratjp 16y agoIt amazes me how so many times this python feature gets overlooked: >>> x=5 >>> 1<x<10 True >>> 1<x<3 False EDIT: fixed spaces, thanks epochwolf for the indent tip.
- epochwolf 16y ago>>> x=5 >>> 1<x<10 True >>> 1<x<3 False (Indent 4 spaces to show code)
- judofyr 16y agoIf anyone is interested, here's how you could implement it in Ruby: http://judofyr.net/posts/chained-comparisons.html http://judofyr.net/posts/chained-comparisons.html
- mkramlich 16y agothat's good-strange, though, not bad-strange. i think in the OA they were mostly talking about bad-strange.
- halo 16y agoI was disappointed after clicking the link, because from the title, it sounded like it would be an insightful list of unusual useful features, but instead it's mostly a boring list of language design bugs or quirks.
- jperras 16y agoThe strangest language 'feature' I've come across must be 'ticks' in PHP: > A tick is an event that occurs for every N low-level tickable statements executed by the parser within the declare block. The value for N is specified using ticks=N within the declare blocks's directive section. ( http://www.php.net/manual/en/control-structures.declare.php http://www.php.net/manual/en/control-structures.declare.php ) PHP is a hodgepodge of inconsistent APIs and general weirdness already, but I really did sit back and have a good WTF moment when I discovered this 'feature'. I have yet to encounter many people who have ever heard of ticks, let alone anyone who has actually implement functionality that depended on them. I've never seen something like that in Python or Ruby.
- deleted 16y ago[deleted]
- silentbicycle 16y agoIt's really not that strange - it's probably intended debugging & profiling code. It sounds like Lua's debugging hook (http://www.lua.org/manual/5.1/manual.html#lua_sethook http://www.lua.org/manual/5.1/manual.html#lua_sethook), which can run a callback every N vm instructions. I made a simple profiler by setting the hook to run every X ticks (typically 10,000), recording the call stack, and then seeing where most of the execution happens. If every other time you look at the vm, it's in the same place, then it's clearly a hotspot. I don't know of an equivalent in Python or Ruby, off the top of my head, but I'd be surprised if they weren't available.
- gamache 16y agoPerl will convert from base 26 to base 10 if you know how to ask: $ perl -E 'say lc (@a="a".."asdf")' 30530
- ralph 16y agoBase 26 or 36? Is 'a' 0 or 10? Does 's' overflow to the next column, like 09 in octal?
- defen 16y agoHow is call/cc not on there...don't tell me your mind wasn't blown when you learned about that one.
- regularfry 16y agoIt's interesting how many of these that aren't outright misfeatures are recognisable as half-implemented Common Lisp features if you squint at them sideways: Python's comparison chains, bc's quit/halt difference, VB7's Loop, JS's multiple-value return, SFINAE in C++... I'm sure there are others.
- omaranto 16y agoI mostly agree but in the case of comparison chains it is lisp that has the half-implemented version: of course a<b<c is (< a b c), but a<=b<c, which is actually more common in my code, becomes (and (<= a b) (< b c)). Mathematica, which has much in common with lisp, does something analogous to (inequalities a '<= b '< c), using symbols for the comparisons.
- Groxx 16y agoGotta read through a bit, but there are some excellent ones in there. Personal favorite with C++ templates: assert( ( o-------------o |L \ | L \ | L \ | o-------------o | ! ! ! ! ! o | ! L | ! L | ! L| ! o-------------o ).volume == ( o-------------o | ! ! ! ! ! o-------------o ).area * int(I-------------I) ); http://stackoverflow.com/questions/1995113/strangest-language-feature/2024573#2024573 http://stackoverflow.com/questions/1995113/strangest-languag...
- losethos 16y agoI'm guessing it was something like this: mov eax, 12[rbp]
- silentbicycle 16y agoI'm a bit disappointed in this discussion. "strangest" language feature sounds like a crowd pointing and laughing. Boring! What are some novel, underappreciated, unexpectedly useful language features? (And this emphatically isn't about "my favorite language vs yours".) Here are a couple, to get things rolling. Pattern matching. This is a favorite of mine - stating what you want (or expect), possibly with variables, and letting the language generate the tree of if/case statements. I find pattern-matching code extremely easy to read, easy to extend, almost always right the first time, etc. It works with both static (ML-style variant types, reminding you to check exhaustively) and dynamic (Erlang-style, "handle what you can or throw an exception") typing. awk is based around a weaker form of pattern matching (only matching against ints and regexes, rather than whole trees), and it's still great for quick hacks. PM seems to mesh poorly with conventional OO, though. Compile-time metaprogramming. This is HN, you've probably heard plenty about Lisp macros, so I'll leave it at that. Incremental development / hot code loading. Erlang has this (with soft real-time guarantees), Lisp, Smalltalk, and basically anything image-based has had this for ages. It's often easier to grow a system piece by piece than to build it upfront and plug in together afterward. Iterators/generators. Without needing a fully lazy-by-default language such as Haskell, it's often handy to have a handle into a (possibly infinite) stream that you can pull from as necessary. Prolog combines pattern matching (unification really, a step beyond pattern matching) with backtracking, so you can write "generate and test" code: "here's what I want, this generates a stream of all possible candidates, here's how to narrow it down". It's sometimes too slow for use in production (due to combinatorial blowups), but it's excellent for prototyping, and can usually be made good enough with some tweaks. Coroutines and actors. Like iterators and generators, but breaking the flow of execution into lots of little autonomous pieces. Communication makes dataflow explicit, most things can be easily understood in isolation, and they can often be run in parallel. (Coroutines are cooperative.)
- kanak 16y agoTo this excellent list I'd add: First Class Continuations like in Scheme.
- silentbicycle 16y ago
- mkramlich 16y agoFor me it was strange that Ruby used "end" as the block ending delimiter in a world and era where so many other languages were using "}" quite effectively, thank you very much. And Python was showing you didn't even need that much. It felt like a throwback to an earlier era of programming, like COBOL or Pascal.
- steveklabnik 16y agoYou can use {} instead of do/end if you'd like.
- mkramlich 16y agogreat! wonder why most people don't use it? I keep seeing "end" in almost every chunk of Ruby code I see on the web.
- steveklabnik 16y agoThe general convention is that {} is for one line blocks, and do/end for multiline. [1,2,3].each{|n| puts n } versus [1,2,3].each do |n| m = n + 1 puts m end The reason? do/end is much prettier than {}, but {} is really nice for chaining... [1,3,2].collect{|n| n + 2 }.sort
- ShardPhoenix 16y agoI find it easier to type "end" than "}".
- mkramlich 16y agobut it's 3 characters versus 1. is it easier because you don't have to hit SHIFT?
- yxhuvud 16y agoThere are a lot stranger stuff hiding in Ruby. Flip-flops. Do I need to elaborate?
- j_baker 16y agoI'd have to say intercal's COMEFROM: http://en.wikipedia.org/wiki/COME_FROM http://en.wikipedia.org/wiki/COME_FROM