# \[Pitch #2\] Build-Time Constant Values

**URL:** <https://forums.swift.org/t/pitch-2-build-time-constant-values/56762>\
**Category:** Pitches\
**Created:** [April 14, 2022, 10:02pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762 "2022-04-14T22:02:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ArtemC](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemc/32/27369_2.png) [@ArtemC](https://forums.swift.org/u/ArtemC)\
**Post date:** [April 14, 2022, 10:02pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/1 "2022-04-14T22:02:40Z")

</div>

# Build-Time Constant Values

- Authors: [Artem Chikin](https://github.com/artemcm), [Ben Cohen](https://github.com/airspeedswift), [Xi Ge](https://github.com/nkcsgexi)

## Introduction

A Swift language feature for requiring certain values to be knowable at compile-time. This is achieved through an attribute, `@const`, constraining properties and function parameters to have compile-time knowable values. Such information forms a foundation for richer compile-time features in the future, such as extraction and validation of values at compile time.

Related forum threads:

- [[Pitch] Compile-Time Constant Values](https://forums.swift.org/t/pitch-compile-time-constant-values/53606)

## Motivation

Compile-time constant values are values that can be known or computed during compilation and are guaranteed to not change after compilation. Use of such values can have many purposes, from enforcing desirable invariants and safety guarantees to enabling users to express arbitrarily complex compile-time algorithms.

The first step towards building out support for compile-time constructs in Swift is a basic primitives consisting of an attribute to declare function parameters and properties to require being known at _compile-time_. While this requirement explicitly calls out the compiler as having additional guaranteed information about such declarations, it can be naturally extended into a broader sense of _build-time_ known values - with the compiler being able to inform other tools with type-contextual value information. For an example of the latter, see the “Declarative Package Manifest” motivating use-case below.

## Proposed Solution

The Swift compiler will recognize declarations of properties, local variables, and function parameters declared with a `@const` attribute as having an additional requirement to be known at compile-time. If a `@const` property or variable is initialized with a runtime value, the compiler will emit an error. Similarly, if a runtime value is passed as an argument to a `@const` function parameter, the compiler will emit an error. Aside from participating in name mangling, the attribute has no runtime effect.

## Detailed Design

### Property `@const` attribute

A stored property on a `struct` or a `class` can be marked with a `@const` attribute to indicate that its value is known at compile-time.

```swift
struct Foo {
  @const let title: String = "foo"
}

```

Similarly to Implicitly-Unwrapped Optionals, the mental model for semantics of this attribute is that it is a flag on the declaration that guarantees that the compiler is able to know its value as shared by all instance of the type. For now, `@const let` and `@const static let` are equivalent in what information the `@const` attribute conveys to the compiler.(_AC: Worth mentioning here that in the future,_ `@const let` _properties will gain an ability to be initialized with compile-time expressions_). Unlike a plain `static let` stored property, a `@const static let` property does not need to refer to a location in memory shared by all instances of the type, and can be elided by the compiler entirely. Default-initializing a `@const` property with a runtime value or not default-initializing it at all results in an compilation error.

### Parameter `@const` attribute

A function parameter can be marked with a `@const` keyword to indicate that values passed to this parameter at the call-site must be compile-time-known values.

```swift
func foo(@const input: Int) {...}

```

### Supported Types

The requirement that values of `@const` properties and parameters be known at compile-time restricts the allowable types for such declarations. The current scope of the proposal includes:

- Integer and floating-point and boolean literals.
- String literals (excluding interpolated strings).
- Enum cases with no associated values.
- Tuple literals consisting of the above list items.
- Array and dictionary literals consisting of the above list items.

This list will expand in the future to include more literal-value kinds or potential new compile-time valued constructs.

### Protocol `@const` property requirement

A protocol author may require conforming types to default initialize a given property with a compile-time-known value by specifying it as `@const static` in the protocol definition. For example:

```swift
protocol NeedsConstGreeting {
    @const static let greeting: String
}

```

If a conforming type initializes `greeting` with something other than a compile-time-known value, a compilation error is produced:

```swift
struct Foo: NeedsConstGreeting {
  // 👍
  static let greeting = "Hello, Foo"
}

struct Bar: NeedsConstGreeting {
  // error: 'greeting' must be initialized with a const value
  static let greeting = "\(Bool.random ? "Hello" : "Goodbye"), Bar"
}

```

## Forward-looking design aspects

### Propagation Rules

Though this proposal does not itself introduce propagation rules of `@const`-ness, their future existence is worth discussing in this design. Consider the example:

```swift
@const let i = 1
let j = i

```

Our intent is to allow the use of `i` where `@const` values are expected in the future, for example`@const let k = i` or `f(i)` where `f` is `func f(@const _: Int)`. It is therefore important to consider whether `@const` is propagated to values like `j` in the above example, which determines whether or not statements like `f(j)` and `@const let k = j` are valid code. While it is desreable to allow such uses of the value within the same compilation unit, if `j` is `public`, automatically inferring it to be `@const` is problematic at the module boundary: it creates a contract with the module's clients that the programmer may not have indended. Therefore, `public` properties must explicitly be marked `@const` in order to be accessible as such outside the defining module. This is similar in nature to `Sendable` inference - `internal` or `private` entities can automatically be inferred by the compiler as `Sendable`, while `public` types must explicitly opt-in.

### Memory placement

Effect on runtime placement of `@const` values is an implementation detail that this proposal does not cover beyond indicating that today this attribute has no effect on memory layout of such values at runtime. It is however a highly desireable future direction for the implementation of this feature to allow the use read-only memory for `@const` values. With this in mind, it is important to allow semantics of this attribute to allow such implementation in the future. For example, a global `@const let`, by being placed into read-only memory removes the need for synchronization on access to such data. Moreover, using read-only memory reduces memory pressure that comes from having to maintain all mutable state in-memory at a given program point - read-only data can be evicted on-demand to be read back later. These are desireable traits for optimization of existing programs which become increasingly important for enabling of low-level system programs to be written in Swift.

In order to allow such implementation in the future, this proposal makes the _value_ of `public` `@const` values/properties a part of a module's ABI. That is, a resilient library that vends `@const let x = 11` changing the value of `x` is considered an ABI break. This treatment allows `public` `@const` data to exist in a single read-only location shared by all library clients, without each client having to copy the value or being concerned with possible inconsistency in behavior across library versions.

## Motivating Example Use-Cases

### Facilitate Compile-time Extraction of Values

The [Result Builder-based SwiftPM Manifest](https://forums.swift.org/t/pre-pitch-swiftpm-manifest-based-on-result-builders/53457) pre-pitch outlines a proposal for a manifest format that encodes package model/structure using Swift’s type system via Result Builders. Extending the idea to use the builder pattern throughout can result in a declarative specification that exposes the entire package structure to build-time tools, for example:

```swift
let package = Package {
  Modules {
    Executable("MyExecutable", public: true, include: {
        Internal("MyDataModel")
      })
    Library("MyLibrary", public: true, include: {
        Internal("MyDataModel", public: true)
      })
    Library("MyDataModel")
    Library("MyTestUtilities")
    Test("MyExecutableTests", for: "MyExecutable", include: {
        Internal("MyTestUtilities")
        External("SomeModule", from: "some-package") 
      })
    Test("MyLibraryTests", for: "MyLibrary")
  }
  Dependencies {
    SourceControl(at: "https://git-service.com/foo/some-package", upToNextMajor: "1.0.0")
  } 
}

```

A key property of this specification is that all the information required to know how to build this package is encoded using compile-time-known concepts: types and literal (and therefore compile-time-known) values. This means that for a category of simple packages where such expression of the package’s model is possible, the manifest does not need to be executed in a sandbox by the Package Manager - the required information can be extracted at manifest _build_ time.

To _ensure_ build-time extractability of the relevant manifest structure, a form of the above API can be provided that guarantees the compile-time known properties. For example, the following snippet can guarantee the ability to extract complete required knowledge at build time:

```swift
Test("MyExecutableTests", for: "MyExecutable", include: {
        Internal("MyTestUtilities")
        External("SomeModule", from: "some-package") 
      })

```

By providing a specialized version of the relevant types (`Test`, `Internal`, `External`) that rely on parameters relevant to extracting the package structure being `const`:

```swift
struct Test {
  init(@const _ title: String, @const for: String, @DependencyBuilder include: ...) {...} 
}
struct Internal {
  init(@const _ title: String)
}
struct External {
  init(@const _ title: String, @const from: String)
}

```

This could, in theory, allow SwiftPM to build such packages without executing their manifest. Some packages, of course, could still require run-time (execution at package build-time) Swift constructs. More-generally, providing the possibility of declarative APIs that can express build-time-knowable abstractions can both eliminate (in some cases) the need for code execution - reducing the security surface area - and allow for further novel use-cases of Swift’s DSL capabilities (e.g. build-time extractable database schema, etc.).

### Enforcement of Compile-Time Attribute Parameters

Attribute definitions can benefit from additional guarantees of compile-time constant values. Imagine a property wrapper that declares a property is to be serialized and that it must be stored/retrieved using a specific string key. `Codable` requires users to provide a `CodingKeys` `enum` boilerplate, relying on the `enum`’s `String` raw values. Alternatively, such key can be specified on the property wrapper itself:

```swift
struct Foo {
  @SpecialSerializationSauce(key: "title") 
  var someSpecialTitleProperty: String
}

@propertyWrapper
struct SpecialSerializationSauce {
  init(@const key: String) {...}
}

```

Having the compiler enforce the compile-time constant property of `key` parameter eliminates the possibility of an error where a run-time value is specified which can cause serialized data to not be able to be deserialized, for example.

Enforcing compile-time constant nature of the parameters is also the first step to allowing attribute/library authors to be able to check uses by performing compile-time sanity checking and having the capability to emit custom build-time error messages.

### Enforcement of Non-Failable Initializers

Ergonomics of the recently-pitched [Foundation.URL](https://forums.swift.org/t/foundation-url-improvements/54057) would benefit greatly from the ability to require the string argument to be compile-time constant. With evolving compile-time evaluation facilities, Swift may even gain an ability to perform compile-time validation of such URLs even though the user may never be able to express a fully compile-time constant `Foundation.URL` type because this type is a part of an ABI-stable SDK. While a type like `StaticString` may be used to require that the argument string must be static, which string is chosen can still be determined at runtime, e.g.:

```swift
URL(Bool.random() ? "https://valid.url.com" : "invalid url . com")

```

### Guaranteed Optimization Hints

Similarly, ergonomics of numeric intrinsics can benefit from allowing only certain function parameters to be required to be compile-time known. For example, requiring a given numeric operation to specify a `@const` parameter for the rounding mode of an operation as an enum case, while allowing the operands of the operation be runtime values, allowing the compiler to generate more-efficient code.

## Source compatibility

This is a purely additive change and has no source compatibility impacts.

## Effect on ABI stability and API resilience

The new function parameter attribute is a part of name mangling. The _value_ of `public @const` properties is a part of a module's ABI. See discussion on _Memory placement_ for details.

## Effect on SwiftPM packages

There is no impact on SwiftPM packages.

## Alternatives Considered

### Using a keyword or an introducer instead of an attribute

`@const` being an attribute, as opposed to a keyword or a new introducer (such as `const` instead of `let`), is an approach that is more amenable to applying to a greater variety of constructs in the futures, in addition to property and parameter declarations, such as `@const func`. In addition, as described in comparison to Implicitly-Unwrapped Optionals above, this attribute does not fundamentally change the behavior of the declaration, rather it restricts its handling by the compiler, similar to `@objc`.

### Difference to `StaticString`-like types

As described in the **Enforcement of Non-Failable Initializers** , the key difference to types like `StaticString` that require a literal value is the `@const` attribute's requirement that the exact value be known at compile-time. `StaticString` allows for a runtime selection of multiple compile-time known values.

### Placing `@const` on the declaration type

One altenative to declaring compile-time known values as proposed here with the declaration attribute:

```swift
@const let x = 11

```

Is to instead shift the annotation to declared property's type:

```swift
let x: @const Int = 11

```

This shifts the information conveyed to the compiler about this declaration to be carried by the declaration's type. Semantically, this departs from, and widely broadens the scope from what we intend to capture: the knowability of the declared _value_. Encoding the compile-time property into the type system would force us to reckon with a great deal of complexity and unintended consequences. Consider the following example:

```swift
typealias CI = @const Int
let x: CI?

```

What is the type of `x`? It appears to be `Optional<@const Int>`, which is not a meaningful or useful type, and the programmer most likely intended to have a `@const Optional<Int>`. And although today Implicitly-Unwrapped optional syntax conveys an additional bit of information about the declared value using a syntactic indicator on the declared type, without affecting the declaration's type, the [historical context](https://www.swift.org/blog/iuo/) of that feature makes it a poor example to justify requiring consistency with it.

## Future Directions

- Constant-propogation - allow default-initialization of `@const` properties using other `@const` values and allow passing `@const` values to `@const` parameters.
- Toolchain support for extracting compile-time values at build time.
- Compile-time expressions - allow expressions that operate on compile-time-known values, from binary operators to control flow.
- Compile-time types - allow types consisting of `const` properties to be treated as compile-time-known values.
- Compile-time functions - consisting of expressions operating on compile-time-known values and `const` parameters.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [April 14, 2022, 10:52pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/2 "2022-04-14T22:52:55Z")

</div>

> [@ArtemC](#):
>
> ### Parameter `@const` attribute
> 
> A function parameter can be marked with a `@const` keyword to indicate that values passed to this parameter at the call-site must be compile-time-known values.
> 
> ```swift
> func foo(input: @ **const** Int) {...}
> 
> ```

Since it's the _value passed to the parameter_ that's `@const`, based on precedent with builders and such, wouldn't it be rather `func foo(@const input: Int)` as opposed to `func foo(input: @const Int)`?

---

<div class="post-metadata">

**Author:** ![ArtemC](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemc/32/27369_2.png) [@ArtemC](https://forums.swift.org/u/ArtemC)\
**Post date:** [April 14, 2022, 10:55pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/3 "2022-04-14T22:55:21Z")

</div>

Ah, that's right. That's an error in the proposal. The current implementation even does it the way you describe. Let me fix that in the text, thank you for the catch.

---

<div class="post-metadata">

**Author:** ![1-877-547-7272](https://avatars.discourse-cdn.com/v4/letter/1/278dde/32.png) [@1-877-547-7272](https://forums.swift.org/u/1-877-547-7272)\
**Post date:** [April 14, 2022, 10:59pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/4 "2022-04-14T22:59:12Z")

</div>

> [@ArtemC](#):
>
> Ergonomics of the recently-pitched `Foundation.URL` [insert link here] would benefit greatly from the ability to require the string argument to be compile-time constant.

Looks like you forgot to include this link — [Foundation URL Improvements](https://forums.swift.org/t/foundation-url-improvements/54057)

---

<div class="post-metadata">

**Author:** ![ArtemC](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemc/32/27369_2.png) [@ArtemC](https://forums.swift.org/u/ArtemC)\
**Post date:** [April 14, 2022, 11:04pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/5 "2022-04-14T23:04:17Z")

</div>

Fixed, thank you.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [April 14, 2022, 11:06pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/6 "2022-04-14T23:06:44Z")

</div>

Can't say I'm enthusiastic about the proposal but it seems useful. I do rather object to `@const`, as it's inelegant holdover from C++ (AFAICT). Given how rarely this will be used, can't a slightly longer, more clear name be used like `@buildTime`? Such a term, in addition to more clearly explaining what's happening, could be much more readable, as it can be read as "at build time".

---

<div class="post-metadata">

**Author:** ![Keith](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/keith/32/291_2.png) [@Keith](https://forums.swift.org/u/Keith)\
**Post date:** [April 15, 2022, 12:23am UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/7 "2022-04-15T00:23:06Z")

</div>

I'm a big fan of this! We currently use `StaticString` in some cases to fake this, but I like how having something like this could enable future standard library API that would benefit from this, like your URL initializer example.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [April 15, 2022, 2:19am UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/8 "2022-04-15T02:19:38Z")

</div>

> [@Jon\_Shier](#):
>
> I do rather object to `@const` , as it's inelegant holdover from C++ (AFAICT). Given how rarely this will be used, can't a slightly longer, more clear name be used like `@buildTime` ?

`const` is to constant what `func` is to function. i think it will become quite commonly used…

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [April 15, 2022, 2:20am UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/9 "2022-04-15T02:20:50Z")

</div>

Const is also a runtime property, so there’s nothing in the name that indicates it’s evaluated at _build time_.

---

<div class="post-metadata">

**Author:** ![filip-sakel](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/filip-sakel/32/8697_2.png) [@filip-sakel](https://forums.swift.org/u/filip-sakel)\
**Post date:** [April 15, 2022, 3:57am UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/10 "2022-04-15T03:57:35Z")

</div>

It’s great to see this feature moving forward!

* * *

> [@ArtemC](#):
>
> ```swift
> @PropertyWrapper
> struct SpecialSerializationSauce {
> init(key: const String) {...}
> }
> 
> ```

The property-wrapper attribute starts with a lowercase “p” and I think “const” is meant to be an attribute preceding the parameter name.

---

<div class="post-metadata">

**Author:** ![fclout](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/fclout/32/36155_2.png) [@fclout](https://forums.swift.org/u/fclout)\
**Post date:** [April 15, 2022, 7:59am UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/11 "2022-04-15T07:59:08Z")

</div>

I have a few questions. Least consequentially:

```swift
protocol NeedsConstGreeting {
    @const static let greeting: String
}

```

Today, it's not possible to use `let` in a protocol. Are we allowing `let` with this proposal? Is `@const static var greeting: String { get }` allowed as well?

More consequentially: I have similar feedback to the last pitch. Quoting the motivation section:

> Compile-time constant values are values that can be known or computed during compilation and are guaranteed to not change after compilation. Use of such values can have many purposes, from enforcing desirable invariants and safety guarantees to enabling users to express arbitrarily complex compile-time algorithms.

I very much want this. I'm super excited about constant evaluation in general. However, I'm struggling to see how the pitch paves the way for the future. I recognize the value of `@const` for variables (I see it as meaning something similar to `constexpr` variables in C++), but I don't understand how `@const` for function parameters and protocol requirements fit in a future of arbitrarily complex compile-time algorithms.

For SwiftPM, a tool blessed with compiler support, `@const` for function parameters is useful because the tool knows how to extract the values of `@const` arguments. Unfortunately, there's virtually no way Swift users can do the same thing in their project. The proposal also lists URL as a type that could benefit from `@const` parameters, but `@const` doesn't do anything unless the function is able to inspect the arguments it's passed. That would be controlled by the compile-time evaluation of a function, not the fact that its parameter is `@const`. In fact, by adding `@const` to a function parameter, we _prevent it_ from ever being used with non-constant arguments, which is a restriction I don't personally see being very broadly applicable.

So, I see how this is useful to SwiftPM, but are we adding `@const` parameters _only_ for SwiftPM? Where will `@const` parameters remain once Swift has compile-time evaluation of functions?

I also don't understand how `@const` protocol members contribute to the goal of compile-time evaluation. To me, compile-time evaluation means state that can be transformed at build-time. `@const` enforces that the value cannot ever change. If we were building a protocol for compile-time-evaluatable collections with the primitives presented today, we would need a `@const` count, and by virtue of being `@const` it cannot change. This seems to mean you could never have a `var` collection that is transformed in a function evaluated at compile-time, and that falls short of expressing arbitrarily complex compile-time algorithms.

So, here too, I don't understand how we start from this primitive to build up more compile-time evaluation. Wouldn't it make more sense to have "`@const` conformances" (indicating the entire protocol implementation satisfies whatever the requirements are to compile-time evaluation) than `@const` protocol members? In what cases do we want _the protocol_ to decide that some (not necessarily all!) members must be known at compile-time, instead of letting users of the protocol choose a type that supports compile-time evaluation?

---

<div class="post-metadata">

**Author:** ![aerobounce](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aerobounce/32/14175_2.png) [@aerobounce](https://forums.swift.org/u/aerobounce)\
**Post date:** [April 15, 2022, 8:57am UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/12 "2022-04-15T08:57:11Z")

</div>

This is very nice and I like `@` attribute particularly. It feels settled and Swifty.

---

<div class="post-metadata">

**Author:** ![Finagolfin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/finagolfin/32/34388_2.png) [@Finagolfin](https://forums.swift.org/u/Finagolfin)\
**Post date:** [April 15, 2022, 1:09pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/13 "2022-04-15T13:09:30Z")

</div>

> we would need a `@const` count, and by virtue of being `@const` it cannot change. This seems to mean you could never have a `var` collection that is transformed in a function evaluated at compile-time, and that falls short of expressing arbitrarily complex compile-time algorithms.

At present, you are correct, as this pitch only allows @const to be set for compile-time known constants. But the plan is to eventually allow "potential new compile-time valued constructs," including the "Compile-time expressions" mentioned at the end someday.

@const currently would mean constant at both compile and run time, but it will eventually be expanded to allow mutation at compile-time, so that the full compile-time algorithms you want can be run to create constants for runtime. That is merely a future direction, however, and is out of scope for this pitch.

---

<div class="post-metadata">

**Author:** ![michelf](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michelf/32/1180_2.png) [@michelf](https://forums.swift.org/u/michelf)\
**Post date:** [April 15, 2022, 1:43pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/14 "2022-04-15T13:43:47Z")

</div>

> [@Finagolfin](#):
>
> That is merely a future direction, however, and is out of scope for this pitch.

It seems to me that considering future directions could lead to a different approach. It's hard to determine if the current syntax will be adequate for compile time expressions, types, and declarations without thinking a bit forward about the requirements of compile time evaluation. Perhaps future directions should be expanded with some examples.

---

<div class="post-metadata">

**Author:** ![fclout](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/fclout/32/36155_2.png) [@fclout](https://forums.swift.org/u/fclout)\
**Post date:** [April 15, 2022, 4:52pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/15 "2022-04-15T16:52:20Z")

</div>

I see no path forward for fundamental types like `Array` or `String` to be available at compile-time with the currently described new features. This proposal's `@const` takes away runtime mutability. This is the important takeaway of this paragraph. If we're not able to reuse fundamental types in compile time evaluation, any function that should be evaluatable both at runtime and compile-time needs two distinct copies.

---

<div class="post-metadata">

**Author:** ![ArtemC](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/artemc/32/27369_2.png) [@ArtemC](https://forums.swift.org/u/ArtemC)\
**Post date:** [April 15, 2022, 5:10pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/16 "2022-04-15T17:10:29Z")

</div>

> [@fclout](#):
>
> For SwiftPM, a tool blessed with compiler support, `@const` for function parameters is useful because the tool knows how to extract the values of `@const` arguments. Unfortunately, there's virtually no way Swift users can do the same thing in their project. The proposal also lists URL as a type that could benefit from `@const` parameters, but `@const` doesn't do anything unless the function is able to inspect the arguments it's passed. That would be controlled by the compile-time evaluation of a function, not the fact that its parameter is `@const` . In fact, by adding `@const` to a function parameter, we _prevent it_ from ever being used with non-constant arguments, which is a restriction I don't personally see being very broadly applicable.
> 
> So, I see how this is useful to SwiftPM, but are we adding `@const` parameters _only_ for SwiftPM? Where will `@const` parameters remain once Swift has compile-time evaluation of functions?

The SwiftPM manifest example here should not require any special blessing from the compiler to work in the future. Having this concept be captured by the compiler because of this attribute does not mean that only the compiler can reason, or act on these values. It is why **Future Directions** lists toolchain support for extracting compile-time values of a program at build time, in some sort of structured fashion. Such tooling should be usable by SwiftPM to achieve this much the same as it would be by any other clients.

> [@Jon\_Shier](#):
>
> I do rather object to `@const` , as it's inelegant holdover from C++ (AFAICT). Given how rarely this will be used, can't a slightly longer, more clear name be used like `@buildTime` ? Such a term, in addition to more clearly explaining what's happening, could be much more readable, as it can be read as "at build time".

> [@Jon\_Shier](#):
>
> Const is also a runtime property, so there’s nothing in the name that indicates it’s evaluated at _build time_ .

I do not think I agree to `const` being a C++ holdover here, exactly because we are not using it to describe a _runtime_ property with it, as C++ does. If anything, I would argue that "constant" is a more-intuitive way to express a value being fixed (at build time) rather than a runtime characteristic, particularly to people not familiar with C++.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [April 15, 2022, 5:12pm UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/17 "2022-04-15T17:12:06Z")

</div>

> [@ArtemC](#):
>
> I do not think I agree to `const` being a C++ holdover here, exactly because we are not using it to describe a _runtime_ property with it, as C++ does. If anything, I would argue that "constant" is a more-intuitive way to express a value being fixed (at build time) rather than a runtime characteristic, particularly to people not familiar with C++.

Except Swift already has this as a runtime construct, `let`. So the build time behavior is _the_ key differentiator here, not that you're creating a fixed value.

---

<div class="post-metadata">

**Author:** ![fclout](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/fclout/32/36155_2.png) [@fclout](https://forums.swift.org/u/fclout)\
**Post date:** [April 16, 2022, 12:43am UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/18 "2022-04-16T00:43:06Z")

</div>

> [@ArtemC](#):
>
> The SwiftPM manifest example here should not require any special blessing from the compiler to work in the future. Having this concept be captured by the compiler because of this attribute does not mean that only the compiler can reason, or act on these values. It is why **Future Directions** lists toolchain support for extracting compile-time values of a program at build time, in some sort of structured fashion. Such tooling should be usable by SwiftPM to achieve this much the same as it would be by any other clients.

I appreciate that it will be available to third parties, but creating the annotation before the tooling to consume it seems like it's putting the cart ahead of the horse and leaving a learning opportunity on the table. I'm still not sure how the feature paves the way to compile-time evaluation, either.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [April 16, 2022, 1:22am UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/19 "2022-04-16T01:22:07Z")

</div>

I mentioned this in the previous review, as well. "const" and "constant" are typically used in connection with immutability, but that is actually orthogonal to what is being proposed here - which as you say is the ability to reason about the value at build-time.

AFAICT, mutable `@const` values should be totally fine in principle (meaning: "mutable values, whose value can be reasoned about at build-time, should be totally fine in principle").

Whether or not you should expect the compiler to reason about the value depends more on the mutating operations you perform on it. But in theory it could understand some, why not?

---

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [April 16, 2022, 3:01am UTC](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762/20 "2022-04-16T03:01:15Z")

</div>

> [@fclout](#):
>
> Is `@const static var greeting: String { get }` allowed as well?

`@const static let greeting` in a protocol means "require implementors of the protocol to provide a compile-time constant for `greeting`." This value must be knowable at compile time, unlike a regular `let` which can be calculated at runtime (but once set, cannot be changed).

I am not sure what `@const static var greeting: String { get }` would mean.

`static var greeting: String { get }` effectively means "provide a function `greeting` that returns a `String`". As a convenience, the compiler will synthesize one of these from a `let static greeting: String` and that can be used to fulfill that requirement.

In future proposals, it may be that we can require functions to be compile-time-evaluable to a constant, and `@const static var greeting: String { get }` could be the spelling for that for computed properties. But that would not be how you would write a constant requirement on the protocol – the protocol would still be `@const let`. In a conformance, though, you would be able to use a constant-evaluable computed get to fulfill a protocol's `@const let greeting: String` requirement.

[Next page](https://forums.swift.org/t/pitch-2-build-time-constant-values/56762.md?page=2)
