Oldes / Rebol-wishes

Repository for keeping Rebol related wishes out of issues
0 stars 0 forks source link

Parity Between MAKE and construction syntax #30

Open Siskin-Bot opened 4 years ago

Siskin-Bot commented 4 years ago

Submitted by: Hostilefork

MAKE TYPE! ... and #[type! ...] have historically performed similar actions. They had different entry points in R3-Alpha, with the former being the response to an A_MAKE "action!", and the latter the product of a confusingly-named "MakeType" function, e.g. MT_Object().

What the two paths did was sometimes the same, and shared code by means of the A_MAKE action delegating to MT_XXX. Sometimes it just repeated the code, and did the same thing. Sometimes it repeated the code and did slightly different things. :-/

While construction syntax was mostly a subset of MAKE syntax, a notable exception was for array types generally. Construction syntax allowed the pre-loading of an index into the scanned value:

>> x: #[paren! [a b c] 2]
== (b c)

>> head x
== (a b c)

This shows construction syntax being used to create a PAREN! value that is pre-configured at an internal index.

The internal index is optional, so construction syntax is effectively variadic:

>> x: #[paren! [a b c]]
== (a b c)

Yet MAKE is not variadic, and has a fixed arity of 2, acting identically to TO:

>> make paren! [[a b c] 2]
== ([a b c] 2)

>> make paren! [a b c]
== (a b c)

This could be a reasonable argument that MAKE of an ANY-ARRAY! type with a BLOCK! argument should treat it as data and position, while the simpler conversion is covered by TO. Also, since the construction syntax is passing in a temporary series generated by the loader, it gets reuses vs. copying. Applied to MAKE that would mean:

>> foo: [a b c]
>> bar: make paren! reduce [foo 2]
(b c)

>> append foo 'd
[a b c d]

>> bar
(b c d)

The variadic MAKE feature appears to only have been used by #[image! ... and ANY-SERIES! construction. The proposal here would be:

This would create parity between MAKE and construction syntax, so they could share a common and well-tested code path. If MAKE were determined to be more general and permit forms that construction syntax did not, then that limitation would be indicated by passing a boolean parameter to the shared construction routine.


Imported from: https://github.com/rebol/rebol-issues/issues/2263

Comments:


Hostilefork mentioned this issue on Apr 8, 2016: Permit "AS" Aliasing of types with same series storage class


Hostilefork commented on Apr 8, 2016:

I'll add a general note about something that is an existing problem. Some MAKE or construction syntax calls would invoke the evaluator.

It seems generally like MAKE is the problem, and should be a low-level construction means that does not perform evaluations. If evaluation is necessary to construct something, that should be done by a higher-level routine than MAKE. There are actually some good mechanical reasons for having all the evaluations done before trying to construct a low-level object in the memory pools, because if you wind up running code it could trigger things like garbage collection which may inspect the partially built thing you are in the middle of constructing.

So that's bad from the interpreter code's perspective no matter what. But it's particularly noticeably bad from the user's perspective to call the evaluator while scanning. That means you can wind up with things like THROWs or RETURNs... or files being opened and closed...just because you tried to LOAD or TRANSCODE a string with "... #[some-type! ...] ..." in it.