It seems like your proposed replacement for FutharkScript might be a good case for using FC/IS Ã la Pipefish? It's the most lightweight way of segregating your impurities, and you don't need a heavier one.
There is a connection, but it is important that "real Futhark" truly is pure (ignoring nontermination and other errors), and that the magic impure functions we need in interpreted Futhark do not need any particularly sensible properties associated, as they will never show up in application code.
The Futhark interpreter always supposed impure effects, since it is needed to implement the trace and break functions used for debugging. The way it works is very much similar to the "functional core, imperative shell" approach, in that interpretation takes place within a free monad, such that the interpreter can issue abstract effects, but has no influence on how those effects are actually interpreted by the (somewhat confusingly named) effect interpreter. This is also how we extended the interpreter to support "foreign functions" - we simply added a new effect encoding "please ask the outside world to call this function and then invoke this continuation with the result".
Free monads are probably my favourite technique for decoupling the issuing of effects from the execution of effects.
Free monads are probably my favourite technique for decoupling the issuing of effects from the execution of effects.
Coincidentally I'm currently working on the section of my manifesto where I explain why we need at least one functional programming language designed by someone who isn't a professional mathematician/computer scientist. Y'all are too darn intelligent.
Free monads are not so difficult to grasp except for the somewhat oblique nomenclature ("free" is taken from algebra). They are about as tricky to use as coroutines (which I always found to be a much more difficult term to grasp!). One good way to look at a free monad is that they are very much like a coroutine or a yield statement in languages like Python, except that the caller (what I call the "effect interpreter") can provide a new value that to the coroutine becomes the return value of "yield". Free monads can do more than this (the continuation may be multi-shot), but that is not a problem to me. There is no issue with a construct being very powerful, as long as simple things remain simple. This is the effect interpreter for futhark repl (before all the foreign function stuff is merged). The only complicated case is the one for breakpoints, but that is because it needs to do an interactive user interface.
I unironically think this is exactly why rust is so successful.
Its a 20/80 take on a functional language from an imperative programmer's point of view with escape hatches and some other stuff sprinkled in.
Mine's a 100% take on a functional language, with no escape hatches, and though it's not the easiest language in the world, it will be the easiest one anyone's ever used in production.
If you're not familiar with Pipefish, I'm trying to recruit some people for about two weeks from now who don't know anything about it and would be interested in approaching it like anyone else would, from the main page of the website, knowing nothing about it.
If you're interested in finding out what a language like that looks like, could I put you down for a "maybe"? I see that you like femboys and dislike anti-Semites: we will get along.
sure, ill take a look. although I might not be your target audience as im experienced in a lot of languages. id be more interested in what a python + C# or js only, or a Cpp only programmer would have to say compared to me
6
u/Inconstant_Moo 🧿 Pipefish 6d ago edited 5d ago
It seems like your proposed replacement for FutharkScript might be a good case for using FC/IS Ã la Pipefish? It's the most lightweight way of segregating your impurities, and you don't need a heavier one.
Functional core, imperative shell
Pipefish and the lambda calculus