On Mon, May 31, 2021 at 7:36 AM Marc Nieper-Wißkirchen <
[email protected]> wrote:
>
> In what I have written so far about typing, I have been more concerned
> about enforcing (through runtime errors) the distinction between immutable
> and mutable types, not so much to enforce the affine/linear protocol. Even
> if the latter is not possible, it means nothing to the former. I have to
> think about dynamically typing the affine/linear protocol a bit more.
>
Without explicit mutation protocol (that you can reliably call only for
side effects), the distinction of functional and linear-updating version
isn't the matter of immutability at all. The linear-updating version is a
declaration by the caller that the argument won't be retained, so that the
implementation can do certain optimization. As far as that contract is
kept, mutation isn't observable (except speed and memory allocation).
Semantically you can treat everything as if they're immutable. Calling a
linear-updating version simply gives optimization hints.
> As a library writer, you document your interface. Depending on whether you
> accept only mutable or also immutable types, the user of your library
> routine will have to copy the argument.
>
So you're talking about asking the copying to the user? Something like
this?
(define (my-library-function input)
(if (immutable? input)
(functional-update input)
(linear-update! input)))
What I was thinking was something like this:
(define (my-library-function input)
(liner-update! (if (immutable? input) (copy input) input)))
Thinking about it now, the former does look cleaner---immutable input
produces immutable output, mutable input produces mutable output.
The thing I wanted to avoid is the following. Copying is a waste if the
caller won't use the input after this.
(define (my-library-function input)
(liner-update! (copy input)))