Dlaczego zwracanie / ponawianie oceny funkcji wynikowych w kontekście wywołującym, ale wyniki bloków nie są oceniane?

Ostatniej nocy dowiedziałem się o opcji / redo, kiedyreturn z funkcji. Pozwala ci wrócićinne funkcja, która jest następnie wywoływana w miejscu wywołania i ponownie wywołuje ewaluatora z tej samej pozycji

>> foo: func [a] [(print a) (return/redo (func [b] [print b + 10]))] 

>> foo "Hello" 10
Hello
20

Nawet jeślifoo jest funkcją, która przyjmuje tylko jeden argument, terazdziała jak funkcja, która miała dwa argumenty. Coś takiego wymagałoby w przeciwnym razie, aby dzwoniący wiedział, że zwracasz funkcję, a ten rozmówca musiałby ręcznie użyćdo ewaluator.

Tak więc bezreturn/redo, dostaniesz:

>> foo: func [a] [(print a) (return (func [b] [print b + 10]))] 

>> foo "Hello" 10
Hello
== 10

foo zużyła swój jeden parametr i zwróciła funkcję według wartości (która nie została wywołana, dlatego interpreter przeniósł się dalej). Następnie wyrażenie ocenia się na 10. Jeślireturn/redo nie istniałeś, musiałbyś napisać:

>> do foo "Hello" 10
Hello
20

Dzięki temu rozmówca nie musi znać (lub troszczyć się), czy wybrałeś zwrot funkcji do wykonania. I jest fajny, ponieważ możesz robić takie rzeczy, jak optymalizacja połączeń ogonowych lub pisanie opakowania dla samej funkcji powrotu. Oto wariantreturn który drukuje wiadomość, ale nadal wychodzi z funkcji i zapewnia wynik:

>> myreturn: func [] [(print "Leaving...") (return/redo :return)]

>> foo: func [num] [myreturn num + 10]

>> foo 10
Leaving...
== 20

Ale funkcje nie są jedyną rzeczą, która zachowuje siędo. Więc jeśli jest to ogólny wzór dla„usunięcie potrzeby DO w callsite”, więc dlaczego to nic nie drukuje?

>> test: func [] [return/redo [print "test"]]

>> test 
== [print "test"]

Właśnie zwrócił blok po wartości, tak jakby miał normalny zwrot. Czy nie powinien był wydrukować „testu”? To codo zrobiłbym ... z tym:

>> do [print "test"]
test

questionAnswers(2)

yourAnswerToTheQuestion