Sam Mason wrote:
> On Mon, Jun 04, 2007 at 09:51:55AM -0400, Jonathan S. Shapiro wrote:
>> On Mon, 2007-06-04 at 11:23 +0100, Sam Mason wrote:
>>> On Sun, Jun 03, 2007 at 10:16:47PM -0400, Jonathan S. Shapiro wrote:
>>>>   2. Captured by-reference arguments are legal in *escaping* closures,
>>>>      but a *copy* of the by-reference value is made at the time of
>>>>      closure construction.
>>>>
>>>>      This yields sensible behavior and preserves type safety, but it
>>>>      introduces behavioral subtlety that will confuse programmers. 
>>> I think this would confuse the semantics a lot, apparently simple
>>> changes to an expression could change its behaviour considerably.
>> No more so (or less so) than any procedure call that is passed a
>> reference.
> 
> OK, I think I completely missed what you meant when you said copying
> the "by-reference value". 

Even I thought the closed variable is copied by value. This is exactly 
similar to the r-value getting copied as  a result of being passed 
by-value to closure-construction operator.

> I've just noticed a problem with these by-references values though.
> That of calling a "by-reference" method with the reference to an element
> of a union and changing the tag of the union invalidating the type of
> the element inside the "by-reference" function.  I can only think of
> very contrived bits of code that would trigger it, but it would break
> type safety.

I did not understand this problem, can you please explain. In BitC, the 
de-constructed value of a tagged union (resulting from a switch -- see 
`x' below) is not a first class entity. It can only appear on the LHS of 
a selection (.) operator, and it is a *copy* of the original union value 
on which we are performing a switch.

For example:

(defunion (list 'a) nil (cons car:'a cdr:(list 'a)))

(define (f z:(by-ref bool) y)
    (set! y nil)
    (set! x #f))

(let ((y:(mutable (list (mutable bool))) (cons #t nil)))
   (switch y x
      (nil ())
      (cons (f x.car y)))

In the above example, both assignments in the function f are legal and 
safe. The only legal way to mutate a union value is to set! the entire 
union value, not individual fields in one constructor. Of course, if the 
constructors contain a value of reference type, it is legal to mutate 
the contents of the cell named by that reference.

Even if there is a problem with unions, it might be easy to fix by 
restricting the usage of de-constructed variables. In fact, not all 
values / expressions can be used in a pass-by reference position (ex: 
the literal 1 cannot be passed by reference).

>> The reason I want this is that there is an idiom for writing constructor
>> and re-initializer procedures that requires it. The problem at present
>> is that there is no clean way to re-initialize a data structure that is
>> unboxed, nor any way to characterize field get/set as a procedure call
>> within the language.
> 
> yes, which is why (I believe) references got added to C++.  I've never
> seen a way to do this safely without some heavy type-level stuff, like
> alias types.  This is a big step from what you've got at the moment
> though.

This proposal does not introduce the generic & operator. We can only 
have a down-flow of stack addresses passed by reference as far as I can 
see. This can be thought of as a degenerate case of region-analysis. I 
am missing the safety problem you are referring to, that would require a 
stronger static analysis.

Swaroop.

_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to