是否存在具有以下功能的编程语言?

Does a programming language with the following features exist?

提问人:hatcyl 提问时间:7/21/2016 最后编辑:user207421hatcyl 更新时间:3/15/2019 访问量:257

问:

是否有一种语言可以支持以下概念,或者是否有一种模式可以实现与现有概念类似的功能?

概念

我想定义具有以下属性的:、、、;其中 和 .RectangleLengthHeightAreaPerimeterArea = Length * HeightPerimeter = (2 * Length) + (2 * Height)

鉴于上面的语句,如果我想通过给它 a 和 a 来创建一个,它当然应该自动填充其余属性。RectangleLengthHeight

但是,它应该更进一步并自动允许您创建具有任意两个属性(例如和)的属性,因为这在数学上也足以创建相同的 .RectangleHeightPerimeterRectangle

为了帮助解释这个想法,请举个例子:

//Declaration
Rectangle
{
    Height, Length, Area, Perimeter;

    Area = Height * Length;
    Perimeter = (2 * Length) + (2 * Height);
}

//Usage
main()
{
    var rectangleA = new Rectangle(Height, Length);
    var rectangleB = new Rectangle(Height, Area);

    Assert(rectangleA == rectangleB);
}

请注意,我不需要为 定义构造函数。请注意,如果 a 是使用 和 创建的,我不需要指定所需的特定逻辑。RectangleRectangleHeightArea

编辑:应该是矩形,而不是正方形。

与语言无关的 编程 语言设计

评论

0赞 Gordon Gustafson 7/21/2016
听起来有点像 Haskell 的类型类,但我对它们还不够了解,无法将其添加为答案。
0赞 Charlie Fish 7/21/2016
这听起来更像是一个库,而不是一种编程语言
0赞 slebetman 7/21/2016
是的。Javascript的。查看 getter 和 setter(不,不是设计模式,而是语言功能)
0赞 user207421 7/21/2016
在 1980 年代有一篇关于这个问题的 OOPSLA 论文,您可以在其中将 Area 定义为长度和宽度的乘积,并且类型系统理解这一点,因此不允许您使用不仅类型错误而且尺寸错误的单位。
0赞 hatcyl 7/21/2016
@slebetman 如果你能给我看一个 Javascript 的例子,那就太棒了。写下答案!

答:

6赞 Frank Puffer 7/22/2016 #1

您正在寻找的是一种具有集成计算机代数系统的语言。它必须能够解决与不同变量相关的方程。

虽然有可能实现这样的东西,但我怀疑它是否有意义,因为在许多情况下,要么没有解决方案,要么有多个解决方案。

如果只给出面积和周长,即使是您的简单示例也不起作用,因为通常有两种解决方案。(我假设你的类实际上表示一个矩形而不是一个正方形,否则你不应该有单独的长度和高度变量。

例:

Input: area = 2, perimeter = 6
Solution 1: length = 2, height = 1
Solution 2: length = 1, height = 2

另一条与您的问题无关的评论:您的类显然包含冗余的成员变量。由于各种原因,这是一件坏事,最重要的是不一致的可能性。除非你有非常严格的性能约束,否则你应该只存储其中的两个,比如长度和宽度,并在需要时提供计算其他方法的方法。

评论

0赞 hatcyl 7/22/2016
你是对的,给定一个和一个可能有不止一个解决方案。在这种情况下,永远不会有构造函数。或者更好的是,该构造函数将返回一个可能的列表。AreaPerimeterRectangles
0赞 hatcyl 7/22/2016
是的,我确实有多余的变量。这实际上是这个问题的动机。你怎么知道哪些是真实的,哪些是派生的?
1赞 Frank Puffer 7/22/2016
@hatcyl:为了决定使用哪些变量,我想到了两个标准:(1)需要更频繁地访问的变量。(2)从中可以更容易地计算出其他的那些。在您的示例中,我将避免存储面积和周长,因为计算其他值将涉及平方根。
2赞 alter_igel 7/22/2016 #2

在 C# 中,可以使用具有隐式 getter 和 setter 的属性。这样你就可以写出这样的东西:

public class Square {
    public int Length {
        get { return length; }
        set { length = value; }
    }
    public int Area {
        get { return length * length; }
        set { length = Math.Sqrt(value); }
    }
    public int Perimeter {
        get { return length * 4; }
        set { length = value / 4; }
    }
    private int length;
}

现在你可以写:

Square square = new Square();
square.Length = 2;
Console.WriteLine(square.Length);    // "2"
Console.WriteLine(square.Area);      // "4"
Console.WriteLine(square.Perimeter); // "8"
square.Area = 9;
Console.WriteLine(square.Length);    // "3"
Console.WriteLine(square.Area);      // "9"
Console.WriteLine(square.Perimeter); // "12"

编辑:

C# 还允许您在实例化对象时自行选择命名属性:

Square square1 = new Square { Perimeter = 12 };
Square square2 = new Square { Length = 4 };

评论

1赞 Frank Puffer 7/22/2016
我不认为这回答了这个问题,因为你必须明确定义每个属性的计算方式。
0赞 hatcyl 7/22/2016
是的,这实际上是我现在的首选方法。我本质上是在试图找到一种更优雅的方式来做到这一点。
0赞 Kromster 7/22/2016
计算机对我们称之为“矩形”的东西一无所知,它们需要我们以一种或另一种方式设置这些规则;
0赞 hatcyl 7/22/2016
是的,但是计算机应该知道,如果那样的话.Area = Length * WidthLength = Area / Width
0赞 hatcyl 7/22/2016
@Tim Straubinger 现在你让我想知道,你上面的例子在 a 和 a 下会是什么样子?LengthWidth
2赞 Luca Angeletti 7/28/2016 #3

我不认为这样的东西确实以编程语言的形式存在。

本体

然而,我能想到的第一种方法是定义一个本体,我的意思是一组关于

  1. 实体:矩形、正方形、狗、汽车等......
  2. 属性:面积、高度、轮子数量等......
  3. (1) 和 (2) 之间的关系:矩形的面积是高度 * 宽度,...

现在给定了属性列表和所需的输出实体

我有,我需要一个heightwidthRectangle

系统可以通过规则图搜索路径,以根据提供的输入生成所需的结果。

真实世界的例子

Wolfram Alpha 可能遵循上述技术

enter image description here

enter image description here

3赞 Daniel 8/12/2016 #4

当然,这样的语言是存在的。正如您现在在自己对这个答案的评论中指出的那样,许多人都这样做了。

在下面的示例中,我将使用 Powerloom 表示系统,该系统是用一种称为 STELLA 的语言实现的。 你可以在 Common Lisp 环境中使用它。 一旦你安装了所有的东西,你就可以通过运行以下命令来加载语言:

(cl:load "load-powerloom.lisp")
(in-package "STELLA")
(in-dialect "KIF")

这就是开始构建令人敬畏的几何对象所需的全部内容。 在 STELLA 中,你可以用原语定义一个概念:defconcept

(defconcept Rectangle (?r)
  :documentation "Curious geometrical objects that live on a plane.")

并用以下命令定义其属性:deffunction

(deffunction rect-height ((?t Rectangle)) :-> (?n INTEGER))
(deffunction rect-length ((?t Rectangle)) :-> (?n INTEGER))
(deffunction area ((?t Rectangle)) :-> (?n INTEGER))
(deffunction perimeter ((?t Rectangle)) :-> (?n INTEGER))

要确定矩形的面积、周长和边之间的关系,您必须做出一些断言。这就是你要做的。assert

(assert (forall (?t Rectangle)
                (= (area ?t) (* (rect-height ?t) (rect-length ?t)))))
(assert (forall (?t Rectangle)
                (= (perimeter ?t) (+ (* 2 (rect-height ?t))
                                     (* 2 (rect-length ?t))))))

您告诉 STELLA,对于所有矩形,面积是高度和长度的乘积,对于所有矩形,周长是高度的两倍加上长度的两倍。

现在,您可以实例化对象,只要它们有意义,赋予它什么属性并不重要。

(definstance rect1 :Rectangle true :rect-height 10 :rect-length 10)
(definstance rect2 :Rectangle true :area 40 :rect-height 20)

在这里,您将高度和长度作为参数,并使用面积和高度进行实例化。rect1rect2

但是,检查语言是否符合您的期望总是好的:

STELLA> (retrieve all ?x (= (area rect1) ?x))
There is 1 solution:
  #1: ?X=100

STELLA> (retrieve all ?x (= (rect-length rect2) ?x))
There is 1 solution:
  #1: ?X=2

如果你厌倦了矩形,决定建造一个漂亮的正方形,为什么不推导出一个概念呢?

(defconcept Square ((?r Rectangle))
  :documentation "Weird rectangles that fascinated the Greeks"
  :<=> (= (rect-height ?r) (rect-length ?r)))

只需告诉 STELLA 正方形是高度和长度相等的矩形。

现在试试看:

STELLA> (definstance nice-rectangle :Rectangle true :rect-length 10 :area 100)
|i|NICE-RECTANGLE
STELLA> (ask (Square nice-rectangle))
TRUE

我根本不是专家,但我发现这种语言很吸引人。可悲的是,互联网上关于它的信息太少了。甚至手册也不完整。 有关更多信息,我建议从这些幻灯片开始。

著名的著作 SICP 在这里教授如何为这种语言构建一个非确定性评估器最后,可以在这里看到一篇精彩的文章,描述了这些想法背后的动机和应用。

评论

1赞 engineerX 8/12/2016
我尊重这个答案
0赞 hatcyl 8/12/2016
哇,这听起来非常有前途!
0赞 hatcyl 8/12/2016
所以,看起来我正在寻找基于逻辑的语言 - en.wikipedia.org/wiki/... - 我认为我正在寻找的本质是“基于逻辑的语言指定了解决方案必须具有的一组属性,而不是一组获得解决方案的步骤。
0赞 linuxfan says Reinstate Monica 1/21/2017
恭喜 - +1,因为你很清楚这个问题。