Elias Mårtenson

@loke@functional cafe

In this post I would like to explain what KAP is, the reasons for implementing it, and what the current state of the project is.

It all starts with APL. APL is a programming language designed in 1966 by Kenneth E. Iverson. To many it's mostly known for it's unusual syntax which tends to be very compact and uses a large number of special symbols, making APL code very different from most other languages.

The language itself can be extremely terse, allowing you to describe very complex computations with very little code. A classic example of this is the routine that computes the next iteration of Conway's Game of Life:

{↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}

However, as powerful as APL is, it also suffers from some limitations. In particular, while array based computations are extremely simple, traditional imperative code is very ugly. I could probably spend a lot of time explaining all the details but suffice it to say that if you want to construct a simple loop in APL you have to use what essentially amounts to GOTO. Anything more complex and the code quickly becomes very painful.

There is one commercial software vendor that produces an APL dialect: Dyalog. The Dyalog product is really nice. It's fast, it has a lot of extensions and it has support for structured programming constructs such as regular while-loops, and also object orientation.

The drawbacks of Dyalog is that it's not free, and due to APL history, a lot of syntax for its extensions tends to be rather ugly (in this author's opinion, of course).

If you want to play with APL yourself, I recommend using GNU APL. It's a free implementation which implements everything that is part of standard APL as well as a number of extensions (some of which are Dyalog-compatible).

Experimenting with new concepts

GNU APL is aligning very strongly with the ISO APL specification and IBM's APL2 implementation. Extensions are only implemented when they are seen as being a natural part of what APL is. This makes for a very stable product, and there are a lot of users who rely on these features.

The stability of GNU APL does mean that it's difficult to experiment with new language features, and because of this I decided to implement a new language that takes some features from APL and then adds new features that are very different from traditional APL, to the point that fundamental low-level functionality can be changed.

The result of this project is KAP. KAP is a project that has been in development for a few months, and at its core it's mostly APL. It implements a large subset of APL functionality, but not all. It is also not compatible with APL for some key features. My intention is to write separate articles about these features.

Main features of KAP

So what are these new features that KAP provides? Well, the most important ones are listed here:

  • First-class functions
  • Closures
  • Hash tables
  • Namespaces
  • Custom syntax (like a light version of macros)
  • Tables can have labels
  • First-class symbols (taken from Lisp)

There are also a number of features that makes backward compatibility difficult or impossible:

  • All arrays are immutable (this allows for data sharing)
  • Computation is lazy (a function may or may not be called, depending on whether the data is needed)

The language is implemented in Kotlin as a multiplatform project. It can currently be compiled for the JVM or as a native binary. At some point it may also be possible to compile to Javascript, but currently the Javascript compiler does not support reflection. Once this has been implemented, it should be possible to generate Javascript code.

This article is long enough already, so I will conclude by providing links to the Github project page: https://github.com/lokedhs/array

I also have a link to a video that illustrates what the graphics capabilities look like: https://peertube.mastodon.host/videos/watch/4a19ca9e-7ca6-4142-bda6-c353915bfe23

If you have an questions, I can be reached on the Fediverse under @loke@functional.cafe

This is a new test of write.as.

As with the previous posts here, this post does not contain any useful information.

I will, however, at some point post some real content here.

This is a test post.

This post is not supposed to contain any useful information. I'm just testing the platform.

Here is some source code:

(defun render-op-list (stream maxima-sym displayed-sym exprs)
  (with-aligned-rendering (stream)
    (iterate-exprs (expr exprs maxima-sym :first-sym first)
      (unless first
        (aligned-spacing 0.2)
        (render-aligned-string "~a" displayed-sym)
        (aligned-spacing 0.2))
      (render-aligned () (render-maxima-expression stream expr)))))

Just a test of write.as

This is not an actual blog post, but rather just a test of the platform.

I'd like to write actual blog posts, but I don't know if I have the time or dedication to do so. But, if I actually do it, I'll probably try this one.