Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Back out legality of x: (), CHECK-SET, SET+GET/OPT #216

Merged
merged 4 commits into from
Jan 12, 2016
Merged

Back out legality of x: (), CHECK-SET, SET+GET/OPT #216

merged 4 commits into from
Jan 12, 2016

Conversation

hostilefork
Copy link
Member

This is a set of changes rolled up that were triggered by the idea from
@earl to make an operation designed to "set-and-test" a variable, which
came off as notationally pleasing without having to sacrifice the error
on plain get word assignments of unsets.

It makes the core operation where a value is optional named SET/OPT
and GET/OPT, which is just as short as GET/ANY and SET/ANY but more
in line with the present intentions for the connection between the unset
state and optional parameters and values. The /ANY variations are
moved into user code for reasons that they were likely going to have to be
anyway...which will slow the primitives down some in the near term but
there should be ways of addressing it if it becomes a problem.

Due to hedging as a result of thoughts in chat, a previous decision to name
the opposite operation of UNSET? as SET? is revoked...before any more
cases of it get created. It is not certain that this is the best use of the word,
or if it should be used at all, so the more conservative ANY-VALUE? was
chosen to match the existing typeset (which is still containing unsets for the
moment but about to change).

With refinement arguments being unset by default, adapting bits of code
that had assumed they were NONE! required rewriting or a way to check
for a set state.  Rather than NOT UNSET? the operation SET? was
added--with rationale that SET! would not be a data type (given MAP!
and other concerns) and that this was a common test.

A realization in chat while trying to find a more communicative name
for VALUE? led to this possibility:

    >> set 'x 10
    >> set? 'x
    == true

    >> unset 'x
    >> unset? 'x
    == true

It paints a rather clear picture that SET? and UNSET? might be seen as
operations on variables as opposed to values.  (Bound words being the
closest thing Rebol has to representing "variables", as they are the
access points for both reads and writes.)  However it also raises a
number of questions.

So whether that decision goes forward or not, it made it seem hasty at
this point in time to pre-decide on SET? as the opposite of UNSET?
for values.  The ANY-VALUE! category typeset is already used in
function specs and considered "anything but UNSET!" (pending upcoming
change, it's still a synonym for ANY-TYPE! until #opt vs <opt> is
decided for function specs.)

Given that ANY-VALUE? is a safe bet, and may ultimately evolve into
simply VALUE? (if legacy uses can be corraled in relevant code or
given compatibility shims until they can be adapted), it replaces
SET? in this commit.  There are few uses so best to back them out
now that the question exists before they become widespread.
The problem which allowing `x: ()` to not be an error was designed to
address can be handled in a less system-breaking way with a primitive
suggested by @earl, which is CHECK-SET...an arity-2 function that
soft-quotes its first parameter, which is constrained to be either a
set-word or a set-path:

     if check-set var: thing-that-may-be-unset [
         ...
     ]

Idiomatically this comes across reasonably well that var: is being
set by this code.  CHECK-SET does not come off most importantly
as a query due to the lack of a question mark, rather as some form
of setting that involves a check.  Even if glossed as CHECK-SET? it
still fits well, as it seems an assignment has happened whether you
realize var: is a parameter to check-set or not.

The promise of this option outweighs the loss in locality of error
delivery given by allowing `x: ()`--hence that will be backed out
shortly.
This was a long-pending modification being motivated by taking another
step toward straightening out unsets.  The /ANY refinement has no
bearing on optional setting (and ANY has another much more common
meaning) while the /OPT refinement corresponds directly to the idea
of a value which can be unset as well as carry a range of other values.

GET already had a legacy mezzanine to support its fallthrough of
being able to get values like `get 3`, an ability that Red also did not
carry forward.  This moved SET out as well--which is forward-thinking
based on the idea that the current interface of SET for setting objects
positionally breaks the rule that objects aren't supposed to be
accessed by position.  Hence rather than pollute the core with a
deprecated refinement this moves the refinement out.

Having the versions of SET and GET be in user code will slow them
down some, which is unfortunate...but it's a temporary state as the
/ANY versions will be legacy mode after a sufficiently long time is
given with /OPT being offered for code to adapt.  There are also some
pending designs for speeding up such wrappers in a way that might not
require new bodies just to rename refinements (though as mentioned,
that's not necessarily all these particular wrappers will do.)
This reverses the decision to allow a plain assignment via set-word to
accept UNSET!.  The reasonings motivating the feature were valid, but
it can be done a better way, as pointed out by @earl and implemented
in CHECK-UNSET.

As a result, this restores locality of errors in bad assignments...
again requiring those places where an unset should unset in an assign
to explicit use of the SET/OPT operation (formerly SET/ANY)
@hostilefork hostilefork merged commit e65608a into metaeducation:master Jan 12, 2016
@earl
Copy link

earl commented Jan 12, 2016

Fantastic. Thanks for the quick turn-around!

@hostilefork hostilefork deleted the unset-assign-is-error branch January 13, 2016 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants