I was thinking of ways to use the sig function. First check if two function can be called with
the same arguments.
It is useful if we want to declare a dependency:
We want to check that the user of our library
create a specific function
(for example an error handling function). This is a code that check if two functions
signature are the same: ;Check if two list have the same structure
(def same-shape (lst1 lst2)
(if (and (atom lst1) (atom lst2)) t
(or (atom lst1) (atom lst2)) nil
(if (and (empty lst1) (empty lst2)) t
(or (empty lst1) (empty lst2)) nil
(with (l1 (car lst1) l2 (car lst2) r1 (cdr lst1) r2 (cdr lst2))
(if (and (atom l1) (atom l2))
(same-shape r1 r2)
(and (acons l1) (acons l2))
(and (same-shape l1 l2) (same-shape r1 r2))
nil )))))
;Argument that are not a destructor list
(def var-arg (v)
(or (atom v) (caris v 'o)))
;Check if two function signature are the same
(def same-sig (lst1 lst2)
(if (and (atom lst1) (atom lst2)) t
(or (atom lst1) (atom lst2)) nil
(if (and (empty lst1) (empty lst2)) t
(or (empty lst1) (empty lst2)) nil
(with (l1 (car lst1) l2 (car lst2) r1 (cdr lst1) r2 (cdr lst2))
(if (and (var-arg l1) (var-arg l2))
(same-sig r1 r2)
(and (acons l1) (acons l2))
(and (same-shape l1 l2) (same-sig r1 r2))
nil )))))
The next code is for checking if a function
can be called with a list of arguments: ;Check if the list lst can be destruct to binds
(def can-ds (binds lst)
(if (empty binds)
(if (atom lst) t nil)
(atom binds)
(if (empty lst) nil t)
; a cons binds
(if (acons lst)
(and (can-ds (car binds) (car lst))
(can-ds (cdr binds) (cdr lst)))
nil)))
;Check if a function with args can be called with
;the arguments call-args
(def can-call (call-args args)
(if (empty call-args)
(if (acons args)
(if (caris (car args) 'o) ;optional arg
(can-call nil (cdr args))
nil)
t)
(empty args) nil
(atom args) t
(if (or (atom (car args)) (caris (car args) 'o))
(can-call (cdr call-args) (cdr args))
(and (can-ds (car args) (car call-args))
(can-call (cdr call-args) (cdr args))))))
Examples of how we use those functions: (def add (a b) (+ a b))
(def mul (a b) (* a b))
(same-sig (sig 'add) (sig 'mul)) => t
(can-call '(1 2) (sig 'add)) => t
|