Автор Тема: [Oberon7] "Man or Boy test" by Donald Knuth  (Прочитано 45676 раз)

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
[Oberon7] "Man or Boy test" by Donald Knuth
« : Июль 04, 2013, 08:58:57 pm »
"Man or boy?" Donald Knuth

http://rosettacode.org/wiki/Man_or_boy_test

Попробовал решение для онлайн-компилятора Оберона-7:
MODULE test;
IMPORT JS;

TYPE Function = PROCEDURE ():INTEGER;

PROCEDURE F0():  INTEGER; BEGIN RETURN  0 END F0;
PROCEDURE F1():  INTEGER; BEGIN RETURN  1 END F1;
PROCEDURE Fn1(): INTEGER; BEGIN RETURN -1 END Fn1;

PROCEDURE A(ink: INTEGER; x1, x2, x3, x4, x5: Function): INTEGER;
VAR
  res : INTEGER;
  k   : INTEGER;

  PROCEDURE B(): INTEGER;
  BEGIN
    DEC(k);
    RETURN A(k, B, x1, x2, x3, x4)
  END B;

BEGIN
  k := ink;
  IF k <= 0 THEN
    res := x4() + x5();
  ELSE
    res := B();
  END;
  RETURN res
END A;

BEGIN
    JS.alert(A(10, F1, Fn1, Fn1, F1, F0))
END test.

а он мне раз и заявил: "Нельзя, мол, ссылаться на локальную процедуру"!
Компилятор от akron1 с ним солидарен...

Я что-то запямятовал -- в Обероне-7 действительно есть такое ограничение?
Если есть, значит для Оберона-7 нельзя сделать "взрослый" компилятор (Man)? Язык вынуждает компиляторы быть "детскими" (Boy)?

ЗЫ. Ну и моё решение для хацкеля (зря что ли его делал):
import Data.IORef
import Control.Monad

main = do
    k <- newIORef 10
    print =<< a k (return 1) (return (-1)) (return (-1)) (return 1) (return 0)

a in_k x1 x2 x3 x4 x5 = do
    k <- newIORef =<< readIORef in_k
    let b = do
            k `modifyIORef` (\x -> x-1)
            a k b x1 x2 x3 x4

    k' <- readIORef k
    if k' <= 0 then liftM2 (+) x4 x5 else b
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #1 : Июль 04, 2013, 09:04:54 pm »
Есть такое ограничение:
Цитировать
6.5. Procedure types
Variables of a procedure type T have a procedure (or NIL) as value. If a procedure P is assigned to
a procedure variable of type T, the (types of the) formal parameters of P must be the same as those
indicated in the formal parameters of T. The same holds for the result type in the case of a function
procedure (see 10.1). P must not be declared local to another procedure, and neither can it be a
standard procedure.
Y = λf.(λx.f (x x)) (λx.f (x x))

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #2 : Июль 05, 2013, 03:18:41 pm »
Я что-то запямятовал -- в Обероне-7 действительно есть такое ограничение?

Оно всегда так было в паскалях. Типа - скажи нет скрытой неэффективности. Не говоря об усложнении компилятора :) В общем случае связанный с локальной процедурой контекст (локальные переменные) надо где-то хранить (в куче). Кроме того, есть еще VAR-параметры... Короче не работает это для оберонов.

P.S. Хотя с точки зрения транслятора в жабаскрипт никаких проблем нет, т.е. это чисто искусственное ограничение, чтобы остаться верным букве репорта.
« Последнее редактирование: Июль 05, 2013, 03:20:56 pm от vlad »

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #3 : Июль 05, 2013, 04:13:05 pm »
Я что-то запямятовал -- в Обероне-7 действительно есть такое ограничение?

Оно всегда так было в паскалях. Типа - скажи нет скрытой неэффективности. Не говоря об усложнении компилятора :) В общем случае связанный с локальной процедурой контекст (локальные переменные) надо где-то хранить (в куче). Кроме того, есть еще VAR-параметры... Короче не работает это для оберонов.

При этом в Модуле-3 это работает...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #4 : Июль 05, 2013, 05:00:23 pm »
Думаю обсуждение пойдет бодрее, если ты сформулируешь задачу на русском.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #5 : Июль 05, 2013, 05:14:19 pm »
Думаю обсуждение пойдет бодрее, если ты сформулируешь задачу на русском.

На русском она описана тут: "О распределении памяти при выполнении теста Кнута"

Там суть в том, что бы вызвать взаимную рекурсию двух процедур, одна из которых является локальной для другой и имеет доступ к объемлющему контексту текущего вызова (замыкание с мутабельной переменной).
При этом уже на небольших параметрах происходит большая нагрузка на стек...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #6 : Июль 05, 2013, 05:27:50 pm »
Я что-то запямятовал -- в Обероне-7 действительно есть такое ограничение?

P.S. Хотя с точки зрения транслятора в жабаскрипт никаких проблем нет, т.е. это чисто искусственное ограничение, чтобы остаться верным букве репорта.

А может стоит убрать это ограничение? Ведь данный транслятор не предназначен для генерации кода для мелкоконтроллеров, и в нём оно не имеет особого смысла...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #7 : Июль 05, 2013, 06:33:51 pm »
Я что-то запямятовал -- в Обероне-7 действительно есть такое ограничение?

P.S. Хотя с точки зрения транслятора в жабаскрипт никаких проблем нет, т.е. это чисто искусственное ограничение, чтобы остаться верным букве репорта.

А может стоит убрать это ограничение? Ведь данный транслятор не предназначен для генерации кода для мелкоконтроллеров, и в нём оно не имеет особого смысла...
Это нарушит совместимость и создаст еще один диалект. Кроме того, современный Оберон, как и раньше, позиционируется как язык общего назначения, а не только для микроконтроллеров
.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #8 : Июль 05, 2013, 06:37:06 pm »
Я что-то запямятовал -- в Обероне-7 действительно есть такое ограничение?

P.S. Хотя с точки зрения транслятора в жабаскрипт никаких проблем нет, т.е. это чисто искусственное ограничение, чтобы остаться верным букве репорта.

А может стоит убрать это ограничение? Ведь данный транслятор не предназначен для генерации кода для мелкоконтроллеров, и в нём оно не имеет особого смысла...

Это нарушит совместимость и создаст еще один диалект. Кроме того, современный Оберон, как и раньше, позиционируется как язык общего назначения, а не только для микроконтроллеров .

Да кому нужна эта совместимость оберонов при таком неполном их описании?
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #9 : Июль 05, 2013, 06:40:44 pm »
Нам нужен. Что бы наши компиляторы были совместимы хотя бы на базовом уровне.
Y = λf.(λx.f (x x)) (λx.f (x x))

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #10 : Июль 06, 2013, 12:00:52 pm »
Нам нужен. Что бы наши компиляторы были совместимы хотя бы на базовом уровне.

Ты рассуждаешь как схоласт, а не как истинный оберонщик, последователь Вирта.
Ведь что говорят оберонщики: "Вот вам минимальное языковое ядро, для своей задачи расширяйте его как хотите..."
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

DddIzer

  • Гость
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #11 : Июль 06, 2013, 12:27:25 pm »

Ведь что говорят оберонщики: "Вот вам минимальное языковое ядро, для своей задачи расширяйте его как хотите..."
полный п..ж они говорят.. "Вот вам минимальное языковое ядро... и на все ваши задачи его вполне хватит"

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #12 : Июль 06, 2013, 12:34:21 pm »
Попробовал решение для онлайн-компилятора Оберона-7:
...
а он мне раз и заявил: "Нельзя, мол, ссылаться на локальную процедуру"
Может, получится выкрутиться средствами модуля JS?

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #13 : Июль 06, 2013, 12:54:39 pm »
Попробовал решение для онлайн-компилятора Оберона-7:
...
а он мне раз и заявил: "Нельзя, мол, ссылаться на локальную процедуру"
Может, получится выкрутиться средствами модуля JS?

Проще уж сразу на JS сделать. На JS тут проблемы не возникает:
var JS = function(){return this;}();
var test = function (){

function F0(){
return 0;
}

function F1(){
return 1;
}

function Fn1(){
return -1;
}

function A(ink/*INTEGER*/, x1/*Function*/, x2/*Function*/, x3/*Function*/, x4/*Function*/, x5/*Function*/){
var res = 0;
var k = 0;

function B(){
--k;
return A(k, B, x1, x2, x3, x4);
}
k = ink;
if (k <= 0){
res = x4() + x5();
}
else {
res = B();
}
return res;
}
JS.alert(A(10, F1, Fn1, Fn1, F1, F0));
}();
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: [Oberon7] "Man or Boy test" by Donald Knuth
« Ответ #14 : Июль 06, 2013, 01:46:56 pm »
Ты рассуждаешь как схоласт, а не как истинный оберонщик, последователь Вирта.
Ведь что говорят оберонщики: "Вот вам минимальное языковое ядро, для своей задачи расширяйте его как хотите..."

Минимальное "расширение", которое практически не повлияет на эффективность (не требует GC и кучи) и на другие аспекты языка, а также сохранит пресловутую "герметичность", я представляю так:
- Вводится маркер для параметра процедуры (по аналогии с VAR), что этот параметр процедурного типа может быть локальной процедурой из процедуры выше по стеку. Например некий LOCAL:
PROCEDURE p(f: LOCAL PROCEDURE);
- Такая "LOCAL f" может быть только вызвана или передана в другую процедуру, но не может быть приведена к обычной процедурной переменной и не может быть передана по ссылке (VAR).
- Обычная процедурная переменная или процедура может быть передана как LOCAL (хотя можно сделать более интересно, но это отдельная тема).

Такое расширение позволит решить оригинальную задачу. Кроме того, можно попытаться написать хоть какую-нибудь библиотеку алгоритмов - тот же sort/find/for_each без тех ужасов, которые надо городить сейчас. И вообще появятся хоть какие-то зачатки функционального программирования в обероне. В оригинальном виде локальные процедуры в обероне имеют совсем мало смысла (не зря их Вирт собирается выпилить).
« Последнее редактирование: Июль 06, 2013, 01:49:09 pm от vlad »