How to Write Generic Function in Swift? - swift

I'm trying to write a general argmin function in Swift. Here is my code:
func argmin<X, Y:Comparable, R:SequenceType, where X== R.Generator.Element>
(f:(X)->Y, domain:R)->X{
var gen = domain.generate()
var best = gen.next()!
var minval = f(best)
while let this = gen.next() {
let value = f(this)
if value < minval {
best = this
minval = value
}
}
return best
}
I get the error message "Expected identifier to name generic parameter" when I try to compile this definition. I have no idea what this means. It sounds like an error one would get on calling the function, not defining it, but even then, I wouldn't understand it.
I'm just starting to learn Swift. Can you explain this message? (BTW, I know this function will blow up if called with an empty sequence. I'm not worrying about that yet.)

You have to remove this comma:
func argmin<X, Y:Comparable, R:SequenceType, where X== R.Generator.Element>
^
Placed that, it tells the compiler there's another generic parameter. The error message just says that - maybe in a cryptic way, but once you know, it's clearer what it means

Related

swift 5.1 evaluate a closure in the wrong way

I'm having an issue with evaluation of one line of code
if i break it down to two lines, it's working , but in one line of code, it's just evaluate in a 'new' to a 'wrong' way.
my main reason for asking this question, is not to solve it, I know I can use parenthesis to solve it, and break it to Two line, but don't want to solve it, I just want to know why its evaluated like this , and if there's a solution for this : some setting to patch , in Order THAT it will work in ONE LINE OF CODE :
Heres the code that working in Two lines
Heres the code that trying to do the same thing, but rise an error as you can see:
full code of both working and not working :
class ClosuresStack {
var dic = Dictionary<String,(()->String)->String >()
subscript(_ str:String)-> (()->String)->String {
get {
return dic[str]!
}
set {
dic[str] = newValue
}
}
}
func createClosuresStak() -> ClosuresStack {
let cs = ClosuresStack()
func takesAClosureReturnA_string(_ closure:()->String) ->String {
return closure() + " Two"
}
cs["C"] = takesAClosureReturnA_string
return cs
}
let c = createClosuresStak()["C"]
let str = c{"One"}
print(str) // print: One Two
let c = createClosuresStak()["C"]{"One"} // error -->
now, I want to somehow understand how to change it that it will work in ONE LINE OF CODE : meaning that the evaluation of 'createClosuresStak()["C"]{"One"}' will create a closure after ["C"] , and then from that point writing the {"One"}
will make it a full evaluate of the line :
let c = createClosuresStak()["C"]{"One"}
making 'c' a String
if that's not possible, I need to know it Too , tnx :)
UPDATE
tnx for the comments , its help me understand the problem more clearly :
1) im understanding that the createClosuresStak()["C"]{"One"}
acutely trying to add the string 'One' as another parameter to the sub script , and there for the error from the compiler was that is cannot subscript (String,()->String} , 'C' as the string inside the [] , and the other parameter {"One"} -> BUT , isn't that some kind of a bug?, been that i'm using [] ,Cleary the compiler need to 'understand' that I want to subscript a String, also by power of inferring that swift has,
2) now I'm still trying to get that syntax to work as it is so I try to change some things, in order to get it to work :
so I created a function that take a string, and return a dictionary of type : Dictionary<String,()->String>, and then trying so subscript it
and the compiler don't rise an error that way :
func closuresDictionary(_ s:String) -> Dictionary<String,()->String> {
var dic = Dictionary<String,()->String>()
func foo()->String {
return s + " Two"
}
dic["C"] = foo
return dic
}
let c = closuresDictionary("One")["C"]{ "SomeString" }
c is now a closure of type ()->String which does noting with string that I put inside, so the syntax works, but the outcome is not doing anything.
when im changing the return type of the dictionary to a different closure : (String)->String instead of ()->String , im getting the same old error, that I'm trying to subscript a (String,(String)->String)
and I need a function that will take the string inside the {} , and create something from it meaning that I need to subscript to return a closure of (String)->String
its seems like there's no way to do that
im adding two more pictures of my last trying in order to get this line of code in current syntax to work
the wanted syntax working but the outcome is not an outcome not doing any thing with the string inside the {}:
same error, by changing the function to (String)->String
Your example:
let c = createClosuresStak()["C"]{"One"}
is using trailing closure syntax.
Trailing closure syntax works by including the trailing closure as an additional parameter to a function call. Subscripting an array is really a function call under the hood (to a function called subscript), and Swift is trying to pass that closure as a second parameter to the subscripting call, which is what the error is explaining:
Cannot subscript a value of type 'ClosuresStack' with an argument of type '(String, () -> String)'.
In other words, you can't pass both "C" and the closure {"One"} to the subscripting function.
There are at least 3 ways to fix this and still put it on one line:
Option 1: Use an explicit call to pass the closure instead of using trailing closure syntax
Wrap the closure in () to make the call explicit:
let c1 = createClosuresStak()["C"]({"One"})
print(c1)
Option 2: Wrap the createClosureStak()["C"] in parentheses
That lets Swift know the subscripting only gets "C" as a parameter and allows trailing closure syntax to work as expected:
let c2 = (createClosuresStak()["C"]){"One"}
print(c2)
Option 3: Add .self to the result before the trailing closure syntax:
That again finishes the subscripting call and avoids the confusion.
let c3 = createClosuresStak()["C"].self {"One"}
print(c3)
Personally, I would choose option one, because trailing closure syntax is unnecessary syntactic sugar that clearly is not working here.

Possible in swift to do a recursive function call with javascriptcore?

I have a function that is called by javascript with JavascriptCore.
Now inside that function I have to evaluate a javascript again under a certain condition. This should call the same function.
let My_JS_Function: #convention(block) ( String, String, String ) -> ( ) = {
thing_1, thing_2, thing_3
in
let my_Condition = true
if my_Condition {
let c = JSContext()
// compiling error: "Variable used within its own initial value"
Context.setObject(unsafeBitCast(My_JS_Function, AnyObject.self), forKeyedSubscript: "My_JS_Function")
c.evaluateScript("My_JS_Function("value 1","value 2","value 3");")
}
}
Now XCode tells me:
Variable used within its own initial value
Does anybody know wheather there's a way how to solve this problem?
Maybe a way to write the My_JS_Function as a function and not like here as a variable?
I could fix the problem with avoiding having functions as properties.
Therefor I put the functionality in an extra class and used JSExport.
One example for how it can be done with JSExport can be found here.

Lazy load MirrorType

Let's say I have something like this
struct A {
lazy var b: String = { return "Hello" }()
}
If I try to reflect struct A and access the value for b through its MirrorType like so:
var a = A()
var r = reflect(a)
for i in 0..r.count {
let (n, m) = r[i]
println("\(m.value)")
var c = a.b
println("\(m.value)")
}
I get nil in the console both times. Note that the underlying value type is Swift.Optional<Swift.String>, and the variable name is somewhat confusingly b.storage. Is there a way to access the underlying value of a lazy-loaded variable using reflection or initialize it from its MirrorType or am I stuck waiting for someone to write a first-class reflection api for Swift?
The MirorType is very limited in it's functionality. Besides that it's replaced by other functionality in Xcode 7 beta 4.
The point in your case is that the property has not been used yet. So it's actually still nil. The only way to make it not nil is by accessing the property by getting it's value. Unfortunately in Swift you can not do that by executing .valueForKey("propertyName")
If you are looking for a reflection library that is trying to get as much as possible out of Swift, then have a look at EVReflection

Conditional instructions in swift

I am trying to write in swift something that should be very basic, but I can't seem to get a handle on it :
First, I create a global variable. For example:
var xx:Int
Then, I want to create a conditional instruction. Something like :
if (xx == 1){
//do something
}
else if (xx == 2) {
//do something else
}
I can do this very easily in Objective-C, but I can't seem to be able to do it in Swift. I have looked everywhere, and don't seem to find the answer.
With the code you provided you're probably getting the error: "Variable xx used before initialized". This is happening because the declaration of the variable is incomplete, you neither gave a value to the variable nor told the compiler it is an optional. You have three options:
Give a initial value to it; var xx: Int = //value here
Declare it as an optional (doing this you say that it may not have a value, if it does the code will be executed, if it doesn't it won't); var xx: Int?
Force unwrap the variable (it still an optional, but if you force-unwrap it you're assuring the compiler that the variable will have a value when needed, otherwise it'll crash); var xx: Int!
Or you can say var xx = Int() that way it's initialized and the default initialization is equal to 0. This is different than the other answers and allows you to have a value from the get go if you're not sure what value might be assigned during runtime.
In addition to the other poster's point that you must assign an initial value before you can use xx, you also need to lose the parentheses around the condition in your if statement:
var xx:Int
xx = 2
if xx == 1
{
//do something
}
else if xx == 2
{
//do something else
}

Recasting 'UnsafePointer<Void>' to 'CFHTTPMessageRef'

I've tried dozens of things to get this right and just can't come up with anything that works. Can anyone tell me what's wrong with the following Swift code:
let incomingRequest: CFHTTPMessageRef? = CFDictionaryGetValue(self.incomingRequests as CFMutableDictionaryRef, unsafeAddressOf(incomingFileHandle!)) as CFHTTPMessageRef
The code above gives the error message: 'UnsafePointer<Void>' is not convertible to 'CFHTTPMessageRef'
I guess what I don't understand is how do I convert an 'UnsafePointer' returned by a Core Foundation function to the pointer type it should be (i.e. CFHTTPMessageRef in this case). How do I find documentation on how to do this. I've read everything I can find, but nothing so far explains how to recast return values to what they should have been in the first place. This has to be documented somewhere, doesn't it?
EDIT
Here's the code I'm having trouble with:
let incomingRequest = CFDictionaryGetValue(self.incomingRequests as CFMutableDictionaryRef, unsafeAddressOf(incomingFileHandle!))
unsafeBitCast(incomingRequest, CFHTTPMessageRef.self)
if (incomingRequest != nil) {
let success: Boolean = CFHTTPMessageAppendBytes(incomingRequest as CFHTTPMessageRef, unsafeAddressOf(data!.bytes) as UnsafePointer<UInt8>, data!.length)
if success { // Do something... }
The CFHTTPMessageAppendBytes call still gives a "Type 'UnsafePointer' does not conform to protocol 'AnyObject'". And the following 'if' check for 'success' complains that "Type 'Boolean' doesn not conform to protocol 'BooleanType'". What the heck is that about? Boolean isn't a Boolean type?
I find the strict type checking of Swift extremely frustrating. So far it is far more difficult to code in than Obj-C, C, or any of the other languages I've used. I'm sure it's because I just don't get it, or haven't found the right documentation, but this is really driving me crazy.
Use unsafeBitCast. As following example:
import Foundation
var x = "1"
var dict : NSMutableDictionary = [x: "2"]
var y = CFDictionaryGetValue(dict as CFMutableDictionaryRef, unsafeAddressOf(x))
let str: NSString = unsafeBitCast(y, NSString.self)
str == "2"
FYI: There is one quora related with unsafeBitCast. http://www.quora.com/Why-does-Swift-not-allow-implicit-type-conversion