Re: Comparing Pika-syle and JNI-style Jim Blandy 14 Jan 2004 20:45 UTC
Tom Lord <xxxxxx@emf.net> writes: > /* untested code */ > t_scm_error > scm_assq (t_scm_word * answer, > t_scm_arena instance, > t_scm_word * key, > t_scm_word * alist) > { > struct assq_frame > { > SCM_FRAME; > scm_word_t * pair; > scm_word_t * key; > } l; > > SCM_PROTECT_FRAME (l); > > > scm_make_false (answer, instance); > > while (scm_is_pair (instance, alist)) > { > scm_car (&l.pair, instance, alist); > scm_car (&l.key, instance, &l.pair); > if (scm_values_eq (instance, &l.key, key)) > { > SCM_LSET (answer, instance, &l.pair); > break; > } > scm_cdr (alist, instance, alist); > } > > SCM_UNPROTECT_FRAME (l); > return 0; > } It's worth noting here that SCM_LSET is essentially a 'linearizing' assignment operator. I'd been thinking of providing a similar operator for Minor: /* Free the reference DEST, if DEST is non-zero; then return SRC. This is meant to help free a variable's value before assigning to it: x = mn_set (c, x, new_value); */ mn_ref *mn_set (mn_call *, mn_ref *dest, mn_ref *src); If Minor provided an operator like that, then one could write the Minor example in a very similar fashion to the Pika example: mn_ref * assq (mn_call *c, mn_ref *key, mn_ref *alist) { mn_ref *pair = 0; mn_ref *pair_key = 0; while (mn_pair_p (c, alist)) { pair = mn_set (c, pair, mn_car (c, alist)); pair_key = mn_set (c, pair_key, mn_car (c, pair)); if (mn_ref_eq (c, key, pair_key)) return pair; alist = mn_to_cdr (c, alist); } return mn_false (c); } Here's Tom's code again, for reference: /* untested code */ t_scm_error scm_assq (t_scm_word * answer, t_scm_arena instance, t_scm_word * key, t_scm_word * alist) { struct assq_frame { SCM_FRAME; scm_word_t * pair; scm_word_t * key; } l; SCM_PROTECT_FRAME (l); scm_make_false (answer, instance); while (scm_is_pair (instance, alist)) { scm_car (&l.pair, instance, alist); scm_car (&l.key, instance, &l.pair); if (scm_values_eq (instance, &l.key, key)) { SCM_LSET (answer, instance, &l.pair); break; } scm_cdr (alist, instance, alist); } SCM_UNPROTECT_FRAME (l); return 0; } I think this underscores how fundamentally similar the two are: - Minor calls correspond to Pika frames. - Minor heap-allocates while Pika stack-allocates. I think the biggest difference between the two is that Pika ties reference lifetimes very tightly to lexical block lifetimes, whereas Minor binds them to call lifetimes, but allows/requires you to do some other explicit frees. Each has some advantages and some disadvantages.