Skip to content

A macro for algebraic data types (ADTs) #58

Description

@glyh

I just stumble across ADT in python, and it translate into this in hy. Which is kinda ugly.

Here I present a macro, so it's looks a bit better:

macro implementation
(defmacro defadt [name #* constructors]
  (let [alts []]
    `(do
       (import 
         __future__  [annotations]
         dataclasses [dataclass])
       ~@(lfor alt constructors 
            (if (= (type alt) hy.models.List)
              (let [[name #* fields] alt
                    fids (list (map 
                                (fn [id] (hy.models.Symbol f"arg{(+ id 1)}"))
                                (range (len fields))))]
                (alts.append name)
                `(defclass [dataclass] ~name []
                   ~@(lfor [f-id f-type] (list (zip fids fields))
                      `(annotate ~f-id ~f-type))
                   (defn __str__ [self]
                     (+ ~f"({name}" 
                        ~@(list 
                            (map (fn [fid] `(+ " " (str (getattr self ~(str fid))))) 
                                 fids)) 
                        ")"))))
              (do 
                (alts.append alt)
                `(defclass [dataclass] ~alt []
                   (defn __str__ [_]
                     ~f"({alt})")))))
       (setv ~name (| ~@alts)))))

(defadt Shape 
  [Point float float]
  [Circle float float float]
  [Rectangle float float float])

(Circle 3 4 5)

(defadt Tree
  Dead
  [Leaf int]
  [Branch Tree Tree])

(Branch
  (Branch (Leaf 1) (Leaf 2))
  (Branch (Dead) (Branch (Dead) (Dead))))

But noted that not all properties is supported, because in my perspective we should keep adt simple.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions