Skip to content
kokoro_aya edited this page Apr 20, 2022 · 2 revisions

The project's name

The project was first named as amatsukaze (天津風) at the inspiration of a wind that comes from the high sky.

As the project switched from Antlr to Kotlin DSL implementation, it's named as simulatte. The meaning of this name will not be revealed.

Background

The project was inspired by Swift Playgrounds and Karel the Robot. Both target to novice to programming and highlight some foundamental ideas of learning a programming language. While the Playgrounds is relatively completed and provides two chapters of several sections from introducing simple commands to structural coding such as loops and branches, from usage of functions to more creative maps, the Karel the Robot is more simplist and fewer resources are available.

Last year with the release of Catalina, the Catalyst was brought and therefore the Playgrounds, which was only available on iPadOS, is brought into the MacOS therefore I played it for a while. Then, an idea arose, which is to implement the playground myself using another tech stack, when I first knew Karel the Robot while I was reading something about C#. In CS study, reinventing wheels is an important way to learn: by re-studying what has been discovered, the learner could understand core of the technology or method that he/she is learning -- Wikipedia.

From the technical view, the Playgrounds provides a full powerful Swift runtime, which means that you can do almost anything you want in it as if you are using Xcode. Meanwhile, there are different implementations of Karel the Robot, most of them implement a simple VM with minimum of command that are used by their playgrounds. My goal became therefore to keep the language and implementation as simple as possible while giving it a maximum of expressiveness power.

As cited in the project of Karel, problem solving means translating human-understandable problem decriptions into machine-executable programs, where the abstraction plays an important role. Both Playgrounds and Karel the Robot emphasise it and I believe that my project could also make a spotlight over it.

As explained in the same source, abstraction is just how the human being organize processes such as doing a laundry in hierarchical levels. As we continue to dive deeper in abstracting to lower levels, until individual muscle movements, we could write instructions for most simple-minded beings so that they could do laundry by following these instructions carefully.

That's where comes the idea of algorithms, which every computer program is based on. That's how we talk to the computers.

Overall Design

The idea was to implement a front-back separated architecture. It decouples the implementation of the server from that of client. As I didn't know anything about GUI design, it allows me to concentrate first over works that I'm available to achieve. The connection between two parts is a relatively easy work via http request and json serialization.

The project is designed in a loosely coupled way. Much usage of a lot of HOF, lambdas and other features has been made to make the code more declarative and self-explained. Several principles such as composition over inheritance is followed.

The core part consists of a playground implementation, an intermediate layer (Manager), an entrypoint and a corelanguage implementation (first a visitor pattern of Antlr then the Kotlin DSL Builder).

There are several other classes regarding the routing, codegen and calling the eval engine.

See Design of Project for more info about each package and several classes.

In order to decouple different modules and add more customizability to them, reflection and interface mixin were used.

A Timeline

  • 2020.7 - a minimum implementation with basic commands and custom commands
  • 2020.8 - first client implementation
  • 2020.10 - functions and arrays
  • 2020.12 - multi-characters, ranges, closure, second client implementation
  • 2021.4 - game mode, usage of annotation
  • 2021.5 - switch to Kotlin DSL, third client implementation (see ironica for more info)
  • 2022.4 - minor updates with a rewrite of React/UmiJS front-end

Why Kotlin (1)

Kotlin is a quite recent language. But it's really powerful. Besides, it's elegant and declarative. I don't know much about Kotlin at the time I started the project.

The language has lambda and functions as its first citizens, which means a lot of flexibility and expressiveness. They have made the development a pleasure and I learnt some concepts of the language during the development.

From Antlr implementation to Kotlin DSL

As the project become part of an academic project, it encountered time limit and other pressures. The design of my second language was a bit complicated to handle. At the time (with new acquired knowledges) I noticed the possibility to use Kotlin DSL to represent Kotlin codes and data structures in Kotlin. Then I decided to abandon (maybe temporarily) my language implementation and switch to the Kotlin DSL approach.

Luckily I have chosen Kotlin so that the transition was almost painless. The Kotlin DSL, along with codegen and eval engine, provides a perfect solution for my needs.

Why Kotlin (2)

What's more, with Antlr it's nearly impossible to write unit tests. With Kotlin DSL, the tests are as simple as writing native codes inside a data structure.

From the point of view of a user, Kotlin might be a large complicated language, but its so many syntax sugar allows to level down the difficulty for a beginner. The language is highly declarative, which emphasises fully the idea of abstraction.

Besides, it's a language that comes with lots of interesting features such as nullable, HOF and lambdas. Unlike the idea that "we must learning the basis", I believe that as one day we will encounter complex logics and problems of null, for example, it's better to expose them to learners as early as possible. Same as functional programming, although it doesn't take an important place in playground, but it's always possible to discover some of it within Kotlin DSL. As for me, I'm appealed by the elegance and succinctness of FP, and I believe for a beginner Kotlin could be the best compromise between imperative style and FP style.

Some drawbacks...

The choice is not perfect. There are some disadvantages:

  • No more barrier between user input and the playground runtime as it provides reflect supports.

    But for a best user experience, it's not recommended to access not documented APIs of Simulatte or playground data structure

  • The performance is much worse comparing to Antlr implementation. In fact, a user's code is passed first into a data structure, then converted into a string representation, then re-taken by the eval engine. Not to mention the overhead for running an eval engine.

  • Impossible to inject custom logics into control flows such as loop, branches. Of course, you have to make your own language implementation to inject a custom logic, such as calling the appendEntry() into for example each turn of a loop. More subtle controls of the behavior of playground is therefore impossible.

After all, the benefits of using Kotlin DSL overcome the drawbacks.

Where to go from here

Several paths are possible from here.

  • Develop a full content (book) of different levels, sections and chapters.
  • More chapters on advanced programming features in Kotlin/JVM.
  • More tests.
  • Eliminate bugs.
  • Implement a better client (C/S architecture) using Unity3d.
  • Implement a better client (monolithic app) using LibKTX or LWJGL.
  • Reimplement a better playground language with IR & VM.
  • Bring more customizable playgrounds into the project, such as plugins and scenarios.
  • Extend its scripting and customizing possibilities, to bring a full working playground with Kotlin DSL.
  • A more appealing user interface.
  • Improvements such as syntax highlighting, IDE integration, auto-completion, code snippet insertion, pre compile error warning, etc, a language server protocol could be in help.

Lots of possibilities...

This project is currently in hibernation. I'm currently working on some other projects to implement my own language. Maybe one day I will retake this project and give it another look.