Call me crazy, but I like type suffixes

General FreeBASIC programming questions.
Qlink
Posts: 79
Joined: Jun 06, 2007 15:21

Call me crazy, but I like type suffixes

Post by Qlink »

I just upgraded to the latest version of the compiler, and now suffix support is gone, is there a good reason for removing this functionality from the main FreeBasic dialect? These suffixes are a major part of the BASIC language, and I can't really see any reason why, if people don't like them, they don't just stop using them.

I could use lang QB or lite or deprecated dialects, but my understanding is that they restrict the newer FB features I can use. I'm perfectly happy with cutting off the $ from function names, but I'd still rather not declare each and every variable before I use it. So, what should I do?
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Post by counting_pine »

The main advantage lang fb has over lang fblite is support for object orientation. (Though many consider explicit variables an advantage too.)
If you don't need object orientation, then fblite should do just about everything you need.
We created it with a more QBASIC-esque programming style in mind, so it should hopefully work well for you.
Last edited by counting_pine on May 03, 2008 0:23, edited 1 time in total.
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

You can use var x = 0, s = "" - the initial values define the data types for these variables.
The variable declaring makes the code more readable and easier to debug. ;-)
Qlink
Posts: 79
Joined: Jun 06, 2007 15:21

Post by Qlink »

I don't know about more readable... sometimes it's nice to see what type the variable is just by looking at its suffix, so I don't have to scroll all the way up to find where I declared it, or start adding things like _string _integer and _long to the end of my variable names.

FBlite sounds nice, I hope it stays up to date though.
Eclipzer
Posts: 432
Joined: Oct 01, 2005 10:50
Location: Maryland
Contact:

Post by Eclipzer »

suffixes are a major part of the BASIC language, and I can't really see any reason why, if people don't like them, they don't just stop using them.
Honestly, I agree with you. This was a big gripe for me in updating to the latest version of FB. However, things change, and FBs feature set far outweighs these "short-comings". It's just an adjustment you have to make, so adapt and move on. It's worth it.
I'd still rather not declare each and every variable before I use it. So, what should I do?
Another annoyance for me as well. I absolutely loved not having to declare all my minor variables. I often find myself repeatedly using variables i,x,y,u,v all the time in FOR ... NEXT loops and it can be a bit bothersome to have to explicitly declare them every time I want to use them. To me, it just slows things down and makes my code bigger. I can see justification on both ends of this issue. However, if explicit declaration is in the best interest of the language, then so be it. That's good enough for me, I guess.
it's nice to see what type the variable is just by looking at its suffix, so I don't have to scroll all the way up to find where I declared it, or start adding things like _string _integer and _long to the end of my variable names.
I completely agree with you here. To me, the suffix support was especially useful in reading other people's code as I could instantly tell the type of information being manipulated. This quickly allowed me to construct a mental picture of what's happening. Now, there's this constant back and forth between looking at code and then comparing it against declarations.

This feature was also extremely useful when dealing with numeric and string variables simultaneously within a code block. One things I liked was having two variables with the same name, but one being a string version of the other:

Code: Select all

dim char  as integer
dim char$ as string
Now to get this same type of clarity I have to do something like:

Code: Select all

dim charIndex  as integer
dim charString as string
It just seems like extra unnecessary typing. I think the area that this change has the biggest affect on, though, is in function delcarations that contain a large number of paramters. Take my rotozooming routine:

Code: Select all

declare sub img_roto_draw(x0 as integer,y0 as integer,cx as double,cy as double,sx as double,sy as double,ang as integer,alpha as integer,frame as integer,source as imagedat ptr)

vs:

declare sub img_roto_draw(x0%,y0%,cx!,cy!,sx!,sy!,ang%,alpha%,frame%,source as imagedat ptr)  
Having to writing out the name of the datatype for each parameter normally means you have about 8-12 characters between parameters, as opposed to 2 using a suffix. To me, this makes reading declarations more difficult and normally means I have scroll horizontally back and forth just to see all the parameters.

So, I guess the biggest thing is that I'm forced to develop new coding practices to accommodate these changes. Now that everything must be explicitly declared, where should I declare it. Should I declare every variable I will use in a code block before the code, making it easier to locate variable declarations, but more difficult to move chunks of code around?

Code: Select all

dim as datatype1 myVar1,myVar2, ... ,myVarN
dim as datatype2 myVar1,myVar2, ... ,myVarN
dim as datatype3 myVar1,myVar2, ... ,myVarN

...

'code block here

or do I declare variables only right before I will use them, effectively making it easier to move code around but more difficult to locate variable declarations?

Code: Select all


dim as datatype1 myVar1,myVar2, ... ,myVarN

'code portion 1 here

dim as datatype2 myVar1,myVar2, ... ,myVarN

'code portion 2 here

...

dim as datatypeN myVar1,myVar2, ... ,myVarN

'code portion N here

These are the types of situation we didn't really have to concern ourselves with before. I guess I'm just kinda glad that I'm not the only who was really surprised by these changes. It's funny how something that might seem like a minor change really isn't as it forces you to restructure how you code, in essence altering the language itself.

Though I think explicit declaration is debatable, I think having suffixes in some form is definitely beneficial, even if it is only in declaring variables. so:

dim x% would really just translate to dim x as integer, etc.

Hmm, I feel like you could create a macro for that, but I haven't messed with those much.
anonymous1337
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: California

Post by anonymous1337 »

This is a large topic in computer programming for me. I'd like to say a whole lot, but I'll keep it simple.

Programming languages now enforce good coding practice. It makes code easier to read and maintain. Compilers optimize very well now. Good coding practice can mean well-optimized code.

Bad coding practice, which often tries to develop rapidly or optimize manually (not that manual optimization is bad), is harder for the compiler to optimize. It's harder to debug and code becomes harder to maintain.


The idea is that code is going to not only be written once, but rewritten, expanded upon, and may require massive changes. Enforcing good coding practice means that the language itself can help programmers do these things.

I agree that for rapid development, modern coding methods may not be ideal. Class Libraries help here a lot though...
Eclipzer
Posts: 432
Joined: Oct 01, 2005 10:50
Location: Maryland
Contact:

Post by Eclipzer »

So...suffixes are bad coding practice?
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Post by MichaelW »

In my view using the QB suffixes is not a bad coding practice, but as a means of specifying/indicating the type of a variable they are now incomplete. Instead of trying to introduce new suffixes using more arbitrary, meaningless characters, I think it makes a lot more sense to use a simple system of prefixes that specify the type in some meaningful way, something like the system(s) that Microsoft typically uses for Windows code.
Eclipzer
Posts: 432
Joined: Oct 01, 2005 10:50
Location: Maryland
Contact:

Post by Eclipzer »

I think it makes a lot more sense to use a simple system of prefixes that specify the type in some meaningful way, something like the system(s) that Microsoft typically uses for Windows code.
I think it would be helpful if you elaborated here or at least posted a link to what you mean.
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Post by stylin »

Eclipzer wrote:...I often find myself repeatedly using variables i,x,y,u,v all the time in FOR ... NEXT loops and it can be a bit bothersome to have to explicitly declare them every time I want to use them.
FWIW, since v.0.17b, you can do,

FOR i AS INTEGER = ...

if you just need i for the duration of the loop.
Now, there's this constant back and forth between looking at code and then comparing it against declarations.
I don't use type suffix symbols, but I can see what you are talking about. Though, constant backtracking could be a sign that you have insufficiently descriptive variable names or unnecessarily complex algorithms or lengthy procedures.

The new (>= v.18.x) default passing conventions tend to create lots of this as well, particularly if you make use of type aliases; there's no way to be sure of how something is passed to a procedure without either looking up a declaration or explicitly specifying BYREF/BYVAL (which seems to make a mixed-default scheme rather useless and error-prone, IMHO).

A common practice for procedure declarations with numerous parameters is to make use of line-continuation, like,

Code: Select all

declare sub img_roto_draw ( _
    x0 as integer,          _
    y0 as integer,          _
    cx as double,           _
    cy as double,           _
    sx as double,           _
    sy as double,           _
    ang as integer,         _
    alpha as integer,       _
    frame as integer,       _
    source as imagedat ptr  _
)
arguably making both the types and the number of the parameters easier to see at a glance. Another common idiom is to package related parameters into one or more objects, and pass those instead.
Now that everything must be explicitly declared, where should I declare it.
Both of the methods you describe are used all the time. I think for the most part this is a style issue, but there are more advantages to declaring [and initializing] variables and objects when they are first needed. For example, you'll want to delay declaring objects that are expensive to construct at the beginning of a procedure if there is a chance the procedure could be exited early (invalid input, can't allocate some resources, etc.). And, since this method is generally more efficient when dealing with objects, I just follow it with my local variable declarations as well (I like to err on the side of consistency, if anything).

QBasic/QuickBASIC allowed multiple variables of the same name with different type suffix symbols. Combined with the implicit declaration, this used to get me in all kinds of trouble. I'd forget a type suffix symbol, or appended the wrong one by accident, and would have to search for the source of my error. Not fun, I'd rather take the time to state my intentions from the get-go, than take time in the debugger, but that's just me.

I could be wrong, but I believe MichaelW is referring to the hungarian notation used throughout the WinAPI (which makes me sick, bleh :)):
http://en.wikipedia.org/wiki/Hungarian_notation
Eclipzer
Posts: 432
Joined: Oct 01, 2005 10:50
Location: Maryland
Contact:

Post by Eclipzer »

FWIW, since v.0.17b, you can do,

FOR i AS INTEGER = ...

if you just need i for the duration of the loop.
I am quite aware of this and I have used it as well. I'm not sure if I really like it, however, from a stylistic stand point. Personally, I think this makes my nested loops look ugly. It just looks clunky to me. Regardless, this doesn't change the fact that you're still explicitly declaring the type, you're just doing it using FOR instead of DIM. Also, I believe i's scope here is limited to the FOR ... NEXT loop, which is nice to know, because I'm sure that can be useful in specific situations, but as heavily as I use these vars, if I have to declare them, I'll do so once:

Code: Select all

  dim as integer i,x,y,u,v 'declare all my iterators because I hate typing "as integer" 1000 times =)

  for i=0 to count-1
    for y=0 to height-1
      for x=0 to length-1
      next
    next
  next
constant backtracking could be a sign that you have insufficiently descriptive variable names or unnecessarily complex algorithms or lengthy procedures.
True. Of course, if I'm looking at code I didn't write, well that's not my fault is it?
A common practice for procedure declarations with numerous parameters is to make use of line-continuation, like,

Code: ‹ Select › ‹ Contract ›
Declare Sub img_roto_draw ( _
x0 As Integer, _
y0 As Integer, _
cx As Double, _
cy As Double, _
sx As Double, _
sy As Double, _
ang As Integer, _
alpha As Integer, _
frame As Integer, _
source As imagedat Ptr _
)

arguably making both the types and the number of the parameters easier to see at a glance.
I've seen this method and used it once or twice. From a style stand-point this seems like a waste of space to me. Though, I guess if you're only using it for the declaration, which you could stuff in a *.bi file anyway, it might work from a functionality stand-point. Typing out your declarations this way, or even breaking a single-line declaration into this format seems a bit time-consuming though. I really wish you didn't have to use an underscore to do this as well. It just doesn't look good. I mean, the parameters have to be placed between parenthesis anyway, so you've got your necessary character markers built into the syntax. So, why the underscore?
Another common idiom is to package related parameters into one or more objects, and pass those instead.
I've considered this, but I feel strongly against it for this purpose. It just doesn't strike me as a very user-friendly way to do things. You'd have to create your object and set the object parameters all before you pass it. Feels like too many steps.
there are more advantages to declaring [and initializing] variables and objects when they are first needed. For example, you'll want to delay declaring objects that are expensive to construct at the beginning of a procedure if there is a chance the procedure could be exited early
Agreed.
QBasic/QuickBASIC allowed multiple variables of the same name with different type suffix symbols. Combined with the implicit declaration, this used to get me in all kinds of trouble.
True. However, I don't see any trouble with using suffix symbols for explicit declaration. I liken this to the PRINT command, which has an optional symbol ? you can use to achieve the exact same thing. It's fast as hell. Do you have to use it? No, but it just saves a lot of time and space.

Code: Select all

' suffixes (optional) for declaration only
  dim myInt%
  dim myLong& 
  dim myDbl#
  dim mySgl!
  dim myString$
  
  ? myInt,myLong,myDbl,mySgl,myString 'no need to use suffixes here
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Post by stylin »

True. Of course, if I'm looking at code I didn't write, well that's not my fault is it?
Well, no, but I didn't think we were talking about other people's code.

I can type decently fast, but even if I couldn't I don't think I could notice a difference between one- and multi- line procedure declarations or calls, but that's just me. I think one of the developers was trying to add support for multi-line procedure declarations without underscores a while ago, but I didn't keep up with how that was going (IMHO it would be kinda nice, but why add [yet another] inconsistency to the language..). Using multi-line procedure declarations also allows you quick, dirty and compact code documentation opportunities:

Code: Select all

' Copies a number of bytes from one location to another.
declare function memcpy ( _
    byval dst as any ptr,       _ ' where to copy the bytes
    byval src as const any ptr, _ ' where to get the bytes
    byval n as uinteger         _ ' the number of bytes to copy
) as any ptr ' = dst
Probably overkill for something like memcpy, but it's a nice "feature" anyway.

Back on topic, I just see type suffixes as a bad idea. They seem very non-BASIC, just like @ versus VARPTR (even though I always use @, never the other address-of operators, nm..).

There is never confusion as to what "AS INTEGER" means.

There are no class suffix symbols, so the biggest benefit I see is quickly being able to tell numeric, string and class types apart. But again, that really shouldn't be necessary with descriptive variable names, elegant code structure and judicial commenting. (IMHO, if I can't tell whether some variable is a number/string/object, it either doesn't matter or it smells of bad design..)
Qlink
Posts: 79
Joined: Jun 06, 2007 15:21

Post by Qlink »

Back on topic, I just see type suffixes as a bad idea. They seem very non-BASIC, just like @ versus VARPTR (even though I always use @, never the other address-of operators, nm..).
I don't know about that... so I did a little research. Apparently type suffixes weren't in the original Dartmouth BASIC, but then there was only one data type in that early language. I do know that they were in AppleSoft BASIC on the Apple ][ and many other early microcomputer BASICs. To me, this makes them very BASIC like.
jevans4949
Posts: 1186
Joined: May 08, 2006 21:58
Location: Crewe, England

Post by jevans4949 »

Qlink wrote:... Apparently type suffixes weren't in the original Dartmouth BASIC, but then there was only one data type in that early language. I do know that they were in AppleSoft BASIC on the Apple ][ and many other early microcomputer BASICs. To me, this makes them very BASIC like.
They may not have been in the original, but the dollar suffix was certainly standard before microprocessor-base systems came on the scene. I think it was around in the late 1960's when I first learned, though I can't find documentation.

I think the original probabbly implemented all variables as 32-bit floating point, but some early microprocessor-based interpreters only did integer. The other type suffixes were probably invented by Microsoft, and certainly pre IBM PC.

EDIT: The DIM statement was originally only used for arrays - it is an abbreviation of DIMENSION.
anonymous1337
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: California

Post by anonymous1337 »

I think suffixes and a lot of these strange things BASIC has historically done is against the goals of BASIC... Same with quirky syntax :-P

And IMO suffixes are bad coding practice, or at least not good coding practice. It makes code messy, and being able to have char$ and char% is strange to me and even messier.
Post Reply