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

Implement MAIN #405

Closed
masak opened this issue Oct 15, 2018 · 5 comments
Closed

Implement MAIN #405

masak opened this issue Oct 15, 2018 · 5 comments

Comments

@masak
Copy link
Owner

masak commented Oct 15, 2018

I haven't felt the need for it so far, but now that I'm picturing the module ecosystem of 007 modules, a MAIN function seems like it would pull its own weight.

  • It would act as a kind of "am I being run directly (as opposed to being loaded as a module)" check, and a rather nice-looking one at that. Python has this pattern, but does it through magic variables, which actually looks ugly and surprisingly un-Pythonic. Anyway, it seems that modules often want this, a way to be run directly and basically act as a CLI tool as well.

  • It would also allow for a nice, clean way to accept command-line arguments. In the long run we might also want to have some kind of array with all the arguments in it, but this will do for a start.

I figure the semantics should be this: all of the mainline runs first, and then MAIN runs, if it contains a Func value. Note that all of the mainline runs, no matter where the MAIN is defined. Doing it this way also allows patterns such as

my MAIN = printHeader;

...in case we already had a (possibly exported) function already doing what we wanted MAIN to do. (Python would approve.)

@masak
Copy link
Owner Author

masak commented Oct 23, 2018

Note that all of the mainline runs, no matter where the MAIN is defined.

Yes, you can write convoluted code because of this, that looks like it's running out of order. But it's not something we're going to enforce either way. Just write clear code.

@masak
Copy link
Owner Author

masak commented Oct 26, 2018

As implementation started, I realized two things:

  • If the MAIN method is not a Func, we just ignore it. (Could be more strict, but I don't see why we should panic here rather than quietly ignore... Since MAIN is something of an "extra" nicety from the start.)

  • We should pass in the CLI arguments (all strings) and bind to MAIN normally. We then intercept the exception about parameter mismatch, and turn it into a usage message and an exit status of 1. (We can skip having a --usage flag for now.)

masak pushed a commit that referenced this issue Oct 26, 2018
@masak
Copy link
Owner Author

masak commented Oct 26, 2018

I just realized a thing: MAIN macro. At first I thought this was just a fanciful notion, but the more I think about it, the more consistent it seems.

So now I think we have to do it that way, even pending the appearance of a motivating use case. Maybe through a different issue, though.

@masak
Copy link
Owner Author

masak commented May 16, 2019

One interesting consequence of #490 on MAIN is that it'll be trivially easy to have several MAIN "methods"/multis. #417, for example, could easily add a MAIN("test") multi.

The problem, though, is what we do when switching over types. I've always disliked what Perl 6 does here, even if it might be a necessary evil. I don't want IntStr et al. But if everything that comes in via the argument list is strings — which, face it, it is — then any kind of type matching we do has to be done in where blocks. Is that... OK? Is it enough? How do we say "can be parsed as an Int" in 007? I think this needs to be tried out in practice.

@masak
Copy link
Owner Author

masak commented May 16, 2019

Ooh, and all this should mean that the --usage thing can also just be another injected MAIN multi. A catch-all (defined last, which is important because of the where blocks) could defer to --usage and have it print to STDERR.

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

No branches or pull requests

1 participant