0

I have been reading some posts and it always get me confused.

1, some says a language is static/dynamic by how the type is determined, in runtime or in compile time. But should we say the language is static/dynamic typing language rather than static/dynamic language?

2, in some comparison of swift vs objective-c. We know that objective-c uses its runtime to do dynamic method dispatch. And some uses this as a reason to say that the language/objective-c is dynamic, is this true?!

3, I'm sometimes confused about the OOP's polymorphism, some says in order to make it work, the language HAS to support method dynamic dispatching. Is this right?

4, for swift, I know it's a static typing language, but is it a static or dynamic method dispatching language? and is it a static or dynamic language overall??

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Tony Lin
  • 922
  • 6
  • 25
  • Even statically typed languages have dynamic dispatch. Obvious examples: Swift, ObjC. If you have `let car: Car = SportsCar()`, and you call `car.vroom()`, the runtime has to dynamically dispatch that method call, to determine what the correct method implementation is. The type is still statically known: it's `Car`, or some subtype of it. – Alexander Mar 18 '19 at 03:52
  • @Alexander I guess this is a partial answer to my question #3. from what you described, it sounds like if the language supports OOP's polymorphism, it means the language is capable of `method dynamic dispatch`. But is this always the case? – Tony Lin Mar 18 '19 at 05:35
  • Possible duplicate of [What is the difference between statically typed and dynamically typed languages?](https://stackoverflow.com/questions/1517582/what-is-the-difference-between-statically-typed-and-dynamically-typed-languages) – aridlehoover Mar 18 '19 at 06:00

2 Answers2

3
  1. I've never heard of the term "static language" or "dynamic language." The usual terms I've heard of are "statically typed language" or "dynamically typed language."

  2. "Dynamic" isn't a defined term in this context, so there's not much to say here.

  3. Polymorphism has multiple different meanings, so I'll assume you mean subtype polymorphism. In that case, yes, dynamic dispatch is necessary. The whole idea is that you want objects of different types to behave in their own way in response to the same message (method call). The only way to do this is to decouple messages and function invocations, so that an appropriate function can be called at runtime depending on the type of the receiver of the message.

  4. Swift is a statically typed language, through and through. This might be obscured a bit by type inference. If you have an expression like

     func someFunction() -> Int { return 123 }
     let x = someFunction()
    

    The type inference doesn't mean "x has some type that will be figured out at runtime." To the contrary, it means "The type of x can be deduced at runtime because we already know the type of someFunction."

    All types in Swift are known at compile time. In the worst case, a must at least have type Any, which is still a type. It's not a particularly useful type (because there isn't much an Any is guaranteed to be able to do), but it's still a type.

    There is some confusion in that there's talk of types at compile time and runtime types. Here's an example:

         class Car {
             func vroom() { print("vroom") }
         }
    
         class SportsCar: Car {
             override func vroom() { print("VROOOOOM") }
         }
    
         let car: Car = SportsCar()
    
         func driveSportsCar(_: SportsCar) { print("driving") }
         // Compile types are what determine usage compatibility
         driveSportsCar(car) //  cannot convert value of type 'Car' to expected argument type 'SportsCar'
    
         // Runtime types are what determine method implementations
         car.vroom() // => "VROOOOOM"
    

    In this example, car has a compile time type of Car, and a runtime type of SportsCar. The compile time type determines how it can be used, where it can be passed, etc. For example, you couldn't pass car to a driveSportsCar() function, because even though its runtime type is SportsCar, its compile time type is Car, which isn't compatible.

    The runtime type of an object is what determines the method implementations to be called.

Alexander
  • 59,041
  • 12
  • 98
  • 151
  • thanks, but I'm still a bit confused, especially from the 41 upvotes answer from https://stackoverflow.com/questions/29924477/is-swift-a-dynamic-or-static-language . He stated that the swift is static because of its static typing at compile time, which makes sense to me. BUT, he then said the Objective-c is dynamic because you can do method swizzle, etc. He used the term like "swift is static and objectives is dynamic" which is contradictory to what you said, which confuses me even more. – Tony Lin Mar 18 '19 at 23:44
  • I think the confusion stems from the terms "dynamic" and "static," which aren't really defined (unlike "dynamic typing", "static typing"). Objective C is just as statically typed as Swift. They don't differ in this regard. The difference is that Objective C doesn't take advantage of the static type information it has to statically dispatch methods. Doing so would make the system much faster, but would disallow all the cool stuff you could otherwise do with the runtime (creating new subclasses at runtime, method swizzling, proxy objects, method forwarding, etc.). – Alexander Mar 19 '19 at 01:57
  • Fundamentally, the Objective C runtime serves as a single point at which all method calls can be intercepted. In Objective C, *all* method calls go through `objc_msgSend` (and its variants). The benefit of this is that you have a single place where you can make changes. Classes have method tables that associate method names (selectors) and function pointers (of the implementations). If you want to swizzle two methods, you merely swap around the mapping of names to function pointers. Since all method calls always do a look up in these tables, all calls are impacted immediately – Alexander Mar 19 '19 at 02:00
  • On the flip side, if you allowed method inlining and other optimizations (which Swift heavily uses), then you have a single method's body "copy pasted" into a whole bunch of places. Doing so removes the need for instructions for jump, saving the previous registers, restoring the registers and return. It makes your code much faster, but you lose the convenience of a single interception point. You can't swizzle these methods without some borderline-impossible modification of the app binary (to swap around the instructions in place). – Alexander Mar 19 '19 at 02:02
  • So Objective C could be said to be more "dynamic" because it favours supporting runtime features over performance, whereas Swift heavily favours performance. However, in Swift you have the `dynamic` keyword, to "opt-into" the runtime features on a need-by-need basis. But again, that's not really a rigorously defined term. It's just a pattern of particular design priorities over others. – Alexander Mar 19 '19 at 02:06
2
  1. Swift is a statically ‘typed’ language which means that It performs type checks before run-time.
  2. Swift uses direct dispatch, table dispatch with its witness table, or message dispatch (obj-c ) depending on various situations, you can take a look at this article: https://www.raizlabs.com/dev/2016/12/swift-method-dispatch/ some of the examples are outdated but the concepts will be made more clear
  3. Static dispatch doesn’t support polymorphism because it needs to know which implementation for a method will be executed at compile time. Hope this helps a bit.
adri
  • 265
  • 2
  • 5