Well my idea also included module(X), modelled after the os() function, e.g.
#if os(OSX)
#if import UIKit
// Some UIKit-related declarations
#endif
// Later in the same file
func f() {
#if module(UIKit)
// Use UIKit-only declarations
#endif
}
Looking forward to seeing more feedback, esp from Erica. My concern was that
hasModule() was just a bit raw.
I will point out a few concerns I have:
Is there a better way of writing this with nothing inside:
#if import UIKit
#endif
Is it strange that all other functions with #if use parentheses (), but not
import?
However, I just feel code like this doesn’t feel very Swifty:
#if hasModule(UIKit)
import UIKit
#endif
> However, I don't get your concerns of "whether already imported or not".
> Isn't `import` strictly about bringing identifiers of linked libraries
> visible in the current file and not about linking to libraries in code.
I was originally going to include this, but cut it out, because it would be an
unclear way to still import something. import ‘returned’ a boolean. So forgot
to cut that bit out too.
#if ! import SomethingCool
import SomeFallback
#endif
> On 13 May 2016, at 6:54 PM, Gwendal Roué <[email protected]> wrote:
>
> Hello,
>
> `#if import Foo` can not deal with the fact that a single source file may
> have to perform the importability test several times.
>
> For example:
>
> #if canImport(UIKit)
> import UIKit
> // Some UIKit-related declarations
> #endif
> // Later in the same file
> func f() {
> #if canImport(UIKit)
> // Use UIKit-only declarations
> #endif
> }
>
> I know, I know, some will tell me to refactor my code. So let's just say I'm
> prototyping and that the code doesn't have its final shape, OK?
>
> Still, testing for module importability is not the same as importing it.
>
> Gwendal Roué
>
>> Le 13 mai 2016 à 10:40, Pyry Jahkola via swift-evolution
>> <[email protected] <mailto:[email protected]>> a écrit :
>>
>> Patrick,
>>
>> I think you're making valuable points here. I also can't think of cases
>> where you wouldn't also import a module in case it was found to be
>> importable. So the use cases I can think of could as well be tackled by
>> allowing expressions such as `import Foo.Bar` as compile-time checks within
>> the conditions of `#if` like you suggested. That would bring those libraries
>> only visible within the scope of that block.
>>
>> However, there can be cases where you're considering importing more than one
>> module, so something like:
>>
>> #if import Foo, import Bar
>> ...
>> #elseif import Baz
>> ...
>> #endif
>>
>> should be considered in that design too. And I don't like the fact that it
>> would import many modules in one line of code.
>>
>> However, I don't get your concerns of "whether already imported or not".
>> Isn't `import` strictly about bringing identifiers of linked libraries
>> visible in the current file and not about linking to libraries in code.
>>
>> — Pyry
>>
>>> I guess one issue I can see is it’s used in two different ways:
>>> - The first use of canImport is used to check whether it can import a
>>> module, and then does so, but there’s no requirement for it to do so. Is
>>> this the right this to do?
>>> - The second use of canImport makes no guarantee that the module has been
>>> imported, only that it can.
>>>
>>> What if instead `import` could return whether it imported or not, when used
>>> with #if? Instead of ‘can import’, you get ‘did just import’ and ‘has
>>> imported’.
>>>
>>>
>>> import Required // Error if not present, current behaviour
>>>
>>> #if import CoolThing // Skips code block if not present, imports otherwise
>>> // Do something with CoolThing module
>>> #else
>>> import AlmostAsCoolThing
>>> #endif
>>>
>>> and you test at the use-site
>>>
>>> #if module(X) // Does not import, only checks if it has been imported
>>> // use things that are available in X
>>> #else
>>>
>>>
>>> As per Pyry’s feedback, you could add a version:
>>>
>>> #if import Frobnication(<1.7.3) // <- Only added version constraint here.
>>> extension Knob : Frobnicatable { ... }
>>> #endif
>>>
>>>
>>>
>>> Just a way to make it less low level.
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution