82

I hear this word a lot in sentences like "javascript is a very expressive language". Does it just mean there aren't a lot of rules, or does "expressive" have a more specific meaning?

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
morgancodes
  • 25,055
  • 38
  • 135
  • 187
  • Ok, thanks for the responses. Seems it's a slippery word! I will avoid using it and stick to those I'm sure I understand. – morgancodes Mar 12 '09 at 15:55
  • I'm as surprised as the OP. It's strange how confidently people use the word in technical literature as if it has an exact meaning. – Sridhar Sarnobat May 27 '15 at 18:55

8 Answers8

67

'Expressive' means that it's easy to write code that's easy to understand, both for the compiler and for a human reader.

Two factors that make for expressiveness:

  • intuitively readable constructs
  • lack of boilerplate code

Compare this expressive Groovy, with the less expressive Java eqivalent:

3.times {
   println 'Hip hip hooray'
}

vs

for(int i=0; i<3; i++) {
    System.out.println("Hip hip hooray");
}

Sometimes you trade precision for expressiveness -- the Groovy example works because it assumes stuff that Java makes you to specify explicitly.

slim
  • 40,215
  • 13
  • 94
  • 127
  • 2
    What do you mean by "precision" in your two examples? What does Groovy assume which Java makes you specificy? (Note: the use of an `int` loop variable in Java is an artifact of Java; it is essentially meaningless and not any more "precise" than Groovy's `3.times`, so that's not it) – Andres F. Dec 24 '12 at 04:44
  • 6
    @AndresF. Technically speaking, Groovy assumes you are writing to the standard output, whereas Java forces you to explicitly state this. I'd argue that's a completely 100% good assumption on the part of Groovy, but there's that. But I think the OP's point was misstated as I initially had your reaction. Upon further reflection, I think the point is not that the core functionality behind the code is less precise, but the *how* is less precise. In Groovy, we don't know how the looping is performed behind the scenes. Whereas the loop is not behind the scenes in Java at all. Hence, expressiveness. – Ben Lee Oct 11 '13 at 16:01
  • 1
    The New Oxford American Dictionary defines _"expressive"_ as _"effectively conveying thought or feeling"_. I assume this is what is meant by _"easy to understand"_; the code can effectively convey it's intent without requiring documentation to explain it in human language. – Jeffrey Fulton Jul 25 '17 at 17:38
  • I am also wondering about the notation `expressiveness`. While I generally got the idea which is very intuitive, I am wonderful whether there are some "formal definition" of language expressiveness, and if so, what are the "quantitative metrics" to measure expressiveness? – lllllllllllll Jun 19 '20 at 08:59
18

I take it to mean that it's capable of expressing ideas/algorithms/tasks in an easy-to-read and succinct way.

Usually I associate a language being expressive with syntactic sugar, although that's not always the case. Examples in C# of it being expressive would be:

  • foreach (instead of explicitly writing the iteration)
  • the using statement (instead of explicitly writing the try/finally)
  • query expressions (simpler syntax for writing LINQ queries)
  • extension methods (allowing chaining of method calls, again primarily for LINQ)
  • anonymous methods and lambda expressions (allowing easier delegate and expression tree construction)

A different example would be generics: before C# got generics, you couldn't express the idea of "an ArrayList containing only strings" in code. (You could document it, of course, or write your own StringList type, but that's not quite the same.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • While I mostly agree with this, I have to take exception to your inclusion of anonymous methods and lambda expressions in things that make code more expressive. I agree that these make code more elegant, but definitely not easier to understand unless you are fully versed in them. In some ways anonymous functions/methods make programs harder to debug, particularly in languages like javascript. I guess, when easy to read and succint conflict with each other, I choose easy to read, which also implies easy to understand. – jmarkmurphy Sep 28 '22 at 18:08
  • 1
    @jmarkmurphy: Yes, if you don't understand lambda expressions, they're confusing. Is that not the case for every feature? Of course they can be overused as well - but I would generally *far* rather use lambdas when using LINQ than write a separate method for each `Where`, `Select` etc clause. – Jon Skeet Sep 28 '22 at 19:24
  • @ZXX: But an anonymous method can be used to implement that comparison predicate... anonymous methods really aren't *that* different to lambda expressions when they're converted into delegates. They're terser, and can handle type inference for anonymous types, but that's all. The other major difference is in terms of conversion to expression trees, though... that's an area where anonymous methods just don't have the feature at all. – Jon Skeet Nov 07 '22 at 09:25
  • @jmarkmurphy anonymous methods and lambda expressions are very different. Lambda expressions increase expressive power, anonymous methods don't. Lambda allows you to de-facto inject code into something that couldn't be extended otherwise. Simple example - comparison predicate that needs to "mean"/do substantial work with correlated data but still fit into algo that only knows ">=". Complex example - graph crawler with code kept local to invocation point. That's why there was a rush to bring it into C# and C++. Don't forget that lambda is not function - it's AST => can be transformed. – ZXX Nov 07 '22 at 09:42
  • @ZXX: "Don't forget that lambda is not function - it's AST => can be transformed" Well, that's the case for expression tree conversions, but when lambda expressions are converted into delegate types (which is probably the majority of use cases), they're really, really similar to anonymous methods. – Jon Skeet Nov 07 '22 at 12:18
  • @Jon that's implementation detail :-) We are talking expressivity (expressive power). When you write lambda expression you are declaring (to compiler) that it's free to do with given "expression" whatever it wants - it's open. The sec you declare delegate it's black box - wild function pointer compiler doesn't dare to touch in principle. If compiler is not doing anything smart in this version that's his problem => next version :-) We'd actually have to decompile to see. Lambda can do currying. Result can be flat since it's still expression etc. Y-combinator could have some interesting aspects – ZXX Nov 09 '22 at 07:49
  • @ZXX: I disagree - but I'm going to leave it at that, as Stack Overflow comment threads are not meant to be for discussion, which is what this absolutely has become. – Jon Skeet Nov 09 '22 at 07:54
11

Neal Grafter has a blog with a good quote from it on the subject...

In my mind, a language construct is expressive if it enables you to write (and use) an API that can't be written (and used) without the construct.

I'd say that it means you can more naturaly express your thoughts in code.

TofuBeer
  • 60,850
  • 18
  • 118
  • 163
6

That's a tough one.

For me, it has to do with the ease at which you can express your intent. This is different in different languages, and also depends a lot on what you want to do, so this is an area where generalizations are common. It's also subjective and personal, of course.

It's easy to think that a more high-level language is always more expressive, but I don't think that is true. It depends on what you're trying to express, i.e. on the problem domain.

If you wanted to print the floating-point number that has the binary pattern 0xdeadbeef, that is far easier to do in C than in Bash, for instance. Yet Bash is, compared to C, an ultra-high-level language. On the other hand, if you want to run a program and collect its output into a text file, that is so simple it's almost invisible in Bash, yet would require at least a page of code in C (assuming a POSIX environment).

unwind
  • 391,730
  • 64
  • 469
  • 606
2

Here, a very controversial comparison:

http://redmonk.com/dberkholz/2013/03/25/programming-languages-ranked-by-expressiveness/

So, what are the best languages by these metrics?

If you pick the top 10 based on ranking by median and by IQR, then take the intersection of them, here’s what’s left. The median and IQR are listed immediately after the names:

Augeas (48, 28): A domain-specific languages for configuration files

Puppet (52, 65): Another DSL for configuration REBOL (57, 47): A language designed for distributed computing

eC (75, 75): Ecere C, a C derivative with object orientation

CoffeeScript (100, 23): A higher-level language that transcompiles to JavaScript

Clojure (101,51): A Lisp dialect for functional, concurrent programming

Vala (123, 61): An object-oriented language used by GNOME

Haskell (127, 71): A purely functional, compiled language with strong static typing

Community
  • 1
  • 1
AA.
  • 4,496
  • 31
  • 35
1

http://en.wikipedia.org/wiki/Expressive_power

Yardena
  • 2,837
  • 20
  • 17
  • 3
    I didn't find that article to be a clear example of expressiveness in computer programming (what the OP is looking for). It's not very expressive. Also by its primary definition, Assembly and C# would be equally expressive since they can represent the same ideas even though one is clearly more expressive than the other. What other answer's helped me understand is that it's the 'ease' of expressing an idea that makes the difference among other things. – Despertar Jul 12 '13 at 07:43
1

Maybe this site http://gafter.blogspot.com/2007/03/on-expressive-power-of-programming.html can help you

In short he says: In my mind, a language construct is expressive if it enables you to write (and use) an API that can't be written (and used) without the construct. In the context of the Closures for Java proposed language extension, control abstraction APIs are the kind of thing that don't seem to be supported by the competing proposals.

TStamper
  • 30,098
  • 10
  • 66
  • 73
0

I'd make a distinction between expressivity and expressiveness.

Expressivity - expressive power = the breadth of ideas that can be represented and communicated in a language (with reasonable effort)

Expressiveness - ability to express complex things in a compact way without having to spell out details - the opposite of wordiness (this goes down to "easier to write or understand" or compactness of expression(s) ) This definition is used by that controversial article already mentioned.

The qualifier (with reasonable effort) serves to avoid the sharp edge (and contrived stretches) of "at all" (people "proving" that "everything" can be written in language X even though it's clearly not meant for "that" - example mad "proofs" that "imperative/iterative algo can be written in XSLT")

With these definitions we can reason how expressiveness and expressivity can be antagonists. So called "higher"/declarative languages usually have high expressiveness (compact expressions denote functionality of hundreds, thousands lines of code) but substantially decreased expressivity. They achieve compactness of expression by restricting the domain (things they can work with, ideas one can express in them).

Strictly functional languages have to do huge acrobatics to express very simple things (like counting) if they can at all. When they can't they are incomplete and relegated to a rather narrow, specialized, application.

One thing we didn't touch on is performance. Language that can't give fast result gets relegated to academic, sketching, experimental use. Would you call a language "more expressive" if the same algo runs 100 times slower in it? You'd call it a waste of time :-)

High expressiveness (easier to write or understand) tends to cost a lot of perf, high expressivity usually lets you choose whether to do (approx) the same algo with "lower" (faster) or "higher" (slower) constructs.

Python is good example since it mixes constructs with high expressivity and expressiveness (it's not by chance that it's so bellowed) - as long as they are not mixed that is :-) You'll see articles (including here on StackOverflow) comparing how using very different constructs for the same problem can result in huge perf differences. But it's the fact that you do have a choice (high expressivity) that gives you reasonable trust that you will find (measure) the fastest way - eventually :-)

Quite recent debate: Gremlin vs Cypher (on its way to be enshrined as GQL standard). Cypher is praised for being simple, easier to learn, declarative. But it can't express algos/tactics (in graph crawling) that Gremlin can even in theory and is 100-200 times slower - by admission of the team/company that's writing it and popularizing.

This is why it's important to be aware whether you are talking about expressivity or expressiveness and not reduce it to a vague "expressive".

High expressivity of Gremlin lets you use declarative and imperative "way" as needed and write whole crawler as "engine" (shall we say FSA :-) When I was writing a system with very complex graph crawling, crawlers were in strict C++ (modern - lambdas, higher order templates, packs) based on the style/concepts of Gremlin (you have to think in terms of a crawler being active, 'live' and how far (in the future :-) he can look if you want any chance of being fast).

Gremlin vs Cypher situation is very interesting exactly because they are almost diametric opposites - Cypher all expressiveness (all the way down to simple,easy,declarative), Gremlin all expressivity. If you are writing missile navigation (or algorithmic trading) which one would you chose? How would you know where to look if you call both "expressive" ? :-)

ZXX
  • 4,684
  • 27
  • 35