~technomancy/fennel#117: 
Expose safe method of modifing forms in macros

Some previous issues (1) resulted in a copy function being added to macros.fnl, to perform form modification hygienically.

It's probably worth formalising an interface to this, as well as documenting why it exists, so that macro writers can avoid the same mistakes.

https://github.com/bakpakin/Fennel/blob/fe02668a69acde9ca99ea6f91fe6902099f18242/src/fennel/macros.fnl#L4-L7

While the function is (currently?) pretty small, and generic (it operates on any table), I think it is probably worth giving it a more descriptive name to prompt its correct usage.

I am not sure if it should be called (clone-list ...) because it could be useful in other contexts, or perhaps limited to only the list type?

There is also the option of making it more complicated than table-in->table-out, such as (safely-modify-list some-list (fn [the-list] (table.insert the-list 2 :argument))) but that might not be to everyones taste.

I think including the "safely" term implies that there is a complementary "unsafe" way to do it, which sort of self-documents that you should use the function. That said, if the macro guide included some big words saying "hey if you're going to do (X f), do (X (copy f))" that's maybe just as good.

  1. https://github.com/bakpakin/Fennel/issues/416 &https://todo.sr.ht/~technomancy/fennel/110
Status
REPORTED
Submitter
~rktjmp
Assigned to
No-one
Submitted
2 years ago
Updated
a month ago
Labels
enhancement macros needs-design

~rktjmp 2 years ago

Also should the copy function be deep-recursive? Not quite sure on the semantics of it in the compiler context I guess. Since it is compile time, a recursive deep copy wont have any negative runtime impact at least.

~technomancy a month ago

I've made a branch that has this here: https://git.sr.ht/~technomancy/fennel/commit/04333f2224df734a4c5d406a08a033de5043c205

This is a simple metatable-preserving shallow-copy for generalized tables (the original copy only worked on sequences and lists because it didn't use pairs), which I think is good enough most of the time. It's quite rare that you'd have a macro that does invasive changes beyond the top level.

Having a higher-order function which takes an updater function would make sense if the data were immutable, but doesn't really fit with mutable tables.

Anyway, interested in hearing your thoughts.

Register here or Log in to comment, or comment via email.