#함수형프로그래밍 #Clojure #개념

리스프(LISP) 혹은 리습은 프로그래밍 언어의 계열로, 함수형 언어로 포트란에 이어 두번쨰로 오래된 고급 프로그래밍 언어이다.
오늘날 가장 널리 알려진 일반 리스프 변종은 커먼 리스프와 스킴이다.
내가 실습을 진행할 리스프 변종은 Clojure 이다
본래 실용적인 목적 아래 컴퓨터 프로그래밍을 활용한 수학 표기법을 나타내기 위한 목적으로 만들어졌다.
이는 알론소 처치의 람다 대수의 표기법을 많이 영향 받았다.
곧이어 인공지능 연구소에서 가장 인기있는 언어가 되었다.리스프는 컴퓨터 과학의 많은 개념들의 선구자로서 트리 자료구조, 가비지 컬렉션, 동적 자료형과 인터프리터와 같은 개념을 개척했다.
LISP 이름 자체는 LISt Processing의 줄임말으로, 연결리스트는 리스프의 주요 자료구조 중 하나로 리스프 코드는 그 자체로 하나의 리스트이다.
LISP에서 코드와 데이터는 동일한 구조로 표현된다. 즉, 리스프에서 코드는 리스트(List) 로 표현되며, 이 리스트는 데이터로서도 취급될 수 있다
이러한 특징은 LISP의 메타 프로그래밍 능력을 크게 강화시킨다
LISP 는 S-표현식으로 코드가 작성되며, S-표현식은 리스트(List)와 원자(Atom) 로 구성된다. 이 구조는 LISP의 데이터 구조와 동일하므로 프로그램의 코드와 데이터가 본질적으로 동일한 형식으로 다루어진다
이 특성으로 프로그램 코드 자체가 데이터처럼 쉽게 조작 될 수 있다. 프로그램이 자신의 코드를 동적으로 생성, 변경, 평가할 수 있는 메타 프로그래밍이 가능해진다
velong 코드블록이 lisp를 지원하지 않는다..
lisp 간단한 예시 코드
;; 산술 연산
(+ 1 2 3 4) ;; 더하기, 결과: 10
(* 2 3 4) ;; 곱하기, 결과: 24
(- 10 3) ;; 빼기, 결과: 7
(/ 20 5) ;; 나누기, 결과: 4
;; 변수정의
(setq x 10)
(setq y 20)
(+ x y) ;; 결과: 30
;; 함수정의
(defun add (a b)
(+ a b))
(add 5 7) ;; 결과: 12
;; 조건문
(defun check-number (x)
(if (> x 0)
"Positive"
"Non-positive"))
(check-number 5) ;; 결과: "Positive"
(check-number -3) ;; 결과: "Non-positive"
;; 재귀함수
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))
(factorial 5) ;; 결과: 120
;; 리스트 처리
(setq my-list '(1 2 3 4 5))
(car my-list) ;; 리스트의 첫 번째 요소, 결과: 1
(cdr my-list) ;; 리스트의 첫 번째 요소를 제외한 나머지, 결과: (2 3 4 5)
(append my-list '(6 7)) ;; 리스트를 합침, 결과: (1 2 3 4 5 6 7)
;; 매크로 정의
(defmacro unless (condition &body body)
`(if (not ,condition)
(progn ,@body)))
(unless (= 1 2)
(print "1 is not equal to 2"))
;; 반복문
(loop for i from 1 to 5
do (print i))
LISP은 함수형 프로그래밍 개념을 매우 잘 지원한다. 함수형 프로그래밍은 함수를 일급 객체로 다루며, 함수 내에서 다른 함수를 인자로 받거나 반환 할 수 있다 또한 상태 변화 없이 순수 함수를 사용하는 것을 장려한다
예시
(mapcar #'(lambda (x) (+ x 1)) '(1 2 3))
LISP은 재귀를 매우 자연스럽게 지원한다. 재귀는 함수가 자기 자신을 호출하는 기법으로, 특히 복잡한 문제를 간결하게 표현할 수 있게 해준다
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))
LISP의 매크로는 매우 강력한 기능으로, 프로그램이 실행되기 전에 코드를 변환할 수 있게 한다. 매크로는 특정 코드 패턴을 보다 간결하게 표현하거나 새로운 언어 구조를 정의하는데 사용할 수 있다
매크로는 코드의 재사용성을 높히고, 복잡한 코드를 간결하게 작성할 수 있게 한다
LISP는 동적타이핑을 지원한다. 이는 변수의 타입이 런타임에 결정되며, 프로그래머가 명시적으로 타입을 선언할 필요가 없음을 의미한다. 타입체크는 프로그램이 실행되는 동안에 이루어진다
이는 코드의 유연성을 높이고, 코드 작성 속도를 올려준다
LISP는 초기부터 자동 메모리 관리, 즉 가비지 컬렉션을 지원했다. 이는 프로그래머가 직접 메모리를 관리하지 않아도 되도록하여 메모리 누수나 잘못된 메모리 참조와 같은 문제를 줄인다.
메모리 관리의 부담을 줄이고, 안정적인 프로그램 실행을 보장
LISP 이름에서부터 알 수 있듯이, LISP는 리스트(list) 처리를 위한 언어로 설계되었다. 리스트는 LISP의 기본적인 데이터 구조로, 코드와 데이터 모두 리스트로 표현된다
리스트 조작: 리스트의 생성, 접근, 수정 등의 작업을 매우 간단하게 수행할 수 있다.
예시: 리스트 생성 (list 1 2 3) 또는 리스트 접근 (car (1 2 3))은 리스트의 첫번째 요소를 반환한다
LISP는 REPL(Read-Eval-Print-Loop) 을 통해 인터랙티브하게(실시간으로) 프로그래밍을 할 수 있다. REPL에서는 코드를 한 줄 씩 입력하고 즉시 실행 결과를 확인할 수 있다.
REPL은 빠른 프로토타이핑^[시제품과 같은 코드를 테스트하는것]이랑 디버깅을 가능케 하며, 실시간으로 코드를 테스트하고 수정할 수 있다.
LISP은 본질적으로 매우 유연하며, 사용자 정의함수나 매크로를 활용하여 언어를 쉽게 확장할 수 있다
새로운 제어구조나 문법을 LISP의 매크로 시스템을 통해 쉽게 추가할 수 있다
LISP는 명령형 프로그래밍의 구조적 프로그램 제어 구조를 지원한다 if, cond, loop, progn^[중괄호처럼 블록단위로 처리하게 해주는 제어문] 등 다양한 제어 흐름 구조를 제공하여, 복잡한 논리를 간결하게 표현할 수 있다
LISP는 매우 많은 현대의 고급언어에 영향을 끼친 만큼, 요즘 보이는 프로그래밍 언어에서는 위의 특징들을 대부분 갖추고 있는것 같다.
하지만 그럼에도 LISP만 가지고있는 강력한 특징들은 다음과 같다
LISP은 두 특징을 잘 사용하여 프로그램의 코드를 데이터로서 활용할 수 있기 때문에 메타프로그래밍^[프로그램이 자기자신을 조작하거나 생성하는 기법]과 확장성에서 매우 강력하다고 한다