jackfirth / racket-disposable

An experimental Racket library providing an abstraction for values associated with external resources that allows automatic resource pooling, per-thread virtual construction, and monadic composition
Apache License 2.0
7 stars 0 forks source link

Allow the use of multiple values #113

Open kstrafe opened 6 years ago

kstrafe commented 6 years ago

This is useful when implementing TCP listeners. These return (values input-port output-port). It would be useful if this were possible to do:

(define (accept) (tcp-accept listener))
(define (close i o)
  (close-input-port i)
  (close-output-port o))
(define disposable-connection (disposable accept close))
(with-disposable ([(i o) disposable-connection])
    ...)
jackfirth commented 6 years ago

I've gone back and forth on this one; I still can't quite tell if it's a good idea. See #8 for my last thoughts on this.

What about adding pattern matching support to with-disposable instead?

kstrafe commented 6 years ago

I read your thoughts and sticking values into a list is exactly what I'm doing currently, then using a macro to make it look nice (extracting the values and placing them in variables using match) How would the pattern matching look like?

jackfirth commented 6 years ago

With pattern matching it would look something like this:

(with-disposable ([(list a b) disposable-pair-of-things])
  ...)

But I'm not sure if it's better to have a separate with-disposable/match form or just make this part of with-disposable. In theory I suppose there could be a syntax parameter that defines how to bind things to make the choice of pattern matching syntax user-defined. That's probably too complicated though.

kstrafe commented 6 years ago

I think I'd prefer

(with-disposable ([(a b) disposable-stuff])
   ...)

for values, if possible. This style matches with my expectations of let forms, and seems most natural. Of course an addition of with-disposable/match wouldn't hurt either.

jackfirth commented 6 years ago

In that example would (with-disposable ([both disposable-stuff])) and (with-disposable ([(a b) disposable-stuff])) both be allowed for the same disposable? Would both be a two-element list?

kstrafe commented 6 years ago

Perhaps an error if disposable-stuff's constructor returns (values x y), in the first case.

jackfirth commented 6 years ago

Alright, I think I'm convinced this is worth doing. It would technically be backwards incompatible (due to contract changes in functions like call/disposable) and I'm not sure how best to implement it, but I'll leave the issue open for now.