I hope you can humour me and not challenge the assumptions baked into the question. That's a separate, if interesting, exercise.
At some point everyone realizes that if you want to do things "generally" then you want an ML. And after that we slowly get the surface area of general languages hardening until we don't really see that many new features popping up all the time. Afterwards all the innovation shifts to niche programming languages and DSLs.
I would give your idea a try. I think it's good.
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 ^^'.
https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...
LINQ has multiples issues compared to what I want to do.
It's slow (at leat 1000x slower than a for loop)
There is no query optimizer by default, and even less a runtime query optimiser.
It's directly translated to procedural code, it doesn't get compiled and translated like a query engine will do in an SQL DB.
I love SQL for what it can do, but I am constantly annoyed at how inconsistent it is and how terrible it is for generating queries via software. It feels ripe for a replacement that is semantically similar but syntactically different.
https://en.m.wikipedia.org/wiki/D_(data_language_specificati...
I will read it, but mind that, I said "general purpose" I don't want this to be a language used to be only used as a Database. The whole app should be written in it.
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.
* Ponylang. Pure Actor model. Static typing to enforce safe concurrent semantics in almost all respects. Plus ORCA GC. Upshot: high performance, and type theory grounded guarantees of no deadlocks, no livelocks, and no data races. Chief downsides are that MS Research has hired its founder, and it's a fledgling language/community.
* Elixir. Kinda Actor modelish. Dynamic typing, solid community. Someone else has posted about it.
* Raku. Someone else has posted about it. Chief downsides are that it's got slow single core performance and small community. Upsides include ease of use for multi core code. `start` schedules a lambda or function or statement on a virtual thread. cf Go's `go`. No `async`.
Java also has some basic thread synchronization primitives built into the language. It's way easier than you probably think. And it gets even more interesting with the upcoming project loom, which gives you the same programming model for lightweight and real threads.
Async programming is a pox on the industry. It's very useful in rare situations that require extremely high performance, but for general business processing, function coloring adds a ton of accidental complexity.
The millionth prime number using 1 CPU:
$ raku -e 'say (1..Inf).grep(*.is-prime).skip(999999).head'
15485863
real 0m5.515s
Using whatever CPU cores are available (using `.hyper`): $ raku -e 'say (1..Inf).hyper(batch => 10000).grep(*.is-prime).skip(999999).head'
15485863
real 0m2.036s- 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
I am surprised that there are still no software development platforms where you use one language for all levels and do not have to translate between different ways of representing data and interacting with services.
The interesting applications are where multiple agents (people and/or other systems) are working on the same data. The methods to define such forms of cooperation are rather primitive. On one hand you have the databases with their transactions and pessimistic locking approaches. On the other hand you have git repositories with optimistic locking and manual merging. Sometimes you would like to have something in the middle, where you can define which operations conflict (do not commute) and how to deal with them.
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?
void constanttime doStuff(vector<whatever> v)
However, it would likely require extensive dedicated support and would necessarily be limited (hello, halting problem!). I could see that working and be useful for common complexity values, e.g. O(n^k), O(log n) etc.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.
I have used c#, and javascript. And not felt any issues by lack of virtualenv.
I know python need it because otherwise it does not support project level modules. But that is a python only problem
The reason is that pip/most package managers have a default to install a package globally. Which can be annoying especially for noobs.
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.
>> Language that represent numbers as rationals
so π would be represented as π/1 or τ/2?Also wouldn't it make comparisons quite expensive?
Instead od Pi I'd prefer to have Pi(3) equal exactly 3.14, or Pi(2) equal exactly 3.1 and so on.
Since numbers would be kept as smallest numerator, denominator pair comparison would be just compaing those.
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.
Javascript supports first class functions, lexical scoping, and tail recursion.
AFAICT from stackoverflow, the Safari JS engine optimizes tail recursion, while Firefox is apparently working on it.
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 don't think there exists any timeline where we don't end up with something we would recognizably call a programming language.
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.
So far, Rust...
> with type system like Haskell/TypeScript/Rust/Ocaml
Still Rust...
> and simplicity of Go
As long as that's ”for similar tasks” and anywhere outside of Go’s particular sweet spots, AFAICT, that's still Rust...
A very strong type system, makes native binaries, has low level control, but it writes and reads super simply. Generics are at the module ("package") and function level, not at the type level, and can take other packages as parameters.
Specifically, what does "simplicity of go" mean to you
My biggest problem is that it's not possible to represent "duck typing" (structural typing), which is core to ruby. So an object that is "callable" (a lambda with no args, a block with no args or an object with call and no args) cannot be represented, since the expectation is that the object includes some interface (module), not that it has a method #call
https://en.wikipedia.org/wiki/Nim_(programming_language)#Des...
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.
EDIT: Plus, Rust’s initial debut was mid-2010, so it would have been a coin flip chance at worst.