Re: [swift-evolution] [Proposal] Type Narrowing

2016-11-08 Thread David Hart via swift-evolution

> On 3 Nov 2016, at 20:23, Nevin Brackett-Rozinsky via swift-evolution 
>  wrote:
> 
> This looks like a lot of complexity for very little gain.
> 
> Aside from any implementation concerns, this proposal substantially increases 
> the cognitive load on developers. To figure out what a piece of code means, 
> someone reading it will have to mentally keep track of a “type stack” for 
> every variable. That is the opposite of “clarity at the point of use”.

Very well said. I think this is perhaps the number one complaint I have about 
the proposal.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Jose Cheyo Jimenez via swift-evolution


> On Nov 8, 2016, at 1:05 PM, Anton Zhilin  wrote:
> 
> 2016-11-08 23:43 GMT+03:00 Jose Cheyo Jimenez :
> 
>> Thank for thinking of this. I am not sure on the advantage of having nil as 
>> a concrete type. 
>> 
>> Have you seen this talk?
>> 
>> https://realm.io/news/swift-summit-al-skipp-monads/
>> 
>> "The concept of “nil” does not exist in Swift (despite the existence of the 
>> keyword nil!)"
>> 
>> Does that talk change your mind about this pitch?
> 
> Not much. We can talk about Swift literals being untyped as much as we want, 
> but still all of them, except for nil, have an internal storage type, which 
> is also picked by default.
> 
Having nil be a concrete type would be extremely confusing to me. I believe 
currently nil gets stripped out during compilation and it gets replaced with 
their respective Optional.none
 nil is just a convenient way to work with optionals. The same goes to implicit 
unwrap optionals !

I guess I don't see a reason why nil should be a concrete at all.  

> For example, integer literals are Builtin.Int2048, if I’m not mistaken. But 
> we just can’t store nil without creating an instance of a potentially complex 
> type.
> 
> And this proposal is not about adding nil to all types. You can do this now 
> with Any, in any case:
> 
> let optionalInt1: Any = 42
> let optionalInt2: Any = ()   // ewww
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread John McCall via swift-evolution

> On Nov 8, 2016, at 1:07 PM, Anton Zhilin via swift-evolution 
>  wrote:
> 
> 2016-11-08 23:53 GMT+03:00 Pyry Jahkola  >:
> 
> 
> 
> Then why not just:
> 
> public protocol ExpressibleByIntLiteral {
>   static var `nil`: Self
> }
> 
> …such that Foo.nil creates your nil value of type Foo?
> 
> 
> This proposal is not about creating an alternate syntax for nil as 
> Optional. It’s about granting nil literal its own type:
> 
> let a = nil
> print(type(of: a))  //=> Nil

Is this desirable?

John.

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


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
2016-11-09 0:12 GMT+03:00 Adrian Zubarev :

Could you elaborate an implementation for one of these functions:
>
func == (left: T?, right: Nil) {
switch left {
case .some(_): return false
case .none: return true
}
}

The implementation is basically the same as of now, except that instead of
Nil, there is _OptionalNilComparisonType.

Main use case of Nil would essentially be partial specialization of
functions.
See example with optional comparison: there exists a generic version that
takes a proper ExpressibleByNilLiteral (in this case Optional), but we
can apply simpler logic in case we see nil.

Frankly speaking, I’m not sure myself this feature would find any use
except for the mentioned optional comparison operators.
So I will probably stop pushing this forward.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
2016-11-09 0:11 GMT+03:00 arkadi daniyelian :

I could not clearly see the exact, concrete problem with the current
> implementation. IMAO such fundamental change requires a *very* serious
> reason and some thought on performance side of thing.
>
Performance will not be hurt, because as Robert noted, Nil will be
isomorphic to ().
Concrete problem, as stated in the proposal, is “hacks” that standard
library has to contain, because nil does not have its LiteralType.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Robert Widmann via swift-evolution
-1.  This type is isomorphic to () from a language-internal perspective and 
will introduce an extra name for which no useful algorithms can be written 
against from an external one - which makes the proposal isomorphic to one that 
introduces a keyword without significant justification.

~Robert Widmann

2016/11/08 16:07、Anton Zhilin via swift-evolution  
のメッセージ:

> 2016-11-08 23:53 GMT+03:00 Pyry Jahkola :
> 
>> Then why not just:
>> 
>> public protocol ExpressibleByIntLiteral {
>>   static var `nil`: Self
>> }
>> 
>> …such that Foo.nil creates your nil value of type Foo?
> 
> This proposal is not about creating an alternate syntax for nil as 
> Optional. It’s about granting nil literal its own type:
> 
> let a = nil
> print(type(of: a))  //=> Nil
> ___
> 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] Nil struct

2016-11-08 Thread Adrian Zubarev via swift-evolution
Could you elaborate an implementation for one of these functions:

func == (left: T?, right: Nil)
…
I’m a little confused how these would work, because the types are different and 
the optional is either .none or .some(T) of type Optional where the other 
side is Nil.



-- 
Adrian Zubarev
Sent with Airmail

Am 8. November 2016 um 22:07:53, Anton Zhilin (antonyzhi...@gmail.com) schrieb:

2016-11-08 23:53 GMT+03:00 Pyry Jahkola :

Then why not just:

    public protocol ExpressibleByIntLiteral {
      static var `nil`: Self
    }

…such that Foo.nil creates your nil value of type Foo?
This proposal is not about creating an alternate syntax for  
nil as Optional. It’s about granting  
nil literal its own type:

let a = nil
print(type(of: a))  //=> Nil
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
2016-11-08 23:44 GMT+03:00 Adrian Zubarev :

At first glance this doesn’t make any sense to me:
>
> public protocol ExpressibleByNilLiteral {
>   associatedtype NilLiteralType = Nil
>   init(nilLiteral: NilLiteralType)
> }
>
> What’s the need for associatedtype there?
>
> Shouldn’t it be just like this:
>
> public protocol ExpressibleByNilLiteral {
>
>   init(nilLiteral: Nil)
> }
>
> Probably. I just looked at ExpressibleByBooleanLiteral, and it contained
BooleanLiteralType, which should always be Bool by convention.
If someone knows, why this associatedtype is needed in
ExpressibleByBooleanLiteral, please explain.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
2016-11-08 23:43 GMT+03:00 Jose Cheyo Jimenez :

Thank for thinking of this. I am not sure on the advantage of having nil as
> a concrete type.
>
> Have you seen this talk?
>
> https://realm.io/news/swift-summit-al-skipp-monads/
>
> "The concept of “nil” does not exist in Swift (despite the existence of
> the keyword nil!)"
>
> Does that talk change your mind about this pitch?
>
Not much. We can talk about Swift literals being untyped as much as we
want, but still all of them, except for nil, have an internal storage type,
which is also picked by default.
For example, integer literals are Builtin.Int2048, if I’m not mistaken. But
we just can’t store nil without creating an instance of a potentially
complex type.

And this proposal is not about adding nil to all types. You can do this now
with Any, in any case:

let optionalInt1: Any = 42let optionalInt2: Any = ()   // ewww

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


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Adrian Zubarev via swift-evolution
This is a clean approach but that would not solve the example I mentioned.

let document: Document = [
"key" = nil // won't work for the second version of the implementation I 
mentioned
]
Do solve this problem here, I’d need a real Nil type I could extend.

extension Nil : MyProtocol { … }
Than the above example will work correctly.



-- 
Adrian Zubarev
Sent with Airmail

Am 8. November 2016 um 21:53:44, Pyry Jahkola (pyry.jahk...@iki.fi) schrieb:

If we start from this thought…

Adrian Zubarev wrote:
Shouldn’t it be just like this:
public protocol ExpressibleByNilLiteral {

  init(nilLiteral: Nil)
}

Then why not just:

    public protocol ExpressibleByIntLiteral {
      static var `nil`: Self
    }

…such that Foo.nil creates your nil value of type Foo?

— Pyry

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


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Pyry Jahkola via swift-evolution
If we start from this thought…

> Adrian Zubarev wrote:
> Shouldn’t it be just like this:
> public protocol ExpressibleByNilLiteral {
> 
>   init(nilLiteral: Nil)
> }

Then why not just:

public protocol ExpressibleByIntLiteral {
  static var `nil`: Self
}

…such that Foo.nil creates your nil value of type Foo?

— Pyry

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


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Adrian Zubarev via swift-evolution
At first glance this doesn’t make any sense to me:

public protocol ExpressibleByNilLiteral {
  associatedtype NilLiteralType = Nil
  init(nilLiteral: NilLiteralType)
}
What’s the need for associatedtype there?

Shouldn’t it be just like this:

public protocol ExpressibleByNilLiteral {

  init(nilLiteral: Nil)
}
I actually would appreciate this change, because of one thing I run into a few 
days ago.

I’m building a library for BSON (Binary JSON) where I have a struct Document 
which conforms to ExpressibleByDictionaryLiteral. Than I have a protocol which 
can convert any type to a value type my document can store.

Now I would have to choose how to implement ExpressibleByDictionaryLiteral:

public init(dictionaryLiteral elements: (String, Element.Value)...)

public init(dictionaryLiteral elements: (String, ElementValueConvertible)…)

If I would go for the second version, I’d lose the ExpressibleByNilLiteral from 
my value type but I could use every other type naturally.

With the proposed change I could extend Nil with my protocol and make the 
conversion naturally again.

That is the only advantage I would gain from such a change in the language.



-- 
Adrian Zubarev
Sent with Airmail

Am 8. November 2016 um 21:30:26, Anton Zhilin via swift-evolution 
(swift-evolution@swift.org) schrieb:

Gist link

Introduction

Change  
nil literal type from  
() to  
Nil.
Before:

public protocol ExpressibleByNilLiteral {
  init(nilLiteral: ())
}
After:

public struct Nil {
  init()
}
public protocol ExpressibleByNilLiteral {
  associatedtype NilLiteralType = Nil
  init(nilLiteral: NilLiteralType)
}
Motivation

Currently,  
nil differs from other literals: it doesn’t have its own type.
But in some cases we want to deal directly with it, without creating any 
instances.

The most important use case is comparison of an  
Optional to  
nil.
Currently, this operation is implemented using a hidden struct  
_OptionalNilComparisonType,
which is needed precisely because because  
nil does not have its own type.
Removal of such underscored types is one of the goals stated in Generics 
manifesto.

Additionally, declaration of  
ExpressibleByNilLiteral differs from all other  
Expressibles,
because it doesn’t have a  
Literal type. It is generally beneficial to eliminate special cases.

Proposed solution

Introduce a struct  
Nil, which becomes the default type for  
nil literals:

public struct Nil : ExpressibleByNilLiteral {
  init()
  init(nilLiteral: NilLiteralType)
}

let a = nil
print(type(of: a))   //=> Nil
Rewrite  
ExpressibleByNilLiteral:

public protocol ExpressibleByNilLiteral {
  associatedtype NilLiteralType = Nil
  init(nilLiteral: NilLiteralType)
}
Make use of  
Nil in the standard library:

public func == (left: T?, right: Nil)
public func == (left: Nil, right: T?)
public func != (left: T?, right: Nil)
public func != (left: Nil, right: T?)
public func ~= (left: Nil, right: T?)
Source compatibility


Nil identifier is taken, therefore applications that already use it will stop 
compiling.
Automatic migration is somewhat possible by renaming of the old entity; manual 
migration is recommended.

Applications that use declare  
ExpressibleByNilLiteral conformances will stop compiling.
Automatic migration is possible.

Effect on ABI stability

Applications that use  
Nil identifier will have to make ABI-breaking changes.

Otherwise, the change can mostly be applied in an ABI-compatible manner.

___
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] Nil struct

2016-11-08 Thread Jose Cheyo Jimenez via swift-evolution
Thank for thinking of this. I am not sure on the advantage of having nil as a 
concrete type. 

Have you seen this talk?

https://realm.io/news/swift-summit-al-skipp-monads/

"The concept of “nil” does not exist in Swift (despite the existence of the 
keyword nil!)"

Does that talk change your mind about this pitch? 





> On Nov 8, 2016, at 12:30 PM, Anton Zhilin via swift-evolution 
>  wrote:
> 
> Gist link
> 
> Introduction
> 
> Change nil literal type from () to Nil.
> Before:
> 
> public protocol ExpressibleByNilLiteral {
>   init(nilLiteral: ())
> }
> After:
> 
> public struct Nil {
>   init()
> }
> public protocol ExpressibleByNilLiteral {
>   associatedtype NilLiteralType = Nil
>   init(nilLiteral: NilLiteralType)
> }
> Motivation
> 
> Currently, nil differs from other literals: it doesn’t have its own type.
> But in some cases we want to deal directly with it, without creating any 
> instances.
> 
> The most important use case is comparison of an Optional to nil.
> Currently, this operation is implemented using a hidden struct 
> _OptionalNilComparisonType,
> which is needed precisely because because nil does not have its own type.
> Removal of such underscored types is one of the goals stated in Generics 
> manifesto.
> 
> Additionally, declaration of ExpressibleByNilLiteral differs from all other 
> Expressibles,
> because it doesn’t have a Literal type. It is generally beneficial to 
> eliminate special cases.
> 
> Proposed solution
> 
> Introduce a struct Nil, which becomes the default type for nil literals:
> 
> public struct Nil : ExpressibleByNilLiteral {
>   init()
>   init(nilLiteral: NilLiteralType)
> }
> 
> let a = nil
> print(type(of: a))   //=> Nil
> Rewrite ExpressibleByNilLiteral:
> 
> public protocol ExpressibleByNilLiteral {
>   associatedtype NilLiteralType = Nil
>   init(nilLiteral: NilLiteralType)
> }
> Make use of Nil in the standard library:
> 
> public func == (left: T?, right: Nil)
> public func == (left: Nil, right: T?)
> public func != (left: T?, right: Nil)
> public func != (left: Nil, right: T?)
> public func ~= (left: Nil, right: T?)
> Source compatibility
> 
> Nil identifier is taken, therefore applications that already use it will stop 
> compiling.
> Automatic migration is somewhat possible by renaming of the old entity; 
> manual migration is recommended.
> 
> Applications that use declare ExpressibleByNilLiteral conformances will stop 
> compiling.
> Automatic migration is possible.
> 
> Effect on ABI stability
> 
> Applications that use Nil identifier will have to make ABI-breaking changes.
> 
> Otherwise, the change can mostly be applied in an ABI-compatible manner.
> 
> ___
> 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] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
Gist link 
Introduction

Change nil literal type from () to Nil.
Before:

public protocol ExpressibleByNilLiteral {
  init(nilLiteral: ())
}

After:

public struct Nil {
  init()
}
public protocol ExpressibleByNilLiteral {
  associatedtype NilLiteralType = Nil
  init(nilLiteral: NilLiteralType)
}

Motivation

Currently, nil differs from other literals: it doesn’t have its own type.
But in some cases we want to deal directly with it, without creating any
instances.

The most important use case is comparison of an Optional to nil.
Currently, this operation is implemented using a hidden struct
_OptionalNilComparisonType,
which is needed precisely because because nil does not have its own type.
Removal of such underscored types is one of the goals stated in Generics
manifesto.

Additionally, declaration of ExpressibleByNilLiteral differs from all other
Expressibles,
because it doesn’t have a Literal type. It is generally beneficial to
eliminate special cases.
Proposed solution

Introduce a struct Nil, which becomes the default type for nil literals:

public struct Nil : ExpressibleByNilLiteral {
  init()
  init(nilLiteral: NilLiteralType)
}
let a = nilprint(type(of: a))   //=> Nil

Rewrite ExpressibleByNilLiteral:

public protocol ExpressibleByNilLiteral {
  associatedtype NilLiteralType = Nil
  init(nilLiteral: NilLiteralType)
}

Make use of Nil in the standard library:

public func == (left: T?, right: Nil)public func == (left: Nil,
right: T?)public func != (left: T?, right: Nil)public func !=
(left: Nil, right: T?)public func ~= (left: Nil, right: T?)

Source compatibility

Nil identifier is taken, therefore applications that already use it will
stop compiling.
Automatic migration is somewhat possible by renaming of the old entity;
manual migration is recommended.

Applications that use declare ExpressibleByNilLiteral conformances will
stop compiling.
Automatic migration is possible.
Effect on ABI stability

Applications that use Nil identifier will have to make ABI-breaking changes.

Otherwise, the change can mostly be applied in an ABI-compatible manner.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Contiguous Memory and the Effect of Borrowing on Safety

2016-11-08 Thread John McCall via swift-evolution
> On Nov 8, 2016, at 7:44 AM, Joe Groff via swift-evolution 
>  wrote:
>> On Nov 7, 2016, at 3:55 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Mon Nov 07 2016, John McCall  wrote:
>> 
 On Nov 6, 2016, at 1:20 PM, Dave Abrahams via swift-evolution 
  wrote:
 
 
 Given that we're headed for ABI (and thus stdlib API) stability, I've
 been giving lots of thought to the bottom layer of our collection
>>> 
 abstraction and how it may limit our potential for efficiency.  In
 particular, I want to keep the door open for optimizations that work on
 contiguous memory regions.  Every cache-friendly data structure, even if
 it is not an array, contains contiguous memory regions over which
 operations can often be vectorized, that should define boundaries for
 parallelism, etc.  Throughout Cocoa you can find patterns designed to
 exploit this fact when possible (NSFastEnumeration).  Posix I/O bottoms
 out in readv/writev, and MPI datatypes essentially boil down to
 identifying the contiguous parts of data structures.  My point is that
 this is an important class of optimization, with numerous real-world
 examples.
 
 If you think about what it means to build APIs for contiguous memory
 into abstractions like Sequence or Collection, at least without
 penalizing the lowest-level code, it means exposing UnsafeBufferPointers
 as a first-class part of the protocols, which is really
 unappealing... unless you consider that *borrowed* UnsafeBufferPointers
 can be made safe.  
 
 [Well, it's slightly more complicated than that because
 UnsafeBufferPointer is designed to bypass bounds checking in release
 builds, and to ensure safety you'd need a BoundsCheckedBuffer—or
 something—that checks bounds unconditionally... but] the point remains
 that
 
 A thing that is unsafe when it's arbitrarily copied can become safe if
 you ensure that it's only borrowed (in accordance with well-understood
 lifetime rules).
>>> 
>>> UnsafeBufferPointer today is a copyable type.  Having a borrowed value
>>> doesn't prevent you from making your own copy, which could then escape
>>> the scope that was guaranteeing safety.
>>> 
>>> This is fixable, of course, but it's a more significant change to the
>>> type and how it would be used.
>> 
>> It sounds like you're saying that, to get static safety benefits from
>> ownership, we'll need a whole parallel universe of safe move-only
>> types. Seems a cryin' shame.
> 
> We've discussed the possibility of types being able to control their 
> "borrowed" representation. Even if this isn't something we generalize, arrays 
> and contiguous buffers might be important enough to the language that your 
> safe BufferPointer could be called 'borrowed ArraySlice', with the owner 
> backreference optimized out of the borrowed representation. Perhaps Array's 
> own borrowed representation would benefit from acting like a slice rather 
> than a whole-buffer borrow too.

The disadvantage of doing this is that it much more heavily penalizes the case 
where we actually do a copy from a borrowed reference — it becomes an actual 
array copy, not just a reference bump.

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


Re: [swift-evolution] Contiguous Memory and the Effect of Borrowing on Safety

2016-11-08 Thread John McCall via swift-evolution
> On Nov 7, 2016, at 4:59 PM, Dave Abrahams  wrote:
> on Mon Nov 07 2016, John McCall  wrote:
> 
>>> On Nov 7, 2016, at 3:55 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> on Mon Nov 07 2016, John McCall  wrote:
>>> 
> On Nov 6, 2016, at 1:20 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
>> 
> 
> Given that we're headed for ABI (and thus stdlib API) stability, I've
> been giving lots of thought to the bottom layer of our collection
 
> abstraction and how it may limit our potential for efficiency.  In
> particular, I want to keep the door open for optimizations that work on
> contiguous memory regions.  Every cache-friendly data structure, even if
> it is not an array, contains contiguous memory regions over which
> operations can often be vectorized, that should define boundaries for
> parallelism, etc.  Throughout Cocoa you can find patterns designed to
> exploit this fact when possible (NSFastEnumeration).  Posix I/O bottoms
> out in readv/writev, and MPI datatypes essentially boil down to
> identifying the contiguous parts of data structures.  My point is that
> this is an important class of optimization, with numerous real-world
> examples.
> 
> If you think about what it means to build APIs for contiguous memory
> into abstractions like Sequence or Collection, at least without
> penalizing the lowest-level code, it means exposing UnsafeBufferPointers
> as a first-class part of the protocols, which is really
> unappealing... unless you consider that *borrowed* UnsafeBufferPointers
> can be made safe.  
> 
> [Well, it's slightly more complicated than that because
> UnsafeBufferPointer is designed to bypass bounds checking in release
> builds, and to ensure safety you'd need a BoundsCheckedBuffer—or
> something—that checks bounds unconditionally... but] the point remains
> that
> 
> A thing that is unsafe when it's arbitrarily copied can become safe if
> you ensure that it's only borrowed (in accordance with well-understood
> lifetime rules).
 
 UnsafeBufferPointer today is a copyable type.  Having a borrowed value
 doesn't prevent you from making your own copy, which could then escape
 the scope that was guaranteeing safety.
 
 This is fixable, of course, but it's a more significant change to the
 type and how it would be used.
>>> 
>>> It sounds like you're saying that, to get static safety benefits from
>>> ownership, we'll need a whole parallel universe of safe move-only
>>> types. Seems a cryin' shame.
>> 
>> Well, if we can eliminate the unsafe, copyable types, that would be
>> great, of course.  I don't know whether that's achievable given our C
>> interop goals.
> 
> I'm not suggesting we can do that.  
> 
> I'm suggesting that in order to get a copy of some borrowed thing, you
> might have to utter the word "unsafe" because it's a thing that can't
> escape without compromising static safety guarantees, e.g. (strawman
> syntax):
> 
>   interop_with_c(unsafe { someBuffer })

Hmm.  We might be able to to do this.

John.

>> Another option is to attack escapes directly.  The safety guarantee
>> you're looking for is just that the value doesn't escape its scope,
>> and while it's true that move-only borrowed values aren't allowed to
>> escape, that constraint doesn't *require* borrowing or move-only-ness
>> to work.  We already have non-escaping values in the language —
>> noescape functions — and there's nothing stopping us from applying
>> that same logic to other types.  
> 
> Sure, but if a copyable version of a type is unsafe to handle, and
> “unsafe” is encoded into the type's name, we end up with no way to
> represent in code the fact that an instance that's been statically
> constrained to be borrowed and non-escaping is actually safe.
> 
> Look, today we have 
> 
>   a.withUnsafeBufferPointer {
>  ...
>   }
> 
> Now, if we had a version of UnsafeBufferPointer that included bounds
> checking, we'd still need to spell that 
> 
>   a.withUnsafeBoundsCheckedBufferPointer {
>  ...
>   }
> 
> today.  With first-class ownership, it could be
> 
>   a.withBoundsCheckedBufferPointer {
>  ...
>   }
> 
> totally safe!  So what does that imply about the name we'll use for the
> type of the closure parameter?
> 
>> There would be annotation problems, though, since existing functions
>> operating on pointers would be allowed to escape them.
> 
> Not sure what you have in mind here.
> 
> -- 
> -Dave

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


Re: [swift-evolution] Contiguous Memory and the Effect of Borrowing on Safety

2016-11-08 Thread Joe Groff via swift-evolution

> On Nov 7, 2016, at 3:55 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Mon Nov 07 2016, John McCall  wrote:
> 
>>> On Nov 6, 2016, at 1:20 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> Given that we're headed for ABI (and thus stdlib API) stability, I've
>>> been giving lots of thought to the bottom layer of our collection
>> 
>>> abstraction and how it may limit our potential for efficiency.  In
>>> particular, I want to keep the door open for optimizations that work on
>>> contiguous memory regions.  Every cache-friendly data structure, even if
>>> it is not an array, contains contiguous memory regions over which
>>> operations can often be vectorized, that should define boundaries for
>>> parallelism, etc.  Throughout Cocoa you can find patterns designed to
>>> exploit this fact when possible (NSFastEnumeration).  Posix I/O bottoms
>>> out in readv/writev, and MPI datatypes essentially boil down to
>>> identifying the contiguous parts of data structures.  My point is that
>>> this is an important class of optimization, with numerous real-world
>>> examples.
>>> 
>>> If you think about what it means to build APIs for contiguous memory
>>> into abstractions like Sequence or Collection, at least without
>>> penalizing the lowest-level code, it means exposing UnsafeBufferPointers
>>> as a first-class part of the protocols, which is really
>>> unappealing... unless you consider that *borrowed* UnsafeBufferPointers
>>> can be made safe.  
>>> 
>>> [Well, it's slightly more complicated than that because
>>> UnsafeBufferPointer is designed to bypass bounds checking in release
>>> builds, and to ensure safety you'd need a BoundsCheckedBuffer—or
>>> something—that checks bounds unconditionally... but] the point remains
>>> that
>>> 
>>> A thing that is unsafe when it's arbitrarily copied can become safe if
>>> you ensure that it's only borrowed (in accordance with well-understood
>>> lifetime rules).
>> 
>> UnsafeBufferPointer today is a copyable type.  Having a borrowed value
>> doesn't prevent you from making your own copy, which could then escape
>> the scope that was guaranteeing safety.
>> 
>> This is fixable, of course, but it's a more significant change to the
>> type and how it would be used.
> 
> It sounds like you're saying that, to get static safety benefits from
> ownership, we'll need a whole parallel universe of safe move-only
> types. Seems a cryin' shame.

We've discussed the possibility of types being able to control their "borrowed" 
representation. Even if this isn't something we generalize, arrays and 
contiguous buffers might be important enough to the language that your safe 
BufferPointer could be called 'borrowed ArraySlice', with the owner 
backreference optimized out of the borrowed representation. Perhaps Array's own 
borrowed representation would benefit from acting like a slice rather than a 
whole-buffer borrow too.

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


Re: [swift-evolution] [Proposal] Type Narrowing

2016-11-08 Thread ilya via swift-evolution
If I correctly understand the proposal, I'm -1 on this.

(1) You can define different methods with the same name on T and
Optional (description is such an example). Then what does this do?

// someMethod is defined both for T and T?
// var foo: T?
if foo != nil {
foo.someMethod()
}

I say there is a clear expectation that foo.someMethod() should call the
method of T?, even inside the if block, since this is how the dot works.
However, according to the proposal it will call another method (or become
an error?).

I think the languages that use optional narrowing are the ones where T? is
not a separate type, so that it cannot have its own methods.

(2) Should this work?

// compilcatedStuff is a method of T
// class A { var foo: T? }

if foo != nil {
foo.compilcatedStuff()
foo.compilcatedStuff()
foo.compilcatedStuff()
}

Suppose the compiler doesn't have enough information about compilcatedStuff
to know what happens inside. Then it's possible that foo.compilcatedStuff
will actually change foo (for example, foo could be a relationship and
compilcatedStuff may be deleting the relationship). So, what is the
suggestion for this example? Perhaps

if foo != nil {
foo.compilcatedStuff()
foo?.compilcatedStuff()
foo?.compilcatedStuff()
}

or some other choice?


On Tue, Nov 8, 2016 at 9:44 AM Haravikk via swift-evolution <
swift-evolution@swift.org> wrote:

> On 7 Nov 2016, at 19:31, Charlie Monroe  wrote:
> There are two cases:
>
> if foo != nil {
> foo!.doSomething()
> }
>
>
> Currently, accessing a non-optional value with ! produces an error:
>
> let foo = Bar()
> foo!.doSomething() // ERROR
>
>
> Second:
>
> if foo != nil {
> // Using ? to be extra cautious, if foo is var
> foo?.doSomething()
> }
>
>
> This again currently produces an error:
>
> let foo = Bar()
> foo?.doSomething() // ERROR
>
>
> Which is generally, what would semantically happen - the variable would
> loose it optionality. Or am I wrong?
>
>
> I probably haven't clarified well enough but under type-narrowing these
> would be warnings rather than errors; i.e- the general type of foo is still
> Optional, the type-checker merely knows that it can't be nil at that point,
> so would inform you that the ? or ! are unnecessary.
>
> This is what I was trying to get at in the type-widening section;
> basically, if you have a variable whose type is narrowed, but do something
> that makes no sense for the narrowed type, then the type is widened until
> either a match is found or it can't go any wider (producing an error as
> normal).
>
> So in your examples foo is Optional.some, as a result the ? and !
> operators make no sense, so the type is widened back to Optional where
> it does make sense and the code compiles, but a warning is produced to
> inform you that you don't need to use those operators.
>
> On 7 Nov 2016, at 19:31, Charlie Monroe  wrote:
> I agree that designing a language around the compiler speed is wrong, but
> I believe designing the language without taking it into account is just as
> wrong. It's not worth designing features that would make the compilation so
> slow it would render the language unusable.
>
> Note that I have only very limited experience with compiler
> implementation, I've only made a few minor things with Clang a few years
> back, so please feel free to correct me.
>
>
> I'm not that familiar with the actual architecture either, but narrowing
> *should* be fairly simple; basically any time the compiler hits a condition
> or statement defined as a narrowing trigger, it pops the new narrower type
> onto a stack of types for that variable (in that branch). Now whenever the
> compiler reaches another statement for that variable (method call etc.) it
> resolves it first against the narrowest type, otherwise it goes up the
> stack (widening) till it finds a match or fails.
>
> When a branch closes with a stack of types, the compiler will compare to
> other branches to see which type is the narrowest that they have in common;
> this is actually fairly simple (shorten the stack for each branch to the
> length of the shortest stack, then discard elements until the current one
> is a match for all branches, thus you now know what the narrowest type is
> past that point).
>
> So, for types that never narrow there should be no speed difference, while
> for narrowed types there shouldn't be much of a difference, as these stacks
> of types shouldn't get very large in most cases (I'd expect anything more
> than three to be pretty rare).
> ___
> 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] Type Narrowing

2016-11-08 Thread Haravikk via swift-evolution

> On 7 Nov 2016, at 19:31, Charlie Monroe  wrote:
> There are two cases:
> 
> if foo != nil { 
> foo!.doSomething() 
> }
> 
> Currently, accessing a non-optional value with ! produces an error:
> 
> let foo = Bar()
> foo!.doSomething() // ERROR
> 
> Second:
> 
> if foo != nil { 
> // Using ? to be extra cautious, if foo is var
> foo?.doSomething() 
> }
> 
> This again currently produces an error:
> 
> let foo = Bar()
> foo?.doSomething() // ERROR
> 
> Which is generally, what would semantically happen - the variable would loose 
> it optionality. Or am I wrong?

I probably haven't clarified well enough but under type-narrowing these would 
be warnings rather than errors; i.e- the general type of foo is still Optional, 
the type-checker merely knows that it can't be nil at that point, so would 
inform you that the ? or ! are unnecessary.

This is what I was trying to get at in the type-widening section; basically, if 
you have a variable whose type is narrowed, but do something that makes no 
sense for the narrowed type, then the type is widened until either a match is 
found or it can't go any wider (producing an error as normal).

So in your examples foo is Optional.some, as a result the ? and ! 
operators make no sense, so the type is widened back to Optional where it 
does make sense and the code compiles, but a warning is produced to inform you 
that you don't need to use those operators.

> On 7 Nov 2016, at 19:31, Charlie Monroe  wrote:
> I agree that designing a language around the compiler speed is wrong, but I 
> believe designing the language without taking it into account is just as 
> wrong. It's not worth designing features that would make the compilation so 
> slow it would render the language unusable.
> 
> Note that I have only very limited experience with compiler implementation, 
> I've only made a few minor things with Clang a few years back, so please feel 
> free to correct me.

I'm not that familiar with the actual architecture either, but narrowing 
*should* be fairly simple; basically any time the compiler hits a condition or 
statement defined as a narrowing trigger, it pops the new narrower type onto a 
stack of types for that variable (in that branch). Now whenever the compiler 
reaches another statement for that variable (method call etc.) it resolves it 
first against the narrowest type, otherwise it goes up the stack (widening) 
till it finds a match or fails.

When a branch closes with a stack of types, the compiler will compare to other 
branches to see which type is the narrowest that they have in common; this is 
actually fairly simple (shorten the stack for each branch to the length of the 
shortest stack, then discard elements until the current one is a match for all 
branches, thus you now know what the narrowest type is past that point).

So, for types that never narrow there should be no speed difference, while for 
narrowed types there shouldn't be much of a difference, as these stacks of 
types shouldn't get very large in most cases (I'd expect anything more than 
three to be pretty rare).___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution