Re: [stack] problems with high-level purely linear languages

Don Groves <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <[email protected]>
On Mar 14, 2008, at 19:12 , John Nowak wrote:

> This may be too esoteric to post, but I seem to recall a few people
> being interested, so here it is.
>
> Brief intro: A linear language is one in which all values are always
> singly referenced. Such a language can do away with garbage collection
> and allow mutation of data while remaining purely functional. Linear
> languages also match up nicely with how the real world works, for
> whatever that's worth. For more info, check Henry Baker's research
> archive.
>
> Concatenative languages have this nice property where, due to the lack
> of binding and especially due to the ability of functions to return
> multiple arguments, it becomes possible to have a purely linear
> language without any type system needed to enforce it. When you 'dup'
> a value, the value and everything it references gets copied. This may
> seem grossly inefficient, and sometimes it is, but the fact that you
> get to work with cache-friendly mutable data structures can often make
> up for it. That's the theory anyway.
>
> There's a catch: In order to have a linear values without linear or
> uniqueness types, *every* value needs to be linear. As a quick
> example, imagine a language where every value is linear and operations
> are implemented via mutation *except* for lists which are persistent.
> If you were to take the head of a list of linear values, or simply dup
> the list itself, you'd have two references to a single linear value
> which destroys the whole thing. All of the purely functional niceness
> is out the window.
>
> I've spent some time experimenting with linear interpreters and I've
> come to the conclusion that pervasive linearity is a wholly terrible
> idea for a high level language. It's also a wholly terrible idea for a
> low level language where sharing and mutation are critical for
> performance, so it seems purely linear languages aren't much good for
> general purpose programming. This is probably not surprising to most
> people.
>
> Leaving the performance issues aside, here are three less obvious but
> equally critical issues I ran into when designing a purely linear
> typed language:
>
> 1. Things like records and tuples become much more complicated. In
> functional languages, accessing a field of a tuple returns a reference
> to an immutable value. In a linear language, accessing a field of a
> tuple requires that you *deep copy* the value onto the stack. Given
> how unacceptable this is, it becomes necessary to *move* the value to
> the stack so it can be mutated and then placed back into the tuple. To
> support this, the type system needs to have some notion of "nullable"
> types where a record or tuple field can either be null or a value of
> some other type, but never both.
>
> 2. Linear languages are only pure if your program is a big chain of
> unary functions. This breaks down however when you do anything more
> interesting. Say you introduce contracts to your language so that you
> can test pre and post conditions for functions. In order for contracts
> to be a sensible addition, they cannot have any impact on a program so
> that a program behaves identically if they're removed. With a non-
> linear functional language, it's easy to save the top N values on the
> stack, perform the test (the type system can ensure the test has no
> side effects), and then restore the original values when the test is
> over. With a linear language, you'd have to *copy* the top N values
> which is grossly inefficient. The only way around copying is to
> introduce "read-only" types to allow values to on the stack to be used
> provided that they're not updated. This means that a function without
> side effects isn't *actually* pure if it works via mutation because
> the mutation *will be visible* when dealing with things like
> contracts. The additional type system machinery necessary to get
> around this is quite ugly.
>
> 3. References in a linear language must be mutable. This is because
> avoiding copying requires that you *remove* values from a reference
> cell, update them, and then replace them. This also means that
> accessing a reference cell may result in a runtime error if the cell
> is currently empty. Offering "pure" references would again require
> some sort of "read-only" type system extension. Of course, non-linear
> functional languages have no need for pure references to begin with as
> data is already easily sharable.
>
> In short, in addition the obvious potential efficiency problems, there
> are a host of other issues that complicate the language, make
> programming more awkward, and increase the risk of runtime errors. I'm
> of the opinion that it makes much more sense to start with a non-
> linear language and add uniqueness types for the cases in which
> they're beneficial. Uniqueness types essentially prevent you from
> duplicating a "unique" value or any value that references a unique
> value. Such a type system extension is straightforward and non-
> obtrusive; it seems to be implementable in a concatenative language
> via essentially the same mechanism used in ML's equality types.
>
> - John


While I have not done the level of thinking and experimenting with
linearity you clearly have, I have a few suggested rules regarding
the use of linearity in concatenative languages:

(1) Only temporary objects (on the stack) need be linear. Persistent
(named) objects may have any number of references simply by not
allowing them to be deleted -- once created, they exist for the life
of the program.

(2) Named objects are immutable.

(3) Mutable objects must exist in a closure, thus maintaining a
single reference.

If these rules are followed, it seems to me that linearity can be a
useful tool in these languages.
--
don
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.