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

DO of a script that's modularized can only return MODULE! #2373

Open
hostilefork opened this issue Apr 15, 2019 · 2 comments
Open

DO of a script that's modularized can only return MODULE! #2373

hostilefork opened this issue Apr 15, 2019 · 2 comments

Comments

@hostilefork
Copy link
Member

hostilefork commented Apr 15, 2019

If you have a script that is not a module, you may be motivated to make it a module in order to get the benefits of features like isolation. So if you have something like:

 Rebol [
     Title: "My fun script"
 ]
 private-fun: function [] [print "I am private"]
 fun: function [] [print "I am public" private-fun]

 print "Type FUN for enjoyment"
 1 + 2

You might want the behavior with DO to say:

>> do %my-fun-script.reb
Type FUN for enjoyment
== 3

Then, if you wanted to get the benefits of a module, you might change the header:

 Rebol [
     Title: "My fun script"
     Type: Module
     Options: [isolate]
     Exports: [fun]
 ]

...BUT... doing this changes the behavior of DO to return a MODULE!, not the last thing evaluated to. If you've configured your console to print out the result (instead of hiding it like R3-Alpha does by default) you might get something like:

>> do %my-fun-script.reb
Type FUN for enjoyment
== make module! [
    fun: 'make action! [[] [...]]
    private-fun: 'make action! [[] [...]]
    function: 'make action! [[spec body] [...]]
    print: 'make action! [[line /html] [...]]
    +: 'make action! [[value1 value2] [...]]
]

So once it's a module, DO no longer gets the result of the body. So this means modularized scripts are not directly interchangeable with non-modularized ones. That's inconvenient.

I'd propose that IMPORT be what returns a module. Then, DO of a module returns the body evaluative result...just as if the script were not a module.

Modules that are named in a header don't have any obvious place to convey their evaluative results to a script that Needs: them. But that's not to say there couldn't be a dialect for capturing them into variables if one wanted:

Needs: [My-Fun-Script => result-var]  ; Random notational idea 

(Note: The specific motivating example I have relates to a console configured to display modules, and not wanting the message to be missed. So there's no particularly interesting return result, and DO could just return VOID!. But as mentioned, this seems like a loss for any script which is just being modularized for context isolation and still wants to return a value.)

@Mark-hi
Copy link

Mark-hi commented Apr 15, 2019

(1) Aren't needed modules imported, hence result-var would only hold the module itself?
(2) Just confirming: if you want it silent when done your module body must end with a void, right?

@hostilefork
Copy link
Member Author

If you have a script that is not a module, you may be motivated to make it a module in order to get the benefits of features like isolation.

So actually... the general philosophy of things being a "module" is that they do not have side effects, and are loaded only once for a session.

e.g. this is true in JavaScript and Python. And true in pure functional languages, because...well, nothing has side effects (unless explicitly designed to do so) and the act of importing is not one of those side-effect-having situations.

So it's really just a matter of terminology. "you should be able to DO a module and get a result" is the wrong way of saying "you should be able to isolate a script".

For sanity's sake--instead of creating two entirely different styles of programming (leaky-but-only-to-user-context and non-leaky)--there is full isolation of all scripts with DO:

https://forum.rebol.info/t/where-do-variables-go-when-you-do-from-a-module/1567

If you want a "leaky DO" then you would load the code as a block, INTERN it to wherever you want it to leak, and then DO it as a block...not DO it as a file.

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

2 participants