A macro syntax that was both expressive/hygienic, but allowed for better integration with tooling (frequently tools have no introspection into expanded macro code, and debugging macros almost always sucks). I'm not sure how to solve this problem however, but I think procedural macros in Rust are a decent enough start (debugging them sucks right now, but I see no reason why that has to be the case).
Along the same lines of the previous paragraphs (programming things around the program itself, like meta programming) is that the build process in most languages sucks, and requires using outside tools in different languages (be it a config file, make script, python/shell scripting, etc). I'd really like it if I could write my entire build process in the language I'm building, including pre/post build steps, specifying a dependency tree, etc.
An idea I love to work with is a purely declarative syntax, similar to configuration languages like TOML or JSON. But inside declarations you can write imperative code that synthesizes your declarative code programmatically. Now you can do this in JS today with some discipline, and make it kinda typed in Typescript. But if you have a fairly strict and limited type system and good error messaging/debugging workflow it's actually a fairly powerful concept. It helps deal with the oscillation in the industry between "configuration is code" and "configuration is actually a bitch to write for complex systems." You can start with a pure configuration for your system, but then as complexity grows write imperative code that synthesizes the configuration.
But in my ideal language you'd probably have a repl or virtual machine that could be sandboxed and used to execute the build scripts, including invoking the compiler as a library.
Some of them are:
- Macros (both hygienic and unhygienic)
- Bitwise manipulations
- Less confusing syntax for types than C has
- ASCII based (not Unicode, although you can write programs to work with data in any character set, including Unicode)
- Meta-programming
- Low-level features
- You have enough ropes to hang yourself, and also a few more just in case
- GOTO and GOSUB
- Direct dealing with the stack
- GADTs (without runtime support)
- Control over optimizations in different parts of the file
- Better namespacing
- Binary include files
I am sorry I did not write more elaboration of this. Also, I have more ideas too, but did not write them on here right now.
In terms of control flow, why do you need GOTO, why GOSUB instead of a normal function call, and what do you mean by "direct dealing with the stack?"
This sounds a lot like a version of C++ without the cruft and C backwards compatibility. Which is a fantastic idea, and I know it's been attempted many times. Which languages out there today do you think fit your criteria the closest?
GOTO is sometimes the best and clearest way to make something, although usually it will not be needed. Ideally, other flow controls such as FOR, WHILE, etc would be defined in terms of GOTO by use of hygienic macros, rather than being built-in features. You can then define your own flow controls too if you use some pattern a lot that giving that pattern its own name and macro is useful.
Direct dealing with the stack can be used to do some stuff normally done only in assembly language (although GNU C has some stuff, such as reading the stack pointer). But assembly language is specific to the target computer, and many libraries are not designed to be used with assembly language programs. However, some direct dealing with the stack might also depend on the target computer. Macros producing inline assembly code may be used if needed.
I do not know which other programming languages do such thing.
let name = "Jane";
let str = s{}:John said "Don't do that, {name}!":s
I would also like a JSON-like shorthand for declaring nested structures, without having to define each individual component separately. Eg: struct Person {
user: {string name, int age},
address: {string street, ...}
}
let p = new Person(<json>);
print(p.user.age);
Convenience with arrays (python slicing is nice), maps, and primitive types pay huge dividends. arr.first();
arr.last();
arr[5,-5]; //5th to 5th to last
Built-in arbitrary length/precision numbers would be neat.Besides that, tons and tons of useful libraries: IO, Date, JSON, DB Bindings, etc.
- expressive type system
- easy & intuitive to start with, but also powerful if needed (low floor, high ceiling)
- has a relatively small set of core concepts which are then composed together to build things further
- rich set of libraries (although pretty obvious and not really a feature)
I think our search for the "grail" general language will continue, probably forever. Languages such as Haskell, Rust & Go (and probably a lot of others I haven't heard of) are breaking the boundaries and introducing new concepts which then slowly spill over to more "mainstream" languages (e.g. the advent of functional programming constructs we are witnessing in Java, JS etc.).
Other than that, I also believe that more and more DSLs will start appearing, which is basically languages specialised for a specific purpose - which will make them extra convenient in their domain but not usable in the general case. Also, I expect the tooling (IDEs, build systems) to become more tightly integrated with the language, especially for the DSLs - creating the end product which at the end will be usable not only by the programming experts.
I have actually, together with my brother, been working on such an idea for the past year. We made a DSL for the domain of web apps - it is basically a declarative language that compiles to the stack of choice implemented in the general language (e.g. React/Node). This makes it possible to express some web-app specific concepts with much less code, but is also constrained to that specific domain.
If anybody wants to take a look it is here: https://github.com/wasp-lang/wasp
Would be interesting to see the results of your research and what majority thinks are the ideal language features.
A build system that makes it super easy to do the right thing with regard to locking dependency versions.
A compiler backend that generates reasonably small binaries.
For example have all the nitty-gritty cool features for a low level programming language BUT also maintain Python-tier readability.