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

Differentiate global variables from local variables #2607

Open
swilmet opened this issue Nov 11, 2017 · 14 comments
Open

Differentiate global variables from local variables #2607

swilmet opened this issue Nov 11, 2017 · 14 comments
Labels

Comments

@swilmet
Copy link
Contributor

@swilmet swilmet commented Nov 11, 2017

So with Meson all the variables are accessible in all meson.build files. For a big project, this can become a maintenance problem.

Normally the variables are immutable, so writing by mistake the same variable name in two different meson.build files should trigger an error (but this is currently not the case, see #2606 ).

It would be better to be able to differentiate local variables (those used in only one meson.build file) from global variables (those used in several meson.build files). It is possible to use a convention when naming those variables, but it would be better to have support from the type system.

@swilmet

This comment has been minimized.

Copy link
Contributor Author

@swilmet swilmet commented Nov 11, 2017

Normally the variables are immutable, so writing by mistake the same variable name in two different meson.build files should trigger an error (but this is currently not the case, see #2606 ).

OK so since this is not a bug, it makes the whole thing much more fragile.

I've adopted this convention now:

  • Local variables in lower_case.
  • Global variables in UPPER_CASE.
@liugang

This comment has been minimized.

Copy link
Contributor

@liugang liugang commented Nov 11, 2017

support local keyword before local variable maybe a good choice

do this is a good idea, but it will broken lots of existed meson projects.

Local variables in lower_case.
Global variables in UPPER_CASE.
@swilmet

This comment has been minimized.

Copy link
Contributor Author

@swilmet swilmet commented Nov 12, 2017

To not break the Meson API, there could also be a new setting in the project() command to enable the feature. And this could become the default for Meson version 2.

That way the feature can be implemented the other way around: local variables by default, and for a variable to be global, a keyword must be added, like "global" or "export". I find it more natural like this.

@nirbheek

This comment has been minimized.

Copy link
Member

@nirbheek nirbheek commented Nov 12, 2017

There is no such thing as 'global' or 'local' scope in Meson since the concept of scopes does not exist, and does not make sense since there are no functions. The ability to place build files in subdirs is provided for ease of use, and it is essential for variables to be accessible between build files in different subdirs. For example, you create a library in one directory and use it in your tools, tests, examples, and other library directories.

However, it is a real problem that people can clobber variables without meaning to. I think we can add a qualifier like const that causes an error when variables are reassigned. Alternatively, we can warn by default on clobbers and have a qualifier like var that suppresses it.

I like the const way though because it makes it very explicit that some variables are special and that their value will be reused elsewhere, say via a subproject or in other subdirs.

@swilmet

This comment has been minimized.

Copy link
Contributor Author

@swilmet swilmet commented Nov 12, 2017

In Object-Oriented Programming, there is this concept called encapsulation, also known as information hiding. A code following that practice is easier to reason about, because it is possible to understand a piece of code without the need to understand all the rest. A class exports a public interface and hides its implementation details, so when using that class in another part of the codebase, we can just look at its public interface to know how to use it and what features it provides.

For a meson.build file, its public interface would just be its list of global variables, i.e. the variables that are meant to be used in other meson.build files.

If you have read any sort of programming best-practices guide, you should know that global variables should be avoided if possible. In Meson, all variables are global… Don't you see anything wrong with that? In order to understand a meson.build file, you must potentially look at all the other meson.build files to know where is the relevant variable assignment (with mutable variables it makes things worse since a variable can be re-assigned in any other meson.build file). So it makes things harder to reason about.

Even if the type system doesn't enforce it, it is useful to distinguish global variables from local variables when reading the code. With my above convention with global variables in UPPER_CASE, I directly know if a variable is meant to be used in other meson.build files. In C, you can look at a *.h file to know what the "class" exports in its public interface. With Autotools the "global variables" are exported explicitly with the AC_SUBST macro. Currently in most projects using Meson as its build system, when reading a meson.build file there is no way to know the list of variables that are meant to be used in other meson.build files, i.e. its public interface.

Something that would be useful is preventing a variable from being re-assigned in another meson.build file. So a variable would be defined in a certain meson.build file, and all other meson.build files could use that variable, but not assign it a different value. A little the same as AC_SUBST.

@nirbheek

This comment has been minimized.

Copy link
Member

@nirbheek nirbheek commented Nov 12, 2017

Meson's build file language is not a programming language, and build files in general have totally different use-cases compared to programming languages. It is more useful to look at specific use-cases than trying to reason by analogy.

Sometimes it can indeed be difficult to figure out where a variable is defined if it's used across subdir(), but the fact that it works like that is also a useful feature that is used by all non-trivial build files that I have seen.

A good rule of thumb is to define the variable in the parent build file of whichever build files use it, unless it points to a target or something else that is entirely contained within a subdir. In general, I think this problem is better solved via your IDE.

I also don't agree with the Autotools comparison at all because AC_SUBST is about autoconf substituting variables in .in files, so the equivalent in Meson is actually configure_file() + configuration_data().

Something that would be useful is preventing a variable from being re-assigned in another meson.build file

I agree, that is a user error that we can easily design to avoid, which is why I suggested const.

@jpakkane

This comment has been minimized.

Copy link
Member

@jpakkane jpakkane commented Nov 12, 2017

When this was originally designed there was a very difficult balancing act between ease of use and security. The current approach was chosen due to objects being immutable and most projects needing to have variables visible. The biggest isolator is subprojects, where variables are fully separated and can only be accessed in limited ways and explicitly.

Like most things in life this is not a perfect solution but a compromise between many different competing requirements.

@jibsen

This comment has been minimized.

Copy link
Contributor

@jibsen jibsen commented Nov 12, 2017

One workaround would be to prefix variables that you wish were local with the subdir they are in. It looks like the glib meson build system sometimes does this.

With all variables being global and objects being immutable, there will be a proliferation in variable names. Perhaps if there were a switch to get warnings about clobbering, especially across subdirs?

I am personally not a fan of using all caps names, that could quickly make meson build files look like CMake.

@swilmet

This comment has been minimized.

Copy link
Contributor Author

@swilmet swilmet commented Nov 12, 2017

Meson's build file language is not a programming language

There is:

  • variable assignment
  • function/method calls
  • logical operators
  • conditions
  • loops
  • executing external commands

Code is code. It is important to write clean and maintainable code. It is no different for the build system.

@TingPing

This comment has been minimized.

Copy link
Member

@TingPing TingPing commented Nov 12, 2017

@jibsen I think that is just best practice in general and mostly avoids any accidental conflicts.

@volo-zyko

This comment has been minimized.

Copy link

@volo-zyko volo-zyko commented Dec 28, 2017

that could quickly make meson build files look like CMake.

It's not that easy. CMake is 18 years effort. :)

Seriously, does Python code look like CMake? They also have a convention about all caps global variable names. Separating local and global variables with a different naming scheme is a good thing. It makes the code more maintainable/readable. And this could be just a convention. That's my opinion.

So, what's the decision for this ticket? I'm curious because I'm considering meson for using in a big proprietary project and this issue is important to me.

@kugel-

This comment has been minimized.

Copy link

@kugel- kugel- commented Jul 24, 2018

I too think local variables are crucial for any bigger project.

@Ericson2314

This comment has been minimized.

Copy link
Member

@Ericson2314 Ericson2314 commented Jan 5, 2019

FWIW I would prefer the restrictions of something like https://github.com/dhall-lang/dhall-lang rather than no functions/scope to keep the language decidable. Some day...

@rulatir

This comment has been minimized.

Copy link

@rulatir rulatir commented Dec 8, 2019

Literally everyone:

It would be better to be able to differentiate local variables (those used in only one meson.build file) from global variables (those used in several meson.build files).

Meson authors:

God forbid! If we allow this, people will start using it to circumvent Meson's opinionatedness!

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

Successfully merging a pull request may close this issue.

None yet
10 participants
You can’t perform that action at this time.