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

2017-09-04 Thread Alejandro Martinez via swift-evolution
Sorry for jumping late into this,
about the topic of compile time execution, I raised it pretty much in
the beginning of Swift being open sourced and it stills pops in my
mind everytime I see Jonathan Blow use it in his language.

So for my own curiosity, how feasible it is for Swift to do it with
the current compiler pipeline (SIL, LLVM)? And by that I mean
actually marking some function/file and letting it run at compile
time. Would it be posible for the compiler to interpret arbitrary
Swift code? It probably won't be easy but I just want to know if it's
closer to "it can be done" or "no way". From Blow's streams I know
that this probably would have to work by compiling everything it can
before interpreting the compile-time code which I don't know how Swift
would deal with it.
But ignoring that, I would be pretty happy if we could have things
like the ones mentioned (including a be able to do what Sourcery and
what the compiler with equatable/etc do in plain Swift).

Thanks


On Thu, Aug 10, 2017 at 1:10 PM, Tino Heth via swift-evolution
 wrote:
> Imho this topic was much better than that other one ;-) — and I just
> realised that of metaprogramming build on top of reflection wasn't discussed
> in its own thread yet…
> I fear "constexpr" is already burned, because people associate it with
> things like calculating Fibonacci numbers at compile time (which is kind of
> cool, but doesn't have much merit for most of us).
>
> Right now, there is SE-185, which allows to synthesise Equatable and
> Hashable.
> To do so, nearly 1500 lines of C++ are needed, and even if we assume that
> two thirds are comments and whitespace, it's still a big piece of code that
> could only be written by someone with deep knowledge about C++ and the Swift
> compiler.
> Compile time metaprogramming could do the same, but in probably less than
> twenty lines of Swift that could be written rather easily by anyone who
> knows the language…
>
> So to update my list of things that might be added, there are also some
> points that are already there and whose implementation could have been
> simplified drastically:
>
> - Forwarding of protocol conformance (Kotlin, for example, has this: When a
> member conforms to a protocol, you don't have to write a bunch of methods
> that just say "let my member do this")
> - init with reduced boilerplate
> - Subtyping for non-class types, including a "newtype" option
> - Property behaviours
>
> - Equatable, Hashabable
> - Encoding/Decoding
>
> I still wonder that virtually no one else seems to be thrilled about the
> power of the idea… @gor.f.gyolchanyan would you like join an attempt to
> raise the attention?
>
> - Tino
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>



-- 
Alejandro Martinez
http://alejandromp.com
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-24 Thread Dave Abrahams via swift-evolution

on Mon Jul 31 2017, John McCall  wrote:

>> I see your point. Dynamically-sized in-place allocation is something
>> that completely escaped me when I was thinking of fixed-size
>> arrays. I can say with confidence that a large portion of
>> private-class-copy-on-write value types would greatly benefit from
>> this and would finally be able to become true value types.
>
> To be clear, it's not obvious that using an inline array is always a
> good move for performance!  But it would be a tool available for use
> when people felt it was important.

Just to point out that people may be missing the case of fixed capacity
variable sized arrays, which are an important component of a general
system for optimizing variably-sized data structures. Implementing such
an array without dynamic allocation requires language support.

Cheers,

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-10 Thread Tino Heth via swift-evolution
Imho this topic was much better than that other one ;-) — and I just realised 
that of metaprogramming build on top of reflection wasn't discussed in its own 
thread yet…
I fear "constexpr" is already burned, because people associate it with things 
like calculating Fibonacci numbers at compile time (which is kind of cool, but 
doesn't have much merit for most of us).

Right now, there is SE-185, which allows to synthesise Equatable and Hashable.
To do so, nearly 1500 lines of C++ are needed, and even if we assume that two 
thirds are comments and whitespace, it's still a big piece of code that could 
only be written by someone with deep knowledge about C++ and the Swift compiler.
Compile time metaprogramming could do the same, but in probably less than 
twenty lines of Swift that could be written rather easily by anyone who knows 
the language…

So to update my list of things that might be added, there are also some points 
that are already there and whose implementation could have been simplified 
drastically:
> - Forwarding of protocol conformance (Kotlin, for example, has this: When a 
> member conforms to a protocol, you don't have to write a bunch of methods 
> that just say "let my member do this")
> - init with reduced boilerplate
> - Subtyping for non-class types, including a "newtype" option
> - Property behaviours
- Equatable, Hashabable
- Encoding/Decoding

I still wonder that virtually no one else seems to be thrilled about the power 
of the idea… @gor.f.gyolchanyan would you like join an attempt to raise the 
attention?

- Tino___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-06 Thread John McCall via swift-evolution
> On Aug 6, 2017, at 11:59 PM, Daryle Walker  wrote:
>> On Aug 1, 2017, at 2:58 PM, John McCall > > wrote:
>> 
>>> 
>>> On Aug 1, 2017, at 9:53 AM, Daryle Walker >> > wrote:
>>> 
 On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan >>> > wrote:
 
 Well, yeah, knowing its size statically is not a requirement, but having a 
 guarantee of in-place allocation is. As long as non-escaped local 
 fixed-size arrays live on the stack, I'm happy. 🙂
>>> 
>>> I was neutral on this, but after waking up I realized a problem. I want to 
>>> use the LLVM type primitives to implement fixed-size arrays. Doing a 
>>> run-time determination of layout and implementing it with alloca forfeits 
>>> that (AFAIK). Unless the Swift run-time library comes with LLVM (which I 
>>> doubt). Which means we do need compile-time constants after all.
>> 
>> We are not going to design the Swift language around the goal of producing 
>> exact LLVM IR sequences.  If you can't phrase this in real terms, it is 
>> irrelevant.
> 
> It isn’t being LLVM-specific, but for any similar system. The instruction 
> generator has certain primitives, like 16-bit integers or 32-bit floats. LLVM 
> (and probably rivals) also has aggregate primitives, heterogenous and 
> homogenous (and the latter as standard and vector-unit). I want to use those 
> primitives when possible. Saving sizing allocations until run-time, after 
> it’s too late for sized-array-specific generated instructions, means that the 
> array is probably implemented with general buffer pointer and length 
> instructions. Any opportunities for IR-level optimization of the types is 
> gone.

> How often do you expect a statically sized array to need said size determined 
> at run-time (with a function) versus a compile-time specification (with an 
> integer literal or “constexpr” expression)? This may enable a 1% solution 
> that anti-optimizes the 99% case.

If the array type is ultimately written with a constant bound, it will reliably 
end up having a constant static size for the same reason that (Either, Float) has a constant static size despite tuples, optionals, and 
Either all being generic types: the compiler automatically does this sort of 
deep substitution when it's computing type layouts.

Now, a generic method on all bounded array types would not know the size of 
'self', for two reasons: it wouldn't know the bound, and it wouldn't know the 
layout of the element type.  But of course we do have optimizations to generate 
specialized implementations of generic functions, and the specialized 
implementation would obviously be able to compute a static size of 'self' 
again.  Moreover, a language design which required bounds to always be constant 
would only help this situation in an essentially trivial way: by outlawing such 
a method from being defined in the first place.

John.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-06 Thread Daryle Walker via swift-evolution
> On Aug 3, 2017, at 8:20 PM, Karl Wagner via swift-evolution 
>  wrote:
> 
>>> The root cause, of course, is that the VLAs require new stack allocations 
>>> each time, and the stack is only deallocated as one lump when the frame 
>>> ends.
>> 
>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go out 
>> of scope.
> 
> Learned something today.
> 
> Anyway, if the goal is stack allocation, I would prefer that we explored 
> other ways to achieve it before jumping to a new array-type. I’m not really a 
> fan of a future where [3; Double] is one type and (Double, Double, Double) is 
> something else, and Array is yet another thing.

Just about every system programming language has all three of these, since you 
can’t really stop these “similar” types from co-existing. The third type uses 
remote storage, while the first two are scoped storage. A heterogenous product 
type template has to include homogenous product types as a subset. And 
instruction generators can produce different code between tuples and arrays; 
are you willing to forfeit one set of optimizations?

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-06 Thread Daryle Walker via swift-evolution
> On Aug 1, 2017, at 2:58 PM, John McCall  wrote:
> 
>> 
>> On Aug 1, 2017, at 9:53 AM, Daryle Walker > > wrote:
>> 
>>> On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan >> > wrote:
>>> 
>>> Well, yeah, knowing its size statically is not a requirement, but having a 
>>> guarantee of in-place allocation is. As long as non-escaped local 
>>> fixed-size arrays live on the stack, I'm happy. 🙂
>> 
>> I was neutral on this, but after waking up I realized a problem. I want to 
>> use the LLVM type primitives to implement fixed-size arrays. Doing a 
>> run-time determination of layout and implementing it with alloca forfeits 
>> that (AFAIK). Unless the Swift run-time library comes with LLVM (which I 
>> doubt). Which means we do need compile-time constants after all.
> 
> We are not going to design the Swift language around the goal of producing 
> exact LLVM IR sequences.  If you can't phrase this in real terms, it is 
> irrelevant.

It isn’t being LLVM-specific, but for any similar system. The instruction 
generator has certain primitives, like 16-bit integers or 32-bit floats. LLVM 
(and probably rivals) also has aggregate primitives, heterogenous and 
homogenous (and the latter as standard and vector-unit). I want to use those 
primitives when possible. Saving sizing allocations until run-time, after it’s 
too late for sized-array-specific generated instructions, means that the array 
is probably implemented with general buffer pointer and length instructions. 
Any opportunities for IR-level optimization of the types is gone.

How often do you expect a statically sized array to need said size determined 
at run-time (with a function) versus a compile-time specification (with an 
integer literal or “constexpr” expression)? This may enable a 1% solution that 
anti-optimizes the 99% case.

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-06 Thread Félix Cloutier via swift-evolution

> Le 6 août 2017 à 08:15, Karl Wagner  a écrit :
> 
>> 
>> On 4. Aug 2017, at 20:15, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Aug 4, 2017, at 1:19 PM, Félix Cloutier via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> That's not a concern with the `let` case that Robert brought up, since you 
>>> can't mutate a `let` array at all.
>>> 
>>> The big thing is that unconstrained escape analysis is uncomputable. Since 
>>> Swift array storage is COW, any function that receives the array as a 
>>> parameter is allowed to take a reference on its storage. If the storage 
>>> lives on the stack and that reference outlives the stack frame, you've got 
>>> a problem. It's the same problem that motivated @escaping for closures.
>>> 
>>> You could allow storage to be on the stack by forcing user to make a 
>>> pessimistic copy, which is possibly not an improvement.
>> 
>> Right.  I think maybe the name people keeping using for this feature is 
>> misleading; a better name would be "inline arrays" or "directly-stored 
>> arrays".  Having a fixed size is a necessary condition for storing the array 
>> elements directly, but the people asking for this feature are really asking 
>> for the different representation, not just the ability to statically 
>> constrain the size of an array.
>> 
>> That representation difference comes with a lot of weaknesses and 
>> trade-offs, but it's also useful sometimes.
>> 
>> John.
>> 
> 
> Right, and the question I’ve been asking (indirectly) is: why is this only 
> useful for arrays?

One special thing about fixed-size arrays is that they address the sore spot of 
C interop.

> Doesn’t it really apply to any value-type which allocates storage which it 
> manages with COW semantics (e.g. Dictionary, Set, Data, your own custom 
> types…)? Really, we want to inform the compiler that the 
> dynamically-allocated memory is part of the value - and if it sees that the 
> storage is only allocated once, it should be allowed to allocate that storage 
> inline with the value, on the stack.

Assuming that fixed-size arrays are a different type (like FixedSizeArray 
vs Array), the feature work that supports them would likely be sufficient to 
support fixed-size whatever collections, too. However (and I'm talking a bit 
through my hat here, that's not my area of expertise), I think that there could 
be some drawbacks to implementing some other collections in a fixed amount of 
memory. For instance, you have to decide on a fixed number of buckets for sets 
and dictionaries, regardless of what ends up in the collection. Dictionaries 
and sets also tend to use more memory than arrays, which could cause storage 
size to balloon up to degrees that are not immediately obvious.

> As I understand it, the only problem with this is when a function takes such 
> a value as a parameter and assigns it to some escaping reference (an ivar, 
> global, or capturing it inside an escaping closure).
> 
> So why can’t such assignments simply check if the value has inline storage 
> and copy it to the heap if necessary? The compiler should be able to optimise 
> the function so the check (which is really cheap anyway) only needs to happen 
> once per function. Because the entire type has value semantics, we can 
> substitute the original value with the copy for the rest of the function 
> (preventing further copies down the line).

The rest of the function might not be enough, especially if you use the same 
array for multiple calls. See:

> var globalArray = [[Int]]
> func append(array: [Int])
>   globalArray.append(array)
> }
> 
> func foo() {
>   let bar = [1,2,3]
>   append(array: bar)
>   append(array: bar)
>   append(array: bar)
> }

The function that escapes the array is `append(array:)`, so you'd get one copy 
per call to `append(array:)`, unless functions start annotating the escaping 
behavior of each parameter. That could work in many cases, but the compiler 
would still have to be pessimistic in common instances, like when calls to 
virtual functions are involved, including closures and calls to methods of 
objects represented as protocol instances. (Also, the amount of work required 
is likely to be significant.)

Félix

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-06 Thread John McCall via swift-evolution

> On Aug 6, 2017, at 11:15 AM, Karl Wagner  wrote:
> 
> 
>> On 4. Aug 2017, at 20:15, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Aug 4, 2017, at 1:19 PM, Félix Cloutier via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> That's not a concern with the `let` case that Robert brought up, since you 
>>> can't mutate a `let` array at all.
>>> 
>>> The big thing is that unconstrained escape analysis is uncomputable. Since 
>>> Swift array storage is COW, any function that receives the array as a 
>>> parameter is allowed to take a reference on its storage. If the storage 
>>> lives on the stack and that reference outlives the stack frame, you've got 
>>> a problem. It's the same problem that motivated @escaping for closures.
>>> 
>>> You could allow storage to be on the stack by forcing user to make a 
>>> pessimistic copy, which is possibly not an improvement.
>> 
>> Right.  I think maybe the name people keeping using for this feature is 
>> misleading; a better name would be "inline arrays" or "directly-stored 
>> arrays".  Having a fixed size is a necessary condition for storing the array 
>> elements directly, but the people asking for this feature are really asking 
>> for the different representation, not just the ability to statically 
>> constrain the size of an array.
>> 
>> That representation difference comes with a lot of weaknesses and 
>> trade-offs, but it's also useful sometimes.
>> 
>> John.
>> 
> 
> Right, and the question I’ve been asking (indirectly) is: why is this only 
> useful for arrays? Doesn’t it really apply to any value-type which allocates 
> storage which it manages with COW semantics (e.g. Dictionary, Set, Data, your 
> own custom types…)? Really, we want to inform the compiler that the 
> dynamically-allocated memory is part of the value - and if it sees that the 
> storage is only allocated once, it should be allowed to allocate that storage 
> inline with the value, on the stack.

There are absolutely things we could do as part of the Array implementation to 
dynamically avoid heap allocations for temporary arrays.  However, it would be 
very difficult to take advantage of that for arrays stored in temporary structs 
or enums; worse, even if we could, it still wouldn't have the optimal 
representation that people want for mathematical types like vectors and 
matrices.

John.


> 
> As I understand it, the only problem with this is when a function takes such 
> a value as a parameter and assigns it to some escaping reference (an ivar, 
> global, or capturing it inside an escaping closure).
> 
> So why can’t such assignments simply check if the value has inline storage 
> and copy it to the heap if necessary? The compiler should be able to optimise 
> the function so the check (which is really cheap anyway) only needs to happen 
> once per function. Because the entire type has value semantics, we can 
> substitute the original value with the copy for the rest of the function 
> (preventing further copies down the line).
> 
> 
> // Module one
> 
> import ModuleTwo
> 
> func doSomething() {
> 
> let values = (0..<5).map { _ in random() }// allocated inline, since 
> the size can never change
> ModuleTwo.setGlobalItems(values)  // passes a stack-allocated 
> array to the (opaque) function
> }
> 
> // Module two
> 
> var GlobalItems = [Int]()
> var MoreGlobalItems = [Int]()
> 
> func setGlobalItems(_ newItems: [Int]) {
> 
> GlobalItems = newItems  // assignment to escaping reference: 
> checks for inline storage, copies to heap if needed
> 
> // all references to ‘newItems’ from this point refer to the copy known 
> to be on the heap
> 
> MoreGlobalItems = newItems  // we already have a known out-of-line copy 
> of the value; no checks or copying needed
> }
> 
> // To make it more explicit...
> 
> func setGlobalItems_explicit(_ newItems: [Int]) {
> 
> let newItems_heap = newItems.backing.isAllocatedInline ? 
> newItems(withBacking: newItems.backing.clone()) : newItems
> GlobalItems   = newItems_heap
> MoreGlobalItems   = newItems_heap
> }
> 
> 
> This would require some special language support for values that allocate 
> memory which is managed as COW.
> 
> - Karl
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-06 Thread Karl Wagner via swift-evolution

> On 6. Aug 2017, at 17:15, Karl Wagner via swift-evolution 
>  wrote:
> 
> let newItems_heap = newItems.backing.isAllocatedInline ? 
> newItems(withBacking: newItems.backing.clone()) : newItems

Should, of course, be:

let newItems_heap = newItems.backing.isAllocatedInline ? Array(withBacking: 
newItems.backing.clone()) : newItems___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-06 Thread Karl Wagner via swift-evolution

> On 4. Aug 2017, at 20:15, John McCall via swift-evolution 
>  wrote:
> 
>> 
>> On Aug 4, 2017, at 1:19 PM, Félix Cloutier via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> That's not a concern with the `let` case that Robert brought up, since you 
>> can't mutate a `let` array at all.
>> 
>> The big thing is that unconstrained escape analysis is uncomputable. Since 
>> Swift array storage is COW, any function that receives the array as a 
>> parameter is allowed to take a reference on its storage. If the storage 
>> lives on the stack and that reference outlives the stack frame, you've got a 
>> problem. It's the same problem that motivated @escaping for closures.
>> 
>> You could allow storage to be on the stack by forcing user to make a 
>> pessimistic copy, which is possibly not an improvement.
> 
> Right.  I think maybe the name people keeping using for this feature is 
> misleading; a better name would be "inline arrays" or "directly-stored 
> arrays".  Having a fixed size is a necessary condition for storing the array 
> elements directly, but the people asking for this feature are really asking 
> for the different representation, not just the ability to statically 
> constrain the size of an array.
> 
> That representation difference comes with a lot of weaknesses and trade-offs, 
> but it's also useful sometimes.
> 
> John.
> 

Right, and the question I’ve been asking (indirectly) is: why is this only 
useful for arrays? Doesn’t it really apply to any value-type which allocates 
storage which it manages with COW semantics (e.g. Dictionary, Set, Data, your 
own custom types…)? Really, we want to inform the compiler that the 
dynamically-allocated memory is part of the value - and if it sees that the 
storage is only allocated once, it should be allowed to allocate that storage 
inline with the value, on the stack.

As I understand it, the only problem with this is when a function takes such a 
value as a parameter and assigns it to some escaping reference (an ivar, 
global, or capturing it inside an escaping closure).

So why can’t such assignments simply check if the value has inline storage and 
copy it to the heap if necessary? The compiler should be able to optimise the 
function so the check (which is really cheap anyway) only needs to happen once 
per function. Because the entire type has value semantics, we can substitute 
the original value with the copy for the rest of the function (preventing 
further copies down the line).


// Module one

import ModuleTwo

func doSomething() {

let values = (0..<5).map { _ in random() }// allocated inline, since 
the size can never change
ModuleTwo.setGlobalItems(values)  // passes a stack-allocated 
array to the (opaque) function
}

// Module two

var GlobalItems = [Int]()
var MoreGlobalItems = [Int]()

func setGlobalItems(_ newItems: [Int]) {

GlobalItems = newItems  // assignment to escaping reference: checks 
for inline storage, copies to heap if needed

// all references to ‘newItems’ from this point refer to the copy known to 
be on the heap

MoreGlobalItems = newItems  // we already have a known out-of-line copy of 
the value; no checks or copying needed
}

// To make it more explicit...

func setGlobalItems_explicit(_ newItems: [Int]) {

let newItems_heap = newItems.backing.isAllocatedInline ? 
newItems(withBacking: newItems.backing.clone()) : newItems
GlobalItems   = newItems_heap
MoreGlobalItems   = newItems_heap
}


This would require some special language support for values that allocate 
memory which is managed as COW.

- Karl

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-04 Thread Robert Bennett via swift-evolution
Sorry, not sure how I missed that 😑.

> On Aug 4, 2017, at 3:16 PM, Félix Cloutier  wrote:
> 
> 
>> Le 4 août 2017 à 11:39, Robert Bennett  a écrit :
>> 
>>> That's not a concern with the `let` case that Robert brought up, since you 
>>> can't mutate a `let` array at all.
>>> 
>>> The big thing is that unconstrained escape analysis is uncomputable. Since 
>>> Swift array storage is COW, any function that receives the array as a 
>>> parameter is allowed to take a reference on its storage. If the storage 
>>> lives on the stack and that reference outlives the stack frame, you've got 
>>> a problem. It's the same problem that motivated @escaping for closures.
>>> 
>>> You could allow storage to be on the stack by forcing user to make a 
>>> pessimistic copy, which is possibly not an improvement.
>> 
>> 
>> Good point. If this is only problematic when multiple threads are accessing 
>> an array, then it could still be worthwhile if all accesses are (provably) 
>> on the thread that created the array.
> 
> To be clear, it's a problem independently of multi-threading. `func foo() -> 
> [Int] { return [1, 2, 3] }` is the most basic representation of it: you can't 
> store the array in the stack frame if you return it. (To be fair, that one 
> would be caught by escape analysis of any quality.) `func foo() { bar([1, 2, 
> 3, 4]) }` is another example: if you don't know what `bar` does with the 
> array, you can't store it on the stack because it might pass it to an object 
> that lives on the heap and outlives `foo`, for instance. @escaping solves 
> that problem for closures by specifically annotating parameters when the 
> assigned closure could still be referenced after the called function returns.
> 
>> And pessimistic copying might still be worth it for arrays below a certain 
>> size — for instance, copying an Array of length 1 (and recall that the 
>> array in question is a constant so its size is known at compile time) would 
>> definitely be worth not having that array in heap memory.
> 
> You only need pessimistic copies when that copy escapes, and since it 
> escapes, it needs to live on the heap by definition. Right now an array of 
> size 1 passed to 4 objects on the heap has one single backing representation. 
> With pessimistic copies, you'd get 4 times that buffer of size 1, which is 
> definitely not an improvement.
> 
>> Going back to the literal notion of FSAs — fixed size arrays not necessarily 
>> on the stack — I think that simply copying Array’s implementation sans 
>> RangeReplaceableCollection conformance is not a bad way to go. Any 
>> optimizations used for `let` Arrays could probably be applied to this type 
>> of FSA.
> 
> We're actually splitting this in multiple directions. John talks of 
> variable-sized arrays necessarily on the stack. :)
> 
> I see two useful characteristics to fixed-size arrays, which, 
> uncoincidentally, are what it takes to use them for C interop:
> 
> Their storage is inlined into their container (whether it be the stack or an 
> object)
> Their length is part of their type (and not directly included with the data 
> itself)
> 
> This is also enough to implement fixed-size arrays not necessarily on the 
> stack, mind you.
> 
> Félix
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-04 Thread Félix Cloutier via swift-evolution

> Le 4 août 2017 à 11:39, Robert Bennett  a écrit :
> 
>> That's not a concern with the `let` case that Robert brought up, since you 
>> can't mutate a `let` array at all.
>> 
>> The big thing is that unconstrained escape analysis is uncomputable. Since 
>> Swift array storage is COW, any function that receives the array as a 
>> parameter is allowed to take a reference on its storage. If the storage 
>> lives on the stack and that reference outlives the stack frame, you've got a 
>> problem. It's the same problem that motivated @escaping for closures.
>> 
>> You could allow storage to be on the stack by forcing user to make a 
>> pessimistic copy, which is possibly not an improvement.
> 
> 
> Good point. If this is only problematic when multiple threads are accessing 
> an array, then it could still be worthwhile if all accesses are (provably) on 
> the thread that created the array.

To be clear, it's a problem independently of multi-threading. `func foo() -> 
[Int] { return [1, 2, 3] }` is the most basic representation of it: you can't 
store the array in the stack frame if you return it. (To be fair, that one 
would be caught by escape analysis of any quality.) `func foo() { bar([1, 2, 3, 
4]) }` is another example: if you don't know what `bar` does with the array, 
you can't store it on the stack because it might pass it to an object that 
lives on the heap and outlives `foo`, for instance. @escaping solves that 
problem for closures by specifically annotating parameters when the assigned 
closure could still be referenced after the called function returns.

> And pessimistic copying might still be worth it for arrays below a certain 
> size — for instance, copying an Array of length 1 (and recall that the 
> array in question is a constant so its size is known at compile time) would 
> definitely be worth not having that array in heap memory.

You only need pessimistic copies when that copy escapes, and since it escapes, 
it needs to live on the heap by definition. Right now an array of size 1 passed 
to 4 objects on the heap has one single backing representation. With 
pessimistic copies, you'd get 4 times that buffer of size 1, which is 
definitely not an improvement.

> Going back to the literal notion of FSAs — fixed size arrays not necessarily 
> on the stack — I think that simply copying Array’s implementation sans 
> RangeReplaceableCollection conformance is not a bad way to go. Any 
> optimizations used for `let` Arrays could probably be applied to this type of 
> FSA.

We're actually splitting this in multiple directions. John talks of 
variable-sized arrays necessarily on the stack. :)

I see two useful characteristics to fixed-size arrays, which, uncoincidentally, 
are what it takes to use them for C interop:

Their storage is inlined into their container (whether it be the stack or an 
object)
Their length is part of their type (and not directly included with the data 
itself)

This is also enough to implement fixed-size arrays not necessarily on the 
stack, mind you.

Félix___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-04 Thread Robert Bennett via swift-evolution
> That's not a concern with the `let` case that Robert brought up, since you 
> can't mutate a `let` array at all.
> 
> The big thing is that unconstrained escape analysis is uncomputable. Since 
> Swift array storage is COW, any function that receives the array as a 
> parameter is allowed to take a reference on its storage. If the storage lives 
> on the stack and that reference outlives the stack frame, you've got a 
> problem. It's the same problem that motivated @escaping for closures.
> 
> You could allow storage to be on the stack by forcing user to make a 
> pessimistic copy, which is possibly not an improvement.


Good point. If this is only problematic when multiple threads are accessing an 
array, then it could still be worthwhile if all accesses are (provably) on the 
thread that created the array. And pessimistic copying might still be worth it 
for arrays below a certain size — for instance, copying an Array of length 
1 (and recall that the array in question is a constant so its size is known at 
compile time) would definitely be worth not having that array in heap memory.

Going back to the literal notion of FSAs — fixed size arrays not necessarily on 
the stack — I think that simply copying Array’s implementation sans 
RangeReplaceableCollection conformance is not a bad way to go. Any 
optimizations used for `let` Arrays could probably be applied to this type of 
FSA.

On Aug 4, 2017, at 2:15 PM, John McCall via swift-evolution 
mailto:swift-evolution@swift.org>> wrote:

> 
>> On Aug 4, 2017, at 1:19 PM, Félix Cloutier via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> That's not a concern with the `let` case that Robert brought up, since you 
>> can't mutate a `let` array at all.
>> 
>> The big thing is that unconstrained escape analysis is uncomputable. Since 
>> Swift array storage is COW, any function that receives the array as a 
>> parameter is allowed to take a reference on its storage. If the storage 
>> lives on the stack and that reference outlives the stack frame, you've got a 
>> problem. It's the same problem that motivated @escaping for closures.
>> 
>> You could allow storage to be on the stack by forcing user to make a 
>> pessimistic copy, which is possibly not an improvement.
> 
> Right.  I think maybe the name people keeping using for this feature is 
> misleading; a better name would be "inline arrays" or "directly-stored 
> arrays".  Having a fixed size is a necessary condition for storing the array 
> elements directly, but the people asking for this feature are really asking 
> for the different representation, not just the ability to statically 
> constrain the size of an array.
> 
> That representation difference comes with a lot of weaknesses and trade-offs, 
> but it's also useful sometimes.
> 
> John.
> 
> 
> 
>> 
>>> Le 4 août 2017 à 09:21, Taylor Swift via swift-evolution 
>>> mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> No, that doesn’t work. In many cases you want to mutate the elements of the 
>>> array without changing its size. For example, a Camera struct which 
>>> contains a matrix buffer, and some of the matrices get updated on each 
>>> frame that the camera moves. The matrix buffer also stores all of the 
>>> camera’s stored properties, so what would be conceptually stored properties 
>>> are actually computed properties that get and set a Float at an offset into 
>>> the buffer. Of course this could all be avoided if we had fixed layout 
>>> guarantees in the language, and then the Camera struct could be the matrix 
>>> buffer and dispense with the getters and setters instead of managing a heap 
>>> buffer.
>>> 
>>> On Fri, Aug 4, 2017 at 11:02 AM, Robert Bennett via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> So, I’m getting into this thread kind of late, and I’ve only skimmed most 
>>> of it, but…
>>> 
>>> A special FSA on the stack seems like the wrong direction. Wouldn’t it make 
>>> more sense to have *all* value types that don’t change in size — including 
>>> `let` Arrays — live on the stack? In which case, FSA would merely act like 
>>> a normal `let` Array, without RangeReplaceableCollection conformance, whose 
>>> elements could be changed via subscripting. I know nothing about the 
>>> underlying implementation details of Swift, so I may be way off base here.
>>> 
 On Aug 4, 2017, at 2:18 AM, David Hart >>> > wrote:
 
 Don’t small arrays live on the stack?
 
> On 4 Aug 2017, at 06:35, Félix Cloutier via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> As far as I can tell, currently, all arrays live on the heap.
> 
>> Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution 
>> mailto:swift-evolution@swift.org>> a écrit :
>> 
>> Where do constant Arrays currently live? I hope the answer is on the 
>> stack, since their size doesn’t change.
>> 
>> On Aug 3, 2017, at 8:44 PM, Tay

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

2017-08-04 Thread John McCall via swift-evolution

> On Aug 4, 2017, at 1:19 PM, Félix Cloutier via swift-evolution 
>  wrote:
> 
> That's not a concern with the `let` case that Robert brought up, since you 
> can't mutate a `let` array at all.
> 
> The big thing is that unconstrained escape analysis is uncomputable. Since 
> Swift array storage is COW, any function that receives the array as a 
> parameter is allowed to take a reference on its storage. If the storage lives 
> on the stack and that reference outlives the stack frame, you've got a 
> problem. It's the same problem that motivated @escaping for closures.
> 
> You could allow storage to be on the stack by forcing user to make a 
> pessimistic copy, which is possibly not an improvement.

Right.  I think maybe the name people keeping using for this feature is 
misleading; a better name would be "inline arrays" or "directly-stored arrays". 
 Having a fixed size is a necessary condition for storing the array elements 
directly, but the people asking for this feature are really asking for the 
different representation, not just the ability to statically constrain the size 
of an array.

That representation difference comes with a lot of weaknesses and trade-offs, 
but it's also useful sometimes.

John.



> 
>> Le 4 août 2017 à 09:21, Taylor Swift via swift-evolution 
>> mailto:swift-evolution@swift.org>> a écrit :
>> 
>> No, that doesn’t work. In many cases you want to mutate the elements of the 
>> array without changing its size. For example, a Camera struct which contains 
>> a matrix buffer, and some of the matrices get updated on each frame that the 
>> camera moves. The matrix buffer also stores all of the camera’s stored 
>> properties, so what would be conceptually stored properties are actually 
>> computed properties that get and set a Float at an offset into the buffer. 
>> Of course this could all be avoided if we had fixed layout guarantees in the 
>> language, and then the Camera struct could be the matrix buffer and dispense 
>> with the getters and setters instead of managing a heap buffer.
>> 
>> On Fri, Aug 4, 2017 at 11:02 AM, Robert Bennett via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> So, I’m getting into this thread kind of late, and I’ve only skimmed most of 
>> it, but…
>> 
>> A special FSA on the stack seems like the wrong direction. Wouldn’t it make 
>> more sense to have *all* value types that don’t change in size — including 
>> `let` Arrays — live on the stack? In which case, FSA would merely act like a 
>> normal `let` Array, without RangeReplaceableCollection conformance, whose 
>> elements could be changed via subscripting. I know nothing about the 
>> underlying implementation details of Swift, so I may be way off base here.
>> 
>>> On Aug 4, 2017, at 2:18 AM, David Hart >> > wrote:
>>> 
>>> Don’t small arrays live on the stack?
>>> 
 On 4 Aug 2017, at 06:35, Félix Cloutier via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 As far as I can tell, currently, all arrays live on the heap.
 
> Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution 
> mailto:swift-evolution@swift.org>> a écrit :
> 
> Where do constant Arrays currently live? I hope the answer is on the 
> stack, since their size doesn’t change.
> 
> On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>> 
>> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
 
 The root cause, of course, is that the VLAs require new stack 
 allocations each time, and the stack is only deallocated as one lump 
 when the frame ends.
>>> 
>>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go 
>>> out of scope.
>>> 
>> 
>> Learned something today.
>> 
>> Anyway, if the goal is stack allocation, I would prefer that we explored 
>> other ways to achieve it before jumping to a new array-type. I’m not 
>> really a fan of a future where [3; Double] is one type and (Double, 
>> Double, Double) is something else, and Array is yet another 
>> thing.
>> 
>> They are completely different things. 
>> 
>> [3; Double] is three contiguous Doubles which may or may not live on the 
>> stack. 
>> 
>> (Double, Double, Double) is three Doubles bound to a single variable 
>> name, which the compiler can rearrange for optimal performance and may 
>> or may not live on the stack. 
>> 
>> Array is an vector of Doubles that can dynamically grow and 
>> always lives in the heap.
>>  
>> 
>> From what I’ve read so far, the problem with stack-allocating some Array 
>> that you can pass to another function and which otherwise does not 
>> escape, is that the function may make an escaping reference (e.g. 
>> assigning it to an 

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

2017-08-04 Thread Félix Cloutier via swift-evolution
That's not a concern with the `let` case that Robert brought up, since you 
can't mutate a `let` array at all.

The big thing is that unconstrained escape analysis is uncomputable. Since 
Swift array storage is COW, any function that receives the array as a parameter 
is allowed to take a reference on its storage. If the storage lives on the 
stack and that reference outlives the stack frame, you've got a problem. It's 
the same problem that motivated @escaping for closures.

You could allow storage to be on the stack by forcing user to make a 
pessimistic copy, which is possibly not an improvement.

> Le 4 août 2017 à 09:21, Taylor Swift via swift-evolution 
>  a écrit :
> 
> No, that doesn’t work. In many cases you want to mutate the elements of the 
> array without changing its size. For example, a Camera struct which contains 
> a matrix buffer, and some of the matrices get updated on each frame that the 
> camera moves. The matrix buffer also stores all of the camera’s stored 
> properties, so what would be conceptually stored properties are actually 
> computed properties that get and set a Float at an offset into the buffer. Of 
> course this could all be avoided if we had fixed layout guarantees in the 
> language, and then the Camera struct could be the matrix buffer and dispense 
> with the getters and setters instead of managing a heap buffer.
> 
> On Fri, Aug 4, 2017 at 11:02 AM, Robert Bennett via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> So, I’m getting into this thread kind of late, and I’ve only skimmed most of 
> it, but…
> 
> A special FSA on the stack seems like the wrong direction. Wouldn’t it make 
> more sense to have *all* value types that don’t change in size — including 
> `let` Arrays — live on the stack? In which case, FSA would merely act like a 
> normal `let` Array, without RangeReplaceableCollection conformance, whose 
> elements could be changed via subscripting. I know nothing about the 
> underlying implementation details of Swift, so I may be way off base here.
> 
>> On Aug 4, 2017, at 2:18 AM, David Hart > > wrote:
>> 
>> Don’t small arrays live on the stack?
>> 
>>> On 4 Aug 2017, at 06:35, Félix Cloutier via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> As far as I can tell, currently, all arrays live on the heap.
>>> 
 Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution 
 mailto:swift-evolution@swift.org>> a écrit :
 
 Where do constant Arrays currently live? I hope the answer is on the 
 stack, since their size doesn’t change.
 
 On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
> 
> 
> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> The root cause, of course, is that the VLAs require new stack 
>>> allocations each time, and the stack is only deallocated as one lump 
>>> when the frame ends.
>> 
>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go 
>> out of scope.
>> 
> 
> Learned something today.
> 
> Anyway, if the goal is stack allocation, I would prefer that we explored 
> other ways to achieve it before jumping to a new array-type. I’m not 
> really a fan of a future where [3; Double] is one type and (Double, 
> Double, Double) is something else, and Array is yet another thing.
> 
> They are completely different things. 
> 
> [3; Double] is three contiguous Doubles which may or may not live on the 
> stack. 
> 
> (Double, Double, Double) is three Doubles bound to a single variable 
> name, which the compiler can rearrange for optimal performance and may or 
> may not live on the stack. 
> 
> Array is an vector of Doubles that can dynamically grow and 
> always lives in the heap.
>  
> 
> From what I’ve read so far, the problem with stack-allocating some Array 
> that you can pass to another function and which otherwise does not 
> escape, is that the function may make an escaping reference (e.g. 
> assigning it to an ivar or global, or capturing it in a closure).
> 
> How about if the compiler treated every Array it receives in a function 
> as being potentially stack-allocated. The first time you capture it, it 
> will check and copy to the heap if necessary. All subsequent escapes 
> (including passing to other functions) use the Array known to be 
> allocated on the heap, avoiding further checking or copying within the 
> function.
> 
> The same goes for Dictionary, and really any arbitrary value-type with 
> COW storage. The memory that those types allocate is part of the value, 
> so it would be cool if we could treat it like that.
> 
> 
> This is not true. FSAs have nothing to do with automatic

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

2017-08-04 Thread Félix Cloutier via swift-evolution
I've never seen the Swift compiler put array storage on automatic storage, even 
for small arrays. I don't think that it has much to do with their size, though 
(for any array that is not incredibly large).

> Le 3 août 2017 à 23:18, David Hart  a écrit :
> 
> Don’t small arrays live on the stack?
> 
>> On 4 Aug 2017, at 06:35, Félix Cloutier via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> As far as I can tell, currently, all arrays live on the heap.
>> 
>>> Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution 
>>> mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> Where do constant Arrays currently live? I hope the answer is on the stack, 
>>> since their size doesn’t change.
>>> 
>>> On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 
 
 On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
>> 
>> The root cause, of course, is that the VLAs require new stack 
>> allocations each time, and the stack is only deallocated as one lump 
>> when the frame ends.
> 
> That is true of alloca(), but not of VLAs.  VLAs are freed when they go 
> out of scope.
> 
 
 Learned something today.
 
 Anyway, if the goal is stack allocation, I would prefer that we explored 
 other ways to achieve it before jumping to a new array-type. I’m not 
 really a fan of a future where [3; Double] is one type and (Double, 
 Double, Double) is something else, and Array is yet another thing.
 
 They are completely different things. 
 
 [3; Double] is three contiguous Doubles which may or may not live on the 
 stack. 
 
 (Double, Double, Double) is three Doubles bound to a single variable name, 
 which the compiler can rearrange for optimal performance and may or may 
 not live on the stack. 
 
 Array is an vector of Doubles that can dynamically grow and always 
 lives in the heap.
  
 
 From what I’ve read so far, the problem with stack-allocating some Array 
 that you can pass to another function and which otherwise does not escape, 
 is that the function may make an escaping reference (e.g. assigning it to 
 an ivar or global, or capturing it in a closure).
 
 How about if the compiler treated every Array it receives in a function as 
 being potentially stack-allocated. The first time you capture it, it will 
 check and copy to the heap if necessary. All subsequent escapes (including 
 passing to other functions) use the Array known to be allocated on the 
 heap, avoiding further checking or copying within the function.
 
 The same goes for Dictionary, and really any arbitrary value-type with COW 
 storage. The memory that those types allocate is part of the value, so it 
 would be cool if we could treat it like that.
 
 
 This is not true. FSAs have nothing to do with automatic storage, their 
 static size only makes them eligible to live on the stack, as tuples are 
 now. The defining quality of FSAs is that they are static and contiguous. 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-04 Thread Taylor Swift via swift-evolution
No, that doesn’t work. In many cases you want to mutate the elements of the
array without changing its size. For example, a Camera struct which
contains a matrix buffer, and some of the matrices get updated on each
frame that the camera moves. The matrix buffer also stores all of the
camera’s stored properties, so what would be conceptually stored properties
are actually computed properties that get and set a Float at an offset into
the buffer. Of course this could all be avoided if we had fixed layout
guarantees in the language, and then the Camera struct could *be* the
matrix buffer and dispense with the getters and setters instead of managing
a heap buffer.

On Fri, Aug 4, 2017 at 11:02 AM, Robert Bennett via swift-evolution <
swift-evolution@swift.org> wrote:

> So, I’m getting into this thread kind of late, and I’ve only skimmed most
> of it, but…
>
> A special FSA on the stack seems like the wrong direction. Wouldn’t it
> make more sense to have *all* value types that don’t change in size —
> including `let` Arrays — live on the stack? In which case, FSA would merely
> act like a normal `let` Array, without RangeReplaceableCollection
> conformance, whose elements could be changed via subscripting. I know
> nothing about the underlying implementation details of Swift, so I may be
> way off base here.
>
> On Aug 4, 2017, at 2:18 AM, David Hart  wrote:
>
> Don’t small arrays live on the stack?
>
> On 4 Aug 2017, at 06:35, Félix Cloutier via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> As far as I can tell, currently, all arrays live on the heap.
>
> Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution <
> swift-evolution@swift.org> a écrit :
>
> Where do constant Arrays currently live? I hope the answer is on the
> stack, since their size doesn’t change.
>
> On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
>
> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> The root cause, of course, is that the VLAs require new stack allocations
>> each time, and the stack is only deallocated as one lump when the frame
>> ends.
>>
>>
>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go
>> out of scope.
>>
>>
>> Learned something today.
>>
>> Anyway, if the goal is stack allocation, I would prefer that we explored
>> other ways to achieve it before jumping to a new array-type. I’m not really
>> a fan of a future where [3; Double] is one type and (Double, Double,
>> Double) is something else, and Array is yet another thing.
>>
>
> They are completely different things.
>
> [3; Double] is three *contiguous* Doubles which may or may not live on
> the stack.
>
> (Double, Double, Double) is three Doubles bound to a single variable
> *name*, which the compiler can rearrange for optimal performance and may
> or may not live on the stack.
>
> Array is an vector of Doubles that can dynamically grow and always
> lives in the heap.
>
>
>>
>> From what I’ve read so far, the problem with stack-allocating some Array
>> that you can pass to another function and which otherwise does not escape,
>> is that the function may make an escaping reference (e.g. assigning it to
>> an ivar or global, or capturing it in a closure).
>>
>> How about if the compiler treated every Array it receives in a function
>> as being potentially stack-allocated. The first time you capture it, it
>> will check and copy to the heap if necessary. All subsequent escapes
>> (including passing to other functions) use the Array known to be allocated
>> on the heap, avoiding further checking or copying within the function.
>>
>> The same goes for Dictionary, and really any arbitrary value-type with
>> COW storage. The memory that those types allocate is part of the value, so
>> it would be cool if we could treat it like that.
>>
>>
> This is not true. FSAs have nothing to do with automatic storage, their
> static size only makes them *eligible* to live on the stack, as tuples
> are now. The defining quality of FSAs is that they are static and
> contiguous.
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-04 Thread Robert Bennett via swift-evolution
So, I’m getting into this thread kind of late, and I’ve only skimmed most of 
it, but…

A special FSA on the stack seems like the wrong direction. Wouldn’t it make 
more sense to have *all* value types that don’t change in size — including 
`let` Arrays — live on the stack? In which case, FSA would merely act like a 
normal `let` Array, without RangeReplaceableCollection conformance, whose 
elements could be changed via subscripting. I know nothing about the underlying 
implementation details of Swift, so I may be way off base here.

> On Aug 4, 2017, at 2:18 AM, David Hart  wrote:
> 
> Don’t small arrays live on the stack?
> 
>> On 4 Aug 2017, at 06:35, Félix Cloutier via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> As far as I can tell, currently, all arrays live on the heap.
>> 
>>> Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution 
>>> mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> Where do constant Arrays currently live? I hope the answer is on the stack, 
>>> since their size doesn’t change.
>>> 
>>> On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 
 
 On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
>> 
>> The root cause, of course, is that the VLAs require new stack 
>> allocations each time, and the stack is only deallocated as one lump 
>> when the frame ends.
> 
> That is true of alloca(), but not of VLAs.  VLAs are freed when they go 
> out of scope.
> 
 
 Learned something today.
 
 Anyway, if the goal is stack allocation, I would prefer that we explored 
 other ways to achieve it before jumping to a new array-type. I’m not 
 really a fan of a future where [3; Double] is one type and (Double, 
 Double, Double) is something else, and Array is yet another thing.
 
 They are completely different things. 
 
 [3; Double] is three contiguous Doubles which may or may not live on the 
 stack. 
 
 (Double, Double, Double) is three Doubles bound to a single variable name, 
 which the compiler can rearrange for optimal performance and may or may 
 not live on the stack. 
 
 Array is an vector of Doubles that can dynamically grow and always 
 lives in the heap.
  
 
 From what I’ve read so far, the problem with stack-allocating some Array 
 that you can pass to another function and which otherwise does not escape, 
 is that the function may make an escaping reference (e.g. assigning it to 
 an ivar or global, or capturing it in a closure).
 
 How about if the compiler treated every Array it receives in a function as 
 being potentially stack-allocated. The first time you capture it, it will 
 check and copy to the heap if necessary. All subsequent escapes (including 
 passing to other functions) use the Array known to be allocated on the 
 heap, avoiding further checking or copying within the function.
 
 The same goes for Dictionary, and really any arbitrary value-type with COW 
 storage. The memory that those types allocate is part of the value, so it 
 would be cool if we could treat it like that.
 
 
 This is not true. FSAs have nothing to do with automatic storage, their 
 static size only makes them eligible to live on the stack, as tuples are 
 now. The defining quality of FSAs is that they are static and contiguous. 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread David Hart via swift-evolution
Don’t small arrays live on the stack?

> On 4 Aug 2017, at 06:35, Félix Cloutier via swift-evolution 
>  wrote:
> 
> As far as I can tell, currently, all arrays live on the heap.
> 
>> Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution 
>> mailto:swift-evolution@swift.org>> a écrit :
>> 
>> Where do constant Arrays currently live? I hope the answer is on the stack, 
>> since their size doesn’t change.
>> 
>> On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> 
>>> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
> 
> The root cause, of course, is that the VLAs require new stack allocations 
> each time, and the stack is only deallocated as one lump when the frame 
> ends.
 
 That is true of alloca(), but not of VLAs.  VLAs are freed when they go 
 out of scope.
 
>>> 
>>> Learned something today.
>>> 
>>> Anyway, if the goal is stack allocation, I would prefer that we explored 
>>> other ways to achieve it before jumping to a new array-type. I’m not really 
>>> a fan of a future where [3; Double] is one type and (Double, Double, 
>>> Double) is something else, and Array is yet another thing.
>>> 
>>> They are completely different things. 
>>> 
>>> [3; Double] is three contiguous Doubles which may or may not live on the 
>>> stack. 
>>> 
>>> (Double, Double, Double) is three Doubles bound to a single variable name, 
>>> which the compiler can rearrange for optimal performance and may or may not 
>>> live on the stack. 
>>> 
>>> Array is an vector of Doubles that can dynamically grow and always 
>>> lives in the heap.
>>>  
>>> 
>>> From what I’ve read so far, the problem with stack-allocating some Array 
>>> that you can pass to another function and which otherwise does not escape, 
>>> is that the function may make an escaping reference (e.g. assigning it to 
>>> an ivar or global, or capturing it in a closure).
>>> 
>>> How about if the compiler treated every Array it receives in a function as 
>>> being potentially stack-allocated. The first time you capture it, it will 
>>> check and copy to the heap if necessary. All subsequent escapes (including 
>>> passing to other functions) use the Array known to be allocated on the 
>>> heap, avoiding further checking or copying within the function.
>>> 
>>> The same goes for Dictionary, and really any arbitrary value-type with COW 
>>> storage. The memory that those types allocate is part of the value, so it 
>>> would be cool if we could treat it like that.
>>> 
>>> 
>>> This is not true. FSAs have nothing to do with automatic storage, their 
>>> static size only makes them eligible to live on the stack, as tuples are 
>>> now. The defining quality of FSAs is that they are static and contiguous. 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread Félix Cloutier via swift-evolution
As far as I can tell, currently, all arrays live on the heap.

> Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution 
>  a écrit :
> 
> Where do constant Arrays currently live? I hope the answer is on the stack, 
> since their size doesn’t change.
> 
> On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>> 
>> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
 
 The root cause, of course, is that the VLAs require new stack allocations 
 each time, and the stack is only deallocated as one lump when the frame 
 ends.
>>> 
>>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go out 
>>> of scope.
>>> 
>> 
>> Learned something today.
>> 
>> Anyway, if the goal is stack allocation, I would prefer that we explored 
>> other ways to achieve it before jumping to a new array-type. I’m not really 
>> a fan of a future where [3; Double] is one type and (Double, Double, Double) 
>> is something else, and Array is yet another thing.
>> 
>> They are completely different things. 
>> 
>> [3; Double] is three contiguous Doubles which may or may not live on the 
>> stack. 
>> 
>> (Double, Double, Double) is three Doubles bound to a single variable name, 
>> which the compiler can rearrange for optimal performance and may or may not 
>> live on the stack. 
>> 
>> Array is an vector of Doubles that can dynamically grow and always 
>> lives in the heap.
>>  
>> 
>> From what I’ve read so far, the problem with stack-allocating some Array 
>> that you can pass to another function and which otherwise does not escape, 
>> is that the function may make an escaping reference (e.g. assigning it to an 
>> ivar or global, or capturing it in a closure).
>> 
>> How about if the compiler treated every Array it receives in a function as 
>> being potentially stack-allocated. The first time you capture it, it will 
>> check and copy to the heap if necessary. All subsequent escapes (including 
>> passing to other functions) use the Array known to be allocated on the heap, 
>> avoiding further checking or copying within the function.
>> 
>> The same goes for Dictionary, and really any arbitrary value-type with COW 
>> storage. The memory that those types allocate is part of the value, so it 
>> would be cool if we could treat it like that.
>> 
>> 
>> This is not true. FSAs have nothing to do with automatic storage, their 
>> static size only makes them eligible to live on the stack, as tuples are 
>> now. The defining quality of FSAs is that they are static and contiguous. 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread Félix Cloutier via swift-evolution

> Le 3 août 2017 à 17:44, Taylor Swift via swift-evolution 
>  a écrit :
> 
> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> The root cause, of course, is that the VLAs require new stack allocations 
>>> each time, and the stack is only deallocated as one lump when the frame 
>>> ends.
>> 
>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go out 
>> of scope.
>> 
> 
> Learned something today.
> 
> Anyway, if the goal is stack allocation, I would prefer that we explored 
> other ways to achieve it before jumping to a new array-type. I’m not really a 
> fan of a future where [3; Double] is one type and (Double, Double, Double) is 
> something else, and Array is yet another thing.
> 
> They are completely different things. 
> 
> [3; Double] is three contiguous Doubles which may or may not live on the 
> stack. 
> 
> (Double, Double, Double) is three Doubles bound to a single variable name, 
> which the compiler can rearrange for optimal performance and may or may not 
> live on the stack. 

To be clear, there is no Swift value type that guarantees that the order in 
which fields are laid out is the same as the order in which they're declared. 
It's not just tuples. (Structs imported from C are always laid out with their C 
layout, of course.)

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread Taylor Swift via swift-evolution
For what it’s worth, I’d be happy with just subscripts on tuples and some
form of shorthand for their size. Maybe

(Float ... 5)

or something like that. That would obviate the need for an attribute too.

On Thu, Aug 3, 2017 at 11:48 PM, Karl Wagner  wrote:

>
> Actually, if you do a lot of graphics programming like I do, the memory
> layout is very, *very* important. Swift may not care about layout, but
> many APIs that it interacts with do.
>
>
> Sure; I’m well-aware of how important it can be to decide on an
> appropriate memory layout. I’m very much in favour of opting-in to
> contiguous layout for tuples.
>
> Is @fixed_layout actually planned to be part of the language? I was under
> the impression it’s just a placeholder attribute. Either way, I’d
> appreciate not having to write Float sixteen times for a 4x4 matrix type.
>
>
> AFAIK @fixed_layout is a placeholder attribute. And I’m also very much in
> favour of a shorthand for declaring a fixed-size list.
>
> I just don’t see why we need to introduce this new kind of list-like thing
> in order to get what we need. It makes it harder to project a coherent
> message about when to use which data-type.
>
> - Karl
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread Karl Wagner via swift-evolution

> Actually, if you do a lot of graphics programming like I do, the memory 
> layout is very, very important. Swift may not care about layout, but many 
> APIs that it interacts with do. 
> 

Sure; I’m well-aware of how important it can be to decide on an appropriate 
memory layout. I’m very much in favour of opting-in to contiguous layout for 
tuples.

> Is @fixed_layout actually planned to be part of the language? I was under the 
> impression it’s just a placeholder attribute. Either way, I’d appreciate not 
> having to write Float sixteen times for a 4x4 matrix type.
> 

AFAIK @fixed_layout is a placeholder attribute. And I’m also very much in 
favour of a shorthand for declaring a fixed-size list.

I just don’t see why we need to introduce this new kind of list-like thing in 
order to get what we need. It makes it harder to project a coherent message 
about when to use which data-type.

- Karl___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread Taylor Swift via swift-evolution
On Thu, Aug 3, 2017 at 11:17 PM, Karl Wagner  wrote:

>
> On 4. Aug 2017, at 02:44, Taylor Swift via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
>
> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> The root cause, of course, is that the VLAs require new stack allocations
>> each time, and the stack is only deallocated as one lump when the frame
>> ends.
>>
>>
>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go
>> out of scope.
>>
>>
>> Learned something today.
>>
>> Anyway, if the goal is stack allocation, I would prefer that we explored
>> other ways to achieve it before jumping to a new array-type. I’m not really
>> a fan of a future where [3; Double] is one type and (Double, Double,
>> Double) is something else, and Array is yet another thing.
>>
>
> They are completely different things.
>
> [3; Double] is three *contiguous* Doubles which may or may not live on
> the stack.
>
> (Double, Double, Double) is three Doubles bound to a single variable
> *name*, which the compiler can rearrange for optimal performance and may
> or may not live on the stack.
>
> Array is an vector of Doubles that can dynamically grow and always
> lives in the heap.
>
>
>
> Yeah, I understand that — the problem I have is that I’m not sure it’s
> going to be obvious to everybody *else* when they should use which. We
> need to balance semantic purity against simplicity and ease-of-learning.
>
> For example, I’m not sure many users are aware that tuple elements in
> Swift don’t have an ordered relationship; they certainly give that
> impression. This is especially confusing as "In mathematics a tuple is a
> finite ordered list (sequence) of elements.” [https://en.wikipedia.org/
> wiki/Tuple]
>
>
>> From what I’ve read so far, the problem with stack-allocating some Array
>> that you can pass to another function and which otherwise does not escape,
>> is that the function may make an escaping reference (e.g. assigning it to
>> an ivar or global, or capturing it in a closure).
>>
>> How about if the compiler treated every Array it receives in a function
>> as being potentially stack-allocated. The first time you capture it, it
>> will check and copy to the heap if necessary. All subsequent escapes
>> (including passing to other functions) use the Array known to be allocated
>> on the heap, avoiding further checking or copying within the function.
>>
>> The same goes for Dictionary, and really any arbitrary value-type with
>> COW storage. The memory that those types allocate is part of the value, so
>> it would be cool if we could treat it like that.
>>
>>
> This is not true. FSAs have nothing to do with automatic storage, their
> static size only makes them *eligible* to live on the stack, as tuples
> are now. The defining quality of FSAs is that they are static and
> contiguous.
>
>
> Really, the only *practical* difference between a FSA and a tuple is the
> memory layout. Do most users really need to care about that? For those
> users that do, wouldn’t an @-attribute be a less intrusive change to the
> language than a whole new list-style type?
>
> For example, the benefit to having Collection-conforming tuples as our
> FSAs would be that they don’t necessarily have to be contiguous. If you
> have a large multi-dimensional list of Bools or some other tiny type, you
> might also *benefit* from those layout optimisations.
>
> I like the simplicity in telling people:
>
> - If you need a dynamically-sized list, use an Array
> - If you need a fixed-sized list, use a tuple (and it will get an
> optimised layout. You can override this with an attribute, similar to
> @fixed_layout or @inlineable).
>
> - Karl
>

Actually, if you do a lot of graphics programming like I do, the memory
layout is very, *very* important. Swift may not care about layout, but many
APIs that it interacts with do.

Is @fixed_layout actually planned to be part of the language? I was under
the impression it’s just a placeholder attribute. Either way, I’d
appreciate not having to write Float sixteen times for a 4x4 matrix type.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread Karl Wagner via swift-evolution

> On 4. Aug 2017, at 02:44, Taylor Swift via swift-evolution 
>  wrote:
> 
> 
> 
> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> The root cause, of course, is that the VLAs require new stack allocations 
>>> each time, and the stack is only deallocated as one lump when the frame 
>>> ends.
>> 
>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go out 
>> of scope.
>> 
> 
> Learned something today.
> 
> Anyway, if the goal is stack allocation, I would prefer that we explored 
> other ways to achieve it before jumping to a new array-type. I’m not really a 
> fan of a future where [3; Double] is one type and (Double, Double, Double) is 
> something else, and Array is yet another thing.
> 
> They are completely different things. 
> 
> [3; Double] is three contiguous Doubles which may or may not live on the 
> stack. 
> 
> (Double, Double, Double) is three Doubles bound to a single variable name, 
> which the compiler can rearrange for optimal performance and may or may not 
> live on the stack. 
> 
> Array is an vector of Doubles that can dynamically grow and always 
> lives in the heap.
>  

Yeah, I understand that — the problem I have is that I’m not sure it’s going to 
be obvious to everybody else when they should use which. We need to balance 
semantic purity against simplicity and ease-of-learning.

For example, I’m not sure many users are aware that tuple elements in Swift 
don’t have an ordered relationship; they certainly give that impression. This 
is especially confusing as "In mathematics a tuple is a finite ordered list 
(sequence) of elements.” [https://en.wikipedia.org/wiki/Tuple 
]

> 
> From what I’ve read so far, the problem with stack-allocating some Array that 
> you can pass to another function and which otherwise does not escape, is that 
> the function may make an escaping reference (e.g. assigning it to an ivar or 
> global, or capturing it in a closure).
> 
> How about if the compiler treated every Array it receives in a function as 
> being potentially stack-allocated. The first time you capture it, it will 
> check and copy to the heap if necessary. All subsequent escapes (including 
> passing to other functions) use the Array known to be allocated on the heap, 
> avoiding further checking or copying within the function.
> 
> The same goes for Dictionary, and really any arbitrary value-type with COW 
> storage. The memory that those types allocate is part of the value, so it 
> would be cool if we could treat it like that.
> 
> 
> This is not true. FSAs have nothing to do with automatic storage, their 
> static size only makes them eligible to live on the stack, as tuples are now. 
> The defining quality of FSAs is that they are static and contiguous. 

Really, the only practical difference between a FSA and a tuple is the memory 
layout. Do most users really need to care about that? For those users that do, 
wouldn’t an @-attribute be a less intrusive change to the language than a whole 
new list-style type?

For example, the benefit to having Collection-conforming tuples as our FSAs 
would be that they don’t necessarily have to be contiguous. If you have a large 
multi-dimensional list of Bools or some other tiny type, you might also benefit 
from those layout optimisations.

I like the simplicity in telling people:

- If you need a dynamically-sized list, use an Array
- If you need a fixed-sized list, use a tuple (and it will get an optimised 
layout. You can override this with an attribute, similar to @fixed_layout or 
@inlineable).

- Karl___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread Robert Bennett via swift-evolution
Where do constant Arrays currently live? I hope the answer is on the stack, 
since their size doesn’t change.

> On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> 
> 
> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
>  wrote:
 
 The root cause, of course, is that the VLAs require new stack allocations 
 each time, and the stack is only deallocated as one lump when the frame 
 ends.
>>> 
>>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go out 
>>> of scope.
>>> 
>> 
>> Learned something today.
>> 
>> Anyway, if the goal is stack allocation, I would prefer that we explored 
>> other ways to achieve it before jumping to a new array-type. I’m not really 
>> a fan of a future where [3; Double] is one type and (Double, Double, Double) 
>> is something else, and Array is yet another thing.
> 
> They are completely different things. 
> 
> [3; Double] is three contiguous Doubles which may or may not live on the 
> stack. 
> 
> (Double, Double, Double) is three Doubles bound to a single variable name, 
> which the compiler can rearrange for optimal performance and may or may not 
> live on the stack. 
> 
> Array is an vector of Doubles that can dynamically grow and always 
> lives in the heap.
>  
>> 
>> From what I’ve read so far, the problem with stack-allocating some Array 
>> that you can pass to another function and which otherwise does not escape, 
>> is that the function may make an escaping reference (e.g. assigning it to an 
>> ivar or global, or capturing it in a closure).
>> 
>> How about if the compiler treated every Array it receives in a function as 
>> being potentially stack-allocated. The first time you capture it, it will 
>> check and copy to the heap if necessary. All subsequent escapes (including 
>> passing to other functions) use the Array known to be allocated on the heap, 
>> avoiding further checking or copying within the function.
>> 
>> The same goes for Dictionary, and really any arbitrary value-type with COW 
>> storage. The memory that those types allocate is part of the value, so it 
>> would be cool if we could treat it like that.
>> 
> 
> This is not true. FSAs have nothing to do with automatic storage, their 
> static size only makes them eligible to live on the stack, as tuples are now. 
> The defining quality of FSAs is that they are static and contiguous. 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread Taylor Swift via swift-evolution
On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution <
swift-evolution@swift.org> wrote:

>
> The root cause, of course, is that the VLAs require new stack allocations
> each time, and the stack is only deallocated as one lump when the frame
> ends.
>
>
> That is true of alloca(), but not of VLAs.  VLAs are freed when they go
> out of scope.
>
>
> Learned something today.
>
> Anyway, if the goal is stack allocation, I would prefer that we explored
> other ways to achieve it before jumping to a new array-type. I’m not really
> a fan of a future where [3; Double] is one type and (Double, Double,
> Double) is something else, and Array is yet another thing.
>

They are completely different things.

[3; Double] is three *contiguous* Doubles which may or may not live on the
stack.

(Double, Double, Double) is three Doubles bound to a single variable *name*,
which the compiler can rearrange for optimal performance and may or may not
live on the stack.

Array is an vector of Doubles that can dynamically grow and always
lives in the heap.


>
> From what I’ve read so far, the problem with stack-allocating some Array
> that you can pass to another function and which otherwise does not escape,
> is that the function may make an escaping reference (e.g. assigning it to
> an ivar or global, or capturing it in a closure).
>
> How about if the compiler treated every Array it receives in a function as
> being potentially stack-allocated. The first time you capture it, it will
> check and copy to the heap if necessary. All subsequent escapes (including
> passing to other functions) use the Array known to be allocated on the
> heap, avoiding further checking or copying within the function.
>
> The same goes for Dictionary, and really any arbitrary value-type with COW
> storage. The memory that those types allocate is part of the value, so it
> would be cool if we could treat it like that.
>
>
This is not true. FSAs have nothing to do with automatic storage, their
static size only makes them *eligible* to live on the stack, as tuples are
now. The defining quality of FSAs is that they are static and contiguous.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-03 Thread Karl Wagner via swift-evolution
>> 
>> The root cause, of course, is that the VLAs require new stack allocations 
>> each time, and the stack is only deallocated as one lump when the frame ends.
> 
> That is true of alloca(), but not of VLAs.  VLAs are freed when they go out 
> of scope.
> 

Learned something today.

Anyway, if the goal is stack allocation, I would prefer that we explored other 
ways to achieve it before jumping to a new array-type. I’m not really a fan of 
a future where [3; Double] is one type and (Double, Double, Double) is 
something else, and Array is yet another thing.

>From what I’ve read so far, the problem with stack-allocating some Array that 
>you can pass to another function and which otherwise does not escape, is that 
>the function may make an escaping reference (e.g. assigning it to an ivar or 
>global, or capturing it in a closure).

How about if the compiler treated every Array it receives in a function as 
being potentially stack-allocated. The first time you capture it, it will check 
and copy to the heap if necessary. All subsequent escapes (including passing to 
other functions) use the Array known to be allocated on the heap, avoiding 
further checking or copying within the function.

The same goes for Dictionary, and really any arbitrary value-type with COW 
storage. The memory that those types allocate is part of the value, so it would 
be cool if we could treat it like that.

- Karl___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-02 Thread John McCall via swift-evolution

> On Aug 2, 2017, at 6:29 PM, Karl Wagner  wrote:
> 
> 
>> On 3. Aug 2017, at 00:21, John McCall > > wrote:
>> 
>> 
>>> On Aug 2, 2017, at 6:10 PM, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 On Aug 2, 2017, at 5:56 PM, Karl Wagner >>> > wrote:
> On 31. Jul 2017, at 21:09, John McCall via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
>> mailto:gor.f.gyolchan...@icloud.com>> 
>> wrote:
>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 On Jul 30, 2017, at 11:43 PM, Daryle Walker >>> > 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.
> 
> You're making huge leaps here.  The primary purpose of a fixed-size array 
> feature is to allow the array to be allocated "inline" in its context 
> instead of "out-of-line" using heap-allocated copy-on-write buffers.  
> There is no reason that that representation would not be supportable just 
> because the array's bound is not statically known; the only thing that 
> matters is whether the bound is consistent for all instances of the 
> container.
> 
> That is, it would not be okay to have a type like:
>  struct Widget {
>let length: Int
>var array: [length x Int]
>  }
> because the value of the bound cannot be computed independently of a 
> specific value.
> 
> But it is absolutely okay to have a type like:
>  struct Widget {
>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>  }
> It just means that the bound would get computed at runtime and, 
> presumably, cached.  The fact that this type's size isn't known 
> statically does mean that the compiler has to be more pessimistic, but 
> its values would still get allocated inline into their containers and 
> even on the stack, using pretty much the same techniques as C99 VLAs.
 
 Do we really want to make that guarantee about heap/stack allocation? 
 C99’s VLAs are not very loop-friendly:
 
 echo "int main() { 
 for(int i = 0; i<100; i++) {
   int myArray[i * 1000]; myArray[0] = 32;
 }
 return 0;
   }" | clang -x c - && ./a.out
 
 Segmentation Fault: 11
 
 C compilers also do not inline code with VLAs by default. If you force it, 
 you expose yourself to possible stack overflows:
 
 echo "static inline void doSomething(int i) {
 int myArray[i * 1000]; myArray[0] = 32;
   }
   int main() {
 for(int i = 0; i<100; i++) {
   doSomething(i);
 }
   return 0;
   }" | clang -x c - && ./a.out
 
 Segmentation Fault: 11
 
 I wouldn’t like us to import these kinds of issues in to Swift
>>> 
>>> We probably would not make an absolute guarantee of stack allocation, no.
>> 
>> Although I will note that the problem in your example has nothing to do with 
>> it being a loop and everything to do with it asking for an almost 4GB array. 
>> :)
>> 
>> John.
> 
> 
> Yeah, apologies - it was a bit of a poorly-written example.
> 
> The root cause, of course, is that the VLAs require new stack allocations 
> each time, and the stack is only deallocated as one lump when the frame ends.

That is true of alloca(), but not of VLAs.  VLAs are freed when they go out of 
scope.  Your example crashes only because it is doing a huge stack allocation.

#include 
#include 

void foo(size_t n) {
int fd = open("/dev/null", O_RDONLY);
for (int i = 0; i < 1000; ++i) {
char buffer[n];
read(fd, buffer, n);
}
close(fd);
}

int main() {
foo(10);
}

> A 

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

2017-08-02 Thread Karl Wagner via swift-evolution

> On 3. Aug 2017, at 00:21, John McCall  wrote:
> 
> 
>> On Aug 2, 2017, at 6:10 PM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Aug 2, 2017, at 5:56 PM, Karl Wagner >> > wrote:
 On 31. Jul 2017, at 21:09, John McCall via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
> mailto:gor.f.gyolchan...@icloud.com>> 
> wrote:
>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker >> > 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.
 
 You're making huge leaps here.  The primary purpose of a fixed-size array 
 feature is to allow the array to be allocated "inline" in its context 
 instead of "out-of-line" using heap-allocated copy-on-write buffers.  
 There is no reason that that representation would not be supportable just 
 because the array's bound is not statically known; the only thing that 
 matters is whether the bound is consistent for all instances of the 
 container.
 
 That is, it would not be okay to have a type like:
  struct Widget {
let length: Int
var array: [length x Int]
  }
 because the value of the bound cannot be computed independently of a 
 specific value.
 
 But it is absolutely okay to have a type like:
  struct Widget {
var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
  }
 It just means that the bound would get computed at runtime and, 
 presumably, cached.  The fact that this type's size isn't known statically 
 does mean that the compiler has to be more pessimistic, but its values 
 would still get allocated inline into their containers and even on the 
 stack, using pretty much the same techniques as C99 VLAs.
>>> 
>>> Do we really want to make that guarantee about heap/stack allocation? C99’s 
>>> VLAs are not very loop-friendly:
>>> 
>>> echo "int main() { 
>>> for(int i = 0; i<100; i++) {
>>>   int myArray[i * 1000]; myArray[0] = 32;
>>> }
>>> return 0;
>>>   }" | clang -x c - && ./a.out
>>> 
>>> Segmentation Fault: 11
>>> 
>>> C compilers also do not inline code with VLAs by default. If you force it, 
>>> you expose yourself to possible stack overflows:
>>> 
>>> echo "static inline void doSomething(int i) {
>>> int myArray[i * 1000]; myArray[0] = 32;
>>>   }
>>>   int main() {
>>> for(int i = 0; i<100; i++) {
>>>   doSomething(i);
>>> }
>>>   return 0;
>>>   }" | clang -x c - && ./a.out
>>> 
>>> Segmentation Fault: 11
>>> 
>>> I wouldn’t like us to import these kinds of issues in to Swift
>> 
>> We probably would not make an absolute guarantee of stack allocation, no.
> 
> Although I will note that the problem in your example has nothing to do with 
> it being a loop and everything to do with it asking for an almost 4GB array. 
> :)
> 
> John.


Yeah, apologies - it was a bit of a poorly-written example.

The root cause, of course, is that the VLAs require new stack allocations each 
time, and the stack is only deallocated as one lump when the frame ends. A 
fixed-size object could be allocated once and re-used. Inlining prevents new 
stack frames being created and hence defers deallocation of those objects until 
the outer function ends, pushing up the high-water mark of the stack.

The problem also happens with an outer loop of only 10_000, so only 38MB. 
Still, enough to blow it up.

- Karl___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-02 Thread John McCall via swift-evolution

> On Aug 2, 2017, at 6:10 PM, John McCall via swift-evolution 
>  wrote:
> 
>> On Aug 2, 2017, at 5:56 PM, Karl Wagner > > wrote:
>>> On 31. Jul 2017, at 21:09, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan >>> > wrote:
> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> On Jul 30, 2017, at 11:43 PM, Daryle Walker > > 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.
>>> 
>>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>>> feature is to allow the array to be allocated "inline" in its context 
>>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  There 
>>> is no reason that that representation would not be supportable just because 
>>> the array's bound is not statically known; the only thing that matters is 
>>> whether the bound is consistent for all instances of the container.
>>> 
>>> That is, it would not be okay to have a type like:
>>>  struct Widget {
>>>let length: Int
>>>var array: [length x Int]
>>>  }
>>> because the value of the bound cannot be computed independently of a 
>>> specific value.
>>> 
>>> But it is absolutely okay to have a type like:
>>>  struct Widget {
>>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>>  }
>>> It just means that the bound would get computed at runtime and, presumably, 
>>> cached.  The fact that this type's size isn't known statically does mean 
>>> that the compiler has to be more pessimistic, but its values would still 
>>> get allocated inline into their containers and even on the stack, using 
>>> pretty much the same techniques as C99 VLAs.
>> 
>> Do we really want to make that guarantee about heap/stack allocation? C99’s 
>> VLAs are not very loop-friendly:
>> 
>> echo "int main() { 
>> for(int i = 0; i<100; i++) {
>>   int myArray[i * 1000]; myArray[0] = 32;
>> }
>> return 0;
>>   }" | clang -x c - && ./a.out
>> 
>> Segmentation Fault: 11
>> 
>> C compilers also do not inline code with VLAs by default. If you force it, 
>> you expose yourself to possible stack overflows:
>> 
>> echo "static inline void doSomething(int i) {
>> int myArray[i * 1000]; myArray[0] = 32;
>>   }
>>   int main() {
>> for(int i = 0; i<100; i++) {
>>   doSomething(i);
>> }
>>   return 0;
>>   }" | clang -x c - && ./a.out
>> 
>> Segmentation Fault: 11
>> 
>> I wouldn’t like us to import these kinds of issues in to Swift
> 
> We probably would not make an absolute guarantee of stack allocation, no.

Although I will note that the problem in your example has nothing to do with it 
being a loop and everything to do with it asking for an almost 4GB array. :)

John.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-02 Thread John McCall via swift-evolution
> On Aug 2, 2017, at 5:56 PM, Karl Wagner  wrote:
>> On 31. Jul 2017, at 21:09, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan >> > wrote:
 On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
> On Jul 30, 2017, at 11:43 PM, Daryle Walker  > 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.
>> 
>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>> feature is to allow the array to be allocated "inline" in its context 
>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  There 
>> is no reason that that representation would not be supportable just because 
>> the array's bound is not statically known; the only thing that matters is 
>> whether the bound is consistent for all instances of the container.
>> 
>> That is, it would not be okay to have a type like:
>>  struct Widget {
>>let length: Int
>>var array: [length x Int]
>>  }
>> because the value of the bound cannot be computed independently of a 
>> specific value.
>> 
>> But it is absolutely okay to have a type like:
>>  struct Widget {
>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>  }
>> It just means that the bound would get computed at runtime and, presumably, 
>> cached.  The fact that this type's size isn't known statically does mean 
>> that the compiler has to be more pessimistic, but its values would still get 
>> allocated inline into their containers and even on the stack, using pretty 
>> much the same techniques as C99 VLAs.
> 
> Do we really want to make that guarantee about heap/stack allocation? C99’s 
> VLAs are not very loop-friendly:
> 
> echo "int main() { 
> for(int i = 0; i<100; i++) {
>   int myArray[i * 1000]; myArray[0] = 32;
> }
> return 0;
>   }" | clang -x c - && ./a.out
> 
> Segmentation Fault: 11
> 
> C compilers also do not inline code with VLAs by default. If you force it, 
> you expose yourself to possible stack overflows:
> 
> echo "static inline void doSomething(int i) {
> int myArray[i * 1000]; myArray[0] = 32;
>   }
>   int main() {
> for(int i = 0; i<100; i++) {
>   doSomething(i);
> }
>   return 0;
>   }" | clang -x c - && ./a.out
> 
> Segmentation Fault: 11
> 
> I wouldn’t like us to import these kinds of issues in to Swift

We probably would not make an absolute guarantee of stack allocation, no.

John.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-02 Thread Karl Wagner via swift-evolution

> On 31. Jul 2017, at 21:09, John McCall via swift-evolution 
>  wrote:
> 
>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan  
>> wrote:
>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>>  wrote:
>>> 
 On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.
> 
> You're making huge leaps here.  The primary purpose of a fixed-size array 
> feature is to allow the array to be allocated "inline" in its context instead 
> of "out-of-line" using heap-allocated copy-on-write buffers.  There is no 
> reason that that representation would not be supportable just because the 
> array's bound is not statically known; the only thing that matters is whether 
> the bound is consistent for all instances of the container.
> 
> That is, it would not be okay to have a type like:
>  struct Widget {
>let length: Int
>var array: [length x Int]
>  }
> because the value of the bound cannot be computed independently of a specific 
> value.
> 
> But it is absolutely okay to have a type like:
>  struct Widget {
>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>  }
> It just means that the bound would get computed at runtime and, presumably, 
> cached.  The fact that this type's size isn't known statically does mean that 
> the compiler has to be more pessimistic, but its values would still get 
> allocated inline into their containers and even on the stack, using pretty 
> much the same techniques as C99 VLAs.

Do we really want to make that guarantee about heap/stack allocation? C99’s 
VLAs are not very loop-friendly:

echo "int main() { 
for(int i = 0; i<100; i++) {
  int myArray[i * 1000]; myArray[0] = 32;
}
return 0;
  }" | clang -x c - && ./a.out

Segmentation Fault: 11

C compilers also do not inline code with VLAs by default. If you force it, you 
expose yourself to possible stack overflows:

echo "static inline void doSomething(int i) {
int myArray[i * 1000]; myArray[0] = 32;
  }
  int main() {
for(int i = 0; i<100; i++) {
  doSomething(i);
}
  return 0;
  }" | clang -x c - && ./a.out

Segmentation Fault: 11

I wouldn’t like us to import these kinds of issues in to Swift

- Karl___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-02 Thread John McCall via swift-evolution
> On Aug 2, 2017, at 12:17 PM, Félix Cloutier  wrote:
> `[Int x N]` solves all of the problems that I mentioned, and I'm happy with 
> that syntax. In fact, I'm championing its merits versus an approach that 
> doesn't include the number of elements. :)
> 
> Unless I got things wrong this entire time, the proposed spelling 
> 
>  was `fixed [Int]`, with no mention of the number of elements.

I agree that an array with a dynamic, value-specific but fixed bound seems 
basically pointless.  It's more of a minor optimization hint than a real type.

John.


> 
> Félix
> 
>> Le 2 août 2017 à 09:00, John McCall > > a écrit :
>>> 
 var foo = fixed [Int]()
 for i in 0..>>>foo.append(i)
 }
>>> 
>>> Arrays can't work if elements don't have a fixed size. How big is an 
>>> element in this example?
>> 
>> This is not the idea.  The idea is more like
>> 
>>   let n = ...
>>   var foo = [Int x n](repeating: 13)
>> 
>> The bound value is still fundamentally part of the type of the variable; 
>> it's just that the actual value is not known statically.
>> 
>> John.
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-02 Thread Tino Heth via swift-evolution

> The bound value is still fundamentally part of the type of the variable; it's 
> just that the actual value is not known statically.
I don't know enough about the internals to prove such a conclusion ;-), but my 
intuition said that this would be possible…

My intuition also says that this might add little value, but much confusion ;-)___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-02 Thread Félix Cloutier via swift-evolution
`[Int x N]` solves all of the problems that I mentioned, and I'm happy with 
that syntax. In fact, I'm championing its merits versus an approach that 
doesn't include the number of elements. :)

Unless I got things wrong this entire time, the proposed spelling 

 was `fixed [Int]`, with no mention of the number of elements.

Félix

> Le 2 août 2017 à 09:00, John McCall  a écrit :
>> 
>>> var foo = fixed [Int]()
>>> for i in 0..>> foo.append(i)
>>> }
>> 
>> Arrays can't work if elements don't have a fixed size. How big is an element 
>> in this example?
> 
> This is not the idea.  The idea is more like
> 
>   let n = ...
>   var foo = [Int x n](repeating: 13)
> 
> The bound value is still fundamentally part of the type of the variable; it's 
> just that the actual value is not known statically.
> 
> John.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-02 Thread John McCall via swift-evolution

> On Aug 2, 2017, at 11:44 AM, Félix Cloutier via swift-evolution 
>  wrote:
> 
> 
>> Le 31 juil. 2017 à 18:54, Xiaodi Wu > > a écrit :
>> It doesn't allow you to specify the size of the array, it's just a promise 
>> that the array is some immutable size. For instance, a `fixed [CGFloat]` 
>> would be a terrible type to represent a vector, but a 
>> FixedSizeArray would be appropriate, at least for the backing 
>> storage. A raw tuple would be a poor choice because dynamically indexing 
>> into them is painful.
>> 
>> Shouldn't this be solved by improvements to tuples? It's a highly desired 
>> feature (by me and at least a few others) to allow tuples to conform to 
>> protocols, whether fixed-size arrays are added or not. I expect that 
>> conforming homogeneous tuples to Collection and enabling subscripting is 
>> simply a matter of time.
> 
> Of course, if this happens, the point is moot and we have the type of 
> fixed-size arrays that I've been asking for. However, crystal-balling Chris's 
> last comment on the matter, it looks like it might not be happening too soon 
> .
> 
>> `fixed` is only useful when the compiler can determine the size of the array 
>> statically. This makes it mostly useless as a storage qualifier if you 
>> received the array as a parameter (*even* if you received a `fixed` array), 
>> because you know that it has a constant size but you don't know what that 
>> size is.
>> Therefore, using a fixed-size array as a generic parameter (crucially, such 
>> as `fixed [fixed [Int]]`) is unlikely to work.
>> Even if that semantic hurdle is overcome, we'd still have no idea how much 
>> memory to allocate for the outer array's buffer to make it work.
>> 
>> As John McCall has replied, the array's bounds don't need to be statically 
>> known for fixed-size arrays to have benefits.
> 
> This (partially) applies to the first point, but it leaves a lot of holes. 
> The size does not need to be statically known, but you need to know how much 
> memory you're going to need ahead of allocating it. How much memory do you 
> need for this?
> 
>> var foo = fixed [Int]()
>> for i in 0..>  foo.append(i)
>> }
> 
> Arrays can't work if elements don't have a fixed size. How big is an element 
> in this example?

This is not the idea.  The idea is more like

  let n = ...
  var foo = [Int x n](repeating: 13)

The bound value is still fundamentally part of the type of the variable; it's 
just that the actual value is not known statically.

John.

>> var foo = fixed [fixed [Int]]()
>> foo.append([1])
>> foo.append([2, 3])
> 
> 
> Where do you allocate this array's storage, and how big is it?
> 
>> struct Foo {
>>  var array: fixed [Int]
>> }
>> 
>> var foo = Foo()
>> foo.array.append(4)
> 
> 
> In the general case, this makes `fixed` meaningful as a type annotation for 
> parameters, but instantiating such an object in the first place would require 
> you to give up a lot of flexibility in how it's populated. The unconstrained 
> problem of finding how many elements you'll have in an array is uncomputable.
> 
> You could say that a fixed-size array stays as big as it was when it was 
> instantiated, but this still causes problems with fixed-size arrays in 
> structures (storage has already been allocated when the initializer runs), 
> and with generic collections (you couldn't initialize a variable-sized array 
> of fixed-size arrays, for instance).
>> Even if `fixed [fixed [Int]]` could work, then each inner array could still 
>> have a different size, which is almost certainly not what you intend by 
>> nesting two fixed-size arrays.
>> 
>> That's fair, but why at that point wouldn't you make your own Matrix type of 
>> fixed size, which uses an Array of fixed size as the underlying storage?
> 
> I'd do it if I needed to, but there are plenty of 2D arrays that are just 
> that and don't need their own wrapper type to function, and I'd be happier to 
> not do it.
>> Layout compatibility is important if you want to use fixed-size arrays to 
>> replace the clunky tuples that currently represent fixed-size arrays in 
>> structs exported from C (which is probably my one single biggest motivation 
>> for fixed-size arrays). You can't achieve layout compatibility if the size 
>> is part of the data instead of part of the type.
>> 
>> For me, that's an anti-goal, as IMO tuples are the most sensible way of 
>> bridging a lot of these fixed-size arrays from C. Quite simply, I'd argue 
>> that the most idiomatic way to represent four CGFloat instances is 
>> `(CGFloat, CGFloat, CGFloat, CGFloat)`. The solution to certain operations 
>> being clunky with tuples is to improve the ergonomics of tuples. For 
>> instance, if we need a shorthand to avoid typing all those `CGFloat`s, then 
>> add one: `(4 * CGFloat)`. If we need subscripting, then add it.
> 
> I think that any template-based fixed-s

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

2017-08-02 Thread Félix Cloutier via swift-evolution

> Le 31 juil. 2017 à 18:54, Xiaodi Wu  a écrit :
> It doesn't allow you to specify the size of the array, it's just a promise 
> that the array is some immutable size. For instance, a `fixed [CGFloat]` 
> would be a terrible type to represent a vector, but a FixedSizeArray 4> would be appropriate, at least for the backing storage. A raw tuple would 
> be a poor choice because dynamically indexing into them is painful.
> 
> Shouldn't this be solved by improvements to tuples? It's a highly desired 
> feature (by me and at least a few others) to allow tuples to conform to 
> protocols, whether fixed-size arrays are added or not. I expect that 
> conforming homogeneous tuples to Collection and enabling subscripting is 
> simply a matter of time.

Of course, if this happens, the point is moot and we have the type of 
fixed-size arrays that I've been asking for. However, crystal-balling Chris's 
last comment on the matter, it looks like it might not be happening too soon 
.

> `fixed` is only useful when the compiler can determine the size of the array 
> statically. This makes it mostly useless as a storage qualifier if you 
> received the array as a parameter (*even* if you received a `fixed` array), 
> because you know that it has a constant size but you don't know what that 
> size is.
> Therefore, using a fixed-size array as a generic parameter (crucially, such 
> as `fixed [fixed [Int]]`) is unlikely to work.
> Even if that semantic hurdle is overcome, we'd still have no idea how much 
> memory to allocate for the outer array's buffer to make it work.
> 
> As John McCall has replied, the array's bounds don't need to be statically 
> known for fixed-size arrays to have benefits.

This (partially) applies to the first point, but it leaves a lot of holes. The 
size does not need to be statically known, but you need to know how much memory 
you're going to need ahead of allocating it. How much memory do you need for 
this?

> var foo = fixed [Int]()
> for i in 0..   foo.append(i)
> }

Arrays can't work if elements don't have a fixed size. How big is an element in 
this example?

> var foo = fixed [fixed [Int]]()
> foo.append([1])
> foo.append([2, 3])


Where do you allocate this array's storage, and how big is it?

> struct Foo {
>   var array: fixed [Int]
> }
> 
> var foo = Foo()
> foo.array.append(4)


In the general case, this makes `fixed` meaningful as a type annotation for 
parameters, but instantiating such an object in the first place would require 
you to give up a lot of flexibility in how it's populated. The unconstrained 
problem of finding how many elements you'll have in an array is uncomputable.

You could say that a fixed-size array stays as big as it was when it was 
instantiated, but this still causes problems with fixed-size arrays in 
structures (storage has already been allocated when the initializer runs), and 
with generic collections (you couldn't initialize a variable-sized array of 
fixed-size arrays, for instance).
> Even if `fixed [fixed [Int]]` could work, then each inner array could still 
> have a different size, which is almost certainly not what you intend by 
> nesting two fixed-size arrays.
> 
> That's fair, but why at that point wouldn't you make your own Matrix type of 
> fixed size, which uses an Array of fixed size as the underlying storage?

I'd do it if I needed to, but there are plenty of 2D arrays that are just that 
and don't need their own wrapper type to function, and I'd be happier to not do 
it.
> Layout compatibility is important if you want to use fixed-size arrays to 
> replace the clunky tuples that currently represent fixed-size arrays in 
> structs exported from C (which is probably my one single biggest motivation 
> for fixed-size arrays). You can't achieve layout compatibility if the size is 
> part of the data instead of part of the type.
> 
> For me, that's an anti-goal, as IMO tuples are the most sensible way of 
> bridging a lot of these fixed-size arrays from C. Quite simply, I'd argue 
> that the most idiomatic way to represent four CGFloat instances is `(CGFloat, 
> CGFloat, CGFloat, CGFloat)`. The solution to certain operations being clunky 
> with tuples is to improve the ergonomics of tuples. For instance, if we need 
> a shorthand to avoid typing all those `CGFloat`s, then add one: `(4 * 
> CGFloat)`. If we need subscripting, then add it.

I think that any template-based fixed-size array structure would still need 
that kind of (4 * CGFloat) syntax to be implemented, or some other facility to 
allocate a parameterized amount of automatic storage. With that said, if we can 
implement fixed-size arrays with just that without having to wait for the 
restrictions on anonymous types to be lifted, to me, it's a fully acceptable 
solution.

> Besides, attaching fixed-size array semantics to an inherently variable-size 
> Array is awkward. For `fixed` to be ef

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

2017-08-01 Thread Chris Lattner via swift-evolution

> On Aug 1, 2017, at 3:36 PM, Jean-Daniel via swift-evolution 
>  wrote:
> 
>> I disagree. Most of the standard library is in protocols and small generic 
>> wrapper structures, which are prime candidates for compile-time evaluation. 
>> Even if Foundation has to be dropped (which is actually not that big of a 
>> deal), I think adapting the standard library to be less architecturally 
>> dependent to make it accessible in compiletime wouldn’t be such a big 
>> problem considering that it is already largely driven by protocols.
>> I think the architectural differences are negligible largely due to LLVM IR, 
>> which is portable (even byte ordering is taken into account).
> 
> Why this long due myth subsist, LLVM IR is not portable. You can produce 
> portable IR by limiting the scope of the input language, but it does not even 
> provides a way to express sizeof(long) in a architecture independent way. And 
> I don’t even mention the type layouts.

If you’re claiming that there is no way to express the natural pointer size of 
the machine, then that’s factually incorrect.  This will compute the 
target-specific size of %T (even if it is a pointer):
getelementptr %T* null, i64 1

The problems major problems are with C though: sizeof(long) is itself a huge 
can of worms, consider LP64 vs LLP64 architectures, as one simple example.  C 
has a preprocessor that exposes machine parameters too early, and many other 
problems exist.  AFAIK, these issues aren’t exposed by Swift, except via the 
Builtin module and imported C APIs & types.

-Chris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-01 Thread Jean-Daniel via swift-evolution

> Le 30 juil. 2017 à 12:23, Gor Gyolchanyan via swift-evolution 
>  a écrit :
> 
>> On Jul 30, 2017, at 1:03 PM, Daniel Vollmer via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Hello,
>> 
>>> On 30. Jul 2017, at 08:52, Gor Gyolchanyan via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> [snip]
>> 
>>> This is a huge undertaking, but if we split it in two parts: "executing at 
>>> compiletime" and "exposing swift’s frontend”, this could surely be done by 
>>> Swift 5. From all the ideas that I’ve had or seen on this mailing list, in 
>>> my opinion this is the most ground-braking, powerful and useful, so I’d be 
>>> willing to work day and night to help implement this.
>> 
>> As you say, I agree that these are separate concepts (compile-time 
>> evaluation vs. meta-programming), but the first is surely going to be 
>> helpful for the second.
> 
> That’s exactly what I had in mind: compiletime execution comes first, 
> meta-programming gets built on top of it.
> 
>> As far as I can tell, compile-time evaluation would probably lose most / all 
>> of the stdlib. I’d hate to replicate parts of the standard library in a 
>> restricted subset of the language so that they are available in `constexpr` 
>> mode (which is what 80% of C++’s template meta-programming libraries do). 
>> I’m also not quite sure how to make that feature work with cross-compilation 
>> when host and target differ in architecture.
> 
> I disagree. Most of the standard library is in protocols and small generic 
> wrapper structures, which are prime candidates for compile-time evaluation. 
> Even if Foundation has to be dropped (which is actually not that big of a 
> deal), I think adapting the standard library to be less architecturally 
> dependent to make it accessible in compiletime wouldn’t be such a big problem 
> considering that it is already largely driven by protocols.
> I think the architectural differences are negligible largely due to LLVM IR, 
> which is portable (even byte ordering is taken into account).

Why this long due myth subsist, LLVM IR is not portable. You can produce 
portable IR by limiting the scope of the input language, but it does not even 
provides a way to express sizeof(long) in a architecture independent way. And I 
don’t even mention the type layouts.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-01 Thread John McCall via swift-evolution

> On Aug 1, 2017, at 9:53 AM, Daryle Walker  wrote:
> 
>> On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan > > wrote:
>> 
>>> 
>>> On Jul 31, 2017, at 11:23 PM, John McCall >> > wrote:
>>> 
 
 On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan >>> > wrote:
 
 
> On Jul 31, 2017, at 10:09 PM, John McCall  > wrote:
> 
>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
>> mailto:gor.f.gyolchan...@icloud.com>> 
>> wrote:
>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 On Jul 30, 2017, at 11:43 PM, Daryle Walker >>> > 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.
> 
> You're making huge leaps here.  The primary purpose of a fixed-size array 
> feature is to allow the array to be allocated "inline" in its context 
> instead of "out-of-line" using heap-allocated copy-on-write buffers.  
> There is no reason that that representation would not be supportable just 
> because the array's bound is not statically known; the only thing that 
> matters is whether the bound is consistent for all instances of the 
> container.
> 
> That is, it would not be okay to have a type like:
>  struct Widget {
>let length: Int
>var array: [length x Int]
>  }
> because the value of the bound cannot be computed independently of a 
> specific value.
> 
> But it is absolutely okay to have a type like:
>  struct Widget {
>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>  }
> It just means that the bound would get computed at runtime and, 
> presumably, cached.  The fact that this type's size isn't known 
> statically does mean that the compiler has to be more pessimistic, but 
> its values would still get allocated inline into their containers and 
> even on the stack, using pretty much the same techniques as C99 VLAs.
 
 I see your point. Dynamically-sized in-place allocation is something that 
 completely escaped me when I was thinking of fixed-size arrays. I can say 
 with confidence that a large portion of private-class-copy-on-write value 
 types would greatly benefit from this and would finally be able to become 
 true value types.
>>> 
>>> To be clear, it's not obvious that using an inline array is always a good 
>>> move for performance!  But it would be a tool available for use when people 
>>> felt it was important.
>> 
>> That's why I'm trying to push for compile-time execution system. All these 
>> problems (among many others) could be designed out of existence and the 
>> compiler would be incredibly simple in the light of all the different 
>> specific features that the community is asking for. But I do feel your urge 
>> to avoid inventing a bulldozer factory just for digging a hole in a sandbox. 
>> It doesn't have to be relied upon by the type checker or generic resolution 
>> mechanism. It would be purely auxiliary. But that would single-handedly move 
>> a large chunk of the compiler into stdlib and a huge portion of various 
>> little incidental proposals would fade away because they can now easily be 
>> implemented in Swift for specific purposes.
>> 
>> 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).
> 
> The difference between having to use dynamic offsets + alloca() and 
> static offsets + a normal stack slot is noticeable but not nearly as 
> extreme as you're imagining.  And again, in most common cases we would 
>

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

2017-08-01 Thread Gor Gyolchanyan via swift-evolution

> On Aug 1, 2017, at 4:53 PM, Daryle Walker  wrote:
> 
>> On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan > > wrote:
>> 
>>> 
>>> On Jul 31, 2017, at 11:23 PM, John McCall >> > wrote:
>>> 
 
 On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan >>> > wrote:
 
 
> On Jul 31, 2017, at 10:09 PM, John McCall  > wrote:
> 
>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
>> mailto:gor.f.gyolchan...@icloud.com>> 
>> wrote:
>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 On Jul 30, 2017, at 11:43 PM, Daryle Walker >>> > 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.
> 
> You're making huge leaps here.  The primary purpose of a fixed-size array 
> feature is to allow the array to be allocated "inline" in its context 
> instead of "out-of-line" using heap-allocated copy-on-write buffers.  
> There is no reason that that representation would not be supportable just 
> because the array's bound is not statically known; the only thing that 
> matters is whether the bound is consistent for all instances of the 
> container.
> 
> That is, it would not be okay to have a type like:
>  struct Widget {
>let length: Int
>var array: [length x Int]
>  }
> because the value of the bound cannot be computed independently of a 
> specific value.
> 
> But it is absolutely okay to have a type like:
>  struct Widget {
>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>  }
> It just means that the bound would get computed at runtime and, 
> presumably, cached.  The fact that this type's size isn't known 
> statically does mean that the compiler has to be more pessimistic, but 
> its values would still get allocated inline into their containers and 
> even on the stack, using pretty much the same techniques as C99 VLAs.
 
 I see your point. Dynamically-sized in-place allocation is something that 
 completely escaped me when I was thinking of fixed-size arrays. I can say 
 with confidence that a large portion of private-class-copy-on-write value 
 types would greatly benefit from this and would finally be able to become 
 true value types.
>>> 
>>> To be clear, it's not obvious that using an inline array is always a good 
>>> move for performance!  But it would be a tool available for use when people 
>>> felt it was important.
>> 
>> That's why I'm trying to push for compile-time execution system. All these 
>> problems (among many others) could be designed out of existence and the 
>> compiler would be incredibly simple in the light of all the different 
>> specific features that the community is asking for. But I do feel your urge 
>> to avoid inventing a bulldozer factory just for digging a hole in a sandbox. 
>> It doesn't have to be relied upon by the type checker or generic resolution 
>> mechanism. It would be purely auxiliary. But that would single-handedly move 
>> a large chunk of the compiler into stdlib and a huge portion of various 
>> little incidental proposals would fade away because they can now easily be 
>> implemented in Swift for specific purposes.
>> 
>> 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).
> 
> The difference between having to use dynamic offsets + alloca() and 
> static offsets + a normal stack slot is noticeable but not nearly as 
> extreme as you're imagining.  And again, in most common cases we would 
>

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

2017-08-01 Thread Daryle Walker via swift-evolution
> On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan  
> wrote:
> 
>> 
>> On Jul 31, 2017, at 11:23 PM, John McCall > > wrote:
>> 
>>> 
>>> On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan >> > wrote:
>>> 
>>> 
 On Jul 31, 2017, at 10:09 PM, John McCall >>> > wrote:
 
> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
> mailto:gor.f.gyolchan...@icloud.com>> 
> wrote:
>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker >> > 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.
 
 You're making huge leaps here.  The primary purpose of a fixed-size array 
 feature is to allow the array to be allocated "inline" in its context 
 instead of "out-of-line" using heap-allocated copy-on-write buffers.  
 There is no reason that that representation would not be supportable just 
 because the array's bound is not statically known; the only thing that 
 matters is whether the bound is consistent for all instances of the 
 container.
 
 That is, it would not be okay to have a type like:
  struct Widget {
let length: Int
var array: [length x Int]
  }
 because the value of the bound cannot be computed independently of a 
 specific value.
 
 But it is absolutely okay to have a type like:
  struct Widget {
var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
  }
 It just means that the bound would get computed at runtime and, 
 presumably, cached.  The fact that this type's size isn't known statically 
 does mean that the compiler has to be more pessimistic, but its values 
 would still get allocated inline into their containers and even on the 
 stack, using pretty much the same techniques as C99 VLAs.
>>> 
>>> I see your point. Dynamically-sized in-place allocation is something that 
>>> completely escaped me when I was thinking of fixed-size arrays. I can say 
>>> with confidence that a large portion of private-class-copy-on-write value 
>>> types would greatly benefit from this and would finally be able to become 
>>> true value types.
>> 
>> To be clear, it's not obvious that using an inline array is always a good 
>> move for performance!  But it would be a tool available for use when people 
>> felt it was important.
> 
> That's why I'm trying to push for compile-time execution system. All these 
> problems (among many others) could be designed out of existence and the 
> compiler would be incredibly simple in the light of all the different 
> specific features that the community is asking for. But I do feel your urge 
> to avoid inventing a bulldozer factory just for digging a hole in a sandbox. 
> It doesn't have to be relied upon by the type checker or generic resolution 
> mechanism. It would be purely auxiliary. But that would single-handedly move 
> a large chunk of the compiler into stdlib and a huge portion of various 
> little incidental proposals would fade away because they can now easily be 
> implemented in Swift for specific purposes.
> 
> 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).
 
 The difference between having to use dynamic offsets + alloca() and static 
 offsets + a normal stack slot is noticeable but not nearly as extreme as 
 you're imagining.  And again, in most common cases we would absolutely be 
 able to fold a bound statically and fall into the optimal path you're 
 talking about.  The critical guarantee, that the array does not get 
 heap-allocated, is still absolut

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

2017-08-01 Thread Steve Canon via swift-evolution


Sent from my iPhone
> On Jul 31, 2017, at 23:47, John McCall via swift-evolution 
>  wrote:
> 
> I disagree; it seems to me that a homogeneous fixed-size sequence is its own 
> concept, and there isn't any natural link between that concept and that of a 
> tuple.  The elements of a tuple are independent with no naturally-implied 
> relationship; or put another way, tuple indices are nominal, not ordinal.

Right. This distinction is subtle, but important, even when the tuple is 
homogenous.

For the mathematically-inclined, this is much like the distinction between R^2 
(vector / fixed size array) and C (tuple / struct). They are isomorphic as 
vector spaces over R, but C has a bunch of extra structure that depends on one 
piece being real and the other being imaginary, but in R^2 the two components 
are always treated the same.

This even has calling convention implications; for efficiency, on most 
architectures, most of the time, it's best to pass a two-element vector as 
elements 0 and 1 of a vector register, but to pass a complex number as two 
scalars.

- Steve
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-01 Thread Tino Heth via swift-evolution

>> I expect that conforming homogeneous tuples to Collection and enabling 
>> subscripting is simply a matter of time.
> 
> I disagree; it seems to me that a homogeneous fixed-size sequence is its own 
> concept, and there isn't any natural link between that concept and that of a 
> tuple.
I'm reliefed to read this response coming from an @apple.com address ;-).
Imho it's a terrible idea two introduce two different kinds of tuples:
Arrays are one of the building blocks of programming, and they deserve being 
called with their name.
Tuples share more with structs than with arrays.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 9:54 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> On Mon, Jul 31, 2017 at 11:45 AM, Félix Cloutier  > wrote:
> 
>> Sure, and hence my point: suppose now `foo` is a function in the stdlib, and 
>> the stdlib authors have annotated the function so that it is `func foo(arr: 
>> fixed [Int])`. Then, any user who writes `var array = ...` could benefit 
>> from a performance boost because the compiler will not longer have to be 
>> pessimistic about copying in order to maintain COW semantics. This is why I 
>> made an explicit analogy to the design proposed for ownership in Swift, 
>> where end users don't have to understand it in order to benefit from the 
>> feature because the functions they call can give sufficiently important 
>> hints to help the compiler avoid unnecessary copying.
>>  
>> I don't think that you claimed that this should be a solution to the 
>> fixed-size array problem, but just in case, also note that it's not. We 
>> can't make any [Int] layout-compatible with C fixed-size arrays because the 
>> length has to be encoded in the type (as it cannot be encoded in the data 
>> itself).
>> 
>> I don't understand this point. Can you elaborate on what you mean here? Why 
>> does it have to be layout-compatible?
> 
> 
> Then it seems that I have stricter requirements for fixed-size arrays than 
> you do, and I'd be curious to hear what you want to get out of fixed-size 
> arrays. If we compare a hypothetical `fixed [int]` to a hypothetical 
> `FixedSizeArray`, these are some of the things that matter to me which 
> `fixed` can't offer:
> 
> It doesn't allow you to specify the size of the array, it's just a promise 
> that the array is some immutable size. For instance, a `fixed [CGFloat]` 
> would be a terrible type to represent a vector, but a FixedSizeArray 4> would be appropriate, at least for the backing storage. A raw tuple would 
> be a poor choice because dynamically indexing into them is painful.
> 
> Shouldn't this be solved by improvements to tuples? It's a highly desired 
> feature (by me and at least a few others) to allow tuples to conform to 
> protocols, whether fixed-size arrays are added or not. I expect that 
> conforming homogeneous tuples to Collection and enabling subscripting is 
> simply a matter of time.

I disagree; it seems to me that a homogeneous fixed-size sequence is its own 
concept, and there isn't any natural link between that concept and that of a 
tuple.  The elements of a tuple are independent with no naturally-implied 
relationship; or put another way, tuple indices are nominal, not ordinal.

Importing C arrays as tuples is a big old hack that has never really worked out 
well.

John.
> `fixed` is only useful when the compiler can determine the size of the array 
> statically. This makes it mostly useless as a storage qualifier if you 
> received the array as a parameter (*even* if you received a `fixed` array), 
> because you know that it has a constant size but you don't know what that 
> size is.
> Therefore, using a fixed-size array as a generic parameter (crucially, such 
> as `fixed [fixed [Int]]`) is unlikely to work.
> Even if that semantic hurdle is overcome, we'd still have no idea how much 
> memory to allocate for the outer array's buffer to make it work.
> 
> As John McCall has replied, the array's bounds don't need to be statically 
> known for fixed-size arrays to have benefits.
>  
> Even if `fixed [fixed [Int]]` could work, then each inner array could still 
> have a different size, which is almost certainly not what you intend by 
> nesting two fixed-size arrays.
> 
> That's fair, but why at that point wouldn't you make your own Matrix type of 
> fixed size, which uses an Array of fixed size as the underlying storage?
> 
> Layout compatibility is important if you want to use fixed-size arrays to 
> replace the clunky tuples that currently represent fixed-size arrays in 
> structs exported from C (which is probably my one single biggest motivation 
> for fixed-size arrays). You can't achieve layout compatibility if the size is 
> part of the data instead of part of the type.
> 
> For me, that's an anti-goal, as IMO tuples are the most sensible way of 
> bridging a lot of these fixed-size arrays from C. Quite simply, I'd argue 
> that the most idiomatic way to represent four CGFloat instances is `(CGFloat, 
> CGFloat, CGFloat, CGFloat)`. The solution to certain operations being clunky 
> with tuples is to improve the ergonomics of tuples. For instance, if we need 
> a shorthand to avoid typing all those `CGFloat`s, then add one: `(4 * 
> CGFloat)`. If we need subscripting, then add it.
> 
> Besides, attaching fixed-size array semantics to an inherently variable-size 
> Array is awkward. For `fixed` to be effective, it needs to disable methods 
> that change the size of the array, or warn that you're using them. I don't 
> like the cross-concern impact: now a keyword needs to know about me

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

2017-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 11:29 PM, Félix Cloutier  wrote:
> No, this is a misunderstanding: I mean "you" as yourself, not "you" as the 
> compiler. As far as I know, given a type variable, as in `let foo: 
> NSObject.Type = NSArray.self`, you (the developer) can't use `foo` to 
> instantiate a generic type.

Ah, yes, I did misunderstand what you were saying.

> The question stands again: are there any specific reasons that you can't do 
> that right now, or is it just because the need for this is not particularly 
> evident?

There is no specific reason you can't do that right now.  We could certainly 
just allow you to name a local constant in type contexts if it happens to be of 
metatype type — I don't know if that would be the best language design, but 
there's nothing inherent about the language model that makes it unreasonable.  
I do think we would at least demand that it be a constant and not a variable.

John.


> 
> Félix
> 
>> Le 31 juil. 2017 à 11:29, John McCall  a écrit :
>> 
>>> On Jul 31, 2017, at 3:58 AM, Félix Cloutier  wrote:
>>> It seems to me that this applies just the same to type generic parameters. 
>>> Are there any reason that you can't instantiate a generic type at runtime, 
>>> or is it just because the need is not as evident as it would/could be with 
>>> non-type generic parameters?
>> 
>> Are you under the impression that Swift does not, today, instantiate generic 
>> types at runtime?
>> 
>> A lot of this entire thread seems to be premised on really weird, incorrect 
>> assumptions about the Swift compilation model.
>> 
>> John.
>> 
>>> 
 Le 30 juil. 2017 à 21:10, John McCall via swift-evolution 
  a écrit :
 
> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.
 
 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.
 
 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).
 
 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  wrote:
> 
>>> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>>>  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@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>> 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread Félix Cloutier via swift-evolution
No, this is a misunderstanding: I mean "you" as yourself, not "you" as the 
compiler. As far as I know, given a type variable, as in `let foo: 
NSObject.Type = NSArray.self`, you (the developer) can't use `foo` to 
instantiate a generic type.

The question stands again: are there any specific reasons that you can't do 
that right now, or is it just because the need for this is not particularly 
evident?

Félix

> Le 31 juil. 2017 à 11:29, John McCall  a écrit :
> 
>> On Jul 31, 2017, at 3:58 AM, Félix Cloutier  wrote:
>> It seems to me that this applies just the same to type generic parameters. 
>> Are there any reason that you can't instantiate a generic type at runtime, 
>> or is it just because the need is not as evident as it would/could be with 
>> non-type generic parameters?
> 
> Are you under the impression that Swift does not, today, instantiate generic 
> types at runtime?
> 
> A lot of this entire thread seems to be premised on really weird, incorrect 
> assumptions about the Swift compilation model.
> 
> John.
> 
>> 
>>> Le 30 juil. 2017 à 21:10, John McCall via swift-evolution 
>>>  a écrit :
>>> 
 On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.
>>> 
>>> 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.
>>> 
>>> 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).
>>> 
>>> 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  wrote:
 
>> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>>  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@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread Xiaodi Wu via swift-evolution
On Mon, Jul 31, 2017 at 11:45 AM, Félix Cloutier 
wrote:

>
> Sure, and hence my point: suppose now `foo` is a function in the stdlib,
> and the stdlib authors have annotated the function so that it is `func
> foo(arr: fixed [Int])`. Then, any user who writes `var array = ...` could
> benefit from a performance boost because the compiler will not longer have
> to be pessimistic about copying in order to maintain COW semantics. This is
> why I made an explicit analogy to the design proposed for ownership in
> Swift, where end users don't have to understand it in order to benefit from
> the feature because the functions they call can give sufficiently important
> hints to help the compiler avoid unnecessary copying.
>
>
>
> I don't think that you claimed that this should be a solution to the
>> fixed-size array problem, but just in case, also note that it's not. We
>> can't make any [Int] layout-compatible with C fixed-size arrays because the
>> length has to be encoded in the type (as it cannot be encoded in the data
>> itself).
>>
>
> I don't understand this point. Can you elaborate on what you mean here?
> Why does it have to be layout-compatible?
>
>
> Then it seems that I have stricter requirements for fixed-size arrays than
> you do, and I'd be curious to hear what you want to get out of fixed-size
> arrays. If we compare a hypothetical `fixed [int]` to a hypothetical
> `FixedSizeArray`, these are some of the things that matter to me
> which `fixed` can't offer:
>
>
>- It doesn't allow you to specify the size of the array, it's just a
>promise that the array is some immutable size. For instance, a `fixed
>[CGFloat]` would be a terrible type to represent a vector, but a
>FixedSizeArray would be appropriate, at least for the backing
>storage. A raw tuple would be a poor choice because dynamically indexing
>into them is painful.
>
>
Shouldn't this be solved by improvements to tuples? It's a highly desired
feature (by me and at least a few others) to allow tuples to conform to
protocols, whether fixed-size arrays are added or not. I expect that
conforming homogeneous tuples to Collection and enabling subscripting is
simply a matter of time.


>
>- `fixed` is only useful when the compiler can determine the size of
>the array statically. This makes it mostly useless as a storage qualifier
>if you received the array as a parameter (*even* if you received a `fixed`
>array), because you know that it has a constant size but you don't know
>what that size is.
>- Therefore, using a fixed-size array as a generic parameter
>(crucially, such as `fixed [fixed [Int]]`) is unlikely to work.
>- Even if that semantic hurdle is overcome, we'd still have no idea
>how much memory to allocate for the outer array's buffer to make it work.
>
>
As John McCall has replied, the array's bounds don't need to be statically
known for fixed-size arrays to have benefits.


>
>- Even if `fixed [fixed [Int]]` could work, then each inner array
>could still have a different size, which is almost certainly not what you
>intend by nesting two fixed-size arrays.
>
>
That's fair, but why at that point wouldn't you make your own Matrix type
of fixed size, which uses an Array of fixed size as the underlying storage?


>- Layout compatibility is important if you want to use fixed-size
>arrays to replace the clunky tuples that currently represent fixed-size
>arrays in structs exported from C (which is probably my one single biggest
>motivation for fixed-size arrays). You can't achieve layout compatibility
>if the size is part of the data instead of part of the type.
>
>
For me, that's an anti-goal, as IMO tuples are the most sensible way of
bridging a lot of these fixed-size arrays from C. Quite simply, I'd argue
that the most idiomatic way to represent four CGFloat instances is
`(CGFloat, CGFloat, CGFloat, CGFloat)`. The solution to certain operations
being clunky with tuples is to improve the ergonomics of tuples. For
instance, if we need a shorthand to avoid typing all those `CGFloat`s, then
add one: `(4 * CGFloat)`. If we need subscripting, then add it.

Besides, attaching fixed-size array semantics to an inherently
> variable-size Array is awkward. For `fixed` to be effective, it needs to
> disable methods that change the size of the array, or warn that you're
> using them. I don't like the cross-concern impact: now a keyword needs to
> know about method implementations to restrict them. It also has to work
> with extension methods on the Array type, and it shouldn't apply to just
> mutating functions because mutations that don't change the length of the
> array are fine.
>

The idea is that all facilities which would benefit from knowing that an
array is of a fixed count would opt into that benefit by indicating as
such. That is, all stdlib array methods that are guaranteed to preserve the
size of the array would be annotated as such. Again, by analogy

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

2017-07-31 Thread David Sweeris via swift-evolution

On Jul 31, 2017, at 12:15 AM, Gor Gyolchanyan via swift-evolution 
 wrote:

>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>  wrote:
>> 
>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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. 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).

Not at all... it'd let us use non-type parameters to affect a value's type... 
The classic example (or at least the one that I keep typing out whenever the 
topic comes up) is vector matrix math:
func *  (lhs: Matrix, 
rhs: Matrix) -> Matrix {
// no need to check if the dimensions at runtime because the type system 
turned dimension mismatches into a compile-time error
...
}

Sticking with the math theme, if you can make the variable's name (that is, 
your package's variable type, not a Swift var or let) part of its type, I 
suspect there's a trick you could do in a symbolic manipulation library 
involving simplifying equations (but I haven't thought it through enough to say 
for sure).

- Dave Sweeris
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread David Sweeris via swift-evolution

> On Jul 31, 2017, at 1:37 PM, Gor Gyolchanyan via swift-evolution 
>  wrote:
> 
> 
>>> On Jul 31, 2017, at 11:23 PM, John McCall  wrote:
>>> 
>>> 
 On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan 
  wrote:
 
 
> On Jul 31, 2017, at 10:09 PM, John McCall  wrote:
> 
>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
>>  wrote:
>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>>  wrote:
>>> 
>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.
 
 You're making huge leaps here.  The primary purpose of a fixed-size array 
 feature is to allow the array to be allocated "inline" in its context 
 instead of "out-of-line" using heap-allocated copy-on-write buffers.  
 There is no reason that that representation would not be supportable just 
 because the array's bound is not statically known; the only thing that 
 matters is whether the bound is consistent for all instances of the 
 container.
 
 That is, it would not be okay to have a type like:
  struct Widget {
let length: Int
var array: [length x Int]
  }
 because the value of the bound cannot be computed independently of a 
 specific value.
 
 But it is absolutely okay to have a type like:
  struct Widget {
var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
  }
 It just means that the bound would get computed at runtime and, 
 presumably, cached.  The fact that this type's size isn't known statically 
 does mean that the compiler has to be more pessimistic, but its values 
 would still get allocated inline into their containers and even on the 
 stack, using pretty much the same techniques as C99 VLAs.
>>> 
>>> I see your point. Dynamically-sized in-place allocation is something that 
>>> completely escaped me when I was thinking of fixed-size arrays. I can say 
>>> with confidence that a large portion of private-class-copy-on-write value 
>>> types would greatly benefit from this and would finally be able to become 
>>> true value types.
>> 
>> To be clear, it's not obvious that using an inline array is always a good 
>> move for performance!  But it would be a tool available for use when people 
>> felt it was important.
> 
> That's why I'm trying to push for compile-time execution system. All these 
> problems (among many others) could be designed out of existence and the 
> compiler would be incredibly simple in the light of all the different 
> specific features that the community is asking for. But I do feel your urge 
> to avoid inventing a bulldozer factory just for digging a hole in a sandbox. 
> It doesn't have to be relied upon by the type checker or generic resolution 
> mechanism. It would be purely auxiliary.

FWIW, if we were having this conversation before maintaining source 
compatibility was such an important goal, I'd be far more willing to go along 
with just getting a feature implemented so that we can play now and tweak the 
design later. As it is, though — and even without that compatibility goal — 
realistically speaking, it'll be a year+ before anything major that we approve 
now is likely to make its way into an official toolchain. There's no need to 
rush the process, not until we near the end of the Swift 5 proposal timeframe.

Although I will give my +1 for having this discussion being declared in-scope 
for a Swift 5.


> But that would single-handedly move a large chunk of the compiler into stdlib 
> and a huge portion of various little incidental proposals would fade away 
> because they can now easily be implemented in Swift for specific purposes.

Getting rid of as much "compiler magic" as possible is one of Swift's goals. If 
soneobe though of a way to move the grammar spec itself into the stdlib, I 
think there are some of us who'd support that. (To be clear, while I think 
that'd be "winter-storm on Pluto"-cool, I'm 

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

2017-07-31 Thread Gor Gyolchanyan via swift-evolution

> On Jul 31, 2017, at 11:52 PM, John McCall  wrote:
> 
>> On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan > > wrote:
>>> On Jul 31, 2017, at 11:23 PM, John McCall >> > wrote:
>>> 
 
 On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan >>> > wrote:
 
 
> On Jul 31, 2017, at 10:09 PM, John McCall  > wrote:
> 
>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
>> mailto:gor.f.gyolchan...@icloud.com>> 
>> wrote:
>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 On Jul 30, 2017, at 11:43 PM, Daryle Walker >>> > 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.
> 
> You're making huge leaps here.  The primary purpose of a fixed-size array 
> feature is to allow the array to be allocated "inline" in its context 
> instead of "out-of-line" using heap-allocated copy-on-write buffers.  
> There is no reason that that representation would not be supportable just 
> because the array's bound is not statically known; the only thing that 
> matters is whether the bound is consistent for all instances of the 
> container.
> 
> That is, it would not be okay to have a type like:
>  struct Widget {
>let length: Int
>var array: [length x Int]
>  }
> because the value of the bound cannot be computed independently of a 
> specific value.
> 
> But it is absolutely okay to have a type like:
>  struct Widget {
>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>  }
> It just means that the bound would get computed at runtime and, 
> presumably, cached.  The fact that this type's size isn't known 
> statically does mean that the compiler has to be more pessimistic, but 
> its values would still get allocated inline into their containers and 
> even on the stack, using pretty much the same techniques as C99 VLAs.
 
 I see your point. Dynamically-sized in-place allocation is something that 
 completely escaped me when I was thinking of fixed-size arrays. I can say 
 with confidence that a large portion of private-class-copy-on-write value 
 types would greatly benefit from this and would finally be able to become 
 true value types.
>>> 
>>> To be clear, it's not obvious that using an inline array is always a good 
>>> move for performance!  But it would be a tool available for use when people 
>>> felt it was important.
>> 
>> That's why I'm trying to push for compile-time execution system. All these 
>> problems (among many others) could be designed out of existence and the 
>> compiler would be incredibly simple in the light of all the different 
>> specific features that the community is asking for. But I do feel your urge 
>> to avoid inventing a bulldozer factory just for digging a hole in a sandbox. 
>> It doesn't have to be relied upon by the type checker or generic resolution 
>> mechanism. It would be purely auxiliary. But that would single-handedly move 
>> a large chunk of the compiler into stdlib and a huge portion of various 
>> little incidental proposals would fade away because they can now easily be 
>> implemented in Swift for specific purposes.
> 
> My point here had nothing to do with compile-time vs. dynamic-time evaluation 
> of array bounds.  Inline array storage is not a performance panacea even if 
> everything about them is static.  The exact balance point will vary by 
> element type, machine, and the overall load on the memory system in your 
> program, but even for an array of bytes, as the size of the array grows it 
> will eventually become the case that retaining a buffer pointer will be 
> cheaper than copying the buffer contents.

Yeah, the compile-time stuff is completely off-topic

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

2017-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan  
> wrote:
>> On Jul 31, 2017, at 11:23 PM, John McCall > > wrote:
>> 
>>> 
>>> On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan >> > wrote:
>>> 
>>> 
 On Jul 31, 2017, at 10:09 PM, John McCall >>> > wrote:
 
> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
> mailto:gor.f.gyolchan...@icloud.com>> 
> wrote:
>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker >> > 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.
 
 You're making huge leaps here.  The primary purpose of a fixed-size array 
 feature is to allow the array to be allocated "inline" in its context 
 instead of "out-of-line" using heap-allocated copy-on-write buffers.  
 There is no reason that that representation would not be supportable just 
 because the array's bound is not statically known; the only thing that 
 matters is whether the bound is consistent for all instances of the 
 container.
 
 That is, it would not be okay to have a type like:
  struct Widget {
let length: Int
var array: [length x Int]
  }
 because the value of the bound cannot be computed independently of a 
 specific value.
 
 But it is absolutely okay to have a type like:
  struct Widget {
var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
  }
 It just means that the bound would get computed at runtime and, 
 presumably, cached.  The fact that this type's size isn't known statically 
 does mean that the compiler has to be more pessimistic, but its values 
 would still get allocated inline into their containers and even on the 
 stack, using pretty much the same techniques as C99 VLAs.
>>> 
>>> I see your point. Dynamically-sized in-place allocation is something that 
>>> completely escaped me when I was thinking of fixed-size arrays. I can say 
>>> with confidence that a large portion of private-class-copy-on-write value 
>>> types would greatly benefit from this and would finally be able to become 
>>> true value types.
>> 
>> To be clear, it's not obvious that using an inline array is always a good 
>> move for performance!  But it would be a tool available for use when people 
>> felt it was important.
> 
> That's why I'm trying to push for compile-time execution system. All these 
> problems (among many others) could be designed out of existence and the 
> compiler would be incredibly simple in the light of all the different 
> specific features that the community is asking for. But I do feel your urge 
> to avoid inventing a bulldozer factory just for digging a hole in a sandbox. 
> It doesn't have to be relied upon by the type checker or generic resolution 
> mechanism. It would be purely auxiliary. But that would single-handedly move 
> a large chunk of the compiler into stdlib and a huge portion of various 
> little incidental proposals would fade away because they can now easily be 
> implemented in Swift for specific purposes.

My point here had nothing to do with compile-time vs. dynamic-time evaluation 
of array bounds.  Inline array storage is not a performance panacea even if 
everything about them is static.  The exact balance point will vary by element 
type, machine, and the overall load on the memory system in your program, but 
even for an array of bytes, as the size of the array grows it will eventually 
become the case that retaining a buffer pointer will be cheaper than copying 
the buffer contents.

> 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

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

2017-07-31 Thread Gor Gyolchanyan via swift-evolution

> On Jul 31, 2017, at 11:23 PM, John McCall  wrote:
> 
>> 
>> On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan > > wrote:
>> 
>> 
>>> On Jul 31, 2017, at 10:09 PM, John McCall >> > wrote:
>>> 
 On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan >>> > wrote:
> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> On Jul 30, 2017, at 11:43 PM, Daryle Walker > > 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.
>>> 
>>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>>> feature is to allow the array to be allocated "inline" in its context 
>>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  There 
>>> is no reason that that representation would not be supportable just because 
>>> the array's bound is not statically known; the only thing that matters is 
>>> whether the bound is consistent for all instances of the container.
>>> 
>>> That is, it would not be okay to have a type like:
>>>  struct Widget {
>>>let length: Int
>>>var array: [length x Int]
>>>  }
>>> because the value of the bound cannot be computed independently of a 
>>> specific value.
>>> 
>>> But it is absolutely okay to have a type like:
>>>  struct Widget {
>>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>>  }
>>> It just means that the bound would get computed at runtime and, presumably, 
>>> cached.  The fact that this type's size isn't known statically does mean 
>>> that the compiler has to be more pessimistic, but its values would still 
>>> get allocated inline into their containers and even on the stack, using 
>>> pretty much the same techniques as C99 VLAs.
>> 
>> I see your point. Dynamically-sized in-place allocation is something that 
>> completely escaped me when I was thinking of fixed-size arrays. I can say 
>> with confidence that a large portion of private-class-copy-on-write value 
>> types would greatly benefit from this and would finally be able to become 
>> true value types.
> 
> To be clear, it's not obvious that using an inline array is always a good 
> move for performance!  But it would be a tool available for use when people 
> felt it was important.

That's why I'm trying to push for compile-time execution system. All these 
problems (among many others) could be designed out of existence and the 
compiler would be incredibly simple in the light of all the different specific 
features that the community is asking for. But I do feel your urge to avoid 
inventing a bulldozer factory just for digging a hole in a sandbox. It doesn't 
have to be relied upon by the type checker or generic resolution mechanism. It 
would be purely auxiliary. But that would single-handedly move a large chunk of 
the compiler into stdlib and a huge portion of various little incidental 
proposals would fade away because they can now easily be implemented in Swift 
for specific purposes.

 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).
>>> 
>>> The difference between having to use dynamic offsets + alloca() and static 
>>> offsets + a normal stack slot is noticeable but not nearly as extreme as 
>>> you're imagining.  And again, in most common cases we would absolutely be 
>>> able to fold a bound statically and fall into the optimal path you're 
>>> talking about.  The critical guarantee, that the array does not get 
>>> heap-allocated, is still absolutely intact.
>> 
>> Yet again, Swift (specifically - you in this case) is teaching me to trust 
>> the compiler to optimize, which is still an alien feeling to me even after 
>> all these years of heavy Swift usa

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

2017-07-31 Thread John McCall via swift-evolution

> On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan  
> wrote:
> 
> 
>> On Jul 31, 2017, at 10:09 PM, John McCall > > wrote:
>> 
>>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan >> > wrote:
 On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
> On Jul 30, 2017, at 11:43 PM, Daryle Walker  > 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.
>> 
>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>> feature is to allow the array to be allocated "inline" in its context 
>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  There 
>> is no reason that that representation would not be supportable just because 
>> the array's bound is not statically known; the only thing that matters is 
>> whether the bound is consistent for all instances of the container.
>> 
>> That is, it would not be okay to have a type like:
>>  struct Widget {
>>let length: Int
>>var array: [length x Int]
>>  }
>> because the value of the bound cannot be computed independently of a 
>> specific value.
>> 
>> But it is absolutely okay to have a type like:
>>  struct Widget {
>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>  }
>> It just means that the bound would get computed at runtime and, presumably, 
>> cached.  The fact that this type's size isn't known statically does mean 
>> that the compiler has to be more pessimistic, but its values would still get 
>> allocated inline into their containers and even on the stack, using pretty 
>> much the same techniques as C99 VLAs.
> 
> I see your point. Dynamically-sized in-place allocation is something that 
> completely escaped me when I was thinking of fixed-size arrays. I can say 
> with confidence that a large portion of private-class-copy-on-write value 
> types would greatly benefit from this and would finally be able to become 
> true value types.

To be clear, it's not obvious that using an inline array is always a good move 
for performance!  But it would be a tool available for use when people felt it 
was important.

>>> 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).
>> 
>> The difference between having to use dynamic offsets + alloca() and static 
>> offsets + a normal stack slot is noticeable but not nearly as extreme as 
>> you're imagining.  And again, in most common cases we would absolutely be 
>> able to fold a bound statically and fall into the optimal path you're 
>> talking about.  The critical guarantee, that the array does not get 
>> heap-allocated, is still absolutely intact.
> 
> Yet again, Swift (specifically - you in this case) is teaching me to trust 
> the compiler to optimize, which is still an alien feeling to me even after 
> all these years of heavy Swift usage. Damn you, C++ for corrupting my brain 😀.

Well.  Trust but verify. :)

> In the specific case of having dynamic-sized in-place-allocated value types 
> this will absolutely work. But this raises a chicken-and-the-egg problem: 
> which is built in what: in-place allocated dynamic-sized value types, or 
> specifically fixed-size arrays? On one hand I'm tempted to think that value 
> types should be able to dynamically decide (inside the initializer) the exact 
> size of the allocated memory (no less than the static size) that they occupy 
> (no matter if on the heap, on the stack or anywhere else), after which they'd 
> be able to access the "leftover" memory by a pointer and do whatever they 
> want with it. This approach seems more logical, since this is essentially how 
> fixed-size arrays would be implemented under the hood. But on the other hand, 
> this does make use of unsafe point

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

2017-07-31 Thread Gor Gyolchanyan via swift-evolution

> On Jul 31, 2017, at 10:09 PM, John McCall  wrote:
> 
>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan  
>> wrote:
>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>>  wrote:
>>> 
 On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.
> 
> You're making huge leaps here.  The primary purpose of a fixed-size array 
> feature is to allow the array to be allocated "inline" in its context instead 
> of "out-of-line" using heap-allocated copy-on-write buffers.  There is no 
> reason that that representation would not be supportable just because the 
> array's bound is not statically known; the only thing that matters is whether 
> the bound is consistent for all instances of the container.
> 
> That is, it would not be okay to have a type like:
>  struct Widget {
>let length: Int
>var array: [length x Int]
>  }
> because the value of the bound cannot be computed independently of a specific 
> value.
> 
> But it is absolutely okay to have a type like:
>  struct Widget {
>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>  }
> It just means that the bound would get computed at runtime and, presumably, 
> cached.  The fact that this type's size isn't known statically does mean that 
> the compiler has to be more pessimistic, but its values would still get 
> allocated inline into their containers and even on the stack, using pretty 
> much the same techniques as C99 VLAs.

I see your point. Dynamically-sized in-place allocation is something that 
completely escaped me when I was thinking of fixed-size arrays. I can say with 
confidence that a large portion of private-class-copy-on-write value types 
would greatly benefit from this and would finally be able to become true value 
types.

>> 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).
> 
> The difference between having to use dynamic offsets + alloca() and static 
> offsets + a normal stack slot is noticeable but not nearly as extreme as 
> you're imagining.  And again, in most common cases we would absolutely be 
> able to fold a bound statically and fall into the optimal path you're talking 
> about.  The critical guarantee, that the array does not get heap-allocated, 
> is still absolutely intact.

Yet again, Swift (specifically - you in this case) is teaching me to trust the 
compiler to optimize, which is still an alien feeling to me even after all 
these years of heavy Swift usage. Damn you, C++ for corrupting my brain 😀.
In the specific case of having dynamic-sized in-place-allocated value types 
this will absolutely work. But this raises a chicken-and-the-egg problem: which 
is built in what: in-place allocated dynamic-sized value types, or specifically 
fixed-size arrays? On one hand I'm tempted to think that value types should be 
able to dynamically decide (inside the initializer) the exact size of the 
allocated memory (no less than the static size) that they occupy (no matter if 
on the heap, on the stack or anywhere else), after which they'd be able to 
access the "leftover" memory by a pointer and do whatever they want with it. 
This approach seems more logical, since this is essentially how fixed-size 
arrays would be implemented under the hood. But on the other hand, this does 
make use of unsafe pointers (and no part of Swift currently relies on unsafe 
pointers to function), so abstracting it away behind a magical fixed-size array 
seems safer (with a hope that a fixed-size array of UInt8 would be optimized 
down to exactly the first case).

>>> 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.
>

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

2017-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan  
> wrote:
>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>  wrote:
>> 
>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.

You're making huge leaps here.  The primary purpose of a fixed-size array 
feature is to allow the array to be allocated "inline" in its context instead 
of "out-of-line" using heap-allocated copy-on-write buffers.  There is no 
reason that that representation would not be supportable just because the 
array's bound is not statically known; the only thing that matters is whether 
the bound is consistent for all instances of the container.

That is, it would not be okay to have a type like:
  struct Widget {
let length: Int
var array: [length x Int]
  }
because the value of the bound cannot be computed independently of a specific 
value.

But it is absolutely okay to have a type like:
  struct Widget {
var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
  }
It just means that the bound would get computed at runtime and, presumably, 
cached.  The fact that this type's size isn't known statically does mean that 
the compiler has to be more pessimistic, but its values would still get 
allocated inline into their containers and even on the stack, using pretty much 
the same techniques as C99 VLAs.

> 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).

The difference between having to use dynamic offsets + alloca() and static 
offsets + a normal stack slot is noticeable but not nearly as extreme as you're 
imagining.  And again, in most common cases we would absolutely be able to fold 
a bound statically and fall into the optimal path you're talking about.  The 
critical guarantee, that the array does not get heap-allocated, is still 
absolutely intact.

>> 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?

The Equatable protocol does guarantee reflexivity.

> Moreover, as far as I know, Equatable is not recognized by the compiler in 
> any way, so it's just a regular protocol.

That's not quite true: we synthesize Equatable instances in several places.

> 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 thing the compiler really *needs* to know is whether two types are 
known to be the same, i.e. whether two values are known to be the same.  An 
elaborate compile-time execution system would not be sufficient here, because 
again, Swift is not C or C++: we need to be able to answer that question even 
in generic code rather than relying on the ability to fold all computations 
statically.  We do not want to add an algebraic solver to the type-checker.  
The obvious alternative is to simply be conservatively correct by treating 
independent complex expressions as always yielding different values.

>> 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 
>> exactl

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

2017-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 3:58 AM, Félix Cloutier  wrote:
> It seems to me that this applies just the same to type generic parameters. 
> Are there any reason that you can't instantiate a generic type at runtime, or 
> is it just because the need is not as evident as it would/could be with 
> non-type generic parameters?

Are you under the impression that Swift does not, today, instantiate generic 
types at runtime?

A lot of this entire thread seems to be premised on really weird, incorrect 
assumptions about the Swift compilation model.

John.

> 
>> Le 30 juil. 2017 à 21:10, John McCall via swift-evolution 
>>  a écrit :
>> 
>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.
>> 
>> 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.
>> 
>> 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).
>> 
>> 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  wrote:
>>> 
> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>  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@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread Félix Cloutier via swift-evolution
> Sure, and hence my point: suppose now `foo` is a function in the stdlib, and 
> the stdlib authors have annotated the function so that it is `func foo(arr: 
> fixed [Int])`. Then, any user who writes `var array = ...` could benefit from 
> a performance boost because the compiler will not longer have to be 
> pessimistic about copying in order to maintain COW semantics. This is why I 
> made an explicit analogy to the design proposed for ownership in Swift, where 
> end users don't have to understand it in order to benefit from the feature 
> because the functions they call can give sufficiently important hints to help 
> the compiler avoid unnecessary copying.
>  
> I don't think that you claimed that this should be a solution to the 
> fixed-size array problem, but just in case, also note that it's not. We can't 
> make any [Int] layout-compatible with C fixed-size arrays because the length 
> has to be encoded in the type (as it cannot be encoded in the data itself).
> 
> I don't understand this point. Can you elaborate on what you mean here? Why 
> does it have to be layout-compatible?


Then it seems that I have stricter requirements for fixed-size arrays than you 
do, and I'd be curious to hear what you want to get out of fixed-size arrays. 
If we compare a hypothetical `fixed [int]` to a hypothetical `FixedSizeArray`, these are some of the things that matter to me which `fixed` can't offer:

It doesn't allow you to specify the size of the array, it's just a promise that 
the array is some immutable size. For instance, a `fixed [CGFloat]` would be a 
terrible type to represent a vector, but a FixedSizeArray would be 
appropriate, at least for the backing storage. A raw tuple would be a poor 
choice because dynamically indexing into them is painful.
`fixed` is only useful when the compiler can determine the size of the array 
statically. This makes it mostly useless as a storage qualifier if you received 
the array as a parameter (*even* if you received a `fixed` array), because you 
know that it has a constant size but you don't know what that size is.
Therefore, using a fixed-size array as a generic parameter (crucially, such as 
`fixed [fixed [Int]]`) is unlikely to work.
Even if that semantic hurdle is overcome, we'd still have no idea how much 
memory to allocate for the outer array's buffer to make it work.
Even if `fixed [fixed [Int]]` could work, then each inner array could still 
have a different size, which is almost certainly not what you intend by nesting 
two fixed-size arrays.
Layout compatibility is important if you want to use fixed-size arrays to 
replace the clunky tuples that currently represent fixed-size arrays in structs 
exported from C (which is probably my one single biggest motivation for 
fixed-size arrays). You can't achieve layout compatibility if the size is part 
of the data instead of part of the type.

Besides, attaching fixed-size array semantics to an inherently variable-size 
Array is awkward. For `fixed` to be effective, it needs to disable methods that 
change the size of the array, or warn that you're using them. I don't like the 
cross-concern impact: now a keyword needs to know about method implementations 
to restrict them. It also has to work with extension methods on the Array type, 
and it shouldn't apply to just mutating functions because mutations that don't 
change the length of the array are fine.

What would you use `fixed [Int]` for? Only as an optimization tool?

Félix___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread Xiaodi Wu via swift-evolution
On Mon, Jul 31, 2017 at 3:39 AM, Félix Cloutier 
wrote:

>
> Le 31 juil. 2017 à 00:40, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> a écrit :
>
>
> On Mon, Jul 31, 2017 at 02:15 Gor Gyolchanyan via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> > On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> >
>> >> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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?
>
>
> The optimization is defeated as soon as the storage buffer might escape,
> just like for closures. Consider this:
>
> func foo(arr: [Int])
>
> var array = [1, 2, 3, 4]
> foo(arr: array)
> array[1] = 2
>
>
> If `array` is "unrolled" to the stack, and `foo` keeps a reference to the
> storage, then `array[1] = 2` has to pessimistically create a new storage
> buffer to maintain COW semantics. It could also leave a dangling reference
> to the buffer if the function returns before all of the other references
> are gone. I'd rather not get into @escaping arrays.
>

Sure, and hence my point: suppose now `foo` is a function in the stdlib,
and the stdlib authors have annotated the function so that it is `func
foo(arr: fixed [Int])`. Then, any user who writes `var array = ...` could
benefit from a performance boost because the compiler will not longer have
to be pessimistic about copying in order to maintain COW semantics. This is
why I made an explicit analogy to the design proposed for ownership in
Swift, where end users don't have to understand it in order to benefit from
the feature because the functions they call can give sufficiently important
hints to help the compiler avoid unnecessary copying.

I don't think that you claimed that this should be a solution to the
> fixed-size array problem, but just in case, also note that it's not. We
> can't make any [Int] layout-compatible with C fixed-size arrays because the
> length has to be encoded in the type (as it cannot be encoded in the data
> itself).
>

I don't understand this point. Can you elaborate on what you mean here? Why
does it have to be layout-compatible?


> Félix
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread Gor Gyolchanyan via swift-evolution
> On Jul 31, 2017, at 12:16 PM, Tino Heth <2...@gmx.de> wrote:
> 
> 
>> 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?
> I think it's a good idea in general, but I don't think I'd notice if this 
> feature would exist, so just to save some work for the compiler (and Core), 
> I'd prefer to first get the feature itself, and improve it later.
> So from my high-level perspective, I think the order should be
> 0) Add support for value literals as generic parameters

Value literals would be limited to the ones accepted by ExpressibleBy*Literal, 
which would be very limiting for anything that isn't an Int or a Float. This 
might solve the specific case of fixed-size arrays, but otherwise would be 
nearly useless.

> 1) Add Array
> 2) Add support for generic parameters that are evaluated at compile time
> 3) Make everything fast ;-)
> n) Add useful additions like detecting arrays that aren't declared as fixed 
> length, but could
> 
> I think the alternative to macros (don't care much how hygienic they are ;-) 
> could be even more beneficial, but it's a topic that stands on its own (not 
> sure wether this thread is more for fixed size arrays or metaprogramming… ;-)

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread Tino Heth via swift-evolution

> 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?
I think it's a good idea in general, but I don't think I'd notice if this 
feature would exist, so just to save some work for the compiler (and Core), I'd 
prefer to first get the feature itself, and improve it later.
So from my high-level perspective, I think the order should be
0) Add support for value literals as generic parameters
1) Add Array
2) Add support for generic parameters that are evaluated at compile time
3) Make everything fast ;-)
n) Add useful additions like detecting arrays that aren't declared as fixed 
length, but could

I think the alternative to macros (don't care much how hygienic they are ;-) 
could be even more beneficial, but it's a topic that stands on its own (not 
sure wether this thread is more for fixed size arrays or metaprogramming… ;-)___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread Félix Cloutier via swift-evolution

> Le 31 juil. 2017 à 00:40, Xiaodi Wu via swift-evolution 
>  a écrit :
> 
> 
> On Mon, Jul 31, 2017 at 02:15 Gor Gyolchanyan via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> > On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
> > mailto:swift-evolution@swift.org>> wrote:
> >
> >> On Jul 30, 2017, at 11:43 PM, Daryle Walker  >> > 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?

The optimization is defeated as soon as the storage buffer might escape, just 
like for closures. Consider this:

> func foo(arr: [Int])
> 
> var array = [1, 2, 3, 4]
> foo(arr: array)
> array[1] = 2

If `array` is "unrolled" to the stack, and `foo` keeps a reference to the 
storage, then `array[1] = 2` has to pessimistically create a new storage buffer 
to maintain COW semantics. It could also leave a dangling reference to the 
buffer if the function returns before all of the other references are gone. I'd 
rather not get into @escaping arrays.

I don't think that you claimed that this should be a solution to the fixed-size 
array problem, but just in case, also note that it's not. We can't make any 
[Int] layout-compatible with C fixed-size arrays because the length has to be 
encoded in the type (as it cannot be encoded in the data itself).

Félix

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread Gor Gyolchanyan via swift-evolution
> On Jul 31, 2017, at 11:09 AM, Xiaodi Wu  wrote:
> 
> 
> On Mon, Jul 31, 2017 at 02:51 Gor Gyolchanyan  > wrote:
>> On Jul 31, 2017, at 10:40 AM, Xiaodi Wu > > wrote:
>> 
>> 
>> On Mon, Jul 31, 2017 at 02:15 Gor Gyolchanyan via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> > On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>> > mailto:swift-evolution@swift.org>> wrote:
>> >
>> >> On Jul 30, 2017, at 11:43 PM, Daryle Walker > >> > 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

If a simple compiler hint is what you mean, then I'd go for something less 
array-centric and more along the lines of "arbitrary compiler hint", much like 
how C preprocessor has pragmas.
I'd go for this syntax instead:

var baz: @hint(fixed) Int = [1, 2, 3]

Which has the added benefit of prepping the general syntax for any other part 
of the language where the compiler could use a little hand-holding from the 
human.
I didn't want it to be simply @fixed, because the singular attributes so far 
follow the pattern of being mandatory, rather than optional hints, so that we 
don't confuse people by having at attribute that may or may not actually do 
anything and reserve that to a single very specific attribute.

But this is all outside of the topic.

Within the topic there were two major points made regarding compile-time 
evaluation:
* It's not warranted to consider this unless actual use cases are brought forth.
* Many of those use cases can be solved at run-time (e.g. generic value 
parameters).

My counter-point to those are:
* It's always possible to do things at run-time. I think it isn't worth 
spending time implementing a feature and complicating the language if it won't 
provide enough performance and convenience gains.
* Many of the features discussed here (including generic value parameters and 
fixed-size arrays) would be much simpler, more convenient, more performant and 
more powerful if the underlying deal-breaking lack of compile-time facilities 
was remedied.

> 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-re

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

2017-07-31 Thread Xiaodi Wu via swift-evolution
On Mon, Jul 31, 2017 at 02:51 Gor Gyolchanyan 
wrote:

> On Jul 31, 2017, at 10:40 AM, Xiaodi Wu  wrote:
>
>
> On Mon, Jul 31, 2017 at 02:15 Gor Gyolchanyan via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> > On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> >
>> >> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.
>>
>> > T

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

2017-07-31 Thread Xiaodi Wu via swift-evolution
On Mon, Jul 31, 2017 at 02:49 Goffredo Marocchi  wrote:

>
>
> Sent from my iPhone
>
> On 31 Jul 2017, at 08:40, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Mon, Jul 31, 2017 at 02:15 Gor Gyolchanyan via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> > On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> >
>> >> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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 in some cases humans may make an easier judgement call than the
> compiler?
>

Hence, why I'm asking why it shouldn't be an option for the human to help
the compiler with an annotation.

Because the compiler complexity is already growing and compile time is not
> exactly showing massive reductions and people are worried that as Swift
> gains more features and complexity with genetics and reflection and other
> features that compilation time will grow even more?
>

Do you have any evidence that this would be a performance-limiting task for
the compiler? Even if so, what's wrong with limiting the compiler to
inferring only the easiest cases, and allowing for manual annotation to
help the compiler in more complicated ones as an optional performance
enhancement? In other words, my question is, what is wrong with fixed-sized
arrays being--syntactically--simply arrays with resizing disabled? The flip
side of the coin is, why shouldn't normal arrays simply
be--syntactically--fixed-sized arrays with resizing enabled?

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.)
>> >>

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

2017-07-31 Thread Félix Cloutier via swift-evolution
It seems to me that this applies just the same to type generic parameters. Are 
there any reason that you can't instantiate a generic type at runtime, or is it 
just because the need is not as evident as it would/could be with non-type 
generic parameters?

> Le 30 juil. 2017 à 21:10, John McCall via swift-evolution 
>  a écrit :
> 
>> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.
> 
> 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.
> 
> 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).
> 
> 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  wrote:
>> 
 On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
  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@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-31 Thread Gor Gyolchanyan via swift-evolution

> On Jul 31, 2017, at 10:40 AM, Xiaodi Wu  wrote:
> 
> 
> On Mon, Jul 31, 2017 at 02:15 Gor Gyolchanyan via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> > On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
> > mailto:swift-evolution@swift.org>> wrote:
> >
> >> On Jul 30, 2017, at 11:43 PM, Daryle Walker  >> > 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). 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.

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 happe

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

2017-07-31 Thread Goffredo Marocchi via swift-evolution


Sent from my iPhone

> On 31 Jul 2017, at 08:40, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> 
>> On Mon, Jul 31, 2017 at 02:15 Gor Gyolchanyan via swift-evolution 
>>  wrote:
>> > On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>> >  wrote:
>> >
>> >> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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 in some cases humans may make an easier judgement call than the 
compiler? Because the compiler complexity is already growing and compile time 
is not exactly showing massive reductions and people are worried that as Swift 
gains more features and complexity with genetics and reflection and other 
features that compilation time will grow even more?

> 
>> 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  wrote:
>> >>
>>  On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>>   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, includin

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

2017-07-31 Thread Xiaodi Wu via swift-evolution
On Mon, Jul 31, 2017 at 02:15 Gor Gyolchanyan via swift-evolution <
swift-evolution@swift.org> wrote:

> > On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> >> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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?

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  wrote:
> >>
>  On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution <
> swift-evolution@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@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-evolution
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evo

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

2017-07-31 Thread Gor Gyolchanyan via swift-evolution
> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>  wrote:
> 
>> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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. 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  wrote:
>> 
 On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
  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@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread John McCall via swift-evolution
> On Jul 30, 2017, at 11:43 PM, Daryle Walker  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.

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.

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).

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  wrote:
> 
>>> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>>>  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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Daryle Walker via swift-evolution
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. 

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  wrote:

>> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>>  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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread John McCall via swift-evolution
> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>  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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Robert Bennett via swift-evolution
Is there any reason that constexpr couldn’t be inferred? Wherever you need 
something to be compile time constant — value-based generics, rawValue enum 
cases, etc — the compiler could make sure that the value was known at compile 
time, and if not then raise an error. Basically, assume everything is constexpr 
unless it can be shown to not (necessarily) be the case.

> On Jul 30, 2017, at 5:34 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
>> On Jul 30, 2017, at 10:03 AM, Gor Gyolchanyan via swift-evolution 
>>  wrote:
>> Tino Heth:
>> If you read my reply to Daniel Vollmer, you’ll find that we’re thinking 
>> about the exact same thing. Your code snippers show my vision of compiletime 
>> beautifully 🙂.
>> Now what I really want at this point is to here the opinions of the core 
>> team on this topic.
>> 
>> Swift Core Team:
>> Have you guys thought of this? Do you think this is a good idea to put on 
>> the table or do you have different plans?
> 
> I don’t speak for the core team as a whole, but here are my personal 
> opinions.  Note that this is off the cuff, without a lot of deliberate 
> consideration, so YMMV:
> 
> 1) I don’t think it makes sense to add constexpr before there is a motivating 
> use-case for it.  I agree that it could be useful with fixed sized arrays and 
> with constant parameters to generics, but we don’t have either of those yet.  
> If it were up to me, the place to start would be figuring out constant 
> generic parameters, since the answer there could inform fixed size arrays.
> 
> 2) I agree that there is heavy overlap with constexpr and macros, and that it 
> would be (probably showstoppingly) unfortunate to require duplication of 
> large swaths for the stdlib to make it work with constexprs.  Adding 
> “constexpr” to a few operator implementations would be reasonable though, and 
> may be a way to formalize “transparent”.
> 
> 3) I’m a fan of eventually adding a very general, but still hygienic, macro 
> system at some point, and assume that the # sigil will be used to for all 
> things macros.  For example, I’ve come to see the old “property behaviors” 
> proposal as being better reimagined as “property macros”, which suggest 
> syntax like “var #resettable foo : T” or something like that.
> 
> 4) The macro system should eventually support unstructured compile time 
> expansion, along the lines of what people do with Gyb and Sourcery with all 
> the tradeoffs they bring.
> 
> I tend to prefer that exploration in this space happen in order of points 
> above, and would prefer not to get to a generalized macro system for a couple 
> of years - just to give Swift more time to mature and develop without it.  
> Other languages have gotten macro systems too early in their development, and 
> become too reliant on it.  Perhaps if C didn’t have one it would have ended 
> up with a proper import mechanism.  Perhaps if Rust didn’t have one, some of 
> its decisions would have been different.  etc.
> 
> -Chris
> 
> 
> 
>> 
 On Jul 30, 2017, at 7:56 PM, Tino Heth <2...@gmx.de> wrote:
 
 
 more elaborate compile-time facilities, which would also provide extremely 
 powerful meta programming features
>>> That's an interesting twist — but whenever you put a "meta" somewhere, 
>>> things tend to get complicated, and people end up with different 
>>> associations to the topic… ;-)
>>> I took a brief look at the C++ document, but it seemed still to much 
>>> macro-like to me.
>>> 
>>> My take on the topic would be he ability to express common programming 
>>> tasks (declaring a class, overriding a method…) in the language itself.
>>> Imagine
>>> public class ProxyViewController: UIView {}
>>> Could be written as
>>> let subclass = createClass(classname: "ProxyViewController", superclass: 
>>> UIViewController, accessLevel: .public)
>>> 
>>> Quite stupid at first sight, and basically the exact opposite of syntactic 
>>> sugar ("syntactic salt" already has a meaning… so I'd call it "syntactic 
>>> pepper" ;-).
>>> But now imagine that:
>>> 
>>> for (method, implementation) in UIViewController.methods where 
>>> method.accessLevel == .open {
>>> subclass.methods[method] = { parameters in
>>> print("Subclass method \(method) called with \(parameters)")
>>> return implementation(parameters)
>>> }
>>> }
>>> 
>>> 
>>> Not that stupid anymore, isn't it?
>>> I think this would be way cooler than poking around with variants of search 
>>> & replace…
>>> 
>>> - Tino
>>> 
>>> (to get syntax colouring, I wrote ~30 lines of Swift that turn the straw 
>>> man example into valid code… it's fun, maybe I play with it a little bit 
>>> more ;-)
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mail

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

2017-07-30 Thread Daryle Walker via swift-evolution

> On Jul 30, 2017, at 5:34 PM, Tino Heth <2...@gmx.de> wrote:
> 
>> If you read my reply to Daniel Vollmer, you’ll find that we’re thinking 
>> about the exact same thing. 
> Good to hear — read that post later, but I guess repeating doesn't hurt here: 
> People still talk about macros... ;-)
> 
>>> So while I think they’re both great features to have, I assume the core 
>>> team will have higher priorities on their schedule, as I don’t see how 
>>> these features wouldn’t eat up most resources for at least (!) one Swift 
>>> release-cycle.
>> 
>> That’s just it: the core team is already prioritizing a lot of features that 
>> would greatly benefit from this. In fact, if this would be implemented, a 
>> large portion of the swift compiler could be moved into the standard 
>> library, because it wouldn’t be magic any more. This would single-handedly 
>> reduce the implementation time and effort of most proposals by a very large 
>> margin.
> 
> … and I like specific examples ;-), so out of my head, four features that 
> people want to have and that could be added easily with "Meta-Swift":
> - Forwarding of protocol conformance (Kotlin, for example, has this: When a 
> member conforms to a protocol, you don't have to write a bunch of methods 
> that just say "let my member do this")
> - init with reduced boilerplate
> - Subtyping for non-class types, including a "newtype" option
> - Property behaviours

The first and third items in that list seem similar to the “strong type-alias” 
idea I just updated (at 
). Is it 
close to what you’re talking about? I did the update because I recently looked 
up product and sum types again, and saw things called subtypes and quotient 
types. I realized that, with a little tweaking, strong-type-aliases could what 
would be needed to model sub- and quotient types.

> Imho the reflection capabilities that are needed to make the feature fly are 
> the big tasks — using this information shouldn't be that hard, as it's just a 
> explicit way of telling the compiler what to do.
> Assuming that reflection will be improved anyways, it might be a very cheap 
> feature with huge benefit.

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Tino Heth via swift-evolution

> If you read my reply to Daniel Vollmer, you’ll find that we’re thinking about 
> the exact same thing. 
Good to hear — read that post later, but I guess repeating doesn't hurt here: 
People still talk about macros... ;-)

>> So while I think they’re both great features to have, I assume the core team 
>> will have higher priorities on their schedule, as I don’t see how these 
>> features wouldn’t eat up most resources for at least (!) one Swift 
>> release-cycle.
> 
> That’s just it: the core team is already prioritizing a lot of features that 
> would greatly benefit from this. In fact, if this would be implemented, a 
> large portion of the swift compiler could be moved into the standard library, 
> because it wouldn’t be magic any more. This would single-handedly reduce the 
> implementation time and effort of most proposals by a very large margin.

… and I like specific examples ;-), so out of my head, four features that 
people want to have and that could be added easily with "Meta-Swift":
- Forwarding of protocol conformance (Kotlin, for example, has this: When a 
member conforms to a protocol, you don't have to write a bunch of methods that 
just say "let my member do this")
- init with reduced boilerplate
- Subtyping for non-class types, including a "newtype" option
- Property behaviours

Imho the reflection capabilities that are needed to make the feature fly are 
the big tasks — using this information shouldn't be that hard, as it's just a 
explicit way of telling the compiler what to do.
Assuming that reflection will be improved anyways, it might be a very cheap 
feature with huge benefit.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Chris Lattner via swift-evolution
On Jul 30, 2017, at 10:03 AM, Gor Gyolchanyan via swift-evolution 
 wrote:
> Tino Heth:
> If you read my reply to Daniel Vollmer, you’ll find that we’re thinking about 
> the exact same thing. Your code snippers show my vision of compiletime 
> beautifully 🙂.
> Now what I really want at this point is to here the opinions of the core team 
> on this topic.
> 
> Swift Core Team:
> Have you guys thought of this? Do you think this is a good idea to put on the 
> table or do you have different plans?

I don’t speak for the core team as a whole, but here are my personal opinions.  
Note that this is off the cuff, without a lot of deliberate consideration, so 
YMMV:

1) I don’t think it makes sense to add constexpr before there is a motivating 
use-case for it.  I agree that it could be useful with fixed sized arrays and 
with constant parameters to generics, but we don’t have either of those yet.  
If it were up to me, the place to start would be figuring out constant generic 
parameters, since the answer there could inform fixed size arrays.

2) I agree that there is heavy overlap with constexpr and macros, and that it 
would be (probably showstoppingly) unfortunate to require duplication of large 
swaths for the stdlib to make it work with constexprs.  Adding “constexpr” to a 
few operator implementations would be reasonable though, and may be a way to 
formalize “transparent”.

3) I’m a fan of eventually adding a very general, but still hygienic, macro 
system at some point, and assume that the # sigil will be used to for all 
things macros.  For example, I’ve come to see the old “property behaviors” 
proposal as being better reimagined as “property macros”, which suggest syntax 
like “var #resettable foo : T” or something like that.

4) The macro system should eventually support unstructured compile time 
expansion, along the lines of what people do with Gyb and Sourcery with all the 
tradeoffs they bring.

I tend to prefer that exploration in this space happen in order of points 
above, and would prefer not to get to a generalized macro system for a couple 
of years - just to give Swift more time to mature and develop without it.  
Other languages have gotten macro systems too early in their development, and 
become too reliant on it.  Perhaps if C didn’t have one it would have ended up 
with a proper import mechanism.  Perhaps if Rust didn’t have one, some of its 
decisions would have been different.  etc.

-Chris



> 
>> On Jul 30, 2017, at 7:56 PM, Tino Heth <2...@gmx.de > 
>> wrote:
>> 
>> 
>>> more elaborate compile-time facilities, which would also provide extremely 
>>> powerful meta programming features
>> That's an interesting twist — but whenever you put a "meta" somewhere, 
>> things tend to get complicated, and people end up with different 
>> associations to the topic… ;-)
>> I took a brief look at the C++ document, but it seemed still to much 
>> macro-like to me.
>> 
>> My take on the topic would be he ability to express common programming tasks 
>> (declaring a class, overriding a method…) in the language itself.
>> Imagine
>> public class ProxyViewController: UIView {}
>> Could be written as
>> let subclass = createClass(classname: "ProxyViewController", superclass: 
>> UIViewController, accessLevel: .public)
>> 
>> Quite stupid at first sight, and basically the exact opposite of syntactic 
>> sugar ("syntactic salt" already has a meaning… so I'd call it "syntactic 
>> pepper" ;-).
>> But now imagine that:
>> 
>> for (method, implementation) in UIViewController.methods where 
>> method.accessLevel == .open {
>> subclass.methods[method] = { parameters in
>> print("Subclass method \(method) called with \(parameters)")
>> return implementation(parameters)
>> }
>> }
>> 
>> 
>> Not that stupid anymore, isn't it?
>> I think this would be way cooler than poking around with variants of search 
>> & replace…
>> 
>> - Tino
>> 
>> (to get syntax colouring, I wrote ~30 lines of Swift that turn the straw man 
>> example into valid code… it's fun, maybe I play with it a little bit more ;-)
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Gor Gyolchanyan via swift-evolution
> On Jul 30, 2017, at 9:29 PM, Christopher Kornher  wrote:
> 
> I am not sure that macros and annotations would be good, either. It may be 
> impossible to avoid them, given Swift’s goal of “world domination”. Both 
> features are very useful in certain applications.

I’d argue that exposing swift’s front-end as a built-in module with APIs for 
creating instances of language constructs and building them programmatically 
and then allowing one to run that code at compile time would make it much 
easier to achieve “world domination” because generating code through a 
well-defined and well-documented API written in the same language as the one 
being generated would be much easier than using the equivalent of what Xcode 
uses to represent the code for semantical highlighting, navigation and 
debugging purposes (which, I imagine, is just text with some metadata).

> We could continue to use custom tools like Cog and Sourcery when we need to, 
> or standardize and better integrate their functionality. I honestly am not 
> sure which is a better solution.

Well, gyb is the tool written specifically for swift and a large portion of the 
standard library and the `Builtin` module is generated by gyb. That doesn’t 
look like a design choice to me. It looks more like the lesser of two evils 
(the other being manual, error-prone boilerplate).

> "Hygienic Macros” and “Annotations” have both been discussed. Both of these 
> features would bring power and complexity to the language, to be sure. I just 
> wanted to voice my opinion that these features, if and when they arrive, 
> should be transparent, i.e., the generated code should be visible and 
> sensibly formatted so that it can be examined and debugged. This would be a 
> hard problem, and I am not sure if it is even possible for complex macro & 
> annotation combinations…

If the metaprogramming facilities are implemented as a builtin module that 
exposes the swift frontend as a compile-time API, it would be much easier to 
adapt the debugging tools to encompass it, than trying to reverse-engineer the 
code, generated by semantically-unaware macro system, since the generated code 
was never in textual form in the first place. It would even allow things like 
Xcode generating a textural representation of the generated source for 
debugging purposes (where your mentioned formatters would come in handy).

> C macros are not hygienic and not “transparent”. C preprocessor output, for 
> example, is largely unusable.
> 
> The uses of macros and annotation overlap. Introducing macros and annotations 
> at the same time would provide a chance to sensibly balance the features of 
> each and provide a coherent set of guidelines for developers. 

I’m not sure what you mean by “annotations”, but if you’re referring to 
arbitrary user-defined metadata attached to language constructs, then the 
API-based codeine would make this exceedingly easy, because LLVM libraries 
natively support metadata on pretty much everything, so it would be a simple 
matter of not forgetting to expose those to Swift as well.

> - Chris K
> 
>> On Jul 30, 2017, at 12:03 PM, Gor Gyolchanyan via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> I don’t think a Cog-like or Gyb-like macro system would be good. That’s 
>> essentially a preprocessor and we all know how that worked out for C. The 
>> only a code-generation feature can exist in a safe language like Swift is by 
>> making it a first-class citizen as described previously. I’m not sure 
>> whether or not the core team would consider such a thing, bit I am very 
>> certain that a text-based macro system is something they’d never consider.
>> 
>>> On Jul 30, 2017, at 8:54 PM, Christopher Kornher >> > wrote:
>>> 
>>> I assume that the planned “hygienic macro” facility, if it has access to 
>>> metadata, or “annotations", could be used for these sorts of meta tasks, .
>>> 
>>> This is slightly off-topic, but I hope that there is a way for macros to be 
>>> fully expanded and debuggable (and even formatted). I use Cog with Swift as 
>>> a kind of "macro-system on steroids” that provides these features. I would 
>>> love to see a Cog-like system included as a standard feature of the 
>>> language in the future. It could be a component of annotations, macros, or 
>>> both.
>>> 
>>> I would like to see a source code generation pre-pass added for 
>>> annotations, and hopefully macros when they arrive, so that developers can 
>>> see, debug, and code against the expanded code. I realize that may be 
>>> difficult or even impossible for some macros.
>>> 
>>> GOG uses Python as its macro language, which is certainly compatible with 
>>> Apple’s toolchain. Using a real programming language for annotations, is 
>>> extremely powerful.
>>> 
>>> The danger of adding a macro system too early, is that it can be used as a 
>>> “cheat” to implement functionality that should be part of the base language 
>>> and discoura

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

2017-07-30 Thread Christopher Kornher via swift-evolution
I am not sure that macros and annotations would be good, either. It may be 
impossible to avoid them, given Swift’s goal of “world domination”. Both 
features are very useful in certain applications.

We could continue to use custom tools like Cog and Sourcery when we need to, or 
standardize and better integrate their functionality. I honestly am not sure 
which is a better solution.

"Hygienic Macros” and “Annotations” have both been discussed. Both of these 
features would bring power and complexity to the language, to be sure. I just 
wanted to voice my opinion that these features, if and when they arrive, should 
be transparent, i.e., the generated code should be visible and sensibly 
formatted so that it can be examined and debugged. This would be a hard 
problem, and I am not sure if it is even possible for complex macro & 
annotation combinations…

C macros are not hygienic and not “transparent”. C preprocessor output, for 
example, is largely unusable.

The uses of macros and annotation overlap. Introducing macros and annotations 
at the same time would provide a chance to sensibly balance the features of 
each and provide a coherent set of guidelines for developers. 

- Chris K

> On Jul 30, 2017, at 12:03 PM, Gor Gyolchanyan via swift-evolution 
>  wrote:
> 
> I don’t think a Cog-like or Gyb-like macro system would be good. That’s 
> essentially a preprocessor and we all know how that worked out for C. The 
> only a code-generation feature can exist in a safe language like Swift is by 
> making it a first-class citizen as described previously. I’m not sure whether 
> or not the core team would consider such a thing, bit I am very certain that 
> a text-based macro system is something they’d never consider.
> 
>> On Jul 30, 2017, at 8:54 PM, Christopher Kornher > > wrote:
>> 
>> I assume that the planned “hygienic macro” facility, if it has access to 
>> metadata, or “annotations", could be used for these sorts of meta tasks, .
>> 
>> This is slightly off-topic, but I hope that there is a way for macros to be 
>> fully expanded and debuggable (and even formatted). I use Cog with Swift as 
>> a kind of "macro-system on steroids” that provides these features. I would 
>> love to see a Cog-like system included as a standard feature of the language 
>> in the future. It could be a component of annotations, macros, or both.
>> 
>> I would like to see a source code generation pre-pass added for annotations, 
>> and hopefully macros when they arrive, so that developers can see, debug, 
>> and code against the expanded code. I realize that may be difficult or even 
>> impossible for some macros.
>> 
>> GOG uses Python as its macro language, which is certainly compatible with 
>> Apple’s toolchain. Using a real programming language for annotations, is 
>> extremely powerful.
>> 
>> The danger of adding a macro system too early, is that it can be used as a 
>> “cheat” to implement functionality that should be part of the base language 
>> and discourage language development. I trust that the core team will not let 
>> this happen.
>> 
>> See Cog: 
>> https://nedbatchelder.com/code/cog/ 
>> 
>> A fully integrated Cog-like facility this should have language support to 
>> cleanup the (pretty ugly) delimiters and eventually tool support to 
>> selectively toggle expansion, as we can today with code blocks, for example, 
>> in many tools.
>> 
>> I don’t mean to derail this discussion, but it seems that an annotation or 
>> macro system would be appropriate for this kind of feature.
>> 
>> - Chris
>> 
>> 
>>> On Jul 30, 2017, at 11:03 AM, Gor Gyolchanyan via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Tino Heth:
>>> If you read my reply to Daniel Vollmer, you’ll find that we’re thinking 
>>> about the exact same thing. Your code snippers show my vision of 
>>> compiletime beautifully 🙂.
>>> Now what I really want at this point is to here the opinions of the core 
>>> team on this topic.
>>> 
>>> Swift Core Team:
>>> Have you guys thought of this? Do you think this is a good idea to put on 
>>> the table or do you have different plans?
>>> 
 On Jul 30, 2017, at 7:56 PM, Tino Heth <2...@gmx.de > 
 wrote:
 
 
> more elaborate compile-time facilities, which would also provide 
> extremely powerful meta programming features
 That's an interesting twist — but whenever you put a "meta" somewhere, 
 things tend to get complicated, and people end up with different 
 associations to the topic… ;-)
 I took a brief look at the C++ document, but it seemed still to much 
 macro-like to me.
 
 My take on the topic would be he ability to express common programming 
 tasks (declaring a class, overriding a method…) in the language itself.
 Imagine
 public class ProxyViewController: UIView {}
 Could be written as
 let subclass = createClass(classname: 

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

2017-07-30 Thread Christopher Kornher via swift-evolution
For completeness: I forgot to mention that I have been meaning to check-out 
Sourcery, which is possibly a more “Swifty” tool. I use Cog’s file-scope 
extensively, and it is unclear to me if that is a feature of Sourcery

https://github.com/krzysztofzablocki/Sourcery

OK, now I am sure that someone is going to tell me that I am off-topic :)

- Chris K

> On Jul 30, 2017, at 11:54 AM, Christopher Kornher  wrote:
> 
> I assume that the planned “hygienic macro” facility, if it has access to 
> metadata, or “annotations", could be used for these sorts of meta tasks, .
> 
> This is slightly off-topic, but I hope that there is a way for macros to be 
> fully expanded and debuggable (and even formatted). I use Cog with Swift as a 
> kind of "macro-system on steroids” that provides these features. I would love 
> to see a Cog-like system included as a standard feature of the language in 
> the future. It could be a component of annotations, macros, or both.
> 
> I would like to see a source code generation pre-pass added for annotations, 
> and hopefully macros when they arrive, so that developers can see, debug, and 
> code against the expanded code. I realize that may be difficult or even 
> impossible for some macros.
> 
> GOG uses Python as its macro language, which is certainly compatible with 
> Apple’s toolchain. Using a real programming language for annotations, is 
> extremely powerful.
> 
> The danger of adding a macro system too early, is that it can be used as a 
> “cheat” to implement functionality that should be part of the base language 
> and discourage language development. I trust that the core team will not let 
> this happen.
> 
> See Cog: 
> https://nedbatchelder.com/code/cog/ 
> 
> A fully integrated Cog-like facility this should have language support to 
> cleanup the (pretty ugly) delimiters and eventually tool support to 
> selectively toggle expansion, as we can today with code blocks, for example, 
> in many tools.
> 
> I don’t mean to derail this discussion, but it seems that an annotation or 
> macro system would be appropriate for this kind of feature.
> 
> - Chris
> 
> 
>> On Jul 30, 2017, at 11:03 AM, Gor Gyolchanyan via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Tino Heth:
>> If you read my reply to Daniel Vollmer, you’ll find that we’re thinking 
>> about the exact same thing. Your code snippers show my vision of compiletime 
>> beautifully 🙂.
>> Now what I really want at this point is to here the opinions of the core 
>> team on this topic.
>> 
>> Swift Core Team:
>> Have you guys thought of this? Do you think this is a good idea to put on 
>> the table or do you have different plans?
>> 
>>> On Jul 30, 2017, at 7:56 PM, Tino Heth <2...@gmx.de > 
>>> wrote:
>>> 
>>> 
 more elaborate compile-time facilities, which would also provide extremely 
 powerful meta programming features
>>> That's an interesting twist — but whenever you put a "meta" somewhere, 
>>> things tend to get complicated, and people end up with different 
>>> associations to the topic… ;-)
>>> I took a brief look at the C++ document, but it seemed still to much 
>>> macro-like to me.
>>> 
>>> My take on the topic would be he ability to express common programming 
>>> tasks (declaring a class, overriding a method…) in the language itself.
>>> Imagine
>>> public class ProxyViewController: UIView {}
>>> Could be written as
>>> let subclass = createClass(classname: "ProxyViewController", superclass: 
>>> UIViewController, accessLevel: .public)
>>> 
>>> Quite stupid at first sight, and basically the exact opposite of syntactic 
>>> sugar ("syntactic salt" already has a meaning… so I'd call it "syntactic 
>>> pepper" ;-).
>>> But now imagine that:
>>> 
>>> for (method, implementation) in UIViewController.methods where 
>>> method.accessLevel == .open {
>>> subclass.methods[method] = { parameters in
>>> print("Subclass method \(method) called with \(parameters)")
>>> return implementation(parameters)
>>> }
>>> }
>>> 
>>> 
>>> Not that stupid anymore, isn't it?
>>> I think this would be way cooler than poking around with variants of search 
>>> & replace…
>>> 
>>> - Tino
>>> 
>>> (to get syntax colouring, I wrote ~30 lines of Swift that turn the straw 
>>> man example into valid code… it's fun, maybe I play with it a little bit 
>>> more ;-)
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Gor Gyolchanyan via swift-evolution
I don’t think a Cog-like or Gyb-like macro system would be good. That’s 
essentially a preprocessor and we all know how that worked out for C. The only 
a code-generation feature can exist in a safe language like Swift is by making 
it a first-class citizen as described previously. I’m not sure whether or not 
the core team would consider such a thing, bit I am very certain that a 
text-based macro system is something they’d never consider.

> On Jul 30, 2017, at 8:54 PM, Christopher Kornher  wrote:
> 
> I assume that the planned “hygienic macro” facility, if it has access to 
> metadata, or “annotations", could be used for these sorts of meta tasks, .
> 
> This is slightly off-topic, but I hope that there is a way for macros to be 
> fully expanded and debuggable (and even formatted). I use Cog with Swift as a 
> kind of "macro-system on steroids” that provides these features. I would love 
> to see a Cog-like system included as a standard feature of the language in 
> the future. It could be a component of annotations, macros, or both.
> 
> I would like to see a source code generation pre-pass added for annotations, 
> and hopefully macros when they arrive, so that developers can see, debug, and 
> code against the expanded code. I realize that may be difficult or even 
> impossible for some macros.
> 
> GOG uses Python as its macro language, which is certainly compatible with 
> Apple’s toolchain. Using a real programming language for annotations, is 
> extremely powerful.
> 
> The danger of adding a macro system too early, is that it can be used as a 
> “cheat” to implement functionality that should be part of the base language 
> and discourage language development. I trust that the core team will not let 
> this happen.
> 
> See Cog: 
> https://nedbatchelder.com/code/cog/ 
> 
> A fully integrated Cog-like facility this should have language support to 
> cleanup the (pretty ugly) delimiters and eventually tool support to 
> selectively toggle expansion, as we can today with code blocks, for example, 
> in many tools.
> 
> I don’t mean to derail this discussion, but it seems that an annotation or 
> macro system would be appropriate for this kind of feature.
> 
> - Chris
> 
> 
>> On Jul 30, 2017, at 11:03 AM, Gor Gyolchanyan via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Tino Heth:
>> If you read my reply to Daniel Vollmer, you’ll find that we’re thinking 
>> about the exact same thing. Your code snippers show my vision of compiletime 
>> beautifully 🙂.
>> Now what I really want at this point is to here the opinions of the core 
>> team on this topic.
>> 
>> Swift Core Team:
>> Have you guys thought of this? Do you think this is a good idea to put on 
>> the table or do you have different plans?
>> 
>>> On Jul 30, 2017, at 7:56 PM, Tino Heth <2...@gmx.de > 
>>> wrote:
>>> 
>>> 
 more elaborate compile-time facilities, which would also provide extremely 
 powerful meta programming features
>>> That's an interesting twist — but whenever you put a "meta" somewhere, 
>>> things tend to get complicated, and people end up with different 
>>> associations to the topic… ;-)
>>> I took a brief look at the C++ document, but it seemed still to much 
>>> macro-like to me.
>>> 
>>> My take on the topic would be he ability to express common programming 
>>> tasks (declaring a class, overriding a method…) in the language itself.
>>> Imagine
>>> public class ProxyViewController: UIView {}
>>> Could be written as
>>> let subclass = createClass(classname: "ProxyViewController", superclass: 
>>> UIViewController, accessLevel: .public)
>>> 
>>> Quite stupid at first sight, and basically the exact opposite of syntactic 
>>> sugar ("syntactic salt" already has a meaning… so I'd call it "syntactic 
>>> pepper" ;-).
>>> But now imagine that:
>>> 
>>> for (method, implementation) in UIViewController.methods where 
>>> method.accessLevel == .open {
>>> subclass.methods[method] = { parameters in
>>> print("Subclass method \(method) called with \(parameters)")
>>> return implementation(parameters)
>>> }
>>> }
>>> 
>>> 
>>> Not that stupid anymore, isn't it?
>>> I think this would be way cooler than poking around with variants of search 
>>> & replace…
>>> 
>>> - Tino
>>> 
>>> (to get syntax colouring, I wrote ~30 lines of Swift that turn the straw 
>>> man example into valid code… it's fun, maybe I play with it a little bit 
>>> more ;-)
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Christopher Kornher via swift-evolution
I assume that the planned “hygienic macro” facility, if it has access to 
metadata, or “annotations", could be used for these sorts of meta tasks, .

This is slightly off-topic, but I hope that there is a way for macros to be 
fully expanded and debuggable (and even formatted). I use Cog with Swift as a 
kind of "macro-system on steroids” that provides these features. I would love 
to see a Cog-like system included as a standard feature of the language in the 
future. It could be a component of annotations, macros, or both.

I would like to see a source code generation pre-pass added for annotations, 
and hopefully macros when they arrive, so that developers can see, debug, and 
code against the expanded code. I realize that may be difficult or even 
impossible for some macros.

GOG uses Python as its macro language, which is certainly compatible with 
Apple’s toolchain. Using a real programming language for annotations, is 
extremely powerful.

The danger of adding a macro system too early, is that it can be used as a 
“cheat” to implement functionality that should be part of the base language and 
discourage language development. I trust that the core team will not let this 
happen.

See Cog: 
https://nedbatchelder.com/code/cog/ 

A fully integrated Cog-like facility this should have language support to 
cleanup the (pretty ugly) delimiters and eventually tool support to selectively 
toggle expansion, as we can today with code blocks, for example, in many tools.

I don’t mean to derail this discussion, but it seems that an annotation or 
macro system would be appropriate for this kind of feature.

- Chris


> On Jul 30, 2017, at 11:03 AM, Gor Gyolchanyan via swift-evolution 
>  wrote:
> 
> Tino Heth:
> If you read my reply to Daniel Vollmer, you’ll find that we’re thinking about 
> the exact same thing. Your code snippers show my vision of compiletime 
> beautifully 🙂.
> Now what I really want at this point is to here the opinions of the core team 
> on this topic.
> 
> Swift Core Team:
> Have you guys thought of this? Do you think this is a good idea to put on the 
> table or do you have different plans?
> 
>> On Jul 30, 2017, at 7:56 PM, Tino Heth <2...@gmx.de > 
>> wrote:
>> 
>> 
>>> more elaborate compile-time facilities, which would also provide extremely 
>>> powerful meta programming features
>> That's an interesting twist — but whenever you put a "meta" somewhere, 
>> things tend to get complicated, and people end up with different 
>> associations to the topic… ;-)
>> I took a brief look at the C++ document, but it seemed still to much 
>> macro-like to me.
>> 
>> My take on the topic would be he ability to express common programming tasks 
>> (declaring a class, overriding a method…) in the language itself.
>> Imagine
>> public class ProxyViewController: UIView {}
>> Could be written as
>> let subclass = createClass(classname: "ProxyViewController", superclass: 
>> UIViewController, accessLevel: .public)
>> 
>> Quite stupid at first sight, and basically the exact opposite of syntactic 
>> sugar ("syntactic salt" already has a meaning… so I'd call it "syntactic 
>> pepper" ;-).
>> But now imagine that:
>> 
>> for (method, implementation) in UIViewController.methods where 
>> method.accessLevel == .open {
>> subclass.methods[method] = { parameters in
>> print("Subclass method \(method) called with \(parameters)")
>> return implementation(parameters)
>> }
>> }
>> 
>> 
>> Not that stupid anymore, isn't it?
>> I think this would be way cooler than poking around with variants of search 
>> & replace…
>> 
>> - Tino
>> 
>> (to get syntax colouring, I wrote ~30 lines of Swift that turn the straw man 
>> example into valid code… it's fun, maybe I play with it a little bit more ;-)
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Gor Gyolchanyan via swift-evolution
Tino Heth:
If you read my reply to Daniel Vollmer, you’ll find that we’re thinking about 
the exact same thing. Your code snippers show my vision of compiletime 
beautifully 🙂.
Now what I really want at this point is to here the opinions of the core team 
on this topic.

Swift Core Team:
Have you guys thought of this? Do you think this is a good idea to put on the 
table or do you have different plans?

> On Jul 30, 2017, at 7:56 PM, Tino Heth <2...@gmx.de> wrote:
> 
> 
>> more elaborate compile-time facilities, which would also provide extremely 
>> powerful meta programming features
> That's an interesting twist — but whenever you put a "meta" somewhere, things 
> tend to get complicated, and people end up with different associations to the 
> topic… ;-)
> I took a brief look at the C++ document, but it seemed still to much 
> macro-like to me.
> 
> My take on the topic would be he ability to express common programming tasks 
> (declaring a class, overriding a method…) in the language itself.
> Imagine
> public class ProxyViewController: UIView {}
> Could be written as
> let subclass = createClass(classname: "ProxyViewController", superclass: 
> UIViewController, accessLevel: .public)
> 
> Quite stupid at first sight, and basically the exact opposite of syntactic 
> sugar ("syntactic salt" already has a meaning… so I'd call it "syntactic 
> pepper" ;-).
> But now imagine that:
> 
> for (method, implementation) in UIViewController.methods where 
> method.accessLevel == .open {
> subclass.methods[method] = { parameters in
> print("Subclass method \(method) called with \(parameters)")
> return implementation(parameters)
> }
> }
> 
> 
> Not that stupid anymore, isn't it?
> I think this would be way cooler than poking around with variants of search & 
> replace…
> 
> - Tino
> 
> (to get syntax colouring, I wrote ~30 lines of Swift that turn the straw man 
> example into valid code… it's fun, maybe I play with it a little bit more ;-)

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Tino Heth via swift-evolution

> more elaborate compile-time facilities, which would also provide extremely 
> powerful meta programming features
That's an interesting twist — but whenever you put a "meta" somewhere, things 
tend to get complicated, and people end up with different associations to the 
topic… ;-)
I took a brief look at the C++ document, but it seemed still to much macro-like 
to me.

My take on the topic would be he ability to express common programming tasks 
(declaring a class, overriding a method…) in the language itself.
Imagine
public class ProxyViewController: UIView {}
Could be written as
let subclass = createClass(classname: "ProxyViewController", superclass: 
UIViewController, accessLevel: .public)

Quite stupid at first sight, and basically the exact opposite of syntactic 
sugar ("syntactic salt" already has a meaning… so I'd call it "syntactic 
pepper" ;-).
But now imagine that:

for (method, implementation) in UIViewController.methods where 
method.accessLevel == .open {
subclass.methods[method] = { parameters in
print("Subclass method \(method) called with \(parameters)")
return implementation(parameters)
}
}


Not that stupid anymore, isn't it?
I think this would be way cooler than poking around with variants of search & 
replace…

- Tino

(to get syntax colouring, I wrote ~30 lines of Swift that turn the straw man 
example into valid code… it's fun, maybe I play with it a little bit more ;-)___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Gor Gyolchanyan via swift-evolution
> On Jul 30, 2017, at 1:03 PM, Daniel Vollmer via swift-evolution 
>  wrote:
> 
> Hello,
> 
>> On 30. Jul 2017, at 08:52, Gor Gyolchanyan via swift-evolution 
>>  wrote:
> 
> [snip]
> 
>> This is a huge undertaking, but if we split it in two parts: "executing at 
>> compiletime" and "exposing swift’s frontend”, this could surely be done by 
>> Swift 5. From all the ideas that I’ve had or seen on this mailing list, in 
>> my opinion this is the most ground-braking, powerful and useful, so I’d be 
>> willing to work day and night to help implement this.
> 
> As you say, I agree that these are separate concepts (compile-time evaluation 
> vs. meta-programming), but the first is surely going to be helpful for the 
> second.

That’s exactly what I had in mind: compiletime execution comes first, 
meta-programming gets built on top of it.

> As far as I can tell, compile-time evaluation would probably lose most / all 
> of the stdlib. I’d hate to replicate parts of the standard library in a 
> restricted subset of the language so that they are available in `constexpr` 
> mode (which is what 80% of C++’s template meta-programming libraries do). I’m 
> also not quite sure how to make that feature work with cross-compilation when 
> host and target differ in architecture.

I disagree. Most of the standard library is in protocols and small generic 
wrapper structures, which are prime candidates for compile-time evaluation. 
Even if Foundation has to be dropped (which is actually not that big of a 
deal), I think adapting the standard library to be less architecturally 
dependent to make it accessible in compiletime wouldn’t be such a big problem 
considering that it is already largely driven by protocols.
I think the architectural differences are negligible largely due to LLVM IR, 
which is portable (even byte ordering is taken into account).

> As for the meta-programming / macro part, a recent C++ proposal tries to 
> extend the language in that direction: 
> https://herbsutter.files.wordpress.com/2017/07/p0707r1.pdf .
> Ignoring the syntax, at the very least it might reduce the need for gyb in 
> places. That said, because Swift’s and C++’s instantiation model for generic 
> code is so different, there’s going to be some blockers there…

C++ relies on its template system as a compile-time code generation mechanism 
to achieve this, that’s why it can get away with little-to-no metaprogramming 
concepts. The major drawback is that it’s a lot like the C preprocessor: it’s a 
dumb search-replace shtick that has to be micromanaged to work correctly. Since 
Swift’s generics are a whole different kind of fruit, they are more closely 
related to C++’s functions that take a polymorphic pointer, rather then a 
template function, so Swift’s generics are not going to be of any help in this. 
My idea was to introduce a first-class toolset to Swift that allows one to 
essentially generate arbitrary Swift code at compile-time, but rather than 
generating a string and mixing it into the source, it would be much more 
AST-aware and safe. This could be done by executing a function at compiletime 
that returns an instance of Meta.TypeDefinition, which would be declared as 
compiletime struct (meaning, that the type and its instances cannot exist at 
runtime). The import keyword could be reused to not only statically import 
modules, but to import instances of Meta.TypeDefinition.

> So while I think they’re both great features to have, I assume the core team 
> will have higher priorities on their schedule, as I don’t see how these 
> features wouldn’t eat up most resources for at least (!) one Swift 
> release-cycle.

That’s just it: the core team is already prioritizing a lot of features that 
would greatly benefit from this. In fact, if this would be implemented, a large 
portion of the swift compiler could be moved into the standard library, because 
it wouldn’t be magic any more. This would single-handedly reduce the 
implementation time and effort of most proposals by a very large margin.

>   Daniel.
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-30 Thread Daniel Vollmer via swift-evolution
Hello,

> On 30. Jul 2017, at 08:52, Gor Gyolchanyan via swift-evolution 
>  wrote:

[snip]

> This is a huge undertaking, but if we split it in two parts: "executing at 
> compiletime" and "exposing swift’s frontend”, this could surely be done by 
> Swift 5. From all the ideas that I’ve had or seen on this mailing list, in my 
> opinion this is the most ground-braking, powerful and useful, so I’d be 
> willing to work day and night to help implement this.

As you say, I agree that these are separate concepts (compile-time evaluation 
vs. meta-programming), but the first is surely going to be helpful for the 
second.

As far as I can tell, compile-time evaluation would probably lose most / all of 
the stdlib. I’d hate to replicate parts of the standard library in a restricted 
subset of the language so that they are available in `constexpr` mode (which is 
what 80% of C++’s template meta-programming libraries do). I’m also not quite 
sure how to make that feature work with cross-compilation when host and target 
differ in architecture.

As for the meta-programming / macro part, a recent C++ proposal tries to extend 
the language in that direction: 
https://herbsutter.files.wordpress.com/2017/07/p0707r1.pdf .
Ignoring the syntax, at the very least it might reduce the need for gyb in 
places. That said, because Swift’s and C++’s instantiation model for generic 
code is so different, there’s going to be some blockers there…

So while I think they’re both great features to have, I assume the core team 
will have higher priorities on their schedule, as I don’t see how these 
features wouldn’t eat up most resources for at least (!) one Swift 
release-cycle.

Daniel.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-29 Thread Gor Gyolchanyan via swift-evolution
I’ve thought about this a lot lately. I think, given llvm’s built-in MCJIT 
engine and interpreter, it would be relatively easy to skip the under-developed 
constexpr that C++ settled on and go straight for a more elaborate compile-time 
facilities, which would also provide extremely powerful meta programming 
features (think C preprocessor macros, except context-aware, more powerful, 
convenient and safe). D (http://dlang.org) has this feature, which is really 
great, but it doesn’t save the otherwise sloppy and lackluster language.
In a nutshell, marking something as compiletime (or some more fitting keyword 
for the purpose) would do two things:
Any runtime-defined facilities (code to be executed, values of function 
parameters, assertion and precondition checks) would be attempted to be 
run/acquired at compiletime.
If any of those facilities are not possible to compute at compiletime, a 
compiler error would occur.
Besides being useful in generic value parameters, this could also be used to 
define a much more elaborate reflection system in Swift (which would now be 
much less of a magic).
If in addition to this, select parts of Swift’s frontend would be exposed to 
the language in the form of compile-time mutable values (like types, variables, 
functions, attributes), then users could use these compiletime facilities to do 
what Swift’s gyb.py (https://github.com/apple/swift/blob/master/utils/gyb.py 
) currently does (and 
if you’re like me, you find yourself using it a lot, especially for libraries 
with a complete integration with some other library).

This is a huge undertaking, but if we split it in two parts: "executing at 
compiletime" and "exposing swift’s frontend”, this could surely be done by 
Swift 5. From all the ideas that I’ve had or seen on this mailing list, in my 
opinion this is the most ground-braking, powerful and useful, so I’d be willing 
to work day and night to help implement this.

> On Jul 30, 2017, at 2:02 AM, Daryle Walker via swift-evolution 
>  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?
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-07-29 Thread Daryle Walker via swift-evolution
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?

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution