Can go be functional?

Part 1. Iterators

Go's generics leave a fair amount to be desired, especially if you're trying to implement functional primitives.

In the following code, there is nowhere for me to provide the type of X. I can only make a map function that returns the same type as the generic type T provided on the receiver

// INVALID
func (o *Option[T]) Map(f func(T) K) *Option[K]

However, I can write Map as a free function and provide the generic type parameter

// VALID
func Map[T any, K any](o *Option[T], f func(T) K) *Option[K]

There already exist an iterator interface in iter.Seq. If you create an adapter interface like

type IntoIter[T any] interface {
	Iter() iter.Seq[T]
}

This could be even more generic Unfortunately, go doesn't allow implementing methods on interfaces or foreign types or
interfaces, like with rust's traits. This means you can't have identity interfaces implementations like

// INVALID
func (i iter.Seq[T]) IntoIter() iter.Seq[T]{
	return i
}

So instead we need to use iter.Seq[T] as our generic interface

func Map[T any, K any](i iter.Seq[T], f func(T) K) iter.Seq[K]

Though we can use type constraint adapters

type Iter[T any] interface {
	iter.Seq[T] | IntoIter[T]
}


func Into[T any](i Iter[T]) iter.Seq[T] {
	switch i := any(i).(type) {
		case iter.Seq[T]:
			return i
		case IntoIter[T]:
			return i.Iter()
	}
	// impossible due to type constriants
	return nil
}

func Map[T any, K any](i Iter[T], f func(T) K ) Iter[T]

But guess what, that doesn't work either. Go type constraint interfaces can't contain methods...which kind of ruins this.

All of this is to say that yes, you can obviously write functional code with go, but it is missing a lot of the core language features needed to make it really ergonomic. You can follow along with the functional go experiments I'm doing at in my fn package.