or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
![image alt](https:// "title") | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | Emoji list | ||
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing
xxxxxxxxxx
Open discussion: September 2023
This is the doc for open discussion within wg-async about various design questions and other topics. Please feel free to propose a topic below.
On the day of the meeting, we'll do a quick poll to sort the topics by interest and then go through them one by one. If you have a brief (under 5 min) introduction prepared for the group, we'll take that into account as we prioritize the topics.
tags:
open-discussion
Attendance: TC, tmandry, Zach Mitchell, eholk, yosh, vincenzo
Leave discussion topics below.
https://blog.yoshuawuyts.com/linearity-and-control/
Purpose of
linear fn
tmandry: Why do we need to mark functions, and not just arguments / type parameters, as
linear
?yosh: I'm trying to page this back in. In general like, I'm pretty convinced this interpretation of linearity is not what we want, so I've not really thought about it much since writing the second post.
yosh: I believe the main reason is that futures are weird. An
async fn
is not just a function, it's also a type containing the actual computation's state machine. So when we saylinear async fn
, that not only governs the arguments passed into the function - but also the function itself.yosh:
Fn{,Once,Mut}
have a very similar property: if we take a closure as an argument somewhere, then we have to know somehow whether that closure is trying to uphold the linearity guarantees or not. And functions can be passed as closures, we need a notation for functions too.yosh: We have this problem in reverse for
unsafe fn
. Where if you have anunsafe fn
, you can't actually pass it as a closure anywhere because we don't haveUnsafeFn
traits.tmandry: You want closure values to be linear if they capture linear types.
yosh: Yes.
tmandry: It feels different from
async
andtry
effects though in that it doesn't affect the control flow of the function (e.g.map
).TC: Do free functions need to be marked
linear
?yosh: If we ever want to pass it as a function argument
TC: But we can pass a
Fn
somewhere that expects anUnsafeFn
, etc.yosh: Yes.
Destructor arguments
tmandry: One of the benefits I've had in mind for linear types is that it would allow explicit destructors that take arguments, e.g. a context that's needed for destruction. So maybe not all linear types should be
Drop
?yosh: I think that's a valid thing to want, and that sort of touches on the two different interpretations of linearity:
#[must_use]
yosh: Being able to pass arguments into the destructor works really well with the first variant. But that interpretation of linearity has the downside that it leads to pretty different usage patterns than what we're used to in Rust today. Feedback on Niko's earlier post on linearity showed that, where things like closures run into a lot of issues.
yosh: Instead what I hope we might be able to do is take the "will Drop" interpretation of linearity, and over time give it more capabilities. Maybe using context/capabilities we can find a way to pass arguments into destructors?
eholk: I kind of like that linear types make destructors a convention or design pattern, like constructors are in Rust, rather than necessarily something special.
tmandry: I think 2 is the thing I've been calling
?Leak
/!Leak
in my head. Skeptical of being able to use contexts/capabilities for destructor args because it's saying you couldn't destruct the value without the context… hm, might work?.. but I'm not sure.yosh: I think 2 is way more valuable than being able to pass arguments into the destructor.
Linear Drop and owned references
eholk: The proposal to have the linear version of
drop
takeself
probably won't work for pinned data (admittedly, drop is wrong for pinned data already), because aself
arg is semantically moved from the callers frame into thedrop
function's frame. I've seen a few people discuss something like&owned T
references, which it seems like will be necessary here.yosh: do you have a link to discussions about
&owned T
? I haven't heard of that before I think?eholk: No, but here's a quick example of how
&owned
would work:Basically,
&owned
passes the obligation/right to drop the value pointed to by the reference, so it is considered moved after passing it somewhere else, even though the value stays in the same place in memory.yosh: oh, so it's like logical move (ownership has changed) vs physical move (the address has changed)?
eholk: Exactly!
yosh: innnnnnterestingggggg - I'll need a bit to process this I think haha
yosh: ohhhh, could this be used for like
alloca
etc? I believe it's called "box constructors" or something? Or in-place box. Ha, I forget. Placement new!tmandry: I could see it working for
Pin
.Pin<&owned T>
.yosh:
Pin
is must not moveWhy is it not possible to write scoped async blocks?
zmitchell: Just for my understanding, I'm not clear on the first example in the post e.g. that it's not possible to write something like scoped threads. What is the safety concern that's preventing it?
yosh: Gankra's post linked at the start covers this in-depth. But the tldr is that when you call a regular function, nothing else can happen concurrently with it on the same thread. You call a function, and it runs until it returns. That's a way to hold onto references without relying on destructors.
yosh: Async functions don't run when called, they run when
.await
ed. Meaning we have space in between where you could have a reference andmem::forget
it, which will throw the system off. We need a way to guarantee nothing else can be done with the references while they're being held in the closure, and we don't have a great way of doing that in async Rust right now. Does that… make sense?zmitchell: Yes, thanks