0

Is there a usable programming language that disallows all side effects except for its input stream (aka STDIN) and its output stream (aka STDOUT)? All executable scripts in the language should be guaranteed to produce exactly the same output when given the same input (unless they don't terminate soon enough). This excludes any other external state such as:

  • access to the file system (like known to be limited in sandboxes)
  • access to APIs, databases, network connections...
  • access to environment variables, time

By usable I mean the language should include basic datatypes and operations as known from other programming languages, unlike for instance a Turing machine emulator. How could such a language be useful? It would allow execution of arbitrary scripts for reproducible data transformation.

A defined subset of a more powerful language can also be useful if there is a practical way to actually define and enforce the subset.

P.S.: I extended the question and added an example answer with a language that is actually used for reproducible data transformation but too limited for more complex tasks.

  • 3
    Are you also excluding things like APIs, Databases, Network connections, etc? If so, how exactly would such a language even be useful to anybody if it couldn't access any kind of external resource? – Ben Cottrell Mar 18 at 20:53
  • 2
    @BenCottrell It can do math and transform any input into output, so long as it does not change the input in place. If you have a very inefficient computer, you can also start a long-running program and warm your hands over the machine. – GlenPeterson Mar 18 at 20:59
  • 1
    @GlenPeterson Any language can do that, why would someone choose such a restricted language for those things as opposed to, say, Python? – Ben Cottrell Mar 18 at 21:04
  • 4
    The problem with disallowing "all side-effects except …" is that this can have unintended ahem side-effects. For example Erik Meijer once demonstrated in a video, how a subset of C♯ (actually, it was Polyphonic C♯, a research language extending C♯ with the join-calculus) that has "no side-effects except" concurrency, can use concurrency to implement shared mutable state. – Jörg W Mittag Mar 18 at 21:15
  • 1
    @BenCottrell Removing all dependencies on external state and side effects, or at least pushing them to the edges of your program makes it extremely easy to test any function with a minimum of mocking. If you're writing a credit-card processing application or a currency exchange app, you might want to write the core in an incredibly safe and testable language like that, then write the interactive stuff that goes around the safe core in another language. – GlenPeterson Mar 19 at 13:38
3

Check out Total Functional Programming which mentions Epigram and Charity.

Haskell is the first that comes to mind, having the best combination of purity and popularity. You can also search for "purely functional programming languages." Everything is evaluated lazily. Even STDIN and STDOUT are handled purely by passing in a fake "state-of-the-world" parameter and returning it "modified." This little bit of trickery allows Input/Output to appear functional to the program.

Programs in Haskell (and presumably other purely functional languages) are not sequential. You do not write, "First do this, then do that." You simply list dependencies. "This depends on that." Then the program figures out what has to happen first (imagine it starts with the results, and puts everything on a stack until it gets to the inputs, then pops things off the stack to process in order).

  • 2
    I knew someone would mention functional languages, but it's possible to write Haskell programs with side effects, for instance via Data.Time.Clock. – Jakob Mar 18 at 20:45
  • 1
    Maybe you should edit your question to make that clearer. I don't know Prolog, but it may be closer to what you're looking for. Any such language would be very limited in what it could do. – GlenPeterson Mar 18 at 20:52
  • Getting the time isn't a side effect, although it is impure. – Andrew Piliser Mar 18 at 20:52
  • @Jakob all I see is pure functions and a value of type IO UTCTime. Where's the side effect? – Caleth Mar 19 at 11:22
  • @Caleth: the side-effect is that the result is not reprodicible because it is based on additional external states (here the date). Is there another name instead of "side-effect" for this wanted behaviour? – Jakob Mar 19 at 12:07
3

It's pretty difficult to accidentally open a file in Haskell. A lot of people don't know how to do it on purpose. Just don't use the parts you don't want. Since there is no way to interpret any IO actions outside of the main function, an appropriately designed and audited main can prevent unwanted side effects for your entire program.

0

A very limited language without side-effects for reproducible data transformation is the subset of sed having the form:

s/regexp/replacement/

Same input will always produce same output no matter how you choose regexep and replacement. This does not apply to extended search-and-replace-statements such as in Perl with the /e flag.

  • Then how about the subset of Haskell that excludes Data.Time.Clock and the likes? Or a suitable subset of any language, for that matter? I do that with python every day. – Goyo Mar 19 at 8:42
  • @Goyo So how do I practically ensure that "Data.Time.Clock and the likes" are not used? I'm sure there exists a subset of Haskell that answers my question but how exectely is this subset defined in an enforceable way? – Jakob Mar 19 at 10:42
  • 1
    How do you enforce not editing in place or using mutable state like sed s/today/"$(date)"/ when using sed? By refraining yourself from doing that. – Goyo Mar 19 at 11:18
  • @Goyo then my answer is wrong and it shows how difficult it is to define a safe subset of an existing language. Therefore my original question. – Jakob Mar 19 at 12:05
  • 1
    @Goyo I want to refrain other people from doing that so "just don't use this feature" is no helpful answer, but thanks for pointing out my own error about sed! – Jakob Mar 19 at 12:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.