SlideShare une entreprise Scribd logo
1  sur  26
Macro & compilation
Ikhoon
Introduction
 Macro
 호칭
 Macro function or 줄여서 macro
 용도
 Lisp의 syntax를 확장하는 하나의 방법
 Tool
 PPMX(pretty print macro expansion)
 Compiler
 역할
 Lisp프로그램을 기계언어로 바꾸는 역할
 효과
 일반적으로 10 ~ 100배 정도의 성능 향상
Macro as shorthand
 (INCF A) vs. (SETQ A (+ A 1))
 매크로는 복잡한 표현을 간략하게 할 수 있음
 SETF vs. SETQ
 매크로 SETF, INCF는 special 함수 SETQ보다 smart함
 (incf (aref (nth array-num *list-of-arrays*)
(first subscripts)))
 DEFSTRUCT 매크로
 MAKE-STARSHIP, STARSHIP-P, STARSHIP-NAME 의 함
수를 암묵적으로 생성
Macro expansion
 Lisp의 Macro는 자동으로 표현식을 확장
 입력 인자를 평가하지 않는 약어 확장 함수
 > (ppmx (incf a))
Macro expansion:
(SETQ A (+ A 1))
 > (ppmx (incf a))
Macro expansion:
(LET ((#:G0144 (+ A 1)))
(SETQ A #:G0144))
Defining a macro
 DEFMACRO
 매크로는 defmacro를 이용해서 정의
 Syntax는 defun과 유사
 Macro 함수는 평가되어 질 수 있는 표현식을 만들어 반환
 간단한 버전의 incf
 list를 이용해서 lisp이 평가할수있는 표현식 생성
 (defmacro simple-incf (var)
(list ’setq var (list ’+ var 1)))
(setf a 4)
> (simple-incf a)
5
 (defmacro simple-incf (var &optional (amount 1))
(list ’setq var (list ’+ var amount)))
(setf b 2)
> (simple-incf b (* 3 a))
17
Why macro?
 Function or MACRO
 INCF 함수는 매크로로만 만들 수 있다.
 함수버전 incf
(defun faulty-incf (var)
(setq var (+ var 1)))
(setf a 7)
> (faulty-incf a)
8
> (faulty-incf a)
8
> a
7 ;; a 값이 증가 되지 않음
 인자 값이 함수로 들어가기 전에 평가되어짐
 증가한 값은 함수내의 지역 변수 var이지 a가 아님
Macros as syntactic extensions
 Macro의 목적
 Lisp Language의 syntax확장
 Macro vs. Function
1. Function의 인자는 항상 평가 된다. Macro의 인자는 평가
되지 않는다.
2. Function의 결과값은 어떤 것이든지 될 수 있다. Macro의
반환 값은 반드시 유효한 Lisp 표현이어야 한다.
3. Macro가 반환한 표현은 즉시 평가되어 진다. Function의
반환 결과는 평가되어 지지 않는다.
Macros as syntactic extensions
 Special functions
 SETQ, IF, LET, BLOCK 등..
 Common lisp의 가장 하위 레벨의 블록들
 Scoping, block 과 loop과 같은 기본적인 제어구조를 책임
짐
 Macro와 마찬가지로 인자들을 평가하지 않음
 평가하기 위한 표현을 반환하자 않음
 새로운 special function을 쓸 수 없음, lisp implementer만
이 할 수 있음
The backquote character
 Backquote [ ` ]
 Quote와 유사하게 list를 인용하기 위해서 사용
 Unquote
 Comma [ , ]
 Backquote된 list의 어떤 값 앞에 comma가 붙게 되면 unquote됨
 Unquote는 쓰여진 표현이 자체가 아니가 그것의 값을 의미
(setf name ’fred)
> `(this is ,name from pittsburgh)
(THIS IS FRED FROM PITTSBURGH)
> `(i gave ,name about ,(* 25 8) dollars)
(I GAVE FRED ABOUT 200 DOLLARS)
 Simple-incf
 (defmacro simple-incf (var) ;; list를 사용한 매크로
(list ’setq var (list ’+ var 1)))
 (defmacro simple-incf (var &optional (amount 1)) ;; backquote를 사용한 매크로
`(setq ,var (+ ,var ,amount)))
Splicing with backquote
 Splice
 Comma-at [ ,@ ]
 ,@에 의해서 생기는 결과 값은 단순히 삽입되는 것이 아니라 접
합되어(spliced)짐
 ,@는 가장 외각의 괄호가 없어 지는 역할을 하기 때문에 반드시
list에서만 적용해야 함
(setf name ’fred)
(setf address ’(16 maple drive))
> `(,name lives at ,address now) ;;
Inserting.
(FRED LIVES AT (16 MAPLE DRIVE) NOW)
> `(,name lives at ,@address now) ;;
Splicing.
(FRED LIVES AT 16 MAPLE DRIVE NOW)
The compiler
 Function compilation
 COMPILE 이라는 명령어를 통해서 가능
 File compilation
 COMPILE-FILE 이라는 명령어를 통해서 할 수 있음
 성능
 10 ~ 100배정도 향상 가능
Compiling entire programs
 에러메시지 처리
 Global variable
 Global variable을 사용하면 “assumed to be SPECIAL” 이라는 경고
문구가 출력됨
 DEFVAR, DEFPARAMETER, DEFCONSTANT를 적절하게 이용하
여 경고 메시지를 없앨 수 있음
 선언은 파일의 초반부 OR 그 값을 참조하는 함수 전에 선언되어야
함
 MACRO
 매크로의 선언은 반드시 어떤 함수가 그것을 참조하기 전에 놓여져
야 함
 함수 foo 가 매크로 bar를 부를 때 bar가 foo보다 뒤에 있다면 foo를
컴파일 할 때 매크로 bar를 확장해야 하는 것을 알지 못함
 Built-in 함수
 내장함수 재정의 하면 컴파일 에러가 남
Advanced topics:
The &body lambda-list keyword
 WHILE loop in lisp
 (defmacro while (test &body body)
`(do ()
((not ,test))
,@body))
 매크로를 통해서 새로운 syntax를 추가함
 &body
 &body는 &rest와 동일한 기능
 남겨진 인자들이 list의 형태로 넘어옴
 매크로를 읽을 때 나머지 부분들이 Lisp code의 body부분
이 된다는 것을 알려줌
Advanced topics:
Destructuring lambda lists (1)
 Destructuring
 매크로는 입력인자를 평가 안 함
 입력 표현을 자동으로 분리될 수 있도록 List 처럼 취급 가능
 매크로에서 가능
 복잡한 syntax 제어 구조에 용이
 (defmacro mix-and-match (p q) ;; not destruturing
(let ((x1 (first p))
(y1 (second p))
(x2 (first q))
(y2 (second q)))
`(list ’(,x1 ,y1)
’(,x1 ,y2)
’(,x2 ,y1)
’(,x2 ,y2))))
 (defmacro mix-and-match ((x1 y1) (x2 y2)) ;; destruturing
`(list ’(,x1 ,y1)
’(,x1 ,y2)
’(,x2 ,y1)
’(,x2 ,y2)))
Advanced topics:
Destructuring lambda lists - example
 DOVECTOR
 (defmacro dovector ((var vector-exp
&optional result-form)
&body body)
`(do* ((vec-dov ,vector-exp)
(len-dov (length vec-dov))
(i-dov 0 (+ i-dov 1))
(,var nil))
((equal i-dov len-dov) ,result-form)
(setf ,var (aref vec-dov i-dov))
,@body))
> (dovector (x ’#(foo bar baz))
(format t "~&X is ~S" x))
X is FOO
X is BAR
X is BAZ
NIL
 vec-dov, len-dov, i-dov 는 초기값을 담기 위한 지역 변수
 변수 이름 충돌을 막기 위해서 package system과 gensyms를 사용하는 것이 바람직하지만
이 책의 범위를 벗어 나는 내용
?
Advanced topics:
Macros and lexical scoping
 함수로 incf 만들기
 값이 평가되는 것이 피하기 위해 symbol을 사용함
 변수에 대한 Read & Update가 가능해야 함
 전역변수는 가능
 (defun faulty-incf (var)
(set var (+ (symbol-value var) 1)))
(setf a 7)
> (faulty-incf ’a)
8
> (faulty-incf ’a)
9
> a
9
 지역 변수는 매크로만 가능
 (defun test-simple (turnip)
(simple-incf turnip))
(defun test-faulty (turnip)
(faulty-incf ’turnip))
> (test-simple 37)
38
> (test-faulty 37)
 Error: TURNIP unassigned variable.
 FAULTY-INCF의 부모 lexical-context는 global-context이기 때문에 TEST-FAULTY의 지역변수 TURNIP에 lexically하
게 접근이 되어지지 않는다.
Advanced topics:
Dynamic scoping
 Lexical scoping
 정의
 X변수에 접근하기 위해서는 X가 정해진 body 안에서만 접근가능
 전역함수
 DEFUN으로 정의 되어짐
 자신의 local 변수와 전역 변수 접근 가능
 지역함수
 함수 BAR안에 lambda 표현 식으로 정의
 자신의 변수, BAR의 변수와 전역 변수 접근 가능
 Dynamic scoping
 Dynamic variable은 Special variable이라고도 부름
 정의
 변수 X가 special로 선언되면 다른 함수의 지역 변수가 될 수 없고
어디서나 접근이 가능
 DEFVAR 매크로를 통해 정의될 수 있음
Advanced topics:
Dynamic scoping - example
 (defvar birds) ;; bird를 special로 선언
(setf fish ’(salmon tuna)) ;; fish – lexical
(setf birds ’(eagle vulture)) ;; birds – special
(defun ref-fish () ;; 참조 함수 선언
fish)
(defun ref-birds ()
birds)
(ref-fish) => (salmon tuna) ;; top level에서 실행
(ref-birds) => (eagle vulture)
 (defun test-lexical (fish)
(list fish (ref-fish)))
> (test-lexical ’(guppy minnow)) ;; lexical 변수 참조
((GUPPY MINNOW) (SALMON TUNA)) ;; ref-fish함수 안의 fish는 lexical scoping에 따라 전역 변수 참조
 (defun test-dynamic (birds)
(list birds (ref-birds))) ;; dynamic 변수 참조
> (test-dynamic ’(robin sparrow)) ;; ref-birds 함수 안의 birds는 dynamic 변수 bird 참조
((ROBIN SPARROW) (ROBIN SPARROW))
 > (ref-birds)
(EAGLE VULTURE)
 TEST-DYNAMIC의 body로 들어 갈 때 새로운 dynamic 변수 birds가 새기고 TEST-DYNAMIC을 떠날 때 까지 변수
birds는 이값을 참조 하게 됨
Advanced topics:
defvar, defparameter, defconstant
 DEFVAR
 초기 값 없이 선언 될 수 있음
 (defvar *total-glasses*)
 한번 그 값이 선언되면 defvar를 통해서 바꿀 수 없음
> (defvar *total-glasses* 0
"Total glasses sold so far")
> (defvar *total-glasses* 3
"Total glasses sold so far")
> *total-glasses*
0
 DEFPARAMETER
 초기 값과 함께 선언 되어야 함
 (defparameter abc 10)
 선언된 값을 defparameter를 통해 바꿀 수 있음
> (defparameter *max-glasses* 500
"Maximum number of glasses we can make")
> (defparameter *max-glasses* 300)
> *max-glasses*
300
 defvar와 defparameter는 똑같은 문법 구조이지만 defparameter는 프로그램이 실행되는 동안 변화되지 않아야 하는 값에 사용
 DEFCONSTANT
 만들어진 상수는 절대 바뀌지 않음
 Lisp의 special valiable들은 관습적으로 *로 둘러 싸서 표현 하지만 defconstant는 예외를 적용
 Lisp는 PI와 같은 내장 상수들이 있음
Advanced topics:
Rebinding special variables
 Function 인자
 함수의 인자를 special 변수의 이름으로 지정하여 호출 시 rebinding
(defun print-in-base (*print-base* x)
(format t "~&~D is written ~S in base ~D."
x x *print-base*))
> (print-in-base 2 205)
205 is written 11001101 in base 2.
NIL
 LET
 LET을 통한 바인딩
(defvar *foo* 2)
(defun bump-foo ()
(incf *foo*))
(defun rebind-boo ()
(let ((*foo* 100))
(incf *foo*)
(bump-foo)))
Ansi Lisp:
Macro design – example(1)
 ntimes 매크로 만들기
 입력된 숫자횟수만큼 반복 실행하는 매크로
 (ntimes count &body body)
 > (ntimes 10
(princ "."))
..........
NIL
 References
 ansi lisp
 http://onlisp.blogspot.com/2007/12/10-ansi-common-lisp.html
Ansi Lisp:
Macro design – example(2)
 ntimes 매크로
 (defmacro ntimes (n &rest body)
`(do ((x 0 (+ x 1)))
((>= x ,n))
,@body))
 문제점
 변수 x를 생성해서 기존에 변수 x가 있었다면 의도치 않은 결과 발생
 잘못된 예
 (let ((x 10))
(ntimes 5
(setf x (+ x 1)))
x)
10
 X에 10을 할당하고 그 값을 5번 증가 시켜야 하지만 결과 값은 그대로 10이 됨
 매크로 확장
 (let ((x 10))
(do ((x 0 (+ x 1)))
((>= x 5))
(setf x (+ x 1))) ;; let으로 생성된 x가 아닌 do안의 변수 x가 증가
x)
Ansi Lisp:
Macro design – example(3)
 수정된 ntimes 매크로
 do loop안의 변수를 gensym을 통하여 프로그램내의 어느 심볼과도 같지 않게 만듬
 (defmacro ntimes (n &rest body)
(let ((g (gensym)))
`(do ((,g 0 (+ ,g 1)))
((>= ,g ,n))
,@body)))
 문제점
 반복 평가
 do 문의 body가 평가 될때 마다 n이 새롭게 평가 된다.
 잘못된 예
 > (let ((v 10))
(ntimes (setf v (- v 1))
(princ ".")))
.....
NIL
 원하는 결과는 v에서 10에서 1을 뺀 9개의 점을 출력
 매크로 확장
 (let ((v 10))
(do ((#:g1 0 (+ #:g1 1)))
((>= #:g1 (setf v (- v 1))))
(princ ".")))
Ansi Lisp:
Macro design – example(4)
 수정된 ntimes 매크로
 (defmacro ntimes (n &rest body)
(let ((g (gensym))
(h (gensym)))
`(let ((,h ,n))
(do ((,g 0 (+ ,g 1)))
((>= ,g ,h))
,@body))))
 문제점
 해결됨
 끝

Contenu connexe

Tendances

스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)Yongha Yoo
 
스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오Taeoh Kim
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍Young-Beom Rhee
 
자바8 람다식 소개
자바8 람다식 소개자바8 람다식 소개
자바8 람다식 소개beom kyun choi
 
자바스크립트 기초문법~함수기초
자바스크립트 기초문법~함수기초자바스크립트 기초문법~함수기초
자바스크립트 기초문법~함수기초진수 정
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기Yongha Yoo
 
동작 파라미터와 람다 In java 8
동작 파라미터와 람다 In java 8동작 파라미터와 람다 In java 8
동작 파라미터와 람다 In java 8진우 이
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리ETRIBE_STG
 
Lua 문법 -함수
Lua 문법 -함수Lua 문법 -함수
Lua 문법 -함수Jaehoon Lee
 
Java 8 api :: lambda 이용하기
Java 8 api :: lambda 이용하기Java 8 api :: lambda 이용하기
Java 8 api :: lambda 이용하기rupert kim
 
프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js function프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js functionYoung-Beom Rhee
 
Assembly 스터디 2
Assembly 스터디 2Assembly 스터디 2
Assembly 스터디 2Jinkyoung Kim
 
Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기지수 윤
 
Java8 & Lambda
Java8 & LambdaJava8 & Lambda
Java8 & Lambda기현 황
 
프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oopYoung-Beom Rhee
 

Tendances (20)

스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
 
스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
 
자바8 람다식 소개
자바8 람다식 소개자바8 람다식 소개
자바8 람다식 소개
 
자바스크립트 기초문법~함수기초
자바스크립트 기초문법~함수기초자바스크립트 기초문법~함수기초
자바스크립트 기초문법~함수기초
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기
 
동작 파라미터와 람다 In java 8
동작 파라미터와 람다 In java 8동작 파라미터와 람다 In java 8
동작 파라미터와 람다 In java 8
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리
 
자바 8 학습
자바 8 학습자바 8 학습
자바 8 학습
 
Lua 문법 -함수
Lua 문법 -함수Lua 문법 -함수
Lua 문법 -함수
 
Java 8 api :: lambda 이용하기
Java 8 api :: lambda 이용하기Java 8 api :: lambda 이용하기
Java 8 api :: lambda 이용하기
 
Lua 문법
Lua 문법Lua 문법
Lua 문법
 
프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js function프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js function
 
Assembly 스터디 2
Assembly 스터디 2Assembly 스터디 2
Assembly 스터디 2
 
Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기
 
5 swift 기초함수
5 swift 기초함수5 swift 기초함수
5 swift 기초함수
 
Java8 & Lambda
Java8 & LambdaJava8 & Lambda
Java8 & Lambda
 
Java lambda
Java lambdaJava lambda
Java lambda
 
iOS 메모리관리
iOS 메모리관리iOS 메모리관리
iOS 메모리관리
 
프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop
 

Similaire à Macro & compilation

RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수Aiden Seonghak Hong
 
파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229Yong Joon Moon
 
EcmaScript6(2015) Overview
EcmaScript6(2015) OverviewEcmaScript6(2015) Overview
EcmaScript6(2015) Overviewyongwoo Jeon
 
Taocp 1.4.1 subroutine
Taocp 1.4.1 subroutineTaocp 1.4.1 subroutine
Taocp 1.4.1 subroutineYoungkwon Lee
 
파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304Yong Joon Moon
 
PySpark 배우기 Ch 06. ML 패키지 소개하기
PySpark 배우기 Ch 06. ML 패키지 소개하기PySpark 배우기 Ch 06. ML 패키지 소개하기
PySpark 배우기 Ch 06. ML 패키지 소개하기찬희 이
 
헷갈리는 자바스크립트 정리
헷갈리는 자바스크립트 정리헷갈리는 자바스크립트 정리
헷갈리는 자바스크립트 정리은숙 이
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019min woog kim
 
Perl Script Document
Perl Script DocumentPerl Script Document
Perl Script Document오석 한
 
R 프로그래밍 기본 문법
R 프로그래밍 기본 문법R 프로그래밍 기본 문법
R 프로그래밍 기본 문법Terry Cho
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSCirculus
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!WooYoung Cho
 
[2017 Incognito] 시스템 해킹 기법 정리
[2017 Incognito] 시스템 해킹 기법 정리[2017 Incognito] 시스템 해킹 기법 정리
[2017 Incognito] 시스템 해킹 기법 정리NAVER D2
 
Scala, Scalability
Scala, ScalabilityScala, Scalability
Scala, ScalabilityDongwook Lee
 
Java jungsuk3 ch14_lambda_stream
Java jungsuk3 ch14_lambda_streamJava jungsuk3 ch14_lambda_stream
Java jungsuk3 ch14_lambda_stream성 남궁
 

Similaire à Macro & compilation (20)

함수적 사고 2장
함수적 사고 2장함수적 사고 2장
함수적 사고 2장
 
7장매크로
7장매크로7장매크로
7장매크로
 
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
 
파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229
 
EcmaScript6(2015) Overview
EcmaScript6(2015) OverviewEcmaScript6(2015) Overview
EcmaScript6(2015) Overview
 
Taocp 1.4.1 subroutine
Taocp 1.4.1 subroutineTaocp 1.4.1 subroutine
Taocp 1.4.1 subroutine
 
파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304
 
PySpark 배우기 Ch 06. ML 패키지 소개하기
PySpark 배우기 Ch 06. ML 패키지 소개하기PySpark 배우기 Ch 06. ML 패키지 소개하기
PySpark 배우기 Ch 06. ML 패키지 소개하기
 
헷갈리는 자바스크립트 정리
헷갈리는 자바스크립트 정리헷갈리는 자바스크립트 정리
헷갈리는 자바스크립트 정리
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
 
Perl Script Document
Perl Script DocumentPerl Script Document
Perl Script Document
 
R 프로그래밍 기본 문법
R 프로그래밍 기본 문법R 프로그래밍 기본 문법
R 프로그래밍 기본 문법
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JS
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!
 
[2017 Incognito] 시스템 해킹 기법 정리
[2017 Incognito] 시스템 해킹 기법 정리[2017 Incognito] 시스템 해킹 기법 정리
[2017 Incognito] 시스템 해킹 기법 정리
 
Scalability
ScalabilityScalability
Scalability
 
Scala, Scalability
Scala, ScalabilityScala, Scalability
Scala, Scalability
 
Java jungsuk3 ch14_lambda_stream
Java jungsuk3 ch14_lambda_streamJava jungsuk3 ch14_lambda_stream
Java jungsuk3 ch14_lambda_stream
 
ES6 for Node.js Study 2주차
ES6 for Node.js Study 2주차ES6 for Node.js Study 2주차
ES6 for Node.js Study 2주차
 

Macro & compilation

  • 2. Introduction  Macro  호칭  Macro function or 줄여서 macro  용도  Lisp의 syntax를 확장하는 하나의 방법  Tool  PPMX(pretty print macro expansion)  Compiler  역할  Lisp프로그램을 기계언어로 바꾸는 역할  효과  일반적으로 10 ~ 100배 정도의 성능 향상
  • 3. Macro as shorthand  (INCF A) vs. (SETQ A (+ A 1))  매크로는 복잡한 표현을 간략하게 할 수 있음  SETF vs. SETQ  매크로 SETF, INCF는 special 함수 SETQ보다 smart함  (incf (aref (nth array-num *list-of-arrays*) (first subscripts)))  DEFSTRUCT 매크로  MAKE-STARSHIP, STARSHIP-P, STARSHIP-NAME 의 함 수를 암묵적으로 생성
  • 4. Macro expansion  Lisp의 Macro는 자동으로 표현식을 확장  입력 인자를 평가하지 않는 약어 확장 함수  > (ppmx (incf a)) Macro expansion: (SETQ A (+ A 1))  > (ppmx (incf a)) Macro expansion: (LET ((#:G0144 (+ A 1))) (SETQ A #:G0144))
  • 5. Defining a macro  DEFMACRO  매크로는 defmacro를 이용해서 정의  Syntax는 defun과 유사  Macro 함수는 평가되어 질 수 있는 표현식을 만들어 반환  간단한 버전의 incf  list를 이용해서 lisp이 평가할수있는 표현식 생성  (defmacro simple-incf (var) (list ’setq var (list ’+ var 1))) (setf a 4) > (simple-incf a) 5  (defmacro simple-incf (var &optional (amount 1)) (list ’setq var (list ’+ var amount))) (setf b 2) > (simple-incf b (* 3 a)) 17
  • 6. Why macro?  Function or MACRO  INCF 함수는 매크로로만 만들 수 있다.  함수버전 incf (defun faulty-incf (var) (setq var (+ var 1))) (setf a 7) > (faulty-incf a) 8 > (faulty-incf a) 8 > a 7 ;; a 값이 증가 되지 않음  인자 값이 함수로 들어가기 전에 평가되어짐  증가한 값은 함수내의 지역 변수 var이지 a가 아님
  • 7. Macros as syntactic extensions  Macro의 목적  Lisp Language의 syntax확장  Macro vs. Function 1. Function의 인자는 항상 평가 된다. Macro의 인자는 평가 되지 않는다. 2. Function의 결과값은 어떤 것이든지 될 수 있다. Macro의 반환 값은 반드시 유효한 Lisp 표현이어야 한다. 3. Macro가 반환한 표현은 즉시 평가되어 진다. Function의 반환 결과는 평가되어 지지 않는다.
  • 8. Macros as syntactic extensions  Special functions  SETQ, IF, LET, BLOCK 등..  Common lisp의 가장 하위 레벨의 블록들  Scoping, block 과 loop과 같은 기본적인 제어구조를 책임 짐  Macro와 마찬가지로 인자들을 평가하지 않음  평가하기 위한 표현을 반환하자 않음  새로운 special function을 쓸 수 없음, lisp implementer만 이 할 수 있음
  • 9. The backquote character  Backquote [ ` ]  Quote와 유사하게 list를 인용하기 위해서 사용  Unquote  Comma [ , ]  Backquote된 list의 어떤 값 앞에 comma가 붙게 되면 unquote됨  Unquote는 쓰여진 표현이 자체가 아니가 그것의 값을 의미 (setf name ’fred) > `(this is ,name from pittsburgh) (THIS IS FRED FROM PITTSBURGH) > `(i gave ,name about ,(* 25 8) dollars) (I GAVE FRED ABOUT 200 DOLLARS)  Simple-incf  (defmacro simple-incf (var) ;; list를 사용한 매크로 (list ’setq var (list ’+ var 1)))  (defmacro simple-incf (var &optional (amount 1)) ;; backquote를 사용한 매크로 `(setq ,var (+ ,var ,amount)))
  • 10. Splicing with backquote  Splice  Comma-at [ ,@ ]  ,@에 의해서 생기는 결과 값은 단순히 삽입되는 것이 아니라 접 합되어(spliced)짐  ,@는 가장 외각의 괄호가 없어 지는 역할을 하기 때문에 반드시 list에서만 적용해야 함 (setf name ’fred) (setf address ’(16 maple drive)) > `(,name lives at ,address now) ;; Inserting. (FRED LIVES AT (16 MAPLE DRIVE) NOW) > `(,name lives at ,@address now) ;; Splicing. (FRED LIVES AT 16 MAPLE DRIVE NOW)
  • 11. The compiler  Function compilation  COMPILE 이라는 명령어를 통해서 가능  File compilation  COMPILE-FILE 이라는 명령어를 통해서 할 수 있음  성능  10 ~ 100배정도 향상 가능
  • 12. Compiling entire programs  에러메시지 처리  Global variable  Global variable을 사용하면 “assumed to be SPECIAL” 이라는 경고 문구가 출력됨  DEFVAR, DEFPARAMETER, DEFCONSTANT를 적절하게 이용하 여 경고 메시지를 없앨 수 있음  선언은 파일의 초반부 OR 그 값을 참조하는 함수 전에 선언되어야 함  MACRO  매크로의 선언은 반드시 어떤 함수가 그것을 참조하기 전에 놓여져 야 함  함수 foo 가 매크로 bar를 부를 때 bar가 foo보다 뒤에 있다면 foo를 컴파일 할 때 매크로 bar를 확장해야 하는 것을 알지 못함  Built-in 함수  내장함수 재정의 하면 컴파일 에러가 남
  • 13. Advanced topics: The &body lambda-list keyword  WHILE loop in lisp  (defmacro while (test &body body) `(do () ((not ,test)) ,@body))  매크로를 통해서 새로운 syntax를 추가함  &body  &body는 &rest와 동일한 기능  남겨진 인자들이 list의 형태로 넘어옴  매크로를 읽을 때 나머지 부분들이 Lisp code의 body부분 이 된다는 것을 알려줌
  • 14. Advanced topics: Destructuring lambda lists (1)  Destructuring  매크로는 입력인자를 평가 안 함  입력 표현을 자동으로 분리될 수 있도록 List 처럼 취급 가능  매크로에서 가능  복잡한 syntax 제어 구조에 용이  (defmacro mix-and-match (p q) ;; not destruturing (let ((x1 (first p)) (y1 (second p)) (x2 (first q)) (y2 (second q))) `(list ’(,x1 ,y1) ’(,x1 ,y2) ’(,x2 ,y1) ’(,x2 ,y2))))  (defmacro mix-and-match ((x1 y1) (x2 y2)) ;; destruturing `(list ’(,x1 ,y1) ’(,x1 ,y2) ’(,x2 ,y1) ’(,x2 ,y2)))
  • 15. Advanced topics: Destructuring lambda lists - example  DOVECTOR  (defmacro dovector ((var vector-exp &optional result-form) &body body) `(do* ((vec-dov ,vector-exp) (len-dov (length vec-dov)) (i-dov 0 (+ i-dov 1)) (,var nil)) ((equal i-dov len-dov) ,result-form) (setf ,var (aref vec-dov i-dov)) ,@body)) > (dovector (x ’#(foo bar baz)) (format t "~&X is ~S" x)) X is FOO X is BAR X is BAZ NIL  vec-dov, len-dov, i-dov 는 초기값을 담기 위한 지역 변수  변수 이름 충돌을 막기 위해서 package system과 gensyms를 사용하는 것이 바람직하지만 이 책의 범위를 벗어 나는 내용
  • 16. ?
  • 17. Advanced topics: Macros and lexical scoping  함수로 incf 만들기  값이 평가되는 것이 피하기 위해 symbol을 사용함  변수에 대한 Read & Update가 가능해야 함  전역변수는 가능  (defun faulty-incf (var) (set var (+ (symbol-value var) 1))) (setf a 7) > (faulty-incf ’a) 8 > (faulty-incf ’a) 9 > a 9  지역 변수는 매크로만 가능  (defun test-simple (turnip) (simple-incf turnip)) (defun test-faulty (turnip) (faulty-incf ’turnip)) > (test-simple 37) 38 > (test-faulty 37)  Error: TURNIP unassigned variable.  FAULTY-INCF의 부모 lexical-context는 global-context이기 때문에 TEST-FAULTY의 지역변수 TURNIP에 lexically하 게 접근이 되어지지 않는다.
  • 18. Advanced topics: Dynamic scoping  Lexical scoping  정의  X변수에 접근하기 위해서는 X가 정해진 body 안에서만 접근가능  전역함수  DEFUN으로 정의 되어짐  자신의 local 변수와 전역 변수 접근 가능  지역함수  함수 BAR안에 lambda 표현 식으로 정의  자신의 변수, BAR의 변수와 전역 변수 접근 가능  Dynamic scoping  Dynamic variable은 Special variable이라고도 부름  정의  변수 X가 special로 선언되면 다른 함수의 지역 변수가 될 수 없고 어디서나 접근이 가능  DEFVAR 매크로를 통해 정의될 수 있음
  • 19. Advanced topics: Dynamic scoping - example  (defvar birds) ;; bird를 special로 선언 (setf fish ’(salmon tuna)) ;; fish – lexical (setf birds ’(eagle vulture)) ;; birds – special (defun ref-fish () ;; 참조 함수 선언 fish) (defun ref-birds () birds) (ref-fish) => (salmon tuna) ;; top level에서 실행 (ref-birds) => (eagle vulture)  (defun test-lexical (fish) (list fish (ref-fish))) > (test-lexical ’(guppy minnow)) ;; lexical 변수 참조 ((GUPPY MINNOW) (SALMON TUNA)) ;; ref-fish함수 안의 fish는 lexical scoping에 따라 전역 변수 참조  (defun test-dynamic (birds) (list birds (ref-birds))) ;; dynamic 변수 참조 > (test-dynamic ’(robin sparrow)) ;; ref-birds 함수 안의 birds는 dynamic 변수 bird 참조 ((ROBIN SPARROW) (ROBIN SPARROW))  > (ref-birds) (EAGLE VULTURE)  TEST-DYNAMIC의 body로 들어 갈 때 새로운 dynamic 변수 birds가 새기고 TEST-DYNAMIC을 떠날 때 까지 변수 birds는 이값을 참조 하게 됨
  • 20. Advanced topics: defvar, defparameter, defconstant  DEFVAR  초기 값 없이 선언 될 수 있음  (defvar *total-glasses*)  한번 그 값이 선언되면 defvar를 통해서 바꿀 수 없음 > (defvar *total-glasses* 0 "Total glasses sold so far") > (defvar *total-glasses* 3 "Total glasses sold so far") > *total-glasses* 0  DEFPARAMETER  초기 값과 함께 선언 되어야 함  (defparameter abc 10)  선언된 값을 defparameter를 통해 바꿀 수 있음 > (defparameter *max-glasses* 500 "Maximum number of glasses we can make") > (defparameter *max-glasses* 300) > *max-glasses* 300  defvar와 defparameter는 똑같은 문법 구조이지만 defparameter는 프로그램이 실행되는 동안 변화되지 않아야 하는 값에 사용  DEFCONSTANT  만들어진 상수는 절대 바뀌지 않음  Lisp의 special valiable들은 관습적으로 *로 둘러 싸서 표현 하지만 defconstant는 예외를 적용  Lisp는 PI와 같은 내장 상수들이 있음
  • 21. Advanced topics: Rebinding special variables  Function 인자  함수의 인자를 special 변수의 이름으로 지정하여 호출 시 rebinding (defun print-in-base (*print-base* x) (format t "~&~D is written ~S in base ~D." x x *print-base*)) > (print-in-base 2 205) 205 is written 11001101 in base 2. NIL  LET  LET을 통한 바인딩 (defvar *foo* 2) (defun bump-foo () (incf *foo*)) (defun rebind-boo () (let ((*foo* 100)) (incf *foo*) (bump-foo)))
  • 22. Ansi Lisp: Macro design – example(1)  ntimes 매크로 만들기  입력된 숫자횟수만큼 반복 실행하는 매크로  (ntimes count &body body)  > (ntimes 10 (princ ".")) .......... NIL  References  ansi lisp  http://onlisp.blogspot.com/2007/12/10-ansi-common-lisp.html
  • 23. Ansi Lisp: Macro design – example(2)  ntimes 매크로  (defmacro ntimes (n &rest body) `(do ((x 0 (+ x 1))) ((>= x ,n)) ,@body))  문제점  변수 x를 생성해서 기존에 변수 x가 있었다면 의도치 않은 결과 발생  잘못된 예  (let ((x 10)) (ntimes 5 (setf x (+ x 1))) x) 10  X에 10을 할당하고 그 값을 5번 증가 시켜야 하지만 결과 값은 그대로 10이 됨  매크로 확장  (let ((x 10)) (do ((x 0 (+ x 1))) ((>= x 5)) (setf x (+ x 1))) ;; let으로 생성된 x가 아닌 do안의 변수 x가 증가 x)
  • 24. Ansi Lisp: Macro design – example(3)  수정된 ntimes 매크로  do loop안의 변수를 gensym을 통하여 프로그램내의 어느 심볼과도 같지 않게 만듬  (defmacro ntimes (n &rest body) (let ((g (gensym))) `(do ((,g 0 (+ ,g 1))) ((>= ,g ,n)) ,@body)))  문제점  반복 평가  do 문의 body가 평가 될때 마다 n이 새롭게 평가 된다.  잘못된 예  > (let ((v 10)) (ntimes (setf v (- v 1)) (princ "."))) ..... NIL  원하는 결과는 v에서 10에서 1을 뺀 9개의 점을 출력  매크로 확장  (let ((v 10)) (do ((#:g1 0 (+ #:g1 1))) ((>= #:g1 (setf v (- v 1)))) (princ ".")))
  • 25. Ansi Lisp: Macro design – example(4)  수정된 ntimes 매크로  (defmacro ntimes (n &rest body) (let ((g (gensym)) (h (gensym))) `(let ((,h ,n)) (do ((,g 0 (+ ,g 1))) ((>= ,g ,h)) ,@body))))  문제점  해결됨