2012-04-14 2 views
2

В настоящее время я беру курс обучения в университете и замечаю, что я откусил немного больше, чем могу пережевывать. Курс посвящен языку программирования Oz, и я читаю электронную книгу об этом, чтобы лучше узнать его, и я пытаюсь решить некоторые упражнения, чтобы проверить мое понимание. Я довольно застрял в определенном упражнении, и я не совсем понимаю, как его решить. Вопрос:Порты и ячейки в Оз

Реализация портов. В главе 5 мы ввели понятие порта, , который является простым каналом связи. Порты имеют операции {NewPort S P}, которые возвращают порт P с потоком S и {Send P X}, , который отправляет сообщение X на порт P. Из этих операций видно, что порты представляют собой разделенный на состояние ОБЪЯВЛЕНИЕ ADT. Для этого выполните реализацию портов в терминах ячеек, используя методы раздела 6.4.

Ключевые слова с сохранением состояния и элементы. Я пытался реализовать поведение портов с использованием клеток со следующим подходом:

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} 

Мой последний шаг будет добавить обертку/пару для развертывания для обеспечения защиты ADT, но сначала я хочу функциональность, чтобы работать должным образом. Это похоже на правильное поведение, но это не так, как я этого хотел. Я хотел был бы иметь возможность позвонить {Browse MyStream}, без @, только один раз. Я надеялся, что браузер отобразит что-то по линиям firstSent|secondSent|_<future>, вместо этого отобразит <Cell>, как и следовало ожидать, и мне нужно вызвать Browse на него после каждого Send, а вывод будет показан в виде списка: [firstSent secondSent].

Если я правильно помню теорию, которую я читал, это связано с нетерпением и ленивой оценкой, соответственно приводящей к (конечным) спискам vs (бесконечных) потоков.

У меня такое чувство, что я не делаю это совершенно правильно, хотя у меня нет опыта с функциональными языками, может ли кто-нибудь помочь мне с примером порта, реализованного с помощью ячеек? (В основном ваша собственная реализация существующего NewPort и Send)

Спасибо заранее

+1

FYI (и не имеет значения) фраза: «Я откусила больше, чем я могу пережевывать» :-) – paxdiablo

+0

Спасибо, я не носитель английского языка, но я исправлю это: P – Warkst

ответ

1

Поток представляет собой список с несвязанным хвостом. Например. первоначально список - это просто несвязанная переменная _. Всякий раз, когда элемент послан, хвост привязан к новой паре, например .:

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

Хвост всегда остается несвязанным, если не закрыть порт.

Теперь вы используете ячейку как указатель на конец списка. Первоначально ячейка просто указывает на S. Затем операция SendEx состоит из следующих этапов:

(1) Read the current tail from the cell. 
(2) Declare a new unbound variable that will serve as the new tail. 
(3) Unify: current tail = X | new tail 
(4) Store the new tail in the cell. 

Надеюсь, это поможет.

+0

Я думаю Я понимаю все, кроме одного ... На шаге 3 вы заменяете текущий хвост (unbound) на X | новый хвост (из которого новый хвост также несвязан). Но как вы можете привязать хвост, если он объявлен как переменная только для чтения? – Warkst

+0

Ой, думаю, я понял ...вы не определяете хвост как только для чтения, но вы возвращаете поток в виде списка только для чтения, не так ли? Таким образом, объект stream - это весь список, и ячейка отслеживает хвост, поэтому вы можете привязываться к концу потока с помощью объединения. Я думаю, что так оно и работает, исправьте меня, если я ошибаюсь: D – Warkst

+1

@Warkst: Да, точно! – wmeyer

Смежные вопросы