Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impure function mistake #50

Closed
gyzerok opened this issue Jul 17, 2015 · 6 comments
Closed

Impure function mistake #50

gyzerok opened this issue Jul 17, 2015 · 6 comments

Comments

@gyzerok
Copy link
Contributor

gyzerok commented Jul 17, 2015

Hi!
Its duplicating of my email via gitbook.

In Chapter 6 following function seems to be impure:

var img = function (url) {
  return $('<img />', { src: url });
};

As I've understood from previous chapters img is impure because it relies on $ which isnt directly passed via arguments. But in the text there is nothing about img impurity so some folks can assume its pure.

Am I right?

@DrBoolean
Copy link

Hi!

In this case, it's available via the outer closure as a dependency - just like _. This is valid code in a pure functional language, but I totally see what you mean... I have to research dependencies and get back to you on this one. I can say that there's an effort to purify environment via CoEffects (http://tomasp.net/blog/2014/why-coeffects-matter/) and that my pure chapter does totally suggest that this is impure.

@KtorZ KtorZ closed this as completed in ab1353b Feb 20, 2016
@marcelobart
Copy link

marcelobart commented Oct 16, 2018

In a common manner and in Chapter 6 too:

  const host = 'api.flickr.com';
  const path = '/services/feeds/photos_public.gne';
  const query = t => `?tags=${t}&format=json&jsoncallback=?`;
  const url = t => `https://${host}${path}${query(t)}`;

The url is impure? Because it use the host and path constants!

@KtorZ
Copy link
Member

KtorZ commented Oct 16, 2018

@marcelobart
It's not. To convince yourself, ask yourself the following question:

"Will various executions of my program in various environments will change the value of host and path?"

The answer is no, host and part are pure values (contants in that case) that you simply define outside of url and pull them inside via a closure. We talk about impure value whenever you refer to something that may change at runtime, because of the system's environment or anything that doesn't solely depends on what's written in your program.

@marcelobart
Copy link

Hummm, make sense!

If we look only, and really only, to the url function, I think it's okay to consider it an impure fn.
For example: if we export the function to make a unit test, without host and path (and query) it will break.

But in a application context, the url and host always exists, make the whole scope pure. Is that right?

Thanks for the explanation! :D

@KtorZ
Copy link
Member

KtorZ commented Oct 16, 2018

Hmmm... not exactly sure what you mean by " if we export the function to make a unit test, without host and path (and query) it will break." but I believe you have a false sense of what closures are in JavaScript.

  const host = 'api.flickr.com';
  const path = '/services/feeds/photos_public.gne';
  const query = t => `?tags=${t}&format=json&jsoncallback=?`;

  const url = t => `https://${host}${path}${query(t)}`;
  
  exports.url = url;

This is a perfectly valid (and I'd even say, recommended) way of exposing the url function and nothing will break. This way, host and path are just encapsulated inside the module and not accessible by anyone else. The only way for users of that module to define urls is by using the provided API: url.

@marceloadsj
Copy link

marceloadsj commented Oct 16, 2018

No, I know what closures are, (@marcelobart here, :P)!

I mean that, if we start to "componentize" the code, and does not put all the necessary functions and consts (in this case: host, path and query) inside the same closure, we will get an error.

I understand that, to url function works as pure, the three "dependencies" must be pure/not mutable.

I don't say that it is wrong, but when I think in "functional way" of writing things, I think to a more functionitization approach of everything, hahaha. :P (I don't know if this way of think is right in fp).

// Simplified version!

// using, for example (ramda)
const host = R.always('api.flickr.com');
const path = R.always('/services/feeds/photos_public.gne');

// and composing/converging it to create url fn
const url = R.converge((h, p) => `https://${h}${p}`, [host, path]);

// url() === "https://api.flickr.com/services/feeds/photos_public.gne"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants