Динамически -глубокое связывание и глубокое связывание - PullRequest
1 голос
/ 24 февраля 2012

Я работаю над этой проблемой, и я получил ответы:

Статически: 13

Динамически-глубокая привязка: 2 <- я не уверен насчет этого </p>

Динамически-мелкое связывание: 2 <- я не уверен насчет этого </p>

это правильно?

Рассмотрим программу ниже (на языке, подобном Паскалю). Каков выход язык статически ограничен? Какой вывод языка динамически ограничен а использует глубокую привязку? Какой вывод языка динамически ограничен и использует поверхностное связывание?

Program main;
   x: integer := 2;
   y: integer := 1;
procedure f3(z: integer)
   begin 
       x = z + x + y;
   end
procedure f2(p: procedure, z: integer)
     int x := 5;
   begin
              p(z) 
   end
procedure f1(z: integer)
      int y := z
   begin
     f2(f3,y);
  end

begin /* main program */
f1(4);
       print(x)
end

1 Ответ

1 голос
/ 24 февраля 2012

Для случаев статической области и динамической области с мелкой привязкой, почему бы не попробовать их? Использование Perl со статической областью действия:

my $x = 2;
my $y = 1;
sub f3($) {
  my $z = shift;
  $x = $z + $x + $y;
}
sub f2($$) {
  my ($p, $z) = @_;
  my $x = 5;
  $p->($z);
}
sub f1($) {
  my $z = shift;
  my $y = $z;
  f2(\&f3, $y);
}
f1(4);
print "$x\n";

Я получаю 7 (что составляет 4 + 2 + 1). Изменяя my s на local s, чтобы получить динамическую область с мелкой привязкой, я получаю 2, как вы и предсказывали.

Тестирование динамического контекста с глубоким связыванием сложнее, потому что так мало языков поддерживают его. В этот ответ некоторое время назад я опубликовал код Perl, который реализовал глубокое связывание «вручную», передавая хэш ссылок на скаляры; используя тот же подход:

#!/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->{x} = new_scalar 2;
$V->{y} = new_scalar 1;

sub f3(\%$) {
  my $V = shift;
  my $z = $V->{z};                 # save existing z
  $V->{z} = new_scalar shift;      # create & initialize new z
  ${$V->{x}} = ${$V->{z}} + ${$V->{x}} + ${$V->{y}};
  $V->{z} = $z;                    # restore old z
}
sub f2(\%$$) {
  my $V = shift;
  my $p = shift;
  my $z = $V->{z};                 # save existing z
  $V->{z} = new_scalar shift;      # create & initialize new z
  my $x = $V->{x};                 # save existing x
  $V->{x} = new_scalar 5;          # create & initialize new x
  $p->(${$V->{z}});
  $V->{x} = $x;                    # restore old x
  $V->{z} = $z;                    # restore old z
}
sub f1(\%$) {
  my $V = shift;
  my $z = $V->{z};                 # save existing z
  $V->{z} = new_scalar shift;      # create & initialize new z
  my $y = $V->{y};                 # save existing y
  $V->{y} = new_scalar ${$V->{z}}; # create & initialize new y
  f2(%$V, bind_proc(%$V, \&f3), ${$V->{y}});
  $V->{y} = $y;                    # restore old y
  $V->{z} = $z;                    # restore old z
}
f1(%$V, 4);
print "${$V->{x}}\n";

__END__

Я получаю 10 (то есть 4 + 2 + 4).

...