Update:
Be sure to read the improved 2nd draft of this article instead. The following content is the original article, only saved for posterity, a...
For further actions, you may consider blocking this person and/or reporting abuse
As the saying goes, you achieve perfection not when you have nothing more to add, but when there is nothing left to remove.
I would start with something mature and comfortable, like C# or Js, and start removing things that I think are bad. Async/await , void returns, null values, for/while loops, etc. Kill as much as possible. Then try coding. See what doesn't work, then fix it.
The only reason we don't do that within any existing PL is backward compatibility, but you won't have that problem. Instead you get tons of existing code that you can refactor to test your design. Don't reinvent the wheel.
"Inside every big ugly language there is a small beautiful language trying to come out." -- sinelaw
Most valuable comment. True indeed, thanks for the reminder.
ReScript is the language I've found that seems to most closely fulfill the set of most important familiar features. It has:
(F# with Fable is another equivalent alternative, if you're into .NET)
What about a soundly typed language that transpiles to Clojure and ClojureScript (which again transpiles to JS)?
It could be based on Subject-Verb-Object syntax, and Data First Functional Programming, with sweet-expressions, written in OCaml, to get sound type inference.
That could get pretty close to the dream...!
Typed Clojure is not it... youtu.be/a0gT0syAXsY?t=94
The syntax is a non-starter. It also has only local type inference. The problem might be Clojure's ad-hoc polymorphism complicates things quite a bit... I'd rather have parametric polymorphism ala. OCaml and ReScript.
One syntactical feature I dreamed about in future languages is blanks or placeholder parameters for functions.
If I have a function which takes multiple parameters for example a functin which divide a number x by y and add z to it, the current function structure will look like this
function util(x,y,z) // divides x by y and adds z
I envision something like the following
function divide( x )by( y )andadd( z ) { ... }
function zipfile( filepath )andEncrypt( withKey )andUploadToAWS( creds ) { ... }
Function names will be self-descriptive.
Self-descriptive function names is a very good idea and practise! Chaining atomic functions is another good idea.
In that regard, you might find the concept of piping in functional languages interesting.
Check out the ts-belt library for Typescript:
mobily.github.io/ts-belt/docs/gett...
Or the TC39 proposal for addition of the pipe operator to JavaScript:
github.com/tc39/proposal-pipeline-...
Chaining is a very powerful idea, I have used some excellent frameworks in Java.
What I am proposing is change the style of passing parameters only, instead of parameters at the end of function name, put gaps/blanks in the middle of functionname.
I look at the list and cant help but wonder, have you looked at Crystal ?
Many of the bullets are defined by the author's dislike for specific aspects of Ruby. With this context, Crystal seems like a poor suggestion.
I love Ruby though, it's one of the most beautiful languages I know. :-) Elixir and Crystal have inherited some of its beauty in terms of syntax.
I think a language could be even more beautiful, though. By using FP and composition in a readable way. Railway-oriented programming in F# is particularly beautiful. A Clojure/Lisp like language, with some beautification fix to the s-expression syntax, might be the best way to start. One interesting avenue there is sweet-expressions by Dr. David A. Wheeler.
Yes, I have looked at it briefly.
Briefly I can say that I agree with you, if programming languages are just tools to convert ideas to machine executable bytes as efficient and flexible as possible, then they need features like those, and some of them are already exist but not all in one.
But unfortunetally world is not perfect, and we (engineers) are needed to solve problems with limited resources and with not so efficient tools.
Finally, since we are the last coders of the time, enjoying coding with our favorite language until rise of the machines seems to be the best option.
"Not overly terse" "No overly verbose"
There is a lot of good thinking here. Deep thinking by domain experts can inspire great progress, so thank you for sharing.
However, I believe your focus on the length of names belies an inadequate effort on the matter of naming. I know your proposals for modulating name length (compiler griping about either too short or too long) is unworkable; the ridicule it would produce alone dooms this concept, never mind the properties of the many real languages people use.
Since we're dreaming here I'll share with you my unconstrained dream of how to deal with names. An overview of my dream naming paradigm, followed by brief elaborations of each point:
The best names are no names. After that you have concise and universally recognized symbols. After utilizing the previous affordances you use a small number of short names with limited scope. Finally, after having discovered something that is actually worthy of a lengthy name (not subject to elision through expressions, not accommodated by a concise symbol and in need of more than a small number of characters due to scope) you invent a longer, meaningful name.
No names: expressions deliver this. It should rarely be necessary to create names to represent the value of intermediate computation. I imagine, in my dream language, an environment where expressions fold/unfold (similar to code folding in editors) allowing the programmer to dig into complex expressions when necessary and ignore detail when not. With such an affordance one would simply forgo some large number of names.
Universal symbols: We see from the mathematics used in (non-software) engineering that well known symbols provide great value through a large variety of concise symbols. Why should we need type/read "struct" or "function" or "return" or many other ubiquitous things in our dream language? Can we not have concise symbols? Shouldn't DSLs represented in our dream language be able to introduce domain specific symbols? Do not concern yourself with the limits of keyboards or character sets; a dream language should consider voice input, gestures, non-Unicode representation and other advanced mechanisms.
Short (C like) names with limited scope: Within a limited scope a small number (up to about a half dozen) of concise names are fine. Lengthy names can make expressions harder to consume, violating the reading >>> writing view. For centuries mathematicians have utilized concision to convey fabulously complex expressions with great success. Programming should have this affordance as well; short names are not bad when confined to a limited context and long names do automatically equate with improving comprehension.
Having dealt with the vast bulk of names through the above mechanisms we are left with those things for which we actually need to invent bespoke names; they can't be obviated through expressions, don't rise to the level of a concise abstract symbol and are not confined to a limited context. Only now do you write prose.
Changing topics:
R. Martins view of the value of reading vs writing (the 10x time spent assertion) is insufficient to guide language design. The behavior of real programmers belies the high value of writing without regard to future comprehension. So while it true that we spend more time later reading what has been written, it does not automatically follow that the value of this later work is greater than the former, even if it is 10x more time. A language that values reading to the detriment of writing may suffer by creating excessive burden on the writer. COBOL may be an example of such. Java as well.
It looks a lot like Nim.
I did look briefly at Nim and while it looks like a nice language in its own right, it is quite different from the language that I envision. I dream of a more pure functional language (e.g. uses
map
instead offor
-loops etc.), for starters.The problem with functional language constructs like
map
is that they are less intuitive/familiar for beginners. I have found it easier to teach loops thanmap/filter/reduce
. A solution could be that the language suggest this to the developer and offer automatic refactoring of the for-loop, something like: "It might better to use themap
function instead -> refactor".yeah,
map
has a problematic name for beginners. It should have been called something likeapply
. Because you "apply" an operation to some thing. "Mapping" a set of things to another set of things (by way of a function) is too much derived from abstract mathematics to be beginner friendly (as is much of FP lingo, sadly).I mostly agree. And I have a series of ideas for how to actually implement it all, which I'm very slowly doing: dawn-lang.org