根据维基百科:函数式编程是一种编程范式,它将计算视为数学函数的评估,并避免状态和可变数据.(强调我的).
这是真的吗?我个人的理解是,它使状态更明确,因为编程实质上是将函数(变换)应用于给定状态以获得转换状态.特别是像monad这样的结构允许你通过函数显式地携带状态.我也不认为任何编程范式都可以完全避免状态.
那么,维基百科的定义是对还是错?如果它是错误的,那么定义函数式编程的更好方法是什么?
编辑:我想这个问题的核心是什么是国家?您是否了解状态是变量或对象属性(可变数据)还是不可变数据也是状态?举个例子(在F#中):
let x = 3
let double n = 2 * n
let y = double x
printfn "%A" y
Run Code Online (Sandbox Code Playgroud)
你会说这个片段是否包含状态?
编辑2:感谢大家的参与.我现在明白这个问题更多的是语言上的差异,使用了state一个社区与另一个社区不同的词,正如布莱恩在评论中提到的那样.特别是,功能编程社区中的许多人(主要是Haskellers)解释state为携带一些动态状态,如随时间变化的信号.state诸如有限状态机,Representational State Transfer和无状态网络协议之类的其他用途可能意味着不同的东西.
今天,我所遇到的Python元类的一个令人惊讶的定义在这里,与元类定义有效的内联.相关部分是
class Plugin(object):
class __metaclass__(type):
def __init__(cls, name, bases, dict):
type.__init__(name, bases, dict)
registry.append((name, cls))
Run Code Online (Sandbox Code Playgroud)
什么时候使用这样的内联定义是有意义的?
进一步的论点:
一种方式的论点是创建的元类在其他地方使用这种技术是不可重用的.一个反驳论点是,使用元类的一个常见模式是定义元类并在一个类中使用它,然后从中继承.例如,在保守的元类中定义
class DeclarativeMeta(type):
def __new__(meta, class_name, bases, new_attrs):
cls = type.__new__(meta, class_name, bases, new_attrs)
cls.__classinit__.im_func(cls, new_attrs)
return cls
class Declarative(object):
__metaclass__ = DeclarativeMeta
def __classinit__(cls, new_attrs): pass
Run Code Online (Sandbox Code Playgroud)
本来可以写成
class Declarative(object): #code not tested!
class __metaclass__(type):
def __new__(meta, class_name, bases, new_attrs):
cls = type.__new__(meta, class_name, bases, new_attrs)
cls.__classinit__.im_func(cls, new_attrs)
return cls
def __classinit__(cls, new_attrs): pass
Run Code Online (Sandbox Code Playgroud)
还有其他考虑吗?
在Erlang中,我们鼓励您不要匹配您实际未处理的模式.例如:
case (anint rem 10) of
1 -> {ok, 10}
9 -> {ok, 25}
end;
Run Code Online (Sandbox Code Playgroud)
是一种鼓励的风格,其他可能的结果导致badmatch结果.这与Erlang中的"让它崩溃"理念是一致的.
另一方面,F#会在等效的F#代码中发出"不完整的模式匹配",就像这里一样.
问题是:为什么F#不会通过增加与等效语句匹配的每个模式来有效地删除警告
|_ -> failwith "badmatch"
Run Code Online (Sandbox Code Playgroud)
并使用"让它崩溃"的理念?
编辑:到目前为止有两个有趣的答案:要么避免在不处理代数数据类型的所有情况时可能出现的错误; 或者因为.Net平台.找出哪个是检查OCaml的一种方法.那么,OCaml的默认行为是什么?
编辑:消除在Erlang没有背景的.Net人员的误解.Erlang哲学的要点不是产生总是崩溃的坏代码.让它崩溃意味着让其他进程修复错误.不是编写函数以便它可以处理所有可能的情况,而是让调用者(例如)处理自动抛出的坏情况.对于那些具有Java背景的人来说,它就像是一个带有已检查异常的语言之间的区别,它必须声明它可能会返回的每个可能的异常,以及一个语言,其中函数可能引发未明确声明的异常.
有没有办法将给定的Python抽象语法树(AST)转换为源代码?
这是一个如何使用Python ast模块的一个很好的例子,特别是一个NodeTransformer.我正在寻找一种方法将生成的AST转换回源,因此可以直观地检查更改.
我有一个值列表(1维),我想知道最好的数据结构/算法,以找到最接近我的查询值.我在这里找到的大多数解决方案(全部?)是针对2个或更多维度的.任何人都可以向我建议我的案例方法吗?
我的直觉告诉我对数据进行排序并以某种方式使用二进制搜索.顺便说一句,对于所需的任何树的构造或插入时间没有限制,因此可能有人可以建议一个比简单的排序列表更好的树.
是否存在以不扩展到封闭函数的方式定义范围的语言?换句话说,有一种语言,其中的代码如下(类似Python的语法):
>>> x = 3
>>> def fact(n):
... print x
... return reduce(lambda u, v: u*v, xrange(1, n+1), 1)
...
Run Code Online (Sandbox Code Playgroud)
会产生错误,因为x未在函数内定义fact?
通常,是否存在任何函数的范围不包含其中定义的函数的语言?
编辑:感谢您提供的信息.我之所以想到这一点,是因为内部函数能够访问其包含函数所提供的所有环境的情况听起来非常接近我对Joe Armstrong在他反对OOP的论证中描述的情况:
因为面向对象语言的问题是他们已经拥有了所有这些隐含的环境.你想要一个香蕉,但你得到的是一只拿着香蕉和整个丛林的大猩猩.
另外相关的是,我听说新语言没有全局命名空间,但我不知道它是如何工作的.
我可以想象在下面的Brian的评论中提出的内置函数(从__builtins__Pythonspeak或System中导入的函数在许多其他语言中)的问题是由解释器/编译器在每个函数中人为引入的.毕竟他们几乎总是特别用语言对待.另一种选择是将它们作为对象的方法作为参数传递给函数或从内部作为模块导入.
类型值如何:
type Tree =
| Node of int * Tree list
Run Code Online (Sandbox Code Playgroud)
有一个值引用自己以功能方式生成的值吗?
对于Tree的合适定义,结果值应该等于以下Python代码中的x:
x = Tree()
x.tlist = [x]
Run Code Online (Sandbox Code Playgroud)
编辑:显然需要更多解释.我正在尝试学习F#和函数式编程,所以我选择实现之前用其他语言编写的封面树.这里相关的是每个级别的点是下面级别的点的子集.结构在概念上达到了水平 - 无限.
在命令式语言中,节点具有包含其自身的子列表.我知道这可以在F#中强制执行.不,它不会在封面树算法的情况下创建无限循环.
我想为 Django REST Framework 应用程序上的视图编写单元测试。测试应该使用 PUT 上传文件,本质上相当于
http -a malkaouri PUT http://localhost:8000/data-packages/upload/ka @tmp/hello.py
到目前为止我写的代码是
factory = APIRequestFactory()
request = factory.put( '/data-packages/upload/ka',
data,
content_type='application/octet-stream',
content_disposition="attachment; filename=data.dump")
force_authenticate(request, user)
view = PackageView.as_view()
response = view(request, "k.py")
Run Code Online (Sandbox Code Playgroud)
显然,它不会上传文件。运行测试时的具体错误是400:
{u'detail': u'缺少文件名。请求应包含一个带有文件名参数的 Content-Disposition 标头。'}
值得注意的是,我使用请求工厂来测试视图而不是完整的客户端。这就是使这个问题中的解决方案对我不起作用的原因。
设置内容处置标头的正确方法是什么?