<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Taiwo Ayomide</title>
    <description>The latest articles on DEV Community by Taiwo Ayomide (@taiwo_ayomide).</description>
    <link>https://dev.to/taiwo_ayomide</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2595335%2Fda42663c-6361-4dac-8bc3-bf5ce2fc6805.png</url>
      <title>DEV Community: Taiwo Ayomide</title>
      <link>https://dev.to/taiwo_ayomide</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/taiwo_ayomide"/>
    <language>en</language>
    <item>
      <title>Building Your First Gleam Application: A Weather CLI Tool</title>
      <dc:creator>Taiwo Ayomide</dc:creator>
      <pubDate>Sat, 21 Dec 2024 08:36:57 +0000</pubDate>
      <link>https://dev.to/taiwo_ayomide/building-your-first-gleam-application-a-weather-cli-tool-1fb1</link>
      <guid>https://dev.to/taiwo_ayomide/building-your-first-gleam-application-a-weather-cli-tool-1fb1</guid>
      <description>&lt;p&gt;Ever wanted to learn a modern programming language that combines the reliability of Erlang with the simplicity of TypeScript? Meet Gleam - a type-safe language that makes building reliable applications a breeze. In this tutorial, we'll build a practical weather CLI tool while learning Gleam's core concepts.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5mc3mvy30l21dkzj880.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5mc3mvy30l21dkzj880.jpeg" alt="Gleam Logo" width="474" height="245"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What We're Building
&lt;/h2&gt;

&lt;p&gt;We'll create a command-line tool that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetches real-time weather data from OpenWeather API&lt;/li&gt;
&lt;li&gt;Displays formatted weather information&lt;/li&gt;
&lt;li&gt;Handles errors gracefully&lt;/li&gt;
&lt;li&gt;Uses Gleam's powerful type system&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we start, you'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Erlang OTP (24 or later)&lt;/li&gt;
&lt;li&gt;Gleam (latest version)&lt;/li&gt;
&lt;li&gt;A text editor&lt;/li&gt;
&lt;li&gt;Basic command line familiarity&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Setting Up Your Environment
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Installing Gleam
&lt;/h3&gt;

&lt;p&gt;On macOS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;gleam
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# First install Erlang&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;erlang

&lt;span class="c"&gt;# Then install Gleam using precompiled binary&lt;/span&gt;
&lt;span class="c"&gt;# Visit gleam.run for latest installation instructions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, open PowerShell as Administrator and run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Set-ExecutionPolicy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RemoteSigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CurrentUser&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Scoop package manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get.scoop.sh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After Scoop is installed, install Erlang first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;erlang&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then install Gleam:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;scoop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;gleam&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;gleam&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotdwnvkksai2h37mezhd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotdwnvkksai2h37mezhd.png" alt="Gleam Install" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Our Project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gleam new weather_cli
&lt;span class="nb"&gt;cd &lt;/span&gt;weather_cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates our project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;weather_cli/
├── src/
│   └── weather_cli.gleam
├── test/
│   └── weather_cli_test.gleam
└── gleam.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Part 1: Understanding Gleam Basics
&lt;/h2&gt;

&lt;p&gt;Let's start with some Gleam fundamentals. Create a new file &lt;code&gt;src/basics.gleam&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub fn main() {
  // Variables are immutable by default
  let message = "Hello, Gleam!"
  io.println(message)

  // Basic types
  let temperature = 23
  let is_sunny = True
  let coordinates = #(51.5074, -0.1278)  // Tuple

  // Pattern matching
  case is_sunny {
    True -&amp;gt; io.println("Wear sunscreen!")
    False -&amp;gt; io.println("Bring an umbrella!")
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Part 2: Building Our Weather Types
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;src/types.gleam&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub type Weather {
  Weather(
    temperature: Float,
    description: String,
    humidity: Int,
    wind_speed: Float,
  )
}

pub type WeatherError {
  ApiError(String)
  ParseError(String)
}

pub type WeatherResult =
  Result(Weather, WeatherError)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Part 3: Creating the API Client
&lt;/h2&gt;

&lt;p&gt;First, add dependencies to your &lt;code&gt;gleam.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;gleam_http&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"~&amp;gt; 3.0"&lt;/span&gt;
&lt;span class="py"&gt;gleam_json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"~&amp;gt; 0.5"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;src/api.gleam&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import gleam/http
import gleam/json
import gleam/result

pub fn fetch_weather(city: String) -&amp;gt; WeatherResult {
  let api_key = "your_api_key"
  let url = "http://api.openweathermap.org/data/2.5/weather?q=" 
    &amp;lt;&amp;gt; city 
    &amp;lt;&amp;gt; "&amp;amp;appid=" 
    &amp;lt;&amp;gt; api_key

  case http.get(url) {
    Ok(response) -&amp;gt; parse_response(response.body)
    Error(error) -&amp;gt; Error(ApiError(error))
  }
}

fn parse_response(json_string: String) -&amp;gt; WeatherResult {
  try json_data = json.decode(json_string)
  try temp = json.get_float(json_data, ["main", "temp"])
  try desc = json.get_string(json_data, ["weather", 0, "description"])
  try humidity = json.get_int(json_data, ["main", "humidity"])
  try wind = json.get_float(json_data, ["wind", "speed"])

  Ok(Weather(
    temperature: kelvin_to_celsius(temp),
    description: desc,
    humidity: humidity,
    wind_speed: wind,
  ))
}

fn kelvin_to_celsius(kelvin: Float) -&amp;gt; Float {
  kelvin -. 273.15
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Part 4: Creating the CLI Interface
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;src/cli.gleam&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import gleam/io
import gleam/string

pub fn display_weather(result: WeatherResult) {
  case result {
    Ok(weather) -&amp;gt; {
      io.println("\n=== Weather Report ===")
      io.println("Temperature: " &amp;lt;&amp;gt; string.from_float(weather.temperature) &amp;lt;&amp;gt; "°C")
      io.println("Conditions: " &amp;lt;&amp;gt; weather.description)
      io.println("Humidity: " &amp;lt;&amp;gt; string.from_int(weather.humidity) &amp;lt;&amp;gt; "%")
      io.println("Wind Speed: " &amp;lt;&amp;gt; string.from_float(weather.wind_speed) &amp;lt;&amp;gt; " m/s")
    }
    Error(error) -&amp;gt; {
      case error {
        ApiError(msg) -&amp;gt; io.println("API Error: " &amp;lt;&amp;gt; msg)
        ParseError(msg) -&amp;gt; io.println("Parse Error: " &amp;lt;&amp;gt; msg)
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Part 5: Putting It All Together
&lt;/h2&gt;

&lt;p&gt;Update &lt;code&gt;src/weather_cli.gleam&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import gleam/io
import gleam/string
import api
import cli

pub fn main() {
  io.println("Enter city name:")
  let city = io.get_line()

  case string.trim(city) {
    "" -&amp;gt; io.println("City name cannot be empty!")
    city -&amp;gt; {
      let weather = api.fetch_weather(city)
      cli.display_weather(weather)
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the Application
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gleam run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Enter city name:
London
=== Weather Report ===
Temperature: 18.5°C
Conditions: partly cloudy
Humidity: 72%
Wind Speed: 4.1 m/s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;Let's break down the key concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Type Safety&lt;/strong&gt;: Gleam's type system catches errors at compile time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pattern Matching&lt;/strong&gt;: We use it extensively for error handling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result Type&lt;/strong&gt;: Handles success and error cases elegantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immutable Data&lt;/strong&gt;: Makes our code more predictable&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Advanced Features to Try
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add support for multiple cities&lt;/li&gt;
&lt;li&gt;Include forecast data&lt;/li&gt;
&lt;li&gt;Save favorite locations&lt;/li&gt;
&lt;li&gt;Add temperature unit conversion&lt;/li&gt;
&lt;li&gt;Include weather alerts&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Common Pitfalls and Solutions
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;API Key Management&lt;/strong&gt;: Store in environment variables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JSON Parsing&lt;/strong&gt;: Handle missing fields gracefully&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Messages&lt;/strong&gt;: Provide user-friendly error information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate Limiting&lt;/strong&gt;: Add delays between API calls&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why Gleam?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Type Safety&lt;/strong&gt;: Catch errors before they reach production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Erlang Compatibility&lt;/strong&gt;: Access to the entire Erlang ecosystem&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern Syntax&lt;/strong&gt;: Familiar to JavaScript/TypeScript developers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Great Documentation&lt;/strong&gt;: Despite being newer, well-documented&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Growing Community&lt;/strong&gt;: Active development and community support&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add error handling for network issues&lt;/li&gt;
&lt;li&gt;Implement caching for API responses&lt;/li&gt;
&lt;li&gt;Create a configuration file for settings&lt;/li&gt;
&lt;li&gt;Add colorful terminal output&lt;/li&gt;
&lt;li&gt;Deploy as a standalone binary&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gleam.run" rel="noopener noreferrer"&gt;Official Gleam Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hexdocs.pm/gleam_stdlib" rel="noopener noreferrer"&gt;Gleam Standard Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.gg/Fm8Pwmy" rel="noopener noreferrer"&gt;Gleam Discord Community&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;X handle: &lt;a href="https://x.com/dev_ayomide" rel="noopener noreferrer"&gt;https://x.com/dev_ayomide&lt;/a&gt;&lt;br&gt;
Discord handle: &lt;a href="https://discordapp.com/users/1165333488933810336" rel="noopener noreferrer"&gt;https://discordapp.com/users/1165333488933810336&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
