Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
FunctionBuilderでコンパイラを表現しようとした
Search
yosshi
June 18, 2019
Technology
0
770
FunctionBuilderでコンパイラを表現しようとした
FunctionBuilderでコンパイラを表現しようとしたけど、できなかったしユースケースも違った話
yosshi
June 18, 2019
Tweet
Share
More Decks by yosshi
See All by yosshi
Object Oriented Software Development
yosshi4486
0
100
SwiftでZeplinのダークモード対応ツールを作ったよ
yosshi4486
0
450
Implement side-menu with SwiftUI
yosshi4486
2
640
Other Decks in Technology
See All in Technology
GCASアップデート(202506-202508)
techniczna
0
220
九州の人に知ってもらいたいGISスポット / gis spot in kyushu 2025
sakaik
0
210
僕たちが「開発しやすさ」を求め 模索し続けたアーキテクチャ #アーキテクチャ勉強会_findy
bengo4com
0
2.6k
Oracle Base Database Service:サービス概要のご紹介
oracle4engineer
PRO
1
20k
Delegate authentication and a lot more to Keycloak with OpenID Connect
ahus1
0
240
Claude Code x Androidアプリ 開発
kgmyshin
1
380
[OCI Technical Deep Dive] OCIで生成AIを活用するためのソリューション解説(2025年8月5日開催)
oracle4engineer
PRO
0
130
AIエージェントを現場で使う / 2025.08.07 著者陣に聞く!現場で活用するためのAIエージェント実践入門(Findyランチセッション)
smiyawaki0820
7
1.3k
ABEMAにおける 生成AI活用の現在地 / The Current Status of Generative AI at ABEMA
dekatotoro
0
450
形式手法特論:位相空間としての並行プログラミング #kernelvm / Kernel VM Study Tokyo 18th
ytaka23
3
1.5k
AIが住民向けコンシェルジュに?Amazon Connectと生成AIで実現する自治体AIエージェント!
yuyeah
0
230
Gaze-LLE: Gaze Target Estimation via Large-Scale Learned Encoders
kzykmyzw
0
170
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
139
34k
Designing for humans not robots
tammielis
253
25k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Intergalactic Javascript Robots from Outer Space
tanoku
272
27k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.6k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.8k
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.5k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
We Have a Design System, Now What?
morganepeng
53
7.7k
What's in a price? How to price your products and services
michaelherold
246
12k
Transcript
FunctionBuilderͰίϯ ύΠϥΛදݱ͠Α͏ͱͨ͠ Yumemi.inc Αͬ͠ʔɹ
ࣗݾհ ΏΊΈiOSΤϯδχΞ 24ࡀ SwiftUIͱxPlatʹڵຯਂʑ Vue.js/node.js/CS @seijin4486
SwiftUI͔ͬͨ͢͝ શʹDSLʁ͔ͱࢥ͍͖ɺSwiftͷྗΛੜ͔͠ ͬͨه๏ implict return/property wrapper/function builder UIKitͰഓͬͨܦݧ͕ແʹؼ͢͜ͱશ෦ΕͯiOS ΤϯδχΞ྆खͰສࡀ(ͪΖΜUIKitͷݟࠓޙ ੜ͖Δͣ
ࠓͬͯΔͷ ίϯϐϡʔλʔγεςϜͷཧ ͱ࣮ VM͔ΒΞηϯϒϥม͢Δ ͱ͜ΖͰ͑ͳ͍͔ͳ…ɻ
͜͏ॻ͚ͨΒؾ࣋ͪྑ͍ͷͰʂ var body: some VMCommand { Function(name: “mult”) { Push(.constant,
0) Pop(.local, 0) Push(.argument, 1) Pop(.local, 1) Label(“LOOP”) …. Label(“END”) Return } ɹ… } var commands: [Command] = [] func build() -> String { commands.append(Push(.constant, 0)) commands.append(Pop(.argument, 1)) commands.append(Pop(.local, 1)) commands.append(Label(“Loop”)) return commands .map { $0.generate() } .joined(separator: “\n”) } ݱঢ় FunctionBuilderͷظ
ͬͯΈΑ͏ʂ
Ͱ͖ͳ͔ͬͨ
Ұ෦ɺͰ͖ͳ͔ͬͨ TupleViewͷΑ͏ͳΈΛͬͯɺ࣮ࡍʹbody ͷπϦʔΛߏங͢ΔΈ͕͔Βͳ͔ͬͨ SwiftUIͰHTMLͷඳըΛ͢ΔϓϩδΣΫτΛݟͨ ͕ɺMirror࠶ىॲཧΛͬͯؤுͬͯΔ ៉ྷͳղܾ๏ఘΊͯɺҰ୴͜Μͳܗʹͨ͠
FunctionBuilder @_functionBuilder struct CommandBuilder { public static func buildBlock<Content>(_ content:
Content) -> String where Content: Command { content.body } public static func buildBlock<T1, T2>(_ t1: T1, _ t2: T2) -> String where T1: Command, T2: Command { [t1.body, t2.body] .joined(separator: "\n") } struct TupleCommand<T>ͷར༻ఘΊͨ protocol Command { var body: String { get } } struct AssemblyCommand: Command { var body: String init(@CommandBuilder builder: () -> String) { body = builder() } }
͜͏ॻ͚ΔΑ͏ʹͳΓ·ͨ͠ struct Add: Command { var body: String { AssemblyCommand
{ A.symbol(.sp) C.assign(destination: .am, computation: .mMinusOne) C.assign(destination: .d, computation: .m) C.assign(destination: .a, computation: .aMinusOne) C.assign(destination: .m, computation: .dPlusM) }.body } }
ίϯύΠϧ࣌ & ใ͚ͭͨ͠ struct Add: Command { var body: String
{ AssemblyCommand { () -> String in … ᶃ CommandBuilder.buildBlock( … ᶄ A.symbol(.sp), C.assign(destination: .am, computation: .mMinusOne), C.assign(destination: .d, computation: .m), C.assign(destination: .a, computation: .aMinusOne), C.assign(destination: .m, computation: .dPlusM) ) }.body } } @_functionBuilder struct CommandBuilder { public static func buildBlock<T1, T2>(_ t1: T1, _ t2: T2) -> String where T1: Command, T2: Command { [t1.body, t2.body] .joined(separator: "\n") } ᶃ ΫϩʔδϟͷฦΓ ᶄ CommandBuilder
৮ͬͯΈͨײ ࢹ֮తͳཧղ༻ҙੑ্͕͕Δ(Έ͍͢) buildBlockgybͰੜ͞Εͯͦ͏ TupleViewΛͲ͏ͬͯΔ͔Γ͍ͨ Ϣʔεέʔε͕ҧͬͨ
Ϣʔεέʔε͕ҧͬͨ…ͳͥʁ SwiftUIɺ։ൃऀ͕ࣗ༝ʹViewStackΛΊΔ struct MyGroupView : View { var category: String
var categorizedItems: [Item] var body: some View { VStack(alignment: .leading, spacing: 10) { Text(category) .padding(.top, 10) .padding(.leading, 8) .background(Color.green) .cornerRadius(5) .padding(5) Group { ForEach(categorizedItems) { item in ListRow(item: item) } } } .padding(.bottom, 10) } }
Ϣʔεέʔε͕ҧͬͨ…ͳͥʁ Push, Pop, Call, FunctionͳͲɺVMΛׂ/ύʔε͠ ͨ༰ʹґଘͯ͠ߏங͢ΔͷͰɺ։ൃऀ͕ࣗߏ ங͢Δߏ͕΄΅ଘࡏ͠ͳ͍ ϝϦοτ΄΅ͳ͍ VMهड़DSLͱͯ͠FunctionBuilderΛ༻͍ΔͳΒ… ΞϦ(?)
·ͱΊ Apple͕ViewBuilderͰ࡞ͬͨ༰ΛͲ͏ඳը͍ͤͯ͞Δͷ ͔͔Βͳ͍ɻΓ͍ͨ ViewBuilderΛ͏ͱɺ͘͢͝ݟ͘͢ॻ͚Δࣄ͕͔ͬͨ ΤϯδχΞଆ͕ߏΛࣗ༝ʹهड़͢ΔέʔεͰɺઈେ ͳޮՌΛൃش͢Δɻ ࠓճͷόοΫΤϯυίϯύΠϥͰͬͯΈΔࢼΈࣦഊ Ͱ៉ྷʹݟ͑Δ