Re: [swift-evolution] Ad hoc enums / options

2016-06-02 Thread L Mihalkovic via swift-evolution
On Jun 2, 2016, at 6:42 AM, Félix Cloutier  wrote:I don't understand this. All of what you said applies to structs and does not apply to tuples. What makes it fundamentally impossible to have a "tuple-like enum"?
Félix
the swift type system contains nominal and structural types. Structural types are ‘shapes’ (Int/Int , String/Int/Int … ) that are associated with a location (variable, fcn return, ..) in the source code. The other types are ‘names’. These names by themselves would be useless, so we can define what these names should represent by listing some characteristics (members, cases, …). Depending on what we say they are, these ‘names’ behave differently. Enums are nominal, tuples are structural. That alone means that however alike they APPEAR to be, they BEHAVE very differently: a tuple has BY DEFINITION one-value-for-each-slot it contains, whereas an enum has a single value that is one-and-only-one of the possible values of the domain it forms. So they are fundamentally different because they simply are (by definition). 
Le 1 juin 2016 à 20:56:27, L. Mihalkovic via swift-evolution  a écrit :On Jun 1, 2016, at 11:38 PM, Tony Allevato  wrote:I find myself agreeing with the idea that ad hoc enums are to enums as structs are to tuples. Based on that analogy, why should an ad hoc enum *need* a name (autogenerated or otherwise) any more than a tuple needs a name? A nameless enum is basically a square circle. An enum is a nominal type, which entails that it is characterized by the existence of its name. Two enums with the exact same internal shape are different if their names are different, and two enums with different internal shapes but the same name will trigger a compiler type redefinition error because the name is what identities the enum. Would those who dislike ad hoc enums argue that this also shouldn't be allowed:    func foo(bar: (x: Int, y: Int)) {}    let t: (x: Int, y: Int) = (x: 5, y: 5)If someone writes `(.fit | .fill)` (or whatever the hypothetical syntax might be), that should just *be* the type the same way that `(x: Int, y: Int)` is a type without a name, and that type can be used in argument lists, variables, or whatever. There shouldn't be any worry about declarations across multiple functions colliding or being incompatible any more than we would worry about two functions declaring arguments of type `(x: Int, y: Int)` would collide or be incompatible.One side of ad hoc enums that I'd like to see explored is that, by being unnamed, they're basically anonymous finite sets and we could apply well-defined subset relationships to them: in other words, we could consider allowing this:    func foo(bar: (.fit | .fill)) {      baz(bar: bar)    }    func baz(bar: (.fit | .fill | .florp) { ... }In other words, an ad hoc enum T can be used wherever an ad hoc enum U is expected if T ⊆ U.On Wed, Jun 1, 2016 at 1:43 PM L. Mihalkovic via swift-evolution  wrote:

> On Jun 1, 2016, at 6:51 PM, Vladimir.S  wrote:
>
> Yes, I also can support the idea of autogenerated type name (like Enum_fit_OR_fill) as long as it allows to do all the things we are discussing here: declare (.fit|.fill) in function, use .fit on calling side, use (.fit|.fill) to declare temporary variable of type compatible with such function parameter etc.
>

It all works because the compiler is just being a thoughless scribe that just writes the standard enum we don't bother to write ourselves. Because the heuristic is simple and straightforward then it is predictible. The enum can be used with its long name be ause it is a real enum. And writing the short form of it also works because the compiler knowns uniquely what the long name is everytime it runs into the short name.


> But how do you suggest to define a type of such function in `typealias` for example? i.e. for func my(option: (.fit|.fill) {..}
>
> typealias MyFunc = ((.fit|.fill)) -> ()
> or as
>
> typealias MyFunc = (Enum_fit_OR_fill) -> ()
>

Ideally there is no difference whatsoever, there is a single enum, it is produced at the module level, and it has the long form name.

There can be rules that would prevent us from doing that with externally visible APIs, if the core team fuges that we should take the time to write our enums manually and cleanly to make them visible to the world, but it is not a necessary rule.


>
> But I still can't support the idea of limiting the usage of such enums - i.e. "To deal with milti site definition, the compiler would simply flag a error/warning, or be silent in the presence of a new annotation:". I really think we need then introduce the same rule for tuples - so no one can use the same tuple declaration in function - they then should declare separate struct type or use @something for such functions. Nobody wants such rule for tuples.
>

Multi site thing is not a limitation... Is is a proposed rule to say that we are able to be 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Vladimir.S via swift-evolution

> I was referring to the subtle distinction between creating an Int32 from a
> literal (the first one) and creating an Int from a literal and then
> coercing it to Int32 (the second one).

I understand the difference and just trying to find out if that 
behavior(Int32(x) vs x as Int32)  could really produce problems at run-time 
as was stated in initial message for this proposal.


On 03.06.2016 0:57, Tony Allevato wrote:

On Thu, Jun 2, 2016 at 2:38 PM Vladimir.S > wrote:

What is wrong with your examples?

var x1: Int32 = 0
var x2 = Int32(0)
print(x1.dynamicType, x2.dynamicType) // Int32 Int32


I was referring to the subtle distinction between creating an Int32 from a
literal (the first one) and creating an Int from a literal and then
coercing it to Int32 (the second one). So, I was pondering whether this was
the cause of some complex expressions I've had problems with in the past.
However, looking at the specific code, it looks like I had the *opposite*
problem.

This expression is evaluated quickly in Swift 2.2:

let value = Int64((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
(0x3b << 28) |
  (0x56 << 35) | (0x00 << 42) | (0x05 << 49) | (0x26 << 56) | (0x01 << 63))

This one errors out with "expression was too complex to be solved in
reasonable time":

let value: Int64 = (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21)
| (0x3b << 28) |
  (0x56 << 35) | (0x00 << 42) | (0x05 << 49) | (0x26 << 56) | (0x01 << 63)




On 03.06.2016 0:17, Tony Allevato via swift-evolution wrote:
> +1. As someone who thought "var x: Int32 = 0" and "var x = Int32(0)" were
> equivalent, this is very good to know (and very good to fix).
>
> I'm starting to wonder now if some of the times I've hit "expression was
> too complex" errors with large 64-bit multi-term expressions with
literals
> were caused by coercions happening that I didn't realize.
>
>
> On Thu, Jun 2, 2016 at 9:31 AM John McCall via swift-evolution
> 
>>
wrote:
>
> The official way to build a literal of a specific type is to
write the
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
>
> Nonetheless, programmers often try the following:
> UInt16(7)
>
> Unfortunately, this does /not/ attempt to construct the value
using the
> appropriate literal protocol; it instead performs overload resolution
> using the standard rules, i.e. considering only single-argument
> unlabelled initializers of a type which conforms to
> IntegerLiteralConvertible.  Often this leads to static
ambiguities or,
> worse, causes the literal to be built using a default type (such as
> Int); this may have semantically very different results which are
only
> caught at runtime.
>
> In my opinion, using this initializer-call syntax to build an
> explicitly-typed literal is an obvious and natural choice with
several
> advantages over the "as" syntax.  However, even if you disagree, it's
> clear that programmers are going to continue to independently try to
> use it, so it's really unfortunate for it to be subtly wrong.
>
> Therefore, I propose that we adopt the following typing rule:
>
>   Given a function call expression of the form A(B) (that is, an
> /expr-call/ with a single, unlabelled argument) where B is
> an /expr-literal/ or /expr-collection/, if A has type T.Type for some
> type T and there is a declared conformance of T to an appropriate
> literal protocol for B, then the expression is always resolves as a
> literal construction of type T (as if the expression were written
"B as
> A") rather than as a general initializer call.
>
> Formally, this would be a special form of the argument conversion
> constraint, since the type of the expression A may not be immediately
> known.
>
> Note that, as specified, it is possible to suppress this typing
rule by
> wrapping the literal in parentheses.  This might seem distasteful; it
> would be easy enough to allow the form of B to include extra
> parentheses.  It's potentially useful to have a way to suppress this
> rule and get a normal construction, but there are several other
ways of
> getting that effect, such as explicitly typing the literal argument
> (e.g. writing "A(Int(B))").
>
> A conditional conformance counts as a declared conformance even
if the
> generic arguments are known to not satisfy the conditional
> 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread L. Mihalkovic via swift-evolution

> On Jun 2, 2016, at 6:08 PM, John McCall via swift-evolution 
>  wrote:
> 
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.

Looking transversally at all literal protocols as this proposes to operates 
reminds me that the knowledge that a protocol has the right semantic is based 
on a convention, rather than on conformance. Would it be conceibable to look 
into something like the following, that all others would specialize.

protocol LiteralConvertible {}

This might offer a stronger identification than the name. It might also be 
interesting to define an associated type, but that would exclude 
NilLiteralConvertible.

Note: as compiler expert, I would appreciate your thinking on the notion of 
formally expressing what might otherwise be a known strong semantic 
relationship. Is there any incentive to pursue, known disavantages, ...


> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect, such 
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
> 
> A conditional conformance counts as a declared conformance even if the 
> generic arguments are known to not satisfy the conditional conformance.  This 
> permits the applicability of the rule to be decided without having to first 
> decide the type arguments, which greatly simplifies the type-checking problem 
> (and may be necessary for soundness; I didn't explore this in depth, but it 
> certainly feels like a very nasty sort of dependence).  We could potentially 
> weaken this for cases where A is a direct type reference with bound 
> parameters, e.g. Foo([]) or the same with a typealias, but I think 
> there's some benefit from having a simpler specification, both for the 
> implementation and for the explicability of the model.
> 
> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Vladimir.S via swift-evolution
> Like I said, the standard library and compiler conspire to make sure 
that easy cases like this are caught at compile time, but that would not 
help non-standard types that conform to IntegerLiteralConvertible.

>
> Also, even for standard types, the syntax only works statically if the 
literal fits in the range of Int, which may not be a superset of the 
desired type.  For example, UInt64(0x100) would not work on a 
32-bit platform.  It is diagnosed statically, however.


I believe I understand the problem you described, but I really can't figure 
out how this problem can produce a unexpected behavior and run-time errors, 
as was stated in your initial message. So, this is why I was asking for any 
code that can prove this. The example with UInt64(0x100) on 32bit 
systems will raise error at _compilation_ time. Could someone provide any 
code to illustrate the possible problems at run-time? I understand that we 
need to fix this somehow in any case.


For others, who not really understand the issue(probably I'm not the one, I 
hope ;-) ) : If we'd have Int128 type, we can't create an instance of it in 
this form:

let x = Int128(92233720368547758070)
(92233720368547758070 == Int.max * 10)
as '92233720368547758070' literal will be treated always as of Int type.

In more general description, the difference between UIntN(xxx) and yyy as 
UIntN is that xxx will be treated as Int(so it can't be greater than 
Int.max for example) then this Int will be sent to UIntN(:Int) initializer 
and then we have UIntN as a result of call to initializer; yyy will be 
treated as UIntN literal just by its definition, no calling to any 
initializer, yyy can be of any value allowed for UIntN.


But again, could someone help with examples when this can produce problems 
at run-time?


On 03.06.2016 1:12, John McCall wrote:

On Jun 2, 2016, at 2:36 PM, Vladimir.S  wrote:
Well, I understand that it seems like there is some problem with UIntN() 
initialization, but can't find any simple code that will demonstrate this..

All below works as expected:

var x1: Int32 = 0
var x2 = Int32(0)

print(x1.dynamicType, x2.dynamicType) // Int32 Int32

// integer overflows when converted from 'Int' to 'UInt16'
//var x = UInt16(100_000)
//var x = UInt16(-10)

// negative integer cannot be converted to unsigned type 'UInt64'
// var x = UInt64(-1)

So, what code will produce some unexpected behavior / error at runtime?


Like I said, the standard library and compiler conspire to make sure that easy 
cases like this are caught at compile time, but that would not help 
non-standard types that conform to IntegerLiteralConvertible.

Also, even for standard types, the syntax only works statically if the literal 
fits in the range of Int, which may not be a superset of the desired type.  For 
example, UInt64(0x100) would not work on a 32-bit platform.  It is 
diagnosed statically, however.

John.



On 03.06.2016 0:25, John McCall wrote:

On Jun 2, 2016, at 1:56 PM, Vladimir.S  wrote:

Often
this leads to static ambiguities or, worse, causes the literal to be built
using a default type (such as Int); this may have semantically very
different results which are only caught at runtime.


Seems like I'm very slow today.. Could you present a couple of examples where 
such initialization(like UInt16(7)) can produce some unexpected behavior / 
error at runtime?


UIntN has unlabeled initializers taking all of the standard integer types, 
including itself.  The literal type will therefore get defaulted to Int.  The 
legal range of values for Int may not be a superset of the legal range of 
values for UIntN.  If the literal is in the legal range for an Int but not for 
the target type, this might trap at runtime.  Now, for a built-in integer type 
like UInt16, we will recognize that the coercion always traps and emit an error 
at compile-time, but this generally won't apply to other types.

John.



On 02.06.2016 19:08, John McCall via swift-evolution wrote:

The official way to build a literal of a specific type is to write the
literal in an explicitly-typed context, like so:
  let x: UInt16 = 7
or
  let x = 7 as UInt16

Nonetheless, programmers often try the following:
  UInt16(7)

Unfortunately, this does /not/ attempt to construct the value using the
appropriate literal protocol; it instead performs overload resolution using
the standard rules, i.e. considering only single-argument unlabelled
initializers of a type which conforms to IntegerLiteralConvertible.  Often
this leads to static ambiguities or, worse, causes the literal to be built
using a default type (such as Int); this may have semantically very
different results which are only caught at runtime.

In my opinion, using this initializer-call syntax to build an
explicitly-typed literal is an obvious and natural choice with several
advantages over the "as" syntax.  However, even if you disagree, it's clear
that programmers are going to 

Re: [swift-evolution] Working with enums by name

2016-06-02 Thread Leonardo Pessoa via swift-evolution
Patrick, I never said the order of the enum was intrinsic. If the offset of the 
case were the truth of the enum as you said enums would be ordinal types and 
you could do tests like "Planet.Mercury > Planet.Venus" without any extra code. 
But enums are nominal types not ordinal types so you can only distinguish the 
different values but they have no particular order or any other property. Two 
simple examples of nominal types are colours and cardinal points. Do they have 
any particular order? That's how enums are implemented in Swift (as a nominal 
type) and that's another reason why working with case names makes even more 
sense.

L

-Original Message-
From: "Patrick Smith" 
Sent: ‎02/‎06/‎2016 11:18 PM
To: "Leonardo Pessoa" 
Cc: "Brent Royal-Gordon" ; "swift-evolution" 

Subject: Re: [swift-evolution] Working with enums by name

>From what I understand, enums normally are represented internally by an offset 
>— that is their truth. With RawRepresentable enums, you are saying “no, I want 
>the truth to be something else”. But it seems that they are still represented 
>internally by an offset, so you can’t reorder a RawRepresentable enum’s cases 
>and maintain ABI compatibility either.


So what you are saying about the order of cases being an intrinsic part of an 
enum does make sense. I’m not sure if can still lead to confusing / fragile 
code though.


Patrick




On 2 Jun 2016, at 10:17 PM, Leonardo Pessoa  wrote:


There are several ways to solve this, which IMO is a basic functionality of 
enums, writing code that is currently possible and works. But that's the issue, 
you still have to write code to have a basic functionally. I don't remember not 
being able to do this out-of-the-box in any language I worked with.

L


From: Patrick Smith
Sent: ‎02/‎06/‎2016 02:07 AM
To: Brent Royal-Gordon
Cc: Leonardo Pessoa; swift-evolution
Subject: Re: [swift-evolution] Working with enums by name


Great points Brent. I think the ValuesEnumerable method would be the most 
straight forward. Also, the number of cases are likely only going to be in 
range of 6–20, so iterating would be fine I think. People can create something 
like `Dictionary(Planet.allValues.enumerated().lazy.map{ ($1, $0) })` (I think 
that’s right) if they really need.


> On 2 Jun 2016, at 2:40 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> Or the `ValuesEnumerable` proposal would give you a convenient, though 
> slightly slow, way to do two-way lookup by order:
> 
> enum Planet: String, ValuesEnumerable {
> var order: Int {
> return Planet.allValues.index(of: self)!
> }
> init(order: Int) {
> self = Planet.allValues[order]
> }
> case mercury, venus, …
> }___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Working with enums by name

2016-06-02 Thread Patrick Smith via swift-evolution
>From what I understand, enums normally are represented internally by an offset 
>— that is their truth. With RawRepresentable enums, you are saying “no, I want 
>the truth to be something else”. But it seems that they are still represented 
>internally by an offset, so you can’t reorder a RawRepresentable enum’s cases 
>and maintain ABI compatibility either.

So what you are saying about the order of cases being an intrinsic part of an 
enum does make sense. I’m not sure if can still lead to confusing / fragile 
code though.

Patrick


> On 2 Jun 2016, at 10:17 PM, Leonardo Pessoa  wrote:
> 
> There are several ways to solve this, which IMO is a basic functionality of 
> enums, writing code that is currently possible and works. But that's the 
> issue, you still have to write code to have a basic functionally. I don't 
> remember not being able to do this out-of-the-box in any language I worked 
> with.
> 
> L
> From: Patrick Smith 
> Sent: ‎02/‎06/‎2016 02:07 AM
> To: Brent Royal-Gordon 
> Cc: Leonardo Pessoa ; swift-evolution 
> 
> Subject: Re: [swift-evolution] Working with enums by name
> 
> Great points Brent. I think the ValuesEnumerable method would be the most 
> straight forward. Also, the number of cases are likely only going to be in 
> range of 6–20, so iterating would be fine I think. People can create 
> something like `Dictionary(Planet.allValues.enumerated().lazy.map{ ($1, $0) 
> })` (I think that’s right) if they really need.
> 
> 
> > On 2 Jun 2016, at 2:40 PM, Brent Royal-Gordon via swift-evolution 
> >  wrote:
> > 
> > Or the `ValuesEnumerable` proposal would give you a convenient, though 
> > slightly slow, way to do two-way lookup by order:
> > 
> > enum Planet: String, ValuesEnumerable {
> > var order: Int {
> > return Planet.allValues.index(of: self)!
> > }
> > init(order: Int) {
> > self = Planet.allValues[order]
> > }
> > case mercury, venus, …
> > }
> 

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

>> On Jun 2, 2016, at 6:51 PM, John McCall via swift-evolution 
>>  wrote:
>> 
>> On Jun 2, 2016, at 4:33 PM, Xiaodi Wu  wrote:
>> The IntegerLiteral type idea might be worth exploring. It does seem to 
>> provide some additional consistency. For example, wasn't it clarified on 
>> this list just recently that literals don't have a type and adopt one based 
>> on context? It'd be nice to point out that 42 is an IntegerLiteral when 
>> explaining that it's not an Int.
> 
> I think that's a very promising way of thinking about literals.  Writing a 
> literal creates a notional value whose type is the informal, infinite-precise 
> type of all integer/FP/collection/etc. literals, which (1) can be implicitly 
> converted to any type that implements the appropriate protocol and (2) in 
> fact *must* be converted to some such type (possibly the default type for 
> that literal) in order for the code to be executable.  You can then think 
> about this proposal as saying that an explicit conversion from that informal 
> type to a literal-convertible type follows the same path as an implicit 
> conversion would have.

It sounds like the reason you don't want to remove the label is because it 
distinguishes the literal initializer and you don't want it called with a 
variable accidentally right?  

What if we do something like this:

init(_ value: IntegerLiteralType, literal: IntegerLiteral = #literal)

The idea here is that the IntegerLiteral type and friends are special types 
that have no members and cannot be used except by the literal convertible 
protocols and their conformances.  There is nothing you can do with the value 
at all.  

The trick is that by defaulting it to #literal we are indicating the compiler 
synthesizes the logical value, as with #file, #line, etc.  The compiler would 
refuse to synthesize this value when a literal is not used.  This means it is 
never selected when the user provides a variable to a converting initializer.  
If an independent initializer accepting a value of the same type also exists 
that would be selected.  However, when a literal *is* used and the type 
conforms to the relevant literal convertible protocol the compiler always 
synthesized the value making it always the most specific overload.

Of course no runtime value would actually exist.  This is just a logical value 
marking the fact that a literal was used to call the initializer.  

This approach solves the same problem while retaining semantic consistency with 
the language (no label elision or short circuit of overload resolution).  The 
magic is arguably a lot more restrained - types for which values can only be 
supplied by the compiler.  We could artificially restrict usage of these types 
if we wanted to, but we wouldn't have to.  Nothing could be accomplished by 
using the types anywhere else so nobody do so and it wouldn't be actively 
harmful to allow them to be used anywhere other types can be used.  Only the 
ability to create values of the type needs to be restricted and we can already 
write types like that by marking the initializers private.

Any thoughts on this approach?

> 
> John.
> 
>> 
>>> On Thu, Jun 2, 2016 at 18:22 Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> > So, you think that this syntax is enticing to new developers who 
>>> > naturally think that the feature works the way that I'm proposing it 
>>> > should work, and you think that the right solution is to make the syntax 
>>> > illegal so that you can more conveniently tell them it doesn't work that 
>>> > way? :)
>>> 
>>> I think the difference between a cast (which merely reinterprets a value as 
>>> a compatible type) and a fullwidth conversion (which creates a similar 
>>> instance of an incompatible type) is very important to understanding how to 
>>> write Swift, and we shouldn't muddy the waters by creating a magic syntax.
>>> 
>>> > You can still tell them that it's a struct and you're calling an 
>>> > initializer on it; it's just that the initializer chosen is the special 
>>> > literal initializer because the argument is a literal.
>>> 
>>> If you're planning to change `IntegerLiteralConvertible` and friends to 
>>> require a fullwidth conversion initializer like `init(_ value: 
>>> IntegerLiteralType)`, then this is simply an overload resolution rule. In 
>>> that case, I think your proposal is fine.
>>> 
>>> But if you're going to call `init(integerLiteral:)` like it's `init(_:)`, I 
>>> don't think that's a good idea. Parameter labels are supposed to be 
>>> significant; we don't want to lose that.
>>> 
>>> --
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> 

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 4:57 PM, Sean Heber  wrote:
> 
> This might be silly, but what if there were a struct with all of the relevant 
> fields (not sure what the best name would be):
> 
> struct MemoryLayout {
>  let size: Int
>  let alignment: Int
>  let stride: Int
> // etc
> }
> 
> Then you’d only maybe need two functions:
> 
> memoryLayout(of:) and memoryLayout(ofType:)

I like this much better than individual functions.  I do not like the next idea 
that considers using a property.  We moved away from that approach with 
dynamicType and should stick with that direction.  It's not worth bringing up 
that debate again IMO.

> 
> Or perhaps just a single property on all types named “memoryLayout” (or 
> whatever) that returns the MemoryLayout struct:
> 
> Int.memory.size
> type(of: 42).memoryLayout.size
> // etc
> 
> Or just a single property on UnsafePointer if we went that route..
> 
> It seems like this sort of approach would keep namespace pollution down, at 
> least?
> 
> l8r
> Sean
> 
> 
>>> On Jun 2, 2016, at 4:55 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
>>> I don't disagree with the points you make.  But one can argue that this is 
>>> a good thing.  It calls attention to code that requires extra attention and 
>>> care.  In some ways this is similar to 'UnsafeMutablePointer' vs '*T'.  
>>> Verbosity was a deliberate choice in that case.
>> 
>> You know...rather than introducing a new type like MemoryLayout, would it 
>> make sense to do this with static properties on UnsafePointer?
>> 
>>UnsafePointer.pointeeSize
>>UnsafePointer.pointeeAlignment
>>UnsafePointer.pointeeSpacing
>> 
>> If you need this information, 90% of the time you're probably using 
>> UnsafePointer or one of its friends, right?
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
>> ___
>> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 4:47 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Isn't this the same argument for .dynamicType over type(of:) though?
> 
> Given that that debate has been settled in favor of the latter, I think the 
> question today is how best to come up with a consistent scheme.
> 
> Earlier in this conversation, it was pointed out (by Matt, I think?) that one 
> key advantage of type(of:) is that it takes on a syntax that is actually 
> possible to write in Swift, since one cannot extend Any.

Yep, IMO we should stick with the strategy that if something *looks* like a 
user-definable construct it should be possible to at least write the 
declaration even if it wouldn't be possible to implement.  That rules out 
static or instance properties or methods that apply to all types.

> 
> If we take this principle to its logical conclusion, properties (of a type or 
> instance) which apply to Any should be global functions.
> 
>> On Thu, Jun 2, 2016 at 16:26 Russ Bishop  wrote:
>> 
>>> On Jun 2, 2016, at 2:05 PM, Xiaodi Wu  wrote:
>>> 
>>> 
>>> In the earlier conversation, it was pointed out (by Dave A., I think?) that 
>>> examples such as Array.size show how this solution can get confusing. And 
>>> even though there aren't fixed-length arrays in Swift, those may come one 
>>> day, making the syntax even more confusing.
>> 
>> 
>> Array.count is a function taking an instance; I’m not sure I agree it would 
>> be terribly confusing… then again I run in Xcode with the quick help pane 
>> open so I see the doc comments for every type, property, and function as I 
>> move around the code. It’s quite handy :)
>> 
>> I could see including memory in the name (or something similar) if we want 
>> to be extra clear about it.
>> 
>> Int.memorySize
>> Int.memoryAlignment
>> 
>> 
>> Ultimately the type’s size in memory is a property of the type so it seems 
>> clear that is where it belongs (being careful not to steal too much of the 
>> namespace of course).
>> 
>> 
>> Russ
> ___
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Xiaodi Wu via swift-evolution
As I said above, I disagree. Unsafe things should have names that call
attention to themselves. Safe things should not, *especially* if they're
unsafe-adjacent. It's not useful in a line of code to have every part of it
competing for your attention merely because they're typically used in
conjunction with an unsafe operation. It's essential that the unsafe
operation itself stand out.

Ever see a doctor clicking their mouse faster than a video gamer to dismiss
20 warnings in a row on a computer screen? That's what happens when
everything unsafe-adjacent calls attention to itself.
On Thu, Jun 2, 2016 at 19:53 Matthew Johnson  wrote:

>
>
> Sent from my iPad
>
> On Jun 2, 2016, at 4:25 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On the other hand, on its own sizeof() is not unsafe, and so the argument
> that it should be longer to call attention to itself (by analogy with
> UnsafePointer) isn't quite apt.
>
>
> These operations aren't themselves unsafe.  But they are low level details
> that are not useful unless you are doing something that requires special
> care.  A name that stands out more calls attention to the surrounding
> code.  That is a good thing IMO.
>
>
> And I'm not sure we really want to encourage anyone else to be defining a
> global function named size(of:) anyway, so I wouldn't consider vacating
> that name for end-user purposes to be a meaningful positive.
> On Thu, Jun 2, 2016 at 16:15 Tony Allevato  wrote:
>
>> Given that these are fairly low-level values with very specialized uses,
>> I definitely agree that they should be somehow namespaced in a way that
>> doesn't cause us to make very common words unusable for our users.
>>
>> Even size(of:) seems more general to me than I'd like. I'd like to see
>> the word "memory" as part of the name somehow, whether it's a wrapping type
>> or a function prefix of some sort. These values are specialized; we don't
>> need to optimize typing them, IMO.
>>
>> On Thu, Jun 2, 2016 at 2:06 PM Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> On Thu, Jun 2, 2016 at 3:46 PM, John McCall via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 On Jun 2, 2016, at 1:43 PM, Russ Bishop  wrote:

 On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution <
 swift-evolution@swift.org> wrote:

 I still think the value-based APIs are misleading and that it would be
 better to ask people to just use a type explicitly.

 John.



 I agree; in fact *why aren’t these properties on the type itself*? The
 type is what matters; why can’t the type just tell me it’s size?
 Having free functions or magic operators seems to be another holdover
 from C.


 Int.size
 Int.alignment
 Int.spacing

 let x: Any = 5
 type(of: x).size


 The compiler should be able to statically know the first three values
 and inline them. The second is discovering the size dynamically.


 Two reasons.  The first is that this is a user-extensible namespace via
 static members, so it's somewhat unfortunate to pollute it with names from
 the library.  The second is that there's currently no language mechanism
 for adding a static member to every type, so this would have to be
 built-in.  But I agree that in the abstract a static property would be
 preferable.

>>>
>>> In the earlier conversation, it was pointed out (by Dave A., I think?)
>>> that examples such as Array.size show how this solution can get confusing.
>>> And even though there aren't fixed-length arrays in Swift, those may come
>>> one day, making the syntax even more confusing.
>>>
>>> ___
>>> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 4:25 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On the other hand, on its own sizeof() is not unsafe, and so the argument 
> that it should be longer to call attention to itself (by analogy with 
> UnsafePointer) isn't quite apt.

These operations aren't themselves unsafe.  But they are low level details that 
are not useful unless you are doing something that requires special care.  A 
name that stands out more calls attention to the surrounding code.  That is a 
good thing IMO.

> 
> And I'm not sure we really want to encourage anyone else to be defining a 
> global function named size(of:) anyway, so I wouldn't consider vacating that 
> name for end-user purposes to be a meaningful positive.
>> On Thu, Jun 2, 2016 at 16:15 Tony Allevato  wrote:
>> Given that these are fairly low-level values with very specialized uses, I 
>> definitely agree that they should be somehow namespaced in a way that 
>> doesn't cause us to make very common words unusable for our users.
>> 
>> Even size(of:) seems more general to me than I'd like. I'd like to see the 
>> word "memory" as part of the name somehow, whether it's a wrapping type or a 
>> function prefix of some sort. These values are specialized; we don't need to 
>> optimize typing them, IMO.
>> 
>>> On Thu, Jun 2, 2016 at 2:06 PM Xiaodi Wu via swift-evolution 
>>>  wrote:
>> 
>>> On Thu, Jun 2, 2016 at 3:46 PM, John McCall via swift-evolution 
>>>  wrote:
>> On Jun 2, 2016, at 1:43 PM, Russ Bishop  wrote:
>> On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution 
>>  wrote:
>> 
>> I still think the value-based APIs are misleading and that it would be 
>> better to ask people to just use a type explicitly.
>> 
>> John.
> 
> 
> I agree; in fact why aren’t these properties on the type itself? The type 
> is what matters; why can’t the type just tell me it’s size? 
> Having free functions or magic operators seems to be another holdover 
> from C. 
> 
> 
> Int.size
> Int.alignment
> Int.spacing
> 
> let x: Any = 5
> type(of: x).size
> 
> 
> The compiler should be able to statically know the first three values and 
> inline them. The second is discovering the size dynamically.
 
 Two reasons.  The first is that this is a user-extensible namespace via 
 static members, so it's somewhat unfortunate to pollute it with names from 
 the library.  The second is that there's currently no language mechanism 
 for adding a static member to every type, so this would have to be 
 built-in.  But I agree that in the abstract a static property would be 
 preferable.
>>> 
>>> In the earlier conversation, it was pointed out (by Dave A., I think?) that 
>>> examples such as Array.size show how this solution can get confusing. And 
>>> even though there aren't fixed-length arrays in Swift, those may come one 
>>> day, making the syntax even more confusing.
>>> 
>> 
>>> ___
>>> 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] [Pitch] #warning

2016-06-02 Thread Harlan Haskins via swift-evolution
Based on the feedback from this list, I’ve submitted a revised proposal as PR 
#353.

https://github.com/apple/swift-evolution/pull/353

Thanks,
Harlan

> On Jun 1, 2016, at 9:25 PM, Ben Langmuir via swift-evolution 
>  wrote:
> 
>> 
>> On Jun 1, 2016, at 10:54 AM, Jordan Rose via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On May 29, 2016, at 13:20, Chris Lattner via swift-evolution 
>>> > wrote:
>>> 
 On May 29, 2016, at 12:58 PM, Erica Sadun > wrote:
 One could make a weak argument that #warning/#error/#message make a nice 
 family of flexible alerts
 just because they're kind of what we're used to already. 
>>> 
>>> Right: it isn’t a bad thing at all, but it is certainly the case that 
>>> people often request adding features to Swift that they see in other 
>>> languages.  Our task is to look at whether the problem is real and 
>>> significant enough to solve, and if the proposal solves it in the best 
>>> possible way consistent with the rest of Swift.
>>> 
>>> An similar example is "#pragma mark”.  Instead of introducing language 
>>> support for it, we codified a comment marker (since it is semantically 
>>> identical to a comment).  Xcode picks it up and does the right thing, and I 
>>> think it has worked out well.
>>> 
>>> As to #warning, Swift’s use of warnings are significant different than the 
>>> use in C.  In C compilers, many of the warnings produced *should* be 
>>> errors, but can’t be because that effects language conformance and could 
>>> break a large body of code.  Swift doesn’t have this problem, so it treats 
>>> warnings as “things that should be addressed before you commit your patch, 
>>> but shouldn’t block a build if (e.g.) you’re in the middle of a big 
>>> refactoring”.  For example, an unused variables is a warning in Swift.
>> 
>> This sounds exactly like what I’d use #warning for. “I’m in the middle of a 
>> big refactoring, and I haven’t gotten to this part yet; let me put a warning 
>> in so I can test the other part but won’t forget to come back to it.” It 
>> might also make sense for doing a series of commits on a branch when you 
>> need to fix something before merging back to trunk.
> 
> +1 to the proposal, and Jordan has captured my feelings very well here so I 
> won’t repeat him.
> 
>> 
>> I think it is important for such diagnostics to show up in compilation, not 
>> just in IDEs, especially with people using the Swift Package Manager. We 
>> could have the compiler parse every comment looking for TODOs and FIXMEs by 
>> default, and emit those as warnings, but I’d want to find out if that 
>> creates a noticeable difference in parsing time. (It also seems odd that 
>> comments would be controlled by #if, but maybe that’s silly.)
>> 
>> +1 to the proposal from me, though I agree with Brent that the parentheses 
>> don’t feel right. This is closer to #if and #setline than #available and 
>> #selector.
>> 
>> Jordan
>> 
>> P.S. #error is also interesting, but more for “things that should never 
>> happen” (like the else branch of a platform check), which makes it a bit 
>> less important. #info/#message can be useful but I’d like to see a concrete 
>> case before designing it.
>> 
>> 
>> ___
>> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 4:33 PM, Xiaodi Wu  wrote:
> The IntegerLiteral type idea might be worth exploring. It does seem to 
> provide some additional consistency. For example, wasn't it clarified on this 
> list just recently that literals don't have a type and adopt one based on 
> context? It'd be nice to point out that 42 is an IntegerLiteral when 
> explaining that it's not an Int.

I think that's a very promising way of thinking about literals.  Writing a 
literal creates a notional value whose type is the informal, infinite-precise 
type of all integer/FP/collection/etc. literals, which (1) can be implicitly 
converted to any type that implements the appropriate protocol and (2) in fact 
*must* be converted to some such type (possibly the default type for that 
literal) in order for the code to be executable.  You can then think about this 
proposal as saying that an explicit conversion from that informal type to a 
literal-convertible type follows the same path as an implicit conversion would 
have.

John.

> 
> On Thu, Jun 2, 2016 at 18:22 Brent Royal-Gordon via swift-evolution 
> > wrote:
> > So, you think that this syntax is enticing to new developers who naturally 
> > think that the feature works the way that I'm proposing it should work, and 
> > you think that the right solution is to make the syntax illegal so that you 
> > can more conveniently tell them it doesn't work that way? :)
> 
> I think the difference between a cast (which merely reinterprets a value as a 
> compatible type) and a fullwidth conversion (which creates a similar instance 
> of an incompatible type) is very important to understanding how to write 
> Swift, and we shouldn't muddy the waters by creating a magic syntax.
> 
> > You can still tell them that it's a struct and you're calling an 
> > initializer on it; it's just that the initializer chosen is the special 
> > literal initializer because the argument is a literal.
> 
> If you're planning to change `IntegerLiteralConvertible` and friends to 
> require a fullwidth conversion initializer like `init(_ value: 
> IntegerLiteralType)`, then this is simply an overload resolution rule. In 
> that case, I think your proposal is fine.
> 
> But if you're going to call `init(integerLiteral:)` like it's `init(_:)`, I 
> don't think that's a good idea. Parameter labels are supposed to be 
> significant; we don't want to lose that.
> 
> --
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Xiaodi Wu via swift-evolution
The IntegerLiteral type idea might be worth exploring. It does seem to
provide some additional consistency. For example, wasn't it clarified on
this list just recently that literals don't have a type and adopt one based
on context? It'd be nice to point out that 42 is an IntegerLiteral when
explaining that it's not an Int.

On Thu, Jun 2, 2016 at 18:22 Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:

> > So, you think that this syntax is enticing to new developers who
> naturally think that the feature works the way that I'm proposing it should
> work, and you think that the right solution is to make the syntax illegal
> so that you can more conveniently tell them it doesn't work that way? :)
>
> I think the difference between a cast (which merely reinterprets a value
> as a compatible type) and a fullwidth conversion (which creates a similar
> instance of an incompatible type) is very important to understanding how to
> write Swift, and we shouldn't muddy the waters by creating a magic syntax.
>
> > You can still tell them that it's a struct and you're calling an
> initializer on it; it's just that the initializer chosen is the special
> literal initializer because the argument is a literal.
>
> If you're planning to change `IntegerLiteralConvertible` and friends to
> require a fullwidth conversion initializer like `init(_ value:
> IntegerLiteralType)`, then this is simply an overload resolution rule. In
> that case, I think your proposal is fine.
>
> But if you're going to call `init(integerLiteral:)` like it's `init(_:)`,
> I don't think that's a good idea. Parameter labels are supposed to be
> significant; we don't want to lose that.
>
> --
> Brent Royal-Gordon
> Architechies
>
> ___
> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread T.J. Usiyan via swift-evolution
+1
It has nagged at me that this can happen even though I understood *why* it
happens.

On Thu, Jun 2, 2016 at 6:22 PM, John McCall via swift-evolution <
swift-evolution@swift.org> wrote:

> > On Jun 2, 2016, at 2:43 PM, Brent Royal-Gordon 
> wrote:
> >> In my opinion, using this initializer-call syntax to build an
> explicitly-typed literal is an obvious and natural choice with several
> advantages over the "as" syntax.  However, even if you disagree, it's clear
> that programmers are going to continue to independently try to use it, so
> it's really unfortunate for it to be subtly wrong.
> >
> > I've seen developers do this; in one memorable case, it resulted in
> Swift taking a ridiculously long time to typecheck an expression, since the
> seemingly pinned-down types of the literals had actually become *more*
> ambiguous, not less.
>
> Yes, this would also tend to improve compile times, since currently we end
> up generating a massively-ambiguous constraint system which must be
> resolved by type defaulting.  That's not really why I'm proposing this,
> though.
>
> > However, it's not difficult to teach developers to use `as`. Usually
> what's happening is that their mental model of the language is wrong: they
> think of `UInt16(foo)` as a cast to a primitive type, and are surprised to
> learn that it's actually an initializer on a struct and they're
> initializing an instance. Learning this helps them understand how the
> language works, what the difference is between initializers and `as`, and
> how they can write the same things they see in the standard library types.
>
> So, you think that this syntax is enticing to new developers who naturally
> think that the feature works the way that I'm proposing it should work, and
> you think that the right solution is to make the syntax illegal so that you
> can more conveniently tell them it doesn't work that way? :)
>
> You can still tell them that it's a struct and you're calling an
> initializer on it; it's just that the initializer chosen is the special
> literal initializer because the argument is a literal.
>
> John.
>
>
>
> >
> > I think *actually* turning this into magic would be counterproductive.
> The better solution is to make the compiler replace me in that story, by
> having it emit a warning with a fix-it. It keeps initializer calls meaning
> exactly what they say. (And it doesn't require an evolution proposal to do,
> since you can add a warning with a mere bug.)
> >
> >   UInt16(42)
> >   ^~ ^~
> >   Use of initializer with integer literal does not cast '42' to
> 'UInt16'
> >   Fix-It: Replace with '42 as UInt16'
> >
> > --
> > Brent Royal-Gordon
> > Architechies
> >
>
> ___
> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Brent Royal-Gordon via swift-evolution
> So, you think that this syntax is enticing to new developers who naturally 
> think that the feature works the way that I'm proposing it should work, and 
> you think that the right solution is to make the syntax illegal so that you 
> can more conveniently tell them it doesn't work that way? :)

I think the difference between a cast (which merely reinterprets a value as a 
compatible type) and a fullwidth conversion (which creates a similar instance 
of an incompatible type) is very important to understanding how to write Swift, 
and we shouldn't muddy the waters by creating a magic syntax.

> You can still tell them that it's a struct and you're calling an initializer 
> on it; it's just that the initializer chosen is the special literal 
> initializer because the argument is a literal.

If you're planning to change `IntegerLiteralConvertible` and friends to require 
a fullwidth conversion initializer like `init(_ value: IntegerLiteralType)`, 
then this is simply an overload resolution rule. In that case, I think your 
proposal is fine.

But if you're going to call `init(integerLiteral:)` like it's `init(_:)`, I 
don't think that's a good idea. Parameter labels are supposed to be 
significant; we don't want to lose that.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 2:43 PM, Brent Royal-Gordon  wrote:
>> In my opinion, using this initializer-call syntax to build an 
>> explicitly-typed literal is an obvious and natural choice with several 
>> advantages over the "as" syntax.  However, even if you disagree, it's clear 
>> that programmers are going to continue to independently try to use it, so 
>> it's really unfortunate for it to be subtly wrong.
> 
> I've seen developers do this; in one memorable case, it resulted in Swift 
> taking a ridiculously long time to typecheck an expression, since the 
> seemingly pinned-down types of the literals had actually become *more* 
> ambiguous, not less.

Yes, this would also tend to improve compile times, since currently we end up 
generating a massively-ambiguous constraint system which must be resolved by 
type defaulting.  That's not really why I'm proposing this, though.

> However, it's not difficult to teach developers to use `as`. Usually what's 
> happening is that their mental model of the language is wrong: they think of 
> `UInt16(foo)` as a cast to a primitive type, and are surprised to learn that 
> it's actually an initializer on a struct and they're initializing an 
> instance. Learning this helps them understand how the language works, what 
> the difference is between initializers and `as`, and how they can write the 
> same things they see in the standard library types.

So, you think that this syntax is enticing to new developers who naturally 
think that the feature works the way that I'm proposing it should work, and you 
think that the right solution is to make the syntax illegal so that you can 
more conveniently tell them it doesn't work that way? :)

You can still tell them that it's a struct and you're calling an initializer on 
it; it's just that the initializer chosen is the special literal initializer 
because the argument is a literal.

John.



> 
> I think *actually* turning this into magic would be counterproductive. The 
> better solution is to make the compiler replace me in that story, by having 
> it emit a warning with a fix-it. It keeps initializer calls meaning exactly 
> what they say. (And it doesn't require an evolution proposal to do, since you 
> can add a warning with a mere bug.)
> 
>   UInt16(42)
>   ^~ ^~
>   Use of initializer with integer literal does not cast '42' to 'UInt16'
>   Fix-It: Replace with '42 as UInt16'
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 2:36 PM, Vladimir.S  wrote:
> Well, I understand that it seems like there is some problem with UIntN() 
> initialization, but can't find any simple code that will demonstrate this..
> 
> All below works as expected:
> 
> var x1: Int32 = 0
> var x2 = Int32(0)
> 
> print(x1.dynamicType, x2.dynamicType) // Int32 Int32
> 
> // integer overflows when converted from 'Int' to 'UInt16'
> //var x = UInt16(100_000)
> //var x = UInt16(-10)
> 
> // negative integer cannot be converted to unsigned type 'UInt64'
> // var x = UInt64(-1)
> 
> So, what code will produce some unexpected behavior / error at runtime?

Like I said, the standard library and compiler conspire to make sure that easy 
cases like this are caught at compile time, but that would not help 
non-standard types that conform to IntegerLiteralConvertible.

Also, even for standard types, the syntax only works statically if the literal 
fits in the range of Int, which may not be a superset of the desired type.  For 
example, UInt64(0x100) would not work on a 32-bit platform.  It is 
diagnosed statically, however.

John.

> 
> On 03.06.2016 0:25, John McCall wrote:
>>> On Jun 2, 2016, at 1:56 PM, Vladimir.S  wrote:
 Often
 this leads to static ambiguities or, worse, causes the literal to be built
 using a default type (such as Int); this may have semantically very
 different results which are only caught at runtime.
>>> 
>>> Seems like I'm very slow today.. Could you present a couple of examples 
>>> where such initialization(like UInt16(7)) can produce some unexpected 
>>> behavior / error at runtime?
>> 
>> UIntN has unlabeled initializers taking all of the standard integer types, 
>> including itself.  The literal type will therefore get defaulted to Int.  
>> The legal range of values for Int may not be a superset of the legal range 
>> of values for UIntN.  If the literal is in the legal range for an Int but 
>> not for the target type, this might trap at runtime.  Now, for a built-in 
>> integer type like UInt16, we will recognize that the coercion always traps 
>> and emit an error at compile-time, but this generally won't apply to other 
>> types.
>> 
>> John.
>> 
>>> 
>>> On 02.06.2016 19:08, John McCall via swift-evolution wrote:
 The official way to build a literal of a specific type is to write the
 literal in an explicitly-typed context, like so:
   let x: UInt16 = 7
 or
   let x = 7 as UInt16
 
 Nonetheless, programmers often try the following:
   UInt16(7)
 
 Unfortunately, this does /not/ attempt to construct the value using the
 appropriate literal protocol; it instead performs overload resolution using
 the standard rules, i.e. considering only single-argument unlabelled
 initializers of a type which conforms to IntegerLiteralConvertible.  Often
 this leads to static ambiguities or, worse, causes the literal to be built
 using a default type (such as Int); this may have semantically very
 different results which are only caught at runtime.
 
 In my opinion, using this initializer-call syntax to build an
 explicitly-typed literal is an obvious and natural choice with several
 advantages over the "as" syntax.  However, even if you disagree, it's clear
 that programmers are going to continue to independently try to use it, so
 it's really unfortunate for it to be subtly wrong.
 
 Therefore, I propose that we adopt the following typing rule:
 
 Given a function call expression of the form A(B) (that is, an
 /expr-call/ with a single, unlabelled argument) where B is
 an /expr-literal/ or /expr-collection/, if A has type T.Type for some type
 T and there is a declared conformance of T to an appropriate literal
 protocol for B, then the expression is always resolves as a literal
 construction of type T (as if the expression were written "B as A") rather
 than as a general initializer call.
 
 Formally, this would be a special form of the argument conversion
 constraint, since the type of the expression A may not be immediately 
 known.
 
 Note that, as specified, it is possible to suppress this typing rule by
 wrapping the literal in parentheses.  This might seem distasteful; it would
 be easy enough to allow the form of B to include extra parentheses.  It's
 potentially useful to have a way to suppress this rule and get a normal
 construction, but there are several other ways of getting that effect, such
 as explicitly typing the literal argument (e.g. writing "A(Int(B))").
 
 A conditional conformance counts as a declared conformance even if the
 generic arguments are known to not satisfy the conditional conformance.
 This permits the applicability of the rule to be decided without having to
 first decide the type arguments, which greatly simplifies the type-checking
 

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Xiaodi Wu via swift-evolution
Nope. I use it with Metal buffers, for example :)

Moreover, there's nothing inherently unsafe about sizeof, and I think it's
important, *especially when you're working with UnsafePointers*, that safe
things look safe. If the moment a pointer comes into the picture everything
related to it is prefixed with Unsafe, that word loses its meaning entirely.
On Thu, Jun 2, 2016 at 16:54 Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:

> > I don't disagree with the points you make.  But one can argue that this
> is a good thing.  It calls attention to code that requires extra attention
> and care.  In some ways this is similar to 'UnsafeMutablePointer' vs
> '*T'.  Verbosity was a deliberate choice in that case.
>
> You know...rather than introducing a new type like MemoryLayout, would it
> make sense to do this with static properties on UnsafePointer?
>
> UnsafePointer.pointeeSize
> UnsafePointer.pointeeAlignment
> UnsafePointer.pointeeSpacing
>
> If you need this information, 90% of the time you're probably using
> UnsafePointer or one of its friends, right?
>
> --
> Brent Royal-Gordon
> Architechies
>
> ___
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Erica Sadun via swift-evolution

> On Jun 2, 2016, at 3:55 PM, Brent Royal-Gordon  wrote:
> 
>> I don't disagree with the points you make.  But one can argue that this is a 
>> good thing.  It calls attention to code that requires extra attention and 
>> care.  In some ways this is similar to 'UnsafeMutablePointer' vs '*T'.  
>> Verbosity was a deliberate choice in that case.
> 
> You know...rather than introducing a new type like MemoryLayout, would it 
> make sense to do this with static properties on UnsafePointer?
> 
>   UnsafePointer.pointeeSize
>   UnsafePointer.pointeeAlignment
>   UnsafePointer.pointeeSpacing
> 
> If you need this information, 90% of the time you're probably using 
> UnsafePointer or one of its friends, right?
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

Some quick greppage -- E

public/core/BridgeObjectiveC.swift:_sanityCheck(sizeofValue(self) >=
public/core/Builtin.swift:public func sizeofValue(_:T) -> Int {
public/core/Character.swift:let bits = sizeofValue(initialUTF8) &* 8 &- 1
public/core/Unicode.swift:  if utf8Count < sizeofValue(result) {

private/SwiftPrivateLibcExtras/Subprocess.swift:let errnoSize = 
sizeof(errno.dynamicType)
private/SwiftPrivateLibcExtras/SwiftPrivateLibcExtras.swift:return 
sizeof(UInt) * 8
private/SwiftReflectionTest/SwiftReflectionTest.swift:  sendBytes(from: 
, count: sizeof(UInt.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  sendBytes(from: , 
count: sizeof(T.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  fread(, 
sizeof(UInt.self), 1, stdin)
private/SwiftReflectionTest/SwiftReflectionTest.swift:  sendBytes(from: 
, count: sizeof(UInt.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  let pointerSize = 
UInt8(sizeof(UnsafePointer.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  let anyPointer = 
UnsafeMutablePointer(allocatingCapacity: sizeof(Any.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  
anyPointer.deallocateCapacity(sizeof(Any.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  allocatingCapacity: 
sizeof(ThickFunction0.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  
fn.deallocateCapacity(sizeof(ThickFunction0.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  allocatingCapacity: 
sizeof(ThickFunction1.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  
fn.deallocateCapacity(sizeof(ThickFunction1.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  allocatingCapacity: 
sizeof(ThickFunction2.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  
fn.deallocateCapacity(sizeof(ThickFunction2.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  allocatingCapacity: 
sizeof(ThickFunction3.self))
private/SwiftReflectionTest/SwiftReflectionTest.swift:  
fn.deallocateCapacity(sizeof(ThickFunction3.self))
public/core/BridgeObjectiveC.swift:   
sizeof(Optional.self) * count)
public/core/Builtin.swift:/// In particular, `sizeof(X.self)`, when `X` is a 
class type, is the
public/core/Builtin.swift:public func sizeof(_:T.Type) -> Int {
public/core/Builtin.swift:  return Int(Builtin.sizeof(T.self))
public/core/Builtin.swift:/// In particular, `sizeof(a)`, when `a` is a class 
instance, is the
public/core/Builtin.swift:  return sizeof(T.self)
public/core/Builtin.swift:  _precondition(sizeof(T.self) == sizeof(U.self),
public/core/Builtin.swift:sizeof(_HeapObject.self),
public/core/Character.swift:// Notice that the result of sizeof() is a 
small non-zero number and can't
public/core/HeapBuffer.swift:  sizeof(_HeapObject.self),
public/core/HeapBuffer.swift:  _valueOffset() + sizeof(Value.self),
public/core/ManagedBuffer.swift:  
_class_getInstancePositiveExtentSize(bufferClass) == sizeof(_HeapObject.self)
public/core/ManagedBuffer.swift:  == _valueOffset + sizeof(Value.self)),
public/core/ManagedBuffer.swift:  
_class_getInstancePositiveExtentSize(bufferClass) == sizeof(_HeapObject.self)
public/core/ManagedBuffer.swift:  == _valueOffset + sizeof(Value.self)),
public/core/ManagedBuffer.swift:  sizeof(_HeapObject.self),
public/core/ManagedBuffer.swift:  _valueOffset + sizeof(Value.self),
public/core/Runtime.swift.gyb:  _sanityCheck(sizeof(_Buffer32.self) == 32)
public/core/Runtime.swift.gyb:  _sanityCheck(sizeof(_Buffer72.self) == 72)
public/core/Runtime.swift.gyb:  for _ in 0..<(2 * sizeof(UnsafePointer) - 
result.utf16.count) {
public/core/Sequence.swift:// `n` * sizeof(Iterator.Element) of memory, 
because slices keep the entire
public/core/StringUTF8.swift:  let utf16Count = 
Swift.min(sizeof(_UTF8Chunk.self), count - i)
public/core/StringUTF8.swift:return 0xFF << 
numericCast((sizeof(Buffer.self) &- 1) &* 8)
public/core/Unicode.swift:  let utf8Max = sizeof(_UTF8Chunk.self)
public/core/VarArgs.swift:count: (sizeof(T.self) + sizeof(Int.self) - 1) / 
sizeof(Int.self))

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Sean Heber via swift-evolution
This might be silly, but what if there were a struct with all of the relevant 
fields (not sure what the best name would be):

struct MemoryLayout {
  let size: Int
  let alignment: Int
  let stride: Int
 // etc
}

Then you’d only maybe need two functions:

memoryLayout(of:) and memoryLayout(ofType:)

Or perhaps just a single property on all types named “memoryLayout” (or 
whatever) that returns the MemoryLayout struct:

Int.memory.size
type(of: 42).memoryLayout.size
// etc

Or just a single property on UnsafePointer if we went that route..

It seems like this sort of approach would keep namespace pollution down, at 
least?

l8r
Sean


> On Jun 2, 2016, at 4:55 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> I don't disagree with the points you make.  But one can argue that this is a 
>> good thing.  It calls attention to code that requires extra attention and 
>> care.  In some ways this is similar to 'UnsafeMutablePointer' vs '*T'.  
>> Verbosity was a deliberate choice in that case.
> 
> You know...rather than introducing a new type like MemoryLayout, would it 
> make sense to do this with static properties on UnsafePointer?
> 
>   UnsafePointer.pointeeSize
>   UnsafePointer.pointeeAlignment
>   UnsafePointer.pointeeSpacing
> 
> If you need this information, 90% of the time you're probably using 
> UnsafePointer or one of its friends, right?
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Tony Allevato via swift-evolution
On Thu, Jun 2, 2016 at 2:38 PM Vladimir.S  wrote:

> What is wrong with your examples?
>
> var x1: Int32 = 0
> var x2 = Int32(0)
> print(x1.dynamicType, x2.dynamicType) // Int32 Int32
>

I was referring to the subtle distinction between creating an Int32 from a
literal (the first one) and creating an Int from a literal and then
coercing it to Int32 (the second one). So, I was pondering whether this was
the cause of some complex expressions I've had problems with in the past.
However, looking at the specific code, it looks like I had the *opposite*
problem.

This expression is evaluated quickly in Swift 2.2:

let value = Int64((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
(0x3b << 28) |
  (0x56 << 35) | (0x00 << 42) | (0x05 << 49) | (0x26 << 56) | (0x01 <<
63))

This one errors out with "expression was too complex to be solved in
reasonable time":

let value: Int64 = (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21)
| (0x3b << 28) |
  (0x56 << 35) | (0x00 << 42) | (0x05 << 49) | (0x26 << 56) | (0x01 <<
63)



>
> On 03.06.2016 0:17, Tony Allevato via swift-evolution wrote:
> > +1. As someone who thought "var x: Int32 = 0" and "var x = Int32(0)" were
> > equivalent, this is very good to know (and very good to fix).
> >
> > I'm starting to wonder now if some of the times I've hit "expression was
> > too complex" errors with large 64-bit multi-term expressions with
> literals
> > were caused by coercions happening that I didn't realize.
> >
> >
> > On Thu, Jun 2, 2016 at 9:31 AM John McCall via swift-evolution
> > > wrote:
> >
> > The official way to build a literal of a specific type is to write
> the
> > literal in an explicitly-typed context, like so:
> > let x: UInt16 = 7
> > or
> > let x = 7 as UInt16
> >
> > Nonetheless, programmers often try the following:
> > UInt16(7)
> >
> > Unfortunately, this does /not/ attempt to construct the value using
> the
> > appropriate literal protocol; it instead performs overload resolution
> > using the standard rules, i.e. considering only single-argument
> > unlabelled initializers of a type which conforms to
> > IntegerLiteralConvertible.  Often this leads to static ambiguities
> or,
> > worse, causes the literal to be built using a default type (such as
> > Int); this may have semantically very different results which are
> only
> > caught at runtime.
> >
> > In my opinion, using this initializer-call syntax to build an
> > explicitly-typed literal is an obvious and natural choice with
> several
> > advantages over the "as" syntax.  However, even if you disagree, it's
> > clear that programmers are going to continue to independently try to
> > use it, so it's really unfortunate for it to be subtly wrong.
> >
> > Therefore, I propose that we adopt the following typing rule:
> >
> >   Given a function call expression of the form A(B) (that is, an
> > /expr-call/ with a single, unlabelled argument) where B is
> > an /expr-literal/ or /expr-collection/, if A has type T.Type for some
> > type T and there is a declared conformance of T to an appropriate
> > literal protocol for B, then the expression is always resolves as a
> > literal construction of type T (as if the expression were written "B
> as
> > A") rather than as a general initializer call.
> >
> > Formally, this would be a special form of the argument conversion
> > constraint, since the type of the expression A may not be immediately
> > known.
> >
> > Note that, as specified, it is possible to suppress this typing rule
> by
> > wrapping the literal in parentheses.  This might seem distasteful; it
> > would be easy enough to allow the form of B to include extra
> > parentheses.  It's potentially useful to have a way to suppress this
> > rule and get a normal construction, but there are several other ways
> of
> > getting that effect, such as explicitly typing the literal argument
> > (e.g. writing "A(Int(B))").
> >
> > A conditional conformance counts as a declared conformance even if
> the
> > generic arguments are known to not satisfy the conditional
> > conformance.  This permits the applicability of the rule to be
> decided
> > without having to first decide the type arguments, which greatly
> > simplifies the type-checking problem (and may be necessary for
> > soundness; I didn't explore this in depth, but it certainly feels
> like
> > a very nasty sort of dependence).  We could potentially weaken this
> for
> > cases where A is a direct type reference with bound parameters, e.g.
> > Foo([]) or the same with a typealias, but I think there's some
> > benefit from having a simpler specification, both for the
> > implementation and for the explicability of the model.
> >
> > John.
> > 

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Brent Royal-Gordon via swift-evolution
> I don't disagree with the points you make.  But one can argue that this is a 
> good thing.  It calls attention to code that requires extra attention and 
> care.  In some ways this is similar to 'UnsafeMutablePointer' vs '*T'.  
> Verbosity was a deliberate choice in that case.

You know...rather than introducing a new type like MemoryLayout, would it make 
sense to do this with static properties on UnsafePointer?

UnsafePointer.pointeeSize
UnsafePointer.pointeeAlignment
UnsafePointer.pointeeSpacing

If you need this information, 90% of the time you're probably using 
UnsafePointer or one of its friends, right?

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Xiaodi Wu via swift-evolution
See, I've made this mistake as well, and *not* because I thought it casts
the literal. I had always assumed that something like `UInt16(42)` would
initialize using the integer literal init, since it seems logical that
that's the most specific. The proposed change reflects my currently
erroneous mental model.
On Thu, Jun 2, 2016 at 16:42 Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:

> > In my opinion, using this initializer-call syntax to build an
> explicitly-typed literal is an obvious and natural choice with several
> advantages over the "as" syntax.  However, even if you disagree, it's clear
> that programmers are going to continue to independently try to use it, so
> it's really unfortunate for it to be subtly wrong.
>
> I've seen developers do this; in one memorable case, it resulted in Swift
> taking a ridiculously long time to typecheck an expression, since the
> seemingly pinned-down types of the literals had actually become *more*
> ambiguous, not less.
>
> However, it's not difficult to teach developers to use `as`. Usually
> what's happening is that their mental model of the language is wrong: they
> think of `UInt16(foo)` as a cast to a primitive type, and are surprised to
> learn that it's actually an initializer on a struct and they're
> initializing an instance. Learning this helps them understand how the
> language works, what the difference is between initializers and `as`, and
> how they can write the same things they see in the standard library types.
>
> I think *actually* turning this into magic would be counterproductive. The
> better solution is to make the compiler replace me in that story, by having
> it emit a warning with a fix-it. It keeps initializer calls meaning exactly
> what they say. (And it doesn't require an evolution proposal to do, since
> you can add a warning with a mere bug.)
>
> UInt16(42)
> ^~ ^~
> Use of initializer with integer literal does not cast '42' to
> 'UInt16'
> Fix-It: Replace with '42 as UInt16'
>
> --
> Brent Royal-Gordon
> Architechies
>
> ___
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Xiaodi Wu via swift-evolution
Isn't this the same argument for .dynamicType over type(of:) though?

Given that that debate has been settled in favor of the latter, I think the
question today is how best to come up with a consistent scheme.

Earlier in this conversation, it was pointed out (by Matt, I think?) that
one key advantage of type(of:) is that it takes on a syntax that is
actually possible to write in Swift, since one cannot extend Any.

If we take this principle to its logical conclusion, properties (of a type
or instance) which apply to Any should be global functions.

On Thu, Jun 2, 2016 at 16:26 Russ Bishop  wrote:

>
> On Jun 2, 2016, at 2:05 PM, Xiaodi Wu  wrote:
>
>
> In the earlier conversation, it was pointed out (by Dave A., I think?)
> that examples such as Array.size show how this solution can get confusing.
> And even though there aren't fixed-length arrays in Swift, those may come
> one day, making the syntax even more confusing.
>
>
>
> Array.count is a function taking an instance; I’m not sure I agree it
> would be terribly confusing… then again I run in Xcode with the quick help
> pane open so I see the doc comments for every type, property, and function
> as I move around the code. It’s quite handy :)
>
> I could see including memory in the name (or something similar) if we want
> to be extra clear about it.
>
> Int.memorySize
> Int.memoryAlignment
>
>
> Ultimately the type’s size in memory *is a property of the type* so it
> seems clear that is where it belongs (being careful not to steal too much
> of the namespace of course).
>
>
> Russ
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Brent Royal-Gordon via swift-evolution
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.

I've seen developers do this; in one memorable case, it resulted in Swift 
taking a ridiculously long time to typecheck an expression, since the seemingly 
pinned-down types of the literals had actually become *more* ambiguous, not 
less.

However, it's not difficult to teach developers to use `as`. Usually what's 
happening is that their mental model of the language is wrong: they think of 
`UInt16(foo)` as a cast to a primitive type, and are surprised to learn that 
it's actually an initializer on a struct and they're initializing an instance. 
Learning this helps them understand how the language works, what the difference 
is between initializers and `as`, and how they can write the same things they 
see in the standard library types.

I think *actually* turning this into magic would be counterproductive. The 
better solution is to make the compiler replace me in that story, by having it 
emit a warning with a fix-it. It keeps initializer calls meaning exactly what 
they say. (And it doesn't require an evolution proposal to do, since you can 
add a warning with a mere bug.)

UInt16(42)
^~ ^~
Use of initializer with integer literal does not cast '42' to 'UInt16'
Fix-It: Replace with '42 as UInt16'

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Vladimir.S via swift-evolution

What is wrong with your examples?

var x1: Int32 = 0
var x2 = Int32(0)
print(x1.dynamicType, x2.dynamicType) // Int32 Int32


On 03.06.2016 0:17, Tony Allevato via swift-evolution wrote:

+1. As someone who thought "var x: Int32 = 0" and "var x = Int32(0)" were
equivalent, this is very good to know (and very good to fix).

I'm starting to wonder now if some of the times I've hit "expression was
too complex" errors with large 64-bit multi-term expressions with literals
were caused by coercions happening that I didn't realize.


On Thu, Jun 2, 2016 at 9:31 AM John McCall via swift-evolution
> wrote:

The official way to build a literal of a specific type is to write the
literal in an explicitly-typed context, like so:
let x: UInt16 = 7
or
let x = 7 as UInt16

Nonetheless, programmers often try the following:
UInt16(7)

Unfortunately, this does /not/ attempt to construct the value using the
appropriate literal protocol; it instead performs overload resolution
using the standard rules, i.e. considering only single-argument
unlabelled initializers of a type which conforms to
IntegerLiteralConvertible.  Often this leads to static ambiguities or,
worse, causes the literal to be built using a default type (such as
Int); this may have semantically very different results which are only
caught at runtime.

In my opinion, using this initializer-call syntax to build an
explicitly-typed literal is an obvious and natural choice with several
advantages over the "as" syntax.  However, even if you disagree, it's
clear that programmers are going to continue to independently try to
use it, so it's really unfortunate for it to be subtly wrong.

Therefore, I propose that we adopt the following typing rule:

  Given a function call expression of the form A(B) (that is, an
/expr-call/ with a single, unlabelled argument) where B is
an /expr-literal/ or /expr-collection/, if A has type T.Type for some
type T and there is a declared conformance of T to an appropriate
literal protocol for B, then the expression is always resolves as a
literal construction of type T (as if the expression were written "B as
A") rather than as a general initializer call.

Formally, this would be a special form of the argument conversion
constraint, since the type of the expression A may not be immediately
known.

Note that, as specified, it is possible to suppress this typing rule by
wrapping the literal in parentheses.  This might seem distasteful; it
would be easy enough to allow the form of B to include extra
parentheses.  It's potentially useful to have a way to suppress this
rule and get a normal construction, but there are several other ways of
getting that effect, such as explicitly typing the literal argument
(e.g. writing "A(Int(B))").

A conditional conformance counts as a declared conformance even if the
generic arguments are known to not satisfy the conditional
conformance.  This permits the applicability of the rule to be decided
without having to first decide the type arguments, which greatly
simplifies the type-checking problem (and may be necessary for
soundness; I didn't explore this in depth, but it certainly feels like
a very nasty sort of dependence).  We could potentially weaken this for
cases where A is a direct type reference with bound parameters, e.g.
Foo([]) or the same with a typealias, but I think there's some
benefit from having a simpler specification, both for the
implementation and for the explicability of the model.

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Vladimir.S via swift-evolution
Well, I understand that it seems like there is some problem with UIntN() 
initialization, but can't find any simple code that will demonstrate this..


All below works as expected:

var x1: Int32 = 0
var x2 = Int32(0)

print(x1.dynamicType, x2.dynamicType) // Int32 Int32

// integer overflows when converted from 'Int' to 'UInt16'
//var x = UInt16(100_000)
//var x = UInt16(-10)

// negative integer cannot be converted to unsigned type 'UInt64'
// var x = UInt64(-1)

So, what code will produce some unexpected behavior / error at runtime?

On 03.06.2016 0:25, John McCall wrote:

On Jun 2, 2016, at 1:56 PM, Vladimir.S  wrote:

Often
this leads to static ambiguities or, worse, causes the literal to be built
using a default type (such as Int); this may have semantically very
different results which are only caught at runtime.


Seems like I'm very slow today.. Could you present a couple of examples where 
such initialization(like UInt16(7)) can produce some unexpected behavior / 
error at runtime?


UIntN has unlabeled initializers taking all of the standard integer types, 
including itself.  The literal type will therefore get defaulted to Int.  The 
legal range of values for Int may not be a superset of the legal range of 
values for UIntN.  If the literal is in the legal range for an Int but not for 
the target type, this might trap at runtime.  Now, for a built-in integer type 
like UInt16, we will recognize that the coercion always traps and emit an error 
at compile-time, but this generally won't apply to other types.

John.



On 02.06.2016 19:08, John McCall via swift-evolution wrote:

The official way to build a literal of a specific type is to write the
literal in an explicitly-typed context, like so:
   let x: UInt16 = 7
or
   let x = 7 as UInt16

Nonetheless, programmers often try the following:
   UInt16(7)

Unfortunately, this does /not/ attempt to construct the value using the
appropriate literal protocol; it instead performs overload resolution using
the standard rules, i.e. considering only single-argument unlabelled
initializers of a type which conforms to IntegerLiteralConvertible.  Often
this leads to static ambiguities or, worse, causes the literal to be built
using a default type (such as Int); this may have semantically very
different results which are only caught at runtime.

In my opinion, using this initializer-call syntax to build an
explicitly-typed literal is an obvious and natural choice with several
advantages over the "as" syntax.  However, even if you disagree, it's clear
that programmers are going to continue to independently try to use it, so
it's really unfortunate for it to be subtly wrong.

Therefore, I propose that we adopt the following typing rule:

 Given a function call expression of the form A(B) (that is, an
/expr-call/ with a single, unlabelled argument) where B is
an /expr-literal/ or /expr-collection/, if A has type T.Type for some type
T and there is a declared conformance of T to an appropriate literal
protocol for B, then the expression is always resolves as a literal
construction of type T (as if the expression were written "B as A") rather
than as a general initializer call.

Formally, this would be a special form of the argument conversion
constraint, since the type of the expression A may not be immediately known.

Note that, as specified, it is possible to suppress this typing rule by
wrapping the literal in parentheses.  This might seem distasteful; it would
be easy enough to allow the form of B to include extra parentheses.  It's
potentially useful to have a way to suppress this rule and get a normal
construction, but there are several other ways of getting that effect, such
as explicitly typing the literal argument (e.g. writing "A(Int(B))").

A conditional conformance counts as a declared conformance even if the
generic arguments are known to not satisfy the conditional conformance.
This permits the applicability of the rule to be decided without having to
first decide the type arguments, which greatly simplifies the type-checking
problem (and may be necessary for soundness; I didn't explore this in
depth, but it certainly feels like a very nasty sort of dependence).  We
could potentially weaken this for cases where A is a direct type reference
with bound parameters, e.g. Foo([]) or the same with a typealias, but
I think there's some benefit from having a simpler specification, both for
the implementation and for the explicability of the model.

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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 2:05 PM, Xiaodi Wu  wrote:
> On Thu, Jun 2, 2016 at 3:46 PM, John McCall via swift-evolution 
> > wrote:
>> On Jun 2, 2016, at 1:43 PM, Russ Bishop > > wrote:
>>> On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution 
>>> > wrote:
>>> 
>>> I still think the value-based APIs are misleading and that it would be 
>>> better to ask people to just use a type explicitly.
>>> 
>>> John.
>> 
>> 
>> I agree; in fact why aren’t these properties on the type itself? The type is 
>> what matters; why can’t the type just tell me it’s size? 
>> Having free functions or magic operators seems to be another holdover from 
>> C. 
>> 
>> 
>> Int.size
>> Int.alignment
>> Int.spacing
>> 
>> let x: Any = 5
>> type(of: x).size
>> 
>> 
>> The compiler should be able to statically know the first three values and 
>> inline them. The second is discovering the size dynamically.
> 
> Two reasons.  The first is that this is a user-extensible namespace via 
> static members, so it's somewhat unfortunate to pollute it with names from 
> the library.  The second is that there's currently no language mechanism for 
> adding a static member to every type, so this would have to be built-in.  But 
> I agree that in the abstract a static property would be preferable.
> 
> In the earlier conversation, it was pointed out (by Dave A., I think?) that 
> examples such as Array.size show how this solution can get confusing. And 
> even though there aren't fixed-length arrays in Swift, those may come one 
> day, making the syntax even more confusing.

Yes, I think that it is clear that, even if we added a property on all types, 
it would not be acceptable to name that property something like "size"; it 
would have to be something longer like "storageSize".

John.

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Erica Sadun via swift-evolution

> On Jun 2, 2016, at 3:28 PM, John McCall via swift-evolution 
>  wrote:
> 
>> On Jun 2, 2016, at 2:05 PM, Xiaodi Wu > > wrote:
>> On Thu, Jun 2, 2016 at 3:46 PM, John McCall via swift-evolution 
>> > wrote:
> 
> Yes, I think that it is clear that, even if we added a property on all types, 
> it would not be acceptable to name that property something like "size"; it 
> would have to be something longer like "storageSize".

Suggested names so far for augmenting the base:

* memorySize, memoryAlignment, memorySpacing/memoryStride
* storageSize, storageAlignment, storageSpacing/storageStride

-- E


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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Russ Bishop via swift-evolution

> On Jun 2, 2016, at 2:05 PM, Xiaodi Wu  wrote:
> 
> 
> In the earlier conversation, it was pointed out (by Dave A., I think?) that 
> examples such as Array.size show how this solution can get confusing. And 
> even though there aren't fixed-length arrays in Swift, those may come one 
> day, making the syntax even more confusing.


Array.count is a function taking an instance; I’m not sure I agree it would be 
terribly confusing… then again I run in Xcode with the quick help pane open so 
I see the doc comments for every type, property, and function as I move around 
the code. It’s quite handy :)

I could see including memory in the name (or something similar) if we want to 
be extra clear about it.

Int.memorySize
Int.memoryAlignment


Ultimately the type’s size in memory is a property of the type so it seems 
clear that is where it belongs (being careful not to steal too much of the 
namespace of course).


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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Xiaodi Wu via swift-evolution
On the other hand, on its own sizeof() is not unsafe, and so the argument
that it should be longer to call attention to itself (by analogy with
UnsafePointer) isn't quite apt.

And I'm not sure we really want to encourage anyone else to be defining a
global function named size(of:) anyway, so I wouldn't consider vacating
that name for end-user purposes to be a meaningful positive.
On Thu, Jun 2, 2016 at 16:15 Tony Allevato  wrote:

> Given that these are fairly low-level values with very specialized uses, I
> definitely agree that they should be somehow namespaced in a way that
> doesn't cause us to make very common words unusable for our users.
>
> Even size(of:) seems more general to me than I'd like. I'd like to see the
> word "memory" as part of the name somehow, whether it's a wrapping type or
> a function prefix of some sort. These values are specialized; we don't need
> to optimize typing them, IMO.
>
> On Thu, Jun 2, 2016 at 2:06 PM Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On Thu, Jun 2, 2016 at 3:46 PM, John McCall via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> On Jun 2, 2016, at 1:43 PM, Russ Bishop  wrote:
>>>
>>> On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> I still think the value-based APIs are misleading and that it would be
>>> better to ask people to just use a type explicitly.
>>>
>>> John.
>>>
>>>
>>>
>>> I agree; in fact *why aren’t these properties on the type itself*? The
>>> type is what matters; why can’t the type just tell me it’s size?
>>> Having free functions or magic operators seems to be another holdover
>>> from C.
>>>
>>>
>>> Int.size
>>> Int.alignment
>>> Int.spacing
>>>
>>> let x: Any = 5
>>> type(of: x).size
>>>
>>>
>>> The compiler should be able to statically know the first three values
>>> and inline them. The second is discovering the size dynamically.
>>>
>>>
>>> Two reasons.  The first is that this is a user-extensible namespace via
>>> static members, so it's somewhat unfortunate to pollute it with names from
>>> the library.  The second is that there's currently no language mechanism
>>> for adding a static member to every type, so this would have to be
>>> built-in.  But I agree that in the abstract a static property would be
>>> preferable.
>>>
>>
>> In the earlier conversation, it was pointed out (by Dave A., I think?)
>> that examples such as Array.size show how this solution can get confusing.
>> And even though there aren't fixed-length arrays in Swift, those may come
>> one day, making the syntax even more confusing.
>>
>> ___
>> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 1:56 PM, Vladimir.S  wrote:
> > Often
> > this leads to static ambiguities or, worse, causes the literal to be built
> > using a default type (such as Int); this may have semantically very
> > different results which are only caught at runtime.
> 
> Seems like I'm very slow today.. Could you present a couple of examples where 
> such initialization(like UInt16(7)) can produce some unexpected behavior / 
> error at runtime?

UIntN has unlabeled initializers taking all of the standard integer types, 
including itself.  The literal type will therefore get defaulted to Int.  The 
legal range of values for Int may not be a superset of the legal range of 
values for UIntN.  If the literal is in the legal range for an Int but not for 
the target type, this might trap at runtime.  Now, for a built-in integer type 
like UInt16, we will recognize that the coercion always traps and emit an error 
at compile-time, but this generally won't apply to other types.

John.

> 
> On 02.06.2016 19:08, John McCall via swift-evolution wrote:
>> The official way to build a literal of a specific type is to write the
>> literal in an explicitly-typed context, like so:
>>let x: UInt16 = 7
>> or
>>let x = 7 as UInt16
>> 
>> Nonetheless, programmers often try the following:
>>UInt16(7)
>> 
>> Unfortunately, this does /not/ attempt to construct the value using the
>> appropriate literal protocol; it instead performs overload resolution using
>> the standard rules, i.e. considering only single-argument unlabelled
>> initializers of a type which conforms to IntegerLiteralConvertible.  Often
>> this leads to static ambiguities or, worse, causes the literal to be built
>> using a default type (such as Int); this may have semantically very
>> different results which are only caught at runtime.
>> 
>> In my opinion, using this initializer-call syntax to build an
>> explicitly-typed literal is an obvious and natural choice with several
>> advantages over the "as" syntax.  However, even if you disagree, it's clear
>> that programmers are going to continue to independently try to use it, so
>> it's really unfortunate for it to be subtly wrong.
>> 
>> Therefore, I propose that we adopt the following typing rule:
>> 
>>  Given a function call expression of the form A(B) (that is, an
>> /expr-call/ with a single, unlabelled argument) where B is
>> an /expr-literal/ or /expr-collection/, if A has type T.Type for some type
>> T and there is a declared conformance of T to an appropriate literal
>> protocol for B, then the expression is always resolves as a literal
>> construction of type T (as if the expression were written "B as A") rather
>> than as a general initializer call.
>> 
>> Formally, this would be a special form of the argument conversion
>> constraint, since the type of the expression A may not be immediately known.
>> 
>> Note that, as specified, it is possible to suppress this typing rule by
>> wrapping the literal in parentheses.  This might seem distasteful; it would
>> be easy enough to allow the form of B to include extra parentheses.  It's
>> potentially useful to have a way to suppress this rule and get a normal
>> construction, but there are several other ways of getting that effect, such
>> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>> 
>> A conditional conformance counts as a declared conformance even if the
>> generic arguments are known to not satisfy the conditional conformance.
>> This permits the applicability of the rule to be decided without having to
>> first decide the type arguments, which greatly simplifies the type-checking
>> problem (and may be necessary for soundness; I didn't explore this in
>> depth, but it certainly feels like a very nasty sort of dependence).  We
>> could potentially weaken this for cases where A is a direct type reference
>> with bound parameters, e.g. Foo([]) or the same with a typealias, but
>> I think there's some benefit from having a simpler specification, both for
>> the implementation and for the explicability of the model.
>> 
>> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Tony Allevato via swift-evolution
+1. As someone who thought "var x: Int32 = 0" and "var x = Int32(0)" were
equivalent, this is very good to know (and very good to fix).

I'm starting to wonder now if some of the times I've hit "expression was
too complex" errors with large 64-bit multi-term expressions with literals
were caused by coercions happening that I didn't realize.


On Thu, Jun 2, 2016 at 9:31 AM John McCall via swift-evolution <
swift-evolution@swift.org> wrote:

> The official way to build a literal of a specific type is to write the
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
>
> Nonetheless, programmers often try the following:
> UInt16(7)
>
> Unfortunately, this does *not* attempt to construct the value using the
> appropriate literal protocol; it instead performs overload resolution using
> the standard rules, i.e. considering only single-argument unlabelled
> initializers of a type which conforms to IntegerLiteralConvertible.  Often
> this leads to static ambiguities or, worse, causes the literal to be built
> using a default type (such as Int); this may have semantically very
> different results which are only caught at runtime.
>
> In my opinion, using this initializer-call syntax to build an
> explicitly-typed literal is an obvious and natural choice with several
> advantages over the "as" syntax.  However, even if you disagree, it's clear
> that programmers are going to continue to independently try to use it, so
> it's really unfortunate for it to be subtly wrong.
>
> Therefore, I propose that we adopt the following typing rule:
>
>   Given a function call expression of the form A(B) (that is, an
> *expr-call* with a single, unlabelled argument) where B is an
> *expr-literal* or *expr-collection*, if A has type T.Type for some type T
> and there is a declared conformance of T to an appropriate literal protocol
> for B, then the expression is always resolves as a literal construction of
> type T (as if the expression were written "B as A") rather than as a
> general initializer call.
>
> Formally, this would be a special form of the argument conversion
> constraint, since the type of the expression A may not be immediately known.
>
> Note that, as specified, it is possible to suppress this typing rule by
> wrapping the literal in parentheses.  This might seem distasteful; it would
> be easy enough to allow the form of B to include extra parentheses.  It's
> potentially useful to have a way to suppress this rule and get a normal
> construction, but there are several other ways of getting that effect, such
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>
> A conditional conformance counts as a declared conformance even if the
> generic arguments are known to not satisfy the conditional conformance.
> This permits the applicability of the rule to be decided without having to
> first decide the type arguments, which greatly simplifies the type-checking
> problem (and may be necessary for soundness; I didn't explore this in
> depth, but it certainly feels like a very nasty sort of dependence).  We
> could potentially weaken this for cases where A is a direct type reference
> with bound parameters, e.g. Foo([]) or the same with a typealias, but
> I think there's some benefit from having a simpler specification, both for
> the implementation and for the explicability of the model.
>
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Tony Allevato via swift-evolution
Given that these are fairly low-level values with very specialized uses, I
definitely agree that they should be somehow namespaced in a way that
doesn't cause us to make very common words unusable for our users.

Even size(of:) seems more general to me than I'd like. I'd like to see the
word "memory" as part of the name somehow, whether it's a wrapping type or
a function prefix of some sort. These values are specialized; we don't need
to optimize typing them, IMO.

On Thu, Jun 2, 2016 at 2:06 PM Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> On Thu, Jun 2, 2016 at 3:46 PM, John McCall via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On Jun 2, 2016, at 1:43 PM, Russ Bishop  wrote:
>>
>> On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> I still think the value-based APIs are misleading and that it would be
>> better to ask people to just use a type explicitly.
>>
>> John.
>>
>>
>>
>> I agree; in fact *why aren’t these properties on the type itself*? The
>> type is what matters; why can’t the type just tell me it’s size?
>> Having free functions or magic operators seems to be another holdover
>> from C.
>>
>>
>> Int.size
>> Int.alignment
>> Int.spacing
>>
>> let x: Any = 5
>> type(of: x).size
>>
>>
>> The compiler should be able to statically know the first three values and
>> inline them. The second is discovering the size dynamically.
>>
>>
>> Two reasons.  The first is that this is a user-extensible namespace via
>> static members, so it's somewhat unfortunate to pollute it with names from
>> the library.  The second is that there's currently no language mechanism
>> for adding a static member to every type, so this would have to be
>> built-in.  But I agree that in the abstract a static property would be
>> preferable.
>>
>
> In the earlier conversation, it was pointed out (by Dave A., I think?)
> that examples such as Array.size show how this solution can get confusing.
> And even though there aren't fixed-length arrays in Swift, those may come
> one day, making the syntax even more confusing.
>
> ___
> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Russ Bishop via swift-evolution

> On Jun 2, 2016, at 9:08 AM, John McCall via swift-evolution 
>  wrote:
> 
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.


+1 to the proposal; I’m embarrassed to admit I thought it worked this way 
already. 

Any type that wants more control shouldn’t be adopting the literal convertible 
protocols anyway.

Russ

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Xiaodi Wu via swift-evolution
On Thu, Jun 2, 2016 at 3:46 PM, John McCall via swift-evolution <
swift-evolution@swift.org> wrote:

> On Jun 2, 2016, at 1:43 PM, Russ Bishop  wrote:
>
> On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I still think the value-based APIs are misleading and that it would be
> better to ask people to just use a type explicitly.
>
> John.
>
>
>
> I agree; in fact *why aren’t these properties on the type itself*? The
> type is what matters; why can’t the type just tell me it’s size?
> Having free functions or magic operators seems to be another holdover from
> C.
>
>
> Int.size
> Int.alignment
> Int.spacing
>
> let x: Any = 5
> type(of: x).size
>
>
> The compiler should be able to statically know the first three values and
> inline them. The second is discovering the size dynamically.
>
>
> Two reasons.  The first is that this is a user-extensible namespace via
> static members, so it's somewhat unfortunate to pollute it with names from
> the library.  The second is that there's currently no language mechanism
> for adding a static member to every type, so this would have to be
> built-in.  But I agree that in the abstract a static property would be
> preferable.
>

In the earlier conversation, it was pointed out (by Dave A., I think?) that
examples such as Array.size show how this solution can get confusing. And
even though there aren't fixed-length arrays in Swift, those may come one
day, making the syntax even more confusing.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Vladimir.S via swift-evolution

> Often
> this leads to static ambiguities or, worse, causes the literal to be built
> using a default type (such as Int); this may have semantically very
> different results which are only caught at runtime.

Seems like I'm very slow today.. Could you present a couple of examples 
where such initialization(like UInt16(7)) can produce some unexpected 
behavior / error at runtime?


On 02.06.2016 19:08, John McCall via swift-evolution wrote:

The official way to build a literal of a specific type is to write the
literal in an explicitly-typed context, like so:
let x: UInt16 = 7
or
let x = 7 as UInt16

Nonetheless, programmers often try the following:
UInt16(7)

Unfortunately, this does /not/ attempt to construct the value using the
appropriate literal protocol; it instead performs overload resolution using
the standard rules, i.e. considering only single-argument unlabelled
initializers of a type which conforms to IntegerLiteralConvertible.  Often
this leads to static ambiguities or, worse, causes the literal to be built
using a default type (such as Int); this may have semantically very
different results which are only caught at runtime.

In my opinion, using this initializer-call syntax to build an
explicitly-typed literal is an obvious and natural choice with several
advantages over the "as" syntax.  However, even if you disagree, it's clear
that programmers are going to continue to independently try to use it, so
it's really unfortunate for it to be subtly wrong.

Therefore, I propose that we adopt the following typing rule:

  Given a function call expression of the form A(B) (that is, an
/expr-call/ with a single, unlabelled argument) where B is
an /expr-literal/ or /expr-collection/, if A has type T.Type for some type
T and there is a declared conformance of T to an appropriate literal
protocol for B, then the expression is always resolves as a literal
construction of type T (as if the expression were written "B as A") rather
than as a general initializer call.

Formally, this would be a special form of the argument conversion
constraint, since the type of the expression A may not be immediately known.

Note that, as specified, it is possible to suppress this typing rule by
wrapping the literal in parentheses.  This might seem distasteful; it would
be easy enough to allow the form of B to include extra parentheses.  It's
potentially useful to have a way to suppress this rule and get a normal
construction, but there are several other ways of getting that effect, such
as explicitly typing the literal argument (e.g. writing "A(Int(B))").

A conditional conformance counts as a declared conformance even if the
generic arguments are known to not satisfy the conditional conformance.
 This permits the applicability of the rule to be decided without having to
first decide the type arguments, which greatly simplifies the type-checking
problem (and may be necessary for soundness; I didn't explore this in
depth, but it certainly feels like a very nasty sort of dependence).  We
could potentially weaken this for cases where A is a direct type reference
with bound parameters, e.g. Foo([]) or the same with a typealias, but
I think there's some benefit from having a simpler specification, both for
the implementation and for the explicability of the model.

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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 3:41 PM, John McCall  wrote:
> 
>>> On Jun 2, 2016, at 12:10 PM, Matthew Johnson  wrote:
>>> On Jun 2, 2016, at 1:46 PM, Austin Zheng via swift-evolution 
>>>  wrote:
>>> 
>>> +1.
>>> 
>>> The primary advantage is that it aligns the language semantics with how 
>>> most programmers expect this common C-language-family idiom to behave and 
>>> removes a potential source of silently wrong code.
>>> 
>>> The primary disadvantage is that it introduces special-case behavior to 
>>> certain types of initializers (although, to be fair, this special-case 
>>> behavior is easily recognizable: unlabeled one-argument initializer with a 
>>> literal as the argument).
>>> 
>>> I think the advantage outweighs the disadvantage.
>> 
>> Agree.  This change basically means the label isn’t intended to be used by 
>> callers, but is only present to distinguish the initializer used by the 
>> protocol from any other unlabeled initializer accepting the same type.  But 
>> conceptually it is treated as the *most specific* unlabelled initializer 
>> possible, thus winning the overload resolution.
>> 
>> How important is it that we have the ability to distinguish between literals 
>> and non-literals with the same type?  If that isn’t important, maybe the 
>> literal convertible protocols could be reworked such that the label isn’t 
>> necessary.  That would eliminate the special-case elision of the label.
> 
> There is no way to rework the literal protocols so that this behavior just 
> falls out.  It's easy enough to convince yourself of this if you try to work 
> through an actual example.

Ok, I'll trust you on this point.  +1 on the idea as you proposed it.

> 
> John.
> 
>> 
>>> 
>>> This problem should be addressed one way or another. I prefer this 
>>> solution, but if it is rejected for whatever reason we should at least 
>>> explicitly outlaw A(literal) syntax in favor of "literal as A".
>>> 
>>> Austin
>>> 
 On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution 
  wrote:
 The official way to build a literal of a specific type is to write the 
 literal in an explicitly-typed context, like so:
 let x: UInt16 = 7
 or
 let x = 7 as UInt16
 
 Nonetheless, programmers often try the following:
 UInt16(7)
 
 Unfortunately, this does not attempt to construct the value using the 
 appropriate literal protocol; it instead performs overload resolution 
 using the standard rules, i.e. considering only single-argument unlabelled 
 initializers of a type which conforms to IntegerLiteralConvertible.  Often 
 this leads to static ambiguities or, worse, causes the literal to be built 
 using a default type (such as Int); this may have semantically very 
 different results which are only caught at runtime.
 
 In my opinion, using this initializer-call syntax to build an 
 explicitly-typed literal is an obvious and natural choice with several 
 advantages over the "as" syntax.  However, even if you disagree, it's 
 clear that programmers are going to continue to independently try to use 
 it, so it's really unfortunate for it to be subtly wrong.
 
 Therefore, I propose that we adopt the following typing rule:
 
   Given a function call expression of the form A(B) (that is, an expr-call 
 with a single, unlabelled argument) where B is an expr-literal or 
 expr-collection, if A has type T.Type for some type T and there is a 
 declared conformance of T to an appropriate literal protocol for B, then 
 the expression is always resolves as a literal construction of type T (as 
 if the expression were written "B as A") rather than as a general 
 initializer call.
 
 Formally, this would be a special form of the argument conversion 
 constraint, since the type of the expression A may not be immediately 
 known.
 
 Note that, as specified, it is possible to suppress this typing rule by 
 wrapping the literal in parentheses.  This might seem distasteful; it 
 would be easy enough to allow the form of B to include extra parentheses.  
 It's potentially useful to have a way to suppress this rule and get a 
 normal construction, but there are several other ways of getting that 
 effect, such as explicitly typing the literal argument (e.g. writing 
 "A(Int(B))").
 
 A conditional conformance counts as a declared conformance even if the 
 generic arguments are known to not satisfy the conditional conformance.  
 This permits the applicability of the rule to be decided without having to 
 first decide the type arguments, which greatly simplifies the 
 type-checking problem (and may be necessary for soundness; I didn't 
 explore this in depth, but it certainly feels like a very nasty sort 

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 1:43 PM, Russ Bishop  wrote:
>> On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution 
>> > wrote:
>> 
>> I still think the value-based APIs are misleading and that it would be 
>> better to ask people to just use a type explicitly.
>> 
>> John.
> 
> 
> I agree; in fact why aren’t these properties on the type itself? The type is 
> what matters; why can’t the type just tell me it’s size? 
> Having free functions or magic operators seems to be another holdover from C. 
> 
> 
> Int.size
> Int.alignment
> Int.spacing
> 
> let x: Any = 5
> type(of: x).size
> 
> 
> The compiler should be able to statically know the first three values and 
> inline them. The second is discovering the size dynamically.

Two reasons.  The first is that this is a user-extensible namespace via static 
members, so it's somewhat unfortunate to pollute it with names from the 
library.  The second is that there's currently no language mechanism for adding 
a static member to every type, so this would have to be built-in.  But I agree 
that in the abstract a static property would be preferable.

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Erica Sadun via swift-evolution

> On Jun 2, 2016, at 2:43 PM, Russ Bishop  wrote:
> 
> 
>> On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution 
>> > wrote:
>> 
>> I still think the value-based APIs are misleading and that it would be 
>> better to ask people to just use a type explicitly.
>> 
>> John.
> 
> 
> I agree; in fact why aren’t these properties on the type itself? The type is 
> what matters; why can’t the type just tell me it’s size? 
> Having free functions or magic operators seems to be another holdover from C. 
> 
> 
> Int.size
> Int.alignment
> Int.spacing
> 
> let x: Any = 5
> type(of: x).size
> 
> 
> The compiler should be able to statically know the first three values and 
> inline them. The second is discovering the size dynamically.
> 
> 
> Russ

If achievable, this would certainly be clean and elegant.

-- E

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Austin Zheng via swift-evolution
That makes sense. Thanks for sharing your reasoning.

On Thu, Jun 2, 2016 at 1:38 PM, John McCall  wrote:

> On Jun 2, 2016, at 11:55 AM, Austin Zheng  wrote:
> I think we should actually go further.
>
> If this proposal is accepted, disallow "as" as a way of specifying the
> type to construct from a literal.
>
>
> I see no reason to restrict "as" like this.  We're not going to stop using
> type context as a way of determining the type of a literal, and "as" is a
> general feature for providing type context.
>
> If this proposal isn't accepted, disallow using literal values as the
> argument to one-unlabeled-argument constructors.
>
>
> I can't imagine accepting this, either; it would be a major regression in
> the usefulness of unlabeled initializers.  At best, this would be
> appropriate only when the type conforms to an appropriate literal protocol.
>
> In general, Swift gives unlabeled initializers an idiomatic meaning: they
> coerce the argument to the target type in a nominally value-preserving
> way.  One way of viewing this proposal is that it recognizes that there is
> an obvious way to do that when the target type supports being directly
> formed from the given kind of literal.  But if the target type doesn't
> support that, coercing a value of some other appropriate literal type is
> still a completely reasonable behavior.
>
> John.
>
>
> Austin
>
> On Thu, Jun 2, 2016 at 11:46 AM, Austin Zheng 
> wrote:
>
>> +1.
>>
>> The primary advantage is that it aligns the language semantics with how
>> most programmers expect this common C-language-family idiom to behave and
>> removes a potential source of silently wrong code.
>>
>> The primary disadvantage is that it introduces special-case behavior to
>> certain types of initializers (although, to be fair, this special-case
>> behavior is easily recognizable: unlabeled one-argument initializer with a
>> literal as the argument).
>>
>> I think the advantage outweighs the disadvantage.
>>
>> This problem should be addressed one way or another. I prefer this
>> solution, but if it is rejected for whatever reason we should at least
>> explicitly outlaw A(literal) syntax in favor of "literal as A".
>>
>> Austin
>>
>> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> The official way to build a literal of a specific type is to write the
>>> literal in an explicitly-typed context, like so:
>>> let x: UInt16 = 7
>>> or
>>> let x = 7 as UInt16
>>>
>>> Nonetheless, programmers often try the following:
>>> UInt16(7)
>>>
>>> Unfortunately, this does *not* attempt to construct the value using the
>>> appropriate literal protocol; it instead performs overload resolution using
>>> the standard rules, i.e. considering only single-argument unlabelled
>>> initializers of a type which conforms to IntegerLiteralConvertible.  Often
>>> this leads to static ambiguities or, worse, causes the literal to be built
>>> using a default type (such as Int); this may have semantically very
>>> different results which are only caught at runtime.
>>>
>>> In my opinion, using this initializer-call syntax to build an
>>> explicitly-typed literal is an obvious and natural choice with several
>>> advantages over the "as" syntax.  However, even if you disagree, it's clear
>>> that programmers are going to continue to independently try to use it, so
>>> it's really unfortunate for it to be subtly wrong.
>>>
>>> Therefore, I propose that we adopt the following typing rule:
>>>
>>>   Given a function call expression of the form A(B) (that is, an
>>> *expr-call* with a single, unlabelled argument) where B is an
>>> *expr-literal* or *expr-collection*, if A has type T.Type for some type
>>> T and there is a declared conformance of T to an appropriate literal
>>> protocol for B, then the expression is always resolves as a literal
>>> construction of type T (as if the expression were written "B as A") rather
>>> than as a general initializer call.
>>>
>>> Formally, this would be a special form of the argument conversion
>>> constraint, since the type of the expression A may not be immediately known.
>>>
>>> Note that, as specified, it is possible to suppress this typing rule by
>>> wrapping the literal in parentheses.  This might seem distasteful; it would
>>> be easy enough to allow the form of B to include extra parentheses.  It's
>>> potentially useful to have a way to suppress this rule and get a normal
>>> construction, but there are several other ways of getting that effect, such
>>> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>>>
>>> A conditional conformance counts as a declared conformance even if the
>>> generic arguments are known to not satisfy the conditional conformance.
>>> This permits the applicability of the rule to be decided without having to
>>> first decide the type arguments, which greatly simplifies the 

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Russ Bishop via swift-evolution

> On Jun 2, 2016, at 11:30 AM, John McCall via swift-evolution 
>  wrote:
> 
> I still think the value-based APIs are misleading and that it would be better 
> to ask people to just use a type explicitly.
> 
> John.


I agree; in fact why aren’t these properties on the type itself? The type is 
what matters; why can’t the type just tell me it’s size? 
Having free functions or magic operators seems to be another holdover from C. 


Int.size
Int.alignment
Int.spacing

let x: Any = 5
type(of: x).size


The compiler should be able to statically know the first three values and 
inline them. The second is discovering the size dynamically.


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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Erica Sadun via swift-evolution

> On Jun 2, 2016, at 2:13 PM, Matthew Johnson  wrote:
> I don't disagree with the points you make.  But one can argue that this is a 
> good thing.  It calls attention to code that requires extra attention and 
> care.  In some ways this is similar to 'UnsafeMutablePointer' vs '*T'.  
> Verbosity was a deliberate choice in that case.

And mentioned.

https://github.com/erica/swift-evolution/blob/sizestride/proposals/-sidestride.md

-- E

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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 12:10 PM, Matthew Johnson  wrote:
>> On Jun 2, 2016, at 1:46 PM, Austin Zheng via swift-evolution 
>> > wrote:
>> 
>> +1.
>> 
>> The primary advantage is that it aligns the language semantics with how most 
>> programmers expect this common C-language-family idiom to behave and removes 
>> a potential source of silently wrong code.
>> 
>> The primary disadvantage is that it introduces special-case behavior to 
>> certain types of initializers (although, to be fair, this special-case 
>> behavior is easily recognizable: unlabeled one-argument initializer with a 
>> literal as the argument).
>> 
>> I think the advantage outweighs the disadvantage.
> 
> Agree.  This change basically means the label isn’t intended to be used by 
> callers, but is only present to distinguish the initializer used by the 
> protocol from any other unlabeled initializer accepting the same type.  But 
> conceptually it is treated as the *most specific* unlabelled initializer 
> possible, thus winning the overload resolution.
> 
> How important is it that we have the ability to distinguish between literals 
> and non-literals with the same type?  If that isn’t important, maybe the 
> literal convertible protocols could be reworked such that the label isn’t 
> necessary.  That would eliminate the special-case elision of the label.

There is no way to rework the literal protocols so that this behavior just 
falls out.  It's easy enough to convince yourself of this if you try to work 
through an actual example.

John.

> 
>> 
>> This problem should be addressed one way or another. I prefer this solution, 
>> but if it is rejected for whatever reason we should at least explicitly 
>> outlaw A(literal) syntax in favor of "literal as A".
>> 
>> Austin
>> 
>> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution 
>> > wrote:
>> The official way to build a literal of a specific type is to write the 
>> literal in an explicitly-typed context, like so:
>> let x: UInt16 = 7
>> or
>> let x = 7 as UInt16
>> 
>> Nonetheless, programmers often try the following:
>> UInt16(7)
>> 
>> Unfortunately, this does not attempt to construct the value using the 
>> appropriate literal protocol; it instead performs overload resolution using 
>> the standard rules, i.e. considering only single-argument unlabelled 
>> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
>> this leads to static ambiguities or, worse, causes the literal to be built 
>> using a default type (such as Int); this may have semantically very 
>> different results which are only caught at runtime.
>> 
>> In my opinion, using this initializer-call syntax to build an 
>> explicitly-typed literal is an obvious and natural choice with several 
>> advantages over the "as" syntax.  However, even if you disagree, it's clear 
>> that programmers are going to continue to independently try to use it, so 
>> it's really unfortunate for it to be subtly wrong.
>> 
>> Therefore, I propose that we adopt the following typing rule:
>> 
>>   Given a function call expression of the form A(B) (that is, an expr-call 
>> with a single, unlabelled argument) where B is an expr-literal or 
>> expr-collection, if A has type T.Type for some type T and there is a 
>> declared conformance of T to an appropriate literal protocol for B, then the 
>> expression is always resolves as a literal construction of type T (as if the 
>> expression were written "B as A") rather than as a general initializer call.
>> 
>> Formally, this would be a special form of the argument conversion 
>> constraint, since the type of the expression A may not be immediately known.
>> 
>> Note that, as specified, it is possible to suppress this typing rule by 
>> wrapping the literal in parentheses.  This might seem distasteful; it would 
>> be easy enough to allow the form of B to include extra parentheses.  It's 
>> potentially useful to have a way to suppress this rule and get a normal 
>> construction, but there are several other ways of getting that effect, such 
>> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>> 
>> A conditional conformance counts as a declared conformance even if the 
>> generic arguments are known to not satisfy the conditional conformance.  
>> This permits the applicability of the rule to be decided without having to 
>> first decide the type arguments, which greatly simplifies the type-checking 
>> problem (and may be necessary for soundness; I didn't explore this in depth, 
>> but it certainly feels like a very nasty sort of dependence).  We could 
>> potentially weaken this for cases where A is a direct type reference with 
>> bound parameters, e.g. Foo([]) or the same with a typealias, but I 
>> think there's some benefit from having a simpler specification, both for the 
>> 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 11:55 AM, Austin Zheng  wrote:
> I think we should actually go further.
> 
> If this proposal is accepted, disallow "as" as a way of specifying the type 
> to construct from a literal.

I see no reason to restrict "as" like this.  We're not going to stop using type 
context as a way of determining the type of a literal, and "as" is a general 
feature for providing type context.

> If this proposal isn't accepted, disallow using literal values as the 
> argument to one-unlabeled-argument constructors.

I can't imagine accepting this, either; it would be a major regression in the 
usefulness of unlabeled initializers.  At best, this would be appropriate only 
when the type conforms to an appropriate literal protocol.

In general, Swift gives unlabeled initializers an idiomatic meaning: they 
coerce the argument to the target type in a nominally value-preserving way.  
One way of viewing this proposal is that it recognizes that there is an obvious 
way to do that when the target type supports being directly formed from the 
given kind of literal.  But if the target type doesn't support that, coercing a 
value of some other appropriate literal type is still a completely reasonable 
behavior.

John.

> 
> Austin
> 
> On Thu, Jun 2, 2016 at 11:46 AM, Austin Zheng  > wrote:
> +1.
> 
> The primary advantage is that it aligns the language semantics with how most 
> programmers expect this common C-language-family idiom to behave and removes 
> a potential source of silently wrong code.
> 
> The primary disadvantage is that it introduces special-case behavior to 
> certain types of initializers (although, to be fair, this special-case 
> behavior is easily recognizable: unlabeled one-argument initializer with a 
> literal as the argument).
> 
> I think the advantage outweighs the disadvantage.
> 
> This problem should be addressed one way or another. I prefer this solution, 
> but if it is rejected for whatever reason we should at least explicitly 
> outlaw A(literal) syntax in favor of "literal as A".
> 
> Austin
> 
> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution 
> > wrote:
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect, such 
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
> 
> A conditional conformance counts as a declared conformance even if the 
> generic arguments are known to not satisfy the conditional conformance.  This 
> permits the applicability of the rule to be decided without having to first 
> decide the type arguments, which greatly simplifies the type-checking problem 
> (and may be necessary for soundness; I didn't explore this in depth, but it 
> certainly feels like a very nasty sort of dependence).  We could 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread David Sweeris via swift-evolution

> On Jun 2, 2016, at 12:57 PM, John McCall  wrote:
> 
>> On Jun 2, 2016, at 10:49 AM, David Sweeris > > wrote:
>> I’m not entirely sure what an “expr-collection” is.
> 
> Collection literals, e.g. [x,y,z] and [a: x, b: y].
Thought so, but I wasn’t sure. Thanks for clarifying :-)

> 
>> Does your proposal mean that in this code:
>> func foo() -> Int {...}
>> var w = 0
>> var x = T(foo())
>> var y = T(w)
>> var z = T(0)
>> different initializers would be used for `x`,`y`, and `z`?
> 
> z would be initialized using the literal initializer if T conforms to that 
> protocol, yes.
> 
>> If so, that seems a potential source of much subtler problems.
> 
> Note that this is only an issue for types that conform to the literal 
> protocols.

Oh, I know. The crux of my concern is that while the difference between 
`UInt16(7)` and `7 as UInt16` is subtle, it’s not that subtle… the literal 
convertible syntax doesn’t even look that much like a call to init, so it 
shouldn’t be that surprising if explicitly calling the init function might send 
you down a different code path. OTOH, this proposal silently (and invisibly) 
rewrites an explicit call to`init(_: Int)` to `init(integerLiteral: 
IntegerLiteralType)`, which seems worse. Again, I don’t disagree that there’s a 
subtlety here, but at least with the current behavior, the unexpected behavior 
comes from not paying attention to syntax.

>> I don’t disagree that you’ve identified a potential source of issues, but 
>> it’s conceivable that there might be circumstances where the "semantically 
>> very different results” are desired. I can’t think of any off the top of my 
>> head, but I’m not convinced that means they don’t exist.
> 
> I do not think that anybody writes UInt64(0) and *wants* the 0 to be built as 
> an Int and then coerced to UInt64.

I can’t think of why anyone would either — all my *LiteralConvertible types 
just pass on the literal arguments to an init that takes an Int (or whatever) — 
but “a failure of imagination…”

I guess I’m just saying that with the way Swift treats literals, potential 
confusion is inevitable, and that it’s better to contain the subtleties to 
syntax which already involves some implicit behavior, rather than to start 
rewriting explicit code simply because we think the programmer doesn’t know 
what they’re doing.

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 2:58 PM, Erica Sadun  wrote:
> 
> 
>> On Jun 2, 2016, at 12:47 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> On Jun 2, 2016, at 1:30 PM, John McCall  wrote:
>> 
 On Jun 2, 2016, at 11:22 AM, Matthew Johnson  
 wrote:
 On Jun 2, 2016, at 12:01 PM, John McCall  wrote:
 
>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu  wrote:
>> We could have a primary initializer like this:
>> 
>> init(_ type: T.Type)
>> 
>> It would look better than a default initializer that requires the type to be 
>> passed as a generic argument.  The fact that it is not labeled would make it 
>> clear that this is the primary initializer.
>> 
>>> 
>>> I still think the value-based APIs are misleading and that it would be 
>>> better to ask people to just use a type explicitly.
>> 
>> Sure.  I don't necessarily disagree.  But I think it's important to make 
>> clear that this is orthogonal to the struct vs free function discussion.  
>> That was the main point I was trying to make.  :)
>> 
>>> 
 Adding the label will eliminate the potential for confusion about type vs 
 metatype.  Wanting to know the size of the metatype is probably extremely 
 rare, but there is not reason to prohibit it.
>>> 
>>> I agree that the label makes the problem better.
>>> 
>>> John.
> 
> 
> I do want to say that while I'm including this in Alternatives Considered 
> (and will update as soon as we finish lunch), that I stand by the 
> freestanding functions as preferable to this clever but extremely indirect 
> approach.
> 
> I believe the MemoryLayout type introduces a level of indirection that is 
> less helpful in the rare times the user will consume this functionality, that 
> it clutters calls and adds cognitive burden for reading code.
> 
> Let me give you some examples:
> 
> let errnoSize = sizeof(errno.dynamicType)
> return sizeof(UInt) * 8
> sendBytes(from: , count: sizeof(UInt.self))
> _class_getInstancePositiveExtentSize(bufferClass) == sizeof(_HeapObject.self)
> bytesPerIndex: sizeof(IndexType))
> 
> In every example, calling a size function's clarity is simpler than using the 
> Memory Layout approach:
> 
> let errnoSize = MemoryLayout.init(t: errno).size
> return MemoryLayout.size * 8
> sendBytes(from: , count: MemoryLayout.size)
> _class_getInstancePositiveExtentSize(bufferClass) == 
> MemoryLayout<_HeapObject.self>.size
> bytesPerIndex: MemoryLayout.size
> 
> The full type specification lends the calls an importance and verbosity they 
> don't deserve compared to their simpler counterparts. The eye is drawn every 
> time to the "MemoryLayout" pattern:
> 
> * Prominence of the type constructor
> * Simplicity of the function call
> * Number of code characters used
> * Swift's adherence to a mantra of concision and clarity.
> 
> It fails all these. To put it in usability terms: it's a big stinking mess 
> compared to the readability and eye tracking of the simpler function. (I've 
> cc'ed in Chris Lattner, who has people who can test this kind of thing on 
> call.)

I don't disagree with the points you make.  But one can argue that this is a 
good thing.  It calls attention to code that requires extra attention and care. 
 In some ways this is similar to 'UnsafeMutablePointer' vs '*T'.  Verbosity 
was a deliberate choice in that case.

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Erica Sadun via swift-evolution

> On Jun 2, 2016, at 12:47 PM, Matthew Johnson via swift-evolution 
>  wrote:
> On Jun 2, 2016, at 1:30 PM, John McCall  > wrote:
> 
>>> On Jun 2, 2016, at 11:22 AM, Matthew Johnson >> > wrote:
>>> On Jun 2, 2016, at 12:01 PM, John McCall >> > wrote:
>>> 
> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution 
> > wrote:
>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu > > wrote:
> We could have a primary initializer like this:
> 
> init(_ type: T.Type)
> 
> It would look better than a default initializer that requires the type to be 
> passed as a generic argument.  The fact that it is not labeled would make it 
> clear that this is the primary initializer.
> 
>> 
>> I still think the value-based APIs are misleading and that it would be 
>> better to ask people to just use a type explicitly.
> 
> Sure.  I don't necessarily disagree.  But I think it's important to make 
> clear that this is orthogonal to the struct vs free function discussion.  
> That was the main point I was trying to make.  :)
> 
>> 
>>> Adding the label will eliminate the potential for confusion about type vs 
>>> metatype.  Wanting to know the size of the metatype is probably extremely 
>>> rare, but there is not reason to prohibit it.
>> 
>> I agree that the label makes the problem better.
>> 
>> John.


I do want to say that while I'm including this in Alternatives Considered (and 
will update as soon as we finish lunch), that I stand by the freestanding 
functions as preferable to this clever but extremely indirect approach.

I believe the MemoryLayout type introduces a level of indirection that is less 
helpful in the rare times the user will consume this functionality, that it 
clutters calls and adds cognitive burden for reading code.

Let me give you some examples:

let errnoSize = sizeof(errno.dynamicType)
return sizeof(UInt) * 8
sendBytes(from: , count: sizeof(UInt.self))
_class_getInstancePositiveExtentSize(bufferClass) == sizeof(_HeapObject.self)
bytesPerIndex: sizeof(IndexType))

In every example, calling a size function's clarity is simpler than using the 
Memory Layout approach:

let errnoSize = MemoryLayout.init(t: errno).size
return MemoryLayout.size * 8
sendBytes(from: , count: MemoryLayout.size)
_class_getInstancePositiveExtentSize(bufferClass) == 
MemoryLayout<_HeapObject.self>.size
bytesPerIndex: MemoryLayout.size

The full type specification lends the calls an importance and verbosity they 
don't deserve compared to their simpler counterparts. The eye is drawn every 
time to the "MemoryLayout" pattern:

* Prominence of the type constructor
* Simplicity of the function call
* Number of code characters used
* Swift's adherence to a mantra of concision and clarity.

It fails all these. To put it in usability terms: it's a big stinking mess 
compared to the readability and eye tracking of the simpler function. (I've 
cc'ed in Chris Lattner, who has people who can test this kind of thing on call.)

-- E


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


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 1:55 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> I think we should actually go further.
> 
> If this proposal is accepted, disallow "as" as a way of specifying the type 
> to construct from a literal.

I’m not sure.  I agree it would be bad style to use `as` here.  But I’m not 
sure if it should be banned or not.

> 
> If this proposal isn't accepted, disallow using literal values as the 
> argument to one-unlabeled-argument constructors.

I don’t know about this.  It says that if you want users to initialize your 
type with an unlabeled argument that has a type which has a corresponding 
literal you *must* conform to the corresponding literal convertible protocol.  
Do we really want to require that?  Maybe, but maybe not.  We definitely 
*should not* allow such an initializer to be written if it cannot be called 
with a literal.

For example, if I have:

`init(_ a: [String])`

users could call the initializer with an array variable but not a array 
literal.  That would be very bad IMO.  Either this initializer is banned 
altogether, or we allow it to be called with a literal. 

FWIW, there are types in the standard library with overlapping initializers in 
this new model:

public init(_ value: UInt8)
public init(integerLiteral value: UInt8)

I’m not sure whether they actually need to do different things or whether they 
are just provided so you can initialize the type with a variable and also use 
literals in a context expecting that type.

I think it’s important to understand whether overlap like this is necessary or 
not.  If behavior should always be identical I am in favor of refactoring the 
literal convertible protocols as part of this change.

> 
> In either case we should disabuse users of the notion that A(literal) is an 
> initializer that behaves exactly the same as other initializers.
> 
> Austin
> 
> On Thu, Jun 2, 2016 at 11:46 AM, Austin Zheng  > wrote:
> +1.
> 
> The primary advantage is that it aligns the language semantics with how most 
> programmers expect this common C-language-family idiom to behave and removes 
> a potential source of silently wrong code.
> 
> The primary disadvantage is that it introduces special-case behavior to 
> certain types of initializers (although, to be fair, this special-case 
> behavior is easily recognizable: unlabeled one-argument initializer with a 
> literal as the argument).
> 
> I think the advantage outweighs the disadvantage.
> 
> This problem should be addressed one way or another. I prefer this solution, 
> but if it is rejected for whatever reason we should at least explicitly 
> outlaw A(literal) syntax in favor of "literal as A".
> 
> Austin
> 
> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution 
> > wrote:
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Austin Zheng via swift-evolution
On Thu, Jun 2, 2016 at 12:11 PM, Xiaodi Wu  wrote:

> +1 to the proposal. I can also see the argument for disallowing multiple
> ways of doing the same thing, though disallowing the use of `as` in this
> way might be introducing another special case.
>
>
The "as", "as?" and "as!" operators in Swift are already surprisingly
overloaded.  Joe Groff's proposal lists 9 (!!!) different things "as?" does
here:
https://github.com/apple/swift-evolution/blob/master/proposals/0083-remove-bridging-from-dynamic-casts.md
.

"as" is also overloaded in this sense. It performs bridging casts (soon to
go away?), upcasts that can never fail (e.g. subclass to superclass), and
defining the concrete type of a literal expression. It wouldn't be a big
loss for "as" to lose the last meaning.



> If the proposal is accepted, I'd also advocate for the suggestion in the
> initial proposal to apply the rule regardless of the number of parentheses,
> so that `A((B))` behaves the same way as `A(B)`.
>

+1. Yes please.


>
> On Thu, Jun 2, 2016 at 1:55 PM, Austin Zheng via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> I think we should actually go further.
>>
>> If this proposal is accepted, disallow "as" as a way of specifying the
>> type to construct from a literal.
>>
>> If this proposal isn't accepted, disallow using literal values as the
>> argument to one-unlabeled-argument constructors.
>>
>> In either case we should disabuse users of the notion that A(literal) is
>> an initializer that behaves exactly the same as other initializers.
>>
>> Austin
>>
>> On Thu, Jun 2, 2016 at 11:46 AM, Austin Zheng 
>> wrote:
>>
>>> +1.
>>>
>>> The primary advantage is that it aligns the language semantics with how
>>> most programmers expect this common C-language-family idiom to behave and
>>> removes a potential source of silently wrong code.
>>>
>>> The primary disadvantage is that it introduces special-case behavior to
>>> certain types of initializers (although, to be fair, this special-case
>>> behavior is easily recognizable: unlabeled one-argument initializer with a
>>> literal as the argument).
>>>
>>> I think the advantage outweighs the disadvantage.
>>>
>>> This problem should be addressed one way or another. I prefer this
>>> solution, but if it is rejected for whatever reason we should at least
>>> explicitly outlaw A(literal) syntax in favor of "literal as A".
>>>
>>> Austin
>>>
>>> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 The official way to build a literal of a specific type is to write the
 literal in an explicitly-typed context, like so:
 let x: UInt16 = 7
 or
 let x = 7 as UInt16

 Nonetheless, programmers often try the following:
 UInt16(7)

 Unfortunately, this does *not* attempt to construct the value using
 the appropriate literal protocol; it instead performs overload resolution
 using the standard rules, i.e. considering only single-argument unlabelled
 initializers of a type which conforms to IntegerLiteralConvertible.  Often
 this leads to static ambiguities or, worse, causes the literal to be built
 using a default type (such as Int); this may have semantically very
 different results which are only caught at runtime.

 In my opinion, using this initializer-call syntax to build an
 explicitly-typed literal is an obvious and natural choice with several
 advantages over the "as" syntax.  However, even if you disagree, it's clear
 that programmers are going to continue to independently try to use it, so
 it's really unfortunate for it to be subtly wrong.

 Therefore, I propose that we adopt the following typing rule:

   Given a function call expression of the form A(B) (that is, an
 *expr-call* with a single, unlabelled argument) where B is an
 *expr-literal* or *expr-collection*, if A has type T.Type for some
 type T and there is a declared conformance of T to an appropriate literal
 protocol for B, then the expression is always resolves as a literal
 construction of type T (as if the expression were written "B as A") rather
 than as a general initializer call.

 Formally, this would be a special form of the argument conversion
 constraint, since the type of the expression A may not be immediately 
 known.

 Note that, as specified, it is possible to suppress this typing rule by
 wrapping the literal in parentheses.  This might seem distasteful; it would
 be easy enough to allow the form of B to include extra parentheses.  It's
 potentially useful to have a way to suppress this rule and get a normal
 construction, but there are several other ways of getting that effect, such
 as explicitly typing the literal argument (e.g. writing "A(Int(B))").

 A conditional conformance counts as a declared conformance 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread David Waite via swift-evolution
Would it be possible to have a warning on usage if there is an ambiguity here?

Otherwise, if we want T(0) to work, shouldn't we change the initializer 
signatures for LiteralConvertibles to match the desired behavior, rather than 
make it a special case?

-DW

> On Jun 2, 2016, at 1:57 PM, John McCall via swift-evolution 
>  wrote:
> 
>> On Jun 2, 2016, at 10:49 AM, David Sweeris > > wrote:
>> I’m not entirely sure what an “expr-collection” is.
> 
> Collection literals, e.g. [x,y,z] and [a: x, b: y].
> 
>> Does your proposal mean that in this code:
>> func foo() -> Int {...}
>> var w = 0
>> var x = T(foo())
>> var y = T(w)
>> var z = T(0)
>> different initializers would be used for `x`,`y`, and `z`?
> 
> z would be initialized using the literal initializer if T conforms to that 
> protocol, yes.
> 
>> If so, that seems a potential source of much subtler problems.
> 
> Note that this is only an issue for types that conform to the literal 
> protocols.
> 
>> I don’t disagree that you’ve identified a potential source of issues, but 
>> it’s conceivable that there might be circumstances where the "semantically 
>> very different results” are desired. I can’t think of any off the top of my 
>> head, but I’m not convinced that means they don’t exist.
> 
> I do not think that anybody writes UInt64(0) and *wants* the 0 to be built as 
> an Int and then coerced to UInt64.
> 
> John.
> 
>> 
>> So… I’m tentatively -1
>> 
>> - Dave Sweeris
>> 
>>> On Jun 2, 2016, at 11:08 AM, John McCall via swift-evolution 
>>> > wrote:
>>> 
>>> The official way to build a literal of a specific type is to write the 
>>> literal in an explicitly-typed context, like so:
>>> let x: UInt16 = 7
>>> or
>>> let x = 7 as UInt16
>>> 
>>> Nonetheless, programmers often try the following:
>>> UInt16(7)
>>> 
>>> Unfortunately, this does not attempt to construct the value using the 
>>> appropriate literal protocol; it instead performs overload resolution using 
>>> the standard rules, i.e. considering only single-argument unlabelled 
>>> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
>>> this leads to static ambiguities or, worse, causes the literal to be built 
>>> using a default type (such as Int); this may have semantically very 
>>> different results which are only caught at runtime.
>>> 
>>> In my opinion, using this initializer-call syntax to build an 
>>> explicitly-typed literal is an obvious and natural choice with several 
>>> advantages over the "as" syntax.  However, even if you disagree, it's clear 
>>> that programmers are going to continue to independently try to use it, so 
>>> it's really unfortunate for it to be subtly wrong.
>>> 
>>> Therefore, I propose that we adopt the following typing rule:
>>> 
>>>   Given a function call expression of the form A(B) (that is, an expr-call 
>>> with a single, unlabelled argument) where B is an expr-literal or 
>>> expr-collection, if A has type T.Type for some type T and there is a 
>>> declared conformance of T to an appropriate literal protocol for B, then 
>>> the expression is always resolves as a literal construction of type T (as 
>>> if the expression were written "B as A") rather than as a general 
>>> initializer call.
>>> 
>>> Formally, this would be a special form of the argument conversion 
>>> constraint, since the type of the expression A may not be immediately known.
>>> 
>>> Note that, as specified, it is possible to suppress this typing rule by 
>>> wrapping the literal in parentheses.  This might seem distasteful; it would 
>>> be easy enough to allow the form of B to include extra parentheses.  It's 
>>> potentially useful to have a way to suppress this rule and get a normal 
>>> construction, but there are several other ways of getting that effect, such 
>>> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>>> 
>>> A conditional conformance counts as a declared conformance even if the 
>>> generic arguments are known to not satisfy the conditional conformance.  
>>> This permits the applicability of the rule to be decided without having to 
>>> first decide the type arguments, which greatly simplifies the type-checking 
>>> problem (and may be necessary for soundness; I didn't explore this in 
>>> depth, but it certainly feels like a very nasty sort of dependence).  We 
>>> could potentially weaken this for cases where A is a direct type reference 
>>> with bound parameters, e.g. Foo([]) or the same with a typealias, but 
>>> I think there's some benefit from having a simpler specification, both for 
>>> the implementation and for the explicability of the model.
>>> 
>>> John.
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Xiaodi Wu via swift-evolution
+1 to the proposal. I can also see the argument for disallowing multiple
ways of doing the same thing, though disallowing the use of `as` in this
way might be introducing another special case.

If the proposal is accepted, I'd also advocate for the suggestion in the
initial proposal to apply the rule regardless of the number of parentheses,
so that `A((B))` behaves the same way as `A(B)`.

On Thu, Jun 2, 2016 at 1:55 PM, Austin Zheng via swift-evolution <
swift-evolution@swift.org> wrote:

> I think we should actually go further.
>
> If this proposal is accepted, disallow "as" as a way of specifying the
> type to construct from a literal.
>
> If this proposal isn't accepted, disallow using literal values as the
> argument to one-unlabeled-argument constructors.
>
> In either case we should disabuse users of the notion that A(literal) is
> an initializer that behaves exactly the same as other initializers.
>
> Austin
>
> On Thu, Jun 2, 2016 at 11:46 AM, Austin Zheng 
> wrote:
>
>> +1.
>>
>> The primary advantage is that it aligns the language semantics with how
>> most programmers expect this common C-language-family idiom to behave and
>> removes a potential source of silently wrong code.
>>
>> The primary disadvantage is that it introduces special-case behavior to
>> certain types of initializers (although, to be fair, this special-case
>> behavior is easily recognizable: unlabeled one-argument initializer with a
>> literal as the argument).
>>
>> I think the advantage outweighs the disadvantage.
>>
>> This problem should be addressed one way or another. I prefer this
>> solution, but if it is rejected for whatever reason we should at least
>> explicitly outlaw A(literal) syntax in favor of "literal as A".
>>
>> Austin
>>
>> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> The official way to build a literal of a specific type is to write the
>>> literal in an explicitly-typed context, like so:
>>> let x: UInt16 = 7
>>> or
>>> let x = 7 as UInt16
>>>
>>> Nonetheless, programmers often try the following:
>>> UInt16(7)
>>>
>>> Unfortunately, this does *not* attempt to construct the value using the
>>> appropriate literal protocol; it instead performs overload resolution using
>>> the standard rules, i.e. considering only single-argument unlabelled
>>> initializers of a type which conforms to IntegerLiteralConvertible.  Often
>>> this leads to static ambiguities or, worse, causes the literal to be built
>>> using a default type (such as Int); this may have semantically very
>>> different results which are only caught at runtime.
>>>
>>> In my opinion, using this initializer-call syntax to build an
>>> explicitly-typed literal is an obvious and natural choice with several
>>> advantages over the "as" syntax.  However, even if you disagree, it's clear
>>> that programmers are going to continue to independently try to use it, so
>>> it's really unfortunate for it to be subtly wrong.
>>>
>>> Therefore, I propose that we adopt the following typing rule:
>>>
>>>   Given a function call expression of the form A(B) (that is, an
>>> *expr-call* with a single, unlabelled argument) where B is an
>>> *expr-literal* or *expr-collection*, if A has type T.Type for some type
>>> T and there is a declared conformance of T to an appropriate literal
>>> protocol for B, then the expression is always resolves as a literal
>>> construction of type T (as if the expression were written "B as A") rather
>>> than as a general initializer call.
>>>
>>> Formally, this would be a special form of the argument conversion
>>> constraint, since the type of the expression A may not be immediately known.
>>>
>>> Note that, as specified, it is possible to suppress this typing rule by
>>> wrapping the literal in parentheses.  This might seem distasteful; it would
>>> be easy enough to allow the form of B to include extra parentheses.  It's
>>> potentially useful to have a way to suppress this rule and get a normal
>>> construction, but there are several other ways of getting that effect, such
>>> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>>>
>>> A conditional conformance counts as a declared conformance even if the
>>> generic arguments are known to not satisfy the conditional conformance.
>>> This permits the applicability of the rule to be decided without having to
>>> first decide the type arguments, which greatly simplifies the type-checking
>>> problem (and may be necessary for soundness; I didn't explore this in
>>> depth, but it certainly feels like a very nasty sort of dependence).  We
>>> could potentially weaken this for cases where A is a direct type reference
>>> with bound parameters, e.g. Foo([]) or the same with a typealias, but
>>> I think there's some benefit from having a simpler specification, both for
>>> the implementation and for the explicability of the model.
>>>
>>> John.
>>>
>>> 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 1:46 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> +1.
> 
> The primary advantage is that it aligns the language semantics with how most 
> programmers expect this common C-language-family idiom to behave and removes 
> a potential source of silently wrong code.
> 
> The primary disadvantage is that it introduces special-case behavior to 
> certain types of initializers (although, to be fair, this special-case 
> behavior is easily recognizable: unlabeled one-argument initializer with a 
> literal as the argument).
> 
> I think the advantage outweighs the disadvantage.

Agree.  This change basically means the label isn’t intended to be used by 
callers, but is only present to distinguish the initializer used by the 
protocol from any other unlabeled initializer accepting the same type.  But 
conceptually it is treated as the *most specific* unlabelled initializer 
possible, thus winning the overload resolution.

How important is it that we have the ability to distinguish between literals 
and non-literals with the same type?  If that isn’t important, maybe the 
literal convertible protocols could be reworked such that the label isn’t 
necessary.  That would eliminate the special-case elision of the label.

> 
> This problem should be addressed one way or another. I prefer this solution, 
> but if it is rejected for whatever reason we should at least explicitly 
> outlaw A(literal) syntax in favor of "literal as A".
> 
> Austin
> 
> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution 
> > wrote:
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect, such 
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
> 
> A conditional conformance counts as a declared conformance even if the 
> generic arguments are known to not satisfy the conditional conformance.  This 
> permits the applicability of the rule to be decided without having to first 
> decide the type arguments, which greatly simplifies the type-checking problem 
> (and may be necessary for soundness; I didn't explore this in depth, but it 
> certainly feels like a very nasty sort of dependence).  We could potentially 
> weaken this for cases where A is a direct type reference with bound 
> parameters, e.g. Foo([]) or the same with a typealias, but I think 
> there's some benefit from having a simpler specification, both for the 
> implementation and for the explicability of the model.
> 
> John.
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> 
> ___
> 

Re: [swift-evolution] Ad hoc enums / options

2016-06-02 Thread Ricardo Parada via swift-evolution
Hi Laurent,

Do you have the details of your proposal, I missed it. 

Thanks

> On Jun 2, 2016, at 1:48 AM, L Mihalkovic  wrote:
> 
> 
>>> On Jun 2, 2016, at 5:05 AM, Christopher Kornher via swift-evolution 
>>>  wrote:
>>> 
>>> 
>> 
>>> On Jun 1, 2016, at 7:48 PM, Ricardo Parada via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> On May 31, 2016, at 3:04 PM, Erica Sadun via swift-evolution 
>>>  wrote:
>>> 
 let _ = scaleAndCropImage(image: myImage, toSize: size, operation: .fill)
 
 You would not be able to assign `.fill` to a variable and use that for the 
 operation value.
>>> 
>>> This is my objection to this idea. It does not encourage reuse.
>> 
>> -1For me too. Introducing this quasi-enum would increase cognitive load with 
>> little, if any, net benefit. This is the sort of feature that looks great 
>> and works wonderfully in example apps, but does not scale well to real 
>> systems, where options show up in more methods through time, get passed 
>> around to helpers, stored, marshaled into various formats, etc.
>> 
>> As someone mentioned, this would probably be a good fit If Swift adopts a 
>> structural type system (I suppose, I have ever used a language with one to 
>> my knowledge, unless duck typing counts)
>> 
>> As syntactic sugar for a true enum declaration, it would be a “cool” 
>> feature, but reuse would still be problematic. 
> 
> 
> there is no reuse problem in the interpretation I propose, and the long/short 
> form names are completely interchangeable.
> 
>> 
>>> 
>>> I would not be able to assign to a variable:
>>> 
>>> let selectedOperation = .fill
>>> 
>>> In order to then do this later in the program:
>>> 
>>> scaleAndCropImage(image: myImage, toSize: size, operation: 
>>> selectedOperation)
>>> ___
>>> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Austin Zheng via swift-evolution
I think we should actually go further.

If this proposal is accepted, disallow "as" as a way of specifying the type
to construct from a literal.

If this proposal isn't accepted, disallow using literal values as the
argument to one-unlabeled-argument constructors.

In either case we should disabuse users of the notion that A(literal) is an
initializer that behaves exactly the same as other initializers.

Austin

On Thu, Jun 2, 2016 at 11:46 AM, Austin Zheng  wrote:

> +1.
>
> The primary advantage is that it aligns the language semantics with how
> most programmers expect this common C-language-family idiom to behave and
> removes a potential source of silently wrong code.
>
> The primary disadvantage is that it introduces special-case behavior to
> certain types of initializers (although, to be fair, this special-case
> behavior is easily recognizable: unlabeled one-argument initializer with a
> literal as the argument).
>
> I think the advantage outweighs the disadvantage.
>
> This problem should be addressed one way or another. I prefer this
> solution, but if it is rejected for whatever reason we should at least
> explicitly outlaw A(literal) syntax in favor of "literal as A".
>
> Austin
>
> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> The official way to build a literal of a specific type is to write the
>> literal in an explicitly-typed context, like so:
>> let x: UInt16 = 7
>> or
>> let x = 7 as UInt16
>>
>> Nonetheless, programmers often try the following:
>> UInt16(7)
>>
>> Unfortunately, this does *not* attempt to construct the value using the
>> appropriate literal protocol; it instead performs overload resolution using
>> the standard rules, i.e. considering only single-argument unlabelled
>> initializers of a type which conforms to IntegerLiteralConvertible.  Often
>> this leads to static ambiguities or, worse, causes the literal to be built
>> using a default type (such as Int); this may have semantically very
>> different results which are only caught at runtime.
>>
>> In my opinion, using this initializer-call syntax to build an
>> explicitly-typed literal is an obvious and natural choice with several
>> advantages over the "as" syntax.  However, even if you disagree, it's clear
>> that programmers are going to continue to independently try to use it, so
>> it's really unfortunate for it to be subtly wrong.
>>
>> Therefore, I propose that we adopt the following typing rule:
>>
>>   Given a function call expression of the form A(B) (that is, an
>> *expr-call* with a single, unlabelled argument) where B is an
>> *expr-literal* or *expr-collection*, if A has type T.Type for some type
>> T and there is a declared conformance of T to an appropriate literal
>> protocol for B, then the expression is always resolves as a literal
>> construction of type T (as if the expression were written "B as A") rather
>> than as a general initializer call.
>>
>> Formally, this would be a special form of the argument conversion
>> constraint, since the type of the expression A may not be immediately known.
>>
>> Note that, as specified, it is possible to suppress this typing rule by
>> wrapping the literal in parentheses.  This might seem distasteful; it would
>> be easy enough to allow the form of B to include extra parentheses.  It's
>> potentially useful to have a way to suppress this rule and get a normal
>> construction, but there are several other ways of getting that effect, such
>> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>>
>> A conditional conformance counts as a declared conformance even if the
>> generic arguments are known to not satisfy the conditional conformance.
>> This permits the applicability of the rule to be decided without having to
>> first decide the type arguments, which greatly simplifies the type-checking
>> problem (and may be necessary for soundness; I didn't explore this in
>> depth, but it certainly feels like a very nasty sort of dependence).  We
>> could potentially weaken this for cases where A is a direct type reference
>> with bound parameters, e.g. Foo([]) or the same with a typealias, but
>> I think there's some benefit from having a simpler specification, both for
>> the implementation and for the explicability of the model.
>>
>> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Sean Heber via swift-evolution
+1

l8r
Sean


> On Jun 2, 2016, at 1:46 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> +1.
> 
> The primary advantage is that it aligns the language semantics with how most 
> programmers expect this common C-language-family idiom to behave and removes 
> a potential source of silently wrong code.
> 
> The primary disadvantage is that it introduces special-case behavior to 
> certain types of initializers (although, to be fair, this special-case 
> behavior is easily recognizable: unlabeled one-argument initializer with a 
> literal as the argument).
> 
> I think the advantage outweighs the disadvantage.
> 
> This problem should be addressed one way or another. I prefer this solution, 
> but if it is rejected for whatever reason we should at least explicitly 
> outlaw A(literal) syntax in favor of "literal as A".
> 
> Austin
> 
> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution 
>  wrote:
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect, such 
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
> 
> A conditional conformance counts as a declared conformance even if the 
> generic arguments are known to not satisfy the conditional conformance.  This 
> permits the applicability of the rule to be decided without having to first 
> decide the type arguments, which greatly simplifies the type-checking problem 
> (and may be necessary for soundness; I didn't explore this in depth, but it 
> certainly feels like a very nasty sort of dependence).  We could potentially 
> weaken this for cases where A is a direct type reference with bound 
> parameters, e.g. Foo([]) or the same with a typealias, but I think 
> there's some benefit from having a simpler specification, both for the 
> implementation and for the explicability of the model.
> 
> 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-evolution


Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Austin Zheng via swift-evolution
+1.

The primary advantage is that it aligns the language semantics with how
most programmers expect this common C-language-family idiom to behave and
removes a potential source of silently wrong code.

The primary disadvantage is that it introduces special-case behavior to
certain types of initializers (although, to be fair, this special-case
behavior is easily recognizable: unlabeled one-argument initializer with a
literal as the argument).

I think the advantage outweighs the disadvantage.

This problem should be addressed one way or another. I prefer this
solution, but if it is rejected for whatever reason we should at least
explicitly outlaw A(literal) syntax in favor of "literal as A".

Austin

On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution <
swift-evolution@swift.org> wrote:

> The official way to build a literal of a specific type is to write the
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
>
> Nonetheless, programmers often try the following:
> UInt16(7)
>
> Unfortunately, this does *not* attempt to construct the value using the
> appropriate literal protocol; it instead performs overload resolution using
> the standard rules, i.e. considering only single-argument unlabelled
> initializers of a type which conforms to IntegerLiteralConvertible.  Often
> this leads to static ambiguities or, worse, causes the literal to be built
> using a default type (such as Int); this may have semantically very
> different results which are only caught at runtime.
>
> In my opinion, using this initializer-call syntax to build an
> explicitly-typed literal is an obvious and natural choice with several
> advantages over the "as" syntax.  However, even if you disagree, it's clear
> that programmers are going to continue to independently try to use it, so
> it's really unfortunate for it to be subtly wrong.
>
> Therefore, I propose that we adopt the following typing rule:
>
>   Given a function call expression of the form A(B) (that is, an
> *expr-call* with a single, unlabelled argument) where B is an
> *expr-literal* or *expr-collection*, if A has type T.Type for some type T
> and there is a declared conformance of T to an appropriate literal protocol
> for B, then the expression is always resolves as a literal construction of
> type T (as if the expression were written "B as A") rather than as a
> general initializer call.
>
> Formally, this would be a special form of the argument conversion
> constraint, since the type of the expression A may not be immediately known.
>
> Note that, as specified, it is possible to suppress this typing rule by
> wrapping the literal in parentheses.  This might seem distasteful; it would
> be easy enough to allow the form of B to include extra parentheses.  It's
> potentially useful to have a way to suppress this rule and get a normal
> construction, but there are several other ways of getting that effect, such
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>
> A conditional conformance counts as a declared conformance even if the
> generic arguments are known to not satisfy the conditional conformance.
> This permits the applicability of the rule to be decided without having to
> first decide the type arguments, which greatly simplifies the type-checking
> problem (and may be necessary for soundness; I didn't explore this in
> depth, but it certainly feels like a very nasty sort of dependence).  We
> could potentially weaken this for cases where A is a direct type reference
> with bound parameters, e.g. Foo([]) or the same with a typealias, but
> I think there's some benefit from having a simpler specification, both for
> the implementation and for the explicability of the model.
>
> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Matthew Johnson via swift-evolution
+1 to this.  It seems like a very straightforward thing to do.

Sent from my iPad

> On Jun 2, 2016, at 11:08 AM, John McCall via swift-evolution 
>  wrote:
> 
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect, such 
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
> 
> A conditional conformance counts as a declared conformance even if the 
> generic arguments are known to not satisfy the conditional conformance.  This 
> permits the applicability of the rule to be decided without having to first 
> decide the type arguments, which greatly simplifies the type-checking problem 
> (and may be necessary for soundness; I didn't explore this in depth, but it 
> certainly feels like a very nasty sort of dependence).  We could potentially 
> weaken this for cases where A is a direct type reference with bound 
> parameters, e.g. Foo([]) or the same with a typealias, but I think 
> there's some benefit from having a simpler specification, both for the 
> implementation and for the explicability of the model.
> 
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 11:22 AM, Matthew Johnson  wrote:
> On Jun 2, 2016, at 12:01 PM, John McCall  > wrote:
> 
>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution 
>>> > wrote:
 On Jun 2, 2016, at 10:38 AM, Xiaodi Wu > wrote:
 
 Well, as I understand it, it's not actually possible to write your own 
 type(of:), so we're going from a "magic" property to a "magic" function at 
 least for now.
>>> 
>>> No, but you *can* write `func foo(_ t: T)` which accepts any value (you 
>>> *cannot* write a property that is available for all properties - that would 
>>> require the ability to write `extension Any`.  This is the distinction I am 
>>> making.  Of course the implementation is compiler magic no matter how we 
>>> express it syntactically.  But we can make it *appear* just like it might 
>>> if the implementation *wasn’t* compiler magic.  That makes it fit into the 
>>> language better IMO and was the biggest motivator for changing 
>>> `dynamicType`.
>>> 
 
 I'm most alarmed that one implication of the MemoryLayout proposal is loss 
 of the `ofValue` family of functions. These functions don't fit with the 
 design: imagine, what is `MemoryLayout.size(ofValue: Float(42))`? 
 But the response seems to be that these functions don't seem necessary at 
 all and should be removed. "I don't see a use for it" is an insufficient 
 justification for a feature removal. Looking to other languages, C# has 
 sizeof as a static property but tellingly offers the equivalent of 
 sizeofValue (well, strideofValue) as a function in a different module. 
 Essentially every other C-family language that exposes pointers to the 
 user offers both of and ofValue equivalents. The question is, how does a 
 user with existing code using sizeofValue() migrate to Swift 3? I do not 
 see a viable answer with the MemoryLayout design.
>>> 
>>> Going with MemoryLayout *does not* mean we would have to give up the value 
>>> functions if we don’t want to:
>>> 
>>> struct MemoryLayout {
>>> init() {}
>>> init(t: T) { /* throw away the value */ }
>>> 
>>> // we could omit the static properties and require 
>>> // writing MemoryLayout() if we don’t like the duplication
>>> static let size: Int
>>> static let spacing: Int
>>> static let alignment: Int
>>> 
>>> let size: Int
>>> let spacing: Int
>>> let alignment: Int
>>> }
>>> 
>>> let size = MemoryLayout.size
>>> let sizeOfValue = MemoryLayout(42).size
>> 
>> There's no good reason for this type to be generic.  It should be 
>> non-generic and require the use of the instance properties.
> 
> Dave's initial suggestion was generic and Joe suggested static properties.  I 
> suppose it doesn't have to be generic if we pass the type directly to the 
> initializer, but that design would eliminate the possibility of inferring the 
> type from a value (which some people seem to want to retain).
> 
> I didn't mean to advocate either way about adding a value initializer and 
> instance properties.  I was only trying to show that it is *possible* to do 
> that if we want to preserve the ofValue capabilities.
> 
>> 
>> It's actively harmful for this type to appear to be computed from a value.  
>> The layout is not in any way tied to the dynamic type of the value — for 
>> example, it is not the instance layout of the most-derived class or the 
>> value layout of the dynamic type of an existential.  
> 
> Understood, but that same problem exists for the current ofValue operations 
> doesn't it? We can discuss removing them (I am not opposed to that), but that 
> is independent of whether we should use a MemoryLayout struct as opposed to 
> free functions.

I'm not trying to dictate the entire design.  I'm saying that, if you're going 
to have a layout structure, I see no reason for it to be generic, and you 
should absolutely not make the primary way of constructing it be implicitly 
value-based.

I still think the value-based APIs are misleading and that it would be better 
to ask people to just use a type explicitly.

> Adding the label will eliminate the potential for confusion about type vs 
> metatype.  Wanting to know the size of the metatype is probably extremely 
> rare, but there is not reason to prohibit it.

I agree that the label makes the problem better.

John.

> 
>> 
>> John.
>> 
>>> 
 
 On Thu, Jun 2, 2016 at 8:03 AM Matthew Johnson > wrote:
 
 
 Sent from my iPad
 
 On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution 
 > wrote:
 
> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith  

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread Christopher Kornher via swift-evolution
+1
 I have started using the ‘()’ syntax without even thinking about it. I never 
knew that it behaved in the way described. Using ‘()’ syntax will be natural 
for anyone with C++ experience.


> On Jun 2, 2016, at 10:08 AM, John McCall via swift-evolution 
>  wrote:
> 
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect, such 
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
> 
> A conditional conformance counts as a declared conformance even if the 
> generic arguments are known to not satisfy the conditional conformance.  This 
> permits the applicability of the rule to be decided without having to first 
> decide the type arguments, which greatly simplifies the type-checking problem 
> (and may be necessary for soundness; I didn't explore this in depth, but it 
> certainly feels like a very nasty sort of dependence).  We could potentially 
> weaken this for cases where A is a direct type reference with bound 
> parameters, e.g. Foo([]) or the same with a typealias, but I think 
> there's some benefit from having a simpler specification, both for the 
> implementation and for the explicability of the model.
> 
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 12:01 PM, John McCall  wrote:
> 
>>> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu  wrote:
>>> 
>>> Well, as I understand it, it's not actually possible to write your own 
>>> type(of:), so we're going from a "magic" property to a "magic" function at 
>>> least for now.
>> 
>> No, but you *can* write `func foo(_ t: T)` which accepts any value (you 
>> *cannot* write a property that is available for all properties - that would 
>> require the ability to write `extension Any`.  This is the distinction I am 
>> making.  Of course the implementation is compiler magic no matter how we 
>> express it syntactically.  But we can make it *appear* just like it might if 
>> the implementation *wasn’t* compiler magic.  That makes it fit into the 
>> language better IMO and was the biggest motivator for changing `dynamicType`.
>> 
>>> 
>>> I'm most alarmed that one implication of the MemoryLayout proposal is loss 
>>> of the `ofValue` family of functions. These functions don't fit with the 
>>> design: imagine, what is `MemoryLayout.size(ofValue: Float(42))`? 
>>> But the response seems to be that these functions don't seem necessary at 
>>> all and should be removed. "I don't see a use for it" is an insufficient 
>>> justification for a feature removal. Looking to other languages, C# has 
>>> sizeof as a static property but tellingly offers the equivalent of 
>>> sizeofValue (well, strideofValue) as a function in a different module. 
>>> Essentially every other C-family language that exposes pointers to the user 
>>> offers both of and ofValue equivalents. The question is, how does a user 
>>> with existing code using sizeofValue() migrate to Swift 3? I do not see a 
>>> viable answer with the MemoryLayout design.
>> 
>> Going with MemoryLayout *does not* mean we would have to give up the value 
>> functions if we don’t want to:
>> 
>> struct MemoryLayout {
>> init() {}
>> init(t: T) { /* throw away the value */ }
>> 
>> // we could omit the static properties and require 
>> // writing MemoryLayout() if we don’t like the duplication
>> static let size: Int
>> static let spacing: Int
>> static let alignment: Int
>> 
>> let size: Int
>> let spacing: Int
>> let alignment: Int
>> }
>> 
>> let size = MemoryLayout.size
>> let sizeOfValue = MemoryLayout(42).size
> 
> There's no good reason for this type to be generic.  It should be non-generic 
> and require the use of the instance properties.

Dave's initial suggestion was generic and Joe suggested static properties.  I 
suppose it doesn't have to be generic if we pass the type directly to the 
initializer, but that design would eliminate the possibility of inferring the 
type from a value (which some people seem to want to retain).

I didn't mean to advocate either way about adding a value initializer and 
instance properties.  I was only trying to show that it is *possible* to do 
that if we want to preserve the ofValue capabilities.

> 
> It's actively harmful for this type to appear to be computed from a value.  
> The layout is not in any way tied to the dynamic type of the value — for 
> example, it is not the instance layout of the most-derived class or the value 
> layout of the dynamic type of an existential.  

Understood, but that same problem exists for the current ofValue operations 
doesn't it? We can discuss removing them (I am not opposed to that), but that 
is independent of whether we should use a MemoryLayout struct as opposed to 
free functions.

> Furthermore, saying that it is computed from a value means that attempting to 
> compute it from a type will succeed using the layout of the metatype, which 
> seems like a catastrophic failure of API design.

I was a bit hasty with the argument label and my example calling code wouldn't 
have actually worked.  I should have included a clear external label.

This is what we would want to actually do (Erica, can you update again?):

init(ofValue: @autoclosure () -> T) { }

Used like this:

let sizeOfValue = MemoryLayout(ofValue: 42).size

Adding the label will eliminate the potential for confusion about type vs 
metatype.  Wanting to know the size of the metatype is probably extremely rare, 
but there is not reason to prohibit it.

> 
> John.
> 
>> 
>>> 
 On Thu, Jun 2, 2016 at 8:03 AM Matthew Johnson  
 wrote:
 
 
 Sent from my iPad
 
> On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
>> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith  
>> wrote:
>> I really like this idea. This IMO is lower level functionality than 
>> `type(of:)` (née dynamicType), so I think it makes sense for it to be 
>> grouped under its own domain, the MemoryLayout 

Re: [swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 10:49 AM, David Sweeris  wrote:
> I’m not entirely sure what an “expr-collection” is.

Collection literals, e.g. [x,y,z] and [a: x, b: y].

> Does your proposal mean that in this code:
> func foo() -> Int {...}
> var w = 0
> var x = T(foo())
> var y = T(w)
> var z = T(0)
> different initializers would be used for `x`,`y`, and `z`?

z would be initialized using the literal initializer if T conforms to that 
protocol, yes.

> If so, that seems a potential source of much subtler problems.

Note that this is only an issue for types that conform to the literal protocols.

> I don’t disagree that you’ve identified a potential source of issues, but 
> it’s conceivable that there might be circumstances where the "semantically 
> very different results” are desired. I can’t think of any off the top of my 
> head, but I’m not convinced that means they don’t exist.

I do not think that anybody writes UInt64(0) and *wants* the 0 to be built as 
an Int and then coerced to UInt64.

John.

> 
> So… I’m tentatively -1
> 
> - Dave Sweeris
> 
>> On Jun 2, 2016, at 11:08 AM, John McCall via swift-evolution 
>> > wrote:
>> 
>> The official way to build a literal of a specific type is to write the 
>> literal in an explicitly-typed context, like so:
>> let x: UInt16 = 7
>> or
>> let x = 7 as UInt16
>> 
>> Nonetheless, programmers often try the following:
>> UInt16(7)
>> 
>> Unfortunately, this does not attempt to construct the value using the 
>> appropriate literal protocol; it instead performs overload resolution using 
>> the standard rules, i.e. considering only single-argument unlabelled 
>> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
>> this leads to static ambiguities or, worse, causes the literal to be built 
>> using a default type (such as Int); this may have semantically very 
>> different results which are only caught at runtime.
>> 
>> In my opinion, using this initializer-call syntax to build an 
>> explicitly-typed literal is an obvious and natural choice with several 
>> advantages over the "as" syntax.  However, even if you disagree, it's clear 
>> that programmers are going to continue to independently try to use it, so 
>> it's really unfortunate for it to be subtly wrong.
>> 
>> Therefore, I propose that we adopt the following typing rule:
>> 
>>   Given a function call expression of the form A(B) (that is, an expr-call 
>> with a single, unlabelled argument) where B is an expr-literal or 
>> expr-collection, if A has type T.Type for some type T and there is a 
>> declared conformance of T to an appropriate literal protocol for B, then the 
>> expression is always resolves as a literal construction of type T (as if the 
>> expression were written "B as A") rather than as a general initializer call.
>> 
>> Formally, this would be a special form of the argument conversion 
>> constraint, since the type of the expression A may not be immediately known.
>> 
>> Note that, as specified, it is possible to suppress this typing rule by 
>> wrapping the literal in parentheses.  This might seem distasteful; it would 
>> be easy enough to allow the form of B to include extra parentheses.  It's 
>> potentially useful to have a way to suppress this rule and get a normal 
>> construction, but there are several other ways of getting that effect, such 
>> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>> 
>> A conditional conformance counts as a declared conformance even if the 
>> generic arguments are known to not satisfy the conditional conformance.  
>> This permits the applicability of the rule to be decided without having to 
>> first decide the type arguments, which greatly simplifies the type-checking 
>> problem (and may be necessary for soundness; I didn't explore this in depth, 
>> but it certainly feels like a very nasty sort of dependence).  We could 
>> potentially weaken this for cases where A is a direct type reference with 
>> bound parameters, e.g. Foo([]) or the same with a typealias, but I 
>> think there's some benefit from having a simpler specification, both for the 
>> implementation and for the explicability of the model.
>> 
>> 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] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread David Sweeris via swift-evolution
I’m not entirely sure what an “expr-collection” is. Does your proposal mean 
that in this code:
func foo() -> Int {...}
var w = 0
var x = T(foo())
var y = T(w)
var z = T(0)
different initializers would be used for `x`,`y`, and `z`? If so, that seems a 
potential source of much subtler problems.

I don’t disagree that you’ve identified a potential source of issues, but it’s 
conceivable that there might be circumstances where the "semantically very 
different results” are desired. I can’t think of any off the top of my head, 
but I’m not convinced that means they don’t exist.

So… I’m tentatively -1

- Dave Sweeris

> On Jun 2, 2016, at 11:08 AM, John McCall via swift-evolution 
>  wrote:
> 
> The official way to build a literal of a specific type is to write the 
> literal in an explicitly-typed context, like so:
> let x: UInt16 = 7
> or
> let x = 7 as UInt16
> 
> Nonetheless, programmers often try the following:
> UInt16(7)
> 
> Unfortunately, this does not attempt to construct the value using the 
> appropriate literal protocol; it instead performs overload resolution using 
> the standard rules, i.e. considering only single-argument unlabelled 
> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
> this leads to static ambiguities or, worse, causes the literal to be built 
> using a default type (such as Int); this may have semantically very different 
> results which are only caught at runtime.
> 
> In my opinion, using this initializer-call syntax to build an 
> explicitly-typed literal is an obvious and natural choice with several 
> advantages over the "as" syntax.  However, even if you disagree, it's clear 
> that programmers are going to continue to independently try to use it, so 
> it's really unfortunate for it to be subtly wrong.
> 
> Therefore, I propose that we adopt the following typing rule:
> 
>   Given a function call expression of the form A(B) (that is, an expr-call 
> with a single, unlabelled argument) where B is an expr-literal or 
> expr-collection, if A has type T.Type for some type T and there is a declared 
> conformance of T to an appropriate literal protocol for B, then the 
> expression is always resolves as a literal construction of type T (as if the 
> expression were written "B as A") rather than as a general initializer call.
> 
> Formally, this would be a special form of the argument conversion constraint, 
> since the type of the expression A may not be immediately known.
> 
> Note that, as specified, it is possible to suppress this typing rule by 
> wrapping the literal in parentheses.  This might seem distasteful; it would 
> be easy enough to allow the form of B to include extra parentheses.  It's 
> potentially useful to have a way to suppress this rule and get a normal 
> construction, but there are several other ways of getting that effect, such 
> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
> 
> A conditional conformance counts as a declared conformance even if the 
> generic arguments are known to not satisfy the conditional conformance.  This 
> permits the applicability of the rule to be decided without having to first 
> decide the type arguments, which greatly simplifies the type-checking problem 
> (and may be necessary for soundness; I didn't explore this in depth, but it 
> certainly feels like a very nasty sort of dependence).  We could potentially 
> weaken this for cases where A is a direct type reference with bound 
> parameters, e.g. Foo([]) or the same with a typealias, but I think 
> there's some benefit from having a simpler specification, both for the 
> implementation and for the explicability of the model.
> 
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread John McCall via swift-evolution
> On Jun 2, 2016, at 8:48 AM, Matthew Johnson via swift-evolution 
>  wrote:
>> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu > > wrote:
>> 
>> Well, as I understand it, it's not actually possible to write your own 
>> type(of:), so we're going from a "magic" property to a "magic" function at 
>> least for now.
> 
> No, but you *can* write `func foo(_ t: T)` which accepts any value (you 
> *cannot* write a property that is available for all properties - that would 
> require the ability to write `extension Any`.  This is the distinction I am 
> making.  Of course the implementation is compiler magic no matter how we 
> express it syntactically.  But we can make it *appear* just like it might if 
> the implementation *wasn’t* compiler magic.  That makes it fit into the 
> language better IMO and was the biggest motivator for changing `dynamicType`.
> 
>> 
>> I'm most alarmed that one implication of the MemoryLayout proposal is loss 
>> of the `ofValue` family of functions. These functions don't fit with the 
>> design: imagine, what is `MemoryLayout.size(ofValue: Float(42))`? 
>> But the response seems to be that these functions don't seem necessary at 
>> all and should be removed. "I don't see a use for it" is an insufficient 
>> justification for a feature removal. Looking to other languages, C# has 
>> sizeof as a static property but tellingly offers the equivalent of 
>> sizeofValue (well, strideofValue) as a function in a different module. 
>> Essentially every other C-family language that exposes pointers to the user 
>> offers both of and ofValue equivalents. The question is, how does a user 
>> with existing code using sizeofValue() migrate to Swift 3? I do not see a 
>> viable answer with the MemoryLayout design.
> 
> Going with MemoryLayout *does not* mean we would have to give up the value 
> functions if we don’t want to:
> 
> struct MemoryLayout {
> init() {}
> init(t: T) { /* throw away the value */ }
> 
> // we could omit the static properties and require 
> // writing MemoryLayout() if we don’t like the duplication
> static let size: Int
> static let spacing: Int
> static let alignment: Int
> 
> let size: Int
> let spacing: Int
> let alignment: Int
> }
> 
> let size = MemoryLayout.size
> let sizeOfValue = MemoryLayout(42).size

There's no good reason for this type to be generic.  It should be non-generic 
and require the use of the instance properties.

It's actively harmful for this type to appear to be computed from a value.  The 
layout is not in any way tied to the dynamic type of the value — for example, 
it is not the instance layout of the most-derived class or the value layout of 
the dynamic type of an existential.  Furthermore, saying that it is computed 
from a value means that attempting to compute it from a type will succeed using 
the layout of the metatype, which seems like a catastrophic failure of API 
design.

John.

> 
>> 
>> On Thu, Jun 2, 2016 at 8:03 AM Matthew Johnson > > wrote:
>> 
>> 
>> Sent from my iPad
>> 
>> On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>>> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith >> > wrote:
>>> I really like this idea. This IMO is lower level functionality than 
>>> `type(of:)` (née dynamicType), so I think it makes sense for it to be 
>>> grouped under its own domain, the MemoryLayout type.
>>> 
>>> Plus MemoryLayout can be extended with new convenience methods.
>>> 
>>> I’m fine with those old methods being removed, but I never use them so! Is 
>>> it the same as calling type(of:) then using that with MemoryLayout? I 
>>> imagine they could be fixit’d easily, and that they compile down to the 
>>> same underlying code.
>>> 
>>> I'm actually souring to the idea. It goes in the diametrically opposite 
>>> direction from dynamicType. There, something was changed from being 
>>> property-like to being function-like. Here, Dave's proposal would take 
>>> something that's a function and turn it into a property. Hmm.
>> 
>> That's not a fair comparison though.  With dynamicType we removed a "magic" 
>> property visible on all types, which isn't something you can write and 
>> turned it into a function (which is obviously something you can write).  
>> 
>> Dave's MemoryLayout creates a new type to bundle together related items 
>> which makes their semantic relationship more clear.  It also receives the 
>> type via a generic argument rather than a function argument and makes the 
>> properties static.  That is more representative of what is actually 
>> happening and could help to prevent confusion.  
>> 
>> If we really need an 'ofValue' option that infers T from a value the 
>> properties on MemoryLayout could also be made available 

[swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

2016-06-02 Thread John McCall via swift-evolution
The official way to build a literal of a specific type is to write the literal 
in an explicitly-typed context, like so:
let x: UInt16 = 7
or
let x = 7 as UInt16

Nonetheless, programmers often try the following:
UInt16(7)

Unfortunately, this does not attempt to construct the value using the 
appropriate literal protocol; it instead performs overload resolution using the 
standard rules, i.e. considering only single-argument unlabelled initializers 
of a type which conforms to IntegerLiteralConvertible.  Often this leads to 
static ambiguities or, worse, causes the literal to be built using a default 
type (such as Int); this may have semantically very different results which are 
only caught at runtime.

In my opinion, using this initializer-call syntax to build an explicitly-typed 
literal is an obvious and natural choice with several advantages over the "as" 
syntax.  However, even if you disagree, it's clear that programmers are going 
to continue to independently try to use it, so it's really unfortunate for it 
to be subtly wrong.

Therefore, I propose that we adopt the following typing rule:

  Given a function call expression of the form A(B) (that is, an expr-call with 
a single, unlabelled argument) where B is an expr-literal or expr-collection, 
if A has type T.Type for some type T and there is a declared conformance of T 
to an appropriate literal protocol for B, then the expression is always 
resolves as a literal construction of type T (as if the expression were written 
"B as A") rather than as a general initializer call.

Formally, this would be a special form of the argument conversion constraint, 
since the type of the expression A may not be immediately known.

Note that, as specified, it is possible to suppress this typing rule by 
wrapping the literal in parentheses.  This might seem distasteful; it would be 
easy enough to allow the form of B to include extra parentheses.  It's 
potentially useful to have a way to suppress this rule and get a normal 
construction, but there are several other ways of getting that effect, such as 
explicitly typing the literal argument (e.g. writing "A(Int(B))").

A conditional conformance counts as a declared conformance even if the generic 
arguments are known to not satisfy the conditional conformance.  This permits 
the applicability of the rule to be decided without having to first decide the 
type arguments, which greatly simplifies the type-checking problem (and may be 
necessary for soundness; I didn't explore this in depth, but it certainly feels 
like a very nasty sort of dependence).  We could potentially weaken this for 
cases where A is a direct type reference with bound parameters, e.g. 
Foo([]) or the same with a typealias, but I think there's some benefit 
from having a simpler specification, both for the implementation and for the 
explicability of the model.

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Erica Sadun via swift-evolution

> On Jun 2, 2016, at 10:12 AM, Matthew Johnson  wrote:
>> On Jun 2, 2016, at 11:04 AM, Erica Sadun > > wrote:
>>> On Jun 2, 2016, at 9:48 AM, Matthew Johnson via swift-evolution 
>>> > wrote:
>>> 
>>> struct MemoryLayout {
>>> init() {}
>>> init(t: T) { /* throw away the value */ }
>> 
>> And amended Alternatives with this. :)
> 
> Thanks!  Can you change the init signature with Pyry’s improvement: `init(_: 
> @autoclosure () -> T) {}`?

https://github.com/erica/swift-evolution/blob/sizestride/proposals/-sidestride.md

-- E

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 11:04 AM, Erica Sadun  wrote:
> 
> 
>> On Jun 2, 2016, at 9:48 AM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> struct MemoryLayout {
>> init() {}
>> init(t: T) { /* throw away the value */ }
>> 
>> // we could omit the static properties and require 
>> // writing MemoryLayout() if we don’t like the duplication
>> static let size: Int
>> static let spacing: Int
>> static let alignment: Int
>> 
>> let size: Int
>> let spacing: Int
>> let alignment: Int
>> }
>> 
>> let size = MemoryLayout.size
>> let sizeOfValue = MemoryLayout(42).size
> 
> And amended Alternatives with this. :)

Thanks!  Can you change the init signature with Pyry’s improvement: `init(_: 
@autoclosure () -> T) {}`?

> 
> - E
> 

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 11:04 AM, Pyry Jahkola  wrote:
> 
>> Matthew Johnson wrote:
>> 
>> Going with MemoryLayout *does not* mean we would have to give up the value 
>> functions if we don’t want to:
>> 
>> struct MemoryLayout {
>> init(t: T) { /* throw away the value */ }
>> // …
>> }
>> 
>> let sizeOfValue = MemoryLayout(42).size
> 
> You could also use @autoclosure here to avoid evaluating whatever expression 
> there is:
> 
> struct MemoryLayout {
> init(_: @autoclosure () -> T) {}
> // ...
> }

Brilliant!  Why didn’t I think of that? :-)

> 
> — Pyry
> 

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


Re: [swift-evolution] Ad hoc enums / options

2016-06-02 Thread Félix Cloutier via swift-evolution
You talked about the "compiler's point of view" and said about tuples that "the 
compiler never thinks that they are the same type". At which level is that true 
if we're not talking about the internal workings of the compiler?

There is consensus that Swift does not currently allow enums to be defined like 
tuples. Of course this is not how things work currently; we wouldn't be having 
a proposal otherwise! I don't see what this adds to the conversation. You could 
use that argument against any idea of future development.

Félix

> Le 1 juin 2016 à 23:25:10, L Mihalkovic  a 
> écrit :
> 
> 
>> On Jun 2, 2016, at 8:04 AM, Félix Cloutier > > wrote:
>> 
>> I was once relying on the state of things to judge the validity of some 
>> access modifier claims and I was rebuked on the grounds that proposals 
>> should be evaluated based on their merits, not on implementation details.
>> 
>> And as far as implementation details go, this doesn't match what I 
>> understand of tuples. Looking at SIL, tuple types from different 
>> declarations appear just as identical as they do in source code. In fact, 
>> the output is exactly the same even when using a tuple typealias. Do you 
>> have an experiment or compiler code that would support your claims?
> 
> I do not understand your question as it is formulated. What I described is 
> the external behavior. I did not make any reference to the internal structure 
> of the C++ that has managed to make heavy reuse of certain concepts across 
> the whole type system, so indeed part of the differences we perceive at the 
> language level do not exist identically at the implementation level. A fact 
> remains, the language is defined by its grammar… and the grammar chose to 
> expose certain concepts through what we know as struct, class, enum, tuple. 
> Swift could have decided to offer a single Ω data type that would have 
> displayed the behavior of all it current user defined types depending on 
> where it was used. but that would not be swift, right?!
> 
>> Félix
>> 
>>> Le 1 juin 2016 à 22:35:21, L Mihalkovic via swift-evolution 
>>> > a écrit :
>>> 
>>> 
 On Jun 1, 2016, at 11:20 PM, Vladimir.S > wrote:
 
 OK, I understand most of your points and feel the same regarding the 
 proposed feature... but:
 
 > .. the compiler does not like when we define the same thing twice, and 
 > thse short form amount to doing what he does not let us do. ..
 > .. if we use an annotation that lets it know that "it is not a mistake..
 > I really dont want to write that enum myself, even though I am using the
 > same abbreviation twice". Otherwise, the compiler would let us know that
 > the second time could be a mistake because there is already something
 > with the same name...
 
 I just wanted to understand how such enums are different than tuples in 
 meaning of "I don't want to write the struct myself", "Yes, I'm using the 
 same tuple twice", "Compiler will let us know that we used the same tuple 
 again and probably mistake as has already the same". (Not about 
 differences in implementation/representation on compiler level, but on 
 level of one who is writting the code)
 
 Should we use the same arguments to propose the special annotation when we 
 have the same tuple more than once? No. So I believe there should be no 
 such limitation and special annotation for proposed enums.
 
>>> 
>>> I am not sure the parallel can be made. A tuple is characterized by its 
>>> structure, BUT the scope of its use is the VARIABLE where it is being used 
>>> (I am simplifying by only referring to var/let cases). So from the 
>>> compiler’s point of view, there is not a giant Tuples hash table where it 
>>> can look for a given tuple definition based on its intrinsic name. So even 
>>> if you repeat the same tuple definition every other line in your source 
>>> code, the compiler never thinks that they are the same type because they 
>>> ARE NOT the same. Each one is a different variable (the compiler would 
>>> complain that the variable is defined multiple times though). To simplify 
>>> the model, you could almost think that a tuple is a degenerate struct that 
>>> is internally given the name of its usage site. It is not quite true but it 
>>> is a close-enough approximation of what it really is.
>>> 
>>> The only rational for allowing a 
>>> @I_know_what_I_am_doing_so_please_dont_complain annotation is to allow (and 
>>> I am not saying it should be allowed)
>>> 
>>> 
>>> func scaleAndCropLargeImage(
>>> image: UIImage,
>>> toSize size: CGSize,
>>> operation: (.Fit | .Fill) = .Fit
>>> ) -> UIImage {
>>>   whoCaresThereIsReallyASingleTypeOfImagesAnyhow()
>>> }
>>> 
>>> func scaleAndCropSmallImage(

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Xiaodi Wu via swift-evolution
Both good points. I could live with your solution.

On Thu, Jun 2, 2016 at 10:48 AM Matthew Johnson 
wrote:

> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu  wrote:
>
> Well, as I understand it, it's not actually possible to write your own
> type(of:), so we're going from a "magic" property to a "magic" function at
> least for now.
>
>
> No, but you *can* write `func foo(_ t: T)` which accepts any value (you
> *cannot* write a property that is available for all properties - that would
> require the ability to write `extension Any`.  This is the distinction I am
> making.  Of course the implementation is compiler magic no matter how we
> express it syntactically.  But we can make it *appear* just like it might
> if the implementation *wasn’t* compiler magic.  That makes it fit into the
> language better IMO and was the biggest motivator for changing
> `dynamicType`.
>
>
> I'm most alarmed that one implication of the MemoryLayout proposal is loss
> of the `ofValue` family of functions. These functions don't fit with the
> design: imagine, what is `MemoryLayout.size(ofValue: Float(42))`?
> But the response seems to be that these functions don't seem necessary at
> all and should be removed. "I don't see a use for it" is an insufficient
> justification for a feature removal. Looking to other languages, C# has
> sizeof as a static property but tellingly offers the equivalent of
> sizeofValue (well, strideofValue) as a function in a different module.
> Essentially every other C-family language that exposes pointers to the user
> offers both of and ofValue equivalents. The question is, how does a user
> with existing code using sizeofValue() migrate to Swift 3? I do not see a
> viable answer with the MemoryLayout design.
>
>
> Going with MemoryLayout *does not* mean we would have to give up the value
> functions if we don’t want to:
>
> struct MemoryLayout {
> init() {}
> init(t: T) { /* throw away the value */ }
>
> // we could omit the static properties and require
> // writing MemoryLayout() if we don’t like the duplication
> static let size: Int
> static let spacing: Int
> static let alignment: Int
>
> let size: Int
> let spacing: Int
> let alignment: Int
> }
>
> let size = MemoryLayout.size
> let sizeOfValue = MemoryLayout(42).size
>
>
> On Thu, Jun 2, 2016 at 8:03 AM Matthew Johnson 
> wrote:
>
>>
>>
>> Sent from my iPad
>>
>> On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith 
>> wrote:
>>
>>> I really like this idea. This IMO is lower level functionality than
>>> `type(of:)` (née dynamicType), so I think it makes sense for it to be
>>> grouped under its own domain, the MemoryLayout type.
>>>
>>> Plus MemoryLayout can be extended with new convenience methods.
>>>
>>> I’m fine with those old methods being removed, but I never use them so!
>>> Is it the same as calling type(of:) then using that with MemoryLayout? I
>>> imagine they could be fixit’d easily, and that they compile down to the
>>> same underlying code.
>>>
>>
>> I'm actually souring to the idea. It goes in the diametrically opposite
>> direction from dynamicType. There, something was changed from being
>> property-like to being function-like. Here, Dave's proposal would take
>> something that's a function and turn it into a property. Hmm.
>>
>>
>> That's not a fair comparison though.  With dynamicType we removed a
>> "magic" property visible on all types, which isn't something you can write
>> and turned it into a function (which is obviously something you can write).
>>
>>
>> Dave's MemoryLayout creates a new type to bundle together related items
>> which makes their semantic relationship more clear.  It also receives the
>> type via a generic argument rather than a function argument and makes the
>> properties static.  That is more representative of what is actually
>> happening and could help to prevent confusion.
>>
>> If we really need an 'ofValue' option that infers T from a value the
>> properties on MemoryLayout could also be made available as instance
>> properties and it could have an initializer that accepts an instance to T
>> and throws the value away.  However, I'm not at all convinced this is
>> necessary.
>>
>> On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> 2. Dave A. and others expressed the opinion that these should probably
>>> not be global functions; his preference was for:
>>>
>>> ```
>>> MemoryLayout.size // currently sizeof()
>>> MemoryLayout.spacing // currently strideof()
>>> MemoryLayout.alignment // currently alignof()
>>> ```
>>>
>>> 3. Dave A. proposed that sizeofValue(), strideofValue(), and
>>> alignofValue() are better off removed altogether. I don't know if people
>>> are going to be happy about this idea.
>>>
>>>
>>>
>> 

Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 10:38 AM, Xiaodi Wu  wrote:
> 
> Well, as I understand it, it's not actually possible to write your own 
> type(of:), so we're going from a "magic" property to a "magic" function at 
> least for now.

No, but you *can* write `func foo(_ t: T)` which accepts any value (you 
*cannot* write a property that is available for all properties - that would 
require the ability to write `extension Any`.  This is the distinction I am 
making.  Of course the implementation is compiler magic no matter how we 
express it syntactically.  But we can make it *appear* just like it might if 
the implementation *wasn’t* compiler magic.  That makes it fit into the 
language better IMO and was the biggest motivator for changing `dynamicType`.

> 
> I'm most alarmed that one implication of the MemoryLayout proposal is loss of 
> the `ofValue` family of functions. These functions don't fit with the design: 
> imagine, what is `MemoryLayout.size(ofValue: Float(42))`? But the 
> response seems to be that these functions don't seem necessary at all and 
> should be removed. "I don't see a use for it" is an insufficient 
> justification for a feature removal. Looking to other languages, C# has 
> sizeof as a static property but tellingly offers the equivalent of 
> sizeofValue (well, strideofValue) as a function in a different module. 
> Essentially every other C-family language that exposes pointers to the user 
> offers both of and ofValue equivalents. The question is, how does a user with 
> existing code using sizeofValue() migrate to Swift 3? I do not see a viable 
> answer with the MemoryLayout design.

Going with MemoryLayout *does not* mean we would have to give up the value 
functions if we don’t want to:

struct MemoryLayout {
init() {}
init(t: T) { /* throw away the value */ }

// we could omit the static properties and require 
// writing MemoryLayout() if we don’t like the duplication
static let size: Int
static let spacing: Int
static let alignment: Int

let size: Int
let spacing: Int
let alignment: Int
}

let size = MemoryLayout.size
let sizeOfValue = MemoryLayout(42).size

> 
> On Thu, Jun 2, 2016 at 8:03 AM Matthew Johnson  > wrote:
> 
> 
> Sent from my iPad
> 
> On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution 
> > wrote:
> 
>> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith > > wrote:
>> I really like this idea. This IMO is lower level functionality than 
>> `type(of:)` (née dynamicType), so I think it makes sense for it to be 
>> grouped under its own domain, the MemoryLayout type.
>> 
>> Plus MemoryLayout can be extended with new convenience methods.
>> 
>> I’m fine with those old methods being removed, but I never use them so! Is 
>> it the same as calling type(of:) then using that with MemoryLayout? I 
>> imagine they could be fixit’d easily, and that they compile down to the same 
>> underlying code.
>> 
>> I'm actually souring to the idea. It goes in the diametrically opposite 
>> direction from dynamicType. There, something was changed from being 
>> property-like to being function-like. Here, Dave's proposal would take 
>> something that's a function and turn it into a property. Hmm.
> 
> That's not a fair comparison though.  With dynamicType we removed a "magic" 
> property visible on all types, which isn't something you can write and turned 
> it into a function (which is obviously something you can write).  
> 
> Dave's MemoryLayout creates a new type to bundle together related items which 
> makes their semantic relationship more clear.  It also receives the type via 
> a generic argument rather than a function argument and makes the properties 
> static.  That is more representative of what is actually happening and could 
> help to prevent confusion.  
> 
> If we really need an 'ofValue' option that infers T from a value the 
> properties on MemoryLayout could also be made available as instance 
> properties and it could have an initializer that accepts an instance to T and 
> throws the value away.  However, I'm not at all convinced this is necessary.
> 
>>> On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>>> 
>>> 2. Dave A. and others expressed the opinion that these should probably not 
>>> be global functions; his preference was for:
>>> 
>>> ```
>>> MemoryLayout.size // currently sizeof()
>>> MemoryLayout.spacing // currently strideof()
>>> MemoryLayout.alignment // currently alignof()
>>> ```
>>> 
>>> 3. Dave A. proposed that sizeofValue(), strideofValue(), and alignofValue() 
>>> are better off removed altogether. I don't know if people are going to be 
>>> happy about this idea.
>> 
>> 
> 
>> ___
>> 

Re: [swift-evolution] [Returned for Revision] SE-0095: Replace protocol<P1, P2> syntax with Any<P1, P2>

2016-06-02 Thread Austin Zheng via swift-evolution
I'm sure the list is getting sick of me making this point over and
over again :), so I'll only do it one more time: I find the lack of
delimiters far worse in terms of readability for type expressions of
any appreciable complexity than any number of `Any<>` tokens. In fact,
I'm a bit surprised the core team decided to go in this direction,
given their stance on parentheses for function types, and replacing
operators like "&&" or "||" with "and" or "or". I respect their
decision, though.

On 6/2/16, Thorsten Seitz  wrote:
>
>
>> Am 02.06.2016 um 07:42 schrieb Austin Zheng via swift-evolution
>> :
>>
>> Excellent.
>>
>> I put together a PR with a revised proposal containing the core team's
>> recommended approach. If anyone is curious they can see it here:
>> https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md
>>
>> Since this is the de-facto second round discussion thread, I'll start with
>> my personal opinion (which is *not* reflected in the PR): the '&'
>> separators in lieu of commas are a good idea, but I would still prefer the
>> types to be wrapped in "Any<>", at least when being used as existentials.
>
> I'm very happy with using `&` as I find this very readable.
> I would prefer not having to wrap them into `Any<>`. While I can image
> `Any<>`, or rather `any<>`, for existentials with `where` clauses, I would
> absolutely hate having to wrap all existentials into that which would
> introduce a lot of noise.
>
>>
>> My reasons:
>>
>> - Jordan Rose brought up a good point in one of the discussion threads
>> today: a resilience goal is to allow a library to add an associated type
>> to a protocol that had none and not have it break user code. If this is
>> true whatever syntax is used for existentials in Swift 3 should be a valid
>> subset of the generalized existential syntax used to describe protocol
>> compositions with no associated types.
>
> If `P` is an existential there is no problem either, isn't it? No need to
> require `Any`.
>
>
>
>>
>> - I would rather have "Any<>" be used consistently across all existential
>> types eventually than have it only be used for (e.g.) existential types
>> with `where` constraints, or allowing two different representations of the
>> same existential type (one with Any, and one without).
>
> Far too much noise!
>
>
>>
>> - I think any generalized existential syntax without delimiting markers
>> (like angle braces) is harder to read than syntax with such markers, so I
>> would prefer a design with those markers.
>
> I think markers are only needed if a `where` clause is present and probably
> not even then.
>
> -Thorsten
>
>
>>
>> Best,
>> Austin
>>
 On Jun 1, 2016, at 10:17 PM, Chris Lattner  wrote:


 On Jun 1, 2016, at 9:53 PM, Austin Zheng  wrote:

 This was indeed a very thorough review by the core team. I'll prepare a
 v2 proposal with this feedback taken into account so we can continue
 moving things along.

 One quick question - is making whatever syntax is chosen for Swift 3
 "forward-compatible" with a future generalized existential feature a
 concern?
>>>
>>> Yes it is a concern, but we assume that the “X & Y” syntax will always be
>>> accepted going forward, as sugar for the more general feature that is yet
>>> to be designed.
>>>
>>> -Chris
>>
>> ___
>> 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] [Returned for Revision] SE-0095: Replace protocol<P1, P2> syntax with Any<P1, P2>

2016-06-02 Thread Thorsten Seitz via swift-evolution


> Am 02.06.2016 um 07:42 schrieb Austin Zheng via swift-evolution 
> :
> 
> Excellent.
> 
> I put together a PR with a revised proposal containing the core team's 
> recommended approach. If anyone is curious they can see it here: 
> https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md
> 
> Since this is the de-facto second round discussion thread, I'll start with my 
> personal opinion (which is *not* reflected in the PR): the '&' separators in 
> lieu of commas are a good idea, but I would still prefer the types to be 
> wrapped in "Any<>", at least when being used as existentials.

I'm very happy with using `&` as I find this very readable.
I would prefer not having to wrap them into `Any<>`. While I can image `Any<>`, 
or rather `any<>`, for existentials with `where` clauses, I would absolutely 
hate having to wrap all existentials into that which would introduce a lot of 
noise. 

> 
> My reasons:
> 
> - Jordan Rose brought up a good point in one of the discussion threads today: 
> a resilience goal is to allow a library to add an associated type to a 
> protocol that had none and not have it break user code. If this is true 
> whatever syntax is used for existentials in Swift 3 should be a valid subset 
> of the generalized existential syntax used to describe protocol compositions 
> with no associated types.

If `P` is an existential there is no problem either, isn't it? No need to 
require `Any`. 



> 
> - I would rather have "Any<>" be used consistently across all existential 
> types eventually than have it only be used for (e.g.) existential types with 
> `where` constraints, or allowing two different representations of the same 
> existential type (one with Any, and one without).

Far too much noise!


> 
> - I think any generalized existential syntax without delimiting markers (like 
> angle braces) is harder to read than syntax with such markers, so I would 
> prefer a design with those markers.

I think markers are only needed if a `where` clause is present and probably not 
even then.

-Thorsten 


> 
> Best,
> Austin
> 
>>> On Jun 1, 2016, at 10:17 PM, Chris Lattner  wrote:
>>> 
>>> 
>>> On Jun 1, 2016, at 9:53 PM, Austin Zheng  wrote:
>>> 
>>> This was indeed a very thorough review by the core team. I'll prepare a v2 
>>> proposal with this feedback taken into account so we can continue moving 
>>> things along.
>>> 
>>> One quick question - is making whatever syntax is chosen for Swift 3 
>>> "forward-compatible" with a future generalized existential feature a 
>>> concern?
>> 
>> Yes it is a concern, but we assume that the “X & Y” syntax will always be 
>> accepted going forward, as sugar for the more general feature that is yet to 
>> be designed.
>> 
>> -Chris
> 
> ___
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 10:01 AM, Charlie Monroe  wrote:
> 
>> Isn’t this a short-term concern?  I thought that requirement was going away.
> 
> AFAIK there are still concerns about ambiguity - [Int] - is it an array with 
> one element (Int.self), or is it [Int].self?

IIRC Joe Groff was going to work on sorting out the remaining issues but the 
plan is to move ahead eventually.

> 
>> 
>>> For this reason, this proposal prefers using no-label calls for types 
>>> (otherwise they would have been ofType) and labeled calls for values:
>>> 
>>> print(sizeof(Int)) // works
>>> print(sizeof(Int.self)) // works
>>> 
>>> func withoutLabel(thetype: T.Type) -> Int { return sizeof(T) }
>>> func withLabel(label label: T.Type) -> Int { return sizeof(T) }
>>> 
>>> 
>>> // Works
>>> print(withoutLabel(Int))
>>> 
>>> // Works
>>> print(withLabel(label: Int.self))
>>> 
>>> // Does not work
>>> // error: cannot create a single-element tuple with an element label
>>> // print(withLabel(label: Int)) 
>>> 
>>> 
>>> So with this in mind:
>>> 
>>> /// Returns the contiguous memory footprint of `T`.
>>> ///
>>> /// Does not include any dynamically-allocated or "remote" storage.
>>> /// In particular, `size(X.self)`, when `X` is a class type, is the
>>> /// same regardless of how many stored properties `X` has.
>>> public func size(_: T.Type) -> Int
>>> 
>>> /// Returns the contiguous memory footprint of  `T`.
>>> ///
>>> /// Does not include any dynamically-allocated or "remote" storage.
>>> /// In particular, `size(of: a)`, when `a` is a class instance, is the
>>> /// same regardless of how many stored properties `a` has.
>>> public func size(of: T) -> Int
>>> 
>>> /// Returns the least possible interval between distinct instances of
>>> /// `T` in memory.  The result is always positive.
>>> public func spacing(_: T.Type) -> Int
>>> 
>>> /// Returns the least possible interval between distinct instances of
>>> /// `T` in memory.  The result is always positive.
>>> public func spacing(of: T) -> Int
>>> 
>>> /// Returns the minimum memory alignment of `T`.
>>> public func alignment(_: T.Type) -> Int
>>> 
>>> /// Returns the minimum memory alignment of `T`.
>>> public func alignment(of: T) -> Int
>>> -- E
>> 
>> ___
>> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 10:03 AM, Xiaodi Wu  wrote:
> 
> That proposal was returned for revision; as far as user ergonomics in Swift 
> 3, .self is going to be a consideration. Best to find a solution that reads 
> nicely regardless of the situation with .self removal.

From the core team decision:

"The core team would definitely like to circle back to this proposal after 
Swift 3 is out the door."

I think we should consider the best long-term design.  If that happens to be 
dropping labels great, but if not, maybe we don’t want to do that just because 
it will look better in Swift 3 at the cost of a better design when “.self” is 
not required.

Dave’s MemoryLayout approach avoids the question of labels entirely.  This is 
another subtle nudge in that direction IMO.

> 
> On Thu, Jun 2, 2016 at 9:57 AM Matthew Johnson  > wrote:
>> On Jun 2, 2016, at 9:43 AM, Erica Sadun > > wrote:
>> 
>> Supporting Dave A, type-based calls are much more likely to be used than 
>> instance calls, unlike with dynamicType/type(of:)
>> 
>> Term stdlib search   gist search Google site:github +swift
>> sizeof   157 169 4880
>> sizeofValue  4   34  584
>> alignof  44  11  334
>> alignofValue 5   5   154
>> strideof 347 19  347
>> strideofValue4   5   163
>> Type-based calls like sizeof() are poor candidates for parameter labels. 
>> While it's acceptable to write sizeof(Int), but one must write size(of: 
>> Int.self) (with the trailing self) when the function has a label.
> 
> Isn’t this a short-term concern?  I thought that requirement was going away.
> 
>> For this reason, this proposal prefers using no-label calls for types 
>> (otherwise they would have been ofType) and labeled calls for values:
>> 
>> print(sizeof(Int)) // works
>> print(sizeof(Int.self)) // works
>> 
>> func withoutLabel(thetype: T.Type) -> Int { return sizeof(T) }
>> func withLabel(label label: T.Type) -> Int { return sizeof(T) }
>> 
>> 
>> // Works
>> print(withoutLabel(Int))
>> 
>> // Works
>> print(withLabel(label: Int.self))
>> 
>> // Does not work
>> // error: cannot create a single-element tuple with an element label
>> // print(withLabel(label: Int)) 
>> 
>> 
>> So with this in mind:
>> 
>> /// Returns the contiguous memory footprint of `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(X.self)`, when `X` is a class type, is the
>> /// same regardless of how many stored properties `X` has.
>> public func size(_: T.Type) -> Int
>> 
>> /// Returns the contiguous memory footprint of  `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(of: a)`, when `a` is a class instance, is the
>> /// same regardless of how many stored properties `a` has.
>> public func size(of: T) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(_: T.Type) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(of: T) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func alignment(_: T.Type) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func alignment(of: T) -> Int
>> -- E

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Xiaodi Wu via swift-evolution
That proposal was returned for revision; as far as user ergonomics in Swift
3, .self is going to be a consideration. Best to find a solution that reads
nicely regardless of the situation with .self removal.

On Thu, Jun 2, 2016 at 9:57 AM Matthew Johnson 
wrote:

> On Jun 2, 2016, at 9:43 AM, Erica Sadun  wrote:
>
> Supporting Dave A, type-based calls are much more likely to be used than
> instance calls, unlike with dynamicType/type(of:)
>
> Termstdlib searchgist searchGoogle site:github +swift
> sizeof 157 169 4880
> sizeofValue 4 34 584
> alignof 44 11 334
> alignofValue 5 5 154
> strideof 347 19 347
> strideofValue 4 5 163
> Type-based calls like sizeof() are poor candidates for parameter labels.
> While it's acceptable to write sizeof(Int), but one must write size(of:
> Int.self) (with the trailing self) when the function has a label.
>
>
> Isn’t this a short-term concern?  I thought that requirement was going
> away.
>
> For this reason, this proposal prefers using no-label calls for types
> (otherwise they would have been ofType) and labeled calls for values:
>
> print(sizeof(Int)) // worksprint(sizeof(Int.self)) // works
> func withoutLabel(thetype: T.Type) -> Int { return sizeof(T) }func 
> withLabel(label label: T.Type) -> Int { return sizeof(T) }
>
> // Worksprint(withoutLabel(Int))
> // Worksprint(withLabel(label: Int.self))
> // Does not work// error: cannot create a single-element tuple with an 
> element label// print(withLabel(label: Int))
>
>
>
> So with this in mind:
>
> /// Returns the contiguous memory footprint of `T`.
> ///
> /// Does not include any dynamically-allocated or "remote" storage.
> /// In particular, `size(X.self)`, when `X` is a class type, is the
> /// same regardless of how many stored properties `X` has.
> public func size(_: T.Type) -> Int
>
> /// Returns the contiguous memory footprint of  `T`.
> ///
> /// Does not include any dynamically-allocated or "remote" storage.
> /// In particular, `size(of: a)`, when `a` is a class instance, is the
> /// same regardless of how many stored properties `a` has.
> public func size(of: T) -> Int
>
> /// Returns the least possible interval between distinct instances of
> /// `T` in memory.  The result is always positive.
> public func spacing(_: T.Type) -> Int
>
> /// Returns the least possible interval between distinct instances of
> /// `T` in memory.  The result is always positive.
> public func spacing(of: T) -> Int
>
> /// Returns the minimum memory alignment of `T`.
> public func alignment(_: T.Type) -> Int
>
> /// Returns the minimum memory alignment of `T`.
> public func alignment(of: T) -> Int
>
> -- E
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Charlie Monroe via swift-evolution
> Isn’t this a short-term concern?  I thought that requirement was going away.

AFAIK there are still concerns about ambiguity - [Int] - is it an array with 
one element (Int.self), or is it [Int].self?

> 
>> For this reason, this proposal prefers using no-label calls for types 
>> (otherwise they would have been ofType) and labeled calls for values:
>> 
>> print(sizeof(Int)) // works
>> print(sizeof(Int.self)) // works
>> 
>> func withoutLabel(thetype: T.Type) -> Int { return sizeof(T) }
>> func withLabel(label label: T.Type) -> Int { return sizeof(T) }
>> 
>> 
>> // Works
>> print(withoutLabel(Int))
>> 
>> // Works
>> print(withLabel(label: Int.self))
>> 
>> // Does not work
>> // error: cannot create a single-element tuple with an element label
>> // print(withLabel(label: Int)) 
>> 
>> 
>> So with this in mind:
>> 
>> /// Returns the contiguous memory footprint of `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(X.self)`, when `X` is a class type, is the
>> /// same regardless of how many stored properties `X` has.
>> public func size(_: T.Type) -> Int
>> 
>> /// Returns the contiguous memory footprint of  `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(of: a)`, when `a` is a class instance, is the
>> /// same regardless of how many stored properties `a` has.
>> public func size(of: T) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(_: T.Type) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(of: T) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func alignment(_: T.Type) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func alignment(of: T) -> Int
>> -- E
> 
> ___
> 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] [swift-evolution-announce] [Rejected] SE-0097: Normalizing naming for "negative" attributes

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 9:52 AM, Sean Heber via swift-evolution 
>  wrote:
> 
> In terms of naming, I almost feel like “None” would be a better name for it 
> as then it reads somewhat as the opposite of “Any” and that has a nice 
> symmetry to me.

+ 1.  Although the inverse of “None” is really “All” (as in “all or none”).  
I’m not necessarily suggesting we use “All”, just pointing out the linguistic 
relationship.  

That said, I do believe we should *consider* alternatives names for “Any” as 
part of the discussion of the name for a bottom type.  It would be nice 
symmetry if we found names for the top and bottom types that are inverses of 
each other.

> 
> l8r
> Sean
> 
> 
>> On Jun 2, 2016, at 4:04 AM, Brent Royal-Gordon via swift-evolution 
>>  wrote:
>> 
>>> 1) For noreturn, the core team prefers to explore a solution where a 
>>> function can be declared as returning an non-constructable “bottom” type 
>>> (e.g. an enum with zero cases).  This would lead to something like:
>>> 
>>> func abort() -> NoReturn { … }
>>> 
>>> This will require some new support in the compiler, but should flow better 
>>> through the type system than @noreturn in function composition and other 
>>> applications.  Joe Groff offered to write a proposal for this.
>> 
>> Are you thinking in terms of a *real* bottom type—that is, a type which is 
>> the subtype of all types—or a fake bottom type which is simply an empty enum?
>> 
>> If you're thinking about a real bottom type, I wouldn't want to call it 
>> `NoReturn`, because the bottom type may end up playing a larger role in the 
>> language. Given our use of `Any`, the natural names for a bottom type are 
>> probably `All` (as the subtype of all types) or `None` (as a type with no 
>> instances). I do worry that those names are a little too short and 
>> attractive, though. `None` might be mistaken for `Void`; `All` might be 
>> mistaken for `Any`, and wouldn't make much sense when read as the return 
>> value of a function.
>> 
>> My best suggestion is `Never`. A function with a `Never` return type would 
>> read as "never returns":
>> 
>>  func abort() -> Never { … }
>> 
>> If it appeared in, say, a generic type, it would mean "never occurs":
>> 
>>  let result: Result
>> 
>> Flowing from that, we can end up with functions taking a `Never` parameter, 
>> which are never called:
>> 
>>  result.flatMapError { (_: Never) in fatalError("can't happen") }
>> 
>> Or `Never?` values, which are never `some`:
>> 
>>  let _: Never? = Result.error
>> 
>> (By the way, the return type of the force unwrap operator on a `Never?` is 
>> `Never`, which is just right: if you force unwrap a `Never?`, it will always 
>> trap, never return.)
>> 
>> The main issue I see with `Never` is that it's an adverb, not a noun. But 
>> the nouns all seem to have problems. And besides, the bottom type isn't so 
>> much a thing as a lack of a thing, isn't it? That's bound to have a slightly 
>> funky name.
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
>> ___
>> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution

> On Jun 2, 2016, at 9:43 AM, Erica Sadun  wrote:
> 
> Supporting Dave A, type-based calls are much more likely to be used than 
> instance calls, unlike with dynamicType/type(of:)
> 
> Term  stdlib search   gist search Google site:github +swift
> sizeof157 169 4880
> sizeofValue   4   34  584
> alignof   44  11  334
> alignofValue  5   5   154
> strideof  347 19  347
> strideofValue 4   5   163
> Type-based calls like sizeof() are poor candidates for parameter labels. 
> While it's acceptable to write sizeof(Int), but one must write size(of: 
> Int.self) (with the trailing self) when the function has a label.

Isn’t this a short-term concern?  I thought that requirement was going away.

> For this reason, this proposal prefers using no-label calls for types 
> (otherwise they would have been ofType) and labeled calls for values:
> 
> print(sizeof(Int)) // works
> print(sizeof(Int.self)) // works
> 
> func withoutLabel(thetype: T.Type) -> Int { return sizeof(T) }
> func withLabel(label label: T.Type) -> Int { return sizeof(T) }
> 
> 
> // Works
> print(withoutLabel(Int))
> 
> // Works
> print(withLabel(label: Int.self))
> 
> // Does not work
> // error: cannot create a single-element tuple with an element label
> // print(withLabel(label: Int)) 
> 
> 
> So with this in mind:
> 
> /// Returns the contiguous memory footprint of `T`.
> ///
> /// Does not include any dynamically-allocated or "remote" storage.
> /// In particular, `size(X.self)`, when `X` is a class type, is the
> /// same regardless of how many stored properties `X` has.
> public func size(_: T.Type) -> Int
> 
> /// Returns the contiguous memory footprint of  `T`.
> ///
> /// Does not include any dynamically-allocated or "remote" storage.
> /// In particular, `size(of: a)`, when `a` is a class instance, is the
> /// same regardless of how many stored properties `a` has.
> public func size(of: T) -> Int
> 
> /// Returns the least possible interval between distinct instances of
> /// `T` in memory.  The result is always positive.
> public func spacing(_: T.Type) -> Int
> 
> /// Returns the least possible interval between distinct instances of
> /// `T` in memory.  The result is always positive.
> public func spacing(of: T) -> Int
> 
> /// Returns the minimum memory alignment of `T`.
> public func alignment(_: T.Type) -> Int
> 
> /// Returns the minimum memory alignment of `T`.
> public func alignment(of: T) -> Int
> -- E

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


Re: [swift-evolution] [swift-evolution-announce] [Rejected] SE-0097: Normalizing naming for "negative" attributes

2016-06-02 Thread Sean Heber via swift-evolution
In terms of naming, I almost feel like “None” would be a better name for it as 
then it reads somewhat as the opposite of “Any” and that has a nice symmetry to 
me.

l8r
Sean


> On Jun 2, 2016, at 4:04 AM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> 1) For noreturn, the core team prefers to explore a solution where a 
>> function can be declared as returning an non-constructable “bottom” type 
>> (e.g. an enum with zero cases).  This would lead to something like:
>> 
>>  func abort() -> NoReturn { … }
>> 
>> This will require some new support in the compiler, but should flow better 
>> through the type system than @noreturn in function composition and other 
>> applications.  Joe Groff offered to write a proposal for this.
> 
> Are you thinking in terms of a *real* bottom type—that is, a type which is 
> the subtype of all types—or a fake bottom type which is simply an empty enum?
> 
> If you're thinking about a real bottom type, I wouldn't want to call it 
> `NoReturn`, because the bottom type may end up playing a larger role in the 
> language. Given our use of `Any`, the natural names for a bottom type are 
> probably `All` (as the subtype of all types) or `None` (as a type with no 
> instances). I do worry that those names are a little too short and 
> attractive, though. `None` might be mistaken for `Void`; `All` might be 
> mistaken for `Any`, and wouldn't make much sense when read as the return 
> value of a function.
> 
> My best suggestion is `Never`. A function with a `Never` return type would 
> read as "never returns":
> 
>   func abort() -> Never { … }
> 
> If it appeared in, say, a generic type, it would mean "never occurs":
> 
>   let result: Result
> 
> Flowing from that, we can end up with functions taking a `Never` parameter, 
> which are never called:
> 
>   result.flatMapError { (_: Never) in fatalError("can't happen") }
> 
> Or `Never?` values, which are never `some`:
> 
>   let _: Never? = Result.error
> 
> (By the way, the return type of the force unwrap operator on a `Never?` is 
> `Never`, which is just right: if you force unwrap a `Never?`, it will always 
> trap, never return.)
> 
> The main issue I see with `Never` is that it's an adverb, not a noun. But the 
> nouns all seem to have problems. And besides, the bottom type isn't so much a 
> thing as a lack of a thing, isn't it? That's bound to have a slightly funky 
> name.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Erica Sadun via swift-evolution
Supporting Dave A, type-based calls are much more likely to be used than 
instance calls, unlike with dynamicType/type(of:)

Termstdlib search   gist search Google site:github +swift
sizeof  157 169 4880
sizeofValue 4   34  584
alignof 44  11  334
alignofValue5   5   154
strideof347 19  347
strideofValue   4   5   163
Type-based calls like sizeof() are poor candidates for parameter labels. While 
it's acceptable to write sizeof(Int), but one must write size(of: Int.self) 
(with the trailing self) when the function has a label. For this reason, this 
proposal prefers using no-label calls for types (otherwise they would have been 
ofType) and labeled calls for values:

print(sizeof(Int)) // works
print(sizeof(Int.self)) // works

func withoutLabel(thetype: T.Type) -> Int { return sizeof(T) }
func withLabel(label label: T.Type) -> Int { return sizeof(T) }


// Works
print(withoutLabel(Int))

// Works
print(withLabel(label: Int.self))

// Does not work
// error: cannot create a single-element tuple with an element label
// print(withLabel(label: Int)) 


So with this in mind:

/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(X.self)`, when `X` is a class type, is the
/// same regardless of how many stored properties `X` has.
public func size(_: T.Type) -> Int

/// Returns the contiguous memory footprint of  `T`.
///
/// Does not include any dynamically-allocated or "remote" storage.
/// In particular, `size(of: a)`, when `a` is a class instance, is the
/// same regardless of how many stored properties `a` has.
public func size(of: T) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory.  The result is always positive.
public func spacing(_: T.Type) -> Int

/// Returns the least possible interval between distinct instances of
/// `T` in memory.  The result is always positive.
public func spacing(of: T) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment(_: T.Type) -> Int

/// Returns the minimum memory alignment of `T`.
public func alignment(of: T) -> Int
-- E___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

On Jun 2, 2016, at 6:26 AM, Brent Royal-Gordon via swift-evolution 
 wrote:

>> /// Returns the contiguous memory footprint of `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(of: X.self)`, when `X` is a class type, is the
>> /// same regardless of how many stored properties `X` has.
>> public func size(of: T.Type) -> Int
>> 
>> /// Returns the contiguous memory footprint of  `T`.
>> ///
>> /// Does not include any dynamically-allocated or "remote" storage.
>> /// In particular, `size(of: a)`, when `a` is a class instance, is the
>> /// same regardless of how many stored properties `a` has.
>> public func size(ofValue: T) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(of: T.Type) -> Int
>> 
>> /// Returns the least possible interval between distinct instances of
>> /// `T` in memory.  The result is always positive.
>> public func spacing(ofValue: T) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func align(of: T.Type) -> Int
>> 
>> /// Returns the minimum memory alignment of `T`.
>> public func align(ofValue: T) -> Int
> 
> If `type(of:)` takes an instance, then I think `size(of:)`, `spacing(of:)` 
> and `align(of:)` need to do the same, with `size(ofType:)`, 
> `spacing(ofType:)`, and `align(ofType:)` handling the type side of things.

+1 if we stick with the function direction.  But I'm not convinced this is the 
best direction.

> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

>> On Jun 2, 2016, at 12:27 AM, Xiaodi Wu via swift-evolution 
>>  wrote:
>> 
>> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith  wrote:
>> I really like this idea. This IMO is lower level functionality than 
>> `type(of:)` (née dynamicType), so I think it makes sense for it to be 
>> grouped under its own domain, the MemoryLayout type.
>> 
>> Plus MemoryLayout can be extended with new convenience methods.
>> 
>> I’m fine with those old methods being removed, but I never use them so! Is 
>> it the same as calling type(of:) then using that with MemoryLayout? I 
>> imagine they could be fixit’d easily, and that they compile down to the same 
>> underlying code.
> 
> I'm actually souring to the idea. It goes in the diametrically opposite 
> direction from dynamicType. There, something was changed from being 
> property-like to being function-like. Here, Dave's proposal would take 
> something that's a function and turn it into a property. Hmm.

That's not a fair comparison though.  With dynamicType we removed a "magic" 
property visible on all types, which isn't something you can write and turned 
it into a function (which is obviously something you can write).  

Dave's MemoryLayout creates a new type to bundle together related items which 
makes their semantic relationship more clear.  It also receives the type via a 
generic argument rather than a function argument and makes the properties 
static.  That is more representative of what is actually happening and could 
help to prevent confusion.  

If we really need an 'ofValue' option that infers T from a value the properties 
on MemoryLayout could also be made available as instance properties and it 
could have an initializer that accepts an instance to T and throws the value 
away.  However, I'm not at all convinced this is necessary.

>>> On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> 2. Dave A. and others expressed the opinion that these should probably not 
>>> be global functions; his preference was for:
>>> 
>>> ```
>>> MemoryLayout.size // currently sizeof()
>>> MemoryLayout.spacing // currently strideof()
>>> MemoryLayout.alignment // currently alignof()
>>> ```
>>> 
>>> 3. Dave A. proposed that sizeofValue(), strideofValue(), and alignofValue() 
>>> are better off removed altogether. I don't know if people are going to be 
>>> happy about this idea.
> 
> ___
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 2, 2016, at 12:05 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
>> On Wed, Jun 1, 2016 at 11:55 PM, Xiaodi Wu  wrote:
>>> On Wed, Jun 1, 2016 at 11:28 PM, Erica Sadun via swift-evolution 
>>>  wrote:
>> 
>>> Upon accepting SE-0098, the core team renamed the proposed stdlib function 
>>> from dynamicType() to type(of:).  They write, "The core team recognizes 
>>> that this means that we should probably resyntax the existing 
>>> sizeof/strideof functions, but that should be a follow-on discussion."
>>> 
>>> Follow on discussion started. Have at it.
>> 
>> See: http://thread.gmane.org/gmane.comp.lang.swift.evolution/15830
> 
> To summarize the previous discussion:
> 
> 1. Per Joe Groff, although sizeof() and friends are treated as terms-of-art, 
> these names were lifted straight from C and do not correspond to anything 
> named "sizeof" in LLVM.
> 
> 2. There are issues with using a name such as stride(of:), because 
> stride(...) already means something else in the stdlib; moreover, size(of:) 
> isn't the best name for something that doesn't do what its C namesake does; 
> therefore, larger changes to the naming were suggested.
> 
> 2. Dave A. and others expressed the opinion that these should probably not be 
> global functions; his preference was for:
> 
> ```
> MemoryLayout.size // currently sizeof()
> MemoryLayout.spacing // currently strideof()
> MemoryLayout.alignment // currently alignof()
> ```

Thanks for the summary.  I missed the original thread.  

I think I like this approach despite its verbosity.  Will give it a little bit 
more thought...

> 
> 3. Dave A. proposed that sizeofValue(), strideofValue(), and alignofValue() 
> are better off removed altogether. I don't know if people are going to be 
> happy about this idea.
> 
> * * *
> 
> If we take inspiration from type(of:), then it's actually sizeofValue(), 
> etc., that should be renamed size(of:), etc. Also, a fun tidbit is that 
> what's currently called sizeof(), etc.--the ones that take types rather than 
> values--are actually not very good candidates for having parameter labels, 
> because it's OK to write `sizeof(Int)`, but one must currently write 
> `size(of: Int.self)` when the function has a label.
> 
> 
> 
> ___
> 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] Working with enums by name

2016-06-02 Thread Leonardo Pessoa via swift-evolution
There are several ways to solve this, which IMO is a basic functionality of 
enums, writing code that is currently possible and works. But that's the issue, 
you still have to write code to have a basic functionally. I don't remember not 
being able to do this out-of-the-box in any language I worked with.

L

-Original Message-
From: "Patrick Smith" 
Sent: ‎02/‎06/‎2016 02:07 AM
To: "Brent Royal-Gordon" 
Cc: "Leonardo Pessoa" ; "swift-evolution" 

Subject: Re: [swift-evolution] Working with enums by name

Great points Brent. I think the ValuesEnumerable method would be the most 
straight forward. Also, the number of cases are likely only going to be in 
range of 6–20, so iterating would be fine I think. People can create something 
like `Dictionary(Planet.allValues.enumerated().lazy.map{ ($1, $0) })` (I think 
that’s right) if they really need.


> On 2 Jun 2016, at 2:40 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> Or the `ValuesEnumerable` proposal would give you a convenient, though 
> slightly slow, way to do two-way lookup by order:
> 
>   enum Planet: String, ValuesEnumerable {
>   var order: Int {
>   return Planet.allValues.index(of: self)!
>   }
>   init(order: Int) {
>   self = Planet.allValues[order]
>   }
>   case mercury, venus, …
>   }

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


Re: [swift-evolution] Working with enums by name

2016-06-02 Thread Leonardo Pessoa via swift-evolution
I understand you don't like to rely on the name of your enum cases in you code 
and that's fine, you can still work with them as is, you won't have to change 
the way you work just because you don't like the proposal but that doesn't mean 
everybody has the same opinion you do. But perhaps then instead of enums we 
should go back to using simple constants because that's exactly what enum cases 
become if their names are not how you're expected to reference, store and 
retrieve their values (yes, I understand there are other benefits to using 
enums instead of constants but that's just how you're using them).

L

-Original Message-
From: "Brent Royal-Gordon" 
Sent: ‎02/‎06/‎2016 01:40 AM
To: "Leonardo Pessoa" 
Cc: "Vladimir.S" ; "swift-evolution" 

Subject: Re: [swift-evolution] Working with enums by name

> Brent, for needing "both Int and Double values" there is a proposal to add 
> tuples instead of the current raw values or allowing assessor properties per 
> case, you should check those out. Perhaps this could also be used to 
> cryptoghaphically sign a raw value but I'm not sure.

I know; I was the one who suggested accessors.

> As for working with enum values by name a few examples have already been 
> posted in today but I've done a lot more research in the subject along the 
> day and found there is a correlation between enums and nominal level values 
> in statistics; we cannot test them for a particular order (this could also be 
> interesting for statistic apps but it's another case) and no math with them 
> is valid. So, e.g., the result of the following operation on the planets enum 
> is nonsense:
> 
> |   let planet = Planet(rawValue: Planet.Mars.rawValue - 
> Planet.Mercury.rawValue)
> 
> The result will be different if the enum values are zero based than if not. 
> Also any change in list order or the base index or add a new element to the 
> middle of the list will break your intended code if you're storing the raw 
> value in a database. And we know these changes happen.

All of this is true. And all of this is an argument that *you're using raw 
values wrong*.

Raw values are a serialization mechanism. You might be serializing merely 
within your process, or you might be writing out to disk, through IPC, or 
across the network, but in all cases you are serializing. You should not be 
doing arithmetic with a serialized representation (unless that arithmetic is a 
part of the serialization process, like an error-correcting code you're 
applying to it). You should not be sorting serialized representations. You 
should be either communicating the raw value or recreating the instance with 
it—nothing else.

In other words, all of these are arguments for putting the order of the Planet 
in a separate property rather than in the `rawValue`. This would free up the 
`rawValue` to be a `String` containing the case name. This is not an argument 
for having both an Int `rawValue` and a String `caseName`; this is an argument 
for having both a String `rawValue` and an Int property.

enum Planet: String {
accessor var order: Int

case mercury { order = 0 }
case venus { order = 1 }
...etc...
}

(Want it to be automatic? One could imagine having a compiler substitution for 
"the index of this case" which could be used as the default value for an 
accessor:

enum Planet: String {
accessor var order: Int = #caseIndex
case mercury, venus, ...
}

Or let you choose a base:

enum Planet: String {
accessor var order: Int = #caseOrder(from: 1)
case mercury, venus, ...
}

Or the `ValuesEnumerable` proposal would give you a convenient, though slightly 
slow, way to do two-way lookup by order:

enum Planet: String, ValuesEnumerable {
var order: Int {
return Planet.allValues.index(of: self)!
}
init(order: Int) {
self = Planet.allValues[order]
}
case mercury, venus, …
}

In short, there are several plausible mechanisms to automate assignment of 
these numbers, should you want to do that.)

> Actually, given this characteristic of nominal types (statistic), we should 
> vow to removing init(rawValue:) completely from the language.

That doesn't follow. The fact that changing something would break code doesn't 
mean that thing should be removed; it means you should be cautious about 
changing that thing. If you rename a case, its name changes; does that mean we 
shouldn't have case name lookups either? Changing any identifier could break 
something; maybe we should abolish all identifiers from Swift?

> The real value you're working with in enums is the enum case name not any 
> associated 

Re: [swift-evolution] [Returned for Revision] SE-0095: Replace protocol<P1, P2> syntax with Any<P1, P2>

2016-06-02 Thread Taras Zakharko via swift-evolution
I never had any problems with commas, as I always read them as conjunctive 
clauses, but I understand that an explicit conjunction may be less confusing. 
Personally, I’d prefer if there was no special syntax (aka Any<>) for 
existential types, whether generalised or not. I fail to see a principal 
difference between an existential type vardecl and a non-existential type 
vardecl: both can be described as sets of factual types, with non-existential 
declarations trivially being sets of cardinality one. Under this perspective, 
adopting different syntax for these cases feels like an idiosyncratic decision 
to me. I also disagree that Any<> makes existential types more readable, on 
contrary, they introduce visual clutter. A considerably complex existential 
definition could always be hidden behind a typealias.

Ideally, I’d like ALL type references in variable declarations be treated as 
existentials: the variable is declared as belonging to a certain set of factual 
types (in most cases this will trivially be a single factual type). IMO, this 
would result in a simple and concise system. It would also make type-erased 
wrappers unnecessary, simplifying the language. 

Best, 

 Taras


> On 02 Jun 2016, at 07:42, Austin Zheng via swift-evolution 
>  wrote:
> 
> Excellent.
> 
> I put together a PR with a revised proposal containing the core team's 
> recommended approach. If anyone is curious they can see it here: 
> https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md
>  
> 
> 
> Since this is the de-facto second round discussion thread, I'll start with my 
> personal opinion (which is *not* reflected in the PR): the '&' separators in 
> lieu of commas are a good idea, but I would still prefer the types to be 
> wrapped in "Any<>", at least when being used as existentials.
> 
> My reasons:
> 
> - Jordan Rose brought up a good point in one of the discussion threads today: 
> a resilience goal is to allow a library to add an associated type to a 
> protocol that had none and not have it break user code. If this is true 
> whatever syntax is used for existentials in Swift 3 should be a valid subset 
> of the generalized existential syntax used to describe protocol compositions 
> with no associated types.
> 
> - I would rather have "Any<>" be used consistently across all existential 
> types eventually than have it only be used for (e.g.) existential types with 
> `where` constraints, or allowing two different representations of the same 
> existential type (one with Any, and one without).
> 
> - I think any generalized existential syntax without delimiting markers (like 
> angle braces) is harder to read than syntax with such markers, so I would 
> prefer a design with those markers.
> 
> Best,
> Austin
> 
>> On Jun 1, 2016, at 10:17 PM, Chris Lattner > > wrote:
>> 
>> 
>>> On Jun 1, 2016, at 9:53 PM, Austin Zheng >> > wrote:
>>> 
>>> This was indeed a very thorough review by the core team. I'll prepare a v2 
>>> proposal with this feedback taken into account so we can continue moving 
>>> things along.
>>> 
>>> One quick question - is making whatever syntax is chosen for Swift 3 
>>> "forward-compatible" with a future generalized existential feature a 
>>> concern?
>> 
>> Yes it is a concern, but we assume that the “X & Y” syntax will always be 
>> accepted going forward, as sugar for the more general feature that is yet to 
>> be designed.
>> 
>> -Chris
> 
> ___
> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Brent Royal-Gordon via swift-evolution
> /// Returns the contiguous memory footprint of `T`.
> ///
> /// Does not include any dynamically-allocated or "remote" storage.
> /// In particular, `size(of: X.self)`, when `X` is a class type, is the
> /// same regardless of how many stored properties `X` has.
> public func size(of: T.Type) -> Int
> 
> /// Returns the contiguous memory footprint of  `T`.
> ///
> /// Does not include any dynamically-allocated or "remote" storage.
> /// In particular, `size(of: a)`, when `a` is a class instance, is the
> /// same regardless of how many stored properties `a` has.
> public func size(ofValue: T) -> Int
> 
> /// Returns the least possible interval between distinct instances of
> /// `T` in memory.  The result is always positive.
> public func spacing(of: T.Type) -> Int
> 
> /// Returns the least possible interval between distinct instances of
> /// `T` in memory.  The result is always positive.
> public func spacing(ofValue: T) -> Int
> 
> /// Returns the minimum memory alignment of `T`.
> public func align(of: T.Type) -> Int
> 
> /// Returns the minimum memory alignment of `T`.
> public func align(ofValue: T) -> Int

If `type(of:)` takes an instance, then I think `size(of:)`, `spacing(of:)` and 
`align(of:)` need to do the same, with `size(ofType:)`, `spacing(ofType:)`, and 
`align(ofType:)` handling the type side of things.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-02 Thread Jānis Kiršteins via swift-evolution
I think you misunderstood my proposed syntax. To clarify:

enum Suit {
let bezierPath: UIBezierPath // Stored property declaration

case spades {
let bezierPath = UIBezierPath() // Declare and initialize and
local variable, this is not stored property declaration
// add drawing commands to bezierPath
self.bezierPath = bezierPath // Initialize stored property
with local variable. Stored property is shared among cases
}
}


I agree that cases should not be treated as pseudo-type, I am not
proposing that. What I am proposing is the that enum instance
behaviour and data can be very dependent of it case. And that there
should be easier and clearer ways to configure that using stored
properties.


On Thu, Jun 2, 2016 at 10:26 AM, Brent Royal-Gordon
 wrote:
>> As stated before it supposed to be per case initialization. You cannot
>> really have this analogy with other types as they have type and
>> instance while enums have type, case and instance.
>
> No. If structs have just type and instance, then so do enums.
>
> Cases in enums are analogous to stored properties in structs: they are a 
> means of organizing and representing concrete storage. They are not 
> first-class entities in the way that types and instances are. Much mischief 
> comes from thinking of cases as pseudo-types, or as some sort of peer to a 
> type.
>
>> But consider this:
>>
>> struct Struct {
>>static let bezierPath: UIBezierPath // shared
>>
>>static func initialize() {
>>bezierPath = UIBezierPath()
>>}
>> }
>
> Yes, because there's a `static` keyword on that declaration. That marks it as 
> something different from an ordinary `let`. Similarly, part of the idea of my 
> use of accessors is that the `accessor` keyword marks it as something 
> different from an ordinary `var`.
>
> (Also, you shouldn't use `initialize()` in Swift; you should set the variable 
> directly. Also also, I'm pretty sure that wouldn't work at all, because 
> `initialize()` is a normal method, not an initializer, and `bezierPath` is a 
> constant.)
>
> --
> Brent Royal-Gordon
> Architechies
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-02 Thread Brent Royal-Gordon via swift-evolution
> As stated before it supposed to be per case initialization. You cannot
> really have this analogy with other types as they have type and
> instance while enums have type, case and instance.

No. If structs have just type and instance, then so do enums.

Cases in enums are analogous to stored properties in structs: they are a means 
of organizing and representing concrete storage. They are not first-class 
entities in the way that types and instances are. Much mischief comes from 
thinking of cases as pseudo-types, or as some sort of peer to a type.

> But consider this:
> 
> struct Struct {
>static let bezierPath: UIBezierPath // shared
> 
>static func initialize() {
>bezierPath = UIBezierPath()
>}
> }

Yes, because there's a `static` keyword on that declaration. That marks it as 
something different from an ordinary `let`. Similarly, part of the idea of my 
use of accessors is that the `accessor` keyword marks it as something different 
from an ordinary `var`.

(Also, you shouldn't use `initialize()` in Swift; you should set the variable 
directly. Also also, I'm pretty sure that wouldn't work at all, because 
`initialize()` is a normal method, not an initializer, and `bezierPath` is a 
constant.)

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Patrick Smith via swift-evolution
Yeah I realise who Dave is :)

Ok, that’s good to know about your uses. An extra benefit that MemoryLayout has 
is a developer who is familiar with sizeof() from other languages (I only know 
of C), if it was called the same thing in Swift they might just go ahead and 
use it and add their own alignment tricks. Whereas a MemoryLayout type ties of 
all this functionality together in the one place, where they can discover that 
`stride`/`spacing` might serve them better.

Patrick

> On 2 Jun 2016, at 4:23 PM, Xiaodi Wu  wrote:
> 
> On Thu, Jun 2, 2016 at 12:37 AM, Patrick Smith  > wrote:
> Yes but, if they weren’t functions now, what would be the best design?
> 
> Dave's suggestions then were made in the context of a language that had 
> `.dynamicType`. The question today is how best to align these functions with 
> `type(of:)`. If we were to ignore this context, I'm not sure on what basis we 
> could judge whether a property or function is 'best' for these facilities.
>  
> How many Swift developers will be using this functionality? Less than 1%? I 
> trust Dave’s judgement because he is in that small group.
> 
> I would caution against this assumption. I'm not a particularly advanced 
> developer by any stretch of the imagination, and I've been using `strideof()` 
> plenty of times while doing some math with Accelerate.framework and Metal 
> buffers. That said, Dave's in a very small group indeed, the group that wrote 
> these functions to start with.

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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-02 Thread Jānis Kiršteins via swift-evolution
As stated before it supposed to be per case initialization. You cannot
really have this analogy with other types as they have type and
instance while enums have type, case and instance. But consider this:

struct Struct {
static let bezierPath: UIBezierPath // shared

static func initialize() {
bezierPath = UIBezierPath()
}
}

On Thu, Jun 2, 2016 at 12:18 AM, Brent Royal-Gordon
 wrote:
>> UIBezierPath is shared for all instances of the enum case. So stored
>> properties are stored per case, not per instance (you have associated
>> values for per instance values).
>>
>>> that isn't really what this syntax suggests is happening
>>
>> Please explain what makes you think that way.
>
> Because you wrote `let bezierPath = UIBezierPath()` in the middle of a type 
> definition, and in all other types, you would get a new bezier path for each 
> instance.
>
> struct Struct {
> let bezierPath = UIBezierPath() // per instance
> }
> class Class {
> let bezierPath = UIBezierPath() // per instance
> }
> func function() {
> let bezierPath = UIBezierPath() // per call
> }
> enum Enum {
> case aCase {
> let bezierPath = UIBezierPath() // shared?!?!
> }
> }
>
> --
> Brent Royal-Gordon
> Architechies
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Returned for Revision] SE-0095: Replace protocol<P1, P2> syntax with Any<P1, P2>

2016-06-02 Thread Austin Zheng via swift-evolution
I definitely agree with your concern about angle brackets being used outside a 
generic context. However, I think I'd prefer the core team syntax (unadorned 
"P1 & P2") if delimiters are out of the question for now.

One option might be to use parentheses: Any(X & Y & Z), or square brackets: 
Any[X & Y & Z]. The former might look too much like a function call, although 
if we're going to call '&' a type infix operator we might as well stretch the 
analogy as far as it'll go. I actually like the second approach: you can't 
define static subscripts (and you wouldn't be able to define them on `Any` even 
if you could), so it wouldn't occupy an already-extant syntactic slot. Either 
would give existential types their own characteristic syntax, avoiding the 
angle brackets issue you brought up.

Austin

> On Jun 1, 2016, at 11:39 PM, Xiaodi Wu  wrote:
> 
> On Thu, Jun 2, 2016 at 12:42 AM, Austin Zheng via swift-evolution 
> > wrote:
> Excellent.
> 
> I put together a PR with a revised proposal containing the core team's 
> recommended approach. If anyone is curious they can see it here: 
> https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md
>  
> 
> 
> Since this is the de-facto second round discussion thread, I'll start with my 
> personal opinion (which is *not* reflected in the PR): the '&' separators in 
> lieu of commas are a good idea, but I would still prefer the types to be 
> wrapped in "Any<>", at least when being used as existentials.
> 
> My reasons:
> 
> - Jordan Rose brought up a good point in one of the discussion threads today: 
> a resilience goal is to allow a library to add an associated type to a 
> protocol that had none and not have it break user code. If this is true 
> whatever syntax is used for existentials in Swift 3 should be a valid subset 
> of the generalized existential syntax used to describe protocol compositions 
> with no associated types.
> 
> - I would rather have "Any<>" be used consistently across all existential 
> types eventually than have it only be used for (e.g.) existential types with 
> `where` constraints, or allowing two different representations of the same 
> existential type (one with Any, and one without).
> 
> - I think any generalized existential syntax without delimiting markers (like 
> angle braces) is harder to read than syntax with such markers, so I would 
> prefer a design with those markers.
> 
> Agree with your reasons, but I'm still uncomfortable that things inside the 
> angle brackets would behave differently here than elsewhere. Would it help to 
> make a keyword out of `any` for existentials? Then you could have this:
> 
> ```
> func foo(value: any X & Y)
> ```
> 
> Best,
> Austin
> 
>> On Jun 1, 2016, at 10:17 PM, Chris Lattner > > wrote:
>> 
>> 
>>> On Jun 1, 2016, at 9:53 PM, Austin Zheng >> > wrote:
>>> 
>>> This was indeed a very thorough review by the core team. I'll prepare a v2 
>>> proposal with this feedback taken into account so we can continue moving 
>>> things along.
>>> 
>>> One quick question - is making whatever syntax is chosen for Swift 3 
>>> "forward-compatible" with a future generalized existential feature a 
>>> concern?
>> 
>> Yes it is a concern, but we assume that the “X & Y” syntax will always be 
>> accepted going forward, as sugar for the more general feature that is yet to 
>> be designed.
>> 
>> -Chris
> 
> 
> ___
> 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] [Returned for Revision] SE-0095: Replace protocol<P1, P2> syntax with Any<P1, P2>

2016-06-02 Thread Xiaodi Wu via swift-evolution
On Thu, Jun 2, 2016 at 12:42 AM, Austin Zheng via swift-evolution <
swift-evolution@swift.org> wrote:

> Excellent.
>
> I put together a PR with a revised proposal containing the core team's
> recommended approach. If anyone is curious they can see it here:
> https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md
>
> Since this is the de-facto second round discussion thread, I'll start with
> my personal opinion (which is *not* reflected in the PR): the '&'
> separators in lieu of commas are a good idea, but I would still prefer the
> types to be wrapped in "Any<>", at least when being used as existentials.
>
> My reasons:
>
> - Jordan Rose brought up a good point in one of the discussion threads
> today: a resilience goal is to allow a library to add an associated type to
> a protocol that had none and not have it break user code. If this is true
> whatever syntax is used for existentials in Swift 3 should be a valid
> subset of the generalized existential syntax used to describe protocol
> compositions with no associated types.
>
> - I would rather have "Any<>" be used consistently across all existential
> types eventually than have it only be used for (e.g.) existential types
> with `where` constraints, or allowing two different representations of the
> same existential type (one with Any, and one without).
>
> - I think any generalized existential syntax without delimiting markers
> (like angle braces) is harder to read than syntax with such markers, so I
> would prefer a design with those markers.
>

Agree with your reasons, but I'm still uncomfortable that things inside the
angle brackets would behave differently here than elsewhere. Would it help
to make a keyword out of `any` for existentials? Then you could have this:

```
func foo(value: any X & Y)
```

Best,
> Austin
>
> On Jun 1, 2016, at 10:17 PM, Chris Lattner  wrote:
>
>
> On Jun 1, 2016, at 9:53 PM, Austin Zheng  wrote:
>
> This was indeed a very thorough review by the core team. I'll prepare a v2
> proposal with this feedback taken into account so we can continue moving
> things along.
>
> One quick question - is making whatever syntax is chosen for Swift 3
> "forward-compatible" with a future generalized existential feature a
> concern?
>
>
> Yes it is a concern, but we assume that the “X & Y” syntax will always be
> accepted going forward, as sugar for the more general feature that is yet
> to be designed.
>
> -Chris
>
>
>
> ___
> 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] [Rejected] SE-0097: Normalizing naming for "negative" attributes

2016-06-02 Thread Jacob Bandes-Storch via swift-evolution
On Wed, Jun 1, 2016 at 10:25 PM, Chris Lattner  wrote:

> On Jun 1, 2016, at 9:28 PM, Jacob Bandes-Storch 
> wrote:
>
>
> On imported Objective-C API, the core team did a quick study of the Cocoa
>> APIs and found that most closure/block parameters are escaping in
>> practice.  As such, the core team feels that it isn’t overly burdensome to
>> ask that imported Objective-C APIs annotate their semantically noescape
>> block parameters with the clang __attribute__((noescape)) attribute.
>>
>
> This part is what I proposed last year; still waiting on an update:
>
>
> https://github.com/apple/swift-evolution/blob/master/proposals/0012-add-noescape-to-public-library-api.md
>
>
>
> The problem with that proposal, and the reason it is sitting around in
> limbo is:
>
> 1) it is prescriptive of a process “Audit system C/Objective-C
> libraries...", not a proposal for a set of specific changes.
>
> 2) swift-evolution isn’t the right place to propose changes for Foundation
> or other APIs outside of the standard library.
>
> It has been stuck in a crack for a long time, and has no hope of getting
> unstuck.  I think that at this point the right thing is to close it.  Is
> that ok with you?
>
> -Chris
>

Okay, but is there any other way the community can have input on the set of
functions/methods that should be updated, and some visibility into
whether/when this will happen? It was my impression that Philippe was
making progress on this, but I hadn't heard any more for a while. (My
concern would be APIs getting missed due to lack of community input.)
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Ad hoc enums / options

2016-06-02 Thread L Mihalkovic via swift-evolution

> On Jun 2, 2016, at 8:04 AM, Félix Cloutier  wrote:
> 
> I was once relying on the state of things to judge the validity of some 
> access modifier claims and I was rebuked on the grounds that proposals should 
> be evaluated based on their merits, not on implementation details.
> 
> And as far as implementation details go, this doesn't match what I understand 
> of tuples. Looking at SIL, tuple types from different declarations appear 
> just as identical as they do in source code. In fact, the output is exactly 
> the same even when using a tuple typealias. Do you have an experiment or 
> compiler code that would support your claims?

I do not understand your question as it is formulated. What I described is the 
external behavior. I did not make any reference to the internal structure of 
the C++ that has managed to make heavy reuse of certain concepts across the 
whole type system, so indeed part of the differences we perceive at the 
language level do not exist identically at the implementation level. A fact 
remains, the language is defined by its grammar… and the grammar chose to 
expose certain concepts through what we know as struct, class, enum, tuple. 
Swift could have decided to offer a single Ω data type that would have 
displayed the behavior of all it current user defined types depending on where 
it was used. but that would not be swift, right?!

> Félix
> 
>> Le 1 juin 2016 à 22:35:21, L Mihalkovic via swift-evolution 
>> > a écrit :
>> 
>> 
>>> On Jun 1, 2016, at 11:20 PM, Vladimir.S >> > wrote:
>>> 
>>> OK, I understand most of your points and feel the same regarding the 
>>> proposed feature... but:
>>> 
>>> > .. the compiler does not like when we define the same thing twice, and 
>>> > thse short form amount to doing what he does not let us do. ..
>>> > .. if we use an annotation that lets it know that "it is not a mistake..
>>> > I really dont want to write that enum myself, even though I am using the
>>> > same abbreviation twice". Otherwise, the compiler would let us know that
>>> > the second time could be a mistake because there is already something
>>> > with the same name...
>>> 
>>> I just wanted to understand how such enums are different than tuples in 
>>> meaning of "I don't want to write the struct myself", "Yes, I'm using the 
>>> same tuple twice", "Compiler will let us know that we used the same tuple 
>>> again and probably mistake as has already the same". (Not about differences 
>>> in implementation/representation on compiler level, but on level of one who 
>>> is writting the code)
>>> 
>>> Should we use the same arguments to propose the special annotation when we 
>>> have the same tuple more than once? No. So I believe there should be no 
>>> such limitation and special annotation for proposed enums.
>>> 
>> 
>> I am not sure the parallel can be made. A tuple is characterized by its 
>> structure, BUT the scope of its use is the VARIABLE where it is being used 
>> (I am simplifying by only referring to var/let cases). So from the 
>> compiler’s point of view, there is not a giant Tuples hash table where it 
>> can look for a given tuple definition based on its intrinsic name. So even 
>> if you repeat the same tuple definition every other line in your source 
>> code, the compiler never thinks that they are the same type because they ARE 
>> NOT the same. Each one is a different variable (the compiler would complain 
>> that the variable is defined multiple times though). To simplify the model, 
>> you could almost think that a tuple is a degenerate struct that is 
>> internally given the name of its usage site. It is not quite true but it is 
>> a close-enough approximation of what it really is.
>> 
>> The only rational for allowing a 
>> @I_know_what_I_am_doing_so_please_dont_complain annotation is to allow (and 
>> I am not saying it should be allowed)
>> 
>> 
>> func scaleAndCropLargeImage(
>> image: UIImage,
>> toSize size: CGSize,
>> operation: (.Fit | .Fill) = .Fit
>> ) -> UIImage {
>>   whoCaresThereIsReallyASingleTypeOfImagesAnyhow()
>> }
>> 
>> func scaleAndCropSmallImage(
>> image: UIImage,
>> toSize size: CGSize,
>> operation: (.Fit | .Fill) = .Fit
>> ) -> UIImage {
>>   whoCaresThereIsReallyASingleTypeOfImagesAnyhow()
>> }
>> 
>> 
>> private 
>> func whoCaresThereIsReallyASingleTypeOfImagesAnyhow(
>> image: UIImage,
>> toSize size: CGSize,
>> operation: (.Fit | .Fill) = .Fit
>> ) -> UIImage {
>> 
>> ___
>> 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] [Pitch] Renaming sizeof, sizeofValue, strideof, strideofValue

2016-06-02 Thread Xiaodi Wu via swift-evolution
On Thu, Jun 2, 2016 at 12:37 AM, Patrick Smith  wrote:

> Yes but, if they weren’t functions now, what would be the best design?
>

Dave's suggestions then were made in the context of a language that had
`.dynamicType`. The question today is how best to align these functions
with `type(of:)`. If we were to ignore this context, I'm not sure on what
basis we could judge whether a property or function is 'best' for these
facilities.


> How many Swift developers will be using this functionality? Less than 1%?
> I trust Dave’s judgement because he is in that small group.
>

I would caution against this assumption. I'm not a particularly advanced
developer by any stretch of the imagination, and I've been using
`strideof()` plenty of times while doing some math with
Accelerate.framework and Metal buffers. That said, Dave's in a very small
group indeed, the group that wrote these functions to start with.

> On 2 Jun 2016, at 3:27 PM, Xiaodi Wu  wrote:
>
> On Thu, Jun 2, 2016 at 12:24 AM, Patrick Smith  wrote:
>
>> I really like this idea. This IMO is lower level functionality than
>> `type(of:)` (née dynamicType), so I think it makes sense for it to be
>> grouped under its own domain, the MemoryLayout type.
>>
>> Plus MemoryLayout can be extended with new convenience methods.
>>
>> I’m fine with those old methods being removed, but I never use them so!
>> Is it the same as calling type(of:) then using that with MemoryLayout? I
>> imagine they could be fixit’d easily, and that they compile down to the
>> same underlying code.
>>
>
> I'm actually souring to the idea. It goes in the diametrically opposite
> direction from dynamicType. There, something was changed from being
> property-like to being function-like. Here, Dave's proposal would take
> something that's a function and turn it into a property. Hmm.
>
>> On 2 Jun 2016, at 3:05 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> 2. Dave A. and others expressed the opinion that these should probably
>> not be global functions; his preference was for:
>>
>> ```
>> MemoryLayout.size // currently sizeof()
>> MemoryLayout.spacing // currently strideof()
>> MemoryLayout.alignment // currently alignof()
>> ```
>>
>> 3. Dave A. proposed that sizeofValue(), strideofValue(), and
>> alignofValue() are better off removed altogether. I don't know if people
>> are going to be happy about this idea.
>>
>>
>>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Ad hoc enums / options

2016-06-02 Thread Félix Cloutier via swift-evolution
I was once relying on the state of things to judge the validity of some access 
modifier claims and I was rebuked on the grounds that proposals should be 
evaluated based on their merits, not on implementation details.

And as far as implementation details go, this doesn't match what I understand 
of tuples. Looking at SIL, tuple types from different declarations appear just 
as identical as they do in source code. In fact, the output is exactly the same 
even when using a tuple typealias. Do you have an experiment or compiler code 
that would support your claims?

Félix

> Le 1 juin 2016 à 22:35:21, L Mihalkovic via swift-evolution 
>  a écrit :
> 
> 
>> On Jun 1, 2016, at 11:20 PM, Vladimir.S > > wrote:
>> 
>> OK, I understand most of your points and feel the same regarding the 
>> proposed feature... but:
>> 
>> > .. the compiler does not like when we define the same thing twice, and 
>> > thse short form amount to doing what he does not let us do. ..
>> > .. if we use an annotation that lets it know that "it is not a mistake..
>> > I really dont want to write that enum myself, even though I am using the
>> > same abbreviation twice". Otherwise, the compiler would let us know that
>> > the second time could be a mistake because there is already something
>> > with the same name...
>> 
>> I just wanted to understand how such enums are different than tuples in 
>> meaning of "I don't want to write the struct myself", "Yes, I'm using the 
>> same tuple twice", "Compiler will let us know that we used the same tuple 
>> again and probably mistake as has already the same". (Not about differences 
>> in implementation/representation on compiler level, but on level of one who 
>> is writting the code)
>> 
>> Should we use the same arguments to propose the special annotation when we 
>> have the same tuple more than once? No. So I believe there should be no such 
>> limitation and special annotation for proposed enums.
>> 
> 
> I am not sure the parallel can be made. A tuple is characterized by its 
> structure, BUT the scope of its use is the VARIABLE where it is being used (I 
> am simplifying by only referring to var/let cases). So from the compiler’s 
> point of view, there is not a giant Tuples hash table where it can look for a 
> given tuple definition based on its intrinsic name. So even if you repeat the 
> same tuple definition every other line in your source code, the compiler 
> never thinks that they are the same type because they ARE NOT the same. Each 
> one is a different variable (the compiler would complain that the variable is 
> defined multiple times though). To simplify the model, you could almost think 
> that a tuple is a degenerate struct that is internally given the name of its 
> usage site. It is not quite true but it is a close-enough approximation of 
> what it really is.
> 
> The only rational for allowing a 
> @I_know_what_I_am_doing_so_please_dont_complain annotation is to allow (and I 
> am not saying it should be allowed)
> 
> 
> func scaleAndCropLargeImage(
> image: UIImage,
> toSize size: CGSize,
> operation: (.Fit | .Fill) = .Fit
> ) -> UIImage {
>   whoCaresThereIsReallyASingleTypeOfImagesAnyhow()
> }
> 
> func scaleAndCropSmallImage(
> image: UIImage,
> toSize size: CGSize,
> operation: (.Fit | .Fill) = .Fit
> ) -> UIImage {
>   whoCaresThereIsReallyASingleTypeOfImagesAnyhow()
> }
> 
> 
> private 
> func whoCaresThereIsReallyASingleTypeOfImagesAnyhow(
> image: UIImage,
> toSize size: CGSize,
> operation: (.Fit | .Fill) = .Fit
> ) -> UIImage {
> 
> ___
> 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