OpenVMS isn't in the supported list of Swift packages, so comparing it to that 
is pointless.

https://github.com/apple/swift/blob/c3b7709a7c4789f1ad7249d357f69509fb8be731/lib/Basic/LangOptions.cpp#L26-L36


static const StringRef SupportedConditionalCompilationOSs[] = {
  "OSX",
  "tvOS",
  "watchOS",
  "iOS",
  "Linux",
  "FreeBSD",
  "Windows",
  "Android",
  "PS4",
};

Look, this code is already battle tested in Swift. It's even used in the test 
case for the interpreter:

https://github.com/apple/swift/blob/c3b7709a7c4789f1ad7249d357f69509fb8be731/test/Interpreter/SDK/libc.swift#L10-L14
 
<https://github.com/apple/swift/blob/c3b7709a7c4789f1ad7249d357f69509fb8be731/test/Interpreter/SDK/libc.swift#L10-L14>



#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
  import Darwin
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
  import Glibc
#endif

Alex

> On 15 Nov 2016, at 19:51, Drew Crawford <[email protected]> wrote:
> 
> Thanks for using specific examples, as they are illustrative.
> 
>> Or, as used in 
>> https://github.com/drewcrawford/Caroline/blob/edd8aefef44717ecfa03c629100baf095fab983a/caroline-static-tool/main.swift
>>  
>> <https://github.com/drewcrawford/Caroline/blob/edd8aefef44717ecfa03c629100baf095fab983a/caroline-static-tool/main.swift>
>>  to just get access to the exit() function, which is the same across all 
>> platforms.
> 
> 
> exit is an interesting case.  Believe it or not, it is *not* portable, as 
> used here.  The C standard defines two constants for its parameter: 
> EXIT_SUCCESS (defined to be zero) and EXIT_FAILURE (undefined).  You can pass 
> other values (trivia time: only values less than 0377, because the high bits 
> of this integer are reserved on some platforms), but the "fail-iarity" or 
> "successiness" of values other than the defined two are not specified and may 
> take on different meanings on different platforms.  C programmers commonly 
> pick a nonzero value to indicate failure (as I did here) – sometimes multiple 
> distinct values to indicate different kinds of failure – but this is actually 
> non-portable.
> 
> The reason I am being pedantic here is because it demonstrates a broader 
> point: people do not actually write portable code; they target either their 
> current platform or some vague amalgamation of  2-3 platforms in their 
> immediate vicinity.  All the platforms I cared about do something sane with 
> exit(1) so it's "portable enough".  But "portable enough" isn't portable.
> 
>>  In any case, the four lines at the top of your files are almost certainly 
>> inconsistent on other platforms; for example, do you test for freebsd? Or 
>> ps4?
> 
> This is a feature, not a bug.  We *like* compiler errors because they give us 
> early warning we got something wrong.
> 
> I *want* the compiler to stop me when compiling this for OpenVMS.  When I 
> wrote this code, I had only Darwin/Glibc in mind, and on that basis, I used 
> exit(1). The working assumption is now violated, and the compiler is correct 
> to remind me about it.  I don't know, and would need to go find out, what 
> kind of exit is sensible for VMS.  Or to move to EXIT_FAILURE like a language 
> lawyer.
> 
> But the compile error itself is not a silly annoyance that I would like to 
> "solve" by blindly putting more libcs in the list etc. This is a guard rail 
> where I indicated the platforms I had in mind when writing this code, and 
> when I wake up one morning in a drunken stupor and try to do something else, 
> we fire a warning shot.
> 
> It's a safety feature, like force-unwrap.  If you're sure it won't blow up, 
> you can put an exclamation mark in there and shut up the compiler.  If you're 
> sure it's portable to bsd, add bsd to the list and shut up the compiler.  But 
> the resolution to this compile error is not to import more libcs.  The 
> resolution is to *consider carefully if that is a good idea*.
> 
> The assumption embedded in the proposal is that of course we want the program 
> to compile, and the question is merely to calculate the set of import 
> statements that will achieve compilation, for which the proposal offers an 
> algorithm.  My argument is that actually we do not want the program to 
> compile unless we are reasonably sure it will work as intended, and the 
> question is what syntax allows the author to reasonably encode their 
> assumptions so that when they are violated we provide a moment of quiet 
> reflection to consider e.g. if exit(1) is sensible on VMS.
> 
> The existing system is imperfect (and very ugly) but does a surprisingly good 
> job in this dimension.
> 
>>  It also doesn't seem to support some of the other platforms that might be 
>> desirable in a test framework, such as iOS, watchOS or tvOS.
> 
> I do support iOS (not in this component – it's a command-line tool, so the 
> omission of iOS in this file is deliberate, and the compatibility issues go 
> far beyond exit).  I don't yet support watchOS or tvOS because I don't have 
> CI for those platforms yet and in my view supporting a platform is more than 
> adjusting an import statement and wondering if it will compile.
> 
> So in summary:
> 
> 1.  I would not use this feature in the cited examples
> 
> 2.  I would prefer it if others did not use this feature.  When I see "import 
> Glibc" at the top of a file I know what I am signing up for.  When I see 
> "import libc" for all I know the developer used Windows.
> 
> Finally, this is more of a detail, but I still do not understand how this 
> would be implemented for a Linux platform without Glibc, such as Arch.  The 
> current proposal has 
> 
> 
> 
>>   #if os(Linux)
>> 
>>       @_exported import Glibc
>> 
> 
> which is obviously not going to compile on Arch.  So if the goal is to have 
> syntax that is portable the current proposal does not do it.
> 
> I do believe there is some room for a more moderate reform on the libc 
> problem.  For example instead of the traditional ifdefs, we could have
> 
>> import? Glibc
>> 
>> import? Darwin
>> 
> 
> Where the "import?" keyword imports the module if available or otherwise has 
> no effect.
> 
> This preserves the majority of desireable properties discussed above (clearly 
> indicates the intended libcs, provides guard rails similar to the present 
> regime) while being significantly shorter than the present regime.  It also 
> contemplates problems that the current proposal does not, such as Arch (we 
> can continue to list libcs until we find one, and Swift already has rules for 
> resolving multiple imports), and it is more broadly applicable to other kinds 
> of import problems than libc imports narrowly.
> 
> One problem with the import? idea is that it glosses e.g. watchOS/tvOS/macOS 
> as "Darwin" when that is not strictly true (posix_spawn for example) but it's 
> at least a far more sensible unification than VMS/Darwin.  We do have a clear 
> path to check Darwin portability in the compiler (e.g. require 
> @availability(macOS) for posix_spawn) while no similar path exists to check 
> Darwin/VMS portability.  So I think doing something moderate is at least 
> plausible.
> 
> Still, it may be a solution in search of a problem.  If you are writing 
> against something as badly fractured as POSIX, it should feel like it, and 
> even a small unification may be a step too far.
> 
> Of course, the real solution to writing portable code is to target a portable 
> standard, such as Foundation or some alternative high-level library.
> On November 15, 2016 at 10:27:14 AM, Alex Blewitt ([email protected] 
> <mailto:[email protected]>) wrote:
> 
>> 
>>> On 11 Nov 2016, at 03:48, Drew Crawford <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>>     grep -R "import Glibc" ~/Code --include "*.swift" | wc -l
>>>     297
>>> 
>>> As someone who might be characterized as suffering from the problem this 
>>> proposal purports to solve, I am not convinced.
>>> 
>>> The primary problem here is that "libc" is a misnomer.  Did you mean musl, 
>>> dietlibc, or glibc?  Did you mean "whatever libc my distro likes?"  Swift 
>>> in practice only supports one per platform, but that is a bug not a 
>>> feature, and that bug should not be standardized.  We could try to invent 
>>> some syntax to specify one but now we are back with the current system 
>>> again.
>> 
>> We're at the current system to start off with, though. When you do "import 
>> Darwin" or "import GlibC" you're getting whatever the platform has, 
>> regardless of what you call it. You could call it something else, like 
>> "Platform" or "Base" but it doesn't change the suggestion itself.
>> 
>>> The other problem is that in all my usages, "import Glibc" is not a real 
>>> problem I face.  The real problems are that "the libcs plural" are *just 
>>> different*.  Darwin has timeval64, glibc does not, and you'd better check 
>>> your arch and pick the right one, only on one platform.  SO_REUSEADDR has 
>>> one type in Brand X and another type in Brand Y.  Don't even get me 
>>> *started* on poll, EREs, or half a dozen other behavioral variations.  
>> 
>> Yes, these are issues. Some of them will be worked out with the swift server 
>> workgroup, or at least standardising Socket as a type which abstracts the 
>> platform away. But we're at that position at the moment, whether or not 
>> there's a standard module to represent Darwin/Glibc.
>> 
>>> Taking two different libraries and pretending they are the same is not the 
>>> solution, it's the disease.  The way out of this swamp for most developers 
>>> is to use a real Swift library, the same damn Swift library, on all 
>>> platforms (sadly, Foundation today does not meet this requirement).  The 
>>> way out of this swamp for crazy people like me who must write to the metal 
>>> is to actually write to the metal, to the particular libc being targeted, 
>>> not to a hypothetical platonic ideal libc which does not exist.  
>>> 
>>> I realize that four lines at the top of my files is a *visible* annoyance, 
>>> but fixing it just promotes it to an invisible one. 
>> 
>> Not necessarily, it can be a starting point to fix some of the other 
>> problems. In any case, the four lines at the top of your files are almost 
>> certainly inconsistent on other platforms; for example, do you test for 
>> freebsd? Or ps4?
>> 
>> https://github.com/drewcrawford/Caroline/blob/26cd0d71e57a62fac6258e4e13dfd6849a1945c6/caroline-static-tool/FileUtils.swift
>>  
>> <https://github.com/drewcrawford/Caroline/blob/26cd0d71e57a62fac6258e4e13dfd6849a1945c6/caroline-static-tool/FileUtils.swift>
>> 
>> 
>> 
>> 
>> #if
>> os(OSX)
>> 
>> import
>> Darwin
>> 
>> #elseif
>> os(Linux)
>> 
>> import
>> Glibc
>> 
>> #endif
>> 
>> So your test framework doesn't work on FreeBSD by default. Yet they've still 
>> got the same 'write' method. It also doesn't seem to support some of the 
>> other platforms that might be desirable in a test framework, such as iOS, 
>> watchOS or tvOS. You'll just get silent errors on those when it's used on 
>> those platforms. And as new platforms get added, your code will slowly drift 
>> further away from supporting everything to supporting a few known values.
>> 
>> Now granted, some of these may have yet more incompatible versions for 
>> 'write' which needs handling specifically. That's bad, and it should be 
>> something that can be worked on. But most of the other functions (like 
>> 'close') don't need handling specifically. Or, as used in 
>> https://github.com/drewcrawford/Caroline/blob/edd8aefef44717ecfa03c629100baf095fab983a/caroline-static-tool/main.swift
>>  
>> <https://github.com/drewcrawford/Caroline/blob/edd8aefef44717ecfa03c629100baf095fab983a/caroline-static-tool/main.swift>
>>  to just get access to the exit() function, which is the same across all 
>> platforms.
>> 
>> Other proposals - such as Johannes' treatment of how to handle errno - will 
>> help work around these problems. Perhaps we end up with a generic write 
>> function that wraps the platform specific one to abstract that away as well, 
>> which reduces these issues one by one.
>> 
>> Alex

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to