Low-Code Programming Models

Low-code has the potential to empower more people to automate tasks by creating computer programs.


INTRODUCTION
Low-code is the subject of much current enthusiasm stirred by market research companies and confirmed by vendors rushing to embrace the label [7,32].But it is cryptic exactly what low-code programming means, let alone how it works, and the scientific literature hardly uses the term.We can decode the term by breaking it into its components.Programming means developing computer programs, which comprise instructions for a computer to execute.Traditionally, programming means writing code in a textual programming language, such as C, Java, or Python.In contrast, low-code programming minimizes the use of a textual programming language.Instead, it aims to use alternative techniques that are closer to how users naturally think about their task.
Users of low-code range from professional developers to so-called citizen developers.A citizen developer is an amateur programmer with little professional programming education.Citizen developers, having chosen a career different from programming, tend to have more domain expertise.Lowcode enables domain experts to become citizen developers.At the same time, low-code platforms should also strive to make pro-developers (professionals with an education or career in software development) more productive.
Whether used by a citizen developer or a pro-developer, low-code programming aims to save the time and tedium of performing a task by hand [35].Further motivation for individuals comes from the joy of creating something useful, thinking about tasks in a computational way, and acquiring programming skills that can advance their career.Besides individuals, businesses may have their own motivation for adopting low-code platforms.Low-code platforms can alleviate the shortage of pro-developers, reduce mistakes of tedious manual tasks, and multiply the time savings from one individual's low-code program to their colleagues [32].Another factor driving low-code is the rise of cloud-based software as a service, providing both more interfaces to automate and a platform on which to deploy automations.
A few concepts are closely related to low-code programming.No-code programming is more purist, with zero handwritten code in a textual programming language.This term mostly appears in marketing materials and analyst reports.End-user programming (EUP) puts the emphasis on who is doing the programming (the end-user as citizen developer) rather than on how they are not doing their programming (not with textual code) [6].This term is common in the academic literature and overlaps with low-code, but does not preclude the use of a textual programming language.Another gap between EUP and low-code is that the latter aims to serve not just end users but also pro-developers [7,32].
Bock and Frank [7] and Sahay et al. [32] recently compared commercial low-code platforms, and Barricelli et al. recently mapped the end-user programming literature [6].In contrast, this article bridges the gap between low-code and the academic literature and adds missing details and perspective.Low-code encompasses more specialized techniques, such as VPLs (visual programming languages), PBD (programming by demonstration), PBE (programming by example), RPA (robotic process automation), PBNL (programming by natural language), and others.Surveys on these are more specific and often dated [4,8,22,35].In contrast, this article reviews recent literature across all above-listed techniques.
Given that low-code offers citizen developers a model to create computer programs, this article explores low-code from the perspective of programming models.A programming model is a set of abstractions that supports developing computer programs.Programming models can be low-code or not, and they can be domain-specific or general-purpose.Some programming models are languages; e.g., Java is a general-purpose language and SQL is domain-specific, and neither is low-code.Scratch is a low-code programming model for kids that is media-centric [30], making it domainspecific.The programming-model perspective helps this article highlight common techniques for writing, reading, and executing programs.Furthermore, the programming-model perspective helps relate low-code to research into program synthesis and domain-specific languages.
This article includes a deep-dive for three prominent lowcode techniques: visual programming, programming by demonstration, and programming by natural language.The deep-dive focuses on fundamental building blocks and a unifying framework common to all three.The citations in this article cover both seminal work and recent advances in lowcode programming models, for instance, based on artificial intelligence.Overall, this article aims to cut through the buzz surrounding low-code so as to expose the technical foundations underneath.We hope that doing so will foster better development of the field through awareness of existing (albeit scattered) research.Ultimately, we hope this will lead to even more empowered citizen developers.

PROBLEM STATEMENT
If low-code is the solution, then what is the problem?Given the term low-code, it might seem that the answer is obviously code.Unfortunately, that answer is superficial and nonconstructive.Defining a thing solely by what it is not, as the term low-code appears to do, causes confusion.Consider two other recent similarly-named trends: NoSQL and serverless.At the surface, one might think NoSQL was mostly about rejecting SQL, but in fact, it was more about flexible data and consistency models than about the query language.Similarly, serverless computing was not about eliminating compute servers, but about hiding them behind better abstractions.Defining a new trend by rejecting an old one grabs attention at the expense of being misleading.Just like serverless still needs servers, low-code (and even no-code!)still needs code.
Instead, the three terms low-code, NoSQL, and serverless have one thing in common: a desire to avoid specific baggage while preserving core value.In NoSQL, the core value is durable and consistent storage.In serverless, it is portable and elastic compute.What then is the core value that lowcode aims to preserve?This article argues that it is computer programming.Programming is to low-code what computing is to serverless.Low-code is about creating instructions for a computer to execute or interpret.These instructions form a computer program, typically in a domain-specific language (DSL).For instance, low-code is often based on search-based program synthesis, and synthesis usually targets a DSL carefully crafted for the purpose [2].The program may not be exposed to the user, but it is there.
One way to better understand the problem statement behind low-code is to look at who it is for.The top portion of Figure 1 shows the spectrum of low-code users.They range from citizen developers at one end to pro-developers at the other end, with intermediate stages here dubbed semi developers.In this simplified view, users at the citizen developer  end of the spectrum tend to have the most domain knowledge and users at the pro-developer end have the most programming expertise.Low-code can enable citizen developers to self-serve their programming needs instead of depending on pro-developers.At the same time, low-code can make prodevelopers more productive, e.g., in a new domain.Finally, low-code can break barriers between developers across the spectrum and help them collaborate on common ground.
The middle portion of Figure 1 shows three representative low-code techniques.Programming expertise induces a Venn diagram over the users, with the smallest subset being able to use the largest range of programming techniques.An edge between a set of users and a low-code technique indicates that the users write or read a program with that technique.Specifically, all users can use programming by demonstration and programming by natural language (edges to the outermost set of users encompassing citizen-, semi-, and prodevelopers).Only semi-developers and pro-developers can readily use visual programming, though citizen developers may be easily trained to do so, as evidenced by Scratch [30].And only pro-developers are likely to directly use a domainspecific language (DSL).Therefore, while low-code typically targets a DSL, that DSL may not be exposed, or if it is, may only be exposed to pro-developers.That is especially true in the common case of a DSL that is embedded [18] in a generalpurpose textual programming language such as Python.
If the core value of low-code is to create computer programs, what exactly is it about created programs that is deemed valuable?One way to shed more light on this question is to look at a seemingly opposing trend, namely the as-code movement.The as-code movement started with infrastructure as code, which automates standing up compute resources and the services running on them from a source code repository and a backup [19].By treating this process as code, organizations can speed it up, reduce mistakes, and facilitate testing.Another instance of as-code is security as code, where security policies, templates, and configuration files all live in a source code repository [26].By treating them as code, they can be versioned, inspected by humans, and checked by machines.To summarize, the as-code movement sees value in programs that are repeatable, tested, versioned, human-readable, and machine-checkable.These are also desirable properties for low-code programs.
When citizen developers use low-code, it is typically to create a program that saves time on a task they would otherwise do by hand.We will round out the problem statement by looking at what tasks low-code is good for.Generally speaking, low-code helps if it shaves off more time from a task than the time spent doing the low-code programming.This is true for tasks that are repetitive or time-consuming.Of course, the equation shifts when the program can be used not just by the developer who created it, but also by others, shaving time off of their tasks as well.In the extreme, prodevelopers create programs used by millions.Low-code is most appropriate when it saves time, but not enough time to make professional coding economically feasible.Low-code is suitable for tasks that are rule-based and low on exceptions.And besides the time savings, it can be even more beneficial when the tedium of doing the task by hand causes errors.

TECHNIQUES
This section is a deep-dive into three representative techniques for low-code programming: VPLs (visual programming languages), PBD (programming by demonstration), and PBNL (programming by natural language).These three are a good set for the following reasons.Sahay et al.'s paper declares low-code as synonymous with just one technique, VPLs [32], but we found that perspective too narrow.Barricelli et al. list 14 different techniques for end-user programming [6], but they are not clearly separated, and reviewing them all in detail would get too long-winded.In the past, the dominant low-code technique has been spreadsheets [9].The three techniques we chose instead align with present and future trends: VPLs are central to current commercial lowcode platforms [32]; PBD is the back-bone of robotic process automation (RPA), which often uses record-and-replay [35]; and PBNL is poised to grow thanks to advances in deep learning based large language models [11,34,39].
Furthermore, the three techniques are well-suited for citizen developers by drawing upon universal skills: VPLs draw upon seeing, PBD draws upon the ability to use a computer application, and PBNL draws upon speaking.In fact, lowcode can offer an alternative modality when some other approach is impeded, such as using speech interfaces when a user's hands or eyes are unavailable.Finally, VPLs, PBD, and PBNL are sufficient to span a set of building blocks that can also be arranged differently for use with other low-code techniques, such as spreadsheets, rules, wizards, or templates.Not all building blocks appear in all techniques, but the following blocks recur enough to warrant brief up-front definitions: • code canvas: renders code, e.g., visually as a flow graph • palette: offers components for drag-and-drop selection • text box: holds natural-language text used for code search, description, or generation • player: has buttons for capture, replay, pause, or step • stage: shows the effect of code execution • configuration pane: lets the user customize components, e.g., via graphical controls such as check-boxes or sliders, or textually by typing small formulas Low-code techniques support not just writing programs, but also reading and executing them.Low-code techniques differ in which of the above-listed building blocks are engaged to read, write, or execute programs.Whereas Figure 1 blurred the read/write/execute distinction by using undirected edges, the rest of this section explicates the distinction by using directed edges and colors (orange for read, dark blue for write, and purple for execute).

Visual Programming Languages
The user drags visual components from a palette to a canvas, connects them, and configures them.

Palette Code canvas Stage
Config.pane Description.Visual programming languages let users write programs by directly manipulating their visual representation.There is a plethora of possible visual representations [8], often inspired by domain notation, such as electrical circuit diagrams.Two prominent domain-independent visual representations are boxes-and-arrows (e.g., BPMN [28]) or interlocking puzzle pieces (e.g., Scratch [30]).Here, boxes or puzzle pieces represent instructions in the program, and arrows between boxes or the interlock of pieces represent how data and control flows between instructions.Despite the diversity in visual languages, their programming environments tend to comprise similar building blocks, as depicted in Figure 2. The central building block is the code canvas, where the user can both read (red arrow from canvas to eye) and write (blue arrow from hand to canvas) the program.Writing the program also involves dragging components from the palette to the canvas and possibly configuring them in a separate configuration pane.The programming environment also often includes a stage, which visually shows a concrete program execution in progress.For example, in Scratch, the stage shows sprites in a virtual world.Besides making the environment more engaging, the stage is also crucial for program understanding and debugging.To facilitate this, the stage is usually tightly connected to the canvas, helping the user navigate back and forth.
Strengths, weaknesses, and mitigations.One strength of VPLs is that they tend to be easy to read, either by reusing notation that is already familiar to the domain expert or by using a clean notation with general appeal [8].Another strength is that, in contrast to PBD or PBNL, VPLs are usually unambiguous, thus increasing programmer control and reducing mistakes.Finally, compared to textual programming languages, visual languages can rule out syntax errors [37] and even simple type errors [30] by construction.
In the context of low-code programming, the main weakness of visual programming languages is that they are not always self-explanatory; that is why Figure 1 connects them to semi-developers.The mitigation for this need-to-learn is user education, and for some VPLs, education is a primary purpose [30].The visual notation can take up a lot of screen real estate; the mitigation for this is to elide detail, e.g., by requiring a configuration pane or via modular language constructs [3,27].Even the palette can get too full, hindering discoverability, which can be mitigated by search facilities.A drawback of visual languages compared to textual languages is that they tend to be co-dependent on their visual programming environment, hindering the use of basic tools such as diffing or search, or of third-party tools such as linters or code generators.This can be mitigated by backing the visual language with a textual domain-specific language [37].
Literature.Some seminal VPLs include Harel's StateCharts system specification language [16]; BPMN-on-BPEL for modeling and executing business processes [28]; and the Scratch language for teaching kids programming [30].Boshernitsan and Downes chronicle early VPLs and categorize them into purely visual vs. hybrid (mixed with text), and complete (sufficient procedural abstraction and data abstraction to be self-hosting) or not [8].
Other papers address VPL implementation approaches, such as meta-tools (tool used to implement other tools) and the model-view-controller (MVC) pattern (which lets users manipulate the same model through multiple synchronized views).VisPro is a meta-tool for creating visual programming environments [40].VisPro advocates for a coordinated set of visual and textual languages, using MVC to expose the same program (model) via multiple languages (views).More recently, Blockly is a meta-tool for creating VPLs with interlocking puzzle pieces [29] like in Scratch.And mage is a meta-tool for embedding VPLs in notebooks [21].Some VPLs target pro-developers and are embedded in professional programming environments or languages.Projectional editing, such as in MPS [37], doubles down on the MVC paradigm, where even the textual language is projected into a view that precludes syntax errors.More recent work has demonstrated VPLs as libraries extending textual languages such as Racket (a Lisp dialect) [3] and Elm (an ML dialect) [27].

Programming by Demonstration
The user demonstrates the behavior on a canvas, with some configuration during or after recording.

Stage Player
Config.pane The program is most useful if executing it does not yield exactly the same behavior as the initial demonstration, but rather, generalizes to different data.For example, a program for ordering a taxi to any new location is more general and more useful than a program for ordering a taxi to only a single hard-coded location.Generalizing typically requires identifying variables or parameters, and may even entail adding conditionals, loops, or function calls.Unfortunately, a single demonstration is an inherently ambiguous specification for such a more general program.Therefore, PBD systems often also provide a configuration pane that allows users to disambiguate the generalization either during or after demonstration.Some PBD systems also have a code canvas that renders the recorded program for the user to read, e.g., visually or in natural language.

Code canvas
Strengths, weaknesses, and mitigations.The main strength of programming by demonstration is that the user can work directly with the software applications they are already familiar with from their day-to-day work [23].This makes PBD well-suited for citizen developers, as there is no indirection between programming and execution.Furthermore, a demonstration is more concrete than a program in a different paradigm, since it works on specific values and has a straight-line flow of control and data.
Unfortunately, being so concrete is also PBD's main weakness: to turn a demonstration into a program, it must be generalized, and automatic generalization may not capture the user's intent [14].Mitigations include hand-configuration [23] or multi-shot demonstration [15].PBD can be brittle with respect to the graphical user interface of the application on stage, especially when that changes; mitigations include heuristics and specialized recorders that can map perception to application-level concepts [33].Generalization can also overshoot, allowing a program to plow ahead even in unforeseen circumstances [17].This can be mitigated by providing guard-rails, such as an attended execution mode that asks the user to confirm before certain actions.Finally, PBD can result in programs that are hard to understand because they include spurious steps or are too fine-grained, which is of course a problem in low-code programming [10].This can be mitigated by pruning and by discovering macro-steps.Literature.A good example of a PBD system is CoScripter, where the stage is a web browser and the code canvas displays the program in natural language [23].The CoScripter paper describes interviews that informed its design, as well as experiences from real-world usage in a business setting.In Rousillon, the stage is also a web browser and the canvas displays the program in a VPL, fusing sequences of several low-level steps into a single puzzle piece [10].In VASTA, the stage is the display of a mobile phone, and the system uses machine learning to reverse-engineer screenshots into user interface elements [33].In DIYA, the stage is a web browser and users customize the program during recording via voice input [14].Robotic Process Automation applies PBD to business processes, by letting a human business worker demonstrate a process on the existing software and referring to the automatic replay engine as a robot [35].
Programming by demonstration (PBD) is closely related to programming by example (PBE), since a demonstration is an elaborate example.FlashFill is a seminal PBE system that uses example input and output columns in a spreadsheet to synthesize a program for transforming inputs to outputs [15].Both PBD and PBE are based on program synthesis [2].Recent work has harnessed novel machine-learning techniques for program synthesis, such as learned search strategies in DeepCoder [5] and learned libraries in DreamCoder [13].
PBD can be profitably combined with other low-code techniques.The play-in / play-out approach is a PBD system codesigned with its own VPL based on sequence diagrams [17].And SwaggerBot is a PBD system embedded in a naturallanguage conversational agent, enabling a form of PBNL [36].

Programming by Natural Language
The user enters natural language text via keyboard or voice, and the system synthesizes a program.Description.In this low-code technique, the user enters text in natural language, either by typing on the keyboard or via speech-to-text.Figure 4 indicates these two possibilities via blue arrows from the user's hand or mouth to the text canvas.The PBNL system translates the user's text, or utterance, to a program.The system can optionally render the program on a code canvas for the user to read.This rendering might use a VPL, or it might use a controlled natural language [22] for a disambiguated version of the user's utterance.The PBNL system can execute the program immediately or save it for later, and the user may choose to execute the program multiple times, e.g., after changes to the program's input data.The system can also optionally show the effect of the program's execution on a stage.For example, if the program is a query in a spreadsheet, the spreadsheet is the stage, and the result can be shown as a new table.
Strengths, weaknesses, and mitigations.The main strength of PBNL is that it is not just low-code, but more generally, low on demands during programming.As shown in Figure 4, its programming environment has only three building blocks (text canvas, code canvas, and stage), and all three are optional.That means PBNL can in principle even be applied in circumstances where the user's hands and eyes are otherwise occupied.PBNL makes it particularly easy for citizen developers to create programs.Another strength of PBNL is its expressiveness: natural language can express virtually anything humans want to communicate.PBNL restricts neither the sophistication nor the domains of programs.
Unfortunately, while PBNL makes creating programs trivial, those programs are often wrong [4].Natural language is ambiguous, since humans are often vague and tend to omit context or assume common ground.On top of that, natural language processing (NLP) technologies are imperfect.The optional code canvas and stage mitigate this weakness, by showing the user the synthesized program or its effect, thus giving them a chance to correct it.Another mitigation is to encourage users to keep their utterances short and not take advantage of the full expressiveness of natural language, since simpler programs are easier to get right [24].Furthermore, some PBNL systems support hand-editing the program.Another weakness of PBNL systems is that they often require an aligned corpus of utterances and programs to train machine-learning models, and obtaining such a corpus is expensive.Mitigating this is an active research topic in the machine-learning research community [34,38].
Literature.As an interdisciplinary field of research, PBNL is best illuminated through multiple surveys.Androutsopoulos et al. surveyed natural-language interfaces to databases, a prominent form of PBNL going back to the 1960s [4].A common approach is to parse a natural-language utterance into a tree and then map that tree to a database query.Kuhn surveyed controlled natural languages (CNLs), which restrict inputs to be unambiguous while preserving some natural properties [22].Compared to unrestricted natural language, CNLs may make it harder for citizen developers to write programs, but may make it easier to write correct programs.Allamanis et al. surveyed machine learning for code, arguing that code has a "naturalness" that makes it possible to adapt various NLP technologies to work on code [1].The survey covers some code-generating models relevant to PBNL.
The most successful NLP technology applied to PBNL is semantic parsers, which are machine-learning models that translate from natural language to an abstract syntax tree (AST) of a program.For instance, SILT learns rule-based semantic parsers that have been demonstrated for programs that coach robotic soccer teams or for programs that query geographic databases [20].The Overnight paper addresses the problem of obtaining an aligned corpus for training a semantic parser via synthetic data generation and crowdsourced paraphrasing [38].Pumice tackles the ambiguity of natural language by a dialogue, where the system prompts for clarification which the user can provide via natural language or demonstration [24].And Shin et al. show how to coax a pre-trained large language model into doing semantic parsing without requiring fine-tuning [34].
Another approach to PBNL is program synthesis, which typically searches a space of possible programs [2].Desai et al. describe a meta-synthesizer that, given a DSL grammar and an aligned corpus, creates a synthesizer from natural language to programs in the DSL [12].PBNL is not limited to domain-specific languages for citizen developers.Yin and Neubig describe a semantic parser that uses deep learning to encode a sequence of natural-language tokens, then decodes that into a Python AST [39].Codex is a pre-trained large language model for natural language first fine-tuned on unlabeled code, then fine-tuned again on an aligned corpus of utterances and programs [11].While the previous section covered three low-code techniques in depth, this section covers cross-cutting topics beyond any single technique.Table 1 compares the three techniques from Section 3. The Activity columns indicate how each technique supports the user in writing, reading, and executing programs.The main difference is in the Write column: users write programs mainly on the code canvas for VPLs, the stage for PBD, and a text canvas in PBNL.On the other hand, there is little difference in the Read and Execute columns: users read programs on a code canvas (if provided), and watch them executing on the stage (if visible).That hints at an opportunity for reusing building blocks across tools for different techniques.

PERSPECTIVES
A core problem with low-code programming is ambiguity.While visual programming languages can be rigorous and unambiguous, there is ambiguity in how to generalize from a demonstration to a program that works in different situations, and natural languages are inherently ambiguous as well.More ambiguous techniques may only work reliably on small and simple problems.Systems for PBD and PBNL must guess at the user's intent, and are likely to guess wrong when programs get complicated.This motivates offering users an option to read or even correct programs or their executions.
A core goal of low-code programming is to reduce the need to learn a programming language.Citizen developers can demonstrate a program or describe it in natural language without having been taught how to do so.Visual programming, on the other hand, is often not quite as selfexplanatory, which is why Figure 1 associates it more with semi-developers.On the other hand, depending on the user's attitude, the need-to-learn can also be a positive aspect, since it grows computational thinking skills.
Artificial Intelligence for Low-Code.Does the ongoing rapid progress in AI fuel progress in low-code?This article argues that yes, it does, in proportion to the ambiguity of the lowcode technique.Out of the three techniques in Table 1, AI is most prominent for PBNL, which is also the most ambiguous.PBNL can hardly avoid AI except by using a controlled natural language [22], but that would make it feel more like code.Currently a rising AI approach for PBNL is to use large language models with code generation [11,34].We expect PBNL to grow along with relevant advances in AI.AI is also prominent in PBD, which Table 1 characterizes as medium ambiguity.For example, DeepCoder shows the interplay between program synthesis for defining a space of possible programs and checking whether a given program is correct, and AI for guiding the search through that space [5].As another example, VASTA uses speech recognition, object recognition, and optical character recognition to better understand a user's demonstration of a task [33].
Communicating with Humans and Machines.Pro-developers use code in textual programming languages to communicate with a computer, telling it what to do.In addition, developers can also use programming languages to communicate with each other or with their own future self.A low-level programming language such as C gives developers more control, whereas a high-level language such as Python arguably makes communication among humans more effective.Similarly, low-code programs can also serve both to communicate instructions to a computer and to communicate among lowcode users.Being even more high-level than, say, Python, low-code can serve as a lingua franca to help citizen developers and pro-developers communicate more effectively with each other.For instance, a citizen developer might use PBD to communicate a desired behavior to a pro-developer to flesh out [17].Conversely, a pro-developer might use PBNL or a VPL to communicate a proposed behavior to a domain expert for explanation or approval [28].Domain-Specific Languages for Low-Code.All three low-code techniques from Section 3 are intrinsically related to domainspecific languages (DSLs): most visual programming languages are DSLs (e.g.Scratch [30]), and both programming by demonstration and programming by natural language usually target DSLs (e.g.DIYA targets its co-designed ThingTalk 2.0 DSL [14]).Mernik et al. list further benefits of DSLs: they facilitate program analysis, verification, optimization, parallelization, and transformation (AVOPT) [25].
While reviewing the low-code literature reveals a close tie to DSLs, those DSLs are not always exposed to the user.For instance, the DSL may manifest as a proprietary file format or as an undocumented internal representation.If the DSL is exposed, users can more easily read, test, and audit programs, version them and store them in a shared repository, and manipulate them with tools for program transformation or generation.Also, an exposed DSL is less locked into a specific programming environment or its vendor.When exposed, the DSL should be designed for humans, possibly based on interviews and user studies as role-modeled by Leshed et al. [23].On the other hand, a DSL that is not exposed will be shaped by different factors, such as the ease of enumerating valid programs, which can be improved by asymmetry [13].
DSLs (including DSLs for low-code) may be embedded in a general-purpose language.Compared to a stand-alone DSL, an embedded DSL is often easier to implement (e.g., due to not requiring a custom parser) and easier to use (e.g., due to syntax highlighting and auto-completion tools of the host language).The approach to implementing an embedded DSL depends on the facilities of the host language.One approach is Pure Embedding, which uses higher-order functions and lazy evaluation, such as in Haskell [18].Another example is Lightweight Modular Staging, which uses operator overloading and dynamic compilation, such as in Scala [31].

Model Controller
Views / Projections with a superset of the components from each low-code technique.Low-code programming tools provide one or more views of the program.Some of these views, or projections, are read-only, while others are read-write views.When multiple views are present, the system keeps them in synch with a single joint model, and through that, with each other.Edits in one view are projected live to all other views.The model is a program in a domain-specific language (DSL).As discussed previously, the DSL may or may not be exposed to the user, and may or may not be embedded in a host programming language.Optionally, the system may even expose the textual DSL as another view, for instance, in a structure editor [37].Besides the model and the view, the third part of the MVC pattern is the controller, which, for low-code, can contain a player and/or a configuration pane.
Combining Multiple Low-Code Techniques.When users write a program by demonstration or by natural language, the system may let them read their program on a code canvas.And once a system lets users read programs on a code canvas, a logical next step is to also let them write programs there, such as, to correct mistakes from generalization or from natural language processing.This yields a combination of low-code techniques, where users can write programs in multiple ways.Such combinations can compensate for weaknesses of techniques.For example, in Rousillon, the user first writes a program by demonstrating how to scrape data from web pages [10]; since one weakness of PBD is ambiguity, Rousillon next shows the resulting program to the user in a scratch-like VPL [10].As another example, Pumice combines PBD with PBNL: the user first writes a program via natural language; since one weakness of PBNL is ambiguity, Pumice next lets the user clarify with PBD [24].
Meta-tools and Meta-circularity.A meta-tool for low-code is a tool that is used to implement low-code tools.In traditional programming languages, meta-tools (such as parser generators) have long been an essential part of the toolwriter's repertoire.Similarly, meta-tools for low-code can speed up the development of low-code tools by automating well-known but tedious pieces.Thus, meta-tools make it easier to build several tools or variants, for instance, to experiment with the user experience.There are examples of meta-tools for all three low-code techniques discussed in Section 3: Blockly is a VPL meta-tool [29], DreamCoder is a PBD meta-tool [13], and Overnight is a PBNL meta-tool [38].
A meta-circular tool for low-code is a meta-tool for lowcode that is itself a low-code tool.Not all meta-tools are metacircular tools, as that requires them to be powerful enough for serious software development.Supporting all that power can compromise the tool's low-code nature: complex features can get in the way of learning easy ones.On the positive side, meta-circular tools can democratize the creation of lowcode tools themselves.Furthermore, tool developers who use their own tools may empathize more with their users' needs.Examples for meta-circular low-code tools include VisPRO [40] and Racket [3] (both for VPLs).
Low-Code Foundation.In addition to meta-tools, are there other reusable modules that make it easier to build new lowcode tools?The beginning of Section 3 listed several reusable building blocks for low-code programming interfaces: code canvas, palette, text box, player, stage, and configuration pane.Besides making it easier to create low-code tools, such reuse can also give different tools a more uniform look-andfeel, thus reducing the need-to-learn.In the case of multiple low-code tools for the same domain, reusing the same domain-specific language makes them more interoperable.Of course, low-code tools in different domains will require different DSLs, but they may still be able to reuse some sublanguage, such as expressions or formulas with basic arithmetic and logical operators and a function library.There are also AI components that can be reused across low-code tools, such as speech recognition modules, a search-based program synthesis engine, semantic parsers, or language models.End-user Software Engineering.Most of the discussion on lowcode programming focuses on writing a program: it enables citizen developers to rapidly create a prototype.But what happens over time when these programs stick around, get used in new circumstances that the developer did not foresee, get modified or generalized, and proliferate?At that point, users need end-user software engineering (EUSE) for quality control, for instance, by showing test coverage, letting users add assertions, and helping them localize faults directly in their low-code programming environment [9].Another way to support EUSE is to expose the DSL, which makes it easier to adopt established software development workflows and the associated tools (such as version-controlled source code repositories, regression tests, or issue trackers) for low-code.

CONCLUSION
This article reviews research relevant to low-code programming models with a focus on visual programming, programming by demonstration, and programming by natural language.It maps low-code techniques to target users and discusses common building blocks, strengths, and weaknesses.This article argues that domain-specific languages and the model-view-controller pattern constitute a common backbone and unifying principle across low-code techniques.

Figure 1 :
Figure 1: Low-code users and techniques.