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

时间:2023-01-02 22:00:56

I was recently thinking how I'm not always using the beautiful concepts of OO when writing Pythonic programs. In particular, I thought I'd be interested in seeing a language where I could write the typical web script as

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

# 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') 

See what happens? I am trying to make as many objects as possible; each paragraph declares something I call transform. For example, there is a transform HTTPHeaders. In an imperative language that would be a declaration of class, object and function combined:

走着瞧吧?我想尽可能多地制作物品;每个段落声明我称之为变换的东西。例如,有一个转换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]

However, I want to have no way to specify that an object should change unless the inputs from which the objects is made change; and no way to have side effects. This makes for a drastic simplification of language. I believe this means we're doing a functional programming ("a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data").

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

I certainly try to use things like Python classes, M-V-C framework and Django (thanks to the answer), but I don't think they have the concepts above and below.

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

  1. Each object has a value field that can be referred just by writing the class name.
  2. 每个对象都有一个值字段,可以通过编写类名来引用它。

  3. If HTTPHeader is referred somewhere, this means that a static, unchangeable object HTTPHeader is created as soon as possible. All references to HTTPHeader then refer to this object.
  4. 如果在某处引用HTTPHeader,则意味着尽快创建静态的,不可更改的对象HTTPHeader。然后,对HTTPHeader的所有引用都引用此对象。

  5. Suppose I want to repeat the program with the same URI object while the interpreter is still in memory. Since Flags depends only on URI and HTTPHeaders only on Flags, those are not recalculated. However, if Database is modified, then Questions need to be recalculated, and thus the HTTPOutput may change too.
  6. 假设我想在解释器仍在内存中时使用相同的URI对象重复该程序。由于Flags仅依赖于标志上的URI和HTTPHeader,因此不会重新计算这些标志。但是,如果修改了数据库,则需要重新计算问题,因此HTTPOutput也可能会更改。

  7. The interpreter automatically deduces the correct sequence of initializing the classes. Their dependency must form a tree for that to happen, of course.
  8. 解释器自动推导出初始化类的正确顺序。当然,他们的依赖必须形成一棵树。

I believe this will be a useful models for programs like web scripts where there are no side effects. Is there a useful language where one writes program similar to this already?

我相信这对于没有副作用的Web脚本等程序来说是一个有用的模型。是否有一种有用的语言可以写出类似于此的程序?

6 个解决方案

#1


If you really want to delve into web application development with Python, then look at Django. You are better off using a MVC architecture in this case and Django does a very nice job of supporting MVC applications.

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

What you are probably interested in is more of a Declarative programming approach than a functional one. Functional programming is more concerned with mapping an input to an output as a pure (mathematical) function. The declarative approach is all about stating what should happen instead of how to do it.

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

In any case, dig into Model-View-Controller and Django. You will probably find that it fits the bill in a completely different manner.

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

#2


Take a look at F#. It is specifically designed as a functional language (based on OCaml) with OO support utilizing the .NET stack.

看看F#。它专门设计为一种功能语言(基于OCaml),具有利用.NET堆栈的OO支持。

#3


I don't think it's exactly what you are looking for but Scala tries to integrate OO and functional features under a common language.

我不认为它正是您正在寻找的,但Scala尝试在一种通用语言下集成OO和功能特性。

#4


Your code looks like a DSL for web applications and Sinatra is such a DSL. Sinatra does not do exactly what you do there but it's in the same ballpark. http://www.sinatrarb.com/ - it's written in Ruby but hey, let's all be friends here in dynamic languages land.

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

#5


This actually feels very much like Haskell, except that you're not using pure functions here. For example, Flags doesn't have the URI passed into it; URI is a separate definition that is presumably not producing the same URI every time it's called, and so on.

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

For URI to be a pure function, it would have to have a parameter that would give it the current request, so that it can always return the same value for the same inputs. (Without any parameters to work on, a pure function can only return the same result over the life of a closure.) However, if you want to avoid explicitly giving URI a parameter every time, this can be done with various techniques; we do this with monads in Haskell.

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

It seems to me that the style of programming you're thinking of might be based on "combinators," having small functions that are glued together inside a framework to produce a large, complex function that does the overall processing.

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

#6


I see my favourite language has not been mentioned yet, so I'd like to jump in and suggest Dyalog APL as a language for 100% function programming. APL has a looong history and was developed when there was no Internet - but Dyalog is the most active provider of APL-Implementations and they also have a fully function webserver that is available free of charge. (The interpreter is also available free of charge for non-commercial use.)

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

#1


If you really want to delve into web application development with Python, then look at Django. You are better off using a MVC architecture in this case and Django does a very nice job of supporting MVC applications.

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

What you are probably interested in is more of a Declarative programming approach than a functional one. Functional programming is more concerned with mapping an input to an output as a pure (mathematical) function. The declarative approach is all about stating what should happen instead of how to do it.

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

In any case, dig into Model-View-Controller and Django. You will probably find that it fits the bill in a completely different manner.

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

#2


Take a look at F#. It is specifically designed as a functional language (based on OCaml) with OO support utilizing the .NET stack.

看看F#。它专门设计为一种功能语言(基于OCaml),具有利用.NET堆栈的OO支持。

#3


I don't think it's exactly what you are looking for but Scala tries to integrate OO and functional features under a common language.

我不认为它正是您正在寻找的,但Scala尝试在一种通用语言下集成OO和功能特性。

#4


Your code looks like a DSL for web applications and Sinatra is such a DSL. Sinatra does not do exactly what you do there but it's in the same ballpark. http://www.sinatrarb.com/ - it's written in Ruby but hey, let's all be friends here in dynamic languages land.

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

#5


This actually feels very much like Haskell, except that you're not using pure functions here. For example, Flags doesn't have the URI passed into it; URI is a separate definition that is presumably not producing the same URI every time it's called, and so on.

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

For URI to be a pure function, it would have to have a parameter that would give it the current request, so that it can always return the same value for the same inputs. (Without any parameters to work on, a pure function can only return the same result over the life of a closure.) However, if you want to avoid explicitly giving URI a parameter every time, this can be done with various techniques; we do this with monads in Haskell.

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

It seems to me that the style of programming you're thinking of might be based on "combinators," having small functions that are glued together inside a framework to produce a large, complex function that does the overall processing.

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

#6


I see my favourite language has not been mentioned yet, so I'd like to jump in and suggest Dyalog APL as a language for 100% function programming. APL has a looong history and was developed when there was no Internet - but Dyalog is the most active provider of APL-Implementations and they also have a fully function webserver that is available free of charge. (The interpreter is also available free of charge for non-commercial use.)

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