This page is part of the web mail archives of SRFI 50 from before July 7th, 2015. The new archives for SRFI 50 contain all messages, not just those from before July 7th, 2015.
> From: Jim Blandy <jimb@xxxxxxxxxx> > 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: > [nice example] So we're another step closer to saying that these two interfaces are just duals of each other (modulo error handling foo and topics we haven't gotten to yet like tail calls and continuation foo). But they aren't _quite_ duals. JNI/Minor-style still has this mandatory separate allocation of handles and liveness of unfreed handles until returning from C to Scheme (at least in implementations not storing scheme values in `mn_ref *' variables and using conservative GC). At the very least, JNI/Minor-style is tolerant of code that is generally undesirable. You're niftier example indirectly reveals the problem: > 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); > } Ok, but now: while (N--) { ... assq (...); ... } is O(N) space. I guess you need to put back the free calls just before the returns -- right where GCUNPROs would go. There's also that: > pair = mn_set (c, pair, mn_car (c, alist)); needs to allocate and free an intermediate handle (for the return value of mn_car, in implementations that don't store scheme values directly in `mn_ref *' variables and use conservative GC techniques) but the relative cost of those mandatory instructions in minor compared to other things in Pika is something I'd find hard to guess about. > I think this underscores how fundamentally similar the two are: > - Minor calls correspond to Pika frames. Correspond to but aren't isomorphic because of their different lifetimes. That's the almost-but-not-quite-duals point. You seem to agree: > - 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. I don't mean to be gratuitously argumentative. I don't see any advantage to the call-lifetime hack other than that it is slightly more tolerant of sloppy code that we'd want to discourage anyway. Your revised assq implementation is an example. Just as a point of interest: I remember back in the early days of Guile the syntax issues of C code were something we worried quite a lot about. Some of the discussions concluded, for example, that conservative GC was imperative because we figured that anything else would be too hard for "average C programmers" to use and it seemed (incorrectly) at the time that conservative GC let us write Scheme expressions in C in a very direct style without having to think about it too hard. Two things happened in the years following: (a) GC became much more widely accepted (thank you, James Gosling) and so what the "average C programmer" can be counted on for has expanded; (b) it turns out that conservative GC is a sham in the sense that if you use it without a deep understanding of permissable C optimizations and eternal vigilance about what they might effect -- you're going to lose by writing subtly incorrect code. Scheme expressions aren't (in a simple way) C expressions and that's all there is too it -- trying to hide that fact in the manner of JNI doesn't help anyone (anymore). I think there's an analogy between the interactions of conservative GC and C optimizations on the one hand and on the other hand the interactions between JNI/Minor-style conventions and semantics and call lifetimes on the other. -t