Может ли конкатенационный язык использовать префиксную нотацию? - PullRequest
2 голосов
/ 03 марта 2012

Конкатенативные языки обладают некоторыми очень интригующими характеристиками, такими как способность составлять функции разной степени сложности и возможность выделять любой раздел функции.Тем не менее, многие люди увольняют их из-за использования постфиксной нотации и сложности чтения.Кроме того, польские, вероятно, не ценят людей, использующих свои тщательно разработанные обозначения задом наперед.

Итак, возможно ли иметь префиксную запись?Если это так, какие будут компромиссы?

У меня есть представление о том, как это может работать, но у меня нет опыта работы с конкатенационными языками, поэтому я, вероятно, что-то упускаю.По сути, функция будет оцениваться в обратном порядке, а значения будут извлекаться из стека в обратном порядке.Чтобы продемонстрировать это, я сравним постфикс с тем, как будет выглядеть префикс.Вот некоторые конкатенативные выражения с традиционной постфиксной нотацией.

5 dup *                             ! Multiply 5 by itself
3 2 -                               ! Subtract 2 from 3
(1, 2, 3, 4, 5) [2 >] filter length ! Get the number of integers from 1 to 5
                                    ! that are greater than 2

Выражения вычисляются слева направо: в первом примере 5 помещается в стек, затем dup дублирует верхнюю частьзначение в стеке, то * умножает два верхних значения в стеке.Функции извлекают свой последний аргумент первым из стека: во втором примере, когда вызывается -, 2 находится на вершине стека, но это последний аргумент.

Вот что ядумаю, что префиксная нотация будет выглядеть так:

* dup 5
- 3 2
length filter (1, 2, 3, 4, 5) [< 2]

Выражения вычисляются справа налево, и функции извлекают первый аргумент из стека.Обратите внимание, что пример фильтра префиксов читается гораздо ближе к его описанию и выглядит как аппликативный стиль.Одна проблема, которую я заметил, состоит в том, что факторизация вещей может быть не такой полезной.Например, в постфиксной нотации вы можете выделить 2 - из 3 2 -, чтобы создать функцию subtractTwo.В префиксной нотации вы можете выделить - 3 из - 3 2, чтобы создать функцию subtractFromThree, которая не выглядит столь же полезной.

Запрещение любых явных проблем, возможно, конкатенирующий язык, использующий префиксную нотацию, может победитьлюди, которые не любят постфиксную запись.Любое понимание приветствуется.

Ответы [ 4 ]

3 голосов
/ 21 мая 2015

Я только что прочитал о Om Language

Кажется, о чем вы говорите.Из его описания (выделено мной):

Язык Om:

  • новый, максимально простой конкатенативный , гомоиконическое программирование и нотация алгоритмовязык с:
    • минимальным синтаксисом, состоящим только из трех элементов.
    • префиксная нотация , в которой функции управляют остальной частью самой программы.[...]

В нем также говорится, что он еще не закончен и еще многое изменится.

Тем не менее, похоже, чтоработает, и действительно интересно как подтверждение концепции.

3 голосов
/ 22 мая 2012

Я пишу такой язык прямо сейчас, как это происходит, и до сих пор мне нравятся некоторые побочные эффекты использования префиксной нотации.Семантика основана на Joy:

  • Файлы анализируются слева направо, но выполняются справа налево.
  • По расширению определения должны приходить после точка, в которой они используются.
  • Как приятный побочный эффект, комментарии - это просто списки, которые удаляются.

Вот факториальная функция, например:

def 'fact [cond [* fact - 1 dup] [1 drop] dup]

Мне также легче рассуждать о коде, когда я пишу его, но у меня нет сильного опыта в конкатенационных языках.Вот мой (вероятно, наивный) вывод функции карты над списками.Функция 'nb' отбрасывает что-то и используется для комментариев.'stash [f]' входит в темп, запускает 'f' для остальной части стека, затем возвращает темп обратно.

def 'map [q [cons map stash [head swap i] dup stash [tail dup]] [nb] is_cons nip]
nb [map [f] (cons x y) -> cons map [f] x f y
    stash [tail dup]    [f] (cons x y)       = [f] y (cons x y)
    dup                 [f] y (cons x y)     = [f] [f] y (cons x y)
    stash [head swap i] [f] [f] y (cons x y) = [f] x (f y)
    cons map            [f] x (f y)          = cons map [f] x f y

    map [f] [] -> []]
3 голосов
/ 03 сентября 2012

Ну, конечно, если ваши слова все еще с фиксированной арностью, то это просто вопрос выполнения токенов справа налево.

Только из-за функций n-arity обозначение префикса подразумевает круглые скобки, и только из-за того, что человеческий «порядок чтения» совпадает с порядком выполнения, языковой стек подразумевает постфикс.

0 голосов
/ 08 марта 2012

Я представляю себе конкатенирующий префиксный язык без стека.Он может вызывать функции, которые затем интерпретируют код, пока не получат все необходимые операнды.Затем интерпретатор вызывает следующую функцию.Потребуется только одна конструкция памяти - результат.Все остальное можно прочитать из исходного кода во время выполнения.Как вы могли заметить, я говорю о интерпретируемом языке, а не скомпилированном.

...