I made a language a while back that was used to implement custom logic for a product (I've since replaced it with a more declarative system that's basically TOML but where values can be expressions that get evaluated to generate the actual values). One goal of this language was that it should always terminate[1], so it had no unbounded loops. Another goal was that it should be deterministic, so all input was gathered before execution and all output was accumulated to be processed at the end. The entire thing ran in a database transaction (so input could be queried, then the code was executed as a pure function of this input, then the result would be written back to the database or sent elsewhere). Externally triggered events would cause this to run. Essentially an event driven synchronous[2] language of the transformational system variety. It was slightly inspired by Lustre[3], which is used in critical systems like aeroplanes, trains and power plants. I'm a big fan of this style of language.
Basically, by constraining what the language can do or can be used for, you can design much more powerful semantics or language features for the things that it is designed for, similar to a domain specific language. I guess it really would be a somewhat more general domain specific language, or at least domain specific to multiple domains.
I was thinking about this while walking home from the shops and was wondering if such a language would be beneficial to solve some challenges I hit in my work and I was going to spend some time thinking what semantics would be useful, but haven't done so yet and then came across this HN submission. :)
[1] I was also thinking about how the halting problem doesn't really say that determining if a program halts is impossible, just that there are programs that are not computable. If you add constraints (like not being able to feed the program to itself as is done in the halting problem and not allowing unbounded loops) then it is possible to determine if a program will terminate or not.
[2] https://en.wikipedia.org/wiki/Synchronous_programming_langua...
[3] https://en.wikipedia.org/wiki/Lustre_(programming_language)
Dhall is a good example - https://github.com/dhall-lang/dhall-haskell .
So a "pure language" here is just a bs marketing term rather than any inherent feature in the language. As far as purity goes, a language like c does that just fine. That's as pure a language as it can get.
This whole opinionated "can never allocate memory" is condescending to engineers. A powerful language should be safe by default (to take some of the pressure off the developers of having to be always careful) but have the knobs to let them take full control when needed. C# does this very well.
You say this, but people do it all the time.