Hi Rowan,

Rowan Collins wrote:
On 04/01/2016 16:34, Andrea Faulds wrote:
In Haskell, a purely-functional programming language, certain
operators (and also certain math functions like abs()) are defined as
part of "typeclasses", somewhat akin to interfaces in classical
object-oriented languages like Java or PHP. These typeclasses group
related operations together, and a conforming implementation of that
typeclass must implement all the operations. [...] I think it would be
more worth pursuing a Haskell-style approach in PHP, most likely with
a hierarchy of magic interfaces.

For those not familiar with type classes, it's worth mentioning
something you clarified to me over Twitter some time ago, about how they
differ from interfaces (correct me if I go wrong). With an interface,
the definition of GMP could include "implements NumLike", meaning that
any instance of GMP "is a NumLike object"; there are only two entities
to define: the interface, and the class which implements it. With a type
class, GMP itself wouldn't implement NumLike, you would have a third
entity, which was "an instance of NumLike for GMP objects"; GMP would
"have a NumLike type class", defined externally to it.

That's correct, yes. In Haskell, the data type definition, the type class definition, and the the type class implementation are all separate, which is different from Java-style interfaces (which PHP has) where you combine interface implementation with data type definition.

This goes some way to addressing the question of which operand receives
the message that an overloaded operator has been invoked - the
implementation would not have a "$this". As I understand it,
multi-parameter type classes even allow you to bridge between types that
aren't aware of each other - e.g. define the result of gmp_init(42) +
\Litipk\BigNumbers\Decimal::create(42)

Indeed, since type class implementations are separate from the data types they apply to and the definition of the typeclass. Data types in Haskell themselves don't really have awareness of other things anyway, Haskell doesn't have objects.

(A nitpick: at least in the case of `Num` type class, where + is defined, Haskell doesn't actually let you define how to add one type to another, at least not directly, since it has only one type parameter. Instead, you have to do an explicit conversion if you want to do such an addition. And anyway, it's true that *for multi-parameter type classes*, what you describe would be possible.)

And yes, you can make an implementation of operators yourself for types which don't already have one.

The major disadvantage to separating the implementation of the operator
/ type class from the class definition is that I can't see how it would
work with autoloading.

Yeah, I don't know how well type classes for operator overloading would work in PHP. I was thinking of using interfaces instead for PHP operator overloading, since they're what we already have and are familiar, even if they lack some of type classes' benefits. The problem with interfaces, though, is the $this one, as you mentioned. That's a bit of a headache.

Thanks for your input!
--
Andrea Faulds
https://ajf.me/

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to