Search code examples
language-agnosticprogramming-languageslanguage-design

Does a programming language with the following features exist?


Is there a language which will support the following concept or is there a pattern to achieve something similar with existing one?

Concept

I want to define a Rectangle with the following properties: Length, Height, Area, Perimeter; where Area = Length * Height and Perimeter = (2 * Length) + (2 * Height).

Given the statement above, if I want to create a Rectangle by giving it a Length and a Height, it should of course automatically fill out the rest of the properties.

However, it should go further and automatically allow you to create a Rectangle with any two properties (say Height and Perimeter) because that is also mathematically enough to create the same Rectangle.

Example

To help explain the idea, take this example:

//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);
}

Notice how I didn't need to define constructors for Rectangle. Notice I did not need specify the specific logic needed if a Rectangle was created using Height and Area.

Edit: Should be rectangle and not a square for a proper example.


Solution

  • Of course such a language exists. Many do, as you've now pointed out in your own comment to this answer.

    In the example below I'll be using the Powerloom representation system, implemented in a language called STELLA. You can play with it from within a Common Lisp environment. Once you have everything installed you can load the language by running:

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

    That's about all you need to start building awesome geometrical objects. Within STELLA you may define a concept with the primitive defconcept:

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

    And define its properties with 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))
    

    To make the relations between area, perimeter and the sides of your rectangle, you'll have to make some assertions. That's what you'll have assert for.

    (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))))))
    

    You are telling STELLA that for all rectangles, the area is the product of height and length, and that for all rectangles, the perimeter is twice the height plus twice the length.

    Now you can instantiate your objects, and it doesn't matter what properties you give it, as long as they make sense.

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

    Here you instantiate rect1 with height and length as parameters, and rect2 with area and height.

    But its always good to check that the language is doing what you expect:

    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
    

    If you ever get tired of rectangles and decide to build a beautiful square, why not derive a concept?

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

    Simply tell STELLA that squares are rectangles where height and length are equal.

    Now try it out:

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

    I'm not an expert at all, but I find the language fascinating. It's sad that there is so little information about it on the internet. Even the manual is incomplete. For more information I'd suggest starting with these slides.

    The famous book SICP teaches how to build a nondeterministic evaluator for such a language here. And finally, a wonderful write up describing motivations and applications behind these ideas can be seen here.