Varargs in Channel

Issue #1334 wontfix
Henrique Gemignani
created an issue

Making the Channel:push (and Channel:supply) functions receive multiple arguments, and the Channel:pop (and Channel:demand) functions return multiple values.

local channel = love.thread.newChannel()
channel:push("a", 40, "z")

local a, b, c = channel:pop()

If interested in this idea, I will make a PR for this.

Comments (5)

  1. Henrique Gemignani reporter

    I actually know about the multi level tables ;)

    It's two parts:

    • Simpler usage in lua, avoiding packing and unpacking in tables:
    local function processCommand(commandName, ...)
        local func = commands[commandName]
        if func then
            func(...)
            return true
        end
    end
    
    -- Packing
    channel:push({"doStuff", 10, 50})
    while processCommand(unpack(channel:pop() or {})) do end
    
    -- Multi arg
    channel:push("doStuff", 10, 50)
    while processCommand(channel:pop()) do end
    
    • Easier usage in C++
    // Packing
    auto table = new std::vector<std::pair<Variant, Variant>>();
    table->emplace_back(1.0, Variant("doStuff", 7));
    table->emplace_back(2.0, 10.0);
    table->emplace_back(3.0, 50.0);
    Variant var(table);
    channel->push(var);
    
    // Multi arg
    std::vector<Variant> args;
    args.emplace_back("doStuff", 7);
    args.emplace_back(10.0);
    args.emplace_back(50.0);
    channel->push(args);
    

    Expanding on the second one, dealing with love::Variant on the C++ side is a mess.

  2. Bart van Strien

    I kind of see the point, but your examples are exaggerated.

    local function processCommand(command)
        local func = command and commands[command[1]]
        if func then
            func(unpack(command, 2))
            return true
        end
    end
    
    -- Packing
    channel:push{"doStuff", 10, 50}
    while processCommand(channel:pop()) do end
    

    You explicitly designed your function to require unpack.

    As for the C++ API, they would be mostly equivalent:

    auto table = new std::vector<std::pair<Variant, Variant>>();
    table->emplace_back(1.0, Variant("doStuff", 7));
    table->emplace_back(2.0, 10.0);
    table->emplace_back(3.0, 50.0);
    channel->push(table);
    
    auto args = new std::vector<Variant>;
    args->emplace_back("doStuff", 7);
    args->emplace_back(10.0);
    args->emplace_back(50.0);
    channel->push(args);
    

    (Or you could pass both by reference and copy/move, if you want to.)

    And yes, Variant isn't exactly nice from the C++ side, but that's also not really a priority, and hard to circumvent.

    I can see some advantages to multiple return values on the lua side, but the actual use cases seem to be limited. And as a con, it's yet more Variant code, that doesn't really improve its API, needs to be maintained, and largely mimics the table code.

  3. Bart van Strien

    I might revisit this, but even though I like this on some conceptual level, I don't actually see much of a use case. And of course it now also clashes with the timeouts, as mentioned.

  4. Log in to comment