git-subtree-dir: users/wpcarro git-subtree-mainline:464bbcb15cgit-subtree-split:24f5a642afChange-Id: I6105b3762b79126b3488359c95978cadb3efa789
		
			
				
	
	
		
			142 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
| ;;; number.el --- Functions for working with numbers -*- lexical-binding: t -*-
 | |
| 
 | |
| ;; Author: William Carroll <wpcarro@gmail.com>
 | |
| ;; Version: 0.0.1
 | |
| ;; Package-Requires: ((emacs "24"))
 | |
| ;; Homepage: https://user.git.corp.google.com/wpcarro/briefcase
 | |
| 
 | |
| ;;; Commentary:
 | |
| ;;
 | |
| ;; Classifications of numbers:
 | |
| ;; - Natural: (a.k.a positive integers, counting numbers); {1, 2, 3, ... }
 | |
| ;;
 | |
| ;; - Whole: Natural Numbers, plus zero; {0, 1, 2, 3, ...}
 | |
| ;;
 | |
| ;; - Integers: Whole numbers plus all the negatives of the natural numbers;
 | |
| ;;   {... , -2, -1, 0, 1, 2, ...}
 | |
| ;;
 | |
| ;; - Rational numbers: (a.k.a. fractions) where the top and bottom numbers are
 | |
| ;;   integers; e.g., 1/2, 3/4, 7/2, ⁻4/3, 4/1.  Note: The denominator cannot be
 | |
| ;;   0, but the numerator can be.
 | |
| ;;
 | |
| ;; - Real numbers: All numbers that can be written as a decimal.  This includes
 | |
| ;;   fractions written in decimal form e.g., 0.5, 0.75 2.35, ⁻0.073, 0.3333, or
 | |
| ;;   2.142857. It also includes all the irrational numbers such as π, √2 etc.
 | |
| ;;   Every real number corresponds to a point on the number line.
 | |
| ;;
 | |
| ;; The functions defined herein attempt to capture the mathematical definitions
 | |
| ;; of numbers and their classifications as defined above.
 | |
| 
 | |
| ;;; Code:
 | |
| 
 | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | |
| ;; Dependencies
 | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | |
| 
 | |
| (require 'prelude)
 | |
| (require 'dash)
 | |
| 
 | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | |
| ;; Library
 | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | |
| 
 | |
| (defconst number-test? t
 | |
|   "When t, run the test suite defined herein.")
 | |
| 
 | |
| ;; TODO: What about int.el?
 | |
| 
 | |
| ;; TODO: How do we handle a number typeclass?
 | |
| 
 | |
| (defun number-positive? (x)
 | |
|   "Return t if `X' is a positive number."
 | |
|   (> x 0))
 | |
| 
 | |
| (defun number-negative? (x)
 | |
|   "Return t if `X' is a positive number."
 | |
|   (< x 0))
 | |
| 
 | |
| ;; TODO: Don't rely on this. Need to have 10.0 and 10 behave similarly.
 | |
| (defun number-float? (x)
 | |
|   "Return t if `X' is a floating point number."
 | |
|   (floatp x))
 | |
| 
 | |
| (defun number-natural? (x)
 | |
|   "Return t if `X' is a natural number."
 | |
|   (and (number-positive? x)
 | |
|        (not (number-float? x))))
 | |
| 
 | |
| (defun number-whole? (x)
 | |
|   "Return t if `X' is a whole number."
 | |
|   (or (= 0 x)
 | |
|       (number-natural? x)))
 | |
| 
 | |
| (defun number-integer? (x)
 | |
|   "Return t if `X' is an integer."
 | |
|   (or (number-whole? x)
 | |
|       (number-natural? (- x))))
 | |
| 
 | |
| ;; TODO: How defensive should these guards be?  Should we assert that the inputs
 | |
| ;; are integers before checking evenness or oddness?
 | |
| 
 | |
| ;; TODO: Look up Runar (from Unison) definition of handling zero as even or odd.
 | |
| 
 | |
| ;; TODO: How should rational numbers be handled? Lisp is supposedly famous for
 | |
| ;; its handling of rational numbers.
 | |
| ;; TODO: `calc-mode' supports rational numbers as "1:2" meaning "1/2"
 | |
| ;; (defun number-rational? (x))
 | |
| 
 | |
| ;; TODO: Can or should I support real numbers?
 | |
| ;; (defun number-real? (x))
 | |
| 
 | |
| (defun number-even? (x)
 | |
|   "Return t if `X' is an even number."
 | |
|   (or (= 0 x)
 | |
|       (= 0 (mod x 2))))
 | |
| 
 | |
| (defun number-odd? (x)
 | |
|   "Return t if `X' is an odd number."
 | |
|   (not (number-even? x)))
 | |
| 
 | |
| (defun number-dec (x)
 | |
|   "Subtract one from `X'.
 | |
| While this function is undeniably trivial, I have unintentionally done (- 1 x)
 | |
|   when in fact I meant to do (- x 1) that I figure it's better for this function
 | |
|   to exist, and for me to train myself to reach for it and its inc counterpart."
 | |
|   (- x 1))
 | |
| 
 | |
| (defun number-inc (x)
 | |
|   "Add one to `X'."
 | |
|   (+ x 1))
 | |
| 
 | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | |
| ;; Tests
 | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | |
| 
 | |
| (when number-test?
 | |
|   (prelude-assert
 | |
|    (number-positive? 10))
 | |
|   (prelude-assert
 | |
|    (number-natural? 10))
 | |
|   (prelude-assert
 | |
|    (number-whole? 10))
 | |
|   (prelude-assert
 | |
|    (number-whole? 0))
 | |
|   (prelude-assert
 | |
|    (number-integer? 10))
 | |
|   ;; (prelude-assert
 | |
|   ;;  (= 120 (number-factorial 5)))
 | |
|   (prelude-assert
 | |
|    (number-even? 6))
 | |
|   (prelude-refute
 | |
|    (number-odd? 6))
 | |
|   (prelude-refute
 | |
|    (number-positive? -10))
 | |
|   (prelude-refute
 | |
|    (number-natural? 10.0))
 | |
|   (prelude-refute
 | |
|    (number-natural? -10))
 | |
|   (prelude-refute
 | |
|    (number-natural? -10.0)))
 | |
| 
 | |
| (provide 'number)
 | |
| ;;; number.el ends here
 |