samples/iyi/basics.iyi
The first half hour — what a person writes before they write anything real.
# The first half hour — what a person writes before they write anything real. # # ./bin/iyi run samples/iyi/basics.iyi # # The other samples each document a rule. This one documents nothing: it is # here because the prelude grows only when a program in this repository needs # something (SPEC.md 0.1.0 item 3), and a person meeting the language writes # these six programs before they write a module. Every method this file calls # is one somebody reached for in their first half hour and did not find. module samples/basics # 1. Counting, with a range rather than a `while`. total = 0 (1..10).each { |i| total = total + i } puts total # => 55 # 2. FizzBuzz, because it is the first thing anybody types. (1..15).each do |i| if i % 15 == 0 puts "FizzBuzz" elsif i % 3 == 0 puts "Fizz" elsif i % 5 == 0 puts "Buzz" else puts i end end # 3. Picking things out of a list. numbers = [3, 1, 4, 1, 5, 9, 2, 6] puts numbers.first # => 3 puts numbers.select { |n| n > 3 }.join(",") # => 4,5,9,6 puts numbers.includes?(9) # => true puts numbers.sorted.join(",") # => 1,1,2,3,4,5,6,9 puts numbers.join(",") # => 3,1,4,1,5,9,2,6, untouched # The pair. `sorted` hands back a copy and `sort_in_place` changes the array, # and the second one is spelled out on purpose: Crystal calls the copy `sort` # and the mutating one `sort!`, a name that cannot be written here, so a plain # `sort` would mean one thing in this library and the opposite in Crystal's # (SPEC.md III.1.7a). numbers.sort_in_place { |a, b| a < b ? -1 : (a == b ? 0 : 1) } puts numbers.join(",") # => 1,1,2,3,4,5,6,9 # 4. Adding them up two ways. puts numbers.sum # => 31 puts numbers.reduce(0) { |a, b| a + b } # => 31 # 5. Text. greeting = "Hello, World" puts greeting.downcase # => hello, world puts greeting.includes?("World") # => true puts greeting.size # => 12 # A character is a byte here, and its code is a number to do arithmetic on: # the Caesar shift every second program is. shifted = "" greeting.each_char do |c| if c.letter? base = c >= 'a' ? 'a'.ord : 'A'.ord shifted = shifted + ((c.ord - base + 3) % 26 + base).chr.to_s else shifted = shifted + c.to_s end end puts shifted # => Khoor, Zruog # 6. Counting words, which is where a dictionary earns its place. counts = {} of String => Int32 ["a", "b", "a", "c", "a"].each do |word| counts[word] = (counts[word]? || 0) + 1 end puts counts["a"] # => 3 puts counts.size # => 3 puts counts # => {"a" => 3, "b" => 1, "c" => 1}, in the order they went in # 7. The second half hour: the same count over real text, and the five most # frequent words in order. Splitting text into words is a walk over its # characters, a dictionary's pairs go into an array to be sorted, and the # sort takes a key rather than a comparison. text = "the cat sat on the mat; the mat sat under the cat. THE END" word = "" words = [] of String text.each_char do |c| if c.alphanumeric? word = word + c.to_s elsif !word.empty? words << word.downcase word = "" end end words << word.downcase unless word.empty? puts words.size # => 14 frequency = {} of String => Int32 words.each { |w| frequency[w] = (frequency[w]? || 0) + 1 } pairs = [] of Tuple(String, Int32) frequency.each { |w, n| pairs << {w, n} } pairs.sort_in_place_by { |pair| -pair[1] } pairs.first(3).each { |pair| puts "#{pair[0].ljust(5)} #{pair[1]}" } # => the 5 # => cat 2 # => sat 2 puts pairs.sorted_by { |pair| pair[0] }.first(2).map { |pair| pair[0] } # => ["cat", "end"]
Press Run.
The pane no longer holds samples/iyi/basics.iyi. Run executes iyi-basics.wasm, the module the compiler built from the recorded file, so your edit is not in this run: there is no iyi compiler in this page. How this works
recorded with iyi 0.18.0 (built on Crystal 1.22.0-dev [2a9653052] (2026-10-18)) · Linux 7.0.0-38-generic x86_64, QEMU Virtual CPU version 2.5+ · 2026-10-19
You can type in the pane: nothing here compiles, so what you type cannot run, and the page says which bytes it is running the moment the text stops being the recorded file. There is no standard input, no filesystem and no threads on this target, and one sample fails on purpose for exactly that reason.
Run executes iyi-basics.wasm, the module the compiler built from this file, in your browser. How this works
Try it on your machine
Copy the program into basics.iyi, change something, and run it. Only a compiler on your own machine can run what you wrote.
$ iyi run basics.iyi