Have proper value-returning functions ever been considered?

Consider this:

function(foo OUTPUT_VARIABLE)
    set(${OUTPUT_VARIABLE} 1 PARENT_SCOPE)
endfunction()

function(bar)
    foo(RESULT)
    if (${RESULT} EQUALS 1)
    endif()
endfunction()

Wouldn’t it be nice if we could write this as:

function(foo)
    return 1
endfunction()

function(bar)
    if (foo() EQUALS 1)
    endif()
endfunction()

I’m interested in understanding why this is a difficult problem. For example, on the surface it seems you could actually just transpile the second example into this, and then run cmake against the transpiled code:

function(foo)
    set(__INTERNAL_CMAKE_RETURN_VALUE 1 PARENT_SCOPE)
endfunction()

function(bar)
    foo(RESULT)
    if (__INTERNAL_CMAKE_RETURN_VALUE EQUALS 1)
    endif()
endfunction()

I’m sure there are many cases I’m not thinking of, but that’s why I’m asking here, to have a better understanding of why this doesn’t work.

Function return values have been suggested several times. IMO they should not be added. Once functions have return values, people will want an expression syntax to call them inside arguments to other functions. The function call/argument syntax is not well suited for such things. That is a level of complexity I’d prefer not to add to the language.

There’s no such location for a “transpile” to occur in CMake’s architecture. CMake has two separate parsers for the CMake language. The first takes care of comments and the command setup. It is basically just looking for [command-name]([args])[newline] once comments are stripped out. This is why even endif (), continue (), and such things have parentheses. [args] is expanded by ExpandVariableInString and a list splitter which does variable dereferencing and splitting into an argument vector (tracking quoting used for some purposes such as if) to pass to the named command. This parsing setup is pretty baked-in and not feasible to change at this time. It’s the core reason why there is no expression syntax for CMake’s language itself: it’s just not a parser that knows about commands that are not the first thing on a line.