Hi! Andy Wingo <wi...@pobox.com> writes:
[...] >> scm_tcs_closures Interpreted procedures > > I am hoping to devise a way never to see these in the VM, on the > eval-cleanup branch. Cool! >> scm_tc7_subr_2o SCM (*) () -- 0 arguments. >> scm_tc7_subr_1 SCM (*) (SCM) -- 1 argument. >> scm_tc7_subr_1o SCM (*) (SCM) -- 1 optional argument. >> scm_tc7_subr_2o SCM (*) (SCM, SCM) -- 2 required args. >> scm_tc7_subr_2o SCM (*) (SCM, SCM) -- 2 optional args. >> scm_tc7_subr_3 SCM (*) (SCM, SCM, SCM) -- 3 required args. >> scm_tc7_lsubr SCM (*) (SCM) -- list subrs >> scm_tc7_lsubr_2 SCM (*) (SCM, SCM, SCM) > > I would like to make these all be gsubrs. There are very few places > where these constants actually exist in code "out there" -- normally the > way to do this is to use scm_c_define_gsubr, and it does the right > thing. > > I'll probably do a: > > #define scm_tc7_subr_2o \ > scm_tc7_subr_2o_NO_LONGER_EXISTS_USE_scm_c_define_gsubr > > or something like that. You can't do that because such subrs are created by `create_gsubr ()' when the signature allows it. Or did you mean `create_gsubr ()' would now create only gsubrs? These specialized subr types allow for faster dispatch, as opposed to the argument count checks (and argument copies) that are done in `scm_i_gsubr_apply ()'. Thus, I think replacing all of them with gsubrs may have a negative impact performance-wise. >> scm_tc7_dsubr double (*) (double) -- double subrs > > I'll remove these, changing their implementations to be gsubrs. This > only affects $sin et al; I'll probably roll the transcendental versions > into the subrs as well. Yes, it seems to be seldom used. However, it might be a semi-public API... >> scm_tc7_cxr c[da]+r > > I'll change these to be subrs. OK (this was essentially an interpreter hack AIUI). >> scm_tc7_asubr SCM (*) (SCM, SCM) -- "accumulating" subrs. > > These are interesting. We have to keep the C signature of e.g. scm_sum, > otherwise many things would break. So I'd change scm_sum to be a gsubr > with two optional arguments, and then on the Scheme level do something > like: > > (define + > (let (($+ +)) > (lambda args > (cond ((null? args) ($+)) > ((null? (cdr args)) ($+ (car args))) > ((null? (cddr args)) ($+ (car args) (cadr args))) > (else (apply + ($+ (car args) (cadr args)) (cddr args))))))) > > The VM already compiles (+ a b c) to (add (add a b) c), where add is a > primitive binary instruction. OK. >> scm_tc7_rpsubr SCM (*) (SCM, SCM) -- predicate subrs. > > Likewise, we'll have to do something like the + case. > >> scm_tc7_smob Applicable smobs > > Well... we probably have to support these also as a primitive procedure > type. It could be we rework smobs in terms of structs, and if that > happens, we can use applicable structs -- but barring that, this would > be a fourth procedure type. Yes. >> scm_tc7_gsubr Generic subrs > > Actually applying gsubrs can be complicated, due to optional args, rest > args, and the lack of `apply' in C. I guess we should farm out > application to a scm_i_gsubr_applyv trampoline that takes its args as an > on-the-stack vector. Indeed. >> scm_tc7_pws Procedures with setters >> Gets the procedure, and applies that. This needs to be inlined into >> the VM to preserve tail recursion. > > Ideally these would be implemented as applicable structs. We'll see. > >> scm_tcs_struct Applicable structs > > Check if the struct is applicable, and if so apply its effective method. Sounds like a nice plan! Thanks, Ludo'.