Generalised to coercion to any of the argumements (ending 2.82)

This commit is contained in:
Oliver Payne 2022-02-13 17:54:57 +00:00
parent 74050eeb6c
commit 7147075c21
1 changed files with 17 additions and 4 deletions

View File

@ -89,19 +89,27 @@
(cond ((null? l) #f)
((eq? (car l) '()) #t)
(else (any-empty-list (cdr l)))))
(define (coerce-args args type-tags)
(if (null? type-tags)
'()
(let* ((type (car type-tags))
(coerced-args (map (coerce-to type) args)))
(if (not (any-empty-list coerced-args))
coerced-args
(coerce-args args (cdr type-tags))))))
(let ((type-tags (map type-tag args)))
(let ((proc (get op type-tags)))
(if proc
(apply proc (map contents args))
(if (> (length args) 1)
(let* ((type1 (car type-tags))
(coerced-args (map (coerce-to type1) args)))
(if (not (any-empty-list coerced-args))
(let ((coerced-args (coerce-args args type-tags)))
(if (not (null? coerced-args))
(apply apply-generic (cons op coerced-args))
(error "Tried coercing all args to first type"
(error "Can't coerce arguments to a common type"
(list op type-tags))))
(error "Too few args"))))))
;; map coerce-to onto all arguments for the type of each argument.
;; The first one that returns all non empty arguments is the coercion
;; that is used.
@ -365,3 +373,8 @@
;; b: If the arguments are of the same type, and if there isn't an operation defined for
;; that combination of arguments, then apply-generic will try to coerce a type to itself,
;; so there is a need change it.
;; 2.82: The approach of coercing to a common type would not work where there is a function
;; that takes mixed types. For example, if we have an operator to add a complex to a rational.
;; It isn't possible to coerce from one to the other, so a mixed-type operator is needed, and this
;; approach would fail.