I love generic methods in C#
Can’t wait to see them here as well
Thanks a lot for the updates
I love generic methods in C#
Can’t wait to see them here as well
Thanks a lot for the updates
Yes, those annotations are part of the Language spec, not just a temporary beta thing: Type checking - Luau
As for how type-system driven optimization will interact with mixed code, that’s a hard problem. At the end of the day you’ll have to profile and see when that eventually becomes available, however, using type assertions and other techniques it’s a safe bet that you will always be able to kick the available optimizations into working for whatever specific pieces of code you need to make fast even if the rest of your code doesn’t have annotations.
There’s also this bug where after having studio open for a while, studio will stop auto completing global variables:
This is absolutely true and annoying. How do you disable LuaU?
You can’t disable Luau, it’s literally the language you use to code in Roblox. You’re thinking of the Luau Type Checker, in which case, you can’t since it’s built in.
Luau is the variant of Lua that roblox runs on. It is basically what people call “Roblox Lua”. It has the stuff roblox has in it. Pure lua is very similarly. Luau is just a fork of Lua with better features and such to work on Roblox.
Did you read what I even said… Compound operators for the logical AND/OR operators
I’m sure this has been asked in the past but are there any plans for manual garbage collection? Like how one would create then free an array in C
int *array = malloc(5 * sizeof(int));
free(array);
maybe something in luau like
local array = table.create(5);
delete(array);
I know in regular lua you would do this a-la
local array = { 1, 2, 3, 4, 5 };
array = nil;
collectgarbage('collect');
I really only ask because there’s no (easily-findable) documentation on how Luau does it’s gc other than… this
What are your uses for having a way to manually trigger garbage collection?
It feels very footgun-y. You shouldn’t ever have to worry about what the garbage collector is doing behind the scenes because if you’re designing code around it, you’re doing it wrong.
All you have to really know is that once an object (table, userdata) falls out of scope, it will cease to exist in memory at some point in the near future.
all cool, however, is there some method of defining functions inside of tables when assigning type to it? For example this
export type external = {
Test: (boolean) -> (),
}
local External: external = {}
function External.Test(Bool)
print(Bool)
end
return External
Will give a warning W000: (7,1) Table type 'External' not compatible with type 'external', missing field 'Test'
, i thought of doing this
local External: external = {
Test = function(Bool)
print(Bool)
end,
}
return External
However it’s ugly, possible way could be changing the function type to Test: (boolean) -> ()?
but that will cause other warnings like W000: (13,1) Cannot call non-function ((boolean) -> ()) | nil
when calling it for obvious reasons. Same thing happens with the properties.
For module scripts i can fix it by instead of assigning the type when creating the table, use the type assertion operator
return External :: external
Lack of transparency is my largest problem here. My use-case would be to immediately dispose of tables that hold a lot of data within them - if all I know is that the gc would collect them “at some point” then I’d feel more comfortable collecting the garbage on my own when its time to dispose of these objects. I understand how one could think this is a footgun but until Roblox tells us what’s happening “behind the scenes” I feel like we should at least get solid reasoning as to why we can’t do it ourselves other than new scripters might blow their ro-toes off. Considering script injection exploits release within hours after every client build release, I don’t see how it would open the client up to anything worse other than an overflow/crash. Then again my knowledge of cpp is amateur at best - this is where I circle back to transparency and lack of documentation on everything aforementioned
An overflow (as in your example) is already a critical security vulnerability. The most likely issues would come from double free and use after free on pointers. Memory issues like these make up about 70% of all attack vectors (according to both Google and Microsoft in independent studies).
Also, it simply isn’t necessary to do it manually. If you don’t have enough memory, GC will run.
Fair enough. But again, this provides no insight into how Luau gc is actually performed. However this is where I’ll stop bringing it up, for now at least
We don’t have any plans to introduce manual memory management - it can be error prone and can violate strict sandboxing guarantees that our implementation provides.
When we finish the garbage collection implementation we will likely write a separate page explaining a bit how garbage collection works, as some of these details are interesting and/or help explain the behavior of GC, and some help understand how to write efficient programs.
Thanks for the response. I’m looking forward to reading the documentation
I’ve run into a bit of a pickle with luau syntax
So I have this variable called “playingTrack” which is typed as AnimationTrack?
So when I call the following:
playingTrack = animator:LoadAnimation(animation)
playingTrack:Play(
animation:GetAttribute('EmoteFadeTime'),
nil,
animation:GetAttribute('EmoteSpeed')
)
I get this warning for the second line:
In this context, I know for sure that the animationTrack exists. So the logical solution is to add a type annotation to overcome the limitations of the type system:
playingTrack :: AnimationTrack:Play(
animation:GetAttribute('EmoteFadeTime'),
nil,
animation:GetAttribute('EmoteSpeed')
)
Looks like this will be a syntax error, so I’ll just wrap playingTrack :: AnimationTrack
in parentheses, right?
(playingTrack :: AnimationTrack):Play(
animation:GetAttribute('EmoteFadeTime'),
nil,
animation:GetAttribute('EmoteSpeed')
)
Nope, that just leads to ambiguous syntax
I guess I’ll just add a semicolon at the beginning of the line.
;(playingTrack :: AnimationTrack):Play(
animation:GetAttribute('EmoteFadeTime'),
nil,
animation:GetAttribute('EmoteSpeed')
)
Nope, that adds this warning
No matter how much indentation I give that line, it still says my statement spans multiple lines.
Not sure what to do here.
The solution (and generally the way you should be using it) is to use the as on the variable assignment rather than in the middle of an expression.
local playingTrack: AnimationTrack = nil
playingTrack = animator:LoadAnimation(animation) :: AnimationTrack
playingTrack:Play() --> works
local x: {number|number} = {1, 2, 3}
local y = x[1] - x[2] -- Type 'number|number` could not be converted into 'number'
Vector2:Cross
returns a number but is incorrectly typed to return a Vector2
Positional array types like typescript would be a cool feature (probably pending the fix of the first bug though):
type Pair<T,U> = {T, U}
My playingTrack was typed as AnimationTrack?
, not AnimationTrack
local playingTrack: AnimationTrack? = nil
-- ... closure involving playingTrack
playingTrack = animator:LoadAnimation(animation) :: AnimationTrack
playingTrack:Play() --> does not work
Oh, I see the problem, you want Type? = Type
to effectively assert temporary narrowing of the variable, that would make sense.