You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
in zsh, if you initialise a function with no name, it's treated as an anonymous function, more here
i think it'd be really cool to have that as a feature here
I think I found a reasonably easy way to add this to the existing code. Please test the patch below, and try to break it.
Only the syntax function { commandlist; } is supported by this patch, so an anonymous function should have all the features of a ksh-style function. The zsh variant () { commandlist; } doesn't make as much sense for ksh because POSIX-style functions don't keep local state (except for positional parameters).
parse.c: Accept the anonymous function syntax; substitute "(anon)" for the missing function name.
xec.c: If the name of a function definition starts with (, assume it's anonymous; allocate a temporary function node on the AST stack, process the function definition as normal, but then immediately execute and unset it.
Found a couple problems. This patch improves namespace handling in xec.c, and disallows anonymous functions within compound assignments (i.e., typeset -T definitions) where they make no sense.
this implementation seems not to include the ability for arguments to actually be passed to the anonymous functions, which zsh allows [and which is a feature i really like about it]
coude you maybe patch that in too?
Yes, that's not implemented in the patch. I've tried to look into how to do it, and it's definitely non-trivial, because it requires changing ksh's whole idea of what a function definition is. So that is going to take me much longer to figure out, if ever.
Plus, that syntax of adding arguments after the } seems really ugly to me. The zsh manual also flags up that it's inconsistent with established shell grammar: “Arguments to the function may be specified as words following the closing brace defining the function, hence if there are none no arguments (other than $0) are set. This is a difference from the way other functions are parsed: normal function definitions may be followed by certain keywords such as else or fi, which will be treated as arguments to anonymous functions, so that a newline or semicolon is needed to force keyword interpretation.”
So, it would require modifying the shell grammar in a more fundamental way and I'm not sure I'm prepared to do that. It's a general rule that keywords after } don't require semicolons to separate them. For example, if true; then { { echo one; echo two; } } fi, on a single line, is valid grammar on all the POSIX shells. Introducing an exception to that carries a high risk of introducing regressions along with it.
I also don't really see the point of arguments to anonymous functions in the first place, because anonymous functions are one-time functions, so any arguments can simply be moved into the function body, either by hardcoding them or by using the set command. For example, the following is exactly equivalent to your example above:
variable=outside
function{typeset variable=inside
set -- this and that
print "I am $variable with arguments $*"
}
print "I am $variable"
Anonymous functions are good for executing a locally scoped block once, for example, if you want to do initialisation without unwanted global side effects. But if an anonymous function is executed multiple times with different arguments (in a loop for example), then it's better off being a normally named function anyway – it's a clearer coding style, and it's more efficient as you avoid redefining the function multiple times.
So, I don't really see why the lack of arguments to anonymous functions is actually a problem.
ig it was because i saw someone using them in alias definitions and using $1 and such, but i suppose a neater thing to do would probably be putting it in a regular named function
these functions do have a use to them outside of that occasionally, though i have more experience in using them in perl, c# and elixir; seeing as this shell was considered on par with perl at some point though, there may be a use for it if you code ksh93 like it was in fact perl?
Activity
McDutchie commentedon May 21, 2026
I think I found a reasonably easy way to add this to the existing code. Please test the patch below, and try to break it.
Only the syntax
function { commandlist; }is supported by this patch, so an anonymous function should have all the features of a ksh-style function. The zsh variant() { commandlist; }doesn't make as much sense for ksh because POSIX-style functions don't keep local state (except for positional parameters).(, assume it's anonymous; allocate a temporary function node on the AST stack, process the function definition as normal, but then immediately execute and unset it.Patch version 1
McDutchie commentedon May 22, 2026
Found a couple problems. This patch improves namespace handling in xec.c, and disallows anonymous functions within compound assignments (i.e.,
typeset -Tdefinitions) where they make no sense.Patch version 2
tungstengmd commentedon May 22, 2026
i'll add the patch by the time i get to my computer hopefully!
tungstengmd commentedon May 22, 2026
this implementation seems not to include the ability for arguments to actually be passed to the anonymous functions, which zsh allows [and which is a feature i really like about it]
coude you maybe patch that in too?
tungstengmd commentedon May 22, 2026
testing the example script from the zsh manual [with one change to make it ksh compatible]:
and it doesn't work, due to the inability to pass args :<
McDutchie commentedon May 23, 2026
Yes, that's not implemented in the patch. I've tried to look into how to do it, and it's definitely non-trivial, because it requires changing ksh's whole idea of what a function definition is. So that is going to take me much longer to figure out, if ever.
Plus, that syntax of adding arguments after the
}seems really ugly to me. The zsh manual also flags up that it's inconsistent with established shell grammar: “Arguments to the function may be specified as words following the closing brace defining the function, hence if there are none no arguments (other than $0) are set. This is a difference from the way other functions are parsed: normal function definitions may be followed by certain keywords such aselseorfi, which will be treated as arguments to anonymous functions, so that a newline or semicolon is needed to force keyword interpretation.”So, it would require modifying the shell grammar in a more fundamental way and I'm not sure I'm prepared to do that. It's a general rule that keywords after
}don't require semicolons to separate them. For example,if true; then { { echo one; echo two; } } fi, on a single line, is valid grammar on all the POSIX shells. Introducing an exception to that carries a high risk of introducing regressions along with it.I also don't really see the point of arguments to anonymous functions in the first place, because anonymous functions are one-time functions, so any arguments can simply be moved into the function body, either by hardcoding them or by using the
setcommand. For example, the following is exactly equivalent to your example above:Anonymous functions are good for executing a locally scoped block once, for example, if you want to do initialisation without unwanted global side effects. But if an anonymous function is executed multiple times with different arguments (in a loop for example), then it's better off being a normally named function anyway – it's a clearer coding style, and it's more efficient as you avoid redefining the function multiple times.
So, I don't really see why the lack of arguments to anonymous functions is actually a problem.
tungstengmd commentedon May 23, 2026
ig it was because i saw someone using them in alias definitions and using $1 and such, but i suppose a neater thing to do would probably be putting it in a regular named function
these functions do have a use to them outside of that occasionally, though i have more experience in using them in perl, c# and elixir; seeing as this shell was considered on par with perl at some point though, there may be a use for it if you code ksh93 like it was in fact perl?