在OO中使用函数式语言概念 - 是否有语言?

时间:2009-06-15 18:21:02

标签: language-agnostic functional-programming oop

我最近在想着在编写Pythonic程序时我并不总是使用OO的漂亮概念。特别是,我认为我有兴趣看到一种可以编写典型网页脚本的语言

# Fictional language 
# This script's combined effect is to transform (Template, URI, Database) -> HTTPOutput

HTTPOutput: 
    HTTPHeaders + Maintext

Flags:                              # This is a transform URI -> Flags 
    value = URI.split('?').after
    refresh = 'r' in value
    sort = /sort=([a-z])/.search(value)

HTTPHeaders:                       # This is a transform Flags -> HTTPHeaders
    'Content-type:...' +  Flags.refresh ? 'Refresh: ...' : ''

Maintext:
    Template.replace('$questions', PresentedQuestions [:20] )

Questions:
    (Flags.sort = 'r') ? RecentQuestions : TopQuestions 

PresentedQuestions:
    Questions % '<h4>{title}</h4><p>{body}</p>'

RecentQuestions:
    Database.Questions . sort('date')  

TopQuestions:
    Database.Questions . sort('votes') 

看看会发生什么?我想尽可能多地制作物品;每个段落声明我称之为 transform 的东西。例如,有一个变换HTTPHeaders。在命令式语言中,它将是类,对象和函数的组合声明:

class HTTPHeaders_class
{
     public char* value
     HTTPHeaders_class() 
     {
         value = ... + Flags.refresh ? + ... // [1] 
     }

}

class Flags_class 
{
     public char* flagstring;
     public bool refresh;
     ...
     Flags_class() 
     {
         value = ... /* [3] */ 
         refresh = ...
     }
}

Flags = new Flags_class (URI)
HTTPHeaders = new HTTPHeaders_class (Flags)   // [2]

但是,我希望无法指定对象应该更改,除非对象的输入发生变化;并没有办法产生副作用。这大大简化了语言。我相信这意味着我们正在做functional programming(“一种将计算视为数学函数评估并避免状态和可变数据的编程范式”)。

我当然尝试使用像Python类,M-V-C框架和Django这样的东西(感谢答案),但我不认为他们有上面和下面的概念。

  1. 每个对象都有一个value字段,可以通过编写类名来引用。
  2. 如果在某处引用HTTPHeader,则意味着尽快创建静态的,不可更改的对象HTTPHeader。所有对HTTPHeader的引用都会引用此对象。
  3. 假设我想在解释器仍在内存中时使用相同的URI对象重复该程序。由于Flags仅取决于URI上的HTTPHeadersFlags,因此不会重新计算这些内容。但是,如果修改了Database,则需要重新计算Questions,因此HTTPOutput也可能会发生变化。
  4. 解释器自动推导出初始化类的正确顺序。当然,他们的依赖必须形成一棵树才能实现。
  5. 我相信这对于没有副作用的网络脚本等程序来说是一个有用的模型。是否有一种有用的语言可以写出与此类似的程序?

6 个答案:

答案 0 :(得分:4)

如果您真的想深入研究使用Python进行Web应用程序开发,请查看Django。在这种情况下,最好使用MVC架构,Django在支持MVC应用程序方面做得非常好。

您可能感兴趣的更多的是Declarative programming方法,而不是功能方法。函数式编程更关注将输入映射为纯(数学)函数。声明性方法是关于说明应该发生什么而不是如何做到这一点。

无论如何,深入了解Model-View-Controller和Django。您可能会发现它以完全不同的方式适合该法案。

答案 1 :(得分:4)

看看F#。它专门设计为一种函数式语言(基于OCaml),OO支持利用.NET堆栈。

答案 2 :(得分:1)

我认为这不是你想要的,但Scala试图在一种共同的语言下整合OO和功能特征。

答案 3 :(得分:1)

您的代码看起来像是用于Web应用程序的DSL,而Sinatra就是这样的DSL。 Sinatra并没有完全按照你的方式去做,但它在同一个球场。 http://www.sinatrarb.com/ - 它是用Ruby写的,但是嘿,让我们在动态语言中成为朋友。

答案 4 :(得分:1)

这实际上感觉非常像Haskell,除了你没有在这里使用纯函数。例如,Flags没有传递URI; URI是一个单独的定义,可能每次调用时都不会生成相同的URI,依此类推。

要使URI成为纯函数,它必须有一个参数来为它提供当前请求,以便它始终可以为相同的输入返回相同的值。 (没有任何参数可以处理,纯函数只能在闭包的整个生命周期内返回相同的结果。)但是,如果你想避免每次都明确给出URI一个参数,可以用各种方法完成技术;我们在Haskell中使用monads进行此操作。

在我看来,您正在考虑的编程风格可能基于“组合器”,它具有在框架内粘合在一起的小功能,以产生一个大型,复杂的功能来完成整个处理。

答案 5 :(得分:1)

我看到我最喜欢的语言还没有被提及,所以我想进入并建议Dyalog APL作为100%函数编程的语言。 APL有悠久的历史,并且在没有互联网的情况下开发 - 但Dyalog是最活跃的APL实施提供商,它们还具有免费提供的全功能webserver。 (翻译也可以免费用于非商业用途。)