Declined Multi-line UDFs

May 20, 2008
10,498
77
Syracuse, NY, USA
Multi-line user-defined functions would be nice ... perhaps in libraries (?).

Code:
@my_function {
rem commands
rem ...
rem need a way to specify the value of the function call
}
Here's a rather clumsy way of using a library function (or alias?, or BTM?) to mimmick a UDF without any temp files. These aren't the best of examples but I hope they make a point.

Code:
v:\> function udf
%@exec[@%$]%_this

v:\> library /f factorial
factorial {
set _this=1
do i=2 to %1
set /a _this*=%i
enddo
}

v:\> library /f ncr
ncr {
set _this=%@eval[%@udf[factorial %1] / %@udf[factorial %2] / %@udf[factorial %@eval[%1-%2]]]
}

v:\> echo %@udf[factorial 7]
5040

v:\> echo %@udf[ncr 6 2]
15
 

samintz

Scott Mintz
May 20, 2008
1,409
13
Solon, OH, USA
I'm not understanding. What's different between a FUNCTION and a LIBRARY function? Why is one more advantageous over the other?
 
May 20, 2008
10,498
77
Syracuse, NY, USA
I'm not understanding. What's different between a FUNCTION and a LIBRARY function? Why is one more advantageous over the other?
I think "library function" is unfortunate terminology. To me, the things currently usable in libraries are more like aliases (of even BTM files) ... they don't "have values" ... they do things. A function is an expression (like %@inc[5]) that is automatically replaced by its value.
 

samintz

Scott Mintz
May 20, 2008
1,409
13
Solon, OH, USA
Ahh. I get it. You want to be able to use a "library function" in an expression instead of as a command. Did you want the definition to be multi-line or the invocation to be multi-line or both? e.g.
Code:
function  myfunc = {
...
}
echo @myfunc(
...
)
 

samintz

Scott Mintz
May 20, 2008
1,409
13
Solon, OH, USA
I did this fairly easily:
Code:
library /f factorial
factorial {
setlocal
set _this=1
do i=2 to %1
  set /a _this*=%i
enddo
echo %_this
endlocal
}
function factorial=`%@execstr[factorial %1]`

factorial 6
720

echo %@factorial[6]
720
 
May 20, 2008
10,498
77
Syracuse, NY, USA
Ahh. I get it. You want to be able to use a "library function" in an expression instead of as a command. Did you want the definition to be multi-line or the invocation to be multi-line or both?
I want the definition to be multi-line. That can't be done now without jumping through some hoops.
 
May 20, 2008
10,498
77
Syracuse, NY, USA
See what a difference @EXECSTR makes:
Code:
v:\> function factorial
%@execstr[factorial %1]

v:\> library /f factorial
factorial {
set _this=1
do i=2 to %1
set /a _this*=%i
enddo
echo %_this
}

v:\> timer & do i=1 to 1000 ( echo %@factorial[6] > nul ) & timer
Timer 1 on: 17:02:52
Timer 1 off: 17:03:23  Elapsed: 0:00:31.25
Code:
v:\> function factorial
%@exec[@factorial %1]%_this

v:\> library /f factorial
factorial {
set _this=1
do i=2 to %1
set /a _this*=%i
enddo
}

v:\> timer & do i=1 to 1000 ( echo %@factorial[6] > nul ) & timer
Timer 1 on: 17:08:12
Timer 1 off: 17:08:14  Elapsed: 0:00:01.84
 
May 20, 2008
10,498
77
Syracuse, NY, USA
That's a pretty substantial difference. How does the function delay the expansion of %_this?
That's just normal behavior. There are two expressions in %@exec[@factorial %1]%_this ... evaluated left to right. After %@exec[@factorial %1] is evaluated (empty string), _this is set.
 

samintz

Scott Mintz
May 20, 2008
1,409
13
Solon, OH, USA
That's a clever hack too. But to your original point, you need 3 things to make it work:
1) A library function or BTM file
2) a FUNCTION that invokes the LIBRARY function
3) a variable that holds the output of the LIBRARY function.
 
May 20, 2008
10,498
77
Syracuse, NY, USA
That's a clever hack too. But to your original point, you need 3 things to make it work:
1) A library function or BTM file
2) a FUNCTION that invokes the LIBRARY function
3) a variable that holds the output of the LIBRARY function.
Yup, it was just a hack. I'd like more elegant support for multi-line user-defined functions. It seems a reasonable enhancement of the library mechanism.
 
  • Like
Reactions: samintz