From: Douglas K. <do...@go...> - 2013-11-08 22:11:44
|
Many user-defined higher-order functions would do well to immediately coerce their funarg designator(s) - assuming they accept designators and/or functions - into functions right at the start. (Take for example 'mapcrap' which was an iterator in use at a previous job). But presently the best that user code can do is unportably call sb-kernel:%coerce-callable-to-fun by itself because there are no builtin coercions to function. It would be nice to make COERCE do that. The patch below will, if triggered, say that it's unable to optimize away FDEFINITION, but that's much better than being unable to optimize away COERCE. Then the user can write: (defun mapthing (f-spec input) (declare ((or function symbol) f-spec)) (let ((f (coerce f-spec 'function))) ...) I used 'type=' rather than (csubtypep tspec ...) because if the user writes (coerce f '(function (integer integer) integer)) I would rather let COERCE choke on that. Perhaps better would be to make it a compile-time full warning. I'm not sure the optimizer is the right place to do that. Is it? --- a/src/compiler/typetran.lisp +++ b/src/compiler/typetran.lisp @@ -772,7 +772,10 @@ (give-up-ir1-transform "~@<~S specifies dimensions other than (*) in safe code.~:@>" tval))) - (t + ((and (type= tspec (specifier-type 'function)) + (csubtypep (lvar-type x) (specifier-type '(or function symbol)))) + `(the ,tval (%coerce-callable-to-fun x))) + (t (give-up-ir1-transform "~@<open coding coercion to ~S not implemented.~:@>" tval)))))) |
From: Stas B. <sta...@gm...> - 2013-11-09 00:53:04
|
Douglas Katzman <do...@go...> writes: > Many user-defined higher-order functions would do well to immediately > coerce their funarg designator(s) - assuming they accept designators and/or > functions - into functions right at the start. (Take for example 'mapcrap' > which was an iterator in use at a previous job). > > But presently the best that user code can do is unportably call > sb-kernel:%coerce-callable-to-fun by itself because there are no builtin > coercions to function. It would be nice to make COERCE do that. The patch > below will, if triggered, say that it's unable to optimize away > FDEFINITION, but that's much better than being unable to optimize away > COERCE. > Then the user can write: > (defun mapthing (f-spec input) (declare ((or function symbol) f-spec)) > (let ((f (coerce f-spec 'function))) ...) > > I used 'type=' rather than (csubtypep tspec ...) because if the user writes > (coerce f '(function (integer integer) integer)) I would rather let COERCE > choke on that. Perhaps better would be to make it a compile-time full > warning. > I'm not sure the optimizer is the right place to do that. Is it? > > > --- a/src/compiler/typetran.lisp > +++ b/src/compiler/typetran.lisp > @@ -772,7 +772,10 @@ > (give-up-ir1-transform > "~@<~S specifies dimensions other than (*) in safe > code.~:@>" > tval))) > - (t > + ((and (type= tspec (specifier-type 'function)) > + (csubtypep (lvar-type x) (specifier-type '(or function > symbol)))) > + `(the ,tval (%coerce-callable-to-fun x))) > + (t > (give-up-ir1-transform > "~@<open coding coercion to ~S not implemented.~:@>" > tval)))))) One thing that wouldn't work: (coerce 'defun 'function) => DEFUN is a macro. [Condition of type SIMPLE-TYPE-ERROR] (sb-kernel:%coerce-callable-to-fun 'defun) => #<CLOSURE (LAMBDA (&REST SB-C::ARGS) :IN MACRO-FUNCTION) {100164985B}> -- With best regards, Stas. |