While working on my MTL project, I've tried to come up with some features that would make working with expressions easier. Two ideas that I came up with have stuck, and I feel that they could be quite useful if implemented in arc. The cool thing about them is they could theoretically be written in any lisp-based language. The first idea is an old one: A type system. My influence on this comes from Common Lisp's "deftype". When I first learned about "deftype", I hated it. At first, I figured it was like "typedef" in C (kind of), but I learned it was really a fancy predicate system. It's kind of like your "Type" is given a name, and its qualities are typically given in the form of a combination of predicates and/or a symbol naming a previously defined type. My approach to implementing this would go along the lines of the following: 1. Create a global table named "tags". This will be used for containing the tagged predicate functions. 2. Create a macro that takes a "name" and a "body" of code. In arc style, I feel like using the syntax for anonymous functions would extend well here. Example: (deftag posnum (and (is (type _) 'num) (> _ 0))) Expansion: (= (tags 'posnum) (fn (_) (and (is (type _) 'num) (> _ 0)))) You could then either rewrite the "isa" macro to support the "tags" table, or you could simply deal with using more parenthesis. Examples: ((tags 'posnum) 0) -> nil ((tags 'posnum) 1) -> t The second idea is also not new: Pattern matching. From time to time, I tinker with the Rust language, and my influence mainly comes from this, but I know it doesn't originate from Rust. It would be a combination of Arc-style "if", C-style "switch" and Rust-style "match". It would support multiple clauses just like "if", but I can't figure out how to format code on the forum, so it looks unreadable and I've just made single-clause examples. Examples: ; Checks if x is a sym (match x sym (prn "x is a symbol.")) ; Checks if x is a cons and binds car to "a" and cdr to "d". (match x (cons a d) (prn "x is a cons. car: " a ", cdr: " d)) Of course it could be changed, and extended. For instance adding the ability to pattern match a closure or macro to its arguments, body and environment, or adding the wildcard "_" symbol to ignore matching particular parts of an expression. Examples: ; Ignores body & env of closure (match x (fn args _ _)(prn "x is a closure. args: " args)) ; Ignores all closure values (match x fn (prn "x is a closure.")) ; Specifically check if x equals "Hello" (match x "Hello" (prn "x is Hello")) I feel like the "match" idea could be extremely helpful in writing macros that deal with manipulating complex expressions. Any comments or criticism? |