Raku Programming Mastery: From Perl’s Evolution to Next-Generation Scripting
Goal: Master Raku (formerly Perl 6), the revolutionary language that reimagined dynamic programming. Learn to harness its unique grammar system for parsing, leverage gradual typing for safety without sacrificing flexibility, build concurrent applications with promises and supplies, and understand why Raku represents one of the most ambitious language redesigns in programming history. By the end, you will think in Raku’s paradigm-transcending way and build tools that would be impossible or impractical in other languages.
Why Raku Matters
Raku is not just “Perl 6”—it is a complete reimagining of what a dynamic language can be. After 15 years of design and development (2000-2015), Raku emerged as a language that incorporates lessons from every major programming paradigm while maintaining the pragmatic, get-things-done spirit of Perl.
The Evolution Story
Perl 5 (1994) Perl 6 Design (2000) Raku (2019)
+-----------------+ +-------------------+ +------------------+
| TMTOWTDI | | Clean up the | | Renamed to Raku |
| Regex Power | -----> | cruft, keep the | -------> | Stable, Growing |
| CPAN Ecosystem | | power, add modern | | Independent from |
| Line Noise | | features | | Perl 5 |
+-----------------+ +-------------------+ +------------------+
| | |
v v v
"Swiss Army "Everything you "A language from
Chainsaw" ever wanted" the future"
Why Learn Raku in 2025?
-
Grammars: Raku’s grammar system is unique among mainstream languages. You can define parsers as elegantly as you define classes, making compiler construction and data format parsing accessible to all programmers.
-
Gradual Typing: Mix dynamic and static typing freely. Add type constraints where they help, leave them out where they do not. The language adapts to your needs.
-
Concurrency Built-In: Promises, supplies (reactive streams), channels, and parallel execution are first-class citizens, not afterthoughts.
-
Unicode Native: Every string is a sequence of graphemes (human-perceived characters), not bytes. Identifiers can use Unicode, making code more expressive.
-
Object System with Roles: A clean OO system with traits (roles) that solves the diamond inheritance problem elegantly.
-
Operator Overloading Done Right: Create new operators (even with new precedence levels) without breaking anything.
Raku vs Perl 5
Feature Comparison:
Perl 5 Raku
+---------------------------+ +---------------------------+
| References are complex | | Native objects, no refs |
| OO requires blessed refs | | Built-in class syntax |
| Regex is strings | | Regex is a first-class |
| | | language construct |
| Single-threaded model | | Built-in concurrency |
| Weak typing | | Gradual typing system |
| CPAN modules | | Zef ecosystem (growing) |
| Backward compatible | | Clean break, fresh start |
+---------------------------+ +---------------------------+
Real-World Adoption
- Cro: A modern web framework for building HTTP services
- Grammar::Tracer: Parse complex data formats with debugging
- Text processing: Natural evolution from Perl’s text manipulation strengths
- Bioinformatics: BioRaku for sequence analysis
- Research and Academia: Language design research and education
The Raku Mindset
Traditional Programming Raku Programming
+------------------------+ +------------------------+
| Pick one paradigm | | Use what fits best |
| Work around limits | | Language adapts to you |
| Parse with regex hacks | | Use proper grammars |
| Concurrency is hard | | Concurrency is natural |
| Types or no types | | Types when you want |
+------------------------+ +------------------------+
Prerequisites and Background Knowledge
Essential Prerequisites
Before starting these projects, you should be comfortable with:
- Basic programming concepts: Variables, loops, conditionals, functions
- Command-line usage: Running scripts, navigating directories
- Text editor proficiency: Any editor you are comfortable with
- Basic regular expressions: Pattern matching fundamentals (helpful, not required)
Helpful But Not Required
- Perl 5 experience: Understanding Perl concepts will accelerate learning
- Object-oriented programming: Classes, inheritance, polymorphism
- Functional programming: Higher-order functions, immutability
- Concurrent programming: Threads, async/await concepts
Self-Assessment Questions
Before beginning, can you answer these?
- What is the difference between a compiled and interpreted language?
- How do regular expressions match patterns in text?
- What is the purpose of object-oriented programming?
- Why is Unicode important for modern applications?
If you struggled with any of these, consider reviewing the fundamentals first.
Development Environment Setup
# Install Rakudo (the main Raku implementation)
# On macOS with Homebrew:
brew install rakudo
# On Ubuntu/Debian:
apt-get install rakudo
# On Windows:
# Download from https://rakudo.org/downloads
# Verify installation:
raku --version
# Install the module manager:
# zef comes with Rakudo Star, or install separately
zef --version
# Test your first program:
echo 'say "Hello, Raku!"' > hello.raku
raku hello.raku
Time Investment Expectations
| Your Background | Expected Time per Project | Total Course Time |
|---|---|---|
| New to Programming | 4-6 hours | 80-100 hours |
| Perl 5 Developer | 2-3 hours | 40-60 hours |
| Other Language Experience | 3-4 hours | 60-80 hours |
Core Concept Analysis
Sigils: The Variable Type Markers
Raku uses sigils (symbols before variable names) to indicate the type of container:
Sigil System:
$scalar @array %hash &callable
+--------+ +--------+ +--------+ +--------+
| Single | | Ordered| | Key/ | |Function|
| Value | | List | | Value | | Code |
+--------+ +--------+ +--------+ +--------+
| | | |
v v v v
$name @names %ages &greet
$count @items %config &process
# Scalars - single values
my $name = "Alice";
my $age = 30;
my $active = True;
# Arrays - ordered sequences
my @colors = <red green blue>;
my @numbers = 1, 2, 3, 4, 5;
# Hashes - key-value pairs
my %person = name => "Bob", age => 25;
my %config = :verbose, :debug; # Pair syntax
# Callables - subroutines and methods
my &greeter = sub ($name) { say "Hello, $name!" };
greeter("World");
Twigils: Secondary Sigils
Twigils provide additional context about where a variable comes from:
Twigil Meaning Example
+-------+ +----------------+ +------------------+
| ^ | | Placeholder | | $^a, $^b |
| : | | Named param | | $:name |
| ! | | Attribute | | $!private-attr |
| . | | Accessor | | $.public-attr |
| * | | Dynamic scope | | $*DEBUG |
| ? | | Compile-time | | $?FILE |
| = | | Pod variable | | $=pod |
| ~ | | Sublanguage | | $~Grammar |
+-------+ +----------------+ +------------------+
The Type System
Type Hierarchy (Simplified):
Mu (root)
|
+-----------+-----------+
| |
Any Junction
|
+----+----+----+----+
| | | | |
Cool Str Int Rat List
|
+--+--+
| |
Str Int
# Gradual typing in action
my $dynamic = "anything"; # No type constraint
my Int $count = 42; # Must be an integer
my Str $name = "Alice"; # Must be a string
# Type checking
say 42.WHAT; # (Int)
say "hello".WHAT; # (Str)
# Subtype constraints
subset PositiveInt of Int where * > 0;
my PositiveInt $age = 25; # Works
# my PositiveInt $bad = -5; # Fails!
# Union types with where clauses
my Int $x where 0 <= * <= 100 = 50; # Range constraint
Blocks and Lambdas
Block Types:
Bare Block Pointy Block WhateverCode
+-----------+ +-------------+ +------------+
| { ... } | | -> $x { } | | * + 1 |
| No params | | Has params | | Placeholder|
+-----------+ +-------------+ +------------+
| | |
v v v
my $b = { my $add = -> $a, $b my @doubled =
say "hi" { $a + $b }; @nums.map(* * 2)
}; $add(2, 3); # 5
Object-Oriented Programming with Roles
Class and Role Relationship:
Role: Printable Role: Comparable
+-------------+ +---------------+
| method Str | | method cmp |
+-------------+ +---------------+
\ /
\ /
v v
Class: Person
+------------------+
| has $.name |
| has $.age |
| does Printable |
| does Comparable |
+------------------+
role Printable {
method Str() { ... } # Abstract method (must be implemented)
}
role Comparable {
method compare($other) { ... }
}
class Person does Printable does Comparable {
has $.name;
has $.age;
method Str() { "$.name (age $.age)" }
method compare(Person $other) {
$.age <=> $other.age
}
}
Grammars: Parsing as a First-Class Citizen
Grammar Structure:
Grammar: JSON Input Text
+-------------------+ '{"name": "Alice"}'
| rule TOP | |
| <object> | v
| rule object | +---------------+
| '{' <pairs> '}'| | Parse Tree |
| rule pairs | | +-> object |
| <pair>+ | | +-> pair |
| rule pair | | +->key|
| <key> ':' val | | +->val|
+-------------------+ +---------------+
grammar JSON {
rule TOP { <object> | <array> }
rule object { '{' <pairs>? '}' }
rule pairs { <pair>+ % ',' }
rule pair { <string> ':' <value> }
rule array { '[' <values>? ']' }
rule values { <value>+ % ',' }
rule value { <string> | <number> | <object> |
<array> | 'true' | 'false' | 'null' }
token string { '"' <-["]>* '"' }
token number { '-'? \d+ ['.' \d+]? }
}
Concurrency Model
Concurrency Primitives:
Promise Supply Channel
+--------------+ +---------------+ +---------------+
| Single value | | Stream of | | Thread-safe |
| Future | | values | | queue |
| One-shot | | Reactive | | Send/Receive |
+--------------+ +---------------+ +---------------+
| | |
v v v
my $p = start { my $s = supply { my $c = Channel.new;
slow-calc() emit 1; emit 2; $c.send(42);
}; }; $c.receive;
await $p; $s.tap: { .say };
Concept Summary Table
| Concept | What You Must Internalize | Where It Appears |
|---|---|---|
| Sigils ($, @, %) | Container type indicators, not just decoration | Projects 1-3 |
| Twigils | Scope and context markers for variables | Projects 4-5 |
| Gradual Typing | Types as optional constraints, not requirements | Projects 3-6 |
| Grammars | Parsing as object-oriented pattern matching | Projects 7-9 |
| Regexes | A sub-language, not string patterns | Projects 6-8 |
| Roles | Composable behavior units, solving diamond problem | Projects 4-5 |
| Promises | Single-value futures for async operations | Projects 10-12 |
| Supplies | Reactive streams for event-driven programming | Projects 11-12 |
| Meta-Object Protocol | Introspection and runtime modification | Projects 13-14 |
| Unicode | Native grapheme handling, not byte sequences | Projects 8-9 |
Deep Dive Reading by Concept
Core Language
- Think Raku by Laurent Rosenfeld (free online) - Chapters 1-5: Variables, operators, control flow
- Learning Perl 6 by brian d foy - Chapters 1-4: Getting started, basics, operators
Object-Oriented Programming
- Think Raku - Chapters 11-14: Classes, roles, inheritance
- Raku Documentation (docs.raku.org) - Object Orientation section
Grammars and Parsing
- Parsing with Perl 6 Regexes and Grammars by Moritz Lenz - Complete guide
- Think Raku - Chapter 17: Grammars
Concurrency
- Raku Documentation - Concurrency section
- Think Raku - Chapter 16: Parallelism and concurrency
Functional Programming
- Think Raku - Chapter 6: Subroutines, Chapter 10: Higher-order functions
- Learning Perl 6 - Chapter 14: Functional programming
Quick Start Guide: Your First 48 Hours
If you are overwhelmed, here is your roadmap for the first two days:
Day 1 (4-6 hours)
- Install Rakudo (30 min)
- Complete Project 1: Hello Raku Explorer (2-3 hours)
- Read Think Raku Chapters 1-2 (1-2 hours)
Day 2 (4-6 hours)
- Complete Project 2: Text Statistics Analyzer (3-4 hours)
- Experiment in the REPL (1 hour)
- Browse docs.raku.org (1 hour)
After 48 hours, you will have:
- A working Raku environment
- Understanding of sigils and basic syntax
- Experience with file I/O and text processing
- Familiarity with Raku’s unique features
Recommended Learning Paths
Path A: Coming from Perl 5 (Fastest)
Project 1 -> Project 3 -> Project 7 -> Project 10 -> Project 15
(basics) (OO/roles) (grammars) (concurrency) (Perl 5 interop)
Path B: Coming from Python/Ruby (Scripting Focus)
Project 1 -> Project 2 -> Project 6 -> Project 8 -> Project 11
(basics) (text proc) (regexes) (Unicode) (web scraping)
Path C: Coming from Java/C# (OO Focus)
Project 1 -> Project 3 -> Project 4 -> Project 5 -> Project 13
(basics) (OO basics) (roles) (typing) (MOP)
Path D: Complete Beginner (Thorough)
Projects 1 -> 2 -> 3 -> 4 -> 5 -> ... -> 18 (sequential)
Project List
Project 1: Hello Raku Explorer
- Main Programming Language: Raku
- Difficulty: Level 1: Beginner
- Knowledge Area: Language Basics / Syntax
- Time Estimate: 2-3 hours
What you will build: An interactive command-line program that explores Raku’s basic syntax, variable types, operators, and unique features. The program will demonstrate sigils, twigils, string interpolation, and basic I/O.
Why it teaches Raku: This project immediately confronts you with what makes Raku different: sigils that mean something, twigils for scope, and operators you have never seen before. You cannot just translate from another language—you must think in Raku.
Core challenges you will face:
- Understanding sigils maps to knowing when to use $, @, and %
- String interpolation maps to mastering double-quoted strings and closures
- Operators maps to learning Raku’s expanded operator set
- I/O basics maps to using say, print, get, and prompt
Key Concepts:
- Sigils and Variables: Think Raku Ch. 2
- Operators: Think Raku Ch. 3
- Basic I/O: docs.raku.org/language/io
Prerequisites: Basic programming knowledge.
Real World Outcome:
$ raku hello-explorer.raku
Welcome to the Raku Explorer!
Enter your name: Alice
Hello, Alice! Your name has 5 characters.
Demonstrating sigils:
$scalar = 42 (single value)
@array = [1, 2, 3] (ordered list)
%hash = {name => Alice, age => 30} (key-value pairs)
Demonstrating operators:
String repetition: 'Raku' x 3 = RakuRakuRaku
Range: 1..5 = (1 2 3 4 5)
Sequence: 1, 2, 4 ... 64 = (1 2 4 8 16 32 64)
Smart match: 42 ~~ Int = True
Your exploration is complete!
The Core Question You Are Answering: How does Raku’s syntax differ from other languages, and what do these differences enable?
Concepts You Must Understand First:
- What is a variable? (review any programming fundamentals)
- What is standard input/output? (command-line basics)
- What is an operator? (basic programming)
Questions to Guide Your Design:
- How will you prompt for and read user input?
- How will you demonstrate each sigil type meaningfully?
- Which operators best showcase Raku’s uniqueness?
- How will you structure the output for clarity?
Thinking Exercise: Before coding, write out by hand what each sigil represents. Draw a diagram showing how @array[0] is actually $array[0] (the scalar inside the array).
The Interview Questions They Will Ask:
- What is the difference between $ and @ sigils in Raku?
- How does string interpolation work in Raku?
- What is the … sequence operator and how does it work?
- Explain the smart match operator (~~).
- How do you read from standard input in Raku?
Hints in Layers:
- Hint 1: Start with
my $name = prompt "Enter your name: "; - Hint 2: Use
.charsmethod on strings to get length - Hint 3: The sequence operator
...can infer patterns:1, 2, 4 ... 64doubles - Hint 4: Use
sayfor output with newline,printwithout
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Variables | Think Raku | Ch. 2 | | Operators | Think Raku | Ch. 3 | | I/O | docs.raku.org | /language/io |
Common Pitfalls and Debugging:
| Problem | Cause | Fix |
|———|——-|—–|
| “Variable requires declaration” | Missing my | Add my before first use |
| Unexpected output | Wrong sigil | Remember: $ single, @ list, % hash |
| No newline in output | Using print | Use say instead |
Learning Milestones:
- Basic: Your program prompts for input and echoes it back
- Intermediate: You demonstrate all three main sigil types correctly
- Advanced: You use unique Raku operators like
...and~~
Project 2: Text Statistics Analyzer
- Main Programming Language: Raku
- Difficulty: Level 1: Beginner
- Knowledge Area: Text Processing / File I/O
- Time Estimate: 3-4 hours
What you will build: A command-line tool that analyzes text files, producing statistics like word count, line count, character count, average word length, most common words, and reading level estimation.
Why it teaches Raku: Text processing is where Raku shines. This project teaches you file handling, string methods, hashes for counting, and the powerful words and lines methods that make text manipulation elegant.
Core challenges you will face:
- Reading files maps to using slurp or IO::Path methods
- Counting words maps to using
.wordsmethod and hashes - Frequency analysis maps to hash manipulation and sorting
- Calculating statistics maps to using reduce and mathematical operations
Key Concepts:
- File I/O: docs.raku.org/type/IO::Path
- String Methods: docs.raku.org/type/Str
- Hashes: Think Raku Ch. 5
Prerequisites: Project 1 completed.
Real World Outcome:
$ raku text-stats.raku sample.txt
Text Statistics for: sample.txt
================================
Lines: 1,247
Words: 15,832
Characters: 89,456
Unique words: 2,341
Average word length: 5.65 characters
Longest word: "internationalization" (20 chars)
Top 10 Most Common Words:
1. the (892 occurrences)
2. and (456 occurrences)
3. to (423 occurrences)
4. of (398 occurrences)
5. a (356 occurrences)
6. in (312 occurrences)
7. is (289 occurrences)
8. that (234 occurrences)
9. for (198 occurrences)
10. it (167 occurrences)
Estimated reading level: 8th grade (Flesch-Kincaid)
The Core Question You Are Answering: How does Raku make text processing more elegant than traditional approaches?
Concepts You Must Understand First:
- What is a hash and how do you increment values?
- How do you iterate over a list in a loop?
- What is the difference between lines and words?
Questions to Guide Your Design:
- Should you read the entire file at once or line by line?
- How will you normalize words (lowercase, strip punctuation)?
- What data structure will you use for word frequencies?
- How will you efficiently find the most common words?
Thinking Exercise: Before coding, manually analyze this sentence: “The cat sat on the mat.” Count words, unique words, and word frequencies by hand.
The Interview Questions They Will Ask:
- What is the difference between
.slurpand.linesin Raku? - How do you iterate over hash key-value pairs?
- What method would you use to sort a hash by value?
- How does Raku handle Unicode in text processing?
- Explain the Bag type and when you would use it instead of a hash.
Hints in Layers:
- Hint 1: Use
"file.txt".IO.slurpto read entire file - Hint 2:
.wordssplits on whitespace,.lclowercases - Hint 3: Consider using
Baginstead of hash for counting - Hint 4: Sort pairs with
.sort(-*.value).head(10)
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | File I/O | Think Raku | Ch. 8 | | Strings | Think Raku | Ch. 7 | | Hashes | Think Raku | Ch. 5 |
Common Pitfalls and Debugging:
| Problem | Cause | Fix |
|———|——-|—–|
| Punctuation in words | Not cleaning input | Use .subst or regex |
| Case sensitivity | Not normalizing | Use .lc on words |
| Memory issues | Large file slurped | Use .lines iterator |
Learning Milestones:
- Basic: Your program counts lines, words, and characters
- Intermediate: You correctly identify word frequencies
- Advanced: You implement reading level calculation
Project 3: Object-Oriented Address Book
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: Object-Oriented Programming
- Time Estimate: 4-5 hours
What you will build: A fully-featured address book application demonstrating Raku’s object system with classes, attributes, methods, inheritance, and basic persistence (saving/loading from files).
Why it teaches Raku: Raku’s OO system is a complete redesign from Perl 5’s blessed references. You will learn the class keyword, the has declarator, automatic accessors, and how Raku makes OO programming clean and explicit.
Core challenges you will face:
- Defining classes maps to using
class,has, andmethod - Attribute access maps to understanding
.vs!twigils - Object construction maps to using
.newandBUILD - Persistence maps to serialization and file I/O
Key Concepts:
- Classes: docs.raku.org/language/classtut
- Attributes: Think Raku Ch. 11
- Methods: Think Raku Ch. 11
Prerequisites: Projects 1-2 completed.
Real World Outcome:
$ raku address-book.raku
Address Book v1.0
=================
Commands: add, list, search, edit, delete, save, load, quit
> add
Name: Alice Johnson
Email: alice@example.com
Phone: 555-1234
Address: 123 Main St
Contact added successfully!
> list
ID Name Email Phone
1 Alice Johnson alice@example.com 555-1234
> search alice
Found 1 contact(s):
1 Alice Johnson alice@example.com 555-1234
> save contacts.dat
Saved 1 contact(s) to contacts.dat
> quit
Goodbye!
The Core Question You Are Answering: How does Raku’s object system improve upon traditional OO approaches?
Concepts You Must Understand First:
- What is encapsulation and why does it matter?
- What is the difference between a class and an object?
- How do constructors work in OO languages?
Questions to Guide Your Design:
- What attributes does a Contact need?
- Should attributes be public (
.) or private (!)? - How will you generate unique IDs for contacts?
- What format will you use for persistence?
Thinking Exercise: Design the Contact class on paper. List all attributes with their types, and decide which should be read-only vs read-write.
The Interview Questions They Will Ask:
- What is the difference between
has $.nameandhas $!name? - How do you make an attribute required in Raku?
- Explain the
BUILDsubmethod and when you need it. - How do you implement a custom
.gistor.Strmethod? - What is the difference between
methodandsubmethod?
Hints in Layers:
- Hint 1:
class Contact { has $.name; has $.email; } - Hint 2: Use
is requiredtrait for mandatory attributes - Hint 3: Override
.gistfor custom string representation - Hint 4: Use JSON::Tiny module for serialization
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Classes | Think Raku | Ch. 11-12 | | Attributes | docs.raku.org | /language/objects | | Persistence | Think Raku | Ch. 15 |
Common Pitfalls and Debugging:
| Problem | Cause | Fix |
|———|——-|—–|
| “Cannot modify immutable” | Attribute is read-only | Use is rw trait |
| Wrong accessor | Using $! vs $. | $. for public, $! for private |
| BUILD not called | Wrong signature | Use named parameters |
Learning Milestones:
- Basic: You can create and display Contact objects
- Intermediate: Your address book supports CRUD operations
- Advanced: You implement save/load with file persistence
Project 4: Roles and Composition System
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: Object-Oriented Programming / Roles
- Time Estimate: 4-5 hours
What you will build: A flexible entity system for a game or simulation that uses roles for composable behavior. Entities like Player, Enemy, and NPC will mix in roles like Movable, Damageable, Inventoried, and Talkable.
Why it teaches Raku: Roles are Raku’s solution to the problems with traditional inheritance. This project teaches you to think in terms of behavior composition rather than inheritance hierarchies, and to understand how roles differ from both interfaces and mixins.
Core challenges you will face:
- Defining roles maps to using the
rolekeyword - Composing roles maps to using
doesin class declarations - Role conflicts maps to understanding disambiguation
- Parameterized roles maps to creating flexible, reusable behaviors
Key Concepts:
- Roles: docs.raku.org/language/objects#Roles
- Composition: Think Raku Ch. 13
- Conflict Resolution: docs.raku.org/language/objects#Conflict_resolution
Prerequisites: Project 3 completed.
Real World Outcome:
$ raku entity-system.raku
Entity System Demo
==================
Creating entities:
Player "Hero" created with roles: Movable, Damageable, Inventoried
Enemy "Goblin" created with roles: Movable, Damageable
NPC "Merchant" created with roles: Talkable, Inventoried
Demonstrating behaviors:
Hero moves to position (10, 20)
Hero takes 15 damage (HP: 100 -> 85)
Hero picks up "Sword of Valor"
Hero's inventory: Sword of Valor, Health Potion x3
Goblin moves to position (12, 18)
Goblin attacks Hero for 10 damage
Hero HP: 85 -> 75
Merchant says: "Welcome, traveler! Browse my wares."
Merchant's inventory: Iron Sword, Leather Armor, Torch x5
Entity types:
Hero does: Movable, Damageable, Inventoried
Goblin does: Movable, Damageable
Merchant does: Talkable, Inventoried
The Core Question You Are Answering: How do roles solve the problems of traditional inheritance while enabling flexible code reuse?
Concepts You Must Understand First:
- What is the diamond problem in multiple inheritance?
- What is the difference between “is-a” and “has-a” relationships?
- Why is composition often preferred over inheritance?
Questions to Guide Your Design:
- What behaviors should be roles vs base class features?
- How will you handle conflicts if two roles define the same method?
- Should roles have state (attributes) or only behavior?
- How will entities interact with each other?
Thinking Exercise: Draw a diagram showing which roles each entity type should have. Consider: can a role require another role?
The Interview Questions They Will Ask:
- What is the difference between a role and an abstract class?
- How do you resolve method conflicts when composing roles?
- Can roles have attributes? If so, how do they work?
- What is a parameterized role and when would you use one?
- Explain the
doesvsbutoperators for roles.
Hints in Layers:
- Hint 1:
role Movable { has $.x = 0; has $.y = 0; method move($dx, $dy) { ... } } - Hint 2: Use
doesin class definition:class Player does Movable does Damageable { } - Hint 3: Resolve conflicts with explicit method:
method foo { self.RoleName::foo() } - Hint 4: Use
.does(RoleName)to check if an object has a role
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Roles | Think Raku | Ch. 13 | | Composition | docs.raku.org | /language/objects | | Conflicts | Think Raku | Ch. 13 |
Common Pitfalls and Debugging:
| Problem | Cause | Fix |
|———|——-|—–|
| “Method conflicts” | Same method in multiple roles | Explicitly resolve in class |
| Role not found | Missing use or definition | Check file/module loading |
| Attribute shadowing | Same attr name in roles | Use unique names or resolve |
Learning Milestones:
- Basic: You define roles and apply them to classes
- Intermediate: Entities can interact using role-based behaviors
- Advanced: You handle role conflicts and use parameterized roles
Project 5: Gradual Typing Laboratory
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: Type System
- Time Estimate: 3-4 hours
What you will build: A type experimentation playground that demonstrates Raku’s gradual typing system, including basic types, subset types, where clauses, multi dispatch, and type coercion.
Why it teaches Raku: Raku’s type system is unique—it is completely optional but incredibly powerful when used. This project teaches you to think about types as constraints that help catch bugs early while maintaining the flexibility of dynamic typing.
Core challenges you will face:
- Basic type constraints maps to using built-in types like Int, Str, Bool
- Subset types maps to creating custom type constraints
- Where clauses maps to adding runtime type checks
- Multi dispatch maps to type-based function overloading
Key Concepts:
- Type System: docs.raku.org/language/typesystem
- Subsets: docs.raku.org/language/typesystem#subset
- Multi Dispatch: docs.raku.org/language/functions#Multi-dispatch
Prerequisites: Projects 1-3 completed.
Real World Outcome:
$ raku type-lab.raku
Gradual Typing Laboratory
==========================
=== Basic Type Constraints ===
typed-add(5, 3) = 8 # Int, Int -> Int
typed-add("5", 3) = Error: Type check failed
=== Subset Types ===
my PositiveInt $age = 25; # OK
my PositiveInt $age = -5; # Error: Constraint violated
my Email $contact = "user@example.com"; # OK
my Email $contact = "not-an-email"; # Error: Invalid email format
=== Where Clauses ===
my Int $score where 0 <= * <= 100 = 85; # OK
Attempting to set 150... # Error: Where constraint failed
=== Multi Dispatch ===
process("hello") -> "String: hello"
process(42) -> "Number: 42"
process([1, 2, 3]) -> "List: 1, 2, 3"
process({a => 1}) -> "Hash: a => 1"
=== Coercion Types ===
my Int() $from-string = "42"; # Coerced from Str to Int
Value: 42, Type: (Int)
=== Type Introspection ===
42.WHAT -> (Int)
42.^name -> Int
42 ~~ Int -> True
42 ~~ Cool -> True (Int does Cool)
The Core Question You Are Answering: How do you balance type safety with dynamic flexibility in Raku?
Concepts You Must Understand First:
- What is static vs dynamic typing?
- What is a type constraint and why is it useful?
- How do generic/template types work in other languages?
Questions to Guide Your Design:
- When should you add type constraints to your code?
- How do subset types differ from just using
whereclauses? - What happens when type coercion fails?
- How does multi dispatch choose which candidate to call?
Thinking Exercise: Write down three functions that would benefit from multi dispatch. For each, list what types the parameters could be and how the behavior should differ.
The Interview Questions They Will Ask:
- Explain the difference between gradual and static typing.
- How do you create a custom type in Raku?
- What is multi dispatch and how does Raku’s dispatcher work?
- How would you validate an email address using Raku’s type system?
- What is type coercion in Raku and when is it useful?
Hints in Layers:
- Hint 1:
subset PositiveInt of Int where * > 0; - Hint 2:
multi sub process(Str $s) { }for type-specific handling - Hint 3: Use
Int()in signature for coercion:sub foo(Int() $n) { } - Hint 4: Use
.^mroto see the method resolution order
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Type System | docs.raku.org | /language/typesystem | | Subsets | Think Raku | Ch. 6 | | Multi Dispatch | Think Raku | Ch. 6 |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | “Type check failed” | Wrong type passed | Check parameter types | | Multi ambiguity | Overlapping signatures | Make signatures more specific | | Coercion failed | Invalid input | Handle with try/CATCH |
Learning Milestones:
- Basic: You use built-in types as constraints
- Intermediate: You create custom subset types with
where - Advanced: You implement multi-dispatch functions
Project 6: Regex Evolution Explorer
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: Regular Expressions / Pattern Matching
- Time Estimate: 4-5 hours
What you will build: A regex testing and demonstration tool that showcases Raku’s evolved regex syntax, including named captures, grammars, code blocks, and the key differences from traditional (Perl 5/PCRE) regexes.
Why it teaches Raku: Raku completely reinvented regular expressions, turning them from opaque strings into a readable, composable sub-language. Understanding Raku regexes is essential for using grammars effectively.
Core challenges you will face:
- New syntax maps to learning Raku’s cleaner regex notation
- Named captures maps to using
<name>and$<name> - Modifiers maps to using
:i,:g, and others - Code blocks maps to embedding Raku code in regexes
Key Concepts:
- Regexes: docs.raku.org/language/regexes
- Captures: docs.raku.org/language/regexes#Capturing
- Assertions: docs.raku.org/language/regexes#Assertions
Prerequisites: Basic regex knowledge, Projects 1-2 completed.
Real World Outcome:
$ raku regex-explorer.raku
Raku Regex Explorer
===================
=== Syntax Comparison ===
Perl 5: /\d+/ Raku: /\d+/
Perl 5: /[a-z]+/ Raku: /<[a..z]>+/
Perl 5: /(?:foo|bar)/ Raku: /[foo|bar]/
Perl 5: /foo(?=bar)/ Raku: /foo <?before bar>/
Perl 5: /(?i)hello/ Raku: /:i hello/
=== Named Captures ===
Input: "John Smith, age 42"
Pattern: /$<first>=(\w+) \s+ $<last>=(\w+) ',' \s* 'age' \s+ $<age>=(\d+)/
Match found!
$<first> = "John"
$<last> = "Smith"
$<age> = "42"
=== Character Classes ===
<alpha> matches: a, Z, Alpha (not: 1, @)
<digit> matches: 0, 9 (not: a, -)
<alnum> matches: a, 5 (not: @, -)
<xdigit> matches: a, F, 9 (not: g, Z)
<space> matches: " ", "\t", "\n"
=== Quantifiers ===
? = 0 or 1 (optional)
* = 0 or more
+ = 1 or more
** 3 = exactly 3
** 2..5 = between 2 and 5
=== Code Blocks in Regex ===
Pattern: /(\d+) { say "Found number: $0" }/
Input: "Price: 42 dollars"
Output: Found number: 42
The Core Question You Are Answering: How does Raku’s regex redesign make pattern matching more readable and powerful?
Concepts You Must Understand First:
- What is a regular expression and how does matching work?
- What are capturing groups in traditional regexes?
- What is the difference between greedy and lazy matching?
Questions to Guide Your Design:
- How will you demonstrate the syntax differences clearly?
- What examples best show the power of named captures?
- How will you handle and display match failures?
- What code blocks would be useful inside regexes?
Thinking Exercise: Take a complex Perl 5 regex you have written or seen. Rewrite it in Raku syntax, using named captures and whitespace for readability.
The Interview Questions They Will Ask:
- What is the difference between
<[a..z]>anda..zin Raku regexes? - How do you make a regex case-insensitive in Raku?
- Explain the difference between
||and|in Raku regexes. - How do code blocks work inside Raku regexes?
- What is the difference between
token,rule, andregex?
Hints in Layers:
- Hint 1: Whitespace is ignored by default in Raku regexes
- Hint 2: Use
$<name>=patternfor named captures - Hint 3:
<[a..z]>is a character class (not[a-z]) - Hint 4: Use
{ code }inside regex for side effects
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Regexes | Parsing with Perl 6 Regexes and Grammars | Ch. 1-3 | | Syntax | docs.raku.org | /language/regexes | | Examples | Think Raku | Ch. 9 |
Common Pitfalls and Debugging:
| Problem | Cause | Fix |
|———|——-|—–|
| Match fails | Whitespace matters | Use :sigspace or explicit \s |
| Wrong captures | Numbering confusion | Use named captures |
| Slow matching | Backtracking | Use token instead of regex |
Learning Milestones:
- Basic: You can translate Perl 5 regexes to Raku syntax
- Intermediate: You use named captures and character classes
- Advanced: You embed code blocks in regexes
Project 7: Grammar-Based Parser
- Main Programming Language: Raku
- Difficulty: Level 3: Advanced
- Knowledge Area: Parsing / Grammars
- Time Estimate: 6-8 hours
What you will build: A complete parser for a simple configuration file format (like INI or a custom DSL) using Raku’s grammar system, including an actions class to transform the parse tree into usable data structures.
Why it teaches Raku: Grammars are Raku’s killer feature. This project teaches you to think about parsing as a first-class programming task, not a regex hack. You will learn how grammars extend regexes into full parsing tools.
Core challenges you will face:
- Grammar definition maps to using
grammar,token, andrule - Hierarchical parsing maps to calling sub-rules from rules
- Actions maps to transforming parse results
- Error handling maps to reporting parse failures meaningfully
Key Concepts:
- Grammars: docs.raku.org/language/grammars
- Actions: docs.raku.org/language/grammars#Action_objects
- Parse Trees: Understanding Match objects
Prerequisites: Project 6 completed, understanding of basic parsing concepts.
Real World Outcome:
$ cat config.ini
[database]
host = localhost
port = 5432
name = myapp
[server]
address = 0.0.0.0
port = 8080
debug = true
$ raku grammar-parser.raku config.ini
Parsing config.ini...
Parse successful!
Extracted configuration:
{
database => {
host => "localhost",
port => 5432,
name => "myapp"
},
server => {
address => "0.0.0.0",
port => 8080,
debug => True
}
}
Accessing values:
config<database><host> = localhost
config<server><port> = 8080
The Core Question You Are Answering: How do Raku grammars make building parsers as natural as defining classes?
Concepts You Must Understand First:
- What is a grammar in computer science terms?
- What is the difference between tokenizing and parsing?
- What is a parse tree and how is it used?
Questions to Guide Your Design:
- What are the main components of your file format?
- How will you structure your grammar rules hierarchically?
- What should each action method return?
- How will you handle syntax errors gracefully?
Thinking Exercise: Draw the grammar tree for a simple INI section. Start with TOP, then section, then key-value pairs. What does each level capture?
The Interview Questions They Will Ask:
- What is the difference between
tokenandrulein grammars? - How do actions classes work with grammars?
- What is the Match object and how do you navigate it?
- How do you handle optional or repeated elements in grammars?
- Explain proto tokens and when you would use them.
Hints in Layers:
- Hint 1: Start with
grammar Config { token TOP { <section>+ } } - Hint 2:
tokendoes not backtrack,ruleignores whitespace - Hint 3: Actions class methods match rule names:
method section($/) { ... } - Hint 4: Use
$/.make()to attach transformed data to match
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Grammars | Parsing with Perl 6 Regexes and Grammars | All | | Actions | docs.raku.org | /language/grammars | | Examples | Think Raku | Ch. 17 |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | “No match” | Rule not matching | Use Grammar::Tracer to debug | | Actions not called | Method name mismatch | Names must match rule names | | Infinite loop | Left recursion | Restructure grammar |
Learning Milestones:
- Basic: Your grammar parses the basic structure
- Intermediate: Actions transform parse tree to hash
- Advanced: Error messages indicate where parsing failed
Project 8: Unicode Text Processor
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: Unicode / Text Processing
- Time Estimate: 4-5 hours
What you will build: A text processing tool that demonstrates Raku’s native Unicode support, including grapheme handling, Unicode properties in regexes, normalization forms, and multi-script text processing.
Why it teaches Raku: Raku was designed from the ground up for Unicode. Strings are sequences of graphemes (what humans perceive as characters), not bytes or code points. This project teaches you to handle international text correctly.
Core challenges you will face:
- Grapheme handling maps to understanding Raku’s string model
- Unicode properties maps to using
<:Lu>,<:Emoji>, etc. - Normalization maps to using NFC, NFD, etc.
- Multi-script text maps to handling mixed languages
Key Concepts:
- Unicode in Raku: docs.raku.org/language/unicode
- Unicode Properties: docs.raku.org/language/regexes#Unicode_properties
- Normalization: Understanding NFC, NFD, NFKC, NFKD
Prerequisites: Projects 1-2, basic Unicode awareness.
Real World Outcome:
$ raku unicode-processor.raku
Unicode Text Processor
======================
=== Grapheme Awareness ===
String: "cafe" (with accent) = "cafe" (4 graphemes)
String: "cafe" (combined) = "cafe" (4 graphemes)
Note: Both display the same despite different encodings!
Emoji test: "family" = 1 grapheme (even though it is 7 code points!)
Code points: U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466
=== Unicode Properties in Regex ===
Matching uppercase letters: <:Lu>
Input: "Hello WORLD 123"
Matches: H, W, O, R, L, D
Matching emojis: <:Emoji>
Input: "Hello World!"
Matches: (face), (waving hand), (globe)
=== Normalization ===
Input (NFD): "cafe" (U+0065 U+0301 - e + combining acute)
Output (NFC): "cafe" (U+00E9 - e with acute)
These are equal: "cafe".NFC eq "cafe".NFC -> True
=== Multi-Script Support ===
Input: "Hello, World!"
Languages detected:
- English (Latin script)
- Japanese (Hiragana + Kanji)
- Russian (Cyrillic)
The Core Question You Are Answering: How does Raku’s native Unicode support differ from other languages’ “Unicode as an afterthought” approach?
Concepts You Must Understand First:
- What is the difference between a code point and a grapheme?
- Why are there multiple ways to encode the same character?
- What problems does normalization solve?
Questions to Guide Your Design:
- How will you demonstrate grapheme vs code point counting?
- What Unicode properties are most useful for text processing?
- How will you show that normalization affects comparisons?
- What edge cases in Unicode should you handle?
Thinking Exercise: Find an emoji that is composed of multiple code points (like a family or flag). Manually count the code points vs how many characters you see.
The Interview Questions They Will Ask:
- What is a grapheme and how does Raku handle them?
- How do you match any uppercase letter from any language in Raku?
- Explain Unicode normalization forms and when each is used.
- How does Raku’s string
.charsdiffer from other languages? - What is the difference between
.codesand.charsin Raku?
Hints in Layers:
- Hint 1:
.charscounts graphemes,.codescounts code points - Hint 2:
<:Lu>matches uppercase letters from any script - Hint 3: Use
.NFCor.NFDmethods for normalization - Hint 4: Use
.uninameto get the Unicode name of a character
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Unicode | docs.raku.org | /language/unicode | | Regexes | Think Raku | Ch. 9 | | Strings | Think Raku | Ch. 7 |
Common Pitfalls and Debugging:
| Problem | Cause | Fix |
|———|——-|—–|
| Wrong length | Counting bytes/codes | Use .chars for graphemes |
| Comparison fails | Different normalization | Normalize before comparing |
| Regex miss | Wrong property | Check Unicode property name |
Learning Milestones:
- Basic: You correctly count graphemes in multi-script text
- Intermediate: You use Unicode properties in regexes
- Advanced: You handle normalization for comparisons
Project 9: JSON Parser Grammar
- Main Programming Language: Raku
- Difficulty: Level 3: Advanced
- Knowledge Area: Parsing / Grammars
- Time Estimate: 6-8 hours
What you will build: A complete JSON parser using Raku grammars that handles all JSON types (objects, arrays, strings, numbers, booleans, null) and produces native Raku data structures.
Why it teaches Raku: JSON is a well-defined, recursive format that exercises all aspects of grammar design. Building a JSON parser teaches you nested structures, escape sequences, and the interplay between grammars and actions.
Core challenges you will face:
- Recursive structures maps to grammars calling themselves
- String escapes maps to handling \n, \u0000, etc.
- Number parsing maps to handling integers, floats, scientific notation
- Error positions maps to reporting where parsing fails
Key Concepts:
- Recursive Grammars: Structures that contain themselves
- Escape Handling: Processing special characters
- Actions Classes: Transforming matches to native types
Prerequisites: Project 7 completed, familiarity with JSON format.
Real World Outcome:
$ cat sample.json
{
"name": "Alice",
"age": 30,
"active": true,
"scores": [95.5, 88, 92.3],
"address": {
"city": "Boston",
"zip": "02101"
},
"notes": null
}
$ raku json-parser.raku sample.json
Parsing sample.json...
Parse successful!
Result (as Raku hash):
{
address => {city => "Boston", zip => "02101"},
active => True,
age => 30,
name => "Alice",
notes => Nil,
scores => [95.5, 88, 92.3]
}
Type checks:
$result<name>.WHAT = (Str)
$result<age>.WHAT = (Int)
$result<active>.WHAT = (Bool)
$result<scores>.WHAT = (Array)
$result<notes>.WHAT = Nil
Round-trip test: parse -> serialize -> parse = PASS
The Core Question You Are Answering: How do you build a grammar for a recursive, hierarchical data format?
Concepts You Must Understand First:
- What is the JSON specification and its data types?
- How do recursive grammars work?
- What is the difference between parsing and lexing?
Questions to Guide Your Design:
- How will you handle nested objects and arrays?
- What is the correct way to parse JSON strings with escapes?
- How will your actions convert JSON types to Raku types?
- How will you handle and report malformed JSON?
Thinking Exercise: Write out the grammar rules for JSON on paper. Start with value, then define object, array, string, number, boolean, and null.
The Interview Questions They Will Ask:
- How do you handle recursive structures in grammars?
- Explain how you would parse escape sequences in strings.
- What is the difference between a token and a rule for number parsing?
- How do actions transform a Match into native types?
- How would you add line/column numbers to error messages?
Hints in Layers:
- Hint 1:
token value { <object> | <array> | <string> | <number> | <true> | <false> | <null> } - Hint 2: For strings:
token string { '"' <str-char>* '"' } - Hint 3: Actions use
$<object>.madeto get transformed values - Hint 4: Use
Grammar::Tracerto debug your grammar
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Grammars | Parsing with Perl 6 Regexes and Grammars | All | | JSON Spec | json.org | (specification) | | Actions | docs.raku.org | /language/grammars |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Infinite loop | Left recursion in grammar | Restructure rules | | String escapes fail | Not handling \uXXXX | Add escape handling rule | | Numbers wrong | Not handling all formats | Include exponent, sign |
Learning Milestones:
- Basic: Parse simple JSON objects and arrays
- Intermediate: Handle all JSON types including escapes
- Advanced: Error messages show position, round-trip works
Project 10: Concurrent File Processor
- Main Programming Language: Raku
- Difficulty: Level 3: Advanced
- Knowledge Area: Concurrency / Promises
- Time Estimate: 5-6 hours
What you will build: A multi-file processor that uses Raku’s concurrency primitives (Promises, await, start) to process multiple files in parallel, demonstrating speedup and proper synchronization.
Why it teaches Raku: Raku’s concurrency model is built into the language, not bolted on. This project teaches you to think about parallel processing as a natural part of programming, using promises for one-shot computations.
Core challenges you will face:
- Creating promises maps to using
startblocks - Awaiting results maps to using
awaitand.result - Combining promises maps to using
Promise.allofand.in - Error handling maps to managing failures in concurrent code
Key Concepts:
- Promises: docs.raku.org/type/Promise
- start blocks: docs.raku.org/language/concurrency#start
- Synchronization: Managing shared state safely
Prerequisites: Projects 1-3 completed, basic understanding of concurrency concepts.
Real World Outcome:
$ ls files/
doc1.txt doc2.txt doc3.txt doc4.txt doc5.txt
(each file is ~10MB)
$ raku concurrent-processor.raku files/
Concurrent File Processor
=========================
Processing 5 files with 4 workers...
Starting: doc1.txt
Starting: doc2.txt
Starting: doc3.txt
Starting: doc4.txt
Completed: doc2.txt (1,234,567 words) in 1.2s
Starting: doc5.txt
Completed: doc1.txt (1,345,678 words) in 1.5s
Completed: doc4.txt (1,123,456 words) in 1.1s
Completed: doc3.txt (1,456,789 words) in 1.8s
Completed: doc5.txt (1,234,321 words) in 1.3s
Summary:
Total files: 5
Total words: 6,394,811
Total time: 2.1s (parallel)
Estimated sequential time: 6.9s
Speedup: 3.3x
All files processed successfully!
The Core Question You Are Answering: How does Raku make concurrent programming natural and safe?
Concepts You Must Understand First:
- What is a promise/future in concurrent programming?
- What are race conditions and how do you avoid them?
- What is the difference between concurrency and parallelism?
Questions to Guide Your Design:
- How will you distribute work across available cores?
- How will you collect and combine results from workers?
- How will you handle errors in individual workers?
- How will you track and display progress?
Thinking Exercise: Draw a timeline diagram showing how 5 files would be processed with 4 workers. When does each start and end?
The Interview Questions They Will Ask:
- What is the difference between
startandPromise.in? - How do you wait for multiple promises to complete?
- What happens if a promise throws an exception?
- How does Raku’s
hyperdiffer from explicit promises? - Explain the difference between
awaitand.result.
Hints in Layers:
- Hint 1:
my $p = start { process-file($path) } - Hint 2:
await Promise.allof(@promises)waits for all - Hint 3: Use
tryinside start blocks for error handling - Hint 4: Consider using
raceorhyperfor simpler cases
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Concurrency | docs.raku.org | /language/concurrency | | Promises | Think Raku | Ch. 16 | | Parallelism | docs.raku.org | /type/Promise |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Results lost | Not awaiting promises | Use await or .result | | Race conditions | Shared mutable state | Use locks or atomics | | No speedup | I/O bound, not CPU | Check if parallelism helps |
Learning Milestones:
- Basic: Process files sequentially, then parallelize
- Intermediate: Measure and demonstrate speedup
- Advanced: Handle errors and display progress
Project 11: Reactive Web Scraper
- Main Programming Language: Raku
- Difficulty: Level 3: Advanced
- Knowledge Area: Concurrency / Reactive Programming
- Time Estimate: 6-8 hours
What you will build: A web scraper that uses Raku’s Supply (reactive stream) primitives to manage multiple concurrent downloads, process results as they arrive, and implement rate limiting.
Why it teaches Raku: Supplies are Raku’s reactive programming primitive—streams of values that can be transformed, combined, and consumed asynchronously. This project teaches you to think reactively rather than imperatively.
Core challenges you will face:
- Creating supplies maps to using
supply,emit, anddone - Transforming streams maps to using
.map,.grep,.batch - Rate limiting maps to controlling emission frequency
- Combining supplies maps to using
merge,zip,combine
Key Concepts:
- Supplies: docs.raku.org/type/Supply
- Taps: Subscribing to supply events
- Reactive Patterns: Event-driven programming
Prerequisites: Project 10 completed, basic HTTP knowledge.
Real World Outcome:
$ raku reactive-scraper.raku urls.txt --rate-limit=2
Reactive Web Scraper
====================
Rate limit: 2 requests/second
URLs to process: 20
[00:00] Starting scraper...
[00:01] Fetched: https://example.com/page1 (200 OK, 15.2KB)
[00:01] Fetched: https://example.com/page2 (200 OK, 12.8KB)
[00:02] Fetched: https://example.com/page3 (404 Not Found)
[00:02] Fetched: https://example.com/page4 (200 OK, 18.1KB)
...
[00:12] All URLs processed!
Summary:
Successful: 18
Failed: 2 (pages 3, 17)
Total data: 256.4KB
Average response time: 0.45s
Extracted data saved to: output.json
The Core Question You Are Answering: How do reactive streams simplify complex asynchronous workflows?
Concepts You Must Understand First:
- What is reactive programming?
- What is backpressure in streaming systems?
- How do HTTP requests work at a basic level?
Questions to Guide Your Design:
- How will you emit URLs into the supply?
- How will you implement rate limiting without blocking?
- How will you handle failed requests in the stream?
- How will you collect all results for the summary?
Thinking Exercise: Draw a data flow diagram showing: URL input -> rate limiter -> HTTP fetch -> parser -> output. What happens at each stage?
The Interview Questions They Will Ask:
- What is the difference between a Promise and a Supply?
- How do you subscribe to a Supply?
- Explain hot vs cold observables in Raku terms.
- How would you implement backpressure with Supplies?
- What is the
.sharemethod for on a Supply?
Hints in Layers:
- Hint 1:
supply { for @urls -> $url { emit $url } } - Hint 2: Use
Supply.intervalfor rate limiting - Hint 3:
.throttlecan limit events per second - Hint 4: Use Cro::HTTP::Client for HTTP requests
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Supplies | docs.raku.org | /type/Supply | | Concurrency | Think Raku | Ch. 16 | | HTTP | Cro documentation | /http-client |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Events not firing | Supply not tapped | Add .tap or react block | | Memory growth | Unbounded buffering | Add backpressure | | Rate limit ignored | Wrong interval setup | Check throttle parameters |
Learning Milestones:
- Basic: Create a supply and tap it
- Intermediate: Rate-limit and transform stream
- Advanced: Combine multiple supplies, handle errors
Project 12: Channel-Based Worker Pool
- Main Programming Language: Raku
- Difficulty: Level 3: Advanced
- Knowledge Area: Concurrency / Channels
- Time Estimate: 5-6 hours
What you will build: A worker pool implementation using Raku’s Channel primitive, demonstrating the producer-consumer pattern, work distribution, and graceful shutdown.
Why it teaches Raku: Channels are Raku’s thread-safe queues. This project teaches you the classic concurrency pattern of producers and consumers, and how to coordinate multiple workers processing a shared queue.
Core challenges you will face:
- Channel operations maps to using
.sendand.receive - Worker management maps to creating and coordinating worker threads
- Graceful shutdown maps to using
.closeand detecting termination - Load balancing maps to distributing work evenly
Key Concepts:
- Channels: docs.raku.org/type/Channel
- Producer-Consumer: Classic concurrency pattern
- Shutdown Coordination: Cleanly stopping workers
Prerequisites: Projects 10-11, understanding of threading concepts.
Real World Outcome:
$ raku worker-pool.raku --workers=4 --jobs=100
Worker Pool Demonstration
=========================
Workers: 4
Jobs: 100 (simulated processing tasks)
Starting workers...
Worker 1 started
Worker 2 started
Worker 3 started
Worker 4 started
Submitting jobs...
[Worker 2] Completed job 1 in 0.12s
[Worker 1] Completed job 2 in 0.15s
[Worker 4] Completed job 3 in 0.09s
[Worker 3] Completed job 4 in 0.18s
...
Progress: [========================================] 100/100
Shutting down workers...
Worker 1 shutting down (processed 27 jobs)
Worker 2 shutting down (processed 24 jobs)
Worker 3 shutting down (processed 25 jobs)
Worker 4 shutting down (processed 24 jobs)
Summary:
Total jobs: 100
Total time: 4.2s
Throughput: 23.8 jobs/sec
Average job time: 0.15s
The Core Question You Are Answering: How do channels enable safe communication between concurrent workers?
Concepts You Must Understand First:
- What is a thread-safe queue?
- What is the producer-consumer pattern?
- How do you signal workers to stop?
Questions to Guide Your Design:
- How will workers know when to stop?
- How will you track which worker processed which job?
- How will you handle a worker that crashes?
- How will you balance load across workers?
Thinking Exercise: Draw a diagram with one producer, one channel, and four consumers. Trace a job from submission to completion.
The Interview Questions They Will Ask:
- What happens when you
.receivefrom an empty Channel? - How do you signal workers to shut down?
- What is the difference between Channel and Supply?
- How would you implement a bounded channel (limited size)?
- How do you handle errors in worker threads?
Hints in Layers:
- Hint 1:
my $channel = Channel.new - Hint 2: Workers loop:
while (my $job = $channel.receive) { ... } - Hint 3: Use
$channel.closeto signal no more jobs - Hint 4: Use
CATCHto handle ChannelClosed exception
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Channels | docs.raku.org | /type/Channel | | Concurrency | Think Raku | Ch. 16 | | Patterns | General concurrency literature | N/A |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Workers hang | Channel not closed | Close when done adding jobs | | Lost jobs | Exception not caught | Add CATCH in worker loop | | Unfair distribution | Uneven job times | Randomize or priority queue |
Learning Milestones:
- Basic: Single producer, single consumer
- Intermediate: Multiple workers, fair distribution
- Advanced: Graceful shutdown, error handling
Project 13: Meta-Object Protocol Explorer
- Main Programming Language: Raku
- Difficulty: Level 4: Expert
- Knowledge Area: Meta-programming / Introspection
- Time Estimate: 6-8 hours
What you will build: A tool that demonstrates Raku’s Meta-Object Protocol (MOP), showing how to introspect classes, modify behavior at runtime, and create new types dynamically.
Why it teaches Raku: Raku’s MOP is exposed and usable by regular programmers. This project teaches you that classes are objects too, and you can manipulate them just like any other data.
Core challenges you will face:
- Introspection maps to using
.^methods,.^attributes, etc. - Runtime modification maps to adding methods dynamically
- Type creation maps to building classes at runtime
- Metamodel understanding maps to how Raku represents types
Key Concepts:
- Meta-Object Protocol: docs.raku.org/language/mop
- Introspection: Examining objects and types
- Metaprogramming: Modifying program structure at runtime
Prerequisites: Projects 3-5 completed, solid OO understanding.
Real World Outcome:
$ raku mop-explorer.raku
Meta-Object Protocol Explorer
=============================
=== Introspecting a Class ===
class Person:
Attributes:
- $!name (Str, private)
- $!age (Int, private)
- $.email (Str, public)
Methods:
- new (constructor)
- greet (custom)
- Str (coercion)
Roles:
- Printable
- Comparable
Parent classes:
- Any
- Mu
=== Runtime Method Addition ===
Before: Person.can("wave") = False
Adding "wave" method dynamically...
After: Person.can("wave") = True
$person.wave() -> "*waves hello*"
=== Dynamic Class Creation ===
Creating "Robot" class at runtime...
Adding attribute: $!id
Adding method: beep
Composing role: Movable
my $robot = Robot.new(id => "R2D2");
$robot.beep() -> "Beep boop!"
$robot.move(5, 10) -> Robot moved to (5, 10)
The Core Question You Are Answering: How does Raku expose its type system for manipulation by regular code?
Concepts You Must Understand First:
- What is reflection/introspection in programming?
- What is a metaclass?
- Why would you want to modify types at runtime?
Questions to Guide Your Design:
- What information can you extract from a class?
- How do you add a method to an existing class?
- What are the steps to create a class dynamically?
- What are the risks of runtime type modification?
Thinking Exercise: Think of a class you have written. List everything you might want to know about it at runtime: methods, attributes, parent classes, roles.
The Interview Questions They Will Ask:
- What does the
.^syntax mean in Raku? - How do you get a list of all methods on an object?
- Explain how to add a method to a class at runtime.
- What is the difference between
.WHATand.^name? - How would you implement a simple ORM using MOP?
Hints in Layers:
- Hint 1:
.^methodsreturns all methods,.^attributesfor attributes - Hint 2:
.^add_method('name', method { ... })adds methods - Hint 3:
Metamodel::ClassHOW.new_type(:name<MyClass>)creates classes - Hint 4:
.^composefinalizes a dynamically created type
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | MOP | docs.raku.org | /language/mop | | Metaprogramming | Think Raku | Ch. 14 | | Objects | docs.raku.org | /language/objects |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Method not visible | Not composed | Call .^compose after changes | | Wrong HOW | Using wrong metamodel | Check type kind | | Breaks later | Runtime changes conflict | Be careful with modifications |
Learning Milestones:
- Basic: Extract methods and attributes from classes
- Intermediate: Add methods to existing classes
- Advanced: Create complete classes at runtime
Project 14: Functional Programming Toolkit
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: Functional Programming
- Time Estimate: 4-5 hours
What you will build: A library of functional programming utilities demonstrating Raku’s functional features: higher-order functions, currying, function composition, lazy evaluation, and immutable data patterns.
Why it teaches Raku: Raku supports multiple paradigms, including functional. This project teaches you to think functionally in Raku, using features like Whatever-star, map, reduce, and lazy lists.
Core challenges you will face:
- Higher-order functions maps to functions that take/return functions
- Currying maps to partial application with
.assuming - Composition maps to combining functions with
oorandthen - Lazy evaluation maps to using lazy lists and gather/take
Key Concepts:
- Functional Programming: docs.raku.org/language/functions
- Whatever Star: docs.raku.org/type/Whatever
- Lazy Lists: docs.raku.org/language/list#Lazy_lists
Prerequisites: Projects 1-3 completed.
Real World Outcome:
$ raku fp-toolkit.raku
Functional Programming Toolkit
==============================
=== Higher-Order Functions ===
my @nums = 1, 2, 3, 4, 5;
@nums.map(* ** 2) -> (1, 4, 9, 16, 25)
@nums.grep(* %% 2) -> (2, 4)
@nums.reduce(* + *) -> 15
=== Currying with .assuming ===
sub add($a, $b) { $a + $b }
my &add5 = &add.assuming(5);
add5(3) -> 8
=== Function Composition ===
my &double = * * 2;
my &addOne = * + 1;
my &doubleThenAddOne = &double o &addOne; # Note: right to left!
doubleThenAddOne(5) -> 11 (5 -> 10 -> 11)
=== Lazy Evaluation ===
my @infinite = 1, 2, * + * ... *; # Infinite Fibonacci
@infinite.head(10) -> (1, 2, 3, 5, 8, 13, 21, 34, 55, 89)
=== Immutable Patterns ===
my @list = <a b c>;
my @new = |@list, 'd'; # Creates new list, original unchanged
@list -> (a, b, c)
@new -> (a, b, c, d)
The Core Question You Are Answering: How does Raku support functional programming alongside its other paradigms?
Concepts You Must Understand First:
- What is a higher-order function?
- What is function composition?
- What is lazy vs eager evaluation?
Questions to Guide Your Design:
- How does Whatever-star create anonymous functions?
- How do you partially apply arguments to a function?
- What direction does
o(composition) go? - When should you use lazy lists?
Thinking Exercise: Write out by hand how @list.map(* + 1).grep(* > 5) transforms (1, 5, 10) step by step.
The Interview Questions They Will Ask:
- Explain the Whatever-star
*in Raku. - How do you curry a function in Raku?
- What is the difference between
oandandthen? - How do infinite lists work in Raku?
- How would you implement
composemanually?
Hints in Layers:
- Hint 1:
* + 1becomes-> $x { $x + 1 } - Hint 2:
.assuming(value)creates a curried function - Hint 3:
f o gmeansf(g(x))—apply g first - Hint 4: Use
...for lazy sequences
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Functions | Think Raku | Ch. 6, 10 | | Lazy Lists | docs.raku.org | /language/list | | FP Concepts | Learning Perl 6 | Ch. 14 |
Common Pitfalls and Debugging:
| Problem | Cause | Fix |
|———|——-|—–|
| Wrong result | Composition direction | Remember: o is right-to-left |
| Memory explosion | Eagerly evaluated lazy | Keep lazy until needed |
| Type errors | Wrong Whatever usage | Check how * is interpreted |
Learning Milestones:
- Basic: Use map, grep, reduce effectively
- Intermediate: Create curried functions
- Advanced: Build pipelines with composition
Project 15: Perl 5 Interop Bridge
- Main Programming Language: Raku
- Difficulty: Level 3: Advanced
- Knowledge Area: Interoperability
- Time Estimate: 5-6 hours
What you will build: A project that demonstrates calling Perl 5 code from Raku using Inline::Perl5, enabling access to CPAN modules and gradual migration of Perl 5 codebases.
Why it teaches Raku: Raku’s ecosystem is smaller than CPAN. The ability to call Perl 5 opens up thousands of mature modules. This project teaches you to leverage existing Perl 5 investment while moving to Raku.
Core challenges you will face:
- Setting up Inline::Perl5 maps to installation and configuration
- Calling Perl 5 code maps to using the
usestatement with:from<Perl5> - Data marshalling maps to converting between Raku and Perl 5 types
- Module wrapping maps to creating Raku-friendly APIs around Perl 5 modules
Key Concepts:
- Inline::Perl5: The bridge module
- Data Conversion: How types map between languages
- Module Loading:
:from<Perl5>syntax
Prerequisites: Projects 1-3, some Perl 5 familiarity helpful.
Real World Outcome:
$ raku perl5-bridge.raku
Perl 5 Interoperability Demo
=============================
=== Loading Perl 5 Modules ===
Loading LWP::UserAgent from CPAN...
OK! LWP::UserAgent loaded.
Fetching https://example.com...
Response: 200 OK
Content length: 1256 bytes
=== Using DBI for Database Access ===
Connecting to SQLite via Perl 5 DBI...
Connected!
Query: SELECT * FROM users LIMIT 3
Results:
| id | name | email |
| 1 | Alice | alice@example.com |
| 2 | Bob | bob@example.com |
| 3 | Charlie | charlie@example.com|
=== Calling Custom Perl 5 Code ===
Perl 5 function: sub calculate { my ($a, $b) = @_; return $a ** $b; }
Calling from Raku: calculate(2, 10) = 1024
=== Data Conversion ===
Raku Array -> Perl 5 arrayref: [1, 2, 3]
Raku Hash -> Perl 5 hashref: {a => 1, b => 2}
Round-trip conversion: SUCCESS
The Core Question You Are Answering: How can you leverage the vast CPAN ecosystem while writing new code in Raku?
Concepts You Must Understand First:
- How do different languages handle FFI (Foreign Function Interface)?
- What are the differences between Perl 5 and Raku data types?
- Why is gradual migration valuable for large codebases?
Questions to Guide Your Design:
- Which Perl 5 modules would be most useful to access?
- How will you handle data type conversions?
- What wrapper API will make Perl 5 modules feel native?
- How will you handle errors from Perl 5 code?
Thinking Exercise: Think of a Perl 5 module you have used. Write pseudocode for how you would wrap it with a Raku-native API.
The Interview Questions They Will Ask:
- How do you install and configure Inline::Perl5?
- What is the syntax for loading a Perl 5 module in Raku?
- How are data types converted between Perl 5 and Raku?
- What are the performance implications of using Inline::Perl5?
- How would you structure a gradual migration from Perl 5 to Raku?
Hints in Layers:
- Hint 1:
zef install Inline::Perl5(requires Perl 5 dev headers) - Hint 2:
use LWP::UserAgent:from<Perl5>; - Hint 3: Most scalar types convert automatically
- Hint 4: Use
.perlor.gistto see converted data structures
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Inline::Perl5 | docs.raku.org | /language/5to6-nutshell | | Perl 5 Modules | CPAN | Module documentation | | Migration | Think Raku | Appendix |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Install fails | Missing Perl 5 dev | Install perl-devel | | Module not found | CPAN path wrong | Check Perl 5 @INC | | Data garbled | Wrong conversion | Check type handling |
Learning Milestones:
- Basic: Load and call a simple Perl 5 module
- Intermediate: Use DBI to access a database
- Advanced: Create a Raku wrapper around Perl 5 module
Project 16: Command-Line Application Framework
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: CLI Development
- Time Estimate: 4-5 hours
What you will build: A reusable command-line application framework that handles argument parsing, subcommands, help generation, configuration files, and colored output.
Why it teaches Raku: Raku has excellent support for CLI development through MAIN subroutine magic. This project teaches you to build professional command-line tools with minimal boilerplate.
Core challenges you will face:
- Argument parsing maps to MAIN signature introspection
- Subcommands maps to multi MAIN dispatch
- Help generation maps to Pod and automatic usage
- Configuration maps to file parsing and environment variables
Key Concepts:
- MAIN Subroutine: docs.raku.org/language/create-cli
- Pod Documentation: docs.raku.org/language/pod
- Terminal Formatting: Color and styling
Prerequisites: Projects 1-3 completed.
Real World Outcome:
$ raku mytool.raku --help
mytool - A demonstration CLI framework
USAGE:
mytool <command> [options]
COMMANDS:
init Initialize a new project
build Build the project
test Run tests
deploy Deploy to production
OPTIONS:
--config=<file> Configuration file (default: .mytool.yml)
--verbose Enable verbose output
--help Show this help message
$ raku mytool.raku init --name=myproject
Initializing project: myproject
Creating directory structure...
Creating configuration file...
Done!
$ raku mytool.raku build --verbose
Building project...
[1/5] Compiling source files...
[2/5] Running preprocessor...
[3/5] Linking dependencies...
[4/5] Optimizing output...
[5/5] Generating artifacts...
Build complete! (1.2s)
The Core Question You Are Answering: How does Raku make CLI development more elegant than other approaches?
Concepts You Must Understand First:
- How do traditional argument parsers work (getopt, etc.)?
- What makes a good command-line interface?
- How do subcommands work (like git commit, docker run)?
Questions to Guide Your Design:
- How will MAIN signatures define your interface?
- How will you implement subcommands?
- What configuration sources will you support?
- How will you generate help text automatically?
Thinking Exercise: Design the CLI for a tool you wish existed. Write out the MAIN signatures for each subcommand.
The Interview Questions They Will Ask:
- How does Raku’s MAIN subroutine work?
- How do you define required vs optional parameters?
- How do you implement subcommands with multi MAIN?
- How does Raku generate usage messages automatically?
- How would you add shell completion to your CLI?
Hints in Layers:
- Hint 1:
sub MAIN($arg, :$optional) { }defines the interface - Hint 2: Use
multi MAIN('command', ...)for subcommands - Hint 3:
$*OUT.tchecks if output is a terminal (for colors) - Hint 4: Pod comments before MAIN become help text
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | CLI | docs.raku.org | /language/create-cli | | Pod | docs.raku.org | /language/pod | | IO | Think Raku | Ch. 8 |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | No usage shown | MAIN failed | Check signature match | | Colors garbled | Not a terminal | Check .t before colors | | Config not found | Wrong path | Use absolute path |
Learning Milestones:
- Basic: Single MAIN with arguments and options
- Intermediate: Subcommands with multi MAIN
- Advanced: Config files, colored output, help generation
Project 17: Database Access Layer
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: Database / Persistence
- Time Estimate: 5-6 hours
What you will build: A database access layer using Raku’s DB::* modules, demonstrating connections, queries, prepared statements, transactions, and a simple ORM-like pattern.
Why it teaches Raku: Database access is essential for real applications. This project teaches you to work with relational databases in Raku using native modules rather than Perl 5 interop.
Core challenges you will face:
- Connection management maps to DB::SQLite or DB::Pg setup
- Query execution maps to
.queryand result handling - Prepared statements maps to parameterized queries
- Transactions maps to
.begin,.commit,.rollback
Key Concepts:
- DBIish: docs.raku.org (search DBIish)
- Prepared Statements: Safe query parameterization
- Transactions: ACID properties
Prerequisites: Projects 1-3, basic SQL knowledge.
Real World Outcome:
$ raku database-layer.raku
Database Access Layer Demo
==========================
=== Connection ===
Connecting to SQLite database: demo.db
Connected!
=== Table Creation ===
Creating users table...
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)
Table created!
=== Insert Operations ===
Inserting users with prepared statement...
Inserted: Alice (alice@example.com)
Inserted: Bob (bob@example.com)
Inserted: Charlie (charlie@example.com)
=== Query Operations ===
All users:
| id | name | email |
| 1 | Alice | alice@example.com |
| 2 | Bob | bob@example.com |
| 3 | Charlie | charlie@example.com |
=== Transaction Demo ===
Starting transaction...
Updating Alice's email...
Updating Bob's email...
Transaction committed!
=== ORM-like Pattern ===
my $user = User.find(1);
$user.name -> "Alice"
$user.email -> "alice_new@example.com"
$user.save(); -> Updated in database
The Core Question You Are Answering: How do you build a robust database layer in Raku?
Concepts You Must Understand First:
- What is SQL and relational database basics?
- What is SQL injection and how do prepared statements prevent it?
- What are ACID properties and why do transactions matter?
Questions to Guide Your Design:
- Which database engine will you support (SQLite, PostgreSQL)?
- How will you handle connection pooling?
- How will you build an ORM-like API?
- How will you handle database errors?
Thinking Exercise: Design a simple User class with database backing. What methods would it need? How would you implement .find, .save, .delete?
The Interview Questions They Will Ask:
- How do you prevent SQL injection in Raku?
- How do you handle database transactions?
- What is the difference between DBIish and DB::*?
- How would you implement connection pooling?
- How do you handle database migration?
Hints in Layers:
- Hint 1:
zef install DBIishorzef install DB::SQLite - Hint 2: Use
$db.query('SELECT * FROM users WHERE id = ?', 1) - Hint 3: Wrap multiple operations in
$db.begin/$db.commit - Hint 4: Build objects from hash results
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Databases | docs.raku.org | Module documentation | | SQL | Any SQL primer | Basics | | ORM patterns | General ORM literature | Patterns |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Module not found | Not installed | zef install DB::SQLite | | SQL error | Syntax issue | Check SQL string | | Data not committed | No commit | Add .commit after changes |
Learning Milestones:
- Basic: Connect, create tables, insert data
- Intermediate: Prepared statements, transactions
- Advanced: ORM-like API with model classes
Project 18: Web Application with Cro
- Main Programming Language: Raku
- Difficulty: Level 3: Advanced
- Knowledge Area: Web Development
- Time Estimate: 6-8 hours
What you will build: A web application using Cro, Raku’s modern async web framework. You will build a RESTful API with routing, templates, middleware, and WebSocket support.
Why it teaches Raku: Cro is built on Raku’s async/reactive primitives, making it a natural fit for modern web development. This project teaches you to build production-grade web services in Raku.
Core challenges you will face:
- Routing maps to Cro::HTTP::Router
- Templates maps to Cro::WebApp::Template
- Middleware maps to request/response transformations
- WebSockets maps to Cro::HTTP::Router websocket support
Key Concepts:
- Cro Framework: cro.services documentation
- Async HTTP: Non-blocking request handling
- Reactive Streams: Using supplies in web context
Prerequisites: Projects 10-11, basic web development knowledge.
Real World Outcome:
$ raku cro-app.raku
Starting Cro web application on http://localhost:8080
$ curl http://localhost:8080/api/users
{
"users": [
{"id": 1, "name": "Alice", "email": "alice@example.com"},
{"id": 2, "name": "Bob", "email": "bob@example.com"}
]
}
$ curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name": "Charlie", "email": "charlie@example.com"}'
{
"id": 3,
"name": "Charlie",
"email": "charlie@example.com",
"created": "2025-01-01T12:00:00Z"
}
# Browser at http://localhost:8080
# Shows rendered HTML template with user list
The Core Question You Are Answering: How does Raku’s async nature benefit web application development?
Concepts You Must Understand First:
- What is HTTP and REST?
- What is async/non-blocking I/O?
- What is middleware in web frameworks?
Questions to Guide Your Design:
- How will you structure your routes?
- What data format will your API use?
- How will you handle authentication?
- How will you integrate with your database layer?
Thinking Exercise: Design the routes for a simple blog API: list posts, get post, create post, update post, delete post.
The Interview Questions They Will Ask:
- How does Cro handle concurrent requests?
- How do you define routes in Cro?
- How does Cro’s template system work?
- How do you add middleware to a Cro application?
- How does Cro handle WebSockets?
Hints in Layers:
- Hint 1:
zef install croinstalls the framework - Hint 2:
get -> 'api', 'users' { ... }defines routes - Hint 3: Use
content 'application/json', $datafor JSON responses - Hint 4:
cro stubgenerates starter project
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Cro | cro.services | Documentation | | HTTP | MDN Web Docs | HTTP reference | | REST | RESTful Web APIs | Patterns |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Port in use | Previous instance running | Kill old process | | Route not found | Wrong path syntax | Check route definition | | Template error | Syntax issue | Check template tags |
Learning Milestones:
- Basic: Serve static pages and simple routes
- Intermediate: RESTful API with CRUD operations
- Advanced: Templates, middleware, WebSockets
Project 19: Module Development and Publishing
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: Package Management
- Time Estimate: 4-5 hours
What you will build: A distributable Raku module with proper structure, documentation, testing, and publish it to the Raku ecosystem (or prepare for publishing).
Why it teaches Raku: Creating reusable modules is essential for building and sharing code. This project teaches you the conventions, tooling, and best practices for Raku module development.
Core challenges you will face:
- Module structure maps to lib/, t/, META6.json
- Documentation maps to Pod6 format
- Testing maps to Test module and t/ directory
- Publishing maps to zef ecosystem or fez
Key Concepts:
- Module Structure: Standard directory layout
- META6.json: Module metadata
- Pod Documentation: In-source documentation
Prerequisites: Projects 1-5 completed.
Real World Outcome:
$ tree My-Utils/
My-Utils/
|-- lib/
| `-- My/
| |-- Utils.rakumod
| `-- Utils/
| |-- Text.rakumod
| `-- Math.rakumod
|-- t/
| |-- 00-meta.rakutest
| |-- 01-basic.rakutest
| `-- 02-text.rakutest
|-- META6.json
|-- README.md
`-- Changes
$ cd My-Utils && zef test .
Testing: My-Utils
t/00-meta.rakutest ... ok
t/01-basic.rakutest ... ok
t/02-text.rakutest ... ok
All tests passed!
$ raku -I lib -e 'use My::Utils; say double(21)'
42
$ zef --dry-run upload .
Would upload:
Module: My-Utils
Version: 0.1.0
Files: lib/My/Utils.rakumod, lib/My/Utils/Text.rakumod, ...
The Core Question You Are Answering: How do you create professional, reusable Raku modules?
Concepts You Must Understand First:
- What makes a good module API?
- How does module loading work in Raku?
- What is semantic versioning?
Questions to Guide Your Design:
- What functionality will your module provide?
- How will you organize sub-modules?
- What test coverage is appropriate?
- How will you document public APIs?
Thinking Exercise: Think of a utility you have written multiple times. Design it as a proper module with clear API, documentation, and tests.
The Interview Questions They Will Ask:
- What is the structure of a Raku module?
- What is META6.json and what does it contain?
- How does Raku’s module loading work?
- How do you write tests for Raku modules?
- How do you publish a module to the ecosystem?
Hints in Layers:
- Hint 1: Use
mi6 new My::Moduleto generate scaffold - Hint 2: Document with
#| Doc commentbefore items - Hint 3: Use
is exportto make routines available - Hint 4: Run
prove6 -l t/to run tests
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Modules | docs.raku.org | /language/modules | | Testing | docs.raku.org | /language/testing | | Pod | docs.raku.org | /language/pod |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Module not found | Wrong path | Check lib/ structure | | Export not working | Missing is export | Add trait | | Tests fail | Test syntax | Check Test module usage |
Learning Milestones:
- Basic: Create module structure, basic exports
- Intermediate: Tests pass, documentation present
- Advanced: Ready for ecosystem publishing
Project 20: Testing and Documentation Framework
- Main Programming Language: Raku
- Difficulty: Level 2: Intermediate
- Knowledge Area: Testing / Documentation
- Time Estimate: 4-5 hours
What you will build: A comprehensive test suite demonstrating Raku’s testing capabilities, including unit tests, integration tests, mocking, and generated documentation from Pod.
Why it teaches Raku: Testing is essential for reliable software. This project teaches you Raku’s built-in testing facilities and documentation system, which are more integrated than in most languages.
Core challenges you will face:
- Test organization maps to Test module and t/ files
- Assertions maps to is, ok, nok, dies-ok, etc.
- Mocking maps to Test::Mock or similar
- Documentation maps to Pod6 and extraction
Key Concepts:
- Test Module: Built-in testing
- Pod6: Documentation format
- Test Organization: Conventions and best practices
Prerequisites: Projects 3-5 completed.
Real World Outcome:
$ prove6 -l t/
t/01-unit.rakutest ....... ok
t/02-integration.rakutest . ok
t/03-mocking.rakutest .... ok
All tests successful.
Files=3, Tests=45, 2.5 wallclock secs
$ raku --doc lib/MyModule.rakumod
NAME
MyModule - A demonstration module
SYNOPSIS
use MyModule;
my $result = calculate(5, 10);
say $result; # Output: 15
DESCRIPTION
This module provides mathematical utilities...
METHODS
sub calculate($a, $b --> Int)
Calculates the sum of two numbers.
sub advanced-calc($x --> Num)
Performs advanced calculations...
$ raku --doc=HTML lib/MyModule.rakumod > docs/api.html
Generated: docs/api.html
The Core Question You Are Answering: How do you write comprehensive tests and documentation in Raku?
Concepts You Must Understand First:
- What is unit testing vs integration testing?
- Why is test coverage important?
- How does documentation generation work?
Questions to Guide Your Design:
- What testing patterns will you demonstrate?
- How will you organize tests by category?
- What mocking scenarios are useful?
- How will you document public APIs?
Thinking Exercise: For a function you have written, list: (1) happy path tests, (2) edge cases, (3) error conditions. How many tests total?
The Interview Questions They Will Ask:
- How does Raku’s Test module work?
- What test assertions are available?
- How do you test for expected exceptions?
- How does Pod6 documentation work?
- How do you generate HTML documentation?
Hints in Layers:
- Hint 1:
use Test; plan 5; is $a, $b, "description"; - Hint 2:
dies-ok { code-that-throws }, "should die"; - Hint 3: Use
#|before items for Pod documentation - Hint 4:
raku --doc=Markdown file.rakugenerates docs
Books That Will Help: | Topic | Book | Chapter | |——-|——|———| | Testing | docs.raku.org | /language/testing | | Pod | docs.raku.org | /language/pod | | Test Patterns | Test-Driven Development literature | General |
Common Pitfalls and Debugging: | Problem | Cause | Fix | |———|——-|—–| | Wrong test count | plan N mismatch | Update plan or use done-testing | | Test hangs | Infinite loop in code | Add timeout | | Pod not extracted | Wrong syntax | Check Pod format |
Learning Milestones:
- Basic: Write and run simple tests
- Intermediate: Test edge cases, exceptions
- Advanced: Mocking, comprehensive documentation
Project Comparison Table
| Project | Difficulty | Time | Key Concepts | Practical Value |
|---|---|---|---|---|
| 1. Hello Raku Explorer | Beginner | 2-3h | Sigils, operators, I/O | Foundation |
| 2. Text Statistics Analyzer | Beginner | 3-4h | File I/O, hashes | High |
| 3. OO Address Book | Intermediate | 4-5h | Classes, attributes | High |
| 4. Roles and Composition | Intermediate | 4-5h | Roles, composition | High |
| 5. Gradual Typing Lab | Intermediate | 3-4h | Types, multi dispatch | Medium |
| 6. Regex Evolution | Intermediate | 4-5h | Raku regexes | High |
| 7. Grammar Parser | Advanced | 6-8h | Grammars, actions | Very High |
| 8. Unicode Processor | Intermediate | 4-5h | Unicode, graphemes | High |
| 9. JSON Parser Grammar | Advanced | 6-8h | Recursive grammars | Very High |
| 10. Concurrent File Processor | Advanced | 5-6h | Promises, async | High |
| 11. Reactive Web Scraper | Advanced | 6-8h | Supplies, reactive | High |
| 12. Channel Worker Pool | Advanced | 5-6h | Channels, producer-consumer | High |
| 13. MOP Explorer | Expert | 6-8h | Metaprogramming | Medium |
| 14. Functional Toolkit | Intermediate | 4-5h | FP patterns | High |
| 15. Perl 5 Interop | Advanced | 5-6h | CPAN access, migration | High |
| 16. CLI Framework | Intermediate | 4-5h | MAIN, subcommands | Very High |
| 17. Database Layer | Intermediate | 5-6h | DBIish, SQL | Very High |
| 18. Cro Web App | Advanced | 6-8h | Web development | Very High |
| 19. Module Development | Intermediate | 4-5h | Packaging, publishing | High |
| 20. Testing Framework | Intermediate | 4-5h | Testing, documentation | Very High |
Summary
This learning path takes you from Raku basics to advanced metaprogramming and web development. The key progression is:
- Foundation (Projects 1-3): Learn syntax, text processing, and OO basics
- Intermediate (Projects 4-8): Master roles, typing, regexes, and Unicode
- Advanced Parsing (Projects 7, 9): Unlock Raku’s grammar superpower
- Concurrency (Projects 10-12): Learn promises, supplies, and channels
- Expert Topics (Projects 13-20): MOP, FP, interop, web, and ecosystem
Expected Outcomes
After completing all projects, you will be able to:
- Write idiomatic Raku code that leverages unique language features
- Build parsers for any data format using grammars
- Create concurrent applications with proper synchronization
- Develop web services using the Cro framework
- Access CPAN through Perl 5 interoperability
- Publish reusable modules to the Raku ecosystem
Recommended Book Sequence
- Think Raku by Laurent Rosenfeld (free, covers basics to intermediate)
- Learning Perl 6 by brian d foy (practical introduction)
- Parsing with Perl 6 Regexes and Grammars by Moritz Lenz (grammars deep dive)
- docs.raku.org (official reference for all topics)
Next Steps
- Join the Raku community: #raku on IRC/Matrix
- Browse the module ecosystem: raku.land
- Contribute to open source Raku projects
- Consider migrating a Perl 5 project as practice
References and Resources
Official Resources
- Official Documentation: https://docs.raku.org
- Raku Guide: https://raku.guide
- Raku.land (Module Ecosystem): https://raku.land
Books
- Think Raku by Laurent Rosenfeld (free online)
- Learning Perl 6 by brian d foy (O’Reilly)
- Parsing with Perl 6 Regexes and Grammars by Moritz Lenz
Community
- IRC/Matrix: #raku on libera.chat or Matrix
- Reddit: r/rakulang
- Weekly Newsletter: Raku Weekly
Tools
- Rakudo: Main Raku implementation
- Zef: Module installer
- Cro: Web framework (cro.services)
- Comma IDE: JetBrains-based Raku IDE
Last updated: 2025-01-01 Projects: 20 | Estimated total time: 90-120 hours | Skill progression: Beginner to Expert