Micah
Micah

Reputation: 4550

Swift short syntax of execution

I am looking for the way to write short syntax.

For instance. In JS, PHP and etc.

var a = 1 ;

function Foo ()-> void {}

a && Foo() ;

if a exists, run Foo.

a and Foo itself already mean exist or not, the syntax is away better looks....

However, in Swift, the typing checking is kinda of tough.

var a = 1 ;

func Foo ()-> Foid {} ;

a && Foo();

will generate neither are Bool returning error.

a != nil && Foo() ;

this can resolve and variable condition, but what if the better bypass for the function condition? I just dont want to write something like

if( a != nil ) { Foo() } ;

Yet what is the better syntax for Not Exist?

if ( !a ) or !a //is easy and better looks...

I found not similar thing in swift...

if( a == nil ) // will throws error when its not Optional Typing.

guard var b = xxx else {} // simply for Exist and very long syntax.

Thank you for your advice!

Upvotes: 3

Views: 662

Answers (5)

Chris Zielinski
Chris Zielinski

Reputation: 1391

As mentioned by other contributors, Swift emphasizes readability and thus, explicit syntax. It would be sacrilege for the Swift standard library to support Python-style truth value testing.

That being said, Swift’s extensibility allows us to implement such functionality ourselves—if we really want to.

prefix func !<T>(value: T) -> Bool {
    switch T.self {
    case is Bool.Type:
        return value as! Bool
    default:
        guard Double(String(describing: value)) != 0
            else { return false }

        return true
    }
}

prefix func !<T>(value: T?) -> Bool {
    guard let unwrappedValue = value
        else { return false }

    return !unwrappedValue
}

var a = 1

func foo() -> Void { }

!a && !foo()

Or even define our own custom operator:

prefix operator ✋

prefix func ✋<T>(value: T) -> Bool {
    /// Same body as the previous example.
}

prefix func ✋<T>(value: T?) -> Bool {
    guard let unwrappedValue = value
        else { return false }

    return ✋unwrappedValue
}

var a = 1

func foo() -> Void { }

✋a && ✋foo()

Upvotes: 2

Alexander
Alexander

Reputation: 63264

The expectations you've developed from dynamic languages like PHP and JS (and Ruby, Python for that matter) are almost universally inapplicable to static languages like Swift.

Swift is a statically compiled language. If you reference a variable that doesn't exist, it's not legal Swift code, and the compiler will fail your build. Given that, the question of "how do I check if a variable is undefined?" is completely moot in Swift. If you have a successfully compiling program that references a variable a, then a exists. There's absolutely no reason for a check, and so a mechanism for it doesn't even exist.

Static vs Dynamic typing

Static type systems are like mathematical proof systems. They produce rigerous proofs that certain aspects of your program are valid. This has trade-offs. The rigidity buys you many guarantees. For example, you'll never have a valid Swift program where you accidentally pass an Int where a Bool is expected. The static type system makes that class of error literally impossible, so it's not something you have to remember to check for yourself.

On the other hand, many truths are easier to intuit than to prove. Thus, there's great utility in scripting and dynamic languages, because they don't demand the rigorous proofs of your claims that static languages require. On the down side, their type systems "do" much less. For example, JS happily lets you reference an undefined variable. To remedy this, JS provides a way for you to do a run-time check to see whether a variable is defined or not. But this isn't a problem Swift has, so the "solution" is absent.

When static typing is too hard

Swift actually takes a middle ground position. If you find yourself with a statement that's obviously true, but hard to prove to the compiler, various "escape hatches" exist that allow you to leave the safety of the type system, and go into dynamic land. For example, if you look at an IBOutlet, and see that it's connected to an element in a storyboard, you can intuitively be sure that the IBOutlet is not nil. But that's not something you can prove to the compiler, and hence when you see implicitly unwrapped optionals being used for IBOutlets.

Implicitly unwrapped optionals are one such "escape hatch". The Any type is another, as is unsafeBitcast(_:to:), withoutActuallyEscaping(_:), as!, try!, etc.

Upvotes: 2

E.Coms
E.Coms

Reputation: 11531

Here is one way most similar to what you designed.

You may have to set the type of a to Int?:

  var a: Int? = 1
  func foo ()-> Void {}
  a.map{_ in foo()}

Upvotes: 0

creeperspeak
creeperspeak

Reputation: 5523

In this case you are trying to force Swift to work in a way that you are used to with other languages like JavaScript or PHP, as you say in your comment. There are a few reasons why your code won't compile, but it mainly falls on the fact that Swift doesn't do the same truthy and falsy stuff JS does.

var a = 1
if a {
  print("won't compile")
}
//'Int' is not convertible to 'Bool'

In Swift it's better to use an actual Bool value if that's what it's supposed to be, or if it's truly supposed to be an Int you're just going to have to check the value

var a = true
if a {
  print("this compiles")
}

or

var a = 1
if a > 0 {
  print("this compiles too")
}

Swift really isn't meant to be as loose as JS, so you should just embrace that and take advantage of the safety and readability.

Upvotes: 1

Shreeram Bhat
Shreeram Bhat

Reputation: 3157

Swift takes type safety very seriously. Unlike C or JS we can not use anything that doesn't resolve to Bool value type in If statement in Swift. So there won't be a short hand for that(at-least that I know of). Regarding below code

 if( a == nil ) // will throws error when its not Optional Typing.

Swift doesn't allow you to set nil to non optional types. So there is no need to check for nil. By the way both Obj-C and Swift use verbose syntax, we need to get use to that.

Upvotes: 1

Related Questions