我最近在想着在编写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这样的东西(感谢答案),但我不认为他们有上面和下面的概念。
value
字段,可以通过编写类名来引用。 HTTPHeader
,则意味着尽快创建静态的,不可更改的对象HTTPHeader
。所有对HTTPHeader
的引用都会引用此对象。URI
对象重复该程序。由于Flags
仅取决于URI
上的HTTPHeaders
和Flags
,因此不会重新计算这些内容。但是,如果修改了Database
,则需要重新计算Questions
,因此HTTPOutput
也可能会发生变化。我相信这对于没有副作用的网络脚本等程序来说是一个有用的模型。是否有一种有用的语言可以写出与此类似的程序?
答案 0 :(得分:4)
如果您真的想深入研究使用Python进行Web应用程序开发,请查看Django。在这种情况下,最好使用MVC架构,Django在支持MVC应用程序方面做得非常好。
您可能感兴趣的更多的是Declarative programming方法,而不是功能方法。函数式编程更关注将输入映射为纯(数学)函数。声明性方法是关于说明应该发生什么而不是如何做到这一点。
无论如何,深入了解Model-View-Controller和Django。您可能会发现它以完全不同的方式适合该法案。
答案 1 :(得分:4)
答案 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。 (翻译也可以免费用于非商业用途。)