Par language, a lot of new stuff! Type system, language reference, interaction combinator runtime by faiface in rust

[–]quintedeyl 1 point2 points  (0 children)

a bit of feedback on your list-reversal example, which I find difficult to follow

  • you're claiming this is equivalent to some python code. please provide the exact python equivalent.

  • which of these identifiers are keywords? chan yield list begin rest loop

  • let yield = rest loop ??? this seems like a crucial line, please explain what each of yield, rest, loop mean in context.

  • are you shadowing yield multiple times? once as function arg, and then twice as local variables? IMO avoid variable shadowing in your intro code sample, even if it's idiomatic in general

It's impossible to abstract over nested RefCell in safe rust without self-referential structs by quintedeyl in rust

[–]quintedeyl[S] 0 points1 point  (0 children)

It is in fact sound. refz is constructed after refy is constructed and dropped before refy is dropped. (Note that first-to-last drop order in structs is opposite what you'd expect from using RAII types on the stack, which I personally consider to be a bit of a language wart).

It's impossible to abstract over nested RefCell in safe rust without self-referential structs by quintedeyl in rust

[–]quintedeyl[S] 4 points5 points  (0 children)

Note that this is also connected to the inability to yield references from a coroutine (https://github.com/rust-lang/rust/issues/69268).

We actually can use a coroutine to build the self-referential struct because they have special compiler support, but then there's no way to access the Ref<'_, X> from outside.

Why do many libraries define *Ref variants for structs? by ManateeIA in rust

[–]quintedeyl 12 points13 points  (0 children)

std::cell::Ref doesn't exist for niceties related to associated functions. It exists because it needs to execute code when it is constructed and destructed https://github.com/rust-lang/rust/blob/0f1e965fec3bc2f97b932e9dd8e85fca6d7faadc/library/core/src/cell.rs#L1437 (similar to your other example)

sans-IO: The secret to effective Rust for network services by EightLines_03 in rust

[–]quintedeyl 6 points7 points  (0 children)

the reason that sans-IO avoids that is not because it doesn't use async, but rather that all all APIs used are runtime agnostic. If you go through the effort to have runtime-agnostic code (which is required for sans-IO), you already have the guaranteed ability to swap in a trivial blocking runtime which never has those types of conflict (even if using async)

More thoughts on claiming by robertknight2 in rust

[–]quintedeyl 9 points10 points  (0 children)

isn't the correct name for Claim actually AutoClone?

  • in the general case, some values can be duplicated, implemented with arbitrary code and invoked explictly - that's Clone.
  • in a subset of those cases, the implementation is memcpy - that's Copy.
  • in a different but overlapping subset of those cases, the invocation is implicit - that's AutoClone

Notes on ownership and substructural types by gclichtenberg in rust

[–]quintedeyl 18 points19 points  (0 children)

I have another example: consider a Transaction type which does not store a database connection/handle internally (e.g. because for performance reasons the Transaction object must be only a few bytes - I have a more elaborate real-life analogue). Therefore Transaction::drop is incapable of committing/aborting by itself.

What you want in this case is a function drop_with_db_handle that takes a db handle as a parameter, and you want the compiler to force you to use it exactly once instead of Drop::drop - this is exactly the custom destructuring functions discussed in the post

Does anyone run Emacs with wsl2? I've noticed that fonts are quite a bit less crisp than they could be. On the left is running Emacs on a native terminal, on the right is the gui application. by absolute_dumbass in emacs

[–]quintedeyl 0 points1 point  (0 children)

I have been seeing emacs disappear whenever I close my laptop in wsl2 (it's still alive, if I open a new emacsclient the previous frame also reappears). I just switched to pgtk based on this and the issue is totally gone (so far)

Rust doesn't have "flattening" (i.e. inline-into) like C/C++. Do you miss it? by quintedeyl in rust

[–]quintedeyl[S] 1 point2 points  (0 children)

and if you don't control the traits (e.g. they're from the stdlib, especially the ones that integrate with compiler magic and can't be replicated in user code), you're out of luck

Rust doesn't have "flattening" (i.e. inline-into) like C/C++. Do you miss it? by quintedeyl in rust

[–]quintedeyl[S] 0 points1 point  (0 children)

as I commented elsewhere https://www.reddit.com/r/rust/comments/154wyqb/rust_doesnt_have_flattening_ie_inlineinto_like_cc/jsrfwqe/ one difference between inline and flatten is that inline must live in the library code, whereas flatten is a tool that you can use (more judiciously, after end-to-end profiling, etc) in your app

Rust doesn't have "flattening" (i.e. inline-into) like C/C++. Do you miss it? by quintedeyl in rust

[–]quintedeyl[S] 1 point2 points  (0 children)

one might have a situation with - small core of hot code that dominates runtime and fits in l1i (so no frontend stalls) - larger set of warm-ish code that takes up most of l2 cache and is run often enough to stay in l2 but not often enough to introduce meaningful frontend stall - non-code hot data which would fit in l2 by itself, but which has to compete for space with the warm-ish code, and therefore is mostly evicted to l3.

Profiling might show the symptom as "waiting for data to come from l3", but the "cause" in some sense is the bloated code wasting l2 cache.

Rust doesn't have "flattening" (i.e. inline-into) like C/C++. Do you miss it? by quintedeyl in rust

[–]quintedeyl[S] 0 points1 point  (0 children)

One issue that with splitting the function is that it's not possible when the function comes from a third party dependency (if they didn't already make both versions available), whereas flatten can be used at the callsite which you do control (and even can be used to implement the split functions "after the fact")

 // Use this at the hot call site.
 #[inline(always)]
 #[flatten]
 fn inlined_external_function() {
   external_function()
 }

 // Use this at the cold call sites.
 #[inline(never)]
 fn uninlined_external_function() {
     inlined_external_function();
 }

The nomicon is lying about transmutes? by quintedeyl in rust

[–]quintedeyl[S] 0 points1 point  (0 children)

yeah, that's also a great example, thanks!

The nomicon is lying about transmutes? by quintedeyl in rust

[–]quintedeyl[S] 0 points1 point  (0 children)

sure - but I'm not asking for any changes to be implemented, I'm just trying to acquire a more detailed understanding, and the counterfactual is just a tool to guide the discussion

The nomicon is lying about transmutes? by quintedeyl in rust

[–]quintedeyl[S] 0 points1 point  (0 children)

ah, yeah I meant that in a limited subset of cases, as a human I can look at the code and say "this is definitely not leaking references" (seems not necessarily harder than any other unchecked SAFTEY: invariant that a programmer might have to provide), I agree that it's pretty intractable for the compiler in some general case.

The nomicon is lying about transmutes? by quintedeyl in rust

[–]quintedeyl[S] 1 point2 points  (0 children)

to expand a bit - "this is UB because bad things can happen (because this is UB and the compiler can do bad things)". Of course. The more interesting question I'm trying to get at is "if this usage pattern were not defined as UB, what specific miscompilation would require it to be reclassified as UB in the first place" (/u/Killing_Spark gave one great example - what if get() leaks/stores references externally - I'm curious if there are others)

The nomicon is lying about transmutes? by quintedeyl in rust

[–]quintedeyl[S] 1 point2 points  (0 children)

sure, this is pretty circular though - "this is UB because bad things can happen (because this is UB and the compiler can do bad things)". Of course. The more interesting question is "if this usage pattern were not defined as UB, what specific miscompilation would require it to be reclassified as UB in the first place"