Calculate a hashValue from a func in Swift - swift

I want to send a store a method address in a class, allowing the class to call that method. I want this class to be Hashable, and I want the hashValue to be calculated from the method such that 2 objects pointing to the same method have the same hashValue.
Here is the class init that attempts to calculate the hashValue, but it fails. I think it hashes a pointer to the local variable.
typealias functionAlias = ((Double) -> ())?
class FunctionPointer: Hashable {
private let functionPointer: functionAlias
private let hash: Int
init( functionPointer: functionAlias ) {
self.functionPointer = functionPointer
var f = functionPointer
var h = 0
withUnsafePointer(to: &f, {
ptr in
h = ptr.hashValue
})
self.hash = h
print("self.hash = \(self.hash)")
}
}
Thanks

Related

When declaring static variable for conformance to AdditiveArithmetic, cannot call instance member from same type

I know this sounds crazy for a 10-year-old, but because S4TF doesn't work for me, I'm building my own neural network library in Swift. (I haven't gotten that far.) I'm creating a structure that conforms to AdditiveArithmetic. It also uses Philip Turner's Differentiable, but that's unimportant.
Anyway, when defining the zero variable, I call another variable dimen, defined in the same structure. This raises an error: instance member 'dimen' cannot be used on type 'Electron<T>'
note: the structure I am creating is going to be used to create a multi-dimensional array for neural networks.
Total code (stripped down to remove unimportant bits):
public struct Electron<T> where T: ExpressibleByFloatLiteral, T: AdditiveArithmetic {
var energy: [[Int]: T] = [:]
var dimen: [Int]
public init(_ dim: [Int], with: ElectronInitializer) {
self.dimen = dim
self.energy = [:]
var curlay = [Int](repeating: 0, count: dimen.count)
curlay[curlay.count-1] = -1
while true {
var max: Int = -1
for x in 0..<curlay.count {
if curlay[curlay.count-1-x] == dimen[curlay.count-1-x]-1 {
max = curlay.count-1-x
}
else {break}
}
if max == 0 {break}
else if max != -1 {
for n in max..<curlay.count {
curlay[n] = -1
}
curlay[max-1] += 1
}
curlay[curlay.count-1] += 1
print(curlay)
energy[curlay] = { () -> T in
switch with {
case ElectronInitializer.repeating(let value):
return value as! T
case ElectronInitializer.random(let minimum, let maximum):
return Double.random(in: minimum..<maximum) as! T
}
}()
}
}
subscript(_ coordinate: Int...) -> T {
var convertList: [Int] = []
for conversion in coordinate {
convertList.append(conversion)
}
return self.energy[convertList]!
}
public mutating func setQuantum(_ replace: T, at: [Int]) {
self.energy[at]! = replace
}
}
extension Electron: AdditiveArithmetic {
public static func - (lhs: Electron<T>, rhs: Electron<T>) -> Electron<T> where T: AdditiveArithmetic, T: ExpressibleByFloatLiteral {
var output: Electron<T> = lhs
for value in lhs.energy {
output.energy[value.key] = output.energy[value.key]!-rhs.energy[value.key]!
}
return output
}
public static var zero: Electron<T> {
return Electron.init(dimen, with: ElectronInitializer.repeating(0.0))
}
static prefix func + (x: Electron) -> Electron {
return x
}
public static func + (lhs: Electron<T>, rhs: Electron<T>) -> Electron<T> where T: AdditiveArithmetic, T: ExpressibleByFloatLiteral {
var output: Electron<T> = lhs
for value in lhs.energy {
output.energy[value.key] = output.energy[value.key]!+rhs.energy[value.key]!
}
return output
}
}
public enum ElectronInitializer {
case random(Double, Double)
case repeating(Double)
}
Error:
NeuralNetwork.xcodeproj:59:30: error: instance member 'dimen' cannot be used on type 'Electron'
return Electron.init(dimen, with: ElectronInitializer.repeating(0.0))
I don't know what's happening, but thanks in advance. I'm new to Stack Overflow, so sorry if I did something wrong.
The root of the problem is that dimen is an instance property, while zero is a static property. In a static context, you don't have an instance from which to access dimen, and so the compiler gives you the error. static properties and methods are a lot like global variables and free-functions with respect to accessing instance properties and methods. You'd have to make an instance available somehow. For a static function, you could pass it in, but for a static computed property, you'd either have to store an instance in a stored static property, which isn't allowed for generics, or you'd have to store it in a global variable, which isn't good either, and would be tricky to make work for all the possible T.
There are ways to do what you need though. They all involve implementing some special behavior for a zero Electron rather than relying on access to an instance property in your static .zero implementation. I made some off-the-cuff suggestions in comments, which would work; however, I think a more elegant solution is to solve the problem by creating a custom type for energy, which would require very few changes to your existing code. Specifically you could make an Energy type nested in your Electron type:
internal struct Energy: Equatable, Sequence {
public typealias Value = T
public typealias Key = [Int]
public typealias Element = (key: Key, value: Value)
public typealias Storage = [Key: Value]
public typealias Iterator = Storage.Iterator
public typealias Keys = Storage.Keys
public typealias Values = Storage.Values
private var storage = Storage()
public var keys: Keys { storage.keys }
public var values: Values { storage.values }
public var count: Int { storage.count }
public init() { }
public subscript (key: Key) -> Value? {
get { storage.isEmpty ? .zero : storage[key] }
set { storage[key] = newValue }
}
public func makeIterator() -> Iterator {
storage.makeIterator()
}
}
The idea here is that when energy.storage is empty, it returns 0 for any key, which allows you to use it as a .zero value. I've made it internal, because energy defaults to internal, and so I've done a minimalist job of wrapping a Dictionary, mainly providing subscript operator, and making it conform to Sequence, which is all that is needed by code you provided.
The only changes needed in the rest of your code are to change the definition of energy
var energy: Energy
Then to set it in your initializer, by-passing the bulk of your init when dim is empty.
public init(_ dim: [Int], with: ElectronInitializer) {
self.dimen = dim
self.energy = Energy() // <- Initialize `energy`
// Empty dim indicates a zero electron which doesn't need the
// rest of the initialization
guard dim.count > 0 else { return }
var curlay = [Int](repeating: 0, count: dimen.count)
curlay[curlay.count-1] = -1
while true {
var max: Int = -1
for x in 0..<curlay.count {
if curlay[curlay.count-1-x] == dimen[curlay.count-1-x]-1 {
max = curlay.count-1-x
}
else {break}
}
if max == 0 {break}
else if max != -1 {
for n in max..<curlay.count {
curlay[n] = -1
}
curlay[max-1] += 1
}
curlay[curlay.count-1] += 1
print(curlay)
energy[curlay] = { () -> T in
switch with {
case ElectronInitializer.repeating(let value):
return value as! T
case ElectronInitializer.random(let minimum, let maximum):
return Double.random(in: minimum..<maximum) as! T
}
}()
}
}
And then of course, to change how you create it in your zero property
public static var zero: Electron<T> {
return Electron.init([], with: ElectronInitializer.repeating(0.0))
}
ElectronInitializer isn't actually used in this case. It's just a required parameter of your existing init. This suggests an opportunity to refactor initialization, so you could have an init() that creates a zero Electron in addition to your existing init(dim:with:)

How to prevent duplicate code when initializing variables?

A class has some variables to be initialized in init() and at the same time, the class provides a function to restore these variables to their initial values in restoreInitValues(). Is there any way I can achieve this without setting these values twice (duplicate code) inside both init() and restoreInitValues()?
class Foo {
var varA: Int
var varB: Int
var varC: Int
init() {
//restoreInitValues() // error: call method before all stored proproties are initalized
//or I have to have duplicate code here as restoreInitValues below
varA = 10
varB = 20
varC = 30
}
func restoreInitValues() {
varA = 10
varB = 20
varC = 30
}
}
Personally I would assign the 3 default values to 3 class scope constants, then use those values to init and restore. You could also eliminate the assigning statements in the init if you want, and assign the value when you declare the var. In addition, by having your defaults defined in a class constant if you need to add any other functions to the class they'll be available for use.
class Foo {
let defaultA = 10
let defaultB = 20
let defaultC = 20
var varA: Int
var varB: Int
var varC: Int
init() {
varA = defaultA
varB = defaultB
varC = defaultC
}
func restoreInitValues() {
varA = defaultA
varB = defaultB
varC = defaultC
}
}
You could also define a struct, use it to assign your values, and then use your reset function to init.
struct values{
static let defaultA = 10
static let defaultB = 20
static let defaultC = 30
}
class test {
var a: Int = 0
var b: Int = 0
var c: Int = 0
init(){
resetValues()
}
func resetValues(){
(a, b, c) = (values.defaultA, values.defaultB, values.defaultC)
}
}
Use implicitly unwrapped optionals.
class Foo {
var varA: Int!
var varB: Int!
var varC: Int!
init() {
restoreInitValues()
}
func restoreInitValues() {
varA = 10
varB = 20
varC = 30
}
}
Update: Code's answer below about Implicitly Unwrapped Optionals is the answer. I'm not sure why I couldn't find it in the docs before. I'm leaving my answer for posterity, but you should accept Code's answer.
being new to swift, I gave it a try and found these two solutions, but I'm not sure if they're the best solutions.
The problem seems to be that swift tries hard to ensure that no class instance will ever have uninitialized properties (unless they're marked as optional) after initialization has been performed. It won't let you call non-static methods because you might use the instance before all properties are set. Also, it doesn't trust you to call another method which initializes all of the properties for you presumably because that would be really hard to verify.
For classes, use a private static method to return default values:
class Foo {
//...
init() {
(varA, varB, varC) = Foo.defaultValues()
}
func restoreInitValues() {
(varA, varB, varC) = Foo.defaultValues()
}
static private func defaultValues() -> ( Int, Int, Int ) {
return (10, 20, 30)
}
}
If you don't need a class, structs are copyable by value:
struct Foo {
//...
mutating func restoreInitValues() {
self = Foo()
}
}
or you could give up on restoreInitValues() and just do this:
var f = Foo()
f.varA = 10000
// instead of resetting the internal state of `f`, just replace it with
// a new `Foo` instance
f = Foo()
or you could use a static private method that modifies Foo instances, but to get around the compiler you have to make your properties be optional. This solution has a definite Ick factor:
class Foo {
var varA: Int?
var varB: Int?
var varC: Int?
init() {
Foo.resetValues(in: self)
}
func restoreInitValues() {
Foo.resetValues(in: self)
}
static private func resetValues(in foo: Foo) {
foo.varA = 10
foo.varB = 20
foo.varC = 30
}
}
This leads us back to the heart of the problem: swift requires that all properties be optional or initialized. Another solution would be to simply give all of the properties values (meaningless or not). The downside is that the property definitions may be misleading to someone reading the code for the first time.
class Foo {
var varA = -1
var varB = -1
var varC = -1
init() {
restoreInitValues()
}
func restoreInitValues() {
varA = 10
varB = 20
varC = 30
}
}
Last, check out the answers to this similar question: How to implement two inits with same content without code duplication

Cannot create class object or array of class objects

I'm working on a project thatand am simply trying to create a object instance of a simple custom class:
import Foundation
class Set {
private var gam1: Int!
private var gam2: Int!
init (gam1: Int, gam2: Int) {
self.gam1 = gam1
self.gam2 = gam2
}
//returns set info as array
func getStats () -> [Int] {
let arr = [gam1!, gam2!]
return arr
}
}
The class simply stores a few variables for use later and I want an array of such objects to store several values. However, when I try to create a n instance of the class in a different class I get errors:
import Foundation
class AnotherClass {
var mySet = Set(gam1: 6, gam2: 5) //error 1
//array of set objects
var setArray = [Set]() // error 2
//returns array of set objects
func getSets () -> [Set] { //error 3
return setArray
}
}
The errors state:
Cannot find an initializer for type 'Set' that accepts an argument list of type '(gam1: Int, gam2: Int)'
Cannot invoke initializer for type '[Set]' with no arguments
and
Reference to generic type 'Set' requires arguments in <...>
Any ideas of what the issue is here? could the 'Set' name of the class be conflicting with a reserved keyword?
Many thanks,
Kw
The issue that you are having is due to the naming conflict between Set in the Swift standard library and the one you defined.
This is never a good idea. Instead, give it a more descriptive name (and one that doesn't conflict with anything else). For instance, call it gamHolder and initialize it gamHolder(gam1: <an int>, gam2: <another int>).
Also, if you have defined variables inside the init function they do not need to be forced unwrapped optionals.
For example:
class myClass {
var myInt: Int
init(anInt: Int) {
myInt = anInt
}
}
You defined 2 parameters in your init method (since gam1 and gam2 are not optional). So, you have 2 solutions:
1 - You add parameters into your init call (like this):
var mySet = Set(gam1: 1, gam2: 2)
2 - You change gam1 and gam2 to optionals and you add a zero parameters init:
class Set {
private var gam1: Int?
private var gam2: Int?
init() {
}
init(gam1: Int, gam2: Int) {
self.gam1 = gam1
self.gam2 = gam2
}
// returns set info as array
func getStats() -> [Int] {
let arr = [gam1!, gam2!]
return arr
}
}
So, you will be able to call it like this: var mySet = Set()
Also: be careful: Set is a class used in the Swift standard library. It's never a good idea to use same class names than Swift Standard Library. A name like TenisSet would be better.
Edit:
Here is a final working example with a renamed class:
class TenisSet {
private var gam1: Int?
private var gam2: Int?
init() {
}
init(gam1: Int, gam2: Int) {
self.gam1 = gam1
self.gam2 = gam2
}
// returns set info as array
func getStats() -> [Int] {
let arr = [gam1!, gam2!]
return arr
}
}
class AnotherClass {
var mySet = TenisSet()
// array of set objects
var setArray = [TenisSet]()
// returns array of set objects
func getSets() -> [TenisSet] {
return setArray
}
}

swift set intersect, union, subtract

Does anyone know how to implement set operations with user defined classes, with its property as operated conditions. For instance:
class myClass {
var figure: Int!
}
let classObj1 = myClass()
classObj1.figure = 1
let classObj2 = myClass()
classObj2.figure = 2
let classObj3 = myClass()
classObj3.figure = 1
let set1: Set = [classObj1]
let set2: Set = [classObj2, classObj3]
Is there any method like: (pseudo code)
set2.substract(set1) {s2, s1 in s2.figure == s1.figure}
...so the expected result is [classObj2]?
Many thanks for any suggestion!
Certainly. Make your MyClass conform to Hashable and Equatable in such a way that == compares the figure values. Example:
class MyClass : Hashable {
var figure: Int
init(f:Int) {figure = f}
var hashValue : Int {return figure}
}
func ==(lhs:MyClass, rhs:MyClass) -> Bool {
return lhs.figure == rhs.figure
}

Maintain value semantics in Swift struct, which contains object reference

I have a Swift struct which contains an object for internal storage. How can I make sure the struct has value semantics?
public struct Times {
private let times = NSMutableIndexSet()
mutating func addTimeRange(openTime: Int, closeTime: Int) {
self.times.addIndexesInRange(NSRange(location: openTime, length: closeTime - openTime))
}
}
Swift 3 Update
Swift 3 includes value types for many types from the Foundation framework. There is now an IndexSet struct, which bridges to NSIndexSet. The internal implementation is similar to the Swift 2 solution below.
For more information on the new Foundation value types see: https://github.com/apple/swift-evolution/blob/master/proposals/0069-swift-mutability-for-foundation.md
Old approach in Swift 2
The copy-on-write approach is the right solution. However, it is not necessary to create a copy of the NSMutableIndexSet, if only one struct instance references it. Swift provides a global function called isUniquelyReferencedNonObjC() to determine if a pure Swift object is only referenced once.
Since we cannot use this function with Objective-C classes, we need to wrap NSMutableIndexSet in a Swift class.
public struct Times {
private final class MutableIndexSetWrapper {
private let mutableIndexSet: NSMutableIndexSet
init(indexSet: NSMutableIndexSet) {
self.mutableIndexSet = indexSet
}
init() {
self.mutableIndexSet = NSMutableIndexSet()
}
}
private let times = MutableIndexSetWrapper()
mutating func addTimeRange(openTime: Int, closeTime: Int) {
// Make sure our index set is only referenced by this struct instance
if !isUniquelyReferencedNonObjC(&self.times) {
self.times = MutableIndexSetWrapper(indexSet: NSMutableIndexSet(indexSet: self.times.mutableIndexSet))
}
let range = NSRange(location: openTime, length: closeTime - openTime)
self.times.mutableIndexSet.addIndexesInRange(range)
}
}
Store an NSIndexSet instead of an NSMutableIndexSet. That is exactly why the immutable superclass exists.
public struct Times {
private var times = NSIndexSet()
mutating func addTimeRange(openTime: Int, closeTime: Int) {
let t = NSMutableIndexSet(indexSet:self.times)
t.addIndexesInRange(NSRange(location: openTime, length: closeTime - openTime))
self.times = NSIndexSet(indexSet:t)
}
}
If this were a class instead of a struct, you could cause the last step to be performed automatically by declaring times as #NSCopying and then just using simple assignment:
public class Times {
#NSCopying private var times = NSIndexSet()
func addTimeRange(openTime: Int, closeTime: Int) {
let t = NSMutableIndexSet(indexSet:self.times)
t.addIndexesInRange(NSRange(location: openTime, length: closeTime - openTime))
self.times = t // ensure immutable copy
}
}
It might be an option to use Swift's native Set type which has value-semantics built in since it is a struct itself.
public struct Times {
private var times = Set<Int>()
mutating func addTimeRange(openTime: Int, closeTime: Int) {
(openTime ..< closeTime).map({ index -> Void in self.times.insert(index) })
}
}
let t1 = Times()
var t2 = t1
t2.addTimeRange(0, closeTime: 3)
println(t1.times) // []
println(t2.times) // [2, 0, 1]