[HN Gopher] Functional PHP (2015)
       ___________________________________________________________________
        
       Functional PHP (2015)
        
       Author : luu
       Score  : 50 points
       Date   : 2024-10-13 05:25 UTC (16 hours ago)
        
 (HTM) web link (fluffyandflakey.blog)
 (TXT) w3m dump (fluffyandflakey.blog)
        
       | sourcecodeplz wrote:
       | I've tried Node when the trend started and it was okay. But the
       | problem was that the actual script was also the server. So if the
       | script hanged, the whole server hanged. Went back to PHP and
       | never looked back.
        
         | ec109685 wrote:
         | php has the opposite problem where if a script hangs on io, you
         | can be cooked (assuming other requests blocked similarly).
         | 
         | Different trade offs for sure, but given IO is often the
         | bottleneck, having it force you to think about running code
         | asynchronously can often result in code that runs more in
         | parallel than equivalent first blush php code.
         | 
         | For instance, if you were writing in a function style a program
         | that fetched entries from a web service, for each of those
         | results, run a summarization pass using another service, and
         | then insert summarization result in a database, a style like
         | shown in this article might serialize the summarization /
         | insert operations, one after the other, where you'd instead
         | want each result to be processed in parallel.
         | 
         | Lots of libraries in node that make that easy and the code
         | straightforward to reason about.
        
         | freedomben wrote:
         | It sounds like you "tried Node" but didn't learn/read enough to
         | understand the event loop architecture (and why node is
         | asynchronous). Node is pretty simple (and powerful) but yes if
         | you don't know about the event loop, you'll make a blocking
         | call (synchronous function) and end up blocking the loop (which
         | will hang your whole process).
        
           | sourcecodeplz wrote:
           | I admit, i struggled with promises, within promises, within
           | promises. Synchronous, I understood and just worked for me.
        
             | lexicality wrote:
             | Not that it matters because you don't care and no one uses
             | promises any more but it does really sadden me how much
             | nested promise code I've found over the years.
             | 
             | eg this                   function sad(input) {
             | return new Promise((resolve, reject) =>
             | foo(input).then((data) => {
             | bar(data).then((data2) => {
             | baz(data2).then(resolve, reject)                     })
             | })             );         }
             | 
             | could quite as easily have been written like this:
             | function happy(input) {             return foo(input)
             | .then((data) => bar(data))                 .then((data2) =>
             | baz(data2))         }
             | 
             | But no one seemed to be aware that you can return a promise
             | in the `.then()` callback and have it chain neatly...
        
               | datashaman wrote:
               | async functions return promises. everyone uses promises.
        
               | MrJohz wrote:
               | One of the rules I teach people when they're starting
               | using promises is never ever to write `new Promise(...)`.
               | 
               | That's not because it's bad - it's a useful tool if
               | you're connecting event or callback-based systems to the
               | world of promises and async/await. But a lot of people
               | who are just getting started with promises seem to take a
               | while to get used to chaining, and often resort to using
               | the `new Promise` constructor to get promises to appear
               | in the places they expect. So giving them a blanket rule
               | ("never use `new Promise`") forces them to figure out a
               | different approach.
               | 
               | It's become a lot easier since the introduction of
               | async/await, where chaining isn't so important, but there
               | are still always times when you need to understand that
               | underneath the syntax sugar, there's still promises
               | happening, and so I'm still finding the rule useful.
        
         | Aurel300 wrote:
         | That's not inherent to PHP, but rather the ecosystem it's
         | usually used in. The standard "LAMP" stack, for example, has
         | Apache in it for the actual server, talking to PHP using a CGI
         | interface. So if your PHP script crashes or hangs, the server
         | itself is still up, and capable of serving other clients.
         | 
         | If you set up a Node script where e.g. Express talks directly
         | to the clients, then yes, the script crashing or hanging means
         | the server becomes unavailable or unresponsive. However, you
         | can also set up a layer in front of Node. See cgi-node for
         | replicating the CGI workflow you might be used to.
         | 
         | There are some advantages to the standard Node model though:
         | the program can manage its own resources, such as keeping a
         | database connection open; it can run asynchronous maintenance
         | tasks; it can see and report the current server load; it can
         | easily combine HTTP(S) communication and Web socket streams;
         | etc.
        
           | sgdfhijfgsdfgds wrote:
           | > The standard "LAMP" stack, for example, has Apache in it
           | for the actual server, talking to PHP using a CGI interface.
           | So if your PHP script crashes or hangs, the server itself is
           | still up, and capable of serving other clients.
           | 
           | Not exactly... the standard, typical LAMP stack makes use of
           | mod_php, so the PHP engine is in-process with one of the
           | Apache process.
           | 
           | The fact that Apache has multiprocess/hybrid workers is
           | actually why the server stays up and can serve more requests.
           | 
           | Some contemporary LAMP stacks use FPM, I guess; most of those
           | in shared hosting ISPs for example because of the possibility
           | of running the script as a user process.
        
             | BirAdam wrote:
             | I would imagine that FPM is more common than people realize
             | because it's also usually faster, and running scripts as a
             | separate user is more secure. For example, if PHP is a user
             | with read-only access to the document root, it is far more
             | difficult for an attacker to do file injection.
        
         | anon7000 wrote:
         | I mean, there are tradeoffs with both approaches. It seems to
         | me that Node's stateful approach is used by other web servers
         | and languages too.
         | 
         | The main tradeoff is you're now reloading the entire server for
         | every request in PHP. If you have a massive server or
         | framework, that might not be the fastest thing in the world.
        
         | debacle wrote:
         | This is one of the most underrated features of PHP.
        
         | hipadev23 wrote:
         | You can make this same mistake in PHP blocking operations with
         | 1 worker process in mod_php, php-fpm, or handling sockets
         | directly. The fix is pretty standard: run multiple processes,
         | threads, or use non-blocking operations.
         | 
         | The most common PHP setups are simply running multiple
         | processes behind a httpd daemon, so this problem is less
         | frequently encountered. But it's still lurking at a certain
         | concurrency level.
        
       | skrebbel wrote:
       | (2015)
       | 
       | Btw while this code doesn't win a prize, I agree with the author
       | that functional style is worth it in many cases, even for a
       | language as wordy and cumbersome as PHP. I still love PHP - its
       | deployment story is still unparalleled and its standard library
       | came batteries included since forever.
        
         | ec109685 wrote:
         | php with lambdas eliminates a bunch of the syntax and can let
         | map/reduce style code be colocated while still achieving the
         | functional style benefits.
         | 
         | A big issue though (at least for some apps), is there is no
         | attempt to make that code parallelized for the io parts. So if
         | you aren't careful, you can end up with n+1 style IO calls,
         | making things very slow.
        
           | skrebbel wrote:
           | Personally I consider that a benefit at least as often as
           | not. In Nystromian terms, PHP functions are colorless, and
           | that removes a whole kind of complexity (at the cost of, like
           | you correctly point out, potential performance problems).
        
       | chx wrote:
       | tl;dr: Hardware is cheap. Engineers are expensive.
       | 
       | > Instead of fearing the overhead in PHP for function calls,
       | 
       | Already in 2015 in almost all applications this is a premature
       | optimization which is rightly known as the root of all evil.
       | Please. Your app will talk to the network, likely run a database
       | query which is like thousands or millions of times slower than a
       | function call. Further, even if there is a measurable difference
       | the cost of hardware which makes that difference go away is very
       | likely to be smaller and much smaller at that than the cost of
       | the engineering hours wasted during maintenance when wrestling
       | with code which was written with a "function calls are expensive"
       | mindset.
       | 
       | This doesn't mean you don't need to worry about performance and
       | scalability but even that is going to be much easier if you have
       | a well structured code.
        
         | ec109685 wrote:
         | IO has a very different cost than wasting CPU cycles, so
         | shouldn't necessarily be lumped together when analyzing
         | tradeoffs.
         | 
         | Your point still stands that fundamentally changing the design
         | of code should limited to the hottest parts.
         | 
         | Probably the biggest risk to this style map/reduce code is that
         | you end up having IO deeply nested running synchronously versus
         | grouping operations that can be run in parallel.
        
         | juangacovas wrote:
         | Well, in my particular experience with juniors, it's
         | astonishing the so many ways they have to make any code run
         | slower than it has to be (besides the network and database
         | queries), just by thinking 'nah, this is a computer and it can
         | do millions of ops by second'. And that's why I always take the
         | "premature optimization" dogma with a grain of salt while my
         | life's miserable enough having to accelerate some other's
         | stuff.
        
       | cynicalsecurity wrote:
       | His code is crap, I'm not even sorry for saying this. For the
       | case he is working with, OOP is absolute must.
        
         | SoftTalker wrote:
         | OOP is never an absolute must. It's a design choice, one of
         | several that can be taken.
        
         | huqedato wrote:
         | OOP is a lousy joke.
        
       | cies wrote:
       | You can write OOP-style in C, FP-style in C/C++/Java or even PHP.
       | Sure.
       | 
       | Writing pure FP code (pushing all the side effects to the "edges
       | of the program" in C is possible! But it's going to take a lot of
       | discipline from the programmers: there is no safety-net and lots
       | of dreadful boilerplate.
       | 
       | Impracticle, but possible.
        
       | huqedato wrote:
       | writing/thinking in FP style since 2020. Elixir, Js, F#, Julia
       | and even PhP. Never got back to OOP. Never needed to. I realized
       | what a waste of time and frustration had been OOP for me for
       | almost 15 years (Java, C#).
        
       ___________________________________________________________________
       (page generated 2024-10-13 22:01 UTC)