markrogoyski / math-php

Powerful modern math library for PHP: Features descriptive statistics and regressions; Continuous and discrete probability distributions; Linear algebra with matrices and vectors, Numerical analysis; special mathematical functions; Algebra
MIT License
2.32k stars 238 forks source link

Implicit Behavior of ImmutableSet #466

Open Smoren opened 1 year ago

Smoren commented 1 year ago

Hi @markrogoyski,

I have a suggestion about SetTheory namespace.

I found that ImmutableSet extends Set and the mutation methods of the ImmutableSet implicitly do nothing. I think this is unexpected behavior.

So what about making a new abstract class BaseSet with all the methods of the Set exclude mutators and edit both of Set and ImmutableSet to extend BaseSet?

Something like this:

abstract class BaseSet implements \Countable, \Iterator
{
    protected $A = [];

    public function __construct(array $members = []);
    public function asArray(): array;
    public function length(): int;
    public function isEmpty(): bool;
    public function isMember($x): bool;
    public function isNotMember($x): bool;
    protected function getKey($x): ?string;
    public function isDisjoint(Set $other): bool;
    public function isSubset(Set $B): bool;
    public function isProperSubset(Set $B): bool;
    public function isSuperset(Set $B): bool;
    public function isProperSuperset(Set $B): bool;
    public function union(Set ...$Bs): Set;
    public function intersect(Set ...$Bs): Set;
    public function difference(Set ...$Bs): Set;
    public function symmetricDifference(Set $B): Set;
    public function cartesianProduct(Set ...$Bs): Set;
    public function powerSet(): Set;
    public function copy(): Set;
    public function __toString(): string;
    public function count(): int;

    protected $iterator_keys;
    protected $iterator_position;

    public function rewind(): void;
    public function valid(): bool;
    public function current();
    public function key();
    public function next(): void;
}

class Set extends BaseSet {
    public function add($x): Set;
    public function addMulti(array $x): Set;
    public function remove($x): Set;
    public function removeMulti(array $x): Set;
    public function clear(): Set;
}

class ImmutableSet extends BaseSet
{
}

And one more thing: maybe it's better to have BaseSet implement IteratorAggregate interface instead of Iterator?