Home Explore Blog CI



neovim

2nd chunk of `runtime/doc/lua.txt`
1d6da00ea723018b4c4b71f9d4a075b1f962e53aedbb3e160000000100000fa7
 same everywhere. Scopes
(closures) in particular are very consistent, unlike JavaScript or most other
languages.

Lua has three fundamental mechanisms—one for "each major aspect of
programming": tables, closures, and coroutines.
https://www.lua.org/doc/cacm2018.pdf
- Tables are the "object" or container datastructure: they represent both
  lists and maps, you can extend them to represent your own datatypes and
  change their behavior using |metatable|s (like Python's "datamodel").
- EVERY scope in Lua is a closure: a function is a closure, a module is
  a closure, a `do` block (|lua-do|) is a closure--and they all work the same.
  A Lua module is literally just a big closure discovered on the "path"
  (where your modules are found: |package.cpath|).
- Stackful coroutines enable cooperative multithreading, generators, and
  versatile control for both Lua and its host (Nvim).

                                                          *lua-error-handling*
Lua functions may throw |lua-errors| for exceptional (unexpected) failures,
which you can handle with |pcall()|.
                                                       *lua-result-or-message*
When failure is normal and expected, it's idiomatic to return `nil` which
signals to the caller that failure is not "exceptional" and must be handled.
This "result-or-message" pattern is expressed as the multi-value return type
`any|nil,nil|string`, or in LuaLS notation: >

    ---@return any|nil    # result on success, nil on failure.
    ---@return nil|string # nil on success, error message on failure.
<
Examples of the "result-or-message" pattern:
- |vim.ui.open()|
- |io.open()|
- |luv-error-handling|

When a caller can't proceed on failure, it's idiomatic to `assert()` the
"result-or-message" result: >lua

    local value = assert(fn())

Guidance: use the "result-or-message" pattern for...
- Functions where failure is expected, especially when communicating with the
  external world. E.g. HTTP requests or LSP requests often fail because of
  server problems, even if the caller did everything right.
- Functions that return a value, e.g. Foo:new().
- When there is a list of known error codes which can be returned as a third
  value (like |luv-error-handling|).
<
                                                                    *iterator*
An iterator is just a function that can be called repeatedly to get the "next"
value of a collection (or any other |iterable|). This interface is expected by
|for-in| loops, produced by |pairs()|, supported by |vim.iter|, etc.
https://www.lua.org/pil/7.1.html

                                                                    *iterable*
An "iterable" is anything that |vim.iter()| can consume: tables, dicts, lists,
iterator functions, tables implementing the |__call()| metamethod, and
|vim.iter()| objects.

                                                               *list-iterator*
Iterators on |lua-list| tables have a "middle" and "end", whereas iterators in
general may be logically infinite. Therefore some |vim.iter| operations (e.g.
|Iter:rev()|) make sense only on list-like tables (which are finite by
definition).

                                                           *lua-function-call*
Lua functions can be called in multiple ways. Consider the function: >lua
    local foo = function(a, b)
        print("A: ", a)
        print("B: ", b)
    end

The first way to call this function is: >lua
    foo(1, 2)
    -- ==== Result ====
    -- A: 1
    -- B: 2

This way of calling a function is familiar from most scripting languages. In
Lua, any missing arguments are passed as `nil`, and extra parameters are
silently discarded. Example: >lua
    foo(1)
    -- ==== Result ====
    -- A: 1
    -- B: nil
<
                                                                      *kwargs*
When calling a function, you can omit the parentheses if the function takes
exactly one string literal (`"foo"`) or table literal (`{1,2,3}`). The latter
is often used to mimic

Title: Lua Concepts: Error Handling, Iterators, and Function Calls
Summary
This section delves into Lua concepts, starting with error handling using `pcall()` for exceptional failures and the 'result-or-message' pattern for expected failures, especially in external communications. It then explains iterators and iterables. Finally, it describes various ways to call Lua functions, including the handling of missing or extra parameters, and omitting parenthesis when calling a function with a single string or table literal.