Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 19:56 11 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Passing Arguments by Reference

Author Message
srnet
Senior Member

Joined: 08/08/2014
Location: United Kingdom
Posts: 164
Posted: 11:49pm 06 Feb 2015
Copy link to clipboard 
Print this post

I have a problem with the 'Passing Arguments by Reference' feature of subroutines.

Take this very short program

DIM VAR1 = 1
DIM VAR2 = 0

Print "VAR1 ";
Print VAR1
Do.Write VAR1
Print "VAR1 ";
Print VAR1

END

SUB Do.Write(VAR2)
VAR2 = 2
END SUB


It works as expected, VAR1 picks up the value of VAR2 after the Do.Write call.

However if the DIMs are changed to DIM INTEGER, it does not work, VAR1 stays at 1 and does not pick up a value of 2.

What am I doing wrong ?

Using Micromite II 4.6

Stuart Robinson
GW7HPWEdited by srnet 2015-02-08
$50SAT is Silent but probably still working.
For information on LoRa visit http://www.loratracker.uk/

 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8600
Posted: 12:18am 07 Feb 2015
Copy link to clipboard 
Print this post

Stuart

The issue is that unless you direct otherwise MMBasic assumes variables are floating point. To correct the program change the subroutine definition to:

SUB Do.Write(VAR2 AS INTEGER)

The program is a bit confused because you are declaring VAR2 as a Global variable but then using it as a local variable in the subroutine where it is treated as a FLOAT

Best practice (my view ) is that you should use:
OPTION DEFAULT NONE
OPTION EXPLICIT

at the top of every program.

This forces you to fully declare all variables before use including their type

It also forces you to explicitly type subroutine parameters so

SUB Do.Write(VAR2) would give an error.

Also if you always use LOCAL to declare variables inside subroutines and functions then they won't use Global declarations by mistake.

Peter

 
srnet
Senior Member

Joined: 08/08/2014
Location: United Kingdom
Posts: 164
Posted: 12:39am 07 Feb 2015
Copy link to clipboard 
Print this post

Ah thanks for the explantion.

So when passing values\variables to SUBs and from Functions, the types need to match ?

If that is the case, and there is a variable type mismatch, then the SUB handler presumably knows about it (as it cannot return the value) but does not flag an error ?Edited by srnet 2015-02-08
$50SAT is Silent but probably still working.
For information on LoRa visit http://www.loratracker.uk/

 
srnet
Senior Member

Joined: 08/08/2014
Location: United Kingdom
Posts: 164
Posted: 09:00am 07 Feb 2015
Copy link to clipboard 
Print this post

And how do you achieve the same for Functions if you use 'OPTION DEFAULT NONE'

The example from the manual;

OPTION DEFAULT NONE
OPTION EXPLICIT

SETPIN 2, AIN : SETPIN 3, AIN
PRINT "The highest voltage is" Max(PIN(2), PIN(3))

FUNCTION Max(a, b)
IF a > b THEN
Max = a
ELSE
Max = b
ENDIF
END FUNCTION

Fails with "Error: Variable type not specified"

And;

FUNCTION Max(a AS Integer, b AS INTEGER)

Fails as well.

Leave out the 'OPTION DEFAULT NONE' and it works.
$50SAT is Silent but probably still working.
For information on LoRa visit http://www.loratracker.uk/

 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8600
Posted: 09:21am 07 Feb 2015
Copy link to clipboard 
Print this post

FUNCTION Max(a AS Integer, b AS INTEGER) AS INTEGER
 
srnet
Senior Member

Joined: 08/08/2014
Location: United Kingdom
Posts: 164
Posted: 09:24am 07 Feb 2015
Copy link to clipboard 
Print this post

  matherp said   FUNCTION Max(a AS Integer, b AS INTEGER) AS INTEGER


Again thanks.

Is there a referance anywhere which explains these little pearls of wisdom ?

Edit:

Found it, Manwel P34Edited by srnet 2015-02-08
$50SAT is Silent but probably still working.
For information on LoRa visit http://www.loratracker.uk/

 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2292
Posted: 02:11am 08 Feb 2015
Copy link to clipboard 
Print this post

it does seem to me that there is now a fundamental error in the syntax of the language, where assigning a floating point value to an integer variable does not always throw up an error, but is instead interpreted silently in a confusing and non-obvious manner. the above illustrates a whole new class of 'hidden mistake' that has been introduced to catch out the unwary.


geoff: this has been something that has troubled me for a while. might i suggest you consider a complete rethink of the philosophy surrounding variable names, (implicit and explicit) declarations, and types.


maybe the language should move towards demanding all variables be declared with explicit types. remove DIM and LOCAL completely from the language, to be replaced with VAR as used in Pascal (and with much the same syntax as in Pascal).

for those not familiar with Pascal, the new syntax would be that at the top of the program and beginning of subroutines there would be declarations of the form:

VAR <name> <name>... <name> AS <type>

where arrays are declared as bracketed ranges after the name. ie,

VAR abc(10) AS integer
VAR def(7) AS string(7)
VAR ghi AS string(25)


abc is then an array of 10 integers, def is is an array of 7 strings (each string of length 7 characters maximum), ghi is a string of length 25 characters maximum.

with this change, "$", "%" and "!" would also be eliminated from the language. the only automatic type conversion allowed would be when assigning an integer to a float.


i feel that the present 'compromise' has suddenly made the mmbasic language far more confusing for not just the beginner, but for everyone.

comments, anyone?

rob :-)
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 02:52am 08 Feb 2015
Copy link to clipboard 
Print this post

Rob,


I would agree with the context of what you're suggesting.

The only change I would make is to keep DIM and LOCAL, and simply use either of these in place of your 'VAR' command.

i.e.
DIM abc(10) as integer
DIM def(7) as string(7)
LOCAL ghi as string(25)

Option Explicit can remain.

I do like the 'original' syntax of defining a string with $ and non-strings without $. However, keeping this in causes potential confusion when typing something like:
DIM abc$(10) as integer

So my opinion would be to go with your suggestion but replacing VAR with DIM or LOCAL.

WW
Edited by WhiteWizzard 2015-02-09
For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2292
Posted: 03:31am 08 Feb 2015
Copy link to clipboard 
Print this post

the problem with retaining DIM and LOCAL is that they will be performing an identical function to each other, and this function will differ markedly from the original use (and syntax) of DIM. it is like having a car with the roof switch labelled "lights" - the label does not match the usage.

VAR would be used to define variables. name and function match. there is no confusion of meaning, and code using an existing DIM statement can be made to halt with an error message stating 'the DIM statement is no longer supported' or words to that effect.

DIM becomes an anachronistic statement - left over from the days when variables were created automatically upon use, and back then required only because of the difficulty of automatically creating arrays without causing memory management mayhem on small systems.

OPTION EXPLICIT and OPTION DEFAULT need to both go, as their concepts are not a part of the revised paradigm. 'explicit' is always turned on (and can not be turned off), while with "$", "%" and "!" eliminated there is now no meaning to 'default'.

i would suggest having a look at the syntax of Pascal around this area. it is clean and unambiguous, eliminating the problems that are starting to emerge.


btw, for the record, my own personal philosophy is that for a small BASIC interpreter the explicit declaration route should have been avoided, with "$" and "%" kept/made compulsory to define type. but that boat has long ago sailed - my suggestions are directed towards making the best of the current situation.


rob :-)
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8600
Posted: 08:06am 08 Feb 2015
Copy link to clipboard 
Print this post

It is easy to suggest various flavours of major rework of MMBasic but realistically unlikely to happen even if we could obtain consensus (unlikely as already demonstrated above ).

However, it is easy enough to avoid most problems with the current version.

My view - FWIW

Always use:
OPTION EXPLICIT
OPTION DEFAULT NONE

Only write code in Subroutines or Functions and always define variables in these using LOCAL

The "main" program will then just contain DIM and CONST declarations for genuinely Global variables/constants and then a call to an "INIT" subroutine followed by the call to a "MAIN" subroutine.

OK it isn't syntactically wonderful but we are where we are and if you follow this approach all variable typing issues will be trapped. Also it then matters not whether you use "LOCAL INTEGER i" or "LOCAL i%". Personally, I use "string$", because it is so embedded in the subconscious, but don't use % or !


OPTION EXPLICIT
OPTION DEFAULT NONE
' Global Constants defined here
' Global Variables defined here
Init
Main
END
'
SUB Init
' Local variables needed for initialisation
' Local Constants defined here - no separate syntax needed
' code
END SUB
'
SUB Main
' Local variable needed for main program
' Local Constants defined here - no separate syntax needed
DO
' main program code here
LOOP
END SUB
Edited by matherp 2015-02-09
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 07:09pm 08 Feb 2015
Copy link to clipboard 
Print this post

Peter

On the nose !

Option Default NONE
Option Explicit

are the best defence against variable naming errors

For readability, I personally use % for Int64, $ for Strings, and anything without a suffix is a Float. In a fully compiled environment, the use of specific suffices, ie % $ is unnecessary, but in an interpreted environment anything which aids readability and disambiguates code must be welcomed surely.

People might find this guidance note interesting http://www.g8jcf.dyndns.org/MMBasicIILib/Files/Creating%20Li braries%20for%20MMBasic.pdf

Peter
The only Konstant is Change
 
srnet
Senior Member

Joined: 08/08/2014
Location: United Kingdom
Posts: 164
Posted: 01:27am 09 Feb 2015
Copy link to clipboard 
Print this post

As a beginner to the MMII, I think making mistakes is to be expected.

I was trying to make my LoRa device SUB calls meaningful, so that others would stand a chance of knowing what was going on.

For instance this is the call to set a register on the LoRa device, RFM98\DRF1278F;

LORA.Write(&H01,&H08)

Now, I know what this means, it puts the device into sleep mode by writing to the Opmode register, but this better I think;

LORA.Write(LORA_RegOpMode,&H08)

The SUB is then;

SUB LORA.Write(LORA_Reg AS INTEGER,LORA_Data AS INTEGER) AS INTEGER
LORA_Reg = LORA_Reg OR &H80
PIN(LORA_NSS) = 0
LORA_NULL = SPI(LORA_Reg)
LORA_NULL = SPI(LORA_Data)
PIN(LORA_NSS) = 1
END SUB

Again to me (as a beginner) is fairly clear what is going on in the SUB due to the use of meaningful variable names. However, I had followed the advice in the creating libraries document, so defined 'LORA_RegOpMode’ as a variable with an initial value of &H01, and got into a right mess.

I should have read and heeded the advice in the manual “this practice encourages another class of difficult to find bugs”. So I changed all these fixed values into CONST declarations and my program was much better behaved.

However on the way to fixing this, I noted that sometimes the variable ‘LORA_RegOpMode’ would be altered during the SUB call, sometimes not. The reason was an error on my part, the value should be passed back but only if the two variable types in use match, and therein lies an easy trap for a beginner to fall into.

The way to avoid all this may be by following a strict structure to a program, as recommended by others. I doubt this approach is at all obvious to the average beginner though.

$50SAT is Silent but probably still working.
For information on LoRa visit http://www.loratracker.uk/

 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024