Portability and Power with the F Programming Language
Starting with an internationally standardized programming language as a base, we set out to create the world's best programming language. Any lesser goal would result in an interesting but not a challenging exercise.
Designing a programming language involves thousands of ideas and decisions. Tradeoffs are constantly weighed between efficiency (both compile time and run time), readability, flexibility, familiarity, brevity, redundancy, implementation (compilers and tools), style, elegance, completeness, internationalization, standardization, marketability and target audience, to name just a few. The above facts and myths and the principles listed below helped us to avoid personality conflicts (mostly) and reach decisions based on these goals:
Learnability without loss of professional power
Portability and maintenance of large programs
Minimizing unimportant syntax
Requiring words instead of relying on defaults
A pleasant surprise to the biased authors is the pure elegance of F.
Except for assignment (=) and pointer assignment (=>), the first word of every F statement identifies the statement. All keywords are reserved words, allowing for specific error messages for incorrect syntax or misspelled keywords. Table 1 categorizes all the F statements. The diagram shows that every F procedure, either a subroutine or a function, is contained in a module.
In F, a distinction is made between functions and subroutines. Functions are not allowed to have “side effects” such as modifying global data. All function arguments must be intent(in); subroutine arguments can be intent(in), intent(out) or intent(inout). The intent is required on all procedure arguments, allowing the compiler to check for misuse and forcing both the beginner and professional to document the intentions.
The intrinsic types in F are integer, real, complex, character and logical. User-defined types can be constructed from the intrinsic types and user-defined types. For example, a person can be constructed to have a name, height, phone number and pointer to the next person. Users can define operators which operate on intrinsic and user-defined types.
The attributes of an intrinsic or user-defined type in F are shown in Table 2. Pointers are strongly typed. That is, pointers can point only to objects that are targets. Although this idea makes solid pedagogical sense, the words pointer and target originated for the purpose of better compiler optimization.
A sophisticated array language facilitates operations on whole arrays, contiguous and noncontiguous sections and slices of arrays. For example:
arr(5:1:-2, 3, 6:)
is a reference to the two-dimensional array created by taking the elements 5, 3 and 1 in the first dimension of arr and elements from 6 to the upper bound of the third dimension of arr, all in the third plan of the array. If arr is a 5 by 6 by 7 array, the referenced elements would be (5,3,6), (3,3,6), (1,3,6), (5,3,7), (3,3,7), (1,3,7).
A simpler example that calculates the sum inner product of a row and a column is shown here:
A(i,j) = sum(B(i,:)*C(:,j))g
sum is one of the more than one hundred intrinsic procedures found in F.
Modules are at the core of all F code. Modules are a data encapsulation mechanism that allows data to be grouped with the procedures that operate on that data. Modules can use other modules. As well, programs and procedures can use modules. Using a module makes the public entities of that module available. Examples of modules are found in Table 3.
One does not instantiate an instance of a module as one does with a class in C++ or Java. Instead, the concept of an object is best viewed as a module that defines a public, user-defined type together with the public procedures that operate on that type. The user of such a module can then declare a scalar or array of the defined type and have access to its procedures.
A public, user-defined type can be defined to have private components, so that the type and its procedures can be referenced; however, the parts that make up the type are private to the defining module.
- Bruce Nikkel's Practical Forensic Imaging (No Starch Press)
- Transitioning to Python 3
- Progress on Privacy
- Stepping into Science
- Linux Journal December 2016
- Radio Free Linux
- The Tiny Internet Project, Part II
- CORSAIR's Carbide Air 740
- FutureVault Inc.'s FutureVault
- A Better Raspberry Pi Streaming Solution