我正在寻找各种方法来支持动态类型语言的某种级别的智能感知。由于智能感知信息是基于类型信息,因此在动态语言中实现这一点存在固有的困难。
你知道实现它的算法或方法吗?
答案 0 :(得分:7)
您需要编写一个抽象解释器,它使用类型值执行代码。因此,您通过AST逐步使用抽象解释器,并为每个变量记录已发送的消息或已知类型。当你完成后,你使用结构类型等价(也就是鸭子打字)来推断可能的类型。
PS: 除了类型推断之外,您可能需要查看"How Program History Can Improve Code Completion" by Romain Robbes,解释了如何使用最近的动态语言进一步改善自动完成功能使用过的信息和协作过滤。
所以这就是抽象解释如何适用于像
这样的代码片段def groups(array,&block)
groups = Hash.new
array.each { |ea|
key = block.call(ea)
groups[key] = [] unless groups.include? key
groups[key] << ea
}
return groups
end
你会从
开始array = { :messages => [], :types => [] }
block = { :messages => [], :types => [] }
然后
array = { :messages => [], :types => [] }
block = { :messages => [], :types => [] }
groups = { :messages => [], :types => [Hash] }
然后
array = { :messages => [:each], :types => [] }
block = { :messages => [], :types => [] }
groups = { :messages => [], :types => [Hash] }
然后
array = { :messages => [:each], :types => [] }
block = { :messages => [:call], :types => [] }
groups = { :messages => [], :types => [Hash] }
key = { :messages => [], :types => [] }
然后
array = { :messages => [:each], :types => [] }
block = { :messages => [:call], :types => [] }
groups = { :messages => [:include?,:[]], :types => [Hash] }
group_elements = { :messages => [], :types => [Array] }
key = { :messages => [], :types => [] }
然后
array = { :messages => [:each], :types => [] }
block = { :messages => [:call], :types => [] }
groups = { :messages => [:include?,:[]], :types => [Hash] }
group_elements = { :messages => [:<<], :types => [Array] }
key = { :messages => [], :types => [] }
所以最终我们可以推断出
array
可能是Enumerable
block
可能是Proc
groups
是Hash
Array
元素key
是任何对象答案 1 :(得分:1)
我会为eclipse下载Groovy plugin的来源,它有智能感知(尽可能多),并且认为Groovy是动态类型的动态语言的好样本
答案 2 :(得分:0)
很简单,只需添加一个额外步骤 - type inference。之后,您知道类型信息,并可以向用户提出建议。
答案 3 :(得分:0)
请注意,“动态语言”和“动态类型语言”不一定是相同的。
Microsoft在智能感知系统(VS2008)中处理此问题的方式是,它尽可能地推断出var当前所处的类型。如果/当此更改时,对var的引用将显示更新类型的选项。