Lisp에 여전히 다른 프로그래밍 언어에서 채택되지 않은 특수 기능이 있습니까?


35

Lisp에 여전히 다른 프로그래밍 언어에서 채택되지 않은 특수 기능이 있습니까?

Lisp은 모든 Lisp 프로그래밍 언어를 전체적으로 의미합니다. 나는 Lisp이 얼마나 놀라운 지에 대해 들었고 많은 언어가 Lisp에서 영감을 받았다는 것을 알고 있습니다. 그러나 Lisp에는 여전히 다른 언어로는 불가능한 독점적 인 디자인 기능이 있습니까?

내가 질문을 한 이유는 최근에 아마추어 프로그래머 인 나는 Clojure 를 재미있게 배우기 시작했고 그 결과 Lisp 관련 게시물과 댓글을 많이 찾았지만 한 가지만 언급했기 때문입니다. ", 그러나 다른 현대 프로그래밍 언어는 조건부, 재귀 및 일류 시민으로서의 기능과 같은 Lisp의 많은 아이디어를 이미 채택하고 도난당했습니다. 심지어 메타 프로그래밍 도 여러 언어로 수행 할 수 있습니다.

내가 놓친 부분이 있습니까? "아직도 여전히 다릅니다"?

또는 다른 현대 언어가 Lisp의 모든 좋은 부분을 훔쳐서 Lisp 세계를 괄호 로 파고들 필요가 없기 때문에 운이 좋으며 "Lisp는 달랐습니다".


3
연구 결과를 공유하면 모든 사람에게 도움이됩니다. 당신이 무엇을 시도했고 왜 그것이 당신의 요구를 충족시키지 못했는지 알려주십시오. 이것은 당신이 시간을내어 자신을 돕기 위해 노력했고, 명백한 답변을 되풀이하는 것을 막아 주며, 무엇보다도보다 구체적이고 적절한 답변을 얻는 데 도움이됩니다. 또한 물어
gnat

3
@gnat Thx에 대한 조언을 구하고 내 질문을 업데이트했습니다 :)
iceX

10
한 가지 문제는 언어에 Lisp 기능의 특정 하위 집합 (예 : S- 표현식 및 매크로)이 있으면 언어가 Lisp이라고 주장하는 것입니다. 물론 (이 사람들에 따르면) 리스프가 아닌 언어는 이러한 기능을 가질 수 없습니다.

9
둥근 괄호가 모든 것을 그룹화하는 유일한 형태 인 다른 언어는 없다고 생각합니다 :-)
Doc Brown

가족으로서의 리스프는별로 독특하지는 않지만, 많은 리스프 방언 (라켓, CL, 구성표, 클로저)은 여전히 ​​많은 유용한 / 고유 한 기능을 제공합니다.
jozefg

답변:


28

이 유형의 질문에 대한 표준 참조는 Paul Graham의 Lisp를 다르게 만든 것 입니다. 작성 당시이 기사에 따르면 널리 사용되지 않는 Lisp의 나머지 두 가지 주요 기능은 다음과 같습니다.

8. 기호 트리를 사용 하는 코드 표기법 .

9. 항상 사용 가능한 언어. 읽기 시간, 컴파일 시간 및 런타임은 실제로 구별되지 않습니다. 런타임에 코드를 읽거나 컴파일하는 동안 코드를 컴파일 또는 실행하고, 컴파일하는 동안 코드를 읽거나 실행하며, 코드를 읽거나 컴파일 할 수 있습니다.

주석은 각 요점을 다루고 해당 기능을 사용할 수있는 인기있는 언어를 말합니다.

(9) 리스프 매크로를 가능하게하는 8은 아마도 리스프 만의 고유 한 특징 일 것입니다. 더 이상 새로운 언어를 발명했다고 주장 할 수 없으며 Lisp의 새로운 방언을 디자인 한 것만 가능합니다. -)

이 기사는 2002 년에 마지막으로 개정되었으며 지난 11 년 동안 다양한 새로운 언어가 사용되었으며 일부 언어는 이러한 Lisp 기능을 모두 디자인에 통합 할 수 있습니다.


2
이러한 기능은 Lisp (및 직접 파생 된 변형)에 고유하지 않으며 오랫동안 사용되지 않았습니다.
Donal Fellows

21
@iceX : JavaScript와 Lisp, Smalltalk, Self, Newspeak, APL, Factor, Forth 등과 같은 언어의 차이점은 JavaScript에서 프로그램이 "죽었다"는 것입니다. 텍스트 파일입니다. 실행중인 프로그램을 종료하고 텍스트 파일을 편집 한 다음 완전히 새로운 프로그램 복사본을 시작하십시오. 이러한 다른 환경 (소위 "생생한"환경) 에서 실행중인 프로그램을 중지 하지 마십시오 . 실행중인 프로그램 자체는 메모리에서 실행중인 다른 오브젝트를 조작하는 것과 같은 방식으로 조작하는 오브젝트 세트입니다 . (참고 :이 Clojure에 대한 사실이 아니다, 그러나 대부분의 오래된 Lisps은이 방법을한다.)
요 르그 W MITTAG

2
@ JörgWMittag Wow ... 따라서 Clojure, Clojurescript, lispyscript와 같은 프로그래밍 언어는 Common Lisp처럼 구식 Lisp과 같은 방식으로 코드를 변경할 수 없기 때문에 실제로 "실제 lisp"가 아닙니다. 그들은 그것을 변경할 수없는 경우 (난 그냥 깊고 어두운 토끼 구멍으로 떨어진 것 같은 느낌)하지만 ... ... 왜 내가 코드를 조작하기위한 목적이라고 생각 S-표현을 ... 사용 귀찮게
ICEX

4
@iceX : 많은 언어가 eval유사하거나 유사하며, Haskell의 Template Haskell과 같은 메타 프로그래밍이 가능합니다. Lisp의 독특한 점은 데이터, 코드 및 메타 코드에 대한 표현이 구문뿐만 아니라 동일하지만 실제로는 동일하다는 것입니다.
tdammers

2
@iceX Eval은 그 일부일 뿐이지 만 전부는 아닙니다. Lisp에서는 컴파일 타임에 코드를 실행할 수 있습니다. 읽을 때 코드를 실행할 수 있습니다. 예 clojure는 Lisp의 모든 역 동성을 지원하며 매크로, 리더 매크로 및 평가 기능을 가지고 있으며 REPL을 실행중인 프로그램에 연결하여 즉시 수정 할 수 있습니다.
stonemetal

15

Lisp에서 사용할 수있는 특정 기능이 다른 사람이 없음을 알기 위해 모든 언어를 알아야하기 때문에이 질문에 대답하기가 어렵습니다. 따라서 다음은 내가 경험 한 언어를 기반으로합니다.

내 머리 위로 조건 은 다른 언어로는 보지 못한 것입니다. '예외'라고 생각하지만 호출 스택이 풀리지 않은 곳과 호출자가 예외 사이트에 복구 값을 보낼 수 있지만 처리기와 예외 소스 사이의 호출 스택을 방해 하지 않으면 서 생각 하십시오. 공평하게 말하면, 이것은 실제로 연속의 특별한 응용 프로그램이므로 Ruby와 Scheme은 (적어도) 이것을 할 수 있습니다 .

Lisp의 매크로 시스템은 규칙 성 / 동성애로부터 이점을 얻지 만 Scala는이를 2.12에서 안정적인 기능으로 통합 할 계획 이며 Template Haskell 은 유사한 기능을 주장합니다. 나는 그것들이 Lisp보다 문법적으로 더 복잡 할 것이라고 주장하지만, 컴파일 타임 코드 생성은 관계없이 존재합니다.

그러나 양식을 직접 작성하는 것은 Lisp에서 사용할 수있는 매크로 중 하나 일뿐입니다. 다른 곳에서는 컴파일러 나 판독기 매크로에 해당하는 것을 보지 못했습니다.

완전하고 재개 가능한 프로세스 이미지를 저장하는 일부 방언 (예 : SBCL ) 의 기능 은 훌륭하지만 다시는 독특하지 않습니다. 스몰 토크 는 수십 년 동안 그렇게 해왔습니다.

다른 많은 언어는 배열을 반환 할 때 구조적 할당을 허용하지만 # '값 및 #'다중 값 바인딩 / 문자 값 접근 방식은 여전히 ​​일반적인 Lisp 및 Scheme ( '일반적인'구조화도 수행 할 수 있음)에 고유 한 것으로 보입니다. ). Perl의 'wantarray'는 함수가 스칼라, 목록 또는 void 컨텍스트에서 호출되는지 여부를 결정하여 비슷한 (-ish) 방식으로 반환 값을 조정할 수 있지만 외부에서 'true'여러 반환 값을 보지 못했습니다. 반응식 / CL.

언어 기능 측면에서 Lisp 가 다른 언어로는 할 수없는 이 많지 않을 것입니다 (완전성을 그대로 유지하면서). 그것이 무엇 이다 , 그러나, 코드가 자신의 데이터 구조로 표현되는 언어 코드 - 그건 큰 아이디어를 ™ 만드는 작업하기 상대적으로 쉽게 데이터 일이다.


3
스칼라 매크로는 TH 매크로, 체계 위생 매크로 등 Lisp 매크로보다 훨씬 덜 강력합니다. MetaLua 및 Converge에서도 똑같이 강력한 시스템을 찾을 수 있습니다.
SK-logic

4

수십 년이 지난 후에, 나는 Lisp에 독점적 인 것이 없다고 생각합니다. 그러나 오늘날에도 리스프 외부에서는 찾기 어려운 흥미로운 것들이 많이 있습니다. 염두에 두어야 할 몇 가지 사항 :

  • 정교한 메타 프로토콜 (예 : CLOS)을 가진 고품질 객체 시스템은 원격으로 인기가 없습니다.
  • 여러 방법이 때때로 어딘가에 나타나지만 대부분의 사람들은 그들에 대해 들어 본 적이 없습니다.
  • 다른 사람들이 지적했듯이 조건 시스템은 널리 사용되는 예외 처리 메커니즘과 비교할 때 매우 정교합니다.
  • 언어의 의미론 (eval)의 간결한 표현, 언어를 정의하고이를 직접적으로 심층적으로 적응할 수있는 강력한 접근 방식 ( SICP 참조 )-현재 널리 사용되는 언어의 "평가"기능은 단순히 동일한 속성을 공유하지 않습니다.

마지막으로, 언어 자체에 관한 것이 아니라 Lisp 역사의 일부가되어 시간이 지남에 따라 Lisp에서 배울 것이 더 많습니다. 예를 들어 Interlisp, Symbolics Genera 등 ... Genera에 손을 대지 않는 경우이 comp.lang.lisp 스레드를 참조하십시오. 여기에서 Kent Pitman은 "Emacs는 Genera의 Zmacs의 창백한 그림자"에 대해 설명합니다. Zmacs가 속한 강력한 Lisp 시스템을 보유하고 있으며 Lisp Machine에서 실행되었습니다.


멀티 메소드 디스패치가 런타임시 동적으로 해결되므로 오버로드 된 메소드를 사용하는 것보다 훨씬 느리다는 점을 제외하고는 거의 모든 현대 명령형 언어의 표준 기능인 오버로드 된 메소드 와 구별되는 멀티 메소드에 대한 좋은 설명을 본 적이 없습니다. 컴파일 타임에 해결됩니다.
메이슨 휠러

그들은 중요한 차이점이 있습니다. 그것에 대한 자료를 찾는 데 어려움을 겪고 있다면 언제든지 여기에 새로운 질문을 만들 수 있습니다 ..
Thiago Silva

Julia는 다중 방법을 가지고 있으며 Haskell의 파라 메트릭 다형성은 일종의 다중 방법과 같습니다. 여러 언어로 멀티 메소드를 시뮬레이션하는 방법이 있습니다. 조건 시스템은 내가 정말로 원하는 것입니다 (C # 디버거에서 보았지만 편집하고 계속하십시오).
aoeu256

4

반드시 특정 기능 일 필요는 없습니다 . 전체 모양과 느낌이며 특정 기능 세트가 함께 작동하는 방식입니다.

JavaScript 또는 Java에는 Lisp (가상 머신, 컴파일러 / 평가 기, 가비지 콜렉션 등)의 많은 기능이 있습니다. 그러나 JavaScript는 예를 들어 상징적 프로그래밍 부분이 없으며 수학 기능이 없으며 (내부에는 수레 만 있음) 오류 처리가 부족합니다.

많은 Common Lisp 시스템은 소프트웨어를 오랫동안 다시 시작하지 않고도 다양한 메타 프로그래밍 기술을 사용하여 Lisp 언어를 다양한 차원으로 확장함으로써 새로운 소프트웨어를 점진적으로 확장하는 개발 방식에 최적화되어 있습니다. 따라서 유연하고 확장 가능해야하지만 동시에 강력해야합니다. 프로그램을 중단하지 않고 언어 변경 (매크로는 기본적으로 사용자가 컴파일러를 확장 할 수있는 방법입니다).

이제 JavaScript와 같은 프로그램도 일반적으로 웹 브라우저와 같은 프로그램을 확장하는 데 사용됩니다. 그러나 대부분의 경우 OOP 해커 외에도 JavaScript에서 메타 프로그래밍을 많이하지 않습니다 .

예:

컴퓨터 대수 영역에 대한 일반적인 고급 수학 소프트웨어를 주로 두 가지 방법으로 구현할 수 있습니다. Mathematica 와 같은 특수 언어로 C 엔진을 작성 하거나 고급 Lisp 방언으로 엔진을 작성하십시오 . 공통 리스프의 맥시마 / 맥시마 , 표준 리스프의 감소 , 공통 리스프의 공리

(Python으로 작성된 하나 이상이 있습니다.)

Common Lisp 위에서 실행되는 Axiom 과 같은 기능 세트를 제공하는 시스템은 많지 않습니다 .

이러한 유형의 응용 프로그램에서 Lisp를 매력적으로 만든 것은 고급 기본 수학 (큰 숫자, 비율, ...), 기호 계산, 대화식 컴파일러 등의 기능이 혼합되어 있다는 것입니다. 이러한 것들을 낮은 수준에서 구현하면 이러한 것들을 얻을 수 있습니다. 레벨 언어. 그렇게하면 일반적인 Lisp 시스템의 50 % 이상을 구현하게됩니다.


2

내가 아는 한 Forth는 Lisp처럼 쉽게 동적입니다 .Forth의 동적 코드는 일반적인 Forth 코드처럼 보이지만 Lisp 매크로는 일반적인 Lisp 코드와 다른 기능을 사용하는 경향이 있기 때문에 ( Clojure 에서는 적어도 매크로 외부에서 구문 인용을 사용한 적이 없습니다) 결과적으로 일반 Lisp 코드와 실제로 다르게 보입니다. Forth가 얼마나 동적인지에 대한 예로써, Forth 에서 주석을 구현하는 방법 은 다음과 같습니다.

: (   41 word drop ; immediate
( That was the definition for the comment word. )
( Now we can add comments to what we are doing! )

1
Forth가 재밌는 것처럼, 나는 스택 기반이며 모든 것이 뒤집혀 있기 때문에 항상 불투명하고 어색한 것을 알았습니다.
Robert Harvey

2
호기심에서 '언어의 주요 부분과 분리되어있다'는 것은 무엇을 의미합니까? Lisp의 매크로는 매크로가 정의 된 시점에 정의 된 모든 함수에 대한 전체 액세스 권한을 가지며,이 함수 중 하나를 사용하여 매크로가 확장되는 양식을 작성할 수 있습니다. 여기에는 데이터베이스 및 / 또는 서버에서 검색된 정보가 포함될 수 있습니다. 귀하의 의견 예는 다음과 같이 정의 될 수 있습니다 : (defmacro comment (& rest body)), 그렇지 않습니까?
Danny Woods

1
@DannyWoods 매크로가 일반 코드처럼 보이지 않음을 의미합니다. 적어도 clojure에서는 일반 코드에서 드문 구문 인용 부호, 인용 부호 제거 등을 많이 사용하기 때문에 일반 코드에서 매크로 코드를 알 수 있습니다. 내가 준 그 예제 코드는 즉시 볼 때까지 정상적인 코드처럼 보입니다. 내 대답을 다시 읽으면 제대로 표현되지 않습니다.
stonemetal

1
@stonemetal 걱정할 필요는 없지만 Common Lisp 또는 Clojure의 구문 인용과 관련하여 매크로 관련이 없다는 것은 주목할 가치가 있습니다. 정규 함수 정의에서 백틱 표현식을 사용하는 것이 편리하고 매크로 본문을 일반 목록으로 수동으로 작성할 수 있습니다 (구문 인용이 좋은 것으로 결정하기 위해 한두 번만 수행하면 됨)
Danny Woods

1
공정하게하기 위해, 커스텀 리더 매크로를 등록함으로써 Lisp에서 동일한 작업을 수행 할 수 있습니다.
fjarri

2

Lisp에는 많은 방언이 있으며 각 언어에는 고유 한 기능 세트가 있습니다. 다른 언어로 채택되지 않은 가장 좋아하는 기능은 Interlisp 의 "스파게티 스택"입니다 .

스파게티 스택은 폐쇄와 비슷하지만 스테로이드입니다. 현재 함수뿐만 아니라 전체 컨텍스트를 스택 맨 위까지 저장합니다. 임의로 생성하여 스택 컨텍스트의 계층 구조를 생성 할 수 있다는 점을 제외하고 는 공동 루틴 과 같은 것입니다.


몰랐습니다, 그것을 확인, 답변 주셔서 감사합니다 :)
iceX

7
이것이 Scheme의 연속과 동일합니까?
Nicola Musatti

1
"스파게티 스택"인 @NicolaMusatti는 Scheme과 같은 연속에 대한 일반적인 구현 전략입니다 (스폰지 생성 기능이 반환 된 후 호출 가능).
Alex D
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.