Loosely, pretty much all languages today have some form of: mutability, async, special annotations needed for code that should run concurrently or on the GPU, manual memory management, friction around binding to other languages, ugly or unnecessary syntax, the list of poison pills is endless.
I've barely learned portions of Julia, but it does have mutable variables. Once there's a mutable variable, the rest of the language is basically equivalent to transpiling an imperative language like Javascript. As in, there's little advantage over just using higher-order methods within an imperative language, because unexpected behavior can't be prevented, and code can't be statically analyzed beyond where the monad might change.
Clojure uses Lisp's prefix syntax with () with no infix or postfix format available, forcing everyone from a C-style background or even a math background to manually convert their notation to prefix. MATLAB uses 1-indexed arrays, and I don't think that there's a config option to make them 0-indexed. Erlang is too esoteric along a number of design choices to ever be mainstream, although its Actor model is great. Go has trouble with exceptional behavior and doesn't isolate variables between threads, negating most of its usefulness for concurrency.
Basically what I'm looking for is more like a spreadsheet in code, with no imperative behavior whatsoever. I believe that ClojureScript comes closest by executing functionally without side effects, then allowing imperative behavior while suspended, to get/send IO and then execute again. This most closely matches the way the real world works. Unfortunately languages like Haskell go to great lengths to hide the suspended side of things, making it somewhat of a write-only language like Perl (unreadable to outsiders) and too opaque for students to learn in a reasonable amount of time.
The closest language I've encountered that got it almost right was PHP before version 5, when it passed everything by value via copy-on-write and avoided references. Most of the mental load of imperative programming is in reasoning about mutable state. Once classes passed by references arrived, it just became another variation of Javascript. With more syntax warts and inconsistent naming. But since it's conceptually good and mainly ugly in practice, it's still probably my favorite language so far. React and Redux go to great lengths to encapsulate mutable state, but end up with such ugly syntax or syntactic sugar that little is gained over sticking to HTML with classic Javascript handlers sprinkled in. In which case it's better to go with htmx and stay as declarative as possible.
I tried to keep this brief, but I could blabber on about it forever hah!
I've barely learned portions of Julia, but it does have mutable variables. Once there's a mutable variable, the rest of the language is basically equivalent to transpiling an imperative language like Javascript. As in, there's little advantage over just using higher-order methods within an imperative language, because unexpected behavior can't be prevented, and code can't be statically analyzed beyond where the monad might change.
Clojure uses Lisp's prefix syntax with () with no infix or postfix format available, forcing everyone from a C-style background or even a math background to manually convert their notation to prefix. MATLAB uses 1-indexed arrays, and I don't think that there's a config option to make them 0-indexed. Erlang is too esoteric along a number of design choices to ever be mainstream, although its Actor model is great. Go has trouble with exceptional behavior and doesn't isolate variables between threads, negating most of its usefulness for concurrency.
Basically what I'm looking for is more like a spreadsheet in code, with no imperative behavior whatsoever. I believe that ClojureScript comes closest by executing functionally without side effects, then allowing imperative behavior while suspended, to get/send IO and then execute again. This most closely matches the way the real world works. Unfortunately languages like Haskell go to great lengths to hide the suspended side of things, making it somewhat of a write-only language like Perl (unreadable to outsiders) and too opaque for students to learn in a reasonable amount of time.
The closest language I've encountered that got it almost right was PHP before version 5, when it passed everything by value via copy-on-write and avoided references. Most of the mental load of imperative programming is in reasoning about mutable state. Once classes passed by references arrived, it just became another variation of Javascript. With more syntax warts and inconsistent naming. But since it's conceptually good and mainly ugly in practice, it's still probably my favorite language so far. React and Redux go to great lengths to encapsulate mutable state, but end up with such ugly syntax or syntactic sugar that little is gained over sticking to HTML with classic Javascript handlers sprinkled in. In which case it's better to go with htmx and stay as declarative as possible.
I tried to keep this brief, but I could blabber on about it forever hah!