about summary refs log tree commit diff
path: root/emacs/.emacs.d/wpc/iso.el
blob: c9ce4a48fc71707f2677e526728f77cf4545a055 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
;;; iso.el --- Isomorphisms in Elisp -*- lexical-binding: t -*-
;; Author: William Carroll <wpcarro@gmail.com>

;;; Commentary:
;; Providing basic isomorphisms to improve code quality.

;;; Code:

(require 'dotted)
(require 'tuple)
(require 'symbol)
(require 'string)
(require 'list)
(require 'alist)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Library
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(cl-defstruct iso to from x)

(defconst iso/whitelist
  '((dotted . tuple)
    (symbol . string))
  "Alist representing supported isomorphisms.")

(defconst iso/vertices
  (list/concat (alist/keys iso/whitelist)
               (alist/values iso/whitelist))
  "List of all of the vertices in the iso graph.")

(defun iso/classify (x)
  "Return type of X."
  (cond
   ((string/instance? x) 'string)
   ((symbol/instance? x) 'symbol)
   ((dotted/instance? x) 'dotted)
   ((tuple/instance? x)  'tuple)))

(cl-defun iso/exists? (to from)
  "Return t if an isomorphism of TO to FROM exists."
  ;; TODO: All of this can be improved modelling this with a graph.
  (cond
   ;; to -> from
   ((list/contains? to (alist/keys iso/whitelist))
    (list/contains? from (alist/values iso/whitelist)))
   ;; from -> to
   ((list/contains? from (alist/keys iso/whitelist))
    (list/contains? to (alist/values iso/whitelist)))
   ;; doesn't exist
   (t nil)))

(progn
  (prelude/assert
   (iso/exists? 'symbol 'string))
  (prelude/assert
   (iso/exists? 'dotted 'tuple))
  (prelude/refute
   (iso/exists? 'dotted 'symbol))
  (prelude/refute
   (iso/exists? 'symbol 'list)))

;; TODO: Model this as a graph.
(defconst iso/morphisms
  '((string .
            '(symbol #')
     ))
  (list (:from 'string :to 'symbol :fn #'intern)
        (:from 'symbol :to 'string :fn #'symbol-name)
        )
  "")

(defun iso/to (f x)
  "Apply F to X's to."
  (->> x
       iso-to))

(->> (iso/new "william" :to 'symbol)
     (iso/as-to #'symbol-name)
     )

(cl-defun iso/new (x &key to)
  "Create a new isomorphism of X mapping to TO."
  (let ((from (iso/classify x)))
    (prelude/assert (iso/exists? to from))
    (make-iso :from from
              :to to
              :x x)))

(macros/comment
 (iso/new "william" :to 'symbol)
 (iso/new '(one . two) :to 'tuple))

(provide 'iso)
;;; iso.el ends here