精华内容
下载资源
问答
  • 常用的编程语言有几种?目前主流的编程语言主要有以下几种,C/C++,Java,C#,PHP,Python,Javascript等等。Python:支持强制命令,面向对象和函数式的高级编程语言。C:这是通用的、跨平台、过程化、命令式的编程...

    很多刚刚进大学初学编程的同学很多都会有这个疑惑,虽然已经有很多文章已经提到了这个问题,但是今天我还是给大家一个答案,希望对那些想要学习编程的同学有所帮助。

    366a6116333dc0cc64b78c52e10e7918.png

    常用的编程语言有几种?

    目前主流的编程语言主要有以下几种,C/C++,Java,C#,PHP,Python,Javascript等等。

    Python:支持强制命令,面向对象和函数式的高级编程语言。

    C:这是通用的、跨平台、过程化、命令式的编程语言。C++和C#都是基于C发展而来的。

    C++:它是由高级语言和低级语言想结合,因此被认为是一个中级编程语言,支持过程化编程、广泛编程、面向对象编程和数据抽象的多样化语言。

    C#:C Sharp也是多样化的语言,支持命令式、泛型和面向对象编程。

    Java:这个大家都很熟悉了,它是通用计算机编程语言,并发,基于类,面向对象并专门针对尽可能少的依赖进行设计的。

    JavaScript:是一种动态类型、弱类型、基于原型的语言,内置支持类型。

    PHP:是一种普遍使用的脚本语言。它用来创建动态网页,同时也支持命令行接口。

    总结一下:以上就是我们比较常见的计算机编程语言了。无论是哪种语言的学习,都需要不断的更新自己的知识。

    51bb9bf64338b9b8a0d36767482aefb5.png

    怎么才能够快速入门?

    关于哪个语言好入门,我之前也回答过。这个问题大家都有不同的看法。只是大概说一下,最终楼主自己选择。编程入门,你可以从C开始,C语言是经典的结构化编程语言(有人说难有人说简单),C之后可以学C++、C#或者是java。

    除此之外,想要把编程学好,除了天赋,我觉得还有一点的重要性仅次于天赋,那就是不断的练习!不厌其烦的练习,不停的练习!因为编程本来就是应用性、实践性很强的学科门类,所以实践非常重要!另外想要成为一个优秀的、有能力程序员,做软件开发的话,就来学习C/C++吧!你如果感觉自学C/C++语言有困难的话,我本身是一个C/C++出身的程序员,我整理了一些学习C语言的视频在Q羣,大家有兴趣可以一起来学习,C/C++编程学习,--7.84,14和--31;33。不管你是转行还是找工作,大家都一起成长进步。

    6fbfd68be6459525f5d89d7955d601f9.png

    我认为一个优秀的程序员,也许你职业生涯最多用到冒泡排序,但我还是建议你应该认真学学算法;对每一个程序员我都建议你能够学好数据结构;如果你有更多的兴趣或者更多的精力,网络通信、Linux开发、工程导论这些课程你都要认真学学,才能有竞争力。

    最后希望你能够成功走上程序员这条路,加油!在这里的话,笔者奉上一份C/C++学习路线图,希望对大家有帮助!

    b24f4f84d1721457177ca62604e0c30e.png
    展开全文
  • 函数式编程到底具有哪些特点? 相对于传统的命令式语言,其优势在什么地方? 函数式编程如下几个特点: 1、 函数是第一类型。 函数像其它数据类型一样,可以被赋值,可以当做参数,也可以当做函数的...
    无论 python, ruby, 还是 erlang, lua, 这几个比较新锐的语言,都支持函数式编程。
    函数式编程到底具有哪些特点? 相对于传统的命令式语言,其优势在什么地方?

    函数式编程,有如下几个特点:

    1、 函数是第一类型。
    函数像其它数据类型一样,可以被赋值,可以当做参数,也可以当做函数的返回值。

    其实, C语言的函数,实质就是一种指针类型,因此我们可以说,C语言也是支持函数式编程的。

    2、 函数的执行结果,只与传入的参数相关。
    也就是说,只要传入的参数不变,那么函数的执行结果就是一定的,而不受其它条件影响。
    这就要求我们,在函数内部,不要访问全局变量。

    这点实质上是函数式编程的核心。

    这个用术语表示,叫做“引用透明性”

    3、 变量一旦被赋值,就永远不可修改。
    C 语言如何表示?

    4、 惰性计算
    将一个函数绑定到一个变量的时候,并不立刻计算; 而是在使用的时候才去计算。

    5、 闭包
    在其它函数内部定义的函数

    6、 高阶函数
    使用其它函数作为参数的函数,称为高阶函数

    7、 匿名函数 lambda
    展开全文
  • 终端查看命令有哪些功能命令 这段视频附带了这篇文章,没有它就不会太有意义 上个月,我在Curry On会议上做了演讲,该会议是与学术,编程语言会议ECOOP共同举办的新会议。 Curry On旨在弥合学术界之间的鸿沟。 我...

    终端查看命令有哪些功能命令

    上个月,我在Curry On会议上做了演讲,该会议是与学术,编程语言会议ECOOP共同举办的新会议。 Curry On旨在弥合学术界之间的鸿沟。 我的学术兴趣不包括编程语言,我认为编程语言是计算机科学的子学科,与其他任何学科相比,其始终被高估和交付不足(可能是AI除外)。 我对算法比对抽象更感兴趣,并且编程语言研究主要与后者有关。 但是,作为开发人员,我必须使用我选择使用的编程语言提供的抽象,而令我感到震惊的是,我注意到某些抽象从学术语言到主流的流行,在某些情况下使身体不好,主要引起疼痛。 举个例子,我想想一个事实,即Java中使用monad的人比Haskell中使用monad的人更多。

    在我的演讲中,我提出了命令式编程的核心抽象是阻塞线程。 一旦将其删除,您将失去大多数其他命令式抽象,例如控制流和异常处理(要求它们在库中重新实现),命令式语言带来的大多数优势包括事后调试,性能分析和自动背压。 这也使代码难以编写和阅读。 我声称,无论您是否使用monad减轻其痛苦,异步编程都是对命令式语言的厌恶。 异步与命令之间的不匹配是根本的。 一直以来,我们可以达到与monads一样强大的抽象(如果不是更多的话),这自然适合命令式语言,并与它们的结构和功能完美地结合在一起。

    如果您还没有的话,现在是观看演讲的好时机:

    在我的演讲中,我声称就像monads是纯函数式编程超级抽象一样,延续是命令式编程超级抽象,并且引入了一个抽象,我称之为“作用域延续”,这仅是带分隔符的延续 。一种特殊的酱料(我不知道这个概念是否在其他地方讨论过;如果有,我很想知道它的专有名称(请参阅文章末尾的附加内容))。

    由于我在演讲之前不久就想到了这个主意,因此在介绍范围内的延续时我并没有做好准备,并且由于此后我最近对该主题进行了更多考虑,因此我想继续讨论这个主意。 我提出了三点主张:

    1. 范围内的延续自然适合命令性代码
    2. 范围连续像单子一样强大
    3. 有范围的延续比单子更好

    我认为我为第1点提出了理由,因为范围内的延续使您可以保持命令式控制流,并且它们保留了堆栈上下文,这对于事后调试和性能分析至关重要。 当谈到#2时,我更加模糊,直觉地注意到了monad与续奏之间的联系,并提供了一些示例,但没有证明,而听众中的人则正确地要求我这样做。

    第一回合:连锁–定界延续vs.单声道

    演讲结束后,我与朱利安·阿尼Julian Arni )进行了交谈,后者向我展示了丹·皮波尼Dan Piponi)撰写的博客文章《所有单子的母亲》 有关Reddit的讨论 )使我想到了由Andrzej Filinski 11994年提出的证明 ,定界的连续性(在Filinski的论文中称为部分或可组合的连续性)可以表示任何单峰组合。 他说:

    我们表明,任何其单元和扩展操作可表示为纯功能术语的monad都可以通过“可组合的延续”嵌入按值调用语言中…

    …值得注意的是,monad对“不纯”函数式编程没有可比的影响。 可能的主要原因可能是……单子框架已经内置在渴望有效的功能性语言的语义核心中,因此无需明确表达。 语言(例如,可更新状态,异常或一流的延续)和语言外部(I / O,OS接口等)的“不纯净”构造都遵循一元法。 似乎唯一缺少的方面是程序员能够以与内置效果相同的便利性和自然性使用自己的,特定于应用程序的单子抽象(例如,不确定性或解析器)。

    ……在下文中,我们将展示……具有第一类延续性的语言……已经“单调完成”,因为任何以某种扭曲的单调风格表达的程序也可以直接编写。

    我没有遵循Filinski论文的必要背景,但是,如果我没记错的话,证明的困难源于以下事实:从单子形式到连续形式(他称为“直接样式”)的转换是不是单调函数或单调作曲者的简单数学映射(Haskell称之为bind ),而是需要对其源代码表示进行更深层次的转换。 但是,我将以一种有希望的方式介绍定界连续的具体实现方式,以期解释moand-continuation相似性背后的直觉。

    定界的延续捕获了调用堆栈的一部分。 它使我们暂停计算然后再恢复它。 让我们看一下Java中定界的延续API:

    public class Continuation<T> implements Runnable, Serializable, Cloneable {
       public Continuation(Callable<T> target) { ... }
       public T run() { ... }
       public boolean isDone() { ... }
       public T getResult() { ... }
    
       public static Continuation<?> suspend(Consumer<Continuation<?>> ccc) { ... }
    }

    suspend方法(类似于Scheme的shift )暂停当前的延续(假设我们正在内部运行),并调用(可选)提供的回调ccc (名称cccCalled with Current Continuation的首字母缩写,这是一种玩法)在Scheme的call-cc )。 run功能(对应于Scheme的reset )将执行继续,直到其暂停或终止。 因此,例如:

    class Foo {
        static int foo() {
           bar();
           bar();
           return 3;
        }
    
        static void bar() {
            System.out.println("Pausing...");
            Continuation.suspend(null);
        }
    
        public static void main(String[] args) {
            Continuation<Integer> c = new Continuation(Foo::foo);
            c.run(); // prints "Pausing..."
            c.run(); // prints "Pausing..."
            c.run();
            System.out.println(c.getResult()); // prints "3"
        }
    }

    因为suspend返回继续并将其传递给回调,所以我们可以扩展Continuation类并添加一些内部字段以产生ValuedContinuation

    public class ValuedContinuation<T, Out, In> extends Continuation<T> {
        private Out pauseOut;
        private In pauseIn;
        private RuntimeException pauseInException;
    
        public run(In in);
        public run(RuntimeException e);
        public Out getPauseValue() { ... }
    
        public static <Out, In> In pause(Out value) {...}
        public static      <In> In pause(Consumer<ValuedContinuation<?, ?, In>> ccc) {...}
        public static   <V, In> In pause(V x, BiConsumer<V, ValuedContinuation<?, ?, In>> ccc) {...}
    }

    ValuedContinutation ,我们可以将值传入和传出延续。 如果我们调用pause(3) ,则getPauseValue将返回值3 ,而如果使用run(5)恢复继续,则将由pause返回值5 run(new RuntimeException())将导致pause以引发该异常。 例如:

    ValuedContinuation<Void, Integer, Integer> c = new ValuedContinuation<>(() -> {
                int x = pause(5);
                x = pause(x + 10);
                x = pause(x * 100);
                return null;
            });
    
    while(!c.isDone()) {
       c.run(3);
       System.out.println(c.getPauseValue()); // prints: 5, 13, 300
    }

    现在我们可以理解连续性可以表示任何monad的主张的直觉: 我们的monadic作曲者 (或bind将是传递给pause的回调ccc 每次pause的代码是c.run(x)序列中的下一个monadic函数,并且调用c.run(x)正在应用链中的下一个c.run(x)函数。

    不同的是,一元函数蹦床回到封闭作曲家(绑定),而在这里我们所说的作曲家(我们的ccc我们延续 )。 正如我在演讲中所声称的,命令式语言的延续是命令式语言与所有命令式概念(例如命令式控制流和异常)之间的良好交互,并且保留了对于调试和性能分析非常重要的堆栈上下文。

    在继续之前,让我们看一个使用ccc回调的示例。 它是延续形式的“未来单子”的一个示例。 假设我们有一个异步服务:

    interface AsyncHandler<T> {
        void success(T result);
        void failure(RuntimeException error);
    }
    
    interface AsyncService<T> {
        void submit(AsyncHandler<T> callback);  
    }

    然后,我们可以定义此方法:

    static <T> Consumer<ValuedContinuation<?, ?, T>> await(AsyncService<T> service) {
        return c -> {
            service.submit(new AsyncHandler<T>() {
                  public void success(T result) {
                       c.run(result);
                  }
    
                  public void failure(RuntimeException error) {
                       c.run(error);
                  }
              });
        };
    }

    我们将在延续中运行的代码中使用该代码,如下所示:

    String y = pause(await(service));

    上面的代码将暂停继续,直到服务请求完成,然后将其恢复为结果。

    第二轮:作曲–范围延续与Monad变形金刚

    在演讲中,我还声称即使在纯功能语言中,monad也很难编写2 ,这非常适合monads。 编写monad(即编写使用异常 IO 产生序列的monadic代码)需要使用monad转换器 ,因为它们利用非常高阶的函数来形成一个让人脑筋急转的Lambdish间接函数 ,因此很难理解。

    为了创建易于组合的延续,在我的演讲中,我介绍了作用域延续 ,这是带分隔符的延续的变体。 范围内的延续是嵌套的延续,在任何级别,代码都可以自由地暂停其任何包含的延续。 这个想法与嵌套的try / catch块非常相似,在嵌套的try / catch块中,根据异常类型,执行将跳转到相应嵌套范围的catch块。

    为了测试该想法在实践中的效果如何,我已经在Java和Clojure中实现了一个有范围的延续原型。 您可以分别 Quasar和Pulsar的cont分支( 此处此处)中使用作用域延续来查找代码。

    为了实现延续,我使用了Quasar的工具,该工具非常简单(尽管有范围的延续可能有一天会进入上游Quasar,但这种情况不会很快发生,因为我们首先需要使工具完全透明且可以不使用,我们希望Java 9发布时该怎么做)。 困难的部分是支持在嵌套连续引用不仅存在于堆栈中,而且还可能存在于堆中的环境中克隆嵌套的延续(下面介绍的非确定性延续所需要)。 我尝试了三种不同的方法,但我对其中任何一种都不满意。

    对于范围连续,我们需要稍微更改Continuation (和类似ValuedContinuation )类:

    public class Continuation<S extends Suspend, T> implements Runnable, Serializable, Cloneable {
       public Continuation(Class<S> scope, Callable<T> target) { ... } // <-- scope
       public T run() { ... }
       public boolean isDone() { ... }
       public T getResult() { ... }
    
       public static Continuation<?> suspend(S scope, Consumer<Continuation<?>> ccc) { ... } // <-- scope
    }

    范围是全局名称。 在Java中,我选择代表范围,就像表示异常范围一样:作为类名(在当前实现中,范围是扩展Suspend类, Suspend是一种异常类型)。

    范围的延续定义和使用方式如下:

    class ACont<T> extends ValuedContinuation<AScope, T> {
        public Continuation(Callable<T> target) {
            super(AScope.class);
            // ...
        }
    
        public static AScope A = new AScope();
    }
    
    // similarly BCont, and then:
    
    static void foo() {
        Continuation<Void> c = new ACont(() -> {
            // ...
            Continuation<Void> c = new BCont(() -> {
                // ...
                suspend(B, ...); // suspends the enclosing BCont
                // ...
                suspend(A, ...); // suspends the enclosing ACont
                // ...
            });
            // ...
        });
        // ...
    }

    在Clojure中,范围是全局符号,并且可以将范围的延续定义为:

    (let 
                       ; ....
                       (let 
                                          ; ....
                                          (pause B ...)
                                          ; ...
                                          (pause A ...)
                                          ; ...
                                          ))])))]
        ; ...
    )

    范围延续的概念是,暂停任何封闭的延续范围相当于返回到任何封闭的作曲家(绑定)的单子函数。 但是在范围连续的情况下,我们不需要monad转换器来转换作曲者或链接的monadic函数。

    为了了解这种组合在实际代码中的外观,我实现了两种延续类型: CoIterable (与Python生成器一样,生成具有延续的Iterable并对应于Haskell的list monad)和Ambiguity (实现了不确定性计算)回溯a-la Scheme的amb并对应于Haskell的amb monad。

    孤立地, CoIterable的用法如下:

    Iterable<Integer> range(int from, int to) {
        return new CoIterable<>(() -> {
            for (int i = from; i < to; i++)
                produce(i);
        });
    }

    有关CoIterable运算符的示例,例如flatmapmapfilter请参见此处 ,并请注意,额外的灵活性延续给了我们单子。 由于单子函数将蹦床返回给作曲者,因此必须根据单个平面映射作曲者来实现filtermap操作,而对于延续,我们可以自由地从延续中选择自己的构图规则,并且可以实现filter并独立于flatMap进行map ,以获得更好的性能。

    这是隔离中使用Ambiguity的示例:

    Ambiguity<Integer> amb = solve(() -> {
            int a = amb(1, 2, 3); // a is either 1, 2, or 3
            int b = amb(2, 3, 4); // b is either 2, 3, or 4
    
            assertThat(b < a);    // ... but we know that b < a
            return b;
        });
    
    amb.run(); // returns 2 as that's the only possible solution for b

    现在,让我们看看两者是如何无缝组合的:

    Ambiguity<Integer> amb = solve(() -> {
        Iterable<Integer> a = iterable(() -> {
            produce(amb(2, 1)); // pauses on Ambiguity and CoIterable
            produce(amb(3, 10));
        });
    
        int sum = 0;
        for (int x : a) { // using imperative loops on purpose; functional would work, too
            sum += x;
            assertThat(x % 2 == 0); // we assert that all elements are even
        }
    
        return sum;
    });
    
    amb.run(); // returns 12

    注意如何a延续中止既对Ambiguity以及对CoIterable范围。 它创建一个列表,其第一个元素为21 ,其第二个元素为310 ,产生四个可能的列表: (2, 3)(2, 10)(1, 3)(1, 10) 后来,我们断言所有元件必须是偶数,这意味着对于唯一有效的列表a(2, 10)以及用于唯一可能的值sum是12。

    作为最后一个示例(可以在此处此处的测试中找到更多示例;可以在此处找到Clojure示例),让我们通过另一层嵌套将事情进一步复杂化:

    Fiber<Integer> f = new Fiber<>(() -> {
        Ambiguity<Integer> amb = solve(() -> {
            Iterable<Integer> a = iterable(() -> {
                produce(amb(2, 1));
                sleep(20); // pauses on the Fiber scope
                produce(amb(3, 10));
            });
    
            int sum = 0;
            for (int x : a) {
                sum += x;
                Fiber.sleep(20);
                assertThat(x % 2 == 0);
            }
            return sum;
        });
    
        return amb.run();
    }).start();
    
    f.get(); // returns 12

    现在,我们将整个内容嵌套在光纤中-Quasar的轻量级线程实现-仅仅是Java的ForkJoin调度程序调度的延续而已。 现在,内嵌套代码a在三个不同范围内暂停没有打破汗水,没有任何形式的变压器。

    但是类型安全呢?

    Haskell具有非常丰富的类型系统,而Monad可以极大地发挥作用。 通过查看(monadic)函数的签名,您可以立即知道它可以“驻留”在哪种monad类型中,并且不能在该monad之外的任何地方使用它。 事实证明,可以在不失去其任何期望属性的情况下,对作用域延续进行安全类型化。 为此,我们需要一个(简单的)类型系统来声明:

    void foo() suspends A, B

    这意味着foo可能会在AB范围内暂停延续,因此只能在两个范围内的代码中调用。 然后,将Continuation类定义为(在伪Java中):

    public class Continuation<S extends Suspend, T> implements Runnable, Serializable, Cloneable {
       public Continuation(Class<S> scope, [Callable<T> suspends S|Others] target) { ... }
       public T run() suspends Others { ... }
    
       public static Continuation<?> suspend(S scope, Consumer<Continuation<?>> ccc) suspends S
    }

    因此,延续可以运行任何可能在参数化S范围以及其他范围上可能挂起的目标代码,而run方法可以吞咽S范围,但仍在挂起其他范围。

    事实证明,我们已经有了这样的类型系统- 几乎是 Java的检查异常。 如果我们创建了Suspend范围(所有范围都从该范围下降),则可以像上面的伪Java中的suspend一样使用Java的throws 我之所以没有这样做,是因为Java的类型系统不允许您捕获多个经过检查的异常类型,就像我在上述“ Others所做的那样,这意味着我们需要显式的实例来处理显式的范围变量(挂起一个范围的函数,两个范围等),这可能会使事情变得麻烦。

    然后,我们还可以通过参数化范围来提高ValuedContinuation的类型安全性,这样我们就可以:

    void foo() suspends CoIterableScope<Integer>

    这只会让foo在产生一个Integer序列(而不是String )的CoIterable中被调用。 不幸的是,我们也不能完全做到这一点,因为Java当前不允许泛型异常类型。

    未完待续?

    我希望通过更深入地讨论范围内的连续性,我能够比我在演讲中挥舞过的挥手更好地解释这个想法,并且我很高兴找到Filinski的证明(这在PL圈子中可能是众所周知的) )。

    我希望我的讲话使您相信单语在命令式语言中没有地位(也许除了并行计算之外),如果没有,我很想听听为什么不这样做。 我还相信,即使在PFP语言中,范围连续的合成也比monad更好(而且,monad通常不是一种很好的效果建模方法,但这是另外一个讨论)。

    最后,虽然我坚信命令性语言应该具有某种形式的轻量级线程(AKA光纤,AKA用户模式线程,AKA绿线程排序)和线程(任何类型)不过是由适当的调度程序调度的延续,我不一定认为命令式语言应该直接将范围化的延续公开为抽象。 毕竟,存在抽象以增加代码重用性,帮助代码维护和帮助验证:总之,它们存在以降低开发成本,并且(至少从非研究的角度来看)它们是唯一的度量标准判断3 我认为延续性是PFP优雅的monad的优雅命令,但是我还不相信它们在实践中的作用。

    如果您想了解更多有关延续的知识,那么这就是延续发展历史,它使所有合适的人都受惠。

    附录1

    自从首次发布此博客文章以来,我设法在Philip Wadler1993年发表的一篇论文中找到了关于范围延续的参考,该论文称为Monads and composablecontinuations ,他将范围延续简单地称为“具有多个层次的可组合延续”。 正如Wadler显示定界延续可由monad表示,而Filinsky显示(一年后)monad可表现为定界延续,这有理由推论两者是对偶的。 尽管如此,有理由认为,即使是对偶,每种也都更适合于特定的编程风格,并且毫无疑问,延续更适合于不纯洁的按值调用的语言(命令式和函数式命令式)。 瓦德勒在总结论文时说:

    具有多个层次的可组合延续的一个目标是能够将不同的影响分解为不同的层次。 Danvy和Filinski声称以这种方式将各种效果均匀地组合起来相对容易。 Monads还旨在通过简化组合的方式来分解效果。 但是,没有统一的规则来组合任何两个单子。 本文使用了monad来阐明可组合的延续。 可组合的延续词会阐明单子组合的问题吗?

    附录2

    在网上讨论中,一位读者评论说,我通过谈论单子而不是单子来误解了单子。 我认为这仅是解释上的区别,因此我想澄清一下:

    正如已经证明的(我认为),任何效果都可以由单子模拟,您可以说所有效果都是单子的,但是就像著名笑话中的数学家一样,这是绝对正确的,但绝对没有用(取决于您的观点)。 -视图,我猜)。

    从数学的角度来看,只要两件事同构,它们就是“相同”的。 但是从编程的角度来看,两者可能是非常不同的,因为抽象是与程序员思想上的心理交互,而两个同构的数学概念在心理上与程序员之间的交互也非常不同。 因此,如果在处理抽象时我不必“思考单子”,那么即使它们之间存在同构,抽象也不是单子。

    根据数学解释,“反对单子”与反对数字1一样荒谬。在我的解释中,用阿拉伯数字,教堂数字或集合论数字表示数字1在心理上有很大不同,并且因此,在编程语言上有本质的不同,因为编程语言首先是人类语言的一种。 在编程语言中,抽象是通过数学以及心理(或经济)特性来定义(和测量)的。

    我是一个“算法论者”,而不是一个“抽象论者”(不幸的是,我认为这两个CS观点常常是矛盾的),因此我仅在抽象化在编写和维护方面带来的成本变化方面衡量其有用性我的算法,对我来说,单子是一种设计模式,而不是以某种特定符号表示的数学对象。

    1. 然后我发现这篇文章说,Filinski的证明并不扩展到利用懒惰(按名字呼叫)评估的单子
    2. 例如,尝试使用CompletableFutures组成Java流。 这并不容易。
    3. 请参阅此HN关于该主题的讨论

    翻译自: https://www.javacodegeeks.com/2015/08/from-imperative-to-pure-functional-and-back-again-monads-vs-scoped-continuations.html

    终端查看命令有哪些功能命令

    展开全文
  • paip.函数式编程方法概述以及总结 1 函数式编程:函数式风格..很多命令式语言里支持函数式...函数式编程语言有哪些... 3 2 命令式语言(java,c#,php等)里使用函数式编程风格... 3 3 函数式编程 应用场...

    paip.函数式编程方法概述以及总结

     

     

    1     函数式编程:函数式风格..很多命令式语言里支持函数式编程风格... 1

    1.1      起源 (图灵机,Lisp机器, 神经网络计算机)2

    1.2      函数式编程语言有哪些... 3

    2     命令式语言(java,c#,php等)里使用函数式编程风格... 3

    3     函数式编程 应用场合... 3

    4     函数式编程的特点... 4

    4.1      函数是函数式编程的基本单位... 4

    4.2      保存状态... 4

    4.3      函数式编程的抽象本质... 4

    4.4      -----结果比步骤更重要... 4

    4.5      ----少量数据结构,大量操作... 5

    4.6      种数据驱动型的编程语言:... 5

    4.7      ----函数式编程特点(高阶函数)5

    4.8      传递行为,而不仅仅是传值... 6

    4.9      闭包, 消息... 6

    4.10        内部循环和外部循环... 7

    4.11     10. 函数式编程和递归... 8

    4.12    2. 惰性求值与并行... 9

    4.13    11.  尾递归,伪递归... 9

    4.14        可读性 oop vs fp. 10

    5     优点... 10

    5.1      (多核并行)10

    5.2      代码热部署... 10

    5.3      机器辅助的推理和优化... 11

    5.4      提高代码可读性... 11

    6     缺点... 11

    7     参考... 11

     

    作者Attilax 艾龙,  EMAIL:1466519819@qq.com
    来源:attilax的专栏
    地址:http://blog.csdn.net/attila

     

    1      函数式编程:函数式风格.. 很多命令式语言里支持函数式编程风格

     

    于函数编程(functionalprogramming——FP)

    函数式编程(英语:Functionalprogramming)或者函数程序设计,又称泛函编程,是一种编程范型,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。函数编程语言最重要的基础是λ演算(lambda calculus)。而且λ演算的函数可以接受函数当作输入(引数)和输出(传出值)。

     

    函数式编程是种编程典范,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ 演算(lambda calculus)。而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。和指令式编程相比,函数式编程强调函数的计算比指令的执行重要。和过程化编程相比,函数式编程里,函数的计算可随时调用。

     

    迭代。命令式编程利用迭代来处理许多不同类型的数据结构。许多命令式控制依赖破坏性赋值进行迭代。

     

     除了了构造函数之外,不再提供任何的可变方法。

    你不仅要避免典型的受JavaBeans启发的setXXX方法,还必须注意不要返回可变的对象引用。对象引用被声明成final的,这是实情,但这并不意味这你不能改变它所指向的内容。因此,你需要确保你是防御性地拷贝了从getXXX方法中返回的任何对象引用。

     

     

     

     

     

    1.1  起源 (图灵机,Lisp机器, 神经网络计算机)

    冯·诺曼架构就是你每天都用的计算机的架构的标准:一个CPU,内存,硬盘,一条总线。多核计算机并没有带来本质上的变化。冯·诺曼机是一个很方便,很便宜,上世纪五十年代的实现图灵机的技术,图灵机是执行计算的最知名的抽象模型。

     

    世 上还有其他的计算的机器。比如,Lisp机器,是上世纪50年代对Lisp计算模型的实现。Lisp模型是基于lambda代数的一种计算语言表示法,后 者是与图灵机同构的一种模型。不像图灵机,lambda代数能被人类读和写。但是这二者是同等能力的。它们同样精确的表示了计算机能干什么。

     

    了。还有一些其他的计算机,比如神经网络计算机,译者也不知道怎么翻的计算机(cellular automata),但是这些都不够大众化,至少现在是这样的。

     

     

    1.2  函数式编程语言有哪些

    Haskell,Erlang,还是Scala,F#,都    APL    XSLT Erlang  这些年来,广大程序员都忽视了JavaScript也是一门动态类型语言,还是一门函数语言!

     

    2       命令式语言(java,c#,php等)里使用函数式编程风格

    很多命令式语言里支持函数式编程风格。换句话说,它不是函数式编程语言的专利(尽管它们更适合)。我们应该清楚的区分这两个概念,从而避免对函数式编程语言和命令式编程语言之间的不同产生混淆。

     

    ,命令式编程这个名字是从自然语言(比如英语)的 祈使语气(imperative mood)衍生出来的,在这种语气中宣布命令并按照执行 函数编程是一种强调表达式的计算而非命令的执行的一种编程风格。表达式是用函数结合基本值构成的,它类似于用参数调用函数。

    3      函数式编程应用场合

    我们看完了函数式编程的特点,我们想想函数式编程的应用场合。

    1. 数学推理

    2. 并行程序

    3.热部署:这点其实许多脚本语言也能热部署,但是脚本性能底下.

    那么我们总体地说,其实函数式编程最适合地还是解决局部性的数学小问题,要让函数式编程来做CRUD,来做我们传统的逻辑性很强的Web编程,就有些免为其难了。

     

    4      函数式编程的特点

    4.1  函数是函数式编程的基本单位

    ,所以函数式编程主要处理计算,并惊人地用函数来完成这一过程。函数是函数式编程的基本单位,函数几乎被用于一切,包括

    最简单的计算,甚至变量都由计算取代。在函数式编程中,变量只是表达式的别名(这样我们就不必把所有东西打在一行里)。变量是不能更改的,所有变量只能被

    赋值一次

     

    4.2  保存状态

    函数式程序能保存状态,只是它并非通过变量而是使用函数来保存状态。状态保存在函数的参数中,保存在堆栈上。如果你要保存某个状态一段时间并

     

    4.3  函数式编程的抽象本质

    相信每个程序员都对抽象这个概念不陌生。

    在面向对象编程中,我们说,类是现实事物的一种抽象表示。那么抽象的最大作用在我看来就在于抽象事物的重用性,一个事物越具体,那么他的可重用性就越低,因此,我们再打造可重用性代码,类,类库时,其实在做的本质工作就在于提高代码的抽象性。而再往大了说开来,程序员做的工作,就是把一系列过程抽象开来,反映成一个通用过程,然后用代码表示出来。

    在面向对象中,我们把事物抽象。而在函数式编程中,我们则是在将函数方法抽象,第六节的滤波器已经让我们知道,函数一样是可重用,可置换的抽象单位。

    那么我们说函数式编程的抽象本质则是将函数也作为一个抽象单位,而反映成代码形式,则是高阶函数

    4.4  -----结果比步骤更重要

    函数式编程的特点之一是存在强大的抽象,它隐藏了许多日常操作的细节(比如迭代)。

     

    4.5  ----少量数据结构,大量操作

    在面向对象的命令式编程语言中,重用的单元是类以及与这些类进行通信的消息,这些信息是在类图中捕获的。该领域的开创性著作是 Design Patterns: Elements of Reusable Object-Oriented Software(参阅 参考资料),至少为每个模式提供一个类图。在 OOP 的世界中,鼓励开发人员创建独特的数据结构,以方法的形式附加特定的操作。函数式编程语言尝试采用不同的方式来实现重用。它们更喜欢一些关键的数据结构(如列表、集和映射),并且在这些数据结构上采用高度优化的操作。传递数据结构和高阶函数,以便“插入” 这种机制,针对某一特定用途对其进行定制。例如,在清单 2 中,findAll() 方法接受使用一个代码块作为“插件” 高阶函数(该函数确定了筛选条件),而该机制以有效方式应用了筛选条件,并返回经过筛选的列表。

     

    4.6  种数据驱动型的编程语言:

    一条指令的运算结果又流向下一条指令,作为下一条指令的操作数来驱动此指令的启动执行;(管道的思想)

    能充分地利用程序中指令级并行性;

    不存在共享数据,也不存在指令计数器,指令启动执行的时机仅取决于操作数具备与否

     

    只要有足够多的处理单元,凡是相互间不存在数据相关的指令都可以并行执行。因此,函数式语言的这种数据驱动的编程思想使得它们的语言在并行处理方面具有与生俱来的优势。

    4.7  ----函数式编程特点(高阶函数)

     

    在面向对象编程中,我们把对象传来传去,那在函数式编程中,我们要做的是把函数传来传去,而这个,说成术语,我们把他叫做高阶函数

     

    数学计算机科学中,高阶函数是至少满足下列一个条件的函数:

    • 接受一个或多个函数作为输入
    • 输出一个函数

    在函数式编程中,函数是基本单位,是第一型,他几乎被用作一切,包括最简单的计算,甚至连变量都被计算所取代。在函数式编程中,变量只是一个名称,而不是一个存储单元,这是函数式编程与传统的命令式编程最典型的不同之处。

     

    函数编程支持函数作为第一类对象,有时称为闭包或者仿函数(functor)对象。实质上,闭包是起函数的作用并可以像对象一样操作的对象。与此类似,FP 语言支持高阶函数。高阶函数可以用另一个函数(间接地,用一个表达式)作为其输入参数,在某些情况下,它甚至返回一个函数作为其输出参数。这两种结构结合在一起使得可以用优雅的方式进行模块化编程,这是使用 FP 的最大好处。

     

    4.8   ///传递行为,而不仅仅是传值

    你可以把一个函数看做是一组指令,也就是说,你可以把一组指令告诉另一个函数。想想在很多其他编程语言里面,它只允许你把一些数据告诉另一个函数。举

     

    如果你使用C#有一段时间的话,那么你很可能已经明白这个标题的意思了。在C#中,经常看到一些函数的参数是Action或者Func类型,比如下面这个:

     

     

    这是java在解决函数式编程,引入lambda表达式的同时引入的一个概念,具体的意思就是,定义的一个接口,接口里面必须有且只有一个方法,这样的接口就成为函数式接口。在可以使用lambda表达式的地方,方法声明时必须包含一个函数式的接口。任何函数式接口都可以使用lambda表达式替换。 下面来看lambda的基本逻辑:

     

    button.onAction(newEventHandler<ActionEvent>() {

       @Override

       public void handle(ActionEvent e) {

           doSomethingWith(e);

        }

    });

    4.9  闭包, 消息

     

    闭包, 消息

     Runnable worker = new Runnable() 
     { 
      public void run() 
      { 
        parseData(); 
      } 
     };

    方法 parseData确实封闭(因而有了名字 “闭包”)在 Runnable对象的实例 worker中。它可以像数据一样在方法之间传递,并可以在任何时间通过发送消息(称为run)给 worker对象而执行

    创建闭包

    广意地说,有两种生成闭包的技术,使用闭包的代码可以等效地使用这两种技术。创建闭包后,可以以统一的方式传递它,也可以向它发送消息以让它执行其封装的逻辑。因此,技术的选择是偏好的问题,在某些情况下也与环境有关

    在第一种技术 表达式特化(expressionspecialization)中,由基础设施为闭包提供一个一般性的接口,通过编写这个接口的特定实现创建具体的闭包。在第二种技术 表达式合成(expression composition)中,基础设施提供实现了基本一元 / 二元 / 三元 /.../n 元操作(比如一元操作符 not和二元操作符 and/ or)的具体帮助类。在这里,新的闭包由这些基本构建块的任意组合创建而成。

    Apache Functor Java 语言中的函数编程.htm

     

     

    4.10    / 内部循环和外部循环

    外循环、内循环和Map、Reduce、Filter

       一直到现在,处理Java集合的标准做法是采用外循环。

       顺序处理(sequential handling)。顺序特性也常常引发ConcurrentModificationException

     

    先看一个大家耳熟能详的例子:

     

       List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); 

        

       for (int number : numbers) { 

           System.out.println(number); 

        }

     

    是不是很常见呢?这个叫外部循环(External Iteration)。但是外部循环有什么问题呢?简单来说存在下面三个缺点:

     

    1.只能顺序处理List中的元素(processone by one)

     

    2.不能充分利用多核CPU

     

    3.不利于编译器优化

     

    而如果利用内部循环,代码写成下面这样:

     

       List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); 

        

       numbers.forEach((Integer value) -> System.out.println(value));

          

          

           这样就能规避上面的三个问题:

     

    1.不一定需要顺序处理List中的元素,顺序可以不确定

     

    2.可以并行处理,充分利用多核CPU的优势

     

    3.有利于JIT编译器对代码进行优化

     

    类似的C#从4.0版本开始也支持集合元素并行处理,代码如下:

     

       List<int> nums = new List<int> { 1, 2, 3, 4, 5, 6 }; 

        Parallel.ForEach(nums,(value) => 

       { 

          Console.WriteLine(value); 

       });

          

          

     

    4.11       10. 函数式编程和递归

    和命令式编程相比,函数式编程强调程序的执行结果比执行过程更重要,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程

    递归是函数式编程的一个重要的概念,循环可以没有,但是递归对于函数式编程却是不可或缺的。

    在这里,我得承认,我确实不知道我该怎么解释递归为什么对函数式编程那么重要。我能想到的只是递归充分地发挥了函数的威力,也解决了函数式编程无状态的问题。(如果大家有其他的意见,请赐教)

    递归其实就是将大问题无限地分解,直到问题足够小。

    而递归与循环在编程模型和思维模型上最大的区别则在于:

    循环是在描述我们该如何地去解决问题。

    递归是在描述这个问题的定义

    这里则是在描述我们该如何求解斐波那契数列,应该先怎么样再怎么样。

    而我们明显可以看到,递归相比于循环,具有着更加良好的可读性。

    但是,我们也不能忽略,递归而产生的StackOverflow,而赋值模型呢?我们懂的,函数式编程不能赋值,那么怎么办

    4.12   2. 惰性求值与并行

    第一次接触到惰性求值这个概念应该是在Haskell语言中,看一个最简单的惰性求值,我觉得也是最经典的例子:

    在Haskell里,有个repeat关键字,他的作用是返回一个无限长的List,那么我们来看下:

    take 10 (repeat 1)  

    就是这句代码,如果没有了惰性求值,我想这个进程一定会死在那里,可是结果却是很正常,返回了长度为10的List,List里的值都是1。这就是惰性求值的典型案例。

    我们看这样一段简单的代码:

    def getResult():
        a = getA()   //Take a long time
        b = getB()   //Take a long time
        c = a + b

    这段代码本身很简单,在命令式程序设计中,编译器(或解释器)会做的就是逐一解释代码,按顺序求出a和b的值,然后再求出c。

    可是我们从并行的角度考虑,求a的值是不是可以和求b的值并行呢?也就是说,直到执行到a+b的时候我们编译器才意识到a和b直到现在才需要,那么我们双核处理器就自然去发挥去最大的功效去计算了呢!

    这才是惰性求值的最大威力

    4.13   11.  尾递归,伪递归

    我们之前说到了递归和循环各自的问题,那怎么来解决这个问题,函数式编程为我们抛出了答案,尾递归。

    什么是尾递归,用最通俗的话说:就是在最后一部单纯地去调用递归函数,这里我们要注意“单纯”这个字眼。

    那么我们说下尾递归的原理,其实尾递归就是不要保持当前递归函数的状态,而把需要保持的东西全部用参数给传到下一个函数里,这样就可以自动清空本次调用的栈空间。这样的话,占用的栈空间就是常数阶的了。

    在看尾递归代码之前,我们还是先来明确一下递归的分类,我们将递归分成“树形递归”和“尾递归”,什么是树形递归,就是把计算过程逐一展开,最后形成的是一棵树状的结构

    4.14   可读性 oop vs fp

    面向对象的编程通过封装可变动的部分来构造出可让人读懂的代码,函数式编程则是通过最小化可变动的部分来构造出可让人读懂的代码。

     

    5      优点

    5.1    (核并行)

    核并行程序设计就这样被推到了前线,而命令式编程天生的缺陷却使并行编程模型变得非常复杂,无论是信号量,还是锁的概念,都使程序员不堪其重。

    函数式程序无需任何修改即可并行执行。不用担心死锁和临界区,因为你从未用锁!函数式程序里没有任何数据被同一线程修改两次,更不用说两个不同的线程了。这意味着可以不假思索地简单增加线程而不会引发折磨着并行应用程序的传统问题。

     

    5.2  代码热部署

     

    理想的情况是完全不停止系统任何组件来更新相关的代码。在命令式的世界里这是不可能的。考虑运行时上载一个Java类并重载一个新的定义,那么所有

    这个类的实例都将不可用,因为它们被保存的状态丢失了。我们可以着手写些繁琐的版本控制代码来解决这个问题,然后将这个类的所有实例序列化,再销毁这些实

    例,继而用这个类新的定义来重新创建这些实例,然后载入先前被序列化的数据并希望载入代码可以恰到地将这些数据移植到新的实例。在此之上,每次更新都要重

    新手动编写这些用来移植的代码,而且要相当谨慎地防止破坏对象间的相互关系。理论简单,但实践可不容易。

    对函数式的程序,所有的状态即传递给函数的参数都被保存在了堆栈上,这使的热部署轻而易举!实际上,所有我们需要做的就是对工作中的代码和新版本的

    代码做一个差异比较,然后部署新代码。其他的工作将由一个语言工具自动完成!如果你认为这是个科幻故事,请再思考一下。多年来

    Erlang工程师一直更新着他们的运转着的系统,而无需中断它

     

    5.3  机器辅助的推理和优化

    函数式语言的一个有趣的属性就是他们可以用数学方式推理。因为一种函数式语言只是一个形式系统的实现,所有在纸上完成的运算都可以应用于用这种语言书写的程序。编译器可以用数学理论将转换一段代码转换为等价的但却更高效的代码[7]。多年来关系数据库一直在进行着这类优化

     

    5.4  提高代码可读性

    特别是解决了重复命名变量的问题。

    6      缺点

    F#也许终将成为程序核心数据多线程处理的首选,而C#与VB等将在用户界面交互设计方面继续发挥其强大的潜力。但C# 依然是.NET 的主流设计语言。

    7      参考

    函数式编程扫盲篇 - 飞林沙 - 博客园.htm

     

    函数式编程的优点 -rxr1st的专栏 - 博客频道 - CSDN.NET.htm

    转载于:https://www.cnblogs.com/attilax/p/5964090.html

    展开全文
  • 虽然它是作为开发Web页面的脚本语言而出名的,但是它也被用到了很多非浏览器环境中,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如函数式编程)风格。 现在我们来看看...
  • JavaScript是一种多范式语言,支持事件驱动,功能和命令式(包括面向对象和基于原型的)编程样式。JavaScript最初仅用于客户端。但是,如今,JavaScript也被用作服务器端编程语言。总而言之,用一个简单的句子来说-...
  • Python入门你要懂哪些?

    2020-01-16 19:59:35
    Python作为为数不多的全场景开发语言之一,近年来已经获得了...Python定义:是一个免费、开源、跨平台、动态、面向对象的编程语言。 Python程序的执行(运行)方式两种:交互、文件。 交互 即在命令...
  • Python编程入门经典

    热门讨论 2013-10-27 14:17:39
    10.4.2 选择导出哪些内容 154 10.4.3 为模块建立文档 155 10.4.4 测试模块 164 10.4.5 将模块作为程序运行 165 10.5 创建一个完整的模块 166 10.6 安装模块 171 10.7 本章小结 174 10.8 习题 175 第11章 文本处理 ...
  • 第一章 用一个入门的例子讲什么是DSL,DSL包含哪些部分,有哪些分类,书摘如下: 1. 我们常常会看到这样一种划分:一...2. “声明式”是一个非常模糊的术语,但是它通常适应于所有远离了命令式编程的方式。...远离变
  • C#编程经验技巧宝典

    热门讨论 2008-06-01 08:59:33
    10 <br>0023 如何添加引用第3方控件 11 <br>0024 如何生成DLL文件 11 <br>0025 如何使用不安全代码 11 <br>第2章 语言基础 13 <br>2.1 注释 14 <br>0026 如何对代码进行注释 14 ...
  • 中文版Excel.2007高级VBA编程宝典 1/2

    热门讨论 2012-04-06 16:00:16
     9.2.1 通过“运行子过程/用户窗体”命令执行过程  9.2.2 从“宏”对话框执行过程  9.2.3 用Ctrl 快捷键组合执行过程  9.2.4 从功能区执行过程  9.2.5 从自定义快捷菜单中执行过程  9.2.6 从另一个过程执行...
  • Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐) 基本信息 原书名: Pro Oracle SQL 原出版社: Apress 作者: (美)Karen Morton Kerry Osborne Robyn Sands Riyaj Shamsudeen Jared Still 译者: 朱...
  • CruiseYoung提供的带详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 该资料是《Oracle SQL高级编程》的源代码 对应的书籍资料见: Oracle SQL高级编程(资深Oracle专家力作,...
  • 除本书外,还著广受好评的《Oracle专家高级编程》和《Oracle高效设计》。 作者: Thomas Kyte  Thomas Kyte是Oracle公司核心技术集团的副总裁,从Oracle 7.0.9版本开始就一直任职于Oracle公司,不过,其实他从...
  • 如果你已经一个编程强项,而对各类的编程语言都了解,都熟悉那个领域了,那我想相对我来说你已经是个大高手了,我要像你学习。 但,其实,想让自己的技术进步都得自己去研究、多看书、多查资料的,没有人连端口都...
  • 2021年的第一份程序员书单:一月8本新书打卡

    千次阅读 多人点赞 2021-01-06 15:08:36
    2021年已经开启,在这一年里,你有哪些规划在设想中?总结写的怎么样?上一年的工作完成的怎么样?...Rust是一门系统编程语言,是支持函数式、命令式以及泛型等编程范式的多范式语言。Rust在语法上和C++..
  • Python作业

    2020-10-31 16:14:19
    5、 支持命令式编程 6、函数式编程 7、 面向对象编程 三、python的基本数据类型 标准数据类型:列表(List)、元组(Tuple)、集合(Set)、数字(Number)、字符串(String)、和字典(Dictionary); 1,数字
  • 内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的...
  • 在上一课中,我们已经了解了Python这门语言并安装了运行Python程序所需的环境,相信大家已经迫不及待的想开始自己的Python编程之旅了。首先我们来告诉大家在哪些地方可以写Python程序。 编写代码的工具 交互...
  • stackoverflow 上的程序员应该阅读的非编程类书籍有哪些? 中文版 github 上的一个流行的编程书籍索引 中文版 如果这个仓库对你有帮助,欢迎 star。如果这个仓库帮你提升了技能找到了工作,可以请我喝杯咖啡: ...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    程语言编程语言 程语言 C#.4 1.1 Microsoft.NET——一场新的革命.4 1.2 .NET 与 C#.6 1.3 C#语言的特点.8 1.4 小 结 .11 第二章 运行环境 全面了解.NET.12 2.1 .NET 结构.12 2.2 公用语言运行时环境...
  • C#微软培训资料

    2014-01-22 14:10:17
    程语言编程语言 程语言 C#.4 1.1 Microsoft.NET——一场新的革命.4 1.2 .NET 与 C#.6 1.3 C#语言的特点.8 1.4 小 结 .11 第二章 运行环境 全面了解.NET.12 2.1 .NET 结构.12 2.2 公用语言运行时环境...
  •  C++是在C语言基础上开发的一种集面向对象编程、通用编程和传统的过程化编程于一体的编程语言, 是C语言的超集。本书是根据2003年的ISO/ANSI C++标准编写的,通过大量短小精悍的程序详细而全面地阐 述了C++的基本...
  •  C++是在C语言基础上开发的一种集面向对象编程、通用编程和传统的过程化编程于一体的编程语言, 是C语言的超集。本书是根据2003年的ISO/ANSI C++标准编写的,通过大量短小精悍的程序详细而全面地阐 述了C++的基本...
  •  C++是在C语言基础上开发的一种集面向对象编程、通用编程和传统的过程化编程于一体的编程语言, 是C语言的超集。本书是根据2003年的ISO/ANSI C++标准编写的,通过大量短小精悍的程序详细而全面地阐 述了C++的基本...
  • WEB开发者应该有哪些必备的技能?.epub Web性能优化与HTTP-2.epub Web版Rss阅读器.epub WEB重构之道.epub Web项目开发规范文档.epub Werkzeug中文文档.epub XORM操作指南.epub Yet Another Scheme 入门教程.epub Yii...
  • WEB开发者应该有哪些必备的技能?.epub Web性能优化与HTTP-2.epub Web版Rss阅读器.epub WEB重构之道.epub Web项目开发规范文档.epub Werkzeug中文文档.epub XORM操作指南.epub Yet Another Scheme 入门教程.epub Yii...

空空如也

空空如也

1 2 3
收藏数 52
精华内容 20
关键字:

命令式编程语言有哪些