您能使用过程,功能,逻辑和OO编程语言表示相同的示例吗?

use*_*312 12 paradigms

任何人都可以请给我一个例子,通过使用几乎相同的示例问题,可以帮助我理解程序,功能,逻辑和面向对象的编程模型.

请使用过程,功能,逻辑和OO编程语言给我一些相同问题的示例代码片段.

Kei*_*son 10

http://99-bottles-of-beer.net/

(它具有我自己可怕的99语言.)


Ale*_*rev 10

让我们尝试更简单的例子 - 只计算第n个斐波纳契数.

首先,程序性(在Pascal中):

program Fibonacci;

function fib(n: Integer): Integer;
var a: Integer = 1;
    b: Integer = 1;
    f: Integer;
    i: Integer;
begin
  if (n = 1) or (n = 2) then
     fib := 1
  else
    begin
      for i := 3 to n do
      begin
         f := a + b;
         b := a;
         a := f;
      end;
      fib := f;
    end;
end;

begin
  WriteLn(fib(6));
end.
Run Code Online (Sandbox Code Playgroud)

此示例显示了过程语言的功能:

  • 有一些子程序(在这种情况下的功能)
  • 可能多次为变量赋值(:=运算符)
  • 有循环(在这种情况下运营商)
  • 语言是必不可少的,即我们告诉计算机以什么顺序做什么

二,面向对象(用Python):

class Fibonacci:
   def __init__(self):
       self.cache = {}
   def fib(self, n):
       if self.cache.has_key(n):
           return self.cache[n]
       if n == 1 or n == 2:
            return 1
       else:
           a = 1
           b = 1
           for i in range(2, n):
               f = a + b;
               b = a;
               a = f;
           self.cache[n] = f;
           return f;


fibonaccyCounter = Fibonacci()
print fibonaccyCounter.fib(6)
Run Code Online (Sandbox Code Playgroud)

实际上这个问题不值得创建一个类,所以我添加了已经计算过的结果的缓存.

此示例显示:

  • class及其实例化(创建实例)
  • class有自己的内存部分,自己的状态(self及其成员)
  • 语言是必不可少的,即我们告诉计算机以什么顺序做什么

没有显示,但我们可以例如从抽象类中返回此类,返回某个序列的第n个成员.通过子类化,我们得到定义Fibonacci序列的类,序列1,2,3 ...,序列1,4,9,16,......等.

三,功能风格(Haskell):

import Text.Printf

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

main = printf "%d\n" (fib 6)
Run Code Online (Sandbox Code Playgroud)

演示了函数式编程范例的以下特性:

  • 没有状态,没有变量 - 只是定义了函数
  • 没有循环 - 只有递归
  • 模式匹配:我们分别定义为数字的其余部分"FIB 0","FIB 1"和"FIB N",像没有构建体如果是需要
  • 声明式样式 - 我们没有定义计算函数值的步骤顺序:编译器/解释器/运行时在给定函数定义的情况下自行计算.我们告诉计算机我们想要得到什么,而不是做什么.
  • 懒惰的评价.如果main仅调用"fib 2",则不会调用"fib n",因为仅当需要将其结果作为参数传递给其他函数时才会计算函数.

但是函数式语言的主要特征是函数是第一类对象.这可以通过以下其他实现来证明fib:

fib n = fibs!!n
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)

这里我们将fibs函数作为参数传递给zipWith函数.此示例还演示了延迟评估:"无限"列表仅计算到其他函数所需的范围.

顺便说一句,功能并不一定意味着不面向对象.Scala是一个功能和面向对象的编程语言的例子.

序言:

fib(1, 1).
fib(2, 1).


fib(X, Y):-
        X > 1,
        X1 is X - 1,
        X2 is X - 2,
        fib(X1, Z),
        fib(X2, W),
        Y is W + Z.


main :-
   fib(6,X), write(X), nl.
Run Code Online (Sandbox Code Playgroud)

可以看到以下逻辑编程风格的特征:

  • 语言是声明性的.在功能风格中,我们定义事物而不是告诉它们以什么顺序执行.
  • 但功能风格的不同之处在于我们定义谓词,而不是函数.在这种情况下,谓词fib(X,Y)表示"第X个斐波那契数是Y".给定一些已知的谓词(fib(1,1)和fib(2,1) - 即第一个Fibonacci数为1,第二个Fibonacci数为1)和推断其他谓词的规则(Y是第X个Fibonacci数是Y是第一个斐波那契数和第二个第二个斐波纳契数之和,Prolog推断出有问题的谓词.实际上可能有超过1个答案!
  • 没有输入值和返回值 - 而不是我们定义"输入"和"输出"之间的关系.

该程序还可用于发现Fibonacci数字8位于序列的第6位:

?- between(0,inf,X), fib(X,8).
X = 6 .
Run Code Online (Sandbox Code Playgroud)


Wes*_*Wes 7

项目欧拉问题2:http://projecteuler.net/problem=2

Haskell(功能/逻辑):

p2 = sum [x | x <- fibs, (x `mod` 2) == 0] where
    fibs = unfoldr acc (0,1) where
            acc (prev, cur) | (prev+cur) > 4000000 = Nothing
                            | otherwise            = Just (prev+cur, (cur, prev+cur))
Run Code Online (Sandbox Code Playgroud)

Python(OO):

class FibSum(object):
    def __init__(self, end):
        self.end = end
        self.next_two = (1,0)
        self.sum = 0

    def __iter__(self):
        return self

    def next(self):
        current, previous = self.next_two
        self.next_two = (previous+current, current)
        new = current+previous

        if current >= self.end:
            raise StopIteration
        elif (new % 2) == 0:
            self.sum += new
        else:
            pass


fibcount = FibSum(4000000)
[i for i in fibcount]
print fibcount.sum
Run Code Online (Sandbox Code Playgroud)

C(程序/命令):

#include <stdio.h>

int main(void) 
{
    long int sum, newnum, previous = 0;
    long int current = 1;

    while(current <= 4000000) 
    {
        newnum = previous+current;
        if ((newnum % 2) == 0) 
        {
            sum = sum + newnum;
        }
        previous = current;
        current = newnum;

    }
    printf("%d\n", sum);
}
Run Code Online (Sandbox Code Playgroud)

这是一个用MIT Scheme编写的非常低效的版本

(define (unfold func seed)
    (let* ((result (func seed)))
    (cond ((null? result) ())
    (else (cons (car result) (unfold func (second result)))))))

(define (test x)
    (cond ((> (sum x) 4000000) ())
    (else (list (sum x) (list (second x) (sum x))))))

(define (sum xs)
    (cond ((null? (cdr xs)) (first xs))
    (else (+ (car xs) (sum (cdr xs))))))

(sum (filter (lambda (x) (eq? (modulo x 2) 0)) (unfold test (list 0 1))))
Run Code Online (Sandbox Code Playgroud)

Prolog:从这里开始,由13tazer31发布

fibonacci(_,Current,End,0) :-
        Current > End.
fibonacci(Previous, Current, End, Total) :-
        divisible(Current, 2),
        Next is Current + Previous,
        fibonacci(Current, Next, End, Sum),
        Total is Sum + Current, !.
fibonacci(Previous, Current, End, Total) :-
        Next is Current + Previous,
        fibonacci(Current, Next, End, Total).

divisible(Number, 0) :-
        write(‘Error: division by 0?).         
divisible(Number, Divisor) :-
        Number mod Divisor =:= 0.
Run Code Online (Sandbox Code Playgroud)