@wolf480pl I was thinking of doing a "hyper-pure functional language" experiment that would work something like that. Having strict pass-by-value semantics (no pointers, at all), and a main function that returns it's arguments for processing in the language runtime, which is the only place that can interface with the world would naturally lead to libraries explicitly requiring objects representing external state to them.
@wolf480pl Not quite, I don't think. Tho I'm not well versed in traditional functional languages so might be wrong. this is what I'm thinking off.
@wolf480pl none. Python is the one I know best, but that's not functional, C is far from functional either, others I don't know well enough to know how they work.
Hmm ok I guess I'll have to explain it from scratch. Would you prefer if I borrowed C++/Java's (List<T>) or Python's (List[T]) notation for generics, or just go with Haskell's (List t) ?
@wolf480pl Any but haskell is fine. Do note that I do have a fair bit of knowledge of types, but not the languages that use them, so no need to ELI5.
@ignaloidas ok, so let's go with List<T>.
I'll be using arrow for functions though, so instead of:
first : Function<List<T>, T>
first : List<T> -> T
consider the following type:
type State<S><R> = S -> (R, S)
a function that takes state or type S, and returns a return value of type R, as well as a new state of type S
you can define some nice operators on it that'll make it possible to chain it nicely (then we'll call it a monad), but I'll elaborate on that later.
So what you're saying is, main is a State<RealWorld><int>,
and RealWorld is some non-opaque thing that consists of stdin, stdout, and other things?
@wolf480pl Yeah, somewhat, just with RealWorld being defined by main itself (no predefined structure).
@wolf480pl no. It's run again and again until a sentinel value (not pictured in the diagram) is set to some exit code.
@ignaloidas even more interesting...
and because main is pure, it will never block...
I think you'd need some syntactic sugar for it to be able to not have a huge switch(state) at the start, or sth like Python's generators...
how do you read from regular files though?
Do you somehow return a request to read?
@ignaloidas btw. virtualization would be so easy with this API, even easier than with lua coroutines
@wolf480pl it's quite naturally building a state machine, so having a good switch syntax is a requirement either way. Of course having a large switch is still annoying, but I'd imagine this approach would be more fitting for server applications anyways, where besides startup you don't have many different states.
as for files, you'd just have file objects returned to runtime with appropriate fields written, and the runtime returns them back with what's needed.
@ignaloidas sometimes it's natural to keep state in the (metaphorical) "instruction pointer", especially when you have some form of async io.
Eg. it'd be more convenient to write an entire handshake with a new client as a single linear piece of code than breaking it up into steps.
Anyway, so your idea boils down to main returning "syscalls" it wants to do, and then being called back with the results?
It's pretty cool IMO, and would lend itself well to all kinds of things:
The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!