Expressive Programming

0 views
Skip to first unread message

Saustin Grody

unread,
Aug 5, 2024, 12:15:28 AM8/5/24
to netarvintwax
Adifferent 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.)

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.


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


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.


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 :-)


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.


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" ? :-)


Third-tier languages are heavily biased toward high expressiveness. Of the 15 third-tier languages on this list, 8 are in the top 1/3 of languages, leaving only 7 are in the remaining 2/3. Although these data do not directly show any correlation between age and expressiveness, it seems reasonable that newer, more expressive languages would begin less popular and may grow later.


Looking at the box plots again, I would tend to rule out eC based on the poor performance of the upward-reaching whiskers at the 90th percentiles, indicating a real lack of consistency as often as a quarter of the time (since the 75th percentile is quite good). I would also rule out Puppet and Augeas because they are DSLs.


I like to see hard data but I guess the problem with any exercise like this are the confounding variables. I have a hard time accepting that Javascript is less expressive than Java for example. There are probably reasons why this occurred however those reasons have to be guessed at.


For instance, if I want to code something fast, which is easy to express, then I will often use perl or python. Curiously those languages have a downside, which is they are difficult to read after the fact, if you want them to be efficient, despite being easy to express a concept.


I know and use several of the languages there and I think that Javascript might be a bit of an outlier. I wonder if this is because many projects include pre-packaged libraries like jQuery in their source code. Whenever they update a library it makes a huge impact on their delta. Also, many web-focused projects minify their Javascript which can wreck havoc on an automated analysis tool.


Perhaps rosettacode would be a better place to look given that these are problems where the same exact problem is being solved by each language? Having casually studied that site though, it seems like your results would match well to me.


There is also a slightly earlier variant called J (then came K!). J was developed by Iverson and Hui back in the early 90s and is a synthesis of APL, FL and FP. It is suited more for mathematical and statistical programming. It is also FOSS and under the GPLv3 license. Check out the wiki.


Another example are behavioral signals causes by different best practices across language communities. For example, some language communities are much more invested in ad-hoc code reuse, so large pieces of code are copied from one code base to another, or from the internet.


Also the edit behavior is largely dependent on tools. In languages with refactoring support we can expect engineers to touch much more code at once because tools enable them to do so without fear. Which again leads to larger commits.


Do you think the behavioral differences should reasonably be expected to apply to entire classes of languages, like functional programming? I would expect larger-scale trends across multiple languages to be more resistant to some of the points you mention.


When counting lines of code, it is no surprise that Lisp-like languages made a strong showing, given their minimal syntax. They also have no static type system, which is another very interesting factor to me. Any static type system will require some amount of type annotation, and that will have an impact on conciseness. If it were possible to identify which tokens were purely for the sake of type annotation, then comparing the metrics with and without those tokens included would be very interesting.


You forget that an expressive language can be used in an un-expressive manner. Good developers tend to produce succinct and elegant code using the full range of features of the language. Code of average developers is significantly more verbose. Bad developers sometimes produce mountains of copy-pasta.


Still, the experiment is an interesting start. The next step would be to take the number of developers into account and to model the probability of a developer using a particular language being above/below average


Thanks for your article! I have a question about the data collection process: How did you obtain the monthly LOC per commit numbers? Did you divide the total monthly LOC added for a project by the total monthly number of commits? Or are you able to get data on the individual commits and get the LOC added from those?


This study needs to be weighed by the age of the programming language because there is a huge amount of fortran code being maintained by professeurs who are not modern day computer scientist. Who do not know how to organize their code so that changes do not have to be sweeping. These guys had no idea of object oriented programming. Fortran and OOP is an oxymoron aamof.


In computer science, the expressive power (also called expressiveness or expressivity) of a language is the breadth of ideas that can be represented and communicated in that language. The more expressive a language is, the greater the variety and quantity of ideas it can be used to represent.


For example, the Web Ontology Language expression language profile (OWL2 EL) lacks ideas (such as negation) that can be expressed in OWL2 RL (rule language). OWL2 EL may therefore be said to have less expressive power than OWL2 RL. These restrictions allow for more efficient (polynomial time) reasoning in OWL2 EL than in OWL2 RL. So OWL2 EL trades some expressive power for more efficient reasoning (processing of the knowledge representation language).[1]

3a8082e126
Reply all
Reply to author
Forward
0 new messages