6 ms·
To be fair, the file-handling is probably the 'crustiest' part of the standard library. (To use the posix-flags, you use the Form parameter.) The best way to u
by OneWingedShark 5mo ago
To be fair, the file-handling is probably the 'crustiest' part of the standard library. (To use the posix-flags, you use the Form parameter.)
The best way to use Ada, IMO, is type-first: you define your problem-space in the type-system, then use that to solve your problem. -- Also, because Ada's foreign-function interface is dead easy, you could use imports to handle things in a manner more amiable to your needs/preferences, it's as simple as:
Function Example (X : Interfaces.Unsigned_16) return Boolean
with Import, Convention => COBOL, Link_Name => "xmpl16";
You can even put pre-/post-conditions on it.
- tremon 5mo agoYes, agreed on Ada.Interfaces and the FFI, it's one of the best. The only thing "missing" is auto-import of the definitions in C header files (but there be different dragons). gcc -fdump-ada-specs works fine, but it's effectively a duplication of (non-authoritative) information. That's fine if you're targeting one system, but when targeting multiple systems a single "with Interfaces.C.Syscall_H" quickly becomes a maze of alternative package bodies and accompanying conditional compilation logic. > The best way to use Ada, IMO, is type-first: you define your problem-space in the type-system, then use that to solve your problem I guess that goes to the core of the argument I was trying to make: not that Ada is bad, but that the low-level abstractions in Ada's stdlib are a case of premature optimization. Luckily, I take much less issue with the Numerics and Container parts of the standard library. > To use the posix-flags, you use the Form parameter Do you have any examples/documentation on the use of the Form parameter? According to the RM, it's a String argument so I wouldn't have expected it to support flags. (Also, to correct myself on the signalfd issue: there is GNAT.Signals.Block_Signal to mask signals on the Interrupt_Manager thread)
- OneWingedShark 5mo agoOk, so the Form parameter is implementation defined; this was to allow the implementations the 'wriggle room' to interface with the host-system. For GNAT, these two pieces of documentation are instructive: https://docs.adacore.com/live/wave/gnat_rm/html/gnat_rm/gnat_rm/the_implementation_of_standard_i_o.html#form-strings https://docs.adacore.com/live/wave/gnat_rm/html/gnat_rm/gnat... https://gcc.gnu.org/onlinedocs/gcc-4.9.1/gnat_rm/FORM-Strings.html#FORM-Strings https://gcc.gnu.org/onlinedocs/gcc-4.9.1/gnat_rm/FORM-String... (This second one is older documentation, but illustrates how platform-specific Form parameters could be used.) Ada.Text_IO.Create ( File => File, Mode => Ada.Text_IO.Out_File, Name => "test.txt", Form => "shared=no" ); The "maze of alternative package bodies and accompanying conditional compilation logic" is an artifact of C's approach to 'portability' using the preprocessor. Typically, the conditionality should be stable once you abstract it (using the compiler's project-management to select the correct body for a particular configuration) -- As a stupidly trivial example, consider the path separator, for the specification you could have: Package Dependency is Package OS is Function Separator return String; End OS; End Dependency; -- ... Package Dependency is Package body OS is separate; End Dependency; -- Windows separate (Dependency) Package OS is Function Separator return String is ("\"); End OS; -- Classic Mac separate (Dependency) Package OS is Function Separator return String is (":"); End OS; -- VMS separate (Dependency) Package OS is Function Separator return String is ("."); End OS; -- UNIX-like separate (Dependency) Package OS is Function Separator return String is ("/"); End OS; Then in your the rest of your program, you program against the abstraction of DEPENDENCY.OS (and whatever other dependencies you have, likewise), and thus separate out the implementation dependency.