Last active
August 29, 2015 14:26
-
-
Save skids/9fe5f64d7ce65c2c1695 to your computer and use it in GitHub Desktop.
Implicit named slurpy
This file contains hidden or 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
On the subject of whether methods should have implicit *%_ or not I figured | |
some side-by-side examples would be useful to help the community come to | |
a decision. | |
Note that Mu.new will still have a prototype of *%_. So banning | |
unknown named parameters will require custom constructors in either case, | |
so we'll use them in the examples. | |
EXAMPLE: Only allow one optional/default argument to a method | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::A { | class N::A { | |
method foo (|c (:$a = 1)) { | method foo (:$a = 1) { | |
... | ... | |
} | } | |
} | } | |
EXAMPLE: Allow arbitrary nameds while supplying a default to a particular named | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::B { | class N::B { | |
method foo (:$b = 1) { | method foo (:$b = 1, *%_) { | |
... | ... | |
} | } | |
} | } | |
EXAMPLE: subclass the *::A class and add a new optional/default named parameter, | |
keeping restriction against unknown parameters, when the old parameter is unused in the subclass | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::C does M::A { | class N::C does N::A { | |
method foo (|c (:$a?, :$c = 1)) { | method foo (:$a?, :$c = 1) { | |
... | ... | |
nextwith(:$a); | nextwith(:$a); | |
} | } | |
} | } | |
EXAMPLE: subclass the *::B class and add a new optional/default named parameter, | |
still with no restricition against unknown parameters, when the old parameter is unused in the subclass | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::D does M::B { | class N::D does N::B { | |
method foo (:$c = 1) { | method foo (:$c = 1, *%_) { | |
... | ... | |
nextsame; | nextsame; | |
} | } | |
} | } | |
EXAMPLE: subclass the *::A class and add a new optional/default named parameter, | |
keeping restriction against unknown parameters, when the old parameter is used | |
and mandatory in the subclass | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::E does M::A { | class N::E does N::A { | |
method foo (|c (:$a!, :$c = 1)) { | method foo (:$a!, :$c = 1) { | |
... # Do something with $a | ... # Do something with $a | |
nextwith(:$a); | nextwith(:$a); | |
} | } | |
} | } | |
EXAMPLE: subclass the *::B class and add a new optional/default named parameter, | |
still with no restricition against unknown parameters, when the old parameter is | |
mandatory and used in the subclass | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::F does M::B { | class N::F does N::B { | |
method foo (:$b!, :$c = 1) { | method foo (:$b!, :$c = 1, *%_) { | |
... # Do something with $a | ... # Do something with $a | |
nextsame; | nextsame; | |
} | } | |
} | } | |
So the basic examples really boil down just to the difference between whether paradigm | |
N has to write (|c (#'signature)) everywhere or on the other side whether paradigm M has | |
to write (#'signature , *%_) everywhere. | |
Lets look at what happens when a someone wants to make an N subclass of an M class and vice | |
versa. | |
EXAMPLE: Subclass the *::A class so that it accepts (and ignores) unknown named parameters. | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::G does M::A { | class N::G does N::A { | |
method foo (:$a) { | method foo (:$a, *%_) { | |
... | ... | |
nextwith(:$a) | nextwith(:$a) | |
} | } | |
} | } | |
EXAMPLE: Subclass the ::*B class to not accept unknown named parameters | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::H does M::B { | class N::H does N::B { | |
method foo (|c (:$b? )) { | method foo (:$b?) { | |
... | ... | |
nextsame; | nextsame; | |
} | } | |
} | } | |
EXAMPLE: Patch the *::C class because the maintainer of the *::A class added a new named | |
optional parameter and you want to allow the subclass to use it. | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::C does M::A { | class N::C does N::A { | |
- method foo (|c (:$a?, :$c = 1)) { | - method foo (:$a?, :$c = 1) { | |
+ method foo (|c (:$a?, :$c = 1, :$d?)) { | + method foo (:$a?, :$c = 1, :$d?) { | |
... | ... | |
- nextwith(:$a); | - nextwith(:$a); | |
+ nextwith(:$a, :$d); | + nextwith(:$a, :$d); | |
} | } | |
} | } | |
EXAMPLE: Patch the *::D class because the maintainer of the *::B class added a new named | |
optional parameter and you want to allow the subclass to use it. | |
AS IS | NO IMPLICIT *%_ | |
--------------------------------------------------|------------------------------------------------------- | |
class M::D does M::B { | class N::D does N::B { | |
method foo (:$c = 1) { | method foo (:$c = 1, *%_) { | |
... | ... | |
nextsame; | nextsame; | |
} | } | |
} | } | |
(no patch needed) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment