# Lesson 1: Introduction & Your First Elm Program ## Learning Goals By the end of this lesson, you will: - Understand the Elm REPL - Create your first Elm project - Compile and run Elm code - Understand the project structure ## The Elm REPL Like Node.js, Elm has a REPL (Read-Eval-Print Loop) for experimenting with code. Start it by running: ```bash elm repl ``` Try these expressions: ```elm > 1 + 1 2 : number > "Hello" ++ " World" "Hello World" : String > String.length "Elm" 3 : Int ``` Notice something different from JavaScript? Elm tells you the **type** of each result! ### Key Differences from JavaScript Console | JavaScript | Elm REPL | |-----------|----------| | `"a" + "b"` | `"a" ++ "b"` (string concat uses `++`) | | `1 + "1"` = `"11"` | Error! Can't mix types | | `console.log(x)` | Just type the expression | Type `:exit` to leave the REPL. ## Your First Elm Project Let's create a real project: ```bash mkdir hello-elm cd hello-elm elm init ``` This creates: ``` hello-elm/ ├── elm.json # Project configuration (like package.json) └── src/ # Your Elm source files go here ``` ### Understanding elm.json ```json { "type": "application", "source-directories": ["src"], "elm-version": "0.19.1", "dependencies": { "direct": { "elm/browser": "1.0.2", "elm/core": "1.0.5", "elm/html": "1.0.0" }, "indirect": { ... } }, "test-dependencies": { ... } } ``` **Comparison to JavaScript:** - `source-directories` is like setting up your bundler's entry points - `dependencies` works like `package.json` but with direct/indirect separation - Unlike npm, Elm enforces **semantic versioning automatically** ## Hello World Create `src/Main.elm`: ```elm module Main exposing (main) import Html exposing (text) main = text "Hello, Elm!" ``` Let's break this down: ### 1. Module Declaration ```elm module Main exposing (main) ``` - Every Elm file is a **module** - `exposing (main)` says "make `main` available to other modules" - **JavaScript equivalent:** `export { main }` ### 2. Imports ```elm import Html exposing (text) ``` - Import the `Html` module - `exposing (text)` lets us use `text` directly instead of `Html.text` - **JavaScript equivalent:** `import { text } from 'html'` ### 3. The main Function ```elm main = text "Hello, Elm!" ``` - `main` is the entry point (like `ReactDOM.render` or your app's root) - `text` creates an HTML text node - No `return` keyword needed - the last expression is the return value ## Running Your Code ### Option 1: Elm Reactor (Development Server) ```bash elm reactor ``` Open http://localhost:8000 and click on `src/Main.elm`. ### Option 2: Compile to HTML ```bash elm make src/Main.elm ``` This creates an `index.html` file you can open in a browser. ### Option 3: Elm Live (Hot Reloading) ```bash elm-live src/Main.elm -- --open ``` This opens your browser and reloads on file changes (like webpack-dev-server). ## Exercise 1.1: Experiment in the REPL Start `elm repl` and try: 1. Calculate `123 * 456` 2. Concatenate three strings: "I", " love", " Elm" 3. Find the length of "functional programming" 4. Try `1 + "hello"` - what happens?
Solutions ```elm > 123 * 456 56088 : number > "I" ++ " love" ++ " Elm" "I love Elm" : String > String.length "functional programming" 22 : Int > 1 + "hello" -- TYPE MISMATCH -- The (+) operator is expecting both arguments to be numbers... ```
## Exercise 1.2: Modify Hello World 1. Change the greeting to include your name 2. Try using `String.toUpper` to make it ALL CAPS
Solution ```elm module Main exposing (main) import Html exposing (text) main = text (String.toUpper "Hello, Your Name!") ```
## Exercise 1.3: Multiple Elements We need to use `Html.div` to group multiple elements: ```elm module Main exposing (main) import Html exposing (div, h1, p, text) main = div [] [ h1 [] [ text "Welcome to Elm" ] , p [] [ text "This is a paragraph" ] ] ``` The pattern is: `element attributes children` - `div []` - a div with no attributes - `[ h1 ..., p ... ]` - list of children Create a page with: 1. A heading with your name 2. A paragraph about why you're learning Elm 3. Another paragraph about your programming background
Solution ```elm module Main exposing (main) import Html exposing (div, h1, p, text) main = div [] [ h1 [] [ text "Hi, I'm Learning Elm!" ] , p [] [ text "I want to learn functional programming." ] , p [] [ text "I have experience with JavaScript." ] ] ```
## Key Takeaways 1. **Elm is typed** - The compiler tells you types and catches errors early 2. **No semicolons or braces** - Whitespace and indentation matter 3. **Everything is an expression** - No statements, everything returns a value 4. **String concatenation uses `++`** - Not `+` like JavaScript 5. **HTML is just functions** - `div`, `h1`, `p` are all functions ## Common Mistakes from JavaScript Developers | Mistake | Why It Happens | Elm Way | |---------|---------------|---------| | Using `+` for strings | JavaScript habit | Use `++` | | Forgetting type annotations | JS doesn't have them | Optional but recommended | | Using `return` | JS function habit | Last expression is returned | | Using `{}` for blocks | JS syntax | Use indentation | ## What's Next? In [Lesson 2](02-basics.md), we'll dive deeper into Elm's type system and learn about: - Primitive types (Int, Float, String, Bool) - Type annotations - Records (like JavaScript objects, but better!) - Custom types --- [Next: Lesson 2 - Basic Syntax & Types →](02-basics.md)