teal-language / tl

The compiler for Teal, a typed dialect of Lua
MIT License
2.1k stars 108 forks source link

How to define self paramenter? #561

Closed WeebNetsu closed 1 year ago

WeebNetsu commented 1 year ago

Hello! I took a quick look through the docs and other issues, I might have missed it, but this snippet of code:

local love = require "love"

local function SFX(): any
    return {
        fx_played: boolean = false,

        setFXPlayed = function (self, has_played: boolean)
            self.fx_played = has_played
        end,
    }
end

return SFX

In the above scenario, I need to use self to set fx_played, but how exactly do I set it? Currently it sees self as an unknown type...

I did see this example in the tutorial:

function Point.new(x: number, y: number): Point
   local self = setmetatable({} as Point, { __index = Point })
   self.x = x or 0
   self.y = y or 0
   return self
end

function Point:move(dx: number, dy: number)
   self.x = self.x + dx
   self.y = self.y + dy
end

But flew past me on how I should declare self in this scenario...

lenscas commented 1 year ago

The table you return has no type, thus can not be referenced in the type system. As far as I know, teal has no "Self" shortcut.

However, even if it did, due to use of any this would be useless anyway as that throws away any type information that you have.

You have to make a type that describes the table you return and use it. Then what you are trying to do will be possible.

WeebNetsu commented 1 year ago

So something like this:

local love = require "love"

local type Sfx = record
    fxPlayed: boolean
    setFXPlayed: function(any, boolean)
 end

local function SFX(): Sfx
    return {
        fxPlayed: boolean = false,

        setFXPlayed = function (self, hasPlayed: boolean)
            self.fxPlayed = hasPlayed
        end,
    }
end

return SFX

In the above case, I still sit with the issue of not knowing how to tell Teal about self

WeebNetsu commented 1 year ago

Oh! I think I found the solution, by then just setting self: Sfx, since it's anyways just referencing the function properties

local love = require "love"

local type Sfx = record
    fxPlayed: boolean
    setFXPlayed: function(Sfx, boolean)
 end

local function SFX(): Sfx
    return {
        fxPlayed: boolean = false,

        setFXPlayed = function (self: Sfx, hasPlayed: boolean)
            self.fxPlayed = hasPlayed
        end,
    }
end

local x = SFX()

x:setFXPlayed(true)

return SFX

Now it works! If this is the way to do it, then I think the issue is resolved ;)

hishamhm commented 1 year ago

@WeebNetsu Yes, that's the way to do it :)