> I am trying to explain why the semantics of this way of doing the replacement is cleaner and requires less weird special cases in the code (such as this object that is temporarily dead and suddenly revived) than the way in the article (which I see as a strawman designed to make me dislike linear types).
I've always read that article as exposing linear types as more complicated than just slapping a attribute, at least within the context of Rust, but it might just be a naive view of it.
> The whole point of linear types is to make it so that this is a compile-time error, so I don't really understand your objection. If it helps, I will try this in a different tense: if the type doesn't (in the continual sense) manage to provide a deconstructor which eats the object (and could be used on unwind), then either the user had to have (in the past tense) or the code didn't (in the past tense) compile if there were (at the time of compile) any codepaths without nothrow that could cause such an unwind.
But the point of using linear types is that there are constrains which the normal drop does not fulfil or allow for e.g. the deconstruction is failible, or requires additional data, or (as seems to be your case) needs to be moved off-thread. During an unwind, these things are not guarantee or even available at all (how would unwinding know what parameters to provide? How can it report errors to a caller which doesn't exist?). Otherwise the regular Drop would work fine.
> I think I lost an "a-" there, so I'm hoping that if I said "must deconstruct asynchronously" this makes more sense?
It does make a lot more sense yes.
> As a basic example, you finish your SSL request, and now need to deconstruct the SSL connection, which means you want to close the socket... only no, you first need to do an asynchronous SSL CloseNotify, so you have to await that behavior before you allow that socket object to deconstruct. If you let the object deconstruct before you await the CloseNotify, you haven't really completed the protocol. This is also a great case, as while HTTP itself mitigates this (and even in my system I eventually decided to just close this socket by force), you aren't really supposed to trust where the end of the data you got from the server is (and so in the abstract thought process you can't really return from this function until you've finished this CloseNotify; this means that trying to fire-and-forget this to a background thread--which is essentially the analogy of garbage collection--is not a valid solution).
Ah I see, even in the original I think I'd have misunderstood what you meant by asynchronous deconstruction because I wasn't thinking of the "async" context when I read your comment.
Anyway thanks for the expounding on your issues and their relevance to linear typing.
I've always read that article as exposing linear types as more complicated than just slapping a attribute, at least within the context of Rust, but it might just be a naive view of it.
> The whole point of linear types is to make it so that this is a compile-time error, so I don't really understand your objection. If it helps, I will try this in a different tense: if the type doesn't (in the continual sense) manage to provide a deconstructor which eats the object (and could be used on unwind), then either the user had to have (in the past tense) or the code didn't (in the past tense) compile if there were (at the time of compile) any codepaths without nothrow that could cause such an unwind.
But the point of using linear types is that there are constrains which the normal drop does not fulfil or allow for e.g. the deconstruction is failible, or requires additional data, or (as seems to be your case) needs to be moved off-thread. During an unwind, these things are not guarantee or even available at all (how would unwinding know what parameters to provide? How can it report errors to a caller which doesn't exist?). Otherwise the regular Drop would work fine.
> I think I lost an "a-" there, so I'm hoping that if I said "must deconstruct asynchronously" this makes more sense?
It does make a lot more sense yes.
> As a basic example, you finish your SSL request, and now need to deconstruct the SSL connection, which means you want to close the socket... only no, you first need to do an asynchronous SSL CloseNotify, so you have to await that behavior before you allow that socket object to deconstruct. If you let the object deconstruct before you await the CloseNotify, you haven't really completed the protocol. This is also a great case, as while HTTP itself mitigates this (and even in my system I eventually decided to just close this socket by force), you aren't really supposed to trust where the end of the data you got from the server is (and so in the abstract thought process you can't really return from this function until you've finished this CloseNotify; this means that trying to fire-and-forget this to a background thread--which is essentially the analogy of garbage collection--is not a valid solution).
Ah I see, even in the original I think I'd have misunderstood what you meant by asynchronous deconstruction because I wasn't thinking of the "async" context when I read your comment.
Anyway thanks for the expounding on your issues and their relevance to linear typing.