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

Add limited user-defined functions? #3234

Closed
mkrogius opened this issue Mar 13, 2018 · 25 comments · Fixed by #5460
Closed

Add limited user-defined functions? #3234

mkrogius opened this issue Mar 13, 2018 · 25 comments · Fixed by #5460

Comments

@mkrogius
Copy link

In order to reduce copy and pasting it would be useful to be able to define functions. I agree that it would be a bad thing to make meson turing-complete, so why not allow user-defined functions, but with the restriction that a user-defined function may not call any other user-defined function.

@koteyur
Copy link

koteyur commented Oct 30, 2018

Agree. Restrict recursion (and indirect recursion). Restrict storing function in variables. So language will stay turing-incomplete.

@le-jzr
Copy link

le-jzr commented Jun 7, 2019

It would also help me a great deal.

The simplest way to do this is probably to have the following restrictions:

  • User-defined function must be defined before it is used.
  • It is considered defined after the end of the body.
  • User-defined function may not be changed or redefined.
    • Alternatively, their names can be bound to a new function, but any prior reference keeps pointing to the old definition.

That way, recursion is impossible, parsing is simple, and it adds no expressive power to the language (you can do the same functionality by inlining all such functions).

@le-jzr
Copy link

le-jzr commented Jun 7, 2019

Would such restricted functions/macros be categorically unwanted, or can I take a shot at implementing it?

@jpakkane
Copy link
Member

jpakkane commented Jun 7, 2019

User defined functions will not be accepted. End of discussion.

What you can do instead is to add functionality that provides what you were going to do with your functions and submit that as a pull request instead if it is generally useful. This way everyone can use it.

@koteyur
Copy link

koteyur commented Jun 7, 2019

Thanks for the detailed explanation. Now it is obvious why user defined functions are not needed.

@jpakkane
Copy link
Member

jpakkane commented Jun 7, 2019

Now obviously we can't accept every niche thing in Meson master but we can add general tools that people can use to solve their own problems. The UX won't (and can't) be perfect but unfortunately everything is a tradeoff.

@le-jzr
Copy link

le-jzr commented Jun 7, 2019

I accept the decision, user-defined functions won't happen, message received.

But I feel obligated to say you are contradicting yourself. You say we should add niche tools for everyone to use instead of general functionality that people can solve their own problems with, then the next message says the exact opposite.

@mkrogius
Copy link
Author

mkrogius commented Jun 7, 2019

If the decision is that no user-defined functions will be allowed, how do you propose that we reduce duplication of code in build files? The reason I originally posted this question is because I have 68 lines of meson code that I have to copy paste in a bunch of places. Adding user-defined functions or even just simple macros would help a lot here.

@ePirat
Copy link
Contributor

ePirat commented Jun 7, 2019

Can you maybe given an example of your usecase? For VLC for example I managed to get rid of a lot of repetition by using an array of dictionaries and iterating over them.

@textshell
Copy link
Contributor

For VLC for example I managed to get rid of a lot of repetition by using an array of dictionaries and iterating over them.

I know this is currently the recommended way, but i always feel like that is a work around. Not something that really promotes the spirit of meson being easy and obvious to use.

@mkrogius
Copy link
Author

mkrogius commented Jun 7, 2019

@ePirat Sure! I'm happy to have more experienced mesoners take a look.

What this build file does is:

  • it generates c code for my LCM message definitions in both the source and build folders (because reasons)
  • compiles the c code into a dependency
  • generates python files from the LCM message definitions
  • compiles, zips, and installs the python files.

This exact same code ends up in a bunch of different places since I have a bunch of different folders which contain LCM files that need to be processed. It used to be more lines of meson code until I gave up and made a python script that does all of the steps for the python files at once.

The Meson file: https://gist.github.com/mkrogius/56fadc42cf0b551ba414accfa1dfb488
The python script I made to reduce the size of the meson file: https://gist.github.com/mkrogius/fb6c6c84bbb9c692c7a35f524d50cf66

Ideally I would just have to define all the necessary processing steps for my LCM files once, and then use that definition everywhere else in my project.

For clarity, by LCM I mean this project: https://lcm-proj.github.io/

@tp-m
Copy link
Member

tp-m commented Jun 7, 2019

For what it's worth, there is also PR #5209 which adds an include() function which might help in some cases with managing duplication/repeated chunks.

@TheQwertiest
Copy link
Contributor

Not exactly - #5209 does not allow multiple inclusions of the same file, since it would be equal to function/macros, which are not allowed in meson by design. That PR main purpose is flat layout of split meson.build files (that is multiple split build files in one directory instead of one very long build file and/or multiple subdirectories for each split build file).

@Volker-Weissmann
Copy link
Contributor

User defined functions will not be accepted. End of discussion.

It would be nice if you could provide any explanation, why you don't like non-turing complete user defined functions?

@kugland
Copy link

kugland commented Mar 25, 2021

You can always write your functions in C and call compiler.run(). So, in fact, Meson is Turing-complete after all.

@eli-schwartz
Copy link
Member

And by the same token, you could write your build system in shell scripts plus make, but invoke it from custom_target(). Of course, then you're not really using meson. Meanwhile, compiler.run() can only communicate with meson via comparing the return code or string comparisons, which is good for if/else blocks but does not actually let you implement user defined functions etc. in ways that e.g. dependency().get_variable() could not already do. (Being able to make a decision branch based on input from the OS rather than from meson.build, does not Turing-complete arbitrary functions make.)

I'm not sure where you're going with this logic. Are you trolling?

@Volker-Weissmann
Copy link
Contributor

Volker-Weissmann commented Mar 25, 2021

You can always write your functions in C and call compiler.run(). So, in fact, Meson is Turing-complete after all.

Afaik, the meson documentation says somewhere (I can't find it) that the output of a compiler.run() has to be a pure function of the input files and the compiler may not create files other than the target file or something like this. Meson assumes this to be true so that it can better analyse the meson.build files, and meson will be be buggy if it is not true.

The same is true for run_command() and custom_target()

@jeandet
Copy link
Member

jeandet commented Mar 26, 2021

Would something like partial function help?
I could see some uses to declare some custom_target presets for example I have some ASM dumps like this:

assembly_dump = custom_target('bp1_bench_asm_dump',
  input : matrix_bench,
  output : 'bp1_bench.S',
  capture: true,
  command : [objdump, '-drwCSl', '@INPUT@'],
  build_by_default: true
)

Being able to do something like:

asm_dumper = partial(custom_target, capture: true, command : [objdump, '-drwCSl', '@INPUT@'],build_by_default: true)

then use in several places like:

asm_dumper('bp1_bench_asm_dump', input : matrix_bench, output : 'bp1_bench.S')

That might work with any other meson function/method, it's not a killer feature but would allow some code factorization and make it more readable. I don't think partial functions would make meson Turing complete. A more general pattern would be to make some kind of basic templates.

@eli-schwartz
Copy link
Member

Yes, I've mentioned my longing for this on IRC several times and it would be my preferred way to resolve #6526

@xclaesse
Copy link
Member

@jeandet that really sounds like a use-case for generator(). One reason we don't want to allow user defined function is because we prefer doing things properly in Meson itself rather than letting users work around meson bugs or missing features. It seems your case is exactly that: Better make generator() more flexible and that will profit to everyone rather than letting you write a function that will only profit your project.

@eli-schwartz
Copy link
Member

See the link I posted. :)

Half the time, people say they want functions but what they actually want is a generator that acts more like a custom_target with prepared arguments.

@jeandet
Copy link
Member

jeandet commented Mar 26, 2021

@jeandet that really sounds like a use-case for generator(). One reason we don't want to allow user defined function is because we prefer doing things properly in Meson itself rather than letting users work around meson bugs or missing features. It seems your case is exactly that: Better make generator() more flexible and that will profit to everyone rather than letting you write a function that will only profit your project.

Yeah, I totally agree on Meson philosophy, my example is not the best, my point was more to be able to share inside the same project some functions presets, this is not vital and just a small convenience but I still would be happy to use it.
I don't see how partial functions would allow to work around bugs or missing features in Meson. For example I really miss a PySide2 module in Meson (no time to make it :( ), partial functions would be useless for this.
And again I used an example with custom_target but being able to alias a function with preset arguments could be useful with any function.

@kevr
Copy link

kevr commented Apr 11, 2023

In my case, I'm looking for something that let's me one-liner an executable() + test() pair. In one of my projects, I have tons of these tests scattered all throughout the meson heirarchy, so it would really help to be able to keep the test build logic in one place; as it is, I'm currently repeating the same thing everywhere.

Any suggestions on a way to do this, perhaps, with a generator?

@fbrausse
Copy link

One reason we don't want to allow user defined function is because we prefer doing things properly in Meson itself rather than letting users work around meson bugs or missing features.

You are aware that this issue is about a feature that is missing for users?

@dcbaker
Copy link
Member

dcbaker commented Jul 10, 2023

You are aware that this issue is about a feature that is missing for users?

We are well aware that many users would like to define functions. We have made a conscious choice to not have them, but instead to focus on fixing or adding functionality to the Meson language and/or modulus systems. We know that this means that some features may not be usable immediately, the tradeoff is that there is a single solution which has been implemented in a real programming language, and has tests. We recognize that not everyone make agree that the tradeoffs are worth it, but we do.

At this point this feels like a dead horse. I'm going to go ahead and close and lock it. If there is specific functionality you need, propose it. Meson has a lot of functionality that was added because someone said "hey, this would be great" and other people said "yeah, we could use that too!"

@mesonbuild mesonbuild locked as resolved and limited conversation to collaborators Jul 10, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.