開源日報 每天推薦一個 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/