3

Following uses JavaScript code but F# is tagged for input from functional programmers.

I understand that in functional programming we shouldn't mutate the state or incoming parameters but I'm confused about formal request pattern when it comes to functional programming.

Formal Request pattern consists of an Object having both input and output parameters within the same object.

The function looks up the associated subset of input parameters and populates the associated result field. The request object is subsequently passed to other objects where each function updates or decorates the result hence forming a pipeline.

In other words request object gets populated as it goes through the pipeline and each successive function depends on the result of the previous operation.

for instance in context of following Javascript code.

var request = {
    publicationId: "1234",
    permissions: [] // string array
    schema: null
    // a lot more other input and output params
}

following function reads publicationId & updates permissions

authorization.requestPermissions(request);

following function reads publicationId, permissions (from previous call) & populates schema

article.create(request);
article.upload(request); // uses updated schema from `article.create`
article.publish(request); // uses update schema from `article.upload`

Every subsequent operation is dependent on previous operation's result.

here both permissions and schema are output

console.log(request.permissions)
console.log(request.schema)

Question is, is it violating functional programming?

What could I change in this code to make Formal Request pattern more functional programming compliant.

  • You simple create new instance if output in every function. Which will be passed as input argument in next method. F# have nice "pipe" feature which provide smooth and readable syntax – Fabio May 2 '17 at 6:16
0

This pattern would not be considered an acceptable pattern in functional programming; indeed, in a pure functional programming language it would be rather difficult to implement it as you describe.

To produce a pipeline of processors for some input request in a functional style, you use functions that accept the request in their input and return the modified request as their output. It would also be common to use static typing to ensure that the necessary updates have been performed before a function is called that relies on them. In Haskell, your example would probably end up looking something like:

data Publication = Publication Int
data PublicationPerm = PublicationPerm Int [String]
data PublicationPermSchema = PublicationPermSchema Int [String] Schema

requestPermissions :: Publication -> PublicationPerm
requestPermissions (Publication id) = PublicationPerm id perms
       where perms = ... whatever code is needed to calculate permissions ...

createArticle :: PublicationPerm -> PublicationPermSchema
createArticle (PublicationPerm id perms) = PublicationPermSchema id perms schema
       where schema = ... whatever code is needed to calculate schema ...

logArticle :: PublicationPermSchema -> IO PublicationPermSchema
logArticle (PublicationPermSchema id perms schema) = do
        writeLogLine perms
        writeLogLine schema
        return (PublicationPermSchema id perms schema)

pipeline :: Publication -> IO PublicationPermSchema
pipeline = requestPermissions >>> createArticle >>> logArticle

Note that each function takes an input and returns a new object that also contains the additional information it calculated. The pipeline in the end strings each function together into a combined function that performs all of the actions.

Translation to Javascript loses the static guarantee that the pipeline generates the required information in the correct order, but can be done. It would look something like this:

requestPermisions = pub => ({ id: pub.id; perms: ... calculate permissions here ... })
createArticle = pub => ({ id: pub.id; perms: pub.perms; schema: ... })
logArticle = pub => { console.log (pub.perms); console.log (pub.schema); return pub; }
pipeline = pub => logArticle(createArticle(requestPermissions(pub)))
  • I don't know haskell but still trying to get the concept out of the answered code, I picked JavaScript because it's also functional, possible for your to answer in JavaScript while keeping haskell code intact. it doesn't have to be perfect JavaScript. – Devyiweid May 1 '17 at 23:32
  • can I say that you are suggesting to modify the input object and return as the result? – Devyiweid May 1 '17 at 23:40
  • Modification is generally considered inappropriate in functional programming. Returning a copy is usually better, although less efficient if the language doesn't have good support for it. In Javascript, this could potentially be optimized by using the object prototype to make original object properties available in the result without needing to copy them; I don't know how efficient this would be, but may be worth experimenting with. – Jules May 1 '17 at 23:48
  • i see, basically you are returning a new object while copying values from the input object and setting new values based on calculations – Devyiweid May 1 '17 at 23:49
  • 1
    @Devyiweid: the word "modified" in "functions that accept the request in their input and return the modified request as their output" does not mean "the same object mutated", it means "a new object that is a modified version of the original one". – Jörg W Mittag May 2 '17 at 0:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.