Many DEFPROC, 1 ENDPROC?

Discuss all aspects of programming here. From 8-bit through to modern architectures.
User avatar
sydney
Posts: 1986
Joined: Wed May 18, 2005 9:09 am
Location: Newcastle upon Tyne

Many DEFPROC, 1 ENDPROC?

Postby sydney » Mon Oct 02, 2017 1:58 pm

Is it OK to have a procedure defined within a procedure so you have two DEFPROCs but only one ENDPROC. It seems to work OK in my example below.

Code: Select all

   10 PROCThat
   20 PROCThisAndThat
   30 END
   40 DEFPROCThisAndThat
   50 PRINT "This And ";
   60 DEFPROCThat   
   70 PRINT "That"
   80 ENDPROC

crj
Posts: 315
Joined: Thu May 02, 2013 4:58 pm

Re: Many DEFPROC, 1 ENDPROC?

Postby crj » Mon Oct 02, 2017 2:49 pm

Yes, that's fine. At least as far as the interpreter is concerned, even if not to human aesthetics. You might at least have put a comment there alerting people to what was happening!

You could even (ugh!) GOTO an ENDPROC somewhere completely different in the program.

alex_farlie
Posts: 35
Joined: Sun Jul 07, 2013 9:46 pm

Re: Many DEFPROC, 1 ENDPROC?

Postby alex_farlie » Mon Oct 02, 2017 3:46 pm

crj wrote:Yes, that's fine. At least as far as the interpreter is concerned, even if not to human aesthetics. You might at least have put a comment there alerting people to what was happening!

You could even (ugh!) GOTO an ENDPROC somewhere completely different in the program.


It's even possible in some versions of BBC Basic to do "overloading"

Code: Select all

DEFFNmy_func(a%):func%=0
DEFNmy_func(a%,func%):CASE func OF
WHEN 0: ....
....
ENDCASE
=0


But this may only be true of versions on PC.... Not sure if you could do tricks like that in BASIC V on RISC OS.

User avatar
jgharston
Posts: 2756
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield

Re: Many DEFPROC, 1 ENDPROC?

Postby jgharston » Mon Oct 02, 2017 3:53 pm

Yep, perfectly normal, such as this (DEFFNs in this example):

Code: Select all

      DEFFNNet_TxCount(Stn%,Ctrl%,Port%,Addr%,Len%,RAddr%,Try%,Delay%):LOCAL TxErr%
      DEFFNNet_Tx(Stn%,Ctrl%,Port%,Addr%,Len%,RAddr%):LOCAL TxErr%,Try%,Delay%:Try%=10:Delay%=50
      X%?1=Port%:X%!2=Stn%:X%!4=Addr%:X%!8=Addr%+Len%:X%!12=RAddr%

similarly, you can have multiple ENDPROCs (= in this example):

Code: Select all

      REPEAT:REPEAT:X%?0=Ctrl%:A%=&10:CALL &FFF1:UNTILX%?0 :REM Loop until Tx starts
      IFStn%=&FFFF:UNTIL TRUE:=0                           :REM Broadcast
        REPEAT:TxErr%=FNbyte(&32,0,0):UNTILTxErr%<&80      :REM Loop until complete
        IFTxErr%=&41 OR TxErr%=&42:IFTry%:A%=TIME+Delay%:REPEATUNTILTIME>A%:Try%=Try%-1
      UNTILNOT(TxErr%=&41 OR TxErr%=&42) OR Try%<1:=TxErr%

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

crj
Posts: 315
Joined: Thu May 02, 2013 4:58 pm

Re: Many DEFPROC, 1 ENDPROC?

Postby crj » Tue Oct 03, 2017 4:32 am

jgharston wrote:Yep, perfectly normal

Note that alex_farlie's example showed multiple definitions of the same function name with different numbers of parameters. I'm pretty sure that didn't work on the Beeb, and expect I'd have noticed it the Arc had added it.

alex_farlie
Posts: 35
Joined: Sun Jul 07, 2013 9:46 pm

Re: Many DEFPROC, 1 ENDPROC?

Postby alex_farlie » Tue Oct 03, 2017 9:19 am

alex_farlie wrote:
crj wrote:Yes, that's fine. At least as far as the interpreter is concerned, even if not to human aesthetics. You might at least have put a comment there alerting people to what was happening!

You could even (ugh!) GOTO an ENDPROC somewhere completely different in the program.


It's even possible in some versions of BBC Basic to do "overloading"

Code: Select all

DEFFNmy_func(a%):func%=0
DEFNmy_func(a%,func%):CASE func OF
WHEN 0: ....
....
ENDCASE
=0


[s]But this may only be true of versions on PC.... Not sure if you could do tricks like that in BASIC V on RISC OS.


Just tested and the above as


10 :
20 PRINT FNa(1,0)
30 PRINT FNa(1,2,3)
40
50 END
60
70
80
90
100 DEFFNa(a%,b%):c%=0
110 DEFFNa(A%,b%,c%)
120

example isn't possible on BB4W... I get an Incorrect Arguments error. So I was wrong.

Richard Russell
Posts: 171
Joined: Sun Feb 27, 2011 10:35 am

Re: Many DEFPROC, 1 ENDPROC?

Postby Richard Russell » Tue Oct 03, 2017 11:33 am

alex_farlie wrote:It's even possible in some versions of BBC Basic to do "overloading"

As far as I'm aware the only 'overloading' you can do is of a function or procedure with no parameters and one of the same name with one or more parameters. This works - at least in my versions - because the opening parenthesis is treated as part of the function/procedure name, exactly as it is in the case of an array (indeed the same code is used). So just as name and name() are independent, so are PROCname and PROCname().

But I frequently use the multiple DEFPROC one ENDPROC technique in this sort of way:

Code: Select all

      DEF PROC1 : LOCAL flag : flag = 1
      DEF PROC2 : LOCAL flag : flag = 2
      DEF PROC3 : LOCAL flag : flag = 3
      ... shared code, which tests 'flag'
      ENDPROC

This is a really useful feature, if only in avoiding the use of the dreaded (and slow) GOTO.

Richard.

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Many DEFPROC, 1 ENDPROC?

Postby Rich Talbot-Watkins » Tue Oct 03, 2017 12:12 pm

I've been writing C and C++ for so long now that this just looks like a monstrosity compared to:

Code: Select all

DEF PROC1:PROCa(1):ENDPROC
DEF PROC2:PROCa(2):ENDPROC
DEF PROC3:PROCa(3):ENDPROC

DEF PROCa(flag)
REM ... do something with flag
ENDPROC

The deeper call stack probably means it runs a bit slower, but rather that than passing parameters via globals, creating multiple entry points, etc etc :)

crj
Posts: 315
Joined: Thu May 02, 2013 4:58 pm

Re: Many DEFPROC, 1 ENDPROC?

Postby crj » Tue Oct 03, 2017 1:04 pm

Rich Talbot-Watkins wrote:I've been writing C and C++ for so long now that [...]

Tell me: have you ever encountered Duff's Device? (-8<

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Many DEFPROC, 1 ENDPROC?

Postby Rich Talbot-Watkins » Tue Oct 03, 2017 1:50 pm

crj wrote:
Rich Talbot-Watkins wrote:I've been writing C and C++ for so long now that [...]

Tell me: have you ever encountered Duff's Device? (-8<


Of course! But haven't had to do such low-level C hacking for many years now. Also, these days, with such huge advances in compilers and optimization techniques, I doubt if Duff's Device would even be worthwhile any more. The rule these days tends to be: don't micro-optimize - the compiler almost certainly knows better than you!

Richard Russell
Posts: 171
Joined: Sun Feb 27, 2011 10:35 am

Re: Many DEFPROC, 1 ENDPROC?

Postby Richard Russell » Tue Oct 03, 2017 4:24 pm

Rich Talbot-Watkins wrote:The deeper call stack probably means it runs a bit slower

It could be substantially slower, especially if there are multiple parameters (and even worse if some of them are RETURNed parameters). Interpreted BBC BASIC has a lot of work to do in making the formal parameters (especially strings) 'local', and adding another layer of call hierarchy means this has to be done twice. If it's not speed critical then, fair enough, your suggested alternative is better structured but when speed matters I don't feel that the 'many DEFPROC one ENDPROC' technique is particularly ugly. It's in a completely different league from passing parameters or results in globals!

User avatar
Rich Talbot-Watkins
Posts: 1117
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Many DEFPROC, 1 ENDPROC?

Postby Rich Talbot-Watkins » Tue Oct 03, 2017 5:40 pm

In your example though, doesn't the "LOCAL flag" get processed in exactly the same way as the procedure parameter? I mean, I'd assume that procedure parameters break down internally as "LOCAL whatever: whatever = <value of passed parameter>". That's how I'd've implemented it anyway.

Richard Russell
Posts: 171
Joined: Sun Feb 27, 2011 10:35 am

Re: Many DEFPROC, 1 ENDPROC?

Postby Richard Russell » Tue Oct 03, 2017 8:00 pm

Rich Talbot-Watkins wrote:In your example though, doesn't the "LOCAL flag" get processed in exactly the same way as the procedure parameter?

Well, not "exactly" because LOCALs don't have to be copied from the 'actual' parameters after saving. But that's not really the point, it's the 'real' parameters of the function/procedure that cause the speed issue with your approach:

Code: Select all

      DEF PROC1(par1,par2$,par3(),RETURN par4):PROCshared(1,par1,par2$,par3(),par4):ENDPROC
      DEF PROC2(par1,par2$,par3(),RETURN par4):PROCshared(2,par1,par2$,par3(),par4):ENDPROC
      DEF PROC3(par1,par2$,par3(),RETURN par4):PROCshared(3,par1,par2$,par3(),par4):ENDPROC
     
      DEF PROCshared(flag,par1,par2$,par3(),RETURN par4)
      ... shared code that tests 'flag'
      ENDPROC

All the (substantial) processing of the four parameters now has to be done twice, both on entry and on exit, compared with only once for the 'many DEFPROC' method.

Richard.


Return to “programming”

Who is online

Users browsing this forum: No registered users and 2 guests