Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 12:42 11 Jul 2025 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 : Final PicoMite Release - V6.00.01

     Page 3 of 4    
Author Message
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 574
Posted: 07:23pm 08 Jan 2025
Copy link to clipboard 
Print this post

  Quote  

> list
Dim a As integer : a = 0

Print "a="; a
Add1(a)
Print "a="; a
Add1((a))
Print "a="; a
End

Sub Add1(x As integer)
 x = x+1
 Print "x="; x
End Sub
> run
a= 0
x= 1
a= 1
x= 2
a= 1
>




I think that is a bug (?)
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3358
Posted: 08:11pm 08 Jan 2025
Copy link to clipboard 
Print this post

Why do you think that (a) should be the same as a?

In MMBasic DOS:

a=0
add1((a))
Print "main: ",a,b
End
Sub add1(b)
b=b+1
Print "sub: ",a,b
Return



sub:     0       1
main:    0       0

PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4038
Posted: 08:22pm 08 Jan 2025
Copy link to clipboard 
Print this post

It's meant (*) to be that way.

It's useful to know that it is!

Easy to work around if it troubles you - use the extra parens or just don't modify things passed in as parameters.

(*) let's not get into language debates...

John
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6269
Posted: 08:26pm 08 Jan 2025
Copy link to clipboard 
Print this post

By putting 'a' in brackets '(a)', the interpreter is treating (a) as a formula

A normal variable is passed by reference.
When you use a formula as a parameter for a SUB, it is not passed by reference.

Jim
VK7JH
MMedit
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2608
Posted: 10:06pm 08 Jan 2025
Copy link to clipboard 
Print this post

  WhiteWizzard said  Do I need some form of clearing/nuking this particular old firmware?

Clear_flash_2040.zip
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1575
Posted: 10:33pm 08 Jan 2025
Copy link to clipboard 
Print this post

@Lizby
I think you mean this?
a=0
add1((a))
Print "main: (a)",a,b

a=0
add1(a)
Print "main:  a ",a,b
End

Sub add1(b)
Inc b
Print "sub: ",,,a,b
End Sub


sub:             0       1
main: (a)        0       0
sub:             1       1
main:  a         1       0

Kind regards
Michael
causality ≠ correlation ≠ coincidence
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4038
Posted: 10:41pm 08 Jan 2025
Copy link to clipboard 
Print this post

I like the way you've added b to the print in main!

John
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5056
Posted: 06:51am 09 Jan 2025
Copy link to clipboard 
Print this post

Hi Jim,

I didn't know this. Wow, that opens a whole new universe. I know I struggled with this in several programs, always assuming the ByRef was the only way to pass data to a sub.

But you need to be sharp in how to format everything. Without brackets also seems to work.

mysub a     'ByRef
mysub (a)     'ByRef
mysub ((a))   'ByVal
mysub(a)      'function call ByRef
mysub((a))    'function call ByVal (have not checked, but I assume)


Volhout
Edited 2025-01-09 16:53 by Volhout
PicomiteVGA PETSCII ROBOTS
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10233
Posted: 08:33am 09 Jan 2025
Copy link to clipboard 
Print this post

From the manual

  Quote  Unless you need to return a value via the argument you should not use an argument as a general purpose
variable inside a subroutine or function. This is because another user of your routine may unwittingly use a
variable in their call and that variable could be "magically" changed by your routine. It is much safer to assign
the argument to a local variable and manipulate that instead.
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7858
Posted: 08:36am 09 Jan 2025
Copy link to clipboard 
Print this post

I think this makes sense in BASIC as it always evaluates bracket values first. What we are seeing is two different meanings for brackets. The first meaning is that the command has an argument, the second is that there is a value to be calculated.

myfunction(A) shows this more clearly, the brackets are not optional.
A is being passed by reference

myfunction((A+1))
will cause the evaluator to evaluate the contents of the brackets first and replace them with a temporary value for the call. It detects that this is needed by the fact that the value to be calculated is in its own brackets.

myfunction((A))
will force the evaluator to evaluate the contents as A+0 or simply A as there is nothing else, but the evaluator has been triggered so it has to be a value that is passed.

I wouldn't say that this use of brackets is a "hack". I think BASIC is supposed to work in this way. FORTRAN (which has several influences on BASIC) also passes by value by default, although it uses the VALUE keyword to force passing by value.

Passing values by reference can lead to errors, true, but within a SUB or FUNCTION you should be using LOCAL or STATIC variables if you want them to be private. That makes the behaviour of the routines completely predictable under all circumstances.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4038
Posted: 11:12am 09 Jan 2025
Copy link to clipboard 
Print this post

I think ANSI full BASIC passes by value.

(But MMBasic doesn't claim to be that.)

John
 
bfwolf
Regular Member

Joined: 03/01/2025
Location: Germany
Posts: 75
Posted: 11:46am 09 Jan 2025
Copy link to clipboard 
Print this post

  zeitfest said  
I think that is a bug (?)


Microsoft would it describe it like this:  
"We confirm this behavior not being a bug but a feature!"

Some years ago when I read the MMBasic manual, I noticed, that there is no "language option" to specify whether ByRef or ByVal is requested. So I played (I think with the MSDOS version?) and looked, what happens, when I enclose argument variables with brackets - and it worked!

  matherp said  From the manual

  Quote  Unless you need to return a value via the argument you should not use an argument as a general purpose
variable inside a subroutine or function. This is because another user of your routine may unwittingly use a
variable in their call and that variable could be "magically" changed by your routine. It is much safer to assign
the argument to a local variable and manipulate that instead.


Yes, Peter, I'm with you! It's bad style to modify parameter variables unless they are "return values" - and it's always cleaner, to make a local copy of arguments, that are no "return values", and modify those, if necessary.

But it's "double safe", if the caller may protect it's arguments against modification. This would be achieved (clearly) by having ByVal.

Using the "trick" with enclosing argument variables with brackets and force them being "expressions" (which could be variables, formulas or constants) works until then.

At the moment I see the keywords ByVal and ByRef "nice to have"..

bfwolf
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 574
Posted: 11:58am 09 Jan 2025
Copy link to clipboard 
Print this post

  Quote   FORTRAN ... also passes by value by default,


Did you mean, ... passes by reference by default ...

Using values as call-by-reference arguments in calling statements can lead to ah, unfortunate happenings.  In exact call-by-reference, the argument is expected to be the name of a variable, not a value. Some early language compilers were a bit
vicious and would simply treat the value as a name, so say

call mysub(3)

would simply create and use a variable called '3', probably not the expected
result.
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7858
Posted: 12:20pm 09 Jan 2025
Copy link to clipboard 
Print this post

Sorry, yes - FORTRAN passes by reference.

I bet there's no room to implement these on the Micromite version of MMBasic. Geoff used magical unicorn power to get stuff into that!

.
Edited 2025-01-09 22:27 by Mixtel90
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
bfwolf
Regular Member

Joined: 03/01/2025
Location: Germany
Posts: 75
Posted: 01:33pm 09 Jan 2025
Copy link to clipboard 
Print this post

  Mixtel90 said  
I bet there's no room to implement these on the Micromite version of MMBasic. Geoff used magical unicorn power to get stuff into that!
.


Ok - if it breaks compatibility amongst different platforms, it's hard to solve.
We could live with the brackets "trick".

@Peter: How do you think about my FSEEK(), FREAD$(), FWRITE() ideas?
I recently saw, that the present INPUT$() mostly behaves the same way as FREAD$() would. But I have now idea, how to substitute FWRITE() by PRINT #nbr, ...
And the SEEK command also behaves different - not possible to seek +/- from current position or to file's end. We must track the current position ourselves then instead..

As both LittleFs and Chan's FatFS (probably used for SD-CARDs?) supply the functions to realize FSEEK(), FREAD$(), FWRITE(), I wouldn't expect much work?

bfwolf
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4038
Posted: 03:39pm 09 Jan 2025
Copy link to clipboard 
Print this post

Bearing in mind that the features are frozen now and only bug fixes being done, you may have a wait, especially for things which are hardly important.

John
 
bfwolf
Regular Member

Joined: 03/01/2025
Location: Germany
Posts: 75
Posted: 05:29pm 09 Jan 2025
Copy link to clipboard 
Print this post

Just made an experiment using the DOS/Windows-version (to view the resulting file):

It seems, that
' Note the pending ';' !
PRINT #nbr, wdata$;

just writes the data contained in wdata$ and doesn't append a CR, a TAB, a space or anything else, so this could replace the wanted FWRITE().

Can anybody confirm this behavior for other MMBasic ports?

Maybe I'll write a library, having also a FOPEN() like C offers, and track the current file position with a "hidden" variable e.g. "_current_fpos". The FOPEN() then would initialize the current file position and FSEEK(), FREAD$() and FWRITE() would update it accordingly.

bfwolf
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4038
Posted: 05:37pm 09 Jan 2025
Copy link to clipboard 
Print this post

It's standard BASIC that a ; with PRINT does that.

The user manual I have even says it does that...

John
Edited 2025-01-10 03:40 by JohnS
 
bfwolf
Regular Member

Joined: 03/01/2025
Location: Germany
Posts: 75
Posted: 05:57pm 09 Jan 2025
Copy link to clipboard 
Print this post

Yes, I knew that an ending ';' supresses CR and TAB but was uncertain if perhaps a space would be added. But I think the space is leading numeric variables PRINTed? (for the sign if negative?)

@Geoff, Regarding the user manual:
Within the description for the OPEN statement, a WRITE statement is mentioned but never described in detail anywhere else..
Is the WRITE statement "just an alias" for PRINT or are there differences?

bfwolf
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2608
Posted: 09:34pm 09 Jan 2025
Copy link to clipboard 
Print this post

AFIK there is no individual WRITE command. Write is just a component of other commands.

eg I2C WRITE, SPI WRITE
 
     Page 3 of 4    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025