32. D E C L A R AT I V E P R O G R A M M I N G
•
•
• (Impertive)
• (Declarative)
33. D E C L A R AT I V E P R O G R A M M I N G
•
• (Impertive)
•
• ? (How it is to be computed)
• (Declarative)
34. D E C L A R AT I V E P R O G R A M M I N G
•
• (Impertive)
• (Declarative)
• SQL, Apache Ant(partially), HTML
• ? (What is to be computed)
35.
36. D E C L A R AT I V E U I
• UI ?
• UI ?
// Declarative style
return ViewB(
color: red,
child: ViewC(...),
)
// Imperative style
b.setColor(red)
b.clearChildren()
ViewC c3 = new ViewC(...)
b.add(c3)
55. D A R T
Single Items Multiple Items
Synchronous T getData() List<T> getData()
Asynchronous Future<T> getData() Stream<T> getData()
56. S W I F T
Single Items Multiple Items
Synchronous T getData() Collection<T> getData()
Asynchronous None
Beta
(Publisher<T> in Combine)
57. S W I F T W I T H R X
Single Items Multiple Items
Synchronous T getData() Collection<T> getData()
Asynchronous Single<T> getData() Observable<T> getData()
60. B L O C E X A M P L E : I N F I N I T Y L I S T
import 'package:equatable/equatable.dart';
abstract class PostEvent extends Equatable {}
class Fetch extends PostEvent {
@override
String toString() => 'Fetch';
}
62. class PostBloc extends Bloc<PostEvent, PostState> {
...
@override
Stream<PostState> mapEventToState(PostEvent event) async* {
if (event is Fetch && !_hasReachedMax(currentState)) {
try {
if (currentState is PostUninitialized) {
final posts = await _fetchPosts(0, 20);
yield PostLoaded(posts: posts, hasReachedMax: false);
return;
}
if (currentState is PostLoaded) {
final posts =
await _fetchPosts((currentState as PostLoaded).posts.length, 20);
yield posts.isEmpty
? (currentState as PostLoaded).copyWith(hasReachedMax: true)
: PostLoaded(
posts: (currentState as PostLoaded).posts + posts,
hasReachedMax: false,
);
}
} catch (_) {
yield PostError();
}
}
}
}
63. R E A C T O R K I T E X A M P L E
import RxSwift
class PostListReactor {
enum Action {
...
case fetch([Post])
}
enum Mutation {
case setIsInitialized(Bool)
case setIsLoaded(Bool)
case setPosts([Post])
case setHasReachedMax(Bool)
case setError(Error?)
}
struct State {
let isInitialized: Bool = false
let isLoaded: Bool = false
let posts: [Post] = []
let hasReachedMax: Bool = false
let error: Error? = nil
}
let initialState: State = .init()
...
64. func mutate(action: Action) -> Observable<Mutation> {
switch action {
...
case let .fetch(posts):
let posts: Observable<Mutation> = .just(.setPosts(posts))
let hasReachedMax: Observable<Mutation> = .just(.setHasReachedMax(posts.isEmpty))
return .concat(posts, hasReachedMax)
}
}
func reduce(mutation: Mutation, state: State) -> Observable<State> {
var state = state
switch mutation {
case let .setPost(posts) where currentState.isLoaded:
state.posts += posts
case let .setPost(posts) where !currentState.isLoaded:
state.posts = posts
case let .setHasReachedMax(hasReachedMax):
state.hasReachedMax = hasReachedMax
}
return state
}
}
78. R E F E R E N C E
• Wikipedia: Declarative Programming
• https://en.wikipedia.org/wiki/Declarative_programming
• Declarative UI and Vaadin Designer
• https://www.youtube.com/watch?v=MwuIDsFizMA
• Practical advantages of declarative programming
• ftp://cliplab.org/pub/papers/PARFORCE/second_review/D.WP3.1.M2.3.ps.Z
• Algorithm = Logic + Control
• https://www.doc.ic.ac.uk/~rak/papers/algorithm%20=%20logic%20+%20control.pdf
• List of programming languages by type
• https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Declarative_languages
79. R E F E R E N C E
• Flutter Youtube
• https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw
• WWDC 2019 Data Flow through SwiftUI
• https://developer.apple.com/videos/play/wwdc2019/226/
• Flux
• https://facebook.github.io/flux/docs/in-depth-overview
• ReactorKit
• https://github.com/ReactorKit/ReactorKit