Closed hazer-hazer closed 1 year ago
I think copying Rust's &
syntax makes sense, unless we want to have a
more explicit keyword.
On Fri, Oct 1, 2021, 11:27 AM Hazer Hazer @.***> wrote:
Rust has a feature "lifetimes" for reference validation. Of course, it is possible to reduce cases when explicit annotations are required and don't have them at all in the language. Anyway, are there any plans for lifetime annotations? If not, how would cases such as "reference field in structure/class" be checked?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/alshdavid/BorrowScript/issues/17, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGDQCMQOXZYYSSJ3M3CARGLUEXHMXANCNFSM5FE6ENEQ .
Good question. It's actually a bit tricky. To start with, all builtin types are references.
let a: number = 0
a.increment() // mutate the reference to a
Let's write a function that compares two numbers and returns the largest
function main() {
let a = 5
let b = 10
let c = largest(a, b)
console.log(c)
}
function largest(read x: number, read y: number): number {
if (x > y) {
return x
} else {
return y
}
}
Somewhat similarly to Rust:
function largest<'a>(read 'a x: number, read 'a y: number): 'a number {}
// or we can use the 'lifeof' keyword
function largest<lifeof A>(read A x: number, read A y: number): A number {}
I think this makes sense. number
(like all builtin types) is a reference to an object instance and not a primitive value like i32
.
What we are saying above is:
"Accept read-only references to variables x and y of type number
. Return a reference to a number
that has the shortest life of the parameters with the A
life"
I think works if there are no non-reference value types. I don't like that the generic lifetime param is used differently to other type params.
This would look like:
function main() {
let a = 5
let b = 10
let c = largest(read a, read b)
console.log(c)
}
function largest<lifeof A>(read A x: number, read A y: number): A number {
if (x > y) {
return x
} else {
return y
}
}
Rust looks like:
fn largest<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
if x > y {
x
} else {
y
}
}
fn main() {
let a = &5;
let b = &10;
let c = largest(a, b);
print!("{}", c);
}
Though the return type irks me.
function largest<lifeof A>(read A x: number, read A y: number): A number {}
Specifically
): A number {}
We could have so that a lifeof
parameter (A
in this case) itself is a type that has a type parameter.
function largest<lifeof A>(read A x: number, read A y: number): A<number> {}
Hmm... Now it sounds more and more like "Rust with TypeScript-like syntax", which is not really bad, but I'm not sure if it will work. Rustish safety system is fascinating and the idea of static garbage collection is mind-grabbing, however, some features cannot fully live without GC in runtime, especially JavaScript features. I have so many questions about how this idea is possible to be implemented, but it would be better just to wait until you and contributors will make something workable.
Rust has a feature "lifetimes" for reference validation. Of course, it is possible to reduce cases when explicit annotations are required and don't have them at all in the language. Anyway, are there any plans for lifetime annotations? If not, how would cases such as "reference field in structure/class" be checked?
UPD: I'm talking about cases like
...<'a>
or&'a ...
.