{"id":3675,"date":"2025-04-24T15:00:33","date_gmt":"2025-04-24T09:30:33","guid":{"rendered":"https:\/\/www.rangakrish.com\/?p=3675"},"modified":"2025-04-24T15:00:33","modified_gmt":"2025-04-24T09:30:33","slug":"interfaces-without-inheritance-comparing-c-and-common-lisp","status":"publish","type":"post","link":"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/","title":{"rendered":"Interfaces Without Inheritance: Comparing C++ and Common Lisp"},"content":{"rendered":"<p>Clean interface design is a crucial aspect of software engineering since it enables code flexibility, reuse, and maintainability. Developers who prefer an object-oriented approach typically rely on inheritance to define the interface and thus establish type relationships. While this can lead to a good design if approached carefully, detractors of OOP point out that this can result in rigid hierarchies, and when multiple inheritance is used, it might lead to the infamous <em><strong>\u201cdiamond problem\u201d<\/strong><\/em>.<\/p>\n<p>Experienced C++ developers know that it is possible to define interface compatibility without necessarily resorting to inheritance. For example, <a href=\"https:\/\/www.rangakrish.com\/index.php\/2021\/09\/19\/c-20-concepts\/\" target=\"_blank\" rel=\"noopener\"><em><strong>\u201cConcepts\u201d<\/strong><\/em><\/a>\u00a0introduced in <em><strong>C++20<\/strong><\/em> offer an elegant, static, compile-time solution to this requirement. <em><strong>Common Lisp<\/strong><\/em>, being a dynamic language with support for advanced metaprogramming capabilities, allows us to model this use case differently. In this article, I would like to take a simple example, implement it using <em><strong>C++20 Concept<\/strong><\/em> and then show its corresponding (closest) <em><strong>Lisp<\/strong><\/em> implementation.<\/p>\n<p>Take the example of two shapes, a <em><strong>Rectangle<\/strong><\/em> and a <em><strong>Circle<\/strong><\/em>. The common OOP approach uses inheritance, perhaps starting with an abstract base class called <em><strong>\u201cShape\u201d<\/strong><\/em> and then publicly deriving <em><strong>Rectangle<\/strong><\/em> and <em><strong>Circle<\/strong><\/em> from it, and then overriding the appropriate methods. This typically involves dynamic binding.<\/p>\n<p>Another approach, which is our focus today, uses C++20 <em><strong>\u201cConcept\u201d<\/strong><\/em> to model these classes but without using inheritance.<\/p>\n<figure id=\"attachment_3676\" aria-describedby=\"caption-attachment-3676\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp2.jpg?ssl=1\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" data-attachment-id=\"3676\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/cpp2\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp2.jpg\" data-orig-size=\"675,807\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745423167&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Rectangle and Circle Defined\" data-image-description=\"&lt;p&gt;Rectangle and Circle Defined&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Rectangle and Circle Defined&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp2.jpg\" class=\"wp-image-3676\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp2.jpg?resize=400%2C478&#038;ssl=1\" alt=\"Rectangle and Circle Defined\" width=\"400\" height=\"478\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp2.jpg?resize=251%2C300&amp;ssl=1 251w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp2.jpg?w=675&amp;ssl=1 675w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/a><figcaption id=\"caption-attachment-3676\" class=\"wp-caption-text\"><strong>Rectangle and Circle Defined<\/strong><\/figcaption><\/figure>\n<p>These classes are not derived from a common base class. Note also that I have defined the class <em><strong>\u201cLocality\u201d<\/strong><\/em> with the <em><strong>\u201carea()\u201d<\/strong><\/em> member function returning a <em><strong>\u201cstring\u201d<\/strong><\/em> instead of a numeric value.<\/p>\n<p>Let us now define our <em><strong>\u201cShape\u201d<\/strong> <strong>Concept<\/strong><\/em>:<\/p>\n<figure id=\"attachment_3677\" aria-describedby=\"caption-attachment-3677\" style=\"width: 450px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp1.jpg?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"3677\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/cpp1\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp1.jpg\" data-orig-size=\"857,436\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745423082&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Shape Concept\" data-image-description=\"&lt;p&gt;Shape Concept&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Shape Concept&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp1.jpg\" class=\"wp-image-3677\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp1.jpg?resize=450%2C229&#038;ssl=1\" alt=\"Shape Concept\" width=\"450\" height=\"229\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp1.jpg?resize=300%2C153&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp1.jpg?resize=768%2C391&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp1.jpg?w=857&amp;ssl=1 857w\" sizes=\"(max-width: 450px) 100vw, 450px\" \/><\/a><figcaption id=\"caption-attachment-3677\" class=\"wp-caption-text\"><strong>Shape Concept<\/strong><\/figcaption><\/figure>\n<p>Thus <em><strong>\u201cShape\u201d<\/strong><\/em> is a <em><strong>generic predicate<\/strong><\/em> that checks if the given type has an <em><strong>\u201carea()\u201d<\/strong><\/em> member function taking no parameter and returning a numeric value (that can be converted to a double).<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>To show how this is used, I have defined a <em><strong>\u201cprintArea()\u201d<\/strong><\/em> function that takes argument conforming to a <em><strong>\u201cShape\u201d<\/strong><\/em> and then prints its area.<\/p>\n<p>Here is the <em><strong>\u201cmain()\u201d<\/strong><\/em> function:<\/p>\n<figure id=\"attachment_3678\" aria-describedby=\"caption-attachment-3678\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp3.jpg?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"3678\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/cpp3\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp3.jpg\" data-orig-size=\"683,375\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745423196&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Using the Concept\" data-image-description=\"&lt;p&gt;Using the Concept&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Using the Concept&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp3.jpg\" class=\"wp-image-3678\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp3.jpg?resize=400%2C220&#038;ssl=1\" alt=\"Using the Concept\" width=\"400\" height=\"220\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp3.jpg?resize=300%2C165&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp3.jpg?w=683&amp;ssl=1 683w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/a><figcaption id=\"caption-attachment-3678\" class=\"wp-caption-text\"><strong>Using the Concept<\/strong><\/figcaption><\/figure>\n<p>When the last two lines are commented out, here is the program output:<\/p>\n<figure id=\"attachment_3679\" aria-describedby=\"caption-attachment-3679\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp-output.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3679\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/cpp-output\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp-output.jpg\" data-orig-size=\"807,89\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745423291&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Program Output\" data-image-description=\"&lt;p&gt;Program Output&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Program Output&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp-output.jpg\" class=\"wp-image-3679\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp-output.jpg?resize=400%2C44&#038;ssl=1\" alt=\"Program Output\" width=\"400\" height=\"44\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp-output.jpg?resize=300%2C33&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp-output.jpg?resize=768%2C85&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp-output.jpg?resize=800%2C89&amp;ssl=1 800w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/cpp-output.jpg?w=807&amp;ssl=1 807w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/a><figcaption id=\"caption-attachment-3679\" class=\"wp-caption-text\"><strong>Program Output<\/strong><\/figcaption><\/figure>\n<p>If the last two lines are uncommented, the compiler generates error messages as expected:<\/p>\n<figure id=\"attachment_3680\" aria-describedby=\"caption-attachment-3680\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/compiler-error.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3680\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/compiler-error\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/compiler-error.jpg\" data-orig-size=\"749,202\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745423372&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Compiler Error\" data-image-description=\"&lt;p&gt;Compiler Error&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Compiler Error&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/compiler-error.jpg\" class=\"wp-image-3680\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/compiler-error-300x81.jpg?resize=400%2C108&#038;ssl=1\" alt=\"Compiler Error\" width=\"400\" height=\"108\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/compiler-error.jpg?resize=300%2C81&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/compiler-error.jpg?w=749&amp;ssl=1 749w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/a><figcaption id=\"caption-attachment-3680\" class=\"wp-caption-text\"><strong>Compiler Error Message<\/strong><\/figcaption><\/figure>\n<p>The reason is obvious. These functions take arguments that do not satisfy the <em><strong>\u201cShape\u201d<\/strong><\/em> constraint. Note carefully that even though <em><strong>\u201cLocality\u201d<\/strong><\/em> defines a member function called <em><strong>\u201carea()\u201d<\/strong><\/em>, it does not fully satisfy the constraint since it does not return a numeric value.<\/p>\n<p>Let us now look at the <em><strong>Lisp<\/strong><\/em> implementation. As I said earlier, <em><strong>Lisp<\/strong><\/em> is different from <em><strong>C++<\/strong><\/em> in that it is a dynamically typed language, so the checks are done at <em><strong>run time<\/strong><\/em>, not at compile time. We can issue directives to the compiler regarding types, optimization, safety, etc., but these are implementation dependent.<\/p>\n<p>Here are the <em><strong>\u201crectangle\u201d<\/strong><\/em> and <em><strong>\u201ccircle\u201d<\/strong><\/em> classes:<\/p>\n<figure id=\"attachment_3681\" aria-describedby=\"caption-attachment-3681\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp1.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3681\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/lisp1\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp1.jpg\" data-orig-size=\"649,205\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745434291&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Lisp Classes\" data-image-description=\"&lt;p&gt;Lisp Classes&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Lisp Classes&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp1.jpg\" class=\"wp-image-3681\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp1.jpg?resize=400%2C126&#038;ssl=1\" alt=\"Lisp Classes\" width=\"400\" height=\"126\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp1.jpg?resize=300%2C95&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp1.jpg?w=649&amp;ssl=1 649w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/a><figcaption id=\"caption-attachment-3681\" class=\"wp-caption-text\"><strong>Lisp Classes<\/strong><\/figcaption><\/figure>\n<p>Next we define methods for calculating <em><strong>\u201carea\u201d<\/strong><\/em> for different objects:<\/p>\n<figure id=\"attachment_3682\" aria-describedby=\"caption-attachment-3682\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp2.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3682\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/lisp2\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp2.jpg\" data-orig-size=\"717,429\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745434328&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Defining Generic Methods\" data-image-description=\"&lt;p&gt;Defining Generic Methods&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Defining Generic Methods&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp2.jpg\" class=\"wp-image-3682\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp2.jpg?resize=400%2C239&#038;ssl=1\" alt=\"Defining Generic Methods\" width=\"400\" height=\"239\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp2.jpg?resize=300%2C179&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp2.jpg?w=717&amp;ssl=1 717w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/a><figcaption id=\"caption-attachment-3682\" class=\"wp-caption-text\"><strong>Defining Generic Methods<\/strong><\/figcaption><\/figure>\n<p>Note the default <em><strong>\u201carea\u201d<\/strong><\/em> method that returns zero. This method will normally be called when there is no other specific method that matches the call point.<\/p>\n<p>Below we define the nearest equivalent of our C++ <em><strong>\u201cConcept\u201d<\/strong><\/em> definition. The <em><strong>\u201cshape-p\u201d<\/strong><\/em> method returns <em><strong>True<\/strong><\/em> if and only if there is a <em><strong>matching<\/strong><\/em> <em><strong>\u201carea\u201d<\/strong><\/em> method for the object passed as argument.<\/p>\n<figure id=\"attachment_3683\" aria-describedby=\"caption-attachment-3683\" style=\"width: 450px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp3.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3683\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/lisp3\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp3.jpg\" data-orig-size=\"1035,270\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745434455&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"The Shape Constraint in Lisp\" data-image-description=\"&lt;p&gt;The Shape Constraint in Lisp&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;The Shape Constraint in Lisp&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp3-1024x267.jpg\" class=\"wp-image-3683\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp3.jpg?resize=450%2C117&#038;ssl=1\" alt=\"The Shape Constraint in Lisp\" width=\"450\" height=\"117\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp3.jpg?resize=300%2C78&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp3.jpg?resize=1024%2C267&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp3.jpg?resize=768%2C200&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp3.jpg?w=1035&amp;ssl=1 1035w\" sizes=\"(max-width: 450px) 100vw, 450px\" \/><\/a><figcaption id=\"caption-attachment-3683\" class=\"wp-caption-text\"><strong>The Shape Constraint in Lisp<\/strong><\/figcaption><\/figure>\n<p>Next we define <em><strong>\u201cprint-area\u201d<\/strong><\/em> function that prints the area of the given object. Note the <em><strong>\u201cdeclaim\u201d<\/strong><\/em> declaration before the method as a <em><strong>compiler directive<\/strong><\/em>. It states that the <em><strong>\u201cprint-area\u201d<\/strong><\/em> function takes a <em><strong>\u201cshape\u201d- <\/strong><\/em>conforming object and returns anything. Also note the call to <em><strong>\u201ccheck-type\u201d<\/strong><\/em> in the method to <em><strong>forcibly<\/strong><\/em> check the type compatibility.<\/p>\n<figure id=\"attachment_3684\" aria-describedby=\"caption-attachment-3684\" style=\"width: 400px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp4.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3684\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/lisp4\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp4.jpg\" data-orig-size=\"850,320\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745434486&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"The print-area Method\" data-image-description=\"&lt;p&gt;The print-area Method&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;The print-area Method&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp4.jpg\" class=\"wp-image-3684\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp4.jpg?resize=400%2C151&#038;ssl=1\" alt=\"The print-area Method\" width=\"400\" height=\"151\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp4.jpg?resize=300%2C113&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp4.jpg?resize=768%2C289&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp4.jpg?w=850&amp;ssl=1 850w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/a><figcaption id=\"caption-attachment-3684\" class=\"wp-caption-text\"><strong>The print-area Method<\/strong><\/figcaption><\/figure>\n<p>We then call <em><strong>\u201cprint-area\u201d<\/strong><\/em> on a <em><strong>\u201crectangle\u201d<\/strong><\/em> object as well as a <em><strong>\u201ccircle\u201d<\/strong><\/em> object and these work fine because there is a corresponding <em><strong>\u201carea\u201d<\/strong><\/em> method. However, the last commented expression is illegal and it will trigger a runtime error.<\/p>\n<p>Here is the actual output:<\/p>\n<figure id=\"attachment_3685\" aria-describedby=\"caption-attachment-3685\" style=\"width: 500px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp-output.jpg?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"3685\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/24\/interfaces-without-inheritance-comparing-c-and-common-lisp\/lisp-output-3\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp-output.jpg\" data-orig-size=\"1503,470\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Admin&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1745434571&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Lisp Program Output\" data-image-description=\"&lt;p&gt;Lisp Program Output&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Lisp Program Output&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp-output-1024x320.jpg\" class=\"wp-image-3685\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp-output.jpg?resize=500%2C156&#038;ssl=1\" alt=\"Lisp Program Output\" width=\"500\" height=\"156\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp-output.jpg?resize=300%2C94&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp-output.jpg?resize=1024%2C320&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp-output.jpg?resize=768%2C240&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/lisp-output.jpg?w=1503&amp;ssl=1 1503w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/a><figcaption id=\"caption-attachment-3685\" class=\"wp-caption-text\"><strong>Lisp Program Output<\/strong><\/figcaption><\/figure>\n<p>This example is an attempt to show that <em><strong>C++20 Concepts<\/strong><\/em> can be simulated in a dynamic language such as <em><strong>Lisp<\/strong><\/em>. It is not intended to compare languages otherwise.<\/p>\n<p>The <em><strong>C++<\/strong><\/em> program was tested in <em><strong>Visual Studio Professional (64 bit) ver 17.13.5<\/strong><\/em>. The <strong>Lisp<\/strong> program was tested in <em><strong>LispWorks Enterprise (64 bit) ver 8.0.1<\/strong><\/em> as well as in <em><strong>Allegro CL Enterprise Edition (64 bit) ver 11.0.<\/strong><\/em><\/p>\n<p>You can download the <a href=\"https:\/\/www.rangakrish.com\/downloads\/ConceptExample2.cpp\" target=\"_blank\" rel=\"noopener\"><em><strong>C++<\/strong><\/em><\/a>\u00a0code and <a href=\"https:\/\/www.rangakrish.com\/downloads\/ConceptExample.lisp\" target=\"_blank\" rel=\"noopener\"><em><strong>Lisp<\/strong><\/em><\/a>\u00a0code.<\/p>\n<p>Have a wonderful week!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Clean interface design is a crucial aspect of software engineering since it enables code flexibility, reuse, and maintainability. Developers who prefer an object-oriented approach typically rely on inheritance to define the interface and thus establish type relationships. While this can lead to a good design if approached carefully, detractors of OOP point out that this [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[49,18],"tags":[293,420,110],"class_list":["post-3675","post","type-post","status-publish","format-standard","hentry","category-c","category-lisp","tag-c-20","tag-c20-concept","tag-common-lisp"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9OLnF-Xh","jetpack-related-posts":[{"id":4012,"url":"https:\/\/www.rangakrish.com\/index.php\/2026\/01\/01\/common-lisp-metaobject-protocol-classes-are-just-objects\/","url_meta":{"origin":3675,"position":0},"title":"Common Lisp Metaobject Protocol: Classes are Just Objects!","author":"admin","date":"January 1, 2026","format":false,"excerpt":"In today\u2019s popular languages such as C++, Java, Golang, Rust, Python, etc., classes are fixed constructs defined by the language. They have a definite syntax that can\u2019t be changed while programming. We are all used to this of course. But what makes Common Lisp stand out is that in that\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"A Simple Class","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2026\/01\/code1-300x42.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2351,"url":"https:\/\/www.rangakrish.com\/index.php\/2021\/03\/14\/calling-c-methods-from-lispworks-lisp-part-2\/","url_meta":{"origin":3675,"position":1},"title":"Calling C# Methods from LispWorks Lisp &#8211; Part 2","author":"admin","date":"March 14, 2021","format":false,"excerpt":"In the last article, I showed how we can invoke C# methods from LispWorks Enterprise Edition, through the COM\/Automation interface. That approach relied on invoking the Automation methods dynamically, without depending on the Type library (*.tlb).\u00a0 In this article, I will discuss the other approach, which uses the Type library.\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"C# Code","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2021\/03\/Code2-236x300.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2021\/03\/Code2-236x300.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2021\/03\/Code2-236x300.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":2334,"url":"https:\/\/www.rangakrish.com\/index.php\/2021\/02\/28\/calling-c-methods-from-lispworks-lisp-through-com-interface\/","url_meta":{"origin":3675,"position":2},"title":"Calling C# Methods from LispWorks Lisp through COM Interface","author":"admin","date":"February 28, 2021","format":false,"excerpt":"In an earlier article, I showed how to invoke C# methods from Sicstus Prolog. Today, I would like to detail the steps for doing the same from LispWorks Lisp. LispWorks Enterprise Edition comes budled with support for COM and Automation. This is what we will be using. What this means\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"The COM Server in C#","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2021\/02\/C-Code-300x267.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2935,"url":"https:\/\/www.rangakrish.com\/index.php\/2022\/11\/07\/why-learn-c\/","url_meta":{"origin":3675,"position":3},"title":"Why Learn C++","author":"admin","date":"November 7, 2022","format":false,"excerpt":"This is the third and the last article in the series \u201cWhy Learn Language-XYZ?\u201d. I talked about Prolog and Lisp earlier. The present article is on C++. Once you have gained reasonable proficiency with Prolog and Lisp, you are ready to learn C++! In my view, C++ is a complex\u2026","rel":"","context":"In &quot;C++&quot;","block_context":{"text":"C++","link":"https:\/\/www.rangakrish.com\/index.php\/category\/c\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":617,"url":"https:\/\/www.rangakrish.com\/index.php\/2017\/09\/13\/reuse-of-grammars-through-inheritance\/","url_meta":{"origin":3675,"position":4},"title":"Reuse of Grammars Through Inheritance","author":"admin","date":"September 13, 2017","format":false,"excerpt":"We are familiar with the advantages of class inheritance in object-oriented languages such as C++, C#, Java, and Python. The ability to reuse functionality via inheritance allows us to express our software design optimally, without having to write redundant code. iLangGen encourages the reuse of grammars by supporting Grammar Inheritance,\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"Simple Grammar","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/09\/image1.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/09\/image1.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/09\/image1.png?resize=525%2C300 1.5x"},"classes":[]},{"id":3017,"url":"https:\/\/www.rangakrish.com\/index.php\/2023\/02\/16\/calling-external-dll-functions-from-julia\/","url_meta":{"origin":3675,"position":5},"title":"Calling External DLL Functions from Julia","author":"admin","date":"February 16, 2023","format":false,"excerpt":"Julia supports calling external functions, especially those written in \u201cC\u201d language. As Julia documentation says, such calls do not involve any \u201cboilerplate\u201d code and hence are efficient. In today\u2019s article, I am going to show how to call functions defined in a DLL (Windows 64 bit). Instead of using direct\u2026","rel":"","context":"In &quot;Julia&quot;","block_context":{"text":"Julia","link":"https:\/\/www.rangakrish.com\/index.php\/category\/julia\/"},"img":{"alt_text":"The \"lispEval\" Function","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2023\/02\/code-300x117.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2023\/02\/code-300x117.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2023\/02\/code-300x117.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/3675","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/comments?post=3675"}],"version-history":[{"count":4,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/3675\/revisions"}],"predecessor-version":[{"id":3689,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/3675\/revisions\/3689"}],"wp:attachment":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/media?parent=3675"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/categories?post=3675"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/tags?post=3675"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}