This commit is contained in:
Michael Zhang 2020-02-25 02:29:00 -06:00
parent dd0674a798
commit d8199f9cbb
Signed by: michael
GPG Key ID: BDA47A31A3C8EE6B
12 changed files with 339 additions and 41 deletions

View File

@ -1,12 +1,12 @@
\begin{frame}[fragile]
\frametitle{Deep Dive into Dependency Calculation}
\frametitle{Deep dive into dependency calculation}
\begin{columns}
\begin{column}{0.55\textwidth}
\begin{verbatim}
\begin{column}{0.5\textwidth}
\begin{Verbatim}[fontsize=\small]
component HelloWorld {
model {
name: String = "hello",
name: String = "",
}
view {
@ -14,7 +14,7 @@ component HelloWorld {
"Hello, " {name} "!"
}
}
\end{verbatim}
\end{Verbatim}
\end{column}
\begin{column}{0.3\textwidth}
Points of interest:
@ -28,36 +28,45 @@ component HelloWorld {
\end{frame}
\begin{frame}
\frametitle{Generated Dependency Chart}
\frametitle{Generated dependency chart}
\begin{center}
\includegraphics[width=0.6\textwidth]{{helloworld.dot}.png}
\includegraphics[width=0.6\textwidth]{{./dot/helloworld.dot}.pdf}
\end{center}
\end{frame}
\begin{frame}
\frametitle{Generated Dependency Chart}
\frametitle{Generated dependency chart}
\begin{columns}
\begin{column}{0.4\textwidth}
\includegraphics[width=\textwidth]{{helloworld.dot}.png}
\includegraphics[width=\textwidth]{{./dot/helloworld.dot}.pdf}
\end{column}
\begin{column}{0.5\textwidth}
\begin{itemize}
\item All possible dependent actors are uniquely identified.
\begin{itemize}[<+>]
\item Symbolizes all interactions within the application.
\item All possible dependent actors are uniquely identified.
\item Simple DFS will tell us all updates that need to occur.
\end{itemize}
\end{column}
\end{columns}
\end{frame}
\begin{frame}[fragile]
\frametitle{Case Study 2: Dependencies of TodoMVC}
\begin{frame}
\frametitle{Case study 2: TodoMVC}
\includegraphics[width=\textwidth]{{todomvc.dot}.png}
\begin{center}
\begin{Verbatim}[fontsize=\tiny]
\includegraphics[width=0.7\textwidth]{./todomvc.png}
\end{center}
\end{frame}
\begin{frame}[fragile]
\frametitle{Case study 2: dependencies of TodoMVC}
\begin{center}
\includegraphics[width=0.85\textwidth]{{./dot/todomvc.dot}.pdf}
\begin{BVerbatim}[fontsize=\tiny]
component TodoMVC {
model {
value: String = "",
@ -65,8 +74,9 @@ component TodoMVC {
}
view {
<input bind:value="value" on:submit={|o@todos, o@value| { set!(todos = todos.with(value));
set!(value = ""); }} />
<input bind:value="value"
on:submit={|o@todos, o@value| { set!(todos = todos.with(value));
set!(value = ""); }} />
<ul>
[for (key, line) in {todos} : List<String>]
<li>{line}</li>
@ -74,6 +84,21 @@ component TodoMVC {
</ul>
}
}
\end{Verbatim}
\end{BVerbatim}
\end{center}
\end{frame}
\begin{frame}
\frametitle{Challenges with TodoMVC}
\begin{itemize}
\item Everything within iterator must be parameterized.
\begin{itemize}
\item Generated code must be parameterized as well.
\end{itemize}
\item "Reconciliation", or re-updating the model on change.
\begin{itemize}
\item Consider hash-map-backed linked list implementations.
\end{itemize}
\end{itemize}
\end{frame}

32
dot/component_backend.dot Normal file
View File

@ -0,0 +1,32 @@
digraph {
subgraph {
backend [label = "trait Backend"]
web [label = "struct Web;"]
native [label = "struct Native;"]
web_back_impl [label = "impl Backend for Web", shape="rectangle"]
native_back_impl [label = "impl Backend for Native", shape="rectangle"]
web -> web_back_impl
web_back_impl -> backend
native -> native_back_impl
native_back_impl -> backend
ib_trait [label = "trait InputBoxTrait { type Backend; }"]
ib_web [label = "struct InputBoxWeb {\l web_ref: Reference,\l}\l"]
ib_native [label = "struct InputBoxNative {\l gl_ctx: GlContext,\l}\l"]
ib_web_trait_impl [label = "impl InputBoxTrait for InputBoxWeb {\l type Backend = Web;\l}\l", shape="rectangle"]
ib_native_trait_impl [label = "impl InputBoxTrait for InputBoxNative {\l type Backend = Native;\l}\l", shape="rectangle"]
ib_web_trait_impl -> ib_trait
ib_native_trait_impl -> ib_trait
ib_web -> ib_web_trait_impl
ib_web_trait_impl -> web
ib_native -> ib_native_trait_impl
ib_native_trait_impl -> native
}
}

Binary file not shown.

View File

@ -3,5 +3,6 @@ digraph {
1 [label="ModelValue(\"name\")"]
2 [label="RsxSpan(\"sym_2\")"]
0 -> 1
1 -> 0
1 -> 2
}

BIN
dot/helloworld.dot.pdf Normal file

Binary file not shown.

View File

@ -1,13 +1,20 @@
digraph {
rankdir = "LR";
0 [label="RsxAttr(\"sym_0\", \"value\")"]
subgraph {
rank = "source";
0 [label="RsxAttr(\"sym_0\", \"value\")"]
2 [label="CodeSeg(\"sym_3\")"]
}
1 [label="ModelValue(Leaf(\"value\"))"]
2 [label="CodeSeg(\"sym_3\")"]
3 [label="ModelValue(Leaf(\"todos\"))"]
4 [label="RsxEvent(\"sym_0\", \"submit\")"]
5 [label="CodeSeg(\"sym_9\")"]
6 [label="Iterator(\"sym_8\")"]
subgraph {
rank = "same";
5 [label="CodeSeg(\"sym_9\")"]
6 [label="Iterator(\"sym_8\")"]
7 [label="RsxSpan(\"sym_10\")"]
}
0 -> 1
1 -> 0
2 -> 3
@ -15,4 +22,5 @@ digraph {
4 -> 2
5 -> 6
3 -> 5
6 -> 7
}

BIN
dot/todomvc.dot.pdf Normal file

Binary file not shown.

167
general.tex Normal file
View File

@ -0,0 +1,167 @@
\begin{frame}
\frametitle{Interlude: Generalization}
\begin{itemize}
\item All generated code must never refer to specific implementations.
\item Whether or not a specific component is implemented should be determined at compile time.
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Traits}
\begin{itemize}
\item Traits are interfaces; describe a set of methods.
\item Traits are constraints; they limit function input.
\item Traits are markers; they can indicate certain properties.
\end{itemize}
\begin{center}
\begin{BVerbatim}[fontsize=\small]
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
fn for_each<I, T, F>(mut iter: I, func: F)
where I: Iterator<Item=T>, F: Fn(T) {
loop {
match iter.next() {
Some(next) => func(next),
None => return,
}
}
}
\end{BVerbatim}
\end{center}
\end{frame}
\begin{frame}[fragile]
\frametitle{How can we use traits to our advantage?}
\begin{itemize}
\item Have a \texttt{Backend} trait to represent different backends
\end{itemize}
\begin{center}
\begin{BVerbatim}
trait Backend {
fn func1(...) -> (...);
}
\end{BVerbatim}
\end{center}
\end{frame}
\begin{frame}[fragile]
\frametitle{How can we use traits to our advantage?}
\begin{itemize}
\item Have a \texttt{Component} trait to represent different components
\item \texttt{Component}s are \textit{parameterized} by backends
\end{itemize}
\begin{center}
\begin{BVerbatim}
trait Component<B: Backend> {
fn foo(...) -> Bar;
}
\end{BVerbatim}
\end{center}
\end{frame}
\begin{frame}[fragile]
\frametitle{How can we use traits to our advantage?}
\begin{itemize}
\item Individual components implement a trait on a specific backend.
\item If there's no implementation, the compile will fail.
\end{itemize}
\begin{center}
\begin{BVerbatim}
struct InputBox {
some_field_1: SomeType1,
some_field_2: SomeType2,
}
// Now we can use InputBox for web targets!
impl Component<Web> for InputBox {
fn foo(...) -> Bar {
(...)
}
}
\end{BVerbatim}
\end{center}
\end{frame}
\begin{frame}[fragile]
\frametitle{It's not that easy...}
\begin{itemize}
\item \textbf{Problem:} all backends now share the same data structure.
\item A web input box needs different data than a native one.
\end{itemize}
\begin{columns}
\begin{column}{0.4\textwidth}
\begin{Verbatim}
struct InputBoxWeb {
web_ref: Reference,
}
\end{Verbatim}
\end{column}
\begin{column}{0.4\textwidth}
\begin{Verbatim}
struct InputBoxNative {
gl_ctx: GlContext,
}
\end{Verbatim}
\end{column}
\end{columns}
\end{frame}
\begin{frame}[fragile]
\frametitle{Don't limit components or backends}
We don't want to end up in a scenario where we're enumerating all backends or components. For example:
\vspace{1em}
\begin{columns}
\begin{column}{0.4\textwidth}
\begin{Verbatim}
enum InputBox {
Web(...),
Native(...),
...
}
\end{Verbatim}
\vspace{0.5em}
\small{What happens when we add a new backend?}
\end{column}
\begin{column}{0.4\textwidth}
\begin{Verbatim}
trait Backend {
type InputBox;
type Button;
...
}
\end{Verbatim}
\vspace{0.5em}
\small{What happens when we add a new component?}
\end{column}
\end{columns}
\end{frame}
\begin{frame}
\frametitle{Potential model}
\begin{center}
\includegraphics[width=.85\textwidth]{{./dot/component_backend.dot}.pdf}
\end{center}
\begin{itemize}
\item \small{How do we discover the concrete implementation from the abstract trait?}
\end{itemize}
\end{frame}

View File

@ -6,14 +6,12 @@
\usepackage{graphicx}
\usepackage{fancyvrb}
\graphicspath{ {./dot/} }
\setbeamercovered{transparent}
\title{enterprise}
\subtitle{UI Framework Project}
\author{Michael Zhang}
\date[\today]{SIFT Interview, \today}
\date{\today}
\begin{document}
@ -23,7 +21,18 @@
\end{frame}
\begin{frame}
\frametitle{High-Level Goals}
\frametitle{What's out there today?}
\begin{itemize}[<+>]
\item React: Immediate-mode style framework
\item Elm: Functional message-passing framework
\item Svelte: Compile-time framework
\item Roll your own... ?
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{High-level goals}
\begin{itemize}[<+>]
\item Declarative-style programming.
@ -32,9 +41,6 @@
\item No framework bloat.
\note{enterprise is more like a compiler than a framework in the sense that the code it generates doesn't need to contain the actual compilation process.}
\item Ahead-of-time guarantees.
\note{Another benefit of it being a compiler is that it is difficult to get run-time errors. If it compiles, it works.}
\item Separation of business logic and implementation.
\note{Talk about Epic?}
\end{itemize}
@ -53,7 +59,7 @@
\begin{verbatim}
component HelloWorld {
model {
name: String = "hello",
name: String = "",
}
view {
@ -78,10 +84,12 @@
\include{deps}
\include{general}
\include{codegen}
\begin{frame}
\frametitle{Future Work}
\frametitle{Future work}
\begin{itemize}
\item Full DSL, independent from Rust.
@ -89,6 +97,8 @@
\item Asynchronous event handlers.
\item Eliminating unnecessary model stores.
\item Connecting to other frameworks (GTK, Iced, etc.)
\item Interpreted executor for fast prototyping.
\item Backend code generation.
\end{itemize}
\end{frame}

View File

@ -1,18 +1,18 @@
\begin{frame}[fragile]
\frametitle{Deep Dive into Parsing DSL Syntax}
\frametitle{Deep dive into parsing DSL syntax}
\begin{columns}
\begin{column}{0.3\textwidth}
\begin{itemize}
\begin{itemize}[<+>]
\item Hand-rolled recursive-descent parser.
\item Why not use LR parser generator?
\end{itemize}
\end{column}
\begin{column}{0.55\textwidth}
\begin{verbatim}
\begin{column}{0.5\textwidth}
\begin{Verbatim}[fontsize=\small]
component HelloWorld {
model {
name: String = "hello",
name: String = "",
}
view {
@ -20,7 +20,7 @@ component HelloWorld {
"Hello, " {name} "!"
}
}
\end{verbatim}
\end{Verbatim}
\end{column}
\end{columns}
\end{frame}
@ -30,15 +30,15 @@ component HelloWorld {
\begin{columns}
\begin{column}{0.4\textwidth}
\begin{verbatim}
\begin{Verbatim}
// proc-macro library
pub enum TokenTree {
enum TokenTree {
Group(Group),
Ident(Ident),
Punct(Punct),
Literal(Literal),
}
\end{verbatim}
\end{Verbatim}
\end{column}
\begin{column}{0.4\textwidth}
\begin{itemize}
@ -51,3 +51,58 @@ pub enum TokenTree {
\end{columns}
\end{frame}
\begin{frame}[fragile]
\frametitle{Abstract syntax}
\begin{center}
\begin{BVerbatim}[fontsize=\small]
struct Component {
name: String,
model: ModelMap,
view: Vec<Rsx>,
}
enum Rsx {
Elem(Elem<Rsx>),
Code(Context, Expr),
Text(String),
ForLoop(Pat, Expr, Type, Vec<Rsx>),
}
...
\end{BVerbatim}
\end{center}
\end{frame}
\begin{frame}
\frametitle{Checking your work.. with property testing}
\begin{itemize}[<+>]
\item Define certain properties about the procedures.
\item Define types of data that can be passed in.
\item Create "strategies" for randomly generating complex data.
\item Computer generates input cases based on the strategies.
\item Bonus: input cases are "shrunk" down to the minimal case.
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{Property testing example}
\begin{Verbatim}[fontsize=\small]
proptest! {
#[test]
fn tokens_parse_compatibility(tree in arbitrary_component()) {
// turn the input tree into tokens and back
let tokens = tree.to_token_stream();
let mut visitor = Visitor::from_tokens(tokens.clone());
let tree2 = visitor.next().unwrap().unwrap();
// compare the trees
prop_assert_eq!(tree.name, tree2.name);
prop_assert_eq!(tree.model, tree2.model);
prop_assert_eq!(tree.view, tree2.view);
}
}
\end{Verbatim}
\end{frame}

BIN
todomvc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -8,6 +8,6 @@ killgroup() {
kill 0
}
watchexec -w dot -e dot "dot -Tpng -O dot/*.dot" &
watchexec -w dot -e dot "dot -Tpdf -O dot/*.dot" &
watchexec -e tex "tectonic main.tex" &
wait