Browse files

clobber undef as a poorly defined noun, use Object or Nil

git-svn-id: c213334d-75ef-0310-aa23-eaa082d1ae64
  • Loading branch information...
1 parent 5569877 commit 62d7cb7cc42fbca62c46bb5f4ee577db329d9baa lwall committed Nov 24, 2009
@@ -13,8 +13,8 @@ Synopsis 2: Bits and Pieces
Created: 10 Aug 2004
- Last Modified: 19 Nov 2009
- Version: 191
+ Last Modified: 23 Nov 2009
+ Version: 192
This document summarizes Apocalypse 2, which covers small-scale
lexical items and typological issues. (These Synopses also contain
@@ -591,17 +591,17 @@ Variables with non-native types can always contain I<undefined> values,
such as C<Object>, C<Whatever> and C<Failure> objects. See S04 for more
about failures (i.e. unthrown exceptions):
- my Int $x = undef; # works
+ my Int $x = Int; # works
Variables with native types do not support undefinedness: it is an error
to assign an undefined value to them:
- my int $y = undef; # dies
+ my int $y = Int; # dies
-Conjecture: num might support the autoconversion of undef to NaN, since
-the floating-point form can represent this concept. Might be better
-to make that conversion optional though, so that the rocket designer
-can decide whether to self-destruct immediately or shortly thereafter.
+Since C<num> can support the value C<NaN> but not the general concept of
+undefinedness, you can coerce an undefined value like this:
+ my num = computation() // NaN;
Variables of non-native types start out containing an undefined value
unless explicitly initialized to a defined value.
@@ -1047,14 +1047,18 @@ endianness.)
=head2 Undefined types
-These can behave as values or objects of any class, except that
-C<defined> always returns false. One can create them with the
-built-in C<undef> and C<fail> functions. (See S04 for how failures
-are handled.)
+Perl 6 does not have a single value representing undefinedness.
+Instead, objects of various types can carry type information while
+nevertheless remaining undefined themselves. Whether an object is
+defined is determined by whether C<.defined> returns true or not.
+These typed objects typically represent unitialized values. Failure
+objects are also officially undefined despite carrying exception
+information; these may be created using the C<fail> function, or by
+direct construction of an exception object of some sort. (See S04
+for how failures are handled.)
- Nil Empty list viewed as an item
Object Uninitialized (derivatives serve as type objects)
- Whatever Wildcard (like undef, but subject to do-what-I-mean via MMD)
+ Whatever Wildcard (like Object, but subject to do-what-I-mean via MMD)
Failure Failure (lazy exceptions, thrown if not handled properly)
Whenever you declare any kind of type, class, module, or package, you're
@@ -1074,52 +1078,11 @@ classes:
Whenever a C<Failure> value is put into a typed container, it takes
on the type specified by the container but continues to carry the
-C<Failure> role. (The C<undef> function merely returns the most
-generic C<Failure> object. Use C<fail> to return more specific failures. Use
+C<Failure> role.
+Use C<fail> to return specific failures. Use
C<Object> for the most generic non-failure undefined value. The C<Any>
type is also undefined, but excludes C<junctions> so that autothreading
-may be dispatched using normal multiple dispatch rules.)
-The C<Nil> type is officially undefined as an item but interpolates
-as a null list into list context, and an empty capture into slice
-context. A C<Nil> object may also carry failure information,
-but if so, the object behaves as a failure only in item context.
-Use C<Failure> when you want to return a hard failure that
-will not evaporate in list context. Casting to C<Nil> is one
-way of evaluating an expression and throwing the result away:
- @inclist = map { $_ + 1 }, @list || Nil( warn 'Empty @list!' );
- @inclist = do for @list || Nil( warn 'Empty @list!' ) {
- $_ + 1;
- }
-Or if you want to test whether you got any results back from
-the C<map> or C<for>:
- @inclist = do map { $_ + 1 }, @list or Nil( warn 'Empty @list!' );
- @inclist = do for @list {
- $_ + 1;
- } or Nil( warn 'Empty @list!' )
-Since the construct is in the form of a type cast, the parens are required.
-If that syntax is unappealing or you wish to run multiple statements
-in a block, it happens that the C<sink> statement prefix also converts
-any value to C<Nil>, so the examples above can be expressed
-without parentheses:
- @inclist = map { $_ + 1 }, @list || sink warn 'Empty @list!';
- @inclist = do for @list || sink { warn 'Empty @list!'; $warnings++; } {
- $_ + 1;
- }
- @inclist = do map { $_ + 1 }, @list or sink warn 'Empty @list!';
- @inclist = do for @list {
- $_ + 1;
- } or sink { warn 'Empty @list!'; $warnings++; }
+may be dispatched using normal multiple dispatch rules.
=head2 Immutable types
@@ -1128,7 +1091,7 @@ if and only if their types and contents are identical (that is, if
C<$x.WHICH> eqv C<$y.WHICH>).
Str Perl string (finite sequence of Unicode characters)
- Bit Perl single bit (allows traits, aliasing, undef, etc.)
+ Bit Perl single bit (allows traits, aliasing, undefinedness, etc.)
Int Perl integer (allows Inf/NaN, arbitrary precision, etc.)
Num Perl number (approximate Real, generally via floating point)
Rat Perl rational (exact Real, limited denominator)
@@ -1239,9 +1202,9 @@ the default default for a C<KeyHash> is 0 for numeric types, C<False>
for boolean types, and the null string for string and buffer types.
A C<KeyHash> of a C<Object> type defaults to the undefined prototype
for that type. More generally, the default default is whatever defined
-value an C<undef> would convert to for that value type. A C<KeyHash>
+value a C<Nil> would convert to for that value type. A C<KeyHash>
of C<Scalar> deletes elements that go to either 0 or the null string.
-A C<KeyHash> also autodeletes keys for normal undef values (that is,
+A C<KeyHash> also autodeletes keys for normal undefined values (that is,
those undefined values that do not contain an unthrown exception).
A C<KeySet> is a C<KeyHash> of booleans with a default of C<False>.
@@ -1827,6 +1790,43 @@ also the relative identities of several related objects. Conversely,
you can think of Perl 5 references as a degenerate form of C<Capture>
when you want to refer only to a single item.
+The empty C<Parcel> is a value with a special name: C<Nil>. It is
+the named equivalent of the empty C<()> list. The C<Nil> value is
+officially undefined as an item but interpolates as a null list into
+list context, and an empty parcel into slice context.
+Assigning or binding C<Nil> to any scalar container causes the
+container to throw out any contents and restore itself to an
+uninitialized state (after which it will contain a type object
+appropriate to the declared type of the container, or C<Object>
+for untyped containers).
+Assigning or binding C<Nil> to any composite container (such as an
+C<Array> or C<Hash>) empties the container, resetting it back to an
+uninitialized state. The container object itself remains defined.
+The C<sink> statement prefix will eagerly evaluate any block or
+statement, throw away the results, and instead return the C<Nil> value.
+This can be useful to peg some behavior to an empty list while still
+returning an empty list:
+ # Check that incoming argument list isn't null
+ @inclist = map { $_ + 1 }, @list || sink warn 'Nil input!';
+ @inclist = do for @list || sink { warn 'Nil input!'; $warnings++; } {
+ $_ + 1;
+ }
+ # Check that outgoing result list isn't null
+ @inclist = do map { $_ + 1 }, @list or sink warn 'Nil result!';
+ @inclist = do for @list {
+ $_ + 1;
+ } or sink { warn 'Nil result'; $warnings++; }
+Given C<sink>, there's no need for an "else" clause on Perl 6's loops,
+and the C<sink> construct works in any list, not just C<for> loops.
=item *
A signature object (C<Signature>) may be created with colon-prefixed parens:
@@ -1918,14 +1918,14 @@ To make a slice subscript return something other than values, append an
appropriate adverb to the subscript.
@array = <A B>;
- @array[0,1,2]; # returns 'A', 'B', undef
+ @array[0,1,2]; # returns 'A', 'B', Nil
@array[0,1,2] :p; # returns 0 => 'A', 1 => 'B'
@array[0,1,2] :kv; # returns 0, 'A', 1, 'B'
@array[0,1,2] :k; # returns 0, 1
@array[0,1,2] :v; # returns 'A', 'B'
%hash = (:a<A>, :b<B>);
- %hash<a b c>; # returns 'A', 'B', undef
+ %hash<a b c>; # returns 'A', 'B', Nil
%hash<a b c> :p; # returns a => 'A', b => 'B'
%hash<a b c> :kv; # returns 'a', 'A', 'b', 'B'
%hash<a b c> :k; # returns 'a', 'b'
@@ -1569,8 +1569,8 @@ longer come in via C<@_>. You can either name your formal parameters
explicitly if there is an explicit signature, or pull them out of C<%_>
rather than C<@_> if there is no explicit signature.
-[It's likely this operator will be removed from the core Perl 6 language
-and only supplied by the translator as a macro, so don't write any new
+[This operator will not actually be supplied by the core Perl 6 language
+but only by the translator as a macro, so don't write any new
code with it.]
=item *
@@ -3282,7 +3282,7 @@ as a default because the more specific types listed above it didn't match.
====== ===== ===================== ===================
Any Callable:($) item sub truth X($_)
Any Callable:() simple closure truth X() (ignoring $_)
- Any undef undefined not .defined
+ Any !.defined undefined not .defined
Any * block signature match block successfully binds to |$_
Any .foo method truth ?X i.e. ?.foo
Any .foo(...) method truth ?X i.e. ?.foo(...)
@@ -4096,7 +4096,7 @@ Builtin reduce operators return the following identity values:
[//]() # Any
[min]() # +Inf
[max]() # -Inf
- [=]() # undef (same for all assignment operators)
+ [=]() # Nil (same for all assignment operators)
[,]() # []
[Z]() # []
@@ -1101,7 +1101,7 @@ prohibition on bypassing formal binding.)
=head1 Exceptions
-As in Perl 5, many built-in functions simply return C<undef> when you
+As in Perl 5, many built-in functions simply return an undefined value when you
ask for a value out of range, or the function fails somehow. Perl 6
has C<Failure> objects, any of which refers to an unthrown C<Exception>
object in C<$!> and knows whether it has been handled or not. C<$!>
@@ -1329,7 +1329,7 @@ process initialization time).
If an exception is thrown through a block without a C<CATCH> phaser, the
C<LEAVE>, C<UNDO> and C<POST> phasers will be run at that point, with
C<$!> set to the in-flight exception. If there is no in-flight
-exception when these phasers are run, C<$!> will be C<undef>. The last
+exception when these phasers are run, C<$!> will be C<Nil>. The last
exception caught in the outer block is available as C<< OUTER::<$!> >>,
as usual.
@@ -1533,7 +1533,7 @@ So any Perl 6 function can say
and not care about whether the function is being called in item or list
context. To return an explicit scalar undef, you can always say
- return undef;
+ return Object;
Then in list context, you're returning a list of length 1, which is
defined (much like in Perl 5). But generally you should be using
@@ -812,7 +812,7 @@ Named parameters are optional unless marked with a following C<!>.
Default values for optional named parameters are defined in the same
way as for positional parameters, but may depend only on existing
values, including the values of parameters that have already been
-bound. Named optional parameters default to C<undef> if they have
+bound. Named optional parameters default to C<Nil> if they have
no default. Named required parameters fail unless an argument pair
of that name is supplied.
@@ -195,9 +195,9 @@ parameter is reserved for such purposes.
The C<CANDO> is expected to return an inner container object of
the proper sort (i.e. a variable, subroutine, or method object),
-or a proxy object that can "autovivify" lazily, or C<undef> if that
+or a proxy object that can "autovivify" lazily, or C<Nil> if that
name is not to be considered declared in the namespace in question.
-(Only bare C<undef> is interpreted as "not there", since typed undefs
+(Only bare C<Nil> is interpreted as "not there", since typed undefs
may function as autovivifiable proxy objects. See S12.)
The declaration merely defines the interface to the new object. That object
@@ -831,7 +831,7 @@ to a method in the standard fashion. There are also "dot" variants
that call some number of methods with the same name:
$object.meth(@args) # calls one method or dies
- $object.?meth(@args) # calls method if there is one, otherwise undef
+ $object.?meth(@args) # calls method if there is one, otherwise Nil
$object.*meth(@args) # calls all methods (0 or more)
$object.+meth(@args) # calls all methods (1 or more)
@@ -105,7 +105,7 @@ Each of these has a default action as well. The possible actions are:
Term Default action is to terminate the process.
- Ign Default action is to ignore the signal ($signal.exception is undef by default)
+ Ign Default action is to ignore the signal ($signal.exception is undefined by default)
Core Default action is to terminate the process and dump core (see core(5)).
@@ -157,7 +157,7 @@ The exceptions are:
See L<S04-control> for details on how to handle exceptions.
XXX I'm unsure how the actions in the table above can be made to make sense. The Ign
-actions are already dealt with because %SIG{CHLD}.exception already defaults to undef.
+actions are already dealt with because %SIG{CHLD}.exception already defaults to undefined.
The Term action will probably be self-solving (ie. will terminate the process). The
others I'm just plain unsure about. XXX
@@ -478,7 +478,7 @@ end time
suspended (not diff from block on wakeup signal)
waiting on a handle, a condition, a lock, et cetera
otherwise returns false for running threads
-if it's finished then it's undef(?)
+if it's finished then it's Nil
=item current_continuation
@@ -566,7 +566,7 @@ revive a thread; fail if already running
survives parent thread demise (promoted to process)
process-local changes no longer affects parent
tentatively, the control methods still applies to it
-including wait (which will always return undef)
+including wait (which will always return Nil)
also needs to discard any atomicity context
=item "is throttled" trait
@@ -52,7 +52,7 @@ The following are defined in the C<Object> role:
our Bool multi method defined ( $self: ::role ) is export
C<defined> returns true if the parameter has a value and that value is
-not the undefined value (per C<undef>), otherwise false is returned.
+considered defined by its type, otherwise false is returned.
Same as Perl 5, only takes extra optional argument to ask if value is defined
with respect to a particular role:
@@ -235,23 +235,6 @@ scalar variables. All of the following are exported by default.
-=item undef
- constant Scalar Scalar::undef
-Returns the undefined scalar object. C<undef> has no value at
-all, but for historical compatibility, it will numify to C<0>
-and stringify to the empty string, potentially generating a
-warning in doing so. There are two ways to determine if a
-value equal to undef: the C<defined> function (or method) can
-be called or the C<//> (or C<orelse>) operator can be used.
-C<undef> is also considered to be false in a boolean context.
-Such a conversion does not generate a warning.
-Perl 5's unary C<undef> function is renamed C<undefine> to avoid
-confusion with the value C<undef> (which is always 0-ary now).
=item VAR
This is not really a method, but some kind of macro. See L<S12> for details.
@@ -208,7 +208,7 @@ EOI = End Of Input -- equivalent to End Of File, but applies to other kinds of s
Returns true if it's the end of the input (i.e. end of file or whatever), returns false if
-not, returns undef if we can't say for certain.
+not, fails if we can't say for certain.
=item method seek(Int $position --> Bool)
@@ -328,7 +328,7 @@ Works like awk's RS variable, including treating empty lines
as a terminator if set to the null string.
(An empty line cannot contain any spaces or tabs.)
You may set it to a multi-character string to match a multi-character
-terminator, or to undef to read through the end of file.
+terminator, or to Nil to read through the end of file.
Setting it to "\n\n" means something slightly different
than setting to "", if the file contains consecutive empty lines.
Setting to "" will treat two or more consecutive empty lines
@@ -1334,7 +1334,7 @@ Use C<stat> with the C<:link> option.
Changed to C<.path>, but we haven't gotten around to specifying this on all of them.
The C<.name> method returns the name of the file/socket/uri the handle
-was opened with, if known. Returns undef otherwise. There is no
+was opened with, if known. Returns Nil otherwise. There is no
corresponding C<name()> function.
=item pipe
@@ -262,7 +262,7 @@ The value returned is always a C<StrPos> object. If the substring
is found, then the C<StrPos> represents the position of the first
character of the substring. If the substring is not found, a bare
C<StrPos> containing no position is returned. This prototype C<StrPos>
-evaluates to false because it's really a kind of undef. Do not evaluate
+evaluates to false because it's really a kind of undefined value. Do not evaluate
as a number, because instead of returning -1 it will return 0 and issue
a warning.

0 comments on commit 62d7cb7

Please sign in to comment.