Возврат Tcl по сравнению с последней оценкой в ​​proc — внутренние функции

Когда я пишу процедуру на Tcl, возвращаемое значение которой на самом деле является результатом другой процедуры, я могу сделать одно из следующих действий (см. неявный пример):

proc foo args {
...
...
bar $var1
}

Или я мог бы сделать (см. явный пример):

proc foo args {
...
...
return [ bar var1 ]
}

С точки зрения интерфейса, то есть ввода и вывода, они идентичны. Есть ли они внутри?
Или есть какое-то дополнительное преимущество в неявном возврате по сравнению с явным? Спасибо.


person user1134991    schedule 06.05.2015    source источник


Ответы (1)


В Tcl 8.6 вы можете проверить байт-код, чтобы сравнить такие процедуры.

Если мы определим пару реализаций 'sum', а затем проверим их с помощью tcl::unsupported::disassemble, мы увидим, что использование оператора return приводит к одному и тому же байт-коду.

% proc sum_a {lhs rhs} {expr {$lhs + $rhs}}
% proc sum_b {lhs rhs} {return [expr {$lhs + $rhs}]}

% ::tcl::unsupported::disassemble proc sum_a
ByteCode 0x03C5E8E8, refCt 1, epoch 15, interp 0x01F68CE0 (epoch 15)
  Source "expr {$lhs + $rhs}"
  Cmds 1, src 18, inst 6, litObjs 0, aux 0, stkDepth 2, code/src 0.00
  Proc 0x03CC33C0, refCt 1, args 2, compiled locals 2
      slot 0, scalar, arg, "lhs"
      slot 1, scalar, arg, "rhs"
  Commands 1:
      1: pc 0-4, src 0-17
  Command 1: "expr {$lhs + $rhs}"
    (0) loadScalar1 %v0     # var "lhs"
    (2) loadScalar1 %v1     # var "rhs"
    (4) add 
    (5) done 

% ::tcl::unsupported::disassemble proc sum_b
ByteCode 0x03CAD140, refCt 1, epoch 15, interp 0x01F68CE0 (epoch 15)
  Source "return [expr {$lhs + $rhs}]"
  Cmds 2, src 27, inst 6, litObjs 0, aux 0, stkDepth 2, code/src 0.00
  Proc 0x03CC4B80, refCt 1, args 2, compiled locals 2
      slot 0, scalar, arg, "lhs"
      slot 1, scalar, arg, "rhs"
  Commands 2:
      1: pc 0-5, src 0-26        2: pc 0-4, src 8-25
  Command 1: "return [expr {$lhs + $rhs}]"
  Command 2: "expr {$lhs + $rhs}"
    (0) loadScalar1 %v0     # var "lhs"
    (2) loadScalar1 %v1     # var "rhs"
    (4) add 
    (5) done 

Оператор return на самом деле просто документирует, что вы намеревались вернуть это значение, и это не просто побочный эффект. Использование return не обязательно, но, на мой взгляд, рекомендуется.

person patthoyts    schedule 06.05.2015
comment
Я использую Tcl 8.5. Но я предполагаю, что это одно и то же. Спасибо! - person user1134991; 06.05.2015
comment
disassemble тоже есть в 8.5. Байт-код практически такой же; в 8.6 есть несколько дополнительных оптимизаций, но они незначительны. - person Donal Fellows; 07.05.2015