Skip to content

Instantly share code, notes, and snippets.

@happy-barney
Last active July 3, 2020 04:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save happy-barney/4f3777793e5b484d8a788cf7a9e1beed to your computer and use it in GitHub Desktop.
Save happy-barney/4f3777793e5b484d8a788cf7a9e1beed to your computer and use it in GitHub Desktop.

Meta signatures

Abstract

Imagine every function of instance of its own class with every function argument as class field.

use has word to allocate context variable

	sub foo {
		has $x => isa => <Constraint>, default => 1;
		has $y => isa => <Constraint>, default => 2;

		return $x + $y;
	}

import signature of another fuction

Treat function reference as a role

	sub Parent::foo {
		has $x => default => 1;
		has $y => default => 2;
	}

	sub Child::foo {
		does \& Parent::foo;

		return 2 * $x + $y;
	}

works for anonymous functions as well

	my $foo = sub { ... };
	my $bar = sub { does $foo; ... }

OOP - override shortcut

	override bar {
		return 2 * $x + $y;
	}

OOP - returns constraint

	package Parent {
		sub foo {
			returns Number::Even;
		}
	}

	package Child {
		override foo {
			returns Number::odd;
			# every return will
		}
	}

dependencies - conditionally required

	sub foo {
		has $x => required => 1;
		has $y => required => sub { $x % 2 };
	}

dependencies - address parameter before defined

	sub volume {
		has $x => required => sub { ! exists $area };
		has $y => required => sub { ! exists $area };
		has $z => required => 1;
		has $area => default => sub { $x * $y };

		return $area * $z;
	}

consistency with class declaration

using modified Object::Pad example

class Point {
	has $x = 0;
	has $y = 0;

	method move {
		has $dX;
		has $dY;

		$x += $dX;
		$y += $dY;
	}
}

multiple dispatch

continuation of previous example

{
	method move {
		has $dX =>
			required => sub { exists $dY && ! exists $radius },
			default  => sub { $distance * cos $radius },
			;
		has $dY =>
			required => sub { exists $dX && ! exists $radius },
			default  => sub { $distance * sin $radius },
			;
		has $radius => required => sub { ! exists $dX || ! exists $dY };
		has $distance => required => sub { exists $radius };
		$x += $dX;
		$y += $dY;
	}
}

$obj->move (1, 1);
$obj->move (radius => 0.707, distance => 0.707);
$obj->move (dX => 1, dY => 1);
$obj->move (1, dX => 1);
$obj->move (1, dY => 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment