DEV Community

[Comment from a deleted post]
Collapse
 
madhadron profile image
Fred Ross

Interesting. When I think of the major paradigms of programming, the list that comes to mind is imperative, functional, logic, relational, and maybe concatenative. Each corresponds to a mathematical model of computation and contains a universe of practice derived from that model. So I think what you're really seeing is different communities of practice with somewhat different usages of the already vague term "paradigm."

Are you going to model your solution as message passing? Reaction to events? What, if anything, will you use to draw boundaries between parts of your system?

In functional or logic languages, you would usually end up treating it as tail call recursion. For example, the main loop of an HTTP server in Prolog does something like

accept_loop(Socket) :-
  tcp_accept(Socket, ClientSocket, PeerIP),
  thread_create(handle(ClientSocket), _),
  accept_loop(Socket).

In Scheme it would be something very similar

(define (accept-loop socket)
  (define client-socket (accept socket))
  (fork-thread (lambda () (handle client-socket))
  (accept-loop socket))

In Haskell and other lazy languages, the main structure is often a fold over an infinite sequence.

Collapse
 
notriddle profile image
Michael "notriddle" Howell

So I think what you're really seeing is different communities of practice with somewhat different usages of the already vague term "paradigm."

Probably, yeah. It conflates the tactical choice of avoiding mutability with strategic choices like SOLID or the Actor model.

In functional or logic languages, you would usually end up treating it as tail call recursion.

That's not wrong, but it's a low-level implementation detail, not an insight into how to structure your application overall. That recursion or sequence evaluation is usually hidden behind an abstraction like gen_tcp or the callback given to serve.