96 Examples
Glen Whitney edited this page 2024-09-19 01:56:49 +00:00

This page selects some example programs from "Rust by Example" and shows their intended Husht equivalents. (Of course, the details of the syntax on the Husht side may end up varying in some cases for practical reasons from these initial proposals. The examples will be updated when and if they change, and will be used as cases in the eventual Husht test suite.) Comments included in the Husht versions to add detail/explanation are marked with //!.

Hello World

Rust Husht
// Many comments from the Rust by Example version 
// have been removed
fn main() {
    // Print text to the console.
    println!("Hello World!");
}
// Many comments from the Rust by Example version
// have been removed
fn main
    // Print text to the console.
    println! "Hello World!"

Formatted print

(Skipping for now because we likely want "f-strings" in Husht, which require some thought/design.)

Primitives

Rust Husht
fn main() {
    let logical: bool = true;

    let a_float: f64 = 1.0;  // Regular annotation
    let an_integer   = 5i32;  // Suffix annotation

    let default_float   = 3.0;  // `f64`
    let default_integer = 7;   // `i32`

    // Can infer from another line; here i64:
    let mut inferred_type = 12;
    inferred_type = 4294967296i64;

    let mut mutable = 12; // Mutable `i32`
    mutable = 21;

    // Error! The type of a variable can't be changed.
    mutable = true;

    // Variables can be overwritten with shadowing.
    let mutable = true;
}
fn main
    let logical: bool = true

    let a_float: f64 = 1.0  // Regular annotation
    let an_integer   = 5i32  // Suffix annotation

    let default_float   = 3.0  // `f64`
    let default_integer = 7   // `i32`

    // Can infer from another line; here i64:
    let mut inferred_type = 12
    inferred_type = 4294967296i64

    let mut mutable = 12  // Mutable `i32`
    mutable = 21

    // Error! The type of a variable can't be changed.
    mutable = true

    // Variables can be overwritten with shadowing.
    let mutable = true

Literals and operators

Not really anything new in this subsection.

Tuples

Rust Husht
fn reverse(pair: (i32, bool)) -> (bool, i32) {
    let (int_param, bool_param) = pair;

    (bool_param, int_param)
}

#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);

fn main() {
    // A tuple with a bunch of different types.
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    println!("Long tuple first value: {}", long_tuple.0);
    println!("Long tuple second value: {}", long_tuple.1);

    let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);

    println!("tuple of tuples: {:?}", tuple_of_tuples);

    let pair = (1, true);
    println!("Pair is {:?}", pair);
    println!("The reversed pair is {:?}", reverse(pair));

    // Comma required in one-element tuples:
    println!("One element tuple: {:?}", (5u32,));
    println!("Just an integer: {:?}", (5u32));

    let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
    println!("{:?}", matrix);
}
fn reverse((int_param, bool_param): (i32, bool)) -> (bool, i32)
    (bool_param, int_param)



#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);

fn main()
    // A tuple with a bunch of different types.
    let long_tuple = (1u8, 2u16, 3u32, 4u64
        -1i8, -2i16, -3i32, -4i64
        0.1f32, 0.2f64,
        'a', true)

    println! "Long tuple first value: {}", long_tuple.0
    println! "Long tuple second value: {}", long_tuple.1

    let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16)

    println! "tuple of tuples: {:?}", tuple_of_tuples

    let pair = (1, true)
    println! "Pair is {:?}", pair
    println! "The reversed pair is {:?}", reverse pair

    // Comma required in one-element tuples:
    println! "One element tuple: {:?}", (5u32,)
    println! "Just an integer: {:?}", (5u32)

    let matrix = Matrix 
        1.1, 1.2
        2.1, 2.2
    println! "{:?}", matrix

Arrays and slices

Not really anything new in this subsection; we don't currently expect that Husht will make material changes in array/slice declaration or indexing.

Custom Types

Structures

Rust Husht
#![allow(dead_code)]

#[derive(Debug)]
struct Person {
    name: String,
    age: u8,
}

struct Unit;

struct Pair(i32, f32);

struct Point {
    x: f32,
    y: f32,
}

struct Rectangle {
    top_left: Point,
    bottom_right: Point,
}

fn main() {
    // Create struct with field init shorthand
    let name = String::from("Peter");
    let age = 27;
    let peter = Person { name, age };

    println!("{:?}", peter);

    let point: Point = Point { x: 10.3, y: 0.4 };
    let another_point: Point = Point { x: 5.2, y: 0.2 };

    println!("point coordinates: ({}, {})", point.x, point.y);

    let bottom_right = Point { x: 5.2, ..another_point };

    println!("second point: ({}, {})", bottom_right.x, bottom_right.y);

    // Destructure the point using a `let` binding
    let Point { x: left_edge, y: top_edge } = point;

    let _rectangle = Rectangle {
        top_left: Point { x: left_edge, y: top_edge },
        bottom_right: bottom_right,
    };

    let _unit = Unit;

    let pair = Pair(1, 0.1);

    println!("pair contains {:?} and {:?}", pair.0, pair.1);

    // Destructure a tuple struct
    let Pair(integer, decimal) = pair;

    println!("pair contains {:?} and {:?}", integer, decimal);
}
#![allow(dead_code)]

#[derive(Debug)]
struct Person
    name: String
    age: u8

struct Unit

struct Pair(i32, f32)

struct Point x, y: f32

struct Rectangle
    top_left, bottom_right: Point







fn main
    // Create struct with field init shorthand
    let name = s"Peter"  //! Note s-string
    let age = 27
    let peter = Person name, age

    println! "{:?}", peter

    let point: Point = Point x: 10.3, y: 0.4
    let another_point: Point = Point x: 5.2, y: 0.2

    println! "point coordinates: ({}, {})", point.x, point.y

    let bottom_right = Point x: 5.2, ..another_point

    println! "second point: ({}, {})", bottom_right.x, bottom_right.y

    // Destructure the point using a `let` binding
    let Point x: left_edge, y: top_edge = point

    let _rectangle = Rectangle
        top_left: Point
            x: left_edge, y: top_edge
        bottom_right: bottom_right

    let _unit = Unit

    let pair = Pair 1, 0.1

    println! "pair contains {:?} and {:?}", pair.0, pair.1

    // Destructure a tuple struct
    let Pair integer, decimal = pair

    println! "pair contains {:?} and {:?}", integer, decimal

Enums

Rust Husht
enum WebEvent {
    // An `enum` variant may either be `unit-like`,
    PageLoad,
    PageUnload,
    // like tuple structs,
    KeyPress(char),
    Paste(String),
    // or like structures.
    Click { x: i64, y: i64 },
}

fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad => println!("page loaded"),
        WebEvent::PageUnload => println!("page unloaded"),
        // Destructure `c` from inside the `enum` variant.
        WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
        WebEvent::Paste(s) => println!("pasted \"{}\".", s),
        // Destructure `Click` into `x` and `y`.
        WebEvent::Click { x, y } => {
            println!("clicked at x={}, y={}.", x, y);
        },
    }
}

fn main() {
    let pressed = WebEvent::KeyPress('x');
    let pasted  = WebEvent::Paste("my text".to_owned());
    let click   = WebEvent::Click { x: 20, y: 80 };
    let load    = WebEvent::PageLoad;
    let unload  = WebEvent::PageUnload;

    inspect(pressed);
    inspect(pasted);
    inspect(click);
    inspect(load);
    inspect(unload);
}
enum WebEvent
    // An `enum` variant may either be `unit-like`,
    PageLoad,
    PageUnload,
    // like tuple structs,
    KeyPress(char),
    Paste(String),
    // or like structures.
    Click 
        x, y: i64

fn inspect(event: WebEvent)
    match event //! Note variant auto-import
        PageLoad => println! "page loaded"
        PageUnload => println! "page unloaded"
        // Destructure `c` from inside the `enum` variant.
        KeyPress c => println! "pressed '{}'.", c
        Paste s => println! "pasted \"{}\".", s
        // Destructure `Click` into `x` and `y`.
        Click x, y =>
            println! "clicked at x={}, y={}.", x, y





fn main
    let pressed = WebEvent::KeyPress 'x'
    let pasted  = WebEvent::Paste s"my text"
    let click   = WebEvent::Click x: 20, y: 80
    let load    = WebEvent::PageLoad
    let unload  = WebEvent::PageUnload

    inspect pressed
    inspect pasted
    inspect click
    inspect load
    inspect unload

linked list
Rust Husht
use crate::List::*;

enum List {
    Cons(u32, Box<List>),
    Nil,
}

impl List {
    fn new() -> List {
        Nil
    }

    fn prepend(self, elem: u32) -> List {
        Cons(elem, Box::new(self))
    }

    fn len(&self) -> u32 {
        match self {
            Cons(_, tail) => 1 + tail.len(),
            Nil => 0
        }
    }

    fn stringify(&self) -> String {
        match self {
            Cons(head, tail) => {
                format!("{}, {}", head, tail.stringify())
            },
            Nil => {
                format!("Nil")
            },
        }
    }
}

fn main() {
    let mut list = List::new();

    list = list.prepend(1);
    list = list.prepend(2);
    list = list.prepend(3);

    println!("linked list has length: {}", list.len());
    println!("{}", list.stringify());
}
// use crate::List::*; //! Unneeded: match auto-imports

enum List
    Cons(u32, Box<List>)
    Nil


impl List
    fn new -> List  Nil

    fn prepend(self, elem: u32) -> List
        Cons elem, Box::new self

    fn len(&self) -> u32
        match self
            Cons _, tail => 1 + tail.len()
            Nil => 0

    fn stringify(&self) -> String
        match self
            Cons head, tail =>
                format! "{}, {}", head, tail.stringify()
            Nil => 
                format! "Nil"








fn main
    let mut list = List::new()

    //! These calls could be chained, but they could have
    //! been chained in Rust, and it's not reasonable to
    //! expect Husht to detect chaining opportunities.
    list = list.prepend(1)
    list = list.prepend(2)
    list = list.prepend(3)

    println! "linked list has length: {}", list.len()
    println! "{}", list.stringify()

Constants

Not really anything new in this section.

Variable Bindings

Not really anything new here.

Mutability

Or here.

Scope and shadowing

Rust Husht
fn main() {
    let long_lived_binding = 1;

    {
        let short_lived_binding = 2;
        println!("inner short: {}", short_lived_binding);
    }

    // Error! `short_lived_binding` doesn't exist here
    println!("outer short: {}", short_lived_binding);
    // FIXME ^ Comment out this line

    println!("outer long: {}", long_lived_binding);
}
fn main
    let long_lived_binding = 1

    scope //! Husht needs a keyword; other choices exist
        let short_lived_binding = 2
        println! "inner short: {}", short_lived_binding

    // Error! `short_lived_binding` doesn't exist here
    println! "outer short: {}", short_lived_binding
    // FIXME ^ Comment out this line

    println! "outer long: {}", long_lived_binding


Declare first

Nothing here.

Freezing

Or here.

Types

Nothing new syntax-wise in this entire section.

Conversion

Or here, so far as I can see.

Expressions

Rust Husht
fn main() {
    let x = 5u32;

    let y = {
        let x_squared = x * x;
        let x_cube = x_squared * x;
        x_cube + x_squared + x
    };






    let z = {
        // Final semicolon discards value; `z` ← `()`
        2 * x;
    };

    println!("x is {:?}", x);
    println!("y is {:?}", y);
    println!("z is {:?}", z);
}
fn main
    let x = 5u32

    let y =
        let x_squared = x * x
        let x_cube = x_squared * x
        x_cube + x_squared + x

    //! Here we encounter two important Husht points.
    //! (1) Since there is only a single expression
    //!     following the `let z=`, without the `scope`
    //!     keyword this would merely be `let z = 2 * x`
    //! (2) The final semicolon is allowed and preserved
    //!     by Husht to suppress the return value from the
    //!     scope, but returning the last expression from a
    //!     scope is the default for Husht except in the final
    //!     statement of a function typed to return Unit
    let z = scope
        // Final semicolon discards value; `z` ← `()`
        2 * x;

    println! "x is {:?}", x
    println! "y is {:?}", y
    println! "z is {:?}", z

Flow of Control

if/else

Rust Husht
fn main() {
    let n = 5;

    if n < 0 {
        print!("{} is negative", n);
    } else if n > 0 {
        print!("{} is positive", n);
    } else {
        print!("{} is zero", n);
    }

    let big_n =
        if n < 10 && n > -10 {
            println!(", and is small, * 10");
            // This expression returns an `i32`.
            10 * n
        } else {
            println!(", and is big, / 2");
            // So here must return `i32` as well.
            n / 2
            // TODO ^ Try inserting a semicolon.
        };
    //   ^ Don't forget to put a semicolon here! All `let` bindings need it.

    println!("{} -> {}", n, big_n);
}
fn main
    let n = 5

    //! Note for the "then"-clause to be on the same line
    //! as the condition requires an explicit `then`
    if n < 0
        print! "{} is negative", n
    else if n > 0 then print! "{} is positive", n
    else print! "{} is zero", n

    //! Note more literate logical operators
    let big_n =
        if n < 10 and n > -10
            println! ", and is small, * 10"
            // This expression returns an `i32`.
            10 * n
        else
            println! ", and is big, / 2"
            // So here must return `i32` as well.
            n / 2
            // TODO ^ Try inserting a semicolon.

    //   ^ Don't forget to put a semicolon here! All `let` bindings need it.
    //!  ^ Husht FTW!

    println! "{} -> {}", n, big_n

loop

Rust Husht
fn main() {
    let mut count = 0u32;
    println!("Let's count until infinity!");
    loop {
        count += 1;

        if count == 3 {
            println!("three");
            continue;
        }

        println!("{}", count);

        if count == 5 {
            println!("OK, that's enough");
            break;
        }
    }
}
fn main
    let mut count = 0u32
    println! "Let's count until infinity!"
    loop
        count += 1

        if count == 3
            println! "three"
            continue

        println! "{}", count

        if count == 5
            println! "OK, that's enough"
            break
 



Nesting and labels
Rust Husht
#![allow(unreachable_code, unused_labels)]

fn main() {
    'outer: loop {
        println!("Entered the outer loop");

        'inner: loop {
            println!("Entered the inner loop");
            break 'outer;
        }

        println!("This point will never be reached");
    }

    println!("Exited the outer loop");
}
#![allow(unreachable_code, unused_labels)]

fn main
    'outer loop
        println! "Entered the outer loop"

        'inner loop
            println! "Entered the inner loop"
            break 'outer

        println! "This point will never be reached"

    println! "Exited the outer loop"



Returning from loops
Rust Husht
fn main() {
    let mut counter = 0;

    let result = loop {
        counter += 1;

        if counter == 10 {
            break counter * 2;
        }
    };

    assert_eq!(result, 20);
}
fn main
    let mut counter = 0

    let result = loop
        counter += 1

        if counter == 10 then break counter * 2

    assert_eq! result, 20




while

Rust Husht
fn main() {
    let mut n = 1;

    while n < 21 {
        match () {
            _ if n % 15 == 0 => println!("fizzbuzz"),
            _ if n % 3 == 0  => println!("fizz"),
            _ if n % 5 == 0  => println!("buzz"),
            _ => println!("{}", n)
        }
        n += 1;
    }
}
fn main
    let mut n = 1

    while n < 21
        cond
            n % 15 == 0 => println! "fizzbuzz"
            n % 3 == 0  => println! "fizz"
            n % 5 == 0  => println! "buzz"
            else println! "{}", n

        n += 1


for loops

This subsection introduces the three ways of converting collections into iterators. For convenience, we combine them into a single example here. Note that we have changed the loop specifications in the examples on the Rust side, because it seems more Rust-idiomatic to (for example) iterate on a reference to a collection than to call .iter explicitly.

Rust Husht
fn main() {
    let mut names = vec!["Bob", "Frank", "Ferris"];

    for name in &names {
        match name {
            &"Ferris" => println!("Rustacean alert!"),
            _ => println!("Hello {}", name),
        }
    }
    
    println!("names: {:?}", names);

    for name in &mut names {
        *name = match name {
            &mut "Ferris" => "Rustacean alert!",
            _ => "Hello",
        }
    }

    println!("names: {:?}", names);

    for name in names {
        match name {
            "Hello" => println!("Someone was normal"),
            _ => println!("Warning: {}", name),
        }
    }
    // names has moved here and is unusable:
    // println!("names: {:?}", names); // compile error
}
fn main
    let mut names = vec!["Bob", "Frank", "Ferris"]

    for name in &names
        match name
            &"Ferris" => println! "Rustacean alert!"
            _ => println! "Hello {}", name
    
    println!("names: {:?}", names);



    for name in &mut names
        *name = match name
            &mut "Ferris" => "Rustacean alert!"
            _ => "Hello"

    println! "names: {:?}", names



    for name in names
        match name
            "Hello" => println! "Someone was normal"
            _ => println! "Warning: {}", name

    // names has moved here and is unusable:
    // println!("names: {:?}", names); // compile error


match

There's not really much new Husht-syntax-wise in this section. However, it does raise the challenge of destructuring a nested struct. Suppose Foo has fields bar of type Bar and baz of type Baz, and further each of Bar and Baz have fields x and y. Then the full destructure of a Foo might look like:

let Foo bar: Bar x: x1, y: y1, baz: Baz x: x2, y: y2 = aFoo

Is this really parseable? It seems not; what if Bar also had a Baz field named baz? There's no way for the parser to tell short of analyzing the types. So it seems some braces or linebreaks are necessary. Husht will allow either of course. So you could write:

let Foo bar: Bar {x: x1, y: y1}, baz: Baz x: x2, y: y2 = aFoo

or

let Foo
    bar: Bar x: x1, y: y1
    baz: Baz x: x2, y: y2
    = aFoo

as the spirit moves you.

if-let

It seems the only new point relevant to Husht that arises here is the need to try to do auto-import for destructuring if-let (and maybe just destructuring lets as well), so that if Foo is a enum with variants Bar and Baz, and a is of type Foo, then you can write just if let Bar = a ... rather than if let Foo::Bar = a .... (To be clear, the intention is to tightly scope these auto-imports so that the name Bar doesn't "leak" into the surrounding code from places in which there is a clear implication (such as destructuring a Foo) that they should be in scope.

let-else

while-let

Apparently nothing else new in these sections.

Functions

Methods

Doesn't seem to be anything new here, but ...

Closures

... this one appears to be a biggie. Rust's closure syntax is very unusual, and there's lots of commentary concerning it online. So this first example block shows perhaps the "ideal" way we would recast it. The thing is, I can't understand why it isn't already this way, so maybe we are going to run into parsing problems? If so, we may need to revisit the syntax here.

Rust Husht
fn main() {
    let outer_var = 42;

    let closure_annotated = |i: i32| -> i32 { i + outer_var };
    let closure_inferred  = |i     |          i + outer_var  ;

    println!("closure_annotated: {}", closure_annotated(1));
    println!("closure_inferred: {}", closure_inferred(1));
    // Once closure's type has been inferred, it cannot be inferred again with another type.
    //println!("cannot reuse closure_inferred with another type: {}", closure_inferred(42i64));
    // TODO: uncomment the line above and see the compiler error.

    let one = || 1;
    println!("closure returning one: {}", one());
}
fn main
    let outer_var = 42

    let closure_annotated = i: i32 -> i32 =>  i + outer_var
    let closure_inferred  = i =>  i + outer_var

    println! "closure_annotated: {}", closure_annotated 1
    println! "closure_inferred: {}", closure_inferred 1
    // Once closure's type has been inferred, it cannot be inferred again with another type.
    //println! "cannot reuse closure_inferred with another type: {}", closure_inferred 42i64
    // TODO: uncomment the line above and see the compiler error.

    let one = () => 1 //! Need something to mark empty param list, could use || like Rust...
    println! "closure returning one: {}", one()
Another consideration is whether we want to have a shorthand for non-closure anonymous inline functions (i.e. ones that are enforced not to capture any identifiers). If so, the simplest mechanism might just be to use another arrow, i.e. Husht could look like:
fn main
    let anon_func = x --> x*x
    println! "call unknown {}", anon_func 1.6
    // Exactly the same except for function name:
    fn named_func(x: f64) -> f64 x* x
    println! "call named {}", named_func 1.6
    // Arrow looks slightly funny with type annotations:
    let another = x: i64 -> i64 --> x*x
    // but not too bad I think

Of course, there's no real reason to implement that until/unless we actually want anonymous regular (non-closure) functions.

A final, quite major consideration is whether we want to have syntax for unary single-expression functions parallel to that in Civet. The & symbol would not be appropriate for Husht, but a good choice might be $ since as far as I can tell, it's not used otherwise in Rust except for macro arguments, and it is the conventional "single parameter name for a throwaway unary function" in JavaScript. So in this scheme, closure_inferred above would become just $ + outer_var. Not sure what would be a good way to type-annotate this, possibly ($i32 + outer_var): i32 or maybe there just is no type-annotated single-argument shorthand. And we would have let square = $ * $ as a shorthand for let square = x => x*x. This notation seems so productive that I am just going to presume we want to implement it, and write the rest of the examples in this section in this way when possible.

Capturing
Rust Husht
fn main() {
    use std::mem;

    let consume = || {
        println!("`movable`: {:?}", movable);
        mem::drop(movable);
    };

    // `consume` consumes the variable so this can only be called once.
    consume();

    let haystack = vec![1, 2, 3];

    let contains = move |needle| haystack.contains(needle);

    println!("{}", contains(&1));
    println!("{}", contains(&4));
}
fn main
    use std::mem

    let consume = () =>
        println! "`movable`: {:?}", movable
        mem::drop  movable

    // `consume` consumes the variable so this can only be called once.
    consume()


    let haystack = vec![1, 2, 3]

    let contains = move needle => haystack.contains needle

    println! "{}", contains(&1)  //! That we need the & is Rust weirdoness
    println! "{}", contains(&4)

There doesn't seem to be anything else syntactically relevant in the other subsubsections here, until we get to...

Examples in std

Iterator::any

Rust Husht
pub trait Iterator {
    type Item;

    fn any<F>(&mut self, f: F) -> bool where
        F: FnMut(Self::Item) -> bool;
}

fn main() {
    let vec1 = vec![1, 2, 3];
    let vec2 = vec![4, 5, 6];

    println!("2 in vec1: {}", vec1.iter()     .any(|&x| x == 2));
    println!("2 in vec2: {}", vec2.into_iter().any(|x| x == 2));

    println!("vec1 len: {}", vec1.len());
    println!("First element of vec1 is: {}", vec1[0]);
    // `into_iter()` does move `vec2` and its elements, so they cannot be used again



    let array1 = [1, 2, 3];
    let array2 = [4, 5, 6];

    println!("2 in array1: {}", array1.iter()     .any(|&x| x == 2));
    println!("2 in array2: {}", array2.into_iter().any(|x| x == 2));
}
pub trait Iterator
    type Item

    fn any<F>(&mut self, f: F) -> bool where
        F: FnMut(Self::Item) -> bool //! Should we be able to drop the `Self::` here?

fn main
    let vec1 = vec![1, 2, 3]
        vec2 = vec![4, 5, 6]

    //! Note use of fragment of loop construct to just get the corresponding iterator
    println! "2 in vec1: {}", in &vec1.any *$ == 2 //! since iterator ...
        //! ... returns references, we have to dereference the argument.
        //! Alternatively , we could write `$ == &2`

    println! "2 in vec2: {}", in vec2.any $ == 2

    println! "vec1 len: {}", vec1.len()
    println! "First element of vec1 is: {}", vec1[0]
    // `into_iter()` does move `vec2` and its elements, so they cannot be used again

    let array1 = [1, 2, 3]
        array2 = [4, 5, 6]

    println! "2 in array1: {}", in &array1.any $ == &2
    println! "2 in array2: {}", in array2.any $ == 2

Searching through iterators

Rust Husht
pub trait Iterator {
    type Item;

    fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
        P: FnMut(&Self::Item) -> bool;
}

fn main() {
    let vec1 = vec![1, 2, 3];
    let vec2 = vec![4, 5, 6];

    let mut iter = vec1.iter();
    let mut into_iter = vec2.into_iter();

    println!("Find 2 in vec1: {:?}", iter     .find(|&&x| x == 2));
    println!("Find 2 in vec2: {:?}", into_iter.find(| &x| x == 2));

    let array1 = [1, 2, 3];
    let array2 = [4, 5, 6];

    println!("Find 2 in array1: {:?}", array1.iter()     .find(|&&x| x == 2));
    println!("Find 2 in array2: {:?}", array2.into_iter().find(|&x| x == 2));
}
pub trait Iterator
    type Item

    fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
        P: FnMut(&Self::Item) -> bool
    //! Again, sh/could we allow both `Self::` to be elided?

fn main
    let vec1 = vec![1, 2, 3]
    let vec2 = vec![4, 5, 6]

    let mut iter = in &vec1
    let mut into_iter = in vec2

    println! "Find 2 in vec1: {:?}", iter     .find *$ == &2
    println! "Find 2 in vec2: {:?}", into_iter.find *$ == 2

    let array1 = [1, 2, 3];
    let array2 = [4, 5, 6];

    println! "Find 2 in array1: {:?}", in &array1.find  *$ == &2
    println! "Find 2 in array2: {:?}", in array2.find  *$ == 2

Higher order functions

Rust Husht
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}

fn main() {
    let upper = 1000;

    // Imperative approach
    let mut acc = 0;
    for n in 0.. {
        let n_squared = n * n;

        if n_squared >= upper {
            break;
        } else if is_odd(n_squared) {
            acc += n_squared;
        }
    }
    println!("imperative style: {}", acc);

    // Functional approach
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)
             .take_while(|&n_squared| n_squared < upper)
             .filter(|&n_squared| is_odd(n_squared))
             .sum();
    println!("functional style: {}", sum_of_squared_odd_numbers);
}
// The below will actually make a closure 
// that captures nothing, not a function
// as on the left; do we care?
let is_odd = $ % 2 == 1

fn main
    let upper = 1000

    // Imperative approach
    let mut acc = 0
    for n in 0..
        let n_squared = n * n

        if n_squared >= upper then break
        else if is_odd n_squared
            acc += n_squared

    println! "imperative style: {}", acc


    // Functional approach
    let sum_of_squared_odd_numbers: u32 =
        (0..).map $ * $
             .take_while $ < &upper
             .filter is_odd *$
             .sum()
    println! "functional style: {}", sum_of_squared_odd_numbers

Diverging functions

Rust Husht
fn main() {
    fn sum_odd_numbers(up_to: u32) -> u32 {
        let mut acc = 0;
        for i in 0..up_to {
            let addition: u32 = match i%2 == 1 {
                true => i,
                false => continue,
            };
            acc += addition;
        }
        acc
    }
    println!("Sum of odd numbers up to 9 (excluding): {}", 
        sum_odd_numbers(9)
    );
}
fn main
    fn sum_odd_numbers(up_to: u32) -> u32
        let mut acc = 0

        for i in 0..up_to
            let addition: u32 = match i%2 == 1
                true => i
                false => continue
            acc += addition
        acc


    println! 
        "Sum of odd numbers up to 9 (excluding): {}"
        sum_odd_numbers 9