← Wszystkie wpisy

Filozofia inżynierii: Yukihiro Matsumoto (Matz)

Yukihiro Matsumoto, twórca Ruby, sfotografowany przez Christophera Adamsa w 2018 roku

Najważniejsze wnioski

  • Projektowanie dla ludzi, a nie dla maszyn. Matz uczynił radość programisty funkcją celu i pozwolił, by krzem pokrył rachunek. Każda decyzja składniowa odpowiada na pytanie „jak poczuje się człowiek, czytając to?”, zanim odpowie na pytanie „jak szybko przesuną się bajty?”.
  • Najmniejsze zaskoczenie oznacza najmniejsze moje zaskoczenie. Zasada ta nie jest ankietą oczekiwań początkujących; to jeden biegły autor minimalizujący własną frustrację, mierzoną po dobrym opanowaniu Ruby.
  • MINASWAN: kultura jest wynikiem projektowania. „Matz jest miły, więc i my jesteśmy mili” pokazuje, że społeczność języka to powierzchnia, którą można zaprojektować, a nie zwykły przypadek wynikający z jego gramatyki.
  • Ruby to jeden gust stosowany bez wytchnienia. Jego spójność wynika z syntezy: Perl, Smalltalk, Lisp, Ada i Eiffel zharmonizowane w jeden głos, a nie uśrednione przez komisję.

Zasada

„Dla mnie celem życia jest po części odczuwanie radości. Programiści często czują radość, gdy mogą się skupić na twórczej stronie programowania, dlatego Ruby został zaprojektowany tak, by uszczęśliwiać programistów.” – Yukihiro Matsumoto1

Większość projektów językowych optymalizuje pod kątem maszyny. Szybkość kompilacji, układ pamięci, liczba instrukcji, to wszystko, na czym zależy krzemowi. Matz odwrócił priorytety. Uznał, że to człowiek przy klawiaturze jest tym, kto się liczy, a zadaniem maszyny jest mu służyć. „Maszyny powinny służyć ludziom” – powiedział. „Często programiści nieświadomie służą maszynom. Niech maszyny służą tobie.”2

Radość jest tu twardym ograniczeniem projektowym, a nie miękkim sentymentem przebranym za inżynierię. Jeśli radość człowieka jest funkcją celu, to każda decyzja składniowa, każda nazwa metody, każda wartość domyślna staje się pytaniem o to, jak człowiek poczuje się, czytając i pisząc kod, a nie o to, jak szybko przesuną się bajty. Matz uczynił ten kompromis jawnym i uczciwym: Ruby wyda cykle maszyny, by kupić wygodę programisty. To samo przekonanie sprawia, że gust staje się systemem strukturalnym, a nie ozdobą – doświadczenie osoby wykonującej pracę staje się nośną troską, a nie refleksją doczepioną na końcu.

Jedna decyzja rządzi wszystkim, co następuje: projektować dla ludzi, a nie dla maszyn. Składnia, kultura, motto społeczności – wszystko to z niej wynika. Reszta tego tekstu pokazuje, jak dążenie jednej osoby do własnego szczęścia zahartowało się w dającą się obronić pozycję inżynierską – i dlaczego „służyć człowiekowi” okazuje się równie rygorystyczne jak „służyć maszynie”, a nie odwrotem od tego.

Kontekst

Yukihiro Matsumoto urodził się w prefekturze Osaka w Japonii 14 kwietnia 1965 roku, a od czwartego roku życia wychowywał się w Tottori.3 Określa siebie jako pasjonata języków – nie językoznawcę, lecz pasjonata języków programowania. Do końca liceum był samoukiem w programowaniu, a następnie ukończył studia z informatyki na Uniwersytecie Tsukuba, gdzie pracował w laboratorium badawczym zajmującym się językami programowania i kompilatorami.3 Fascynacja pojawiła się najpierw; Ruby był jej ostatecznym wynikiem.

Nazwę Ruby nadał w lutym 1993 roku – pojawiła się ona podczas rozmowy internetowej z jego współpracownikiem Keiju Ishitsuką, zanim napisano choćby linijkę kodu – a sam język rozwijał przez kolejne lata.13 Motywacją było niezadowolenie. „Naprawdę chciałem prawdziwie obiektowego, łatwego w użyciu języka skryptowego” – wyjaśnił. „Szukałem takiego, ale nie mogłem go znaleźć.”4 Perl był potężny, lecz wedle jego gustu nie był naprawdę obiektowy. Python był obiektowy, lecz wedle jego gustu nie był dość przyjemny. Zbudował więc język, którego sam chciał używać. Pierwszą publiczną wersję wydał 21 grudnia 1995 roku.3

Nazwa była drobnym żartem. Obaj zdecydowali się na Ruby jako kamień szlachetny, ukłon w stronę Perla, języka, na który Ruby po części odpowiadał. Perła, a potem rubin: następca nazwany niczym przyrostowa aktualizacja.4 Przez lata Ruby był zjawiskiem przede wszystkim japońskim, z listami mailingowymi i dokumentacją po japońsku. Globalny przełom nadszedł później i z zewnątrz: David Heinemeier Hansson zbudował na jego podstawie Ruby on Rails, a Rails zaniósł Ruby reszcie świata w połowie pierwszej dekady XXI wieku.4 Język, który jedna osoba zbudowała dla własnego szczęścia, stał się podłożem aplikacji internetowych całego pokolenia.

Praca

Projekt Ruby: radość i zasada najmniejszego zaskoczenia

Matz wygłaszający przemówienie otwierające na EuRuKo 2011, sfotografowany przez Mathiasa Meyera

Najczęściej cytowaną ideą dotyczącą Ruby jest „zasada najmniejszego zaskoczenia” – język powinien zachowywać się tak, jak można się spodziewać, aby uwagę poświęcać problemowi, a nie narzędziu. Matz popiera tę zasadę, lecz prostuje jej częsty błędny odczyt. „Zasada najmniejszego zaskoczenia oznacza zasadę najmniejszego mojego zaskoczenia” – powiedział. „A oznacza zasadę najmniejszego zaskoczenia po bardzo dobrym opanowaniu Ruby.”5

To sprostowanie zawiera całą filozofię w jednym zdaniu. Matz nie ankietował programistów, by uśrednić ich oczekiwania. Zaprojektował język tak, by zminimalizować własną frustrację, zakładając, że język, który zachwyca własnego autora – biegłego, wymagającego użytkownika – zachwyci też innych, gdy osiągną biegłość. „Chciałem zminimalizować swoją frustrację podczas programowania, więc chcę zminimalizować swój wysiłek w programowaniu” – powiedział. „Sam chcę czerpać radość z programowania.”5 Ruby to język osobisty, który osiągnął skalę. Jego spójność nie jest spójnością komisji; to spójność jednego gustu stosowanego bez wytchnienia.

Projektowanie dla ludzi, a nie dla maszyn

Matz traktuje oprogramowanie jak medium dla ludzi, a nie jak zestaw instrukcji dla sprzętu. „Nie lekceważcie czynnika ludzkiego” – powiedział. „Choć siedzimy przed komputerami, są one mediami. Pracujemy dla człowieka, z człowiekiem. Większość naszych zadań i tak dotyczy ludzi.”5 Posuwa tę myśl dalej niż hasło: interfejs jest dla Matza całym produktem. „Jeśli system ma zły interfejs, nikt go nie użyje. Dlatego interfejs, czyli powierzchnia systemu, czy to wobec użytkowników, czy wobec innych maszyn, jest bardzo ważny.”2

Wnioskiem jest odmowa podporządkowania się preferencjom maszyny. Zapytany o relację między człowiekiem a komputerem, Matz odpowiedział bez ogródek: „To my jesteśmy panami. One są niewolnikami.”6 Maszyna istnieje po to, by służyć zamiarowi programisty, a język, który zmusza człowieka do myślenia jak procesor, ma tę relację odwróconą. Bloki Ruby, jego model, w którym wszystko jest obiektem, jego czytelne nazwy metod – Array#each, Integer#times, String#upcase – wszystkie wydają złożoność implementacji, aby powierzchnia czytała się jak zamiar.

MINASWAN: kultura jako wynik projektowania

Najbardziej niezwykłym wytworem Ruby nie jest funkcja; jest nim norma społeczności. Matz słynie z życzliwego, cierpliwego usposobienia, a ta postawa rozprzestrzeniła się w postaci motta: MINASWAN – „Matz jest miły, więc i my jesteśmy mili”.7 We wczesnych dniach Ruby, gdy dyskusje na listach mailingowych robiły się gorące, członkowie społeczności przeciwstawiali się temu, przywołując je, by nadać cieplejszy ton. Rozpowszechniło się ono aż stało się tożsamością.8

Lekcja, którą umyka większości projektantów języków, brzmi: kultura także jest powierzchnią projektową. Język to coś więcej niż jego gramatyka; to doświadczenie zadania pytania i otrzymania hojnej odpowiedzi, przeczytania biblioteki, której autorowi zależało na tym, by ją zrozumieć. Matz zaprojektował składnię, a własnym przykładem zaprojektował również otaczającą ją postawę społeczną. Język zbudowany po to, by uszczęśliwiać programistów, wyhodował społeczność oddaną życzliwości, ponieważ ta sama wartość napędzała oba te zjawiska – społeczność to zasada najmniejszego zaskoczenia zastosowana wobec ludzi.

mruby: filozofia w przestrzeni ograniczonej

W kwietniu 2012 roku Matz udostępnił mruby jako oprogramowanie o otwartym kodzie – lekką, osadzalną implementację Ruby stworzoną z myślą o miejscach, w których pełne Ruby jest zbyt ciężkie: mikrokontrolerach, systemach wbudowanych, urządzeniach konsumenckich.9 Jest ona zgodna z podzbiorem specyfikacji Ruby ISO/IEC 30170 i występuje jako mały interpreter z kompilatorem bytecode oraz maszyną wirtualną, osadzalny w C lub C++ podobnie jak Lua.10

mruby jest interesujący właśnie dlatego, że poddaje filozofię próbie pod presją. Gdy ma się kilobajty pamięci RAM i żadnego luksusu, jeśli chodzi o cykle, czy „projektowanie dla ludzi” przetrwa? Odpowiedzią Matza było zachowanie wyrazistości Ruby przy jednoczesnym zrzuceniu ciężaru środowiska uruchomieniowego – przeniesienie radości pisania w Ruby na warstwę firmware’u, zamiast spychać programistów systemów wbudowanych w dół, do C. Zakład postawiony na człowieka utrzymał się nawet w miejscu najbardziej mu wrogim.

Metoda

Metoda Matza to empatia sformalizowana w dyscyplinę projektową. Powracającym ruchem jest zadawanie pytania nie „co jest poprawne dla maszyny?”, lecz „co poczuje człowiek?” – a następnie zapłacenie każdego kosztu implementacji, jakiego ta odpowiedź wymaga.

Drugim ruchem jest synteza. Ruby jest jawnie wtórny: pragmatyka i wyrażenia regularne Perla, czysto obiektowy model i przesyłanie komunikatów Smalltalka, elastyczność Lispa, fragmenty Ady i Eiffela.4 Matz nie wynalazł nowego paradygmatu. Zaczerpnął najlepsze pomysły z języków, które podziwiał, i zharmonizował je w jeden spójny głos. Niewielu projektantów wykazuje taki gust: dyscyplinę, by brać zamiast wynajdywać, oraz trudniejszą dyscyplinę, by sprawić, że zapożyczone części będą do siebie pasować, a nie zderzać się ze sobą. Zasada najmniejszego zaskoczenia to po części spójność wewnętrzna – gdy poznasz jeden zakątek Ruby, kolejny zachowuje się tak, jak nauczył cię oczekiwać ten pierwszy.

Trzecim ruchem jest uczciwość co do kompromisu. Matz nigdy nie udawał, że Ruby jest szybkim wyborem, i mówił to wprost, zamiast deklarować ciepło, jednocześnie po cichu optymalizując pod testy wydajności. Koszt jest realny i konkretny: ponieważ w Ruby wszystko jest obiektem, nawet liczba całkowita jest obiektem pierwszej klasy, a arytmetyka odbywa się przez wysłanie do niej komunikatu +, a nie przez wykonanie surowej instrukcji maszynowej.14 Wygoda 5.times czy (1..n).map – traktowanie liczb jak obiektów, z którymi można rozmawiać – jest opłacana narzutem na dyspozytornię i alokację, którego int w C nigdy nie ponosi. Matz wybrał czytelną powierzchnię i pozwolił, by środowisko uruchomieniowe wzięło na siebie rachunek, co jest dokładnie tym zakładem wyłożonym wprost.

Łańcuch wpływów

Kto go ukształtował

Larry Wall i Perl. Ruby odziedziczył po Perlu pragmatyczną, zorientowaną na rezultat wrażliwość oraz jego DNA wyrażeń regularnych. Sam Matz przedstawiał Ruby jako odpowiedź na Perla – zachowując praktyczność, naprawiając to, co postrzegał jako jego brak prawdziwej obiektowości. (Wpływ bezpośredni)4

Smalltalk. Przekonanie, że wszystko jest obiektem – liczby całkowite, klasy, nil – i że obliczenia odbywają się przez przesyłanie komunikatów, pochodzi ze Smalltalka. To najgłębsze strukturalne dziedzictwo w modelu obiektowym Ruby. (Wpływ bezpośredni)4

Lisp, Ada i Eiffel. Lisp wniósł elastyczność i poczucie, że to język powinien się naginać do programisty; Ada i Eiffel wniosły inne konkretne fragmenty składni i projektu. Ruby jest syntezą. (Wpływy formujące)4

Kogo ukształtował

Sieć ery Rails. Ruby on Rails uczynił Ruby domyślnym językiem całego pokolenia startupów i nadał „szczęściu dewelopera” argument komercyjny: szczęśliwsi programiści dostarczali szybciej, więc język skupiony na człowieku wygrywał projekty ekonomią, a nie tylko odczuciem.

Bazowe oczekiwanie całego pokolenia. Po Ruby programiści oczekiwali, że języki będą przyjemne – że będą czytać się jak proza, że będą wybaczać, że będą zachwycać. To oczekiwanie zmieniło poprzeczkę, którą nowsze języki musiały pokonać, by traktowano je poważnie.

Crystal i Elixir. Crystal zapożycza składnię Ruby niemal w całości, kompilując się przy tym do natywnego kodu poprzez zaplecze LLVM.11 Elixir, funkcyjny język Joségo Valima dla BEAM, przenosi ergonomiczną wrażliwość Ruby do świata współbieżnego; Valim przywołuje swoje „wcześniejsze doświadczenie w Ruby” w odniesieniu do wielu zapożyczonych konstrukcji.12 Estetyka Ruby przeżyła jego środowisko uruchomieniowe. (Linia stylistyczna)

Myśl przewodnia

Oto produktywne napięcie. Matz optymalizuje pod kątem ludzkiego szczęścia i uczciwie przyznaje, że wydaje na to cykle maszyny. Drugi biegun inżynierii optymalizuje pod kątem maszyny – John Carmack liczący cykle, aż klatka zmieści się w budżecie, Linus Torvalds broniący „dobrego gustu” jako struktury danych, która sprawia, że przypadek szczególny znika. Carmack i Torvalds pytają, na co zasługuje sprzęt; Matz pyta, na co zasługuje człowiek. Żaden z biegunów nie jest błędny. Najlepsze systemy żyją w sporze między nimi – na tyle wyraziste, by człowiek czerpał radość z ich pisania, na tyle zdyscyplinowane, by maszyna nie była obrażona. Matz jest dowodem na to, że „projektować dla człowieka” to prawomocna, rygorystyczna pozycja inżynierska, a nie tylko pociecha. (Pomost serii)

Co z tego wyciągam

Buduję narzędzia dla deweloperów oraz infrastrukturę sterującą dla agentów AI, i to zakład Matza jest tym, który wciąż stawiam: to człowiek w pętli jest tym, kto się liczy. Agent programistyczny, podobnie jak język programowania, jest interfejsem między zamiarem człowieka a wykonaniem maszyny. Jeśli cię zaskakuje, walczy z tobą lub zmusza cię do myślenia jak maszyna zamiast o problemie, to poniósł porażkę – bez względu na to, jak sprytne są jego wewnętrzne mechanizmy. Cały sens tych wewnętrznych mechanizmów polega na tym, by uczynić doświadczenie czytelnym dla człowieka. Dlatego też utrzymuję powierzchnię uczciwą, a stos cienki – manifest bez kompilacji to zasada najmniejszego zaskoczenia zastosowana wobec łańcucha narzędzi. I tak jak Matz odmawiał udawania, że Ruby jest szybki, wolę być uczciwy co do kompromisu, niż go ukrywać: jakość jest jedyną zmienną, a szczęście programisty jest częścią jakości, a nie jej przeciwieństwem.

Najczęściej zadawane pytania

Jaka jest filozofia inżynierska Yukihiro Matsumoto?

Matz projektuje języki programowania pod kątem ludzkiego szczęścia i produktywności, a nie wydajności maszyny. Jego deklarowany cel: „Ruby został zaprojektowany tak, by uszczęśliwiać programistów.”1 Traktuje doświadczenie programisty – czytelność, radość, najmniejsze zaskoczenie – jako nadrzędne ograniczenie projektowe i akceptuje wolniejsze środowisko uruchomieniowe jako uczciwą cenę służenia mu. „Maszyny powinny służyć ludziom” – powiedział. „Niech maszyny służą tobie.”2

Czym jest zasada najmniejszego zaskoczenia w Ruby?

To idea, że język powinien zachowywać się tak, jak spodziewa się doświadczony użytkownik, minimalizując tarcie. Matz wyjaśnia, że oznacza to „zasadę najmniejszego mojego zaskoczenia” – zaprojektował Ruby tak, by zminimalizować własną frustrację jako biegły użytkownik, oraz „zasadę najmniejszego zaskoczenia po bardzo dobrym opanowaniu Ruby”, a nie zaskoczenie początkującego w pierwszym dniu.5

Co oznacza MINASWAN?

MINASWAN to skrót od „Matz jest miły, więc i my jesteśmy mili” – motto społeczności Ruby, które wyrosło z życzliwego, cierpliwego usposobienia Matsumoto. Pierwsi rubyiści przywoływali je, by nadać hojny ton na listach mailingowych, i stało się ono częścią kulturowej tożsamości Ruby.78 Odzwierciedla ono ideę, że społeczność języka sama w sobie jest powierzchnią projektową.

Jakie języki wpłynęły na Ruby?

Ruby jest celową syntezą. Zaczerpnął pragmatyczną wrażliwość i wyrażenia regularne Perla, czysto obiektowy model i przesyłanie komunikatów Smalltalka, elastyczność Lispa oraz elementy Ady i Eiffela. Matz połączył cechy, które podziwiał, w jeden spójny język, zamiast wynajdywać nowy paradygmat.4


Sources


  1. Bill Venners, “The Philosophy of Ruby: A Conversation with Yukihiro Matsumoto, Part I.” Artima Developer, 29 September 2003. “For me the purpose of life is partly to have joy… so Ruby is designed to make programmers happy.” 

  2. Bill Venners, “Matz on Craftsmanship: A Conversation with Yukihiro Matsumoto, Part III.” Artima Developer, 2003. “Machines should serve human beings… Let machines serve you.” Also: interface as the surface of the system. 

  3. “Yukihiro Matsumoto.” Wikipedia. Born 14 April 1965 in Osaka Prefecture, raised in Tottori from age four; University of Tsukuba information science; first Ruby release 21 December 1995; mruby (April 2012). 

  4. Sinclair Target, “The Ruby Story.” Two-Bit History, 19 November 2017. Started 1993; “I really wanted a genuine object-oriented, easy-to-use scripting language”; naming with Keiju Ishitsuka after a gemstone / nod to Perl; influences from Perl, Smalltalk, Lisp, Ada, Eiffel; “I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy”; Rails-driven global breakout. 

  5. Bill Venners, “The Philosophy of Ruby, Part I.” Artima Developer, 2003. “The principle of least surprise means principle of least my surprise”; “I wanted to minimize my frustration during programming”; “Don’t underestimate the human factor… We are working for human, with human.” 

  6. “Yukihiro Matsumoto.” Wikiquote, citing The Philosophy of Ruby, A Conversation with Yukihiro Matsumoto, Part I, Bill Venners, Artima Developer, 2003. “We are the masters. They are the slaves.” 

  7. “Yukihiro Matsumoto.” Wikipedia. “Matz’ demeanor has brought about a motto in the Ruby community: ‘Matz is nice and so we are nice,’ commonly abbreviated as MINASWAN.” 

  8. “MINASWAN.” Wiktionary. Initialism of “Matz is nice and so we are nice”; origin and use as a community-tone norm in Ruby’s early days. 

  9. “Mruby.” Wikipedia. mruby open-sourced April 2012 under Matsumoto’s direction; lightweight, embeddable implementation for constrained environments; conforms to a subset of ISO/IEC 30170. 

  10. “mruby – Lightweight Ruby.” mruby.org. Embeddable interpreter, bytecode compiler (mrbc), and virtual machine; embeddable into C/C++ in a manner similar to Lua; ISO/IEC 30170:2012 compliance. 

  11. “Crystal (programming language).” Wikipedia. “With syntax inspired by the language Ruby… it compiles to much more efficient native code using an LLVM backend.” 

  12. José Valim, “Elixir Design Goals.” elixir-lang.org, 8 August 2013. “Given my previous background in Ruby, it is natural that some of the constructs added were borrowed from Ruby.” Also: Elixir runs on the BEAM (Erlang VM), per “Elixir (programming language),” Wikipedia

  13. “Ruby (programming language).” Wikipedia. “The name ‘Ruby’ originated during an online chat session between Matsumoto and Keiju Ishitsuka on 24 February 1993, before any code had been written for the language.” 

  14. “class Integer.” Ruby Core Reference. “An Integer object represents an integer value.” Arithmetic operators such as self + other are documented as public instance methods, meaning integer arithmetic is performed via method dispatch on an object rather than a raw machine instruction. 

Powiązane artykuły

Filozofia inżynierii: Roberto Ierusalimschy

Roberto Ierusalimschy zaprojektował Lua wokół jednej zasady — mechanizmy, nie polityka — mały, szybki, osadzalny język, …

19 min czytania

Filozofia inżynierska: Guido van Rossum, czytelność się liczy

Guido van Rossum zbudował Pythona na jednym założeniu: kod jest czytany znacznie częściej, niż jest pisany, więc sam jęz…

14 min czytania

The Shader Gallery That Lied: Debugging 216 WebGL Presets

A user said the shader playground looked broken. Pixel-readback testing found 30 dead presets, 11 that never compiled, a…

11 min czytania