Live data from Hacker News

A Dead-Simple Web Stack in Haskell

williamyaoh.com

101–110 of 120 posts

Re: A Dead-Simple Web Stack in Haskell

#102

I think a simple web stack should aspire to the simplicity of the PHP stack, twenty years ago: 1) Create a directory "foo" on your server 2) Make a file called "bar.php" in that directory 3) Write "Hello World!" in the file 4) Open http://localhost/foo/bar.php in the browser and see "Hello World!" Lines of code or configuration so far: zero . 5) Add some actual code to bar.php 6) Reload the page and see the result Nu…

While you can theoretically get to this level of simplicity with various tools I think the difference isn't so much "can it be this simple?" so much as "does this level of simplicity fit my needs?" and that can be harder to quantify. The same thing you wrote in PHP done in Node.js in an arbitrarily named file served from root: require('http').createServer((_, res) => res.end('Hello World')).listen(80); Zero configura…

I think OP's point was that for starting developer PHP is super easy.

- edit a text file with any text editor (notepad?) - copy file onto a server (ftp? scp? git push? -- most servers will process php) - access it through url in browser

The example was about simplicity. OPs text file is 11 bytes long "Hello World", and is a valid PHP, it will run on a server.

This is about how easy a person with no knowledge and no special tools can start doing things.

Your example implies that developer has node installed, and expects the developer to run a server from within node, and then understand how the server handles URLs to functions. Additionally, I don't know how an early developer is expected to get this onto a server. First copy, then ssh onto server, then start the node server on server. That is a lot of steps for beginner to remember.

Additionally, as you mention, changes to file require server restarts, or building a self reload capability. I play with Flask, which has self reloading available, when developer pushes broken code Flask can just crash (self reload fails), and then developer has to start flask again. With PHP, broken code does not crash apache/nginx.

For developers that live and breathe computing knowledge running things through additional steps make sense. C/Java/C++/C# all have compilation and linker steps. Things like Grunt or Less are nothing scary for developers that ran C/C++ code through M4 preprocessors before compiling (now M4 is built into compilers).

So yes, for professionals, PHP is just a programming tool as any other.

But for beginners, PHP is awesome easy to grasp and use.

Re: A Dead-Simple Web Stack in Haskell

#103
post #82

Earlier quoted context omitted.

It sounds like you've never actually used PHP. Even way back when, you could pick from multiple pre-packaged solutions (XAMPP, WAMP, etc). In windows, the installer was a no-brainer click-through wizard, much like any other random software you'd find on sourceforge or whatever. And not only it would setup apache, but also mysql. Then you could click a button to turn on PHP (so no need to type anything in terminal eit…

> you could pick from multiple pre-packaged solutions > like any other random software you'd find on sourceforge or whatever > could click a button to turn on PHP > etc. tl;dr you don't need to know anything. Good summary of why PHP in production "back the days" was usually of very poor quality.

"Poor quality" comes with the territory of popularity. Everyone talks about Java over-engineering horror stories and the Javascript community even coined the "Javascript fatigue" term to summarize the pervasive quality issues in its ecosystem.

But naturally it's perfectly possible to write good quality codebases in those languages.

Re: A Dead-Simple Web Stack in Haskell

#104

Let's walk through my thoughts. Hmm, okay so Spock looks nice. Neat! The routing code looks very easy to read: main = do spockCfg Hello world! " get "users" $ do Spock.json (A.object [ "users" .= users ]) get ("users" var "friends") $ \userID -> do Spock.json (A.object [ "userID" .= (userID :: Int), "friends" .= A.Null ]) Alright, let's figure out how this works. runSpock :: Port -> IO Middleware -> IO () Okay that m…

That documentation indeed could be improved, but I guess the intention here is that basic usage is learned from the tutorials. Though it's possible to figure from that documentation alone as well (I'm reading it for the first time too, but using Haskell often): Path construction collects types of arguments into xs, then HVectElim (heterogeneous vector eliminator, or maybe "elimination") unwraps it into an appropriate…

Basic is the key issue here. Sure I can type this out and get a simple program working (although if I make a transcription error, I'm not super sure I can reason through the code). But if I want to build anything beyond the basic, I can't rely on the three whole tutorials on Spock^[1]. I need to start understanding the library.

But at that point reading the docs is pretty frustrating. Even with your explanations, I can't see how HVectElim or xs, ps, st are okay names. Sure, it's idiomatic. But that doesn't mean its good. What was wrong with types, pathStates and state? Sure it's less terse, but in this case that's fine. Or if they wanted to keep the same naming, at least explain it in the docs!

Having built a web app in Rust, I've certainly run into pain points, but nothing at this level. A library like Rocket has so much more documentation and careful examples^[2]. But also, the interfaces in Rocket are fairly simple. You write a function that returns a type that can be converted into a response. Anything you can serialize with serde can be converted into a response. With Haskell, the interfaces are that my route defining functions return a

  SpockCtxM ctx conn sess st ()
which is actually a

  SpockCtxT ctx (WebStateM conn sess st) 
With WebStateM being

  WebStateT conn sess st (ResourceT IO) 
Yeah...I can kinda infer that these are chained monads but I have no clue what bind or return does. I assume SpockCtxM is a reader monad and WebStateM is a state monad? But that should really be described in the documentation.

I see that the other libraries in the tutorial are better documented than Spock, so hopefully the Haskell ecosystem is getting better at this. But I'm still not sure I'd want to build a web app in Haskell (how's package management? Did you guys ever resolve cabal vs stack?)

[1]: https://www.spock.li/tutorials/

[2]: https://api.rocket.rs/v0.4/rocket/

Re: A Dead-Simple Web Stack in Haskell

#105

I think a simple web stack should aspire to the simplicity of the PHP stack, twenty years ago: 1) Create a directory "foo" on your server 2) Make a file called "bar.php" in that directory 3) Write "Hello World!" in the file 4) Open http://localhost/foo/bar.php in the browser and see "Hello World!" Lines of code or configuration so far: zero . 5) Add some actual code to bar.php 6) Reload the page and see the result Nu…

Where is the step where PHP is installed and running on the machine, bound to port 80? This is a non-trivial step on every system (slightly less trivial if you bind to port > 1024 but still not for the absolute newbie).

Note that you can go much simpler by just loading a file into the browser, and absorbing the dynamism in the front-end. (If you really want a proper URL, then launch a simple static http server in the same directory as the html file.) The great benefit here is that the browsers dev tools are far better than PHP's.

Re: A Dead-Simple Web Stack in Haskell

#106
post #63

Not sure what's meant by "simple" here, but it looks quite complicated to me. Even though I use something similar at work (with Servant), but much simpler (FSVO "simple") approaches as a hobby: - Those frameworks relying on built-in servers, including all their dependencies, are huge. If a program is linked statically (the default for GHC/cabal), that's also a very large codebase that doesn't get updated on system up…

This reminds me of this commit in Redux: https://github.com/reduxjs/redux/commit/9276ff0af6400633d673....

"Simple" is always a relative term. I agree, if "simple" looks like the complication in the post, then I'm turned off from the language because I don't really want to see what "complex" can become.

I have no doubt if I had context of Haskell, I would be able to read that with no trouble - even without Haskell context I think I can grok it pretty well. But imagine a newbie to the industry as a whole? It stops being simple at various stages, very quickly.

Re: A Dead-Simple Web Stack in Haskell

#107
Really happy to read this - I'm using Spock and postgresql-simple, but found Lucid for generating HTML instead of blaze.

I never got around to wrapping my head around handling configuration, so I will definitely take a look at configurator.

I also like the suggestions for what libraries to look at next, sometimes choosing what libraries to go for feels like a jungle for a newcomer.

Re: A Dead-Simple Web Stack in Haskell

#108

Earlier quoted context omitted.

While you can theoretically get to this level of simplicity with various tools I think the difference isn't so much "can it be this simple?" so much as "does this level of simplicity fit my needs?" and that can be harder to quantify. The same thing you wrote in PHP done in Node.js in an arbitrarily named file served from root: require('http').createServer((_, res) => res.end('Hello World')).listen(80); Zero configura…

I think OP's point was that for starting developer PHP is super easy. - edit a text file with any text editor (notepad?) - copy file onto a server (ftp? scp? git push? -- most servers will process php) - access it through url in browser The example was about simplicity. OPs text file is 11 bytes long "Hello World", and is a valid PHP, it will run on a server. This is about how easy a person with no knowledge and no s…

> Your example implies that developer has node installed, and expects the developer to run a server from within node, and then understand how the server handles URLs to functions

The OP's example implies that the developer has Apache and PHP installed at a minimum and that Apache is set to proxy requests to PHP. This requires SSH and starting Apache. I remember doing this back when I first configured my first LAMP server, though most hosting companies will do this for you and usually as part of a cPanel setup (even more dependencies).

> Additionally, as you mention, changes to file require server restarts, or building a self reload capability

In fact, I said just the opposite.

Re: A Dead-Simple Web Stack in Haskell

#109
post #71

Earlier quoted context omitted.

While you can theoretically get to this level of simplicity with various tools I think the difference isn't so much "can it be this simple?" so much as "does this level of simplicity fit my needs?" and that can be harder to quantify. The same thing you wrote in PHP done in Node.js in an arbitrarily named file served from root: require('http').createServer((_, res) => res.end('Hello World')).listen(80); Zero configura…

Eh, that's not a great example. It can be hard to appreciate the simplicity of PHP when one's fully bought into the stockholm syndrome of another language/framework :) Consider this: a hello world in PHP requires no knowledge of programming whatsoever: a file saying "hello world" is enough to get the text to show on a browser. Having two different pages requires no knowledge of if statements, nor of 404 handling. On…

> It can be hard to appreciate the simplicity of PHP when one's fully bought into the stockholm syndrome of another language/framework :)

I used to use PHP and I haven't touched Node.js in quite some time as I've been playing with Rust/(Rocket, Actix Web) and Go's standard lib. So... :)

> Consider this: a hello world in PHP requires no knowledge of programming whatsoever: a file saying "hello world" is enough to get the text to show on a browser

This does not happen with "no knowledge" unless you suppose that copying and pasting arbitrary lines into a command prompt is "no knowledge" (that Apache server isn't going to install and start itself). And if that's allowed then suddenly there's lots of things you can do that require "no knowledge" as even a few lines of JS spewed into an index.js file via cat can get you easy file content streaming and 404 handling without need for a reverse proxy.

> the latest Next.js today is beyond abysmal in comparison

I don't know about Next.js; I've never used it nor does it look like something I'd want to use. I also don't understand why we're comparing Next.js to PHP when the equivalent would be some Drupal-as-a-Service or similar.

Re: A Dead-Simple Web Stack in Haskell

#110
post #71

Earlier quoted context omitted.

While you can theoretically get to this level of simplicity with various tools I think the difference isn't so much "can it be this simple?" so much as "does this level of simplicity fit my needs?" and that can be harder to quantify. The same thing you wrote in PHP done in Node.js in an arbitrarily named file served from root: require('http').createServer((_, res) => res.end('Hello World')).listen(80); Zero configura…

Eh, that's not a great example. It can be hard to appreciate the simplicity of PHP when one's fully bought into the stockholm syndrome of another language/framework :) Consider this: a hello world in PHP requires no knowledge of programming whatsoever: a file saying "hello world" is enough to get the text to show on a browser. Having two different pages requires no knowledge of if statements, nor of 404 handling. On…

The LAMP stack was effectively fucking magic and basically the whole reason many of us are in this field right now. Specifically, PHP/MySQL mostly "just worked" and dealt with most of the stupid stuff for you. Yes, the performance was kinda meh sometimes (but back then a normal page load had a dozen assets, not hundreds) and not-strict typing, behind-the-scenes shenanigans, and other magic made for some interesting bugs... but overall, it worked, and it was easy enough for a middle schooler to pick up.

I switched tracks from webdev to systems pretty quick but sometimes I look at what's going on in webdev today and frankly it's pretty disturbing. The sheer amount of complexity to render some HTML and JS is mind-boggling. And the worst part is it's not even that much better than it was back in the LAMP days. Pages still take forever to load, browser compat is still crap, and heavy sites are still gross. The only difference is the amount of complexity, gatekeeping, and sheer busywork that these new frameworks/languages/systems bring in.

Or maybe I'm just the old man yelling at the clouds.

Post reply on HN