Update
This commit is contained in:
parent
0d8f2a5fea
commit
b35242f273
17 changed files with 58 additions and 31 deletions
|
@ -16,6 +16,8 @@ Remember, portability is about **making it easy for a programmer to take your pr
|
|||
|
||||
**The same goes for languages and [libraries](library.md)**: do NOT use big/bloated languages such as [Python](python.md), [Java](java.md) or [JavaScript](javascript.md) -- your program would immediately become dependent on a hugely complex ecosystem of such language. For portability you should basically **only write in [C](c.md)** (the best established, time tested, relatively simple language supported basically by every platform) or in [C++](cpp.md) at worst, and even with these languages do NOT use the newer standards as these hugely limit the number of compliant compilers that will be able to compile your program. The best is to write in C89 or C99 standard of C. **Minimize the number of libraries you use**, even if it is the standard library of your language -- not all compilers fully adhere to standards and some don't have the standard library even if the should. For [shell](shell.md) [scripts](script.md) only use **[posix shell](posix_shell.md)**, i.e. only use constructs, utilities and flags/features defined by the posix standard, even if you have more "powerful" shell and utilities like [Bash](bash.md) and [GNU](gnu.md) utils.
|
||||
|
||||
{ A great example of how avoiding C features can help your programs be more portable can be seen with [Dusk OS](duskos.md), a very small operating system that will likely be THE system we use if (or rather when) the [collapse](collapse.md) strikes. The system is implementing what they call "Almost C" (https://git.sr.ht/~vdupras/duskos/tree/master/fs/doc/cc/index.txt) -- a language trying to be close to C but avoiding standard compliance to keep simplicity. They want to port C programs but HAVE TO keep it simple so they just can't implement full C and when the judgement day comes, the programs that don't rely on much will simply be the ones that survive. If you just hide behind the excuse "the feature is in the standard so IT HAS TO BE IMEPLEMENTED", your program will end up more unlikely to be ported, an old piece of paper saying your program should run simply won't matter. In Dusk OS you can actually see this porting effort happening right now. ~drummyfish }
|
||||
|
||||
In your compiled programs **always make your own thin [I/O](io.md) abstraction, [decouple](coupling.md) your I/O libraries, separate [frontend](frontend.md) and [backend](backend.md)**. This is one of the most basic and most important things to do. Why? Well unless you're writing a library, you will need to use I/O (write out messages, draw to screen, create [GUI](gui.md), read keyboard commands, read from files, read from network, ...) so you will NEED to use some library for this (C [stdlib](stdlib.md), [SDL](sdl.md), OS [syscalls](syscall.md), [Xlib](xlib.md), ...) but you absolutely DON'T WANT this library to become a hard [dependency](dependency.md) of your program because if your program depends let's say on SDL, you won't be able to make your program run on platforms that don't have SDL. So the situation is that you HAVE TO use some I/O library but you don't want to become dependent on it.
|
||||
|
||||
The way to solve this is to create your own small I/O abstraction in your project, i.e. your own functions (such as `drawPixel`, `writeMessage`, `keyPressed`, `playSound`, `readFrile` etc.) for performing I/O, which you will use inside your main program. These functions will be defined in a small file which will basically be your own small I/O library just for your program. The functions you define there will then internally use functions of whatever underlying I/O system you choose to use at the time as your [frontend](frontend.md) (SDL, Xlib, SFML, ...); the important thing is that your main program code won't itself depend on the underlying system, it will only depend on your I/O abstraction, your own functions. Your custom I/O functions will depend on the underlying I/O system but in a way that's very easy to change -- let's say that your `keyPressed` function internally uses SDL's `SDL_GetKeyboardState` to read keyboard state. If you want to switch from using SDL to using a different frontend, you will only have to change the code in one place: in your I/O abstraction code, i.e. inside your `keyPressed` function. E.g. if you switch from SDL to SFML, you will just delete the code inside your `keyPressed` function and put in another code that uses SFML functions to read keyboard (e.g. the `isKeyPressed` attribute), and your whole code will instantly just work on SFML. In fact you can have multiple implementations of your functions and allow switching of different backends freely -- just as it is possible to compile a [C](c.md) program with any C compiler, you can make it possible to compile your program with any I/O frontend. If you used SDL's specific functions in your main code, you would have to completely rewrite your whole codebase if you wanted to switch away from SDL -- for this reason your main code must never directly touch the underlying I/O system, it must only do so through your I/O abstraction. Of course these principles may apply to any other thing that requires use of external libraries, not just I/O.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue