26

When learning a new programming language you sometimes come across a language feature which makes you wish you had it in your other programming languages that you know.

What are some language feature which were at the time of learning very new to you and that you wish your other programming languages had.

An example of this is generators in Python or C#. Other examples may include list comprehensions in Python, template in C++ or LINQ in .NET or lazy evaluation in Haskell.

What other semi-unique language features have you come across which were completely new and enlightening to you? Are there other features of older programming languages which were unique and have fallen out of fashion?

Brian R. Bondy
  • 7,067
  • 32
  • 53

18 Answers18

26

Practically anything in Haskell

  • Monads. Yes - the big scary word that makes increadibly easy parsers, IO, operations on Lists and other things so easy (once you notice common pattern)
  • Arrows. The same for advanced users ;)
  • Standard stuff like lambdas etc.
  • Currying functions
  • Algebraic data types
  • Pattern matching

And many more.

PS. Yes. I am Haskell fanboy if anyone asked.

Maciej Piechotka
  • 2,465
  • 2
  • 18
  • 19
  • 13
    To be fair, you should give ML credit for most of that list. – munificent Sep 22 '10 at 01:44
  • 1
    Well - except monads and arrows IIRC. But they still are *semi*-unique – Maciej Piechotka Sep 22 '10 at 09:16
  • Any particular reason for downvote? – Maciej Piechotka Sep 23 '10 at 09:08
  • 2
    +1 for pattern matching. I show it to other people and they don't get it. I think it's genius. – Barry Brown Oct 02 '10 at 21:09
  • Obligatory (http://steve-yegge.blogspot.com/2010/12/haskell-researchers-announce-discovery.html). BTW, I'd hardly consider lambdas to be unique, python, C#, javascript, etc. Monads? Most other languages refer to it as chaining; the jquery core is essentially one massive set of HTML/DOM and AJAX monads (Google:jQuery.fn). Currying is also relatively common nowadays. – Evan Plaice Nov 03 '12 at 01:16
  • @EvanPlaice: "standard stuff" sort of implies that it is present in other languages. As of Monads - yes, you can implement it in other languages but it will not have the syntax support but, well, chain of methods. Other languages that do have syntax support (IIRC F#, Scala, ...) were not as popular at the moment of writing answer as they are today. – Maciej Piechotka Nov 04 '12 at 00:38
  • @MaciejPiechotka I'm not even talking about functional languages. If you look at jQuery, the standard functionality is basically one huge monad. It takes a HTML node (that may contain additional sub-nodes) and wraps it with additional functionality. You can also bind the methods to events. There's no explicit syntax in javascript for monads, it's just a common pattern. In python there is a dedicated syntax, decorators. In C# LINQ is a perfect example of a monadic structure, it takes an IEnumerable structure and wraps it. They're not as uncommon as you may think. At least, not anymore. – Evan Plaice Nov 04 '12 at 03:41
  • @EvanPlaice: Arguably they are examples of Monads not a Monads as a feature of language be it syntax sugar or common pattern. Going this logic C also have monads to some extend (one, implicit one). It is correct to say that IEnumerable is a monad and it is correct to say that Java Iterator is a monad (as mathematical object). However LINQ would not allow to implement a Parser or continuation monad - at least not in a straightforward way. – Maciej Piechotka Jun 07 '13 at 19:52
22

Lisp macros.

The Lisp macro language is Lisp, with a few predefined syntax features for the sake of convenience. Using them, it is possible to add major features to the language, such as one's choice of object orientation styles or Prolog-like deterministic matching, without looking out of place. It makes the setf macro possible, which is a conceptually very powerful macro: (setf A B) means that, when you evaluate A you will get B, and that can be extended to any limit you like.

C++ template metaprogramming is capable of similar things, but in a much different language than regular C++.

David Thornley
  • 20,238
  • 2
  • 55
  • 82
19

Python's decorator.

It's extremely easy to implement memoization or timing of function using the decorator.

Example of a function timer.

class FuncTimer(object):
    """ Time how much time a function takes """
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
        self.start_time = time.time()
    def __call__(self, *args):
        self.memo['return'] = self.fn(*args)
        print("Function '%s' took %u seconds" % (self.fn.__name__, time.time() - self.start_time))
        return self.memo['return']

Now if you have a function foo you want to time, you can simply do this,

@FuncTimer
def foo():
    # foo's implememtation goes here

You will see something like,

Function 'foo' took 3 seconds.

grokus
  • 7,536
  • 4
  • 31
  • 46
  • Java has annotations, which have a similar purpose and syntax, but work very differently – Casebash Sep 04 '10 at 00:11
  • 2
    +1: Python's decorators have impressed me more than almost any other feature in the language. They are very beautiful and simple! – Adam Paynter Sep 09 '10 at 23:26
  • Maybe you could share a simple example with us? I don't know Python to be honest. – ShdNx Sep 22 '10 at 14:07
  • @ShdNx, I just added an example. – grokus Sep 22 '10 at 14:34
  • 1
    Shouldn't the start time be computed as part of the call? – detly Jul 16 '12 at 07:48
  • +1 Definitely amazing. You can do similar in javascript (via function passing) but it's not nearly as elegant and becomes downright ugly if you need to pass in parameters. Especially for writing very clean http handler/view extensions. – Evan Plaice Nov 03 '12 at 01:05
15

Casting to void* in C. You can cast everything to raw bytes, and do whatever you want with these data.

(Yes, nowadays it's unique...)

P Shved
  • 7,427
  • 35
  • 50
12

Yield in Python

In Python (and I believe in C#), you can define a so-called generator that pauses function execution at a yield statement, returns the value and on subsequent calls, restarts the function where it left off (with the state preserved between calls). This is great for generating long lists of values where you are only interested in the current value of the function (which is very common). It allows you to build potentially infinitely long sequences while only occupying very limited space in memory.

Chinmay Kanchi
  • 6,173
  • 2
  • 39
  • 51
8

Lambda expressions (closures, nested functions, anonymous methods, whatever you call them).

I first came across them in Perl, instantly loved them and wondered why other languages don’t have them. Nowadays I guess it’s not that unique anymore; even PHP have managed to hack them in somehow. But they were semi-unique at the time.

Timwi
  • 4,411
  • 29
  • 37
8

Continuations from Scheme (later adopted by a few other languages including Ruby.)

finnw
  • 1,467
  • 2
  • 17
  • 21
7

Sets in Delphi are very useful, pretty much just a named boolean array. They're very useful for saving a settings form with 32 checkboxes. But they've got all the same set theory functions (i.e. difference, intersection, union).

I'm not sure if they've fallen out of fashion, but I use them all the time.

Peter Turner
  • 6,897
  • 1
  • 33
  • 57
  • Nice, but wouldn't that be easy to implement in Java, for example: boolean[]? – Mark C Oct 06 '10 at 15:49
  • Yeah, you can, but I don't think it's as succinct as: TForm = (FF_1500 = 1, FF_CA251 = 5, FF_UB04 = 6, FF_MA10 = 7); TFormSet = set of TForm; – Peter Turner Oct 06 '10 at 15:58
7

Send

From Erlang. Sends a message asynchronous to another thread.

Expr1 ! Expr2

Receive

From Erlang. Receives a message from another thread.

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end
Jonas
  • 14,867
  • 9
  • 69
  • 102
6

I really like the unless modifier in Ruby. It seems so natural and replaces a lot of scenarios where your code just seems to be very messy without it.

puts "All good" unless input.nil?

How can you not like that? :D

Jaco Pretorius
  • 4,057
  • 2
  • 27
  • 38
5

C# Properties

/// <summary>
/// Get ID
/// </summary>
public int ID
{
    get; set;
}

vs

(Java)

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}
TheLQ
  • 13,478
  • 7
  • 55
  • 87
  • 2
    Yes, they are better, but this is a bad example. The difference would be much smaller if the getter/setter would actually do something special, and the C# version is documented less. – Bart van Heukelom Sep 11 '10 at 21:14
  • @Bart The Java example is 90% of all the ones that are used. I have rarely seen verification on the set side, and even less on the get side (eg make sure your passing a list, and wrap each get in an immutable list). But most Java people plan for the change that never comes, and in the mean time clutter code. And what do you mean by "the C# version is documented less"? – TheLQ Sep 11 '10 at 21:51
  • 1
    My boss is strongly against the automatic properties of C# and whenever we have an argument about it, neither of us is able to see why the other is right or wrong. I just love them because they make the code so much cleaner and saves me a lot of time in the long run. – mbillard Sep 12 '10 at 01:43
  • @Bart van Heukelom While "Get ID" is inadequate for documentation, I don't think you can hold that as a general statement against properties. The fact you have to write less documentation for a property (write it once instead of twice) is certainly not a disadvantage. – zneak Sep 12 '10 at 15:53
  • 2
    Just don't allow this to encourage people to have getters and setters all over. Only those getters and setters that make sense as actions on an object should be used. – David Thornley Sep 22 '10 at 14:39
  • 3
    They're not called C# properties, they're called Auto-properties – Jaco Pretorius Sep 22 '10 at 14:53
  • 1
    Auto-properties are very common these days. Python, Objective-C... – Casebash Sep 22 '10 at 20:56
5

Unions in C

I can't honestly say that I haven't written enough C to make any of these myself but I have worked with other's code that does.

When it comes down to packaging mixtures of different data in applications that manipulate raw bits/bytes such as networking or binary data storage. In strongly typed languages theres just no easy way to do the equivalent.

Disclaimer:

Although Unions are extremely useful in some cases, they aren't found in most higher level languages because they aren't type safe. IE, you can make data bleed across boundaries of variables using unions (a big no no in the type safe world). With great power comes great responsibility.

Evan Plaice
  • 5,725
  • 2
  • 24
  • 34
  • 2
    IMHO for a good reason. Reinterpreting data is a beatiful way of shooting onself in foot (http://en.wikipedia.org/wiki/Aliasing_(computing)). Better use explicit conversions IMHO. Unions doing right way is IMHO algebraic data types. – Maciej Piechotka Sep 12 '10 at 10:29
  • @Maciej I added a necessary disclaimer. Although, I'm not sure if it accurately explains the dangers of using unions since I don't really have intimate knowledge of using them. I just know that, where I have seen them used the code was a lot more concise and easier to work with than the higher level language equivalent. – Evan Plaice Sep 12 '10 at 10:46
  • The problem is that C is 'highier level language' (just low-level highier level language). Since K&R C it get a lot of rules which allows to use faster portable code. The price is that compiler can assume various things and some be confused. MOST of the `union` use is safe, some is well supported idioms (although technically not correct) - see http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html (although it is more poblem with pointers unions can well fake it). – Maciej Piechotka Sep 12 '10 at 23:25
  • Delphi extended its `record` syntax to support unions: `in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end;` – Frank Shearar Sep 24 '10 at 11:12
5

fancy python argument syntaxes

I'm not sure how unique this is, but in python you can do cool stuff like have keyword pairs automatically made into a dictionary and back. Same with lists:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print "-- This parrot wouldn't", action,
    print "if you put", voltage, "volts through it."
    print "-- Lovely plumage, the", type
    print "-- It's", state, "!"


parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

python docs (scroll down for more argument pasing stuff)

Gordon Gustafson
  • 1,088
  • 1
  • 10
  • 15
  • 1
    +1 for being able to pass a parameter deep in the list *without* having to pass values for all of the optional parameters before it. – eswald Nov 01 '10 at 17:35
4

The C preprocessor. You can even write common code to different platforms with - less or more - ifdefs.

ern0
  • 1,035
  • 3
  • 8
  • 14
3

Objective-C Categories

Categories offer an easy way to extend an object's functionality at runtime (think composition versus inheritance). The classic example is to add a spellchecker to the NSString class.

@interface NSString (SpellChecker)
- (BOOL) checkSpelling;
@end

Also useful for low impact bug-fixes, since a category's implementation of a method will override its parents implementation.

aprock
  • 131
  • 2
2

Ruby's inject method combined with the Symbol#to_proc feature of Ruby 1.9 lets one write some incredibly concise (but still readable) code:

e.g. (1..10).inject(:+)

which sums the integers 1 through 10 => 55

Seeing examples like this made me want to learn Ruby, which I've just started doing.

tcrosley
  • 9,541
  • 1
  • 25
  • 41
  • 9
    To be fair, inject is Ruby's version of fold/foldl/foldr from languages like Lisp, Haskell, etc. – mipadi Sep 22 '10 at 19:38
  • I wouldn't really call this unique. – Daenyth Sep 23 '10 at 00:56
  • 1
    The title of the question says "semi-unique", not unique. Certainly the conciseness of the code afforded by the combination of inject (or map etc) and Symbol#to_proc is way beyond mainstream languages like C, Java, and C++. – tcrosley Sep 23 '10 at 02:06
  • Very concise (and I like it), but I'm not so sure it's that different to something like: Enumerable.Range(1, 10).Aggregate((s,x) => s + x); from C# or other languages – FinnNk Oct 07 '10 at 14:06
1

The Binding Mechanism in JavaFX (R.I.P). The bind keyword enables you to bind the value of a variable to the value of an expression and getting you rid of all those ugly Listener whatsoever boilerplate code.

While JavaFX was quite a fail in many ways, I found many features of the scripting language quite nice.

Oliver Weiler
  • 2,448
  • 19
  • 28
  • 1
    Svelte's reactive declarations (and other reactivity features) do the same thing nowadays: https://svelte.dev/tutorial/reactive-declarations (click "Show me" to see the results). – cyco130 Mar 30 '21 at 08:25
1

String mixins plus compile time function evaluation in D is a pretty unique killer feature. Yes, technically it's two features, but the real power comes from combining them. With this combination, you can write regular D functions that generate code as a string at compile time, and then mix this code into any scope and have it be evaluated as regular D code. The code is fully statically compiled and executes exactly as if it had been handwritten. This feature is even used to work around a couple sticky situations in the standard library.

dsimcha
  • 17,224
  • 9
  • 64
  • 81