Natural Number Arithmetic
Examples Using
Peano-Inspired Structures

H. Conrad Cunningham

11 April 2022

Copyright (C) 2004, 2006, 2008, 2010, 2012, 2013, 2014, 2015, 2016, 2019, 2022, H. Conrad Cunningham
Professor of Computer and Information Science
University of Mississippi
214 Weir Hall
P.O. Box 1848
University, MS 38677
(662) 915-7396 (dept. office)

Browser Advisory: The HTML version of this textbook requires a browser that supports the display of MathML. A good choice as of April 2022 is a recent version of Firefox from Mozilla.

1 Natural Number Arithmetic Examples

1.1 Background

In this set of examples, we develop representations for the natural numbers and their key operations using type and data structures inspired by Peano’s Postulates [3,4], a well-know axiomization of the natural numbers. None of the representations can use any builtin integer type.

Mathematically, we can define the set Nat (of natural numbers) inductively as follows:

    x in Nat if and only if 
         (1) x = 0                                -- zero
      or (2) (Exists y : y in Nat :: x = Succ(y)) -- successor

Note: We consider 0 as being a natural number as is customary for many computer scientists.

The Nat values use a unary representation for the natural numbers; there is one successor object in a linear structure for each natural number value greater than 0.

I have developed these examples in various ways for various languages, but in all cases we seek to use functional techniques in the following ways:

In the examples, I tend to use one of the following program organizations:

1.2 Haskell

This problem is used in exercises in Chapters 21 (Algebraic Data Types) and 25 (Haskell Laws) of the book Exploring Languages with Interpreters and Functional Programming. I first devised this exercise in the early/mid 1990s to ask students to implement simple algebraic data types in my Functional Programming course.

1.3 Scala

This set includes three Scala 2 implementations of the Natural Numbers with the following characteristics:

TODO: Update the old Scala 2 programs to be compatible with Scala 3.

1.4 Elixir

This set includes one Elixir implementation from 2015. It structures the program as a module of pure functions. It represents the natural numbers as Elixir tuples with constants (i.e., Elixir atoms) in the first component and uses structural pattern matching to deconstruct the tuples based on the constant values. (This simulates an algebraic data type mechanism.)

The implementation also seeks to facilitate the possible use of different data representations by separating the module into primitive (private) aspects that can manipulate the data representation directly and nonprimitive (public) that carry out the arithmetic operations using the primitive aspects. These layers should be broken into two separate modules.

TODO: Update the 2015 Elixir code to be compatible with the current release of Elixir.

1.5 Lua

The set includes one Lua implementation from 2013/14. It structures the program as a module of pure functions. It represents the natural numbers as Lua tables with constants in the first component and uses structural pattern matching to deconstruct them. It thus simulates an algebraic data type as Lua tables with tags in the first position. It implements the operations in a functional style. I also stresses modularity, with primitive and nonprimitive layers as discussed above.

TODO: Update the Lua 5.1 program from 2014 to be compatible with the current Lua 5.4 release.

1.6 Ruby

The set includes one Ruby implementation from 2006. It defines a traditional object-oriented class hierarchy organized according to the Composite, Singleton, and Null Object software design pattern. The hierarchy has a base class Nat and subclasses Zero, Succ, and Err.

TODO: Update this old 2006 code for the current version of Ruby.

1.7 Java

The set includes one Java version, whose code was originally written in 2004 using a release of Java with no generics. It uses a traditional object-oriented structure as described above.

1.8 Acknowledgements

I often use this problem when I am learning and/or teaching programming language. I have done that with (at least) Haskell, Java, Ruby, Scala, Lua, and Elixir since sometime in the 1990s. This chapter collects the source code for most of these efforts.`

I retired from the full-time faculty in May 2019. As one of my post-retirement projects, I am continuing work on possible textbooks based on the course materials I had developed during my three decades as a faculty member. In January 2022, I began refining the existing content, integrating separately developed materials together, reformatting the documents, constructing a unified bibliography (e.g., using citeproc), and improving my build workflow and use of Pandoc. I adapted this index page from a portion of my Spring 2019 CSci 555 course notes.

I maintain this chapter as text in Pandoc’s dialect of Markdown using embedded LaTeX markup for the mathematical formulas and then translate the document to HTML, PDF, and other forms as needed.

1.9 References

[1]
Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. 1995. Design patterns: Elements of reusable object-oriented software. Addison-Wesley, Boston, Massachusetts, USA.
[2]
Source Making. 2022. Design patterns. Retrieved from https://sourcemaking.com/design_patterns
[3]
Wikpedia: The Free Encyclopedia. 2022. Peano axioms. Retrieved from https://en.wikipedia.org/wiki/Peano_axioms
[4]
Wolfram Research, Inc. 2022. Peano’s axioms. Retrieved from https://mathworld.wolfram.com/PeanosAxioms.html
[5]
Bobby Woolf. 1997. Null object. In Pattern languages of program design 3, Robert Martin, Dirk Riehle and Frank Buschmann (eds.). Addison-Wesley, Boston, Massachusetts, USA, 5–18.