深/浅约束力(练习)动态/静态范围 [英] Dynamic/Static scope with Deep/Shallow binding (exercises)

查看:329
本文介绍了深/浅约束力(练习)动态/静态范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我学习动态/静态的范围与深/浅绑定和运行code手动,以了解这些不同的范围/绑定的实际工作。我读理论和GOOGLE了一些示例练习,我发现那些都是很简单(如<一个href=\"http://stackoverflow.com/questions/1753186/dynamic-scoping-deep-binding-vs-shallow-binding\">this 之一这与动态作用域非常有帮助),但我无法理解如何范围静态工作。

I'm studying dynamic/static scope with deep/shallow binding and running code manually to see how these different scopes/bindings actually work. I read the theory and googled some example exercises and the ones I found are very simple (like this one which was very helpful with dynamic scoping) But I'm having trouble understanding how static scope works.

下面我发布一个锻炼我做了检查,如果我得到了正确的解决方案:

Here I post an exercise I did to check if I got the right solution:

考虑写在伪code下面的程序:

considering the following program written in pseudocode:

int u = 42; 
int v = 69;
int w = 17;
proc add( z:int )
  u := v + u + z
proc bar( fun:proc )
  int u := w;
  fun(v)
proc foo( x:int, w:int )
  int v := x;
  bar(add)
main
  foo(u,13)
  print(u)
end;

什么是打印到屏幕

What is printed to screen

a)使用静态的范围是什么?答案= 180

a) using static scope? answer=180

b)使用动态范围和深度的结合?答案= 69(总和U = 126,但它的富的地方V,对吧?)

b) using dynamic scope and deep binding? answer=69 (sum for u = 126 but it's foo's local v, right?)

C)使用动态范围和浅约束力?答案= 69(总和U = 101,但它的富的地方V,对吧?)

c) using dynamic scope and shallow binding? answer=69 (sum for u = 101 but it's foo's local v, right?)

PS:我想练习做一些练习这样的,如果你知道我在哪里可以找到这些类型的问题(preferable的解决方案)请给链接,谢谢

PS: I'm trying to practice doing some exercises like this if you know where I can find these types of problems (preferable with solutions) please give the link, thanks!

推荐答案

您的答案词汇(静态)范围内是正确的。您的动态范围,答案是错的,但如果我读你的解释正确的,那是因为你得到了 U 之间的混淆和 v ,而不是因为有关如何深与浅的结合工作,任何真正的误解。 (我假设你的 U / v 混乱只是偶然的,而不是由于对价值观混乱得令人不可思议与在调用引用。)

Your answer for lexical (static) scope is correct. Your answers for dynamic scope are wrong, but if I'm reading your explanations right, it's because you got confused between u and v, rather than because of any real misunderstanding about how deep and shallow binding work. (I'm assuming that your u/v confusion was just accidental, and not due to a strange confusion about values vs. references in the call to foo.)

a)使用静态的范围是什么?答案= 180

a) using static scope? answer=180

正确的。

b)使用动态范围和深度的结合?答案= 69(总和U = 126,但它的富的地方V,对吧?)

b) using dynamic scope and deep binding? answer=69 (sum for u = 126 but it's foo's local v, right?)

您括号中的解释是正确的,但你的答案是错的: U 确实设置为 126 确实本地化 v ,但由于打印 U ,而不是 v ,答案是 126

Your parenthetical explanation is right, but your answer is wrong: u is indeed set to 126, and foo indeed localizes v, but since main prints u, not v, the answer is 126.

C)使用动态范围和浅约束力?答案= 69(总和U = 101,但它的富的地方V,对吧?)

c) using dynamic scope and shallow binding? answer=69 (sum for u = 101 but it's foo's local v, right?)

有关的总和 U 其实就是 97 42 + 13 + 42 ),但由于本地化 U ,答案是 42 。 (你的括号解释是错误的,这一个选项,您似乎已经使用了全局变量是W ,这是 17 在跨preting声明 INT U:= W 的定义;但实际上该声明是指的局部变量是W ,它的第二个参数,它是 13 。但是,这实际上并不影响答案。您的答案是错的这一个,只是因为打印 U ,而不是 v

The sum for u is actually 97 (42+13+42), but since bar localizes u, the answer is 42. (Your parenthetical explanation is wrong for this one — you seem to have used the global variable w, which is 17, in interpreting the statement int u := w in the definition of bar; but that statement actually refers to foo's local variable w, its second parameter, which is 13. But that doesn't actually affect the answer. Your answer is wrong for this one only because main prints u, not v.)

有关词法范围,这是pretty容易通过翻译伪code与词法范围的语言来检查你的答案。同样的动态范围与浅的结合。 (事实上​​,如果你使用Perl,你几乎可以在一次测试两种方式,因为它同时支持;只需使用我的词法范围,然后做一个发现 - 和 - 取代将其更改为本地的动态范围。但是,即使你使用,也就是说,JavaScript的词法范围和Bash动态范围,它应该是快速测试两个)。

For lexical scope, it's pretty easy to check your answers by translating the pseudo-code into a language with lexical scope. Likewise dynamic scope with shallow binding. (In fact, if you use Perl, you can test both ways almost at once, since it supports both; just use my for lexical scope, then do a find-and-replace to change it to local for dynamic scope. But even if you use, say, JavaScript for lexical scope and Bash for dynamic scope, it should be quick to test both.)

深约束力的动态范围是非常棘手的,因为很少有广泛部署的语言都支持它。如果你使用Perl,您可以通过使用从可变名称映射到标量裁判的哈希(关联数组),并通过该散列函数从运作手动实现它。到处是伪code声明了一个局部变量,你保存在一个Perl的词法变量现有的标量的参考,然后把哈希新的映射;并在函数结束时,你恢复原来的标量的参考。为了支持绑定,您创建一个用于创建哈希值的副本,并通过的的其包装功能的包装函数。这里是一个动态范围的,深深的结合你的Perl程序的执行,使用方法:

Dynamic scope with deep binding is much trickier, since few widely-deployed languages support it. If you use Perl, you can implement it manually by using a hash (an associative array) that maps from variable-names to scalar-refs, and passing this hash from function to function. Everywhere that the pseudocode declares a local variable, you save the existing scalar-reference in a Perl lexical variable, then put the new mapping in the hash; and at the end of the function, you restore the original scalar-reference. To support the binding, you create a wrapper function that creates a copy of the hash, and passes that to its wrapped function. Here is a dynamically-scoped, deeply-binding implementation of your program in Perl, using that approach:

#!/usr/bin/perl -w

use warnings;
use strict;

# Create a new scalar, initialize it to the specified value,
# and return a reference to it:
sub new_scalar($)
  { return \(shift); }

# Bind the specified procedure to the specified environment:
sub bind_proc(\%$)
{
  my $V = { %{+shift} };
  my $f = shift;
  return sub { $f->($V, @_); };
}

my $V = {};

$V->{u} = new_scalar 42; # int u := 42
$V->{v} = new_scalar 69; # int v := 69
$V->{w} = new_scalar 17; # int w := 17

sub add(\%$)
{
  my $V = shift;
  my $z = $V->{z};                     # save existing z
  $V->{z} = new_scalar shift;          # create & initialize new z
  ${$V->{u}} = ${$V->{v}} + ${$V->{u}} + ${$V->{z}};
  $V->{z} = $z;                        # restore old z
}

sub bar(\%$)
{
  my $V = shift;
  my $fun = shift;
  my $u = $V->{u};                     # save existing u
  $V->{u} = new_scalar ${$V->{w}};     # create & initialize new u
  $fun->(${$V->{v}});
  $V->{u} = $u;                        # restore old u
}

sub foo(\%$$)
{
  my $V = shift;
  my $x = $V->{x};                     # save existing x
  $V->{x} = new_scalar shift;          # create & initialize new x
  my $w = $V->{w};                     # save existing w
  $V->{w} = new_scalar shift;          # create & initialize new w
  my $v = $V->{v};                     # save existing v
  $V->{v} = new_scalar ${$V->{x}};     # create & initialize new v
  bar %$V, bind_proc %$V, \&add;
  $V->{v} = $v;                        # restore old v
  $V->{w} = $w;                        # restore old w
  $V->{x} = $x;                        # restore old x
}

foo %$V, ${$V->{u}}, 13;
print "${$V->{u}}\n";

__END__

和事实上它打印 126 。这显然​​是混乱的,容易出错,但它也确实能帮助你了解这是怎么回事,所以对教育目的,我认为这是值得的!

and indeed it prints 126. It's obviously messy and error-prone, but it also really helps you understand what's going on, so for educational purposes I think it's worth it!

这篇关于深/浅约束力(练习)动态/静态范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆