Yes, you can, and you'll be happier for it.

LAMP is short for the following open source components to realise a web server:

Linux

Apache

MySQL

PHP

In this picture, Linux provides the OS, Apache the web server, MySQL the database and PHP server-side scripting facilities. In fact, most of these components can be replaced. One can replace Linux with almost any other OS, Apache with Nginx, MySQL with PostgreSQL. PHP is similar to ASP.

There are also larger replacements of this stack, such as Tomcat, which replaces both Apache and PHP. Similar architectures are available for Python (django), Ruby (Ruby on Rails) etc. As we will see below, this is the picture into which SWI-Prolog fits.

The SWI-Prolog web framework

The SWI-Prolog web framework (obviously) does not replace the OS. It does replace Apache, PHP and to some extent MySQL. We could refer to the stack as LP (Linux Prolog). Below, we point at the various libraries that make up the stack and relate them to the LAMP components they replace.

Replacing Apache

The core web services are provided by the following libraries

library(http/thread_httpd) -- Accept HTTP requests

library(http/http_authenticate) -- Basic HTTP authentication

library(http/http_openid) -- OpenID based authentication

library(http/http_session) -- Session management

library(http/http_ssl_plugin) -- Provide SSL functionality (HTTPS)

library(http/http_cors) -- CORS management

library(http/http_dispatch) -- Bind HTTP locations to actions

library(http/http_files) -- Serve plain files from the OS

library(http/http_parameters) -- Read GET and POST form data

For development purposes, there are the following support libraries

library(http/http_log) -- Log traffic

library(http/http_error) -- Present Prolog errors in the browser

Replacing PHP

The previous section provides a basic web server that can serve static pages from the filesystem and optionally does authentication, session management, logging and error handling, i.e., Apache 0.1. The library(http/http_dispatch) binds HTTP locations to Prolog predicates that need to write a document to the current_output stream using the CGI conventions, i.e., write the header followed by two blank lines and the content. There are two high level libraries for generating dynamic pages. None of them relates directly to PHP, but we consider that a good thing.

library(http/html_write) -- Our flagship for server site generated pages

library(http/http_pwp) -- Embed Prolog queries in xhtml pages

Anne Ogborn has written a good tutorial on how to use the SWI-Prolog web framework.

Supporting AJAX

AJAX programming, i.e., initiating HTTP requests from JavaScript to update pages locally without reloading the whole page, is supported by:

library(http/http_json) -- Read/write JSON documents

library(pengines) -- Use Prolog as a query language

Replacing MySQL

There are several replacements for MySQL, depending on

Persistence requirements Sharing requirements Size of the data

The alternatives are

Using the session (Prolog) database This database associates Prolog terms with the current session. This is generally suitable for keeping track of the status of the dialogue with the user. Restarting the server loses the data. Using the dynamic Prolog database Any Prolog programmer should know this. Data stored in dynamic predicates is accessible across sessions. The data can be highly dynamic and fast, but is lost on a server restart. library(persistency) adds persistence to the Prolog database Extends the dynamic database with wrappers to manipulate the dynamic predicates. These wrappers manage a journal, which is restored after a server restart. There is no overhead for read access. The overhead for write access can be controlled by selecting the journal flushing regime. library(semweb/rdf_db) provides (optionally persistent) RDF storage Using the RDF store is similar to using the dynamic database or library(persistency), but enforces the use of the widely recognised RDF data model. For example, you can make your data accessible through SPARQL using ClioPatria library(odbc) provides a connection to RDMS systems This is straightforward and avoids the famous Object-relational impedance mismatch

Developing and deploying your service

Services can be developed simply by running your application on your laptop or desktop and directing your browser to http://localhost:<port> as long as you use relative HTTP locations, preferably computed by http_link_to_id/3 which computes an HREF based on the referenced predicate on the local server and parameters. When ready for testing, you can run the web server in a terminal and use an Apache proxy to make it publically accessible from port 80. If problems occur, you can insert debugging statements, trace the program, fix it and reload the source without shutting down the server. If all runs cleanly, there is this library and accompanying (Debian) Linux init script for production:

library(http/http_unix_daemon) -- Run server as Unix daemon process

Federating your services

The above assumes a single process server. What if one needs more power or wishes to split responsibilities over multiple servers? Obviously, you can use an external load balancing system to distribute the traffic over multiple Prolog servers. SWI-Prolog's session management is ready to deal with the Apache server load balancing facility to keep sessions on the same server. What if you want the servers to communicate?

Use library(odbc) to share a common database

Use TIPC to realise a cluster

Use library(pengines) to distribute queries

Advantages of the LP framework

Why would one choose the SWI-Prolog web programming framework over LAMP, Tomcat, Django, Ruby-on-rails, etc.?

Avoid the Object-relational impedance mismatch. This applies notably when accessing RDMS or RDF storage systems, but also dynamic Prolog predicates are way more easily queried than data stored in imperative languages. See also the ClioPatria whitepaper. The library(pengines) provides any application with a clean modular API that is more elegant than SQL or SPARQL in a few lines of code. Stop string programming. STRINGS ARE WRONG. Virtually all processing in the LP framework is based on proper parsing, term manipulation (Prolog's speciality) and serialization. Quasi quotation support allows for safe interpolation into e.g., HTML and JavaScript fragments embedded in the Prolog source code. Many applications need rules. Prolog is very well suited for such tasks. A few rules are way easier to maintain than nested if-then-else statements. External rule formalisms (e.g., RIF, SWRL) are easily compiled to Prolog. Quite a few problems are nicely expressed as constraint problems and no language mixes with CLP as easily as Prolog. See library(clpfd) and library(chr). DCGs may not have proven to be the ideal for full blown parsing of NLP, but it is still a well integrated framework that can, due to its non-determinism, handle grammars elegantly. If this doesn't suffice, there are various more powerful frameworks that integrate cleanly into Prolog. Prolog allows for hot-swapping code while data stored in dynamic predicates is retained. Programming in Prolog is fun!

Disadvantages of the LP framework

It is difficult to see principal technical disadvantages in the LP framework. The main weakness of Prolog are algorithms that require destructive assignment, intensive array processing or bare-metal performance for e.g., processing pixels. Such requirements are rare in the context of web programming. If necessary, such requirements can be fulfilled using C/C++ plugins.

There is a weakness in scalability and robustness. Both are mostly related to a small user basis and thus limited testing. Notably dealing with unexpected high loads and DDoS attacks is not ironed out. This can be remedied by using a proxy server that implements state-of-the-art DDoS defence techniques, load regulation and load balancing. Slightly more fundamental is that each request is processed by a Prolog thread. This is also the case in Apache, but server architectures that aim at really high traffic such as nginx process many requests using I/O multiplexing.

Another problem is the (un)availability of server-side plugins to access external APIs. Some of this can be remedied by using JavaScript based replacement technology on the client. In other cases, our only counter is to implement these plugins and share them, for example as an add-on.

Our final problem is the lack of masses of Prolog programmers one can easily hire. Running critical Prolog applications is possible if you invest time to become part of the Prolog community. You will get answers to your questions and you will be able to hire someone to solve a problem for you.