Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Procedure inside procedure help

1,226 views
Skip to first unread message

Nhuyen

unread,
Aug 18, 2001, 7:58:20 AM8/18/01
to

Hello all
Can I write procedure inside procedure (please give an example). What about
scope of variable....
Thank you for your help.
Nhuyen


http://www.zfree.co.nz

J French

unread,
Aug 18, 2001, 9:39:01 AM8/18/01
to
Don't do it - it is both pointless and a complication for people
reading your code.

From your previous postings, it does not look like a 'school
assignment' - so just think again - run one up for fun - but do not
write complicted 'release code'.

Dirk Claessens

unread,
Aug 18, 2001, 10:52:13 AM8/18/01
to
J French <je...@iss.u-net.com> schreef in berichtnieuws
3b7e6e7a...@news.u-net.com...

> Don't do it - it is both pointless and a complication for people
> reading your code.

I disagree. ( but I'm not religious about it <g> )
Local procedures/functions _can_ dramatically simplify code.

{------------------}
function DoSomething( x,y,z,w: double ): double;
{---------------------}
procedure DoCalculation(Par:double)
var
Temp: double;
begin
Temp := BlahBlah(x,y,Par);
<longwinding stuff here >
Result := Blah;
end;

var
Temp: double;
begin
if SomeCondition then
Temp := DoCalculation(z)
else
Temp := DoCalculation(w);
Result := Blah_2(Temp)
end;

-The main code in DoSomething() is crystal clear
-The gory details are all contained in 1 place in DoCalculation()


--
Regards,

Dirk Claessens
---------------------------------------------------------
http://www.claessens16.yucom.be
Attention: All spamshields raised; E-mails will bounce!
---------------------------------------------------------


David C. Ullrich

unread,
Aug 19, 2001, 10:25:12 AM8/19/01
to

But you can achieve that crystal clarity just as well by
using a separate DoCalculation function that's _not_ nested.

Which is not to say that nested functions are bad. But people
often think that calling a nested function will be faster,
and it often turns out that it's actually slower. The only
advantage I see is that it makes it clear that the inner
function is not used elsewhere. I tend to put the "inner"
function immediately before the function that's going to
use it, and make certain it's not included in the implementation
section...

>--
>Regards,
>
>Dirk Claessens
>---------------------------------------------------------
>http://www.claessens16.yucom.be
>Attention: All spamshields raised; E-mails will bounce!
>---------------------------------------------------------
>
>
>
>


David C. Ullrich

VBDis

unread,
Aug 19, 2001, 2:15:59 PM8/19/01
to
Im Artikel <3b7e...@zfree.co.nz>, "Nhuyen" <sonp...@zfree.co.nz> schreibt:

>Can I write procedure inside procedure (please give an example). What about
>scope of variable....

procedure Outer(param: integer);
var shared: integer;

procedure Inner;
begin
shared := param; //both are visible and accessible
end;

var nonshared: integer; //invisible in Inner

begin //body of Outer
Inner;
nonshared := shared;
end;

DoDi

Dirk Claessens

unread,
Aug 19, 2001, 3:03:34 PM8/19/01
to
David C. Ullrich <ull...@math.okstate.edu> schreef in berichtnieuws
3b7fcb6...@nntp.sprynet.com...

> On Sat, 18 Aug 2001 16:52:13 +0200, "Dirk Claessens"
> <will....@back.com> wrote:
>
> >J French <je...@iss.u-net.com> schreef in berichtnieuws
> >3b7e6e7a...@news.u-net.com...
> >> Don't do it - it is both pointless and a complication for people
> >> reading your code.
> >
> >I disagree. ( but I'm not religious about it <g> )
> >Local procedures/functions _can_ dramatically simplify code.
[snipped]

> The only advantage I see is that it makes it clear that the inner
> function is not used elsewhere.

Another advantage- if many parameters must be passed - is that the scope of
the inner procedure is the same as the outer procedure. I tried to emphasize
that in the example.
Of course, if the action of the inner procedure is very general ( say,
adding x to y and take the square root of the result ) it would be better to
place it somewhere in a library unit.

Regards - Dirk


AlanGLLoyd

unread,
Aug 19, 2001, 4:12:22 PM8/19/01
to
In article <3b7e...@zfree.co.nz>, "Nhuyen" <sonp...@zfree.co.nz> writes:

>Hello all
>Can I write procedure inside procedure (please give an example). What about
>scope of variable....
>

Should be used only rarely, for multiple calls within the outer procedure,
access to procedure variables varies according to where placed, and the
sub-procs should be heavily marked for clarity. As ...

procedure Outer(ParamA : integer);
// sub-proc start = = = = = = = = = = = = = = = = = = = = =
procedure InnerOne(ParamB : string);
begin
// cannot access Var1 & Var2
end;
// sub-proc finish= = = = = = = = = = = = = = = = = = = = =
var
Var1 : integer;
Var2 : string;
// sub-proc start = = = = = = = = = = = = = = = = = = = = =
procedure InnerTwo(ParamC : string);
begin
// can access Var1 & Var2
end;
// sub-proc finish= = = = = = = = = = = = = = = = = = = = =
begin
//
// main code of Outer()
//
end;

Alan Lloyd
alang...@aol.com

J French

unread,
Aug 20, 2001, 5:22:56 AM8/20/01
to
I re-iterate my point (yes I know an oxymoron)

Just don't do it.

If you must pass huge numbers of parameters, then do it in a Type.

Unless of course you are writing 'write only' code.

David C. Ullrich

unread,
Aug 20, 2001, 9:18:55 AM8/20/01
to
On Sun, 19 Aug 2001 21:03:34 +0200, "Dirk Claessens"
<will....@back.com> wrote:

>David C. Ullrich <ull...@math.okstate.edu> schreef in berichtnieuws
>3b7fcb6...@nntp.sprynet.com...
>> On Sat, 18 Aug 2001 16:52:13 +0200, "Dirk Claessens"
>> <will....@back.com> wrote:
>>
>> >J French <je...@iss.u-net.com> schreef in berichtnieuws
>> >3b7e6e7a...@news.u-net.com...
>> >> Don't do it - it is both pointless and a complication for people
>> >> reading your code.
>> >
>> >I disagree. ( but I'm not religious about it <g> )
>> >Local procedures/functions _can_ dramatically simplify code.
>[snipped]
>> The only advantage I see is that it makes it clear that the inner
>> function is not used elsewhere.
>
>Another advantage- if many parameters must be passed - is that the scope of
>the inner procedure is the same as the outer procedure. I tried to emphasize
>that in the example.

That's another aspect of it. How is it an advantange? (Try to
read that as an actual question, not an assertion that it's not
an adbatange...)

>Of course, if the action of the inner procedure is very general ( say,
>adding x to y and take the square root of the result ) it would be better to
>place it somewhere in a library unit.
>
>Regards - Dirk
>
>


David C. Ullrich

Bjørge Sæther

unread,
Aug 20, 2001, 2:54:40 PM8/20/01
to
"AlanGLLoyd" <alang...@aol.com> skrev i melding
news:20010819161222...@nso-fq.aol.com...

> In article <3b7e...@zfree.co.nz>, "Nhuyen" <sonp...@zfree.co.nz> writes:
>
> >Hello all
> >Can I write procedure inside procedure (please give an example). What
about
> >scope of variable....
> >
>
> Should be used only rarely, for multiple calls within the outer procedure,
> access to procedure variables varies according to where placed, and the
> sub-procs should be heavily marked for clarity. As ...

There are different reasons for using a subroutine - breaking up code to
increase readability or the more usual reason for placing a piece of code in
a routine: reuse.
I kind of wonder when I see subroutines are not concidered "good latin".
Routines contining subroutines are sometimes hard to read, but that's
normally more or less unavoidable (complex routines). I'd say: place it
locally whenever it seems like the simplest, most readable solution. When
such a routine has absolutely no meaning outside the calling routine, it'd
better be placed locally.

--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorge@takethisaway_itte.no (remve the obvious)


Bjørge Sæther

unread,
Aug 20, 2001, 3:10:22 PM8/20/01
to
"David C. Ullrich" <ull...@math.okstate.edu> skrev i melding
news:3b810df...@nntp.sprynet.com...

> On Sun, 19 Aug 2001 21:03:34 +0200, "Dirk Claessens"
> <will....@back.com> wrote:
> >Another advantage- if many parameters must be passed - is that the scope
of
> >the inner procedure is the same as the outer procedure. I tried to
emphasize
> >that in the example.
>
> That's another aspect of it. How is it an advantange? (Try to
> read that as an actual question, not an assertion that it's not
> an adbatange...)

When quite a large stack is built, it's of course an advantage to be able to
access all the data without duplicating a lot of these data. It also saves
some typing....

Bjørge Sæther

unread,
Aug 20, 2001, 3:01:33 PM8/20/01
to
"J French" <je...@iss.u-net.com> skrev i melding
news:3b80d4f2...@news.u-net.com...

> I re-iterate my point (yes I know an oxymoron)
>
> Just don't do it.

Redicolous. It's like declaring local variables as object fields or global
variables. Code that makes no sense elsewhere may very well be placed locally
for clarity. Remember, a routinde declared outside the calling routine is
callable from anywhere lower down in the unit. The routine shows up when
using Code Completion, for one.

I really wonder where this idea is coming from ?

J French

unread,
Aug 21, 2001, 1:06:56 AM8/21/01
to
On Mon, 20 Aug 2001 21:01:33 +0200, "Bjørge Sæther"
<REMOVE_bsaether@THIS_online.no> wrote:

>"J French" <je...@iss.u-net.com> skrev i melding
>news:3b80d4f2...@news.u-net.com...
>> I re-iterate my point (yes I know an oxymoron)
>>
>> Just don't do it.
>
>Redicolous. It's like declaring local variables as object fields or global
>variables. Code that makes no sense elsewhere may very well be placed locally
>for clarity. Remember, a routinde declared outside the calling routine is
>callable from anywhere lower down in the unit. The routine shows up when
>using Code Completion, for one.

Ok, let's put it differently - one day, possibly six months, maybe six
years later, you or someone else will have to re-visit your code.

Let us assume that it is you - do you want to make life hard for
yourself ? Or do you want to write simple, effective, straightforward
code ?

IMO nested procedures are a way of obscuring functionality.

J French

unread,
Aug 21, 2001, 1:06:56 AM8/21/01
to
On Mon, 20 Aug 2001 20:54:40 +0200, "Bjørge Sæther"
<REMOVE_bsaether@THIS_online.no> wrote:


>There are different reasons for using a subroutine - breaking up code to
>increase readability or the more usual reason for placing a piece of code in
>a routine: reuse.
>I kind of wonder when I see subroutines are not concidered "good latin".
>Routines contining subroutines are sometimes hard to read, but that's
>normally more or less unavoidable (complex routines). I'd say: place it
>locally whenever it seems like the simplest, most readable solution. When
>such a routine has absolutely no meaning outside the calling routine, it'd
>better be placed locally.
>

We are talking about *nested* subroutines - not subroutines in
general.

Bjørge Sæther

unread,
Aug 21, 2001, 3:10:59 AM8/21/01
to
"J French" <je...@iss.u-net.com> skrev i melding
news:3b81e800...@news.u-net.com...

> On Mon, 20 Aug 2001 21:01:33 +0200, "Bjørge Sæther"
> <REMOVE_bsaether@THIS_online.no> wrote:
>
> >"J French" <je...@iss.u-net.com> skrev i melding
> >news:3b80d4f2...@news.u-net.com...
> >> I re-iterate my point (yes I know an oxymoron)
> >>
> >> Just don't do it.
> >
> >Redicolous. It's like declaring local variables as object fields or global
> >variables. Code that makes no sense elsewhere may very well be placed
locally
> >for clarity. Remember, a routinde declared outside the calling routine is
> >callable from anywhere lower down in the unit. The routine shows up when
> >using Code Completion, for one.
> Ok, let's put it differently - one day, possibly six months, maybe six
> years later, you or someone else will have to re-visit your code.
>
> Let us assume that it is you - do you want to make life hard for
> yourself ? Or do you want to write simple, effective, straightforward
> code ?

What conciderations do you believe are the most important to me ? I'd tell
you - I sometimes put 10 lines of code in a local routine FOR CLARITY ONLY !
It's a way of "black-boxing" to me. It's local, and its "singular". Let noone
else see it.
I do of course understand that one can find example of horrible coding with
local routines. As long as they work, you'll not have to rewrite them for
reuse, a process normally piece by piece "shaping up" an application's code.
A big chance that "singular" code is of poorer quality than core
functionality. While every step that extracts the general parts of code into
reusable routines is a good one, I think abandoning local routines is simply
not a good piece of advice.

I came to think of a period in my country (around 1985-95) where the
"driving-schools" (don't know the English word for it) learning motorbike
candidats to use only the front brake. While everyone understands this in a
pedagogical perspective, it's absolutely no doubt that applying the rear brak
e appropriately reduces stopping distance with maybe 10-20%. It's mixing of
levels when you let people finish their driving education only having heard
the "newbie teaching version".
I get the same feeling when someone is trying to tell us local routines are
bad. It's just not right, even if I could tell a newbie not to do it "for
now".

> IMO nested procedures are a way of obscuring functionality.
>
> >
> >I really wonder where this idea is coming from ?

I still wonder if this is down the same road as "don't use GoTo" or "don't
let a function create an object" - some model or theory abandoning local
routines ? I am self-thought (well, until I joined the NG's, at least), and
never learned the "right way". When I revisit code written 6 years ago, I do
of course find local routines that I today would place otherwhere, but
definately not all. A local routine is the self-explainatory way of giving a
certain piece of code the perfect scope. Passing references to large
structures of "unfinished" data to an external routine that *must not* be
used for anything but this special case is just not good programming practice
to me.

Bjørge Sæther

unread,
Aug 21, 2001, 3:15:41 AM8/21/01
to
"J French" <je...@iss.u-net.com> skrev i melding
news:3b81e95b...@news.u-net.com...

> On Mon, 20 Aug 2001 20:54:40 +0200, "Bjørge Sæther"
> <REMOVE_bsaether@THIS_online.no> wrote:
>
>
> >There are different reasons for using a subroutine - breaking up code to
> >increase readability or the more usual reason for placing a piece of code
in
> >a routine: reuse.
> >I kind of wonder when I see subroutines are not concidered "good latin".
> >Routines contining subroutines are sometimes hard to read, but that's
> >normally more or less unavoidable (complex routines). I'd say: place it
> >locally whenever it seems like the simplest, most readable solution. When
> >such a routine has absolutely no meaning outside the calling routine, it'd
> >better be placed locally.
> >
> We are talking about *nested* subroutines - not subroutines in
> general.

Me too. Sorry for my unprecise language. I believe the right term is 'local
routine' (a routine placed inside another routine) or 'nested routines' (more
levels of routines inside one "outer" routine) ?

J French

unread,
Aug 21, 2001, 4:41:29 AM8/21/01
to
On Tue, 21 Aug 2001 09:15:41 +0200, "Bjørge Sæther"
<REMOVE_bsaether@THIS_online.no> wrote:

>"J French" <je...@iss.u-net.com> skrev i melding
>news:3b81e95b...@news.u-net.com...
>> On Mon, 20 Aug 2001 20:54:40 +0200, "Bjørge Sæther"
>> <REMOVE_bsaether@THIS_online.no> wrote:
>>
>>
>> >There are different reasons for using a subroutine - breaking up code to
>> >increase readability or the more usual reason for placing a piece of code
>in
>> >a routine: reuse.
>> >I kind of wonder when I see subroutines are not concidered "good latin".
>> >Routines contining subroutines are sometimes hard to read, but that's
>> >normally more or less unavoidable (complex routines). I'd say: place it
>> >locally whenever it seems like the simplest, most readable solution. When
>> >such a routine has absolutely no meaning outside the calling routine, it'd
>> >better be placed locally.
>> >
>> We are talking about *nested* subroutines - not subroutines in
>> general.
>
>Me too. Sorry for my unprecise language. I believe the right term is 'local
>routine' (a routine placed inside another routine) or 'nested routines' (more
>levels of routines inside one "outer" routine) ?
>

I think we are talking at cross purposes - my definition of 'Local' is
something that you do not want anything else to know about outside,
say the Unit. These are, of course invaluable.

One thing I picked up from an old time Mainframe programmer is a
convention of prefixing Function/Procedure names with LS, GS, US to
indicate *desired* scope - (Local, Global (within App), Universal).

Nested procedures make me profoundly nervous - IMO they reduce clarity
and give few benefits. One might conceivably claw back a few clock
cycles, but even then ... well.

It is *nested* routines that are dodgy, the concept of avoiding
*local* routines is well ... I hesitate to say 'bad coding' ... but
let's just say 'shooting oneself in the foot'.

With reference to your other post, I totally agree with 'Black Boxing'
and 'for clarity only' - also that passing irrelevant parameters is
just confusing things - and people that yelp about GoTo probably do
not understand what their code is converted into.

It is slightly embarrassing that I should have been 'unclear'.

AlanGLLoyd

unread,
Aug 21, 2001, 5:31:15 AM8/21/01
to
In article <g2fg7.2711$hc7....@news1.oke.nextra.no>, "Bjørge Sæther"
<REMOVE_bsaether@THIS_online.no> writes:

>There are different reasons for using a subroutine - breaking up code to
>increase readability or the more usual reason for placing a piece of code in
>a routine: reuse.
>I kind of wonder when I see subroutines are not concidered "good latin".
>Routines contining subroutines are sometimes hard to read, but that's
>normally more or less unavoidable (complex routines). I'd say: place it
>locally whenever it seems like the simplest, most readable solution. When
>such a routine has absolutely no meaning outside the calling routine, it'd
>better be placed locally.

Programming is partly art, as well as skill, and there really are few places
where absolutes can be made (for David's benefit I grant that AVs are one place
<gg>). I don't believe an absolute ban on sub-procs can be supported. Bjorge's
comment that "When such a routine has absolutely no meaning outside the calling
routine, it'd
better be placed locally." cannot (I think) be supported at all if by "locally"
he meant as a sub-proc. A high proportion of routines called from within
another routine have no meaning outside, and are called only once form a single
routine, usually this is done for higher level clarity.

My approach to sub-procs are ...

They should be less than an IDE page (they do obscure clarity to some extent
and shorter ones indented and with comment line delimiters help).

They should be significantly shorter than the enclosing proc, although I have
seen an enclosing proc of a few lines in Delphi where the sub-proc was about 25
lines.

They should be called many times by the enclosing proc.

They usually appear in the code "polishing" after it all works <g>.

Alan Lloyd
alang...@aol.com

David C. Ullrich

unread,
Aug 21, 2001, 9:12:20 AM8/21/01
to
On Mon, 20 Aug 2001 21:10:22 +0200, "Bjørge Sæther"
<REMOVE_bsaether@THIS_online.no> wrote:

>"David C. Ullrich" <ull...@math.okstate.edu> skrev i melding
>news:3b810df...@nntp.sprynet.com...
>> On Sun, 19 Aug 2001 21:03:34 +0200, "Dirk Claessens"
>> <will....@back.com> wrote:
>> >Another advantage- if many parameters must be passed - is that the scope
>of
>> >the inner procedure is the same as the outer procedure. I tried to
>emphasize
>> >that in the example.
>>
>> That's another aspect of it. How is it an advantange? (Try to
>> read that as an actual question, not an assertion that it's not
>> an adbatange...)
>
>When quite a large stack is built, it's of course an advantage to be able to
>access all the data without duplicating a lot of these data.

Meaning it's faster? Can you give an actual example where it actually
_is_ faster? I know I always assumed it would be much faster until
I timed it a few times... (maybe faster is not what you meant?)

I'm always suspicious of anything containing the words "of course"
on this sort of issue.

> It also saves
>some typing....
>
>--
>Bjoerge Saether
>Consultant / Developer
>http://www.itte.no
>Asker, Norway
>bjorge@takethisaway_itte.no (remve the obvious)
>
>


David C. Ullrich

Bjørge Sæther

unread,
Aug 21, 2001, 9:20:01 AM8/21/01
to
"AlanGLLoyd" <alang...@aol.com> skrev i melding
news:20010821053115...@nso-cp.aol.com...

> Programming is partly art, as well as skill, and there really are few
places
> where absolutes can be made (for David's benefit I grant that AVs are one
place
> <gg>). I don't believe an absolute ban on sub-procs can be supported.
Bjorge's
> comment that "When such a routine has absolutely no meaning outside the
calling
> routine, it'd
> better be placed locally." cannot (I think) be supported at all if by
"locally"
> he meant as a sub-proc.

That's what I meant, yes.

> A high proportion of routines called from within
> another routine have no meaning outside, and are called only once form a
single
> routine, usually this is done for higher level clarity.
>
> My approach to sub-procs are ...
>
> They should be less than an IDE page (they do obscure clarity to some
extent
> and shorter ones indented and with comment line delimiters help).
>
> They should be significantly shorter than the enclosing proc, although I
have
> seen an enclosing proc of a few lines in Delphi where the sub-proc was
about 25
> lines.
>
> They should be called many times by the enclosing proc.
>
> They usually appear in the code "polishing" after it all works <g>.

This I find reasonable. There are different "degrees" of every concideration,
and the last one, concidering "where in the proccess one is", could be
extende to mean "where in the process and at what accuracy level" - my usage
of nested routines depend highly on the time spent on the task in question.
Often a nested subroutine emerges as a result of rewriting an existing
routine, and I don't want to do even more rewriting. Further, when a piece of
code may be rewritten or even removed, it's often no point in refining it. I
can think of a few examples where nested routines are good (when you need to
pass a h* of a lot of params, or when it is too obscure to be understood
outside its context or when a few lines are called a lort of times), and
quite a few more where it's acceptable, everything taken into concideration.
Poorly written code is even worse when spread around in a lot of routines.
better collect the shit...;-)

Bjørge Sæther

unread,
Aug 21, 2001, 9:33:00 AM8/21/01
to
"David C. Ullrich" <ull...@math.okstate.edu> skrev i melding
news:3b825da...@nntp.sprynet.com...

> On Mon, 20 Aug 2001 21:10:22 +0200, "Bjørge Sæther"
> <REMOVE_bsaether@THIS_online.no> wrote:
>
> >"David C. Ullrich" <ull...@math.okstate.edu> skrev i melding
> >news:3b810df...@nntp.sprynet.com...
> >> On Sun, 19 Aug 2001 21:03:34 +0200, "Dirk Claessens"
> >> <will....@back.com> wrote:
> >> >Another advantage- if many parameters must be passed - is that the
scope
> >of
> >> >the inner procedure is the same as the outer procedure. I tried to
> >emphasize
> >> >that in the example.
> >>
> >> That's another aspect of it. How is it an advantange? (Try to
> >> read that as an actual question, not an assertion that it's not
> >> an adbatange...)
> >
> >When quite a large stack is built, it's of course an advantage to be able
to
> >access all the data without duplicating a lot of these data.
>
> Meaning it's faster? Can you give an actual example where it actually
> _is_ faster? I know I always assumed it would be much faster until
> I timed it a few times... (maybe faster is not what you meant?)
>
> I'm always suspicious of anything containing the words "of course"
> on this sort of issue.

When I'm concerned with speed, I sometimes do timing tests. Not so often when
concidering nested routines. When I write them, it's usually for the ease of
it. I often find such code easier to modify, too. You don't need to look
around for other potential callers. When I write nested routines, I'm usually
very accurate when declaring variables here: before the nested routine - all
variables that are also used within this, below - all that aren't.
Tracing is easier, too.

AlanGLLoyd

unread,
Aug 21, 2001, 3:02:07 PM8/21/01
to
In article <hmog7.3059$hc7....@news1.oke.nextra.no>, "Bjørge Sæther"
<REMOVE_bsaether@THIS_online.no> writes:

>I believe the right term is 'local
>routine' (a routine placed inside another routine) or 'nested routines' (more
>levels of routines inside one "outer" routine) ?

D3 OPLG 4-20 and help "procedural types, compatibility" says ...

"A procedure or function is nested when it's declared within another procedure
or function."

Alan Lloyd
alang...@aol.com

Bjørge Sæther

unread,
Aug 21, 2001, 4:41:46 PM8/21/01
to
"AlanGLLoyd" <alang...@aol.com> skrev i melding
news:20010821150207...@nso-bg.aol.com...

Thanks. I should know this, really, but I obviously have had only a vague
understanding of the terms. I guess the term 'subroutine' does not have a
very clear meaning in Delphi...or what ? And - what does 'local' routine mean
? 'Within scope but not globally accessible' ?

OK, I can read help files, too, of course. I found 'subroutine' used twice in
the help file of D5:

["Changing class defaults to avoid repetition"]
"Most programmers try to avoid repetition. Thus, if you find yourself
rewriting the same lines of code over and over, you place the code in a
subroutine or function, or build a library of routines that you can use in
many programs."

["Caller"]
"This command positions the Disassembly pane at the instruction past the one
that called the current interrupt or subroutine."

...so, subroutine is out of the way...

I found some more about "Local routine" (or "local procedure"):

["Compiler error 99. "Local procedure/function '<Name>' assigned to procedure
variable"]
[...]
program Produce;

var
P: Procedure;

procedure Outer;

procedure Local;
begin
Writeln('Local is executing');
end;

begin
P := Local; (*<-- Error message here*)
end;
[...]

...I think I kind of understand why I'm confused...;-)

Sundial Services

unread,
Aug 21, 2001, 7:21:34 PM8/21/01
to
Procedures/functions within other procedures/functions are only visible
within the procedure/function that contains them. They have access to
local variables declared within the containing procedure.

This notion is useful when the work performed by the outermost procedure
can logically be broken down into smaller pieces, especially pieces that
are used several times.

A good example of a procedure like this is "doExpression," from the
compiler within ChimneySweep. This procedure handles the compiling of
an arithmetic expression. Since this is a standard recursive-descent
compiler, the procedure structure matches the structure of the language
being parsed. An expression is broken down into several different
parts, e.g:

<expression> ::= <term> [{*/} <term> ...]
<term> ::= <factor> [{+-} <factor> ]
<factor> ::= <variable> | <constant | "(" <expression> ")"

There are subroutines (all within "doExpression") that handle <term>s,
<factor>s, and even the (completely recursive) reference to an
<expression> within a <factor>.

All of this complexity is necessary to make the "doExpression" routine
work, but it is -not- something that is interesting or that should be
visible outside of the scope of this innocent-looking outermost
container, "doExpression."

Another added bonus of this approach is that our compiler also has a
module called "doConstantExpression" that contains nearly all of the
same (nested) procedure names within -its- definition. Once again, all
of them are concealed. The fact that the names are duplicated is of no
consequence.

This kind of situation is comparatively rare. It's very, very nice to
have this sort of expressiveness .. it's a hallmark of the Pascal
language .. but the important thing, as always, is to be simple, be
clear, be descriptive. Never use a nifty language feechur just because
it's nifty. :-)

>Nhuyen wrote:
>
> Hello all
> Can I write procedure inside procedure (please give an example). What about
> scope of variable....
> Thank you for your help.
> Nhuyen

------------------------------------------------------------------
Sundial Services :: Scottsdale, AZ (USA) :: (480) 946-8259
mailto:in...@sundialservices.com (PGP public key available.)
> Fast(!), automatic table-repair with two clicks of the mouse!
> ChimneySweep(R): "Click click, it's fixed!" {tm}
> http://www.sundialservices.com/products/chimneysweep

Johan Smit

unread,
Aug 22, 2001, 12:41:06 AM8/22/01
to
On Mon, 20 Aug 2001 20:54:40 +0200, "Bjørge Sæther"
<REMOVE_bsaether@THIS_online.no> wrote:

>There are different reasons for using a subroutine - breaking up code to
>increase readability or the more usual reason for placing a piece of code in
>a routine: reuse.
>I kind of wonder when I see subroutines are not concidered "good latin".
>Routines contining subroutines are sometimes hard to read, but that's
>normally more or less unavoidable (complex routines). I'd say: place it
>locally whenever it seems like the simplest, most readable solution. When
>such a routine has absolutely no meaning outside the calling routine, it'd
>better be placed locally.
>

Is it also not true that the local procedure can access variables of
the procedure? I think the variables need to be declared before the
local procedure. That means less passing of parameters and less stack
use, so must result in faster execution of the local procedure than a
seperate procedure.
Regards
Johan Smit

Frank Peelo

unread,
Aug 22, 2001, 6:45:27 AM8/22/01
to

"Bjørge Sæther" <REMOVE_bsaether@THIS_online.no> wrote in message
news:FUAg7.3898$hc7....@news1.oke.nextra.no...
> ...I guess the term 'subroutine' does not have a

> very clear meaning in Delphi...or what ? And - what does 'local'
routine mean
> ? 'Within scope but not globally accessible' ?

"Subroutine" is a more general term than Procedure or Function. The
word predates Pascal; Procedures and functions are subroutines in
Pascal but other languages use other terms. Of course it has a clear
meaning, to people who use Pascal if not to those who write the
manuals - as do "crash", "reboot" and "time for a pizza".

"Local" also predates Pascal, and computers in general. The definition
of Local which fits best here is probably "Limited or peculiar to a
particular place or places". Local variables and procedures are
therefore the ones which can only be seen within the scope under
consideration. Nested procedures are local procedures. And the
variables defined between the procedure heading and "Begin" are local
variables.

I suppose that if the person you are talking to wants to consider the
Unit as the current scope, the term could get confusing; sometimes one
might say something like "variable blah is local to unit uFooBar" to
avoid this confusion. But more often one would understand correctly,
from the context.

FP


Frank Peelo

unread,
Aug 22, 2001, 6:55:37 AM8/22/01
to

"Johan Smit" <smi...@mweb.co.za> wrote in message
news:3b8337be...@news.mweb.co.za...
...

> Is it also not true that the local procedure can access variables of
> the procedure?

Certainly, and this is useful if you need to do such a thing, because
it saves you having to make those variables global.

> I think the variables need to be declared before the
> local procedure.

Yes. That's Pascal - you tell it first, then it knows.

> That means less passing of parameters and less stack
> use,

Yes, but:

> so must result in faster execution of the local procedure than a
> seperate procedure.

No, not necessarily! As I discovered when trying to convert such code
to C, what you have to consider is, how does the nested procedure get
at the outer procedure's variables and parameters? They are not at a
fixed offset on the stack relative to the nested procedure's stack
frame - because the nested procedure could be called from another
nested procedure or recursively from itself. So an extra hidden value
must be passed in somehow, to indicate where the outer procedure's
variables are. And any access of those variables needs to go through
that value - it's one extra level of indirection. And that slows
access of those values, which offsets any gain from not passing the
data as parameters. Whether the net result is positive or negative
will depend on such things as the types and sizes of the variables,
and how they are used.

FP


David C. Ullrich

unread,
Aug 22, 2001, 8:29:14 AM8/22/01
to
On Tue, 21 Aug 2001 15:33:00 +0200, "Bjørge Sæther"
<REMOVE_bsaether@THIS_online.no> wrote:

Right. Perfectly reasonable reasons to use nested procedures. But
I can't figure out whether today's comment is supposed to be an
explanation of what you meant by "When quite a large stack is built,


it's of course an advantage to be able to access all the data

without duplicating a lot of these data" or a different reason...

> When I write nested routines, I'm usually
>very accurate when declaring variables here: before the nested routine - all
>variables that are also used within this, below - all that aren't.
>Tracing is easier, too.
>
>--
>Bjoerge Saether
>Consultant / Developer
>http://www.itte.no
>Asker, Norway
>bjorge@takethisaway_itte.no (remve the obvious)
>
>


David C. Ullrich

David C. Ullrich

unread,
Aug 22, 2001, 8:31:10 AM8/22/01
to
On Wed, 22 Aug 2001 04:41:06 GMT, smi...@mweb.co.za (Johan Smit)
wrote:

That's what everyone thinks at first. But there's no "must" about it,
in fact using a local procedure often slows things down. Honest.

>Regards
>Johan Smit


David C. Ullrich

VBDis

unread,
Aug 22, 2001, 6:35:02 PM8/22/01
to
Im Artikel <h2fg7.2713$hc7....@news1.oke.nextra.no>, "Bjørge Sæther"
<REMOVE_bsaether@THIS_online.no> schreibt:

>When quite a large stack is built, it's of course an advantage to be able to
>access all the data without duplicating a lot of these data. It also saves
>some typing....

... where often not the amount of typing is important, but the shorter lines
improve the readability of the mainstream code.

Also local data types can be used in nested subroutines, without any export of
the details. IMO the Delphi subroutines allow for far better privacy, than e.g.
classes with private members. All declarations in a subroutine have a narrow
scope, nothing but the subroutine arguments and result type are visible
outside.

DoDi

Bjørge Sæther

unread,
Aug 23, 2001, 4:10:52 AM8/23/01
to
"David C. Ullrich" <ull...@math.okstate.edu> skrev i melding
news:3b83a53...@nntp.sprynet.com...

Yup. I still mean so. Routines that push a lot of stuff on the stack may
loose or gain more from different designs. The old TP TCollection.ForEach
method, for instance, where the local routine in fact doesn't get an own
stack at all (that's the trick, I believe...). It's not at all obvious you
get increased performance, but avoiding passing 6 parameters to an external
routine itself saves quie a few ticks. So does avoiding to copy a string or
putting up local variables.

But, as stated before, there are only few times where I do performance
comparisons in detail. Removing a routine call by duplicating the code inside
the calling routine has allways speeded things up, when I have tried it
(that's not the same as creating a local routine, of course). So has reducing
the number of memory allocations & variable copying. Without having ever
stated that the same performance *can not* be achieved without the use of
local routines, I'm pretty sure "semi-optimized" code may be faster when you
don't pass loads ov parameters to an external routine.

Bjørge Sæther

unread,
Aug 23, 2001, 4:22:29 AM8/23/01
to
"VBDis" <vb...@aol.com> skrev i melding
news:20010822183502...@nso-ck.aol.com...

The two typical nested routines I can think of, is a) Painting/Drawing a
complex control (like a grid), and b) Parsing text. In both cases you may
need a *lot* of variables to keep track of positions, and calling external
routines would typically require a lot of parameters to be passed and there
would easily be a lot of confusion on whether variables were altered or not.
The debugging is also easier, reducing the number of variable watches. I
believe I said it, a typical usage is within routines that would be complex
no matter how (or where making it simple amkes it dead slow).

The other typical way is when you want to make code more readable without
neccesarily optimizing the whole thing.

Bjørge Sæther

unread,
Aug 23, 2001, 4:25:14 AM8/23/01
to
"Frank Peelo" <fpe...@eircom.net> skrev i melding
news:9m02sv$mdp$1...@kermit.esat.net...

That's interesting ! Are there ways of avoiding such two-step access to
stacked variables ?

Frank Peelo

unread,
Aug 23, 2001, 8:25:31 AM8/23/01
to

"Bjørge Sæther" <REMOVE_bsaether@THIS_online.no> wrote in message
news:4%3h7.4946$hc7....@news1.oke.nextra.no...

> "Frank Peelo" <fpe...@eircom.net> skrev i melding
> news:9m02sv$mdp$1...@kermit.esat.net...
...

> > No, not necessarily! As I discovered when trying to convert such
code
> > to C, what you have to consider is, how does the nested procedure
get
> > at the outer procedure's variables and parameters? They are not at
a
> > fixed offset on the stack relative to the nested procedure's stack
> > frame - because the nested procedure could be called from another
> > nested procedure or recursively from itself. So an extra hidden
value
> > must be passed in somehow, to indicate where the outer procedure's
> > variables are. And any access of those variables needs to go
through
> > that value - it's one extra level of indirection. And that slows
> > access of those values, which offsets any gain from not passing
the
> > data as parameters. Whether the net result is positive or negative
> > will depend on such things as the types and sizes of the
variables,
> > and how they are used.
>
> That's interesting ! Are there ways of avoiding such two-step access
to
> stacked variables ?

Well, if you analyse the two procedures, and work out that the inner
one only gets called from the outer one with no other inner procedures
in between - with restrictions like that you could make an
optimisation. But the resulting inner procedure will not work in all
the cases where OP allows it to be called from, because OP allows
recursion, and allows one nested procedure to call another procedure
nested inside the same outer procedure. I don't believe Delphi will
parse the whole outer procedure, work out all the places the nested
procedure gets called from and then compile the nested procedure
accordingly, although I could be wrong about that. But without that
sort of analysis it would have to compile a routine that will work,
when it's called from wherever OP allows it to be called from. There
could well be ways of doing that without the extra level of
indirection but I don't know them.

FP


VBDis

unread,
Aug 24, 2001, 7:09:58 PM8/24/01
to
Im Artikel <9m02sv$mdp$1...@kermit.esat.net>, "Frank Peelo" <fpe...@eircom.net>
schreibt:

>what you have to consider is, how does the nested procedure get
>at the outer procedure's variables and parameters?

BP can be used for the outer procedure's variables, and SP for the inner
procedures.

DoDi

Frank Peelo

unread,
Aug 27, 2001, 5:24:35 AM8/27/01
to

"VBDis" <vb...@aol.com> wrote in message
news:20010824190958...@nso-ck.aol.com...

/me feels silly now...

but then I tried compiling a nested procedure in Delphi 4 and both the
outer and nested procedures start with
push ebp
mov ebp, esp
so I don't feel so bad - Delphi didn't think of it either. The outer
procedure pushes ebp before calling the inner one, which then uses the
pushed ebp to access the outer procedure's variables.

FP


VBDis

unread,
Aug 28, 2001, 8:30:57 PM8/28/01
to
Im Artikel <9md3ee$m40$1...@kermit.esat.net>, "Frank Peelo" <fpe...@eircom.net>
schreibt:

>but then I tried compiling a nested procedure in Delphi 4 and both the


>outer and nested procedures start with
> push ebp
> mov ebp, esp

This can vary, depending on the Delphi version. I didn't say that Delphi does
it this or another way ;-)

The created code also depends on compiler options, like "create stack frames",
optimization etc.

DoDi

0 new messages