<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">How much would `Libc` include? The standard C library? POSIX? Does it provide any abstraction over platform-specific differences? In my mind, the common 'Libc' and/or 'POSIX' module would provide a reasonably consistent interface to libc or POSIX, and you'd still have library-specific modules for library-specific APIs.<div class=""><br class=""></div><div class=""><div class="">-Joe</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 8, 2016, at 11:13 AM, Brian Gesiak via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""># Introduction</div><div class=""><br class=""></div><div class="">Currently, cross-platform Swift programs that rely on symbols defined in libc (`fputs`, `stderr`, etc.) must all write the same five lines of boilerplate code:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; #if os(Linux) || os(FreeBSD)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; import Glibc</div><div class="">&nbsp; &nbsp; #else</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; import Darwin</div><div class="">&nbsp; &nbsp; #endif</div><div class=""><br class=""></div><div class="">Instead, I propose the following, which will work on all platforms:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; import Libc</div><div class=""><br class=""></div><div class=""># Motivation</div><div class=""><br class=""></div><div class="">Let's say we wanted to write a program that, on any platform, would print "Hello world!" to stderr. We'd probably come up with this:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; #if os(Linux) || os(FreeBSD)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; import Glibc</div><div class="">&nbsp; &nbsp; #else</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; import Darwin</div><div class="">&nbsp; &nbsp; #endif</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; fputs("Hello world!", stderr)</div><div class=""><br class=""></div><div class="">The first five lines of this program are necessary to import the symbols `fputs` and `stderr`. Five lines may not be much, but these come with significant drawbacks:</div><div class=""><br class=""></div><div class="">- They must be written in each source file that relies on libc, which is tedious.</div><div class="">- It is subject to frequent change. As Swift is ported to more platforms, that initial check must change to `#if os(Linux) || os(FreeBSD) || os(Windows) || os(Android)`, and so on. End users of Swift may not be actively involved in its development, and so may be surprised when the latest release suddenly necessitates more `os()` conditions.</div><div class="">- These combined force users to make a conscious decision to write cross-platform code--as opposed to simply writing Swift and have it work on other platforms seamlessly.</div><div class=""><br class=""></div><div class="">It would be preferable if people writing Swift did not need to check for the current `os()` in order to write code that works across platforms.</div><div class=""><br class=""></div><div class=""># Proposed solution</div><div class=""><br class=""></div><div class="">Instead of conditionally importing Darwin or Glibc, I propose the following:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; import Libc</div><div class=""><br class=""></div><div class="">This would import whichever libc implementation Swift was compiled with. For Ubuntu Linux releases, this would be Glibc. For OS X releases, this would be Darwin. For Android (coming soon in <a href="https://github.com/apple/swift/pull/1442" class="">https://github.com/apple/swift/pull/1442</a>), this would be Bionic.</div><div class=""><br class=""></div><div class="">This saves the end user from writing boilerplate code, and it isolates them from the rapid expansion of platforms on which Swift is able to be executed.</div><div class=""><br class=""></div><div class="">This idea is not novel: the Swift package manager already defines a "libc" package that is essentially the boilerplate `os()` check above: <a href="https://github.com/apple/swift-package-manager/blob/master/Sources/libc/libc.swift" class="">https://github.com/apple/swift-package-manager/blob/master/Sources/libc/libc.swift</a>.</div><div class=""><br class=""></div><div class="">However, rather than determining which libc implementation to use at runtime (like SwiftPM does above), I propose we allow the Swift stdlib to be compiled with any arbitrary implementation of libc.</div><div class=""><br class=""></div><div class=""># Detailed design</div><div class=""><br class=""></div><div class="">It's my understanding that the majority of this change would take place in the Swift build scripts and CMake modules. Similar to how those scripts export a module named "Glibc" on Linux (see stdlib/public/core/Glibc), this proposal could be implementing by exporting a "Libc" on all platforms.</div><div class=""><br class=""></div><div class="">This would also be accompanied by a change to the Swift 3 migrator that could automatically convert conditional imports of Darwin/Glibc to the new `import Libc`.</div><div class=""><br class=""></div><div class="">We must also devise a strategy for the transient rollout period, when Swift defines a Libc module, but we don't have an OS X SDK that uses that name in the bundled module.map. We can add a compiler hack for that, to transparently translate the name.</div><div class=""><br class=""></div><div class=""># Alternatives considered<br class=""><br class="">I believe there are two contentious points to this proposal: <br class=""><br class="">1. Whether to unify the module name across platforms.<br class="">2. What to name the module.<br class=""><br class="">Alternatives considered on point #1 (whether to unify) include:</div><div class=""><br class=""></div><div class="">1a. The status quo: I consider this to be undesirable for the reasons stated in "Motivation". To reiterate: the current system forces users to go out of their way to write cross-platform Swift code, as opposed to writing code that "just works" everywhere.<br class=""></div><div class="">1b. The current Darwin and Glibc modules are a combination of POSIX and the C standard library. We could export *two* modules. However I believe this introduces additional overhead for users, with only the marginal benefit of clean separation between libc and POSIX.<br class="">1c. A special import statement, defined in the Swift stdlib, that would automatically get preprocessed to the five lines of boilerplate shown above. This has several downsides, most notably the added complexity to Swift syntax.<br class=""><br class="">On point #2 (what to name it), I have spoken with people that raised concerns over the name "Libc":</div><div class=""><br class=""></div><div class="">&gt; Another concern is about compatibility with the C++ modules proposal. If we want this module name to mean something, it should agree with the C++ spec.</div><div class=""><br class=""></div><div class="">I don't know which name was chosen in the C++ spec. I've been searching WG21 papers with no luck--any advice on how to find out would be appreciated!<br class=""><br class="">Aside from the above point, some concrete alternatives for point #2 (what to name it) include:</div><div class=""><br class=""></div><div class="">- `import System`: This is better suited to the idea that the module contains both POSIX and libc.</div><div class="">- `import C`: Drop the "Lib"--just "C". It's cleaner. (<a href="https://www.youtube.com/watch?v=PEgk2v6KntY" class="">https://www.youtube.com/watch?v=PEgk2v6KntY</a>)<br class=""><br class="">---<br class=""><br class="">Thanks for taking the time to read this proposal draft! Feedback (on its contents or on how to proceed with the evolution proposal process) is greatly appreciated.<br class=""><br class="">- Brian Gesiak</div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></body></html>