ExamplesBy LevelBy TopicLearning Paths
1162 Fundamental

Hello World — Functions and Greetings

Functional Programming

Tutorial

The Problem

Implement a greet function that takes a name and returns a greeting string. The simplest possible functional program: a pure function from input to output.

🎯 Learning Outcomes

  • • The most basic unit of functional programming: a pure function with no side effects
  • • How OCaml's string concatenation (^) maps to Rust's format! macro
  • • Type annotations in both languages for function signatures
  • Code Example

    #![allow(clippy::all)]
    pub fn greet(name: &str) -> String {
        format!("Hello, {name}!")
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
    
        #[test]
        fn test_greet_world() {
            assert_eq!(greet("world"), "Hello, world!");
        }
    
        #[test]
        fn test_greet_name() {
            assert_eq!(greet("Rust"), "Hello, Rust!");
        }
    
        #[test]
        fn test_greet_empty() {
            assert_eq!(greet(""), "Hello, !");
        }
    
        #[test]
        fn test_greet_with_spaces() {
            assert_eq!(greet("functional Rust"), "Hello, functional Rust!");
        }
    }

    Key Differences

  • String building: OCaml uses ^ for concatenation; Rust uses format! with inline variable syntax {name}
  • Type annotations: OCaml annotates inline (name : string) : string; Rust annotates in the signature name: &str) -> String
  • Ownership: Rust returns an owned String (heap-allocated); OCaml returns an immutable string value
  • OCaml Approach

    let greet (name : string) : string = "Hello, " ^ name ^ "!" uses the ^ string concatenation operator. OCaml type annotations are optional (inferred) but shown here for clarity.

    Full Source

    #![allow(clippy::all)]
    pub fn greet(name: &str) -> String {
        format!("Hello, {name}!")
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
    
        #[test]
        fn test_greet_world() {
            assert_eq!(greet("world"), "Hello, world!");
        }
    
        #[test]
        fn test_greet_name() {
            assert_eq!(greet("Rust"), "Hello, Rust!");
        }
    
        #[test]
        fn test_greet_empty() {
            assert_eq!(greet(""), "Hello, !");
        }
    
        #[test]
        fn test_greet_with_spaces() {
            assert_eq!(greet("functional Rust"), "Hello, functional Rust!");
        }
    }
    ✓ Tests Rust test suite
    #[cfg(test)]
    mod tests {
        use super::*;
    
        #[test]
        fn test_greet_world() {
            assert_eq!(greet("world"), "Hello, world!");
        }
    
        #[test]
        fn test_greet_name() {
            assert_eq!(greet("Rust"), "Hello, Rust!");
        }
    
        #[test]
        fn test_greet_empty() {
            assert_eq!(greet(""), "Hello, !");
        }
    
        #[test]
        fn test_greet_with_spaces() {
            assert_eq!(greet("functional Rust"), "Hello, functional Rust!");
        }
    }

    Exercises

  • Extend greet to accept a title (e.g., "Dr.", "Prof.") and produce "Hello, Dr. Smith!" — make the title optional using Option<&str>
  • Implement greet_many that takes a Vec<&str> and returns a Vec<String> using .map() on an iterator
  • Add a farewell function and combine both into a Conversation struct that records the greeting and farewell
  • Open Source Repos