As I already explained, I’ve invented and implemented a simple functional language (PYFL) with a few interesting twists. Including a promising but simple approach to input.

The basic language itself is pretty standard, except that it uses infix operators and conventional mathematical notation for function calling; e.g. f(h,a+2*y). It also has a wide range of variable binding operators; as in the program given at the end of this post

VBOs are great but the real elephant in the FP room is I/O. I have a few ideas.

**Monads schmonads**

Haskell uses the seriously complex machinery of monads to do I/O, supposedly without side effects (I don’t accept this). And you end up writing stuff like

`main = do {` ` ` `putStrLn "Hello, World!" ;` ` ` `return ()` ` ` `}` |

which to me looks like C. There must be a more functional approach.

I started from the PyLucid approach, that the output of a program is its value (as an expression) and its input is the value of a special variable *input*. Simple enough.

The problem with adopting this is that pyLucid has streams and PYFL doesn’t. Infinite lists could serve as a substitute but PyFL has only finite lists (to avoid the complications of list closures)

But there is no harm in having an *input* variable and this gives us a simple arrangement: the input becomes the value of *input*, and the corresponding value of the program is the corresponding output. Thus the expression

*input*input*

is a program to compute the square of its input (note that both occurrences of *input* denote the same value – no side effects, this program is equivalent to *input**2*).

What if we do want two inputs, and output their product? If one input variable is kosher, we can have two, *input* and *input2*. Our program is *input*input2.*

Generalizing, we could have *inputn* for every number n. Even better, a function *input(n)* of one number argument. When the computation (which is demand driven) needs the value of, say, *input(3)*, it could prompt for it. In this simplest form the scheme is impractical because in general there is no guarantee that these inputs will be demanded in numerical order; the computation may need *input(4)* before i*nput(3)*.

The solution (following Lucid) is to demand the inputs in order and cache them, so they will be available when the computation needs them.

**Input prompting**

PyFL goes one better. It has an input function whose argument can be an arbitrary string (not necessarily a numeral). This string is used as a prompt. Thus a program to compute the roots of a quadratic equation could be (and in PyFL is)

*valof** a = input(‘coefficient of x squared’);** b = input(‘coefficient of x’);** c = input(‘constant coefficient’)** rdisc = sqrt(b*b-4*a*c);** root1 = (-b + rdisc)/(2*a);** root2 = (-b – rdisc)/(2*a);** result = [% root1, root2 %];**end*

As it happens the computation will need the value of b before that of a. If this is a problem, we can write the definition of root1 as

*root1 = (1/(2*a))*(-b + rdisc);*

(later I’ll explain a more systematic approach). Then the demand for *root* generates a demand for *root1* which generates a demand for *1/(2*a)* and finally a demand for a. Demands for b and c follow shortly, in that order.

Input values are cached in a dictionary using the prompt itself as a key. Thus the implementation won’t ask you again for the coefficient of x squared.

This works well if there is a small finite set of inputs but what if, say, we wanted to sum the values of twenty inputs?

The answer is to generate prompts and embed the a call to the input function in a VBO that runs over the required range. For example

*sumfor i in range(1,20) all ** input(‘a number please(‘+str(i)+’)’)**end*

where *str* converts numbers to strings.

What if the input is being produced by another program? Why would we print the prompts? Because the program can read them digitally, and produce output as required. In other words the producer program is feeding our consumer program by producing its output on demand. It receives a prompt and computes or looks up the corresponding output.

We can save a lot of trouble if the producer knows ahead of time the order in which the input items will be required. Then we can eliminate the prompting dialogue.

The input scheme is not only conceptually simple (none of those pesky monads) but is trivial to implement – about a dozen lines of Python.

Now for output. The idea is … wait, take a look at the word count … this is already too long, the output story will have to wait till next time. Prompt me.

Here’s the promised program

*valof** subsets(s,i) = // the set of all i-element subsets of set s** if i==0 then {{}}** i==1 then collectfor x in s all {% x %} end** else** unionfor x in s all** valof** sminusx = s – {% x %}; // {% x %} is singleton x** withoutx = subsets(sminusx,i); // subsets without x** withx = collectfor u in subsets(sminusx,i-1) all //those with x** {% x %} ++ u** end;** result = withx ++ withoutx; // disjoint union** end** end** fi;** result = subsets({tom dick harry chris pat},3);** end*

which computes all the three element subsets of the set {tom,dick,harry,chris,pat} (PyFL has proper sets).

There are several schmonads here: VBOs are schmonadic, and even valof..end is a commutative schmonadic construct.

I’m a beginner to programming and honestly what you wrote seems even more complex than what you said was seriously complex. Came here because the title of the link led me to believe this was an easier way to learn monads, oh boy was I wrong.

I think mathematics and computer experts don’t seem to realise that what seems simple in their minds doesn’t look like that on paper.