Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yamadapc/simple-warp-server
An unfinished study comparing JavaScript and Haskell servers.
https://github.com/yamadapc/simple-warp-server
Last synced: 15 days ago
JSON representation
An unfinished study comparing JavaScript and Haskell servers.
- Host: GitHub
- URL: https://github.com/yamadapc/simple-warp-server
- Owner: yamadapc
- License: gpl-2.0
- Created: 2015-09-11T18:55:23.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2015-09-15T23:13:25.000Z (over 9 years ago)
- Last Synced: 2024-12-24T11:58:04.411Z (17 days ago)
- Language: Haskell
- Size: 145 KB
- Stars: 3
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
A simple Haskell server
=======================
An unfinished study comparing JavaScript and Haskell servers.## A JavaScript primer
Here's a node.js HTTP server, taken from the [node.js homepage](https://nodejs.org):
```javascript
var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
```It's simple, small and readable. It gets even more readable if you put it like
so:
```javascript
var http = require('http');function handleRequest(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}http.createServer(handleRequest).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
```First comes an import from the `http` module. That's all you need to write it,
which is because the `node.js`' core libraries are really extensive. My
impression, on `node.js`' case of having really broad core libraries, it seems
that there's a certain limitation on how far you can express certain concurrent
scenarios, or computation, really. It's because node.js is a relatively
high-level platform.The core of the server is the `http.createServer` call. It takes a callback
function of type `(http.IncomingMessage, http.ServerResponse)` to nothing,
which gets called every time a request comes in. The body of the
`handleRequest` function is just a couple of method calls over the
`ServerResponse` instance that gets passed in as an argument.There's yet another class underneath this API, `http.Server`, you could rewrite
it as:
```javascript
var http = require('http');var server = new http.Server();
server.on('request', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
});server.listen(1337, '127.0.0.1');
```This is a very common idiom in JavaScript. `http.Server` is actually an
instance of `events.EventEmitter`, which is the `node.js` API for JavaScript's
event listening pattern.I like the example server and that it hides its complexity really well in
really well designed and clean manner. `node.js` style is usually a nice mix of
very object oriented structures, with somewhat functional APIs here and there.And a lot of really popular modules are very object oriented (whether it shows
or not). In `mongoose`'s case this is very clear, it provides a modeling system
for database entities and the logic related to them. It has support for
attaching instance methods, static methods and more. It even has a plugin
system, which will either work as a `mixin` of some kind or go the monkey
patcher way and have fun with some internal, esoteric hack.Here's an example "class" (`Model` actually - and here JavaScript gets unique
about inheritance, because this isn't standard prototypical inheritance
underneath) definition using `mongoose`:
```javascript
var mongoose = require()var userSchema = new mongoose.Schema({
firstName: [{ type: String }]
lastName: [{ type: String }]
})userSchema.methods.fullName = function() {
return this.firstName + this.lastName;
};var User = mongoose.model('User', userSchema);
````superagent` exposes a builder API, `mocha` uses a `Mocha` god class which uses
several other classes (`Runner`, `Spec`, `Reporter` - which is even abstract -,
etc.). I found this reliance on OOP for this bunch of Node.JS libraries to
contrast in an interesting way to the statement JavaScript is a very _lisp-like_
language - not that it isn't.- - -
## The Haskell takeLet's look at a Haskell Warp server:
```haskell
{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Types
import Network.Wai
import Network.Wai.Handler.Warpmain :: IO ()
main = do
putStrLn "Server running at http://127.0.0.1:9000"
run 9000 appapp :: Application
app _req respond = respond $ responseLBS status200 headers body
where
headers = [ ("Content-Type", "text/plan")]
body = "Hello World"
```It's not so far from the Node.js server. `app` is like our server callback in
Node.js. It takes a `_req` object and a `respond` callback function.In way, we could make it more _readable_ by using similar naming to the Node.js
example:
```haskell
main = do
putStrLn "Server running at http://127.0.0.1:9000"
run 9000 handleRequesthandleRequest _req respond = respond $ responseLBS status200 headers body
where
headers = [ ("Content-Type", "text/plan")]
body = "Hello World"
```Even though Haskell is a super typed language, we can omit the type signatures.
It'll just infer them.**TODO** Keep writting about this.
## License
Everything under this repository is licensed under the GPLv2 license.