Hacker News new | past | comments | ask | show | jobs | submit login

I feel the ideas listed here range from nice-to-haves to fundamental weaknesses of all languages that derived from the C/Python/Java family, which almost all mainstream languages seem to be.

I'm working on a platform that tries to remedy some of those, so I'll enum the overlap I have with the author about what's fundamental:

1. The distinction between sync and async should be a runtime/scheduler decision, the way it is say in your CPU scheduler, we shouldn't have to separate functions into sync and async (red and blue, etc.). This is a legacy quirk of trying to bolt asynchrony on runtimes which are intimately dependent on a call stack, while asynchrony can't use the call stack (it uses so called "spaghetti stack" or inverse tree where children link to a parent, or the way say LISP environment frames link to one another).

2. Persistence ("relational programming / value database"). I'd go farther than the author and suggest both his concerns with relational programming and value database have a shared solution: the language SHOULD be the database. It shouldn't be something you code for, then the code becomes SQL, and then the SQL is executed elsewhere. This is also a historical quirk. The relational storage should come with every programming language. This was also the original way in which SQL was intended to be used. Unfortunately SQL databases failed to evolve in terms of general purpose programming and failed to provide also clear ways to separate "clean code" from a deployment with state. You need persistence in programs, but you also need a clear line between initial state (construction from source code only) and deployment with state. I can discuss further how this is done if someone is interested.

Two more things I didn't see mentioned, but are related:

3. Pass by value. If you want to bridge the gap between remote and local calls, timeouts and asynchrony is one thing, but another is that you have no direct zero-latency access to someone else's memory. So you can't pass things by handle or reference like we do in common OOP languages. Runtimes need to lean more heavily into pass-by-value, and optimize large structure copying with concepts like copy-on-write, and other algorithms from "persistent data structures" we're well familiar with. Mutable structures being a configuration of smaller immutable structures also permits seamless, effective caching between remote clients, so they can reference immutable facts that don't "go out of date" or change.

4. Return to "code is data" and "data is code" i.e. so called homoiconicity. So much mindless boilerplate in your programs is the endless reimplementation of proto-interpreters for custom input data, unrecognized Domain Specific Languages. If this DSL was written in a compact, expressive manner, and if you could transform that DSL to code and run it instead, and know it'll be treated just as well as any other code in the system, you wouldn't have to write, and just as importantly look at that boilerplate ever again. This of course requires a runtime with strong, clear safety boundaries on IO and side effects, so that if you fat-finger the conversion and permit injections, you can still feel safe the code can't take over your system, the worst it can do is error out or provide a bad answer which you'll catch on return.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: