I have come across the array forEach function that is a higher order function and it takes only one parameter, i.e., a closure. Now this closure internally loops through all the elements of the array one by one but does not return anything. The implementation of the closure is left to the choice of the user.
I have a custom class MyClass that has a private variable inside it num and a public function setNum(num: Int) to set the value of that private variable from outside. I am just trying to create a similar function factorial inside my custom class that takes only one parameter, i.e., a closure. However, I have to manually call the closure inside factorial, pass the value of num as a parameter to the closure.
Is there a way that the closure can act on num without having passed it as a parameter? Basically I am just trying to replicate the array forEach function. Syntax of array forEach is:
array.forEach(body: (Int) -> Void) -> Void)
Implementation:
arr1.forEach { print($0) }
My code is as below:
import Foundation
public class MyClass {
private var factorialNumber: Double = 0
internal static var instance: MyClass?
public func setFactorialNumber(number value: Double) {
factorialNumber = value
}
public func factorial(body closure: (String?) -> Void) -> Void {
var outputString: String?
var result: Double = 1
if factorialNumber <= 0 {
outputString = nil
} else {
outputString = ""
while(factorialNumber >= 1) {
if factorialNumber == 1 {
outputString = outputString! + "\(factorialNumber) = \(result)"
break
} else {
outputString = outputString! + "\(factorialNumber) x "
}
result = result * factorialNumber
factorialNumber -= 1
}
}
// Finally closure call
closure(outputString)
}
private init() {}
public static func getInstance() -> MyClass {
if self.instance == nil {
self.instance = MyClass()
}
return self.instance!
}
}
And here is how I have to call my function to calculate the factorial:
var obj1 = MyClass.getInstance()
obj1.setFactorialNumber(number: 5)
obj1.factorial{ (result) in
print(result ?? "Factorial Result is Nil")
}
Please note that I have to pass a parameter result inside my closure to get the result of factorial.
Is there a way that the closure can act on num without having passed it as a parameter? Basically I am just trying to replicate the array forEach function ... [And, in your comment:] All I am trying to do is learn how to create higher order functions like array.forEach.
It's hard to understand what you think you're after, but taking you at your word, let's write forEach. Here we go:
extension Sequence {
func myForEach(f: (Element) -> ()) {
for e in self {
f(e)
}
}
}
Let's test it:
[1,2,3].myForEach { print($0) } // prints 1, then 2, then 3
We've done it! We wrote a higher-order function that acts exactly like forEach. So this must be how forEach actually works, more or less.
You can see from the example that it makes no sense to ask not to have to pass a parameter into the function that our forEach takes as a parameter. That is exactly what we must be able to do in order for that function to have an element to operate on.
Related
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:)
I am experimenting with a basic proxy pattern in Swift playgrounds; I am not 100% familiar with it; but some videos are helping.
In my experiment, the subject, C is called through a proxy to perform said actions
ie:
A - Proxy - C
However, in my experiments I find out I can just call C itself directly, without even needing the proxy; so I am left wondering why bother with a proxy when I can call C directly anyway?
So I decided to make the variables in C private; but now I can't call them, or make modifications, and I am not sure how to resolve it.
I also tried a "decorator" pattern I found on stackoverflow to try to manipulate Cs variables, but still its marked private, so its not possible.
Also, the decorator pattern I found uses static variables. This makes me think well, why not just write a static function that creates c in memory, and then update the reference in proxy to that of the results of the static function.
I guess what I'm mis-understanding here is what is the point of a proxy class if you can just call the subject (in this case C) directly anyway?
Examples use Swift playground:
class A {
let proxy: Proxy = Proxy()
var funds: Int {
return self.proxy.funds
}
}
class Proxy {
private let c: C = C()
public var funds: Int {
return c.funds
}
private func canIGetFunds() -> Bool {
guard (self.funds > 0) else {
return false
}
return true
}
func subtractFunds(funds: Int = 0) {
if (canIGetFunds()) {
print ("you have enough funds")
willDebit(funds: funds)
}
else {
print ("Not enough funds")
}
}
private func willDebit(funds: Int = 0) {
self.c.funds -= funds
}
}
class C {
private (set) var funds: Int = 100
}
let a = A()
print (a.funds)
a.proxy.subtractFunds(funds: 50)
This code will throw up a compiler error on:
self.c.funds -= funds
because:
funds setter is inaccessible
the funds variable is indeed private.
So, I tried a decorator too; code I found from stackoverflow (its not mine):
#propertyWrapper
struct Announced<T, U> {
private var announcedFunction: (T) -> U
var wrappedValue: (T) -> U { announcedFunction }
init(wrappedValue: #escaping (T) -> U) {
announcedFunction = { args in
let rv = wrappedValue(args)
print("In: \(args)")
print("Out: \(rv)")
return rv
}
}
}
extension Wallet {
#Announced static var add: ((Int, Int)) -> Int = { $0.0 + $0.1 }
#Announced static var subtract: ((Int, Int)) -> Int = { $0.0 - $0.1 }
}
Now here the add and subtract are static variables; and the contents of the closure are of course wrong because I make no reference to the actual Wallet variables -- I've only put it like this to help with discussion.
The way I got around it is to try to make the (Int, Int) take in a Wallet class, and then return a modified Wallet object where the add or subtract has been completed
So something like this:
#Announced static var subtract: ((w:Wallet, Int)) -> Wallet = {
let newWallet = Wallet()
newWallet.cash = w.cash
newWallet.cash -= $0.1
return newWallet
}
But if I do this pattern, I don't see why I don't just write a static function and disregard this decorator.
I've even tried making C follow a delegate pattern where the Wallet is a delegate of C and adds, subtracts funds; but this too has an issue in that you can call C directly and because is its own delegate it has no reason to fail or throw up an error, etc.
So anyway, probably I'm just overcomplicating:
Whats the point of having a proxy if you can just call the subject directly and do your manipulation that way?
Is there a way to make the proxy pattern the only way you can call and make actions on the subject?
With thanks?
The easiest way is using public/internal setter
class C {
var funds: Int = 100
}
But if you define C in this same file with Proxy then you can use fileprivate(set) access modifier
class Proxy {
...
}
class C {
fileprivate(set) var funds: Int = 100
}
I am trying to call a method which is in another class and use a variable of that class which is getting updated in the method, after the method call. But I am getting a nil value for the variable as the statement is getting called before the method executes completely.
for example: I have two classes A and B. B has a method update and a variable updated.
class A {
let obj_b = B()
func call() {
obj_b.update()
let updated = obj_b.updated
}
}
class B {
var updated: Int?
func updated() {
updated = 1
}
}
what I am trying is much more complex than the example and the method takes about 5secs to execute completely. Is there any way other than returning the variable that I need.
class A {
let obj_b = B()
func call() {
let updated = obj_b.updatedVariable
print("\(updated!)")
}
}
class B {
var updatedVariable: Int?{
return 1
}
}
While calling A
let obj_b = A()
obj_b.call()
Result Prints 1 , this is what you want the variable. You can use computed variable in such case.
I have written a simple queue class in swift. It's implemented by an Array.
Now I want this performs more like built-in array.So I need to implement the []operator but failed. Somebody help?
public class SimpleQueue<T : Any>
{
private var frontCur = 0
private var reuseCur = -1
private var capacity = 0
private var impl = [T]()
public var count : Int
{
get
{
return impl.count - frontCur
}
}
public func empty() -> Bool
{
return self.count == 0
}
public func size() -> Int
{
return impl.count
}
public func append(o : T)
{
if(frontCur > reuseCur && reuseCur >= 0)
{
impl[reuseCur] = o
reuseCur++
}
else
{
impl.append(o)
}
}
public func pop()
{
frontCur++
}
public func front() -> T
{
return impl[frontCur]
}
public postfix func [](index:Int) -> T //Error!!!!
{
return impl[index + frontCur]
}
}
var x = SimpleQueue<Int>()
for index in 1...10{
x.append(index)
}
print(x.count)
for index in 1...3{
x.pop()
}
print(x.count,x.front(),x[2]) // x[2] Error!!!
apple docs
Subscripts enable you to query instances of a type by writing one or
more values in square brackets after the instance name. Their syntax
is similar to both instance method syntax and computed property
syntax. You write subscript definitions with the subscript keyword,
and specify one or more input parameters and a return type, in the
same way as instance methods.
Subscript is not an operator. Just a method marked with the subscript keyword.
subscript (index:Int) -> T {
return impl[index + frontCur]
}
Read this:
class MyColl {
private var someColl : [String] = []
subscript(index: Int) -> String {
get {
return someColl[index]
}
set(value) {
someColl[index] = value
}
}
}
And read this:
Swift has a well-designed and expansive suite of built-in collection types. Beyond Array, Dictionary, and the brand new Set types, the standard library provides slices, lazy collections, repeated sequences, and more, all with a consistent interface and syntax for operations. A group of built-in collection protocols—SequenceType, CollectionType, and several others—act like the steps on a ladder. With each step up, a collection type gains more functionality within the language and the standard library.
typealias CBType = () -> Void
class A {
let b = B()
func test() {
let token = b.register { CBType in
self.b.waitFor([token]) // ERROR: Variable used within its own initial value
}
b.dispatch()
}
}
class B {
private var _callbacks = [String:CBType]()
func register(callback: CBType) -> String {
let id = "1234"
_callbacks[id] = callback
return id
}
func dispatch() {
for (_, cb) in self._callbacks {
cb()
}
}
func waitFor(tokens: [String]) {
}
}
A().test()
When I modify the test function to use a instance variable, things are working again but that syntax feels a bit heavy.
class A {
let b = B()
var token: String?
func test() {
token = b.register { CBType in
self.b.waitFor([self.token!])
}
b.dispatch()
}
}
Why can't I use a local variable in the closure since it will be way past initialization when the closure is finally called?
The constant token doesn't have a value at the time it is captured by the closure.
You can use a mutable variable instead, and the closure will capture the variable rather the its value.
func test() {
var token = ""
token = b.register {
self.b.waitFor([token])
}
b.dispatch()
}
Alternatively, you can pass the token as a parameter into the closure:
typealias CBType = (String) -> Void
class A {
let b = B()
func test() {
let token = b.register { theToken in
self.b.waitFor([theToken])
}
b.dispatch()
}
}
class B {
private var _callbacks = [String:CBType]()
func register(callback: CBType) -> String {
let id = "1234"
_callbacks[id] = callback
return id
}
func dispatch() {
for (id, cb) in self._callbacks {
cb(id)
}
}
func waitFor(tokens: [String]) {
println("Wait for \(tokens)")
}
}
A().test()
In your first example, token doesn't have a value when you make the call self.b.waitFor([token]).
In your second example, everything appears to work because by declaring token like so: var token: String? it is given an initial value (nil).
The issue isn't whether you are using an instance variable -vs- a local variable (or that it's being used within a closure), the issue is that (in the first example) you are trying to use the token within the expression that provides its initial value.
Equivalent to this would be declaring an Int like so: let myValue: Int = myValue + 1 - its initial value is supposed to be "what" + 1?