Since it seems that he used Ruby throughout the book, I wonder if that's the right choice or it will limit the book's audience.
I'm contemplating writing a long "from scratch" style book on another topic and I'm still not sure which language I should use. Using more than one (Java, Python,...) and generating multiple flavours of the book could be a good idea I think.
According to the author, readers of the book are already translating the port of Git in the book to C++, Clojure, Elixir, Haskell, Java, Node, Rust, and Swift
Using more than one (Java, Python,...) and generating multiple flavours of the book could be a good idea I think.
I used to think so too, but tbh I think this will result in either a lot more work than you would like, or your audience are going to end up with one language that is being used ideomatically and the rest of the languages are not being used ideomatically.
Yeah that's pretty much the case with Modern Compiler Implementation in {ML, Java, C} by Appel. The Java and C ones are basically transliterated ML and not everyone appreciates that.
On the one hand, people do buy the Java and C books. On the other hand, I think they eventually realize it's probably easier to learn an ML dialect and learn the "real" code.
This may or may not apply to the git book though, since doing it in Ruby is already not "idiomatic".
I've been working through this book over the past few days, and writing my own git implementation in Rust in parallel, and I've found Ruby to be much simpler from an implementation standpoint. Ruby's standard library provides a lot of useful functionality out of the box (SHA1 digests, the deflate algorithm) which I've had to pull in dependencies for in my Rust version.
Obviously the Rust version is significantly faster, but the Ruby version is higher level and better expresses the concepts the book is trying to demonstrate without getting too bogged down in syntax, types, etc.
I don't really think the choice of language matters that much.
I don't know Ruby at all but I have read through part of the book and can follow the examples pretty easily. Plus, I think I'll get more out of the book if I just use his examples as guidelines and have to do some mental work to translate them into the language I'm using.
Far from it. Ruby blocks aren't really lambdas or anonymous functions. For example when you use return inside a block, it's not just the code in the block is being returned, but the whole enclosing function. And, you don't really "call" a block but yield to it. It's not even an object that you can inspect. It's syntax. It's really a new kind of control structure. Ruby blocks have few equivalents in other languages.
def f(&block)
block.class
end
f { } # => Proc
f(&-> { }) # => Proc
f(&lambda { }) # => Proc
f(&:something) # => Proc
lambda { }.class # => Proc (I think you get the idea)
method(:f).class # => Method
lambda { |i| i + 1 }.call(10) # => 11
you don't typically return in a block, there is implicit return. you would do "next" or "break" depending on what you want to achieve. as far as I know that's the main difference between procs and methods.
(not that anybody would do what I do, most people just use blocks, some people use yield, few people use the &block argument, but that's exactly the same)
Sound a lot like inlined lambdas in Kotlin. Lambdas can be passed with the same block-like syntax, and when they're marked as "inline" you can return from the enclosing function from within the lambda (because the lambda will have its body inlined by the compiler).
Real programming languages introduce too much accidental complexity (memory management, type declarations, etc.) that usually have nothing to do with the subject matter. (Unless you’re writing a book about that particular language of course)
It will also look bad if you happen to choose a language/framework that will be dead 10 years from now, even if the core concepts of your book would stay relevant.
too much accidental complexity (memory management, type declarations, etc.)
I know those were just examples, but that might hint at why ruby is a fine choice here. It has neither explicit memory management nor type declarations. It's pretty close to pseudocode already.
Comments
Since it seems that he used Ruby throughout the book, I wonder if that's the right choice or it will limit the book's audience.
I'm contemplating writing a long "from scratch" style book on another topic and I'm still not sure which language I should use. Using more than one (Java, Python,...) and generating multiple flavours of the book could be a good idea I think.
According to the author, readers of the book are already translating the port of Git in the book to C++, Clojure, Elixir, Haskell, Java, Node, Rust, and Swift
https://twitter.com/mountain_ghosts/status/11148630508075499...
I used to think so too, but tbh I think this will result in either a lot more work than you would like, or your audience are going to end up with one language that is being used ideomatically and the rest of the languages are not being used ideomatically.
Yeah that's pretty much the case with Modern Compiler Implementation in {ML, Java, C} by Appel. The Java and C ones are basically transliterated ML and not everyone appreciates that.
On the one hand, people do buy the Java and C books. On the other hand, I think they eventually realize it's probably easier to learn an ML dialect and learn the "real" code.
This may or may not apply to the git book though, since doing it in Ruby is already not "idiomatic".
I've been working through this book over the past few days, and writing my own git implementation in Rust in parallel, and I've found Ruby to be much simpler from an implementation standpoint. Ruby's standard library provides a lot of useful functionality out of the box (SHA1 digests, the deflate algorithm) which I've had to pull in dependencies for in my Rust version.
Obviously the Rust version is significantly faster, but the Ruby version is higher level and better expresses the concepts the book is trying to demonstrate without getting too bogged down in syntax, types, etc.
I don't really think the choice of language matters that much.
I don't know Ruby at all but I have read through part of the book and can follow the examples pretty easily. Plus, I think I'll get more out of the book if I just use his examples as guidelines and have to do some mental work to translate them into the language I'm using.
As a rubyist, I wish more books were written in it. I suspect it's one of the easier languages to read as pseudo-code, even with less familiarity.
The author discusses this in episode 13 (2019-03-24) of the podcast _The Yak Shave_ at 22:37: http://yakshave.fm/13
From what I understand, Ruby is highly accessible and has a standard library that covers what's used in the book.
If you can read Python you can almost read Ruby code
Ruby has blocks. Python does not. And Ruby blocks are very extensively used.
blocks are the same as passing a function or a lambda in python:
Far from it. Ruby blocks aren't really lambdas or anonymous functions. For example when you use return inside a block, it's not just the code in the block is being returned, but the whole enclosing function. And, you don't really "call" a block but yield to it. It's not even an object that you can inspect. It's syntax. It's really a new kind of control structure. Ruby blocks have few equivalents in other languages.
(not that anybody would do what I do, most people just use blocks, some people use yield, few people use the &block argument, but that's exactly the same)
Sound a lot like inlined lambdas in Kotlin. Lambdas can be passed with the same block-like syntax, and when they're marked as "inline" you can return from the enclosing function from within the lambda (because the lambda will have its body inlined by the compiler).
Just write it in pseudocode.
Real programming languages introduce too much accidental complexity (memory management, type declarations, etc.) that usually have nothing to do with the subject matter. (Unless you’re writing a book about that particular language of course)
It will also look bad if you happen to choose a language/framework that will be dead 10 years from now, even if the core concepts of your book would stay relevant.
I know those were just examples, but that might hint at why ruby is a fine choice here. It has neither explicit memory management nor type declarations. It's pretty close to pseudocode already.
By writing in pseudocode you pretty much guarantee there will be bugs in the implementation because they've never been executed.