SlideShare una empresa de Scribd logo
1 de 68
Descargar para leer sin conexión
那些Rust裡好⽤用的抽象與
實⽤用語法火⼒力力展⽰示
Wayne Tsai
Useful abstractions at rust and it’s
practical usage
About Me
• Frontend, rust and node.js enthusiast
• Desktop app developer with electron
• 12th ITHelp ironman competition
- software development category (champion)
Agenda
• Why Rust
• Collection and Iterator
• Option and Result
• Conclusion
Why Rust
https://www.figma.com/blog/rust-in-production-at-figma/
Why Rust
Node.js and Typescript
https://www.figma.com/blog/rust-in-production-at-figma/
Why Rust
Integrate rust with node.js
https://www.figma.com/blog/rust-in-production-at-figma/
Who is using rust
https://tokio.rs/
Collection and Iterator
Collection and For Syntax
• Typescript
• Rust
let arr = [4, 5, 6];
for(let item of arr) {
console.log(`print: ${item}`);
}
let vec = vec![4,5,6];
for item in vec.iter() {
println!("print: {}", item);
}
// print: 4
// print: 5
// print: 6
TS Array v.s RS Vector
• Typescript
let mapped: number[] = [1,2,3].map(x => x + 1); // [2,3,4]
let filtered: number[] = [1,2,3].filter(x => x > 2); // [3]
• Rust
let mapped: Vec<i32> = vec![1,2,3].iter().map(|x| x + 1).collect(); // [2,3,4]
let filtered: Vec<i32> = vec![1,2,3].iter().filter(|&y| y > 2).collect(); // [3]
Typescript Array
• map 、 filter
• some、reduce、find、forEach…
let mapped: number[] = [1,2,3].map(x => x + 1); // [2,3,4]
let filtered: number[] = [1,2,3].filter(x => x > 2); // [3]
let hasBiggerThanOne = [1, 2, 3].some(x => x > 1); // true
let sum = [1, 2, 3].reduce((acc, curr) => acc + curr, 0); // 6
let finded = [1, 2, 4].find(x => x > 2); // 4
[1,2,3].forEach(x => console.log(x)); // undefined
• map 、 filter
• any、fold、find、forEach…
let has_bigger_than_one = vec![1, 2, 3].iter().any(|x| x > 1); // true
let sum = vec![1,2,3].iter().fold(0, |acc, curr| acc + curr); // 6
let finded = vec![1, 2, 4].iter().find(|&x| x > 2); // Some(4)
let for_eached = vec![1,2,3].iter().for_each(|x| println!("{}", x)); // ()
let mapped: Vec<i32> = vec![1,2,3].iter().map(|x| x + 1).collect(); // [2,3,4]
let filtered: Vec<i32> = vec![1,2,3].iter().filter(|&y| y > 2).collect(); // [3]
Rust Vector
JS Array’s Limit
https://twitter.com/mgechev/status/1280523754615926784?s=20
JS Array’s Limit
https://twitter.com/mgechev/status/1280523754615926784?s=20
JS library’s Solution
import { append, compose, map, take, tap, transduce } from 'ramda';
let data = [1, 2, 3, 4, 5];
let transducer = compose(
tap(x => console.log(`iter_value: ${x}`)),
map(x => x + 1),
take(2)
);
let step = (acc, curr) => append(acc, curr);
let init_val = [];
let result = transduce(transducer, step, init_val)(data);
console.log(`---Result---`, result);
-—-Start——
iter_value: 1
iter_value: 2
—-Result—-
[2, 3]
JS library’s Solution
-—-Start——
iter_value: 1
iter_value: 2
—-Result—-
[2, 3]
import { append, compose, map, take, tap, transduce } from 'ramda';
let data = [1, 2, 3, 4, 5];
let transducer = compose(
tap(x => console.log(`iter_value: ${x}`)),
map(x => x + 1),
take(2)
);
let step = (acc, curr) => append(acc, curr);
let init_val = [];
let result = transduce(transducer, step, init_val)(data);
console.log(`---Result---`, result);
Rust Version
println!("---Start---");
let result: Vec<i32> = vec![1, 2, 3, 4, 5].iter()
.inspect(|x| println!("iter_value: {}", x))
.map(|x| x + 1)
.take(2)
.collect();
println!("---Result---");
println!("{:?}", result);
-—-Start——
iter_value: 1
iter_value: 2
—-Result—-
[2, 3]
Zero Cost Iterator Abstraction
https://doc.rust-lang.org/book/ch13-04-performance.html
Option and Result
Option at Rust
pub enum Option<T> {
None,
Some(T),
}
data Maybe a = Just a | Nothing
Haskell
Billion Dollar Mistake
let obj = null;
const obj = {
a: null
};
console.log(obj.a.b);
Option at Rust
T
Some None
?
Option
pub enum Option<T> {
None,
Some(T),
}
Access Option Value
let obj = Obj {
a: Some(B {
b: 56
})
};
println!("obj.a.b: {:?}", obj.a.as_ref().unwrap().b);
println!(“obj.a.b: {:?}", obj.a.map(|s| s.b));
let obj = Obj { a: None };
println!("Default: {:?}", obj.a.map(|s| s.b).or(Some(0)).unwrap());
// Default: 0
// 56,Borrow A
// 56,Move Occur!
Access Option Value
#[derive(Debug)]
struct Obj {
a: Option<B>
}
#[derive(Debug)]
struct B {
b: Option<i32>
}
let obj = Obj { a: None };
println!("obj.a: {:?}", obj.a);
let getPropB = || obj.a?.b;
println!(“obj.a.b: {:?}", getPropB());
// obj.a: None
// obj.a.b: None
Question Mark Syntax Sugar
#[derive(Debug)]
struct Obj {
a: Option<B>
}
#[derive(Debug)]
struct B {
b: Option<i32>
}
let obj = Obj { a: None };
let getPropB = |o: &Obj| o.a.as_ref()?.b;
println!("obj.a.b: {:?}", getPropB(&obj)); // obj.a.b: None
Map option value
let f = |x: i32| x * 2;
let x = Some(34);
let y = match x {
Some(v) => Some(f(v)),
None => None,
};
println!("y: {:?}", y);
let x = Some(34);
let x = x.map(|v| v + 2);
println!("y: {:?}", y);
// y: 68
// y: 68
34
Some
68
Some
let f = |x: i32| x * 2;
map
Map with another option
// some_z: Some(Some(37))
let some_x = Some(34);
let some_y = Some(3);
let some_z = some_x.map(|x| some_y.map(|y| x + y));
println!("some_z: {:?}", some_z);
34
Some
map
let f = |x| some_y.map(|y| x + y); Some(37)
Some
AndThen with another option
// some_z: Some(37)
let some_x = Some(34);
let some_y = Some(3);
let some_z = some_x.and_then(|x| some_y.map(|y| x + y));
println!("some_z: {:?}", some_z);
34
Some
flat_map/bind
let f = |x| some_y.map(|y| x + y);
37
Some
Think as Railway
https://vimeo.com/113707214
let f = |x: i32| x * 2;
let x = Some(34);
let y = match x {
Some(v) => Some(f(v)),
None => None,
};
Some (34)
None
Some(68)
None
map(|x| x * 2)
Think as Railway
Think as Railway
let f = |x: i32| x * 2;
let x = None;
let y = match x {
Some(v) => Some(f(v)),
None => None,
};
Some (34)
None
Some(68)
None
map(|x| x * 2)
Think as Railway
Some (i32::MAX)
None
Some(i32::MAX)
None
and_then(|x: i32| x.checked_mul(2))
let f = |x: i32| x.checked_mul(2);
let x = Some(i32::MAX);
let y = x.and_then(f);
println!("y: {:?}", y);
Std library with option
https://doc.rust-lang.org/std/primitive.u32.html#method.checked_add
Working with two options
let some_x = Some(1);
let some_y = Some(2);
let xy = some_x.and_then(|x| {
some_y.map(|y| x * y)
});
xy: Some(2)
• and_then
let some_x = Some(1);
let some_y = Some(2);
let xy = some_x
.zip(y)
.map(|(x, y)| x * y);
xy: Some(2)
• zip
Working with multiple options
let some_x = Some(1);
let some_y = Some(2);
let some_z = Some(3);
let xyz = some_x.and_then(|x| {
some_y.and_then(|y| {
some_z.map(|z| x + y + z)
})
});
xyz: Some(6)
• Bad practice:
(TS) Applicative’s solution
import { Just } from "pratica";
let just_x = Just(1);
let just_y = Just(2);
let just_z = Just(3);
let unary_fn = x => y => z => x + y + z;
let just_added = Just(unary_fn)
.ap(just_x)
.ap(just_y)
.ap(just_z)
.inspect();
console.log(just_added); // Just(6)
(RS) Haskell do notation alternative
fn work_with_multiple_option(x: i32, y: i32, z: i32) -> Option<i32> {
let added_x = x.checked_mul(2)?; // 2
let added_y = y.checked_mul(3)?; // 6
let added_z = z.checked_mul(added_x)?; // 6
Some(added_x + added_y + added_z) // 14
}
Result at Rust
Haskell
pub enum Result<T, E> {
Ok(T),
Err(E),
}
data Either a b = Left a | Right b
Result at Rust
T
Ok
?
Result
pub enum Result<T, E> {
Ok(T),
Err(E),
}
E
Err
let f = |x: i32| x * 2;
let x = Ok(34);
let y = match x {
Ok(v) => Ok(f(v)),
Err(e) => Err(e),
};
Ok (34)
Err(e)
Ok(68)
Err(e)
map(|x| x * 2)
Think as Railway - map
let f = |x: i32| x * 2;
let x = Err("x not found");
let y = match x {
Ok(v) => Ok(f(v)),
Err(e) => Err(e),
};
Ok (34)
Err(e)
Ok(68)
Err(e)
map(|x| x * 2)
Think as Railway - map
Fast fail validator with result
fn rule1(input: i32) -> Result<i32, &'static str> {
if i > 4 {
Err("should bigger than four")
} else {
Ok(input)
}
}
fn rule2(input: i32) -> Result<i32, &'static str> {
if i > 5 && i <100 {
Err("should bigger than five and less than one hundred")
} else {
Ok(input)
}
}
Fast fail validator with result
fn valid_int_fast_fail(input: i32) -> Result<i32, &'static str> {
Ok(input)
.and_then(rule1)
.and_then(rule2)
}
fn handle_request(input: i32) -> Result<i32, &'static str> {
valid_int_fast_fail(input)
.map(|x| doSomething(x))
.map_err(|e| println!("Occur error: {:?}", e))
}
Rule1 Rule2 Handle_request
Fast fail validator with result
fn valid_int_fast_fail(input: i32) -> Result<i32, &'static str> {
Ok(input)
.and_then(rule1)
.and_then(rule2)
}
fn handle_request(input: i32) -> Result<i32, &'static str> {
valid_int_fast_fail(input)
.map(|x| doSomething(x))
.map_err(|e| println!("Occur error: {:?}", e))
}
Rule1 Rule2 Handle_request
Input: 6 doSomeThing(6)
Fast fail validator with result
Rule1 Rule2 Handle_request
Input: -1
fn valid_int_fast_fail(input: i32) -> Result<i32, &'static str> {
Ok(input)
.and_then(rule1)
.and_then(rule2)
}
fn handle_request(input: i32) -> Result<i32, &'static str> {
valid_int_fast_fail(input)
.map(|x| doSomething(x))
.map_err(|e| println!("Occur error: {:?}", e))
}
Fast fail validator with result
Rule1 Rule2 Handle_request
Input: -1
handle_err(e)
fn valid_int_fast_fail(input: i32) -> Result<i32, &'static str> {
Ok(input)
.and_then(rule1)
.and_then(rule2)
}
fn handle_request(input: i32) -> Result<i32, &'static str> {
valid_int_fast_fail(input)
.map(|x| doSomething(x))
.map_err(|e| println!("Occur error: {:?}", e))
}
Combine results at vector
fn to_number() {
let strings = vec!["93", "18", "45"];
let converted_numbers: Vec<_> = strings
.into_iter()
.map(|s| s.parse::<i32>())
.collect();
println!("Results: {:?}", converted_numbers);
}
[Ok(93), Ok(18), Ok(45)]
Invert result and vec
Invert result and vec
[Ok(93), Ok(18), Ok(45)]
Invert result and vec
[Ok(93), Ok(18), Ok(45)]
Ok([93, 18, 45])
(TS) Ramda - sequence
(Applicative f, Traversable t) => (a ! f a) ! t (f a) ! f (t a)
R.sequence(Maybe.of, [Just(1), Just(2), Just(3)]); //=> Just([1, 2, 3])
R.sequence(Maybe.of, [Just(1), Just(2), Nothing()]); //=> Nothing()
(TS) Ramda - traverse
Traverse :: (Applicative f, Traversable t) => (a ! f a) ! (a ! f b) ! t a ! f (t b)
Maybe.Just([5, 2.5, 2])
const parseInt = n => d => d === 0 ? Maybe.Nothing() : Maybe.Just(n / d);
R.traverse(Maybe.of, parseInt(10), [2, 4, 5]);
(RS) Iterator - collect
fn to_number_reuslt() -> Result<Vec<i32>, num::ParseIntError> {
let strings = vec!["93", "18", "45"];
let converted_numbers: Result<Vec<i32>, num::ParseIntError> = strings
.into_iter()
.map(|s| s.parse::<i32>())
.collect();
converted_numbers
}
Amazing!!
Ok([93, 18, 45])
Reason: FromIterator
#[stable(feature = "rust1", since = "1.0.0")]
impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
//...
//...
#[inline]
fn from_iter<I: IntoIterator<Item = Result<A, E>>>(iter: I) -> Result<V, E> {
// ...
iter::process_results(iter.into_iter(), |i| i.collect())
}
}
https://doc.rust-lang.org/beta/src/core/result.rs.html#1577-1627
Collect with error
fn to_number_reuslt() -> Result<Vec<i32>, num::ParseIntError> {
let strings = vec!["93", "😱 ", "45"];
let converted_numbers: Result<Vec<i32>, num::ParseIntError> = strings
.into_iter()
.map(|s| s.parse::<i32>())
.collect();
converted_numbers
}
Err(ParseIntError { kind: InvalidDigit })
Ingore all errors
fn to_number_reuslt() -> Result<Vec<i32>, num::ParseIntError> {
let strings = vec!["93", "😱 ", "45"];
let converted_numbers: Result<Vec<i32>, num::ParseIntError> = strings
.into_iter()
.filter_map(|s| s.parse::<i32>().ok())
.collect();
converted_numbers
}
Ok([93, 45])
Control flow with
combinator
Control flow with if else
function genSectionStates(
targetId: string,
groupId: string,
options: SectionStateOptions
): SectionState[] {
let states: SectionState[] = [];
const newState: SectionState = {
targetId,
groupId,
loc: {...options.loc},
};
if (options.isGroup) {
states = options.origSectionStates
? options.origSectionStates
: options.params?.paramA
? decode(options.params.paramA)
: [];
states.push(newState);
} else {
states = [newState];
}
return states;
}
Control flow with combinator
struct SectionStateOptions<'a> {
is_group: bool,
loc: Location,
original_states: Option<Vec<SectionState<'a>>>,
params: Option<SectionParams<'a>>
}
struct SectionParams<'a> {
paramA: Option<Vec<SectionState<'a>>>
}
struct SectionState<'a> {
targetId: &'a str,
groupId: &'a str,
loc: Location
}
struct Location {
column: i32,
line: i32
}
interface SectionStateOptions {
loc: Location,
isGroup: boolean;
origSectionStates: SectionState[],
params: {
paramA: string[]
}
}
interface SectionState {
targetId: string;
groupId: string;
loc: Location;
}
interface Location {
column: number;
line: number;
}
Rust Typescript
Control flow with combinator
fn gen_section_states<'a>(
targetId: &'a str,
groupId: &'a str,
options: &'a SectionStateOptions<'a>
) -> Option<Vec<SectionState<'a>>> {
let new_state = SectionState {
targetId: targetId,
groupId: groupId,
loc: options.loc.clone()
};
let get_orig_states = || options.original_states.clone();
let decode_paramA = || decode(options.params.as_ref()?.paramA.clone());
let states = bool_to_some(options.is_group)
.and_then(|_| get_orig_states().or_else(decode_paramA))
.or(Some(vec![]))
.map(|orig_states| [orig_states, vec![new_state]].concat());
states;
}
Control flow with combinator
if (options.isGroup) {
states = options.origSectionStates
? options.origSectionStates
: options.params?.paramA
? decode(options.params.paramA)
: [];
states.push(newState);
} else {
states = [newState];
}
let get_orig_states = || options.original_states.clone();
let decode_param_a = || decode(options.params.as_ref()?.paramA.clone());
let states = bool_to_some(options.is_group)
.and_then(|_| get_orig_states().or_else(decode_param_a))
.or(Some(vec![]))
.map(|orig_states| [orig_states, vec![new_state]].concat());
Control flow with combinator
fn bool_to_some(cond: bool) -> Option<()> {
if cond {
Some(())
} else {
None
}
}
Control flow with combinator
if (options.isGroup) {
states = options.origSectionStates
? options.origSectionStates
: options.params?.paramA
? decode(options.params.paramA)
: [];
states.push(newState);
} else {
states = [newState];
}
let get_orig_states = || options.original_states.clone();
let decode_param_a = || decode(options.params.as_ref()?.paramA.clone());
let states = bool_to_some(options.is_group)
.and_then(|_| get_orig_states().or_else(decode_param_a))
.or(Some(vec![]))
.map(|orig_states| [orig_states, vec![new_state]].concat());
Control flow with combinator
if (options.isGroup) {
states = options.origSectionStates
? options.origSectionStates
: options.params?.paramA
? decode(options.params.paramA)
: [];
states.push(newState);
} else {
states = [newState];
}
let get_orig_states = || options.original_states.clone();
let decode_param_a = || decode(options.params.as_ref()?.paramA.clone());
let states = bool_to_some(options.is_group)
.and_then(|_| get_orig_states().or_else(decode_param_a))
.or(Some(vec![]))
.map(|orig_states| [orig_states, vec![new_state]].concat());
Control flow with combinator
if (options.isGroup) {
states = options.origSectionStates
? options.origSectionStates
: options.params?.paramA
? decode(options.params.paramA)
: [];
states.push(newState);
} else {
states = [newState];
}
let get_orig_states = || options.original_states.clone();
let decode_param_a = || decode(options.params.as_ref()?.paramA.clone());
let states = bool_to_some(options.is_group)
.and_then(|_| get_orig_states().or_else(decode_param_a))
.or(Some(vec![]))
.map(|orig_states| [orig_states, vec![new_state]].concat());
Conclusion
• Enjoy built-in option and result functionality
With rust, you can…
• Enjoy rust’s zero cost abstraction
• Improve your service’s performance and
memory usage
Thanks for your
Listening!

Más contenido relacionado

La actualidad más candente

Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
aleks-f
 

La actualidad más candente (20)

Node.js API pitfalls
Node.js API pitfallsNode.js API pitfalls
Node.js API pitfalls
 
Advanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptAdvanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScript
 
Functional Scala 2020
Functional Scala 2020Functional Scala 2020
Functional Scala 2020
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of Abstraction
 
Exhibition of Atrocity
Exhibition of AtrocityExhibition of Atrocity
Exhibition of Atrocity
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
 
D3 svg & angular
D3 svg & angularD3 svg & angular
D3 svg & angular
 
EcmaScript 6
EcmaScript 6 EcmaScript 6
EcmaScript 6
 
Haskell in the Real World
Haskell in the Real WorldHaskell in the Real World
Haskell in the Real World
 
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
 
Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
 
Lambda expressions in C++
Lambda expressions in C++Lambda expressions in C++
Lambda expressions in C++
 
Ricky Bobby's World
Ricky Bobby's WorldRicky Bobby's World
Ricky Bobby's World
 
Why Sifu
Why SifuWhy Sifu
Why Sifu
 
Building fast interpreters in Rust
Building fast interpreters in RustBuilding fast interpreters in Rust
Building fast interpreters in Rust
 
ECMAScript 6
ECMAScript 6ECMAScript 6
ECMAScript 6
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
 
Fact, Fiction, and FP
Fact, Fiction, and FPFact, Fiction, and FP
Fact, Fiction, and FP
 
Lenses
LensesLenses
Lenses
 

Similar a Coscup2021 - useful abstractions at rust and it's practical usage

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Useful javascript
Useful javascriptUseful javascript
Useful javascript
Lei Kang
 

Similar a Coscup2021 - useful abstractions at rust and it's practical usage (20)

Groovy
GroovyGroovy
Groovy
 
ECMA5 and ES6 Promises
ECMA5 and ES6 PromisesECMA5 and ES6 Promises
ECMA5 and ES6 Promises
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Brief intro to clojure
Brief intro to clojureBrief intro to clojure
Brief intro to clojure
 
From Javascript To Haskell
From Javascript To HaskellFrom Javascript To Haskell
From Javascript To Haskell
 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScript
 
Useful javascript
Useful javascriptUseful javascript
Useful javascript
 
High performance GPU computing with Ruby RubyConf 2017
High performance GPU computing with Ruby  RubyConf 2017High performance GPU computing with Ruby  RubyConf 2017
High performance GPU computing with Ruby RubyConf 2017
 
LSFMM 2019 BPF Observability
LSFMM 2019 BPF ObservabilityLSFMM 2019 BPF Observability
LSFMM 2019 BPF Observability
 
Functional Reactive Programming with RxJS
Functional Reactive Programming with RxJSFunctional Reactive Programming with RxJS
Functional Reactive Programming with RxJS
 
C++ AMP 실천 및 적용 전략
C++ AMP 실천 및 적용 전략 C++ AMP 실천 및 적용 전략
C++ AMP 실천 및 적용 전략
 
Eta
EtaEta
Eta
 
High Performance GPU computing with Ruby, Rubykaigi 2018
High Performance GPU computing with Ruby, Rubykaigi 2018High Performance GPU computing with Ruby, Rubykaigi 2018
High Performance GPU computing with Ruby, Rubykaigi 2018
 
Halide tutorial 2019
Halide tutorial 2019Halide tutorial 2019
Halide tutorial 2019
 
Go Says WAT?
Go Says WAT?Go Says WAT?
Go Says WAT?
 
Yoyak ScalaDays 2015
Yoyak ScalaDays 2015Yoyak ScalaDays 2015
Yoyak ScalaDays 2015
 
Vcs16
Vcs16Vcs16
Vcs16
 
Beauty and the beast - Haskell on JVM
Beauty and the beast  - Haskell on JVMBeauty and the beast  - Haskell on JVM
Beauty and the beast - Haskell on JVM
 
Rubyconfindia2018 - GPU accelerated libraries for Ruby
Rubyconfindia2018 - GPU accelerated libraries for RubyRubyconfindia2018 - GPU accelerated libraries for Ruby
Rubyconfindia2018 - GPU accelerated libraries for Ruby
 
C Code and the Art of Obfuscation
C Code and the Art of ObfuscationC Code and the Art of Obfuscation
C Code and the Art of Obfuscation
 

Último

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

Último (20)

Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 

Coscup2021 - useful abstractions at rust and it's practical usage

  • 2. About Me • Frontend, rust and node.js enthusiast • Desktop app developer with electron • 12th ITHelp ironman competition - software development category (champion)
  • 3. Agenda • Why Rust • Collection and Iterator • Option and Result • Conclusion
  • 5. Why Rust Node.js and Typescript https://www.figma.com/blog/rust-in-production-at-figma/
  • 6. Why Rust Integrate rust with node.js https://www.figma.com/blog/rust-in-production-at-figma/
  • 7. Who is using rust https://tokio.rs/
  • 9. Collection and For Syntax • Typescript • Rust let arr = [4, 5, 6]; for(let item of arr) { console.log(`print: ${item}`); } let vec = vec![4,5,6]; for item in vec.iter() { println!("print: {}", item); } // print: 4 // print: 5 // print: 6
  • 10. TS Array v.s RS Vector • Typescript let mapped: number[] = [1,2,3].map(x => x + 1); // [2,3,4] let filtered: number[] = [1,2,3].filter(x => x > 2); // [3] • Rust let mapped: Vec<i32> = vec![1,2,3].iter().map(|x| x + 1).collect(); // [2,3,4] let filtered: Vec<i32> = vec![1,2,3].iter().filter(|&y| y > 2).collect(); // [3]
  • 11. Typescript Array • map 、 filter • some、reduce、find、forEach… let mapped: number[] = [1,2,3].map(x => x + 1); // [2,3,4] let filtered: number[] = [1,2,3].filter(x => x > 2); // [3] let hasBiggerThanOne = [1, 2, 3].some(x => x > 1); // true let sum = [1, 2, 3].reduce((acc, curr) => acc + curr, 0); // 6 let finded = [1, 2, 4].find(x => x > 2); // 4 [1,2,3].forEach(x => console.log(x)); // undefined
  • 12. • map 、 filter • any、fold、find、forEach… let has_bigger_than_one = vec![1, 2, 3].iter().any(|x| x > 1); // true let sum = vec![1,2,3].iter().fold(0, |acc, curr| acc + curr); // 6 let finded = vec![1, 2, 4].iter().find(|&x| x > 2); // Some(4) let for_eached = vec![1,2,3].iter().for_each(|x| println!("{}", x)); // () let mapped: Vec<i32> = vec![1,2,3].iter().map(|x| x + 1).collect(); // [2,3,4] let filtered: Vec<i32> = vec![1,2,3].iter().filter(|&y| y > 2).collect(); // [3] Rust Vector
  • 15. JS library’s Solution import { append, compose, map, take, tap, transduce } from 'ramda'; let data = [1, 2, 3, 4, 5]; let transducer = compose( tap(x => console.log(`iter_value: ${x}`)), map(x => x + 1), take(2) ); let step = (acc, curr) => append(acc, curr); let init_val = []; let result = transduce(transducer, step, init_val)(data); console.log(`---Result---`, result); -—-Start—— iter_value: 1 iter_value: 2 —-Result—- [2, 3]
  • 16. JS library’s Solution -—-Start—— iter_value: 1 iter_value: 2 —-Result—- [2, 3] import { append, compose, map, take, tap, transduce } from 'ramda'; let data = [1, 2, 3, 4, 5]; let transducer = compose( tap(x => console.log(`iter_value: ${x}`)), map(x => x + 1), take(2) ); let step = (acc, curr) => append(acc, curr); let init_val = []; let result = transduce(transducer, step, init_val)(data); console.log(`---Result---`, result);
  • 17. Rust Version println!("---Start---"); let result: Vec<i32> = vec![1, 2, 3, 4, 5].iter() .inspect(|x| println!("iter_value: {}", x)) .map(|x| x + 1) .take(2) .collect(); println!("---Result---"); println!("{:?}", result); -—-Start—— iter_value: 1 iter_value: 2 —-Result—- [2, 3]
  • 18. Zero Cost Iterator Abstraction https://doc.rust-lang.org/book/ch13-04-performance.html
  • 20. Option at Rust pub enum Option<T> { None, Some(T), } data Maybe a = Just a | Nothing Haskell
  • 21. Billion Dollar Mistake let obj = null; const obj = { a: null }; console.log(obj.a.b);
  • 22. Option at Rust T Some None ? Option pub enum Option<T> { None, Some(T), }
  • 23. Access Option Value let obj = Obj { a: Some(B { b: 56 }) }; println!("obj.a.b: {:?}", obj.a.as_ref().unwrap().b); println!(“obj.a.b: {:?}", obj.a.map(|s| s.b)); let obj = Obj { a: None }; println!("Default: {:?}", obj.a.map(|s| s.b).or(Some(0)).unwrap()); // Default: 0 // 56,Borrow A // 56,Move Occur!
  • 24. Access Option Value #[derive(Debug)] struct Obj { a: Option<B> } #[derive(Debug)] struct B { b: Option<i32> } let obj = Obj { a: None }; println!("obj.a: {:?}", obj.a); let getPropB = || obj.a?.b; println!(“obj.a.b: {:?}", getPropB()); // obj.a: None // obj.a.b: None
  • 25. Question Mark Syntax Sugar #[derive(Debug)] struct Obj { a: Option<B> } #[derive(Debug)] struct B { b: Option<i32> } let obj = Obj { a: None }; let getPropB = |o: &Obj| o.a.as_ref()?.b; println!("obj.a.b: {:?}", getPropB(&obj)); // obj.a.b: None
  • 26. Map option value let f = |x: i32| x * 2; let x = Some(34); let y = match x { Some(v) => Some(f(v)), None => None, }; println!("y: {:?}", y); let x = Some(34); let x = x.map(|v| v + 2); println!("y: {:?}", y); // y: 68 // y: 68 34 Some 68 Some let f = |x: i32| x * 2; map
  • 27. Map with another option // some_z: Some(Some(37)) let some_x = Some(34); let some_y = Some(3); let some_z = some_x.map(|x| some_y.map(|y| x + y)); println!("some_z: {:?}", some_z); 34 Some map let f = |x| some_y.map(|y| x + y); Some(37) Some
  • 28. AndThen with another option // some_z: Some(37) let some_x = Some(34); let some_y = Some(3); let some_z = some_x.and_then(|x| some_y.map(|y| x + y)); println!("some_z: {:?}", some_z); 34 Some flat_map/bind let f = |x| some_y.map(|y| x + y); 37 Some
  • 30. let f = |x: i32| x * 2; let x = Some(34); let y = match x { Some(v) => Some(f(v)), None => None, }; Some (34) None Some(68) None map(|x| x * 2) Think as Railway
  • 31. Think as Railway let f = |x: i32| x * 2; let x = None; let y = match x { Some(v) => Some(f(v)), None => None, }; Some (34) None Some(68) None map(|x| x * 2)
  • 32. Think as Railway Some (i32::MAX) None Some(i32::MAX) None and_then(|x: i32| x.checked_mul(2)) let f = |x: i32| x.checked_mul(2); let x = Some(i32::MAX); let y = x.and_then(f); println!("y: {:?}", y);
  • 33. Std library with option https://doc.rust-lang.org/std/primitive.u32.html#method.checked_add
  • 34. Working with two options let some_x = Some(1); let some_y = Some(2); let xy = some_x.and_then(|x| { some_y.map(|y| x * y) }); xy: Some(2) • and_then let some_x = Some(1); let some_y = Some(2); let xy = some_x .zip(y) .map(|(x, y)| x * y); xy: Some(2) • zip
  • 35. Working with multiple options let some_x = Some(1); let some_y = Some(2); let some_z = Some(3); let xyz = some_x.and_then(|x| { some_y.and_then(|y| { some_z.map(|z| x + y + z) }) }); xyz: Some(6) • Bad practice:
  • 36. (TS) Applicative’s solution import { Just } from "pratica"; let just_x = Just(1); let just_y = Just(2); let just_z = Just(3); let unary_fn = x => y => z => x + y + z; let just_added = Just(unary_fn) .ap(just_x) .ap(just_y) .ap(just_z) .inspect(); console.log(just_added); // Just(6)
  • 37. (RS) Haskell do notation alternative fn work_with_multiple_option(x: i32, y: i32, z: i32) -> Option<i32> { let added_x = x.checked_mul(2)?; // 2 let added_y = y.checked_mul(3)?; // 6 let added_z = z.checked_mul(added_x)?; // 6 Some(added_x + added_y + added_z) // 14 }
  • 38. Result at Rust Haskell pub enum Result<T, E> { Ok(T), Err(E), } data Either a b = Left a | Right b
  • 39. Result at Rust T Ok ? Result pub enum Result<T, E> { Ok(T), Err(E), } E Err
  • 40. let f = |x: i32| x * 2; let x = Ok(34); let y = match x { Ok(v) => Ok(f(v)), Err(e) => Err(e), }; Ok (34) Err(e) Ok(68) Err(e) map(|x| x * 2) Think as Railway - map
  • 41. let f = |x: i32| x * 2; let x = Err("x not found"); let y = match x { Ok(v) => Ok(f(v)), Err(e) => Err(e), }; Ok (34) Err(e) Ok(68) Err(e) map(|x| x * 2) Think as Railway - map
  • 42. Fast fail validator with result fn rule1(input: i32) -> Result<i32, &'static str> { if i > 4 { Err("should bigger than four") } else { Ok(input) } } fn rule2(input: i32) -> Result<i32, &'static str> { if i > 5 && i <100 { Err("should bigger than five and less than one hundred") } else { Ok(input) } }
  • 43. Fast fail validator with result fn valid_int_fast_fail(input: i32) -> Result<i32, &'static str> { Ok(input) .and_then(rule1) .and_then(rule2) } fn handle_request(input: i32) -> Result<i32, &'static str> { valid_int_fast_fail(input) .map(|x| doSomething(x)) .map_err(|e| println!("Occur error: {:?}", e)) } Rule1 Rule2 Handle_request
  • 44. Fast fail validator with result fn valid_int_fast_fail(input: i32) -> Result<i32, &'static str> { Ok(input) .and_then(rule1) .and_then(rule2) } fn handle_request(input: i32) -> Result<i32, &'static str> { valid_int_fast_fail(input) .map(|x| doSomething(x)) .map_err(|e| println!("Occur error: {:?}", e)) } Rule1 Rule2 Handle_request Input: 6 doSomeThing(6)
  • 45. Fast fail validator with result Rule1 Rule2 Handle_request Input: -1 fn valid_int_fast_fail(input: i32) -> Result<i32, &'static str> { Ok(input) .and_then(rule1) .and_then(rule2) } fn handle_request(input: i32) -> Result<i32, &'static str> { valid_int_fast_fail(input) .map(|x| doSomething(x)) .map_err(|e| println!("Occur error: {:?}", e)) }
  • 46. Fast fail validator with result Rule1 Rule2 Handle_request Input: -1 handle_err(e) fn valid_int_fast_fail(input: i32) -> Result<i32, &'static str> { Ok(input) .and_then(rule1) .and_then(rule2) } fn handle_request(input: i32) -> Result<i32, &'static str> { valid_int_fast_fail(input) .map(|x| doSomething(x)) .map_err(|e| println!("Occur error: {:?}", e)) }
  • 47. Combine results at vector fn to_number() { let strings = vec!["93", "18", "45"]; let converted_numbers: Vec<_> = strings .into_iter() .map(|s| s.parse::<i32>()) .collect(); println!("Results: {:?}", converted_numbers); } [Ok(93), Ok(18), Ok(45)]
  • 49. Invert result and vec [Ok(93), Ok(18), Ok(45)]
  • 50. Invert result and vec [Ok(93), Ok(18), Ok(45)] Ok([93, 18, 45])
  • 51. (TS) Ramda - sequence (Applicative f, Traversable t) => (a ! f a) ! t (f a) ! f (t a) R.sequence(Maybe.of, [Just(1), Just(2), Just(3)]); //=> Just([1, 2, 3]) R.sequence(Maybe.of, [Just(1), Just(2), Nothing()]); //=> Nothing()
  • 52. (TS) Ramda - traverse Traverse :: (Applicative f, Traversable t) => (a ! f a) ! (a ! f b) ! t a ! f (t b) Maybe.Just([5, 2.5, 2]) const parseInt = n => d => d === 0 ? Maybe.Nothing() : Maybe.Just(n / d); R.traverse(Maybe.of, parseInt(10), [2, 4, 5]);
  • 53. (RS) Iterator - collect fn to_number_reuslt() -> Result<Vec<i32>, num::ParseIntError> { let strings = vec!["93", "18", "45"]; let converted_numbers: Result<Vec<i32>, num::ParseIntError> = strings .into_iter() .map(|s| s.parse::<i32>()) .collect(); converted_numbers } Amazing!! Ok([93, 18, 45])
  • 54. Reason: FromIterator #[stable(feature = "rust1", since = "1.0.0")] impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> { //... //... #[inline] fn from_iter<I: IntoIterator<Item = Result<A, E>>>(iter: I) -> Result<V, E> { // ... iter::process_results(iter.into_iter(), |i| i.collect()) } } https://doc.rust-lang.org/beta/src/core/result.rs.html#1577-1627
  • 55. Collect with error fn to_number_reuslt() -> Result<Vec<i32>, num::ParseIntError> { let strings = vec!["93", "😱 ", "45"]; let converted_numbers: Result<Vec<i32>, num::ParseIntError> = strings .into_iter() .map(|s| s.parse::<i32>()) .collect(); converted_numbers } Err(ParseIntError { kind: InvalidDigit })
  • 56. Ingore all errors fn to_number_reuslt() -> Result<Vec<i32>, num::ParseIntError> { let strings = vec!["93", "😱 ", "45"]; let converted_numbers: Result<Vec<i32>, num::ParseIntError> = strings .into_iter() .filter_map(|s| s.parse::<i32>().ok()) .collect(); converted_numbers } Ok([93, 45])
  • 58. Control flow with if else function genSectionStates( targetId: string, groupId: string, options: SectionStateOptions ): SectionState[] { let states: SectionState[] = []; const newState: SectionState = { targetId, groupId, loc: {...options.loc}, }; if (options.isGroup) { states = options.origSectionStates ? options.origSectionStates : options.params?.paramA ? decode(options.params.paramA) : []; states.push(newState); } else { states = [newState]; } return states; }
  • 59. Control flow with combinator struct SectionStateOptions<'a> { is_group: bool, loc: Location, original_states: Option<Vec<SectionState<'a>>>, params: Option<SectionParams<'a>> } struct SectionParams<'a> { paramA: Option<Vec<SectionState<'a>>> } struct SectionState<'a> { targetId: &'a str, groupId: &'a str, loc: Location } struct Location { column: i32, line: i32 } interface SectionStateOptions { loc: Location, isGroup: boolean; origSectionStates: SectionState[], params: { paramA: string[] } } interface SectionState { targetId: string; groupId: string; loc: Location; } interface Location { column: number; line: number; } Rust Typescript
  • 60. Control flow with combinator fn gen_section_states<'a>( targetId: &'a str, groupId: &'a str, options: &'a SectionStateOptions<'a> ) -> Option<Vec<SectionState<'a>>> { let new_state = SectionState { targetId: targetId, groupId: groupId, loc: options.loc.clone() }; let get_orig_states = || options.original_states.clone(); let decode_paramA = || decode(options.params.as_ref()?.paramA.clone()); let states = bool_to_some(options.is_group) .and_then(|_| get_orig_states().or_else(decode_paramA)) .or(Some(vec![])) .map(|orig_states| [orig_states, vec![new_state]].concat()); states; }
  • 61. Control flow with combinator if (options.isGroup) { states = options.origSectionStates ? options.origSectionStates : options.params?.paramA ? decode(options.params.paramA) : []; states.push(newState); } else { states = [newState]; } let get_orig_states = || options.original_states.clone(); let decode_param_a = || decode(options.params.as_ref()?.paramA.clone()); let states = bool_to_some(options.is_group) .and_then(|_| get_orig_states().or_else(decode_param_a)) .or(Some(vec![])) .map(|orig_states| [orig_states, vec![new_state]].concat());
  • 62. Control flow with combinator fn bool_to_some(cond: bool) -> Option<()> { if cond { Some(()) } else { None } }
  • 63. Control flow with combinator if (options.isGroup) { states = options.origSectionStates ? options.origSectionStates : options.params?.paramA ? decode(options.params.paramA) : []; states.push(newState); } else { states = [newState]; } let get_orig_states = || options.original_states.clone(); let decode_param_a = || decode(options.params.as_ref()?.paramA.clone()); let states = bool_to_some(options.is_group) .and_then(|_| get_orig_states().or_else(decode_param_a)) .or(Some(vec![])) .map(|orig_states| [orig_states, vec![new_state]].concat());
  • 64. Control flow with combinator if (options.isGroup) { states = options.origSectionStates ? options.origSectionStates : options.params?.paramA ? decode(options.params.paramA) : []; states.push(newState); } else { states = [newState]; } let get_orig_states = || options.original_states.clone(); let decode_param_a = || decode(options.params.as_ref()?.paramA.clone()); let states = bool_to_some(options.is_group) .and_then(|_| get_orig_states().or_else(decode_param_a)) .or(Some(vec![])) .map(|orig_states| [orig_states, vec![new_state]].concat());
  • 65. Control flow with combinator if (options.isGroup) { states = options.origSectionStates ? options.origSectionStates : options.params?.paramA ? decode(options.params.paramA) : []; states.push(newState); } else { states = [newState]; } let get_orig_states = || options.original_states.clone(); let decode_param_a = || decode(options.params.as_ref()?.paramA.clone()); let states = bool_to_some(options.is_group) .and_then(|_| get_orig_states().or_else(decode_param_a)) .or(Some(vec![])) .map(|orig_states| [orig_states, vec![new_state]].concat());
  • 67. • Enjoy built-in option and result functionality With rust, you can… • Enjoy rust’s zero cost abstraction • Improve your service’s performance and memory usage