FoxPro, or VisualFoxPro, is an object-oriented ISAM DBMS currently owned by, but not originating from Microsoft. It's a derivation of early ExBase.
from Microsoft
Well, not really. From David Fulton's "Fox Software" originally based in Ohio. Microsoft bought them when they were clearly kicking everyone else's butt in the desktop DBMS space.
MS purchased FoxPro for two purposes it appears: First, as a hedge in case MS-Access didn't fly in the market (it was in production at the time), and second, to obtain the "Rushmore" performance enhancement technology, which was used in other MS products.
It is first a language (a dialect of xBase), second a DBMS. It doesn't get down on the hardware, but boy, can it sling data.
The "object-oriented" overlay has really done little to enhance the language or the engine.
Yes, the last two versions from FoxSoftware before MicroSoft bought them (2.0 & 2.5) added the table-based storage of screens and reports as well as a subset of SQL (nicely enhanced with some language integration features).
This stuff was deleted for some reason. I put it back.
I think FoxPro blew an opportunity to maximize the use of DataDictionary(s) and ControlTables in place of objects for GUI's, reports, etc. Version 2.6 actually used tables to store screen and report setups (although it was not documented in the formal manuals and appeared a little rushed); but they did not continue with that tradition when they OO'd it for version 3 and on. It could have been something unique, instead becoming a me-too product.
- I thought I spotted some tabled GUI elements in VisualFoxPro 5 also.
The above statement is incorrect. The Visual versions still store screens, report, visual class libraries, project and intellisense information in Fox tables. They are 'free' tables not tables that belong to a database container. Someone may have deleted the statement because it is incorrect.
It can tend to polarize conversations. ("It's a toy." - "No, it's not." - "Is too." - "Is not.")
As a language xBase sucked. In that sense it *was* a toy. However, its strength was integrating tables into the language and making tables easy to create, browse, and program. If you use tables to organize your applications, then the weakness of the language mattered less. However, it generally lacked views and other virtual tools of relational theory. But that also made it fast in the age of 386's. They later added SQL support, I would note.
I fed my family for almost 10 years with this toy. Not bad for a "hopelessly inadequate" language/DBMS as some of its critics have termed it. Its ability to interactively debug a concept before committing to an approach was something I valued highly.
For an (admittedly poor) example of FoxPro 2.5 (for MsDos) code, see http://josako.freeservers.com/tech/FoxPro/ - JayOsako
RPN Calculator Example (originally posted on usenet)
Here is a quicky FoxPro-based Reverse Polish calculator script that uses a table to define the buttons and their action. Given a choice, I would probably have used parameters to pass around more record references instead of leaving it to global context (one of XBase's S.E. weaknesses) For example, passing around a PHP-style associative array for references to the looked-up Keys (a table) record.
It only does integers, and the validation is rather skimpy. Also, I don't really need the "Op" column since the operations happen to fit the display characters. However, I assumed that they could be different, such as displaying "X" for multiplication instead of an asterisk.
(Shayne originally requested floating point. I skipped that this time around and just did integers because it would have added more validation and formatting nitty gritty that I thought perhaps distracted from structural issues. I hope this is not a problem. Also, some news-readers may mangle the formatting and indentation. If so, I apologize. Try a Courier font if you have problems. Tabs also somehow got mixed in, and you know what they do to formatting.)
Regarding this line here:
calc = operand1 &theOp operand2
The single ampersand implies a syntactical substitution. Thus, if theOp is "+", then this gets executed:
calc = operand1 + operand2
Note that I still don't consider this example very representative of applications that I encounter. But, I thought it might be interesting to see what and how people think of it.
(begin program code)
***** Procedure calculator
set compatible foxplus
set readborder on
set deleted on
set exact on
set confirm on
set safety off
close data
select a
use keys.dbf alias keys
select b
use stack.dbf alias stack
zap
butno = 0
dusplay = "" && number display ("display" is a reserved word)
*---define GUI window and event handling
IF NOT WEXIST("form1")
DEFINE WINDOW form1 ;
AT 8, 40 ;
SIZE 14,28 ;
TITLE "Calc" ;
FONT "Courier New", 10 ;
FLOAT ;
CLOSE ;
MINIMIZE ;
SYSTEM ;
COLOR RGB(,,,192,192,192)
ENDIF
activate window form1
&& displays buttons generated from table
select keys
scan
temp = charcode
tempparm = '"' + charcode + '"'
@ Yloc, Xloc get butno ;
picture "@*HN " + temp valid butpress(&tempparm)
endscan
activate window form1
read cycle modal
return
*--------------------
procedure butpress
parameter theKey
select keys
locate for upper(keys->charcode) = upper(thekey)
do case
case keys->optype = 'K' && digit constants
dusplay = dusplay + charcode
case keys->optype = 'C' && commands
do commands
case keys->optype = 'P' && math operation
do operations with keys->op
endcase
&&----display update
@ 1,1 say dusplay + space(25 - len(dusplay))
show gets
return
*--------------------------
procedure commands
do case
case keys->charcode = 'P' && push
do push with dusplay
dusplay = ""
case keys->charcode = 'C' && clear
dusplay = ""
case keys->charcode = 'Q' && quit
deactivate window form1
close all
cancel
endcase
return
*--------------------------
procedure operations
parameter theOp
raw1 = pop()
raw2 = dusplay
raw1 = iif(empty(raw1),'0',raw1) && convert blank to zero
raw2 = iif(empty(raw2),'0',raw2)
operand1 = val(raw1)
operand2 = val(raw2)
&& [insert division by zero check here]
calc = operand1 &theOp operand2
dusplay = ltrim(str(int(calc)))
return
*--------------------------
procedure push(pushme)
select stack
append blank
replace thevalue with pushme
return
*--------------------------
function pop
select stack
result = ""
goto bottom
if .not. eof()
result = stack->thevalue
delete
endif
return(result)
*--------------------------
(end program code)
Table: Keys
Charcode Optype Op Descript Xloc Yloc
0 K 5.00 10.00
1 K 5.00 4.00
2 K 10.00 4.00
3 K 15.00 4.00
4 K 5.00 6.00
5 K 10.00 6.00
6 K 15.00 6.00
7 K 5.00 8.00
8 K 10.00 8.00
9 K 15.00 8.00
P C Push 10.00 10.00
+ P + Plus 20.00 10.00
- P - Minus 20.00 4.00
* P * Times 20.00 6.00
/ P / Divide 20.00 8.00
C C Clear 15.00 10.00
Q C Quit 5.00 12.00
The other table, "stack", has only one column, "theValue".
[formatting re-work in progress]
-Top-
For anyone who cares, I have a tape calculator I wrote back in the Cretaceous (Fox 2.5b), that exhibits fairly ordinary desktop 10-key calculator behavior, except that it allows editing of the tape.
See also VisualFoxPro, ExBase
CategoryProgrammingLanguage, CategoryExample