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?

18 Answers 18

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.

8
  • 13
    To be fair, you should give ML credit for most of that list.
    – munificent
    Sep 22, 2010 at 1:44
  • 1
    Well - except monads and arrows IIRC. But they still are semi-unique Sep 22, 2010 at 9:16
  • Any particular reason for downvote? Sep 23, 2010 at 9:08
  • 2
    +1 for pattern matching. I show it to other people and they don't get it. I think it's genius. Oct 2, 2010 at 21:09
  • Obligatory (steve-yegge.blogspot.com/2010/12/…). 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. Nov 3, 2012 at 1:16
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++.

4
  • +1 I hope one day I will be able to program in a Lisp dialect. Oct 18, 2010 at 22:59
  • @Helper ...via C++ templates [scary laughter]
    – mlvljr
    Oct 21, 2010 at 22:48
  • @mlvjr: You're scary. Oct 22, 2010 at 14:19
  • In fact, it is the only out-of-the-box feature you will ever need in a language. With the Lisp macros you can add all the other possible features later.
    – SK-logic
    Jul 16, 2012 at 8:09
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.

6
  • Java has annotations, which have a similar purpose and syntax, but work very differently
    – Casebash
    Sep 4, 2010 at 0:11
  • 2
    +1: Python's decorators have impressed me more than almost any other feature in the language. They are very beautiful and simple! Sep 9, 2010 at 23:26
  • Maybe you could share a simple example with us? I don't know Python to be honest.
    – ShdNx
    Sep 22, 2010 at 14:07
  • @ShdNx, I just added an example.
    – grokus
    Sep 22, 2010 at 14:34
  • 1
    Shouldn't the start time be computed as part of the call?
    – detly
    Jul 16, 2012 at 7:48
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...)

9
  • 1
    Object in .Net languages is very similar. Only more type-safe etc. Sep 7, 2010 at 20:01
  • You can cast to object in a lot of languages. Main problem is that many languages separate primitives and objects
    – Casebash
    Sep 22, 2010 at 20:54
  • 5
    @Maciej: even in .NET, you can't really cast primitives to Object. You box them, and it's quite a different beast. Besides, that's still totally different to casting to void*... Oct 18, 2010 at 23:18
  • 1
    Casting to Pointer in Pascal and Object Pascal does the same thing. Oct 26, 2010 at 7:50
  • 1
    @DeanHarding: Well - in C you have int64_t which you cannot always safely cast to void * (Sorry for late - 2 years - reply). Jul 16, 2012 at 6:46
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.

2
  • 1
    Yield is already listed in the question.
    – Trinidad
    Dec 6, 2010 at 14:50
  • This goes all the way back to BCPL. Jul 16, 2012 at 12:22
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.

2
  • 5
    Unique, as long as you count going back to Lisp, which is the second-oldest programming language around. ;-)
    – Michael H.
    Sep 22, 2010 at 1:35
  • -1: Not semi-unique
    – Casebash
    Sep 22, 2010 at 20:55
8

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

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.

2
  • Nice, but wouldn't that be easy to implement in Java, for example: boolean[]?
    – Mark C
    Oct 6, 2010 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; Oct 6, 2010 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
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

2
  • 7
    Perl had it before Ruby. I love it, too. Oct 2, 2010 at 21:10
  • 1
    Nemerle has similar keywords for unless and when which replace the most common branching scenarios which traditionally would use if/else.
    – MattDavey
    Jul 16, 2012 at 9: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;
}
7
  • 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. Sep 11, 2010 at 21:14
  • 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, 2010 at 1:43
  • 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. Sep 22, 2010 at 14:39
  • 3
    They're not called C# properties, they're called Auto-properties Sep 22, 2010 at 14:53
  • 1
    Auto-properties are very common these days. Python, Objective-C...
    – Casebash
    Sep 22, 2010 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.

4
  • 2
    IMHO for a good reason. Reinterpreting data is a beatiful way of shooting onself in foot (en.wikipedia.org/wiki/Aliasing_(computing)). Better use explicit conversions IMHO. Unions doing right way is IMHO algebraic data types. Sep 12, 2010 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. Sep 12, 2010 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 cellperformance.beyond3d.com/articles/2006/06/… (although it is more poblem with pointers unions can well fake it). Sep 12, 2010 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; Sep 24, 2010 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)

1
  • 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 1, 2010 at 17:35
4

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

2
  • 2
    There are better preprocessors readily available that take their own extra step, and work with all languages. Sep 22, 2010 at 14:38
  • I'm pretty happy with ifdef, ifndef and else.
    – ern0
    Mar 14, 2015 at 22:50
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.

1
  • 1
    Very similar to extension methods in C#
    – Casebash
    Sep 22, 2010 at 20:52
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.

4
  • 9
    To be fair, inject is Ruby's version of fold/foldl/foldr from languages like Lisp, Haskell, etc.
    – mipadi
    Sep 22, 2010 at 19:38
  • I wouldn't really call this unique.
    – Daenyth
    Sep 23, 2010 at 0: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, 2010 at 2: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 7, 2010 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.

1
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.

1
  • I also like the return type automatically inferred from a method..
    – nawfal
    Jun 2, 2013 at 16:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.