Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

since a large amount of programming is all about state and side effects

IANA web developer, but...

Doesn't web development typically put state into a database system instead of the scripts the server runs to generate the requested pages? It seems reasonable enough to have a function that takes a page request as input, calls some other functions to look up info from the database, then constructs and returns a page and a sequence of changes to make to the database.



You can do allot with a database sure but sometimes you want multiple transactions within a single request and data will change between them. You may also take input from other sources than a database such as flat files, web APIs emails etc and need to do a bunch of processing between them.

Not to mention if you are using Comet or something where you hold a request open for a long time and push and pull allot of data some of which may not be persisted immediately.

Sure you can probably write your controller logic in a pretty functional way but then you probably end up moving your messy logic into stored procs or something else.


sometimes you want multiple transactions within a single request and data will change between them

Is this an issue with race conditions, or with alternating between reading and writing the state during a single request, or both, or something else entirely?

You may also take input from other sources than a database

This doesn't seem like it should make a difference: you write a function to get the necessary data from whatever source, then call that function in the page request handler (OK, yes, I/O is technically a side effect).

I agree that the processing you do with that data might require some significant rethinking, depending on how it was written/planned out before (sure, state-passing style is always there, though I don't enjoy doing it... really though, I've found that a lot of what I was used to doing imperatively is not all that awkward to do functionally).

Not to mention if you are using Comet or something where you hold a request open for a long time and push and pull allot of data some of which may not be persisted immediately.

What's the conventional way to do this in an imperative language?


Is this an issue with race conditions, or with alternating between reading and writing the state during a single request, or both, or something else entirely?

Usually reading and then writing some state followed by waiting briefly to see if another thread will change the same value, if it does use then do something with the new value and return that to the request.

I agree that the processing you do with that data might require some significant rethinking, depending on how it was written/planned out before (sure, state-passing style is always there, though I don't enjoy doing it... really though, I've found that a lot of what I was used to doing imperatively is not all that awkward to do functionally).

Depends on how much more difficult it is , does it just require and adjustment of thinking to a new paradigm or is doing everything harder? I'm thinking of stuff like Haskell Monads here. I admit I have not much functional knowledge beyond some basic scheme so I'm curious about this.

What's the conventional way to do this in an imperative language?

I guess allocate stuff on the heap which other threads can modify, use monitors to control concurrent access.


does it just require and adjustment of thinking to a new paradigm or is doing everything harder?

Depends on how restrictive your language is. Scheme makes it a lot of things easy, e.g. a sequence of statements is often easy to express with begin/let/let* , whereas Haskell is pickier about use of side effects. The biggest hurdle I had in learning scheme was getting used to using a recursive function where I would normally use a loop.

  (let* [(x (... DB query ...))
         (y (... API query based on x ...))]
     (begin (... write some state based on x and y ...)
            (... wait a bit ...)
            (... read the same piece of state ...)
            (if (... it is unchanged ...)
                (... then ...)
                (... else ...))))
The line between imperative and functional starts to look a bit fuzzy, but let* and begin can be constructed from lambda expressions.


Haskell is actually awesome for something like Comet or just about anything where concurrency is involved.

I'm launching a small Haskell-based product called EventSource HQ (http://www.eventsourcehq.com) taking advantage of just this.

Handling state across threads in Haskell is not a problem at all. Haskell is not bad or complex when it comes to mutable state, it's just very explicit about it. When it comes to doing stuff the involves multiple threads this is a huge advantage.

Haskell is complex in the sense that it brings a whole bunch of new abstractions to the table that can take a lot of work to get a hold of. But while this can make for a steep learning curve, it also comes with a huge payoff, since these abstractions are very powerful.

Stuff like Iteratee's and Enumerators or the newer Conduits can be tough to wrap your head around, but once you do the power of composable abstractions over IO streams can be extremely useful.


We use Erlang to run our (several million messages a day) WebSockets implementation. It's been fine, way more stable and less resource intensive than the equivalent Tornado server.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: