Email list hosting service & mailing list manager

function-call notation instead of generic ref/set! Per Bothner (16 Aug 2015 18:10 UTC)
Re: function-call notation instead of generic ref/set! taylanbayirli@xxxxxx (17 Aug 2015 08:34 UTC)
Re: function-call notation instead of generic ref/set! Per Bothner (17 Aug 2015 16:38 UTC)
Re: function-call notation instead of generic ref/set! taylanbayirli@xxxxxx (18 Aug 2015 09:32 UTC)
Re: function-call notation instead of generic ref/set! Per Bothner (18 Aug 2015 16:39 UTC)

Re: function-call notation instead of generic ref/set! taylanbayirli@xxxxxx 18 Aug 2015 09:32 UTC

Per Bothner <xxxxxx@bothner.com> writes:

> On 08/17/2015 01:34 AM, Taylan Ulrich Bayırlı/Kammer wrote:
>
>> So, it's an unfortunate difference but I guess we'll have to live with
>> it.
>
> I don't see how it's a "difference".
> (set! (vec2 2) 'C) == ((setter vec2) 2 'C) == (vector-set! vec2 2 'C)

Hm, in that case, I suppose it's strictly an extension of the current
practice.

I was thinking that it wouldn't work for cases like

    (set! (documentation-of foo) "Foobar.")

since in (set! (vec i) x), the order within the (vec i) form is
(<object> <field>), meaning that the above would have to be interpreted
as wanting to set the `foo' field of a procedure object.

However, that can be salvaged by specifying that the (<object> <field>)
order only arises from omission of an explicit getter in the first
position, and prohibiting this omission when <object> is a procedure.

In simpler words, the `setter' procedure knows the object it received to
be already a getter when it's a procedure, and otherwise looks up the
getter based on the type of the non-procedure object it received.

I had not thought of that simple solution.

I will think about said omission of getter in (set! (...) ...) forms
independently of omitting them during access.  Although I suspect the
lack of consistency between access and mutation would be undesirable so
it will ultimately rest on whether omission during access is adopted.

> It seems pretty natural to view an array/vector as a kind of function,
> and it's arguably good to use the same syntax for function application
> and array/vector indexing, as it abstracts over the implementation.
>
> The point of the ref or ~ operator (besides terseness) is to abstract
> away from representation choices, thus making it easier to change
> implementation details.  Using function notation goes one step
> further.

To be honest, the abstraction over representation choices is mostly
incidental in this SRFI, since the main intent is to offer a notation
for access and mutation that isn't painful to type often, doesn't
inhibit the code's readability due to clutter, and doesn't force you to
distinguish between *intuitively* very similar operations (*-ref/*-set!).

Going by that, the omission of the ref or tilde doesn't provide a
significant advantage, and might in fact decrease readability because a
programmer tends to intuitively dissociate function calls from field
references, no matter the conceptual similarity.  (It might be different
for someone constantly working in highly abstract fields.)  Thus one
would expect them to also look different in code.

Of course this is all very opinionated, so I'll try to get as much input
as I can and let the collective opinion decide.

> People working with matrixes would probably rather write:
>   (* (A i j) (B i j))
> than:
>   (* (array-ref A i j) (array-ref B i j))
> or even:
>   (* (~ A i j) (~ B i j))

They can just use SRFI-105,

    {A[i j] * B[i j]}

which is very well-suited for this sort of thing, so I would rather not
let that use-case affect this SRFI too much.

Thanks for your input!
Taylan