On Sat, Jul 4, 2020 at 12:34, Shawn Walker <binarycrusader@gmail.com>
wrote:
> I guess I’m spoiled by the rust compiler’s reasoning about > lifetimes. If I try to use ‘x’ once the binding has expired it > won’t let me and tells me why. Here it seems like Scopes should > know the lifetime of the storage and then could prevent or warn about > further use.
Scopes' borrow checker is opt-in, and the core is designed such that
lower level constructs / APIs are not checked. The higher level APIs on
the other hand are built on top of those but with security added in. In
this particular example, it's usually recommended to use the Array
(from Array.sc) data-type instead, which is both bounds and lifetime
checked. Similarly alloca, malloc shouldn't be used directly (ie. use
`local` with a unique type, or a Box<T> for heap).
The bottom line is that in normal usage you will always never deal with
pointers (or use most LLVM intrinsic functions), except when dealing
with external C APIs (in which case you can immediately wrap in a
checked type) or when implementing new language features.
...This is not to say this couldn't change or be added in, but it's my
understanding that the behaviour is by design.
Westerbly (radgeRayden) Snaydley.
On Sat, Jul 4, 2020 at 14:48, Westerbly Snaydley <westerbly@gmail.com>
wrote:
> > > On Sat, Jul 4, 2020 at 12:34, Shawn Walker <binarycrusader@gmail.com> > wrote:>> I guess I’m spoiled by the rust compiler’s reasoning about >> lifetimes. If I try to use ‘x’ once the binding has expired it >> won’t let me and tells me why. Here it seems like Scopes should >> know the lifetime of the storage and then could prevent or warn >> about further use.> > Scopes' borrow checker is opt-in, and the core is designed such that > lower level constructs / APIs are not checked. The higher level APIs > on the other hand are built on top of those but with security added > in. In this particular example, it's usually recommended to use the > Array (from Array.sc) data-type instead, which is both bounds and > lifetime checked. Similarly alloca, malloc shouldn't be used directly > (ie. use `local` with a unique type, or a Box<T> for heap).> The bottom line is that in normal usage you will always never deal > with pointers (or use most LLVM intrinsic functions), except when > dealing with external C APIs (in which case you can immediately wrap > in a checked type) or when implementing new language features.> ...This is not to say this couldn't change or be added in, but it's > my understanding that the behaviour is by design.> > Westerbly (radgeRayden) Snaydley.
Slight correction: in this particular case it's fine to use plain
arrays, I meant it more that it's not recommended to use alloca, and if
you avoided that there would be no problem. The unique Array type
serves as the complementary solution for when you actually would use
dynamically allocated memory (like std::vector, I suppose).
Also, I think you need to hit reply all when responding to mailing list
emails, as your last one didn't show in the archives.
Westerbly (radgeRayden) Snaydley.
On Sat, 4 Jul 2020 at 13:06, Westerbly Snaydley <westerbly@gmail.com> wrote:
> On Sat, Jul 4, 2020 at 14:48, Westerbly Snaydley <westerbly@gmail.com>> wrote:> > On Sat, Jul 4, 2020 at 12:34, Shawn Walker <binarycrusader@gmail.com>> > wrote:> >> I guess I’m spoiled by the rust compiler’s reasoning about> >> lifetimes. If I try to use ‘x’ once the binding has expired it> >> won’t let me and tells me why. Here it seems like Scopes should> >> know the lifetime of the storage and then could prevent or warn> >> about further use.> >> > Scopes' borrow checker is opt-in, and the core is designed such that> > lower level constructs / APIs are not checked. The higher level APIs> > on the other hand are built on top of those but with security added> > in. In this particular example, it's usually recommended to use the> > Array (from Array.sc) data-type instead, which is both bounds and> > lifetime checked. Similarly alloca, malloc shouldn't be used directly> > (ie. use `local` with a unique type, or a Box<T> for heap).> > The bottom line is that in normal usage you will always never deal> > with pointers (or use most LLVM intrinsic functions), except when> > dealing with external C APIs (in which case you can immediately wrap> > in a checked type) or when implementing new language features.> > ...This is not to say this couldn't change or be added in, but it's> > my understanding that the behaviour is by design.> >> > Westerbly (radgeRayden) Snaydley.>> Slight correction: in this particular case it's fine to use plain> arrays, I meant it more that it's not recommended to use alloca, and if> you avoided that there would be no problem. The unique Array type> serves as the complementary solution for when you actually would use> dynamically allocated memory (like std::vector, I suppose).> Also, I think you need to hit reply all when responding to mailing list> emails, as your last one didn't show in the archives.
Yes, that makes sense. I'm relying on the test code mostly as
examples right now to try to make sense of Scopes' usage. That means
I'm learning what works and what doesn't the hard way ;)
As for the reply all mystery, that was because sourcehut refuses to
process email to the list if your client sends text/html and
text/plain instead of just dropping the text/html part (sigh).
gmail's web client lets you explicitly use plain text email, so what's
what I have it set to default to, but the mobile gmail clients
(whether you use native app or web interface) don't let you choose :(
--
Shawn Walker-Salas
On Sat, 4 Jul 2020 at 12:49, Westerbly Snaydley <westerbly@gmail.com> wrote:
> On Sat, Jul 4, 2020 at 12:34, Shawn Walker <binarycrusader@gmail.com>> wrote:> > I guess I’m spoiled by the rust compiler’s reasoning about> > lifetimes. If I try to use ‘x’ once the binding has expired it> > won’t let me and tells me why. Here it seems like Scopes should> > know the lifetime of the storage and then could prevent or warn about> > further use.>> Scopes' borrow checker is opt-in, and the core is designed such that> lower level constructs / APIs are not checked. The higher level APIs on
So if I'm guessing correctly, the borrow checker you're referring to
is the "view propagation" mechanism? However, that can't be used with
the lower-level constructs and some of the APIs?
> the other hand are built on top of those but with security added in. In> this particular example, it's usually recommended to use the Array> (from Array.sc) data-type instead, which is both bounds and lifetime> checked. Similarly alloca, malloc shouldn't be used directly (ie. use> `local` with a unique type, or a Box<T> for heap).
I was trying to puzzle out the subtleties between let, local, etc.
using examples from the tests. The documentation and test examples
made it clear enough that local was stack, global was heap, etc. but
let is still murky to me. My understanding is that let is generally
register-based allocation for values unless you use something like
alloca-x but maybe it's stack too?
--
Shawn Walker-Salas
On Sat, Jul 4, 2020 at 14:28, Shawn Walker <binarycrusader@gmail.com>
wrote:
> So if I'm guessing correctly, the borrow checker you're referring to> is the "view propagation" mechanism? However, that can't be used with> the lower-level constructs and some of the APIs?
Correct. Non-unique ("plain") types - the case for most (all?) of the
low level parts - aren't checked and constructs like `drop` or `view`
are ignored when used on them.
> I was trying to puzzle out the subtleties between let, local, etc.> using examples from the tests. The documentation and test examples> made it clear enough that local was stack, global was heap, etc. but> let is still murky to me. My understanding is that let is generally> register-based allocation for values unless you use something like> alloca-x but maybe it's stack too?
globals are the equivalent to data section variables in an AOT program.
Conceptually they are not the same as something you allocate using
`malloc`; their lifespan is the same as your program's.
`let` binds a value to a name. Generally it's used to bind the
immutable result of an expression, in which case it will be stored in a
virtual register (might be promoted to stack if necessary, but you
still can't change it).
You can also bind a local/global variable to an alias, or even types
and other compile-time only objects. This incurs no transformation, the
only difference is the name by which you call them.
Westerbly (radgeRayden) Snaydley.