3

我有一个关于声明式编程的问题,看看我对这个概念的理解程度。我有一个任务,说明我应该以“声明性方式”在 Java 中制作数独解谜器。查找这意味着什么,我发现了很多模棱两可的定义,说明程序应该以描述必须做什么而不是指定如何做的方式编写。环顾四周,我发现了一个有趣的例子,有人用列表来解释它,专门过滤列表的奇数。

命令式(称为函数):

List resultList = new List()
foreach element in startlist
    do if element % 2 == 1
        do add element to resultList
        od
    od
return returnList

声明式风格(调用上下文):

newList = startList.filter(num -> num%2 ==1)

所以在声明式风格中,指定了我们要保留哪些元素,但没有指定列表的制作方式。这被抽象到列表的 API 中。

那么我的简单问题是:这种方法是否意味着列表库不是声明性的,因为算法被移到那里?在这种情况下,术语“声明性”适用于调用该库的程序部分。因此,程序是不是不可能 100% 声明性的,因为(当然)某个地方需要一个算法来指定事情是如何完成的?如果我在这里错了,请纠正我,因为这将是我理解声明性概念的核心。

在任何情况下,我都在考虑将数独求解器编写为我自己的库(包含所有“命令式”逻辑,以“声明式”函数编程风格包装)和应采取的步骤规范的组合来解决数独,作为对这些库的调用。我还认为我可以使用命令模式作为包装器来将函数作为参数传递给 Java,以进一步使求解器类更具“声明性”。我已经对此进行了试验,并尝试了类似的方法newList = startList.filter(new OddNumberCommand()),使用OddNumberCommand具有该execute功能的命令,从列表中获取一个元素作为参数,如果要从结果列表中保留或丢弃该元素,则返回 true 或 false。

无论如何,这只是我的想法,我想求助于更好地理解这个概念的其他人的帮助,以确保我走的是正确的道路还是错误的道路。请让我知道我错在哪里以及推理中的正确之处,以便我可以学习正确使用声明式编程。

谢谢

4

2 回答 2

5

正如评论者所说,您的示例比声明式编程更具功能性编程,尽管两者在某些方面相似。在真正的声明式编程中,您将更加注重结果——您将指定如何处理列表中有趣的元素,而不是为了列表本身而转换列表。像Jess这样的规则引擎是声明式编程系统的一个例子(免责声明,我是 Jess 的作者。)

回答您的一个简单问题:是的。所有函数式或声明式编程系统都涉及必须在运行程序的真实计算机上实现的运行时系统。由于真正的计算机始终是命令式冯诺依曼机器,因此必须以命令式方式编写运行时系统。因此,它是您的程序和硬件之间的额外抽象层。

于 2012-04-22T11:15:54.383 回答
1

从声明式编程的定义:

声明性语言的特点:

  1. 基于系统的计算模型,其中直接根据输入数据的成分指定关系。
  2. 由描述关系的定义或方程组组成,这些关系指定要计算的内容,而不是如何计算。
  3. 变量的非破坏性赋值。
  4. 使用的数据结构的显式表示。
  5. 执行顺序无关紧要(没有副作用)。
  6. 表达式/定义可以用作值。
  7. 程序员不再负责控制。

声明式程序定义了逻辑(期望的目标或结果)而不是控制(我们如何实现期望的目标)。我们说声明性语言是目标导向或目标驱动的。

我认为在数独的情况下,关键是使用接口作为类之间的契约。这样,您可以在不破坏模型的情况下更改实现。

于 2012-04-22T11:11:41.693 回答