package list import ( "fmt" "strings" ) type EmptyList struct{} type List struct { Value any next *List } func Empty() *EmptyList { return new(EmptyList) } func New(val any) *List { return new(List).Init(val) } func (this *List) Init(val any) *List { return Init(this, val) } func Init(this *List, val any) *List { this.Value = val this.next = nil return this } func (this *List) Conj(val any) *List { return Conj(this, val) } func (this *EmptyList) Conj(val any) *List { return Conj(nil, val) } func Conj(this *List, val any) *List { if this == nil { return New(val) } new_head := New(val) new_head.next = this return new_head } func Rest(this *List) *List { if this == nil { return nil } return this.next } func (this *List) Rest() *List { return Rest(this) } func First(this *List) any { if this == nil { return nil } return this.Value } func (this *List) First() any { return First(this) } func (this *EmptyList) First() any { return First(nil) } func IsEmpty(this *List) bool { return this == nil } func (this *List) IsEmpty() bool { return this == nil } func (this *EmptyList) IsEmpty() bool { return true } func String(this *List) string { if this == nil { return "()" } var sb strings.Builder sb.WriteRune('(') // Iterate and print elements for e := this; e != nil; e = Rest(e) { sb.WriteString(fmt.Sprint(e.Value)) sb.WriteRune(' ') } return sb.String()[:sb.Len()-1] + ")" } func (this *List) String() string { return String(this) }