What does "expressive" mean when referring to programming languages?
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?
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.)
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.
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).
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
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" ? :-)