Skip to content

Commit e76764e

Browse files
authored
Merge pull request #3 from Deric-W/cleanup
mark multiple things as final
2 parents 44cec67 + d587e33 commit e76764e

File tree

9 files changed

+44
-39
lines changed

9 files changed

+44
-39
lines changed

lambda_calculus/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from .terms import Variable, Abstraction, Application
66

7-
__version__ = "2.2.3"
7+
__version__ = "3.0.0"
88
__author__ = "Eric Niklas Wolf"
99
__email__ = "[email protected]"
1010
__all__ = (

lambda_calculus/terms/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from abc import abstractmethod
77
from collections.abc import Sequence, Set, Iterable, Iterator
88
from dataclasses import dataclass
9-
from typing import TypeVar
9+
from typing import TypeVar, final
1010
from .. import visitors
1111
from ..errors import CollisionError
1212
from ..visitors import walking
@@ -128,6 +128,7 @@ def is_combinator(self) -> bool:
128128
return not self.free_variables()
129129

130130

131+
@final
131132
@dataclass(unsafe_hash=True, slots=True)
132133
class Variable(Term[V]):
133134
"""
@@ -197,6 +198,7 @@ def accept(self, visitor: visitors.Visitor[T, V]) -> T:
197198
return visitor.visit_variable(self)
198199

199200

201+
@final
200202
@dataclass(unsafe_hash=True, slots=True)
201203
class Abstraction(Term[V]):
202204
"""
@@ -316,6 +318,7 @@ def replace(self, *, bound: V | None = None, body: Term[V] | None = None) -> Abs
316318
)
317319

318320

321+
@final
319322
@dataclass(unsafe_hash=True, slots=True)
320323
class Application(Term[V]):
321324
"""

lambda_calculus/terms/arithmetic.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
"""Implementations of natural numbers and arithmetic operators"""
44

5+
from typing import Final
56
from . import Term, Variable, Abstraction, Application
67
from .logic import TRUE, FALSE
78

@@ -16,13 +17,13 @@
1617
"number"
1718
)
1819

19-
ISZERO = Variable("n").apply_to(FALSE.abstract("x"), TRUE).abstract("n")
20+
ISZERO: Final = Variable("n").apply_to(FALSE.abstract("x"), TRUE).abstract("n")
2021
"""
2122
Term which evaluates to :const:`lambda_calculus.terms.logic.TRUE`
2223
if its argument is zero, :const:`lambda_calculus.terms.logic.FALSE` otherwise
2324
"""
2425

25-
SUCCESSOR = Abstraction.curried(
26+
SUCCESSOR: Final = Abstraction.curried(
2627
("n", "f", "x"),
2728
Application(
2829
Variable("f"),
@@ -36,7 +37,7 @@
3637
Term evaluating to its argument incremented by one.
3738
"""
3839

39-
PREDECESSOR = Abstraction.curried(
40+
PREDECESSOR: Final = Abstraction.curried(
4041
("n", "f", "x"),
4142
Application.with_arguments(
4243
Variable("n"),
@@ -60,7 +61,7 @@
6061
Term ealuating to its argument decremented by one.
6162
"""
6263

63-
ADD = Abstraction.curried(
64+
ADD: Final = Abstraction.curried(
6465
("m", "n", "f", "x"),
6566
Application.with_arguments(
6667
Variable("m"),
@@ -77,7 +78,7 @@
7778
Term evaluating to the sum of its two arguments.
7879
"""
7980

80-
SUBTRACT = Abstraction.curried(
81+
SUBTRACT: Final = Abstraction.curried(
8182
("m", "n"),
8283
Application.with_arguments(
8384
Variable("n"),
@@ -88,7 +89,7 @@
8889
Term evaluating to the difference of its two arguments.
8990
"""
9091

91-
MULTIPLY = Abstraction.curried(
92+
MULTIPLY: Final = Abstraction.curried(
9293
("m", "n", "f"),
9394
Application(
9495
Variable("m"),
@@ -102,7 +103,7 @@
102103
Term evaluating to the product of its two arguments.
103104
"""
104105

105-
POWER = Abstraction.curried(
106+
POWER: Final = Abstraction.curried(
106107
("b", "e"),
107108
Application(
108109
Variable("e"),

lambda_calculus/terms/combinators.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
"""Common combinators"""
44

5+
from typing import Final
56
from . import Variable, Application
67

78
__all__ = (
@@ -16,7 +17,7 @@
1617
"OMEGA"
1718
)
1819

19-
Y = Application(
20+
Y: Final = Application(
2021
Variable("g").apply_to(
2122
Variable("x").apply_to(Variable("x"))
2223
).abstract("x"),
@@ -28,55 +29,55 @@
2829
Y combinator used to define recursive terms.
2930
"""
3031

31-
S = Variable("x").apply_to(
32+
S: Final = Variable("x").apply_to(
3233
Variable("z"),
3334
Variable("y").apply_to(Variable("z"))
3435
).abstract("x", "y", "z")
3536
"""
3637
S combinator of the SKI combinator calculus.
3738
"""
3839

39-
K = Variable("x").abstract("x", "y")
40+
K: Final = Variable("x").abstract("x", "y")
4041
"""
4142
K combinator of the SKI combinator calculus.
4243
"""
4344

44-
I = Variable("x").abstract("x")
45+
I: Final = Variable("x").abstract("x")
4546
"""
4647
I combinator of the SKI combinator calculus.
4748
"""
4849

49-
B = Variable("x").apply_to(
50+
B: Final = Variable("x").apply_to(
5051
Variable("y").apply_to(Variable("z"))
5152
).abstract("x", "y", "z")
5253
"""
5354
B combinator of the BCKW combinator calculus.
5455
"""
5556

56-
C = Variable("x").apply_to(
57+
C: Final = Variable("x").apply_to(
5758
Variable("z"),
5859
Variable("y")
5960
).abstract("x", "y", "z")
6061
"""
6162
C combinator of the BCKW combinator calculus.
6263
"""
6364

64-
W = Variable("x").apply_to(
65+
W: Final = Variable("x").apply_to(
6566
Variable("y"),
6667
Variable("y")
6768
).abstract("x", "y")
6869
"""
6970
W combinator of the BCKW combinator calculus.
7071
"""
7172

72-
DELTA = Variable("x").apply_to(
73+
DELTA: Final = Variable("x").apply_to(
7374
Variable("x")
7475
).abstract("x")
7576
"""
7677
Term applying its argument to itself.
7778
"""
7879

79-
OMEGA = DELTA.apply_to(DELTA)
80+
OMEGA: Final = DELTA.apply_to(DELTA)
8081
"""
8182
Smallest term with no beta normal form.
8283
"""

lambda_calculus/terms/logic.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
"""Implementations of boolean values and logical operators"""
44

5+
from typing import Final
56
from . import Variable, Abstraction, Application
67

78
__all__ = (
@@ -13,38 +14,38 @@
1314
"IF_THEN_ELSE"
1415
)
1516

16-
TRUE = Abstraction.curried(("x", "y"), Variable("x"))
17+
TRUE: Final = Abstraction.curried(("x", "y"), Variable("x"))
1718
"""
1819
Term representing True.
1920
"""
2021

21-
FALSE = Abstraction.curried(("x", "y"), Variable("y"))
22+
FALSE: Final = Abstraction.curried(("x", "y"), Variable("y"))
2223
"""
2324
Term representing False
2425
"""
2526

26-
AND = Abstraction.curried(
27+
AND: Final = Abstraction.curried(
2728
("p", "q"),
2829
Application.with_arguments(Variable("p"), (Variable("q"), Variable("p")))
2930
)
3031
"""
3132
Term implementing logical conjunction between its two arguments.
3233
"""
3334

34-
OR = Abstraction.curried(
35+
OR: Final = Abstraction.curried(
3536
("p", "q"),
3637
Application.with_arguments(Variable("p"), (Variable("p"), Variable("q")))
3738
)
3839
"""
3940
Term implementing logical disjunction between its two arguments.
4041
"""
4142

42-
NOT = Abstraction("p", Application.with_arguments(Variable("p"), (FALSE, TRUE)))
43+
NOT: Final = Abstraction("p", Application.with_arguments(Variable("p"), (FALSE, TRUE)))
4344
"""
4445
Term performing logical negation of its argument.
4546
"""
4647

47-
IF_THEN_ELSE = Abstraction.curried(
48+
IF_THEN_ELSE: Final = Abstraction.curried(
4849
("p", "a", "b"),
4950
Application.with_arguments(Variable("p"), (Variable("a"), Variable("b")))
5051
)

lambda_calculus/terms/pairs.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
"""Implementation of pairs"""
44

5+
from typing import Final
56
from . import Variable, Abstraction, Application
67
from .logic import TRUE, FALSE
78

@@ -13,7 +14,7 @@
1314
"NULL"
1415
)
1516

16-
PAIR = Abstraction.curried(
17+
PAIR: Final = Abstraction.curried(
1718
("x", "y", "f"),
1819
Application.with_arguments(
1920
Variable("f"),
@@ -24,22 +25,22 @@
2425
Term evaluating to a ordered pair of its two arguments.
2526
"""
2627

27-
FIRST = Abstraction("p", Application(Variable("p"), TRUE))
28+
FIRST: Final = Abstraction("p", Application(Variable("p"), TRUE))
2829
"""
2930
Term evaluating to the first value in its argument.
3031
"""
3132

32-
SECOND = Abstraction("p", Application(Variable("p"), FALSE))
33+
SECOND: Final = Abstraction("p", Application(Variable("p"), FALSE))
3334
"""
3435
Term evaluating to the second value in its argument.
3536
"""
3637

37-
NIL = Abstraction("x", TRUE)
38+
NIL: Final = Abstraction("x", TRUE)
3839
"""
3940
Special Term encoding an empty pair.
4041
"""
4142

42-
NULL = Abstraction(
43+
NULL: Final = Abstraction(
4344
"p",
4445
Application(
4546
Variable("p"),

lambda_calculus/visitors/substitution/unsafe.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"""Substitutions which dont check if the substitutions are valid"""
44

55
from __future__ import annotations
6-
from collections.abc import Set
76
from typing import TypeVar, final
87
from ... import terms
98
from . import DeferrableSubstitution
@@ -28,18 +27,14 @@ class UnsafeSubstitution(DeferrableSubstitution[V]):
2827

2928
value: terms.Term[V]
3029

31-
free_variables: Set[V]
32-
3330
__slots__ = (
3431
"variable",
35-
"value",
36-
"free_variables"
32+
"value"
3733
)
3834

39-
def __init__(self, variable: V, value: terms.Term[V], free_variables: Set[V]) -> None:
35+
def __init__(self, variable: V, value: terms.Term[V]) -> None:
4036
self.variable = variable
4137
self.value = value
42-
self.free_variables = free_variables
4338

4439
@classmethod
4540
def from_substitution(cls, variable: V, value: terms.Term[V]) -> UnsafeSubstitution[V]:
@@ -50,7 +45,7 @@ def from_substitution(cls, variable: V, value: terms.Term[V]) -> UnsafeSubstitut
5045
:param value: value which should be substituted
5146
:return: new instance
5247
"""
53-
return cls(variable, value, value.free_variables())
48+
return cls(variable, value)
5449

5550
def visit_variable(self, variable: terms.Variable[V]) -> terms.Term[V]:
5651
"""

lambda_calculus/visitors/walking.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from __future__ import annotations
66
from collections.abc import Iterator
7-
from typing import TypeVar
7+
from typing import TypeVar, final
88
from .. import terms
99
from . import BottomUpVisitor
1010

@@ -15,6 +15,7 @@
1515
V = TypeVar("V")
1616

1717

18+
@final
1819
class DepthFirstVisitor(BottomUpVisitor[Iterator["terms.Term[V]"], V]):
1920
"""
2021
Visitor yielding subterms depth first
@@ -24,6 +25,8 @@ class DepthFirstVisitor(BottomUpVisitor[Iterator["terms.Term[V]"], V]):
2425
V: represents the type of variables used in terms
2526
"""
2627

28+
__slots__ = ()
29+
2730
def visit_variable(self, variable: terms.Variable[V]) -> Iterator[terms.Term[V]]:
2831
"""
2932
Visit a Variable term.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "lambda_calculus"
3-
version = "2.2.3"
3+
version = "3.0.0"
44
description = "Implementation of the Lambda calculus"
55
requires-python = ">=3.10"
66
keywords = []

0 commit comments

Comments
 (0)