我在编程生涯中相对较晚地遇到了Curry-Howard Isomorphism,也许这有助于我对它完全着迷.这意味着对于每个编程概念,在形式逻辑中存在精确的模拟,反之亦然.这是一个关于这种类比的"基本"列表,在我的头脑中:
program/definition | proof
type/declaration | proposition
inhabited type | theorem/lemma
function | implication
function argument | hypothesis/antecedent
function result | conclusion/consequent
function application | modus ponens
recursion | induction
identity function | tautology
non-terminating function | absurdity/contradiction
tuple | conjunction (and)
disjoint union | disjunction (or) -- corrected by Antal S-Z
parametric polymorphism | universal quantification
Run Code Online (Sandbox Code Playgroud)
那么,对于我的问题:这种同构的一些更有趣/模糊的含义是什么?我不是逻辑学家,所以我确信我只是在这个清单上划过界限.
例如,这里有一些编程概念,我不知道逻辑中精辟的名字:
currying | "((a & b) => c) iff (a => (b => c))"
scope | "known …Run Code Online (Sandbox Code Playgroud) 您认为函数式编程的好处是什么?它们如何适用于今天的程序员?
函数式编程和OOP之间最大的区别是什么?
我有两次最近重构的代码,以便更改参数的顺序,因为有太多的代码,黑客喜欢flip或\x -> foo bar x 42正在发生.
在设计功能签名时,哪些原则可以帮助我充分利用currying?
您将如何在JavaScript中实现多个数组的笛卡尔积?
举个例子,
cartesian([1, 2], [10, 20], [100, 200, 300])
Run Code Online (Sandbox Code Playgroud) 如果函数式编程语言不能保存任何状态,他们如何做一些简单的事情,比如从用户那里读取输入?他们如何"存储"输入(或存储任何数据?)
例如:这个简单的C语言如何转换为像Haskell这样的函数式编程语言?
#include<stdio.h>
int main() {
int no;
scanf("%d",&no);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(我的问题受到了这篇优秀文章的启发:"名词王国的执行".阅读它让我更好地理解了什么是面向对象的编程,Java如何以一种极端的方式实现它,以及函数式编程语言是如何实现的对比.)
oop paradigms haskell programming-languages functional-programming
什么是组合器?
它是"没有自由变量的函数或定义"(在SO上定义)?
或者如何:根据John Hughes在他着名的关于Arrows的论文中,"组合器是一个从程序片段构建程序片段的函数",这是有利的,因为"......使用组合器的程序员构建了大部分所需的自动编程,而不是手工编写每个细节".他接着说,map和filter是这样的组合子的两个常见的例子.
一些符合第一个定义的组合器:
一些符合第二个定义的组合器:
我对第一个定义不感兴趣 - 那些不能帮我写一个真正的程序(如果你说服我错了,那就是+1). 请帮我理解第二个定义.我认为map,filter和reduce非常有用:它们允许我在更高级别编程 - 更少的错误,更短更清晰的代码.以下是关于组合器的一些具体问题:
更新
感谢@CA McCann,我现在对组合器有了更好的理解.但有一个问题对我来说仍然是一个棘手的问题:
用大量使用组合器写的函数程序和没有写的函数程序有什么区别?
我怀疑答案是组合器重型版本更短,更清晰,更通用,但如果可能的话,我希望进行更深入的讨论.
我也在寻找更多关于复杂组合器的例子和解释(比复杂的组合fold语言).
功能语言导致使用递归来解决许多问题,因此许多函数执行尾调用优化(TCO).TCO导致从另一个函数调用函数(或者本身,在这种情况下,这个特性也称为Tail Recursion Elimination,它是TCO的一个子集),作为该函数的最后一步,不需要新的堆栈帧,这减少了开销和内存使用.
Ruby显然已经从函数式语言(lambdas,map等函数等)中"借用"了许多概念,这让我很好奇:Ruby是否执行尾调用优化?
我有一个尾递归寻路算法,我已经在Javascript中实现,并想知道是否有任何(所有?)浏览器可能会得到堆栈溢出异常.
如何在Scala中按两个字段对列表进行排序,在本例中我将按lastName和firstName排序?
case class Row(var firstName: String, var lastName: String, var city: String)
var rows = List(new Row("Oscar", "Wilde", "London"),
new Row("Otto", "Swift", "Berlin"),
new Row("Carl", "Swift", "Paris"),
new Row("Hans", "Swift", "Dublin"),
new Row("Hugo", "Swift", "Sligo"))
rows.sortBy(_.lastName)
Run Code Online (Sandbox Code Playgroud)
我尝试这样的事情
rows.sortBy(_.lastName + _.firstName)
Run Code Online (Sandbox Code Playgroud)
但它不起作用.所以我很好奇一个好的,简单的解决方案.
我一直在关注函数式编程语言和功能的日益增长的可见性.我调查了他们,没有看到上诉的原因.
然后,最近我参加了Kevin Smith在Codemash上的"Erlang基础知识"演讲.
我很喜欢这个演示文稿,并了解到函数式编程的许多属性使得更容易避免线程/并发问题.我理解缺少状态和可变性使得多个线程无法改变相同的数据,但Kevin说(如果我理解正确的话)所有通信都是通过消息进行的,并且同步处理消息(再次避免并发问题).
但我已经读到Erlang用于高度可扩展的应用程序(爱立信首先创建它的全部原因).如果所有内容都作为同步处理的消息处理,那么如何有效处理每秒数千个请求?这不是我们开始转向异步处理的原因 - 所以我们可以同时运行多个操作线程并实现可扩展性吗?看起来这种架构虽然更安全,但在可扩展性方面却倒退了一步.我错过了什么?
我理解Erlang的创建者故意避免支持线程以避免并发问题,但我认为多线程是实现可伸缩性所必需的.
函数式编程语言如何本质上是线程安全的,但仍然可以扩展?
haskell ×2
javascript ×2
algorithm ×1
combinators ×1
concurrency ×1
curry-howard ×1
currying ×1
erlang ×1
oop ×1
paradigms ×1
ruby ×1
scala ×1
scalability ×1
sorting ×1