Default BYVAL or BYREF Parameter Passing?

General FreeBASIC programming questions.
Post Reply

What do you think the parameter passing default should be?

Poll ended at Jul 14, 2007 22:08

1) Default all BYREF ( except function returns ).
13
29%
2) Default all BYVAL ( except arrays, and implicit THIS ).
13
29%
3) Mixed default: all BYVAL except Strings, UDTs and arrays.
8
18%
4) Don't care ( 1 to 3 ), so long as it is documented.
4
9%
5) No default. Explicit BYVAL/BYREF only.
7
16%
 
Total votes: 45
mcredz
Posts: 11
Joined: Apr 30, 2007 1:46

Post by mcredz »

Just my $0.02.

It doesn't really matter a whole heck of a lot what the default is. It needs to be documented, well documented, and over-ridable.

It should also be stable...it should change one more time, and it should stay that way. This kind of change has negative effects on anyone who's written anything more than a few introductory tutorial examples, and even those potentially :) But I'll learn whatever is decided and documented regardless.

and btw: thanks to all of you guys working on fbc & fbe, and the sites, etc. It's an awesome product with an awesome community.
v1ctor
Site Admin
Posts: 3804
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

Post by v1ctor »

Seriously, i doubt there are beginners *to programming* using FB, the language is unfinished, with lots of bugs to fix and is clearly much harder to use than a dozen of languages out there - take the dynamic typed ones as examples.

Anyone that continues using it after installing the package and realizing that "om, it's just a command-line application!" will soon or later find out how to pass parameters by reference.

QB 4.x didn't even support BYVAL but for functions prototypes (to call functions written in other languages) and used that "foo (bar)" horrible hack to pretend the arguments were been pushed by value. I don't think MS had a good reason for that, it was just a mistake like the other hundred ones they made at time - and abandoned decades later in vb.net.

Then, for the same reason, we also should support Variants so beginners wouldn't have to declare the symbol types..

Forget about making 2 different version of fbc, keeping in sync a single source base is hard enough, and in the end most using -lang qb will be using some kind of IDE, it takes 2 minutes to configure them to include a cmd-line option more when invoking the compiler.
mcredz
Posts: 11
Joined: Apr 30, 2007 1:46

Post by mcredz »

v1ctor wrote:Seriously, i doubt there are beginners *to programming* using FB, the language is unfinished, with lots of bugs to fix and is clearly much harder to use than a dozen of languages out there - take the dynamic typed ones as examples.
As an example, I am a hobbyist programmer, but I have had this hobby for many years, so I have already touched TP, C, VB6, VBS, JS enough to follow code and can adapt examples into quick little programs.
v1ctor wrote:QB 4.x didn't even support BYVAL but for functions prototypes (to call functions written in other languages) and used that "foo (bar)" horrible hack to pretend the arguments were been pushed by value. I don't think MS had a good reason for that, it was just a mistake like the other hundred ones they made at time - and abandoned decades later in vb.net.
And this is where I seem to be the minority, I never really touched QB (I was quite happily playing with TP7, and looking at OS/2/DOS x-compilers) and being one of the VB6 users that had already discovered the API, and refuse to move to managed code, and C hurts my head :>, FB is filling a niche for me -- with the bonus that I can use it on my increasing number of linux installations. Hopefully there are more like me who will find a home with FB.

I agree forking = bad_idea, but maybe the idea of no more qb quirks is not such a bad_thing. Don't cater to the beginner, but lets just remember, basic is supposed to be easier than c, right? :)
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Post by coderJeff »

I know it's been a while since anyone commented on this.

Yeah, I have to agree that although there might be many people new to FreeBASIC, I don't think anyone commenting here is *new to programming*. So maybe designing a language ( or making changes to an existing one ) shouldn't be based on a user's skill level. If they stick with it, they should get it eventually.

More thoughts...

BYREF is useful because it allows a programmer (and a compiler) to do "pointer-like" things without the need for any special syntax. BYVAL wouldn't be needed at all just like in QB except as v1ctor mentioned, to interface with an external library.

I think C++ is not a good comparison for an OO language. While C++ allows OO design, it does not enforce the semantics at the language level. Maybe due to mixing paradigms of OO and procedural, FreeBASIC now is kind of like C++ in that the language allows the new OO stuff but still puts most of the burden on the programmer to do it correctly.

This last couple of weeks I have been trying my hand at some PHP coding, to solve a particular problem, and also get some ideas about this reference stuff. In PHP, referencing and passing objects is like in C++, and sometimes requires some careful use of the & operator to get things to work right. Not exactly what I call user friendly.

I think I understand now why Java is designed without any pass-by-reference at all where all objects allocated on the heap and only references are passed. (Yes, by-value). BYREF/BYVAL doesn't really have any meaning in this design - like BYDESC with arrays in FreeBASIC.

Where does that leave us? Well, it kind of sucks that there isn't one default that fits all the designs. BYVAL would appear to be the common denominator, but it really depends on what kind of "object" is being passed. So for now, default BYVAL is probably the best. But I could see later in future some default more along the lines of what v1ctor suggested, with different default for objects/primitives. The thing to keep in mind though is that it wouldn't be exactly the BYVAL/BYREF we are talking about now. How to differentiate between the two types of "objects" (allocated statically or on the heap) will be the challenge.
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Post by stylin »

While C++ may not be the ideal OO language, I think the choice between the different paradigms is to its credit. Some very interesting and fun designs can be made by mixing various methods like that. I also like the choice FreeBASIC gives for the same reason.

I'm not sure how a Java-like object-reference scheme would work in FreeBASIC (like C++). For me, the difference between 'simple' and 'complex' TYPEs is confusing enough, let alone having different behavior for static and dynamic objects (would dynamically allocated primitives behave differently as well ?)

It seems to me that the way things are now, with a universal BYVAL/BYREF scheme, is the most consistent and less confusing (I like to think of arrays as objects that are implicitly passed by reference. This makes sense to me since they can actually act like objects, rather than simple pointers like in C/C++ - and I think it would be good to emphasize this distinction).
jevans4949
Posts: 1186
Joined: May 08, 2006 21:58
Location: Crewe, England

Post by jevans4949 »

I think having some passed byref and some byval would be a bad idea. Either all one thing, or all the other.
Rufus
Posts: 44
Joined: Jul 27, 2005 18:57
Location: England

Post by Rufus »

I think v1ctor is absolutely correct that beginners to programming are unlikely to be using FB. Even 'structured' BASICs in the 1980s had only two numeric data types which made the initial steps in programming much easier. The multiple numeric types in FB are an asset to experienced programmers but would be an added layer of confusion to beginners.

I always use ByVal or ByRef so I have voted for option 5 but I could live with options 2 or 3, (default is to pass parameters ByVal), because that is how I learned to program and it seems the most natural way to do it. It also makes it easier for beginners to understand the purpose and value of breaking a program into subroutines/procedures. (Excuse the unintended pun here.)

Passing parameters ByRef is treated as a 'special case' which is used only where the parameter is to be modified. That is the situation in Pascal and Modula 2 which use the keyword 'var' to indicate that a parameter can be modified.

I have always assumed that the exclusion of arrays and/or strings from pass by value was because memory was in short supply in the 1980s. That is no longer the case. The increase in processor speed (this machine is 1400 times faster than the machine I learned to program on and the BASIC was interpreted) makes the time cost of making copies of parameters to be passed by value very small. If you don't want to pay it then you can always use ByRef.

The big advantage of passing parameters ByRef in FB is that the compiler does a proper type check which ensures that the actual and dummy parameters are of the same type. This picks up errors at compile time and avoids some subtle and difficult to find run time errors.

I would prefer to have proper type checking and compile time error detection even when parameters are passed by value as I think that is what a modern compiler should do. I am not holding my breath...
cha0s
Site Admin
Posts: 5319
Joined: May 27, 2005 6:42
Location: USA
Contact:

Post by cha0s »

Rufus wrote:I would prefer to have proper type checking and compile time error detection even when parameters are passed by value as I think that is what a modern compiler should do. I am not holding my breath...
Why, that would be un-BASIC! :P I tend to agree with you, however.
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Post by stylin »

Rufus, I'm not sure I understand what you mean by 'type checking', could you elaborate ?
Rufus
Posts: 44
Joined: Jul 27, 2005 18:57
Location: England

Post by Rufus »

Try to compile the following code snippet:

Option Explicit

Declare Sub PrintIt(ByRef aByte As Byte)

Dim myShort As Short

myShort = 127

Call PrintIt(myShort)

Sleep

Sub PrintIt(ByRef aByte As Byte)
Print aByte
End Sub 'PrintIt

The compiler will detect a type mismatch, dummy parameter expected is of type Byte, actual parameter when subroutine is called is of type Short.

Now change the two ByRef keywords to ByVal and it will compile without a problem irrespective of the type mismatch. When you run it the code behaves as you would expect

So long as myShort is assigned a value of not more than 127 there is no problem. But if it is assigned a value of 128 (or more) the code does not behave as you expect it to.

When parameters are passed using ByVal this behaviour can introduce a subtle bug which can be very hard to track down.

Unfortunately passing parameters using ByRef is not a complete safeguard. If the type of myShort is changed to uByte the compiler does not detect a type mismatch and the same sort of bug can be introduced.
DrV
Site Admin
Posts: 2116
Joined: May 27, 2005 18:39
Location: Midwestern USA
Contact:

Post by DrV »

This could probably solved with better warnings for implicit narrowing conversions; I don't know how to add these myself, but I presume it would be possible (and probably quite useful).
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Post by stylin »

As for reference and pointer parameters, I agree that mismatches shouldn't be allowed unless explicitly cast. When passing by value however, there's leeway there because FreeBASIC has implicit conversion mechanisms, which IMO are more useful than harmful. Yeah, I agree there should be more warnings for that though.

C++ follows the same behavior, reference or pointer parameter types need to match (one exception is passing a ref or ptr to derived object, since derived objects are base objects), value parameters will be converted if possible.
Rufus
Posts: 44
Joined: Jul 27, 2005 18:57
Location: England

Post by Rufus »

Better warnings of implicit narrowing conversions would be very useful.

There is a similar problem with the built in type conversion functions e.g. CInt etc.

This can be partially solved by writing a series of overloaded functions which pass the parameter ByRef to ensure type checking, do a run time check on the magnitude of the numeric value and only make the conversion if the value will 'fit' in the type you are converting to. It takes a few machine cycles but that may be a price worth paying. In this case it may be better to avoid using unsigned numeric types for the reason given earlier.
v1ctor
Site Admin
Posts: 3804
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

Post by v1ctor »

Yeah, that's a dangerous QB feature that shouldn't be allowed in -lang fb mode.
Rufus
Posts: 44
Joined: Jul 27, 2005 18:57
Location: England

Post by Rufus »

When we used BASICs with only two numeric types, integer and real, implicit type conversions were not a big issue and the only type conversion function was INT.

Modern languages have many more numeric types. For example there are EIGHT integer types in FB. The scope for introducing subtle and difficult to track down errors is much increased.

Microsoft have recognised this and VB.net has Option Strict which prevents implicit type conversion. At compile time this also warns about assigning the double precision return value of a function to a single precision variable.

To avoid the problems which this strict type checking can sometimes cause Microsoft have introduced a generic CType function:

Dim result as typename = CType(expression, typename)

Where expression can be any kind of data, object or structure.

Presumably Cast would fulfil the role in FB.
Post Reply