Suggested change to the sample implementation, & other comments Göran Weinholt (21 Oct 2022 18:08 UTC)
(missing)
Fwd: Suggested change to the sample implementation, & other comments Marc Nieper-Wißkirchen (23 Oct 2022 11:34 UTC)
Re: Suggested change to the sample implementation, & other comments Marc Nieper-Wißkirchen (23 Oct 2022 11:36 UTC)
Re: Suggested change to the sample implementation, & other comments Marc Nieper-Wißkirchen (22 Oct 2022 08:17 UTC)
Re: Suggested change to the sample implementation, & other comments Marc Nieper-Wißkirchen (22 Oct 2022 14:17 UTC)

Re: Suggested change to the sample implementation, & other comments Marc Nieper-Wißkirchen 22 Oct 2022 08:16 UTC

Am Sa., 22. Okt. 2022 um 00:04 Uhr schrieb Lassi Kortela <xxxxxx@lassi.io>:

[...]

> While this is cool, IMHO this example highlights the problem with the
> specification: wrapping these in (perform ...) would imply that (xid-id
> ...) is re-orderable.
>
> If side effects are later added to xid-id, that assumption becomes
> false. (I don't mean to imply that you'd actually add side effects to a
> record field getter, but imagine a big codebase full of procedure calls
> inside (perform ...) blocks and it's not hard for mistakes to slip in.)

If a programmer blindly adds expressions to a "perform" block but does
not know about its semantics, it's the programmer's problem, not the
problem of "perform".

If the programmer is unsure whether the order of expressions matters
but knows one order that will work, they will change "perform" to a
"begin", probably adding a comment that the problem has not been
thoroughly analyzed.

If the programmer is unsure whether the order of expressions matters
and finds one order by experimentation that happens to work, they
should give the task to someone else.

> If "perform" is renamed to something that more clearly indicates it's a
> low-level tool to be used sparingly, that's fine. My worry is that
> people will sprinkle it casually around a codebase, oblivious to the
> fact that it doesn't offer any safeguards.
>
> Another alternative is something like (declare (side-effect-free
> xid-id)) which can be placed closer to the definition of xid-id,
> therefore more likely to be correct.

"Perform" can also be used when there are side effects, even when
there are non-commuting side effects. Think of a procedure
"empty-wastebin" that moves waste to the dump.  Obviously,
(empty-wastebin wb1) and (empty-wastebin wb2) have side effects and
don't commute (because the order of the waste on the dump will be
different), but in most cases, the non-commutativity doesn't matter.
If your program is about such a case, you write

(perform
  (empty-wastebin wb1)
  (empty-wastebin wb2))

If I ask a person to buy a liter of milk and a loaf of bread, I
usually don't care about the order they do it. So, the "perform" form
is about providing the right abstraction and not primarily meant as a
low-level tool. But, of course, because it provides the right
abstraction in its area of application, it allows a compiler to
understand the code better.

[...]