FRED Notes.
For better viewing maximize this frame's area dragging its top & bottom borders. You can hide the top logo and bottom menu. Re-sizing the side borders restores the original frame height. You can also use the navigation keys for scrolling rather than using the mouse.

Understanding FRED starts with a internalization the Fraemwork user interface, a few basic syntax and programming rules and a lot of experimentation. Interactive experimentation will make object and selection-based programming in an event driven environment using interpreter technique accessible. Following are few starting points.

Framework VII unified environment and interface is the reason for its power. Frames of any type can be moved freely between containers. Data of any type can be updated, retrieved, and moved freely between different frame types as well as referenced and expressed as text or quantitative values.

FRED, the Framework VII computer language, is part of this integration. Spreadsheet formulas, database filters, and Library functions are some aspects of the language but FRED can do much more. FRED, can programmatically access any and all the objects in Framework VII, just as you can manually using your eyes, ears (if you are using a vocalizer) and fingers - only that FRED can do it faster, more efficient, and with abilities to sense properties and action results - not available to a human operator. More, FRED can read and parse as well as construct text. It can evaluate text as program code, as well as read and parse text that is not code. In fact you can instruct FRED to understand your own language or even create code. And whether you are a novice with no programming knowledge or a seasoned object-oriented programmer, FRED and Framework provide you with possibly the only interactive, object and function-based, text-aware, interactive visual programming environment, with selection capabilities, non-linear access in an hierarchal contextual polymorphic organization of encapsulated data and code. The above gobble-gook and even terms not mentioned above such as "context based" may be safely ignored while experimenting with FRED but the experience will probably be relevant for a deeper understanding of all those issues (if you care to).

With FRED you could write a program that calls up an Internet or BBS stock service and downloads stock quotes. The FRED program could then read the quotes into a spreadsheet, generate graphs, prepare reports for distribution, and distribute the reports to the appropriate parties by electronic mail. Most importantly, this could all be done automatically, and may include adequate responses to communication failure or irregular data! When irregular data is received the program may attempt to find clues to its origin such as email addresses or names and deliver them with the appropriate alarm. Such program may also use some of FRED large number of modifiable functions designed to provide specific functionality. As an example, a number of functions provide translation between numbers and touch-tone on line instructions signals. With FRED telecommunication functions it is possible to create a stock trading system that prepares touch tone instruction with corresponding printed reports constructing a pick-list of signals. Such program for example will allow a user to select and send touch tone signals into a phone line to perform trades.

This would not be a trivial program, nor would it be easy to write. However, this example illuminates the significant potential of using FRED.

As you work with Framework VII, you will begin to find certain tasks that you perform frequently. You can automate many of these with keystroke macros. (Even a keystroke macro is a small FRED program) In a macro, you systematically tell Framework VII what keys you want FRED to execute. When you press the key that activates the macro, Framework VII recalculates the frame in the Library that contains your program. There comes a point, however, when keystroke macros are not enough. You may want to have a particular key executed when a certain condition is met, otherwise another key should be used. This is where FRED programming begins.

A FRED program may be typed anywhere in Framework V. A simple program may be used to load a file to the desktop:

@fileload("C:\AUTOEXEC.BAT")

The built-in function @fileload received a parameter of the type string (a string of characters) representing a DOS pathname. Simply type this expression, highlight it, and press F5. AUTOEXEC.BAT will be loaded to the desktop and the function result, = #TRUE, will be typed to the right of the selected expression.

Before we continue, note that while the above expression can be executed by highlighting its actual text in a frame text area (as well as anywhere else) and pressing F5, the more elaborate, multi-line programming examples presented here should be typed in a formula area of a frame and run by pressing the F5 key on the frame border. This will allow FRED to highlight syntax errors or undefined references in the code.

By typing the above expression in a formula area of a frame you created a program or a function. It can be run by pressing F5 on or inside the frame or by calling the frame by its name using the @ sign. @myprogram will execute the formula behind the frame MYPROGRAM. Double @ as in @@myprogram will execute the content of MYPROGRAM, allowing a single frame to contain two programs, one in its formula and the other in its content area.

However, FRED power is in its ability to sense - and just like a dog, it does it better than a human. In this case we want FRED to check for the program result and tell us (as well as other part of the program) if the file was or was not loaded. We may want to identify and report the reason for it taking an appropriate (albeit pre-defined) measures. We start by rewriting the program:


@if(@fileload("C:\AUTOEXEC.BAT"),
@prompt("AUTOEXEC.BAT was loaded")
@prompt("Warning!!! AUTOEXEC.BAT was N-O-T loaded!")
)

@fileload returns #TRUE if it succeed in loading a file or #FALSE if it failed. @if will receive the result of @fileload which, as @if's first parameter, will determine if it will execute its 2nd parameter (the if parameter) or its 3rd (the else parameter).

But there is not much of a point in having the program giving a warning but taking no corrective actions. We want a remedial program.
The following program will create a new AUTOEXEC.BAT if one does not exists. It also reports the action taken.

@if(@fileload("C:\AUTOEXEC.BAT"),
@prompt("AUTOEXEC.BAT was loaded"),
(@pk("{Ctrl-Out}{MENU#CE}AUTOEXEC{Return}{In}REM created by FRED "&
@date1(@now)
),
@if(@writetextfile("C:\AUTOEXEC.BAT",AUTOEXEC)=0,
@prompt("AUTOEXEC.BAT was created and written to drive."),
@prompt("AUTOEXEC.BAT was NOT written to drive.")
)
)
)

If the file is loaded @if displays the message calling the first @prompt. It takes no farther action albeit it still reads the rest of the program, something we can and may want to prevent in some cases.
On the other hand, upon a failure to load the file, @if's 3rd parameter, consisting of a list of three expressions - the two functions, @pk and @if enclosed in parentheses, would start by performing keys (@pk) that move the cursor to the desktop level, creates a frame, name it, move inside, types a remark, converts today's date (@now) to a string (@date1), and types it. It then attempt to write the frame to disk as a text file. The program finishes by presenting a messages to the user - if no error was detected (@writetextfile=0) the first message is shown. In case of an error a warning (the 2nd message) is given.

Interpreter Technique.

Note however that while only one of the three messages in the above program will be shown upon finishing, FRED read all 3 messages in their entirety. Even if the first message is the only one to be shown after the file was loaded successfully the last two messages are still read since FRED must find out where the program ends - which is at the last closing parenthesis.

Think about it as a true real-time operation. If the beginning of a program happened to modify the program's end the new code will end up running. In fact it is normal for FRED to write and run its own code continuously.

You can of course use a classic approach and break the above program to a number of elements. Three frames contain the three message strings, OK, CR, NO.


OK contains "AUTOEXEC.BAT was loaded"
CR contains "AUTOEXEC.BAT was created and written to drive."
NO contains "AUTOEXEC.BAT was N-O-T written to drive."

@if(@fileload("C:\AUTOEXEC.BAT"),
@prompt(OK),
(@pk("{Ctrl-Out}{MENU#CE}AUTOEXEC{Return}{In}REM created by FRED "&
@date1(@now)
),
@if(@writetextfile("C:\AUTOEXEC.BAT",AUTOEXEC)=0,
@prompt(CR),
@prompt(NO)
)
)
),

This shorten the program and speed it up but does not save on memory needed to store the program and its data.

Another classic and more practical approach. Since chances are that in most cases we end up loading a file, we stop the program if the file is loaded using @return.

@if(@fileload("C:\AUTOEXEC.BAT"),
@return(@prompt(OK)),
(@pk("{Ctrl-Out}{MENU#CE}AUTOEXEC{Return}{In}REM created by FRED "&
@date1(@now)
),
@if(@writetextfile("C:\AUTOEXEC.BAT",AUTOEXEC)=0,
@prompt(CR),
@prompt(NO)
)
)
)

However, using @return prevents us from adding more code in the same formula. @return ends the run of this function and return control to the calling program, hence, we must call this program from another frame. A larger issue is the obvious redundancy of code and data. The three occurrence of @prompt and the words that appears more than once should be consolidated. Taking advantage of FRED parsing and nesting we will optimize the above program for speed and size:

@local(F),
@prompt((F:="C:\AUTOEXEC.BAT")&" was "&
@if(@fileload(F),
"loaded",
(@pk("{Ctrl-Out}{MENU#CE}AUTOEXEC{Return}{In}REM created by FRED "&
@date1(@now)
),
@if(@writetextfile("C:\AUTOEXEC.BAT",AUTOEXEC)=0,
"created and written to drive.",
"N-O-T written to drive."
)
)
)
)

F which is a dynamic variable (it will be dynamically disposed of at the end of the program and its memory released) is assigned the string "C:\AUTOEXEC.BAT" which is part of all three messages. But there are still few more redundant parts among the three final messages the program may generate. More, the F string can be used more than once. The aim is avoiding data and code redundancy. Having @prompt typed only once and relying on FRED to construct a single text string shifts the execution effort to the faster parts of FRED, the parser and evaluator. FRED operates not only as a text interpreter but also as a text constructor.

@local(F,R),
@prompt((F:="C:\AUTOEXEC.BAT")&" was "&
@if(@fileload(F),
"loaded from",
(@pk("{Ctrl-Out}{MENU#CE}AUTOEXEC{Return}{In}REM created by FRED "&
@date1(@now)
),
@if((R:=@writetextfile(F,AUTOEXEC))=0,
"created and",
"N-O-T"
)&" written to"
)
)&" drive."
,-1),
R=0

Note that the above programs, typed anywhere in Framework VII, may be selected in its entirety using the mouse or the extend select key and executed by pressing F5. The ability to select and run code is useful for quick experiments and testing but to have any practical value as a usable tool a program must be typed info a formula of a frame. This encapsulate the program in a code object allowing calling it from other routines and combining it as part of larger programs. Positioning a code object frame inside other frames determines which other data and code objects are accessible by it. We can also replace "C:\AUTOEXEC.BAT" with a parameter place holder, @item1, which will convert this function to a universal file-loader-creator tool. A second place holder for a parameter that will determine the name of the frame to be written by @writetextfile represent a problem since @writetextfile expect a name-reference type as its second parameter and will not accept a string.
The solution is to convert the string to a reference using @str2ref(@item2). The following program can no more be selected and run since it expect parameters. It must be called from another program. This is why we did not include parameter passing in previous examples.

@local(F,R),
@prompt((F:=@item1)&" was "&
@if(@fileload(F),
"loaded from",
(@pk("{Ctrl-Out}{MENU#CE}"&@item2&"{Return}{In}REM created by FRED "&
@date1(@now)
),
@if((R:=@writetextfile(F,@str2ref(@item2)))=0,
"created and",
"N-O-T"
)&" written to"
)
)&" drive."
,-1),
R=0

We also added a second parameter ,-1, to @prompt which tells it to position the message at the screen center. Note that we also added a variable named R in order to make the program return #TRUE if the file was loaded or successfully written to disk. R is automatically assigned 0 when created. Receiving the result of @writetextfile it will be assigned an error number other than 0 only if an error occur. The parentheses enclosing R:=.. determines the execution order and preventing R from Receiving the rest of the string.

The result of the last expression in the program, R=0, #TRUE or #FALSE, will be displayed in the program frame or will be returned to the calling program as this program returned value. You can see the interpreting power of FRED. The above program is constructing meaningful, albeit simple, text, based on events that may or may not take place at execution time.

The final version adds prototyping with default values using a built-in function. It stops the program and return an error if no first parameter was sent. It also retrieve automatically a frame name from the first parameter DOS pathname by isolating the characters following the last \ (or : if the path is to the current directory) in the pathname.

@local(File,Ret,FrameName,Char),
File:=@iferr(@item1,
@return(#N/A!)
),

Char:=@if(@scan("\",File)=#N/A!,
":",
"\"
),
FrameName:=@mid(File,@rscan(Char,File)+1,@len(File)-@rscan(".",File))
@prompt(File&" was "&
@if(@fileload(File),
"loaded from",
(@pk("{Ctrl-Out}{MENU#CE}"&FrameName&"{Return}{In}REM created by FRED "&
@date1(@now)
),
@if((Ret:=@writetextfile(F,@str2ref(FrameName)))=0,
"created and",
"N-O-T"
)&" written to"
)
)&" drive."
,-1),
Ret=0

To test the expression

@mid(File,@rscan(Char,File)+1,@len(File)-@rscan(".",File))

Simply highlight and calculate an following equivalent expression,

@mid("C:\DIR\ABC.XYZ",
@rscan("\","C:\DIR\ABC.XYZ")+1,
@len("C:\DIR\ABC.XYZ")-@rscan(".","C:\DIR\ABC.XYZ")
)

to see =ABC

You can experiment by calculating parts of the above line, select and calculate
@rscan("\","C:\DIR\ABC.XYZ") to see =7.00
select and calculate
@len("C:\DIR\ABC.XYZ")-@rscan(".","C:\DIR\ABC.XYZ") to see =3.00

Note that highlighting ( or ) and pressing Ctrl-F5 verifies and select an enclosed area. Highlighting a function name and pressing F1 will display its reference, usually with programming examples that can be pasted into your code.

Other pages with FRED related discussions are available on this site.