Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(How) does raku do class synonyms?

Tags:

oop

raku

I have

class Length is Measure export { ... }

I want synonyms that differ only in that the class name is different, I have tried this:

class Distance   is Length is export {}
class Breadth    is Length is export {}
class Width      is Length is export {}
class Height     is Length is export {}
class Depth      is Length is export {}

This kind of works in that $distance ~~ Length, but I also want $length ~~ Distance.

Some kind or coercion would be desirable - eg $length.Distance ~~ Distance to discourage operations like $width = $height + $depth (ie you cannot always add lengths that point along different axes).

Maybe some class kind of := name binding, or a shorthand way to coerce NxN?

Any advice most gratefully received...

like image 616
p6steve Avatar asked Feb 13 '21 18:02

p6steve


People also ask

What are the different raku techniques?

Perhaps one of the more interesting Raku techniques, the Horse Hair Raku technique, drapes horsehair across hot ceramic. You can use feathers, human hair, or dog hair. Anything that has oil content will create a combustible effect to where it leaves a carbon and ash mark on the ceramics. It soaks into the pottery to create a cool design.

What is a raku firing?

The raku process takes place during the final firing. The glaze fire in a raku process ranges in temperature between 1470-1830F (800-1000C). A raku firing is a relatively speedy process, usually taking between 1 and 2 hours. By contrast, a standard firing in a gas or electric kiln can take up to 24 hours from start to finish.

What is the difference between Raku and aka?

The Japanese have two main types of Raku called Kuro (black) and Aka (red). When they fire up the kiln, Aka is cooler than Kuro. The glaze maturing difference plays a role.

What can compete with a raku finish?

Detailed design or texture can compete or interfere with a raku finish. Naked and horsehair raku look most effective when the pottery has been burnished. The burnishing is done when the pottery is leather hard before being dried for the bisque fire. Some potters will apply terra sigillata to their pottery before burnishing.


2 Answers

This is not yet an answer, but might grow into one.

Is the following heading in useful directions for you? I don't necessarily mean for you to use composition instead of inheritance (role), or direct aliasing (constant), or mixins (but), or a dynamic type constraint (where). The code below is just a quick way to prototype until you provide feedback.

role Measurement {}
role Height does Measurement {}
role Width does Measurement {}
constant Breadth = Width;
say Width;                             # (Width)
say Breadth;                           # (Width)
say ::<Breadth>:kv;                    # (Breadth (Width))
say Breadth ~~ Width;                  # True
say Width ~~ Breadth;                  # True

multi infix:<+>
  (::L Measurement \l, 
       Measurement \r where * !~~ L)
{ fail }

say (42 but Width) + (99 but Breadth); # 141
say (42 but Width) + (99 but Height);  # Failed...
like image 193
raiph Avatar answered Nov 07 '22 11:11

raiph


I'd probably need to see a few more usage cases to be hundred percent sure what the best approach is, but at least with respect to ensuring that all length

class A { 
  method ACCEPTS($other) { $other.isa: A }
}

class B is A { }
class C is A { }
class D is A { }

my $b = B.new;
my $c = C.new;
my $d = D.new;

say $b ~~ D; # True
say $d ~~ C; # True
say $c ~~ B; # True

Because the ACCEPTS is defined on A here, that is what will be used for matching against B/C/D. By default, ACCEPTS smart matches using isa($?CLASS), which is why it returns false, but now it'll lock it into using A always.

Another way is to set the class to an alias. This is normally good for when you want to shorten the name of a longer class you imported from a module, but it will work here too:

class A { ... }
our \B = A;   my $b = B.new;
our \C = A;   my $c = C.new;
our \D = A;   my $d = D.new;

say $b ~~ A & C & D; # True

say $b.WHAT; # A
say $b.WHAT; # A
say $b.WHAT; # A

You'll notice that all these claim to be A because they are. All we've done is give another way to access A. This means that not only does B pass for D or A, it's indistinguishable from them because it's identical to them (down to where it's stored in memory).

like image 41
user0721090601 Avatar answered Nov 07 '22 11:11

user0721090601