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

Scoping is unintuitive #490

Closed
pikajude opened this issue Mar 4, 2015 · 10 comments
Closed

Scoping is unintuitive #490

pikajude opened this issue Mar 4, 2015 · 10 comments

Comments

@pikajude
Copy link
Contributor

pikajude commented Mar 4, 2015

$ ({ a }: with { a = "inner"; }; a) { a = "outer"; }
"outer"

Is this by design? It seems weird.

Contrarily, let a = "outer"; in let a = "inner"; in a returns "inner".

pikajude referenced this issue in pikajude/nixpkgs Mar 4, 2015
@vcunat
Copy link
Member

vcunat commented Mar 4, 2015

This is by design IIRC because of some laziness-related properties. (I do agree it's counter-intuitive.)

Laziness above refers to evaluation and not the implementors ;-)

@shlevy
Copy link
Member

shlevy commented Mar 4, 2015

This is by design. It makes most lookups in the presence of with much more efficient, and while I can see how it's a bit odd I think it's more often semantically what you actually want. At this point I don't think we can change it, given how much code depends on the current behavior.

@copumpkin
Copy link
Member

😦 😦 😦

@bennofs
Copy link
Contributor

bennofs commented Mar 9, 2015

Ah, so with never overrides the variables currently in scope? That could make building refactoring tools much easier, as it might actually be possible to know where an identifier comes from!

@shlevy
Copy link
Member

shlevy commented Mar 10, 2015

Is there any action to do here?

@edolstra
Copy link
Member

No, we can't change the with scoping rules at this point. And anyway, it would be a bad idea. See here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with#Ambiguity_contra

@vcunat
Copy link
Member

vcunat commented Mar 10, 2015

Well, that's more of an argument against having/using with at all. I always saw its main use as a shortener, but in a functional language on can instead do something like:

let lib = something.very.long; in { lib.foo /*etc..*/ } 

and do it without the scoping ambiguities.

Anyway, changing behavior of any currently valid code would need strong arguments.

@edolstra
Copy link
Member

No, the Javascript example:

function f(foo, values) {
    with (foo) {
        console.log(values)
    }
}

is not a problem with Nix's scoping rules, because values always resolves to the same variable.

@vcunat
Copy link
Member

vcunat commented Mar 10, 2015

Using with in a dynamic language may obscure where identifiers come from, regardless of using the nix ordering or the intuitive one. One could construct contrived examples, e.g. with two nested withs on attrsets passed by parameters where it isn't clear which of the two contains a certain identifier, etc.

AndersonTorres added a commit to atorres1985-contrib/nixpkgs that referenced this issue Feb 18, 2023
- Reorder the lists in asciibetical order;
- Use install instead of mkdir + cp;
- Use nix functional code construction instead of shell loop code construction;
- Get rid of nested `with` in meta
  + Because `with` itself is an antipattern, as discussed in
    https://nix.dev/anti-patterns/language#with-attrset-expression
  + Because nested `with` has unintuitive behavior, as shown in
    NixOS/nix#490
- Format the code.

Also, add myself as maintainer.
AndersonTorres added a commit to atorres1985-contrib/nixpkgs that referenced this issue Feb 18, 2023
- Reorder the lists in asciibetical order;
- Use install instead of mkdir + cp;
- Use nix functional code construction instead of shell loop code construction;
- Get rid of nested `with` in meta
  + Because `with` itself is an antipattern, as discussed in
    https://nix.dev/anti-patterns/language#with-attrset-expression
  + Because nested `with` has unintuitive behavior, as shown in
    NixOS/nix#490
- Format the code.

Also, add myself as maintainer.
AndersonTorres added a commit to atorres1985-contrib/nixpkgs that referenced this issue Feb 18, 2023
- Reorder the lists in asciibetical order;
- Use install instead of mkdir + cp;
- Use nix functional code construction instead of shell loop code construction;
- Get rid of nested `with` in meta
  + Because `with` itself is an antipattern, as discussed in
    https://nix.dev/anti-patterns/language#with-attrset-expression
  + Because nested `with` has unintuitive behavior, as shown in
    NixOS/nix#490
- Format the code.

Also, add myself as maintainer.
AndersonTorres added a commit to atorres1985-contrib/nixpkgs that referenced this issue Feb 18, 2023
- Get rid of nested `with` in meta
  + Because `with` itself is an antipattern, as explained in
    https://nix.dev/anti-patterns/language#with-attrset-expression
  + Because nested `with` has unintuitive behavior, as shown in
    NixOS/nix#490
- Add meta.longDescription;
- Add meta.changelog;
- Update meta.maintainers list.
AndersonTorres added a commit to atorres1985-contrib/nixpkgs that referenced this issue Feb 20, 2023
- Get rid of nested `with` in meta
  + Because `with` itself is an antipattern, as explained in
    https://nix.dev/anti-patterns/language#with-attrset-expression
  + Because nested `with` has unintuitive behavior, as shown in
    NixOS/nix#490
- Add meta.longDescription;
- Add meta.changelog;
- Update meta.maintainers list.
AndersonTorres added a commit to atorres1985-contrib/nixpkgs that referenced this issue Feb 20, 2023
- Get rid of nested `with` in meta
  + Because `with` itself is an antipattern, as explained in
    https://nix.dev/anti-patterns/language#with-attrset-expression
  + Because nested `with` has unintuitive behavior, as shown in
    NixOS/nix#490
- Add meta.longDescription;
- Add meta.changelog;
- Update meta.maintainers list.
AndersonTorres added a commit to atorres1985-contrib/nixpkgs that referenced this issue Feb 20, 2023
- Get rid of nested `with` in meta
  + Because `with` itself is an antipattern, as explained in
    https://nix.dev/anti-patterns/language#with-attrset-expression
  + Because nested `with` has unintuitive behavior, as shown in
    NixOS/nix#490
- Add meta.longDescription;
- Add meta.changelog;
- Update meta.maintainers list.
AndersonTorres added a commit to atorres1985-contrib/nixpkgs that referenced this issue Mar 5, 2023
As related in https://nix.dev/anti-patterns/language#with-attrset-expression:

- Static analysis can’t reason about the code, because it would have to actually
  evaluate this file to see what variables are in scope;

- As soon as there are two with used, it’s not clear anymore from which the
  variables are coming from;

- Scoping rules around with are not intuitive. Examples:
  - NixOS/nix#490
  - pikajude@eea78e5
gador pushed a commit to gador/nixpkgs that referenced this issue Mar 9, 2023
As related in https://nix.dev/anti-patterns/language#with-attrset-expression:

- Static analysis can’t reason about the code, because it would have to actually
  evaluate this file to see what variables are in scope;

- As soon as there are two with used, it’s not clear anymore from which the
  variables are coming from;

- Scoping rules around with are not intuitive. Examples:
  - NixOS/nix#490
  - pikajude@eea78e5
@ghost ghost mentioned this issue May 26, 2023
12 tasks
@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/removing-most-uses-of-top-level-with/41233/1

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

7 participants