This repository has been archived by the owner on Nov 11, 2019. It is now read-only.
Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Chapter 1 rough draft
- Loading branch information
1 parent
28f9c6e
commit cb01f47288fe7424fb6bff25ceaa6284443e5c3f
Showing
3 changed files
with
110 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,29 @@ | ||
| The Orkestrix Manual | ||
| ******************** | ||
|
|
||
| This is just one example document repeated over and over to test inclusion of multiple chapters into a single PDF or HTML output. | ||
| Rust for Rubyists | ||
| ***************** | ||
|
|
||
| Nobody should only learn one programming language. Before Ruby, I wrote things | ||
| in C, C++, Java, Perl, PHP, and all sorts of things. I've always said that | ||
| I love Ruby, but maybe someday, something would come along that'd be better for | ||
| what I was building. | ||
|
|
||
| I'm not sure if Rust is that language yet, but it is damn interesting. One of | ||
| the worst things about Rust is that there's next to no documentation, though. | ||
| So, I decided that as I figured things out, I'd write them out so that you | ||
| don't have to suffer the way I did. Maybe 'suffer' is too strong a word; Rust | ||
| is worth the hassle, though. | ||
|
|
||
| In this book, we'll talk about why you should care about Rust, how to get up | ||
| and running, the basics of writing software in Rust, and maybe even something | ||
| like building a Ruby gem with Rust. | ||
|
|
||
| NOTE: While this book is called "Rust for Rubyists," it should be accessible | ||
| to anyone who knows about OOP and programming in a dynamically typed language. | ||
| I will make analogies that will make the most sense to Rubyists, but you can | ||
| still get a lot out of this book if you are a programmer of a different sort. | ||
| If your favorite language is static, then you're already ahead of the game. | ||
| You can just disregard a lot of the analogies. | ||
|
|
||
| .. contents:: | ||
|
|
||
| {% include "book/chapter-01.rst" %} | ||
|
|
||
| {% include "book/chapter-01.rst" %} | ||
|
|
||
| {% include "book/chapter-01.rst" %} | ||
|
|
||
| {% include "book/chapter-01.rst" %} | ||
|
|
||
| {% include "book/chapter-01.rst" %} | ||
|
|
||
| {% include "book/chapter-01.rst" %} | ||
|
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,74 +1,113 @@ | ||
| {% import 'macros/ork.jinja' as ork with context %} | ||
|
|
||
| Jazz Pentatonics Example | ||
| ======================== | ||
| Why care about Rust? | ||
| ==================== | ||
|
|
||
| There are two basic pentatonics you can play for Jazz. One is based on the | ||
| Major Scale, the other is based on the Mixolydian mode. If I write | ||
| these out in the key of C they are: | ||
| You already write software in Ruby. It pays your bills. You enjoy it. Why | ||
| should you care about Rust? | ||
|
|
||
| .. image:: examples/jazz_pents.{{ ork.image_ext }} | ||
| > A programming language that doesn't teach you something isn't worth learning. | ||
| > | ||
| > - Someone | ||
|
|
||
| These two pentatonics, when shifted make up all the main arpeggios with common | ||
| additional notes, but without any of the avoid notes like the 4th and the 7th. | ||
| Let's think about Ruby for a minute: what's its biggest weakness? For me, it's | ||
| these things: | ||
|
|
||
| The Scales | ||
| ---------- | ||
| - Concurrency | ||
| - Concurrency | ||
| - Safety guarantees | ||
| - Lots of mutable state | ||
| - Only vaguely functional | ||
| - Speed | ||
| - Complexity. (Smalltalks' semantics fit on an index card) | ||
| - Documentation | ||
| - nil | ||
|
|
||
| To print out the notes in these pentatonics for all keys, I use this code: | ||
| What's awesome about Ruby? | ||
|
|
||
| {{ ork.code("examples/scale_notes.py|idio") }} | ||
| - Blocks | ||
| - Blocks | ||
| - Vaguely functional | ||
| - Syntax is pretty easy | ||
| - Focus on developer happiness | ||
| - Get up and running quickly | ||
| - Dynamically typed | ||
|
|
||
| With just these two versions of the scale I can then play over chords | ||
| in various ways. | ||
| So we could learn a lot from a language that handles concurrency well, has good | ||
| safety guarantees, is immutable by default, and is fast and simple. We don't | ||
| want to sacrifice anonymous functions, pretty syntax, or not making | ||
| `AbstractFactoryFactoryImpls` just to get work done. | ||
|
|
||
| The Chords | ||
| ---------- | ||
| I think that that language is Rust. | ||
|
|
||
| To analyze all the most useful permutations I have a script that goes through | ||
| every chord I need and then tries all the pentatonics to see if any match the | ||
| same notes in the chords. | ||
| Now: Rust is not perfect, by far. Its documentation is poor. It is certainly | ||
| _very_ complex. Fighting with a compiler can be frustrating. But the point is | ||
| to _learn_. And using a language that's very familliar, yet very different, can | ||
| teach us a lot. | ||
|
|
||
| First I setup a bunch of sets for the notes that are in the kinds of | ||
| chords I like to play: | ||
| Here's "Hello World" in Rust: | ||
|
|
||
| {{ ork.codes("examples/chord_analysis.py|idio", "chords") }} | ||
| ``` | ||
| fn main() { | ||
| io::println("hello?"); | ||
| } | ||
| ``` | ||
|
|
||
| Notice how I'm importing the ``scale_notes`` module that I just showed | ||
| you. | ||
| Here's a parallell "Hello World" in Rust: | ||
|
|
||
| I then have an ``analyze_scales_chords`` function which goes through | ||
| all the permutations of chords and the notes from the ``scale_notes`` | ||
| module to find all the possible matches. | ||
| ``` | ||
| use task::spawn; | ||
|
|
||
| {{ ork.codes("examples/chord_analysis.py|idio", "analyze") }} | ||
| fn main() { | ||
|
|
||
| A match is simply any pentatonic that has the same notes as might be | ||
| found in that kind of chord. | ||
| for 10.times { | ||
| do spawn { | ||
| let greeting_message = "Hello?"; | ||
| io::println(greeting_message); | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Once I have that I then need to reduce it to something I can print out: | ||
| Here's a rough port to Ruby: | ||
|
|
||
| {{ ork.codes("examples/chord_analysis.py|idio", "reduce") }} | ||
| ``` | ||
| 10.times do | ||
| Thread.new do | ||
| greeting_message = "Hello?" | ||
| puts greeting_message | ||
| end | ||
| end | ||
| ``` | ||
|
|
||
| And finally I just run it twice. Once to get all the fits for the | ||
| Dominant Scales (Jazz Pentatonics), and once again for the Major Scales | ||
| (Blues Pentatonics): | ||
| That's it. Note the stuff that's *similar* to Ruby: | ||
|
|
||
| {{ ork.codes("examples/chord_analysis.py|idio", "final") }} | ||
| - Variables are in `snake_case` | ||
| - We have 'blocks' that use `{}`. No `do/end` though. | ||
| - Variables, while statically typed, have inference, so we don't need to declare types | ||
|
|
||
| The Results | ||
| ----------- | ||
|
|
||
| Here's the results:: | ||
| Here's some stuff that's _different_: | ||
|
|
||
| {{ d["examples/chord_analysis.py|py"].as_text()|indent(4, false) }} | ||
| - `;` s everywhere. You don't always need them, but let's put them in for now. | ||
| - slightly different syntax, `fn` rather than `def`. | ||
| - Because we have no `do/end`, we use `{}` s instead. | ||
| - The compiler will yell at us harder if we mess up. | ||
|
|
||
| Here's some examples of these scales for different chords using ABC notation:: | ||
| Oh, and: | ||
|
|
||
| {{ d["examples/jazz_pents_example.abc|ss"]|indent(4, false) }} | ||
|
|
||
| And finally what that looks like rendered into SVG: | ||
|
|
||
| .. image:: examples/jazz_pents_example.{{ ork.image_ext }} | ||
| ``` | ||
| $ time ./hello | ||
| ./hello 0.01s user 0.01s system 91% cpu 0.014 total | ||
|
|
||
| $ time ruby hello.rb | ||
| ruby hello.rb 0.02s user 0.01s system 95% cpu 0.026 total | ||
| ``` | ||
|
|
||
| Twice as fast. Yay irrelevant microbenchmarks! | ||
|
|
||
| Anyway, I hope you get my point: There's lots of things about Rust that make | ||
| it syntactically vaguely similar enough to Ruby that you can feel at home, at | ||
| least at first. And its strengths are some of Rubys' greatest weaknesses. | ||
| That's why I think you can learn a lot from playing with Rust, even if you | ||
| don't do it as your day job. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters