关于函数式编程:Y-分钟速成-Lambda-Calculus

Lambda 演算Lambda 演算(lambda calculus, -calculus), 最后由阿隆佐·邱奇(Alonzo Church)提出, 是世界上最小的编程语言. 只管没有数字, 字符串, 布尔或者任何非函数的数据类型, lambda 演算仍能够示意任何图灵机. Lambda 演算由三种元素组成: 变量(variables)、函数(functions)和利用(applications)。 最根本的函数为恒等函数: x.x, 它等价于f(x) = x. 第一个"x"为函数的参数, 第二个为函数体. 自在变量和束缚变量:在函数x.x中, “x"被称作束缚变量因为它同时呈现在函数体和函数参数中在x.y中, "y"被称作自在变量因为它没有被事后申明.求值:求值操作是通过-归约(-Reduction)实现的, 它实质上是词法层面上的替换. 当对表达式(x.x)a求值时, 咱们将函数体中所有呈现的"x"替换为"a” (x.x)a计算结果为: a(x.y)a计算结果为: y你甚至能够创立高阶函数: (x.(y.x))a计算结果为: y.a只管 lambda 演算传统上仅反对单个参数的函数, 但咱们能够通过一种叫作柯里化(Currying)的技巧创立多个参数的函数 (x.y.z.xyz)等价于f(x, y, z) = ((x y) z)有时xy.<body>与x.y.<body>能够调换应用 意识到传统的 lambda 演算没有数字, 字符或者任何非函数的数据类型很重要. 布尔逻辑:在 lambda 演算中没有"真"或"假". 甚至没有 1 或 0. 作为替换: T示意为: x.y.x F示意为: x.y.y 首先, 咱们能够定义一个"if"函数btf, 它当b为真时返回t, b为假时返回f IF等价于: b.t.f.b t f 通过IF, 咱们能够定义根本的布尔逻辑运算符: a AND b等价于: ab.IF a b F a OR b等价于: ab.IF a T b ...

November 23, 2022 · 2 min · jiezi

关于函数式编程:Y-分钟速成-Lambda-Calculus

Lambda 演算Lambda 演算(lambda calculus, -calculus), 最后由阿隆佐·邱奇(Alonzo Church)提出, 是世界上最小的编程语言. 只管没有数字, 字符串, 布尔或者任何非函数的数据类型, lambda 演算仍能够示意任何图灵机. Lambda 演算由三种元素组成: 变量(variables)、函数(functions)和利用(applications)。 最根本的函数为恒等函数: x.x, 它等价于f(x) = x. 第一个"x"为函数的参数, 第二个为函数体. 自在变量和束缚变量:在函数x.x中, “x"被称作束缚变量因为它同时呈现在函数体和函数参数中在x.y中, "y"被称作自在变量因为它没有被事后申明.求值:求值操作是通过-归约(-Reduction)实现的, 它实质上是词法层面上的替换. 当对表达式(x.x)a求值时, 咱们将函数体中所有呈现的"x"替换为"a” (x.x)a计算结果为: a(x.y)a计算结果为: y你甚至能够创立高阶函数: (x.(y.x))a计算结果为: y.a只管 lambda 演算传统上仅反对单个参数的函数, 但咱们能够通过一种叫作柯里化(Currying)的技巧创立多个参数的函数 (x.y.z.xyz)等价于f(x, y, z) = ((x y) z)有时xy.<body>与x.y.<body>能够调换应用 意识到传统的 lambda 演算没有数字, 字符或者任何非函数的数据类型很重要. 布尔逻辑:在 lambda 演算中没有"真"或"假". 甚至没有 1 或 0. 作为替换: T示意为: x.y.x F示意为: x.y.y 首先, 咱们能够定义一个"if"函数btf, 它当b为真时返回t, b为假时返回f IF等价于: b.t.f.b t f 通过IF, 咱们能够定义根本的布尔逻辑运算符: a AND b等价于: ab.IF a b F a OR b等价于: ab.IF a T b ...

November 23, 2022 · 2 min · jiezi

关于函数式编程:理解函数组合compose及中间件实现

什么是函数组合?函数式组合能够了解为将一系列简略根底函数组合成能实现简单工作函数的过程;这些根底函数都须要承受一个参数并且返回数据,这数据应该是另一个尚未可知的程序的输出;利用compose 函数先来看一个只接管两个参数的compose 函数, 前面再欠缺compose函数 var compose = function(f,g) { return function(x) { return f(g(x)); };};这就是函数组合(compose),f 和 g 都是函数, x是在它们之间通过“管道”传输的值。 咱们能够通过组合函数使之产出一个簇新的函数: var toUpperCase = function(str) { return str.toUpperCase(); };var exclaim = function(str) { return str + '!'; };var shout = compose(exclaim, toUpperCase); shout('hello world');// HELLO WORLD!让代码从右向左运行,而不是由内而外运行 // 取列表中的第一个元素var head = function(arr) { return arr[0]; };// 反转列表var reverse = function (arr) { return arr.reduce(function(cur, next){ return [next].concat(cur); }, []);}var last = compose(head, reverse); last(['apple', 'banana', 'orange']); // orange能够看出compose的数据流是从右往左的,且从右向左执行更加可能反映数学上组合的含意; ...

June 18, 2022 · 4 min · jiezi

关于函数式编程:用JavaScript入门函数式编程刚入门趁热分享

函数式编程命令式和申明式咱们入门编程的时候,通常都是从命令式编程开始,即最简略的过程式代码。起初为了解决大型项目又接触到面向对象,也属于命令式。而函数式编程属于申明式,其实它的呈现早于面向对象。 MySQL就是一个很好的申明式语言的例子,它仅仅是申明了流程,却没有将过程的细节裸露进去。 SELECT * from data_base WHERE author='jack';再举一个例子来比拟命令式和申明式的代码: const arr = [1, 2, 3, 4, 5]// 要求将下面的数组中小于 3 的去掉,并且将剩下的数乘上 2// 命令式const result = []for (let i=0; i<arr.length; i++) { if (arr[i] >= 3){ result.push(arr[i] * 2) }}// 申明式const result = arr.filter(n >= 3).map(n => n*2)看了下面的例子你可能会想,申明式的代码就这?再看看下面的 MySQL 的例子,申明式确是如此,通过 filter、map 等办法,封装了细节,而后将逻辑申明进去,并不需要一步一个命令地阐明要怎么做,所以更简洁,而这就是最根本的申明式代码。 当咱们学面向对象的时候,都会先晓得它的三个个性:封装、继承、多态。基于这三个个性,人们在编写代码会延申出很多最佳实际,即设计模式,如工厂模式、依赖注入等。而函数式编程也是如此,有对应的个性和最佳实际。 函数式函数式编程是以函数为主的编程格调,其实程序就是由一段段逻辑组成,而将这些逻辑宰割成一个个函数,再将其组合施展到极致。 函数式解决了一个问题,当命令式的格调写代码时,一开始你能够很间接的实现工作代码,但当你开始思考边界解决和代码复用,慢慢的,你的代码会逐步背负它本不该有的复杂度,而函数式编程能解决这个问题。 程序的实质,除了是数据结构和算法,还能够是计算和副作用。 // 先看个例子,从 localStorage 中取出所有用户数据,并找出年龄最大的,显示在 DOM 上const users = localStorage.getItem('users')const sortedUsers = JSON.parse(users).sort((a, b) => b.age - a.age)const oldestUser = sortedUsers[0]document.querySelector('#user').innerText = oldestUser.name下面的代码很平时,然而了解起来却须要肯定工夫,先做个函数式的优化,将下面所有步骤封装一下。 ...

May 9, 2022 · 3 min · jiezi

关于函数式编程:前端函数式编程浅析

前言 在浅析函数式编程之前,咱们须要明确两个前导概念,即:编程范式(Programming Paradigm)与设计模式(Design Pattern): 对于编程范式(Programming Paradigm),维基百科给出的定义如下: Programming paradigms are a way to classify programming languages based on their features. Languages can be classified into multiple paradigms.能够看出,编程范式是一种组织代码的形式,它与各大语言的特点(特地是语言设计及编译器)非亲非故; 而设计模式(Design Pattern),维基百科给出的定义如下: In software engineering, a software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design.从定义能够得出:设计模式是一种通用的解决方案,编程范式与语言的特点是强相干的,而设计模式则是任何语言都能够依据其特点进行实现的一种通用模板 从前导的概念,咱们能够理解,函数式编程是一种编程范式而不是一种设计模式,因此其与语言是强相干的,从上图能够看出,对于编程范式不能独自通过某一属性或某一边界将其辨别开,尤其是古代高级语言都已根本借鉴了其余语言的特色与办法,所以,目前大多数文章或教材中对编程形式的辨别办法都是做点状剖析,因为其从全局明确辨别的确比拟艰难,而常见的能够泛泛的将编程范式分为:命令式编程和申明式编程。其中命令式编程包含面向过程编程及面向对象编程(也有说面向对象编程属于元编程),而申明式编程包含函数式编程、逻辑式编程、响应式编程,咱们不谨严的能够简略的将常见编程范式进行简化为上图所示分类 概念前言中介绍了编程范式是与语言强相干的,因此函数式编程也是语言强相干的,最早的函数式编程语言是LISP,Schema语言是Lisp语言的一种方言,而古代语言比方Haskell、Clean、Erlang等也前仆后继的实现了函数式编程的特色。对于前端程序员而言,咱们应用的语言是JavaScript或TypeScript,而后者是前者的超集,因此能够算是类JavaScript的语言使用者,对于js而言,因为其设计者Brendan Eich自身是函数式编程的拥趸,因此其设计上借鉴了Schema的函数第一公民(First Class)的理念(ps:所谓函数第一公民,是指 they can be bound to names (including local identifiers), passed as arguments, and returned from other functions, just as any other data type can.,即函数具备能够通过名称绑定、传递参数,并且能够返回其余函数的特色),这就为js的函数式编程埋下了伏笔。既然js能够实现函数式编程的特点,那么函数式编程都有什么特点,或者说怎么样组织代码就是函数式编程了? ...

April 28, 2021 · 4 min · jiezi

关于函数式编程:什么是Sexpression

S-expressions,是 symbolic expressions的缩写, 也叫做 sexprs, 代表 nested list , 它是由编程语言Lisp创造并推广的,Lisp将它们用作源代码和数据。在Lisp罕用的圆括号语法中,s表达式通常被定义为 是 atom, 或者是是(x . y)这种模式,其中x和y也是一个exporession(递归定义)ps: atom的定义,即同时满足非pair数据, 非空数据 (define atom? (lambda (x)(and (not (pair? x)) (not (null? x)))))

April 14, 2021 · 1 min · jiezi