是否有一种梦想语言能够融合动态类型和强类型的优点?

发布于 2024-07-25 20:19:53 字数 862 浏览 3 评论 0原文

我有兴趣学习一种在内部将对象作为哈希表(如 JavaScript)处理的语言,但可以用强类型包装它们,以在设计时提供代码完成/智能感知的好处。 这就是我希望这个梦想语言如何工作的方式:

public class Lion
{
  public void Roar() { Console.WriteLine("Aaarrgghh");}
} 

public static Main(string[] args)
{
  object myCat = new object(); // just plain object, no type!
  // adding a Roar() method to the myCat instance 
  myCat.Roar += delegate() {Console.WriteLine("Miauew");}
  // At this point myCat should qualify to be a Lion.
  // So we should be able to successfully duck-type-cast 
  // her to a lion
  Lion myLion = myCat as Lion;
  // now the myLion reference is strongly typed, 
  // so I expect the Intellisense window pop up 
  // and offer me the Roar() method when I hit the dot after "myLion"
  myLion.Roar();
}

我希望这个程序编译没有错误,运行没有异常并打印 控制台上的“Miauew”。 有没有一种语言可以做到这一点? 也许是 C#4.0?

I would be interested to learn a language that handles objects internally as hashtables (like JavaScript) but could wrap them with strong types to offer the benefits of code completion/intellisense in design time. Here is how I wish this dream language to work:

public class Lion
{
  public void Roar() { Console.WriteLine("Aaarrgghh");}
} 

public static Main(string[] args)
{
  object myCat = new object(); // just plain object, no type!
  // adding a Roar() method to the myCat instance 
  myCat.Roar += delegate() {Console.WriteLine("Miauew");}
  // At this point myCat should qualify to be a Lion.
  // So we should be able to successfully duck-type-cast 
  // her to a lion
  Lion myLion = myCat as Lion;
  // now the myLion reference is strongly typed, 
  // so I expect the Intellisense window pop up 
  // and offer me the Roar() method when I hit the dot after "myLion"
  myLion.Roar();
}

I wish this program to compile without error, run without exception and print
"Miauew" on the Console. Is there a language out there that can do this? Maybe C#4.0?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

や三分注定 2024-08-01 20:19:53

也许是 C# 4.0 中新的动态类型。
看看这个:http://blogs.msdn。 com/cburrows/archive/2008/10/27/c-dynamic.aspx

Maybe the new dynamic type in C# 4.0.
look at this: http://blogs.msdn.com/cburrows/archive/2008/10/27/c-dynamic.aspx

渡你暖光 2024-08-01 20:19:53

相反,这取决于您让 Lion 类型实现非虚拟方法的意图。

扩展类型(给定类型的对象集是那些具有该类型属性的对象,这接近于鸭子类型的静态等效项)要求对象的结构隐含其类型,但是您的 Lion type 没有结构 - 它只表示任何狮子都具有特定的 Roar 方法。 因此,对于你的例子,我看不出有什么方法可以让你的猫变成狮子,因为它不具有你所说的狮子所具有的唯一结构特性。

另一方面,如果您打算说您所说的任何狮子都可能有自己的 Roar 方法或将使用 Lion 中的方法,那么它并没有说明狮子对象的类型,并且 AFAIK 您可以获得与对象上的扩展方法具有相同的行为(尽管我对 C# 的了解不够,无法知道 self 方法是否覆盖 C# 中的扩展方法)。

在动态 IDE 中,在 IDE 可以计算出 myCat 具有 Roar 属性之前,您没有必要强制转换为 Lion - 该信息是静态可推导的。

在具有动态构造类型的语言(例如 JavaScript)中,IDE 支持很难的原因是您可以这样做:

let myCat = {}

if ( locale.name == 'en' )
    myCat.roar = function () { alert ( "Miauew" ); }
else
    mCat[ resources.getString( 'roar' ) ] = 
        function () { alert ( resources.getString ( 'Miauew' ) ); }


// the structure of the type of myCat depends what locale the code
// is running in, so you can't deduce the Intellisense
myCat.

这种情况当然意味着您无法预测代码是否会工作,而无需进行更深入的分析(例如,检查你的法国猫是否总是被要求用法语咆哮)。

如果 Intellisense 无法推断出其结构可静态推断的对象的结构,那么这就是 Intellisense 的弱点,而不是动态类型的弱点。

您认为在您的示例中强类型有什么好处?

It rather depends on what you intended by having the Lion type implement a non-virtual method.

Extension typing ( the set of objects which are of a given type are those which have the properties of the type, which is close to being a static equivalent of duck-typing ) requires that the structure of an object implies its type, but your Lion type has no structure - it only says that anything which is a lion has that particular Roar method. So for your example, I can't see any way you can cast your cat to be a Lion, since it doesn't have the only structural property you have said that Lions have.

If on the other hand you intended by saying that anything you say is a Lion may have either its own Roar method or will use the method in Lion, it's not saying anything about the type of objects which are Lions, and AFAIK you could get the same behaviour with an extension method on object ( though I don't know enough C# to know whether self methods override extension methods in C# ).

In a dynamic IDE, there's no reason that you need to cast to a Lion before the IDE can work out that myCat has a Roar property - that information is statically deducible.

The reason IDE support is hard in languages with dynamically constructed types, such as JavaScript, is that you can do this:

let myCat = {}

if ( locale.name == 'en' )
    myCat.roar = function () { alert ( "Miauew" ); }
else
    mCat[ resources.getString( 'roar' ) ] = 
        function () { alert ( resources.getString ( 'Miauew' ) ); }


// the structure of the type of myCat depends what locale the code
// is running in, so you can't deduce the Intellisense
myCat.

Such situations of course mean that you can't predict whether the code will work either, without much deeper analysis ( for example, checking that your French cat is always asked to roar in French ).

If Intellisense can't deduce the structure of objects whose structure is statically deducible, then that's a weakness in Intellisense, not of dynamic typing.

What would you consider the benefit of strong typing in your example?

凡尘雨 2024-08-01 20:19:53

每次我尝试策划此类事情时,问题都是演员阵容。 当然,您可以只相信程序员的话,但这结合了两种打字系统最糟糕的功能。 也许强制转换可以在运行时检查对象是否实现了 Lion 接口,但这基本上是不可能的。 在这种情况下,它看起来似乎是合理的,因为您所需要的只是 void (*)() 函数的存在。 但一般来说,如果 Lion 有一个 getHabitat 方法,该方法返回一个应该属于另一个接口的对象,该怎么办? 强类型语言需要能够确定它确实如此,但是如果没有实际调用该方法,您通常无法判断非类型代码是否返回栖息地,因此在强类型术语中您无法工作看看它是否是狮子。

因此,我从未解决过这样的问题:当混合弱类型和强类型的代码部分时,最终会得到强类型代码,该代码随时可能调用方法并返回未实现接口的对象应该如此。 这不是强类型,而是带有误导性代码注释的动态类型。

Every time I've tried to plan any such thing, the problem is the cast. Of course you can just take the programmer's word for it, but that combines the worst features of both typing systems. Maybe the cast could check at runtime whether an object implements the Lion interface, but that's basically impossible. In this case it looks plausible since all you need is the existence of a void (*)() function. But in general what if Lion has a getHabitat method that returns an object which is supposed to be of another interface? A strongly typed language needs to be able to say for sure that it really does, but without actually calling the method, you can't in general tell whether untyped code returns a Habitat, and hence in strong-typing terms you can't work out whether it's a Lion.

So I've never got past the problem that when mixing weak- and strong-typed sections of code, you end up with strongly-typed code that at any moment might call a method and get back an object that doesn't implement the interface it's supposed to. That's not strong typing, it's dynamic typing with misleading code comments.

蝶舞 2024-08-01 20:19:53

这是一个有趣的想法,并且之前已经被探索过。 在向您表达我的看法后,我将链接到一些研究和现有的工作。 我将讨论脚本语言和静态命令式语言,因为我认为这就是您正在谈论的内容。

根本问题是类型在静态和动态类型系统中的含义不同。 在动态系统中,类型是值的属性,当值被传递时,类型也是如此。 在静态系统中,您可以限制变量(等)可以保存的值的类型。 到目前为止,一切都很好。

动态语言中的静态类型

当您查看脚本语言中如何使用对象时,就会出现问题 - 它们都是鸭子类型的。 这意味着类型的名称(标称类型)没有用。 所有现代命令式语言(Java、C#、C++、C)都使用名义类型系统。 因此,在 C++ 中,您可能会说您期望一个 Duck,但在 Python 中,您确实想要一个 quack() 的东西。

因此,请考虑将静态类型添加到鸭子类型语言中。 由于函数会将参数传递给 quack(),但它不能说它期望 Duck,因此将两者结合起来很困难。 您可以定义一个名为 quacks 的接口,它可以 quack(),并将其用作类型。 但这确实有点冗长,这消除了动态类型的好处。 但也许,可能有一些类似的东西(某种结构类型系统)可以做吧。

另一种选择是只要求程序员指定 Duck,无论如何,该死的鸭子类型业务 - 没有人真正使用它,不是吗? 但如果你只是用 Python 编写 Java,作为曾经尝试过的人,让我告诉你,这会适得其反。

静态语言中的动态类型

所以让我们以另一种方式来看待它。 C# 将如何从 dynamic 关键字中受益? 简单的答案是不会。 老实说,我在 C# 的 dynamic 中看不到从 Python 获得的任何美丽和自由。 现在,我对它的唯一了解来自 Jon Skeet 的演讲,但我得到的压倒性印象是它冗长且不优雅。 我认为这不是 C# 人员的实现错误。 我认为这是因为 Python 中动态类型解决的问题已经在 C# 中解决了(尽管很冗长),而 dynamic 却没有带来任何好处。

研究静态/动态的东西

查阅Jeremy Siek 的渐进式打字的东西,它是关于最先进的静态的/那里的动态研究。 不过读起来有点困难,我自己也只是粗略地看了一下,所以无法总结。 不过,单独浏览一下他的相关工作还是很有趣的, STOP 会议 可能会有好东西。

Its an interesting idea, and one that has been explored before. I'll link to some research and existing work, after I give you my take. I'll talk about scripting languages and static imperative languages, since I think this is what you're talking about.

The fundamental problem is that types don't mean the same thing in static and dynamic type systems. In a dynamic system, a type is a property of a value, and as the value is passed around, so is the type. In a static system, you restrict the types of values which may be held by variables (etc). So far so good.

Static types in dynamic languages

The problem occurs when you look at how objects are used in scripting languages - they are all duck-typed. This means the name of the type (nominal-typing) isn't useful. All modern imperative languages (Java, C#, C++, C) use nominal type systems. So in C++ you might say you expect a Duck, but in Python you really want something that goes quack().

So consider adding static typing to a duck-typed language. Since a function will expact a parameter to quack(), but it can't say that it expects a Duck, combining the two is difficult. You might define an interface called quacks which can quack(), and use that as the type. But this is a tad verbose really, which kills the benefit of the dynamic typing. Perhaps though, there might be something along these lines (some kind of structural type system) which can do it.

An alternative would be to just require the programmer to specify Duck, and damn this duck-typing business anyway - no one really uses it do they? But then you're just writing Java in Python, and as someone who tried that once, let me tell you its very counter-productive.

Dynamic types in static languages

So lets look at it the other way. How will C# benefit from the dynamic keyword? The simple answer is that it won't. I honestly don't see any of the beauty and freedom that you get from Python in C#'s dynamic. Now, the only thing I know about it comes from a talk by Jon Skeet, but the overwhelming impression I got is that it's verbose and inelegant. And I think that's not an implementation error from the C# folk. I think its because the problems which dynamic typing solves in Python are already solved in C# (albeit verbosely), and dynamic just brings nothing to the party.

Research on static/dynamic stuff

Look up Jeremy Siek's gradual typing stuff, its about the most advanced static/dynamic research out there. Its a bit hard reading though, and I've only given it a cursory look myself, so I can't summarize it. However, its interesting to flick through his related work alone, and the STOP conference will probably have good stuff in it.

我是男神闪亮亮 2024-08-01 20:19:53

与您的示例关系不大,但 Scala 的 隐式转换 是一种经过深思熟虑(尽管有时很难遵循)的机制,以完全受控、静态检查的方式扩展类的功能。

另外,还有结构类型,它可以有时可以以类型安全的方式替代鸭子类型。

Not closely related to your example, but Scala's implicit conversion is a well thought-out (though sometimes hard to follow) mechanism to extend a functionality of a class in a completely controlled, statically checked way.

Also, there is structural typing which can sometimes be useful as a replacement for duck typing in a type-safe way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文