Skip to content

Commit

Permalink
Allow SET/PAD to be used with BLANK on BLOCK! targets
Browse files Browse the repository at this point in the history
R3-Alpha and Red let you write `set [a b] 10`, since the thing
you were setting to was not a block, would assume you meant to set
all the values to that.  BUT since you can set things to blocks,
this has a bad characteristic of `set [a b] [10]` being treated
differently, which can bite you if you `set [a b] value` for some
generic value.

Ren-C does not carry forward the behavior, rather it allows only
one case...to pass in a blank value with /PAD and handle that blank
as if it were an empty block, return blanks.  This permits things
like `if set [a b] find data 'whatever [...]` to do a blank
propagation.

This is to facilitate the only known client of the behavior, which was
the module code.

!!! Should there be a SET/ONLY to allow for `set/only [a b] [10]`
such that a and b would be set to 10?  Adding more complexity to a
primitive like SET is not very desirable, and you can do this other
ways in usermode if it's what you really want.
  • Loading branch information
hostilefork committed May 3, 2017
1 parent 5337611 commit b86b5eb
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
38 changes: 31 additions & 7 deletions src/core/n-data.c
Expand Up @@ -858,17 +858,41 @@ REBNATIVE(set)
REBSPC *target_specifier;

if (IS_BLOCK(ARG(target))) {
if (NOT(IS_BLOCK(ARG(value))))
//
// R3-Alpha and Red let you write `set [a b] 10`, since the thing
// you were setting to was not a block, would assume you meant to set
// all the values to that. BUT since you can set things to blocks,
// this has a bad characteristic of `set [a b] [10]` being treated
// differently, which can bite you if you `set [a b] value` for some
// generic value.
//
// Ren-C does not carry forward the behavior, rather it allows only
// one case...to pass in a blank value with /PAD and handle that blank
// as if it were an empty block, return blanks. This permits things
// like `if set [a b] find data 'whatever [...]` to do a blank
// propagation.
//
// !!! Should there be a SET/ONLY to allow for `set/only [a b] [10]`
// such that a and b would be set to 10? Seems to add complexity for
// a case that is not that compelling.
//
if (IS_BLANK(ARG(value)) && REF(pad)) {
value = ARR_HEAD(EMPTY_ARRAY); // don't change ARG(value)
value_specifier = SPECIFIED;
}
else if (IS_BLOCK(ARG(value))) {
//
// There is no need to check values for voidness in this case,
// since arrays cannot contain voids.
//
value = VAL_ARRAY_AT(ARG(value));
value_specifier = VAL_SPECIFIER(ARG(value));
}
else
fail (ARG(value)); // value must be a block if setting a block

target = VAL_ARRAY_AT(ARG(target));
target_specifier = VAL_SPECIFIER(ARG(target));

// There is no need to check values for voidness in this case, since
// arrays cannot contain voids.
//
value = VAL_ARRAY_AT(ARG(value));
value_specifier = VAL_SPECIFIER(ARG(value));
}
else {
// Use the fact that D_CELL is implicitly terminated so that the
Expand Down
2 changes: 1 addition & 1 deletion src/mezz/sys-load.r
Expand Up @@ -783,7 +783,7 @@ load-module: function [
; set to false later if existing module is used
override?: not no-lib

set [name0: mod0: sum0:] pos: find/skip system/modules name 3
set/pad [name0: mod0: sum0:] pos: find/skip system/modules name 3
] [
; Get existing module's info
case/all [
Expand Down
11 changes: 11 additions & 0 deletions tests/context/set.test.reb
Expand Up @@ -6,3 +6,14 @@
[x: has [a: 1 b: 2] all [error? try [set x reduce [3 ()]] x/a = 1]]
; set [:get-word] [word]
[a: 1 b: _ set [b] [a] b = 'a]

; Behavior in R3-Alpha allowed `set [a b] 10` to set both, but created a
; bad variance with `set [a b] [10]`. Rather than complicate SET with /ONLY,
; the behavior going forward is just to allow blanking with pad, so that
; `set/pad [a b] blank` gives the same effect as `set/pad [a b] []`, except
; returning blank instead of the empty block.
[
a: 10
b: 20
all? [blank = set/pad [a b] blank | blank? a | blank? b]
]

0 comments on commit b86b5eb

Please sign in to comment.