Sunday, July 24, 2022

Changes to the copresheaf viewer

The basic objects of the Locus computer algebra system are copresheaves. Locus implements all my original research and ideas about copresheaves and their congruences, and these ideas in turn have influenced my ideas on the use of copresheaf theory in foundations. Once we have established sufficient motivation for wanting to work in terms of copresheaves, it would be nice as a next step to develop tools to make it easier to work with them.

The first such tool I have devised to work with them is the copresheaf viewer. This was implemented in a very small amount of lines of Clojure code using Graphviz and Swing. It consisted of two components: a view of the source category as displayed by Graphviz and a JList used for interacting with the objects and morphisms of the category. These two components are combined in a split pane as seen below. The problems with this user interface design approach are apparent from the get go. This approach is clearly not scalable.
  • You should be able to interact with the index category in place, rather then having to separately go to the JList to access an item. Imagine if we had a large index category with hundreds of objects and morphisms, then you would have to scroll through all of them to find what you are looking for. Instead you should be able to click an object or morphism in place.
  • The view of the source category should be pannable and zoomable. This will allow you to interact with increasingly large source categories, with hundreds of objects and morphisms so that you can find exactly what you are looking for.
So we need a sort of pannable, zoomable, interactive directed graph viewer. It is clear that JavaFX is the technology for this, as Swing is not suitable for designing applications with advanced graphical transformations. A scene graph, like what is provided by JavaFX, is precisely the sort of technical appartus that is needed for this type of job. Three JavaFX graph editor like programs are available and have been considered: I seriously considered each of these options, because I didn't want to create a JavaFX graph editor myself. Unfortunately, none of theme seems to have the idea of displaying categories in mind. In order to display a category we need to support multiple labeled directed edges. Many of these graph editors don't support labeled edges or perhaps even multiple edges, especially the last two. The first one seems to be specifically concerned with the Eclipse modeling foundation technologies, which is a whole different concern entirely.

Another issue is that these graph editors might not have support for adding event listeners on their vertices and edges. Even if they do, they might have the documentation to describe it. Basically, I have a very specific use case: creating interactive displays of categories. This explains why I created my own JavaFX copresheaf viewer, although I didn't set out to do so. At least with this, you can directly click on an object or a morphism to get its corresponding output, without having to go through a JList. It also supports zooming and panning, so you can get a much better handle on some copresheaves. I want everything in general, but in Locus especially, to go through some kind of copresheaf so this viewer is really the key to everything in our whole algebra system.

The copresheaf viewer is programmed in Java. In order to call it from Clojure, we reify a GraphActionListener with vertex and edge actions that apply the copresheaf to its corresponding objects and morphisms and this works fine for now. This gives us an interactive handle on copresheaves, which works pretty good for now.

The only limitation of this approach is that it has limited capabilities for handling graph layouts. I support a simple mechanism for layouting directed acyclic graphs from their partial orders using a ranking like a Hasse diagram. This is good for a number of simple categories, but for anything else you may have to hand hold the copresheaf viewer so that it lays out the objects of the category appropriately.

One thing that is nice is that if you are viewing an MSet in the JavaFX copresheaf viewer, the loops of the source category of the MSet do not overlap so you can more easily access them. I implemented this with a simple algorithm that goes around the node and places the loops separately so they don't overlap. This didn't even always occur in the Graphviz viewer, which despite working great for almost everything also wasn't built with displaying categories in mind. An option I have considered is using JNI or some other solution to access Graphviz layout mechanisms.

It is clear that no graphical user interface program is perfect, and both my copresheaf viewer and to a much lesser extent Graphviz could use some improvements. I look forward to even being able to replace this JavaFX copresheaf viewer with something else, as long as it works better. The most important thing is achieving the vision of a computing environment based upon presheaf theory, however, that happens.

All I have is a grand vision of presheaf theory involving mathematical means of reasoning about presheaves, data structures and algorithms for running computations involving copresheaves, ideas for how to graphically and interactively display copresheaves, new presheaf theoretic mechanisms for creating ontologies, etc. The Locus project is nothing more then the embodiment of this mathematical vision.

The transference of attention to presheaf topos theory is just the first step in building the future of computing. Once you work in presheaf theory, it is possible to create new topos theoretic ontologies and a geometry of computation. Foundations are important, and so it is only by using topos theoretic foundations that these great avenues of exploration can be made available.

Tuesday, July 19, 2022

Perspectives on web development

When we look at what web development was like at the turn of the first decade of the twenty first century, it had a number of problems. These problems influenced my decision to pick up Clojure at the time. I have identified these problems primarily as lying in the ackwardness of interfacing between HTML, CSS, JavaScript, and PHP. I have identified two ways by which modern JavaScript developers have solved this problem:
  • NodeJS: this solved the distinction between JavaScript and PHP.
  • JSX: this solved the ackwardness of the distinction between JavaScript and HTML.
It was inevitable that with the very real problems and limitations of full web stack development at the time, that JavaScript developers would eventually solve them. I think that especially with the introduction of NodeJS and JSX they solved them pretty well. With these new technologies, modern JavaScript is potentially an enjoyable experience.

NodeJS
In the old days JavaScript was just a browser scripting language. It had no means of server side development, so the use of a server-side language like PHP wasn't simply a choice it was a neccessity. The introduction of NodeJS changed all that, because now it meant you could use JavaScript on the server, and so server-side JavaScript really took off. This made full-stack web development a much more pleasant experience because then you could use JavaScript on both the client side and the server side.

JSX
JavaScript was originally used only to script web pages in the browser, but even then the vanilla JavaScript language that comes installed in most browsers is not a particularly nice way of manipulating HTML. HTML seems like a foreign technology to vanilla JavaScript. The new JSX technology solved this problem. With JSX you can freely combine HTML and JavaScript in the same file, and this is further extended greatly by React.

Modern full stack development with JavaScript
The problem of the distinction between various text-based languages like JavaScript, PHP, HTML, and CSS has basically been solved by the modern JavaScript web development stack. With NodeJS you can use JavaScript on both the client and the server sides, and with JSX you can unify HTML, JavaScript, and even CSS. With NodeJS on the server side and JSX and React on the client side, we have a better approach to full stack web development then before.

Full stack development with Clojure
The situation with full stack web development with Clojure is similar. You can unify client and server sides using Clojure and ClojureScript. Further, we can unify Clojure and HTML using Hiccup, and you can embed CSS in Clojure using Garden and similar technologies. This provides a unified development experience much like modern JavaScript. As both Clojure and modern JavaScript provide unified developer experiences, neither one is better at web development then the other.

The advantage of Clojure comes from being a modern Lisp for the JVM. The JVM is the best engineered piece of software in the world. It has the best tiered just in time compiler architecture with the C1 and C2 compilers. Its instruction set architecture is best architecture for hosting languages. It has the best set of programming languages. It comes equipped with the best set of libraries. Java interop is the biggest advantage of Clojure.

Monday, July 18, 2022

Java editions

The Java developer platform comes in a number of editions. As a JVM languages developer (I created a JVM language) first and foremost I make it my business to have a basic knowledge of the different kinds of Java development, and the different editions of Java.

Java editions
When Java was first created it was basically just Java, but by the time Swing was introduced it was quite a large platform, so around the same time Sun microsystems split it into editions.
  • Java SE: the Java standard edition contains all the base libraries, integration libraries, and the Swing library for creating desktop applications. It used to include JavaFX as well at one point, but it was later moved out of the standard library.
  • Java ME: the Java micro edition is the subset of Java SE that is suitable for mobile and embedded devices, as well as a small set of new specialized functionality for them.
  • Java EE: the Java enterprise edition contains the message service, servlets, enterprise beans, java server pages, web services, and JSON and XML support.
The difference between Java SE and ME is necessitated by the very real differences between hardware devices that I have discussed previously. Mobile and embedded devices necessitate a different type of programming, and Java ME is designed to address that.

Changes to the different editions of Java
The division of the Java platform into editions was created by Sun microsystems in the early days of Java, when the platform first came into its own. Since that time one or two small changes happened to the computing industry, that are worth considering.
  • The rise of Android in the mobile market.
  • The transference of Java EE to the Eclipse foundation.
The first thing is that mobile and embedded devices actually took off like crazy since the early days of Java. While Java has always been based upon the write once run anywhere motto, which meant it could be run on mobile devices, desktops, or any other platform, at first the idea of mobile devices was rather niche. This changed with the explosive growth in mobile devices.

It was Android and not Java ME that took off with this explosive growth in mobile. Android is now the biggest operating system in the world by the number of devices that run it, and most importantly it is based upon a Java API that is not Java ME. Android has basically taken over the role that would've been played by Java ME, so if you want to write for a mobile or embedded device you are probably going to want to use it instead. Java ME probably still has some use somewhere though.

The second thing that happened is that Oracle gave Java EE to the Eclipse foundation, so that it is now called Jakarta EE. Even there, you are probably going to want to use other Java enterprise frameworks like Spring and other technologies for most things, but Jakarta EE is still used underneath by a lot of libraries. We still have Java SE, whose role hasn't changed much from what it was before.

Previously
Java SE overview

Sunday, July 17, 2022

IntelliJ IDEA Ultimate

At the start of the year, I described my tranisition to Cursive for all Clojure development. Following this, I also considered a number of other IDEs like Visual Studio Code, Eclipse, Netbeans, etc. But the fact of the matter is that no one human has an infinite cognitive load. We all need to keep our cognitive load down to a minimum in order to increase our productive efficiency. This has always been important to me.

Already in late 2000s I saw that there was too much incidental complexity in web development. The web technology stack at the time required that you switch between client side languages JavaScript and server-side languages like PHP. This required that you actively memorize incidental syntactic differences between JavaScript and PHP that are not relevant to solving your problem.

This was eventually solved with NodeJS which unified client and server sides under JavaScript. This was certainly a step forward towards reducing the incidental complexity that pervaded full stack web development. But I feel perhaps even the NodeJS doesn't go far enough. There is still incidential complexity of switching between JavaScript, HTML, and CSS. Clojure, combined with Hiccup, goes all the way in allowing you to even unify HTML and code.

So I feel in with Clojure at this time in the hope of reducing the pointless incidental complexity that pervaded full stack web development, and by extension most of the computing industry. Ideas like the unification of code and data, client side and server side development, and all kinds of other aspects of development could provide a fantastic simplification of computing. This in turn could free me up to focus on the concepts that actually matter like mathematical structures.

Clojure shouldn't be compared against a single syntactic language like Java, but rather a collection of them. A single programming language like Java with its own distinct syntax isn't that big of a deal. The incidental complexity comes in when you want to introduce a number of different Algol based languages like JavaScript and PHP with their own syntaxes. I don't want that. By the same token, I don't want the potentially even worse incidental complexity that comes from using different IDEs.

Having to switch between different IDEs would be probably an even bigger problem then switching between different languages. Different IDEs have different hotkeys and user interfaces, which prevents the habituation which is so necessary to using a computer efficiently. An experienced developer habitually used to IntelliJ can use all of its hotkeys seamlessly, producing an unmatched developer experience.

The JVM is the only neutral ground to define your programs. It is the only platform which isn't tied to a language like JavaScript or a single companies languages and developer tools. In particular, the JVM is distinguished by how seamlessly it supports the creation of new languages by serving as a compiler target. But even if it is the best programming platform in the world, where would it be without a IDE? That is where JetBrains comes into play.

It is only by combining the JVM and IntelliJ that you can achieve the best developer experience. While the JVM lets you switch between languages like Java and Clojure on a language level, IntelliJ lets you switch between them on the IDE level. Both have their own roles to play. Furthermore, if you want to truly use Intellij without having to switch between IDEs, you are eventually going to want to get the ultimate version.

Cursive is the best Clojure IDE
The situation we are in now is that the Cursive plugin for IntelliJ is the best IDE for Clojure. I probably wouldn't consider using IntelliJ, let alone paying money for it if it were any other way. This gives IntelliJ a decisive advantage over Java IDE's like Eclipse and Netbeans, which don't have Clojure plugins.

This way you can use Clojure directly within IntelliJ, just as you would use Java. You can even seamlessly mix Java and Clojure into a single project. Best of all, if you just want to make a Java project that doesn't use Clojure, you can do so without the mental overhead of having to switch IDEs. You never want to switch to a different IDE if you don't have to.

Special features of the ultimate edition
The ultimate edition mostly comes equipped with special features for enterprise users and web developers, while the community edition is mostly focused on Java SE. While I am the biggest fan of Swing and JavaFX, realistically if you are want to make business applications you are eventually going to want to handle enterprise and web technologies.
  • Java EE: the ultimate edition provides built in support for all the features of the Java EE (enterprise edition).
  • Spring: the staple of enterprise Java, the Spring framework, is only supported in the ultimate edition.
  • Hibernate: the ultimate edition has full support for the Hibernate framework for handling mapping between object oriented domains and relational databases.
  • Microservices: the ultimate edition has built in support for Quarkus and Micronaut.
  • Web technologies: JavaScript is supported in the ultimate edition along with all other web technologies. In particular, it comes with support for React, which is the basis of all ClojureScript web applications.
Many of these ultimate features might be available in other IDEs, but they don't have support for Clojure so they really aren't an option for us. If you use Clojure in even one of your projects, you are going to want to use IntelliJ.

External links:
IntelliJ IDEA Ultimate The Investment That Pays Off

Thursday, June 23, 2022

Distinguishing features of Clojure

By now it should be readily apparent that Clojure is not like most programming languages. In this post I will attempt to pin down what I think makes Clojure so different, focusing more on the philosophical aspects rather then the implementation details. Clojure is distinguished from most other languages from how tightly it is integrated into the JVM, and by its excellent Java interop - but this is an implementation detail and not the philosophical core of the language.

Clojure is sometimes called a functional language, but it is not too particular about it. Functional programming is just one paradigm under the larger multi-paradigm umbrella. The emphasis on functional programming in particular gets to something deeper about the language, which is its emphasis on concurrency. In Clojure you can have side effects, but they ought to be concurrent.

Code as data

Clojure is a Lisp which means it treats code as data. In the customary manner of Lisp dialects, code is represented by collection data structures. Consequently, like most Lisp dialects the language is optimized around the manipulation of collection data structures like lists and sets. This combination of an emphasis on collection processing and code as data enables the Clojure macro system.

It should be mentioned that code as data is a philosophy rather then a specification. Like so many things it is a work in progress. Clojure did well to extend the simple S-expressions of earlier Lisp dialects with new syntax to create the extensible data notation. As a work in progress, you could further extend the extensible data notation, to add improvements to it. Future language designers may then improve it further.

Separating identity and values

The second most important aspect of Clojure is its emphasis on concurrency and immutability. Clojure has a state model that separates values from identities. Values are immutable but identities are associated with a series of values over time. Clojure doesn't prevent side effects, but it does say that you ought to log them to model changes over time. This enables STM concurrency.

Most of Clojure's constructs: its persistent data structures, its very strong emphasis on immutability and explicit modeling of state, are explained by the overarching goal of supporting concurrency. Immutability aids concurrency because immutable values can be safely shared between threads. Clojure doesn't eschew side effects, but it does emphasize that they ought to be concurrent.

Clojure certainly wouldn't appear in the shape it does now if it was created for any other purpose then its support for concurrency. If for example Clojure was designed with functional programming as an end in itself, it might have been a purely functional language. Instead, it was designed with concurrency in mind, so it doesn't appear like that. Functional programming is a means to an end. It is the currently acceptable means of implementing Clojure's goals of concurrency and explicit progression of time constructs.

Clojure's role in history is that it is a concurrent homoiconic language. There is nothing else in existence like it. It represents a truly unique programming philosophy. I think any other property of the language could be changed if it respected this core philosophy. The properties of being dynamic, functional, hosted, etc are more like implementation details then distinguishing characteristics of the language.

After all, Clojure is nothing like almost any dynamic language you have heard of. Dynamic languages almost never model state like Clojure does. Besides, Clojure developers make frequent use of type hints so that it can often appear like a statically typed language anyways. The typing discipline, the use of type hints, etc is just an implementation detail like any other. Hosting on the JVM is the logical thing to do when implementing a programming language.

These are all implementation details. Even the use of functional programming is mainly because it is more convenient when dealing with state management and concurrency, but as always functional programming must be part of a larger multi-paradigm umbrella. So functional programming is just another implementation detail. The main point is the code is data philosophy and the explicit modeling of time.

Wednesday, June 22, 2022

State management and user interface design

In this post, I will address Clojure's management of state. The importance of persistent data structures, state models, temporal databases, etc will be considered in both the fields of human-computer interaction and concurrency.

Clojure's handling of state

Clojure handles state differently from most other programming languages. Clojure divides logical entities into two types, values and identities.
  • Values: immutable data
  • Identity: an entity associated with a series of values over time
Values do not have state and are therefore immutable. Identities have states, which are their values at certain points in time.

Principles of user interface design

The first principle of user interface design is to always respect a user's decisions. After the user does something, you should never open a modal dialog box saying "Are you sure?." Modal dialogs always take away attention from the user. At the same time, a user may actually change his mind or make a mistake, and need to go back.

The means of supporting this is universal undo. Every major graphical user interface application has some sort of undo functionality. Take web browsers as an example. The key feature of HTML is its support for hyperlinks, which let you browse from one web page to another. Browser's enable the handling of a user's browsing history with forwards and back buttons.

Another example is text editors. They always support undo/redo functionality so that as a user types he/she always has the option of going back to a previous time in his/her typing history. Paint programs, video editors, or basically anything else that supports changing an entity over time supports undo. Undo is already vital to a wide variety of graphical user interface applications.

The key to supporting undo is the temporal management of the state of an application over time. In order to support universal undo we need to move away from the naive view of state, and instead view it a series of values over time. A user may change his mind at any time, which necessitates that we need move the value of our identity back to what it was at an earlier point in time. Furthermore, state managament like this should always be the default in all kinds of graphical user interface applications.

Temporal databases

The implementation of changes in values over time can be provided by temporal databases. A temporal database is like an ordinary database, except it also records changes over time. This is like what we need for graphical user interface applications, as it can be used to model the change's in an application's state over a time provided by the user. These temporal databases will then be the means by which we implement undo.

Interactivity in general

We see that the reason we need to explicitly model state in human-computer interaction is that it involves two different entities interacting with one another. When a human and a computer come together, it necessitates the management of identity so that a common understanding of the state of a program can be reached. This is actually analogous to the situation with concurrency, which involves different processors interacting with one another.
  • Concurrency: the interaction of different processors with one another
  • User interface design: the interaction of humans and computers
The issues in concurrency are somewhat similar: we need to reach agreement about the changes in shared state over time. Clojure's state management mechanisms like software transactional memory will make this easier for you. Concurrency is much easier if you explicity manage identity and state, just like user interface design. The only time when the naive model of state is sufficient is when creating single core programs that don't interact with the user at all.

External links:
Values and Change: Clojure’s approach to Identity and State

Swing HTML gallery

Swing and HTML are alike in a number of ways. Both are used to create graphical programs. Swing is based upon the Java beans component model, whilst HTML is based upon standard markup. Java beans encapsulate Java objects that are like nodes in an XML document. This is formalized by the XMLEncoder class of Java SE. Java beans properties are like HTML attributes. Swing's pluggable look and feel is like CSS.

The two frameworks differ in their original purpose, however. HTML emerged to extend text documents with hyperlinks, while Swing from the start was created as a full fledged graphical application framework. HTML's strength is in its hyperlinks and in creating rich text documents, so it has its own role to play. With the Swing HTML technology of Java SE you can get the strengths and benefits of HTML in your Swing applications.

To add HTML to Swing applications simply create a JEditorPane and set it to uneditable. Then set its editor kit to a HTMLEditorKit from the Swing HTML package. Editor panes are mainly used to view HTML rather then interact with it. There are two exceptions though, as you can use Swing to listen for hyperlink events and form submit events. Otherwise, your interactive components should not be part of an editor pane. Ten simple examples will be provided to demonstrate the cool things you can do with HTML in Swing.

1. An unordered list

(def unordered-list
  [:html
   [:body
    [:ul
     [:li "This is " [:b "bold"] " text"]
     [:li "This is " [:i "italic"] " text"]
     [:li "This is " [:u "underlined"] " text"]
     [:li "This is " [:strike "striked"] " text"]
     [:li "This is a " [:sub "subscript"]]
     [:li "This is a " [:sup "superscript"]]
     [:li
      [:font {:size 9} "This is "]
      [:font {:color "#00FF00", :size 9} "green text"]]
     [:li
      [:font {:size 6} "This is "]
      [:font {:color "#FF0000", :size 6} "red text"]]
     [:li
      [:font {:size 3} "This is "]
      [:font {:color "#0000FF", :size 3} "blue text"]]]]])

An ordered list

(def ordered-list
  [:html
   [:body
    [:h2 "Java history"]
    [:ol
     [:li
      "Java 1.0"
      [:ul
       [:li "AWT"]
       [:li "Base"]]]
     [:li "Java 1.1"
      [:ul
       [:li "Java beans"]
       [:li "SQL"]
       [:li "RMI"]]]
     [:li "Java 1.2"
      [:ul
       [:li "Swing"]
       [:li "CORBA"]]]
     [:li "Java 1.3"
      [:ul
       [:li "Java sound"]
       [:li "JDNI"]]]]]])

A description list

(def description-list
  [:html
   [:body
    [:dl
     [:dt "AWT"]
     [:dd "The original Java GUI toolkit."]
     [:dt "Swing"]
     [:dd "A GUI framework with its own pluggable look and feel."]
     [:dt "JavaFX"]
     [:dd "A modern replacement for Swing."]]]])

Java

(def java-image
   [:html
    [:body
     [:img {:src "https://upload.wikimedia.org/wikipedia/en/thumb/3/30/Java_programming_language_logo.svg/262px-Java_programming_language_logo.svg.png"}]]])

Clojure

(def clojure-image
  [:html
   [:body
    [:img {:src "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Clojure_logo.svg/240px-Clojure_logo.svg.png"}]]])

Code

(def hello-world
  [:html
   [:body
    [:h1 "JVM programming"]
    [:h2 "Java programming"]
    [:pre
 "class HelloWorld {
   public static void main(String[] args) {
     System.out.println(\"Hello world\");
   }
 }"]
    [:hr]
    [:h2 "Clojure programming"]
    [:pre
 "(prn \"Hello world\")"]]])

Blockquotes

(def quote-example
  [:html
   [:body
    [:h2 "Famous programming quotes"]
    "Alan Kay speaking on Lisp"
    [:blockquote "Lisp isn't a language, it's a building material"]
    "Rich Hickey on persistent data structures"
    [:blockquote "If you write a program that uses persistent data structures, you'll be able to sleep at night. You're gonna be happier. Your life is gonna be better."]]])

Swing HTML comparison

(def swing-html-comparison
  [:html
   [:body
    [:table
     [:tr
      [:td]
      [:th "Swing"]
      [:th "HTML"]]
     [:tr
      [:th "Component model"]
      [:td "Java beans"]
      [:td "Markup"]]
     [:tr
      [:th "Styling mechanism"]
      [:td "PLAF"]
      [:td "CSS"]]]]])

Buttons

(def html-buttons
  [:html
   [:body
    [:h1 "Buttons"]
    [:h2 "Ordinary buttons"]
    [:input {:type "submit" :value "Button"} ]
    [:br]
    [:br]
    [:h2 "Toggle buttons"]
    "Checkbox" [:input {:type "checkbox"}]
    [:br]
    [:br]
    [:h3 "GUI toolkit"]
    [:form
     "AWT"
     [:input {:type "radio"}]
     "Swing"
     [:input {:type "radio"}]]

    [:h3 "JSON library"]
    [:form
     "Jackson"
     [:input {:type "radio"}]
     "GSON"
     [:input {:type "radio"}]]]])

Forms

(def forms-example
  [:html
   [:body
    [:table
     [:tr
      [:td "Name: "]
      [:td
       [:input {:type "text"}]]]
     [:tr
      [:td "Password: "]
      [:td [:input {:type "password"}]]]
     [:tr
      [:td "Send to:"]
      [:td
       [:select
        [:option "Oracle"]
        [:option "Microsoft"]]]]]
    [:br ]
    "Message:"
    [:br ]
    [:textarea {:rows "6" :cols "25"}]]])
External links:
Swing HTML package