3 Commits

Author SHA1 Message Date
3ef27bc28a feat: fmt.Stringer 2026-01-17 15:37:31 -05:00
dbb988b633 refactor: replace visitor pattern with type-switch recursion
Closes #36
2026-01-17 15:02:08 -05:00
52d40adcc6 chore: remove unused deltanet package (#35)
## Description

The `deltanet` package was an unused stub in the codebase.
This PR removes it to reduce clutter.

- Removed `pkg/deltanet/deltanet.go`.
- Removed `pkg/deltanet/node.go`.

Closes #34

## Benefits

- Reduces codebase complexity by removing unused code.
- Eliminates potential confusion from an incomplete stub package.

## Checklist

- [x] Code follows conventional commit format.
- [x] Branch follows naming convention (`<type>/<description>`).
- [x] Tests pass (if applicable).
- [x] Documentation updated (if applicable).

Reviewed-on: #35
Co-authored-by: M.V. Hutz <git@maximhutz.me>
Co-committed-by: M.V. Hutz <git@maximhutz.me>
2026-01-17 19:56:58 +00:00
5 changed files with 21 additions and 162 deletions

View File

@@ -1,6 +0,0 @@
// Package "deltanet" is a reduction strategy using ∆-nets.
package deltanet
type Graph struct {
Nodes []Node
}

View File

@@ -1,94 +0,0 @@
package deltanet
/** ------------------------------------------------------------------------- */
// A connection between exactly two nodes in a graph.
type Edge struct {
A, B Node
}
// Returns all nodes the edge is connected to.
func (e Edge) GetConnections() []Node { return []Node{e.A, e.B} }
// Determines if a node is connected via this edge.
func (e Edge) IsConnected(n Node) bool { return e.A == n || e.B == n }
// Swaps an edges connected with one node, for another.
func (e *Edge) Swap(from Node, to Node) {
if e.A == from {
e.A = to
}
if e.B == from {
e.B = to
}
}
// Returns true if the edge is connected to each node via their pricniple ports.
func (e Edge) IsPrincipleEdge() bool {
return e.A.GetMainPort() == e && e.B.GetMainPort() == e
}
/** ------------------------------------------------------------------------- */
type Node interface {
// Returns the principle port that the node is attached to.
GetMainPort() Edge
// Returns all auxiliary ports that the node has. These ports are guaranteed
// to be ordered clockwise, as they would appear graphically.
GetAuxPorts() []Edge
// Returns the label of the node. May be blank.
GetLabel() string
}
/** ------------------------------------------------------------------------- */
type EraserNode struct {
Main Edge
}
func (n EraserNode) GetLabel() string { return "Ⓧ" }
func (n EraserNode) GetMainPort() Edge { return n.Main }
func (n EraserNode) GetAuxPorts() []Edge { return []Edge{} }
/** ------------------------------------------------------------------------- */
type ReplicatorNode struct {
Main Edge
Level uint
Aux []Edge
Deltas []int
}
func (n ReplicatorNode) GetLabel() string { return "" }
func (n ReplicatorNode) GetMainPort() Edge { return n.Main }
func (n ReplicatorNode) GetAuxPorts() []Edge { return n.Aux }
// Returns the level of the replicator node.
func (n ReplicatorNode) GetLevel() uint { return n.Level }
/** ------------------------------------------------------------------------- */
type FanNode struct {
Label string
Main Edge
Left, Right Edge
}
func (n FanNode) GetLabel() string { return n.Label }
func (n FanNode) GetMainPort() Edge { return n.Main }
func (n FanNode) GetAuxPorts() []Edge { return []Edge{n.Left, n.Right} }
/** ------------------------------------------------------------------------- */
type TerminalNode struct {
Label string
Main Edge
}
func (n TerminalNode) GetLabel() string { return n.Label }
func (n TerminalNode) GetMainPort() Edge { return n.Main }
func (n TerminalNode) GetAuxPorts() []Edge { return []Edge{} }
/** ------------------------------------------------------------------------- */

View File

@@ -2,10 +2,14 @@
// expression types in the lambda interpreter. // expression types in the lambda interpreter.
package expr package expr
import (
"fmt"
)
// Expression is the base interface for all evaluatable expression types. // Expression is the base interface for all evaluatable expression types.
// Different evaluation modes (lambda calculus, SKI combinators, typed lambda // Different evaluation modes (lambda calculus, SKI combinators, typed lambda
// calculus, etc.) implement this interface with their own concrete types. // calculus, etc.) implement this interface with their own concrete types.
type Expression interface { type Expression interface {
// String returns a human-readable representation of the expression. // The expression should have a human-readable representation.
String() string fmt.Stringer
} }

View File

@@ -1,12 +1,13 @@
package lambda package lambda
import "git.maximhutz.com/max/lambda/pkg/expr" import (
"git.maximhutz.com/max/lambda/pkg/expr"
)
// Expression is the interface for all lambda calculus expression types. // Expression is the interface for all lambda calculus expression types.
// It embeds the general expr.Expression interface for cross-mode compatibility. // It embeds the general expr.Expression interface for cross-mode compatibility.
type Expression interface { type Expression interface {
expr.Expression expr.Expression
Accept(Visitor)
} }
/** ------------------------------------------------------------------------- */ /** ------------------------------------------------------------------------- */
@@ -16,6 +17,8 @@ type Abstraction struct {
body Expression body Expression
} }
var _ Expression = (*Abstraction)(nil)
func (a *Abstraction) Parameter() string { func (a *Abstraction) Parameter() string {
return a.parameter return a.parameter
} }
@@ -24,16 +27,12 @@ func (a *Abstraction) Body() Expression {
return a.body return a.body
} }
func (a *Abstraction) Accept(v Visitor) {
v.VisitAbstraction(a)
}
func (a *Abstraction) String() string { func (a *Abstraction) String() string {
return Stringify(a) return "\\" + a.parameter + "." + a.body.String()
} }
func NewAbstraction(parameter string, body Expression) *Abstraction { func NewAbstraction(parameter string, body Expression) *Abstraction {
return &Abstraction{parameter: parameter, body: body} return &Abstraction{parameter, body}
} }
/** ------------------------------------------------------------------------- */ /** ------------------------------------------------------------------------- */
@@ -43,6 +42,8 @@ type Application struct {
argument Expression argument Expression
} }
var _ Expression = (*Application)(nil)
func (a *Application) Abstraction() Expression { func (a *Application) Abstraction() Expression {
return a.abstraction return a.abstraction
} }
@@ -51,16 +52,12 @@ func (a *Application) Argument() Expression {
return a.argument return a.argument
} }
func (a *Application) Accept(v Visitor) {
v.VisitApplication(a)
}
func (a *Application) String() string { func (a *Application) String() string {
return Stringify(a) return "(" + a.abstraction.String() + " " + a.argument.String() + ")"
} }
func NewApplication(abstraction Expression, argument Expression) *Application { func NewApplication(abstraction Expression, argument Expression) *Application {
return &Application{abstraction: abstraction, argument: argument} return &Application{abstraction, argument}
} }
/** ------------------------------------------------------------------------- */ /** ------------------------------------------------------------------------- */
@@ -69,26 +66,16 @@ type Variable struct {
value string value string
} }
var _ Expression = (*Variable)(nil)
func (v *Variable) Value() string { func (v *Variable) Value() string {
return v.value return v.value
} }
func (v *Variable) Accept(visitor Visitor) {
visitor.VisitVariable(v)
}
func (v *Variable) String() string { func (v *Variable) String() string {
return Stringify(v) return v.value
} }
func NewVariable(name string) *Variable { func NewVariable(name string) *Variable {
return &Variable{value: name} return &Variable{name}
}
/** ------------------------------------------------------------------------- */
type Visitor interface {
VisitAbstraction(*Abstraction)
VisitApplication(*Application)
VisitVariable(*Variable)
} }

View File

@@ -1,32 +0,0 @@
package lambda
import "strings"
type stringifyVisitor struct {
builder strings.Builder
}
func (v *stringifyVisitor) VisitVariable(a *Variable) {
v.builder.WriteString(a.value)
}
func (v *stringifyVisitor) VisitAbstraction(f *Abstraction) {
v.builder.WriteRune('\\')
v.builder.WriteString(f.parameter)
v.builder.WriteRune('.')
f.body.Accept(v)
}
func (v *stringifyVisitor) VisitApplication(c *Application) {
v.builder.WriteRune('(')
c.abstraction.Accept(v)
v.builder.WriteRune(' ')
c.argument.Accept(v)
v.builder.WriteRune(')')
}
func Stringify(e Expression) string {
b := &stringifyVisitor{builder: strings.Builder{}}
e.Accept(b)
return b.builder.String()
}