AI Front Line introduction:






For more quality content, please follow the wechat official account “AI Front” (ID: AI-Front).

You may have heard of so-called “functional” programming. Maybe you’re even wondering if you should try it next.

The answer is no! It’s hell!

Functional programming has many drawbacks, is not suitable for real project development, and leads to a decrease in productivity. Why is that? Listen to this article.

  • Enterprise-level software in the real world needs to meet a set of complex, stringent, and mandatory requirements related to a large number of abstract expectations embedded in software solutions. In other words, object-oriented programming helps programmers use multiple abstraction mechanisms that are perfectly suited to the complex needs of an enterprise.

This is a mouthful, but bear with me! A clear explanation will follow.

So-called “functional” programming, because it is mathematically based, has no proper abstraction mechanism (obviously, this is not a good idea, since mathematics has no real-world application except in academia). Unlike OOP, functional programming does not attempt to meet the many stringent and complex requirements required by an enterprise.

This code illustrates a common problem in functional programming:

import { filter, first, get } from 'lodash/fp'; const filterByType = type => filter( x => x.type === type ); Const fruits = [{type: 'apple', price: 1.99}, {type: 'orange', price: 2.99}, {type: 'grape', price: 44.95}]; const getFruitPrice = type => fruits => fruits |> filterByType(type) |> first |> get('price'); const getApplePrice = getFruitPrice('apple'); console.log('apple price', getApplePrice(fruits));Copy the code

fp-sucks-apples-fp.js

Do you get mad at him? It’s okay, it’s not just you!

Functional programming does not attempt to properly abstract and encapsulate functionality, as is typically required of all serious enterprises.

No self-respecting software engineer would write code like this! If they do, then they may be dismissed immediately by big, serious companies to prevent further losses. In the next section, we’ll look at a properly abstract OOP program.

Everyone knows that the first responsibility of a professional and self-respecting software engineer is to write future-oriented code that meets complex business needs.

In contrast to the disastrous functional code above, let’s take a quick look at a properly abstract OOP program. It does exactly the same thing, but in an abstract, future-oriented way:

class Fruit { constructor(type, price) { this.type = type; this.price = price; } } class AbstractFruitFactory { make(type, price) { return new Fruit(type, price); } } class AppleFactory extends AbstractFruitFactory { make(price) { return super.make("apple", price); } } class OrangeFactory extends AbstractFruitFactory { make(price) { return super.make("orange", price); } } class GrapeFactory extends AbstractFruitFactory { make(price) { return super.make("grape", price); } } class FruitRepository { constructor() { this.fruitList = []; } locate(strategy) { return strategy.locate(this.fruitList); } put(fruit) { this.fruitList.push(fruit); } } class FruitLocationStrategy { constructor(fruitType) { this.fruitType = fruitType; } locate(list) { return list.find(x => x.type === this.fruitType); } } class FruitPriceLocator { constructor(fruitRepository, locationStrategy) { this.fruitRepository = fruitRepository; this.locationStrategy = locationStrategy; } locatePrice() { return this.fruitRepository.locate(this.locationStrategy).price; } } const appleFactory = new AppleFactory(); const orangeFactory = new OrangeFactory(); const grapeFactory = new GrapeFactory(); const fruitRepository = new FruitRepository(); FruitRepository. Put (appleFactory. Make (1.99)); FruitRepository. Put (orangeFactory. Make (2.99)); FruitRepository. Put (grapeFactory. Make (44.95)); const appleLocationStrategy = new FruitLocationStrategy("apple"); const applePriceLocator = new FruitPriceLocator( fruitRepository, appleLocationStrategy ); const applePrice = applePriceLocator.locatePrice(); console.log("apple", applePrice);Copy the code

file-fp-sucks-apples-oop-js

As we can see, it is properly abstracted from all the core functions. This code is SOLID.

Don’t let the simple fool you! It fulfills all the complex business requirements typically required by any large enterprise.

This robust solution is fully future-oriented and appropriately leverages enterprise-level dependency injection.

Hopefully, by now, the development team has completed the complex business requirements related to code abstraction as dictated by the enterprise. Developers should now focus their resources on implementing the functionality defined by the project manager.

As any real-world enterprise product manager knows, only the new functionality delivered is truly business value. Developers should not waste resources on time-consuming things like unit testing, refactoring, etc.

Obviously, so-called “functional” programming is flawed, and it doesn’t have to make redundant tasks like refactoring, unit testing, and so on easy. This, in turn, distracts the development team, which may inadvertently waste time on useless activities instead of providing new features.

The following example illustrates very clearly the disadvantages of functional programming, which makes refactoring too easy:

// Calculator.js: const isValidInput => true; const btnAddClick = (aText, bText) => { if (! isValidInput(aText) || ! isValidInput(bText)) { return; }} // InputValidator. js: export const isValidInput => true; // calculator.js: import { isValidInput } from './inputValidator'; const btnAddClick = (aText, bText, _isValidInput = isValidInput) => { if (! _isValidInput(aText) || ! _isValidInput(bText)) { return; }}Copy the code

file-fp_refactoring-js

If such refactoring makes you uneasy about its simplicity, you’re not alone! Six lines of code before refactoring, seven lines after refactoring? You must be kidding!

Let’s contrast this with a proper refactoring of object-oriented code:

Public class CalculatorForm {private string aText, bText; private bool IsValidInput(string text) => true; private void btnAddClick(object sender, EventArgs e) { if ( ! IsValidInput(bText) || ! IsValidInput(aText) ) { return; Public class CalculatorForm {private String aText, bText; private readonly IInputValidator _inputValidator; public CalculatorForm(IInputValidator inputValidator) { _inputValidator = inputValidator; } private void btnAddClick(object sender, EventArgs e) { if ( ! _inputValidator.IsValidInput(bText) || ! _inputValidator.IsValidInput(aText) ) { return; } } } public interface IInputValidator { bool IsValidInput(string text); } public class InputValidator : IInputValidator { public bool IsValidInput(string text) => true; } public class InputValidatorFactory { public IInputValidator CreateInputValidator() => new InputValidator(); }Copy the code

file-oop_refactoring-cs

This is what proper programming looks like! Refactor the first 9 lines of code and the last 22 lines. Refactoring requires more effort, which will make enterprise developers think twice before engaging in wasteful activities such as refactoring.

So-called “functional” programmers mistakenly take pride in writing declarative code. This is nothing to be proud of; this kind of code creates a false sense of productivity.

The core responsibilities of any developer should include proper and rigorous object-oriented abstractions (which are also required of any large enterprise).

Let’s take a look at some appropriately abstract OOP code:

class CountryUserSelectionStrategy {
      constructor(country) {
        this.country = country;
      }

      isMatch(user) {
        return user.country === this.country;
      }
    }

    class UserSelector {
      constructor(repository, userSelectionStrategy) {
        this.repository = repository;
        this.userSelectionStrategy = userSelectionStrategy;
      }

      selectUser() {
        let user = null;

        for (const u in users) {
          if ( this.userSelectionStrategy.isMatch(u) ) {
            user = u;
            break;
          }
        }

        return user;
      }
    }

    const userRepository = new UserRepository();
    const userInitializer = new UserInitializer();
    userInitializer.initialize(userRepository);

    const americanSelectionStrategy = new CountryUserSelectionStrategy('USA');
    const americanUserSelector = new UserSelector(userRepository, americanSelectionStrategy);

    const american = americanUserSelector.selectUser();

    console.log('American', american);
Copy the code

file-fp-sucks-imperative-js

Pay attention to the loop command on line 20. Ignore minor boilerplate OOP code that is irrelevant to the task at hand. It must be included in order for the code sample to meet the strict abstractions required by a serious enterprise.

Declarative code, on the other hand, is too succinct and mistakenly leads developers to focus on less important things, such as business logic. Contrast the robust enterprise solution above with the poor “declarative” code below:

SELECT * FROM Users WHERE Country= 'USA';Copy the code

SQL scares me every time because it’s declarative. Why SQL? Why can’t they let developers use proper enterprise-level abstractions and write normal object-oriented code? Especially when we already have the tools. This is surprising.

Object-oriented programming is genius. Unlike “functional” programming, it perfectly models the real world using advanced techniques such as inheritance, polymorphism, and encapsulation.

Any self-respecting software developer should use inheritance every day to make code reusable. As I said before, inheritance perfectly mimics the real world. Cats, for example, always inherit their traits and behaviors from an abstract, real-world animal. Life began in the oceans billions of years ago. As a result, all mammals (including cats) have inherited traits (e.g., Garfield. FishHead) and methods (e.g., Garfield. Swim and Garfield. LayCaviar) from the original fish. No wonder cats love bathing and swimming so much! Humans are all the same, and we can just as easily start laying eggs if we want to!

For code organization, our programs should always follow a similar hierarchical approach. Functional programming mistakenly frees developers from such amazing code-sharing structures inspired by the real world. This has profound implications, especially in very complex enterprise software.

This is just common sense and a perfect model of the real world. The notebook you buy from Chapters comes with a built-in “writing method.” Call this method whenever you want to write something. So, you might not be aware of it, but there are other things you can do, veggies, eat veggies, doHomeWork. It’s just common sense, how else would your mother make you eat your vegetables and do your homework? Of course, she used to call these methods directly!

In the real world, work is impossible without a Manager who specializes in coordinating tasks. Young people may need a manager to meet their basic needs, such as netflix-n-chill. Who is coordinating the process? If they are smart, they will hire multiple managers, as OOP recommends.

In the real world, creating anything new and cool also requires a dedicated Factory. Leonardo owns a Monalisa Tory and Trump builds a secret WallFactory. Russia used to have a CommunismFactory, but now maintains its CorruptionFactory, hidden deep beneath the Kremlin.

We can clearly see that this is just another nail in the coffin of “functional” because it does not attempt to simulate the real world. It is clearly wrong to allow functions to exist independently of objects. Obviously, functional programming does not apply to any actual coding.

First and foremost, software engineers should focus on continuous improvement and growth. In order to truly master object-oriented programming, software engineers must master a great deal of knowledge.

First, they must learn advanced OOP techniques such as inheritance, abstraction, encapsulation, and polymorphism. They should then familiarize themselves with various design patterns (such as singleton patterns) and use them in their code. There are about 30 basic design patterns to learn. In addition, developers should ideally use a variety of enterprise-level abstraction techniques in their code as well.

Second, familiarize yourself with techniques like domain-driven design and learn how to break down monolithic applications. It is also recommended that they learn appropriate refactoring tools, such as Resharper, because OOP code is not easy to refactor.

It takes at least 20-30 years to become proficient in OOP. Even so, most people with 30 years of OOP experience haven’t really mastered it yet. The road to learning is bumpy and full of uncertainty. How exciting it is that OOP developers need a lifetime of learning!

What about the poor functional programmer? Unfortunately, there’s nothing to learn. I’ve personally taught some junior developers functional programming in JavaScript, and they got really good at it in about half a year. They just need to understand some basic concepts and quickly learn how to apply them. What’s fun about lifelong learning? I wouldn’t envy them.

We recognize that our programmers are paid for their time. Just like the construction workers digging holes in my neighborhood for the past two years (they’re building a wall, oh no, a road, by the way).

Let’s define programmer productivity. Everyone who has worked in a large organization knows the simple formula for success:

Productivity = lines of code x bug fixesCopy the code

The human brain is really bad at processing states, and we can only remember about five tasks in our brain at any given time. State during programming can be any data in memory, such as fields/variables in OOP. Using mutable states is like juggling. Few people I know can play three balls at once, let alone five.

OOP takes advantage of this weakness. In OOP, almost everything is mutable. Thank God OOP takes developer productivity very seriously! In OOP, all mutable state can also be shared by reference! This means that we need to consider not only the mutable state of the object we are currently working with, but also the mutable state of the other 10-50 objects with which we interact! It’s similar to playing 50 balls at once, with the added benefit that it’s a great workout for brain muscles.

The Bug? Yes, eventually we’ll lose some of the balls we’ve been playing with. In the interaction between these 50 objects, we might miss some small details. But who cares, really? During production, customers are supposed to report bugs, as any large enterprise does. And then you type those bugs into JIRA, um, pretty serious enterprise-level software. After a few years, these bugs will be fixed. Problem solved!

God, I love using my mobile banking app. It’s very advanced and the bank takes my business very seriously and they take my privacy very seriously. But I was told that these bugs are just features!

So-called “functional” programming mistakenly isolates state and makes it immutable. This has the unfortunate consequence of reducing complexity and thus the number of bugs. Fewer bugs in the code base means fewer bugs to fix. Contractors will no longer be able to charge their customers for fixing these bugs. Developers working in any large enterprise will look bad in the eyes of their managers and can seriously affect their chances of moving up in the organization.

We should also continuously demonstrate our progress to management. What’s the most effective way to do that? Lines of code, of course! If we all switched to functional programming, we would make management very upset and confused. “Declarative” code will make our code much cleaner and significantly fewer lines of code. Achieving the exact same goal can reduce the code by a factor of 3-5 at most, which is unacceptable!

In other words, in the face of serious corporate governance, our productivity will plummet and our jobs will once again be at risk. Moving away from “functional” programming is in our best interest.

The same advice applies to contractors who charge their clients for time worked. Here’s a simple formula for success:

Lines of code = coding practice =? Net profit? $Copy the code

Of course, this formula for success also applies directly to software contractors who charge per line of code:

if (1 == '1') {
  doStuff();
} else {
  // pure profit
}
Copy the code

Unlike functional programming, OOP gives us a consistent way to write spaghetti code, which is a real boon for developer productivity. Spaghetti code means more billable time, which translates into net profit for OOP engineers. Pasta not only tastes delicious, it’s OOP programmers’ bread and butter!

Object orientation is a real boon for contractors and serious business employees alike.

We shouldn’t be afraid to use OOP. Again, those pesky bugs are nothing to worry about! Any serious organization has an entire bug prevention department (aka customer support) whose main job is to protect their developer resources from angry customers. After all, it’s the customer’s fault that the application isn’t used properly.

Developers should not worry about trivial things like bug reports. This ensures that no enterprise resources are wasted and allows developers to focus on implementing new functionality while using appropriate enterprise-level object-oriented abstractions and complex design patterns.

A detailed and rigorous process is often carefully designed to protect enterprise resources. Once a customer encounters a bug, they usually have to look up the customer support phone number online. Customers will see an advanced interactive phone menu with various options. It usually takes two to five minutes to listen to the menu and choose the right option. Impatient clients often give up at this point.

Customers are then typically told that the company is dealing with an “unexpectedly high number of calls” or that “the average wait time is 56 minutes.” They usually apologize for the inconvenience and express how much they value their client’s business. In this step, most customers usually give up reporting bugs. Encouraging music is often played to please customers. They’re also going to get customers to pay attention to this great new app. This app is the one where customers initially had problems.

After waiting 56 minutes, the call was routed to a call center somewhere in North America. The Local American employees are often highly trained and can speak with a strong Indian or Bulgarian accent. The agent will say that he is not responsible for the problem with the application, but is happy to refer the client to another department.

After another 42 minutes of waiting, an agent happily tells the customer that the bug is actually a feature and suggests that the user browse the help section of the application. If the customer still persists, the agent might create a support notification and maybe even call the customer back! This bug cannot be reproduced.

I hope by now you’re convinced that worrying about bugs is not a developer’s job. Organizations often take strict measures to protect developer resources.

If you’re actively looking for work, take some effort to get all the “functional” crap out of your resume or no one will take you seriously. In the real corporate world, no one is trained in childish things like “function combinations,” “pure functions,” “monads,” or “immutable.” You don’t want to look like an outsider. Talking about these things will silence your interviewer and completely destroy your chances of success.

Technical recruiters in companies are also highly trained to distinguish between technologies like Java and JavaScript.

Be sure to intersperse your resume with words that demonstrate your knowledge of strict enterprise-level abstraction techniques such as classes, inheritance, design patterns, dependency injection, entities, abstract factories, and singletons.

When asked to implement the classic FizzBuzz job interview question on a whiteboard, make sure you’re fully prepared. This is your chance to demonstrate your ability to be a serious enterprise system designer. The first step is to fully design the solution, using appropriate OOP design patterns and strict enterprise-level abstraction techniques. FizzBuzz Enterprise edition is a good place to start. A rookie mistake many people make is to rely on poor design techniques such as functions. No wonder they never hear back from potential employers.

After considering all the serious and rigorous arguments above, it is now clear that this so-called “functional” programming does not do any good. Obviously, it should be avoided at all costs.

So-called “functional” programming has been a popular trend in recent years. Glad it’s dying! Large companies like Facebook and Microsoft have long recognized the limitations of functional programming and the obvious advantages of an object-oriented approach to code organization. They are shifting resources to a new generation of object-oriented languages, ReasonOL and BosqueOOP. These languages take state variability to a whole new level, and fortunately, they don’t support useless functional things like immutable data structures.

So, you might ask, what are the alternatives to so-called “functional” programming? Object-oriented programming, stupid! It was given to us by a true programming god. OOP is a force to be reckoned with. It’s the ultimate developer productivity tool, keeping you and your team members busy at work.

May the power of object orientation be with you. And your code. I am a member of the Force. I wish well.

For a more in-depth explanation, see my other object-oriented programming article, Grace of God.

PS: Most of you have already guessed, this is a satirical article. All new developers out there, don’t be so serious, functional programming is great! Take the time to learn and you’ll be ahead of most of your peers.

Original link:

http://medium.com/better-programming/fp-toy-7f52ea0a947e

Today’s recommendation,

Click on the image below to read it