The unset builtin, when invoked without an option, should first try to unset the variable (or array element) specified by its arguments, and then fall back to trying to remove the function definition for the function that has the name specified by the argument if it exists.
bash-5.1$ declare -f a; declare -p a bash: declare: a: not found bash-5.1$ a=hi; declare -f a; declare -p a declare -- a="hi" bash-5.1$ unset a; declare -f a; declare -p a bash: declare: a: not found bash-5.1$ declare -f a; declare -p a bash: declare: a: not found bash-5.1$ a () { echo ;}; a=hi; declare -f a; declare -p a a () { echo } declare -- a="hi" bash-5.1$ unset a; declare -f a; declare -p a bash: declare: a: not found a () { echo } bash-5.1$ declare -f a; declare -p a bash: declare: a: not found bash-5.1$ a () { echo ;}; declare -f a; declare -p a a () { echo } bash: declare: a: not found bash-5.1$ unset a; declare -f a; declare -p a bash: declare: a: not found The -v option can be used to tell the unset builtin to only unset variables (and array elements), and not fall back to removing function definitions. The -f option can be used to tell the unset builtin to only remove function definitions directly. It seems that, if an operand of unset is in the form of validvariablename[something], the unset builtin invoked without options, will only attempt to delete an array element specified by that argument, and will not fall back to removing a function named like the argument (as if the -v option was passed only for that argument). You must specify the -f option to delete a function with a name in that form. bash-5.1$ a=([1]=2 3 4); a[] () { echo ;}; a[0] () { : ;} bash-5.1$ declare -p a; declare -f 'a[]' 'a[0]' declare -a a=([1]="2" [2]="3" [3]="4") a[] () { echo } a[0] () { : } bash-5.1$ unset 'a[]' 'a[0]' 'a[1]' bash-5.1$ declare -p a; declare -f 'a[]' 'a[0]' declare -a a=([2]="3" [3]="4") a[0] () { : } bash-5.1$ unset -f 'a[0]' bash-5.1$ declare -p a; declare -f 'a[]' 'a[0]' declare -a a=([2]="3" [3]="4") Same result if the `a' variable does not exist. bash-5.1$ a[0] () { echo;} bash-5.1$ declare -p a; declare -f 'a[0]' bash: declare: a: not found a[0] () { echo } bash-5.1$ unset 'a[0]' bash-5.1$ declare -p a; declare -f 'a[0]' bash: declare: a: not found a[0] () { echo } bash-5.1$ unset -f 'a[0]' bash: declare: a: not found I think that this is a bug, and that bash's unset builtin should fall back to trying to remove the function named "a[0]" in those cases. Cheers. emanuele6