분류 기타

2021 년 Lisp 프로그래밍 언어 배우기

컨텐츠 정보

  • 조회 416 (작성일 )

본문

많은 Lisp 코드가 큰 코드베이스에 숨어 있으므로 언어에 익숙해지는 것이 현명합니다.


Lisp는 1958 년에 발명되어 두 번째로 오래된 컴퓨터 프로그래밍 언어가 되었습니다. Common Lisp, Emacs Lisp (Elisp), Clojure, Racket, Scheme, Fennel 및 GNU Guile을 포함한 여러 현대 파생물을 생성했습니다.


프로그래밍 언어 디자인에 대해 생각하는 것을 좋아하는 사람들은 구문과 데이터가 동일한 구조를 공유하는 방식 때문에 Lisp를 자주 좋아합니다. Lisp 코드는 본질적으로 목록 목록이며 이름은 LISt Processing의 약자입니다. 프로그래밍 언어의 미학에 대해 생각하는 것을 좋아하는 사람들은 범위 지정에 괄호를 자주 사용하기 때문에 Lisp를 종종 싫어합니다. 사실 Lisp가 많은 자극적인 불필요한 괄호를 의미한다는 것은 일반적인 농담입니다.


디자인 철학을 좋아하든 싫어하든 Lisp는 과거를 흥미롭게 엿볼 수 있으며 Clojure와 Guile 덕분에 미래를 엿볼 수 있습니다. 주어진 산업에서 큰 코드베이스 내에 얼마나 많은 Lisp 코드가 숨어 있는지 놀라실 수 있습니다. 따라서 적어도 언어에 대해 어느 정도 익숙해 져있는 것이 좋습니다.


Lisp 설치 


Lisp에는 많은 구현이 있습니다. 인기 있는 오픈 소스 버전에는 SBCLGCL (GNU Common Lisp)이 있습니다. 배포판의 패키지 관리자를 사용하여 이들 중 하나를 설치할 수 있습니다.


Fedora Linux :


sudo dnf install gcl 


데비안 :


sudo apt install gcl 


macOS의 경우 MacPorts 또는 Homebrew를 사용할 수 있습니다.


sudo port install gcl 


Windows의 경우 gnu.org/software/gcl에서 바이너리를 다운로드하십시오.


이 기사에서는 GCL과 clisp 명령을 사용하고 있지만 대부분의 원칙은 모든 Lisp에 적용됩니다.


List processing 


Lisp 소스 코드의 기본 단위는 목록으로 작성된 표현식입니다. 예를 들어, 이것은 연산자 (+)와 두 개의 정수 (1과 2)의 목록입니다.


(+ 1 2) 


또한 함수 (더하기)와 두 개의 인수 (1 및 2)로 평가되는 기호 (+)를 사용하는 Lisp 표현식입니다. REPL (read-eval-print loop)이라는 대화 형 Common Lisp 환경에서 이 식과 다른 식을 실행할 수 있습니다. Python의 IDLE에 익숙하다면 Lisp의 REPL은 다소 익숙할 것입니다.


REPL을 시작하려면 Common Lisp를 시작합니다.


$ clisp
[1]> 


REPL 프롬프트에서 몇 가지 식을 입력합니다.


[1]> (+ 1 2)
3
[2]> (- 1 2)
-1
[3]> (- 2 1)
1
[4]> (+ 2 3 4)
9 


Functions 


이제 Lisp 표현식의 기본 구조를 알았으므로 Lisp 함수를 유용한 방법으로 활용할 수 있습니다. print 함수는 사용자가 제공 한 인수를 가져 와서 터미널에 표시하고 pprint 함수는 "pretty"를 인쇄합니다. 인쇄 기능에는 다른 변형이 있지만 pprint는 REPL에서 좋습니다.


[1]> (pprint "hello world")

"hello world"

[2]> 


defun으로 자신 만의 함수를 만들 수 있습니다. defun 함수에는 함수의 이름과 함수에서 허용 할 매개 변수가 필요합니다.


[1]> (defun myprinter (s) (pprint s))
MYPRINTER
[2]> (myprinter "hello world")

"hello world"

[3]> 



Variables 


setf를 사용하여 Lisp에서 변수를 만들 수 있습니다.


[1]> (setf foo "hello world")
"hello world"
[2]> (pprint foo)

"hello world"

[3]> 


일종의 파이프 라인의 식 내에 식을 중첩 할 수 있습니다. 예를 들어, string-upcase 함수를 호출하여 해당 문자를 대문자로 변환 한 후 변수의 내용을 예쁘게 인쇄 할 수 있습니다.


[3]> (pprint (string-upcase foo))

"HELLO WORLD"

[4]> 


Lisp는 변수 유형을 설정할 때 선언 할 필요가 없다는 점에서 동적으로 입력됩니다. Lisp는 기본적으로 정수를 정수로 취급합니다.


[1]> (setf foo 2)
[2]> (setf bar 3)
[3]> (+ foo bar)
5 


정수를 문자열로 해석하려면 따옴표를 붙일 수 있습니다.


[4]> (setf foo "2")                                                                                                                      
"2"                                                                                                                                      
[5]> (setf bar "3")                                                                                                                      
"3"
[6]> (+ foo bar)

*** - +: "2" is not a number
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead.
ABORT          :R2      Abort main loop
Break 1 [7]> 


이 샘플 REPL 세션에서 foo와 bar는 모두 따옴표로 묶인 숫자로 설정되어 있으므로 Lisp는 이를 문자열로 해석합니다. 수학 연산자는 문자열에 사용할 수 없으므로 REPL은 디버거 모드로 전환됩니다. 디버거에서 나가려면 키보드에서 Ctrl + D를 누릅니다.


특정 데이터 유형을 테스트하는 typep 함수를 사용하여 객체에 대한 몇 가지 내부 검사를 수행 할 수 있습니다. 토큰 T와 NIL은 각각 True와 False를 나타냅니다.


[4]> (typep foo 'string)
NIL
[5]> (typep foo 'integer)
T 


문자열과 정수 앞의 작은 따옴표 ( ')는 Lisp가 해당 키워드를 변수로 (잘못) 평가하는 것을 방지합니다.


[6]> (typep foo string)
*** - SYSTEM::READ-EVAL-PRINT: variable STRING has no value
[...] 


일반적으로 quote 함수로 수행되는 용어를 보호하는 간단한 방법입니다.


[7]> (typep foo (quote string))
NIL
[5]> (typep foo (quote integer))
T 


Lists 


당연히 Lisp에서 목록을 만들 수도 있습니다.


[1]> (setf foo (list "hello" "world"))
("hello" "world") 


n 번째 함수를 사용하여 목록을 색인화 할 수 있습니다.


[2]> (nth 0 foo)
"hello"
[3]> (pprint (string-capitalize (nth 1 foo)))

"World" 


REPL 종료 


REPL 세션을 종료하려면 키보드에서 Ctrl + D를 누르거나 Lisp에서 quit 키워드를 사용하십시오.


[99]> (quit)
$ 


Scripting 


Lisp는 컴파일되거나 해석 된 스크립팅 언어로 사용될 수 있습니다. 후자는 시작할 때 가장 쉬운 옵션 일 것입니다. 특히 Python 또는 쉘 스크립팅에 이미 익숙한 경우 더욱 그렇습니다.


다음은 GNU Common Lisp로 작성된 간단한 주사위 롤러 스크립트입니다.


#!/usr/bin/clisp

(defun roller (num)  
  (pprint (random (parse-integer (nth 0 num))))
)

(setf userput *args*)
(setf *random-state* (make-random-state t))
(roller userput) 


첫 번째 줄은 스크립트를 실행하는 데 사용할 실행 파일을 POSIX 터미널에 알려줍니다.


defun으로 만든 roller 함수는 무작위 함수를 사용하여 num 목록의 0 번째 항목까지 포함하지 않고 의사 난수를 인쇄합니다. num list는 아직 스크립트에 생성되지 않았지만 함수는 호출 될 때까지 실행되지 않습니다.


다음 행은 시작시 스크립트에 제공된 인수를 userput이라는 변수에 할당합니다. userput 변수는 목록이며 롤러 함수에 전달되면 num이 됩니다.


스크립트의 끝에서 두 번째 줄은 임의의 시드를 시작합니다. 이것은 Lisp에 대부분 난수를 생성하기에 충분한 엔트로피를 제공합니다.


마지막 줄은 사용자 지정 롤러 함수를 호출하여 userput 목록을 유일한 인수로 제공합니다.


파일을 dice.lisp로 저장하고 실행 가능으로 표시하십시오.


chmod +x dice.lisp 


마지막으로 임의의 숫자를 선택할 수 있는 최대 수를 제공하여 실행 해보십시오.


$ ./dice.lisp 21

13
$ ./dice.lisp 21

7
$ ./dice.lisp 21

20 


Lisp 배우기 


Lisp를 개인 스크립트를 위한 실용적인 언어로 사용하거나 경력을 발전시키기 위해 또는 재미있는 실험으로 상상할 수 있는지 여부에 관계없이 매년 Lisp Game Jam에서 특히 창의적인 용도를 볼 수 있습니다 (대부분의 제출물은 오픈 소스이므로 볼 수 있습니다. 당신이 연주하는 것을 배우는 코드).


Lisp는 지속적으로 성장하는 개발자 기반과 모든 분야의 프로그래머를 만족시킬 수 있는 역사적이고 떠오르는 방언을 갖춘 재미 ​​있고 독특한 언어입니다.


https://opensource.com/article/21/5/learn-lisp