Syntax: array=(1 2) array[0]=3 push ${array} 4 # Instead of Bash's ${array[@]} or ${array[*]}: string=$(join ', ' ${array}) value=${array[0]} unset array[0] unset array array=(1 (2 3) 4) array=(one=1 two=2) Compiles to: __a_new __r0 1 2 array=${__r0} __a_set array 0 3 push ${array} 4 string=$(join ', ' ${array}) __a_get __r0 array 0 value=${__r0} __a_unset array 0 __a_new __r0 2 3 __a_new __r1 1 ${__r0} 4 array=${__r1} __a_new __r0 one=1 two=2 array=${__r0} eshrt functions: __a_n=0 # malloc-like, how do we free? __a_new() { __r=${1} shift 1 __a=__a${__a_n} __a_n=$((${__a_n} + 1)) __l=0 for __v in "${@}"; do case ${__v} in *=*) __k=${__v%%=*} __v=${__v#*=} ;; *) __k=${__l} ;; esac eval "${__a}__${__k}=\${__v}" __l=$((${__l} + 1)) done eval "${__a}_l=\${__l}" eval "${__r}=\${__a} } __a_set() { __a=${1} __k=${2} __v=${3} if ! eval "\${${__a}__${__k}+:}"; then eval "${__a}_l=\$((\${${__a}_l} + 1))" fi eval "${__a}__${__k}=\${__v}" } __a_get() { __r=${1} __a=${2} __k=${3} eval "${__r}=\${${__a}__${__k}}" } __a_unset() { } libesh functions: push() { __a=${1} __v=${2} eval "__l=\${${__a}_l}" if ! eval "\${${__a}__${__l}+:}"; then eval "${__a}__${__l}=\${__v}" eval "${__a}_l=\$((\${__l} + 1))" fi } split() { } join() { } pop, shift (name collision), unshift, slice, keys, etc.