Можно ли легко использовать Lisp в неизменяемой функциональной манере?

У меня есть опыт работы с Haskell, и я хочу изучить Common Lisp.

Хорошо обсуждалось, что CL «не является функциональным языком», но я хотел бы знать, можно ли его использовать в качестве функционального языка.

Например, можно ли неизменно использовать все типы данных? Хэш-таблицы Common Lisp, по-видимому, устанавливаются с использованием setf, что явно имеет изменяемую ориентацию. Есть ли способ использовать его неизменным образом?

Помимо аспекта «IO» Common Lisp («чисто» аспекта Haskell), где я взаимодействую с файлами, сетями и т. д., могу ли я удобно писать код на Lisp и быть уверенным, что код будет иметь ссылочную прозрачность?

Могу ли я ожидать таких свойств от популярных библиотек, доступных в Common Lisp?

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


person Community    schedule 26.01.2019    source источник
comment
Common Lisp был специально разработан, чтобы приспособить, по крайней мере, императивное программирование, функциональное программирование, объектно-ориентированное программирование. То, как вы его используете, конечно же, зависит от вас. Если вы пишете программы без каких-либо побочных эффектов, вы создадите программу со ссылочной прозрачностью (другими словами, на языке спецификация возможные побочные эффекты операторов хорошо задокументированы).   -  person Renzo    schedule 26.01.2019
comment
Изучение Common Lisp как своего рода Haskell со скобками на самом деле не так уж полезно, потому что Common Lisp — это совершенно другой язык и экосистема. «в Риме поступай, как римляне».   -  person Rainer Joswig    schedule 26.01.2019
comment
Вы говорите, что хорошо обсуждалось, что CL не является функциональным языком, но моя интерпретация такова, что это не только функциональный язык. Если Lisp не функциональный язык, то что?   -  person coredump    schedule 26.01.2019
comment
См., например. github.com/danlentz/cl-ctrie   -  person coredump    schedule 26.01.2019
comment
@RainerJoswig Разве это не часть философии Лиспа, хотя язык должен адаптироваться к варианту использования, а не заставлять всех использовать его одинаковым образом?   -  person leftaroundabout    schedule 26.01.2019
comment
@leftaroundabout: зачем игнорировать существующий язык Common Lisp с более чем 1000 операторов, типов данных, управляющих структур, переменных и т. д., возможно, лучше, чем разочаровываться в том, что CL — это не Haskell, а всего лишь плохая замена Haskell. Также имейте в виду, что формирование языка для поддержки программирования без побочных эффектов эффективным способом может оказаться задачей не для новичка без более глубокого знания языка...   -  person Rainer Joswig    schedule 26.01.2019
comment
способ использовать [что-либо] неизменным образом — всегда изменять копию, а не оригинал. -- CL - императивный язык, ИМО. Любой императивный язык может использоваться для функционального кодирования (например, C). Я думаю, что отдельные правила вычисления и пространство имен для функций сделают его очень чуждым по сравнению с Haskell. Но в CL возможно все.   -  person Will Ness    schedule 26.01.2019
comment
Я бы сказал, что сила CL в том, что она мультипарадигма. Конечно, вы можете формировать язык по своему желанию и желанию. Но также частью философии CL является использование различных парадигм (FP, OOP, императив, логическое программирование, ...) для соответствующих частей программы. И с точки зрения производительности будет очень эффективно использовать мутацию, но в ограниченном виде.   -  person Gwang-Jin Kim    schedule 28.01.2019


Ответы (1)


Да, конечно, но в зависимости от того, насколько вы хотите, чтобы ограничения применялись, ваш пробег может варьироваться.

Только не мутируй

Вы можете просто избегать setf и всех мест с машинами. Если вам приходится использовать хэш-таблицы или векторы, вы будете много копировать, но для многих приложений накладные расходы на сборку мусора все еще могут быть управляемыми. Во многих местах вы можете использовать списки или списки, с которыми можно обращаться почти как с функциональными структурами данных. Некоторые полезные утилиты находятся в alexandria, т.е. г. copy-hash-table, у которого есть аргумент key, фактически делающий что-то вроде гипотетического map-hash-table. Все остальные функциональные преимущества, такие как функции высшего порядка, map, reduce, remove и т. д., доступны во многих вариантах. Кроме того, некоторые варианты использования могут быть решены довольно декларативно в loop.

Существуют также библиотеки, которые явно упрощают этот стиль, например. г. modf.

Это может завести вас довольно далеко. Я считаю, что легко увидеть, где вы нарушаете ссылочную прозрачность, и избежать этого.

Используйте функциональные структуры данных

Существует FSet, который дает вам множество функциональных структур данных, и есть sycamore, где есть еще кое-что.

Используйте датчики

SERIES появился в CLtL2 в 1990 году и почти стал стандартом в 1994 году. Существует также краны, что добавляет некоторые полезные функции.

Медитировать

Лично я уже не так требователен к чистоте. Иногда легче понять изменение места в цикле, чем жонглирование несколькими привязками в разных экстентах. Я просто сдерживаю мутацию; это похоже на концепцию владения данными. Однако мне нравится иметь чистоту в большем масштабе, как в памяти, так и на диске, т.е. г. журналы только для добавления, базы данных (bknr.datastore).

person Svante    schedule 26.01.2019