I love PL research, for all its warts. I worry that it's wasted on most programmers, because we don't get a comprehensive pedagogy of each type of problem that these abstractions are meant to solve, and contexts where a less abstracted approach is preferable. The result is the much maligned cargo cult method - presented with so many options, we invariably end up with all of them put into production at the same time, for the wrong reasons. Experience is gained through a combination of guess and check, and rumor.
A lot of the confusion with current PL science as it's presented to programmers is in the emphasis on mathematical methods. Restrictions that are proven to improve statistical metrics or lead to important technology within the toolchain get dismissed on the regular as being incomprehensible or incompatible with "my style". Surface changes get the majority of attention, bad or good.
The PL designer has a tough job in that, if they're going for the general purpose crown, they have to comfort the nervous creatures that are ordinary programmers while also incorporating the best practices of the known science.
I think a better illustration of the usefulness of PL research is to compare the languages produced my Microsoft and Google.
Microsoft produces C# and Typescript. Google produced Go and Dart. I think it's fair to say that C# is a better language than Go. The biggest flaw in Go (lack of generics) is met with the weak excuse that they haven't figured out how to do it right. I don't know much about Dart, but Typescript is a stellar language.
Microsoft has a lot of PL expertise in house, including Simon Peyton Jones. Their languages clearly benefit from expertise in PL theory. Google, on the other hand, favors pragmatism over theory and prefers to draw on software engineering experience. Google's languages aren't bad, they just don't seem to have much going for them as languages. Their failings are partly made up for in other things, like the toolchain, libraries, etc.
So I think looking at these real world examples, it's clear that PL theory does lead to better languages, even when one excludes languages like Haskell with little industry adoption.
> Microsoft has a lot of PL expertise in house, including Simon Peyton Jones. Their languages clearly benefit from expertise in PL theory. Google, on the other hand, favors pragmatism over theory and prefers to draw on software engineering experience.
Google has ALOT of PL expertise in house, so much so that a lot of them don't work on PL. There language design is actually quite competitive to Microsoft's, on the theory, design, and implementation sides. Whenever we go to conferences, you'll usually have similar numbers of current and ex-academics from MS and Google.
We have a joke in the PL research community that most of them are working on...ads. But really, there is a lot of PL work that you don't see that doesn't exactly involve new languages (e.g. adding asynch to JavaScript, compiler work, building frameworks, MapReduce, etc...).
Now Apple is the mysterious company that doesn't interact with the research community.
It seems to me that Apple has had a rich history of interesting languages: Squeak, Dylan, Hypertalk, AppleScript and Swift. Those are just the ones I know of.
Pedantic note: it was called Macintosh Common Lisp (MCL), not to be confused with MacLisp, which predates both Apple and Common Lisp and is from MIT's Project MAC.
> I don't know much about Dart, but Typescript is a stellar language.
I don't know Dart either, but I'm wondering how you can compare Typescript and Dart if you happen to know only the former.
> Google, on the other hand, favors pragmatism over theory and prefers to draw on software engineering experience. Google's languages aren't bad, they just don't seem to have much going for them as languages. Their failings are partly made up for in other things, like the toolchain, libraries, etc.
I mostly agree with this.
> it's clear that PL theory does lead to better languages
Languages are not everything. PL theory can also lead to better tools, that work on existing "traditional" languages (the obvious example being static analysis tools).
The best case for learning this stuff is the old adage along the lines of 'Any sufficiently complicated program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of common lisp.' While not exactly true, it definitely rings familiar with some of the bigger projects I've been on. If you're going to have an system that is practically it's own language, it will benefit from you knowing about language design.
I don't think the author actually demonstrated the usefulness of PL research, at least not enough to convince me of it. For that I would need to see actual, regular controlled experiments from PL researchers showing that a given language or construct yields measurable dividends over another, such as reductions in deficits, program size, or development time. Instead what you get from PL researchers is papers full of conjecture advocating some such language or construct, but seldom any scientific evidence to support any of it. Further, programming languages by themselves, in 2015, don't matter that much. Unless a language has an industrial-strength implementation, a robust tool chain, and a vast collection of libraries, it won't, or at least shouldn't, gain widespread adoption.
I think we have far too many languages as it is. Of all the languages I've learned or at least been exposed to, only a handful were genuinely novel, such as Common Lisp/Scheme, Smalltalk, and Haskell, and rest were mere reskins of C. The compile-to-JavaScript languages are easily some of the worst offenders, and it leads me to wonder, how many new languages are the product of a good faith effort to solve a yet-unsolved or poorly-solved problem, and how many spring largely from the vanity of their inventor, who dreams of becoming the next great BDFL, being invited to give keynotes at conferences, and capriciously giving his thumb up or down to enhancement proposal like a Roman Emperor deciding on the fate of a fallen gladiator in the Colosseum?
I actually think we as an industry could benefit from a PL moratorium. How many of us have had to use a language with poor or no IDE support, or one that lacked native code compilation (JiT or otherwise), or that had gaping holes in its standard library simply because it was new and trendy?
It sounds like you missed the point. The point of the article was that a lot of PL research is focused on non pure SE problems/domains.
That is, a large part of the argument was that only a very small amount of PL research is about designing languages that are intended to be used as programming languages in the software engineering sense of the term.
The article gives a myriad of examples of PL researchers who have contributed novel results to non-PL fields of Computer Science by applying PL techniques. In these cases, PL researchers are solving open problems in other areas of Computer Science, such as checking properties of software-defined networks or adaptive Bayesian inference. In these two cases, these are areas where PL researchers applied PL techniques to open problems that other subdisciplines were already studying, and came up with novel and competitive/superior solutions.
In these cases, the "purely software engineering"-oriented metrics/goals mentioned in your post are irrelevant -- the scientific contributions of the PL research exist and can be evaluated independently of the software engineering implications of the work. The language is the methodology, and isn't necessarily intended for use in software engineering.
> For that I would need to see actual, regular controlled experiments from PL researchers showing that a given language or construct yields measurable dividends over another, such as reductions in deficits, program size, or development time.
There's certainly a lack of empirical user research in the field, when the research has that aim.
However, the point of many research languages/features is not that it reduces development cost, etc. but that it exists at all. The article gives examples of non-PL research, eg. the discovery of an incremental algorithm to calculate convex hulls, and these are legitimate results on their own; regardless of whether they "lower convex hull discovery costs", etc. The PL angle is the discovery of general abstractions, eg. a language for incremental computation, of which convex hull discovery is just one of many programs. The discovery of such an abstrction is also a legitimate result on its own; regardless of whether it "lowers incremental algorithm discovery costs"; etc.
These results are a "pure" basis for language and library implementors to work from. If that incremental computation language only existed as, say, a collection of Java classes, then it would be difficult for other implementors (eg. in Javascript) to know which parts of the architecture are fundamental to the approach and which are artefacts of using Java.
Of course, when investigating which primitives to use, there may be no existing language capable of expressing them (short of embedding an interpreter; in which case, you've just created a new language anyway!).
Few academic language creators expect their languages to be adopted. They're usually proofs of concept, or meant to inform and inspire future work. Only a few are meant to be used for real work (for one thing, it places a maintenance burden on the researcher!).
...or "Java with minor improvements". But I think you're talking about PL creators/designers, not researchers. Surely PL researchers don't want yet another reskin of C/Java.
I think a big part of it is that a lot of the traditional programming language researcher obsessions are not that interesting to working developers. For example, proving software correct is used in a very, very small number of cases (mostly safety-critical things like elevators or medical devices), but for most projets the extra development time is nowhere near worth the benefits. Plus for many things like user interfaces, the specification for getting them "correct" may not be any shorter than the code itself (sometimes it's longer.) Elegance and minimalism (how small can you make the language's standard library? etc.) are loved by academics but nobody else cares.
Plus, most academics don't have any awareness that different languages are useful for different things-- because they've never actually done any of the different things. You might want a C-like language to write a kernel, but a TCL or Javascript-like language to write a graphical user interface. Perhaps you want a MATLAB or R-like language to do numerical work. Most PL people don't have any awareness of the different use-cases so they try to produce "the messiah language" that will solve all problems. It never works.
The other thing is that there's not a lot of awareness of the psychological aspects of programming in the PL field. For example, sometimes it is desirable to limit the expressiveness of a programming language in order to make code easier to understand and share between people. These tradeoffs are almost never discussed (I have never seen an academic paper discuss them). Instead languages like Java and Go are ridiculed for the "missing" features (didn't they know that higher-order types were invented by academic language X Y years ago? etc. etc.)
Honestly I don't think including null in the language is a big deal. Academics tend to think it is a big deal because it makes it harder to prove programs correct, but almost nobody does that with Java programs, so it doesn't really matter to most programmers.
null is a natural representation for an optional type. It's efficient because the CPU can implement it by page faulting on null dereferences. Yes, you can have Optional<T> and so forth, but it uses more memory, and Java already has a problem with using a lot of memory.
Even assuming we could somehow solve the efficiency problems with a super-clever compiler and a built-in optional type, the language needs a way to represent the state that an object starts out with. For integers and floats that is 0, for booleans it is false, and for objects it is null. You could argue with the whole concept of imperative programming (and many academics do), but if you have X happening before Y in your imperative program, you better have a way of representing the state of the objects that haven't yet been initialized by Y to X.
C++ got a non-nullable type in the form of references, and it didn't exactly turn the language into a paragon of sweetness and light. It just made things more confusing and annoying since you had to keep flipping back and forth between pointers and refereences, depending on the API you were using. And in typical C++ fashion, they invoked undefined behavior to answer the question of what happened if you accessed a not-yet-initialized reference (for example in a constructor).
There's nothing stopping a compiler from implementing Option<T> as a possibly-null reference when T is a pointer type, which would give you the same efficiency as having nulls in the language while making unchecked usage easy to catch at compile time. (I don't know if any languages do this currently, but there's no reason it couldn't be done. It does turn Option into a special built-in type, but it's universal enough for that to be a decent idea.)
And it's not clear that variables should have values before assignment, beyond "undefined"/"error to use this" -- explicitly initialising a variable to some sentinel value is clearer and safer than relying on the default value being something in particular.
> There's nothing stopping a compiler from implementing Option<T> as a possibly-null reference when T is a pointer type, which would give you the same efficiency as having nulls in the language while making unchecked usage easy to catch at compile time.
Rust does exactly that for its Option<T> type. In fact, it automatically works for a certain category of enums, not just for built-in ones. For example, this type:
enum E<'r> {
A(&'r u64),
B,
}
has the same size as a pointer (because references are guaranteed to be non-null), as has this type:
enum F {
A(Box<u64>),
B,
}
where Box<u64> is an owning pointer to a value on the heap. Rust's Option type doesn't get any special treatment and is not built-in, instead it's implemented like this in the standard library:
There's nothing stopping a compiler from implementing Option<T> as a possibly-null reference when T is a pointer type, which would give you the same efficiency as having nulls in the language while making unchecked usage easy to catch at compile time.
I talked about this in my earlier comment, saying that we could solve the efficiency problem with "a super-clever compiler and a built-in optional type." (To respond to adwn's comment, I would view built-in support for sum datatypes as "built-in support for optional.")
And it's not clear that variables should have values before assignment, beyond "undefined"/"error to use this" -- explicitly initialising a variable to some sentinel value is clearer and safer than relying on the default value being something in particular.
null IS a type which means "undefined/error to use this."
In the particular context of Java, null solves some of the problems of the language, like what happens when a constructor invokes a derived method which reaches up and accesses a not-yet-initialized variable in the superclass. I do think some of these problems could be solved in a different way, but it's not completely straightforward.
I am curious about how Rust solves some of these problems. I'll have to take a look.
null IS a type which means "undefined/error to use this."
It causes runtime errors, rather than compile time ones. It also can move the place an error is detected to elsewhere (since passing null around and sticking it places works fine, right up until you try and use the value you expect), which can be a bit of a pain to trace back.
In the particular context of Java, null solves some of the problems of the language, like what happens when a constructor invokes a derived method which reaches up and accesses a not-yet-initialized variable in the superclass. I do think some of these problems could be solved in a different way, but it's not completely straightforward.
Disallowing method calls before all variables have been initialised in the constructor seems like a relatively simple mostly-fix. For any non-final values, it'd work fine to just set them to some explicit dummy value, and final variables should probably be explicitly assigned anyway. (I can't think of many cases where having computation implicitly operate on undefined values is a good thing...)
Also, to adwn: thanks -- I figured Rust probably did something like that, but haven't really played with it much and hadn't bothered to go check.
> In the particular context of Java, null solves some of the problems of the language, like what happens when a constructor invokes a derived method which reaches up and accesses a not-yet-initialized variable in the super-class. I do think some of these problems could be solved in a different way, but it's not completely straightforward.
That's a non-issue. A derived class shouldn't be able to access any variables from the super-class until after the super-class's constructor has completed. All variables in the super-class should have to be initialized before the constructor completes. The super-class constructor shouldn't be able to read from a variable until after it can be statically determined that it has initialized the variable.
If a class can't work within these constraints, then it can declare the variable as Option<T> initialized to None, and then it is back to the normal Java semantics for that one variable.
> If a class can't work within these constraints, then it can declare the variable as Option<T> initialized to None, and then it is back to the normal Java semantics for that one variable.
By doing that you lose the safety of variables being marked final.
I wish there was a way to seal a variable such that it could not be changed (in the same sense that final works in, not truly readonly) after a certain point, but it could be before then.
I find myself writing far too many variables that should be final, and indeed are final after a certain point, but cannot be marked as such because said point is after the constructor. In particular with lazy-loading.
You can't lazy load a final variable. It has to be assigned in the constructor. If your point is that getting rid of null doesn't solve every single problem that exists, I agree. However, it in no way causes a degradation from the current status quo in nullable-by-default languages.
> Honestly I don't think including null in the language is a big deal. Academics tend to think it is a big deal because it makes it harder to prove programs correct, but almost nobody does that with Java programs, so it doesn't really matter to most programmers.
Speak for yourself. As a professional Java (well, mostly Scala) programmer, not a week goes by without a null pointer exception slowing down development.
> the language needs a way to represent the state that an object starts out with. For integers and floats that is 0, for booleans it is false, and for objects it is null.
No, you don't need a value, you just need semantics for what happens if you do that. E.g. you could make a UninitializedValueException that would only be thrown when you tried to access an uninitialized field. That would be effectively the same behaviour as currently in that case, but it would be much easier to diagnose than NullPointerException, since it can only be thrown when you access an uninitialized field, not e.g. because a map didn't contain a particular entry.
> Even assuming we could somehow solve the efficiency problems with a super-clever compiler and a built-in optional type
This is disingenuous. It's not "somehow" with a "super-clever" compiler. It's a triviality.
> C++ got a non-nullable type in the form of references, and it didn't exactly turn the language into a paragon of sweetness and light. It just made things more confusing and annoying since you had to keep flipping back and forth between pointers and refereences, depending on the API you were using.
That's an argument for not trying to retrofit non-null references onto an existing language. It's not an argument for having nullable references in a new language.
> And in typical C++ fashion, they invoked undefined behavior to answer the question of what happened if you accessed a not-yet-initialized reference (for example in a constructor).
There are varying degrees of "proof", ie. we can have more or less confidence in an argument. In particular, we need to distinguish between "Mathematical proof" and "formal proof".
Mathematical proof is what we tend to think of when we see the word "proof", and it can be defined something like "a thoroughly convincing argument".
A "formal proof" is very different. If we're given a finite set of strings, and a finite set of string-rewriting-rules, then a "formal proof of X" is just "the order in which to apply the rules, such that we turn the given strings into X".
For example, the rule called "modus ponens" says:
If I have strings of the form "X" and "X -> Y", then I can get the string "Y"
If I'm given the modus ponens rule, and the strings "A", "B" and "A -> B -> C", then this is a proof of "C":
1) A -> B -> C (given)
2) A (given)
3) B -> C (modus ponens with 2 and 1)
4) B (given)
5) C (modus ponens with 4 and 3)
When formal proofs were introduced, the idea was to choose the given strings (axioms) and rules such that "formal proof" meant pretty much the same as "Mathematical proof", ie. that formal proofs are convincing and that non-formal proofs aren't.
It's pretty easy to see that type systems (including Java's) are formal systems. The "given strings" are the types with primitive values, ie. I am 'given' the string "bool" since I can always say "true" or "false". The Java equivalents of strings like "A -> B" are methods, with argument type "A" and return type "B". The modus ponens rule says "calling a method with an argument of the correct type gives the result type" (ie. "A -> B" and "A" gives "B"). The Java equivalent of formal proofs are Java programs.
From this perspective, type-checking a Java program is checking the formal proof it represents; ie. ensuring that we only use the rules we were given (anything else is a syntax error, like `bool(5)`) and that the strings match up (eg. that we don't use modus ponens on "A" and "B -> C", which is a type error, like `3 + "hello"`).
> Academics tend to think it is a big deal because it makes it harder to prove programs correct, but almost nobody does that with Java programs, so it doesn't really matter to most programmers.
In fact, it's the exact opposite: every time a Java programmer compiles their code, they are formally verifying that their program is correct. The only Java programmers who don't prove their programs are correct are those few who've never compiled their code.
That might seem pedantic, ie. that I've redefined "proof" to win an argument, but in fact that alternative definition has been around for a century and, more importantly, it is the one PL researchers use (I should know, I am one ;) ).
The reason academics don't like NULL isn't that it makes proving things harder; it's that it makes proving things too easy! Java types are formal statements, by definition; Java programs are proofs of those statements, by definition; we have a whole bunch of machinery for checking these types, IDEs with auto-completion, automated refactoring, etc. so why not use it to prove stuff we care about? For example, a crypto library could encode some security properties as types to make sure consumer classes are using them properly. Then we could have our application require proof that our implementations are correct, like this:
// Works for any LoginComponent, as long as it uses crypto in a provably safe way
final class Application<LoginComponent> {
public Application(LoginComponent lc, UsesCryptoSafely<LoginComponent> proof);
// ...
}
The reason Java programmers don't do this isn't that it's too hard. It's that it's far too easy:
Application<MyLogin> app = new Application(new MyLogin(), NULL);
So easy, in fact, that it's useless: we can use "NULL" to literally prove anything in Java. These are still "formal proofs", but they're very far away from "Mathematical proofs", ie. telling me that your Java program type-checks doesn't convince me that it works the way you want, precisely because the axioms and rules used in Java cannot be used to convince me.
This isn't an ivory tower, pedantic, academical issue; it's an incredibly practical piece of software engineering: we want to find as many bugs as possible for the smallest cost possible. Java is already paying a high cost for its type system, especially since it has no type inference. Yet the existence of NULL undermines it's usefulness for spotting bugs. Basically, Java hits an "anti-sweet spot" where we must annotate everything explicitly and architect our programs to work within the type system's constraints, yet it doesn't give us much confidence that we've squashed bugs.
Compare this to un(i)typed languages like Python, where we don't need annotations and our architectures aren't as constrained; we lose a little confidence but we save a huge cost.
Compare this to strongly typed languages like Haskell, where we're constrained by the type system and we occasionally need a couple of annotations, but we gain a large amount of confidence for that price.
> the language needs a way to represent the state that an object starts out with. For integers and floats that is 0, for booleans it is false, and for objects it is null.
I think you're confusing values with variables. The only value (object, etc.) which is NULL is, well, NULL. You can't change a NULL into an initialised instance; you can only replace it.
You can initialise a variable to be NULL, then redefine it to point at an object later. In that case, I'd say you should either be using an Optional value, or you're initialising your variable too early.
That was a great post! I like the term "anti-sweet spot" for Java's type system, and that's what it truly feels like in practice. Like complex magic spells that aren't that useful in the end.
"In fact, it's the exact opposite: every time a Java programmer compiles their code, they are formally verifying that their program is correct. The only Java programmers who don't prove their programs are correct are those few who've never compiled their code."
I don't think it's reasonable to use all of "prove", "their programs" and "correct" there. Weakening or qualifying any of those could produce a statement I emphatically agree with.
> Weakening or qualifying any of those could produce a statement I emphatically agree with.
My qualification was meant to be "according to the formal systems definition of the words 'prove', 'correct', etc., which was supposed to be applied to consistent systems; yet Java is inconsistent".
Well, I'd actually say that all languages are consistent, it's only particular interpretations of the encodings that may be inconsistent, but that's another discussion ;)
Ah, yeah, when you say you're proving something I think it's worth it to be specific about what, and extra explicit when it differs from the expectations of the audience. There's a lot of "correctness" as used by... anyone not focused on formal systems that is missed by your usage, I think.
Your comment about the lack of 'awareness on usages of different languages' rings so true. Especially for the cases where the research goes into making new 'uber' languages (which was my understanding of most of the research area until reading this article and then investigating more).
I recently watched this talk at UW (http://www.cs.washington.edu/events/colloquia/search/details...) and was frustrated by that exact problem. It is interesting to use data from engineers to determine the usefulness of a language, but you'll still never drive adoption everywhere. There are plenty of other aspects of programming languages which deserve to be applied to other fields of CS and more coverage on the research coming out of those areas.
Currently it is the case that certain languages are better for specific problem domains, but that's mainly a library issue or a platform constraint (e.g. web app -> js). I don't see any reason why we need so many general purpose languages. Domain specific languages, sure. Why do we need so many general purpose languages? What exactly are the design constraints that are fundamentally incompatible between those languages? Case in point: the comment above you cites TCL, Javascript, MATLAB, R as examples of why we need many languages, when all of them are terrible language design. TCL has good built-in gui facilities, Javascript is built into browsers, MATLAB has many scientific libraries, R has many stats libraries. That's why they are used, not because the languages are any good.
> For that I would need to see actual, regular controlled experiments from PL researchers showing that a given language or construct yields measurable dividends over another, such as reductions in deficits, program size, or development time.
You might be interested in Stefan Hanenberg's research:
> Instead what you get from PL researchers is papers full of conjecture advocating some such language or construct, but seldom any scientific evidence to support any of it.
There is PL science and PL design. You won't see much PL design anymore in the academic conferences, they are mostly oriented toward PL science these days. Did you read the article at all? Excerpt:
> But the main point I want to make is that PL research is broader than designing and implementing new languages. To me, a PL researcher is someone who views the programming language as having a central place in solving computing problems.
In other words, PL research is not about designing PLs these days.
> Further, programming languages by themselves, in 2015, don't matter that much. Unless a language has an industrial-strength implementation, a robust tool chain, and a vast collection of libraries, it won't, or at least shouldn't, gain widespread adoption.
That is like saying theoretical physics research doesn't matter much anymore. We are reaping the benefits of 20 year-old PL research today, what about 20 years from now? Have we reached a point where what can be tried and improved in PL has already be done? PL is finished as a field where we can make progress?
> Of all the languages I've learned or at least been exposed to, only a handful were genuinely novel, such as Common Lisp/Scheme, Smalltalk, and Haskell, and rest were mere reskins of C.
What about the experimental languages that you haven't been exposed to? Like that first live programming language called Flogo II in somebodies dissertation? You will never program in that, but it moved us forward.
> largely from the vanity of their inventor, who dreams of becoming the next great BDFL, being invited to give keynotes at conferences, and capriciously giving his thumb up or down to enhancement proposal like a Roman Emperor deciding on the fate of a fallen gladiator in the Colosseum?
Trust me, there is no glory to be had in this game. At best, you'll get your name written down in lots of places, but even Guido van Rossum has a day job.
> I actually think we as an industry could benefit from a PL moratorium.
Because software development will never become software engineering if we continually do the equivalent of changing the number and measure system every five years.
We've gotten better tools for design (say, CAD via Solidworks or Autocad or ANSYS or what have you), but the implementation stuff has been near-constant for almost a century.
And that has meant that we've been able to routinely build gigantic things with hundreds of people that last for decades and can be repaired--software doesn't have the same track record of quality, safety, or anything else really.
That's not a bad thing, mind you; however, our industry does shoot itself in the foot by either mudballing on existing languages or by creating lots of incompatible new languages to solve similar problems. Again, it's as though the mechanical engineers had to learn a new type of math for the same calculations every five years.
Most new programming languages are very incremental. For every Rust and Elm, there are 10 Typescripts, Darts, and Gos. Its like being handed a new and slightly improved AutoCAD every 5 years, which isn't very strange at all. If you leave the industry for 15 years, you might not be familiar with the version of AutoCAD when you come back.
Now the more edgy stuff (say Elm, Rust, even Haskell, and perhaps Scala if you choose to use it that way) IS a bit more different, but adoption is challenging as a result. Its like being handed a new CAD program with a new diagramming paradigm (something AutoDesk would never do, by the way, as their users would kill them).
The functionality is absolutely incremental--but it's the little differences, right, that prevent them from being used together cleanly without passing through some other interface (say, a REST API boundary or TCP connection or something).
To strain our analogy further--it's not like we've got a fundamentally new type of bolt every 5 years...it's that we've got slightly different bolt systems with different diameters that can't be mixed and matched on a project without making maintainers' lives hell. Oh, and in 5 years? The manufacturer is out of business--so sorry about your house door.
Rust and Elm are incremental too. Compare Rust with Cyclone. Compare Elm with the many FRP libraries/languages. Some of those things are presented as new e.g. Elm UI library, but look at FranTk: it was all there and more 15 years ago.
By incremental, I mean, improving on standard practice. Non-incremental meaning something quite different than what you were used to, even if it has been around for...20 years in niche communities.
Your response, colored for me by the downvote I received roughly when you posted it, consists largely of hand waving. Maybe my perception of PL research papers is horribly skewed, but the ones I've read are as I described: conjecture unsupported by evidence. The fact that some researchers are trying to do better is laudable, but it doesn't redeem the field of PL research as a whole.
This bit in particular struck be as absurd:
>Trust me, there is no glory to be had in this game
Humans naturally crave fame, and programmers are no exception. Look at all the developers with Github and Twitter profiles and blogs; are you telling me these people don't want attention?
Inventing a programming languages is one of the few ways that's been shown, on occasion, to make a programmer famous. We all know who Larry Wall, Matz, and Guido are. Frameworks, both front-end and back-end, are another (and I suspect that's part of the reason why we're up to our neck in JS frameworks). Look at DHH, for example. He's a programmer of modest ability who got so famous through Rails that Alan Kay quotes are mis-attributed to him, meanwhile I doubt you know who Daniel Veillard is, despite him being the principal author of LibXML2, one of the most heavily-used pieces of software in the world.
> Maybe my perception of PL research papers is horribly skewed, but the ones I've read are as I described: conjecture unsupported by evidence. The fact that some researchers are trying to do better is laudable, but it doesn't redeem the field of PL research as a whole.
I have the totally opposite opinion: the PL academic community has shifted very much in the science direction so much so that innovative and inventive design work no longer really has a place in their conferences (contrast to the 90s, when this work dominated). Science doesn't take you very far in a design discipline, so as a result we have seen the shifts in focus that the article discusses (away from PL design, toward PL-related science topics).
> Humans naturally crave fame, and programmers are no exception. Look at all the developers with Github and Twitter profiles and blogs; are you telling me these people don't want attention?
Is anyone who does anything and puts it out there craving attention? Maybe they just want to, I don't know, share. There aren't a lot of PL groupies worshiping Roberto Ierusalimschy, for example (who is quite a modest guy in real life). I hang around these people, they don't have particularly large egos.
> We all know who Larry Wall, Matz, and Guido are.
But did you know who Roberto was? Would you be able to pick out Gilad Bracha in a grocery store? I also know who Paris Hilton is, yet she (probably) isn't a PL designer.
>Is anyone who does anything and puts it out there craving attention? Maybe they just want to, I don't know, share.
I never said everyone was motivated purely by vanity, just that it is a major motivator and possible explanation for certain perceived excesses (of languages, frameworks).
>did you know who Roberto was? Would you be able to pick out Gilad Bracha in a grocery store?
I'm typing these messages on a machine with NewSpeak installed on it.
> I never said everyone was motivated purely by vanity, just that it is a major motivator and possible explanation for certain perceived excesses (of languages, frameworks).
Correlation isn't causation, and frankly, I'm not seeing much correlation. The proliferation of languages and frameworks has more to do with itch scratching.
> I'm typing these messages on a machine with NewSpeak installed on it.
Good, then you know that PL designers can be pretty down to earth and in it because they like doing it vs. seeing it as a path to fame and fortune.
I still see the downvote arrow on steveklabnik's comment though? So you're saying that clicking it won't have any effect? I don't see any downvote arrow on your comment, because it's a reply to mine. Could you downvote my comment that you replied to?
As a working PL researcher, I agree with plsceptic: we, the field
of PL research, have a measurement problem. We don't have empirically
validated and methodologically sound studies that quantify the
"dividends" of one PL or PL feature "over another, such as reductions
in deficits, program size, or development time". To be sure, all
this can be measured in principle, and measurement is one of the hallmarks of being
a science. Alas, things are not so simple:
1. Like with cosmology or string theory, experiements that would
readily decide scientific questions (like Java is a better
programming language than ML) are prohibitively expensive. We could
take 10 million programmers, split them in two groups and let them
use the same problem but with one group using language L and the
other language L'. Let this exeriment run for 10 years. Naturally,
during that experiment, both groups must not, in any form or shape,
communicate with each other. Due to the sheer expense of such an
experiment, it's never going to happen.
2. Like the social sciences, reflective humans are integral part of any
relevant experiement, leading to all manner of problems. For example
the participants could actively sabotage the experiment.
Of course PL research isn't the only field that lacks easy
empirics. And like those, PL shouldn't let the perfect be the enemy of the
good. It's quite clear that PL features do have positive productivity
consequences, with garbage collection being the most clear-cut
example. The interesting question is what do we do the absence of good
empirical methods. One answer, and one that has been supremely
successful is mathematical proof, although there is a real danger of
loosing touch with what's needed on the proverbial 'ground'. Another
answer, and one that is clearly being taken, is to let a form of
social evolution play out: flood the world with programming languages,
and see what happens. The poster complains about this flood and I
understand why this can be seen as a problem, but I see this flood of
new PLs as a sign of PL research's triumph: making new programming
languages (for sequential computation) is now so easy that it's a
frequent topic of undergraduate dissertations. Note the qualifier:
while PL development is essentially played out for sequential computation (except at the margins) and
not a research topic any more, languages for parallel and distributed
computation is a wide open field. Note that there are virtually no
typing disciplines or verification methodologies comparable to
dependent types for non-sequential computing.
I would also like to correct the misconception that PL research is
(soley) about developing new languages. Clearly what's a good language
depends in parts of the application domain. PL researchers are few and
application domains are many. Consequently, a core component of PL
research involves the following activities.
a. Finding repeated patterns in software, and the software construction
and evolution processes.
b. Analysing these pattern mathematically, to find common
abstractions. E.g. monads as generalised sequential composition,
pattern matching, or various forms of interaction as a common form
of computation.
c. Automatising repetitive activities, e.g. compilers, or
testing-tools.
Offtopic: So we're all just calling programming languages "PL"'s now? Why is it so hard for people to type?
(Seriously though, it's a strange kind of memetic behavior, I rarely see it abbreviated as "PL" ever, but in each comment I scan, people are using "PL" here too. It was enough to get me to click the article just to see if "PL" was some new thing I haven't heard of.)
PL is a very common abbreviation in the research community and has been for at least decades. Common usage in academia probably stems in part from the fact that conferences are often named by their initials, so the conference on "Principles of Programming Languages" becomes "POPL" and so on.
I imagine the burden will be mitigated by not requiring everyone to have the same level of expertise. The model I see is an architect using the type and proof system to make a language that describes the problem domain at hand. It is this language that will be for the rest of the team. Now, will it look familiar? I would hope so.
A lot of the confusion with current PL science as it's presented to programmers is in the emphasis on mathematical methods. Restrictions that are proven to improve statistical metrics or lead to important technology within the toolchain get dismissed on the regular as being incomprehensible or incompatible with "my style". Surface changes get the majority of attention, bad or good.
The PL designer has a tough job in that, if they're going for the general purpose crown, they have to comfort the nervous creatures that are ordinary programmers while also incorporating the best practices of the known science.