Re: function definition syntax

From: Dan Mercer (dmercer_at_mn.rr.com)
Date: 02/25/04


Date: Wed, 25 Feb 2004 16:26:58 GMT


"Chris F.A. Johnson" <c.fa.johnson@rogers.com> wrote in message news:c1grag$1gtkbj$1@ID-210011.news.uni-berlin.de...
>: >: > Unless you want a recursive function, which cannot be done with
: >: >: > POSIX functions. Or you want to IFS parse without having to save
: >: >: > and restore functions. Or unless you use dtksh. Or you want to use
: >: >: > getopts. Or basically do anything that isn't *** simple.
: >: >:
: >: >: I have NEVER used the first syntax, and yes, I have written
: >: >: recursive functions.
: >: >
: >: > So what did you do for saving the local environment - for saving local variables.
: >:
: >: Put it in an external script, or call the function in a subshell:
: >
: > In which case it might as well be a separate script - you don't need a function.
: > You only need a function if you want to execute in the current process.
: > Some of us old folks remember a time when the performance penalty for
: > creating new processes was severe.
: >
: > Also, if you are going to go into any depth with your recursion, you will
: > rapidly run out of processes.
:
: True; recursion is rarely the answer, and when it is, a shell is
: rarely the best language for it.

But with ksh it is an option and a powerful one at that.

:
: >: myfunc() {
: >:
: >: ( myfunc args )
: >:
: >: ## OR:
: >:
: >: var=`myfunc args`
: >: }
: >:
: >: That's much more reliable than having to remember which syntax
: >: you used to define the function.
: >
: > I think it's much easier to just use the "function" keyword - then you don't have to
: > remember.
:
: And just what does that do?

Imposes Korn functionality.

:
:
: >: Often, the reason for using a function instead of an external
: >: script is to have it modify variables in the current process, so
: >: always using Korn syntax is not an option. Always using POSIX
: >: syntax is.
: >
: > What? When you want to modify a variable globally, you can do so
: > without any extra effort. Variables are automatically global (except for
: > OPTIND) - you have to use typeset to make them local.
:
: Then what's the point of the function keyword? You can use typeset
: without it.

In ksh93 and possibly in posix conforming ksh88 (which I've heard exists
but never used) typeset in a POSIX function DOES NOT limit the scope
of the variable. It merely sets the type.

:
: I think perhaps we are talking about different things. The
: question I was answering was: "What is the difference between the
: two styles of function definition."

That is a fundamental difference, along with local traps and $0 being set to
function name. OPTIND and LINENO are also local to the function
(LINENO being the line being executed. This can be slightly confusing
in an inline function, but in an externally defined function located by
FPATH, the only meaningful signifier.)
:
: > With ksh93 you get namerefs. My ksh93 function libraries are passed the
: > name of the return variable:
: >
: > function substr
: > {
: > # Format: substr RETVAR STRING START [SPAN
: > # e.g substr TAIL "tiger by the tail" -4 4
: > typeset -n RETVAR=${1:?}
: > ...
: > RETVAR=$tail
: > }
: >
: > Of course, the same can be done with ksh88, you just have to use
: > eval
: >
: > eval $RETVAR='$tail'
: >
: >:
: >: Using POSIX syntax I can choose which I want, when I want. I have
: >: functions that need both behaviours.
: >:
: >: >: I often IFS parse in a function without having to save and restore
: >: >: functions.
: >: >
: >: > That was a brain fart - I meant without having to save and restore
: >: > IFS - the restoration of IFS being the gotcha, since it inevitably
: >: > gets screwed up (;-)
: >:
: >: I've never had it screw up.
: >
: > Lucky you. And lucky for your employer if the person maintaining your
: > scripts while you're on vacation or have moved on is smart enough to
: > not overlook restoring IFS.
: >
: > I came back from vacation once and was told "Your script is broken",
: > only to find out that the person covering for me had IMPROVED my
: > script (without checking it out of RCS or going through any of the correct
: > procedures). I wasted a day looking through the official script and trying
: > to get it to break on a test box before checking to see if it matched
: > the production script. He sandwiched a routine in just prior to the
: > restoration of IFS - which made the script blow up in delightfully
: > unpredictable ways. That's when I started IFS splitting only
: > in functions.
: >
: >:
: >: On every POSIX shell I've seen, though I don't thik it's a POSIX
: >: feature, variables can be made local to a function. It's one of
: >: the few non-POSIX features that is common enough to use when it
: >: makes sense. Not that it's hard to save and restore the value of
: >: IFS without it.

Not with portable syntax. In fact, bash's behavior conflicts with
ksh93's (though not ksh88). If anyone has access to HP-UX
please run the following and tell me the results:

    $ sh -c 'tt() { typeset a=b;echo a=$a; };a=z;echo a=$a;tt;echo a=$a'

: >:
: >: >: I have never had a problem using getopts in a function.
: >: >:
: >: >: Can you come up with any examples to prove your points?
: >: >
: >: > Building a library using FPATH (at least in ksh93) would be impossible
: >: > with POSIX syntax - it would suffer from terminal name pollution.
: >:
: >: What's FPATH? I've never used it.
: >
: > The FPATH points to directories containing script files that become
: > undefined functions. It allows you to build libraries without having to
: > explicitly sort files.
: >:
: >: .......
: >: After looking at the ksh man page, I don't see that it offers
: >: anything useful that I cannot do at least as efficiently without
: >: it.
: >
: > You've obviously never programmed in dtksh.
: >
: >:
: >: And it would have to be a significant improvement to make it
: >: worth using a non-portable feature.
: >
: > Since there's no truly portable way to do anything non-trivial, that really
: > shouldn't be a concern. You know, like print
: >
: > -n is an option that will drive you nuts
: >
: > to stdout.
: >
: >:
: >: > No matter how clever you got with your naming convention, inevitably
: >: > you would corrupt either a function's variable or a main line variable.
: >: > Not a problem with Korn style functions and typeset.
: >:
: >: I've never had a problem without Korn style functions.
: >:
: >: But that's only an argument for taking care in naming variables,
: >: not for using a non-standard syntax.
: >
: > Try that with a library of 400 functions. Again, trivial programming requires
: > trivial solutions.
: >:
: >: > I don't believe in "portable" shell programming - I think there's just too
: >: > much differentiation between shells and systems to do it correctly 100%
: >: > of the time.
: >:
: >: Much of that has nothing to do with the shell.
: >:
: >: Using POSIX-conforming scripts in a POSIX environment, it's easy
: >: almost all the time. The only excuse for using non-conforming
: >: scripts is when there is no efficient way to do it without.
: >:
: >: The Korn style of function definition adds nothing that cannot be
: >: achieved by other means without loss of efficiency.
: >:
: >: > Try programming in a Lindows environment, for instance.
: >: > The more power in the shell, the less you have to rely on external programs
: >: > that may not exist (like on Lindows) or may behave differently (like SysV find
: >: > vs GNU find).
: >:
: >: Then you should not depend on either behaviour.
: >:
: >: There's nothing in ksh (or any other shell) that will solve the
: >: problem (if it is one) of different versions of find (or other
: >: external commands).
: >
: > Except you may not need find or grep or sed with ksh.
:
: There is nothing specific to ksh that removes the need for find or
: grep.

Extended pattern globbing that eliminates the need for trivial greps.
:
: >: I've never used Lindows, but I doubt that there's much, if
: >: anything, missing that's standard.
: >
: > Lindows, at least the Lindows 3.0 I got, comes with NOTHING
: > STANDARD - not even grep. It was a major effort to get it
: > configured to a useful (UNIX) environment.
:
: Then it's a broken distro. I haven't heard much good about it.

It's not intended as a complete Linux package - it's intended as a desktop
replacement for Windows. It is becoming more popular overseas than
here.

Dan Mercer

:
: --
: Chris F.A. Johnson http://cfaj.freeshell.org
: ===================================================================
: My code (if any) in this post is copyright 2004, Chris F.A. Johnson
: and may be copied under the terms of the GNU General Public License


Loading