纯函数式编程语言不允许可变数据,但某些计算以命令式方式更自然/直观地表达 - 或者算法的命令式版本可能更有效.我知道大多数函数式语言都不是纯粹的,让你分配/重新分配变量并执行命令性的事情,但通常会阻止它.
我的问题是,为什么不允许本地状态在局部变量中被操作,但是要求函数只能访问它们自己的局部和全局常量(或者只是在外部范围中定义的常量)?这样,所有函数都保持引用透明性(它们在给定相同参数的情况下总是给出相同的返回值),但在函数内,计算可以用命令式术语表示(例如,while循环).
IO等仍然可以通过正常的功能方式完成 - 通过monad或绕过"world"或"universe"令牌.
我最近已经阅读了很多关于Haskell的内容,以及它作为一种纯函数式语言所带来的好处.(我对讨论Lisp的monad不感兴趣)对我来说(至少在逻辑上)尽可能地隔离具有副作用的函数是有意义的.我已经充分使用了setf其他破坏性功能,并且我认识到它们在Lisp和(大多数)其衍生物中的需要.
开始了:
(declare pure)可能帮助优化编译器?或者这是一个有争议的问题,因为它已经知道了?我很感激这里有任何见解.欢迎提供有关编译器实现或可证明性的信息.
编辑
为了澄清,我不打算将这个问题限制在Common Lisp中.它显然(我认为)不适用于某些衍生语言,但我也很好奇其他Lisps的某些功能是否倾向于支持(或不支持)这种设施.
lisp computer-science proof compiler-optimization purely-functional
当您计划使用像Haskell这样的函数式编程语言开发系统时,如何处理分析和设计阶段?
我的背景是命令式/面向对象的编程语言,因此,我习惯使用案例分析和使用UML来记录程序的设计.但事实是,UML本质上与面向对象的软件方式有关.
我很感兴趣的是,为将要使用函数式编程开发的系统开发文档和定义软件设计的最佳方法是什么.
haskell functional-programming analysis software-design purely-functional
我unsafePerformIO最近一直在读,我想问你一件事.我很清楚,真正的语言应该能够与外部环境进行交互,因此unsafePerformIO有些合理.
但是,据我所知,我不知道有什么快速的方法来了解一个看似纯粹的(从类型判断)接口/库是否真的纯粹没有检查代码搜索调用unsafePerformIO(文档可以省略到提到它).我知道只有当你确定引用透明度得到保证时才应该使用它,但我想知道它.
我想用O(1)复杂度和O(n_max)预处理来计算第n个Fibonacci数.
要做到这一点,我需要存储以前计算的值,如在此C++代码中:
#include<vector>
using namespace std;
vector<int> cache;
int fibonacci(int n)
{
if(n<=0)
return 0;
if(cache.size()>n-1)
return cache[n-1];
int res;
if(n<=2)
res=1;
else
res=fibonacci(n-1)+fibonacci(n-2);
cache.push_back(res);
return res;
}
Run Code Online (Sandbox Code Playgroud)
但它依赖于榆树不允许的副作用.
我一直想知道Haskell异常系统如何适应整个"纯函数式语言"的东西.例如,请参阅下面的GHCi会话.
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> head []
*** Exception: Prelude.head: empty list
Prelude> :t head
head :: [a] -> a
Prelude> :t error
error :: [Char] -> a
Prelude> error "ranch"
*** Exception: ranch
CallStack (from HasCallStack):
error, called at <interactive>:4:1 in interactive:Ghci1
Prelude>
Run Code Online (Sandbox Code Playgroud)
头的类型是[a] - > a.但是当你在空列表的特殊情况下调用它时,你会得到一个例外.但是类型签名中没有考虑此异常.
如果我没记错的话,在模式匹配过程中出现故障时,情况类似.类型签名所说的并不重要,如果你没有考虑到每种可能的模式,你就有可能抛出异常.
我没有一个简明扼要的问题要问,但我的头脑正在游泳.将这个奇怪的异常系统添加到其他纯粹优雅语言的动机是什么?它仍然是纯净的,但我只是缺少一些东西?如果我想利用这个异常功能,我将如何去做(即如何捕获和处理异常?还有什么我可以用它们做的吗?)例如,如果我编写使用它的代码"头"功能,当然我应该采取预防措施,以一个空列表以某种方式走私自己的情况.
error-handling haskell functional-programming exception purely-functional
我是刚刚开始学习F#的C#dev,我对单元测试有一些疑问.假设我想要以下代码:
let input () = Console.In.ReadLine()
type MyType= {Name:string; Coordinate:Coordinate}
let readMyType =
input().Split(';')
|> fun x -> {Name=x.[1]; Coordinate = {
Longitude = float(x.[4].Replace(",","."))
Latitude =float(x.[5].Replace(",","."))
}}
Run Code Online (Sandbox Code Playgroud)
您可以注意到,有几点需要考虑:
我认为这样做的方法是:
说实话,我只是在努力找到一个向我展示这个例子的例子,以便学习F#中的语法和其他最佳实践.所以,如果你能告诉我一条非常棒的道路.
提前致谢.
在阅读 Haskell 教科书中关于不同 monad 的章节时,当作者从解释bind和 monad 定律的细节到实际使用 monad时,我反复迷路。突然,诸如“在 monadic 上下文中运行函数”或“运行 monad”之类的表达出现了。同样,在库文档和关于 monad 转换器堆栈的讨论中,我读到一些函数“可以在任何选择的 monad 中运行”的声明。这个“在 monad 中运行”到底是什么意思?
有两件事我似乎不太明白:
return, >>=) 和定律的类型类。因此,在 monad 中“运行”某些东西可能意味着 (a) 将其作为参数提供给return,或 (b) 使用>>=. 如果 monad 是 type m a,那么在 a) 的情况下,某些东西必须是 type a,以匹配return函数的类型。如果 b)某事必须是 type 的函数a -> m b,以匹配函数的类型>>=。由此,我不明白如何在任意 monad 中“运行”某个函数,因为我排序使用的函数>>=都必须具有相同的类型签名,并且我使用的值return必须是特定的 monad 类型参数。run …我对Haskell非常陌生,对语言的"架构"印象深刻,但是我仍然困扰着monad是如何纯粹的.
由于你有任何指令序列,它使它成为一个不纯的函数,尤其是 I/O函数从任何角度来看都不是纯粹的.
是因为Haskell像所有纯函数一样假设IO函数也有返回值,但是以操作码的形式还是什么?我真的很困惑.
GNU C 和 C++ 提供const和pure函数属性。\n来自gnu 在线文档(重点是我的):
在 GNU C 和 C++ 中,您可以使用函数属性来指定某些函数属性,这些属性可以帮助编译器优化调用或更仔细地检查代码的正确性。例如,您可以使用属性来指定函数从不返回 (noreturn)、仅根据其参数的值返回值 (const)或具有 printf 样式参数 (format)。
\n其中 const 属性似乎是 pure 的子集,也取自gnu 文档:
\n\n\nconst 属性比类似的 pure 属性对函数\xe2\x80\x99s\n定义施加了更大的限制。诊断同时使用 const 和 pure 属性声明相同\n函数。
\n
在 C++ 11 中,添加了constexpr说明符。
当应用于函数时,const 属性和 constexpr 说明符之间有区别吗?GCC 是否应用了不同的优化?
\n一个听起来类似的问题是“constexpr”和“const”之间的差异。但我认为这不是重复的。我的问题具体是关于 function 属性const,它似乎与constexpr.