Fixes to build with Go 1.18 official release thanks to @billinghamj input - Thank You
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f9dc00e..1bca3d1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -4,7 +4,7 @@
   test:
     strategy:
       matrix:
-        go-version: [1.18.0-beta1]
+        go-version: [1.18.0]
         os: [ubuntu-latest, macos-latest, windows-latest]
     runs-on: ${{ matrix.os }}
     steps:
@@ -19,4 +19,4 @@
       run: |
         go test -v -race ./...
         # go vet ./...
-        # go test -bench=.
\ No newline at end of file
+        # go test -bench=.
diff --git a/set.go b/set.go
index ca0b1bf..1441467 100644
--- a/set.go
+++ b/set.go
@@ -162,14 +162,7 @@
 	Union(other Set[T]) Set[T]
 
 	// Pop removes and returns an arbitrary item from the set.
-	Pop() any
-
-	// Returns all subsets of a given set (Power Set).
-	// PowerSet({x, y, z}) -> {{}, {x}, {y}, {z}, {x, y}, {x, z}, {y, z}, {x, y, z}}
-	PowerSet() Set[any]
-
-	// Returns the Cartesian Product of two sets.
-	CartesianProduct(other Set[T]) Set[any]
+	Pop() (T, bool)
 
 	// Returns the members of the set as a slice.
 	ToSlice() []T
@@ -195,7 +188,7 @@
 // NewSetWith creates and returns a new set with the given elements.
 // Operations on the resulting set are thread-safe.
 func NewSetWith[T comparable](vals ...T) Set[T] {
-	return NewSetFromSlice[T](vals)
+	return NewSetFromSlice(vals)
 }
 
 // NewSetFromSlice creates and returns a reference to a set from an
diff --git a/set_test.go b/set_test.go
index 4fcb71f..44e3f1a 100644
--- a/set_test.go
+++ b/set_test.go
@@ -975,12 +975,17 @@
 	a.Add("c")
 	a.Add("d")
 
-	captureSet := NewSet[any]()
-	captureSet.Add(a.Pop())
-	captureSet.Add(a.Pop())
-	captureSet.Add(a.Pop())
-	captureSet.Add(a.Pop())
-	finalNil := a.Pop()
+	aPop := func() (v string) {
+		v, _ = a.Pop()
+		return
+	}
+
+	captureSet := NewSet[string]()
+	captureSet.Add(aPop())
+	captureSet.Add(aPop())
+	captureSet.Add(aPop())
+	captureSet.Add(aPop())
+	finalNil := aPop()
 
 	if captureSet.Cardinality() != 4 {
 		t.Error("unexpected captureSet cardinality; should be 4")
@@ -994,7 +999,7 @@
 		t.Error("unexpected result set; should be a,b,c,d (any order is fine")
 	}
 
-	if finalNil != nil {
+	if finalNil != "" {
 		t.Error("when original set is empty, further pops should result in nil")
 	}
 }
@@ -1007,12 +1012,17 @@
 	a.Add("c")
 	a.Add("d")
 
-	captureSet := NewThreadUnsafeSet[any]()
-	captureSet.Add(a.Pop())
-	captureSet.Add(a.Pop())
-	captureSet.Add(a.Pop())
-	captureSet.Add(a.Pop())
-	finalNil := a.Pop()
+	aPop := func() (v string) {
+		v, _ = a.Pop()
+		return
+	}
+
+	captureSet := NewThreadUnsafeSet[string]()
+	captureSet.Add(aPop())
+	captureSet.Add(aPop())
+	captureSet.Add(aPop())
+	captureSet.Add(aPop())
+	finalNil := aPop()
 
 	if captureSet.Cardinality() != 4 {
 		t.Error("unexpected captureSet cardinality; should be 4")
@@ -1026,39 +1036,11 @@
 		t.Error("unexpected result set; should be a,b,c,d (any order is fine")
 	}
 
-	if finalNil != nil {
+	if finalNil != "" {
 		t.Error("when original set is empty, further pops should result in nil")
 	}
 }
 
-func Test_PowerSet(t *testing.T) {
-	a := NewThreadUnsafeSet[string]()
-
-	a.Add("1")
-	a.Add("delta")
-	a.Add("chi")
-	a.Add("4")
-
-	b := a.PowerSet()
-	if b.Cardinality() != 16 {
-		t.Error("unexpected PowerSet cardinality")
-	}
-}
-
-func Test_PowerSetThreadSafe(t *testing.T) {
-	// set := NewSet().PowerSet()
-	// _, setIsThreadSafe := set.(*threadSafeSet)
-	// if !setIsThreadSafe {
-	// 	t.Error("result of PowerSet should be thread safe")
-	// }
-
-	// subset := set.Pop()
-	// _, subsetIsThreadSafe := subset.(*threadSafeSet)
-	// if !subsetIsThreadSafe {
-	// 	t.Error("subsets in PowerSet result should be thread safe")
-	// }
-}
-
 func Test_EmptySetProperties(t *testing.T) {
 	empty := NewSet[string]()
 
@@ -1095,53 +1077,9 @@
 		t.Error("The intesection of any set with the empty set is supposed to be the empty set")
 	}
 
-	d := a.CartesianProduct(empty)
-	if d.Cardinality() != 0 {
-		t.Error("Cartesian product of any set and the empty set must be the empty set")
-	}
-
 	if empty.Cardinality() != 0 {
 		t.Error("Cardinality of the empty set is supposed to be zero")
 	}
-
-	// e := empty.PowerSet()
-	// if e.Cardinality() != 1 {
-	// 	t.Error("Cardinality of the power set of the empty set is supposed to be one { {} }")
-	// }
-}
-
-func Test_CartesianProduct(t *testing.T) {
-	a := NewThreadUnsafeSet[any]()
-	b := NewThreadUnsafeSet[any]()
-	empty := NewThreadUnsafeSet[any]()
-
-	a.Add(1)
-	a.Add(2)
-	a.Add(3)
-
-	b.Add("one")
-	b.Add("two")
-	b.Add("three")
-	b.Add("alpha")
-	b.Add("gamma")
-
-	c := a.CartesianProduct(b)
-	d := b.CartesianProduct(a)
-
-	if c.Cardinality() != d.Cardinality() {
-		t.Error("Cardinality of AxB must be equal to BxA")
-	}
-
-	if c.Cardinality() != (a.Cardinality() * b.Cardinality()) {
-		t.Error("Unexpected cardinality for cartesian product set")
-	}
-
-	c = a.CartesianProduct(empty)
-	d = empty.CartesianProduct(b)
-
-	if c.Cardinality() != 0 || d.Cardinality() != 0 {
-		t.Error("Cartesian product of any set and the empty set Ax0 || 0xA must be the empty set")
-	}
 }
 
 func Test_ToSliceUnthreadsafe(t *testing.T) {
diff --git a/threadsafe.go b/threadsafe.go
index b144ad4..1a137a9 100644
--- a/threadsafe.go
+++ b/threadsafe.go
@@ -227,39 +227,12 @@
 	return ret
 }
 
-func (s *threadSafeSet[T]) PowerSet() Set[any] {
-	s.RLock()
-	unsafePowerSet := s.uss.PowerSet().(*threadUnsafeSet[any])
-	s.RUnlock()
-
-	ret := &threadSafeSet[any]{uss: newThreadUnsafeSet[any]()}
-	for subset := range unsafePowerSet.Iter() {
-		unsafeSubset := subset.(*threadUnsafeSet[any])
-		ret.Add(&threadSafeSet[any]{uss: *unsafeSubset})
-	}
-	return ret
-}
-
-func (s *threadSafeSet[T]) Pop() any {
+func (s *threadSafeSet[T]) Pop() (T, bool) {
 	s.Lock()
 	defer s.Unlock()
 	return s.uss.Pop()
 }
 
-func (s *threadSafeSet[T]) CartesianProduct(other Set[T]) Set[any] {
-	o := other.(*threadSafeSet[T])
-
-	s.RLock()
-	o.RLock()
-
-	unsafeCartProduct := s.uss.CartesianProduct(&o.uss).(*threadUnsafeSet[any])
-	ret := &threadSafeSet[any]{uss: *unsafeCartProduct}
-
-	s.RUnlock()
-	o.RUnlock()
-	return ret
-}
-
 func (s *threadSafeSet[T]) ToSlice() []T {
 	keys := make([]T, 0, s.Cardinality())
 	s.RLock()
diff --git a/threadsafe_test.go b/threadsafe_test.go
index c257f52..9dcb050 100644
--- a/threadsafe_test.go
+++ b/threadsafe_test.go
@@ -472,16 +472,17 @@
 }
 
 func Test_UnmarshalJSON(t *testing.T) {
-	s := []byte(`["test", 1, 2, 3]`) //,["4,5,6"]]`)
-	expected := NewSetFromSlice[any](
-		[]any{
-			json.Number("1"),
-			json.Number("2"),
-			json.Number("3"),
+	s := []byte(`["test", "1", "2", "3"]`) //,["4,5,6"]]`)
+	expected := NewSetFromSlice(
+		[]string{
+			string(json.Number("1")),
+			string(json.Number("2")),
+			string(json.Number("3")),
 			"test",
 		},
 	)
-	actual := NewSet[any]()
+
+	actual := NewSet[string]()
 	err := json.Unmarshal(s, actual)
 	if err != nil {
 		t.Errorf("Error should be nil: %v", err)
@@ -493,17 +494,17 @@
 }
 
 func Test_MarshalJSON(t *testing.T) {
-	expected := NewSetFromSlice[any](
-		[]any{
-			json.Number("1"),
+	expected := NewSetFromSlice(
+		[]string{
+			string(json.Number("1")),
 			"test",
 		},
 	)
 
 	b, err := json.Marshal(
-		NewSetFromSlice[any](
-			[]any{
-				1,
+		NewSetFromSlice(
+			[]string{
+				"1",
 				"test",
 			},
 		),
@@ -512,7 +513,7 @@
 		t.Errorf("Error should be nil: %v", err)
 	}
 
-	actual := NewSet[any]()
+	actual := NewSet[string]()
 	err = json.Unmarshal(b, actual)
 	if err != nil {
 		t.Errorf("Error should be nil: %v", err)
diff --git a/threadunsafe.go b/threadunsafe.go
index c98e6f0..afd15fa 100644
--- a/threadunsafe.go
+++ b/threadunsafe.go
@@ -29,31 +29,9 @@
 	"bytes"
 	"encoding/json"
 	"fmt"
-	"reflect"
 	"strings"
 )
 
-// An OrderedPair represents a 2-tuple of values.
-type OrderedPair[T comparable] struct {
-	First  T
-	Second T
-}
-
-// Equal says whether two 2-tuples contain the same values in the same order.
-func (pair *OrderedPair[T]) Equal(other OrderedPair[T]) bool {
-	if pair.First == other.First &&
-		pair.Second == other.Second {
-		return true
-	}
-
-	return false
-}
-
-// String outputs a 2-tuple in the form "(A, B)".
-func (pair OrderedPair[T]) String() string {
-	return fmt.Sprintf("(%v, %v)", pair.First, pair.Second)
-}
-
 type threadUnsafeSet[T comparable] map[T]struct{}
 
 // Assert concrete type:threadUnsafeSet adheres to Set interface.
@@ -77,27 +55,6 @@
 	return len(*s)
 }
 
-func (s *threadUnsafeSet[T]) CartesianProduct(other Set[T]) Set[any] {
-	o := other.(*threadUnsafeSet[T])
-
-	// NOTE: limitation with Go s or of my knowledge of Go s?
-
-	// I can't seem to declare this without an instantiation cycle.
-	//cartProduct := NewThreadUnsafeSet[OrderedPair[T]]()
-
-	// So here is my crime against humanity.
-	cartProduct := NewThreadUnsafeSet[any]()
-
-	for i := range *s {
-		for j := range *o {
-			elem := OrderedPair[T]{First: i, Second: j}
-			cartProduct.Add(elem)
-		}
-	}
-
-	return cartProduct
-}
-
 func (s *threadUnsafeSet[T]) Clear() {
 	*s = newThreadUnsafeSet[T]()
 }
@@ -230,42 +187,12 @@
 }
 
 // TODO: how can we make this properly , return T but can't return nil.
-func (s *threadUnsafeSet[T]) Pop() any {
+func (s *threadUnsafeSet[T]) Pop() (v T, ok bool) {
 	for item := range *s {
 		delete(*s, item)
-		return item
+		return item, true
 	}
-	return nil
-}
-
-func (s *threadUnsafeSet[T]) PowerSet() Set[any] {
-	// The type must be any comparable so we have to dumb down to any.
-	powSet := NewThreadUnsafeSet[any]()
-
-	nullset := newThreadUnsafeSet[T]()
-	powSet.Add(&nullset)
-
-	for es := range *s {
-		u := newThreadUnsafeSet[any]()
-		j := powSet.Iter()
-		for er := range j {
-			p := newThreadUnsafeSet[T]()
-			if reflect.TypeOf(er).Name() == "" {
-				k := er.(*threadUnsafeSet[T])
-				for ek := range *(k) {
-					p.Add(ek)
-				}
-			} else {
-				p.Add(er.(T))
-			}
-			p.Add(es)
-			u.Add(&p)
-		}
-
-		powSet = powSet.Union(&u)
-	}
-
-	return powSet
+	return
 }
 
 func (s *threadUnsafeSet[T]) Remove(v T) {