Created
February 14, 2012 18:07
-
-
Save TimToady/1828667 to your computer and use it in GitHub Desktop.
now mentions native types and warnings on literal OKness smartmatch attemps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
OKness type unification (DRAFT) | |
======================= | |
Current problems | |
================ | |
Plethora of acceptance/rejection types/values | |
Match | |
True | |
False | |
Nil | |
Failure | |
Match() | |
Match() looks to a newbie like it indicates success when it indicates failure | |
my $x = 0 but True; if $x { say "T" } else { say "F" } # says F in rakudo | |
Bare Failure and Nil are essentially multiplied entities for the same concept | |
The meta-Bool rule for .ACCEPTS feels arbitrary and non-extensible | |
Neither Match nor Nil can deal with arbitrary "interesting values of success/failure" | |
Infectious failure on cascaded methods is hard to check with // | |
Nil has too many methods that make it look like () | |
Nil should not be pretending to be () at all | |
Proposal | |
======== | |
Failure and Match will both go away as insufficiently general. | |
Unify all these under a role called OKness. | |
Within OKness, there are two roles, OK and Nil. | |
Either of these can be instantiated empty or with "interesting values" | |
(those with interesting values denotes as OK+ and Nil+ below). | |
OK lives inside Any. | |
Nil lives outside of Any. | |
A successful match now returns OK instantiated with match info, if any. | |
A failed match returns Nil, with optional "why it didn't match" info for bad failure. | |
(Whether this throws/warns/ignores might depend on the info type.) | |
OK and Nil are primarily for forcing direct resolution of smartmatching; | |
To first approximation, OK/Nil force only truth, definedness, and .REALLY; | |
all other normal methods are delegated to the delegate in .REALLY. | |
OK is intrinsically true, not just via .Bool method, hence: | |
'0 but True' needs to become more like 'OK[REALLY => 0]' so that primitive 'if' | |
works both correctly and quickly. | |
Nil is likewise intrinsically false, not just via .Bool method. | |
In this table, OK/Nil must work in 'if' conditionals, not just ?* and friends: | |
if *.defined inAny payload sink=die unmeta | |
OK+ yes yes yes yes no *.does(OK) & *.can('REALLY') | |
OK yes yes yes no no *.does(OK) & none *.can('REALLY') | |
True yes yes yes no no *.doos(Bool) & ?* | |
False no yes yes no no *.does(Bool) & !* | |
Nil no no no no no *.does(Nil) & none *.can('REALLY') | |
Nil+ no no no yes yes *.does(Nil) & *.can('REALLY') | |
(*.can('REALLY') is probably something more intrinsic) | |
Types outside of OKness must call .Bool to determine truthiness (though native types | |
and known-non-derived types can generally optimize this away). | |
Smartmatching adopts a meta-OKness instead of meta-Bool. | |
[Conjecture: in order to allow a smartmatch that encompasses | |
only OKness types, the OKness type object itself is not meta | |
to smartmatch, so you can say $result ~~ OKness, or have a | |
parameter of type OKness. Otherwise *.does(OKness) would do.] | |
Along with Bool, OKness types may not be used literally in smartmatching, | |
and will warn when such usage is parsed. | |
return; returns () | |
fail "message"; returns Nil+Exception(message) | |
fail $exception ;returns Nil+$exception | |
fail; returns fail "Failed" | |
succeed retains same scoping to topicalizer | |
succeed; returns OK | |
succeed($foo) returns OK+$foo | |
[Conjecture: fail scopes to topicalizer/sub the same as succeed] | |
Any failed method call on any form of Nil passes the Nil through transparently | |
bogus().foo.bar.[$x] // die "Oops: $!"; # sees Nil from bogus() | |
Nil is now an item. | |
Nil no longer tries to emulate () in list context; use () if you mean that. | |
Autovivifying whence probably becomes a form of Nil that is not transparent to .[] and .{} | |
(that is, subscript methods respond to Nil, but pass on any Nil that is not a closure) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What about something like: