25 July 2012

Desktop Applications Again

PCWorld featured an article on changing habits of users of desktop, web, and smartphone software. Some quotes.

Cloud computing
"We had a thesis that people did not want to install software; that the cloud meant that people could use a browser to interact with software and would never have to install anything. We were completely wrong,” Jones says. “People love installing software"

The Web is out
No more Web-based applications: "But given what developers have discovered firsthand, we may see users clamor for native desktop apps, where they previously deemed Web apps to be sufficient."

Also read the blogs referenced in this article. GFA-BASIC 32 survived its time.

18 July 2012

How does GB32 define a word?

Did you ever realize how GB32 defines a word? Is it consistent across the different editor operations? Does a Ctrl-Left keyboard shortcut point to same word start as Ctrl-F? The Ctrl-F accelerator shows the Find Dialog Box where the Find What edit text control defaults to the current word. Is this the same word that is used in Ctrl-Left and Ctrl-Right actions? And what about the mouse double-click? What word does the editor use for the FindNextWord, to locate the next occurrence of that word? An example.

Global iVar1% = $4DC41C
Dim dd As Double = 2.45!

The next table shows the result of the 'current word' used to start the operation.

Word Ctrl Right Find Dlg Double Click
Global Global Global Global
iVar1% iVar1% iVar1 iVar1%
$4DC41C 4DC41C 4DC41C $4DC41C
2.45! 2.45! 2 2 or 45, depending on the position of the caret

Disturbing? At least confusing, because it isn't consistent. To me the whole module containing the editor's find and replace code seems a bit clumsy. (Maybe Frank Ostrowski was somewhat distracted during its development.) I can only guess what leaded to this inconsistency. The $AutoPostFix directive may have caused the decision to use the variable name without a postfix with the Find Dialog. Anyway, I don't like it. In my opinion all operations that determine a word should select the same word and the green marked words seem to be best candidate.

If there would be separate functions that return the current word, it would give me a starting point. Unfortunately, all operations mentioned above have their own getcurrentword algorithm. Another set back, by now I hoped to have had implemented the COM support I promised.

16 July 2012

Efficiently building a String

If you need to build a string by adding lots of pieces together, GFA-BASIC's string handling is relative slow because a new string is created in memory every time a new piece is added.

Often, alternatives are used like string builder functions. String builders allocate a string chunk and then uses memory copy methods to manipulate the data within the same string's memory. You'll find them in all frameworks and libraries of popular programming languages.

GB32 offers an efficient string builder as well, although it is bit hidden. The sprintf() function reserves a chunk of stack memory and uses memory copy functions to copy characters form the source string to a destination string. When it hits on a data placeholder in the source string it copies the data into destination string. Only when all characters and data are copied to destination buffer, the stack buffer in converted to a an actual String.

The difference between the two methods is illustrated below:

Dim sEdPos As String
' Assemble a caret position in a long
Dim EdPos As Long = MakeLong(12, 1)
' Put the string together
sEdPos = "Line: " + Dec(HiWord(EdPos)) + _
  " Column: " + Dec(LoWord(EdPos))
' Or use sprintf()
sEdPos = sprintf("Line: %d Column: %d", _
  HiWord(EdPos), LoWord(EdPos))

12 July 2012

(GB/VB)BASIC isn't dead

You are invited to visit "TIOBE Programming Community Index" at : http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

See the trends in computer language. Right now plain C enjoys the first position, with Java and C++ slowly going down and Objective-C going up. (Visual) Basic remains steady at position 6. Don't confuse it with VB.NET, which is located at position 15. But VB.NET has an increasing audience also.

07 July 2012

Write # or Print #

Why does the GB32 Hash type use Write to save the data from a hash table (= dictionary)?

The correct answer is: In contrast with Print #, Write # uses a non-locale format. In Basic we often choose Print # over Write #, but both have their own goal. It has even been suggested that Write is a relic from prehistoric BASICs. However, this isn't true. To be able to correctly read data from a file into variables using Input #, use the Write # statement instead of the Print # statement to write the data to the files. Using Write # ensures each separate data field is properly delimited.

Both, the Print # and Write # commands, can be used to write data to a sequential text file, however the commands cause the information to be written to the text file differently.

The Write # statement is used to write raw data to the text file as comma- delimited and has the following syntax:

Write #filenumber[,outputlist]

All data written to the file using Print # is internationally aware; that is, the data is properly formatted/converted using the appropriate decimal separator. The syntax is similar, but the result quite different.

Print #filenumber[,outputlist]

Difference 1 – Quotation marks
The Write# command places quotation marks around all text values (strings), but not numeric data. The Date fields are surrounded with #s (pound signs). 
The Input# command is used to retrieve values from a text-only file created with the Write# statement (removes quotation marks from strings).

The Print# command does not enclose the data in quotation marks.

Difference 2 – Delimiter
The Write # command separates two or more values on the same command line with commas.The Print # command separates two or more values on the same command line (separated by a comma) with a tab character.

Print # writes an image of the data to the file, you must delimit the data yourself so it prints correctly. If you use Tab (or a comma) with no arguments to move the print position to the next print zone, Print # also writes the spaces between print fields to the file.

Advantages of Write
When using Write # to write data to a file, several universal assumptions are followed so the data can always be read and correctly interpreted using Input #, regardless of locale:

  • Numeric data is always written using the period as the decimal separator.
  • For Boolean data, either #True# or #False# is printed. The True and False keywords are not translated, regardless of locale.
  • Date data is written to the file using the universal date format. When either the date or the time component is missing or zero, only the part provided gets written to the file.
  • Nothing is written to the file if outputlist data is Empty. However, for data, #Null# is written.
  • If outputlist data is Null data, #Null# is written to the file.
  • For Error data, the output appears as #Error errorcode#. The Error keyword is not translated, regardless of locale.

To get your memory refreshed, look at the following code:

OpenW 1
Write App.Name          // "NoName"
Write CFloat(3.2)       // 3.2
Write CDate(Now)        // #2012-07-11 12:42:33
Write CBool(0)          // #False#
Write CHandle(0)        // #Null#
Write CFloat(3.2), Date // 3.2,#2012-07-11 12:42:33

' Print inserts a space at the front of a number
Print App.Name          // NoName
Print CFloat(3.2)       //  3.2
Print CDate(Now)        // 11-7-2012 12:42:33
Print CBool(0)          // False
Print CHandle(0)        //  0
Print CFloat(3.2), Date // 3.2      #2012-07-11 12:42:33

Unlike the Print # statement, the Write # statement inserts commas between items and quotation marks around strings as they are written to the file. You don't have to put explicit delimiters in the list. Write # inserts a newline character, that is, a carriage return–linefeed (Chr(13) + Chr(10), after it has written the final character in outputlist to the file.

If, at some future time, you want to read the data from a file using the Input # statement, use the Write # statement instead of the Print # statement to write the data to the file. Using Write # ensures the integrity of each separate data field by properly delimiting it, so it can be read back in using Input #. Using Write # also ensures it can be correctly read in any locale.