Mike said:
I'm curious about the ten percent that would have to be thrown out ... If [100% backward compatibility with FoxBASE+ and FoxPro for Windows is required], wouldn't you need to keep 100 percent of the language?
It's been over a year since I considered any of this stuff. I don't remember all the details.
There were a lot of features added post VFP6 that I'd throw out. Some probably common use features (like ActiveX/OLE support so it would work on other platforms -- though I would provide similar support through supplied DLLs which handle common things, allowing also for developers to code and contribute their own extensions back to the community), some of the reporter abilities (though I would replace the reporter with something far more WYSIWYG and flexible to use), some SQL engine enhancements, several things I can't remember off the top of my head.
I would add:
Code:
SET FREEPRO TO [FB,FW,V3,V6,V9]
* Emulate FoxPro at these levels:
* FB = Multi-User FoxBASE+ 2.1
* FW = FoxPro for Windows 2.6
* V3 = Visual FoxPro 3.0
* V6 = Visual FoxPro 6.0
* V9 = Visual FoxPro 9.0
* (no support for 5.0, 7.0 or 8.0)
This would allow certain functions to behave as they did in those particular versions. These can be set while the code is running.
I would alter the way some things are done today so they aren't quite as obtuse. For example, ICASE(). Having a sequential series of parameters is obtuse. Instead, I would devise a definition which allows for the test conditions and then multi-line code snippets to be created (similar to way DEFINE CLASS works today, but it would be DEFINE ICASE name), which then would be referenced by name in the ICASE() statement.
Code:
DEFINE ICASE myicase
[LPARAMETERS lxTest]
[RETURNS lcReturn
* Whatever value lcReturn has at the end is what's returned]
* Can have explicit RETURN clauses at any point
CASE condition1
* code goes here
CASE condition2
* code goes here
OTHERWISE
* code goes here
ENDDEFINE
* Use in code:
k = ICASE(myicase[, variable])
* the ", variable" portion is not needed as myicase will
* inherit the current data environment plus variable state.
* Double-click on "myicase" in the ICASE() statement to
* edit its definition.
In source code the GUI editor would present it as a popup or tooltip (similar to the way memo fields pop up with Ctrl+PgUp in a browse window). That way the code can be multi-line, vertical, spread-out, formatted, easy to observe, easy to line debug, and with full support of multiple commands per case condition, etc., with the end result being a complex case condition able to be used easily as an immediate.
Things along those lines are mostly what I mean by throwing some things out and adding my own stuff, though some of my own stuff would include tables as objects. Records as objects. Fields as objects. Memory variables as objects. Basically everything as an object, able to have objects added to them, method code, event responses, including triggered global and local user events.
All of this is in addition to supporting the standard syntax used today.
A new data storage format would be added to explicitly indicate what type and size I want to store my variable as, such as integer, unsigned integer, floating point, character string, unicode string, etc., and I would provide full conversions between types.
Code:
* Store 1234 as a native type without explicit form
foo = 1234
* Store 1234 explicitly as a 32-bit unsigned integer quantity
* Note: This now allows over-/under-flow events to be
* thrown (see addEvent() below).
foo.u32 = 1234
* Store 1234 as a 64-bit floating point quantity
foo.f64 = 1234
* Store .t. as a text string
foo.c = .t.
* Store "hello world" as unicode
foo.u = "hello world"
* Store current contents as unicode (if not already)
foo.u = foo.as(u)
Other such options.
Objects make it possible:
Code:
foo.alltrim && same as foo = ALLTRIM(foo)
foo.release && same as RELEASE foo
* Add an object to a variable
foo.addObject("Name", "Data tag to go with it, can be anything")
* Add method code to a variable
foo.addMethod("name", reference to code when called)
* Specify that this variable should respond to an event
foo.addEvent("event name", reference to code when called)
* Create multiple clones of itself, which for mere data is
* only of mild interest, but if objects, events or methods have
* been added to a variable, can be more powerful (see below)
foo.clone(newvar1, newvar2, newvar3)
* And of course
foo.saveAsClass(...)
Assignment within use:
Code:
* Today:
foo = 1234
sam = foo * 4
* FreePro:
sam = foo.(1234) * 4
The object nature of everything makes a lot of possibilities.
Other additions are synchronous debugging between two machines, remote debugging, real-time variable monitoring (debugger doesn't have to have code paused to examine variable contents, but continues to examine variable contents while running).
Lots more. Can't remember them all right now. Visual FreePro was well thought out. I may push the code to github in the near future regardless. The object/class structure and program stack I've developed may be useful to another project anyway.
Best regards,
Rick C. Hodgin