-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Interactive Design Meeting 4/17/15 #2167
Comments
Haha, I'm reminded of javscript. Are we going to need to bring over ES6 modules ;-)? |
@RichiCoder1 No. We've had much better solution in C# since the beginning - block scopes and classes. |
Nice work guys. I really like the revised
|
If
I'm also curious about return values of submissions 😄 |
|
Great stuff, it is exciting to see this convo happening in such a transparent fashion! Comments....
i.e. //visible to the caller
export void DoSomething() {
...
}
//not visible
var foo; |
I ❤️ that your muscle memory makes you write scriptcs when you really want to write scripts 😉 |
LOL! so true! |
@khellang aren't they synonymous? #ducks |
Ah yes, I also made a note to suggest #export instead of #import but forgot to mention it. |
Agree with #export rather than #import based on the given definition:
Calling it #import makes it seem like it should do the same thing as #load. |
@adamralph We are still working through implementation details on this (tbc in future notes)! |
Was more referring to #import and #export. Very reminicient of ES6's modules proposal. Javascript rough equivalents would look like: #load Start from "b"
var x = 1;
//I can use my wrapper variable Stark to access b.csx's 'x' without error
var z = Stark.x; #load Stark from "b"
#load "c"
var x = 1;
//These will reference the same 'x' as opposed to creating multiple instances of 'x'
var z = Stark.x;
var w = Lannister.x; and to build on @glennblock's example //visible to the caller
export void DoSomething() {
...
}
//not visible
var foo; which might be also: //visible to the caller
void DoSomething() {
...
}
//not visible
var foo;
#export { DoSomething } // This would probably choke on overloads |
I think the F# approach (pretty much what's mentioned in the issue) is nice:
So top-level variables etc. will be public by default, but you can specify |
Regarding I'm also in favor of explicit exports. That way producers of scripts don't need to be worried with polluting the caller script and the caller script doesn't need to be aware of the loaded script - just the public façade. It was not clear to me if the package author needs to author a script for each supported language or if C# scripts can import VB scripts and vice versa. |
@paulomorgado #import does not export. It imports the members of the target namespace or type into the current scope, just like using does. The only difference is that the scope is the compilation not the file. Very much like VB project-level imports. |
That's what I had understood before and was confused now. Nevertheless, it makes sense to me to export only what I want to export. And in that sense, it might make sense to export those namespaces instead of importing them into the compilation. In the end, it's the same thing looked at from different perspectives. |
Regarding Is it the UI thread? Can one create forms and interact with them? Is there any type of synchronization context? Since this is an interactive environment, if the task is not completed, the user could be questioned on what to do. (a)wait or continue. If the user chooses not to (a)wait, then the whole line will be "ignored". |
Another thing we discussed in our regular scriptcs core team meeting recently was multi-language capability. I.e. a way for host to allow: // a.csx
#load b.vbx into Foo This would require resolution from a file name extension to a language specific implementation, unless some other language feature were introduced to allow specification of the language implementation in code.
|
Or have a convention on the first line of the script file to specify the scripting engine. Or have an argument to |
That was what I had in mind with the 'language feature' suggestion. I can't really think of an elegant way of doing it though. |
We don't plan on supporting multiple languages in a single script. Note that |
I understand that that is the case with a plain old fashioned |
@adamralph Correct me if I'm wrong, but I don't think you can import Ruby script from Python and vice versa (unless of course on DLR :)) |
@tmat I asked for an explanation of the 'wrapper identifier' some time ago (#2167 (comment)) but no-one has answered yet. The Ruby/Python case is completely different. Those are two distinct runtimes. In the .NET case we are dealing with a single runtime but multiple languages, a design tenet of .NET from day one. This is illustrated by C# and VB and has encouraged a huge number of other language implementations. For scriptcs we already have several other language engines, some serious (e.g. https://github.com/scriptcs-contrib/scriptcs-fsharp) and some fun (e.g. https://github.com/filipw/ScriptCs.Engine.Brainfuck). I'm not suggesting that the scripting runtime necessarily needs to support this out of the box, but it would be of enormous benefit if we could hook into the language services (i.e. |
@adamralph I'm confused, Yes, .NET is a single runtime and the common target for languages is IL/metadata and common type system. We don't support creating projects that mix languages because that requires that a) the languages involved have semantically similar top-level declarations that mix well with each other b) there is a common interfaces for all compilers thru which they can cooperate. That doesn't mean you can't interop between scripts written in different languages. The means for interoperability are going to be metadata references. The current extensibility enables host to interpret the content of This is different from |
If you are pre-appending, this will mean all references will be Ie if I have Foo() and Bar() and Foo calls Bar and is loaded into Baz then One thing I dislike about this that the wrapper brings is automatic Glenn
|
@glennblock Yes. '.' is valid in metadata member name. We can also mangle the metadata name arbitrarily if needed. Correct, top-level variables are also accessible thru dotted name. There are several options how to make them truly local to the script - declare them in a block, method, class, lambda, etc. |
@glennblock If the above options for script variable encapsulation turn out to be insufficient we can add another one (e.g. some modifier). For now we think they are good enough. |
Thanks. The lack of encapsulation may not be an issue as if one needs to
|
Class, lambda etc
|
@tmat thanks for the info. I hope you understand why some explanation was/is still required. The comment history shows I'm not the only one who requires it. 😉 I still don't understand how this is going to work. Although Foo\u002EBar(); |
@adamralph The name in source does not necessarily need to be the same as metadata name. In source you'll refer to it as Foo.Bar(); in metadata it will be a method |
But I can't write |
@admaralph they own the compiler, they can make it do whatever they want.
|
@glennblock, just because they can, doesn't mean they should. I can understand avoiding the collision of a But if the collision would exist, then a name collision will still exist. Given a s.csx script file with:
loaded with:
and a class:
which one would |
@paulomorgado You'd get an error that X has already been declared at the declaration of class X. |
Joking aside, I did wonder if a new language feature was being proposed here. I can't imagine that allowing Indeed, from the original proposal above:
//I can use my wrapper variable Stark to access b.csx's 'x' without error
var z = Stark.x; Wrapper identifier, wrapper variable - what is this thing? Assuming the compiler isn't going to allow
|
@tmat, the class X could have been declare before. But that would only result in a different error. I'm still missing the point of not having a wrapper class instead. |
Agreed the identifier gives me an uneasy feeling / feels a big hacky. |
Closing out. We don't need active issues for meeting nodes. |
Interactive Design Meeting 4/17/15
Design Team
The following individuals are members of the dream team:
Anthony D. Green
Chuck Stoner
Dustin Campbell
Kasey Uhlenhuth
Kevin Halverson
Kevin Pilch-Bisson
Lincoln Atkinson
Manish Jayaswal
Matt Warren
Tomas Matousek
Special Guests
Mads Torgersen
Agenda: Async/await, scripting scenarios continued
The purpose of this meeting was to clarify an async/await design issue for our Interactive team as well as continuing our discussion on scripting scenarios from the last couple weeks.
Quotes of the Day
Async/Await in the REPL
Previously, we discussed that a user would not get the next prompt in the REPL while awaiting a Task. There was no technical reason why we couldn't let a user continuing typing, we just thought that it would fit the mental model of a REPL best if we used this design.
However, what if a user types an
await
, decides it's taking too long to complete, and tries to cancel the process? Currently, typingCtrl+C
actually kills the entire process, causing the user to lose all his previous context. There may be some solution around allowing a user to add a Cancellation Token as an argument, but we have decided to not prioritize this scenario right now (we'd rather have functional use of async/await and launch Interactive than wait to release until get this design right).Scripting Scenarios continued...
init.csx file
In the last meeting we discussed allowing NuGet authors to include a
init.csx
file that could set up references and usings as well as provide some initialization code. However, we realized that our proposed method would require each init.csx-esque file to be language-specific. To remedy the pain of an author having to write 3 different scripts for C#, F#, and VB, we decided to tweak our design. NuGets can have a language-agnostic script (we will call itinit.x
for now) which will only contain references and usings. Authors can then additionally choose to write some initialization code in aninit.csx
,init.fsx
, orinit.vbx
script. A developer's script will ignore#load
-ed init scripts that are of a different language.If a NuGet only has a C# init script (or no script at all), other authors can create separate NuGet packages that
#load
the C#-based NuGet and write their owninit.vbx
orinit.fsx
script to set up initialization code.#u global directive
In our last notes there seemed to be some general confusion around the global directive
#u
. We started off by taking another look at our solution and we've made some changes:To avoid having a different directive in every language, we are changing the name of
#u
to#import
. It's use it also more intuitive this way.The purpose of the
#import
directive is to allow script and NuGet authors to "export" usings. For example,This is especially helpful if a NuGet (e.g., WPF) has a lot of usings that will be difficult for users to remember and manually add at the top of each script.
public by default
We readdressed an old issue of whether or not everything in a script should be treated as
public
. Doing this allows users to#load
scripts and directly access all the classes and variables. However, this means any 'temporary' variables a script author created to generate context will litter a developer's IntelliSense if he#load
-ed that script.We discussed several workarounds for this (e.g., placing temporary variables in a block, prefixing temporary variables with "_", allowing
private
), but in the end decided that this is not a top priority scenario at this time. Should problems come up in the future, we will revisit this problem. For now, using blocks to limit the scope of temp variables seems to be a good enough solution.'into' keyword
A user can use the keyword
into
if he wants to isolate things from each other or wants to "discover" methods from a#load
via IntelliSense.For example, a user can do
Instead of having
into
generate a "wrapper class," we think we should take the "wrapper identifier" provided by the user and essentially pre-pend it to every variable and class within the script. This would prevent creating a lot of duplicated code from arbitrary (transitive)#load
-ing. A side-effect of this design is that a variable can be accessed via multiple qualified names (but we decided this is better than having multiple instances of the same variable).These scenarios might help elucidate our design choices:
Scenario 1: Variable of the same name already declared (this will be an error)
Script a.csx
Script b.csx
Scenario 2: Resolve ambiguity with a wrapper identifier
Script a.csx
Script b.csx
Scenario 3: Access variable with nested dependency
Script a.csx
Script b.csx
Script c.csx
Scenario 4: Multiple access points to variable
Script a.csx
Script b.csx
Script c.csx
Scenario 5: Pre-pend wrapper identifiers to prevent duplication
Script a.csx
Script b.csx
Script c.csx
The text was updated successfully, but these errors were encountered: