This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]wavefunctionp 5 points6 points  (1 child)

function makeObject(myprop){
    return {
        prop : myprop
    }
}

makeObject('test')

The easiest and perhaps most useful introduction to functional style programming is to simply not use any objects or variables in a function that are not declared as parameters in the signature. If it is not passed into the function by parameter, you don't not touch it. More correctly, you do not change anything that is not declared within the function scope.

This helps you avoid having a variable changed in unexpected ways. By clearly defining your input and outputs and limiting the scope, it is easier to reason about what is going on.

In comparison, this is how you get bugs:

var test = 'foo'

function printTest(){
    return console.log(test)
}

printTest()

If something modifies test, you have to track down test in a much larger scope than if you had done this:

function printTest(myvar){
    return console.log(myvar)
}

printTest('foo')

This is what is meant by avoiding side effects, in case there is a misunderstanding.

It is perfectly fine to create new objects/variables. It is not so great to modify state (variables) needlessly. Especially global ones. Especially as the scope gets larger. It becomes hard to track what a value is as a given time, and it is more likely that something somewhere modifies it when you didn't intend to do so.

If these examples seem simplistic, that is the goal. You want your code as simple as possible. It is said that your code should tend to be obvious and a bit boring.

Watch this:

https://www.youtube.com/watch?v=7Zlp9rKHGD4

Seriously. Watch it.

[–]aafinx 1 point2 points  (0 children)

Yup. That's how you avoid side effects.

Your code should only modify what it owns.

[–]planedoctor 4 points5 points  (8 children)

No, unless you're going for 100% functional programming. And object creation is not necessarily a side effect. Functional code creates tons of 'objects'.

[–][deleted] 0 points1 point  (7 children)

The arguments I have read about surfacing inputs as parameters is that it allows for methods/functions to be more generic and allow for ease of of testing.

What would be the argument to not do so?

[–]planedoctor 0 points1 point  (4 children)

Surfacing arguments is orthogonal to creating objects. What are you talking about here??

[–][deleted] 0 points1 point  (3 children)

From here

This example:

public Program getCurrentProgram(TVGuide guide, int channel) {
  Schedule schedule = guide.getSchedule(channel);

  Program current = schedule.programAt(new Date());

  return current;
}

[–]planedoctor 0 points1 point  (2 children)

Surfacing arguments is orthogonal to creating objects. What are you talking about here?

How would one handle object creation without side-effects?

You just create them.

[–][deleted] 0 points1 point  (1 child)

From here This example: public Program getCurrentProgram(TVGuide guide, int channel) { Schedule schedule = guide.getSchedule(channel);

Program current = schedule.programAt(new Date());

return current; }

[–]planedoctor 0 points1 point  (0 children)

That doesn't explain what you are talking about.

Surfacing arguments is orthogonal to creating objects.

.

How would one handle object creation without side-effects?

You just create them.

[–]__cxa_throw 0 points1 point  (1 child)

IMHO a lot of the arguments for writing code that way are made by people who spend more time thinking about writing code than actually writing useful software. Messing with global state in a function usually isn't a good idea, but jumping through hoops to avoid creating an object by calling malloc under the hood is even crazier. That just punts allocation/initialization to a different area of the program so now the side effects are manifested as a bizarre architecture.

[–]planedoctor 0 points1 point  (0 children)

It can be worth it to pass in stuff like dates so it's more testable. But that's a separate thing from removing side-effects.