Подтвердить что ты не робот

Объясните мне конкатенативные языки, как будто я восьмилетний

Я читал статью Википедии о конкатенативных языках, и теперь я более смущен, чем когда был.: -)

Что такое конкатенативный язык в терминах глупых людей?

4b9b3361

Ответ 1

На ваш простой вопрос здесь дан субъективный и аргументированный ответ.

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

Для меня это выглядит как термин, который дает Манфреду фон Туну место, где можно повесить шляпу, но может оказаться бесполезным для других программистов.

Хотя PostScript и Forth заслуживают изучения, я не вижу ничего страшного нового или интересного в языке программирования Манфреда фон Тхун Джоя. В самом деле, если вы читаете статью Криса Окасаки о методах встраивания языков постфикса в Haskell, вы можете попробовать все это в обстановке, которая, по сравнению с Джой, полностью распространена.

Так что мой ответ: нет простого объяснения, потому что не существует зрелой теории, лежащей в основе идеи конкатенативного языка. (Как сказали Эйнштейн и Фейнман, если вы не можете объяснить свою идею первокурснику из колледжа, вы на самом деле не понимаете ее.) Я пойду дальше и скажу, что изучение некоторых из этих языков, таких как Forth и PostScript, является превосходное использование времени, попытка выяснить, что именно люди имеют в виду, когда говорят "конкатенация", вероятно, пустая трата вашего времени.

Ответ 2

В обычных языках программирования у вас есть переменные, которые могут быть определены свободно, и вы вызываете методы, используя эти переменные в качестве аргументов. Они просты для понимания, но несколько ограничены. Часто трудно повторно использовать существующий метод, потому что вы просто не можете сопоставить существующие переменные с параметрами, которые требуется методу, или метод A вызывает другой метод B и A, который был бы идеальным для вас, если бы вы могли заменить вызов B с вызовом C.

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

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

Самая большая проблема заключается в том, что у вас нет намека на то, что происходит. Есть только несколько типов данных (список, строка, число), поэтому все сопоставляется с этим. Когда вы получаете часть данных, вам, как правило, не важно, что это такое или откуда оно происходит. Но это затрудняет отслеживание данных с помощью кода, чтобы увидеть, что с ним происходит.

Я считаю, что для успешного использования языков требуется определенный разум. Они не для всех.

[EDIT] У Форта есть некоторое проникновение, но не так много. Вы можете найти PostScript в любом современном лазерном принтере. Таким образом, они являются нишевыми языками.

С функционального уровня они равны с LISP, C-подобными языками и SQL: все они Turing Complete, поэтому вы можете вычислить что угодно. Это просто вопрос, сколько кода вам нужно написать. Некоторые вещи более просты в LISP, некоторые из них более просты в C, некоторые из них более простые в языках запросов. Вопрос, который "лучше", бесполезен, если у вас нет контекста.

Ответ 3

Сначала я сделаю опровержение утверждения Нормана Рэмси о том, что теории нет.

Теория конкатенативных языков

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

Так, например, в Исчислении SKI Combinator (одном из простейших функциональных языков) два члена бок о бок эквивалентны применению первого слагаемого ко второму слагаемому. Например: S K K эквивалентно S(K)(K).

В конкатенативном языке S K K будет эквивалентен S . K . K в Haskell.

Итак, какое большое дело

Чистый конкатенативный язык обладает интересным свойством, что порядок оценки членов не имеет значения. На конкатенативном языке (S K) K совпадает с S (K K). Это не относится к исчислению SKI или к любому другому языку функционального программирования, основанному на функциональном приложении.

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

Теперь для реального мира

Семантика языков на основе стека, которые поддерживают функции более высокого порядка, может быть объяснена с помощью конкатенативного исчисления. Вы просто сопоставляете каждый термин (command/expression/sub-program) как функцию, которая принимает функцию как входную и возвращает функцию в качестве вывода. Вся программа эффективно представляет собой одну функцию преобразования стека.

Реальность такова, что вещи всегда искажены в реальном мире (например, FORTH имеет глобальный словарь, PostScript делает странные вещи, в которых имеет смысл порядок оценки). Большинство практических языков программирования не полностью соответствуют теоретической модели.

Заключительные слова

Я не думаю, что типичный программист или 8-летний человек должен когда-либо беспокоиться о том, что такое конкатенативный язык. Я также не считаю его особенно полезным для языков программирования с голубями как типа X или типа Y.

Ответ 4

После прочтения http://concatenative.org/wiki/view/Concatenative%20language и опираясь на то, что мало помню, когда я играл с Forth в подростковом возрасте, я считаю, что ключевое в конкатенативное программирование связано с:

  • просмотр данных в терминах значений в конкретном стеке данных
  • и функции, манипулирующие материалом в терминах значений popping/pushing в том же стеке данных

Проверьте эти цитаты на приведенной выше веб-странице:

Есть два условия, которые бросаются вокруг, язык стека и конкатенативный язык. Оба определяют аналогичные, но не равные классы языки. По большей части, хотя, они идентичны.

Сегодня большинство языков широко используется являются применимыми языками: центральным построение на языке - это некоторая форма вызова функции, где функция применяется к набору параметров, где каждый параметр сам является результатом вызов функции, имя переменной или константой. В стеке языков, вызов функции выполняется просто написание имени функция; параметры неявные, и они уже должны быть на стек при вызове. результат вызова функции (если есть) затем остается в стеке после возвращает функцию для следующего функции для потребления и т.д. Поскольку функции вызываются просто упомянув их имя без каких-либо дополнительный синтаксис, Forth и Factor ссылайтесь на функции как "слова", потому что в синтаксисе они действительно просто слова.

Это в отличие от аппликативных языков, которые применяют свои функции непосредственно к определенным переменным.

Пример: добавление двух чисел.

Аппликативный язык:

int foo(int a, int b)
{
    return a + b;
}

var c = 4;
var d = 3;
var g = foo(c,d);

Конкатенативный язык (я сделал это, предположил, что он похож на Forth...;))

push 4
push 3
+
pop

Хотя я не думаю, что конкатенативный язык = язык стека, как отмечают авторы выше, кажется похожим.

Ответ 5

Я считаю, что основная идея: 1. Мы можем создавать новые программы, просто объединяя другие программы вместе.

Кроме того, 2. Любой случайный фрагмент программы является допустимой функцией (или подпрограммой).

Хороший старый чистый RPN Forth имеет эти свойства, исключая любой случайный синтаксис без RPN.

В программе 1 2 + 3 * подпрограмма + 3 * принимает 2 аргумента и дает 1 результат. Подпрограмма 2 принимает 0 аргументов и возвращает результат 1. Любой кусок - это функция, и это приятно!

Вы можете создавать новые функции, комбинируя два или более других вместе, возможно, с небольшим клеем. Он будет работать лучше всего, если типы совпадают!

Эти идеи действительно хороши, мы ценим простоту.

Это не ограничивается серийным языком RPN Forth, а также обязательным или функциональным программированием. Эти две идеи также работают для графического языка, где программные единицы могут быть, например, функциями, процедурами, отношениями или процессами.

В сети коммуникационных процессов каждая подсистема может действовать как процесс.

В графе математических отношений каждый подграф является действительным соотношением.

Эти структуры являются "конкатенативными", мы можем каким-либо образом разбить их (нарисовать круги) и объединить их вместе разными способами (рисовать линии).

Ну, как я это вижу. Я уверен, что пропустил много других хороших идей из конкатенирующего лагеря. Хотя я увлекаюсь графическим программированием, я новичок в этом сосредоточении на конкатенации.

Ответ 6

Мое прагматическое (и субъективное) определение для конкатенативного программирования (теперь вы можете избежать прочтения всего остального):

-> Композиция функций экстремальными способами (с синтаксисом обратной польской нотации (RPN)):

( Forth code )
: fib
  dup 2 <= if
    drop 1
  else
    dup 1 - recurse
    swap 2 - recurse +
  then ;

-> все является функцией или, по крайней мере, может быть функцией:

( Forth code )
: 1 1 ; \ define a function 1 to push the literal number 1 on stack

-> аргументы передаются неявно через функции (хорошо, похоже, это определение для неявного программирования), но это в Forth:

a b c

может быть в Lispе:

(c a b)
(c (b a))
(c (b (a)))

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

( Forth code )
: <- execute ; \ apply function

итак, вы получите:

a b c <- \ Lisp: (c a b)
a b <- c <- \ Lisp: (c (b a))
a <- b <- c <- \ Lisp: (c (b (a)))

Ответ 7

Вы не можете объяснить язык, просто получите один (Factor, желательно) и попробуйте некоторые учебные пособия. Учебники лучше, чем ответы Stack Overflow.