Re: Init in Swift

2016-09-06 Thread Gerriet M. Denkmann

> On 7 Sep 2016, at 11:42, Quincey Morris  
> wrote:
> 
> On Sep 6, 2016, at 21:31 , Gerriet M. Denkmann  wrote:
>> 
>> My Swift book (2.2) has no mention of “private” (Swift 3 beta has).
> 
> It’s in the 2.2 book under “Language Guide” section “Access Control”

You are right. I used Books.app on my iPad to search for “private” and it found 
only private-use Unicode code points.
Probably my iPad is broken.

> 
>> But even assuming I had Swift 3, I do not quite understand how this should 
>> be done (I may be a bit dense).
> 
> It’s a bit of syntactical pseudo-magic, but it makes sense when you think 
> about it.

[…]

> In that case, you can freely change the value inside the class, but to 
> clients of the class, it “looks like” the property is declared like this: […]

I am more concerned with methods inside my class (and compiler optimisation, 
which might work better, if the compiler knows something to be constant).


> This use of ‘private(set)’ doesn’t prevent you from accidentally changing the 
> value inside the class somewhere. If you want to do that, you’re going to 
> have to get a bit more exotic, maybe a ‘lazy’ let.

I’ll try to read about “lazy”. But right now I am myself a bit lazy and must 
other things first.

Thanks a lot for your help!

Kind regards,

Gerriet.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-06 Thread Marco S Hyman
> 
> My Swift book (2.2) has no mention of “private” (Swift 3 beta has).
> But even assuming I had Swift 3, I do not quite understand how this should be 
> done (I may be a bit dense).

Page 508 in the Swift 2.2 book I just downloaded from iBooks.

“Getters and Setters
Getters and setters for constants, variables, properties, and subscripts 
automatically receive the same access level as the constant, variable, 
property, or subscript they belong to.

You can give a setter a lower access level than its corresponding getter, to 
restrict the read-write scope of that variable, property, or subscript. You 
assign a lower access level by writing private(set) or internal(set) before the 
var or subscript introducer.

”

Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2.2).” iBooks. 
https://itun.es/us/jEUH0.l



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-06 Thread Quincey Morris
On Sep 6, 2016, at 21:31 , Gerriet M. Denkmann  wrote:
> 
> My Swift book (2.2) has no mention of “private” (Swift 3 beta has).

It’s in the 2.2 book under “Language Guide” section “Access Control"

> But even assuming I had Swift 3, I do not quite understand how this should be 
> done (I may be a bit dense).

It’s a bit of syntactical pseudo-magic, but it makes sense when you think about 
it.

If you have (say) an instance property:

class X {
var x: int
}

then property x is both gettable and settable by clients of the class. If you 
declare it private:

class X {
private var x: int
}

then (like Obj-C) the property is private and can only be used inside the 
class. But you can declare just the setter to be private, using this syntax:

class X {
private(set) var x: int
}

In that case, you can freely change the value inside the class, but to clients 
of the class, it "looks like" the property is declared like this:

class X {
let x: int
}

The Obj-C analog is to declare the property ‘readonly’ in the public interface 
in the .h file, and ‘readwrite’ in a private interface extension inside the .m 
file.

This use of ‘private(set)’ doesn’t prevent you from accidentally changing the 
value inside the class somewhere. If you want to do that, you’re going to have 
to get a bit more exotic, maybe a ‘lazy’ let.

In Swift 2, “private” actually means “accessible by everything in the same 
source file”. In Swift 3, that’s renamed to “fileprivate”, and “private” means 
“accessible only within the declaring class/struct”.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-06 Thread Gerriet M. Denkmann

> On 7 Sep 2016, at 11:28, Quincey Morris  
> wrote:
> 
> On Sep 6, 2016, at 21:14 , Gerriet M. Denkmann  wrote:
>> 
>> But I cannot get this to work.
> 
> Meaning … ?? A compiler error? What does the source code look like, of the 
> protocol with the class func in it? What is the error message?

Struggling in a Playground I get lots of different compiler errors with 
different tries.
The first one I remember: “class” was not allowed in a protocol extension, I 
was told to use “static” instead.

> 
>> NewSuper uses this classFunction like:
>> func otherFunction( arg: UInt64) -> UInt64
>> {
>>  return self.dynamicType.classFunction(  arg ) + 21
>> }
> 
> If this is how you’re using it, it’d be clearer for the method you’re 
> currently calling “classFunction” to be an instance method called something 
> like “utilityFunction”. The only real reason it would *have* to be a class 
> function would be if you’re calling it in a context where there is no 
> instance — and the above is not that.

This is a very good idea. I was using a class function, only because it does 
not access any of the ivars.
But it could be an instance method as well (and, as you mentioned: it better 
should be).

I’ll try to fix this in my code.

Thanks a lot!

Kind regards,

Gerriet.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-06 Thread Gerriet M. Denkmann

> On 7 Sep 2016, at 10:49, Quincey Morris  
> wrote:
> 
> On Sep 6, 2016, at 17:17 , Gerriet M. Denkmann  wrote:
>> 
>> But what to do about localConstantDependingOnSuper?
[…]
> Anyway, this particular example is fairly easily solved by declaring 
> “localConstantDependingOnSuper” as ‘private(set)’.

My Swift book (2.2) has no mention of “private” (Swift 3 beta has).
But even assuming I had Swift 3, I do not quite understand how this should be 
done (I may be a bit dense).

Could you please elaborate?

Kind regards,

Gerriet.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-06 Thread Quincey Morris
On Sep 6, 2016, at 21:14 , Gerriet M. Denkmann  wrote:
> 
> But I cannot get this to work.

Meaning … ?? A compiler error? What does the source code look like, of the 
protocol with the class func in it? What is the error message?

> NewSuper uses this classFunction like:
> func otherFunction( arg: UInt64) -> UInt64
> {
>   return self.dynamicType.classFunction(  arg ) + 21
> }

If this is how you’re using it, it’d be clearer for the method you’re currently 
calling “classFunction” to be an instance method called something like 
“utilityFunction”. The only real reason it would *have* to be a class function 
would be if you’re calling it in a context where there is no instance — and the 
above is not that.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-06 Thread Gerriet M. Denkmann

> On 7 Sep 2016, at 10:49, Quincey Morris  
> wrote:
> 
>> Another problem:
>> Super → SubA and SubB.
>> SubA → SubA1 and SubA2
>> SubB → SubB1 and SubB2
>> 
>> Both SubA1 and SubB1 have identical functions. As have  SubA2 and SubB2.
>> Multiple inheritance would be a solution here; but neither Objective-C nor 
>> Swift can do this (and I don’t like C++).
> 
> There’s not necessarily a straightforward conversion from subclassing to 
> protocol composition. It usually takes some fundamental re-thinking of your 
> approach to to the problem.

Following a suggestion from Greg Parker I solved my multiple inheritance 
problem with protocol extensions:

protocol Number
{
func aFunction() -> Int
}

extension Number
{
func aFunction() -> Int
{
print("Error: \(self.dynamicType) must override \(#function)")
return 0
}
}

protocol Number1: Number {}

extension Number1
{
func aFunction() -> Int
{
print("\(self.dynamicType) \(#function) returns 1")
return 1
}
}

[… Omitted similar code with “1” replaced by “2” …]

class NewSuper: Number {}
class NewSubA: NewSuper {}
class NewSubB: NewSuper {}
class NewSubA1: NewSubA, Number1 {}
class NewSubA2: NewSubA, Number2 {}
class NewSubB1: NewSubB, Number1 {}
class NewSubB2: NewSubB, Number2 {}

No more code repetition here. Very satisfying so far. Thanks to Greg Parker!

But now NewSuper has a class function like:
class func classFunction( number: UInt64 ) -> UInt64
{
print(“Error:  must override \(#function)")
return 0
} 
which is overridden in NewSubA1,2  NewSubB1,2 in the same style as aFunction.
So it should be part of my Number… protocols and extensions.
But I cannot get this to work.

NewSuper uses this classFunction like:
func otherFunction( arg: UInt64) -> UInt64
{
return self.dynamicType.classFunction(  arg ) + 21
}

Kind regards,

Gerriet.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-06 Thread Quincey Morris
On Sep 6, 2016, at 17:17 , Gerriet M. Denkmann  wrote:
> 
> But what to do about localConstantDependingOnSuper?

Now you’re moving the goal posts. :) I said:

> assuming the places of definition aren’t more complicated than in your code

and you’re making it more complicated. Anyway, this particular example is 
fairly easily solved by declaring “localConstantDependingOnSuper” as 
‘private(set)’.

> I do not think this would work for me. There are several subclasses and the 
> superclass contains lots of functions (some of which are overwritten by 
> subclasses).
> If the superclass becomes a protocol then all this code had to be duplicated 
> in each subclass.
> 
> 
> Another problem:
> Super → SubA and SubB.
> SubA → SubA1 and SubA2
> SubB → SubB1 and SubB2
> 
> Both SubA1 and SubB1 have identical functions. As have  SubA2 and SubB2.
> Multiple inheritance would be a solution here; but neither Objective-C nor 
> Swift can do this (and I don’t like C++).

There’s not necessarily a straightforward conversion from subclassing to 
protocol composition. It usually takes some fundamental re-thinking of your 
approach to to the problem.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-06 Thread Greg Parker

> On Sep 6, 2016, at 5:17 PM, Gerriet M. Denkmann  wrote:
> 
>> On 5 Sep 2016, at 13:29, Quincey Morris 
>>  wrote:
>> 
>> More globally, this sort of thing is not terribly idiomatic for Swift, 
>> because you’re trying to hide things that could get exposed other ways, for 
>> example, by “hostile” subclassing. The Swift-ier way would be to use a 
>> protocol instead of (or in addition to, but preferably instead of) the 
>> superclass. The protocol would “force” the subclass to define its own 
>> “onlyKnownBySubclass” locally.
> 
> I do not think this would work for me. There are several subclasses and the 
> superclass contains lots of functions (some of which are overwritten by 
> subclasses).
> If the superclass becomes a protocol then all this code had to be duplicated 
> in each subclass.

Swift protocol extensions can solve some of those problems. The protocol 
extension provides a default implementation to every class that conforms to the 
protocol. Each class may provide its own implementation that overrides the 
protocol extension's default implementation.


-- 
Greg Parker gpar...@apple.com  Runtime 
Wrangler


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-06 Thread Gerriet M. Denkmann

> On 5 Sep 2016, at 13:29, Quincey Morris  
> wrote:
> 
> On Sep 4, 2016, at 22:50 , Gerriet M. Denkmann  wrote:
> 
> If you can’t do that, you can do it with a closure, assuming the places of 
> definition aren’t more complicated than in your code. Something like this:
> 
>> class SuperClass
>> {
>>  let knownBySuperclass: Int
>>  let onlyKnownBySubclass: Int
>>  
>>  init(some: Int, calc: (known: Int) -> Int)
>>  {
>>  knownBySuperclass = some * 2
>>  onlyKnownBySubclass = calc (known: knownBySuperclass)
>>  }
>>  
>>  final func someFunction() -> Void
>>  {
>>  print("Should never be zero: \(onlyKnownBySubclass)")
>>  }
>> }
>> 
>> final class SubClass: SuperClass
>> {
var localConstantDependingOnSuper: Int  //  should really 
be a constant
>>  init(some: Int)
>>  {
localConstantDependingOnSuper = 0   //  all 
must be set before calling super
>>  super.init(some: some) { $0 + 5 }

localConstantDependingOnSuper = knownBySuperclass + 27
> 
>>  }
>> }
>> 
>> let a = SubClass(some:11)
>> a.someFunction() //  prints: “Should never be zero: 27”

This trick with the closure is rather neat. I would never have come up with it. 
Thanks for telling me!
But what to do about localConstantDependingOnSuper?


> More globally, this sort of thing is not terribly idiomatic for Swift, 
> because you’re trying to hide things that could get exposed other ways, for 
> example, by “hostile” subclassing. The Swift-ier way would be to use a 
> protocol instead of (or in addition to, but preferably instead of) the 
> superclass. The protocol would “force” the subclass to define its own 
> “onlyKnownBySubclass” locally.

I do not think this would work for me. There are several subclasses and the 
superclass contains lots of functions (some of which are overwritten by 
subclasses).
If the superclass becomes a protocol then all this code had to be duplicated in 
each subclass.


Another problem:
Super → SubA and SubB.
SubA → SubA1 and SubA2
SubB → SubB1 and SubB2

Both SubA1 and SubB1 have identical functions. As have  SubA2 and SubB2.
Multiple inheritance would be a solution here; but neither Objective-C nor 
Swift can do this (and I don’t like C++).

Current solution: cut and paste and trying to keep both versions in sync.
Anything better?

Kind regards,

Gerriet.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Init in Swift

2016-09-05 Thread Quincey Morris
On Sep 4, 2016, at 22:50 , Gerriet M. Denkmann  wrote:
> 
> I really want “onlyKnownBySubclass” to be a constant (i.e. let instead of var)

There’s an easy way if you can declare both classes in the same file. Then, you 
can just declare the instance variable like this:

>   private(set) var onlyKnownBySubclass: Int


(That’s Swift 2. For Swift 3, use “fileprivate” instead of “private”.) In this 
case, “onlyKnownBySubclass” looks like a “let” property outside that one source 
file.

If you can’t do that, you can do it with a closure, assuming the places of 
definition aren’t more complicated than in your code. Something like this:

> class SuperClass
> {
>   let knownBySuperclass: Int
>   let onlyKnownBySubclass: Int
>   
>   init(some: Int, calc: (known: Int) -> Int)
>   {
>   knownBySuperclass = some * 2
>   onlyKnownBySubclass = calc (known: knownBySuperclass)
>   }
>   
>   final func someFunction() -> Void
>   {
>   print("Should never be zero: \(onlyKnownBySubclass)")
>   }
> }
> 
> final class SubClass: SuperClass
> {
>   init(some: Int)
>   {
>   super.init(some: some) { $0 + 5 }
>   }
> }
> 
> let a = SubClass(some:11)
> a.someFunction()  //  prints: “Should never be zero: 27”

This closure “{ $0 + 5 }” is shorthand for the longer form:

{ 
valuePassed in 
return valuePassed + 5 
}

The idea is that the superclass contributes values by parameters to the closure 
(just one, knownBySuperclass, in this case), and the subclass contributes the 
rest of the expression (which could make use of other subclass properties, 
since this closure occurs after the property initialization phase of the 
subclass init.

More globally, this sort of thing is not terribly idiomatic for Swift, because 
you’re trying to hide things that could get exposed other ways, for example, by 
“hostile” subclassing. The Swift-ier way would be to use a protocol instead of 
(or in addition to, but preferably instead of) the superclass. The protocol 
would “force” the subclass to define its own “onlyKnownBySubclass” locally.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Init in Swift

2016-09-04 Thread Gerriet M. Denkmann
I have a SuperClass with several Subclasses.
The SuperClass will never be instantiated. It just contains code common to all 
subclasses.

Here an example:
I really want “onlyKnownBySubclass” to be a constant (i.e. let instead of var). 
But cannot figure out  how to do this.

class SuperClass
{
let knownBySuperclass: Int
var onlyKnownBySubclass: Int//  this is a constant, only set in 
SubClass.init

init(some: Int)
{
knownBySuperclass = some * 2
onlyKnownBySubclass = 0 //  this value will never be used
}

final func someFunction() -> Void
{
print("Should never be zero: \(onlyKnownBySubclass)")
}
}

final class SubClass: SuperClass
{
override init(some: Int)
{
super.init(some: some)

//  depends on knownBySuperclass:
onlyKnownBySubclass = knownBySuperclass + 5 //  
constant - will never change after this
}
}

let a = SubClass(some:11)
a.someFunction()//  prints: “Should never be zero: 27”

Gerriet.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com