SlideShare a Scribd company logo
1 of 43
Download to read offline
무민(조현석) @ 컨스택츠
(내가 감동 먹은)
Haskell에서 Postgresql을
사용하는 우아한 방법
Quasiquotation
옛날 옛날 아주 먼 옛날에
컨스택츠에 메인 디비가 MongoDB였어요
단테
“postgresql로 이사갑시다!”
나머지 코드(DB, Kafka)
컨스택츠 BE 구성
도메인
Types Service
김은민(토드). [Dev Dive 2022]. (2022. 11. 16.). [Dev Dive_ Backend Day] 하스켈로 백엔드 시스템 만든 이야기 [영상]. 유튜브. https://www.youtube.com/watch?v=YBLZGUeNSu4
SQL이 문자열로?
혹시 쿼리 매퍼일까?
ORM, ODM, FRM은?
이것은 문자열이 아닙니다(?)
QuasiQuotes
쿼리 매퍼도 아닙니다
빨라진 개발 리듬
기능 코딩 -> 기능 해 봄 -> 안 됨 -> 코딩 -> 해 봄 -> 안 됨 ... -> 완성
기능 코딩 -> 테스트 실행 -> 실패 -> 코딩 -> 테스트 실행 -> ... -> 완성
기능 코딩 -> 컴파일 -> 에러 -> 코딩 -> 컴파일 -> 에러 ... -> 완성
사실은 거의 코딩 시점
김은민. [Dev Dive 2022]. (2022. 11. 16.). [Dev Dive_ Backend Day] 하스켈로 백엔드 시스템 만든 이야기 [영상]. 유튜브. https://www.youtube.com/watch?v=YBLZGUeNSu4
애초에 우리는
왜
ORM이라는 걸 쓰게 되었을까?
혹시 내가 함수뽕에 빠져서 시야가 흐려진게 아닐까?
“SQL 중심적인 개발의 문제점”
“누구나 그럴싸한 계획을 갖고 있다.
Hello World를 벗어나기 전까지는”
Why It’s Nice to be Quoted
Quasiquoting for Haskell
개발자는 다양한 DSL을 사용합니다.
JSON
정규표현식
XML
YAML
언어/언어확장이 지원
JSX
정규표현식
언어의 문법에 맞게 내부에서 사용
Kotlin DSL
Querydsl
외부 파일을 사용한다.
Quasiquotation
(파서를 작성하는 것보다 약간의 작업이 더 필요하지만)
Quasiquoting으로 묶인 모든 데이터의 타입이 정확하
다는 것을 컴파일 시간 보장
[quoter| string |]
• ⟨quoter⟩는 임포트된 quoter의 이름이어야 합니다. 임의의 표현이 될 수 없습니다.
• ⟨quoter⟩는 "e", "t", "d" 또는 "p"일 수 없습니다. 템플릿 하스켈 quotations과 겹치기
때문입니다.
• 토큰 [quoter|에는 공백이 없어야 합니다.
• quote된 ⟨string⟩은 임의적일 수 있으며 개행을 포함할 수 있습니다.
• 따옴표로 묶인 ⟨string⟩은 첫 번째 "|]"에서 끝납니다. 그 외 절대 끝나지 않습니다. 해당 문
자 시퀀스를 문자열에 포함하려면 고유한 이스케이프 규칙(예: 대신 문자열 "|~]" 사용)을
만들고 quoter 함수가 "|~]"를 "| ]”로 변환해야 한다.
Quasiquote는 다음 위치 중 하나에서 등장 할 수 있다.
• 표현식
• 패턴
• 타입
• 최상위 선언
data QuasiQuoter = QuasiQuoter { quoteExp :: String -> Q Exp,
quotePat :: String -> Q Pat,
quoteType :: String -> Q Type,
quoteDec :: String -> Q [Dec]
}
그렇다면 내부를 들여다 보자
https://github.com/dylex/postgresql-typed/blob/master/Database/PostgreSQL/Typed/Query.hs
그럼요!
나도 QuasiQuoter를 만들 수 있을까?
-- >>> eval [expr|1|]
-- 1
-- >>> eval [expr|1 + 2|]
-- 3
-- >>> eval [expr|1+2+3|]
-- 6
data Expr = IntExpr Integer
| BinopExpr BinOp Expr Expr
deriving(Show, Typeable, Data)
data BinOp = AddOp
| SubOp
| MulOp
| DivOp
deriving(Show, Typeable, Data)
data Expr = IntExpr Integer
| AntiIntExpr String
| BinopExpr BinOp Expr Expr
| AntiExpr String
deriving(Show, Typeable, Data)
x :: Integer
x = 1
eval [expr|$x + 3|]
parseExpr :: m => String -> m Expr
parseExpr s = …
expr :: QuasiQuoter
expr = QuasiQuoter { quoteExp = quoteExprExp,
quotePat = quoteExprPat,
quoteType = error "",
quoteDec = error "" }
quoteExprExp :: String -> TH.ExpQ
quoteExprExp s = do
expr <- parseExpr s
liftData expr
quoteExprExp :: String -> TH.ExpQ
quoteExprExp s = do loc <- TH.location
let pos = (TH.loc_filename loc,
fst (TH.loc_start loc),
snd (TH.loc_start loc))
expr <- parseExpr pos s
dataToExpQ (const Nothing `extQ` antiExprExp) expr
antiExprExp :: Expr -> Maybe (TH.Q TH.Exp)
antiExprExp (AntiIntExpr v) = Just $ TH.appE (TH.conE (TH.mkName "IntExpr"))
(TH.varE (TH.mkName v))
antiExprExp (AntiExpr v) = Just $ TH.varE (TH.mkName v)
antiExprExp _ = Nothing
quoteExprPat :: String -> TH.PatQ
quoteExprPat s = do loc <- TH.location
let pos = (TH.loc_filename loc,
fst (TH.loc_start loc),
snd (TH.loc_start loc))
expr <- parseExpr pos s
dataToPatQ (const Nothing `extQ` antiExprPat) expr
antiExprPat :: Expr -> Maybe (TH.Q TH.Pat)
antiExprPat (AntiIntExpr v) = Just $ TH.conP (TH.mkName "IntExpr")
[TH.varP (TH.mkName v)]
antiExprPat (AntiExpr v) = Just $ TH.varP (TH.mkName v)
antiExprPat _ = Nothing
eval :: Expr -> Integer
eval (IntExpr n) = n
eval (BinopExpr op x y) = (opToFun op) (eval x) (eval y)
where
opToFun AddOp = (+)
opToFun SubOp = (-)
opToFun MulOp = (*)
opToFun DivOp = div
eval' :: Expr -> Integer
eval' [expr|$int:x|] = x
eval' [expr|$x + $y|] = eval' x + eval' y
eval' [expr|$x - $y|] = eval' x - eval' y
eval' [expr|$x * $y|] = eval' x * eval' y
eval' [expr|$x / $y|] = eval' x `div` eval' y
결론
• 하스켈에는 DSL을 임베드 시킬 수 있는 QuasiQuotes라는 것이 있다.
• (그걸로 만들어진 라이브러리를) 써보니 편하더라

More Related Content

What's hot

온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기
Seungjae Lee
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
min woog kim
 
전형규, M2 클라이언트 스레딩 아키텍쳐, NDC2013
전형규, M2 클라이언트 스레딩 아키텍쳐, NDC2013전형규, M2 클라이언트 스레딩 아키텍쳐, NDC2013
전형규, M2 클라이언트 스레딩 아키텍쳐, NDC2013
devCAT Studio, NEXON
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
devCAT Studio, NEXON
 
[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬
KyeongWon Koo
 
UE4 Garbage Collection
UE4 Garbage CollectionUE4 Garbage Collection
UE4 Garbage Collection
QooJuice
 
08_게임 물리 프로그래밍 가이드
08_게임 물리 프로그래밍 가이드08_게임 물리 프로그래밍 가이드
08_게임 물리 프로그래밍 가이드
noerror
 

What's hot (20)

나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기
 
온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
 
자바 웹프로젝트 개발환경 셋팅
자바 웹프로젝트 개발환경 셋팅자바 웹프로젝트 개발환경 셋팅
자바 웹프로젝트 개발환경 셋팅
 
(독서광) Docs for Developers 기술 문서 작성 완벽 가이드
(독서광) Docs for Developers 기술 문서 작성 완벽 가이드(독서광) Docs for Developers 기술 문서 작성 완벽 가이드
(독서광) Docs for Developers 기술 문서 작성 완벽 가이드
 
Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)
 
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
 
[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기
[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기
[NDC 2010] 그럴듯한 랜덤 생성 컨텐츠 만들기
 
LockFree Algorithm
LockFree AlgorithmLockFree Algorithm
LockFree Algorithm
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
 
[NDC14] 모바일 게임의 다음 혁신 - 야생의 땅 듀랑고의 계산 프로세스 중심 게임 디자인
[NDC14] 모바일 게임의 다음 혁신 - 야생의 땅 듀랑고의 계산 프로세스 중심 게임 디자인[NDC14] 모바일 게임의 다음 혁신 - 야생의 땅 듀랑고의 계산 프로세스 중심 게임 디자인
[NDC14] 모바일 게임의 다음 혁신 - 야생의 땅 듀랑고의 계산 프로세스 중심 게임 디자인
 
전형규, M2 클라이언트 스레딩 아키텍쳐, NDC2013
전형규, M2 클라이언트 스레딩 아키텍쳐, NDC2013전형규, M2 클라이언트 스레딩 아키텍쳐, NDC2013
전형규, M2 클라이언트 스레딩 아키텍쳐, NDC2013
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
 
Git을 조금 더 알아보자!
Git을 조금 더 알아보자!Git을 조금 더 알아보자!
Git을 조금 더 알아보자!
 
[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬[0903 구경원] recast 네비메쉬
[0903 구경원] recast 네비메쉬
 
UE4 Garbage Collection
UE4 Garbage CollectionUE4 Garbage Collection
UE4 Garbage Collection
 
추천시스템 이제는 돈이 되어야 한다.
추천시스템 이제는 돈이 되어야 한다.추천시스템 이제는 돈이 되어야 한다.
추천시스템 이제는 돈이 되어야 한다.
 
08_게임 물리 프로그래밍 가이드
08_게임 물리 프로그래밍 가이드08_게임 물리 프로그래밍 가이드
08_게임 물리 프로그래밍 가이드
 
SPH 기법을 이용한 2D 물 물리 엔진 개발
SPH 기법을 이용한 2D 물 물리 엔진 개발SPH 기법을 이용한 2D 물 물리 엔진 개발
SPH 기법을 이용한 2D 물 물리 엔진 개발
 
게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가
 

Similar to liftIO 2022 quasiquote

Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822
병헌 정
 
자바와 사용하기2
자바와 사용하기2자바와 사용하기2
자바와 사용하기2
destinycs
 

Similar to liftIO 2022 quasiquote (20)

Programming skills 1부
Programming skills 1부Programming skills 1부
Programming skills 1부
 
Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822
 
ES6 for Node.js Study 2주차
ES6 for Node.js Study 2주차ES6 for Node.js Study 2주차
ES6 for Node.js Study 2주차
 
Scala
ScalaScala
Scala
 
Regex
RegexRegex
Regex
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기
 
불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
 
Java advancd ed10
Java advancd ed10Java advancd ed10
Java advancd ed10
 
.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기
 
자바와 사용하기2
자바와 사용하기2자바와 사용하기2
자바와 사용하기2
 
Python programming for Bioinformatics
Python programming for BioinformaticsPython programming for Bioinformatics
Python programming for Bioinformatics
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
 
android_thread
android_threadandroid_thread
android_thread
 
Functional thinking - 책 리뷰 1탄
Functional thinking - 책 리뷰 1탄Functional thinking - 책 리뷰 1탄
Functional thinking - 책 리뷰 1탄
 
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
 
Java.next
Java.nextJava.next
Java.next
 
[Swift] Protocol (2/2)
[Swift] Protocol (2/2)[Swift] Protocol (2/2)
[Swift] Protocol (2/2)
 
0327.web&ruby&rails
0327.web&ruby&rails0327.web&ruby&rails
0327.web&ruby&rails
 
Scalability
ScalabilityScalability
Scalability
 

Recently uploaded

Recently uploaded (8)

JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
JMP 기능의 확장 및 내재화의 핵심 JMP-Python 소개
 
JMP가 걸어온 여정, 새로운 도약 JMP 18!
JMP가 걸어온 여정, 새로운 도약 JMP 18!JMP가 걸어온 여정, 새로운 도약 JMP 18!
JMP가 걸어온 여정, 새로운 도약 JMP 18!
 
데이터 분석 문제 해결을 위한 나의 JMP 활용법
데이터 분석 문제 해결을 위한 나의 JMP 활용법데이터 분석 문제 해결을 위한 나의 JMP 활용법
데이터 분석 문제 해결을 위한 나의 JMP 활용법
 
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
실험 설계의 평가 방법: Custom Design을 중심으로 반응인자 최적화 및 Criteria 해석
 
공학 관점에서 바라본 JMP 머신러닝 최적화
공학 관점에서 바라본 JMP 머신러닝 최적화공학 관점에서 바라본 JMP 머신러닝 최적화
공학 관점에서 바라본 JMP 머신러닝 최적화
 
JMP를 활용한 가속열화 분석 사례
JMP를 활용한 가속열화 분석 사례JMP를 활용한 가속열화 분석 사례
JMP를 활용한 가속열화 분석 사례
 
JMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
JMP를 활용한 전자/반도체 산업 Yield Enhancement MethodologyJMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
JMP를 활용한 전자/반도체 산업 Yield Enhancement Methodology
 
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
(독서광) 인간이 초대한 대형 참사 - 대형 참사가 일어날 때까지 사람들은 무엇을 하고 있었는가?
 

liftIO 2022 quasiquote