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

You cannot declare namespace in script code #1078

Closed
bchavez opened this issue Aug 10, 2015 · 13 comments

Comments

@bchavez
Copy link

commented Aug 10, 2015

Consider the following:

Hello.cs

namespace Foo{
    public class Bar{
        public void SayHello(){
          Console.WriteLine("Hello World");
        }
    }
}

var b = new Foo.Bar();
b.SayHello();
R:\>scriptcs Hello.cs
ERROR: Script compilation failed. [CompilationErrorException] R:\Hello.cs(2,1): error CS7021: You cannot declare namespace in script code

I think scriptcs should work with a uses case like this. Digging deeper seems seems like it's a limitation of the Roslyn compiler?

Thanks,
Brian

@khellang

This comment has been minimized.

Copy link
Member

commented Aug 10, 2015

Yeah, this is a limitation with the current scripting engine (from the September 2012 CTP). This might be gone once we merge #1064. I'm not really up to date on whether the newer bits allow this.

@filipw

This comment has been minimized.

Copy link
Member

commented Aug 10, 2015

All C# scripts use global namespace - this has been part of C# scripting design from the get go, as they get packaged into a Script wrapper class.

It was also defined in the scripting specification, so wouldn't necessarily call it a limitation.

@filipw filipw closed this Aug 10, 2015
@khellang

This comment has been minimized.

Copy link
Member

commented Aug 10, 2015

If this is not a limitation compared to proper C#, I don't know what is... 😄

@adamralph adamralph added the question label Aug 10, 2015
@filipw

This comment has been minimized.

Copy link
Member

commented Aug 10, 2015

it's different semantics, not limitation. Just like lack of global variables or methods is not a limitation of standard C# when compared to scripted code.

@glennblock

This comment has been minimized.

Copy link
Member

commented Aug 10, 2015

Yup. Namespaces are not allowed within classes in C# period today. In the
scripting world you are always running within a wrapper class.

On Mon, Aug 10, 2015 at 2:30 PM Filip W notifications@github.com wrote:

it's different semantics, not limitation. Just like lack of global
variables or methods is not a limitation of standard C# when compared to
scripted code.


Reply to this email directly or view it on GitHub
#1078 (comment).

@bchavez

This comment has been minimized.

Copy link
Author

commented Aug 11, 2015

Well, that's frustrating. Honestly, @filipw @glennblock I think that's a bad idea. Are we really going to have different behaviors for different types of C#?

You can do X in regular C# but can't do that in a scripted version of C#; which on it's face, should work...

These are the types of conversations we are going to be having when we have two types of runnable C# code, scripted or otherwise. Honestly, this can't be good in the long term.

In an ideal world, there should not be any impedance mismatch between the two, (regular?) C# and (scripted?) C#. I respectfully disagree _this is_ a limitation, not one of semantics. C# _is_ C#.

Directives like #load are an understandable design decision for a scripted version of C#.

Anytime I run into issues like this I'm reminded of my quotes from Krzysztof Cwalina & Brad Adams. Emphasis added, but this quote from Framework Design Guidelines applies to so much more than just frameworks.

1.1.7 Well-Designed Frameworks Are _Consistent_

_Consistency is a key_ characteristic of a well designed framework. It is one of the most important factors affecting productivity. A consistent framework allows for transfer of knowledge between parts of the framework that a developer knows to parts that the developer is trying to learn. Consistency also helps developers quickly recognize which parts of the design are truly unique to a particular feature area and so require special attention, and which are just the same old common design patterns and idioms.

👍

@glennblock

This comment has been minimized.

Copy link
Member

commented Aug 11, 2015

@bchavez I don't disagree that it is not ideal, though I understand the reasoning. This is a constraint of C# that is popping it's head due to the way Roslyn does its compilation. I believe Mono has the same constraint. Either way, it is not a constraint set by scriptcs itself.

@glennblock

This comment has been minimized.

Copy link
Member

commented Aug 11, 2015

@bchavez thinking outside of the context of scripting, I don't see the constraint of namespaces being outside of a class as being problematic.

For example

namespace Foo {
  public class Outer {
    namespace Bar {
      public class Inner {
      } 
    }
  }
}

To refer to inner, I it feels natural (to me) to use Foo.Outer.Inner. I can't see a good reason why I'd need a namespace at the inner class level as in general I shouldn't have many inner classes.

The next question becomes why the wrapper class for scripting? The main answer to that is that the CLR requires a type. It would be big change to the CLR to introduce loose members that have no type associated. The wrapping is what enables the loose functions / members we all know and love that scriptcs provides. It solves a whole bunch of problems though it does result in some weirdness.

Thanks to the fact you can still have inner classes you can get pretty close, though not perfect.

For example I can have a classFoo with a Bar class within, thus I can refer to static methods in Bar AS in a similar fashion to if they were a namespace, though they are not.

public class Foo {
  public class Bar {
    public static void DoSomething() {
    }
  }
}

Foo.Bar.DoSomething();

Anyway all and all, I think the value of having a loose / classless experience outweighs the value of inner namespaces, though they would certainly be nice to have.

@bchavez

This comment has been minimized.

Copy link
Author

commented Aug 11, 2015

Hi @glennblock, well, from my perspective, this (Roslyn implementation detail?) effectively blocks us from borrowing and reusing .cs files. For argument's sake, let's guesstimate 99% of the C# code in the wild lives under a namespace (reasonable assumption I hope) ... then why not work with 99% of c# code out of the box?

What we've done here is effectively force devs to strip out namespaces if they want to reuse any existing C# files (IE: POCOs, domain objects, utility classes, helpers). We now have two copies of implementations to maintain (with namespaces and without namespaces)

The discontinuity here is painfully obvious if C# classes written inside a .csproj can't be reused individually outside the scope of the standard compiler/IDE (ie: scriptcs).

@glennblock , I'm not sure I follow your example (or perhaps maybe it's way over my head) but your example has a namespace inside a class. As far as I know using namespaces inside classes have always been invalid since C#'s inception. I'm not aware of any C# compiler that would consume your example. It would be inconsistent otherwise?

I'm not so much advocating changes to the C# language itself (namespaces inside classes). Rather, I'm advocating for valid compile-able C# code (as it stands today) to be considered just as legitimate code inside a scripting context. The latter case would be considered consistent in the grand scheme of things.

@khellang

This comment has been minimized.

Copy link
Member

commented Aug 11, 2015

@bchavez I suggest you open an issues in the Roslyn repo (if it doesn't already exist) and link back here so we can get the discussion going at the right place.

@bchavez

This comment has been minimized.

Copy link
Author

commented Aug 11, 2015

Thanks everyone for the input; as suggested, I've opened a new issue in Roslyn: dotnet/roslyn#4478

@adamralph

This comment has been minimized.

Copy link
Contributor

commented Aug 11, 2015

Whilst I sympathise, and largely agree, with @bchavez, there are tough implementation problems such as those called out @glennblock. I'll chime in on the Roslyn issue.

@glennblock

This comment has been minimized.

Copy link
Member

commented Aug 11, 2015

@bchavez my namespace example was for illustration. The second example
using static classes was to show how you can achieve a similar experience.

As to your point, Rosyln itself does support full classes and namespaces.
The only place it does not today is for scripting.

In practice it has not been much of an issue as scriptcs supports dlls and
packages. So you can take any class (well almost any), compile it to a dll
and use it from your script.

What you cannot do is simply #load an existing class. Yes I agree that
would be nice, but not having it has not been a big impediment (at least so
far)
On Tue, Aug 11, 2015 at 4:58 AM Adam Ralph notifications@github.com wrote:

Whilst I sympathise, and largely agree, with @bchavez
https://github.com/bchavez, there are tough implementation problems
such as those called out @glennblock https://github.com/glennblock.
I'll chime in on the Roslyn issue.


Reply to this email directly or view it on GitHub
#1078 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.