Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: min() max() math functions (was: Re: Feature request (@M):# with context matches)



Bart Schaefer wrote on Sat, Feb 06, 2016 at 17:00:40 -0800:
> On Feb 7, 12:22am, Daniel Shahaf wrote:
> } Subject: min() max() math functions (was: Re: Feature request (@M):# with 
> }
> } I've wished a number of times for a built-in max() math function
> 
> You provided such nice implementations with "functions -M".  Why is it
> important that they be built-ins?
> 
> Generally speaking we've done builtins only where (a) there is a library
> implementation easily linked with or (b) the results of C type coercion
> are at odds with the desired behavior of shell numeric-typed parameters.

I said "built-in" but I meant in zsh/mathfunc, with all other math
functions, for consistency.

I suppose I could package them as an autoload.  Patch below. 

I changed 'while' to 'for' to avoid unnecessary shifts.
(The functions would otherwise be O(N²) in the number of arguments)

How do I shield zmathfunc against callers that unsetopt functionargzero?
.
    % autoload zmathfunc && zmathfunc
    % echo $((max(42,43)))
    43
    % unsetopt functionargzero
    % echo $((max(42,43)))      # now $0 is /bin/zsh, no 'case' branch matches, so $argv[1] is returned
    42
.
I guess I'll have to drop the the multifuncdef usage altogether?

Cheers,

Daniel

diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 07a5eb0..11678e5 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -3796,6 +3796,23 @@ enditem()
 
 See the comments in the function for a few extra tips.
 )
+findex(max)
+findex(min)
+findex(sum)
+findex(zmathfunc)
+xitem(tt(min+LPAR())var(arg)tt(, ...+RPAR()))
+xitem(tt(max+LPAR())var(arg)tt(, ...+RPAR()))
+xitem(tt(sum+LPAR())var(arg)tt(, ...+RPAR()))
+item(tt(zmathfunc))(
+Autoloading tt(zmathfunc) defines the three mathematical functions
+tt(min), tt(max), and tt(sum).  The functions tt(min) and tt(max) take
+one or more arguments.  The function tt(sum) takes zero or more arguments.
+Arguments can be of different types (ints and floats).
+
+Not to be confused with the tt(zsh/mathfunc) module, described in
+ifzman(the section `The zsh/mathfunc Module' in zmanref(zshmodules))\
+ifnzman(noderef(The zsh/mathfunc Module)).
+)
 findex(zmathfuncdef)
 item(tt(zmathfuncdef) [ var(mathfunc) [ var(body) ] ])(
 A convenient front end to tt(functions -M).
diff --git a/Doc/Zsh/mod_mathfunc.yo b/Doc/Zsh/mod_mathfunc.yo
index 5239da5..af1abcc 100644
--- a/Doc/Zsh/mod_mathfunc.yo
+++ b/Doc/Zsh/mod_mathfunc.yo
@@ -36,6 +36,11 @@ that it is therefore only useful immediately after a call to tt(gamma) or
 tt(lgamma).  Note also that `tt(signgam+LPAR()RPAR())' and `tt(signgam)' are
 distinct expressions.
 
+The functions tt(min), tt(max), and tt(sum) are defined not in this module
+but in the tt(zmathfunc) autoloadable function, described in
+ifzman(the section `Mathematical Functions' in zmanref(zshcontrib))\
+ifnzman(noderef(Mathematical Functions)).
+
 The following functions take two floating point arguments: tt(copysign),
 tt(fmod), tt(hypot), tt(nextafter).
 
diff --git a/Functions/Math/.distfiles b/Functions/Math/.distfiles
new file mode 100644
index 0000000..f03668b
--- /dev/null
+++ b/Functions/Math/.distfiles
@@ -0,0 +1,2 @@
+DISTFILES_SRC='
+'
diff --git a/Functions/Math/zmathfunc b/Functions/Math/zmathfunc
new file mode 100644
index 0000000..198454d
--- /dev/null
+++ b/Functions/Math/zmathfunc
@@ -0,0 +1,29 @@
+#autoload
+
+setopt localoptions multifuncdef
+
+zsh_math_func_min zsh_math_func_max() {
+  local result=$1
+  shift
+  local arg
+  for arg ; do
+    case $0 in
+      (*max) (( $arg > result )) && result=$arg;;
+      (*min) (( $arg < result )) && result=$arg;;
+    esac
+  done
+  (( result )) # return
+}
+functions -M max 1 -1 zsh_math_func_max # at least one argument
+functions -M min 1 -1 zsh_math_func_min # at least one argument
+
+zsh_math_func_sum() {
+  local sum
+  local arg
+  for arg ; do
+    (( sum += $arg ))
+  done
+  (( sum ))
+}
+functions -M sum 0 -1 zsh_math_func_sum
+
diff --git a/Src/zsh.mdd b/Src/zsh.mdd
index 86dd588..324435d 100644
--- a/Src/zsh.mdd
+++ b/Src/zsh.mdd
@@ -2,7 +2,7 @@ name=zsh/main
 link=static
 load=yes
 # load=static should replace use of alwayslink
-functions='Functions/Chpwd/* Functions/Exceptions/* Functions/Misc/* Functions/MIME/* Functions/Prompts/* Functions/VCS_Info/* Functions/VCS_Info/Backends/*'
+functions='Functions/Chpwd/* Functions/Exceptions/* Functions/Math/* Functions/Misc/* Functions/MIME/* Functions/Prompts/* Functions/VCS_Info/* Functions/VCS_Info/Backends/*'
 
 nozshdep=1
 alwayslink=1



Messages sorted by: Reverse Date, Date, Thread, Author