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

liberal SWITCH eval, kill SWITCH/DEFAULT, CASE fallout #822

Merged
merged 1 commit into from
Jun 20, 2018
Merged

liberal SWITCH eval, kill SWITCH/DEFAULT, CASE fallout #822

merged 1 commit into from
Jun 20, 2018

Conversation

hostilefork
Copy link
Member

@hostilefork hostilefork commented Jun 19, 2018

The speculative feature of "SWITCH fallout" has been endorsed as a
legitimate way to return a value from a switch. This says that if the
last match item is reached with no associated branch block after it,
the match item itself is the evaluative result:

>> switch 3 [1 ["one"] 2 ["two"] "other"]
== "other"

A question posed about this was:

"Does fallout make SWITCH feel like it's fancier and has good dialecting bones, taking advantage of Rebol's unconventional-ness? Or does it make SWITCH seem weird...like you're looking at incomplete code, missing the branch for the last switch case?"

The decision was that for Rebol's domain, this kind of implementation
choice goes well with the "fast-and-loose" character of the language,
especially with a "fully evaluative switch". It enables styles of
coding that may appeal to programmers who are already used to the
general flexibility of the language, such as:

x: 3
string: switch x [
   1 + 4 ["five"]
   2 ["two"]
   fail "No match found"
]

Going along with the endorsement is the elimination of SWITCH/DEFAULT,
which is not relevant considering the null protocol. Cases that don't use
the result can get the same effect with:

if null? switch [
    ...cases here...
][
    ...default code here...
]

But more importantly, if the result is to be used, you can use the fallout
feature...or it can work with ELSE or UNLESS or any of the other
null-triggered constructs.

Since SWITCH allows the last evaluated condition to fall out, this
extends the ability to CASE. CASE statements now have more structure,
expecting a condition/block alternation...though blocks may appear in
the conditions themselves. Fallout presents a more elegant and
matching way of handling no match. Historically this was done with
a truthy final condition:

case [
   1 > 2 [...]
   3 > 4 [...]
   true [fail "No matching condition"]
]

For fail in particular, this would always have worked if written with
the fail in an unpaired condition slot:

case [
    1 > 2 [...]
    3 > 4 [...]
    fail "No matching condition"
]

But with fallout, any value can appear there:

<fallout> = case [
   1 > 2 [...]
   3 > 4 [...]
   <fallout>
]

One strong argument in favor of the feature is that people can use it
if they want, and ignore it if they want. But it's an option which
errs on the side of expressiveness over strict structure--and anyone
who wants more structure can build that into their own dialects.

The speculative feature of "SWITCH fallout" has been endorsed as a
legitimate way to return a value from a switch.  This says that if the
last match item is reached with no associated branch block after it,
the match item itself is the evaluative result:

    >> switch 3 [1 ["one"] 2 ["two"] "other"]
    == "other"

A question posed about this was:

    "Does fallout make SWITCH feel like it's fancier and has good
    dialecting bones, taking advantage of Rebol's unconventional-ness?
    Or does it make SWITCH seem weird...like you're looking at
    incomplete code, missing the branch for the last switch case?"

The decision was that for Rebol's domain, this kind of implementation
choice goes well with the "fast-and-loose" character of the language,
especially with a "fully evaluative switch".  It enables styles of
coding that may appeal to programmers who are already used to the
general flexibility of the language, such as:

    x: 3
    switch x [
       1 + 4 ["five"]
       2 ["two"]
       fail "No match found"
    ]

Going along with the endorsement is the elimination of SWITCH/DEFAULT,
which is not relevant considering the null protocol.  Most cases can
simply be changed to:

    if null? switch [
        ...
    ][
        ...
    ]

If taken branches all give truthy results, then that could be IF NOT.
But more importantly, it can work with ELSE or UNLESS or any of the
other null-triggered constructs.

Since SWITCH allows the last evaluated condition to fall out, this
extends the ability to CASE.  CASE statements now have more structure,
expecting a condition/block alternation...though blocks may appear in
the conditions themselves.  Fallout presents a more elegant and
matching way of handling no match.  Historically this was done with
a truthy final condition:

    case [
       1 > 2 [...]
       3 > 4 [...]
       true [fail "No matching condition"]
    ]

For fail in particular, this would always have worked if written with
the fail in an unpaired condition slot:

    case [
        1 > 2 [...]
        3 > 4 [...]
        fail "No matching condition"
    ]

But with fallout, any value can appear there:

    <fallout> = case [
       1 > 2 [...]
       3 > 4 [...]
       <fallout>
    ]

One strong argument in favor of the feature is that people can use it
if they want, and ignore it if they want.  But it's an option which
errs on the side of expressiveness over strict structure--and anyone
who wants more structure can build that into their own dialects.

Also disables the ability to run ACTION!s as branches in SWITCH and
CASE, but doesn't necessarily do so permanently.  It leaves the option
open for the future, if people decide it's important.  However, since
it is switched to normal block evaluation there was an issue with the
VALUE_FLAG_UNEVALUATED bit being written on the output of a branch
like `case [true [1]]` since the branch contained an unevaluated
value.  This modifies it so that only function argument fulfillments
let the flag escape.
@hostilefork hostilefork merged commit 6be0632 into metaeducation:master Jun 20, 2018
@hostilefork hostilefork deleted the case-switch-revamp branch June 20, 2018 03:19
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.

1 participant