Beyond REPL? - On Design, Coding, No-Code, SwiftUI and Clojure

Recently, I have been thinking a lot about design, coding, no-code, SwiftUI, and what this all might mean for the Clojure/script community. TLDR - In particular, I wonder if there is any value to create a drag-and-drop no-code interface that creates lines of Clojure/script code.

What follows below is just my amateur two-cents: I’m just putting out my tentative-two-cents-thoughts on possible trends & directions. I would also like to caveat that I’m very much a #Clojurenoob and that I very much welcome critique, and pointers to alternative perspectives.

I also have no real agenda: this is really just some raw thoughts I’m throwing out for discussion, based on what I’m seeing from an amateur pov. If there’s prior work that I missed out, please do point me there! If you think this is nonsense, please feel free to say so, though I must also say that I’m not good enough with Clojure/script to do anything about my idea :sweat_smile: If anybody wants to run with this idea, that would be great!

Reflections on no-code

I had a few observations and thoughts on no-code, after a recent course I attended for work:

  1. No-code tools are now almost at parity with code, especially for simple web apps.
    Tools like Bubble.io allow the development and building of full-fledged web apps, with relatively intuitive interfaces. This allows almost anyone to create any app they have in mind. I think the craziest project I ever saw that demonstrates this, was this project which recreated Civilization VI on Webflow.

  2. No-code tools have overlapped greatly with design and prototyping tools, like Origami Studio, Figma, Framer etc.
    Like these tools, it’s relatively easy to create relatively high-fidelity prototypes and even interactions.

  3. … but one doesn’t just stop there! One can actually ship & test in market for product-market fit.
    An example of that is this startup that used Bubble to build their product, and get into Y Combinator.

But no-code has its problems, one of which is technical debt that grows very quickly, as described in this Hacker News post reply by mrspeaker:

…The rewrite would take some time.
Instead we launched with the Bubble app as it was. It targeted a niche market, and that market came flooding in - it really proved there was demand for the product and the feedback helped shape the end result - months ahead of where would have been if I re-wrote it.

But as the app grew we ended up with “spaghetti no-code”, slow loading times, crazy hacks, giant bundles (that we had no control over)… but again, it was good enough to launch with and validate the company, and it was fast to try out ideas.

We eventually did a full rewrite once we were happy with the overall structure of the app, but the process changed my perspective on the value of no-code tools in the right hands.

Two observations here:
a. no-code tools are great for testing designs, and getting products and features to test in-market quickly, but… performance is an issue at scale.

b. scaling by switching to code requires one to refactor rebuild the entire stack from scratch. It’s also noteworthy that Bubble covers the entire stack from database to front-end. This makes it harder to switch out from Bubble, as there is a much higher switching cost.

Using a stick-shift driving analogy, this is like going from gear 1, then having to stop completely and overhaul the engine before you switch to gear 2.

I would also add that no-code most directly overlaps with the most common web-stack languages: the no-code app that I built was (for all extents and purposes) very similar to the membership portal I created using HTML, CSS, JS and Node, hosted on Heroku…

Learn Clojure directly?

What about using Clojure directly? For most of the folks on Clojureverse, that is a no-brainer, because of your existing familiarity. Clojure and Clojurescript also offer tremendous power and leverage: I’m convinced that Clojure offers the technical leverage Paul Graham wrote about in Beating the Averages for most use-cases.

However, accessing this leverage is a lot for people outside Clojureverse: it’s going to be quite hard for a complete programming noob to grok Clojure sufficiently to make an app for testing the idea in the market. The learning curve is steep, and steeper than a comparative no-code tool.

I would also add that the difficulty is perhaps intrinsic: many of the challenges intrinsic in Clojure have to do with paradigm-shifts. Changing one’s view & perspective is both the simplest and hardest thing in the world. So it’s not trivial.

Alternative? Suggestions from Figma and SwiftUI

Right now, there seems to be a gap between no-code & Clojure: there’s nothing in -between. Maybe what is needed is something of a combination of two things:
a. no-code interface of components, which allows quick & easy product discovery & testing by designers or product managers or non-technical founders,
b. combined with a high-leverage code interface that allows easy refactoring and scaling up by developers. In my mind, it’s a no-brainer that this should be with Clojure/script, simply due to the leverage that the language gives.

This combination reminded me of a completely different tool: Figma.

Figma’s biggest impact isn’t the fact that it’s an interface/interaction design tool like Sketch: from a designer’s pov, the core functionality is very similar. The biggest impact is the fact that Figma allows for the seamless interaction between designers, product managers and developers, shortening the larger design process loop. This was best explained by Kevin Kwok in his blogpost:

Pic from Kevin Kwok’s blog

If you change “design” to “design & code”, that becomes even more interesting, because it offers the possibility of the smooth gear-shift from gear 1 to 2 & beyond, without needing to stop or overhaul. That’s what I think is an interesting possibility to explore.

REPL-driven-development already offers that partially, with the very fast iteration by the engineer. But imagine if designers and PMs can also provide input!

This is where I think SwiftUI offers an interesting illustrative possibility for Clojure/script’s future direction, beyond REPL-driven development.

SwiftUI seems quite similar to Clojure: there is a real-time view of the compiled code & hot reloading (though I’m not sure it allows for expression-level evaluation!) REPL-driven development already offers a lot of this.

For me, the most exciting part of SwiftUI is that it allows drag and drop of components and features into the Canvas, while updating the code base in real-time. This is like a REPL in the other direction: from the app/view into the codebase. It’s almost as though someone has a no-code tool attached to a code editor. That might allow the larger team to iterate more quickly.

So the prompt question I’m posing to the community is this: what if Clojure/script develops SwiftUI-like drag-and-drop of components & features into the app, like a no-code/low-code style “reverse REPL”? How could that help with Clojure/script’s adoption?

4 Likes

That civ4 mock is pretty serious.

No-Code/Visual-Design type tools are great for managing assets and game editors are probably the best example. For 3d stuff, It’s definitely possible to connect to a remote instance of Blender and script it via a repl.

The reverse repl thing (swift ui) is really cool and it’s very attractive for designers/beginning devs/people that want a more immersive experience but I dunno… I don’t feel like it’s that great a feature to have the cursor move to the line when you click on a box on the editor. What happens if you are generating a bunch of boxes by code instead of drawing each box out on the gui? Where does the cursor move to then?

RAD tools for databases are pretty cool too but It also depends on what you’re trying to do. What happens when you want to stream db events via a custom protocol to the ui? I’m not sure how the tool will help.

Visual-tools meeting 6: general monthly meeting may have people doing something similar to what you’re talking about - but with data visualisation as opposed to guis.

2 Likes

Fair points. I had two thoughts in response:

  1. When you’re generating a bunch of boxes using code instead of drawing it on the GUI, that’s probably not very different from the REPL?

  2. The reverse REPL would definitely benefit non-devs more than devs directly. But the gain is that it might allow for a faster design-process-loop of the larger team (including non-devs), in exchange. Kinda like Figma allowing non-designers to actively participate in the overall process.

I’m not sure what you mean by this. Are you saying the cursor would likely move to the same spot?.

can you give an example?


Mind you, this isn’t really a new thing. Visual Studio, Eclipse, Flash had similar features for it’s gui editor. It wasn’t that great an experience. You can do stuff like this in any decent game editor - linking code and visual elements. It’s good for fiddling around with things but I also don’t think visual tools solve the issue of software complexity. In my experience, it usually makes things more complicated - and that’s the tradeoff I guess.

1 Like

These type of tools existed in the past, such as Adobe Flash, Eclipse WindowBuilder (that’s a Java bidirectional one for Swing), etc.

I think maybe the newer batch with being made compatible for the web would become more popular, more people are using computers than ever before as well.

In my experience with the older stuff, it just ended up being used by devs and eventually abandoned because it was easier to do it with code.

There’s a kind of reverse pattern of all this as well, LaTex, Markdown, PlantUML, etc. People actually moving away from visual tools for writing and diagrams and to code based ones.

I still think these tools are great, but I think the market for them are people or companies that don’t have developers. Once they grow big enough to have a developer chances are it will get rewritten in code.

The problem I found is that it’s harder to be precise and to scale with visual tools. How do you have two or three or four people working on it at the same time? How do you reuse parts from one project in another easily? How are you sure all the alignments are handled properly?

And then there’s the issue that you’re working in 2 dimensions, once you start having multiple pages, animations, interactivity, there’s almost too much for the interface to handle.

I think an alternative to these are live-preview. The code is still the interface, but you get a live preview of the application.

Now it be cool to have a two-way interaction, but sometimes the visual view will just mess up your code haha, that’s the downside.

Still, there’s value in certain scenarios for some people. I know in games a lot of things are done through visual editors.

I used to do MaxMSP as well, and that’s not exactly the same thing, it’s more of a visual programming language, and it did work great for the use cases around it, though you’d be able to drop into the code for certain pieces as well when needed.

4 Likes

totally agree with that.

1 Like

This is an area I’ve been thinking about and doing something in for many years now so I’ll share some thoughts.

Firstly, to make sure I understand you correctly, I’m going to paraphrase (and in the process greatly oversimplify) what I believe you’re saying:

  • Clojure/Script is awesome, but the learning curve is steep and only available to devs
  • No-code has great UI tools which non-devs can use more easily to produce, essentially, applications (web sites, etc.)
  • Wouldn’t it be nice if we could combine the awesomeness of Clojure/Script with UIs of no-code so that we can have UIs which can create Clojure/Script code?

I haven’t used SwiftUI so I won’t comment on that. I have used Visual Studio, so I will comment on that.

The way I think about it, you have three types of interface:

  • GUI - Graphical UI
  • TUI - Text-based UI
  • Hybrid GUI and TUI

The desired outcome is what we’ll call an app, but can in actual fact really be anything at all if you are willing to extend the definition. I can in theory write code to generate an image for example.

No-code is pretty much 100% GUI as far as I’ve seen (though I believe some let you write code, which I think are called “low-code”).
Programming languages are 100% TUI.
However, increasingly more and more IDEs are providing Hybrid GUI and TUI capabilities.

Take Visual Studio as an example, and referring to the version I used from 2005 to 2012. We had form designers and web form designers which are very much GUIs which consist of a canvas for drawing forms plus usually a properties panel. You draw something in the GUI, and it would generate code for you which is also editable via a separate TUI.

When I first saw this I thought it was the coolest thing in the world, something that would revolutionize programming. And for a while, it was pretty neat. But as others have said, there are problems. The major issue with this setup is synchronization: I make a change in the GUI, it is reflected in the TUI. Neat. However, I make a change in the TUI, and most of the time the GUI doesn’t understand it. For example, in the GUI I can place a button onto a form and that will generate all the code for the button, the form, and for adding the button to the form in the TUI. However if I now go and update that code in the TUI, the GUI will almost definitely have problems understanding most of the code in that I have entered into the TUI, because, well it’s a GUI and has limitations as to what it can do.

This is actually what makes GUIs so brilliant and so suited to certain scenarios, the fact that they impose constraints on what is possible. However, it also makes bidirectional updating extremely challenging. This might have improved since I used VS, however the fundamental problem will still remain.

The problem can easily be solved by only providing a single interface for coding, so either a GUI or a TUI, in a given context. But allowing a user both will in most cases lead to problems.

As an alternative, you can have a GUI generating initial code by gathering information say in a popup, and generating a function, class or whatever. But, from that point on, the GUI should have no part to play in the further editing of the code, and it should only be done in the TUI. This is in effect what code snippets are, a feature available in most IDEs.

One area where I strongly feel we need better GUI tools is in the management of data or config files or even just structures. Take for example a leiningen project.clj or deps.edn and you can easily write wonderful GUIs that let you edit these files. At present you have to construct one of these files by hand, and you have to lookup what goes into each. The documentation which effectively specifies what can go where, and which information needs to be obtained from other sources (e.g. contacting maven for a list of available packages and package version numbers) can easily be incorporated into an app which allows you to manage these files, and you should never need to manually edit them in a TUI but can if you wish to without breaking the constraints that the GUI is expecting.

Extending this idea a little further, there is no reason why a library developer can’t provide specs for data structures that you need to create to pass to APIs, so that a GUI tool can be used to manage those data structures within your application. For example, I may have an API which requires a map to be specified which has keywords :name, :dob, etc. Obviously for something this small it is hardly worth it, but for a large app config, something can definitely be provided.

Thinking outside of just the Clojure/Script world, HTML and CSS files are prime candidates for GUI-based coding, and there are I’m sure numerous editors which provide this capability.

Another area which I think we can improve on greatly is what I term GUI-in-TUI. A great example of this is when entering colour hex codes into a program, I find it a complete PITA. What would be really nice is if in the middle of my code (within a TUI) at the point at which I wanted to enter a hex code, instead a popup can open and allow me to select a colour from a colour selector widget. Yes, there are plugins which work mostly with CSS stylesheets which can detect a hex code and show its background colour correctly, and that’s wonderful. But we need more things like this.

Along similar lines is drawing shapes. In a TUI I would write imperative or declarative code to represent shape points, stroke colours, fill colours and so on. It would be lovely to just edit say an SVG viewport directly using drawing tools, and for that to generate the correct code in my program. But again we’re back to similar issues that Visual Studio had so we will run into limitations here. Another limitation that is pertinent here is of course how can you express a circle with a variable radius? Or any variables in a GUI where you wish to draw shapes? It isn’t impossible but it’s certainly something you need to think about.

As an alternative to GUI-in-TUI, you can also have TUI-in-GUI. So for instance you can create a button in an interface, and provide say the event handler code as a property of button in the properties panel. Sure, why not. I haven’t explored this as much as I have GUI-in-TUI because I believe there is a lot more that can be done with GUI-in-TUI.

The final thing I want to ask is, which specific category of user are we trying to improve the experience for? Is it for developers, or for designers, or any other category of non-developer? I looked at Bubble a few years ago when I first started out, and my conclusion was that although it was a very nice product, it definitely wasn’t something that developers would ever want to use. I wasn’t sure who the target audience was, but the creators claimed that it was at the very least for people who wanted to create a startup but didn’t want to hire developers, so essentially to save money. This is fair enough, and a reasonably ok selling point, however ultimately someone will have to learn Bubble in order to create their app, and the app would still take time to create it. If I was running a small company, I would much rather hire any number of developers that I could afford than hire someone to produce a Bubble app, because of the flexibility in what they can do. No matter what, Bubble, and all other no-code offerings, will have limitations.

As I see it, Bubble is aimed entirely at non-technical people and essentially allows you to configure components in a limited number of ways and to join them together in again a limited number of ways to provide the functionality of your app. This is wonderful for non-technical people and young children who want to tinker with things, but for most other purposes I don’t think it will appeal to users.

There is also a point about “primitives”. In TUI-based coding, there are well-defined primitives such as numbers, strings, booleans, functions, maps, sets, hash-maps, arrays, objects, classes and other fundamental building blocks that a programmer can learn about and use to construct their programs. And these are pretty universal in that they don’t apply to a single language. If we go the way of the GUI, it’s very difficult to find equivalent building-blocks other than high-level components.

So in conclusion, for developers, I would start with the TUI and work towards incorporating GUIs as and where possible. For non-developers, just use something like Bubble or any of the offerings you have mentioned above.

3 Likes

An obvious example of GUI-in-TUI is emacs. In emacs when connected to a live environment, constructing a “button” that can be used later is as simple as typing (+ 1 2 3) - as all code can be executed.

This is what lisp and in particular clojure provides → an extremely succinct language abstraction.

In the case of targeting a specific environment - (to generate a customised button, within a browser) this functionality is a bit harder to obtain but is infinitely more useful.

Having a live repl into the framework helps a lot (ie. browser console). I’d argue that it’s all that’s needed to do interactive development. You can simple copy and paste code from a file into the browser console and iterate. However, the problem is that copy and pasting code is slow. For cljs devs, this is very trivial (browser repl anyone?). Some people may not want cljs and all the dependencies that it brings. Currently as it stands, tough luck for them.

However, I do think this workflow can be generalised. The only part of cljs that is critical to this is the browser repl protocol. In the case of your svg viewport example. I would imagine a simplified browser/emacs workflow to be along something like:

  • assuming that emacs is somehow connected to the browser and has a function receive input that is invokable.
  • you can then copy and paste code in the browser - in order to generate the gui tool that you need to draw a particular graphic.
  • after you are done editing the graphic, you then press a button (also generated by the copy and pasted code) that calls send input which sends the data representation of the edited graphic back to emacs.
  • going back in emacs you can call receive input. Given the graphic data, and a format function that knows what to do with that data, it will generate the code and print it out at the line you want it to be at.

Of course, this doesn’t have to be strictly browser/emacs. It can be also be any interactive coding environment being able to connect and communicate to a any interactive graphical environment.

Thinking it through a little bit more, this setup should be able to facilitate this type of workflow.

  • cyan coloured blocks already exist.
  • yellow blocks represent the gui tooling (select a color, draw some lines). The source code for the tool written in lisp, and injected into the browser through the js adaptor/transpiler (cljs automatically comes to mind but it can be another transpile mechanism).
  • the purple block contains
    • runtime representation of ui elements (processed by transpiler) (1)
    • transforms to represent ui elements
      • from code to data (2)
      • from data to code (3)
    • any ui elements will require at least (1) for one way injection (from code to browser)
    • two way injection (allow tools to communicate with code) will require (2) and (3)

If the transpiler is generic enough, It should work for any combination of Language/Editor/Graphical UI

ie.
Js/Calva/Browser
Swift/Emacs/SwiftUI
Python/Emacs/Blender

1 Like

Thanks @outrovurt for your detailed reply! I’ll mull on this further.

I just had one point to clarify here:

My main point was that, there’s no bridge between the two: after you build something in Bubble, you basically have to rebuild it in Clojure/script from scratch. That seems to me to be a waste of time and effort.

Yes, emacs is a great example of GUI-in-TUI, and affords many wonderful facilities for developers. The only downside is that there is a steep learning curve and it isn’t really suitable for non-devs, which was the OP’s original target group (I believe).

Lisps also lend themselves nicely to GUI representation due mostly to the well-defined shape of Lisp forms. For example, you can much more easily represent a let block graphically (as say a table of two columns and a return expression) than you can an equivalent programming construct in any other language. The same is true for probably the majority if not all forms. Anything which can be expressed in Lisp via a TUI can be expressed just as easily in a GUI. This then allows you to mix and match different GUI widgets with your standard code to achieve some of the things I described in my post. If this isn’t clear now, I’ll post what I’m working on once I’ve released it as it is pretty much along these lines.

1 Like

There’s no straightforward solution to this, and I suspect that that’s because there actually isn’t one to be found. As I alluded to in my post, I would / have personally started at the “other end”, improving tools for developers and introducing more GUI-based elements there. From that point, build more and more tools on top of that which are more user-friendly towards non-devs, all the while allowing anyone with the right skills to open up those higher level tools, modify, extend, rewrite them and so on.

One major obstacle with No-Code is that the No-Code developer is presented with a set of components, for want of a better word. Those components are configurable in essentially a finite number of ways. But as a Traditional developer, I would like to open up a given component, and see how it works from the inside. What is it made up of? What are its inputs, outputs, overall operation, dependencies and so on. to the best of my knowledge, that isn’t possible with No-Code, because essentially, No-Code components are built with, well, code! So learning how a No-Code component works, or building a No-Code component from scratch would involve learning and understanding code.

This means that the No-Code platform has to provide all the building blocks that can ever be required, and it isn’t particularly easy to look inside those blocks, or to create new fundamental building blocks yourself. The only way to create new components is to combine existing components. This is great for the target audience of the No-Code platform, however it also means that you will hit a brick wall which is pretty much insurmountable.

The point at which a No-Code developer wants to take things further, we are saying that they need to learn how to code! I would even argue that No-Code is itself a form of coding, albeit a greatly watered down version designed to attract non-coders.

The question then becomes: if you as a non-coder wish to become a coder, is it worth investing the time and effort in learning a No-Code platform, and then learning coding from scratch, or should you just put that same time straight into learning coding?

In my opinion this is quite accurate. There is definitely an audience for No-Code, however I think the focus is on getting something up and running quickly without all of the hassle and steep learning curve of learning a programming language, or alternatively without having to pay a lot of money to a development team to produce a similar result. I also see it as a useful tool for prototyping, and I’m sure it can be used in educational settings both for children to create things quickly without having to learn to code, and for teachers to create learning experiences again without all the hassle of coding.

1 Like

sweet. looking forward to it.

1 Like