From the translator: Jim Weirich is a legendary personality in the Ruby community. Unfortunately, he, like all of us, is mortal. Not so long ago, he left us. This translation is a tribute to this man who changed the world a little.
I heard about Jim for a long time: after all, he is the author of the
rake utility, which has become the de facto standard among rubists. To my great luck, I was among the listeners of his speech at
GoRuCo 2012 , where he was told about the advanced features of rake. I remember how I was struck by the dexterity and ease with which Jim spoke on complex topics. Later that year, at the RubyConf conference, I watched one more of his
remarkable speeches explaining some of the basic principles of Lambda calculus. Jim not only explained this not so simple topic in an accessible way, but also did not lose his listeners on the way.
I think now you understand why I was so glad to take this interview from Jim, because this is a unique opportunity to learn a little more about him and to learn something. We also managed to talk about the beginning of his journey in the world of development, about his first steps in Ruby, about functional programming, the threading model in Ruby and even his test framework:
RSpec-Given . So open this interview, do not be lazy to learn about one of the most advanced and charismatic developers!

')
Programmer's brief summary
How did you become a developer? What are your reasons for choosing this profession?I ran into programming back in school, in the good old seventies. I then took a book in the library devoted to the development of a BCD system. As a programming language, an assembler-like language was used. In general, this is somewhat insane, of course, to write under BCD in assembler, but I figured it out.
What does the abbreviation BCD mean?BCD is “Binary Coded Decimal”, a system in which all numbers are stored in the decimal number system (as opposed to the traditional binary).
This is a very unusual machine architecture, and yet valid for a beginner in the programming world. I remember how I came off while learning to write code. I think you can guess what exactly I said to the consultant for the choice of profession. True, after reading the description of a typical programmer in a pamphlet, I am notably despondent.
Do not worry what was written there?Well, something like:
“... You are sitting completely alone, in deep darkness. ... You do not communicate with anyone for many hours of your work! ”After that, I thought that programming is great, but this kind of work ... No, thank you!
During my college years, our consultant advised me: “Why don't you sign up for the Fortran for Beginners course?” You might like it. ” When I came to the first lesson, the lecturer went to the blackboard and began to write code, explaining it in the course. I still remember the name of the first function he wrote - member. I listened to a lecture and suddenly it dawned on me: “This is some kind of strange Fortran dialect. Too many brackets! ” Oh yes, it was Lisp! As it turned out, I got on the first and only course of Dan Friedman, author of the book Little Lisper.
Well, what about the ominous description of the programmer from the brochure?Ha, programming turned out to be a very social activity. Today, even if you work alone, you can always communicate with other people via Twitter, IRC, issues on a githaba, or mailings ... We are no longer the lone wolves that we were described in the 1970s.
Happy discovery
How did you come to Ruby?It was in 2000, if my memory serves me. I then wrote in C ++ and Java, and also very decently in Perl (well, you know, small scripts to reduce the daily routine). And Pearl, unfortunately, after a while began to upset me: he was perfect for fast hacks, but only because it is difficult to write beautiful abstractions on it. Here, for example, I need a list — please spit in Perl, but when the list of lists is already needed, that's all, the language starts to behave awkwardly.
And so I began to look for a new, suitable language for me personally. I wanted something more expressive, which would allow more active use of abstraction. And since I loved object-oriented programming, I also wanted an appropriate language. I very carefully studied Python and made at least 3 approaches to it. But, you know, there was no such thing in the head “Bam!”. Therefore, after a while I stopped my progress in Python, since he never became close to me.

Somewhere during my 3 attempts to learn Python, I received a letter from Dave Thomas in which he wrote: “I found a small language called Ruby here and I really liked it, it can also be to your liking.” I then finished read the book
The Pragmatic Programmer and decided that if Dave himself recommends something, then it is definitely worth a look at. I downloaded Ruby, played with him for just a few minutes and suddenly realized: “Well, here it is! This is exactly the language I was looking for! ” After 3 days I stopped writing in Perl and completely switched to Ruby.
What version of ruby ​​was it?It was Ruby 1.6 (since it was summer 2000 in the yard).
What exactly are you so hooked Ruby?He did everything in the same way as Pearl, but only in an object-oriented manner. I remember, then I thought: “Well, I would write this puzzle in Perl, but if I had objects, I would solve the problem in this way”. After that, I sat down at Ruby, and my solution, built on the facilities, just worked! Of course, I could use quick (and dirty) tricks, like those Pearl allowed me to do, but after a while I found out that Ruby has simply excellent abstractions and the language itself has developed very correctly. I was just happy to meet him.
Is Ruby functional?
Well, Ruby is an object-oriented language. But is it functional at the same time? And what does the word "functional" mean in general?This is a good question, really. Today, functional languages ​​are given increased attention, for example, tonight I will have a meeting with programmers in functional languages ​​in the city of Cincinnati. My wife, in response to this decision, said: “Well, well, tomorrow you are meeting with mere mortal developers?”
In general, there are 2 requirements to make a language functional, the first of which is manipulating functions as first-class objects: transferring functions from one place to another, associating them with variables, using closures to create new functions, and so on. Ruby satisfies the first requirement: we have lambdas and closures, we can associate them with variables and even create dynamically new functions. So, if you look from this side, Ruby is a very functional language.
But there is a second requirement! It makes functional languages ​​so interesting. It is the inadmissibility of changing the state of entities. Ruby does not meet this requirement, because the state of objects is constantly changing!
Functional programming is interesting for its implementation of multithreading. One of the important problems in multithreaded programming is the race condition, when you have, for example, 2 threads working with the same data. With this race, it is unknown who will win. For example, increasing the counter. There are 2 threads, the first of which reads the current value, increments it in the memory register and then puts it back. At this time, the second stream reads, increments the value and writes it.
If (and only if) they alternate in strict order one after another and we start with the number 10, then there will be 11, 12 and so on. You have to be very, very careful when the threads in the shared resource can be changed.
To solve this problem, there are 2 ways: not to use a shared resource, or not to change this resource itself. Functional programming uses the second approach: the data does not change, but only is created. With this approach, multi-threaded programming becomes much easier. I think that in our technological society with each new piece of hardware / processor, the need for multithreading will only grow. And in languages ​​such as Clojure, very good constructions are already built in for easy flow manipulation. In Clojure, if you even change the data, you do it in very specific conditions, when it is safe.
I'm afraid Ruby suffers from this because his model for streams comes from 1960-1970.
Thread Model in Ruby
Yes, it especially affected Ruby's MRI. I personally believe that the interpreter itself is not thread-safe. Is it really so?The interpreter is thread-safe, but this was achieved with the help of GIL (Global Interpreter Lock), the developers spoke a lot about it at RubyConf. The essence of this approach is that when entering the interpreter, a lock is set so that other threads cannot enter it at the same time. All this leads to thread safety, of course, but somewhat, let's say, complicates the work with the threads themselves.
However, are JRuby and Rubinius thread safe?Yes! They impose a lock on the lower level. There is such a thing: if, initially, the architecture of laying the lock at the required level, then it will be easy to do so in the end. To add thread safety to an already existing language is the real problem that MRI developers have to contend with. They added GIL in the end, but this is a somewhat superficial decision.
Matz mentioned that they were testing a different approach, with micro-locks (microlocking), in other words, locking them on shared data. He also said that in this case the code started working much slower than the version with GIL. Here is such a solution price. So if you need to work with streams, then you should look to JRuby or Rubinius. But even when they are used, it must be remembered that shared resources may change, since Ruby does not yet offer good solutions to this problem.
10 publications that every developer should read
I like the fact that new, modern ideas are often based on research and the basis of distant days from the past. For example, the ideas of functional programming or Lambda calculus, which you talked about during your speech at RubyConf.These are things of eighty-year exposure!
Do you still have such things up your sleeve?In 2009, Michael Feathers wrote the article
"10 Papers Every Programmer Should Read at Least Twice" (
unfortunately, the original article itself is no longer available ).
The first book is written by David Parnan and is called
“On the criteria to be used in decomposing systems into modules” . He wrote a simple program “Keyword in context”.

The program runs through the text file, finds all the words, finds parts of the text in which these words are found, and records the found blocks of text so that the words can later be displayed in the catalog along with the text in which they are located. It was an experiment. David wrote two programs using different approaches, and then looked at what happens when new requirements are placed on these programs. During the experiment, it was found that the best way to write a program is to break it down into modules, each of which hides internal content.
Is this one of the ideas of object-oriented programming (OOP)?Yes, one of them, in the OOP, each object stores a piece of information, and what happens inside the world does not care. Therefore, changing the method of storage and interaction with internal parts will not affect others. And this very simple experiment showed what to do. I highly recommend reading
this article in its entirety. I like that David really did the experiment: he wrote the code and checked how he behaves under the new conditions.
Another cool article is
“Can Programming Be Liberated from the von Neumann Style?” By John Backus. This is one of the first publications, which he called "ML", that is, a functional programming language. ML became the basis for languages ​​such as Haskell and OCalm.
Another exciting study that I would like to share is Ken Thompson's
“Reflections on Trusting Trust” . He described a hack for the compiler, with which you can add a bug in Unix, which is not in the source code.
Speeches
You have a natural talent: you can explain very complex topics. How do you do it?You know, I read a bunch of books about performances: how to prepare correctly, how to conduct, actually, a performance and so on. In all books, it is recommended to take notes in the fields and other similar things - but this approach does not work with me!
When preparing for a performance, I like to use a marker board or utility, like Omnigraffle for Mac OS. I start with small rectangles inside which an idea is written. After that, I connect the corresponding ideas with lines. For example, if the performance is related to Ruby, then I write out all the things that I would like to talk about. After that, I connect them with connections, you know, like “mind mapping”. I, however, get a directed graph.
After that, I try to write an interesting story on paper, walking along my resulting graph. Not necessarily in the order in which ideas are located, of course.
That is, is it something like a technical writer?Yes, I like this description!
To transform such difficult topics as Lambda calculus into an interesting story is art. I think many would have lost their eyes when trying to read original scientific works on this topic, written 80 years ago.I believe that the key to a successful performance is to have the most burning eyes. If what you are telling is interesting first of all to you, then you will be interested in the rest of the audience. If only you knew how many professors I met with a terribly monotonous voice while I was studying! This is a quiet horror. After this unforgettable experience, I decided that if I ever perform, I
will never do it the way my lecturers did. All these preparations for the performance - this, of course, is good and it helps, but much more important is the flame in your eyes during the performance.
Rspec-given
Do you still plan to perform?In January, I'm going to talk about my brainchild: the
Given / When / Then framework. This is my favorite child: every time I write tests, I use my framework because it expresses my thoughts very elegantly. I will tell about it on
CodeMash .
Does this framework have something in common with the BDD philosophy? And with Cucumber? Or the fact that you use those 3 keywords is just a coincidence?This is just a coincidence, my framework is not related to Cucumber, although I like it very much with my approach using Given / When / Then.
Using Rspec-Given you simply specify: this is given, this is the code that we are testing and this must be true for the tests to pass. In my opinion, this is a great way to write tests. I used a similar approach, even when I wrote on Test :: Unit: the data is given, here is the test code, and here are the tests themselves. But I tried to find a more elegant solution, since neither Test :: Unit nor Rspec give the necessary methods.
About 2-3 years ago, I reflected on this problem by sketching my ideas on paper. At that time, I was at the Ruby Hoedown conference in Nashville. I passed this piece of paper to the developers next door to collect feedback and opinions. And then Joe O'Brien turned to me and said: "You are not going to write another test framework?"
I played with my ideas for a year or two, until I came across a very simple and wonderfully working implementation on Rspec. It's cool that the rspec has enough flexibility and abstractness to implement what I wanted. As a result, a small library was written on top of Rspec. Thus, you can use the knowledge gained when writing on Rspec with the addition of greater clarity to the tests.
From the translator: Please report any errors found using personal messages, they will be promptly corrected.
References: