Multitier programming: Difference between revisions

Content deleted Content added
No edit summary
Citation bot (talk | contribs)
Removed URL that duplicated identifier. | Use this bot. Report bugs. | #UCB_CommandLine
 
(44 intermediate revisions by 24 users not shown)
Line 1:
{{Short description|Programming paradigm that unifies the development of different tiers in a single compilation unit}}
{{AFC submission||ns=118|u=Kvng|ts=20201028155459}} <!-- Do not remove this line! -->
{{AFC submission|d|nn|u=Guidosalva|ns=118|decliner=Sulfurboy|declinets=20200503041732|ts=20200502105719}} <!-- Do not remove this line! -->
 
'''Multitier programming''' (or '''tierless programming''') is a [[programming paradigm]] for [[distributed computing|distributed software]], which typically follows a [[multitier architecture]], physically separating different functional aspects of the software into different ''tiers'' (e.g., the client, the server and the database in a Web application<ref>{{Cite journal|last1=Hull|first1=Richard|last2=Thiemann|first2=Peter|last3=Wadler|first3=Philip|date=2007|title=07051 Working Group Outcomes – Programming Paradigms for the Web: Web Programming and Web Services|url=http://drops.dagstuhl.de/opus/volltexte/2007/1127|journal=Programming Paradigms for the Web: Web Programming and Web Services|series=Dagstuhl Seminar Proceedings|___location=Dagstuhl, Germany|publisher=Internationales Begegnungs- und Forschungszentrum für Informatik (IBFI)|volume=07051}}</ref>). Multitier programming allows fuctionalitiesfunctionalities that span multiple of such tiers to be developed in a single compilation unit using a single [[programming language]]. Without multitier programming, tiers are developed using different languages, e.g., [[JavaScript]] for the Web client, [[PHP]] for the Web server and [[SQL]] for the database.<ref>{{cite journal|last1=Weisenburger|first1=Pascal|last2=Wirth|first2=Johannes|last3=Salvaneschi|first3=Guido|title=A Survey of Multitier Programming|journal=ACM Comput. Surv.|date=2020|volume=53|issue=4|pages=81:1–81:35|doi=10.1145/3397495|s2cid=218517772 |url=http://www.alexandria.unisg.ch/267228/1/2020_A-Survey-of-Multitier-Programming.pdf }}</ref> Multitier programming is often integrated into [[general-purpose language]]s by extending them with support for distribution.<ref>{{cite book|last1=Caldwell|first1=Sam |editor1-last=Miller|editor1-first=Heather|title=Programming Models for Distributed Computing|date=2016|chapter=General Purpose Languages Extended for Distribution|chapter-url=http://dist-prog-book.com/chapter/5/langs-extended-for-dist.html}}</ref>
 
Concepts from multitier programming were pioneered by the [[Hop (software)|Hop]]<ref name=":0">{{Cite journal|last=Serrano|first=Manuel|date=2012|title=Multitier programming in Hop.|url=https://dblp.org/rec/journals/cacm/SerranoB12.html|journal=Commun. ACM|volume=55|issue=8|pages=53–59|doi=10.1145/2240236.2240253|s2cid=2152326|url-access=subscription}}</ref> and [[Links (programming language)|Links]]<ref name=":1">{{Cite book|last=Cooper|first=Ezra|datetitle=2006Formal Methods for Components and Objects |titlechapter=Links: Web Programming Without Tiers. |date=2006|series=Lecture Notes in Computer Science|volume=4709|url=https://dblp.org/rec/conf/fmco/CooperLWY06.html|pages=266–296|doi=10.1007/978-3-540-74792-5_12|hdl=20.500.11820/ef5f100a-0366-4b85-8ef1-622fd7fbb53a |isbn=978-3-540-74791-8|s2cid=16397220 }}</ref> languages
and have found industrial adoption in solutions such as [[Ocsigen]],<ref name=":2">{{Cite journal|last=Balat|first=Vincent|date=2006|title=Ocsigen: typing web interaction with objective Caml.|url=https://dblp.org/rec/conf/ml/Balat06.html|pages=84–94|doi=10.1145/1159876.1159889|s2cid=6131454|url-access=subscription}}</ref>, [[Opa (programming language)|Opa]],<ref name=":3">Rajchenbach-Teller, D., & Sinot, Franois-R&amp;#39;egisRégis. (2010). Opa: Language support for a sane, safe and secure web. ''Proceedings of the OWASP AppSec Research'', ''2010''(1).</ref>, [[WebSharper]],<ref name=":4">{{Cite journalbook|last1=Bjornson|first1=Joel|last2=Tayanovskyy|first2=Anton|last3=Granicz|first3=Adam|datetitle=2010Implementation and Application of Functional Languages |titlechapter=Composing Reactive GUIs in F# Using WebSharper |journaldate=Proceedings2010|series=Lecture ofNotes thein 22ndComputer InternationalScience Conference on Implementation|volume=6647 and Application of Functional Languages|page=49|___location=Berlin, Heidelberg|publisher=Springer-Verlag|doi=10.1007/978-3-642-24276-2_13|isbn=978-3-642-24275-5 }}</ref>, [[Meteor (web framework)|Meteor]]<ref name=":5">{{Cite book|last=Strack, Isaac|url=https://www.worldcat.org/oclc/823718999|title=Getting started with Meteor JavaScript framework|date=January 2012|isbn=978-1-78216-083-0|___location=Birmingham|oclc=823718999}}</ref> or [[Google Web Toolkit|GWT]].<ref name=":6">{{Cite book|last=Kereki, Federico, 1960-|url=https://www.worldcat.org/oclc/606556208|title=Essential GWT: building for the web with Google Web toolkit 2|date=2011|publisher=Addison-Wesley|isbn=978-0-321-70563-1|___location=Upper Saddle River, NJ|oclc=606556208}}</ref>.
 
Multitier programming provides a ''global view'' on the distributed system. This aspect has been shown similar to other programming paradigms such as [[choreographic programming]],<ref>{{Cite journal |last1=Giallorenzo |first1=Saverio |last2=Montesi |first2=Fabrizio |last3=Peressotti |first3=Marco |last4=Richter |first4=David |last5=Salvaneschi |first5=Guido |last6=Weisenburger |first6=Pascal |date=2021 |editor-last=Møller |editor-first=Anders |editor2-last=Sridharan |editor2-first=Manu |title=Multiparty Languages: The Choreographic and Multitier Cases |url=https://drops.dagstuhl.de/opus/volltexte/2021/14065 |journal=35th European Conference on Object-Oriented Programming (ECOOP 2021) |series=Leibniz International Proceedings in Informatics (LIPIcs) |___location=Dagstuhl, Germany |publisher=Schloss Dagstuhl – Leibniz-Zentrum für Informatik |volume=194 |pages=22:1–22:27 |doi=10.4230/LIPIcs.ECOOP.2021.22 |doi-access=free |isbn=978-3-95977-190-0|s2cid=235748561 }}</ref> [[macroprogramming]],<ref name="Casadei 2023">{{cite journal | last=Casadei | first=Roberto | title=Macroprogramming: Concepts, State of the Art, and Opportunities of Macroscopic Behaviour Modelling | journal=ACM Computing Surveys | publisher=Association for Computing Machinery (ACM) | date=2023-01-11 | volume=55 | issue=13s | pages=1–37 | issn=0360-0300 | doi=10.1145/3579353 | s2cid=245837830 | doi-access=free | arxiv=2201.03473 }}</ref> and [[aggregate computing]].<ref name="Beal Pianini Viroli 2015 pp. 22–30">{{cite journal | last1=Beal | first1=Jacob | last2=Pianini | first2=Danilo | last3=Viroli | first3=Mirko | title=Aggregate Programming for the Internet of Things | journal=Computer | publisher=Institute of Electrical and Electronics Engineers (IEEE) | volume=48 | issue=9 | year=2015 | issn=0018-9162 | doi=10.1109/mc.2015.261 | pages=22–30| hdl=11585/520779 | s2cid=26413 | hdl-access=free }}</ref><ref>{{Cite journal |last1=Audrito |first1=Giorgio |last2=Casadei |first2=Roberto |last3=Damiani |first3=Ferruccio |last4=Salvaneschi |first4=Guido |last5=Viroli |first5=Mirko |date=2022 |editor-last=Ali |editor-first=Karim |editor2-last=Vitek |editor2-first=Jan |title=Functional Programming for Distributed Systems with XC |url=https://drops.dagstuhl.de/opus/volltexte/2022/16248 |journal=36th European Conference on Object-Oriented Programming (ECOOP 2022) |series=Leibniz International Proceedings in Informatics (LIPIcs) |___location=Dagstuhl, Germany |publisher=Schloss Dagstuhl – Leibniz-Zentrum für Informatik |volume=222 |pages=20:1–20:28 |doi=10.4230/LIPIcs.ECOOP.2022.20 |doi-access=free |isbn=978-3-95977-225-9|s2cid=249961384 }}</ref>
 
== Context ==
 
The code of the different tiers can be executed in a distributed manner on different [[Computer network|networked computers]]. For instance, in a [[Multitier architecture#Three-tier architecture|three-tier architecture]], a system is divided into three main layers – typically the presentation, business, and data tiers. This approach has the benefit that by dividing a system into layers, the functionality implemented in one of the layers can be changed independently of the other layers. On the other hand, this architectural decision scatters a cross-cutting functionality belonging to several tiers over several compilation units.
 
In multitier programming, the different tiers are implemented using a single programming language. Different [[Compiler|compilation backends]] take into account the destination tier (e.g., Java for a server and JavaScript for a web browser). Consequently, a functionality that is spread over tiers can be implemented in a single compilation unit of a multitier program.
 
== Example ==
At their core, multitier languages allow developers to define for different pieces of code the tiers to which the code belongs. The language features that enable this definition are quite diverse between different multitier languages, ranging from [[Multi-stage programming|staging]] to [[Annotation#Software and engineering|annotations]] to [[Type system|types]]. The following example shows an Echo client–server application that illustrates different approaches. In the example, the client sends a message to the server and the server returns the same message to the client, where it is appended to a list of received messages.
As an example, we show an Echo client–server application: The client sends a message to the server and the server returns the same message to the client, where it is appended to a list of received messages. The application is simple and self-contained, and – despite all the limitations of short and synthetic examples – it gives us the chance to demonstrate different MT languages side by side.
 
=== Example 1. Echo application in Hop.js. ===
<syntaxhighlight lang="lisp" line="1">
service echo() {
var input = <input type="text" />
return <html>
<body onload=~{
var ws = new WebSocket("ws://localhost:" + ${hop.port} + "/hop/ws")
ws.onmessage = function(event) { document.getElemenetById("list").appendChild(<li>${event.data}</li>) }
}>
<div>
${input}
<button onclick=~{ ws.send(${input}.value) }>Echo!</button>
</div>
<ul id="list" />
</body>
</html>
}
 
var wss = new WebSocketServer("ws")
wss.onconnection = function(event){
var ws = event.value
ws.onmessage = function(event) { ws.send(event.value) }
}
</syntaxhighlight>
</syntaxhighlight>HTML can be embedded directly in Hop code. HTML generated on the server (Line 2–14) is passed to the client. HTML generated on the client can be added to the page using the standard DOM API (Line 6).
 
Hop uses staging to embed code that is to be run on the client into a server-side program: Using the ~{…} notation, the code for the onload (Line 4) and onclick (Line 10) handlers is not immediately executed but the server generates the code for later execution on the client. On the other hand, the ${…} notation escapes one level of program generation. The expressions hop.port (Line 5), event.data (Line 6) and input (Line 9 and 10) are evaluated by the outer server program and the values to which they evaluate are injected into the generated client program. Hop supports [[Multi-stage programming|full stage programming]], i.e., ~{…} expressions can be arbitrarily nested such that not only server-side programs can generate client-side programs but also client-side programs are able to generate other client-side programs.
Hop supports bidirectional communication between a running server and a running client instance through its standard library. In the Echo application, the client connects to the WebSocket server through the standard HTML5 API (Line 5) and sends the current input value (Line 10). The server opens a WebSocket server (Line 17) that returns the value back to the client (Line 20).
 
HTML can be embedded directly in Hop code. HTML generated on the server (Line 2–14) is passed to the client. HTML generated on the client can be added to the page using the standard DOM API (Line 6). Hop supports bidirectional communication between a running server and a running client instance through its standard library. The languageclient allowsconnects to the definitionWebSocket server through the standard HTML5 API (Line 5) and sends the current input value (Line 10). The server opens a WebSocket server (Line 17) that returns the value back to the client (Line 20). ofSo-called services, which are executed on the server and produce a value that is returned to the client that invoked the service. For example, the echo service (Line 1) produces the HTML page served to the web client of the Echo application. Thus, the code in a service block is executed on the server.
 
=== Echo application in Links ===
Because of the ~{. . .} notation, the code for the onload (Line 4) and onclick (Line 10) handlers is not immediately executed but the server generates the code for later execution on the client. On the other hand, the ${. . .} notation escapes one level of program generation. The expressions hop.port (Line 5), event.data (Line 6) and input (Line 9 and 10) are evaluated by the outer server program and the values to which they evaluate are injected into the generated client program. Hop supports full stage programming, i.e., ~{. . .} expressions can be arbitrarily nested such that not only server-side programs can generate client-side programs but also client-side programs are able to generate other client-side programs.
 
=== Example 2. Echo application in Links. ===
<syntaxhighlight lang="java" line="1">
fun echo(item) server {
item
}
 
fun main() server {
page
<html>
<body>
<form l:onsubmit="{appendChildren(<li>{stringToXml(echo(item))}</li>, getNodeById("list"))}">
<input l:name="item" />
<button type="submit">Echo!</button>
</form>
<ul id="list" />
</body>
</html>
}
 
main()
</syntaxhighlight>
Links uses annotations on functions to specify whether they run on the client or on the server (Line 1 and 5). Upon request from the client, the server executes the main function (Line 18), which constructs the code that is sent to the client. Links allows embedding XML code (Line 7–15). XML attributes with the l: prefix are treated specially. The l:name attribute (Line 10) declares an identifier to which the value of the input field is bound. The identi�er can be used elsewhere (Line 9). The code to be executed for the l:onsubmit handler (Line 9) is not immediately executed but compiled to JavaScript for client-side execution. Curly braces indicate Links code embedded into XML. The l:onsubmit handler sends the current input value item to the server by calling echo. The item is returned by the server and appended to the list of received items using standard DOM APIs. The call to the server (Line 9) does not block the client. Instead, the continuation on the client is invoked when the result of the call is available. Client–server interaction is based on resumption passing style: Using continuation passing style transformation and defunctionalization, remote calls are implemented by passing the name of a function for the continuation and the data needed to continue the computation.
 
Links uses annotations on functions to specify whether they run on the client or on the server (Line 1 and 5). Upon request from the client, the server executes the main function (Line 18), which constructs the code that is sent to the client. Links allows embedding XML code (Line 7–15). XML attributes with the l: prefix are treated specially. The l:name attribute (Line 10) declares an identifier to which the value of the input field is bound. The identifier can be used elsewhere (Line 9). The code to be executed for the l:onsubmit handler (Line 9) is not immediately executed but compiled to JavaScript for client-side execution. Curly braces indicate Links code embedded into XML. The l:onsubmit handler sends the current input value item to the server by calling echo. The item is returned by the server and appended to the list of received items using standard DOM APIs. The call to the server (Line 9) does not block the client. Instead, the continuation on the client is invoked when the result of the call is available. Client–server interaction is based on resumption passing style: Using [[continuation passing style]] transformation and [[defunctionalization]], remote calls are implemented by passing the name of a function for the continuation and the data needed to continue the computation.
=== Example 3. Echo application in Ur/Web. ===
<syntaxhighlight lang="sml" line="1">
fun echo (item : string) = return item
 
=== Echo application in ScalaLoci ===
fun main () =
<syntaxhighlight lang="scala" line="1">
let fun mkhtml list =
@multitier object Application {
case list of
@peer type Server <: { type Tie <: Single[Client] => <xml/>}
@peer type Client <: { type Tie <: Single[Server] }
| r :: list => <xml><li>{[r]}</li>{mkhtml list}</xml>
in
item <- source "";
list <- source [];
return <xml><body>
<div>
<ctextbox source={item} />
<buttonvalue="Echo!"onclick={fn =>
list' <- get list;
item' <- get item;
item' <- rpc (echo item');
set list (item' :: list')
}/>
</div>
<ul>
<dyn signal={
list' <- signal list;
return (mkhtml list')
}/>
</ul>
</body></xml>
end
</syntaxhighlight>Ur/Web allows embedding XML code using <xml>. . .</xml> (Line 6 and 7). The {. . .} notation embeds Ur/Web code into XML. {[. . .]} evaluates an expression and embeds its value as a literal. Ur/Web supports functional reactive programming for client-side user interfaces. The example defines an item source (Line 9), whose value is automatically updated to the value of the input field (Line 13) when it is changed through user input, i.e., it is reactive. The list source (Line 10) holds the list of received items from the echo server. Sources, time-changing input values, and signals, time-changing derived values, are Ur/Web’s reactive abstractions, i.e., signals recompute their values automatically when the signals or sources from which they are derived change their value, facilitating automatic change propagation. Upon clicking the button, the current value of list (Line 15) and item is accessed (Line 16), then a remote procedure call to the server’s echo function is invoked (Line 17) and list is updated with the item returned from the server (Line 18). To automatically reflect changes in the user interface, a signal is bound to the signal attribute of the HTML pseudo element <dyn> (Line 22). The signal uses the mkhtml function (Line 24, defined in Line 4), which creates HTML list elements. In addition to remote procedure calls – which initiate the communication from client to server – Ur/Web supports typed message-passing channels, which the server can use to push messages to the client.
 
val message = on[Client] { Event[String]() }
=== Example 4. Echo application in Eliom. ===
val echoMessage = on[Server] { message.asLocal }
<syntaxhighlight lang="ocaml" line="1">
module Echo app = Eliom registration.App (struct let application name = "echo" let global data path = None end)
 
def main() = on[Client] {
let%server main_service = create ~path:(Path []) ~meth:(Get Eliom_parameter.unit) ()
val items = echoMessage.asLocal.list
val list = Signal { ol(items() map { message => li(message) }) }
val inp = input.render
dom.document.body = body(
div(
inp,
button(onclick := { () => message.fire(inp.value) })("Echo!")),
list.asFrag).render
}
}
</syntaxhighlight>
 
ScalaLoci is a language that targets generic distributed systems rather than the Web only, i.e., it is not restricted to a client–server architecture. To this end, ScalaLoci supports peer types to encode the different tiers at the [[Type system|type level]]. Placement types are used to assign locations to data and computations. ScalaLoci supports multitier [[Functional reactive programming|reactives]] – language abstractions for reactive programming that are placed on specific locations – for composing data flows cross different peers.
let%server make input up =
let inp = Html.D.Raw.input () in
let btn = Html.D.button ~a:[Html.D.a_class ["button"]] [Html.D.pcdata "Echo!"] in
ignore [%client
(Lwt.async (fun () ->
Lwt js events.clicks (Html.To dom.of element ~%btn) (fun -> ___
~%up (Js.to string (Html.To dom.of input ~%inp)##.value);
Lwt.return_unit)) : unit) ];
Html.D.div [inp; btn]
 
The application first defines an input field (Line 11) using the ScalaTags library.<ref>{{Cite web|title=ScalaTags|url=https://com-lihaoyi.github.io/scalatags/|website=www.lihaoyi.com|access-date=2021-10-11}}</ref> The value of this field is used in the click event handler of a button (Line 15) to fire the message event with the current value of the input field. The value is then propagated to the server (Line 6) and back to the client (Line 9). On the client, the value of the event are accumulated using the list function and mapped to an HTML list (Line 10). This list is then used in the HTML (Line 16) to display the previous inputs.
let%server()=Echoapp.register _
~service:main service
(fun () () ->
let item_up = Up.create (Eliom_parameter.ocaml "item" [%derive.json :string]) in
let item down = Down.of react (Up.to react item up) in
let list, handle = ReactiveData.RList.create [] in
let list = ReactiveData.RList.map [%shared fun i -> Html.D.li [Html.D.pcdata i] ] list in
let input = make_input item_up in
ignore [%client
(Eliom_client.onload __
(fun ->ignore(React.E.map(funi->ReactiveData.RList.consi~%handle)~%itemdown)):unit)];
Lwt.return (Eliom_tools.D.html ~title:"echo" (Html.D.body [input; Html.R.ul list])))
</syntaxhighlight>Eliom extends let-bindings with section annota- tions %client, %server and %shared – the latter indicates code that runs on both the client and the server. The application starts with a call to Echo_app.register (Line 15). Eliom supports cross- tier reactive values: The application generates a server-side event (Line 18) and a corresponding client-side event (Line 19), which automatically propagates changes from the server to the client. A reactive list (Line 20) holds the items received from the server. Mapping the list produces a list of corresponding HTML elements (Line 21), which can directly be inserted into the generated HTML code (Line 26). Eliom supports a DSL for HTML, providing functions of the same name as the HTML element they generate. Server-side code can contain nested fragments to be run on the client ([%client . . .], Line 23) or to be run on both the client and the server ([%shared . . .], Line 21). Eliom uses injections (prefixed by ~%) to access values on the client side that were computed on the server. The client-side representation of the event item_down is injected into a client fragment to extend the reactive list with every item returned from the server (Line 25). The make_input function (Line 5) generates the main user interface, which processes the stream of button clicks (Line 10) and fires the up event for every item (Line 11). To �re the server-side up event from the client-side, we inject the event via ~%up into the client fragment.
 
=== Example 5. Echo application in GWT. ===
<syntaxhighlight lang="java" line="1">
package echo.client;
public interface EchoServiceextendsRemoteService{
String echo(String item) throws IllegalArgumentException; }
package echo.client;
public interface EchoServiceAsync {
void echo(String item, AsyncCallback<String> callback) throws IllegalArgumentException; }
 
package echo.server;
public class EchoServiceImpl extends RemoteServiceServlet implements EchoService {
public String echo(String item) throws IllegalArgumentException {
return item; } }
package echo.client;
public class Echo implements EntryPoint {
private final EchoServiceAsync echoService = GWT.create(EchoService.class);
public void onModuleLoad() {
final TextBox itemField = new TextBox();
final Button submitButton = new Button("Echo!");
 
RootPanel.get("itemFieldContainer").add(itemField);
RootPanel.get("submitButtonContainer").add(submitButton);
submitButton.addClickHandler(new ClickHandler {
public void onClick(ClickEvent event) {
echoService.echo(itemField.getText(), new AsyncCallback<String>() {
public void onFailure(Throwable caught) { }
public void onSuccess(String result) {
RootPanel.get("itemContainer").add(new Label(result)); } }); } }); } }
</syntaxhighlight>For the sake of brevity, we leave out the external HTML file. The application adds an input field (Line 22) and a button (Line 23) to container elements defined in the HTML file and registers a handler for click events on the button (Line 25). When the button is clicked, the echo method of the echoService is invoked with the current item and a callback – to be executed when the remote call returns. When an item is returned by the remote call, it is added to the list of received items (Line 30). GWT requires developers to specify both the interface implemented by the service (Line 2) and the service interface for invoking methods remotely using a callback (Line 6). The implementation of the echo service (Line 10) simply returns the item sent from the client.
 
=== Example 6. Echo application in ScalaLoci. ===
<syntaxhighlight lang="scala" line="1">
@multitier object Application {
@peer type Server <: { type Tie <: Single[Client] }
@peer type Client <: { type Tie <: Single[Server] }
val message = on[Client] { Event[String]() }
val echoMessage = on[Server] { message.asLocal }
 
def main() = on[Client] {
val items = echoMessage.asLocal.list
val list = Signal { ol(items() map { message => li(message) }) }
val inp = input.render
dom.document.body = body(
div(
inp,
button(onclick := { () => message.fire(inp.value) })("Echo!")),
list.asFrag).render
}
}
</syntaxhighlight>The application first defines an input field (Line 11) using the ScalaTags library<ref>{{Cite web|title=ScalaTags|url=http://www.lihaoyi.com/scalatags/|website=www.lihaoyi.com|access-date=2020-05-04}}</ref>. The value of this field is used in the click event handler of a button (Line 15) to fire the message event with the current value of the input field. The value is then propagated to the server (Line 6) and back to the client (Line 9). On the client, the value of the event are accumulated using the list function and mapped to an HTML list (Line 10). This list is then used in the HTML (Line 16) to display the previous inputs.
<br />
== List of multitier programming languages ==
 
* Hop/Hop.js<ref name=":0">{{Cite journal|last=Serrano|first=Manuel|date=2012|title=Multitier programming in Hop.|url=https://dblp.org/rec/journals/cacm/SerranoB12.html|journal=Commun. ACM|volume=55|issue=8|pages=53–59|doi=10.1145/2240236.2240253|s2cid=2152326|url-access=subscription}}</ref><ref>{{Cite journal|last=Serrano|first=Manuel|date=2006|title=Hop: a language for programming the web 2.0.|url=https://dblp.org/rec/conf/oopsla/SerranoGL06.html|pages=975–985|doi=10.1145/1176617.1176756|s2cid=14306230|url-access=subscription}}</ref><ref>{{Cite book|last=Serrano|first=Manuel|datetitle=2016Proceedings of the 21st ACM SIGPLAN International Conference on Functional Programming |titlechapter=A glimpse of Hopjs. |date=2016|url=https://dblp.org/rec/conf/icfp/SerranoP16.html|pages=180–192|doi=10.1145/2951913.2951916|isbn=9781450342193|s2cid=18393160 }}</ref>
* Links<ref name=":1">{{Cite book|last=Cooper|first=Ezra|datetitle=2006Formal Methods for Components and Objects |titlechapter=Links: Web Programming Without Tiers. |date=2006|series=Lecture Notes in Computer Science|volume=4709|url=https://dblp.org/rec/conf/fmco/CooperLWY06.html|pages=266–296|doi=10.1007/978-3-540-74792-5_12|hdl=20.500.11820/ef5f100a-0366-4b85-8ef1-622fd7fbb53a |isbn=978-3-540-74791-8|s2cid=16397220 }}</ref><ref>{{Cite journal|last=Fowler|first=Simon|date=2019|title=Exceptional asynchronous session types: session types without tiers.|url=https://dblp.org/rec/journals/pacmpl/FowlerLMD19.html|journal=Proc. ACM Program. Lang.|volume=3|issue=POPL|pages=28:1–28:29|doi=10.1145/3290341|s2cid=57757469|doi-access=free|hdl=1808/27512|hdl-access=free}}</ref>
*Ur/Web<ref>{{Cite journal|last=Chlipala|first=Adam|date=2015|title=Ur/Web: A Simple Model for Programming the Web.|url=https://dblp.org/rec/conf/popl/Chlipala15.html|pages=153–165|doi=10.1145/2676726.2677004|s2cid=9440677|url-access=subscription}}</ref>
*Eliom/Ocsigen<ref name=":2">{{Cite journal|last=Balat|first=Vincent|date=2006|title=Ocsigen: typing web interaction with objective Caml.|url=https://dblp.org/rec/conf/ml/Balat06.html|pages=84–94|doi=10.1145/1159876.1159889|s2cid=6131454|url-access=subscription}}</ref><ref>{{Cite book|last=Radanne|first=Gabriel|datetitle=Companion of the Web Conference 2018 on the Web Conference 2018 - WWW '18 |titlechapter=Tierless Web Programming in the Large. |date=2018|url=https://dblp.org/rec/conf/www/RadanneV18.html|pages=681–689|doi=10.1145/3184558.3185953|isbn=9781450356404|s2cid=3304415}}</ref>
*ScalaLoci<ref>{{Cite journal|last=Weisenburger|first=Pascal|date=2018|title=Distributed system development with ScalaLoci.|url=https://dblp.org/rec/journals/pacmpl/WeisenburgerKS18.html|journal=Proc. ACM Program. Lang.|volume=2|issue=OOPSLA|pages=129:1–129:30|doi=10.1145/3276499|s2cid=53090153|doi-access=free}}</ref>
*StiP.js<ref>{{Cite book|last=Philips|first=Laure|datetitle=Proceedings of the 2014 ACM International Symposium on New Ideas, New Paradigms, and Reflections on Programming & Software |titlechapter=Towards Tierless Web Development without Tierless Languages. |date=2014|url=https://dblp.org/rec/conf/oopsla/PhilipsRCM14.html|pages=69–81|doi=10.1145/2661136.2661146|isbn=9781450332101|s2cid=15774367}}</ref><ref>{{Cite journal|last=Philips|first=Laure|date=2018|title=Search-based Tier Assignment for Optimising Offline Availability in Multi-tier Web Applications.|url=https://dblp.org/rec/journals/programming/PhilipsKMR18.html|journal=Programming Journal|volume=2|issue=2|pages=3|doi=10.22152/programming-journal.org/2018/2/3|s2cid=11256561|doi-access=free|arxiv=1712.01161}}</ref>
*Scala Multi-Tier FRP<ref>{{Cite book|last=Reynders|first=Bob|datetitle=Proceedings of the 2014 ACM International Symposium on New Ideas, New Paradigms, and Reflections on Programming & Software |titlechapter=Multi-Tier Functional Reactive Programming for the Web. |date=2014|url=https://dblp.org/rec/conf/oopsla/ReyndersDP14.html|pages=55–68|doi=10.1145/2661136.2661140|isbn=9781450332101|s2cid=16761616}}</ref>
*Opa<ref name=":3">Rajchenbach-Teller, D., & Sinot, Franois-R&amp;#39;egisRégis. (2010). Opa: Language support for a sane, safe and secure web. ''Proceedings of the OWASP AppSec Research'', ''2010''(1).</ref>
*AmbientTalk/R<ref>{{Cite book|last=Carreton|first=Andoni Lombide|datetitle=2010Objects, Models, Components, Patterns |titlechapter=Loosely-Coupled Distributed Reactive Programming in Mobile Ad Hoc Networks. |date=2010|series=Lecture Notes in Computer Science|volume=6141|url=https://dblp.org/rec/conf/tools/CarretonMCM10.html|pages=41–60|doi=10.1007/978-3-642-13953-6_3|isbn=978-3-642-13952-9}}</ref><ref>{{Cite book|last=Dedecker|first=Jessie|date=2006|title=Ambient-Oriented Programming in AmbientTalk.|chapter=Ambient-Oriented Programming in Ambient ''Talk''|series=Lecture Notes in Computer Science|volume=4067|chapter-url=https://dblp.org/rec/conf/ecoop/DedeckerCMDM06.html|pages=230–254|doi=10.1007/11785477_16|isbn=978-3-540-35726-1}}</ref>
*ML5<ref>{{Cite book|last=VII|first=Tom Murphy|datetitle=2007Trustworthy Global Computing |titlechapter=Type-Safe Distributed Programming with ML5. |date=2007|series=Lecture Notes in Computer Science|volume=4912|url=https://dblp.org/rec/conf/tgc/VIICH07.html|pages=108–123|doi=10.1007/978-3-540-78663-4_9|isbn=978-3-540-78662-7|s2cid=12534714 }}</ref>
*WebSharper<ref name=":4">{{Cite journalbook|last1=Bjornson|first1=Joel|last2=Tayanovskyy|first2=Anton|last3=Granicz|first3=Adam|datetitle=2010Implementation and Application of Functional Languages |titlechapter=Composing Reactive GUIs in F# Using WebSharper |journaldate=Proceedings2010|series=Lecture ofNotes thein 22ndComputer InternationalScience Conference|volume=6647 on Implementation and Application of Functional Languages|page=49|___location=Berlin, Heidelberg|publisher=Springer-Verlag|doi=10.1007/978-3-642-24276-2_13|isbn=978-3-642-24275-5 }}</ref>
*Haste<ref>{{Cite journal|last1=Ekblad|first1=Anton|last2=Claessen|first2=Koen|date=2015-05-11|title=A seamless, client-centric programming model for type safe web applications|url=http://dx.doi.org/10.1145/2775050.2633367|journal=ACM SIGPLAN Notices|volume=49|issue=12|pages=79–89|doi=10.1145/2775050.2633367|issn=0362-1340|url-access=subscription}}</ref>
*Fun<ref>{{Cite web|title=Fun (a programming language for the realtime web)|url=http://marcuswest.in/essays/fun-intro/|website=marcuswest.in|access-date=2020-05-04}}</ref>
*Koka<ref>{{Cite journal|last=Leijen|first=Daan|date=2014|title=Koka: Programming with Row Polymorphic Effect Types.|journal=Electronic Proceedings in Theoretical Computer Science|volume=153|url=https://dblp.org/rec/journals/corr/Leijen14.html|pages=100–126|doi=10.4204/EPTCS.153.8|arxiv=1406.2061|s2cid=14902937}}</ref>
*Multi-Tier Calculus<ref>{{Cite book|last=Neubauer|first=Matthias|datetitle=2005Proceedings of the 32nd ACM SIGPLAN-SIGACT symposium on Principles of programming languages |titlechapter=From sequential programs to multi-tier applications by program transformation. |date=2005|url=https://dblp.org/rec/conf/popl/NeubauerT05.html|pages=221–232|doi=10.1145/1040305.1040324|isbn=158113830X|s2cid=10338936}}</ref>
*Swift<ref>{{Cite journal|last1=ChongStephen|last2=LiuJed|last3=C|first3=MyersAndrew|last4=QiXin|last5=VikramK|last6=ZhengLantian|last7=ZhengXin|date=2007-10-14|title=Secure web applications via automatic partitioning|url=https://dl.acm.org/doi/abs/10.1145/1323293.1294265|journal=ACM SIGOPS Operating Systems Review|volume=41|issue=6|pages=31–44|language=EN|doi=10.1145/1323293.1294265|hdl=1813/5769 |hdl-access=free}}</ref>
*Volta<ref>{{Cite journal|last=Manolescu|first=Dragos|date=2008|title=Volta: Developing Distributed Applications by Recompiling.|url=https://dblp.org/rec/journals/software/ManolescuBL08.html|journal=IEEE Software|volume=25|issue=5|pages=53–59|doi=10.1109/MS.2008.131|s2cid=24360031|url-access=subscription}}</ref>
*GWT<ref name=":6">{{Cite book|last=Kereki, Federico, 1960-|url=https://www.worldcat.org/oclc/606556208|title=Essential GWT: building for the web with Google Web toolkit 2|date=2011|publisher=Addison-Wesley|isbn=978-0-321-70563-1|___location=Upper Saddle River, NJ|oclc=606556208}}</ref>
*Meteor<ref name=":5">{{Cite book|last=Strack, Isaac|url=https://www.worldcat.org/oclc/823718999|title=Getting started with Meteor JavaScript framework|date=January 2012|isbn=978-1-78216-083-0|___location=Birmingham|oclc=823718999}}</ref>
*J-Orchestra<ref>{{Cite book|last=Tilevich|first=Eli|datetitle=ECOOP 2002 — Object-Oriented Programming |titlechapter=J-Orchestra: Automatic Java Application Partitioning. |date=2002|series=Lecture Notes in Computer Science|volume=2374|url=https://dblp.org/rec/conf/ecoop/TilevichS02.html|pages=178–204|doi=10.1007/3-540-47993-7_8|hdl=1853/6531 |isbn=978-3-540-43759-8}}</ref>
*Hiphop<ref>{{Cite journalbook|last1=Berry|first1=Gérard|last2=Nicolas|first2=Cyprien|last3=Serrano|first3=Manuel|date=2011|title=Hiphop|url=http://dx.doi.org/10.1145/2093328.2093337|journal=Proceedings of the 1st ACM SIGPLAN Internationalinternational Workshopworkshop on Programming Languagelanguage and Systemssystems Technologiestechnologies for Internetinternet Clientsclients |chapter=Hiphop |date=2011|chapter- PLASTIC '11url=http://dx.doi.org/10.1145/2093328.2093337|page=49|___location=New York, New York, USA|publisher=ACM Press|doi=10.1145/2093328.2093337|isbn=978-1-4503-1171-7|s2cid=1280230}}</ref>
*Distributed Orc<ref>{{Cite journal|last=Thywissen|first=John A.|date=2016|title=Implicitly Distributing Pervasively Concurrent Programs: Extended abstract.|url=https://dblp.org/rec/conf/ecoop/ThywissenPC16.html|pages=1|doi=10.1145/2957319.2957370|s2cid=6124391|url-access=subscription}}</ref>
*Jif/split<ref>{{Cite journal|last=Zdancewic|first=Steve|date=2002|title=Secure program partitioning.|url=https://dblp.org/rec/journals/tocs/ZdancewicZNM02.html|journal=ACM Trans. Comput. Syst.|volume=20|issue=3|pages=283–328|doi=10.1145/566340.566343|s2cid=1776939|url-access=subscription}}</ref>
*Fission<ref>{{Cite journal|last1=Guha|first1=Arjun|last2=Jeannin|first2=Jean-Baptiste|last3=Nigam|first3=Rachit|last4=Tangen|first4=Jane|last5=Shambaugh|first5=Rian|date=2017|editor-last=Lerner|editor-first=Benjamin S.|editor2-last=Bodík|editor2-first=Rastislav|editor3-last=Krishnamurthi|editor3-first=Shriram|title=Fission: Secure Dynamic Code-Splitting for JavaScript|url=http://drops.dagstuhl.de/opus/volltexte/2017/7124|journal=2nd Summit on Advances in Programming Languages (SNAPL 2017)|series=Leibniz International Proceedings in Informatics (LIPIcs)|___location=Dagstuhl, Germany|publisher=Schloss Dagstuhl–Leibniz-Zentrum fuer Informatik|volume=71|pages=5:1–5:13|doi=10.4230/LIPIcs.SNAPL.2017.5|doi-access=free |isbn=978-3-95977-032-3}}</ref>
*SIF<ref>{{Cite journal|last=Chong|first=Stephen|date=2007|title=SIF: Enforcing Confidentiality and Integrity in Web Applications.|url=https://www.usenix.org/conference/16th-usenix-security-symposium/sif-enforcing-confidentiality-and-integrity-web}}</ref>
*WebDSL<ref>{{Cite journal|last=Groenewegen|first=Danny M.|date=2008|title=WebDSL: a ___domain-specific language for dynamic web applications.|url=https://dblp.org/rec/conf/oopsla/GroenewegenHKV08.html|pages=779–780|doi=10.1145/1449814.1449858|s2cid=8073129|url-access=subscription}}</ref>
*Acute<ref>{{Cite journal|last=Sewell|first=Peter|date=2005|title=Acute: high-level programming language design for distributed computation.|url=https://dblp.org/rec/conf/icfp/SewellLWNAHV05.html|pages=15–26|doi=10.1145/1086365.1086370|s2cid=1308126|url-access=subscription}}</ref>
*Mobl<ref>{{Cite book|last=Hemel|first=Zef|datetitle=Proceedings of the 2011 ACM international conference on Object oriented programming systems languages and applications |titlechapter=Declaratively programming the mobile web with Mobl. |date=2011|url=https://dblp.org/rec/conf/oopsla/HemelV11.html|pages=695–712|doi=10.1145/2048066.2048121|isbn=9781450309400|s2cid=10480906}}</ref>
*High-Level Abstractions for Web Programming<ref>{{Cite book|last=Richard-Foy|first=Julien|datetitle=2013Proceedings of the 12th international conference on Generative programming: Concepts & experiences |titlechapter=Efficient high-level abstractions for web programming. |date=2013|url=https://dblp.org/rec/conf/gpce/Richard-FoyBJ13.html|pages=53–60|doi=10.1145/2517208.2517227|isbn=9781450323734|s2cid=14305623}}</ref>
 
== References ==
{{reflist}}
 
{{Programming paradigms navbox}}
==Further reading==
 
* [https://dl.acm.org/doi/abs/10.1145/3328905.3332465 Developing Distributed Systems with Multitier Programming]
[[Category:Programming paradigms]]
* [https://dl.acm.org/doi/10.1145/3397495 A Survey of Multitier Programming]
[[:Category:Programming paradigms]]