Skip to content

Instantly share code, notes, and snippets.

@TimToady
Created February 14, 2012 18:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save TimToady/1828667 to your computer and use it in GitHub Desktop.
Save TimToady/1828667 to your computer and use it in GitHub Desktop.
now mentions native types and warnings on literal OKness smartmatch attemps
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)
@raiph
Copy link

raiph commented May 22, 2015

What about something like:

if *.defined inAny payload sink=die unmeta
true yes yes yes no no ~~ True[Mu]
true+ yes yes yes yes no ~~ True[Any]
false no yes yes no no ~~ False[Mu]
false+ no yes yes yes yes ~~ False[Any]
undef no no no no no ~~ Mu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment