# I/O

## Jack Waugh — 2001-06-19 10:32:23

    In this message, I will write feelings.  I distingush feelings from

    thoughts with the sense that thoughts are articulations I could argue

    for.  In the case of feelings, I want to assert some statements but I

    cannot yet articuate an argument for them.

    I feel:

    The open files in the argument and result in Joy present more of a

    challenge to Joy's claim to be a purely functional language than

    would a dictionary, if we added one to the argument and to the

    result.  Von Thun's line of discussion seems to be leading toward

    saying that including dictionaries in the argument and result would

    smack of assignment, so would break pure functionalism.  But he also

    says the property "pure functional" is not a matter of degree, so

    the "smack of" doesn't seem to fit.

    Haskell is a pure functional langauge.  It exhibits referential

    transparency when read it at face value (Joy seems to have two very

    distinct face values, but Haskell has only one because it looks much

    like ordinary mathematical notation).

    Erlang is an almost-functional language.  If you define a function

    that doesn't do any I/O, it is functional.  But the I/O in Erlang

    does not preserve referential transparency.  That in Haskell does.

    Big difference.

    What about Joy?

    If we read Joy words as functions in one parameter with one result,

    where the data type of the parameter is the same as that of the

    result, and where an instance of that data type contains a stack and

    some open files, then under this reading, Joy is purely functional

    (so is C under the same reading).  Under this reading, the files do

    not break referential transparency because the argument is linear.

    That means you cannot reuse it.  Applying a function to the argument

    eats up the argument forever.  (Some languages allow linearity as an

    optional feature of data types.)  By including files, the argument

    effectively includes the whole world outside the computer.  Let's say

    I scratch my elbow while "dup" is being executed.  dup has been

    applied to an argument that included my itchy elbow.  The result

    includes a less-itchy elbow.  This does not break referential

    transparency (RT) becaue dup will never again be applied to exactly

    the same argument.

    There is another way to read Joy and I think that if Joy enters

    practical use, this is how programmers will usually read it.  Let's

    take "+" for example.  Instead of reading + as a function in one

    parameter and producing one result, as I described above, we can read

    + as a function taking two arguments and producing one result.  The

    arguments are on the stack before + executes.  It consumes the

    arguments from the stack and pushes the result.  Under this reading,

    there is a stack and it changes.  We have said in other messages that

    this reading is false.  But the truth is that Joy is an independent

    object of study and this analysis is as valid as the other one.  It

    will predict the behavior of a system just as well.  Now, under this

    reading, where we talk about the values being popped from the stack

    as arguments to functions and the result pushed as the result from

    applying the function, Joy is still almost functional.  In

    particular, under this reading, there are no variables.  In this

    reading, von Thun is right to attribute importance to the absence of

    variables.  Suppose we could have a variable x, and some notation,

    say "x?", that would mean push the current value of x onto the

    stack.  Then x? would not be RT, because its results as pushed on the

    stack would not depend solely on its arguments as popped from the

    stack.  (Under the other reading, x? is RT because it just maps from

    an argument containing a dictionary, a stack, and an I/O world to a

    result containing a dictionary and a stack and an I/O world.)  Joy

    doesn't have variables, so no variables break RT when we read Joy

    under the interpretation that functions take arguments from the stack

    and push results on the stack.

    However, under the same reading, Joy is not purely functional for the

    same reason that Erlang is not.  That is that the I/O world is

    implicit.  It doesn't enter and leave functions via the official path

    of this reading, being popped from and pushed on the stack.

    So I'm left with one reading of Joy where it is purely functional but

    only in the trivial way that we can read C as purely functional, and

    a second reading of Joy where it is not purely functional for the

    same reason that Erlang is not.  And all this is because of Joy's I/O

    model.