开源日报 每天推荐一个 GitHub 优质开源项目和一篇精选英文科技或编程文章原文,坚持阅读《开源日报》,保持每日学习的好习惯。
今日推荐开源项目:《翻新照片 Bringing-Old-Photos-Back-to-Life》
今日推荐英文原文:《Declarative Versus Imperative Code》

今日推荐开源项目:《翻新照片 Bringing-Old-Photos-Back-to-Life》传送门:项目链接
推荐理由:这个项目是微软新推出的人工智能修复老照片的项目,包括划痕修复,整体颜色复原和面部修复等过程。目前已经推出了试用 demo,不过该项目的模型使用特定分辨率的图片进行了预训练,因此可能不适用于所有自己上传的照片的分辨率。
今日推荐英文原文:《Declarative Versus Imperative Code》作者:Martin Novák
原文链接:https://medium.com/better-programming/declarative-versus-imperative-code-180c0cf4003b
推荐理由:介绍了各种不同的代码风格

Declarative Versus Imperative Code

Terminology and differences in programming paradigms

Believe it or not, you are likely already using multiple programming paradigms as a developer. Because there is nothing more fun than entertaining your friends with programming theory, here is an article that will help you recognize popular paradigms in your code.

Imperative Code

Imperative programming is how we started with Assembly (1949) and continued with languages like C, C++, C#, PHP, and Java. Procedural and object-oriented programming belong under the imperative paradigm.

Your code is based on statements that change the program state by telling the computer how to do things. In other words, your code is based on defining variables and changing the values of those variables.

It is the ideal programming paradigm for people who have a less-than-innocent fetish for telling machines how to do their thinking.

Procedural code

Procedural code uses procedures to manage its structure. A procedure is simply a set of actions run in a specific order that you are able to call repeatedly instead of jumping by using goto commands.
#include <stdio.h>
int main()
{
    int num1, num2, num3;
    int *p1, *p2, *p3;

    //taking input from user
    printf("Enter First Number: ");
    scanf("%d",&num1);
    printf("Enter Second Number: ");
    scanf("%d",&num2);
    printf("Enter Third Number: ");
    scanf("%d",&num3);

    //assigning the address of input numbers to pointers
    p1 = &num1;
    p2 = &num2;
    p3 = &num3;
    if(*p1 > *p2) {
    if(*p1 > *p3){
        printf("%d is the largest number", *p1);
    }else{
        printf("%d is the largest number", *p3);
    }
    }else{
    if(*p2 > *p3){
        printf("%d is the largest number", *p2);
    }else{
        printf("%d is the largest number", *p3);
    }
    }
    return 0;
}
The above example in C language reads three numbers, uses pointers, and through conditional logic drives the program flow to determine the largest number out of the three. Procedural languages like C can offer you a fairly simple and very computing efficient solution to application challenges.

You usually need to read each procedure from top to bottom to understand what it does. Procedural programmers can be sometimes criticized for a tendency of writing spaghetti code. But any college student who hasn’t been dependent on spaghetti with ketchup for dinner had it easy in life.

Examples of procedural programming languages are Pascal (1970) and C (1972). Procedural programming has strong support. Linus Torvalds, the father of Linux, has been quite open in his criticism of C++ and object-oriented programming.

Object-oriented code

Object-oriented programming is modeling objects that hold internal states. The programming code is then based on the relationship among these objects. In classed-based languages, objects are instances of classes.

The code in the methods of the objects is still imperative and based on statements that modify the state.
public interface Retile {
   void walk();
}

public class Turtle implements Reptile {
   @Override
   public void walk() {
      System.out.println("Turtle is walking!");
   }
}

public class Tortoise implements Reptile {
   @Override
   public void walk() {
      System.out.println("Tortoise is walking!");
   }
}

public class ReptileFactory {
   public Reptile getReptile(String reptileType){
      if(reptileType == null){
         return null;
      }     
      if(reptileType.equalsIgnoreCase("TURTLE")){
         return new Turtle();
      } else if(shapeType.equalsIgnoreCase("TORTOISE")){
         return new Tortoise();
      }
      return null;
   }
}

public class ReptileDemo {
   public static void main(String[] args) {
      ReptileFactory reptileFactory = new ReptileFactory();

      Reptile reptile = Reptile.getReptile("TURTLE");

      reptile.walk();
   }
}
The above is an example of a factory design pattern implemented in Java. Notice how all the code focuses on defining classes and using a relationship among them through an interface. Usually, all these classes would be separated out into their own files.

Examples of object-oriented languages are Smalltalk (1972), C++ (1985), Python (1991), Java (1995), JavaScript (1995), Ruby (1995), C# (2000), Scala (2004), and Swift (2014).

JavaScript started as a prototype-based, object-oriented language without classes. Classes were added in ECMAScript 6 in 2015.

When you are studying programming, chances are that, of all the paradigms, you will encounter object-oriented code first and most. Even though it is the most popular paradigm, it still meets with serious criticism for its complexity, difficulty of understanding design patterns, and tricky state management across the application. At the same time, object-oriented programming languages are very mature and professionally appreciated.

In JavaScript, the front-end framework Angular is a great example of C# having a big influence on developers wanting to bring stronger object-oriented principles into web development.

Please continue using object-oriented programming in all your projects. Because if you don’t, all the people that know only this one paradigm will suddenly be out of a job and live in cardboard boxes. And you don’t want to be responsible for that, do you?

Declarative Code

Declarative code is very common, and it is represented by domain-specific, logic, and functional programming languages. Examples of these are HTML, SQL, F#, Prolog, and Lisp.

Declarative code focuses on expressions that are saying what without adding how. For example, HTML code <img src=”./turtle.jpg” /> tells the browser to display an image of a turtle without telling the browser how. It is also typical that a declarative code avoids mutation of state and variables.

Domain-specific code

Domain-specific languages are not Turing complete, which means that they can’t do everything that other Turing-complete languages can. For example, C# (imperative) and F# (declarative) are both Turning-complete languages, and everything that you can develop in one, you can also develop in the other one. HTML is not Turing-complete and allows you to do only specific things.

An example of SQL code that finds employees and their managers in a database:
SELECT e.name, m.name FROM Employee e, Employee m WHERE e.Employee_id=m.Manager_id;
Domain-specific languages are usually very simple to write and read. Because of that fact, they are the most popular way of user interface declaration. For example, the JavaScript programming library React uses JSX for defining components:
const myComponent = props => (


Hello, {props.userName}

};
Examples of domain-specific languages are SQL (1974), HTML (1993), CSS (1996), and XML (1996).

Logic code

Logic programming is a declarative paradigm based on formal logic. A program is a set of sentences in a logical form that express facts and rules about some problem domain.

The most typical logic programming language that is Turing-complete is Prolog (1972). That means that everything that you can write in C language you can in theory also write in Prolog.

Prolog is based on defining predicates that define the relationship between their arguments.
food(salad). % <- salad is food fact
food(pizza). % <- pizza is food fact

?- food(salad). % <- is salad food? True
?- food(turtle). % <- is turtle food? False
In the example above, you define facts that result in true and then you ask questions that again result in true or false boolean.

Remember that turtles are not food and someone should tell that to the starving people on Naked and Afraid.

Prolog is kinda magical when you work in it, and if you disagree then you are an evil baby-eater anyway.

Functional code

Functional programming is a declarative paradigm based on a composition of pure functions. Functional programming languages are Turing complete and based on lambda calculus, which is a system of mathematical logic from the 1930s.

A pure function is a function that depends only on its input and always provides an output without mutating or reading any external state. That is very different from procedural programming. Function composition is then about using simple functions together in a sequence to build your code.

Functional programming has been growing steadily in its popularity in the past years, and it has made its way into imperative programming languages. That means that languages such as Python, C++, and JavaScript are multiparadigmatic as they support writing code in multiple paradigms.

Here is an example of a functional code written in JavaScript using the @7urtle/lambda library:
import {upperCaseOf, trim, map, compose, Maybe} from '@7urtle/lambda';

const getElement = selector => Maybe.of(document.querySelector(selector));
const getText = element => element.textContent;
const transformer = compose(trim, upperCaseOf);
const getElementText = compose(map(transformer), map(getText), getElement);

getElementText('#myTurtle'); // => Maybe('SHELLY')
Functional programming brings a number of new concepts that are not present in object-oriented programming like pure functions, higher-order functions, immutability, functors, partial application, point-free functions, and so on. Because of that, the barrier of entry can be seemingly high, especially since many functional programming articles like to go very deep into its mathematic roots. I recommend having a look at simple articles like @7urtle/lambda JavaScript functional programming basics(https://www.7urtle.com/javascript-functional-programming-basics)for the introduction.

Only evil wizards think that functional programming is bad. So be clever, don’t listen to their wicked curses, and instead burn them at the stake where they belong. And remember that if someone says that monads are difficult, it’s just fake news.

Other examples of functional programming languages are LISP (1984), Haskell (1990), and F# (2005).

Study Your Programming Craft

Many programmers out there are really familiar only with the imperative and object-oriented approach to software development. Learning of other paradigms helps you to become a better developer even if you don’t end up jumping over the fence.
下载开源日报APP:https://openingsource.org/2579/
加入我们:https://openingsource.org/about/join/
关注我们:https://openingsource.org/about/love/