I've lurked on this forum a bit but never posted. Hopefully this is the right place to discuss sort of half-baked ideas ... I did some searching on the forum but haven't found a lot of discussion that seemed related ...
A few years ago while learning swift I invested a few weeks trying to use swift playgrounds for data-sciencey tasks in a manner somewhat similar to how one might use jupyter notebooks. It wasn't a successful experience in the end -- but I still think there is potential for this workflow when/if playground's are expanded/better integrated into swift and (hopefully eventually) improved.
One issue I remember finding particularly annoying was the way it was essentially impossible to share code between a playground and swift application due to the fact that playgrounds allow/expect the use of top-level expressions while normal swift code is not allowed to use this construct except in main.swift.
A similar limitation preventing reuse exists within the ipython jupyter notebook community when one is using the standard tools. In that ecosystem, one writes code in a .ipynb file where the general expectation is generally that the code operates on the module scope and performs side-effects via top-level expressions. The similarity of this limitation is a bit obscured by the fact that python doesn't actually have syntax prohibited top-level expression and .ipynb files are horrendous json files rather than typical text but various tools exist to convert these files into .py files -- and when you do the conversion from a notebook to a .py module, you are left with the fact that code made for use in the notebook context is not parameterisable or reasonably re-useable outside of the notebook context without changes -- and there is no built-in way to make it so.
I find these playground/notebook programming models as implemented tend to force a trade-off -- in order to take advantage of the interesting features of a general purpose edit-eval-loop environment, one is forced to write code in a different style than one would typically use within an application -- there is usually not any clean way to write code which works both within this style (where it can be developed with values inspected interactively) while also being able to be directly re-used within an application or script.
Recently I was confronted with this trade-off again in the jupyter world and made a simple python module that models an ipython notebook as a function and allows one to invoke a notebook from a python program via a function call. I think modeling the interactive development environment as a function definition that can be immediately invoked without supplying external parameters is a pretty accurate fit to the programming model -- and if you actually do model the notebook environment this way, then it turns out you can easily re-use this code made for the notebook environment outside of the notebook environment within an application ...
Its gotten me thinking that something like this concept if applied to swift's implementation of playground's/main.swift might be a really good fit...
I'm imagining that the special flavor of swift allowed inside a playground/main.swift file (where top-level expressions are allowed) might be treated as a kind of syntax sugar for a function definition. To make the concept concrete (specifics are just for example) ...
Suppose a new file extension .swiftscript
was added where top-level expressions were allowed. Expressions at top-level within the .swiftscript are allowed but interpreted as occurring within the body of an implicitly defined function with the same name as the file -- and its this function which is provided by the file to the outside world (the outside world being a containing swift module or whatever implicit module compilation context is created for use in playground runtime). Syntax could be defined to allow parameters to the function to be specified with an alternate syntax which required a name and default value to be supplied for all parameters -- this would ensure the function could be invoked in an interactive context without having to specify any external details -- say something like this:
In SomeFile.swiftscript
// exposes func SomeScript(someParam: String="defaultValue") { print("Do Something with \(someParam)" }
// if compiler support is added to infer the parameter name and type
let someParam = receiveParameter("defaultValue")
// or it could be more explicit ...
let someParam = receiveParameter(someParam: "defaultValue")
...
print("Do Something with \(someParam)!")
Return values could also be supported ...
This idea or something like it could help clarify what playground functionality actually is and might help establish a vision for the future ...:
(1) allow one to easily take a simple concept prototyped in a playground into a parameterized piece of reusable functionality - while still being able to drop back into the prototyping environment when desired
(2) re-interpreting playgrounds as an environment for invoking a specially instrumented function call could make it reasonable to support making this functionality 're-targetable' to any function within a project rather than only applying to playground bundles. It would be an awesome future if 'playground' became a re-targetable feature more like a debugger where one could provide parameters and 'invoke' any compatible function in a project in a 'playground mode' that allowed you to interactively develop the body ...