article.svx
1 --- 2 title: Multilingual perspective 3 subtitle: Programs exist beyond programming languages 4 date: 2021-06-20 5 tags: 6 - learning 7 - languages 8 author: Cam 9 --- 10 11 If there could be one single thing that has benefitted me the most in my 12 work as a programmer, it would be having learned many languages. I wouldn't 13 say that I have mastered most (if any) of the languages I have used, but 14 even just having tried them at all is often enough. 15 16 At first, the benefits seem simple: learn a new language, and you can use 17 it to build new things. For example, to build an iPhone application, you 18 are almost certainly going to want to know Swift. To build a website, 19 you're going to want to know Javascript, HTML, CSS. Learning a new 20 language opens up new opportunities. 21 22 As you grow comfortable with the new language, you start to get used to 23 some of the features and ideas that are made obvious by that language: 24 moving from Swift to Javascript, you miss the static types, the enums, 25 the pattern matching. When forced to switch back to regular old `switch` 26 statements from a language with proper pattern matching, the ideas that 27 you were previously able to express so naturally are no longer 28 immediately expressible. 29 30 Yet, were you never to have learned such a language, to have learned Javascript 31 and Javascript alone, this is not something you would have noticed. You 32 understand the `switch` statement, you understand destructuring, but without 33 being exposed to a language which combines the two into pattern matching, 34 this concept simply does not exist in your mind and you carry on; happy 35 with what you have, unaware of what you are missing. 36 37 Learning a programming language is not learning programming. The language 38 itself is actually just a *notation* by which we express programs. Notation 39 itself is just a tool that we use to visualize and communicate concepts, to 40 store and represent ideas outside of the mind. 41 42 For example, with musical notation, to be able to read and write sheet music 43 is not to be able to write or play a song. The concepts, the notes that sound 44 good together, exist whether we write it down this way or not. 45 46 For programming, it is the same. To be able to read and write one programming 47 language is not to be able to write a program. The concepts we use to build 48 programs exist beyond the language, and we are just using the language to 49 write our ideas down. 50 51 Much like how music is written in different clefs and key signatures---the 52 same symbols interpreted differently to put the common notes for a particular 53 range of instruments into focus---programs are written in different programming 54 languages which make it easier to express certain concepts common for certain 55 types of programs. 56 57 To learn a new programming language is more than just learning how to build a 58 new kind of application. In learning a language, you also learn about the 59 problems and solutions that the language was designed to solve. The ideas 60 on which the language was built, which may be less obvious in languages you are 61 already familiar with, become front of mind for the first time. You are challenged 62 to understand these ideas on a new level, and when it comes time to change 63 languages again, those ideas stick with you and remain relevant. To learn a new 64 programming language is to become a better programmer. 65 66 Of course, this comes with an "everything in moderation" warning: to become a 67 better programmer is not *only* to learn more languages. Just as there are 68 things to learn from new languages, there are just as many things to learn by 69 going deeper into each one. Wait until you are comfortable with a language 70 before moving on to too many more. Then, once you're comfortable with a few, 71 take the time to switch back to languages you thought you knew and use new 72 concepts and discover that, in fact, *you don't know them as well as you thought*. 73 74 ----- 75 76 For those of you looking to find some languages with interesting concepts not 77 made obvious in all others, here are some ideas: 78 1. [Pattern matching][]: As mentioned earlier, available in [Swift][], [Rust][], 79 [Haskell][], and many more (typically functional and functional-supporting 80 languages). Notably missing from many common imperative languages such as 81 Javascript (destructuring is *close*), Java, C++. One of the most useful 82 language features, and one of the saddest to not have available. 83 2. [Prototypal inheritance][]: Popularized by [Javascript][], but most obvious 84 in [Io][]. Take the time to learn Io (it's real quick). Write a few little 85 scripts, play with the prototyping, and suddenly you'll have a new appreciation 86 for prototypes when you go back to Javascript. 87 3. [Coroutines][]: Honestly, full on coroutines are not often available, but 88 to at least learn generators, as found in [Javascript][] and [Python][], 89 is a good time. Relatedly, [async/await][] is another common language feature 90 (available in [Javascript][], [Python][], [Rust][]), which can be implemented 91 easily using generators, so give that a try. 92 4. [Ownership][], referencing, and moves: Made most obvious in [Rust][], once you 93 understand ownership you start to feel nervous about passing mutable data 94 around all over the place, as is common in... well, most languages really. 95 Particularly, switching back to C++ after moving data in Rust is a real 96 experience. Even without ownership being enforced by the compiler, thinking 97 about data in this way, and building your own in-head borrow checker leads 98 to writing cleaner, easier to follow code in all situations. 99 5. [Concurrency][]: A step up from async/await, coroutines, and generators is 100 real concurrency. Not available in some languages (Javascript), and not 101 particularly interesting in many other languages, try out [Rust][] or [Go][] 102 to get a real appreciation for the complexity of concurrent programming. 103 To learn it in a safe environment, such as Rust, gives you a sense of what 104 *not* to do when faced with the relatively unprotected concurrency you find 105 in other languages, like C++ or Java. 106 6. The [monad][]: [Haskell][] is famously full of monads, a concept notorious 107 for being hard to understand. Once you figure it out though, you'll start to 108 see them everywhere. Promises/futures (as in Javascript/Rust) start to feel 109 like monads. Options (Rust/Swift/etc) are monads. Iterators. Observables. 110 UI interaction. Practically everything can be a monad if you try hard enough. 111 If you've learned generators by now, try and implement an approximation of 112 Haskell's `do` notation with `yield` (hint: it's a lot like implementing 113 async/await with `yield`). 114 115 Maybe someday I'll go into more detail on these things---a series of concept 116 tutorials written with a multilingual perspective. 117 118 [Pattern matching]: https://en.wikipedia.org/wiki/Pattern_matching 119 120 [Coroutines]: https://en.wikipedia.org/wiki/Coroutine 121 [async/await]: https://en.wikipedia.org/wiki/Async/await 122 [Concurrency]: https://en.wikipedia.org/wiki/Concurrent_computing 123 124 [Prototypal inheritance]: https://en.wikipedia.org/wiki/Prototype-based_programming 125 126 [monad]: https://en.wikipedia.org/wiki/Monad_(functional_programming) 127 [Ownership]: https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html 128 129 [Swift]: https://docs.swift.org/swift-book/ReferenceManual/Patterns.html 130 [Javascript]: https://developer.mozilla.org/en-US/docs/Web/JavaScript 131 [Python]: https://www.python.org/ 132 [Io]: https://iolanguage.org/ 133 [Rust]: https://www.rust-lang.org/ 134 [Go]: https://golang.org/ 135 [Haskell]: https://www.haskell.org/