scratch/content/html/en/blog/Higher-order-function-in-zsh.md
2011-09-28 17:45:28 +02:00

2.9 KiB

isHidden menupriority kind created_at title author_name author_uri
false 1 article 2011-09-27T15:15:23+02:00 Higher order function in zsh Yann Esposito yannesposito.com

<%= blogimage("main.jpg","Title image") %>

begindiv(intro)

<%= tldr %> some simple implementation of higher order function for zsh.

enddiv

# for each directory in projects dir for toProject in /path/to/projects/*(/N); do # toProject is /path/to/projects/foo # project become foo (:t for tail) project=${toProject:t} for toResource in $toProject/resources/*.gif(.N); do convert $toResource ${toResource:r}.png \rm -f $toResource done done gif_to_png() { convert $1 ${1:r}.png && \rm -f $1 } handle_resources() { map gif_to_png $1/resources/*.gif(.N) } map handle_resources /path/to/projects/*(/N)

Before ⇒

for toProject in Projects/*; do project=$toProject:t if print -- project | grep -v s >/dev/null then print $project for toResource in $toProject/*(.N); do if print -- ${toResource:t} | grep $project >/dev/null; then print -- "X $toResource" fi done fi done

After ⇒

contain_no_s() { print $1 | grep -v s }

function verify_file_name {
local project=$1:t contains_project_name() { print $1:t | grep $project } map "print -- X" $(filter contains_project_name $1/*(.N)) }

map show_project_matchin_file $( filter contain_no_s Projects/* )

Also, the first verstion is a bit easier to read. But the second one is clearly far superior in architecture. Why?

#!/usr/bin/env zsh

Provide higer-order functions

usage:

$ foo(){print "x: $1"}

$ map foo a b c d

x: a

x: b

x: c

x: d

function map { local func_name=$1 shift for elem in $@; print -- $(eval $func_name $elem) }

$ bar() { print $(($1 + $2)) }

$ fold bar 0 1 2 3 4 5

15

-- but also

$ fold bar 0 $( seq 1 100 )

function fold { if (($#<2)) { print -- "ERROR fold use at least 2 arguments" >&2 return 1 } if (($#<3)) { print -- $2 return 0 } else { local acc local right local func_name=$1 local init_value=$2 local first_value=$3 shift 3 right=$( fold $func_name $init_value $@ ) acc=$( eval "$func_name $first_value $right" ) print -- $acc return 0 } }

usage:

$ baz() { print $1 | grep baz }

$ filter baz titi bazaar biz

bazaar

function filter { local predicate=$1 local result typeset -a result shift for elem in $@; do if eval $predicate $elem >/dev/null; then result=( $result $elem ) fi done print $result }