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

Action Jackson! Effective JSON processing in Spring Boot Applications
Action Jackson! Effective JSON processing in Spring Boot ApplicationsAction Jackson! Effective JSON processing in Spring Boot Applications
Action Jackson! Effective JSON processing in Spring Boot ApplicationsJoris Kuipers
 
Asynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & PromisesAsynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & PromisesHùng Nguyễn Huy
 
Getting Started with Spring Authorization Server
Getting Started with Spring Authorization ServerGetting Started with Spring Authorization Server
Getting Started with Spring Authorization ServerVMware Tanzu
 
Design patterns avec Symfony
Design patterns avec SymfonyDesign patterns avec Symfony
Design patterns avec SymfonyMohammed Rhamnia
 
Spring Mvc,Java, Spring
Spring Mvc,Java, SpringSpring Mvc,Java, Spring
Spring Mvc,Java, Springifnu bima
 
Working with Dynamic Content and Adding Templating engines, MVC
Working with Dynamic Content and Adding Templating engines, MVCWorking with Dynamic Content and Adding Templating engines, MVC
Working with Dynamic Content and Adding Templating engines, MVCKnoldus Inc.
 
Event driven microservices with axon and spring boot-excitingly boring
Event driven microservices with axon and spring boot-excitingly boringEvent driven microservices with axon and spring boot-excitingly boring
Event driven microservices with axon and spring boot-excitingly boringAllard Buijze
 
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)Amazon Web Services Korea
 
Presentation Spring, Spring MVC
Presentation Spring, Spring MVCPresentation Spring, Spring MVC
Presentation Spring, Spring MVCNathaniel Richand
 
Java Server Faces (JSF)
Java Server Faces (JSF)Java Server Faces (JSF)
Java Server Faces (JSF)Heithem Abbes
 
IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교JungWoon Lee
 
MongoDB: システム可用性を拡張するインデクス戦略
MongoDB: システム可用性を拡張するインデクス戦略MongoDB: システム可用性を拡張するインデクス戦略
MongoDB: システム可用性を拡張するインデクス戦略ippei_suzuki
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Steven Smith
 

What's hot (20)

Action Jackson! Effective JSON processing in Spring Boot Applications
Action Jackson! Effective JSON processing in Spring Boot ApplicationsAction Jackson! Effective JSON processing in Spring Boot Applications
Action Jackson! Effective JSON processing in Spring Boot Applications
 
Asynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & PromisesAsynchronous JavaScript Programming with Callbacks & Promises
Asynchronous JavaScript Programming with Callbacks & Promises
 
Getting Started with Spring Authorization Server
Getting Started with Spring Authorization ServerGetting Started with Spring Authorization Server
Getting Started with Spring Authorization Server
 
Design patterns avec Symfony
Design patterns avec SymfonyDesign patterns avec Symfony
Design patterns avec Symfony
 
Support programmation orientée objet c# .net version f8
Support programmation orientée objet c#  .net version f8Support programmation orientée objet c#  .net version f8
Support programmation orientée objet c# .net version f8
 
Spring Mvc,Java, Spring
Spring Mvc,Java, SpringSpring Mvc,Java, Spring
Spring Mvc,Java, Spring
 
Working with Dynamic Content and Adding Templating engines, MVC
Working with Dynamic Content and Adding Templating engines, MVCWorking with Dynamic Content and Adding Templating engines, MVC
Working with Dynamic Content and Adding Templating engines, MVC
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Introduction to NodeJS
Introduction to NodeJSIntroduction to NodeJS
Introduction to NodeJS
 
Event driven microservices with axon and spring boot-excitingly boring
Event driven microservices with axon and spring boot-excitingly boringEvent driven microservices with axon and spring boot-excitingly boring
Event driven microservices with axon and spring boot-excitingly boring
 
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
 
Presentation Spring, Spring MVC
Presentation Spring, Spring MVCPresentation Spring, Spring MVC
Presentation Spring, Spring MVC
 
Java Server Faces (JSF)
Java Server Faces (JSF)Java Server Faces (JSF)
Java Server Faces (JSF)
 
Maven
MavenMaven
Maven
 
IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교
 
Spring AOP
Spring AOPSpring AOP
Spring AOP
 
MongoDB: システム可用性を拡張するインデクス戦略
MongoDB: システム可用性を拡張するインデクス戦略MongoDB: システム可用性を拡張するインデクス戦略
MongoDB: システム可用性を拡張するインデクス戦略
 
Node js introduction
Node js introductionNode js introduction
Node js introduction
 
05 1 intro-struttura
05 1 intro-struttura05 1 intro-struttura
05 1 intro-struttura
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0
 

Similar to liftIO 2022 quasiquote

Programming skills 1부
Programming skills 1부Programming skills 1부
Programming skills 1부JiHyung Lee
 
Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822병헌 정
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기Yongha Yoo
 
불어오는 변화의 바람, 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게임서버설계와구현noerror
 
Java advancd ed10
Java advancd ed10Java advancd ed10
Java advancd ed10hungrok
 
.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기.NET에서 비동기 프로그래밍 배우기
.NET에서 비동기 프로그래밍 배우기Seong Won Mun
 
자바와 사용하기2
자바와 사용하기2자바와 사용하기2
자바와 사용하기2destinycs
 
Python programming for Bioinformatics
Python programming for BioinformaticsPython programming for Bioinformatics
Python programming for BioinformaticsHyungyong Kim
 
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 crowJaeseung Ha
 
android_thread
android_threadandroid_thread
android_threadhandfoot
 
Functional thinking - 책 리뷰 1탄
Functional thinking - 책 리뷰 1탄Functional thinking - 책 리뷰 1탄
Functional thinking - 책 리뷰 1탄Jeong-gyu Kim
 
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로Oracle Korea
 
[Swift] Protocol (2/2)
[Swift] Protocol (2/2)[Swift] Protocol (2/2)
[Swift] Protocol (2/2)Bill Kim
 
0327.web&ruby&rails
0327.web&ruby&rails0327.web&ruby&rails
0327.web&ruby&rails민정 김
 

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
 

liftIO 2022 quasiquote