2012-04-14 9 views
2

Ich mache gerade einen Teach-yourself-Kurs an der Universität und merkte, dass ich ein bisschen mehr abgebissen habe, als ich kauen kann. Der Kurs handelt von der Oz Programmiersprache und ich lese ein E-Book darüber, um es besser kennenzulernen und versuche einige Übungen zu lösen, um mein Verständnis zu testen. Ich bin ziemlich fest auf einer bestimmten Übung und ich weiß nicht, wie ich es lösen soll. Die Frage lautet:Ports und Zellen in Oz

Implementierung von Ports. In Kapitel 5 haben wir das Konzept des Ports eingeführt, der ein einfacher Kommunikationskanal ist. Ports haben die Operationen {NewPort S P}, die einen Port P mit Stream S zurücksenden, und {Send P X}, , der Nachricht X an Port P sendet. Aus diesen Operationen ist klar, dass Ports ein zustandsfester entbündelter ADT sind. Für diese Übung implementieren Sie Ports in Bezug auf Zellen, unter Verwendung der Techniken von Abschnitt 6.4.

Die Schlüsselwörter sind Stateful entbündelt und Zellen. Ich habe versucht, das Verhalten von Ports mit dem folgenden Ansatz unter Verwendung von Zellen zu implementieren:

declare 
MyPort 
MyStream 
proc {NewPortEx ?S ?P} 
    P = {NewCell nil} 
    S = !!P %read only view on the cell 
end 
proc {SendEx P X} 
    P:=X|@P %extend the cell's content, a list, with X 
end 
in 
{NewPortEx MyStream MyPort} 
{Browse @MyStream} 
{SendEx MyPort c} 
{Browse @MyStream} 

Mein letzter Schritt ein Wrapper/Unwrapper Paar hinzuzufügen wäre die ADT sicherer zu machen, aber zunächst möchte ich die Funktionalität ordnungsgemäß funktioniert. Dies scheint das richtige Verhalten zu tun, aber es ist nicht so, wie ich es wollte. Ich würde gerne {Browse MyStream}, ohne die @, nur einmal anrufen können. Ich hatte gehofft, dass der Browser etwas in der Richtung von firstSent|secondSent|_<future> anzeigen würde stattdessen zeigt es <Cell>, wie zu erwarten ist, und ich muss Browse darauf nach jeder Send aufrufen, und die Ausgabe wird als eine Liste angezeigt: [firstSent secondSent].

Wenn ich mich richtig an die Theorie erinnere, die ich gelesen habe, hat dies mit eifriger vs fauler Auswertung zu tun, bzw. resultierend in (endlichen) Listen gegen (unendliche) Ströme.

Ich habe das Gefühl, dass ich es nicht ganz richtig mache und ich habe keinerlei Erfahrung mit funktionalen Sprachen. Kann mir jemand helfen, ein Beispiel für einen mit Zellen implementierten Port zu geben? (Im Grunde eine eigene Implementierung des bestehenden NewPort und Send)

Vielen Dank im Voraus

+1

FYI (und irrelevant), der Satz ist "Ich habe mehr abgebissen als ich kann kauen" :-) – paxdiablo

+0

Danke, ich bin kein englischer Muttersprachler, aber ich werde das korrigieren dann: P – Warkst

Antwort

1

Ein Stream ist nur eine Liste mit einem ungebundenen Schwanz. Z.B. Anfangs ist die Liste nur eine nicht gebundene Variable _. Jedes Mal, wenn ein Element gesendet wird, wird der Schwanz auf ein neues Paar gebunden, z.B .:

(1) Initially:   S = _ 
(2) Send 1 to the port: S = 1|_ 
(3) Send 2 to the port: S = 1|2|_ 
etc. 

Der Schwanz bleibt immer ungebunden, wenn Sie den Port schließen.

Jetzt verwenden Sie die Zelle wie einen Zeiger auf das Ende der Liste. Anfänglich zeigt die Zelle nur auf S. Der SendEx-Vorgang besteht dann aus diesen Schritten:

Hoffe, das hilft.

+0

Ich denke Ich verstehe alles außer einer Sache ... In Schritt 3 ersetzen Sie den aktuellen Schwanz (ungebunden) durch X | neuer Schwanz (dessen neuer Schwanz ebenfalls ungebunden ist). Aber wie können Sie den Schwanz binden, wenn er als schreibgeschützte Variable deklariert ist? – Warkst

+0

Oh warte ich glaube ich habe es ...Du definierst den Tail nicht als schreibgeschützt, sondern gibst den Stream als schreibgeschützte Ansicht der Liste zurück, richtig? Das Stream-Objekt ist also die gesamte Liste und die Zelle verfolgt den Schwanz, so dass Sie mithilfe von Vereinheitlichung an das Ende des Streams binden können. Ich denke, so funktioniert es, korrigiere mich, wenn ich falsch liege: D – Warkst

+1

@Warkst: Ja, genau richtig! – wmeyer