Re: [swift-users] Re-initializing lazy vars

2017-10-21 Thread Joanna Carter via swift-users
Oops! forgot to add example code for resetting with non-optional public var :

public struct TestStruct
{
  private var _description: String?
  
  public var description: String
  {
get
{
  return _description ?? ""
}
set
{
  _description = newValue
}
  }
  
  mutating func resetDescription()
  {
_description = nil
  }
}

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Re-initializing lazy vars

2017-10-21 Thread Joanna Carter via swift-users
> It just seems so obvious to create-if-nil, and makes it nice to reset stuff 
> that should be re-created. In my case, after my NSURLSession gets 
> invalidated, I wanted to set the property to nil, and next time a session was 
> needed, it would just get created.

The only thing I would query with the whole concept of resetting an implicitly 
unwrapped optional var is, with a simple example struct :

public struct TestStruct
{
  private var _description: String?
  
  public var description: String!
  {
get
{
  return _description ?? ""
}
set
{
  _description = newValue
}
  }
}

… test code would be :

  {
var test = TestStruct()

test.description = nil

let str: String = test.description
  }

The idea of setting a var to nil and then getting a valid object back seems a 
bit anachronistic.

I think I would rather add an explicit "reset" method.

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Can't implement generic subscript in protocol

2017-09-15 Thread Joanna Carter via swift-users
The answer to the segmentation fault is that I was trying to assign the 
subscript "method" to a closure var of the same signature.

It would seem Swift doesn't allow this :-(

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Can't implement generic subscript in protocol

2017-09-15 Thread Joanna Carter via swift-users
Xcode Version 9.0 (9A235)

Hmmm. I'm now getting a segmentation fault : 11 on a constructor when trying to 
implement type erasure :

protocol DataProvider
{
  associatedtype ItemType
  
  subscript(index: Int) -> ItemType { get }
}

class _AnyDataProviderBoxBase: DataProvider
{
  subscript(index: Int) -> itemType
  {
fatalError()
  }
}

class _AnyDataProviderBox: 
_AnyDataProviderBoxBase
{
  private let _subscript: (_ index: Int) -> providerType.ItemType
  
  init(_ base: providerType) // segmentation fault : 11
  {
_subscript = base.subscript
  }
  
  override subscript(index: Int) -> providerType.ItemType
  {
return _subscript(index)
  }
}

final class AnyDataProvider: DataProvider
{
  private let box: _AnyDataProviderBox
  
  init(_ base: providerType)
  {
self.box = _AnyDataProviderBox(base)
  }
  
  subscript(index: Int) -> providerType.ItemType
  {
return box[index]
  }
}

Joanna

--
Joanna Carter
Carter Consulting

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


[swift-users] Can't implement generic subscript in protocol

2017-09-15 Thread Joanna Carter via swift-users
Greetings

Now we've got generic subscripts, I thought I'd play…

protocol DataProvider
{
  subscript(index: Int) -> itemType { get }
}

class Test : DataProvider // error : Type 'Test' does not conform to protocol 
'DataProvider'
{
  subscript(index: Int) -> String
  {
return "Fred"
  }
}

Simple questions:

1. why does this not compile?
2. should it?
3. is there a workaround without declaring an associated type in the protocol?

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Can you use @autoclosure in a setter?

2017-09-11 Thread Joanna Carter via swift-users
Greetings

> I have a class with a property that needs to be really *really* lazy. So 
> lazy, in fact, that when you assign to that property, the class actually 
> stores a closure of what you assigned, which is only evaluated if and when 
> you actually attempt to read the property.
> 
> Simplified:
> 
> class Foo {
>   private var valueSource: () -> Bar
>   private var valueCache: Bar?
>   
>   init(_ v: @escaping @autoclosure () -> Bar) {
> valueSource = v
>   }
>   
>   var value: Bar {
> get {
>   if let v = valueCache { return v }
>   let w = valueSource()
>   valueCache = w
>   return w
> }
> set {
>   /* ??? */
> }
>   }
>   
>   // I want this function's logic to go in the setter above
>   func setValue(_ v: @escaping @autoclosure () -> Bar) {
> valueSource = v
> valueCache = nil
>   }
> }
> 
> The goal is to be able to write things like “someFoo.value = bar1 / bar2” (or 
> even more complex expressions) and not evaluate them until/unless the result 
> is actually needed.
> 
> Currently I am using “someFoo.setValue( bar1 / bar2 )”, which is not nearly 
> as ergonomic as the assignment syntax. So, is there a way to make this work?

Unless I'm missing something, can't you just call the closure that you passed 
to the init ? Or do you want to use a different closure ?

You could always have a var that is a tuple, with one part being the value and 
the other the closure.

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] CustomStringConvertible?

2017-09-09 Thread Joanna Carter via swift-users
Greetings

> Thanks for your reply, Rien. I just tried this again, and now it seems that 
> either is acceptable. Seems a little weird, but I guess I’d rather have more 
> flexibility than less.

> class GPS : Powerable, CustomStringConvertible {
> // Either of these work
> //var description: String {
> //return "I am a GPS"
> //}
> var description:String = "I am a GPS"

You can also implement description as a let, since there is no intention to 
modify it :

class GPS : Powerable, CustomStringConvertible
{
  let description = "I am a GPS"
  
  …
}

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Still can't derive from a generic class

2017-09-01 Thread Joanna Carter via swift-users
Hi Joe

Thanks for your input on this.

> This is likely due to the runtime not handling cycles properly in type 
> metadata initialization—a subclass T needs its base class metadata for 
> BaseObject, which in turn needs the metadata for T to instantiate the 
> generic type. This is something we plan to fix next year since it requires 
> runtime ABI changes.

Hmmm. I'm finding this really frustrating, waiting for features that I have 
been using for years, in another popular language (C#), to see the light of day.

Maybe application programmers are happy with Swift so far but, when it comes to 
my speciality of designing frameworks, I am constantly finding myself blocked 
by lack of metadata APIs :-(

I am talking about a couple of frameworks that underpin one of the largest 
business management systems in Europe, for which the client is asking a 
MacOS/iOS version.

> Would a protocol-based approach suffice? `Self` in a protocol extension would 
> give you access to the concrete type in a similar way:
> 
> protocol Base: AnyObject {
>  var properties:  [PartialKeyPath : AnyProperty] { get }
> }
> 
> extension Base {
>  func value(for keyPath: KeyPath) -> T?
>  {
>guard let property = properties[keyPath] else
>{
>  return nil
>}
> 
>return property.getValue()
>  }
> 
>  /*etc.*/
> }
> 
> class Test: Base {
>  let properties = [\Test.name: Property()]
> 
>  var name: String {
>get { return value(for: \.name) }
>set { set(value: newValue, for: \.name) }
>  }
> }

At first glance, I thought, Yes! But then I realised that this then requires a 
final class to cater for the use of Self in the protocol; something that would 
be a blocker for the class hierarchies that most users of the framework would 
want to create on top of the Base functionality.

I suppose I could look at using protocol-oriented composition but trying to 
avoid associated types in protocols in frameworks that use generics extensively 
is akin to hitting yourself repeatedly on the head with a hammer ;-)

And I really don't want to have to keep on repeating type-erasure boilerplate 
code to achieve that.

I think the realisation that I may well lose the chance of a pretty massive 
contract and that my client will lose an important business opportunity is 
finally dawning :-(

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Still can't derive from a generic class

2017-08-30 Thread Joanna Carter via swift-users
Hi Kenny

> Just curious, and because I have a distinct lack of imagination: can you 
> share a concrete case of this pattern?

class BaseObject
{
  private let properties: [PartialKeyPath : AnyProperty]
  
  init(properties: [PartialKeyPath : AnyProperty])
  {
self.properties = properties
  }
  
  func value(for keyPath: KeyPath) -> valueType?
  {
guard let property = properties[keyPath] else
{
  return nil
}

return property.getValue()
  }
  
  func set(value: valueType?, for keyPath: KeyPath)
  {
guard let property = properties[keyPath] else
{
  return
}

property.set(value: value)
  }
}

class Test : BaseObject
{
  var name: String?
  {
get
{
  return value(for: \.name)!
}
set
{
  set(value: newValue, for: \.name)
}
  }
  
  var number: Int?
  {
get
{
  return value(for: \.number)!
}
set
{
  set(value: newValue, for: \.number)
}
  }
  
  init()
  {
super.init(properties: [\Test.name : Property(), \Test.number : 
Property()])
  }
}

Without the generic rootType parameter, all the getter and setter methods need 
an explicit mention of the derived class for the keypath :

class Test : BaseObject
{
  var name: String?
  {
get
{
  return value(for: \Test.name)!
}
set
{
  set(value: newValue, for: \Test.name)
}
  }
  
  …
}

It was all so simple in C# :(

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Still can't derive from a generic class

2017-08-29 Thread Joanna Carter via swift-users
Hi Jon

> Le 29 août 2017 à 19:20, Jon Shier  a écrit :
> 
> This works fine for me in a playground in the latest Xcode 9 beta:
> 
> class Test { }
> 
> class Base { }
> 
> class Sub: Base { }
> 
> let sub = Sub()

That may well work but what I want is to be able to do is simpler than that :

class Base { }

class Test : Base { }

let test = Test()


Joanna

--
Joanna Carter
Carter Consulting

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


[swift-users] Still can't derive from a generic class

2017-08-29 Thread Joanna Carter via swift-users
Hi

I would have hoped by now that it should be possible to do :

class BaseObject
{
}

class Test : BaseObject
{
}

All compiles well but, at runtime, when calling let test = Test(), I get a 
"EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)" error.

This is something I have been able to do in C# for many a year. Why oh why can 
I still not do it in Swift ?

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Question with calling a method which returns `Self` on super

2017-08-11 Thread Joanna Carter via swift-users
I really must do more research before making accusations ;-)

> Which still leaves my question of why I have to reimplement the default 
> copy(other:) method from the protocol's extension in the base class ???

Apparently, the answer is to remove the declaration of the copy(other:) method 
from the protocol itself and to leave the default implementation in the 
extension !

So I now end up with :

protocol Copyable
{
  init(other: Self)
}

extension Copyable
{
  func copy() -> Self
  {
return type(of: self).init(other: self)
  }
}


class Shape : Copyable
{
  var color: NSColor
  
  init(color: NSColor)
  {
self.color = color
  }
  
  required init(other: Shape)
  {
color = other.color
  }
}

… and all is well with the world :-)

Mind you, the compiler error messages were hardly helpful to diagnosing this 
particular problem :-(

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Question with calling a method which returns `Self` on super

2017-08-11 Thread Joanna Carter via swift-users
> here is the scenario, I want to implement a Copying protocol which can be 
> used homogeneously
> 
> protocol Copying {
> func copy() -> Self
> }
> 
> Because this protocol contains neither associated-type-requirements or 
> self-requirements(requiring a method returning Self is different), it can 
> surely be used homogeneously.
> 
> let objects: [Copying] = 
> for copyable in objects {
> .
> }

But Copying does contain a Self requirement. It is used the result of the 
copy() method

Here is how I implement Copying :

protocol Copyable
{
  func copy() -> Self
  
  init(other: Self)
}

// This extension provides a default implementation
extension Copyable
{
  func copy() -> Self
  {
return type(of: self).init(other: self)
  }
}

implementing Copyable on a struct is simple :

struct Struct : Copyable
{
  var value: String
  
  init(value: String)
  {
self.value = value
  }
  
  init(other: Struct)
  {
value = other.value
  }
}

But implementing it on a class is slightly more troublesome.

class Shape : Copyable
{
  var color: NSColor
  
  init(color: NSColor)
  {
self.color = color
  }
}

At this stage, the compiler (obviously) screams that Copyable is not 
implemented but the first "error" it notices it marks as being on the default 
implementation in the extension:  Method 'copy()' in non-final class 'Shape' 
must return `Self` to conform to protocol 'Copyable'

Marking this error on the extension method, which obviously does exactly what 
the error says is missing ???

Implementing the copy() method in Shape kills this error message but leaves me 
wondering why I have to now repeat the exact same code in the implementing 
method that I wrote in the default method in the protocol extension ; something 
that the compiler is completely ignoring.

Implementing the protocol with a struct takes account of the default method but 
with a class ignores it. This smells remarkably like a bug !

Nonetheless, I now end up with the following code, complete with duplicate 
copy() method :

class Shape : Copyable
{
  var color: NSColor
  
  func copy() -> Self
  {
return type(of: self).init(other: self)
  }

  init(color: NSColor)
  {
self.color = color
  }
  
  required init(other: Shape)
  {
color = other.color
  }
}

Then I can go on to declare subclasses :

class Circle : Shape
{
  var radius: Double = 0.0
  
  init(color: NSColor, radius: Double)
  {
super.init(color: color)

self.radius = radius
  }

  required init(other: Shape)
  {
super.init(other: other)

if let other = other as? Circle
{
  radius = other.radius
}
  }
}


class Square : Shape
{
  var side: Double = 0.0
  
  init(color: NSColor, side: Double)
  {
super.init(color: color)

self.side = side
  }

  required init(other: Shape)
  {
super.init(other: other)

if let other = other as? Square
{
  side = other.side
}
  }
}

And, the, if I create an extension to Array :

extension Array where Element : Copyable
{
  func copy() -> Array
  {
var result = [Element]()

self.forEach { result.append($0.copy()) }

return result
  }
}

I can then use the following code to create an array of Shapes but, obviously 
not of Copyable, due to its restrictions on the Self requirements on the 
protocol.

{
  let shapes = [Circle(color: .black, radius: 5.0), Square(color: .black, side: 
5.0)]
  
  let copies = shapes.copy()
  
  …
}

Thus, another possible solution to your problem is to declare the required 
init(other: Self) in the protocol.

Which still leaves my question of why I have to reimplement the default 
copy(other:) method from the protocol's extension in the base class ???

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Constraining the conforming type of a protocol

2017-07-30 Thread Joanna Carter via swift-users
IMHO, there is a very subtle difference between :

protocol Toggling : Equatable
{
  …
}

extension Toggling
{
  …
}

… and :

protocol Toggling
{
  …
}

extension Toggling where Self : Equatable
{
  …
}

The first says that any type that implements Toggling also implements Equatable.

The second says that an implementing type can be Toggling without necessarily 
having to be Equatable.

Either way around, you are providing a default implementation for toggled() and 
toggle(), but, with the first version, toggled requires that Self is also 
Equatable.

Therefore, you are saying that, because the default implementation of Toggling 
demands that Self is Equatable, you have to also state that everything that is 
Toggling is also Equatable.

Since :

protocol Toggling where Self : Equatable

… is functionally identical to :

protocol Toggling : Equatable

… why would you want to use a more verbose way of saying the same thing ?

I would venture to suggest that there is no need for the longer syntax and that 
your bug report is not necessary

:-)

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-users] Simultaneous accesses, but modification requires exclusive access

2017-07-24 Thread Joanna Carter via swift-users
> Background:
> Just a little background into what I was trying to achieve (I could be wrong):
> 
> - I have a set of classes C1, C2, C3 which has a lot of common code
> 
> - I would like to build something that can be reused without exposing the 
> implementation details. (I can subclass but would expose the underlying 
> functions, same applies to protocol as well)
> 
> - I thought I would build helper class / struct which would contain the 
> common code. I can make the helper a private property so that the functions 
> wouldn’t be exposed to the instances of C1, C2, C3. In order to achieve that 
> I had to pass some functions from C1 into the Helper struct.
> 
> Question 2:
> - Is this problem (hiding implementation details) normally tackled using 
> Helper class (or struct) or is there a more better approach ?

Usually, as long as the protocol doesn't reference self or have associated 
types, I would use a protocol as the "abstract" type and then you could 
implement it in either a class or struct.

Joanna

--
Joanna Carter
Carter Consulting

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


[swift-users] Swift 4 emulating Decoder behaviour

2017-07-13 Thread Joanna Carter via swift-users
Greetings

I notice that, with Swift 4, I can decode an object like this :

• let retrievedSpot = try decoder.decode(ParkingSpot.self, from: 
retrievedData)  

And that will return a ParkingSpot, as expected, into retrievedSpot.

However, I thought I would try the same technique with one of my pet projects…

I have a protocol  and an implementing struct :

• public protocol PropertyProtocol  
• {  
•   static var propertyType: Any.Type { get }  
•   
•   var untypedValue: Any? { get }  
• }  
•   
• public struct Property : 
PropertyProtocol  
• {  
•   public static var propertyType: Any.Type  
•   {  
• return valueT.self  
•   }  
•   
•   public var untypedValue: Any?  
•   {  
• return value  
•   }  
•   
•   public var value = valueT()  
• }  

Now, I want to be able to use a "factory" method to create an instance of 
Property, bound to its parameter type. So, I followed the same principal as 
Decoder :

• struct PropertyFactory  
• {  
•   static func createProperty(_ type: T.Type) -> PropertyProtocol 
where T : DefaultValueProvider  
•   {  
• return type.createProperty()  
•   }  
• }  

DefaultValueProvider is defined as follows and String is extended to conform to 
it :

• public protocol DefaultValueProvider  
• {  
•   init()  
• }  
•   
• extension String : DefaultValueProvider { }  

Now, this works fine if I pass a known type :

• let pproperty = PropertyFactory.createProperty(String.self)  

But, if I hold the type to be passed in in an Any.Type or 
DefaultValueProvider.Type variable, then doing this :

• let type: Any.Type = String.self  
•   
• if let propertyType = type as? DefaultValueProvider.Type  
• {  
•   let p = PropertyFactory.createProperty(propertyType)  
•  
•   …  

Fails to compile with the message : Cannot invoke 'createProperty' with an 
argument list of type '(DefaultValueProvider.Type)'

Likewise Decoder.decode(…) will not accept storing the type in an Any.Type or 
Decodable.Type variable.

I find this odd and perplexing. Is this a known issue or has nobody yet 
realised that this could be useful ?

Joanna

--
Joanna Carter
Carter Consulting
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users