lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: scheme set list function


From: David Kastrup
Subject: Re: scheme set list function
Date: Mon, 08 Apr 2019 13:08:13 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

Aaron Hill <address@hidden> writes:

> On 2019-04-07 6:01 pm, Andrew Bernard wrote:
>> I am somewhat concerned that there is a misunderstanding you have about
>> Scheme. Scheme procedures are call-by-value. This means the
>> arguments are
>> evaluated and the value then passed to the procedure. The value of the
>> parameter in the calling environment cannot be changed. This is how
>> C and
>> Scheme and many other languages work. [In C you can pass a pointer
>> to alter
>> a variable outside the function. but there is no such thing in
>> Scheme - 
>> for
>> good reasons.] It's not call-by-reference.
>
> The way I understand things, that's not entirely true.  Whether a
> Scheme interpreter/compiler passes by value or reference is an
> implementation detail.

Absolutely not.

> Passing by reference is a convenient optimization to avoid unnecessary
> copies and garbage; and near as I can tell this is very commonly used
> across many environments.

You are misunderstanding what a Scheme value is.  Scheme values are
often objects, objects have identity comparable with eq? .  If you
modify a passed object, that modifies the original.  Whether a value is
an object with identity (like a cons cell or a vector) is not an
implementation detail but very much well-defined.

> As such, procedures can have side effects where the objects that are
> passed to such procedures may be modified.  Consider the 1+last!
> procedure I showed that is not a macro itself, but it still has the
> side effect of altering the list.

It doesn't have "side effects".  It manipulates the given objects.

> Perhaps some confusion stems from the distinction between named
> variables and objects representing values.  A list called "foo" is
> really two things: the actual list and the variable that is bound to
> that list.  Passing "foo" to a procedure involves evaluating the
> variable to obtain the underlying list, and then this list is given a
> new name within the scope of the procedure.  (Let's pretend the
> argument to the procedure is "bar".)  This new name is a distinct
> variable but it is not a copy of the value.

No.  You are confusing variables (which have static duration and
existence) and bindings.  Your description fits some old forms of Lisp
(like Emacs Lisp without use of lexical bindings) but already Common
Lisp does not generally use dynamic binding for its scoping.

> However, if you were to (set! (car bar) ...) or (list-set! bar 0 ...),
> then you could in fact alter the first element of the list that was
> passed in.  (IIRC, you need SRFI-17 which defines setters for car and
> its kin to be able to use the first form.)

But that's not changing the passed value but changing the passed
_object_, a cons cell.

> That all said, I have often read that the idealistic functional
> programmer should in general avoid procedures with side effects.  As
> Harm pointed out, such side effects can be dangerous.  So in a way,
> you could certainly be justified in pretending the system is
> pass-by-value irrespective of the actual implementation.

It is not a pretense.  Scheme is pass-by-value, period.  Some of those
values may be mutable objects.  If you have an actual call-by-reference
mechanism, it does not depend on the argument type whether or not you
can change the argument.  And you'd be able to, say, change a cons cell
to a vector instead of having to retain the original cons cell with its
identity.

-- 
David Kastrup



reply via email to

[Prev in Thread] Current Thread [Next in Thread]