<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Programmdesign eines Interpreters]]></title><description><![CDATA[<p>Hallo,</p>
<p>ein Mitschüler und ich wollen in nächster Zeit als Projekt einen Interpreter programmieren, der auf mathematische Ausdrücke spezialisiert ist.</p>
<p>Momentan stehen wir vor dem Problem, dass wir mehrere Varianten haben, eine Klassenhierarchie der verschiedenen Datentypen zu erstellen, wobei diese jedoch immer an mindestens einer Stelle &quot;hinken&quot;.</p>
<p>Wir hatten vor, eine rein virtuelle Basisklasse &quot;Datatype&quot; zu erstellen und davon verschiedene andere Klassen abzuleiten. Dazu gehören geometrische Objekte wie Geraden, Strecken etc., Vektoren und zu guter letzt Skalare in verschiedenen &quot;Ausführungen&quot; für die Wertebereiche N, Z, Q und R.</p>
<p>Jetzt ist die Frage: Ist es zweckmäßig, alle verschiedenen Variablen in einen Container zu speichern, oder sollte es mehrere (einen für Skalare, einen für Vektoren etc.) geben, um sich den Ärger mit der gemeinsamen Basisklasse zu ersparen? (Hinweis: Mit Ärger ist nicht gemeint, dass ich keine erstellen will, sondern dass es nicht viele gemeinsame Operationen gibt, von einer Methode &quot;toString&quot; mal abgesehen :))</p>
<p>Ich hoffe, ihr könnt mir helfen (bzw. wenn das von euch schon mal jemand gemacht hat, wäre es natürlich noch besser).</p>
<p>Vielen Dank schon einmal.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/140931/programmdesign-eines-interpreters</link><generator>RSS for Node</generator><lastBuildDate>Tue, 01 Sep 2026 21:56:53 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/140931.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 18 Mar 2006 10:33:55 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 18 Mar 2006 10:33:55 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ein Mitschüler und ich wollen in nächster Zeit als Projekt einen Interpreter programmieren, der auf mathematische Ausdrücke spezialisiert ist.</p>
<p>Momentan stehen wir vor dem Problem, dass wir mehrere Varianten haben, eine Klassenhierarchie der verschiedenen Datentypen zu erstellen, wobei diese jedoch immer an mindestens einer Stelle &quot;hinken&quot;.</p>
<p>Wir hatten vor, eine rein virtuelle Basisklasse &quot;Datatype&quot; zu erstellen und davon verschiedene andere Klassen abzuleiten. Dazu gehören geometrische Objekte wie Geraden, Strecken etc., Vektoren und zu guter letzt Skalare in verschiedenen &quot;Ausführungen&quot; für die Wertebereiche N, Z, Q und R.</p>
<p>Jetzt ist die Frage: Ist es zweckmäßig, alle verschiedenen Variablen in einen Container zu speichern, oder sollte es mehrere (einen für Skalare, einen für Vektoren etc.) geben, um sich den Ärger mit der gemeinsamen Basisklasse zu ersparen? (Hinweis: Mit Ärger ist nicht gemeint, dass ich keine erstellen will, sondern dass es nicht viele gemeinsame Operationen gibt, von einer Methode &quot;toString&quot; mal abgesehen :))</p>
<p>Ich hoffe, ihr könnt mir helfen (bzw. wenn das von euch schon mal jemand gemacht hat, wäre es natürlich noch besser).</p>
<p>Vielen Dank schon einmal.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1018869</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1018869</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Sat, 18 Mar 2006 10:33:55 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 18 Mar 2006 10:42:08 GMT]]></title><description><![CDATA[<p>wenn sie nix gemeinsam haben (toString zählt nicht ;)) dann sollten auch die objekte nix miteinander zu tun haben, es sei denn, es ist aus irgendeinem grund zwingend notwendig.</p>
<p>ich denke aber eher, dass die typen aufeinander aufbauen. nen vektor wird z.b. n skalare als member haben usw.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1018875</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1018875</guid><dc:creator><![CDATA[schoolar]]></dc:creator><pubDate>Sat, 18 Mar 2006 10:42:08 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 18 Mar 2006 10:52:59 GMT]]></title><description><![CDATA[<p>Das ist richtig. Ein Vektor soll ein Template sein, der verschiedene Arten von Skalaren aufnehmen kann.<br />
Jetzt bleibt aber noch die zweite Frage, ob die einzelnen Skalare aufeinander aufbauen sollen:</p>
<pre><code class="language-cpp">class Exact // Wertebereich R
{};

class Rational : public Exact // Wertebereich Q
{};

class Integer : public Rational // Werteberich Z
{};

//...
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1018879</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1018879</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Sat, 18 Mar 2006 10:52:59 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 18 Mar 2006 12:24:55 GMT]]></title><description><![CDATA[<p>Es kommt stark darauf an, ob dieser zur Laufzeit bestimmt wird oder nicht. Falls du Ausdrücke wie:<br />
<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mo>{</mo><mi>x</mi><mo>∈</mo><mrow><mi mathvariant="double-struck">R</mi></mrow><mi mathvariant="normal">∣</mi><mfrac><mrow><mn>1</mn></mrow><mrow><mn>2</mn></mrow></mfrac><mo>&lt;</mo><mi>x</mi><mo>&lt;</mo><mn>2</mn><mo>}</mo></mrow><annotation encoding="application/x-tex">\{x\in\mathbb{R}|\frac{1}{2}&lt;x&lt;2\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.845108em;"></span><span class="strut bottom" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="base textstyle uncramped"><span class="mopen">{</span><span class="mord mathit">x</span><span class="mrel">∈</span><span class="mord textstyle uncramped"><span class="mord mathbb">R</span></span><span class="mord mathrm">∣</span><span class="mord reset-textstyle textstyle uncramped"><span class="sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter"></span><span class="mfrac"><span class="vlist"><span style="top:0.345em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord scriptstyle cramped"><span class="mord mathrm">2</span></span></span></span><span style="top:-0.22999999999999998em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle textstyle uncramped frac-line"></span></span><span style="top:-0.394em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle uncramped"><span class="mord scriptstyle uncramped"><span class="mord mathrm">1</span></span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span><span class="sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter"></span></span><span class="mrel">&lt;</span><span class="mord mathit">x</span><span class="mrel">&lt;</span><span class="mord mathrm">2</span><span class="mclose">}</span></span></span></span><br />
erlauben willst, sollte der Wertebereich der Zahl als Quasi-Pimpl übergeben werden:</p>
<pre><code class="language-cpp">class Scalar
{
public:
    Scalar (ValueType* val) : _val (val)
    {}
    // Alle Operatoren auf _val umlenken, ValueType ist für die Fehlerbehandlung zuständig
private:
    ValueType* _val;
};
</code></pre>
<p>So kannst du auch Intervalle als Wertebereich angeben (z.B. durch erstellen eines Template-Typs Intervall, der einen der elementaren Wertebereiche als Parameter hat).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1018938</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1018938</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Sat, 18 Mar 2006 12:24:55 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 18 Mar 2006 13:34:39 GMT]]></title><description><![CDATA[<p>Nein, es soll eine &quot;dynamische Typsicherheit&quot; geben, also dass es ausschließlich die Wertebereiche N, Z, Q und R gibt, aber wenn eine Variable diesen Wertebereich einmal hat, diesen auch beibehalten.</p>
<p>Aber danke für die Idee. Dann bräuchte ich aber trotzdem eine Basisklasse für alle Wertebereiche.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019015</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019015</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Sat, 18 Mar 2006 13:34:39 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 18 Mar 2006 14:08:50 GMT]]></title><description><![CDATA[<p>...was auch durchaus sinnvoll ist. Schließlich hat jeder Wertebereich bestimmte Eigenschaften, die er mit den anderen teilt. (Das wäre im übrigen dynamische Typisierung, du meinst statische!)</p>
<p>Die andere Möglichkeit wäre, die konkreten Scalar-Klassen von <strong>einer</strong> Basisklasse abzuleiten und sie in Templateform zu schreiben, wobei der Wertebereich dann eine Policy-Klasse wäre, die wiederum die Funktionen enthält. Um Polymorphie wirst du eh nicht herumkommen.<br />
In jedem Fall würde ich die Mengen von Skalaren etc. trennen.</p>
<p>Meinst du nicht, dass eine Eingrenzung auf <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mi mathvariant="double-struck">N</mi></mrow></mrow><annotation encoding="application/x-tex">\mathbb{N}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68889em;"></span><span class="strut bottom" style="height:0.68889em;vertical-align:0em;"></span><span class="base textstyle uncramped"><span class="mord textstyle uncramped"><span class="mord mathbb">N</span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mi mathvariant="double-struck">Z</mi></mrow></mrow><annotation encoding="application/x-tex">\mathbb{Z}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68889em;"></span><span class="strut bottom" style="height:0.68889em;vertical-align:0em;"></span><span class="base textstyle uncramped"><span class="mord textstyle uncramped"><span class="mord mathbb">Z</span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mi mathvariant="double-struck">Q</mi></mrow></mrow><annotation encoding="application/x-tex">\mathbb{Q}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68889em;"></span><span class="strut bottom" style="height:0.85556em;vertical-align:-0.16667em;"></span><span class="base textstyle uncramped"><span class="mord textstyle uncramped"><span class="mord mathbb">Q</span></span></span></span></span> und <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mi mathvariant="double-struck">R</mi></mrow></mrow><annotation encoding="application/x-tex">\mathbb{R}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68889em;"></span><span class="strut bottom" style="height:0.68889em;vertical-align:0em;"></span><span class="base textstyle uncramped"><span class="mord textstyle uncramped"><span class="mord mathbb">R</span></span></span></span></span> zu sehr einschränkt? Komplexe Zahlen schließt du so von vorneherein aus.</p>
<p>Du könntest vielleicht mal ein konkretes Beispiel für einen zu verarbeitenden Term geben, sonst basieren die Vorschläge nur auf Mutmaßungen, was du meinen könntest <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019036</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019036</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Sat, 18 Mar 2006 14:08:50 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 18 Mar 2006 14:35:07 GMT]]></title><description><![CDATA[<p>Ich habe einen guten Grund, die komplexen Zahlen auszuschließen. Ich kenne mich nicht gut damit aus und möchte mich auch ehrlich gesagt nicht weiter damit beschäftigen (die übersteigen stark meine Vorstellungskraft).</p>
<p>Ok, hier mal ein Beispielausdruck:</p>
<pre><code>fakultaet(x:uint) := if(x=0,1,x*fakultaet(x-1))
zahl := 5
ergebnis := fakultaet(zahl)
</code></pre>
<p>oder aber</p>
<pre><code>fakultaet(x:uint):uint := if(x=0,1,x*fakultaet(x-1))
zahl:uint := 5
ergebnis:uint := fakultaet(zahl)
</code></pre>
<p>wobei ja die Datentypen automatisch erkannt werden können, eine zusätzliche Deklaration also unnötig wäre.</p>
<p>Dynamische Typisierung bezog sich eher darauf, dass die Datentypen automatisch erkannt werden. In gewissen Sinne aber trotzdem statisch, da stimme ich zu.</p>
<p>Das Problem bei einer Lockerung der Einschränkungen wäre, dass die Syntax verkompliziert würde. Schließlich soll noch mit eingebunden werden, dass man physikalisch rechnen kann (also dass Einheiten mit benutzt werden können).</p>
<p>Und zum Schluss noch ein Hinweis: Überladung soll es nicht geben.</p>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/27a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--right_arrow"
      title=":arrow_right:"
      alt="➡"
    /> Ich hoffe meine (unsere) Intentionen sind klarer geworden <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>PS: Eine Frage hätte ich noch - was bedeutet &quot;Policy-Klasse&quot; und was ist ein &quot;Quasi-Pimpl&quot;? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019055</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019055</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Sat, 18 Mar 2006 14:35:07 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 18 Mar 2006 14:56:39 GMT]]></title><description><![CDATA[<p>Pimpl steht für <strong>P</strong>ointer to <strong>Impl</strong>ementation (oder so ähnlich, kann auch von der Namensgebungskonvention vieler Programmierer kommen, die Zeiger mit p beginnen lassen, was dann in pImpl oder ähnlichem endet), siehe <a href="http://www.gamedev.net/reference/articles/article1794.asp" rel="nofollow">http://www.gamedev.net/reference/articles/article1794.asp</a>.<br />
Eine Policy gibt eine Richtlinie an, das Verhalten der Klasse. So könntest du z.B. bestimmte Funktionen in eine Policy auslagern, wodurch du, durch Übergabe eines anderen Template-Parameters, das Verhalten der Klasse (bzw. eines Objektes der Klasse) in bestimmten Fällen ändern kannst. SmartPointer werden dafür gerne als Beispiel genommen. Dort kann z.B. das Verhalten für Nullpointer (Dereferenzierung, Übergabe etc.) oder bei der Zerstörung des SmartPointers (z.B. Aufruf von delete für den Pointer, Verringern eines Verweiszählers etc.) in Policies ausgelagert werden.</p>
<p>In deinem Beispiel seh ich ehrlich gesagt nichts mathematisches, eigentlich ist das nur ein Beispiel für eine <a href="http://de.wikipedia.org/wiki/Funktionale_Programmiersprache" rel="nofollow">funktionale Programmiersprache</a>. Ersteres fände ich deutlich interessanter, das gibts afaik noch nicht so richtig <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019075</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019075</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Sat, 18 Mar 2006 14:56:39 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 18 Mar 2006 15:33:44 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>warum siehst du dort nichts Mathematisches? Ich meine, ich kann in diesem Codestück natürlcih nicht alle Varianten darstellen. Aber geplant ist auch noch folgendes:</p>
<pre><code>x := abs({1,2,3,4})
y := det({1,2,3;4,5,6;7,8,9})
</code></pre>
<p>usw. usf. Also alle Dinge, die man bei mathematischen Problemen braucht.</p>
<p>Eine Idee hätte ich noch, und zwar folgende:</p>
<pre><code class="language-cpp">class Fraction { }; // Bruchimplementation
class Exact { }; // Implementation reeller Zahlen
//...

template&lt;class T&gt;
class Scalar
{
  protected:
    T value;
  public:
    Scalar(const T&amp; val);
    T getVal();
//...
};

template&lt;class T&gt; Scalar&lt;T&gt; operator + (const Scalar&lt;T&gt;&amp; first,const Scalar&lt;T&gt;&amp; second)
{
  return Scalar&lt;T&gt;(first.getVal()+second.getVal());
}
</code></pre>
<p>Da habe ich aber noch Probleme damit:</p>
<ul>
<li>Wie kann ich alle verschiedenen Skalare in eine Map ablegen? Ohne weiteres geht das sicherlich nicht.</li>
<li>Weiterhin kann ich nicht einfach so einen Scalar&lt;Fraction&gt; in einen Scalar&lt;Exact&gt; umwandeln, obwohl dass eigentlich kein Problem sein darf.</li>
<li>Diese Lösung ist eigentlich überhaupt nicht optimiert.</li>
</ul>
<p>Jetzt gäbe es noch eine zweite Variante:</p>
<pre><code class="language-cpp">class Exact { }; // Implementation reeler Zahlen
class Fraction : public Exact { };
//...
</code></pre>
<p>Funktioniert aber so auch nicht, weil ich nicht vorhatte, eine homogene Implementation durchzuführen. Dies wäre auch wenig zweckmäßig - einen Exact wollte ich in einen String packen, aber warum einen Bruch? Der lässt sich in zwei ints aufspalten.</p>
<p>Also was tun?</p>
<p>PS: Wie sollte eine math. Sprache mit dem Paradigma, einfach zu sein, deiner Meinung nach aussehen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019114</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019114</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Sat, 18 Mar 2006 15:33:44 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sun, 19 Mar 2006 11:28:42 GMT]]></title><description><![CDATA[<p>Wäre es vielleicht auch zu empfehlen, ein ganz anderes Sprachen-Design vorzunehmen? Ich meine, die meisten Skriptsprachen sind nur äußerst locker typisiert (siehe CSL oder JavaScript). Aber ist denn ein &quot;Variant&quot;-Datentyp wirklich elegant?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019547</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019547</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Sun, 19 Mar 2006 11:28:42 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sun, 19 Mar 2006 11:49:53 GMT]]></title><description><![CDATA[<p>evtl. hilfreich:<br />
<a href="http://www.softgames.de/developia/viewarticle.php?cid=17852" rel="nofollow">http://www.softgames.de/developia/viewarticle.php?cid=17852</a><br />
mfg.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019564</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019564</guid><dc:creator><![CDATA[Cpt. Tanga]]></dc:creator><pubDate>Sun, 19 Mar 2006 11:49:53 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sun, 19 Mar 2006 12:39:35 GMT]]></title><description><![CDATA[<p>Ehrlich gesagt sehe ich keinen Grund, eine klassische Typisierung zu benutzen. Schließlich wirst du es außschließlich mit Zahltypen verschiedener Bereiche zu tun haben. Du hast also quasi <em>einen</em> Datentyp, aus dem die anderen durch Einschränkung abgeleitet werden können. Oder du nimmst einen Grundtyp (wie z.B. <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mo>∈</mo><mrow><mi mathvariant="double-struck">N</mi></mrow></mrow><annotation encoding="application/x-tex">\in \mathbb{N}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68889em;"></span><span class="strut bottom" style="height:0.72799em;vertical-align:-0.0391em;"></span><span class="base textstyle uncramped"><span class="mrel">∈</span><span class="mord textstyle uncramped"><span class="mord mathbb">N</span></span></span></span></span> und leitest aus ihm die höheren ab. Das alles impliziert, dass es sinnvoller ist, eher Intervalle und Mengen als (abgeleitete) Datentypen zuzulassen, als Typen mit eher informatischen Bezeichnungen wie uint einzuführen oder gar variants einzuführen<br />
zB:</p>
<pre><code>f(x) := 1/x
    {x in |R | x != 0}
// gut, das != ist ein Stilbruch, passt hier eigentlich nicht hin
|Z := |N &amp; -|N &amp; 0
|Q := |N / |N
|R := |N ^ (1 / |N) // x^n = a -&gt; n-te wurzel aus a = x
// ODER
|Z := x {x in |R | x = int (x)}
|N := x {x in |Z | x &gt; 0}
|Q := p/q {p,q in |Z | p/q}
</code></pre>
<p>Sowas halt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019596</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019596</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Sun, 19 Mar 2006 12:39:35 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sun, 19 Mar 2006 15:00:33 GMT]]></title><description><![CDATA[<p>Danke für den Ratschlag und die Anregung. Aber es ist ja so, dass wir nur ein halbes Jahr lang Zeit haben und ja auch noch was anderes zu tun haben. Insofern stellt sich jetzt die Frage: Ist dieser Umfang schaffbar (zumal wir mit solchen Dingen überhaupt keine Ahnung haben)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019699</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019699</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Sun, 19 Mar 2006 15:00:33 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sun, 19 Mar 2006 15:19:16 GMT]]></title><description><![CDATA[<p>Und noch ein weiteres Problem fällt mir gerade auf: Warum ist es zweckmäßig, die Wertebereiche so dynamisch einzugrenzen? Schließlich wollen wir ja keinen Gleichungslöser basteln, für den das so relevant wäre.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019712</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019712</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Sun, 19 Mar 2006 15:19:16 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sun, 19 Mar 2006 20:21:30 GMT]]></title><description><![CDATA[<p>Eigentlich wird ja nicht der Wertebereich, sondern der Definitionsbereich eingeschränkt. Das ist quasi der &quot;Typersatz&quot;, du sagst damit, dass f(x) mit jedem x aus der Definitionsmenge aufgerufen werden kann. Ich sage nicht, dass es nicht auch sinnvollere Ansätze gibt, aber imho ist für eine rein mathematische, deklarative Programmiersprache &quot;Element der Menge&quot; der einzig sinnvolle Typ. uint etc. sind eigentlich Sachen, die nur Programmierer/Informatiker, nicht Mathematiker etwas angehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1019943</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1019943</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Sun, 19 Mar 2006 20:21:30 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Tue, 21 Mar 2006 12:20:12 GMT]]></title><description><![CDATA[<p>Danke erst einmal für deinen Vorschlag, aber den kann ich nicht verwerten. Ich meine, z. B. bei 1/x, muss man dem Interpreter doch nicht sagen, dass nicht durch 0 dividiert werden darf. Der kriegt das ja eigentlich selber mit und kann dann einen Fehler ausgeben. Diese Definitionen, dass da Werte nicht mit angegeben werden dürfen, dienen ja in der Mathematik (die auf dem Blatt Papier ausgeführt wird) &quot;nur&quot; der Vollständigkeit. Die Definitionsbereiche müssen aber da sein, weshalb auch der ganze Kram mit exact und fraction usw. usf. mit rein muss. Aber was darüber hinausgeht, finde ich fraglich. Denn wie gesagt: Der Interpreter soll keine Gleichungen lösen, sondern wie ein Taschenrechner mit sehr vielen Funktionen agieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1020997</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1020997</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Tue, 21 Mar 2006 12:20:12 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Tue, 21 Mar 2006 15:16:43 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9606">@.filmor</a> Dein R kann keine transentdente Zahlen aufnehmen. Pi wäre ein beispiel.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/1086">@Lars</a> Hupel Sag doch mal wo du deine Sprache anwenden willst. Welche Aufgaben soll sie denn erfüllen? Ich meine für eine Fakultät auszurechnen ist C doch unschlagbar elegant. Soll man sie benutzen um eine Zahl zu finden die bestimmte Eigenschaften aufweist? In dem Fall wäre wohl etwas in Richtung Prolog angebracht.</p>
<p>Desweiteren glaub ich nicht, dass eine Zahl aus N von einer Zahl aus R abgeleitet sein sollte. Eine Zahl aus N ist restriktiver als eine aus R jedoch sollte eine abgeleitete Klasse die Basisklasse erweiteren und nicht einschränken. Umgedreht geht es meiner Meinung nach auch nicht. Nicht jede Zahl aus R hat die gleichen Eigenschaften als eine aus N. Ich glaub eine Zahl aus N sollte implicit konvertibar in eine aus R sein. Mit short und int ist es ja auch so.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1021148</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1021148</guid><dc:creator><![CDATA[Ben04]]></dc:creator><pubDate>Tue, 21 Mar 2006 15:16:43 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Tue, 21 Mar 2006 18:25:52 GMT]]></title><description><![CDATA[<p>Stimmt, aber die kann der Rechner sowieso nur angenähert verwenden. Immerhin sind die meisten irrationalen Zahlen so abgedeckt, unendliche Kettenbrüche bringen nur etwas, wenn sie ein System haben (wie z.B. e oder der Goldene Schnitt). π ist also gar nicht unterzubringen. Aber die &quot;echte&quot; Definition der Reellen Zahlen hab ich nicht so ganz verstanden und könnte sie demnach hier nicht einbringen. (Übrigens fehlt hier sowieso die Hälfte + 1 der Zahlen (jaja, ich weiß |R ist überabzählbar), der Exponent müsste 1 / |Z\{0} und die Basis |N_0 lauten).<br />
Außerdem können die Grundbereiche ja durchaus fest einprogrammiert sein, das war nur ein Beispiel, wie man die Mengen aufbauen könnte. Ich glaub da setz ich mich mal dran, das gefällt mir.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1021239</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1021239</guid><dc:creator><![CDATA[.filmor]]></dc:creator><pubDate>Tue, 21 Mar 2006 18:25:52 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Wed, 22 Mar 2006 12:32:02 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>also angewandt werden soll die Sprache, um &quot;mal eben schnell&quot; einen Taschenrechner zur Verfügung zu haben. Aber ein Taschenrechner mit mehr Funktionen. Intention war, dass es mich genervt hat, für irgendwelche Brute-force-behafteten Probleme immer den Compiler anzuwerfen. Dass man keine tollen Performances aus so einem Konzept herausholen kann, ist mir klar.</p>
<p>Jetzt weiß ich aber immer noch nicht, wie ich am besten eine Hierarche aufbauen sollte. Zweckmäßig wäre vielleicht ein Konzept, wobei alle Grunddatentypen separat entwickelt werden, sprich Brüche etc. Dann gibt es eine Klasse, die z. B. vier verschiedene Pointer enthält, jenachdem, welchen Datentyp er enthält (per enum überprüfbar). Bei einer Operation zweier Variablen würde dann ein Ergebnis bringen, welches vom Datentyp des höherwertigen wäre. Beispiel:</p>
<pre><code class="language-cpp">class Variable
{
  protected:
    Exact *ex;
    Fraction&lt;int&gt; *frac;
    int *i;
    unsigned integer *ui;
  public:
    Variable() : ex(0), frac(0), i(0), ui(0) { }
};
</code></pre>
<p>So z. B. Aber ich habe die Vermutung, dass dies eleganter geht. Möglicherweise müsste ich dafür auf den Templatecharakter von Fraction verzichten. Aber das ginge ja.</p>
<p>Da gäbe es die Möglichkeit</p>
<pre><code>Datentyp
|- Skalar
   |- natürliche Zahl
   |- ganze Zahl
   |- rationale Zahl etc.
|- Geometrie etc.
</code></pre>
<p>Das funktioniert aber nicht, wenn ich die Datentyp-/Skalar-Basisklassen rein virtuell mache, weil eine Templateklasse offenbar keine rein virtuellen Methoden implementieren kann. Zumindest meckert der Compiler, wenn es heißt:</p>
<pre><code class="language-cpp">class Scalar
{ //...
  public:
    virtual Scalar&amp; add(const Scalar&amp; other) = 0;
};

template&lt;class T&gt;
class Fraction : public Scalar
{ //...
  public:
    Fraction add(const Fraction&amp; other) { /*...*/ }
};
</code></pre>
<p>Ich kann dann ein Fraction nicht instanziieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1021646</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1021646</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Wed, 22 Mar 2006 12:32:02 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Wed, 22 Mar 2006 14:40:20 GMT]]></title><description><![CDATA[<p>Ich grüble jetzt aber schon die ganze Zeit an dem Problem, warum ich die virtuelle Methode nicht implementieren kann. Im Grunde genommen wird ja eine Templateklasse bei Instanziierung vom Compiler generiert. Kann der da keine vtable erstellen? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /> Oder wisst ihr eine bessere Möglichkeit?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1021749</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1021749</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Wed, 22 Mar 2006 14:40:20 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Wed, 22 Mar 2006 15:00:05 GMT]]></title><description><![CDATA[<p>Fraction add(const Fraction&amp; other) ist <strong>keine</strong> virtuelle function. das pur virtuelle add der basisklasse hatte eine andere signatur und wird durch dieses neue add versteckt und nicht implementiert. möglich wäre stattdessen</p>
<pre><code class="language-cpp">template&lt;class T&gt;
class Fraction : public Scalar
{ //...
  public:
    Fraction&amp; add(const Scalar&amp; other) { /*...*/ }
};
</code></pre>
<p>oder etwas anderes zu Scalar&amp; referenz-kompatibles als rückgabetyp. Das LSP verlangt, dass in (öffentlich) abgeleiten klassen die anforderungen an rückgabewerte (nur) verschärft werden können (kovarianz) und die anforderungen an parameter veringert (kontravarianz). letzteres ist in C++ allerdings nicht zulässig, hauptsächlich weil referenzen auf const nicht unbedingt direkt gebunden werden (also temporaries erzeugen) und so ein schlupfloch entstehen würde.</p>
<p>in diesem konkreten fall habe ich allerdings sowieso zweifel, dass eine klassenhierarchie überhaupt zweckmäßig ist. für binäre operation bräuchte man doch dem grunde nach eine double-dispatch methode, sofern nicht immer beide operanden vom selben typ sein sollen. virtuelle funktionen helfen hier nicht unbedingt weiter und double-dispatch lässt sich auch gut ohne vererbung implementieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1021762</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1021762</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 22 Mar 2006 15:00:05 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Wed, 22 Mar 2006 15:33:09 GMT]]></title><description><![CDATA[<p>Lars Hupel schrieb:</p>
<blockquote>
<pre><code>Datentyp
|- Skalar
   |- natürliche Zahl
   |- ganze Zahl
   |- rationale Zahl etc.
|- Geometrie etc.
</code></pre>
</blockquote>
<p>Das könnte besser klappen. Dann könnte man Operationen wie folgt definieren:</p>
<pre><code class="language-cpp">Exact operator + (const Exact&amp; first,const Fraction&amp; second);
Fraction operator - (const Fraction&amp; first,int second);
// etc.
</code></pre>
<p>camper schrieb:</p>
<blockquote>
<p>in diesem konkreten fall habe ich allerdings sowieso zweifel, dass eine klassenhierarchie überhaupt zweckmäßig ist. für binäre operation bräuchte man doch dem grunde nach eine double-dispatch methode, sofern nicht immer beide operanden vom selben typ sein sollen. virtuelle funktionen helfen hier nicht unbedingt weiter und double-dispatch lässt sich auch gut ohne vererbung implementieren.</p>
</blockquote>
<p>Worum handelt es sich bei double-dispatch und LSP?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1021800</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1021800</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Wed, 22 Mar 2006 15:33:09 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Wed, 22 Mar 2006 16:04:18 GMT]]></title><description><![CDATA[<p>LSP = Liskovsches Substitutionsprinzip, einfach mal googlen</p>
<p>virtuelle funktionen sind eine form von single-dispatch: der konkrete funktion, die aufgerufen wird, hängt vom dynamischen typ eines parameters (des impliziten objekt parameters) ab. dem gegenüber wählt double-dispatch die aufzurufende funktion anhand des dynamischen typs zweier parameter aus (es macht einen unterschied, ob ich zwei integer, ein integer und eine rationale zahl oder zwei rationale zahlen addiere) - die brutalstmöglich einfache methode, das zu erreichen, sind dynamic_cast orgien...</p>
<p>wenn ich das problem richtig verstehe, ist der 'zahlentyp' in einem solchen intepreter grundsätzlich eine dynamische angelegenheit. man könnte sich auch leicht operationen vorstellen, die den 'typ' einer variablen ändern. möglicherweise würde ein single-element container (boost::any kommt in den sinn) Scalar, der dann jeweils zu einem zeitpunkt einen wert eines zahlentyps enthält, dienlich sein. selbstverständlich könnten dann immer noch alle zahlentyp von etwas abstrakteren abgeleitet sein - das wäre dann aber eher ein implementationsdetail, und nicht teil des interfaces von Scalar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1021853</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1021853</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 22 Mar 2006 16:04:18 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Fri, 24 Mar 2006 18:01:39 GMT]]></title><description><![CDATA[<p>Sorry dass ich erst jetzt schreibe. Habe nicht immer Internet verfügbar.</p>
<p>Also LSP weiß ich jetzt was das ist.</p>
<p>Also ehrlich gesagt habe ich keine Lust auf dynamic_cast, was ja wohl auch verständlich ist. Ich finde solchen Code nicht so elegant <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_down"
      title=":-1:"
      alt="👎"
    /></p>
<p>Jetzt ist das Problem, wie eine elegante Lösung aussieht. Um mein Problem noch einmal klar zu umreißen:</p>
<ul>
<li>Einmal im Skript deklariert, soll der Datentyp einer Variable fest bleiben. Jedoch soll der Datentyp automatisch erkannt werden bzw. ggf. explizit angegeben werden.</li>
<li>Eine Basisklasse ist wichtig, da ich vorhabe, eine Symboltabelle à la &quot;std::map<a href="std::string,Scalar*" rel="nofollow">std::string,Scalar*</a> zu erstellen. Mehrere Symboltabellen wären zwar einfacher, aber durchaus lästig und unelegant.</li>
<li><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    /> Ganz wichtig: Die einzelnen Typen haben verschiedene Wertigkeiten. Das heißt, eine reelle Zahl z. B. 1, rationale Zahl 2, ganze Zahl 3 etc. Wenn eine Operation auf Operanden angewandt wird, so soll das Ergebnis die Wertigkeit des jenigen Operanden übernehmen, der die kleinere Wertigkeitszahl hat. Bsp: <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>x</mi><mo>∈</mo><mrow><mi mathvariant="double-struck">R</mi></mrow><mo separator="true">;</mo><mi>y</mi><mo>∈</mo><mrow><mi mathvariant="double-struck">N</mi></mrow><mo separator="true">;</mo><mi>x</mi><mo>+</mo><mi>y</mi><mo>=</mo><mi>z</mi><mo separator="true">;</mo><mi>z</mi><mo>∈</mo><mrow><mi mathvariant="double-struck">R</mi></mrow></mrow><annotation encoding="application/x-tex">x \in \mathbb{R}; y \in \mathbb{N}; x + y = z; z \in \mathbb{R}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68889em;"></span><span class="strut bottom" style="height:0.88333em;vertical-align:-0.19444em;"></span><span class="base textstyle uncramped"><span class="mord mathit">x</span><span class="mrel">∈</span><span class="mord textstyle uncramped"><span class="mord mathbb">R</span></span><span class="mpunct">;</span><span class="mord mathit" style="margin-right:0.03588em;">y</span><span class="mrel">∈</span><span class="mord textstyle uncramped"><span class="mord mathbb">N</span></span><span class="mpunct">;</span><span class="mord mathit">x</span><span class="mbin">+</span><span class="mord mathit" style="margin-right:0.03588em;">y</span><span class="mrel">=</span><span class="mord mathit" style="margin-right:0.04398em;">z</span><span class="mpunct">;</span><span class="mord mathit" style="margin-right:0.04398em;">z</span><span class="mrel">∈</span><span class="mord textstyle uncramped"><span class="mord mathbb">R</span></span></span></span></span></li>
<li>Ich gebe zu, ich bin faul, also möchte ich mir gerne explizite Casts und enums (so was wie SCALAR_R, SCALAR_Q, SCALAR_N etc.) ersparen.</li>
</ul>
<p>Wenn ich jetzt meinen Ansatz mal auf folgendes Minimalbeispiel reduziere:</p>
<pre><code class="language-cpp">class Scalar
{
  public:
    virtual Scalar&amp; add(const Scalar&amp; other);
};

class Fraction : public Scalar
{
  public:
    virtual Fraction&amp; add(const Fraction&amp; other);
    virtual Fraction&amp; add(const UInteger&amp; other);
    virtual Fraction&amp; add(const Integer&amp; other);
};
</code></pre>
<p>Wie kriege ich (elegant <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/26a0.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--warning"
      title=":warning:"
      alt="⚠"
    /> ) den Compiler dazu, dass er das so kompiliert, wie ich will <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> Also ich meine, dass bei folgendem Snippet</p>
<pre><code class="language-cpp">Fraction f;
Scalar&amp; s = f;
s.add(f);
</code></pre>
<p>Fraction::add und nicht Scalar::add aufgerufen wird. Wie geht das? Muss ich vielleicht meinen Ansatz komplett umstrukturieren <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1023303</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1023303</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Fri, 24 Mar 2006 18:01:39 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 25 Mar 2006 11:18:05 GMT]]></title><description><![CDATA[<p>push</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1023617</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1023617</guid><dc:creator><![CDATA[picocat]]></dc:creator><pubDate>Sat, 25 Mar 2006 11:18:05 GMT</pubDate></item><item><title><![CDATA[Reply to Programmdesign eines Interpreters on Sat, 25 Mar 2006 15:39:48 GMT]]></title><description><![CDATA[<p>Oja, das selbe Problem hab ich auch... Hat den keiner eine Lösung?</p>
<p>Danke</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1023772</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1023772</guid><dc:creator><![CDATA[Rich2403]]></dc:creator><pubDate>Sat, 25 Mar 2006 15:39:48 GMT</pubDate></item></channel></rss>