Skip to content

Commit

Permalink
Kill IS_CONDITIONAL_TRUE()/IS_CONDITIONAL_FALSE()
Browse files Browse the repository at this point in the history
There was a speculative feature implemented which would cause errors
when conditionals were used with literal blocks, to stop the relatively
common newbie mistake:

    if [var = value] [print "var equals value"]

A distinct test than the system test for "falsey-ness" was added which
was a test for "conditional falsehood" which didn't accept literal
blocks.

The supporting infrastructure to be able to offer such an error is the
VALUE_FLAG_UNEVALUATED, which is interesting and has a lot of cool
applications.  But applying it in the core to this feature was deemed
to be a relatively small benefit, and it also breaks several cases
where literals in conditional slots might be useful, such as:

    compose/only [... if (condition) [...] ...]

There may still be applications and means to check this common mistake,
but along with several other "safety measures" this is probably not
a fit for the core primitives.
  • Loading branch information
hostilefork committed Nov 19, 2018
1 parent 1fefdbf commit 2ca0bdc
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 33 deletions.
14 changes: 4 additions & 10 deletions src/core/n-control.c
Expand Up @@ -67,7 +67,7 @@ REBNATIVE(if)
{
INCLUDE_PARAMS_OF_IF;

if (IS_CONDITIONAL_FALSE(ARG(condition))) // fails on void, literal blocks
if (IS_FALSEY(ARG(condition))) // fails on void
return nullptr;

if (Do_Branch_With_Throws(D_OUT, ARG(branch), ARG(condition)))
Expand All @@ -92,7 +92,7 @@ REBNATIVE(if_not)
{
INCLUDE_PARAMS_OF_IF_NOT;

if (IS_CONDITIONAL_TRUE(ARG(condition))) // fails on void, literal blocks
if (IS_TRUTHY(ARG(condition))) // fails on void
return nullptr;

if (Do_Branch_With_Throws(D_OUT, ARG(branch), ARG(condition)))
Expand Down Expand Up @@ -121,7 +121,7 @@ REBNATIVE(either)

if (Do_Branch_With_Throws(
D_OUT,
IS_CONDITIONAL_TRUE(ARG(condition)) // fails on void, literal blocks
IS_TRUTHY(ARG(condition)) // fails on void
? ARG(true_branch)
: ARG(false_branch),
ARG(condition)
Expand Down Expand Up @@ -149,12 +149,6 @@ inline static void Either_Test_Core_May_Throw(
switch (VAL_TYPE(test)) {

case REB_LOGIC: { // test for "truthy" or "falsey"
//
// If this is the result of composing together a test with a literal,
// it may be the *test* that changes...so in effect, we could be
// "testing the test" on a fixed value. Allow literal blocks (e.g.
// use IS_TRUTHY() instead of IS_CONDITIONAL_TRUE())
//
Init_Logic(out, VAL_LOGIC(test) == IS_TRUTHY(arg));
return; }

Expand Down Expand Up @@ -718,7 +712,7 @@ static void Case_Choose_Core_May_Throw(
return;
}

if (IS_CONDITIONAL_FALSE(cell)) { // not a matching condition
if (IS_FALSEY(cell)) { // not a matching condition, fails on void
if (choose) {
Fetch_Next_In_Frame(nullptr, f); // skip next, whatever it is
continue;
Expand Down
19 changes: 0 additions & 19 deletions src/include/sys-value.h
Expand Up @@ -1068,25 +1068,6 @@ inline static bool IS_TRUTHY(const RELVAL *v) {
Init_Logic((out), false)


// Although a BLOCK! value is true, some constructs are safer by not allowing
// literal blocks. e.g. `if [x] [print "this is not safe"]`. The evaluated
// bit can let these instances be distinguished. Note that making *all*
// evaluations safe would be limiting, e.g. `foo: any [false-thing []]`...
// So ANY and ALL use IS_TRUTHY() directly
//
inline static bool IS_CONDITIONAL_TRUE(const REBVAL *v) {
if (GET_VAL_FLAG(v, VALUE_FLAG_FALSEY))
return false;
if (IS_VOID(v))
fail (Error_Void_Conditional_Raw());
if (IS_BLOCK(v) and GET_VAL_FLAG(v, VALUE_FLAG_UNEVALUATED))
fail (Error_Block_Conditional_Raw(v));
return true;
}

#define IS_CONDITIONAL_FALSE(v) \
(not IS_CONDITIONAL_TRUE(v))

inline static bool VAL_LOGIC(const RELVAL *v) {
assert(IS_LOGIC(v));
return NOT_VAL_FLAG((v), VALUE_FLAG_FALSEY);
Expand Down
4 changes: 0 additions & 4 deletions tests/control/if.test.reb
Expand Up @@ -30,10 +30,6 @@
; bitset
(if make bitset! "" [true])

; literal blocks illegal as condition in Ren-C, but evaluation products ok
(error? trap [if [] [true]])
(if identity [] [true])

; datatype
(if blank! [true])
; typeset
Expand Down

0 comments on commit 2ca0bdc

Please sign in to comment.