pub enum StackType {
Empty,
Cons {
rest: Box<StackType>,
top: Type,
},
RowVar(String),
}Expand description
Stack types with row polymorphism
§Understanding Stack Type Representation
Seq uses row polymorphism to type stack operations. The stack is represented
as a linked list structure using Cons cells (from Lisp terminology).
§Components
-
Cons { rest, top }: A “cons cell” pairing a value type with the rest of the stacktop: The type of the value at this positionrest: What’s underneath (anotherCons,Empty, orRowVar)
-
RowVar("name"): A row variable representing “the rest of the stack we don’t care about”- Enables polymorphic functions like
dupthat work regardless of stack depth - Written as
..namein stack effect signatures
- Enables polymorphic functions like
-
Empty: An empty stack (no values)
§Debug vs Display Format
The Debug format shows the internal structure (useful for compiler developers):
Cons { rest: Cons { rest: RowVar("a$5"), top: Int }, top: Int }The Display format shows user-friendly notation (matches stack effect syntax):
(..a$5 Int Int)§Reading the Debug Format
To read Cons { rest: Cons { rest: RowVar("a"), top: Int }, top: Float }:
- Start from the outermost
Cons- itstopis the stack top:Float - Follow
restto the nextCons- itstopis next:Int - Follow
resttoRowVar("a")- this is the polymorphic “rest of stack”
Cons { rest: Cons { rest: RowVar("a"), top: Int }, top: Float }
│ │ │
│ │ └── top of stack: Float
│ └── second from top: Int
└── rest of stack: ..a (whatever else is there)
Equivalent to: (..a Int Float) or in signature: ( ..a Int Float -- ... )§Fresh Variables (e.g., “a$5”)
During type checking, variables are “freshened” to avoid name collisions:
abecomesa$0,a$1, etc.- The number is just a unique counter, not semantically meaningful
a$5means “the 6th fresh variable generated with prefix ‘a’”
§Example Error Message
divide: stack type mismatch. Expected (..a$0 Int Int), got (..rest Float Float)Meaning:
divideexpects twoIntvalues on top of any stack (..a$0)- You provided two
Floatvalues on top of the stack (..rest) - The types don’t match:
IntvsFloat
Variants§
Empty
Empty stack - no values
Cons
Stack with a value on top of rest (a “cons cell”)
Named after Lisp’s cons (construct) operation that builds pairs.
Think of it as: top is the head, rest is the tail.
Fields
RowVar(String)
Row variable representing “rest of stack” for polymorphism
Allows functions to be polymorphic over stack depth.
Example: dup has effect ( ..a T -- ..a T T ) where ..a means
“whatever is already on the stack stays there”.