QFC is short for Quick Functional C. It's a simple parser that automatically reads and does some basic operations on your code, making writing functional Code in C easier.
You will need a gcc refernce in your path to compile the C code that QFC generates. QFC automatically compiles the code it generates.
- Clone this repo
cd qfcqfc <yourcode.qfc>
- Clone this repo
cd qfcgcc qfc.c -o qfc.exeORgcc qfc.c -o qfc.outIf you are on Lunux.qfc <yourcode.qfc>
QFC simply generates C code from easily written Functional-like Code.
It automatically puts struct keyword everywhere, automatically resolves contructor calls, and automatically marks all variables, all function arguments as const.
| QFC | Generated C |
|---|---|
Imports import stdio, string; |
#include <stdio.h> #include <string.h> |
Struct Declarations struct String( int length, char val[MAX_LENGTH]); |
struct String{ const int length; const char val[MAX_LENGTH];}; |
Assuming Above String Struct is defined, String t = String(5, "YOLO"); |
const struct String t = (struct String) {5, "YOLO"}; |
Function declarations int plus(int a, int b){ return a + b; } |
int plus(const int a, const int b){ return a + b; } |
A more Functional Aproach: struct Integer( int val );Integer plus(Integer a, Integer b){return Integer(a.val + b.val);} |
struct Integer{ const int val; };struct Integer plus(const struct Integer a, const struct Integer b){return (struct Integer){a.val + b.val};} |
Struct Declarations like these are designed to look like contructor calls. All local variables are automatically declared const. This is to make your code as immutable as possible, you can't dedclare a variable and then assign it somehting. The following is not a valid syntax for QFC.
Splitting primitive variables into declaration and assignment is not allowed and will lead to errors. This happens because strust types are not allowed to have seperate assignments, so declaring mutable primitives could be done. Therefore, it makes sense to me that this should be not allowed in general.
int a;
a = 5;
Such a splitting of declaration and assignment is not encouraged and hence its support is not planned.
Check the test.qfc to see an a live example of a Lambda Expression. Also check code.c
to see how it gets parsed.
A function that takes a Function as parameter is declared as follows:
void mapIntToFloat(float mapper(int)){
mapper(5); //Call given function
}
//somewhere else in the code
mapIntToFloat(float (int a) => { return (float)a; });
//Generated C Code:
float Lambda0(int a) { return (float)a; };
mapIntToFloat(Lambda0);
Also note that all local variables are automatically declared const, you practically cannot use any loops like for and while.
Instead, you are required to write purely functional recursive functions to replace your loops. For example, consider the follwing.
void print(){
int a = 0;
while(a < 10) {
printf("%d\n", a);
a++;
}
}
void print(int a){
if(a < 10) {
printf("%d\n", a);
print(a + 1);
}
}
void print(){
print(0);
}
In Both the above cases, calling function print() will print numbers starting at 0 ending at 9.