lua-language-server icon indicating copy to clipboard operation
lua-language-server copied to clipboard

feature suggestion: add a notation for callbacks that expects the user to implement

Open ImpleLee opened this issue 4 years ago • 8 comments

There exist some callbacks in the LÖVE framework, like love.conf, love.draw and some others, and there is currently no way in EmmyLua to note that they are callbacks rather than normal functions, and that a new definition of the same function is an implementation rather than a new overload.

Current Behavior

No way to indicate that this is a callback instead of a normal function definition.

-- In the API definition.
---xxx
---@param t string
function callback(t) end


-- In user code
function callback(t)
    t:$
end

There is no completion based on the type of the parameter or ...

Suggested Behavior

Add a new notation for callbacks so when user is defining a new implementation, they can get completion on the parameters. This is especially useful when the parameter is extremely complex (for an example, see love.conf)

-- In the API definition.
---@callback
---xxx
---@param t string
callback = nil

-- In the user code
function callback(t)
    t:$
end

I am totally open to the specific syntax, and I think what is really important is to have a syntax for them.

ImpleLee avatar Mar 29 '21 08:03 ImpleLee

I may support this:

---@type fun(t:iolib)
callback = nil

-- In the user code
function callback(t)
    t:$
end

sumneko avatar Apr 01 '21 03:04 sumneko

I think that should be good enough.

ImpleLee avatar Apr 01 '21 09:04 ImpleLee

After considering some more details, I think maybe it would be better if I could add comment to the parameters (and maybe also the returned value?) just as I can add comment to function parameters and returned values as well.

ImpleLee avatar Apr 01 '21 09:04 ImpleLee

After considering some more details, I think maybe it would be better if I could add comment to the parameters (and maybe also the returned value?) just as I can add comment to function parameters and returned values as well.

I haven't thought of a good way to achieve it. The easy way is:

---@param x string -- comment
---@type fun(x: string)
callback = nil

or I need to implement a complete set of interface specifications like this:

---@callback XXX
---@param x string -- comment

---@type XXX
callback = nil

sumneko avatar Apr 30 '21 07:04 sumneko

I think maybe a specific keyword is better so a normal user will not accidentally misuse this feature...

ImpleLee avatar May 01 '21 09:05 ImpleLee

Currently I have implemented this way:

---@param x number
---@param y boolean
Interface = nil


function Interface(x, y)
    -- x is number and y is boolean here
end

However, I found that this design has problems, such as:

---@param x number
---@param y boolean
Interface = nil


function Interface(y, x)
    -- y is boolean and x is number here
    -- this is obviously not semantic
end

So i need to modify some design, one way is:

---@param [1] number
---@param [2] boolean
Interface = nil


function Interface(x, y)
    -- x is number and y is boolean here
end

sumneko avatar Sep 28 '21 12:09 sumneko

Hey, any way to specify callbacks as params? Saying that I accept as a callback a function that should get this arguments and return this other arguments. Something like

---@param fn function(x:number):string the function to call

If it can have support for generics that will be just awesome

danielo515 avatar Aug 25 '22 15:08 danielo515

Yes, that is the way to define a function param except it is fun not function. @danielo515

There has been some related talk in another issue:

https://github.com/sumneko/lua-language-server/issues/1456

The general consensus seems to be defining functions for overloading and callbacks is not easy or very usable right now.

carsakiller avatar Aug 25 '22 18:08 carsakiller

So I have a library where you instantiate a class and then can set some functions on it that will be called by my library something like this


local Instance = MyClass:new()

function Instance:method () -- This will be called internally, it has a specific type defined by the library
  --Method implementation
end

There is no way for me to type this, if I give MyClass.method a type it will complain that I'm redefining it, if I were to just give the user an @alias I wouldn't be able to define an initial value for this method (something like a default), the library would need to use @as every time it calls the method, and the user would need to specify the type every time they define the method

pablomayobre avatar Feb 14 '23 17:02 pablomayobre

Same issue as @pablomayobre

If we could define functions / classes as interfaces (that can / need to be implemented) that would be amazing

Sygmei avatar Aug 19 '23 02:08 Sygmei