generativity | Generativity refers to the creation of a unique lifetime
kandi X-RAY | generativity Summary
kandi X-RAY | generativity Summary
Generativity refers to the creation of a unique lifetime: one that the Rust borrow checker will not unify with any other lifetime. This can be used to brand types such that you know that you, and not another copy of you, created them. This is required for sound unchecked indexing and similar tricks. The first step of achieving generativity is an invariant lifetime. Then the consumer must not be able to unify that lifetime with any other lifetime. Traditionally, this is achieved with a closure. If you have the user write their code in a for<'a> fn(Invariant<'a>) -> _ callback, the local typechecking within this callback is forced to assume that it can be handed any lifetime (the for<'a> bound), and that it cannot possibly use another lifetime, even 'static, in its place (the invariance). This crate implements a different approach using macros and a Drop-based scope guard. When you call generativity::make_guard! to make a unique lifetime guard, the macro first creates an Id holding an invariant lifetime. It then puts within a Drop type a &'id Id<'id> reference. A different invocation of the macro has a different end timing to its tag lifetime, so the lifetimes cannot be unified. These types have no safe way to construct them other than via make_guard!, thus the lifetime is guaranteed unique. This effectively does the same thing as wrapping the rest of the function in an immediately invoked closure. We do some pre-work (create the tag and give the caller the guard), run the user code (the code after here, the closure previously), and then run some cleanup code after (in the drop implementation). This same technique of a macro hygiene hidden impl Drop can be used by any API that would normally use a closure argument, such as crossbeam's scoped threads, to make the containing scope the safe, wrapped scope if they so desire the trade-off of macro versus closure indentation.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of generativity
generativity Key Features
generativity Examples and Code Snippets
Community Discussions
Trending Discussions on generativity
QUESTION
In the paper "Higher-order Type-level Programming in Haskell", an f :: Type -> Type
is defined to be "generative" in the following way:
Definition (Generativity). f is generative ⇔ f a ~ g b ⇒ f ~ g
I'm going to explicitly write out the intended quantification as I understand it:
...ANSWER
Answered 2021-Aug-15 at 03:22Eh, you're overthinking it. The ~
really is the one from GHC. If you prefer, replace the claim "unsaturated type families are not generative" with "if we expanded ~
to allow unsaturated type families1, then they would not be guaranteed generative2". This latter fact is (part of) the reason we don't bother expanding ~
to allow unsaturated type families -- it would be much less useful for them than it is for other type expressions.
If they were not precise about this divide in the paper, it's just a bit of slightly sloppy writing, such as we've all done at one point or another.
1 You can probably deal with the G
/Maybe
situation by simply allowing type families on one side of ~
but not the other.
2 In fact, I believe it's even stronger: they would be guaranteed not to be generative.
QUESTION
Here is the canonical example for a rigid type variable escaping its scope:
...ANSWER
Answered 2021-Mar-07 at 22:27Writing my comment out as an answer since I guess it helped. :)
I believe your error was in skolemising the argument in the application; instead, it should be instantiated with a fresh metavariable (I’ll write a circumflex for metavars and bold for skolem constants):
fun : ∀a. (∀b. Foo b a) → a
arg : (∀c. Foo c (Bar c Char))
[â0/a]((∀b. Foo b a) → a) = (∀b. Foo b â0) → â0
Foo c (Bar c Char)
[â1/c](Foo c (Bar c Char)) = Foo â1 (Bar â1 Char)
Then, in the subtyping judgement:
… ⊢ Foo â1 (Bar â1 Char) ≤: ∀b. Foo b â0
You still skolemise the ∀-bound variable on the right side as usual:
…, b ⊢ Foo â1 (Bar â1 Char) ≤: Foo b â0
This gives Foo = Foo by generativity, but solves â1 to b by injectivity, and solves â0 to Bar â1 Char. This then correctly gives an occurs check failure when exiting the scope of the quantifier, since the substituted type [â1=b](Bar â1 Char) = Bar b Char contains the skolem constant b.
I say “skolemise” because this does introduce a type constant, but it can also be thought of as just entering the scope of a quantifier (as in “Complete and Easy”), not necessarily performing deep skolemisation.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install generativity
Rust is installed and managed by the rustup tool. Rust has a 6-week rapid release process and supports a great number of platforms, so there are many builds of Rust available at any time. Please refer rust-lang.org for more information.
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page