Is this how dynamic language copes with dynamic requirement? [closed]

The question is in the title. I want to have my thinking verified by experienced people. You can add more or disregard my opinion, but give me a reason.

Here is an example requirement: Suppose you are required to implement a fighting game. Initially, the game only includes fighters, who can attack each other. Each fighter can punch, kick or block incoming attacks. Fighters can have various fighting styles: Karate, Judo, Kung Fu… That’s it for the simple universe of the game. In an OO like Java, it can be implemented similar to this way:

abstract class Fighter {
    int hp, attack;

    void punch(Fighter otherFighter);
    void kick(Fighter otherFighter);
    void block(Figther otherFighter); 
};

class KarateFighter extends Fighter { //...implementation...};
class JudoFighter extends Fighter { //...implementation... };
class KungFuFighter extends Fighter { //...implementation ... };

This is fine if the game stays like this forever. But, somehow the game designers decide to change the theme of the game: instead of a simple fighting game, the game evolves to become a RPG, in which characters can not only fight but perform other activities, i.e. the character can be a priest, an accountant, a scientist etc… At this point, to make it more generic, we have to change the structure of our original design: Fighter is not used to refer to a person anymore; it refers to a profession. The specialized classes of Fighter (KaraterFighter, JudoFighter, KungFuFighter) . Now we have to create a generic class named Person. However, to adapt this change, I have to change the method signatures of the original operations:

class Person {
    int hp, attack;
    List<Profession> skillSet;
};

abstract class Profession {};

class Fighter extends Profession {         
    void punch(Person otherFighter);
    void kick(Person otherFighter);
    void block(Person otherFighter); 
};

class KarateFighter extends Fighter { //...implementation...};
class JudoFighter extends Fighter { //...implementation... };
class KungFuFighter extends Fighter { //...implementation ... };

class Accountant extends Profession {
     void calculateTax(Person p) { //...implementation...};
     void calculateTax(Company c) { //...implementation...};
};
//... more professions...

Here are the problems:

  1. To adapt to the method changes, I have to fix the places where the changed methods are called (refactoring).

  2. Every time a new requirement is introduced, the current structural design has to be broken to adapt the changes. This leads to the first problem.

  3. Rigid structure makes it hard for code reuse. A function can only accept the predefined types, but it cannot accept future unknown types. A written function is bound to its current universe and has no way to accommodate to the new types, without modifications or rewrite from scratch. I see Java has a lot of deprecated methods.

OO is an extreme case because it has inheritance to add up the complexity, but in general for statically typed language, types are very strict.

In contrast, a dynamic language can handle the above case as follow:

;;fighter1 punch fighter2
(defun perform-punch (fighter1 fighter2) ...implementation... )

;;fighter1 kick fighter2
(defun perform-kick (fighter1 fighter2) ...implementation... )

;;fighter1 blocks attacks from fighter2
(defun perform-block (fighter1 fighter2) ...implementation... )

fighter1 and fighter2 can be anything as long as it has the required data for calculation; or methods (duck typing). You don’t have to change from the type Fighter to Person. In the case of Lisp, because Lisp only has a single data structure: list, it’s even easier to adapt to changes. However, other dynamic languages can have similar behaviors as well.

I work primarily with static languages (mainly C and Java, but working with Java was a long time ago). I started learning Lisp and some other dynamic languages this year. I can see how it helps improving my productivity.

14

I am not entirely sure what your question is, because it the question includes a number of vague terms: “dynamic language”, “this” and “dynamic requirement”.

“Dynamic language” can refer to any programming language that does something that other languages may do at compile time. This can include aspects of data values (null or not null), aspects of the type system (e.g. creating new types at runtime), aspects of method and function dispatch and many other aspects.
Your question seems to be primarily concerned with dynamic method dispatch (although you talk about static typing later on).
My attitude to this would be that different languages provide one with different tools of how to deal with requirements and also with changing requirements. In that sense, the answer to your question is probably “yes”. Where languages like Java or Scala provide interfaces and traits to make it easier to adapt the design of your programs to changing requirements, a language like Clojure provides dynamic dispatch, Groovy provides metaprogramming and still other languages provide no or very little tools at all.
I think which of these tools are better suited for the task depends on the details of the task, the details of your definition of “better” (development time and effort, availability of programmer, performance of code, likelihood of certain classes of bugs during runtime etc.) and on personal preference and cannot be answered in general.

2

I think the answer boils down to: yes a “dynamic” language helps your coding productivity as you can make sweeping changes quickly and easily. However, it hurts your release productivity as you have create a mess of code that has no consistent structure to it and lots of only-runtime-detectable errors that will need fixing later, rather than sooner like you’d get in a “static” language.

There’s simply no substitute for doing things correctly, and that means thought, design, and careful consideration of the impact of your changes.

A dynamic language may complain less when you refactor, but it could also be hiding type errors from you that you’d catch at compile time on a statically typed language. In general, you’ll have to refactor your code when your requirements change regardless of whether you’re on a dynamic or statically typed language. There’s no silver bullet there.

C and Java aren’t good benchmarks for static languages, because they have very limited type systems and features. You can’t get anything done in Java without extreme verbosity. Want to pass a tuple? Well, you can’t. Records? You can’t. Want an anonymous function? You’ll have to write 4 lines of boilerplate for a payload that could be as short as 2 + 2. God help you if you want to curry or compose functions.

You have to resort to a bunch of OO hacks to work around those missing features, and even then you can still shoot yourself in the foot with inheritance and null because so many people don’t understand how dangerous they are. So if that’s your only point of reference, just about any dynamic language will allow you to write less code, but not necessarily by virtue of their dynamic typing. Languages like Standard ML or F# also provide those features without burdening you with type annotations because the compiler can infer the types.

A good statically-typed language is more expressive than a dynamically typed language with equivalent features. Dynamic typing deprives you of the ability to express constraints on your data using the type system. That’s because dynamic typing is a special case of static typing – it’s more correct to think of these languages as being unityped. If that seems strange to you, imagine coding in Java using only Object variables and casts. The problem is that mainstream statically typed languages are crippled. But if you’re coding in Lisp, I don’t think you’re too concerned with what’s mainstream.

A dynamic language can be great when faced with dynamic requirements. Personally, I prefer Python to C when I’m faced with a lot of changes. There is far less ceremony compared with C++, C#, Java. But …

Regardless of the language, the architecture of the system / project has a massive impact upon how well we can adapt to changes, such as those that you mention. For me the bigger question is “How quickly can we refactor to accommodate the changes.” For your example, base classes would need changes and I would prefer to have multiple inheritance.

In our projects, the external analysis and design documents are massively revisited when big changes come about. We prefer to issue revised documents and from that make a big list of change requests. And yes, the test suites need a lot of extra work too.

I’m not sure, I’m getting your point here, but different kinds of languages don’t really solve the underlying problem which is, basically, that a once written code base needs to be expanded. While this is something that refactoring, obviously, can solve, maybe the general concept/design of the code was unfortunate in the first place.

For instance, how about a Fighter (or a Person if you later change that) does “just something”. Using, for example Java generics, you can even limit what they can do.

class Fighter {
    void doSomething(Command<? extends FighterCommand> cmd) {
        cmd.execute();
    }
}

One can now easily, at any point during development, expand the abilities of a fighter by just adding another command.

class KickCommand extends FighterCommand {
    @Override
    public void execute() {
        kickSomeone();
    }
}

Using the Command pattern here would absolve you from changing interfaces all over the place just because the fighter needs to punch someone now, too.

And getting closer to what you were asking, extending the Fighter concept to a Person concept should be possible by making the Fighter extend (the now new) Person. If a Person can doSomething(), too, it’s only one @Override in the Fighter away (or deletion of the Fighter method :)).

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật