Distinguish Quantity of the Arguments

Objective: Define a fucntion that:

  • Takes required argument, firstname
  • Takes optional argument, surname
  • Prints different messages depending on whether surname is provided or not.

Python

from typing import Optional

def say_hello(firstname: str, surname: Optional[str] = None):
    if surname is None:
        print(f"Hi {firstname}!")
    else:
        print(f"Hello {firstname} {surname}!")

say_hello("John");
say_hello("Tom", "Brown");

Rust

Here is where builder pattern comes in:

#[derive(Default)]
struct SayHello {
    surname: Option<String>,
}

impl SayHello {
    fn default() -> Self {
        Self{
            ..Default::default()
        }
    }
    
    fn surname(mut self, val: &str) -> Self {
        self.surname = Some(val.to_string());
        self
    }
    
    fn call(&self, firstname: &str) {
        if let Some(surname) = &self.surname {
            println!("Hello {} {}!", firstname, surname);
        } else {
            println!("Hi {}!", firstname);                
        }
    }
}

fn main() {
    SayHello::default().call("John");
    SayHello::default().surname("Brown").call("Tom");
}

Presence of surname is checked in compile time.

Crystal

Variant 1: Presence of surname is checked in compile time.

def say_hello(firstname : String)
  puts "Hi #{firstname}!"
end

def say_hello(firstname : String, surname : String)
  puts "Hello #{firstname} #{surname}!"
end

say_hello "John"
say_hello("Tom", "Brown")

Variant 2: Presence of surname is checked in runtime.

def say_hello(firstname : String, surname : String? = nil)
  if surname
    puts "Hello #{firstname} #{surname}!"
  else
    puts "Hi #{firstname}!"
  end
end

say_hello "John"
say_hello("Tom", "Brown")