I hope you can humour me and not challenge the assumptions baked into the question. That's a separate, if interesting, exercise.
A Relational General Purpose Language.
Not table oriented like SQL, but more OOP/Type oriented, I'm not sure exactly how I want it to be, but surely not table oriented.
No concurrency or async to worry about, you write the relations (exactly like you dont worry about SQL on concurrency while writing an SQL query).
Like a JIT/DB Engine, it has a runtime that analyze the data processed, and optimize further the queries. I believe it even could dynamically figure out of embarrassingly parallel problems and sent it to process on the GPU.
But all of this require a lot of work ^^'.
The next leap was LISP Machines and Smalltalk Single Image Systems, where the developer was given a unified vertically-integrated environment further increasing their productivity. Some even called it a "human–computer symbiosis". But unfortunately this approach has not become mainstream, though I worked with some proprietary database systems based on a Single Image System.
Next we had an era of "Application Generators" or "Fourth Generation Programming Languages". They made application developer's job easier and were closer to modern LowCode/NoCode tools.
Modern SDLC is a chaotic collection of different methodologies, practices, techniques, patterns, and tools (the PLs are just one of these tools). They were created in evolutionary way by optimizing for local maximas, and they might missed the global one.
To summarize, IMO what we need is a higher level application development environment supporting all stages of the modern SDLC, not just a new programming language which will solve only the coding part.
- A strong static type system, but not as in-your-face as Rusts. Abstractions must be cheap in runtime, but not so cheap as to come at the price of more complex programs OR SYNTAX. Strong support for things like sum times with exhaustive matching. Generics. No Nulls. Annotations. All the things you expect from a modern language.
- Struct-oriented imperative programming, like Rust. That is: not a functional language, not an OO language, but a focus on imperative and immutable.
- A runtime with a garbage collector, to enable the above.
- Utf8 strings
- A rust like error handling system with catchable panics for "actually exceptional" things, and forced Result/Option types for everything normal.
Having a lot of experience with programming in C++. C# and JavaScript, I have found that many 'creepy' bugs are related to the confusion arising from assigning an object to some member, where a copy is intended, or the otherway around, that a copy is made where a reference is intended. I have not yet come across a language where this is solved and have started working on such a language myself: https://github.com/FransFaase/DataLang
For example, it would tell module main depends on ui, utils and json, ui on graphics (a third party library) utils on encrypt and IO (which are part of the standard library of the language), json on Streams (another part of the standard library).
It also could say graphics doesn’t use reflection, json is thread-safe and O(input size), utils is pure, encrypt is constant-time, and main isn’t restricted in any way.
The compiler would have to enforce both the dependencies (main couldn’t directly call functions in IO, for example) and the properties (if json uses shared state, it somehow must be properly protected with locks/atomics) (this may, in cases, be a research project. Some properties might be better served with a different or more limited language (that’s what dtrace does for its language, to guarantee it won’t loop forever)
That file would serve as documentation. Tools would exist to render it to svg; users would expect their IDE to do that, maybe even in editable form.
Advantage of separating that from the source files would be that it is harder to accidentally change that information. Spotting them in reviews would be trivial, history could be tracked, etc.
Maybe, the compiler could error when compiling a module where the documentation doesn’t say it’s thread-safe, but it still is, but I can see problems with that, too, where implementers don’t want to commit to something, but still do it. Maybe, we need 3-valued properties: “is thread safe”, ”is not thread-safe”, and “doesn’t want to commit to thread-safety”
Advantage of the compiler enforcing the properties is that they would remain true.
Yes, you can bolt a lot of that on top of about any existing language, but the language needs a culture of doing that. I think golang has shown that the design of a language can influence its culture.
As I said: “I would like to see an experiment”. I’m not sure I would really be happy with the results though. What if there’s that one function that logically belongs in encrypt, but can’t be made constant time? Do you really want to create a sister module for that one function?
That, or if we assume a few more years of speech recognition gets us to rock solid ASR, then a language designed from the ground up with speech as the input in mind, not the keyboard. I lost my ability to type temporarily, a while ago, and this idea has fascinated me since. I think new kinds of graphical “languages” could become more viable with ASR in mind.
Those, or a language that lets you express pipelines better. My typical pipelines at work involve many programs run on different machines. ETL some data with a spark cluster, save it to “memory” aka S3, train a model on a GPU, save it too, then deploy a service. Imagine if five line ‘main’ function in any program had to be split into five files plus a DAG declaration, and to access the state you had to refer to memory addresses by name. And you had no solid linting/type checking/etc across it. That’s the state of pipelines today.
2. Extensible reflection system like in Python
3. 1 official package manager only, with virtualenvs, and 1 official language version manager
4. Compilable and transpilable, like Futhark
5. Algebraic algorithm compiler hints: eg string length is a monoid homomorphism, so if I wanted to label ‘len(str)’ as such the compiler would be smart enough give me a parallelized, async version of string length
6. Higher order functions + partial application + lenses as built-ins
7. Really solid debugging tools, including at minimum time travel features and automatic data structure visualization
8. Jupyter notebook support
9. Can compile to wasm
10. Codegen as a first class feature, to go along w the reflection capabilities. Eg if I want to copy one region of code to another location, be able to do so. But also much more sophisticated operations than copy.
11. String diagram editor for composable module diagrams
12. IDE has built in natural language interface but in a non-interfering way. By which I mean, rather than writing the code for me at my cursor in my code editor, let me write the code on the left, and have the computer make a list of the ‘todos’ and function implementations that will need to be tackled next. Keep me in my flow, while helping me prefetch the next task to do.
Language that represent numbers as rationals and always gives you precise calculations (unless you explicitly want to round them up).
Language that can tell apart 1 meter from 1 second (units like in Frink lang).
Language that has various data structures with consistent interface (like Scala) up to and including relational tables and graphs.
That has structural composable declarative query language that can reach into arbitrary nesting of those data structures with features that allow to build indexes to perform those queries efficiently.
That has features for serializing those structures and indexes into files and using them live from disk instead of ram. (why not have 1TB set in my program?).
Language that can pick a data structure or combination of them that provide capabilities you specify. For example if I want a structure that is fast at inserting elements, checking their presence and taking smallest element (with respect to some measure) I should get sorted linked list combined with a set.
Merge the concept of type and variable (name) in simple functions:
To assign a photo to a contact: contact.image = photo
Here both photo and contact act as matching types and as variable identifiers.
2. 'that' lambda filter
files that exist =>
files.each.filter(it.exist) or
files.each.filter(file=>{file.exist})
3. of keyword : reverse properties title of book => book.title
4. indexing with '#'
Colors = [red, green, blue] Color#1 is red
(zero based indexing can still be done via [] if desired
5. universal in-place assignment
Each operator automatically works with assignment: x ⊛= b is always a shorthand for x = x ⊛ b.
6. universal broadcasting
All functions are automatically broadcasting on lists and pair values:
square number := number * number square [1 2 3] == [1 4 9]
Most programming being done is either DB backed CRUD APIs & UIs.
For the first part, having to write a REST API is mostly repetititve, not same but similar logic.
Some well designed ORMs & automatic wrapper generators get you quite far (compared to hand writing SQL), but the mismatch is still there.
The best backend language will natively work with database. I haven't worked with many technologies in this, but spring data jpa looks like a good initial step to look at.
Second one is UI. Reactivity is the norm but languages are still mostly procedural. Look at all the state management confusion in eg. Flutter.
Svelte is a quite big step here. I think UI language of future should have reactivity built in.
I think overall web dev is kind of broken caused by the fact, that we still let web technologies evolve instead of reinventing them. To write a web based application you need several languages, which are furthermore separated in front- and backend.
NodeJs kind of tries to fill the gap, but it’s still just a technology which refers web languages.
I think of a different kind of technology that might not be based on html/css/js + backend-language.
1. High level like python, but strongly typed
2. "normal" c style syntax
3. First class support for "green thread" style concurrency, like erlang
4. First class support for dataframes and the best of python's various ML/data packages.
5. A really great ORM well integrated into the language, that can handle elastic and nosql as well as sql.
6. A batteries included web solution like laravel that handled the common web use cases like auth, a db admin, etc. Bonus points if it's write once for frontend and backend a la svelte.
7. Pretty much just steal cargo for package management.
I would like to enjoy writing Go as much as I enjoy writing Ruby. But Ruby apps are slow and hard to deploy. Combining their strengths would be great IMHO.
It would need interop with a large subset of existing Python/C libs to ensure adoption.
What this kind of question tells me is that folks are tired of solving business cases, and long for technical challenges. There's nothing inherently wrong with this longing, but we have enough programming languages. Pick something else to solve. Please.