Strong +1, in my experience in other languages OS based tests (or worse, 
browser tests in Javascript, *shudders*) are far too often misused, modules are 
definitely the better way to go.

My only question is whether there should be a way to test minimum module 
versions? If I add support for a module but target a particularly recent 
version then that support won’t compile for platforms with older versions of 
the same module, so I should be able to prevent them from being a match.

> On 22 Mar 2016, at 22:14, Erica Sadun via swift-evolution 
> <[email protected]> wrote:
> 
> Here's another one, hopefully with a little more grounding than the debug 
> test. 
> I welcome feedback both positive and critical, -- E
> 
> Adding an Build Configuration Import Test
> 
> Proposal: SE-00XX
> Author(s): Erica Sadun <http://github.com/erica>
> Status: TBD
> Review manager: TBD
>  <https://gist.github.com/erica/b7f4226b8201945602f2#introduction>Introduction
> 
> Expanding the build configuration suite to test for the ability to import 
> certain modules was first introduced 
> <http://article.gmane.org/gmane.comp.lang.swift.evolution/7516/match=darwin> 
> on the Swift-Evolution list by Kevin Ballard. Although his initial idea 
> (checking for Darwin to differentiate Apple targets from non-Apple targets) 
> proved problematic, developers warmly greeted the notion of an import-based 
> configuration test. Dmitri Gribenko wrote, "There's a direction that we want 
> to move to a unified name for the libc module for all platform, so 'can 
> import Darwin' might not be a viable long-term strategy." Testing for imports 
> offers advantages that stand apart from this one use-case: to test for API 
> availability before use.
> 
>  <https://gist.github.com/erica/b7f4226b8201945602f2#motivation>Motivation
> 
> Swift's existing set of build configurations specify platform differences, 
> not module commonalities. For example, UIKit enables you to write view code 
> supported on both iOS and tvOS. SpriteKit allows common code to render on OS 
> X, iOS, and tvOS that would require an alternate UI on Linux. Testing for 
> Metal support or Media Player would guard code that will not function on the 
> simulator. If the simulator adopted these modules at some future time, the 
> code would naturally expand to provide compatible execution without source 
> modification.
> 
> #if canImport(UIKit)
>    // UIKit-based code
>    #elseif canImport(Cocoa)
>    // OSX code
>    #elseif
>    // Workaround/text, whatever
> #endif
> Guarding code with operating system tests can be less future-proofed than 
> testing for module support. Excluding OS X to use UIColor creates code that 
> might eventually find its way to a Linux plaform. Targeting Apple platforms 
> by inverting a test for Linux essentially broke after the introduction of 
> Windows and FreeBSD build configurations:
> 
> // Exclusive os tests are brittle
> #if !os(Linux)
>    // Matches OSX, iOS, watchOS, tvOS, Windows, FreeBSD
> #endif
> Inclusive OS tests (if os1 || os2 || os3...) must be audited each time the 
> set of possible platforms expands. In addition, compound build statements are 
> harder to write, to validate, and are more confusing to read. They are more 
> prone to errors than a single test that's tied to the API capabilities used 
> by the code it guards.
> 
> Evan Maloney writes, "Being able to test for the importability of a given 
> module/framework at runtime would be extremely helpful. We use several 
> frameworks that are only available in a subset of the platforms we support, 
> and on only certain OS versions. To work around this problem now, we 
> dynamically load frameworks from Obj-C only when we're running on an OS 
> version we know is supported by the framework(s) in question. We can't 
> dynamically load them from Swift because if they're included in an import, 
> the runtime tries to load it right away, leading to a crash on any 
> unsupported platform. The only way to selectively load dynamic frameworks at 
> runtime is to do it via Obj-C. Some sort of check like the ones you propose 
> should let us avoid this."
> 
>  <https://gist.github.com/erica/b7f4226b8201945602f2#detail-design>Detail 
> Design
> 
> #if canImport(module-name) tests for module support by name. My proposed name 
> uses lower camelCase, which is not currently used in the current build 
> configuration vocabulary but is (in my opinion) clearer in intention than the 
> other two terms brought up on the evolution list, #if imports() and #if 
> supports(). 
> 
> This build configuration does not import the module it names
> This build configuration is intended to differentiate API access
> This build configuration should not be used to differentiate platforms
> The supplied module token is an arbitrary string. It does not belong to an 
> enumerated set of known members as this configuration test is intended for 
> use with both first and third party modules for the greatest flexibility. At 
> compile time, Swift determines whether the module can or cannot be linked and 
> builds accordingly.
> #if canImport(module)
>     import module
>     // use module APIs safely
> #endif
> 
> #if canImport(module)
>     // provide solution with module APIs
>     #else
>     // provide alternative solution that does not depend on that module
> #endif
>  <https://gist.github.com/erica/b7f4226b8201945602f2#current-art>Current Art
> 
> Swift currently supports the following configuration tests:
> 
> The literals true and false
> The os() function that tests for OSX, iOS, watchOS, tvOS, Linux, Windows, and 
> FreeBSD
> The arch() function that tests for x86_64, arm, arm64, i386, powerpc64, and 
> powerpc64le
> The swift() function that tests for specific Swift language releases, e.g. 
> swift(>=2.2)
>  
> <https://gist.github.com/erica/b7f4226b8201945602f2#alternatives-considered>Alternatives
>  Considered
> 
> There are no alternatives considered.
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

Reply via email to