What would the perfect programming language look like?

Lt_Storm

Ars Praefectus
16,294
Subscriptor++
But we've successfully made it into the 21st century, ffs! Monitors literally span whole walls, so there's very seldom the need to split one line into more (I also doubt the readability/maintainability of such code). And the computing power in each machine is more than enough that a compiler should be able to determine a coding line's ending on its own. Here's a hint: look for line breaks!

IDK, Realistically, the width of your monitor doesn't matter so much, as keeping things reasonably narrow helps with readability and you can look at multiple files side by side. Moreover, multi-line statements seem common enough to me, pretty much every time you use some fluent builder or streaming API, you are going to have a statement that isn't readable unless you break it across multiple lines.

That said, languages like Ruby handle this elegantly enough, and the perfect language terminates statements with parentheses anyway, more elegant tools from a more civilized age and all.
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
Re must line statements/expressions.

When cleanly used in data pipelines (IME extremely common in lots of LOB, finance and scientific programs) the pipeline operator from F# (I assume stolen from ML and before from anything else similar, it’s an obvious tool in an FP language) is incredible and in any non trivial use case should be multi line to make it clear to read/explain/debug/diff/lots more.

You need to design all your apis to play nice with it though. For me it’s one of the few things in F# I found a slam dunk in readability over equivalent C# without any speed sacrifice or later confusion.
 

timezon3

Ars Scholae Palatinae
1,477
Subscriptor
I'm good with semicolons dying, but I prefer keeping the { }. I'll be honest though, with a good ide with scripted formatting, that stuff matters a lot less. I spent the first twenty years of my career writing (vhdl/verilog) with gvim and not much automation. I'm now writing in scala with vscode and scalafmt set up and it's nice to just write shit, save the file, and have it end up "how it's supposed to be".
 

Lt_Storm

Ars Praefectus
16,294
Subscriptor++
pipeline operator from F# (I assume stolen from ML and before from anything else similar, it’s an obvious tool in an FP language) is incredible and in any non trivial use case should be multi line to make it clear to read/explain/debug/diff/lots more.
That strikes me as similar to the threading macros in Lisp / Clojure. The big difference seems to be that you have to use it repeatedly to actually thread multiple expressions.

Honestly, I wonder how one could define such an operator in F#... This kind of infinite argument operator seems to be one of the bigger weaknesses in HM typing.
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
Wouldn't it be nicer to have this ease of use without the crutch of code editor software?
It’s not a crutch. That’s like calling a hammer a crutch because you could “just hit it with the back of your screwdriver”

Tool use is a huge enabler and, like apes, corvids, octopuses and a few others humans using them is a demonstration of mental and physical agility.

Yes, Morpheus is right that “tools can be the subtlest of traps”, but I don’t think I am infusing my very essence into Rider. I’m likely not using it in my next job so we will find out…
 

timezon3

Ars Scholae Palatinae
1,477
Subscriptor
Wouldn't it be nicer to have this ease of use without the crutch of code editor software?
You're always going to have to write the code in something. May as well have it help you. Is your contention that a language that uses whitespace or indentation to replace brackets is easier to code without a fancy editor? I think I'd disagree with that. I think such a language would pretty much require a fancy editor.
 

iljitsch

Ars Tribunus Angusticlavius
8,474
Subscriptor++
Sure, a code editor can make some stuff better because it understands what you're trying to do. For instance, apply consistent indentation.

But other stuff, such as handling { } blocks, is just a bandaid over something that could/should be fixed on a more funamental level. As I wrote earlier, there is really no reason why you couldn't use indentation to make blocks in C-like languages (keeping { } for unusual circumstances like a block on a single line).

Or pretty much forbid = in a conditional. Sure, if you have an old code base that needs this for insane reasons, have a flag to make it compile anyway. But an = in a conditional is a mistake 99.9% of the time. And this is probably one that code editors can't really handle on their own.
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
Or pretty much forbid = in a conditional. Sure, if you have an old code base that needs this for insane reasons, have a flag to make it compile anyway. But an = in a conditional is a mistake 99.9% of the time. And this is probably one that code editors can't really handle on their own
I have never, ever in C# or Java had a bug from a single ‘=‘ not get immediately trapped by the compiler or intellisense.

Languages post C and C++ did fix it.

The reason you can want it is the idiom if:
Code:
while(var line = f.Readline() != null)
{
    // do something with line
}
I think trying to make that idiom clearer but still fast is an interesting one. Out variables and TryReadLine can achieve it, but at some cost (inline variable definition helps there) but there’s a bunch of boilerplate on the producer side. Implicit variables like Perl are IMO horrible unless you spend all your time in it. Callback functions are elegant, but without some fancy compiler rewriting are slow.
Converting the stream to an enumerator does the trick, but again requires boilerplate the producer side (more so to be allocation free unless you can rely on automatic stack allocation)

I think ultimately the latter is the best approach, and making it easier for the boilerplate to be reduced there is the way forward.
 

ImpossiblyStupid

Smack-Fu Master, in training
81
Subscriptor
But other stuff, such as handling { } blocks, is just a bandaid over something that could/should be fixed on a more funamental level. As I wrote earlier, there is really no reason why you couldn't use indentation to make blocks in C-like languages (keeping { } for unusual circumstances like a block on a single line).
Now you're going to have to describe how it is you'd be putting a block on a single line without a non-newline statement delimiter like ;

I've developed in so many languages in my career that I can't remember the last time I gave two hot damns about syntax. There's nothing that needs to be "fixed" about using delimiters that also doesn't needs to be "fixed" about making whitespace significant.

I don't know that there's a perfect programming language to be had, but if there is, it will also supplant Esperanto.
 

iljitsch

Ars Tribunus Angusticlavius
8,474
Subscriptor++
I do prefer BASIC's more "outspoken" approach. It makes it easier to spot what is missing, e.g. "End If / End Sub / End Select expected".
Then you should definitely check out the various Unix shells. :p

What you mention here is a later evolution of BASIC. It used to be like this:

Code:
 1860 IF H=1 THEN C$=CHR$(A1+C1-1):SR=C2+T:GOTO 1880
 1870 C$=CHR$(A1+C1-1+T):SR=C2
 1880 GOSUB 300:C$=C$+SR$:CP$(B,T+1)=C$

So when the IF on line 1860 evaluates to true, everything from THEN to end of line is executed. So you need that GOTO to skip over line 1870 that handles the ELSE situation.

(For those of you new to BASIC: the $ indicates that a variable is a string or a function returns a string. Other variables are always / by default floats.)
 

iljitsch

Ars Tribunus Angusticlavius
8,474
Subscriptor++
Now you're going to have to describe how it is you'd be putting a block on a single line without a non-newline statement delimiter like ;

Well, obviously I wouldn’t want to make half a century worth of C code no longer compile. So if you want:

Code:
if (a == 1) { b++; c -= 2; }

Then who am I to take that away from you? So keep it like that. Now obviously anyone on board with the new system would make it like this:

Code:
if (a == 1)
  b++
  c -= 2

Which is of course means the exact same thing as:

Code:
if (a == 1) {
  b++;
  c -= 2;
  }

I've developed in so many languages in my career that I can't remember the last time I gave two hot damns about syntax. There's nothing that needs to be "fixed" about using delimiters that also doesn't needs to be "fixed" about making whitespace significant.

Well, the only thing that I can say is that wrangling nested blocks enclosed by { } with just vi can get quite annoying. Sure, I should have adopted a code editor or at least enabled some helpful vim features a decade or two into adopting the habit of writing C, PHP and JS code, but somehow I never got around to that.

But then I discovered Python and although it’s annoying in a myriad of its own unique ways, I firmly believe indentation to create blocks is the right approach.

(For instance, I stupidly used the range() function in a Python for loop. Seemed to make sense. Until I realized that for 200 million iterations, this created an array of 200 million numbers in memory...)

I don't know that there's a perfect programming language to be had, but if there is, it will also supplant Esperanto.

Tio estas sen diri.
 

ramases

Ars Tribunus Angusticlavius
7,569
Subscriptor++
I have never, ever in C# or Java had a bug from a single ‘=‘ not get immediately trapped by the compiler or intellisense.

Yeah, pretty much this.

The same goes with parentheses do demarcate blocks: The most common source of bugs with that is that in eg C you can use parentheses-less single-body-line conditional block, and that class of bugs is trivially exclude-able by placing a linter and/or static code analysis into your workflow.

Meanwhile I do have seen bugs caused by significant white-space, and unfortunately the class of errors produced by it is not exclude-able by static source code analysis.

Ultimately, I want languages not to encourage stupid bugs. Allowing a class of bugs exist that do not have to exist over aesthetics concerns is stupid, especially if those concerns are trivially solvable with modern editors. With a properly set editor typing flow in C#/Java is not really different from Python; if you want to, any IDE worth using will happily insert a newline and position your cursor correctly as soon as you type '{'; likewise, if you really hate looking at those characters so much you can just configure your IDE to de-emphasize them.

Whether the { goes on a separate line or after the conditional is an aesthetics/code-style discussion because choosing either answer does not create/alleviate code quality problems. Choosing between explicit block demarcation and significant white space is not, because choosing explicit block demarcation solves certain code quality problems while significant white space increases them.

It’s not a crutch. That’s like calling a hammer a crutch because you could “just hit it with the back of your screwdriver”

Tool use is a huge enabler and, like apes, corvids, octopuses and a few others humans using them is a demonstration of mental and physical agility.

Yes, Morpheus is right that “tools can be the subtlest of traps”, but I don’t think I am infusing my very essence into Rider. I’m likely not using it in my next job so we will find out…

Quite so.

I've had a number of developers who wanted to edit their code in vim, emacs or other editors without built-in code assist, inspections and similar. Very few of them were able to produce code of the same quality than comparably skilled developers who were using a good IDE. Their code kept containing bugs of types the tool-using developers simply did not make, or far less frequent.

What is more, when I sat down with them to discuss it and made them use an IDE instead vim or whatever, after an adaption period their rate of "bugs likely prevented by code inspection" bugs went down to the same level of everyone else.

Could I have instead worked with them how to avoid those bugs through other methods like working on their coding discipline? Perhaps. But professional development time is a limited commodity, and overall I prefer to focus it on areas where the genuine human input of a skilled developers matters, instead of trying to make the developer better at a job the computer could do for them.
 
Last edited:

koala

Ars Tribunus Angusticlavius
7,579
I was researching git filter/smudge the other day, and really if you have a reversible transform for your language, you can program with whatever syntax you like and you could even collaborate with others and they wouldn't even be aware.

I'm also surprised that there are no languages that emphasize more the AST and which provide "AST editors". With some "styling" you really could choose to use any syntax you like.

(But perhaps it's because, ultimately, syntax does not matter that much.)
 

iljitsch

Ars Tribunus Angusticlavius
8,474
Subscriptor++
What is more, when I sat down with them to discuss it and made them use an IDE instead vim or whatever, after an adaption period their rate of "bugs likely prevented by code inspection" bugs went down to the same level of everyone else.
In other words: those syntaxes are a significant problem.
 

fitten

Ars Legatus Legionis
52,251
Subscriptor++
Back in the day we didn't have all the fancy IDEs and such but got along pretty well... emacs and vi could do some things but you just learned. And if you did make a mistake by doing something like forgetting the }, the compiler caught it because it could. I'm just not a fan of invisible characters being significant program structure... I don't think I'll ever be (and I do program a bit in Python... I like the language except for that).
 

koala

Ars Tribunus Angusticlavius
7,579
Optimizing a language for use with a "dumb" editor is a choice a language designer can do, and it may be beneficial in some scenarios. But it's likely going to make a language less desirable for my usual tasks.

My job won't give me money if I edit with notepad instead of Emacs with LSP and rust-analyzer. They give me money to deliver value to customers. Using a smart editor helps me achieve that goal. The benefits of a smart editor (in my scenario) vs. its costs are so great, it's a no-brainer.

There can't be a "perfect" programming language in all scenarios. Language design has unavoidable tradeoffs.
 

Lt_Storm

Ars Praefectus
16,294
Subscriptor++
I've had a number of developers who wanted to edit their code in vim, emacs or other editors without built-in code assist, inspections and similar. Very few of them were able to produce code of the same quality than comparably skilled developers who were using a good IDE. Their code kept containing bugs of types the tool-using developers simply did not make, or far less frequent.
Slander! Emacs is every bit as capable of code analysis, inspections, refactoring, and similar as any IDE. It is, after all, an entire operating system. The specific package for analysis and inspection is flymake or flycheck. emr does refactoring. lsp-mode does language servers for various languages. yasnippet does code snippets. There are more. Anyone who is using Emacs and yet, somehow, lacks tooling is using Emacs incompetently.

I could probably write a similar defense for vim, as it does have many competent plugins. But, frankly, the defense works less well there. Usually people who pride selves on their vim use think it's good because it doesn't do much, and that view does deserve your scorn. Frankly, if you are a dev who uses Vim, you probably would be better off with Emacs in evil-mode, it is, after all, a better vim; or any IDE with vim emulation, which is, I believe, every IDE.

I'm also surprised that there are no languages that emphasize more the AST and which provide "AST editors". With some "styling" you really could choose to use any syntax you like.
The language is Lisp, and the AST editor is Emacs* in paredit mode (which is available for other IDEs as well). It is super handy and powerful.

You also might be interested in parinfer, which operates based on indentation.

* Not that these two tools aren't available in something like Intellij, it all just originated in Emacs.

(But perhaps it's because, ultimately, syntax does not matter that much.)
Most of that stuff I just mentioned works so well because of Lisp's syntax. So, no, ultimately syntax matters very much. To the point where such interesting ideas become very difficult given the syntax of the average programming language.

On the other hand, smartparens gives the same kind of functionality for other languages (and Lisp too), so perhaps you are right about syntax not mattering too much. (But you will still have to live without parinfer)

I'm just not a fan of invisible characters being significant program structure...
Frankly, I think the entire idea of invisible characters is sort of an editor bug...
 

ramases

Ars Tribunus Angusticlavius
7,569
Subscriptor++
In other words: those syntaxes are a significant problem.

You have a much to narrow view on what realtime static code analysis can do these days, at least for some languages. The same observation I offered not only covers syntax issues and semantic issues but whole classes of genuine logic bugs.

IntelliJ can, for example, detect incompatible bitmasks, incorrect bitshifts, use of APIs that are deprecated or slanted for removal, type erasure issues for example leading to a conditional (like one calling Collections#contains() ) always being false, nullability-hazards, finally-blocks that do not handle exceptions properly, and many more.

Slander! Emacs is every bit as capable of code analysis, inspections, refactoring, and similar as any IDE. It is, after all, an entire operating system. The specific package for analysis and inspection is flymake or flycheck. emr does refactoring. lsp-mode does language servers for various languages. yasnippet does code snippets. There are more. Anyone who is using Emacs and yet, somehow, lacks tooling is using Emacs incompetently.

Okay, that's true. Besides using those packages, if whatever other analysis package you are using offers a callable interface you can integrate it into Emacs, too. It would even be fair to say that in those scenarios you've chosen to implement your own IDE within the Emacs operating system ;)
 

iljitsch

Ars Tribunus Angusticlavius
8,474
Subscriptor++
That's a logical fallacy, arguing a subjective tautology. Explain what "syntax that doesn't get in your way" is, preferably with examples.
Here’s a good one. JSON works like this:

Code:
{
    "name": "Amiga American",
    "type": "ISO",
    "winshortname": "US-U07P",
    "winlocalename": "en-US",
    "winlocaleid": "00000409"
}

So after every key/value pair, there’s a comma. Except the last one. This is syntax that gets extremely in the way. Now obviously editing JSON by hand is not high on the list of best ideas ever, but you can see how copying/pasting stuff around so something else is now the last pair easily leads to a comma too many here or one too few there. And when writing code for generating JSON you always have that annoying special case to consider. ALWAYS having the comma wouldn’t get in the way.

Not strictly syntax, but compare the Javascript XMLHttpRequest constructor. It has all kinds of cool features, but if you just want to do something simple with no error checking, you still need a good amount of boilerplate. You use this to send a request to the HTTP server and receive a response.

Then there are server-sent events using EventSource. With this, you open a connection to the HTTP server and then wait for messages to arrive as it pleases the server to send them. If the connection goes away, it’s reopened automatically. The brilliant part: even though it does more than XMLHttpRequest, it’s just opening the connection and installing an event handler, so two lines of code and you’re up and running!
 

fitten

Ars Legatus Legionis
52,251
Subscriptor++
And when writing code for generating JSON you always have that annoying special case to consider.
If you are writing JSON generating code, hopefully you are a package/subsystem writer because if you're not one of those, you shouldn't be doing it. You should be using a package/subsystem to generate JSON for you.
 

iljitsch

Ars Tribunus Angusticlavius
8,474
Subscriptor++
If you are writing JSON generating code, hopefully you are a package/subsystem writer because if you're not one of those, you shouldn't be doing it. You should be using a package/subsystem to generate JSON for you.
I tried to remember whether I ever actually did write code to generate JSON. I can't remember, so probably not. PHP and Javascript both have functions to handle this.

But in general I really don't like importing dependencies (hence no node.js for me!) so for instance I do have some code that creates XML the hard way.

But my point on that comma stands. Why create a text-based format and then make it hard to actually edit it? If you don't want people messing with your stuff binary is better.
 

fitten

Ars Legatus Legionis
52,251
Subscriptor++
I tried to remember whether I ever actually did write code to generate JSON. I can't remember, so probably not. PHP and Javascript both have functions to handle this.

But in general I really don't like importing dependencies (hence no node.js for me!) so for instance I do have some code that creates XML the hard way.

But my point on that comma stands. Why create a text-based format and then make it hard to actually edit it? If you don't want people messing with your stuff binary is better.

I'm not a huge fan of JSON anyway. I have lived a long time on the database/server side of things and having a verifiable data contract (XSD + XML) for data transmission has been a massive time saver (for getting new customers up and running... give them a sample data file and the XSD and let them tool their intake system to it and/or their output to us) and useful tool many times over the years.
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
Here’s a good one. JSON works like this:

Code:
{
    "name": "Amiga American",
    "type": "ISO",
    "winshortname": "US-U07P",
    "winlocalename": "en-US",
    "winlocaleid": "00000409"
}

So after every key/value pair, there’s a comma. Except the last one. This is syntax that gets extremely in the way. Now obviously editing JSON by hand is not high on the list of best ideas ever, but you can see how copying/pasting stuff around so something else is now the last pair easily leads to a comma too many here or one too few there. And when writing code for generating JSON you always have that annoying special case to consider. ALWAYS having the comma wouldn’t get in the way.
JSON has many warts precisely because people didn't think about the syntax, it's just a legal subset of Javascript (itself a very poorly thought out language[1]. JSON5 really is not that lame in syntax terms - if your in dotnet and using JSON.net then it actually accepts JSON5 so you can do trailing commas.
Note that c# made the trailing comma on lists optional for just this reason (makes many simple 'append on the end' git merges way simpler too)

That you complain about the comma there is not a failure of the comma it's a failure of the design to make using commas as separators pleasant (and it's really pretty trivial to fix, it's just back compat is hard)

YAML has no commas and is shite to write by hand IME, it has a bunch of other issues - in part thanks to it trying to have less syntax.

1. not knocking it, it got done by one person in days and then massiive amounts of commitees have been trying to sort it ever since.
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
Not strictly syntax, but compare the Javascript XMLHttpRequest constructor. It has all kinds of cool features, but if you just want to do something simple with no error checking, you still need a good amount of boilerplate. You use this to send a request to the HTTP server and receive a response.
There's no syntax involved there at all, that's API design. I don't use it so wouldn't comment from any place of expertise on the validity of the claim (though I think you are correct), but I believe that's utterly deprecated now by fetch so obviously someone agreed with you a few years ago...
 

snotnose

Ars Tribunus Militum
2,747
Subscriptor
Why have a comma at all in the first place?
Because if you remove it you create a compatibility nightmare. It won't be long until someone with a comma-less file parses it with a comma-required parser they can't/don't want to "upgrade".

Python did this a while back and people are still bitching about it 10+ years later.

Feel free to create your own markup, call it anything you want except .xml, and let the world judge it.
 

Hagen Stein

Ars Praetorian
567
Subscriptor
Because if you remove it you create a compatibility nightmare. It won't be long until someone with a comma-less file parses it with a comma-required parser they can't/don't want to "upgrade".

Python did this a while back and people are still bitching about it 10+ years later.

Feel free to create your own markup, call it anything you want except .xml, and let the world judge it.

Yeah, I know. But why even design it that way? or keep designing languages that still need ";" as a command delimiter?

And that's one reason, why I actually do prefer XML over JSON.
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
Yeah, I know. But why even design it that way? or keep designing languages that still need ";" as a command delimiter?

And that's one reason, why I actually do prefer XML over JSON.
Because it can be useful. On balance I think I wouldn't include it myself in most new languages, but I'd be interested to see how it would play with integration of a first class REPL (f# requires you use ; for example) and how well intellisense like facilities can work without it.
 

ImpossiblyStupid

Smack-Fu Master, in training
81
Subscriptor
Yeah, I know. But why even design it that way? or keep designing languages that still need ";" as a command delimiter?
It's hard to take any arguments against punctuation for any language seriously. Perhaps the better argument for the "perfect" language would be to allow delimiters to be optional to the extent they can be inferred/unambiguous to the parser. I know Ruby is very flexible in that fashion:

Ruby:
puts('this is cool');
puts 'so is this'

And that's one reason, why I actually do prefer XML over JSON.
While markup for data formats is a whole different ball game, it's also hard to take seriously arguments against blocks being delimited by {} and in favor of them being delimited by <thisnonsense:item></thisnonsense:item>.
 

Apteris

Ars Tribunus Angusticlavius
8,938
Subscriptor
I know Ruby is very flexible in that fashion:

Ruby:
puts('this is cool');
puts 'so is this'
I hate this sort of thing. There is enough complexity in the world to last us ten lifetimes, don't give me more than one syntax for the same thing.

Speaking of which: for, while, do... while. Anyone else in favour of eliminating two of these? Any two, though personally I'd prefer to get rid of the while and do... while.