<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alan Evans</title>
    <description>The latest articles on DEV Community by Alan Evans (@westonal).</description>
    <link>https://dev.to/westonal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F195947%2F13a1b444-aff5-4b62-9535-74db6c90c11a.png</url>
      <title>DEV Community: Alan Evans</title>
      <link>https://dev.to/westonal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/westonal"/>
    <language>en</language>
    <item>
      <title>Advanced Kotlin syntax abuse</title>
      <dc:creator>Alan Evans</dc:creator>
      <pubDate>Sat, 26 Aug 2023 15:36:47 +0000</pubDate>
      <link>https://dev.to/westonal/advanced-kotlin-syntax-abuse-3613</link>
      <guid>https://dev.to/westonal/advanced-kotlin-syntax-abuse-3613</guid>
      <description>&lt;p&gt;Kotlin’s operator overloading and infix notations provide a great opportunity to create a more natural reading codebase, but they also provide a great opportunity to create wonderfully nonsensical code.&lt;/p&gt;

&lt;p&gt;In this article, I’m going to show how this outputs &lt;code&gt;Hello World!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1C9skm5M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y8b0gykvxgftr7a4v3lm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1C9skm5M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y8b0gykvxgftr7a4v3lm.png" alt="Heart shaped code block" width="608" height="590"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Brainfuck
&lt;/h2&gt;

&lt;p&gt;First if you’re not already familiar with the language &lt;em&gt;Brainfuck&lt;/em&gt;, BF for short from now on. It’s an esoteric, Turing complete language that consists of just a handful of symbols:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;+&lt;/code&gt; Add 1&lt;br&gt;
&lt;code&gt;-&lt;/code&gt; Subtract 1&lt;br&gt;
&lt;code&gt;&amp;gt;&lt;/code&gt; Move to the next memory address&lt;br&gt;
&lt;code&gt;&amp;lt;&lt;/code&gt; Move to the previous memory address&lt;br&gt;
&lt;code&gt;[&lt;/code&gt; if the current memory address is zero, skip to the matching ]&lt;br&gt;
&lt;code&gt;]&lt;/code&gt; if the current memory address is non-zero, skip back to the matching [&lt;br&gt;
&lt;code&gt;.&lt;/code&gt; Print the current address as a char&lt;br&gt;
&lt;code&gt;,&lt;/code&gt; Read a value from the input&lt;/p&gt;

&lt;p&gt;A “Hello world!” in BF is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;++++++++[&amp;gt;++++[&amp;gt;++&amp;gt;+++&amp;gt;+++&amp;gt;+&amp;lt;&amp;lt;&amp;lt;&amp;lt;-]
&amp;gt;+&amp;gt;+&amp;gt;-&amp;gt;&amp;gt;+[&amp;lt;]&amp;lt;-]&amp;gt;&amp;gt;.&amp;gt;---.+++++++..++
+.&amp;gt;&amp;gt;.&amp;lt;-.&amp;lt;.+++.------.--------.&amp;gt;&amp;gt;+.
&amp;gt;++.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you would like to understand how this produces this output, Wikipedia explains this well &lt;a href="https://en.wikipedia.org/wiki/Brainfuck#Hello_World"&gt;https://en.wikipedia.org/wiki/Brainfuck#Hello_World&lt;/a&gt;! This article is more about how I created this travesty of a syntax to be acceptable to the Kotlin complier!&lt;/p&gt;

&lt;p&gt;Note that the above BF &lt;em&gt;hello world&lt;/em&gt; mostly matches up with my Kotlin hello world example albeit with some different symbols.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;+&lt;/code&gt; Add 1&lt;br&gt;
&lt;code&gt;-&lt;/code&gt; Subtract 1&lt;br&gt;
&lt;code&gt;r&lt;/code&gt; rather than &lt;code&gt;&amp;gt;&lt;/code&gt; to move to the next memory address&lt;br&gt;
&lt;code&gt;l&lt;/code&gt; rather than &lt;code&gt;&amp;lt;&lt;/code&gt; to move to the previous memory address&lt;br&gt;
&lt;code&gt;[&lt;/code&gt; if the current memory address is zero, skip to the matching &lt;code&gt;]&lt;/code&gt;&lt;br&gt;
&lt;code&gt;]&lt;/code&gt; if the current memory address is non-zero, skip back to the matching &lt;code&gt;[&lt;/code&gt;&lt;br&gt;
&lt;code&gt;o&lt;/code&gt; Print the current address as a char&lt;br&gt;
&lt;code&gt;n&lt;/code&gt; NOOP, its purpose explained later&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;A BF program, like any other, is a list of commands. So I decided I needed to model a &lt;code&gt;Command&lt;/code&gt;, and a &lt;code&gt;Program&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sealed class Command {
    object Add : Command()
    object Subtract : Command()
    object MoveRight : Command()
    object MoveLeft : Command()
    object Print : Command()
    class Loop(val loopContent: Program)
}

class Program(val commands: List&amp;lt;Command&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that I have modelled the loop command as containing another program within the loop. I now have a tree structure.&lt;/p&gt;

&lt;p&gt;I want to keep this all immutable, so I will make an &lt;code&gt;append&lt;/code&gt; method, that will create a new program with the additional command. But first, I’d like a way of testing this all, so I’m going to create some &lt;code&gt;toString&lt;/code&gt; methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sealed class Command {
    object Add : Command() {
        override fun toString() = "+"
    }

    object Subtract : Command() {
        override fun toString() = "-"
    }

    object MoveRight : Command() {
        override fun toString() = "&amp;gt;"
    }

    object MoveLeft : Command() {
        override fun toString() = "&amp;lt;"
    }

    object Print : Command() {
        override fun toString() = "."
    }

    class Loop(val loopContent: Program) : Command() {
        override fun toString() = "[$loopContent]"
    }
}

class Program(val commands: List&amp;lt;Command&amp;gt; = emptyList()) {
    override fun toString(): String {
        return commands.joinToString(separator = "")
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our test cases can ensure that the program contents are as expected before we actually get to the point of wanting to execute it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
fun `can append command`() {
    assertEquals("+", Program(emptyList()).append(Command.Add).toString())
}

@Test
fun `can append 2 commands`() {
    assertEquals("+-", Program(emptyList()).append(Command.Add).append(Command.Subtract).toString())
}

@Test
fun `can append a loop`() {
    assertEquals(
        "+[.]", Program(emptyList()).append(Command.Add)
            .append(Command.Loop(Program(emptyList()).append(Command.Print))).toString()
    )
}
fun Program.append(command: Command) = Program(commands + command)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now build the whole &lt;em&gt;hello world&lt;/em&gt; in this fashion and assert the program structure is correct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val helloWorld: Program = Program(emptyList()).append(Command.Add).append(Command.Add).append(Command.Add).append(Command.Add)
    .append(Command.Add).append(Command.Add)
    .append(Command.Add).append(Command.Add)
    .append(
        Command.Loop(
            Program(emptyList()).append(Command.MoveRight).append(Command.Add).append(Command.Add)
                .append(Command.Add).append(Command.Add).append(
                    Command.Loop(
                        Program(emptyList()).append(Command.MoveRight).append(Command.Add).append(Command.Add)
                            .append(Command.MoveRight).append(Command.Add).append(Command.Add)
                            .append(Command.Add).append(Command.MoveRight).append(Command.Add)
                            .append(Command.Add).append(Command.Add).append(Command.MoveRight)
                            .append(Command.Add).append(Command.MoveLeft).append(Command.MoveLeft)
                            .append(Command.MoveLeft).append(Command.MoveLeft).append(Command.Subtract)
                    )
                ).append(Command.MoveRight).append(Command.Add).append(Command.MoveRight)
                .append(Command.Add)
                .append(Command.MoveRight).append(Command.Subtract).append(Command.MoveRight)
                .append(Command.MoveRight).append(Command.Add)
                .append(Command.Loop(Program(emptyList()).append(Command.MoveLeft)))
                .append(Command.MoveLeft)
                .append(Command.Subtract)
        )
    ).append(Command.MoveRight).append(Command.MoveRight).append(Command.Print).append(Command.MoveRight)
    .append(Command.Subtract).append(Command.Subtract)
    .append(Command.Subtract).append(Command.Print).append(Command.Add).append(Command.Add)
    .append(Command.Add).append(Command.Add)
    .append(Command.Add).append(Command.Add).append(Command.Add).append(Command.Print).append(Command.Print)
    .append(Command.Add).append(Command.Add)
    .append(Command.Add).append(Command.Print).append(Command.MoveRight).append(Command.MoveRight)
    .append(Command.Print).append(Command.MoveLeft).append(Command.Subtract)
    .append(Command.Print).append(Command.MoveLeft).append(Command.Print).append(Command.Add)
    .append(Command.Add).append(Command.Add).append(Command.Print)
    .append(Command.Subtract).append(Command.Subtract).append(Command.Subtract).append(Command.Subtract)
    .append(Command.Subtract)
    .append(Command.Subtract).append(Command.Print).append(Command.Subtract).append(Command.Subtract)
    .append(Command.Subtract)
    .append(Command.Subtract).append(Command.Subtract).append(Command.Subtract).append(Command.Subtract)
    .append(Command.Subtract)
    .append(Command.Print).append(Command.MoveRight).append(Command.MoveRight).append(Command.Add)
    .append(Command.Print).append(Command.MoveRight).append(Command.Add)
    .append(Command.Add).append(Command.Print)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh boy, that badly needs a refactor and some cleaner syntax but at least the test is neat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
fun `can build hello world program structure`() {
    assertEquals(
        "++++++++[&amp;gt;++++[&amp;gt;++&amp;gt;+++&amp;gt;+++&amp;gt;+&amp;lt;&amp;lt;&amp;lt;&amp;lt;-]&amp;gt;+&amp;gt;+&amp;gt;-&amp;gt;&amp;gt;+[&amp;lt;]&amp;lt;-]&amp;gt;&amp;gt;.&amp;gt;---.+++++++..+++.&amp;gt;&amp;gt;.&amp;lt;-.&amp;lt;.+++.------.--------.&amp;gt;&amp;gt;+.&amp;gt;++.",
        helloWorld.toString()
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we do any refactoring, let’s try and make this work with an execute method.&lt;/p&gt;

&lt;p&gt;First we need to model the memory of the machine, known as a tape.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Tape(size: Int = 30000) {
    private val data = Array(size) { 0 }
    private var pointer = 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is just an array and a movable pointer into that array.&lt;/p&gt;

&lt;p&gt;Executing commands is pretty trivial, and you should see that they line up easily with the descriptions of the symbols given earlier in the article.&lt;/p&gt;

&lt;p&gt;The hardest part about writing a BF machine is getting the loops working correctly, but our in-memory tree structure makes even this easy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun Program.execute(tape: Tape = Tape(), writer: PrintWriter = PrintWriter(System.out.writer())) {
    for (command in commands) {
        when (command) {
            is Command.Add -&amp;gt; tape.add()
            is Command.Subtract -&amp;gt; tape.subtract()
            is Command.MoveRight -&amp;gt; tape.moveRight()
            is Command.MoveLeft -&amp;gt; tape.moveLeft()
            is Command.Print -&amp;gt; writer.print(tape.currentAsChar())
            is Command.Loop -&amp;gt; while (tape.current() != 0) {
                command.loopContent.execute(tape, writer)
            }
        }
    }
    writer.flush()
}

class Tape(size: Int = 30000) {
    private val data = Array(size) { 0 }
    private var pointer = 0;

    fun add() {
        data[pointer]++
    }

    fun subtract() {
        data[pointer]--
    }

    fun moveRight() {
        pointer++
    }

    fun moveLeft() {
        pointer--
    }

    fun current(): Int {
        return data[pointer]
    }

    fun currentAsChar(): Char {
        return current().toChar()
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
fun `run hello world`() {
    val stringWriter = StringWriter()
    helloWorld.execute(Tape(), PrintWriter(stringWriter))

    assertEquals("Hello World!\n", stringWriter.toString())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It all works, so it's time to refactor.&lt;/p&gt;

&lt;p&gt;Firstly, &lt;code&gt;Program(emptyList)&lt;/code&gt; appears a lot, it’s always the same and as &lt;code&gt;Program&lt;/code&gt; is immutable, this can be extracted to a constant, &lt;code&gt;n&lt;/code&gt;. I have chosen &lt;code&gt;n&lt;/code&gt; to stand for NOOP, it does nothing, in fact it’s not really a command at all, just an empty program. It’s the identity program, like an identity matrix, it changes no program it is appended to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val n = Program(emptyList())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I want to start overloading operators. Firstly so that this test passes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
fun `add command`() {
    assertEquals("+", (n + n).toString())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I’m going to let IntelliJ be my accomplice:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gNcHyx_f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppsffberihb4zc0sk6wm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gNcHyx_f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppsffberihb4zc0sk6wm.png" alt="IntelliJ suggesting to add Program.plus" width="800" height="257"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Not complete!
operator fun Program.plus(program: Program): Program {
    return append(Command.Add)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will get us past the first test, but not this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
fun `add commands preserve left and right programs`() {
    assertEquals("&amp;lt;+&amp;gt;", (n.append(Command.MoveLeft) + n.append(Command.MoveRight)).toString())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this will:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operator fun Program.plus(program: Program)
  = append(Command.Add).append(program)
With the help of a new append overload to concatenate whole programs:

fun Program.append(program: Program)
  = Program(commands + program.commands)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our first crime against Kotlin has now been committed, &lt;code&gt;plus&lt;/code&gt; now does not only add the left and right operands, but inserts a command too so that the the whole is now greater than the sum of the parts, which is a fine saying, but not very mathematically accurate!&lt;/p&gt;

&lt;p&gt;So how do we get multiple &lt;code&gt;+&lt;/code&gt; s in a row to make sense, well we’ll write a test and let IntelliJ tell us how!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
fun `multiple plus symbols`() {
    assertEquals("&amp;lt;++&amp;gt;", (n.append(Command.MoveLeft) + + n.append(Command.MoveRight)).toString())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0NSc8Wkq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k90j2v0of096fuk2ihiv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0NSc8Wkq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k90j2v0of096fuk2ihiv.png" alt="IntelliJ suggesting to add Program.unaryPlus" width="800" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks IntellJ, you’re making this easy!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operator fun Program.unaryPlus()
  = n.append(Command.Add).append(this)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’m not sure why unary plus can be overridden to be honest, or when you might even want to use it. Unary minus makes some sense, a way to produce a negative version of your type, and maybe Kotlin just allows the unary plus for completeness?&lt;/p&gt;

&lt;p&gt;In any case, we can now start to construct the &lt;em&gt;hello world&lt;/em&gt;, we can have the eight &lt;code&gt;+&lt;/code&gt; symbols at the front of the program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
fun `8 plus symbols`() {
    assertEquals("++++++++", (+ + + + + + + + n).toString())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the presence of &lt;code&gt;n&lt;/code&gt;, without which the compiler would have no idea we’re talking about the &lt;code&gt;Program&lt;/code&gt; type. We can insert these wherever we need to tell the Kotlin compiler about the type.&lt;/p&gt;

&lt;p&gt;Also note that for the first time here, we’ve got to the point where white space matters. Using IntelliJ auto-formatter will bring all these unary pluses together and cause a syntax error. It’s our first big clue that we’re getting off the beaten path here!&lt;/p&gt;

&lt;p&gt;That’s it for the plus, and the procedure for deriving the minus support is identical.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operator fun Program.unaryMinus()
  = n.append(Command.Subtract).append(this)
operator fun Program.minus(program: Program)
  = append(Command.Subtract).append(program)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a way the behavior of these minus implementations are even more unexpected than that of the plus implementations as nothing is subtracted, the programs only get longer!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Loop
&lt;/h2&gt;

&lt;p&gt;The next interesting language feature to misuse is the array indexer to give us the loop syntax.&lt;/p&gt;

&lt;p&gt;I employ the same pattern, write what I want it to look like and let IntelliJ make its suggestions in good faith:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
fun `loops using array syntax`() {
    assertEquals("&amp;gt;[-]", (n.append(Command.MoveRight) [ n.append(Command.Subtract) ]).toString())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9zW0Qwpk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n3ocx62uftez70r8kbdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9zW0Qwpk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n3ocx62uftez70r8kbdg.png" alt="IntelliJ suggesting to add Program.get" width="800" height="194"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operator fun Program.get(loopInner: Program)
  = append(Command.Loop(loopInner))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, that was quick let’s recap what I’ve done there, I’ve taken an overload that was designed to let you look stuff up in your custom classes as though they were arrays/lists and I’ve made it create a mutation of the current program with an appended loop command which contains another program. This is a truly terrible misuse of this feature!&lt;/p&gt;

&lt;p&gt;But where does applying that leave &lt;code&gt;helloWorld&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val helloWorld: Program = + + + + + + + + n [
        n.append(Command.MoveRight) + + + + n[
                n.append(Command.MoveRight) +  + n
                    .append(Command.MoveRight) +  +
                + n.append(Command.MoveRight) +
                        +  + n.append(Command.MoveRight)
                        + n.append(Command.MoveLeft).append(Command.MoveLeft)
                    .append(Command.MoveLeft).append(Command.MoveLeft) - n
        ].append(Command.MoveRight) + n.append(Command.MoveRight) +
                n.append(Command.MoveRight) - n.append(Command.MoveRight)
            .append(Command.MoveRight) +
                n[n.append(Command.MoveLeft)]
                    .append(Command.MoveLeft)
                - n
].append(Command.MoveRight).append(Command.MoveRight).append(Command.Print).append(Command.MoveRight) - - -
n.append(Command.Print) + + + + + + + n.append(Command.Print).append(Command.Print) + + +
n.append(Command.Print).append(Command.MoveRight).append(Command.MoveRight).append(Command.Print).append(Command.MoveLeft) -
        n.append(Command.Print).append(Command.MoveLeft).append(Command.Print) + + + n.append(Command.Print) - - -  - - -
n.append(Command.Print) -  - - -  -  -  - - n.append(Command.Print).append(Command.MoveRight).append(Command.MoveRight) +
        n.append(Command.Print).append(Command.MoveRight) + + n.append(Command.Print)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Move Left and Right
&lt;/h2&gt;

&lt;p&gt;A lot of things remaining can be seen to be extractable, things like &lt;code&gt;n.append(Command.MoveRight)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I’d love to use &lt;code&gt;&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;&lt;/code&gt; but, although these can be overridden in a way, they both boil down to the overridable &lt;code&gt;compareTo&lt;/code&gt; which doesn’t tell you which operator was actually used so I am forced to choose my own symbols for these commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val o = n.append(Command.Print)
val r = n.append(Command.MoveRight)
val l = n.append(Command.MoveLeft)

val helloWorld: Program = + + + + + + + + n [  r + + + + n [
        r + + r + + + r + + + r +
                l.append(Command.MoveLeft).append(Command.MoveLeft).append(Command.MoveLeft) - n
].append(Command.MoveRight) + r + r - r
    .append(Command.MoveRight) + n [ l ]
    .append(Command.MoveLeft) - n
].append(Command.MoveRight).append(Command.MoveRight).append(Command.Print).append(Command.MoveRight) - - -
o + + + + + + + o.append(Command.Print) + + +
o.append(Command.MoveRight).append(Command.MoveRight).append(Command.Print).append(Command.MoveLeft) -
        o.append(Command.MoveLeft).append(Command.Print) + + +o - - -  - - -
o -  - - -  -  -  - - o.append(Command.MoveRight).append(Command.MoveRight) +
        o.append(Command.MoveRight) + + o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, now all that is left are a few appends. What if we just replace them with what we want and let IntelliJ suggest something, it’s worked so far:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--spEY0Eoa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d9r8sl9832l23cw6hn30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--spEY0Eoa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d9r8sl9832l23cw6hn30.png" alt="IntelliJ suggesting to add extension function Program.l" width="800" height="160"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;infix fun Program.l(program: Program)
  = append(Command.MoveLeft).append(program)
infix fun Program.r(program: Program)
  = append(Command.MoveRight).append(program)
infix fun Program.o(program: Program)
  = append(Command.Print).append(program)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have arrived at our horrific destination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val helloWorld: Program =
    + + + + + + + + n [ r + + + + n [ r + + r + + + r + + + r +
    l l l l - n ] r + r + r - r r + n [ l ] l - n ] r r o r - -
    - o + + + + + + + o o + + + o r r o l - o l o + + + o - - -
    - - - o - - - - - - - - o r r + o r + + o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I must be careful of new line locations at this point, but this can be solved by wrapping in &lt;code&gt;(&lt;/code&gt; &lt;code&gt;)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All that remains is to change our execute method into an invoke:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operator fun Program.invoke(tape: Tape = Tape(), writer: PrintWriter = PrintWriter(System.out.writer())) { ... same as execute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we can now actually execute BrainFuck inside Kotlin, simply by wrapping in &lt;code&gt;(&lt;/code&gt; &lt;code&gt;)&lt;/code&gt; and using a following pair of &lt;code&gt;()&lt;/code&gt; to cause the invocation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(
  + + + + + + + + n [ r + + + + n [ r + + r + + + r + + + r + l l
  l l - n ] r + r + r - r r + n [ l ] l - n ] r r o r - - - o + +
  + + + + + o o + + + o r r o l - o l o + + + o - - - - - - o - -
  - - - - - - o r r + o r + + o
)()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which makes for an interesting sight in the IDE as the seemingly random colours hint at our overloading of various &lt;code&gt;val&lt;/code&gt;s and &lt;code&gt;infix&lt;/code&gt; methods:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fxcsSfHR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fzl94hgbsvvvjlkwspl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fxcsSfHR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fzl94hgbsvvvjlkwspl.png" alt="IntelliJ screen shot of main with different colors" width="800" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;This is a Turing complete language within a language, add support for the input stream &lt;code&gt;,&lt;/code&gt; with say &lt;code&gt;i&lt;/code&gt; and you can truly implement anything you wish with just these symbols:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VLN7bUPz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqmgugnd00m7yar9hhyf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VLN7bUPz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqmgugnd00m7yar9hhyf.png" alt="l + o - r n i and square brackets" width="637" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Doom anyone?&lt;/p&gt;




&lt;p&gt;Originally posted in 2020 on medium &lt;a href="https://westonal.medium.com/advanced-kotlin-syntax-abuse-b9f5e46230e4"&gt;https://westonal.medium.com/advanced-kotlin-syntax-abuse-b9f5e46230e4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code available at &lt;a href="https://github.com/westonal/KotlinBrainFuck"&gt;https://github.com/westonal/KotlinBrainFuck&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>brainfuck</category>
      <category>esoteric</category>
    </item>
  </channel>
</rss>
