{"entry_id": "d2e69b83-ac1f-4a26-8ec3-755ba41e9d02", "infos": [{"txt": "A decade of developing a programming language", "language": "english", "position": {"atoms": [{"position_id": 0, "txt": "A decade of developing a programming language", "x": "//title"}]}, "tags": [], "label": "O", "web_segment_id": 0, "global_sentence_id": 0, "edu_l1_label": "EDU_O"}, {"txt": "A decade of developing a programming language", "language": "english", "position": {"atoms": [{"position_id": 219, "txt": "A decade of developing a programming language", "x": "/html/body/div/section/header/h1"}]}, "tags": ["h1"], "label": "article_title", "web_segment_id": 1, "global_sentence_id": 1, "edu_l1_label": "BOT"}, {"txt": "Nov 14, 2023", "language": "english", "position": {"atoms": [{"position_id": 221, "txt": "Nov 14, 2023", "x": "/html/body/div/section/header/time"}]}, "tags": [], "label": "publish_time", "web_segment_id": 2, "global_sentence_id": 2, "edu_l1_label": "EDU_O"}, {"txt": "In 2013, I had an idea: \"", "language": "english", "position": {"atoms": [{"position_id": 223, "txt": "In 2013, I had an idea: \"", "x": "/html/body/div/section/p[1]"}]}, "tags": [], "label": "content", "web_segment_id": 3, "global_sentence_id": 3, "edu_l1_label": "BOS"}, {"txt": "what if I were to build my programming language?\".", "language": "english", "position": {"atoms": [{"position_id": 224, "txt": "what if I were to build my programming language?\".", "x": "/html/body/div/section/p[1]"}]}, "tags": [], "label": "content", "web_segment_id": 3, "global_sentence_id": 4, "edu_l1_label": "IOS"}, {"txt": " Back then my idea came down to \"an interpreted language that mixes elements from Ruby and Smalltalk\", and not much more.", "language": "english", "position": {"atoms": [{"position_id": 225, "txt": " Back then my idea came down to \"an interpreted language that mixes elements from Ruby and Smalltalk\", and not much more.", "x": "/html/body/div/section/p[1]"}]}, "tags": [], "label": "content", "web_segment_id": 3, "global_sentence_id": 5, "edu_l1_label": "IOS"}, {"txt": "Between 2013 and 2015 I spent time on and off trying different languages (C, C++, D and various others I can't remember) to see which one I would use to build my language in.", "language": "english", "position": {"atoms": [{"position_id": 227, "txt": "Between 2013 and 2015 I spent time on and off trying different languages (C, C++, ", "x": "/html/body/div/section/p[2]"}, {"position_id": 229, "txt": "D", "x": "/html/body/div/section/p[2]/a"}, {"position_id": 231, "txt": " and various others I can't remember) to see which one I would use to build my language in.", "x": "/html/body/div/section/p[2]/a"}]}, "tags": [], "label": "content", "web_segment_id": 4, "global_sentence_id": 6, "edu_l1_label": "IOS"}, {"txt": " While this didn't help me find a language I did want to use, it did help me eliminate others.", "language": "english", "position": {"atoms": [{"position_id": 232, "txt": " While this didn't help me find a language I ", "x": "/html/body/div/section/p[2]/a"}, {"position_id": 234, "txt": "did", "x": "/html/body/div/section/p[2]/em"}, {"position_id": 236, "txt": " want to use, it did help me eliminate others.", "x": "/html/body/div/section/p[2]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 4, "global_sentence_id": 7, "edu_l1_label": "IOS"}, {"txt": " For example, C proved to be too difficult to work with.", "language": "english", "position": {"atoms": [{"position_id": 237, "txt": " For example, C proved to be too difficult to work with.", "x": "/html/body/div/section/p[2]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 4, "global_sentence_id": 8, "edu_l1_label": "IOS"}, {"txt": " D seemed more interesting and I managed to implement something that vaguely resembles a virtual machine, but I ultimately decided against using it.", "language": "english", "position": {"atoms": [{"position_id": 238, "txt": " D seemed more interesting and I managed to implement something that vaguely resembles a virtual machine, but I ultimately decided against using it.", "x": "/html/body/div/section/p[2]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 4, "global_sentence_id": 9, "edu_l1_label": "IOS"}, {"txt": " I don't remember exactly why, but I believe it was due to the rift caused by the differences between D version 1 and 2, the general lack of learning resources and packages, and the presence of a garbage collector.", "language": "english", "position": {"atoms": [{"position_id": 239, "txt": " I don't remember exactly why, but I believe it was due to the rift caused by the differences between D version 1 and 2, the general lack of learning resources and packages, and the presence of a garbage collector.", "x": "/html/body/div/section/p[2]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 4, "global_sentence_id": 10, "edu_l1_label": "IOS"}, {"txt": "Somewhere towards the end of 2014 I discovered Rust.", "language": "english", "position": {"atoms": [{"position_id": 241, "txt": "Somewhere towards the end of 2014 I discovered ", "x": "/html/body/div/section/p[3]"}, {"position_id": 243, "txt": "Rust", "x": "/html/body/div/section/p[3]/a"}, {"position_id": 245, "txt": ".", "x": "/html/body/div/section/p[3]/a"}]}, "tags": [], "label": "content", "web_segment_id": 5, "global_sentence_id": 11, "edu_l1_label": "IOS"}, {"txt": " While the state Rust was in at the time is best described as \"rough\", and learning it (especially at the time with the lack of guides) was difficult, I enjoyed using it; much more so than the other languages I had experimented until that point.", "language": "english", "position": {"atoms": [{"position_id": 246, "txt": " While the state Rust was in at the time is best described as \"rough\", and learning it (especially at the time with the lack of guides) was difficult, I enjoyed using it; much more so than the other languages I had experimented until that point.", "x": "/html/body/div/section/p[3]/a"}]}, "tags": [], "label": "content", "web_segment_id": 5, "global_sentence_id": 12, "edu_l1_label": "IOS"}, {"txt": "2015 saw the release of Rust 1.0, and that same year I committed the first few lines of Rust code for Inko, though it would take another two months or so before the code started to (vaguely) resemble that of a programming language.", "language": "english", "position": {"atoms": [{"position_id": 248, "txt": "2015 saw the release of ", "x": "/html/body/div/section/p[4]"}, {"position_id": 250, "txt": "Rust 1.0", "x": "/html/body/div/section/p[4]/a[1]"}, {"position_id": 252, "txt": ", and that same year I committed the ", "x": "/html/body/div/section/p[4]/a[1]"}, {"position_id": 254, "txt": "first few lines of Rust code", "x": "/html/body/div/section/p[4]/a[2]"}, {"position_id": 256, "txt": " for ", "x": "/html/body/div/section/p[4]/a[2]"}, {"position_id": 258, "txt": "Inko", "x": "/html/body/div/section/p[4]/a[3]"}, {"position_id": 260, "txt": ", though it would take another two months or so before the code started to (vaguely) resemble that of a programming language.", "x": "/html/body/div/section/p[4]/a[3]"}]}, "tags": [], "label": "content", "web_segment_id": 6, "global_sentence_id": 13, "edu_l1_label": "IOS"}, {"txt": "Fast-forward to 2023, and Inko is in a state where one can write meaningful programs in it (e.g. HVAC automation software, a Markdown parser, a changelog generator and more).", "language": "english", "position": {"atoms": [{"position_id": 262, "txt": "Fast-forward to 2023, and Inko is in a state where one can write meaningful programs in it (e.g. ", "x": "/html/body/div/section/p[5]"}, {"position_id": 264, "txt": "HVAC automation software", "x": "/html/body/div/section/p[5]/a[1]"}, {"position_id": 266, "txt": ", a ", "x": "/html/body/div/section/p[5]/a[1]"}, {"position_id": 268, "txt": "Markdown parser", "x": "/html/body/div/section/p[5]/a[2]"}, {"position_id": 270, "txt": ", a ", "x": "/html/body/div/section/p[5]/a[2]"}, {"position_id": 272, "txt": "changelog generator", "x": "/html/body/div/section/p[5]/a[3]"}, {"position_id": 274, "txt": " and more).", "x": "/html/body/div/section/p[5]/a[3]"}]}, "tags": [], "label": "content", "web_segment_id": 7, "global_sentence_id": 14, "edu_l1_label": "IOS"}, {"txt": " Inko has also changed considerably over the years:", "language": "english", "position": {"atoms": [{"position_id": 275, "txt": " Inko has also changed considerably over the years:", "x": "/html/body/div/section/p[5]/a[3]"}]}, "tags": [], "label": "content", "web_segment_id": 7, "global_sentence_id": 15, "edu_l1_label": "IOS"}, {"txt": " whereas it was once a gradually typed interpreted language, it's now statically typed and compiles to machine code using LLVM.", "language": "english", "position": {"atoms": [{"position_id": 276, "txt": " whereas it was once a gradually typed interpreted language, it's now statically typed and compiles to machine code using ", "x": "/html/body/div/section/p[5]/a[3]"}, {"position_id": 278, "txt": "LLVM", "x": "/html/body/div/section/p[5]/a[4]"}, {"position_id": 280, "txt": ".", "x": "/html/body/div/section/p[5]/a[4]"}]}, "tags": [], "label": "content", "web_segment_id": 7, "global_sentence_id": 16, "edu_l1_label": "IOS"}, {"txt": " And whereas Inko used to draw inspiration heavily from Ruby and Smalltalk, these days it's closer to Rust, Erlang and Pony than it is to Ruby or Smalltalk.", "language": "english", "position": {"atoms": [{"position_id": 281, "txt": " And whereas Inko used to draw inspiration heavily from Ruby and Smalltalk, these days it's closer to Rust, ", "x": "/html/body/div/section/p[5]/a[4]"}, {"position_id": 283, "txt": "Erlang", "x": "/html/body/div/section/p[5]/a[5]"}, {"position_id": 285, "txt": " and ", "x": "/html/body/div/section/p[5]/a[5]"}, {"position_id": 287, "txt": "Pony", "x": "/html/body/div/section/p[5]/a[6]"}, {"position_id": 289, "txt": " than it is to Ruby or Smalltalk.", "x": "/html/body/div/section/p[5]/a[6]"}]}, "tags": [], "label": "content", "web_segment_id": 7, "global_sentence_id": 17, "edu_l1_label": "IOS"}, {"txt": "Given it's been 10 years since I first started working towards Inko, I'd like to highlight (in no particular order) a few of the things I've learned about building a programming language since first starting work on Inko.", "language": "english", "position": {"atoms": [{"position_id": 291, "txt": "Given it's been 10 years since I first started working towards Inko, I'd like to highlight (in no particular order) a few of the things I've learned about building a programming language since first starting work on Inko.", "x": "/html/body/div/section/p[6]"}]}, "tags": [], "label": "content", "web_segment_id": 8, "global_sentence_id": 18, "edu_l1_label": "IOS"}, {"txt": " This is by no means an exhaustive list, rather it's what I can remember at the time of writing.", "language": "english", "position": {"atoms": [{"position_id": 292, "txt": " This is by no means an exhaustive list, rather it's what I can remember at the time of writing.", "x": "/html/body/div/section/p[6]"}]}, "tags": [], "label": "content", "web_segment_id": 8, "global_sentence_id": 19, "edu_l1_label": "IOS"}, {"txt": "You can find discussions about this article on Reddit here and here, on Hacker News, and on Lobsters.", "language": "english", "position": {"atoms": [{"position_id": 294, "txt": "You can find discussions about this article on Reddit ", "x": "/html/body/div/section/div[1]/div/p"}, {"position_id": 296, "txt": "here", "x": "/html/body/div/section/div[1]/div/p/a[1]"}, {"position_id": 298, "txt": " and ", "x": "/html/body/div/section/div[1]/div/p/a[1]"}, {"position_id": 300, "txt": "here", "x": "/html/body/div/section/div[1]/div/p/a[2]"}, {"position_id": 302, "txt": ", on ", "x": "/html/body/div/section/div[1]/div/p/a[2]"}, {"position_id": 304, "txt": "Hacker News", "x": "/html/body/div/section/div[1]/div/p/a[3]"}, {"position_id": 306, "txt": ", and on ", "x": "/html/body/div/section/div[1]/div/p/a[3]"}, {"position_id": 308, "txt": "Lobsters", "x": "/html/body/div/section/div[1]/div/p/a[4]"}, {"position_id": 310, "txt": ".", "x": "/html/body/div/section/div[1]/div/p/a[4]"}]}, "tags": [], "label": "content", "web_segment_id": 9, "global_sentence_id": 20, "edu_l1_label": "IOS"}, {"txt": "Table of contents", "language": "english", "position": {"atoms": [{"position_id": 312, "txt": "Table of contents", "x": "/html/body/div/section/h2[1]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 10, "global_sentence_id": 21, "edu_l1_label": "BOS"}, {"txt": "Avoid gradual typing", "language": "english", "position": {"atoms": [{"position_id": 314, "txt": "Avoid gradual typing", "x": "/html/body/div/section/h2[2]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 11, "global_sentence_id": 22, "edu_l1_label": "IOS"}, {"txt": "A big change I made was to switch Inko from being a gradually typed language to a statically typed language.", "language": "english", "position": {"atoms": [{"position_id": 316, "txt": "A big change I made was to switch Inko from being a gradually typed language to a statically typed language.", "x": "/html/body/div/section/p[7]"}]}, "tags": [], "label": "content", "web_segment_id": 12, "global_sentence_id": 23, "edu_l1_label": "IOS"}, {"txt": " The idea behind gradual typing was that it would allow you to build a prototype or simple scripts in a short amount of time using dynamic typing, then over time turn the program into a statically typed program (where beneficial).", "language": "english", "position": {"atoms": [{"position_id": 317, "txt": " The idea behind gradual typing was that it would allow you to build a prototype or simple scripts in a short amount of time using dynamic typing, then over time turn the program into a statically typed program (where beneficial).", "x": "/html/body/div/section/p[7]"}]}, "tags": [], "label": "content", "web_segment_id": 12, "global_sentence_id": 24, "edu_l1_label": "IOS"}, {"txt": "In reality, gradual typing ends up giving you the worst of both dynamic and static typing:", "language": "english", "position": {"atoms": [{"position_id": 319, "txt": "In reality, gradual typing ends up giving you the worst of both dynamic and static typing:", "x": "/html/body/div/section/p[8]"}]}, "tags": [], "label": "content", "web_segment_id": 13, "global_sentence_id": 25, "edu_l1_label": "IOS"}, {"txt": " you get the uncertainty and lack of safety (in dynamically typed contexts) of dynamic typing, and the cost of trying to fit your ideas into a statically typed type system.", "language": "english", "position": {"atoms": [{"position_id": 320, "txt": " you get the uncertainty and lack of safety (in dynamically typed contexts) of dynamic typing, and the cost of trying to fit your ideas into a statically typed type system.", "x": "/html/body/div/section/p[8]"}]}, "tags": [], "label": "content", "web_segment_id": 13, "global_sentence_id": 26, "edu_l1_label": "IOS"}, {"txt": " I also found that the use of gradual typing didn't actually make me more productive compared to using static typing.", "language": "english", "position": {"atoms": [{"position_id": 321, "txt": " I also found that the use of gradual typing didn't actually make me more productive compared to using static typing.", "x": "/html/body/div/section/p[8]"}]}, "tags": [], "label": "content", "web_segment_id": 13, "global_sentence_id": 27, "edu_l1_label": "IOS"}, {"txt": " The result was that I found myself avoiding dynamic typing in both Inko's standard library and the programs I wrote.", "language": "english", "position": {"atoms": [{"position_id": 322, "txt": " The result was that I found myself avoiding dynamic typing in both Inko's standard library and the programs I wrote.", "x": "/html/body/div/section/p[8]"}]}, "tags": [], "label": "content", "web_segment_id": 13, "global_sentence_id": 28, "edu_l1_label": "IOS"}, {"txt": " In fact, the few places where dynamic typing was used in the standard library was due to the type system not being powerful enough to provide a better alternative.", "language": "english", "position": {"atoms": [{"position_id": 323, "txt": " In fact, the few places where dynamic typing ", "x": "/html/body/div/section/p[8]"}, {"position_id": 325, "txt": "was", "x": "/html/body/div/section/p[8]/em"}, {"position_id": 327, "txt": " used in the standard library was due to the type system not being powerful enough to provide a better alternative.", "x": "/html/body/div/section/p[8]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 13, "global_sentence_id": 29, "edu_l1_label": "IOS"}, {"txt": "Gradual typing also has performance implications.", "language": "english", "position": {"atoms": [{"position_id": 329, "txt": "Gradual typing also has performance implications.", "x": "/html/body/div/section/p[9]"}]}, "tags": [], "label": "content", "web_segment_id": 14, "global_sentence_id": 30, "edu_l1_label": "IOS"}, {"txt": " Consider this example using keyword arguments:", "language": "english", "position": {"atoms": [{"position_id": 330, "txt": " Consider this example using keyword arguments:", "x": "/html/body/div/section/p[9]"}]}, "tags": [], "label": "content", "web_segment_id": 14, "global_sentence_id": 31, "edu_l1_label": "IOS"}, {"txt": "let x:", "language": "english", "position": {"atoms": [{"position_id": 332, "txt": "let", "x": "/html/body/div/section/div[2]/pre/code/span[1]"}, {"position_id": 334, "txt": " x:", "x": "/html/body/div/section/div[2]/pre/code/span[1]"}]}, "tags": [], "label": "code", "web_segment_id": 15, "global_sentence_id": 32, "edu_l1_label": "EDU_O"}, {"txt": " Any = some_valuex.foo(b:", "language": "english", "position": {"atoms": [{"position_id": 335, "txt": " Any = some_value\n\nx.foo(b:", "x": "/html/body/div/section/div[2]/pre/code/span[1]"}]}, "tags": [], "label": "code", "web_segment_id": 15, "global_sentence_id": 33, "edu_l1_label": "EDU_O"}, {"txt": " 42, a:", "language": "english", "position": {"atoms": [{"position_id": 336, "txt": " ", "x": "/html/body/div/section/div[2]/pre/code/span[1]"}, {"position_id": 338, "txt": "42", "x": "/html/body/div/section/div[2]/pre/code/span[2]"}, {"position_id": 340, "txt": ", a:", "x": "/html/body/div/section/div[2]/pre/code/span[2]"}]}, "tags": [], "label": "code", "web_segment_id": 15, "global_sentence_id": 34, "edu_l1_label": "EDU_O"}, {"txt": " 10)", "language": "english", "position": {"atoms": [{"position_id": 341, "txt": " ", "x": "/html/body/div/section/div[2]/pre/code/span[2]"}, {"position_id": 343, "txt": "10", "x": "/html/body/div/section/div[2]/pre/code/span[3]"}, {"position_id": 345, "txt": ")\n", "x": "/html/body/div/section/div[2]/pre/code/span[3]"}]}, "tags": [], "label": "code", "web_segment_id": 15, "global_sentence_id": 35, "edu_l1_label": "EDU_O"}, {"txt": "Here x is typed as Any, which used to mean the value is dynamically typed.", "language": "english", "position": {"atoms": [{"position_id": 347, "txt": "Here ", "x": "/html/body/div/section/p[10]"}, {"position_id": 349, "txt": "x", "x": "/html/body/div/section/p[10]/code[1]"}, {"position_id": 351, "txt": " is typed as ", "x": "/html/body/div/section/p[10]/code[1]"}, {"position_id": 353, "txt": "Any", "x": "/html/body/div/section/p[10]/code[2]"}, {"position_id": 355, "txt": ", which used to mean the value is dynamically typed.", "x": "/html/body/div/section/p[10]/code[2]"}]}, "tags": [], "label": "content", "web_segment_id": 16, "global_sentence_id": 36, "edu_l1_label": "IOS"}, {"txt": " Because we don't know the type of x in x.foo(...), we can't resolve the keyword arguments to positional arguments at compile-time.", "language": "english", "position": {"atoms": [{"position_id": 356, "txt": " Because we don't know the type of ", "x": "/html/body/div/section/p[10]/code[2]"}, {"position_id": 358, "txt": "x", "x": "/html/body/div/section/p[10]/code[3]"}, {"position_id": 360, "txt": " in ", "x": "/html/body/div/section/p[10]/code[3]"}, {"position_id": 362, "txt": "x.foo(...)", "x": "/html/body/div/section/p[10]/code[4]"}, {"position_id": 364, "txt": ", we can't resolve the keyword arguments to positional arguments at compile-time.", "x": "/html/body/div/section/p[10]/code[4]"}]}, "tags": [], "label": "content", "web_segment_id": 16, "global_sentence_id": 37, "edu_l1_label": "IOS"}, {"txt": " This meant Inko's virtual machine had to provide a runtime fallback, and the keyword arguments had to be encoded into the bytecode.", "language": "english", "position": {"atoms": [{"position_id": 365, "txt": " This meant Inko's virtual machine had to provide a runtime fallback, and the keyword arguments had to be encoded into the bytecode.", "x": "/html/body/div/section/p[10]/code[4]"}]}, "tags": [], "label": "content", "web_segment_id": 16, "global_sentence_id": 38, "edu_l1_label": "IOS"}, {"txt": " While the cost wasn't significant, in a statically typed language the cost is zero because we can resolve the arguments at compile-time.", "language": "english", "position": {"atoms": [{"position_id": 366, "txt": " While the cost wasn't significant, in a statically typed language the cost is zero because we can resolve the arguments at compile-time.", "x": "/html/body/div/section/p[10]/code[4]"}]}, "tags": [], "label": "content", "web_segment_id": 16, "global_sentence_id": 39, "edu_l1_label": "IOS"}, {"txt": "Another issue is that the presence of dynamic types can inhibit compile-time optimizations, such as compile-time inlining (and all the optimizations that depend on it).", "language": "english", "position": {"atoms": [{"position_id": 368, "txt": "Another issue is that the presence of dynamic types can inhibit compile-time optimizations, such as compile-time inlining (and all the optimizations that depend on it).", "x": "/html/body/div/section/p[11]"}]}, "tags": [], "label": "content", "web_segment_id": 17, "global_sentence_id": 40, "edu_l1_label": "IOS"}, {"txt": " If a language uses a Just In Time (JIT) compiler, such as JavaScript (and by extension TypeScript), you can optimize the code at runtime, but that means having to write a JIT compiler which itself is a massive undertaking.", "language": "english", "position": {"atoms": [{"position_id": 369, "txt": " If a language uses a Just In Time (JIT) compiler, such as JavaScript (and by extension ", "x": "/html/body/div/section/p[11]"}, {"position_id": 371, "txt": "TypeScript", "x": "/html/body/div/section/p[11]/a"}, {"position_id": 373, "txt": "), you can optimize the code at runtime, but that means having to write a JIT compiler which itself is a massive undertaking.", "x": "/html/body/div/section/p[11]/a"}]}, "tags": [], "label": "content", "web_segment_id": 17, "global_sentence_id": 41, "edu_l1_label": "IOS"}, {"txt": "The presence of dynamic types also means that even statically typed code may be incorrect, though this depends on how you approach casting dynamically typed values to statically typed values.", "language": "english", "position": {"atoms": [{"position_id": 375, "txt": "The presence of dynamic types also means that even statically typed code may be incorrect, though this depends on how you approach casting dynamically typed values to statically typed values.", "x": "/html/body/div/section/p[12]"}]}, "tags": [], "label": "content", "web_segment_id": 18, "global_sentence_id": 42, "edu_l1_label": "IOS"}, {"txt": " If such a cast doesn't require a runtime check, you may end up passing incorrectly typed data to statically typed code.", "language": "english", "position": {"atoms": [{"position_id": 376, "txt": " If such a cast doesn't require a runtime check, you may end up passing incorrectly typed data to statically typed code.", "x": "/html/body/div/section/p[12]"}]}, "tags": [], "label": "content", "web_segment_id": 18, "global_sentence_id": 43, "edu_l1_label": "IOS"}, {"txt": " If you do perform some sort of runtime check, this may affect performance when such casts are common.", "language": "english", "position": {"atoms": [{"position_id": 377, "txt": " If you do perform some sort of runtime check, this may affect performance when such casts are common.", "x": "/html/body/div/section/p[12]"}]}, "tags": [], "label": "content", "web_segment_id": 18, "global_sentence_id": 44, "edu_l1_label": "IOS"}, {"txt": "Recommendation:", "language": "english", "position": {"atoms": [{"position_id": 379, "txt": "Recommendation:", "x": "/html/body/div/section/p[13]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 19, "global_sentence_id": 45, "edu_l1_label": "IOS"}, {"txt": " either make your language statically typed or dynamically typed (preferably statically typed, but that's a different topic), as gradual typing just doesn't make sense for new languages.", "language": "english", "position": {"atoms": [{"position_id": 381, "txt": " either make your language statically typed or dynamically typed (preferably statically typed, but that's a different topic), as gradual typing just doesn't make sense for new languages.", "x": "/html/body/div/section/p[13]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 19, "global_sentence_id": 46, "edu_l1_label": "IOS"}, {"txt": "The emphasis here is on new languages, as applying gradual typing to an existing language can be useful, especially as an intermediate step towards the language becoming fully statically typed.", "language": "english", "position": {"atoms": [{"position_id": 383, "txt": "The emphasis here is on ", "x": "/html/body/div/section/div[3]/div/p"}, {"position_id": 385, "txt": "new", "x": "/html/body/div/section/div[3]/div/p/em[1]"}, {"position_id": 387, "txt": " languages, as applying gradual typing to an existing language ", "x": "/html/body/div/section/div[3]/div/p/em[1]"}, {"position_id": 389, "txt": "can", "x": "/html/body/div/section/div[3]/div/p/em[2]"}, {"position_id": 391, "txt": " be useful, especially as an intermediate step towards the language becoming fully statically typed.", "x": "/html/body/div/section/div[3]/div/p/em[2]"}]}, "tags": ["em"], "label": "content", "web_segment_id": 20, "global_sentence_id": 47, "edu_l1_label": "IOS"}, {"txt": "Avoid self-hosting your compiler", "language": "english", "position": {"atoms": [{"position_id": 393, "txt": "Avoid self-hosting your compiler", "x": "/html/body/div/section/h2[3]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 21, "global_sentence_id": 48, "edu_l1_label": "IOS"}, {"txt": "Early in the development of Inko, I decided that I wanted to write the compiler in Inko itself, commonly referred to as a \"self-hosted compiler\".", "language": "english", "position": {"atoms": [{"position_id": 395, "txt": "Early in the development of Inko, I decided that I wanted to write the compiler in Inko itself, commonly referred to as a \"self-hosted compiler\".", "x": "/html/body/div/section/p[14]"}]}, "tags": [], "label": "content", "web_segment_id": 22, "global_sentence_id": 49, "edu_l1_label": "IOS"}, {"txt": " The idea was that by doing so, the compiler could be exposed through the standard library, and to have a sufficiently complicated program to test everything Inko has to offer.", "language": "english", "position": {"atoms": [{"position_id": 396, "txt": " The idea was that by doing so, the compiler could be exposed through the standard library, and to have a sufficiently complicated program to test everything Inko has to offer.", "x": "/html/body/div/section/p[14]"}]}, "tags": [], "label": "content", "web_segment_id": 22, "global_sentence_id": 50, "edu_l1_label": "IOS"}, {"txt": "While this seems great on paper, in practise it turns into a real challenge.", "language": "english", "position": {"atoms": [{"position_id": 398, "txt": "While this seems great on paper, in practise it turns into a real challenge.", "x": "/html/body/div/section/p[15]"}]}, "tags": [], "label": "content", "web_segment_id": 23, "global_sentence_id": 51, "edu_l1_label": "IOS"}, {"txt": " Maintaining a single compiler is already a challenge, but maintaining two compilers (one to bootstrap your self-hosted compiler, and the self-hosted compiler itself) is even more difficult.", "language": "english", "position": {"atoms": [{"position_id": 399, "txt": " Maintaining a single compiler is already a challenge, but maintaining two compilers (one to bootstrap your self-hosted compiler, and the self-hosted compiler itself) is even more difficult.", "x": "/html/body/div/section/p[15]"}]}, "tags": [], "label": "content", "web_segment_id": 23, "global_sentence_id": 52, "edu_l1_label": "IOS"}, {"txt": " The process of building the compiler is also more complicated:", "language": "english", "position": {"atoms": [{"position_id": 400, "txt": " The process of building the compiler is also more complicated:", "x": "/html/body/div/section/p[15]"}]}, "tags": [], "label": "content", "web_segment_id": 23, "global_sentence_id": 53, "edu_l1_label": "IOS"}, {"txt": " first you have to build the bootstrapping compiler, then you can use that to build the self-hosted compiler.", "language": "english", "position": {"atoms": [{"position_id": 401, "txt": " first you have to build the bootstrapping compiler, then you can use that to build the self-hosted compiler.", "x": "/html/body/div/section/p[15]"}]}, "tags": [], "label": "content", "web_segment_id": 23, "global_sentence_id": 54, "edu_l1_label": "IOS"}, {"txt": " Ideally you then use that self-hosted compiler to compile itself a second time, so you can ensure the behaviour doesn't subtly change depending on what compiler (the bootstrapping or self-hosted compiler) is used to compile your self-hosted compiler.", "language": "english", "position": {"atoms": [{"position_id": 402, "txt": " Ideally you then use that self-hosted compiler to compile itself a second time, so you can ensure the behaviour doesn't subtly change depending on what compiler (the bootstrapping or self-hosted compiler) is used to compile your self-hosted compiler.", "x": "/html/body/div/section/p[15]"}]}, "tags": [], "label": "content", "web_segment_id": 23, "global_sentence_id": 55, "edu_l1_label": "IOS"}, {"txt": "Because of these challenges, I abandoned this idea in favour of writing the compiler in Rust, and keeping it that way for the foreseeable future.", "language": "english", "position": {"atoms": [{"position_id": 404, "txt": "Because of these challenges, I abandoned this idea in favour of writing the compiler in Rust, and keeping it that way for the foreseeable future.", "x": "/html/body/div/section/p[16]"}]}, "tags": [], "label": "content", "web_segment_id": 24, "global_sentence_id": 56, "edu_l1_label": "IOS"}, {"txt": "Recommendation:", "language": "english", "position": {"atoms": [{"position_id": 406, "txt": "Recommendation:", "x": "/html/body/div/section/p[17]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 25, "global_sentence_id": 57, "edu_l1_label": "IOS"}, {"txt": " defer writing a self-hosted compiler until you have a solid language and ecosystem.", "language": "english", "position": {"atoms": [{"position_id": 408, "txt": " defer writing a self-hosted compiler until you have a solid language and ecosystem.", "x": "/html/body/div/section/p[17]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 25, "global_sentence_id": 58, "edu_l1_label": "IOS"}, {"txt": " A solid language and ecosystem is infinitely more useful to your users than a self-hosted compiler.", "language": "english", "position": {"atoms": [{"position_id": 409, "txt": " A solid language and ecosystem is infinitely more useful to your users than a self-hosted compiler.", "x": "/html/body/div/section/p[17]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 25, "global_sentence_id": 59, "edu_l1_label": "IOS"}, {"txt": "Avoid writing your own code generator, linker, etc", "language": "english", "position": {"atoms": [{"position_id": 411, "txt": "Avoid writing your own code generator, linker, etc", "x": "/html/body/div/section/h2[4]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 26, "global_sentence_id": 60, "edu_l1_label": "BOS"}, {"txt": "When writing a language, it's tempting to take on more than you can or probably should handle.", "language": "english", "position": {"atoms": [{"position_id": 413, "txt": "When writing a language, it's tempting to take on more than you can or probably should handle.", "x": "/html/body/div/section/p[18]"}]}, "tags": [], "label": "content", "web_segment_id": 27, "global_sentence_id": 61, "edu_l1_label": "IOS"}, {"txt": " In particular, it may be tempting to write your own native code generator, linker, C standard library, and so on (i.e what languages such as Zig and Roc are doing).", "language": "english", "position": {"atoms": [{"position_id": 414, "txt": " In particular, it may be tempting to write your own native code generator, linker, C standard library, and so on (i.e what languages such as ", "x": "/html/body/div/section/p[18]"}, {"position_id": 416, "txt": "Zig", "x": "/html/body/div/section/p[18]/a[1]"}, {"position_id": 418, "txt": " and ", "x": "/html/body/div/section/p[18]/a[1]"}, {"position_id": 420, "txt": "Roc", "x": "/html/body/div/section/p[18]/a[2]"}, {"position_id": 422, "txt": " are doing).", "x": "/html/body/div/section/p[18]/a[2]"}]}, "tags": [], "label": "content", "web_segment_id": 27, "global_sentence_id": 62, "edu_l1_label": "IOS"}, {"txt": "My general recommendation is to avoid this unless you have established a clear need for this.", "language": "english", "position": {"atoms": [{"position_id": 424, "txt": "My general recommendation is to avoid this unless you have established a clear need for this.", "x": "/html/body/div/section/p[19]"}]}, "tags": [], "label": "content", "web_segment_id": 28, "global_sentence_id": 63, "edu_l1_label": "IOS"}, {"txt": " And when you do think there's a need, I'd still avoid it.", "language": "english", "position": {"atoms": [{"position_id": 425, "txt": " And when you do think there's a need, I'd still avoid it.", "x": "/html/body/div/section/p[19]"}]}, "tags": [], "label": "content", "web_segment_id": 28, "global_sentence_id": 64, "edu_l1_label": "IOS"}, {"txt": " Writing a language is hard enough as-is and can easily take years.", "language": "english", "position": {"atoms": [{"position_id": 426, "txt": " Writing a language is hard enough as-is and can easily take years.", "x": "/html/body/div/section/p[19]"}]}, "tags": [], "label": "content", "web_segment_id": 28, "global_sentence_id": 65, "edu_l1_label": "IOS"}, {"txt": " For every such component (a linker, a code generator, etc) you add on top, it will take several more years before the stack as a whole becomes useful.", "language": "english", "position": {"atoms": [{"position_id": 427, "txt": " For every such component (a linker, a code generator, etc) you add on top, it will take several more years before the stack as a whole becomes useful.", "x": "/html/body/div/section/p[19]"}]}, "tags": [], "label": "content", "web_segment_id": 28, "global_sentence_id": 66, "edu_l1_label": "IOS"}, {"txt": " That's ignoring the painful fact that such bespoke components are highly unlikely to outperform the established alternatives.", "language": "english", "position": {"atoms": [{"position_id": 428, "txt": " That's ignoring the painful fact that such bespoke components are highly unlikely to outperform the established alternatives.", "x": "/html/body/div/section/p[19]"}]}, "tags": [], "label": "content", "web_segment_id": 28, "global_sentence_id": 67, "edu_l1_label": "IOS"}, {"txt": "Recommendation:", "language": "english", "position": {"atoms": [{"position_id": 430, "txt": "Recommendation:", "x": "/html/body/div/section/p[20]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 29, "global_sentence_id": 68, "edu_l1_label": "IOS"}, {"txt": " there are many developers who think they can write a better linker, code generator, and so on, but few developers who actually succeed in doing so.", "language": "english", "position": {"atoms": [{"position_id": 432, "txt": " there are many developers who think they can write a better linker, code generator, and so on, but few developers who actually succeed in doing so.", "x": "/html/body/div/section/p[20]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 29, "global_sentence_id": 69, "edu_l1_label": "IOS"}, {"txt": " As harsh as it may sound, you are probably not one of them.", "language": "english", "position": {"atoms": [{"position_id": 433, "txt": " As harsh as it may sound, you are probably not one of them.", "x": "/html/body/div/section/p[20]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 29, "global_sentence_id": 70, "edu_l1_label": "IOS"}, {"txt": " Of course once you have an established language, you're free to reinvent as many of these wheels as you see fit.", "language": "english", "position": {"atoms": [{"position_id": 434, "txt": " Of course once you have an established language, you're free to reinvent as many of these wheels as you see fit.", "x": "/html/body/div/section/p[20]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 29, "global_sentence_id": 71, "edu_l1_label": "IOS"}, {"txt": "If you're writing an interpreted language, it's fine and probably even needed to write your own (byte)code generator (unless you target an existing virtual machine such as the JVM), as bytecode generators are typically not that complicated to implement.", "language": "english", "position": {"atoms": [{"position_id": 436, "txt": "If you're writing an interpreted language, it's fine and probably even needed to write your own (byte)code generator (unless you target an existing virtual machine such as the JVM), as bytecode generators are typically not that complicated to implement.", "x": "/html/body/div/section/div[4]/div/p"}]}, "tags": [], "label": "content", "web_segment_id": 30, "global_sentence_id": 72, "edu_l1_label": "IOS"}, {"txt": "Avoid bike shedding about syntax", "language": "english", "position": {"atoms": [{"position_id": 438, "txt": "Avoid bike shedding about syntax", "x": "/html/body/div/section/h2[5]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 31, "global_sentence_id": 73, "edu_l1_label": "IOS"}, {"txt": "The syntax of a language and how its parsed is one of the most boring aspects of building a language.", "language": "english", "position": {"atoms": [{"position_id": 440, "txt": "The syntax of a language and how its parsed is one of the most boring aspects of building a language.", "x": "/html/body/div/section/p[21]"}]}, "tags": [], "label": "content", "web_segment_id": 32, "global_sentence_id": 74, "edu_l1_label": "IOS"}, {"txt": " Writing parsers in general is pretty dull, and there's not a lot you can innovate upon.", "language": "english", "position": {"atoms": [{"position_id": 441, "txt": " Writing parsers in general is pretty dull, and there's not a lot you can innovate upon.", "x": "/html/body/div/section/p[21]"}]}, "tags": [], "label": "content", "web_segment_id": 32, "global_sentence_id": 75, "edu_l1_label": "IOS"}, {"txt": "And yet, it's a subject many developers building their own language seem to spend way too much time on.", "language": "english", "position": {"atoms": [{"position_id": 443, "txt": "And yet, it's a subject many developers building their own language seem to spend ", "x": "/html/body/div/section/p[22]"}, {"position_id": 445, "txt": "way", "x": "/html/body/div/section/p[22]/em"}, {"position_id": 447, "txt": " too much time on.", "x": "/html/body/div/section/p[22]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 33, "global_sentence_id": 76, "edu_l1_label": "IOS"}, {"txt": " There are also plenty of articles titled something along the lines of \"How to build your own programming language\", only covering the basics of writing a parser and nothing more.", "language": "english", "position": {"atoms": [{"position_id": 448, "txt": " There are also plenty of articles titled something along the lines of \"How to build your own programming language\", only covering the basics of writing a parser and nothing more.", "x": "/html/body/div/section/p[22]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 33, "global_sentence_id": 77, "edu_l1_label": "IOS"}, {"txt": "For Inko I took a different approach in its early days:", "language": "english", "position": {"atoms": [{"position_id": 450, "txt": "For Inko I took a different approach in its early days:", "x": "/html/body/div/section/p[23]"}]}, "tags": [], "label": "content", "web_segment_id": 34, "global_sentence_id": 78, "edu_l1_label": "IOS"}, {"txt": " I used an S-expression syntax, instead of designing my own syntax and writing a parser for it.", "language": "english", "position": {"atoms": [{"position_id": 451, "txt": " I used an ", "x": "/html/body/div/section/p[23]"}, {"position_id": 453, "txt": "S-expression", "x": "/html/body/div/section/p[23]/a"}, {"position_id": 455, "txt": " syntax, instead of designing my own syntax and writing a parser for it.", "x": "/html/body/div/section/p[23]/a"}]}, "tags": [], "label": "content", "web_segment_id": 34, "global_sentence_id": 79, "edu_l1_label": "IOS"}, {"txt": " This meant I was able to experiment with the semantics and virtual machine of the language, instead of worrying over what keyword to use for function definitions.", "language": "english", "position": {"atoms": [{"position_id": 456, "txt": " This meant I was able to experiment with the semantics and virtual machine of the language, instead of worrying over what keyword to use for function definitions.", "x": "/html/body/div/section/p[23]/a"}]}, "tags": [], "label": "content", "web_segment_id": 34, "global_sentence_id": 80, "edu_l1_label": "IOS"}, {"txt": "Recommendation:", "language": "english", "position": {"atoms": [{"position_id": 458, "txt": "Recommendation:", "x": "/html/body/div/section/p[24]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 35, "global_sentence_id": 81, "edu_l1_label": "IOS"}, {"txt": " use an existing syntax and parser when prototyping your language, allowing you to focus on the semantics instead of the syntax.", "language": "english", "position": {"atoms": [{"position_id": 460, "txt": " use an existing syntax and parser when prototyping your language, allowing you to focus on the semantics instead of the syntax.", "x": "/html/body/div/section/p[24]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 35, "global_sentence_id": 82, "edu_l1_label": "IOS"}, {"txt": " Once you develop a better understanding of your language you can switch to your own syntax.", "language": "english", "position": {"atoms": [{"position_id": 461, "txt": " Once you develop a better understanding of your language you can switch to your own syntax.", "x": "/html/body/div/section/p[24]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 35, "global_sentence_id": 83, "edu_l1_label": "IOS"}, {"txt": "Cross-platform support is a challenge", "language": "english", "position": {"atoms": [{"position_id": 463, "txt": "Cross-platform support is a challenge", "x": "/html/body/div/section/h2[6]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 36, "global_sentence_id": 84, "edu_l1_label": "BOS"}, {"txt": "This shouldn't be entirely surprising, but supporting different platforms (Linux, macOS, Windows, etc) is hard.", "language": "english", "position": {"atoms": [{"position_id": 465, "txt": "This shouldn't be entirely surprising, but supporting different platforms (Linux, macOS, Windows, etc) is ", "x": "/html/body/div/section/p[25]"}, {"position_id": 467, "txt": "hard", "x": "/html/body/div/section/p[25]/em"}, {"position_id": 469, "txt": ".", "x": "/html/body/div/section/p[25]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 37, "global_sentence_id": 85, "edu_l1_label": "IOS"}, {"txt": " For example, Inko used to support Windows when it used an interpreter.", "language": "english", "position": {"atoms": [{"position_id": 470, "txt": " For example, Inko used to support Windows when it used an interpreter.", "x": "/html/body/div/section/p[25]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 37, "global_sentence_id": 86, "edu_l1_label": "IOS"}, {"txt": " When switching to a compiled language, I had to drop support for Windows as I couldn't get certain things to work (e.g. the assembly used for switching thread stacks).", "language": "english", "position": {"atoms": [{"position_id": 471, "txt": " When switching to a compiled language, I had to drop support for Windows as I couldn't get certain things to work (e.g. the assembly used for switching thread stacks).", "x": "/html/body/div/section/p[25]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 37, "global_sentence_id": 87, "edu_l1_label": "IOS"}, {"txt": "Running tests on different platforms is also not nearly as easy as it should be.", "language": "english", "position": {"atoms": [{"position_id": 473, "txt": "Running tests on different platforms is also not nearly as easy as it should be.", "x": "/html/body/div/section/p[26]"}]}, "tags": [], "label": "content", "web_segment_id": 38, "global_sentence_id": 88, "edu_l1_label": "IOS"}, {"txt": " Take GitHub Actions:", "language": "english", "position": {"atoms": [{"position_id": 474, "txt": " Take ", "x": "/html/body/div/section/p[26]"}, {"position_id": 476, "txt": "GitHub Actions", "x": "/html/body/div/section/p[26]/a"}, {"position_id": 478, "txt": ":", "x": "/html/body/div/section/p[26]/a"}]}, "tags": [], "label": "content", "web_segment_id": 38, "global_sentence_id": 89, "edu_l1_label": "IOS"}, {"txt": " you can use it to run tests on Linux, macOS, and Windows.", "language": "english", "position": {"atoms": [{"position_id": 479, "txt": " you can use it to run tests on Linux, macOS, and Windows.", "x": "/html/body/div/section/p[26]/a"}]}, "tags": [], "label": "content", "web_segment_id": 38, "global_sentence_id": 90, "edu_l1_label": "IOS"}, {"txt": " Unfortunately, the free tier (at the time of writing) only supports AMD64 runners, and while it does support macOS ARM64 runners, these cost $0.16 per minute.", "language": "english", "position": {"atoms": [{"position_id": 480, "txt": " Unfortunately, the free tier (at the time of writing) only supports AMD64 runners, and while it ", "x": "/html/body/div/section/p[26]/a"}, {"position_id": 482, "txt": "does", "x": "/html/body/div/section/p[26]/em"}, {"position_id": 484, "txt": " support macOS ARM64 runners, these cost $0.16 per minute.", "x": "/html/body/div/section/p[26]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 38, "global_sentence_id": 91, "edu_l1_label": "IOS"}, {"txt": "The cost isn't even the biggest problem here, because depending on how often tests run it may not be that big.", "language": "english", "position": {"atoms": [{"position_id": 486, "txt": "The cost isn't even the biggest problem here, because depending on how often tests run it may not be that big.", "x": "/html/body/div/section/p[27]"}]}, "tags": [], "label": "content", "web_segment_id": 39, "global_sentence_id": 92, "edu_l1_label": "IOS"}, {"txt": " Rather, the problem is that paid runners typically aren't available for forks, meaning pull requests from third-party contributors won't be able to run the tests using these runners.", "language": "english", "position": {"atoms": [{"position_id": 487, "txt": " Rather, the problem is that paid runners typically aren't available for forks, meaning pull requests from third-party contributors won't be able to run the tests using these runners.", "x": "/html/body/div/section/p[27]"}]}, "tags": [], "label": "content", "web_segment_id": 39, "global_sentence_id": 93, "edu_l1_label": "IOS"}, {"txt": "And this is ignoring the problem of supporting platforms not supported by your continuous integration platform (e.g. GitHub Actions) of choice.", "language": "english", "position": {"atoms": [{"position_id": 489, "txt": "And this is ignoring the problem of supporting platforms not supported by your continuous integration platform (e.g. GitHub Actions) of choice.", "x": "/html/body/div/section/p[28]"}]}, "tags": [], "label": "content", "web_segment_id": 40, "global_sentence_id": 94, "edu_l1_label": "IOS"}, {"txt": " FreeBSD is a good example of this:", "language": "english", "position": {"atoms": [{"position_id": 490, "txt": " FreeBSD is a good example of this:", "x": "/html/body/div/section/p[28]"}]}, "tags": [], "label": "content", "web_segment_id": 40, "global_sentence_id": 95, "edu_l1_label": "IOS"}, {"txt": " GitHub Actions just doesn't support it, so you need to use qemu or similar software to run FreeBSD in a VM.", "language": "english", "position": {"atoms": [{"position_id": 491, "txt": " GitHub Actions just doesn't support it, so you need to use ", "x": "/html/body/div/section/p[28]"}, {"position_id": 493, "txt": "qemu", "x": "/html/body/div/section/p[28]/a"}, {"position_id": 495, "txt": " or similar software to run FreeBSD in a VM.", "x": "/html/body/div/section/p[28]/a"}]}, "tags": [], "label": "content", "web_segment_id": 40, "global_sentence_id": 96, "edu_l1_label": "IOS"}, {"txt": "Even if you just support Linux, you still have to deal with the differences between Linux distributions.", "language": "english", "position": {"atoms": [{"position_id": 497, "txt": "Even if you ", "x": "/html/body/div/section/p[29]"}, {"position_id": 499, "txt": "just", "x": "/html/body/div/section/p[29]/em"}, {"position_id": 501, "txt": " support Linux, you still have to deal with the differences between Linux distributions.", "x": "/html/body/div/section/p[29]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 41, "global_sentence_id": 97, "edu_l1_label": "IOS"}, {"txt": " For example, Inko uses a Rust wrapper for LLVM (Inkwell), but the low-level LLVM wrapper (llvm-sys) it uses doesn't compile on Alpine Linux, and so Inko doesn't support Alpine Linux for the time being.", "language": "english", "position": {"atoms": [{"position_id": 502, "txt": " For example, Inko uses a Rust wrapper for LLVM (", "x": "/html/body/div/section/p[29]/em"}, {"position_id": 504, "txt": "Inkwell", "x": "/html/body/div/section/p[29]/a[1]"}, {"position_id": 506, "txt": "), but the low-level LLVM wrapper (", "x": "/html/body/div/section/p[29]/a[1]"}, {"position_id": 508, "txt": "llvm-sys", "x": "/html/body/div/section/p[29]/a[2]"}, {"position_id": 510, "txt": ") it uses ", "x": "/html/body/div/section/p[29]/a[2]"}, {"position_id": 512, "txt": "doesn't compile on Alpine Linux", "x": "/html/body/div/section/p[29]/a[3]"}, {"position_id": 514, "txt": ", and so Inko doesn't support Alpine Linux for the time being.", "x": "/html/body/div/section/p[29]/a[3]"}]}, "tags": ["em"], "label": "content", "web_segment_id": 41, "global_sentence_id": 98, "edu_l1_label": "IOS"}, {"txt": "The extend to which this is a problem depends on the language you're trying to build.", "language": "english", "position": {"atoms": [{"position_id": 516, "txt": "The extend to which this is a problem depends on the language you're trying to build.", "x": "/html/body/div/section/p[30]"}]}, "tags": [], "label": "content", "web_segment_id": 42, "global_sentence_id": 99, "edu_l1_label": "IOS"}, {"txt": " For example, if you're building an interpreter written in Rust it probably won't be that bad (though Windows is always going to be a challenge), but it is something you need to be prepared for.", "language": "english", "position": {"atoms": [{"position_id": 517, "txt": " For example, if you're building an interpreter written in Rust it probably won't be that bad (though Windows is always going to be a challenge), but it ", "x": "/html/body/div/section/p[30]"}, {"position_id": 519, "txt": "is", "x": "/html/body/div/section/p[30]/em"}, {"position_id": 521, "txt": " something you need to be prepared for.", "x": "/html/body/div/section/p[30]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 42, "global_sentence_id": 100, "edu_l1_label": "IOS"}, {"txt": "Recommendation:", "language": "english", "position": {"atoms": [{"position_id": 523, "txt": "Recommendation:", "x": "/html/body/div/section/p[31]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 43, "global_sentence_id": 101, "edu_l1_label": "IOS"}, {"txt": " if you're uncertain about supporting a certain platform, err on the side of not supporting it and document this, instead of sort-of-but-not-quite supporting it.", "language": "english", "position": {"atoms": [{"position_id": 525, "txt": " if you're uncertain about supporting a certain platform, err on the side of not supporting it and document this, instead of sort-of-but-not-quite supporting it.", "x": "/html/body/div/section/p[31]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 43, "global_sentence_id": 102, "edu_l1_label": "IOS"}, {"txt": "Compiler books aren't worth the money", "language": "english", "position": {"atoms": [{"position_id": 527, "txt": "Compiler books aren't worth the money", "x": "/html/body/div/section/h2[7]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 44, "global_sentence_id": 103, "edu_l1_label": "BOS"}, {"txt": "While there are plenty of books on compiler development, they tend to not be that useful.", "language": "english", "position": {"atoms": [{"position_id": 529, "txt": "While there are plenty of books on compiler development, they tend to not be that useful.", "x": "/html/body/div/section/p[32]"}]}, "tags": [], "label": "content", "web_segment_id": 45, "global_sentence_id": 104, "edu_l1_label": "IOS"}, {"txt": " In particular, such books tend to dedicate a significant amount of time to parsing, arguably the most boring part of a compiler, then only briefly cover the more interesting topics such as optimizations.", "language": "english", "position": {"atoms": [{"position_id": 530, "txt": " In particular, such books tend to dedicate a significant amount of time to parsing, arguably the most boring part of a compiler, then only briefly cover the more interesting topics such as optimizations.", "x": "/html/body/div/section/p[32]"}]}, "tags": [], "label": "content", "web_segment_id": 45, "global_sentence_id": 105, "edu_l1_label": "IOS"}, {"txt": " Oh, and good luck finding a book that explains how to write a type-checker, let alone one that covers more practical topics such as supporting sub-typing, generics, and so on.", "language": "english", "position": {"atoms": [{"position_id": 531, "txt": " Oh, and good luck finding a book that explains how to write a type-checker, let alone one that covers more practical topics such as supporting sub-typing, generics, and so on.", "x": "/html/body/div/section/p[32]"}]}, "tags": [], "label": "content", "web_segment_id": 45, "global_sentence_id": 106, "edu_l1_label": "IOS"}, {"txt": "Recommendation:", "language": "english", "position": {"atoms": [{"position_id": 533, "txt": "Recommendation:", "x": "/html/body/div/section/p[33]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 46, "global_sentence_id": 107, "edu_l1_label": "IOS"}, {"txt": " start with reading Crafting Interpreters, and read through /r/ProgrammingLanguages on Reddit.", "language": "english", "position": {"atoms": [{"position_id": 535, "txt": " start with reading ", "x": "/html/body/div/section/p[33]/strong"}, {"position_id": 537, "txt": "Crafting Interpreters", "x": "/html/body/div/section/p[33]/a[1]"}, {"position_id": 539, "txt": ", and read through ", "x": "/html/body/div/section/p[33]/a[1]"}, {"position_id": 541, "txt": "/r/ProgrammingLanguages", "x": "/html/body/div/section/p[33]/a[2]"}, {"position_id": 543, "txt": " on Reddit.", "x": "/html/body/div/section/p[33]/a[2]"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 46, "global_sentence_id": 108, "edu_l1_label": "IOS"}, {"txt": " If you're interested in learning more about pattern matching, this Git repository may prove useful.", "language": "english", "position": {"atoms": [{"position_id": 544, "txt": " If you're interested in learning more about pattern matching, ", "x": "/html/body/div/section/p[33]/a[2]"}, {"position_id": 546, "txt": "this Git repository may prove useful", "x": "/html/body/div/section/p[33]/a[3]"}, {"position_id": 548, "txt": ".", "x": "/html/body/div/section/p[33]/a[3]"}]}, "tags": [], "label": "content", "web_segment_id": 46, "global_sentence_id": 109, "edu_l1_label": "IOS"}, {"txt": "Growing a language is hard", "language": "english", "position": {"atoms": [{"position_id": 550, "txt": "Growing a language is hard", "x": "/html/body/div/section/h2[8]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 47, "global_sentence_id": 110, "edu_l1_label": "BOS"}, {"txt": "Building a language is a significant challenge on its own.", "language": "english", "position": {"atoms": [{"position_id": 552, "txt": "Building a language is a significant challenge on its own.", "x": "/html/body/div/section/p[34]"}]}, "tags": [], "label": "content", "web_segment_id": 48, "global_sentence_id": 111, "edu_l1_label": "IOS"}, {"txt": " Growing the number of users using your language and the libraries written in your language?", "language": "english", "position": {"atoms": [{"position_id": 553, "txt": " Growing the number of users using your language and the libraries written in your language?", "x": "/html/body/div/section/p[34]"}]}, "tags": [], "label": "content", "web_segment_id": 48, "global_sentence_id": 112, "edu_l1_label": "IOS"}, {"txt": " That's even more difficult.", "language": "english", "position": {"atoms": [{"position_id": 554, "txt": " That's even more difficult.", "x": "/html/body/div/section/p[34]"}]}, "tags": [], "label": "content", "web_segment_id": 48, "global_sentence_id": 113, "edu_l1_label": "IOS"}, {"txt": " In particular, it seems languages either explode in terms of popularity/interest, even if that may not be warranted (looking at you, V), or it takes years for them to get even a handful of users.", "language": "english", "position": {"atoms": [{"position_id": 555, "txt": " In particular, it seems languages either explode in terms of popularity/interest, even if that may not be warranted (looking at you, ", "x": "/html/body/div/section/p[34]"}, {"position_id": 557, "txt": "V", "x": "/html/body/div/section/p[34]/a"}, {"position_id": 559, "txt": "), or it takes ", "x": "/html/body/div/section/p[34]/a"}, {"position_id": 561, "txt": "years", "x": "/html/body/div/section/p[34]/em"}, {"position_id": 563, "txt": " for them to get even a handful of users.", "x": "/html/body/div/section/p[34]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 48, "global_sentence_id": 114, "edu_l1_label": "IOS"}, {"txt": "Making a living off a programming language is exceptionally difficult, as the number of people willing to donate money is even smaller than those willing to try out your new language.", "language": "english", "position": {"atoms": [{"position_id": 565, "txt": "Making a living off a programming language is ", "x": "/html/body/div/section/p[35]"}, {"position_id": 567, "txt": "exceptionally", "x": "/html/body/div/section/p[35]/em"}, {"position_id": 569, "txt": " difficult, as the number of people willing to donate money is even smaller than those willing to try out your new language.", "x": "/html/body/div/section/p[35]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 49, "global_sentence_id": 115, "edu_l1_label": "IOS"}, {"txt": " This means either dedicating a lot of spare time towards building your language, or quitting your job and funding the development yourself (e.g. using your savings).", "language": "english", "position": {"atoms": [{"position_id": 570, "txt": " This means either dedicating a lot of spare time towards building your language, or quitting your job and funding the development yourself (e.g. using your savings).", "x": "/html/body/div/section/p[35]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 49, "global_sentence_id": 116, "edu_l1_label": "IOS"}, {"txt": " This is what I did by the end of 2021 and while I don't regret doing so, it's a bit painful to watch your wallet shrink over time.", "language": "english", "position": {"atoms": [{"position_id": 571, "txt": " This is what I did by the end of 2021 and while I don't regret doing so, it's a bit painful to watch your wallet shrink over time.", "x": "/html/body/div/section/p[35]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 49, "global_sentence_id": 117, "edu_l1_label": "IOS"}, {"txt": "As far as advice goes, I'm not sure how to approach this as I'm still figuring that out myself.", "language": "english", "position": {"atoms": [{"position_id": 573, "txt": "As far as advice goes, I'm not sure how to approach this as I'm still figuring that out myself.", "x": "/html/body/div/section/p[36]"}]}, "tags": [], "label": "content", "web_segment_id": 50, "global_sentence_id": 118, "edu_l1_label": "IOS"}, {"txt": " What I do know is that a lot of existing advice isn't helpful at all, as it amounts to \"Just get more users, LOL\".", "language": "english", "position": {"atoms": [{"position_id": 574, "txt": " What I do know is that a lot of existing advice isn't helpful at all, as it amounts to \"Just get more users, LOL\".", "x": "/html/body/div/section/p[36]"}]}, "tags": [], "label": "content", "web_segment_id": 50, "global_sentence_id": 119, "edu_l1_label": "IOS"}, {"txt": " Perhaps in another 10 years from now I'll know the answer.", "language": "english", "position": {"atoms": [{"position_id": 575, "txt": " Perhaps in another 10 years from now I'll know the answer.", "x": "/html/body/div/section/p[36]"}]}, "tags": [], "label": "content", "web_segment_id": 50, "global_sentence_id": 120, "edu_l1_label": "IOS"}, {"txt": "The best test suite is a real application", "language": "english", "position": {"atoms": [{"position_id": 577, "txt": "The best test suite is a real application", "x": "/html/body/div/section/h2[9]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 51, "global_sentence_id": 121, "edu_l1_label": "BOS"}, {"txt": "This one is a bit obvious, but worth highlighting regardless:", "language": "english", "position": {"atoms": [{"position_id": 579, "txt": "This one is a bit obvious, but worth highlighting regardless:", "x": "/html/body/div/section/p[37]"}]}, "tags": [], "label": "content", "web_segment_id": 52, "global_sentence_id": 122, "edu_l1_label": "IOS"}, {"txt": " writing unit tests for your language (e.g. for the standard library functions) is important and useful, but nowhere near as useful as writing a real application in the language.", "language": "english", "position": {"atoms": [{"position_id": 580, "txt": " writing unit tests for your language (e.g. for the standard library functions) is important and useful, but nowhere near as useful as writing a real application in the language.", "x": "/html/body/div/section/p[37]"}]}, "tags": [], "label": "content", "web_segment_id": 52, "global_sentence_id": 123, "edu_l1_label": "IOS"}, {"txt": " For example, I wrote a program to control my house's HVAC system in Inko, revealing various bugs and areas of improvement in the process.", "language": "english", "position": {"atoms": [{"position_id": 581, "txt": " For example, I wrote a program to ", "x": "/html/body/div/section/p[37]"}, {"position_id": 583, "txt": "control my house's HVAC system", "x": "/html/body/div/section/p[37]/a"}, {"position_id": 585, "txt": " in Inko, revealing various bugs and areas of improvement in the process.", "x": "/html/body/div/section/p[37]/a"}]}, "tags": [], "label": "content", "web_segment_id": 52, "global_sentence_id": 124, "edu_l1_label": "IOS"}, {"txt": " Such applications also act as a showcase for your language, making it easier for potential users to develop an understanding of what an average project in your language might look like.", "language": "english", "position": {"atoms": [{"position_id": 586, "txt": " Such applications also act as a showcase for your language, making it easier for potential users to develop an understanding of what an average project in your language might look like.", "x": "/html/body/div/section/p[37]/a"}]}, "tags": [], "label": "content", "web_segment_id": 52, "global_sentence_id": 125, "edu_l1_label": "IOS"}, {"txt": "Recommendation:", "language": "english", "position": {"atoms": [{"position_id": 588, "txt": "Recommendation:", "x": "/html/body/div/section/p[38]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 53, "global_sentence_id": 126, "edu_l1_label": "IOS"}, {"txt": " write a few sufficiently complicated programs that are actually useful in your language, then use these as a way of testing functionality and stability of your language.", "language": "english", "position": {"atoms": [{"position_id": 590, "txt": " write a few sufficiently complicated programs that are actually useful in your language, then use these as a way of testing functionality and stability of your language.", "x": "/html/body/div/section/p[38]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 53, "global_sentence_id": 127, "edu_l1_label": "IOS"}, {"txt": " If you can't think of any programs to write, consider porting this changelog generator written in Inko, as it's complex enough to act as a good stress test for your language, but not so complex it will take weeks to port.", "language": "english", "position": {"atoms": [{"position_id": 591, "txt": " If you can't think of any programs to write, consider porting ", "x": "/html/body/div/section/p[38]/strong"}, {"position_id": 593, "txt": "this changelog generator written in Inko", "x": "/html/body/div/section/p[38]/a"}, {"position_id": 595, "txt": ", as it's complex enough to act as a good stress test for your language, but not so complex it will take weeks to port.", "x": "/html/body/div/section/p[38]/a"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 53, "global_sentence_id": 128, "edu_l1_label": "IOS"}, {"txt": "Don't prioritize performance over functionality", "language": "english", "position": {"atoms": [{"position_id": 597, "txt": "Don't prioritize performance over functionality", "x": "/html/body/div/section/h2[10]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 54, "global_sentence_id": 129, "edu_l1_label": "BOS"}, {"txt": "When building a language, it can be tempting to focus heavily on providing a fast implementation, such as a fast and memory efficient compiler, and one can easily spend months working on this.", "language": "english", "position": {"atoms": [{"position_id": 599, "txt": "When building a language, it can be tempting to focus heavily on providing a fast implementation, such as a fast and memory efficient compiler, and one can easily spend months working on this.", "x": "/html/body/div/section/p[39]"}]}, "tags": [], "label": "content", "web_segment_id": 55, "global_sentence_id": 130, "edu_l1_label": "IOS"}, {"txt": " Potential users of your language may care about performance to some degree, but what they care about more is being able to use your language, write libraries in it, and not having to reimplement every basic feature themselves because of a lacking standard library.", "language": "english", "position": {"atoms": [{"position_id": 600, "txt": " Potential users of your language may care about performance to some degree, but what they care about more is being able to ", "x": "/html/body/div/section/p[39]"}, {"position_id": 602, "txt": "use", "x": "/html/body/div/section/p[39]/em"}, {"position_id": 604, "txt": " your language, write libraries in it, and not having to reimplement every basic feature themselves because of a lacking standard library.", "x": "/html/body/div/section/p[39]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 55, "global_sentence_id": 131, "edu_l1_label": "IOS"}, {"txt": "To put it differently:", "language": "english", "position": {"atoms": [{"position_id": 606, "txt": "To put it differently:", "x": "/html/body/div/section/p[40]"}]}, "tags": [], "label": "content", "web_segment_id": 56, "global_sentence_id": 132, "edu_l1_label": "IOS"}, {"txt": " the value of good performance is proportional to the amount of meaningful code (= real applications) written in a language.", "language": "english", "position": {"atoms": [{"position_id": 607, "txt": " the value of good performance is proportional to the amount of meaningful code (= real applications) written in a language.", "x": "/html/body/div/section/p[40]"}]}, "tags": [], "label": "content", "web_segment_id": 56, "global_sentence_id": 133, "edu_l1_label": "IOS"}, {"txt": "Recommendation:", "language": "english", "position": {"atoms": [{"position_id": 609, "txt": "Recommendation:", "x": "/html/body/div/section/p[41]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 57, "global_sentence_id": 134, "edu_l1_label": "IOS"}, {"txt": " as the saying goes:", "language": "english", "position": {"atoms": [{"position_id": 611, "txt": " as the saying goes:", "x": "/html/body/div/section/p[41]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 57, "global_sentence_id": 135, "edu_l1_label": "IOS"}, {"txt": " first make it work, then make it fast.", "language": "english", "position": {"atoms": [{"position_id": 612, "txt": " first make it work, then make it fast.", "x": "/html/body/div/section/p[41]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 57, "global_sentence_id": 136, "edu_l1_label": "IOS"}, {"txt": " This doesn't mean you should not care about performance at all, rather 70-80% of your energy should be directed towards functionality, with the remaining 20-30% directed towards making the language not unreasonably slow.", "language": "english", "position": {"atoms": [{"position_id": 613, "txt": " This doesn't mean you should not care about performance at all, rather 70-80% of your energy should be directed towards functionality, with the remaining 20-30% directed towards making the language not unreasonably slow.", "x": "/html/body/div/section/p[41]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 57, "global_sentence_id": 137, "edu_l1_label": "IOS"}, {"txt": "Building a language takes time", "language": "english", "position": {"atoms": [{"position_id": 615, "txt": "Building a language takes time", "x": "/html/body/div/section/h2[11]"}]}, "tags": ["h2"], "label": "title1", "web_segment_id": 58, "global_sentence_id": 138, "edu_l1_label": "BOS"}, {"txt": "To wrap things up, here's another observation that should be obvious but is worth bringing up regardless:", "language": "english", "position": {"atoms": [{"position_id": 617, "txt": "To wrap things up, here's another observation that should be obvious but is worth bringing up regardless:", "x": "/html/body/div/section/p[42]"}]}, "tags": [], "label": "content", "web_segment_id": 59, "global_sentence_id": 139, "edu_l1_label": "IOS"}, {"txt": " building a simple language for yourself in a short amount of time is doable.", "language": "english", "position": {"atoms": [{"position_id": 618, "txt": " building a simple language for yourself in a short amount of time is doable.", "x": "/html/body/div/section/p[42]"}]}, "tags": [], "label": "content", "web_segment_id": 59, "global_sentence_id": 140, "edu_l1_label": "IOS"}, {"txt": " Building a language meant to be used by many for many years to come is going to take a long time.", "language": "english", "position": {"atoms": [{"position_id": 619, "txt": " Building a language meant to be used by many for many years to come is going to take a ", "x": "/html/body/div/section/p[42]"}, {"position_id": 621, "txt": "long", "x": "/html/body/div/section/p[42]/em"}, {"position_id": 623, "txt": " time.", "x": "/html/body/div/section/p[42]/em"}]}, "tags": ["em"], "label": "content", "web_segment_id": 59, "global_sentence_id": 141, "edu_l1_label": "IOS"}, {"txt": " To illustrate, here are some examples of a few languages and when they released their first stable release (a ?", "language": "english", "position": {"atoms": [{"position_id": 624, "txt": " To illustrate, here are some examples of a few languages and when they released their first stable release (a ", "x": "/html/body/div/section/p[42]/em"}, {"position_id": 626, "txt": "?", "x": "/html/body/div/section/p[42]/code"}]}, "tags": ["em"], "label": "content", "web_segment_id": 59, "global_sentence_id": 142, "edu_l1_label": "IOS"}, {"txt": " indicates no stable release is available at the time of writing):", "language": "english", "position": {"atoms": [{"position_id": 628, "txt": " indicates no stable release is available at the time of writing):", "x": "/html/body/div/section/p[42]/code"}]}, "tags": [], "label": "content", "web_segment_id": 59, "global_sentence_id": 143, "edu_l1_label": "IOS"}, {"txt": "<table <table position_id=\"163\"><thead position_id=\"164\"><tr position_id=\"165\"><th position_id=\"166\">Language</th><th position_id=\"167\">Started in</th><th position_id=\"168\">Release of 1.0.0</th></tr></thead><tbody position_id=\"169\"><tr position_id=\"170\"><td position_id=\"171\">Python</td><td position_id=\"172\">1989</td><td position_id=\"173\">1994</td></tr><tr position_id=\"174\"><td position_id=\"175\">Ruby</td><td position_id=\"176\">1993</td><td position_id=\"177\">1996</td></tr><tr position_id=\"178\"><td position_id=\"179\">Scala</td><td position_id=\"180\">2001</td><td position_id=\"181\">2004</td></tr><tr position_id=\"182\"><td position_id=\"183\">Rust</td><td position_id=\"184\">2006</td><td position_id=\"185\">2015</td></tr><tr position_id=\"186\"><td position_id=\"187\">Go</td><td position_id=\"188\">2007</td><td position_id=\"189\">2012</td></tr><tr position_id=\"190\"><td position_id=\"191\">Elixir</td><td position_id=\"192\">2011</td><td position_id=\"193\">2014</td></tr><tr position_id=\"194\"><td position_id=\"195\">Crystal</td><td position_id=\"196\">2011</td><td position_id=\"197\">2021</td></tr><tr position_id=\"198\"><td position_id=\"199\">Vale</td><td position_id=\"200\">2012</td><td position_id=\"201\">?</td></tr><tr position_id=\"202\"><td position_id=\"203\">Inko</td><td position_id=\"204\">2013</td><td position_id=\"205\">?</td></tr><tr position_id=\"206\"><td position_id=\"207\">Gleam</td><td position_id=\"208\">2016</td><td position_id=\"209\">?</td></tr><tr position_id=\"210\"><td position_id=\"211\">V</td><td position_id=\"212\">2019</td><td position_id=\"213\">?</td></tr></tbody></table>", "language": "english", "position": {"atoms": [{"position_id": 163, "txt": "<table <table position_id=\"163\"><thead position_id=\"164\"><tr position_id=\"165\"><th position_id=\"166\">Language</th><th position_id=\"167\">Started in</th><th position_id=\"168\">Release of 1.0.0</th></tr></thead><tbody position_id=\"169\"><tr position_id=\"170\"><td position_id=\"171\">Python</td><td position_id=\"172\">1989</td><td position_id=\"173\">1994</td></tr><tr position_id=\"174\"><td position_id=\"175\">Ruby</td><td position_id=\"176\">1993</td><td position_id=\"177\">1996</td></tr><tr position_id=\"178\"><td position_id=\"179\">Scala</td><td position_id=\"180\">2001</td><td position_id=\"181\">2004</td></tr><tr position_id=\"182\"><td position_id=\"183\">Rust</td><td position_id=\"184\">2006</td><td position_id=\"185\">2015</td></tr><tr position_id=\"186\"><td position_id=\"187\">Go</td><td position_id=\"188\">2007</td><td position_id=\"189\">2012</td></tr><tr position_id=\"190\"><td position_id=\"191\">Elixir</td><td position_id=\"192\">2011</td><td position_id=\"193\">2014</td></tr><tr position_id=\"194\"><td position_id=\"195\">Crystal</td><td position_id=\"196\">2011</td><td position_id=\"197\">2021</td></tr><tr position_id=\"198\"><td position_id=\"199\">Vale</td><td position_id=\"200\">2012</td><td position_id=\"201\">?</td></tr><tr position_id=\"202\"><td position_id=\"203\">Inko</td><td position_id=\"204\">2013</td><td position_id=\"205\">?</td></tr><tr position_id=\"206\"><td position_id=\"207\">Gleam</td><td position_id=\"208\">2016</td><td position_id=\"209\">?</td></tr><tr position_id=\"210\"><td position_id=\"211\">V</td><td position_id=\"212\">2019</td><td position_id=\"213\">?</td></tr></tbody></table>", "x": "/html/body/div/section/table"}]}, "tags": ["table"], "label": "table", "web_segment_id": 2, "global_sentence_id": 144, "edu_l1_label": "EDU_O"}, {"txt": "On top of that, there can be significant time between a language becoming stable and it becoming popular.", "language": "english", "position": {"atoms": [{"position_id": 630, "txt": "On top of that, there can be significant time between a language becoming stable and it becoming popular.", "x": "/html/body/div/section/p[43]"}]}, "tags": [], "label": "content", "web_segment_id": 60, "global_sentence_id": 145, "edu_l1_label": "IOS"}, {"txt": " Ruby 1.0 released in 1996, but it wouldn't be until 2005 or so that Ruby became popular with the release of Ruby on Rails.", "language": "english", "position": {"atoms": [{"position_id": 631, "txt": " Ruby 1.0 released in 1996, but it wouldn't be until 2005 or so that Ruby became popular with the release of Ruby on Rails.", "x": "/html/body/div/section/p[43]"}]}, "tags": [], "label": "content", "web_segment_id": 60, "global_sentence_id": 146, "edu_l1_label": "IOS"}, {"txt": " Rust in turn saw a rise in popularity following its first stable release, but it would still take a few years for the language to take off.", "language": "english", "position": {"atoms": [{"position_id": 632, "txt": " Rust in turn saw a rise in popularity following its first stable release, but it would still take a few years for the language to take off.", "x": "/html/body/div/section/p[43]"}]}, "tags": [], "label": "content", "web_segment_id": 60, "global_sentence_id": 147, "edu_l1_label": "IOS"}, {"txt": " Scala released version 1.0.0 in 2004, but didn't see widespread adoption until some time between 2010 and 2015.", "language": "english", "position": {"atoms": [{"position_id": 633, "txt": " Scala released version 1.0.0 in 2004, but didn't see widespread adoption until some time between 2010 and 2015.", "x": "/html/body/div/section/p[43]"}]}, "tags": [], "label": "content", "web_segment_id": 60, "global_sentence_id": 148, "edu_l1_label": "IOS"}, {"txt": "Based on these patterns, I suspect that most languages will need at least 5-10 years of development before reaching their first stable release, followed by another 5 years or so before it starts to take off.", "language": "english", "position": {"atoms": [{"position_id": 635, "txt": "Based on these patterns, I suspect that most languages will need at least 5-10 years of development before reaching their first stable release, followed by another 5 years or so before it starts to take off.", "x": "/html/body/div/section/p[44]"}]}, "tags": [], "label": "content", "web_segment_id": 61, "global_sentence_id": 149, "edu_l1_label": "IOS"}, {"txt": " That's all assuming you end up lucky enough for it to actually take off, as there are many languages that instead fade into obscurity.", "language": "english", "position": {"atoms": [{"position_id": 636, "txt": " That's all assuming you end up lucky enough for it to actually take off, as there are many languages that instead fade into obscurity.", "x": "/html/body/div/section/p[44]"}]}, "tags": [], "label": "content", "web_segment_id": 61, "global_sentence_id": 150, "edu_l1_label": "IOS"}, {"txt": "Recommendation:", "language": "english", "position": {"atoms": [{"position_id": 638, "txt": "Recommendation:", "x": "/html/body/div/section/p[45]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 62, "global_sentence_id": 151, "edu_l1_label": "IOS"}, {"txt": " if you want your language to succeed, be prepared for it to take at least 10-15 years.", "language": "english", "position": {"atoms": [{"position_id": 640, "txt": " if you want your language to succeed, be prepared for it to take at least 10-15 years.", "x": "/html/body/div/section/p[45]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 62, "global_sentence_id": 152, "edu_l1_label": "IOS"}, {"txt": " If you expect it to take the world by storm in just a year, you'll be sorely disappointed.", "language": "english", "position": {"atoms": [{"position_id": 641, "txt": " If you expect it to take the world by storm in just a year, you'll be sorely disappointed.", "x": "/html/body/div/section/p[45]/strong"}]}, "tags": ["strong"], "label": "content", "web_segment_id": 62, "global_sentence_id": 153, "edu_l1_label": "IOS"}], "type": "WEB"}
# A decade of developing a programming language
## Avoid gradual typing
## Avoid self-hosting your compiler
## Avoid writing your own code generator, linker, etc
## Avoid bike shedding about syntax
## Cross-platform support is a challenge
## Compiler books aren't worth the money
## Growing a language is hard
## The best test suite is a real application
## Don't prioritize performance over functionality
## Building a language takes time
