[swift-evolution] [Planning][Request] "constexpr" for Swift 5

Xiaodi Wu xiaodi.wu at gmail.com
Mon Jul 31 03:09:32 CDT 2017

On Mon, Jul 31, 2017 at 02:51 Gor Gyolchanyan <gor.f.gyolchanyan at icloud.com>

> On Jul 31, 2017, at 10:40 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> On Mon, Jul 31, 2017 at 02:15 Gor Gyolchanyan via swift-evolution <
> swift-evolution at swift.org> wrote:
>> > On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution <
>> swift-evolution at swift.org> wrote:
>> >
>> >> On Jul 30, 2017, at 11:43 PM, Daryle Walker <darylew at mac.com> wrote:
>> >> The parameters for a fixed-size array type determine the type's
>> size/stride, so how could the bounds not be needed during compile-time? The
>> compiler can't layout objects otherwise.
>> >
>> > Swift is not C; it is perfectly capable of laying out objects at run
>> time.  It already has to do that for generic types and types with resilient
>> members.  That does, of course, have performance consequences, and those
>> performance consequences might be unacceptable to you; but the fact that we
>> can handle it means that we don't ultimately require a semantic concept of
>> a constant expression, except inasmuch as we want to allow users to
>> explicitly request guarantees about static layout.
>> Doesn't this defeat the purpose of generic value parameters? We might as
>> well use a regular parameter if there's no compile-time evaluation
>> involved. In that case, fixed-sized arrays will be useless, because they'll
>> be normal arrays with resizing disabled.
> OTOH, if the compiler can prove that a local array is never resized, why
> *shouldn't* it get all the benefits of a fixed-sized array without having
> to use a special syntax? Put another way, why shouldn't fixed-size be one
> of those optional attributes for arrays, like ownership will be for
> variables, that users can opt into for more performance but is otherwise
> automatically worked out by the compiler?
> Because the compiler shouldn't know what an array is (that is, what a
> Swift array is, not the C array that LLVM has a primitive type for).

Wait, why not? It already does, afaict, just as it knows about integers,
strings, etc. In fact, as I understand it, one dividing line between the
standard library and Foundation is whether or not a type needs compiler
knowledge of it.

And if the compiler doesn't know what an array is and what resizing means,
> then the array has to define that optimization hint itself, which will
> either involve new syntax for attaching metadata for declarative
> special-case solutions. Besides, it won't be getting the full benefits of
> fixed-sized arrays. The biggest benefit of fixed-size arrays is allocation
> cost (which is exactly zero for static fixed-sized arrays and a single
> clock cycle for unescaped local fixed-sized arrays), which is not going to
> improve if an array is simply forbidden from resizing.

I'm not speaking about under the hood; I'm speaking about spelling:

let foo: [Int] = [1, 2, 3] // this clearly needs no resizing
var bar: [Int] = [1, 2, 3] // not clear if this needs resizing
var baz: fixed [Int] = [1, 2, 3] // allow the user to tell the compiler

Under the hood, Swift optimizes as best it can.

For really fast storage, Clang has __builtin_alloca, which could be wrapped
> in an __attribute__((__always_inline__)) function and exposed to Swift.
> For semantically non-resizable arrays, we can simply implement a
> FixedSizeArray with no changes to the language.
> Considering these options, I don't think solving the use case of
> fixed-size arrays is worth complicating the language.
> This is why I'm pushing for elaborate compile-time execution feature. It
> won't solve a specific use-case, it will solve a very wide domain of use
> cases.
> As far as I know, the pinnacle of uses for fixed-size arrays is having a
>> compile-time pre-allocated space of the necessary size (either literally at
>> compile-time if that's a static variable, or added to the pre-computed
>> offset of the stack pointer in case of a local variable).
>> > Value equality would still affect the type-checker, but I think we
>> could pretty easily just say that all bound expressions are assumed to
>> potentially resolve unequally unless they are literals or references to the
>> same 'let' constant.
>> Shouldn't the type-checker use the Equatable protocol conformance to test
>> for equality? Moreover, as far as I know, Equatable is not recognized by
>> the compiler in any way, so it's just a regular protocol. What would make
>> it special? Some types would implement operator == to compare themselves to
>> other types, that's beyond the scope of Equatable. What about those? And
>> how are custom operator implementations going to serve this purpose at
>> compile-time? Or will it just ignore the semantics of the type and reduce
>> it to a sequence of bits? Or maybe only a few hand-picked types will be
>> supported?
>> The seemingly simple generic value parameter concept gets vastly
>> complicated and/or poorly designed without an elaborate compile-time
>> execution system... Unless I'm missing an obvious way out.
>> > The only hard constraint is that types need to be consistent, but that
>> just means that we need to have a model in which bound expressions are
>> evaluated exactly once at runtime (and of course typically folded at
>> compile time).
>> What exactly would it take to be able to execute select piece of code at
>> compile-time? Taking the AST, converting it to LLVM IR and feeding it to
>> the MCJIT engine seems to be easy enough. But I'm pretty sure it's more
>> tricky than that. Is there a special assumption or two made about the code
>> that prevents this from happening?
>> > John.
>> >
>> >> Or do you mean that the bounds are integer literals? (That's what I
>> have in the design document now.)
>> >>
>> >> Sent from my iPhone
>> >>
>> >> On Jul 30, 2017, at 8:51 PM, John McCall <rjmccall at apple.com> wrote:
>> >>
>> >>>> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution <
>> swift-evolution at swift.org> wrote:
>> >>>> The “constexpr” facility from C++ allows users to define constants
>> and functions that are determined and usable at compile-time, for
>> compile-time constructs but still usable at run-time. The facility is a key
>> step for value-based generic parameters (and fixed-size arrays if you don’t
>> want to be stuck with integer literals for bounds). Can figuring out
>> Swift’s story here be part of Swift 5?
>> >>>
>> >>> Note that there's no particular reason that value-based generic
>> parameters, including fixed-size arrays, actually need to be constant
>> expressions in Swift.
>> >>>
>> >>> John.
>> >
>> > _______________________________________________
>> > swift-evolution mailing list
>> > swift-evolution at swift.org
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170731/ad9578f5/attachment.html>

More information about the swift-evolution mailing list