ocena

W niektórych językach programowania eval , skrót od angielskiej ewaluacji , jest funkcją , która ocenia ciąg tak, jakby był wyrażeniem w języku, i zwraca wynik ; w innych wykonuje wiele wierszy kodu tak, jakby zostały one uwzględnione zamiast wiersza zawierającego eval . Wejście do eval niekoniecznie jest ciągiem znaków; może to być ustrukturyzowana reprezentacja kodu, taka jak abstrakcyjne drzewo składniowe (jak formularze Lispa ) lub specjalny typ, taki jak kod (jak w Pythonie). Odpowiednikiem instrukcji jest exec , która wykonuje łańcuch znaków (lub kod w innym formacie) tak, jakby to była instrukcja; w niektórych językach, takich jak Python, oba są obecne, podczas gdy w innych występuje tylko jeden z eval lub exec .

Eval i Apply to przykłady ewaluatorów meta-kołowych , tłumaczy języka, które można przywołać w samym języku. [ potrzebne źródło ]

Zagrożenia bezpieczeństwa

Używanie eval z danymi z niezaufanego źródła może wprowadzić luki w zabezpieczeniach. Na przykład, zakładając, że get_data() pobiera dane z Internetu, ten kod Pythona jest niepewny:

  
  
   sesja  [  'uwierzytelniona'  ]  =  fałszywe  dane  =  get_data  ()  foo  =  eval  (  dane  ) 

Osoba atakująca może dostarczyć programowi ciąg „session.update(authenticated=True)” jako dane, co spowoduje zaktualizowanie słownika sesji w celu ustawienia uwierzytelnionego klucza na wartość True. Aby temu zaradzić, wszystkie dane, które będą używane z eval , muszą zostać zmienione lub muszą zostać uruchomione bez dostępu do potencjalnie szkodliwych funkcji.

Realizacja

W językach interpretowanych eval jest prawie zawsze implementowany z tym samym interpreterem, co normalny kod. W językach kompilowanych ten sam kompilator używany do kompilowania programów może być osadzony w programach korzystających z funkcji eval ; czasami używa się oddzielnych tłumaczy, chociaż powoduje to powielanie kodu .

Języki programowania

ECMAScript

JavaScript

W JavaScript eval jest czymś w rodzaju hybrydy między ewaluatorem wyrażeń a wykonawcą instrukcji . Zwraca wynik ostatniego ocenionego wyrażenia.

Przykład jako ewaluator wyrażenia:

  
 foo  =  2  ;  alert  (  eval  (  'foo + 2'  )); 

Przykład jako wykonawca instrukcji:

  
 foo  =  2  ;  eval  (  'foo = foo + 2;alert(foo);'  ); 

eval JavaScript jest analizowanie tekstu JSON , być może jako część frameworka Ajax . Jednak nowoczesne przeglądarki zapewniają JSON.parse jako bezpieczniejszą alternatywę dla tego zadania.

ActionScript

W ActionScript (języku programowania Flasha) eval nie może służyć do obliczania dowolnych wyrażeń. Zgodnie z dokumentacją Flash 8, jego użycie jest ograniczone do wyrażeń reprezentujących „nazwę zmiennej, właściwości, obiektu lub klipu filmowego do pobrania. Ten parametr może być ciągiem znaków lub bezpośrednim odniesieniem do instancji obiektu”.

ActionScript 3 nie obsługuje eval.

Biblioteka ActionScript 3 Eval i interfejs API De.eval były projektami rozwojowymi mającymi na celu stworzenie odpowiedników eval w języku ActionScript 3. Oba zakończyły się, ponieważ program Adobe Flash Player osiągnął koniec okresu eksploatacji .

Seplenienie

Lisp był oryginalnym językiem wykorzystującym funkcję eval w 1958 roku. W rzeczywistości zdefiniowanie funkcji eval doprowadziło do pierwszej implementacji interpretera języka. Zanim zdefiniowano funkcję eval , funkcje Lispa były ręcznie kompilowane do instrukcji asemblera . Jednak po eval była ona następnie używana jako część prostej pętli odczyt-ocena-wydruk , która stanowiła podstawę pierwszego interpretera Lispa.

eval Lispa zostały również zaimplementowane jako kompilatory.

Funkcja eval w Lispie oczekuje, że formularz zostanie oceniony i wykonany jako argument. Zwrócona wartość podanego formularza będzie wartością zwróconą wywołania eval .

To jest przykładowy kod Lispa:



   




     


 
 ; Forma wywołująca funkcję + z argumentami 1,2 i 3.   ; Zwraca 6.   (  +  1  2  3  )  ; Dlatego w seplenieniu każda forma ma być oceniana   ; wywołanie + zostało wykonane.   ; Możemy uniemożliwić Lispowi wykonanie oceny   ; formularza poprzez poprzedzenie go przedrostkiem „'”, na przykład:   (  setq  form1  '  (  +  1  2  3  ))  ; Teraz form1 zawiera formularz, który może być użyty przez eval, dla   ; przykład:   (  formularz  ewaluacyjny1  )  ; eval ocenił (+ 1 2 3) i zwrócił 6.  

Powszechnie wiadomo, że Lisp jest bardzo elastyczny, podobnie jak funkcja eval . Na przykład, aby oszacować zawartość łańcucha, łańcuch musiałby najpierw zostać przekonwertowany na formę Lispa za pomocą funkcji read-from-string , a następnie wynikowa forma musiałaby zostać przekazana do eval :

   (  eval  (  read-from-string  "(format t \"Hello World!!!~%\")"  )) 

Jednym z głównych punktów nieporozumień jest pytanie, w jakim kontekście oceniane będą symbole w formularzu. W powyższym przykładzie form1 zawiera symbol + . Ocena tego symbolu musi dać funkcję dodawania, aby przykład działał zgodnie z przeznaczeniem. Dlatego niektóre dialekty języka lisp dopuszczają dodatkowy parametr eval określający kontekst oceny (podobnie jak opcjonalne argumenty funkcji eval w Pythonie — patrz poniżej). Przykład w Scheme Lispa (R 5 RS i nowsze):


   




 




   




 
 ;; Zdefiniuj prostą formę, jak w powyższym przykładzie.   (  zdefiniuj  formularz2  '  (  +  5  2  ))  ;Wartość: formularz2  ;; Oceń formularz w początkowym kontekście.   ;; Kontekst oceny nazywany jest „środowiskiem” w slangu Scheme.   (  eval  form2  user-initial-environment  )  ;Wartość: 7  ;; Pomieszaj środowisko początkowe, aby + było   ;; nazwa funkcji odejmowania.   (  środowisko-zdefiniowane  -początkowe-środowisko-użytkownika  '+  -  )  ;Wartość: +  ;; Oceń formularz ponownie.   ;; Zwróć uwagę, że zwrócona wartość uległa zmianie.   (  eval  form2  user-initial-environment  )  ;Wartość: 3 

Perl

W Perlu funkcja eval jest czymś w rodzaju hybrydy między ewaluatorem wyrażeń a wykonawcą instrukcji. Zwraca wynik ostatniego obliczonego wyrażenia (wszystkie instrukcje są wyrażeniami w języku Perl) i pozwala na opuszczenie końcowego średnika.

Przykład jako ewaluator wyrażenia:

  
   $foo  =  2  ;  print  eval  (  '$foo + 2'  ),  "\n"  ; 

Przykład jako wykonawca instrukcji:

  
 $foo  =  2  ;  eval  (  '$foo += 2; print "$foo\n";'  ); 

Perl posiada również bloki eval , które służą jako mechanizm obsługi wyjątków (patrz Składnia obsługi wyjątków#Perl ). Różni się to od powyższego użycia eval z ciągami znaków w kodzie wewnątrz bloków eval jest interpretowany w czasie kompilacji zamiast w czasie wykonywania, więc nie jest to znaczenie eval używane w tym artykule.

PHP

W PHP eval wykonuje kod w łańcuchu prawie dokładnie tak, jakby został umieszczony w pliku zamiast wywołania eval () . Jedynym wyjątkiem jest to, że błędy są zgłaszane jako pochodzące z wywołania eval() , a instrukcje return stają się wynikiem funkcji.

W przeciwieństwie do niektórych języków, argument eval musi być ciągiem jednej lub więcej pełnych instrukcji, a nie tylko wyrażeń; jednak można uzyskać formę „wyrażenia” eval , umieszczając wyrażenie w instrukcji return, co powoduje, że eval zwraca wynik tego wyrażenia.

W przeciwieństwie do niektórych języków, eval w PHP jest „konstrukcją językową”, a nie funkcją, dlatego nie może być używany w niektórych kontekstach, w których mogą występować funkcje, na przykład funkcje wyższego rzędu.

Przykład użycia echa:


  

 <?php  $foo  =  "Witaj, świecie!  \n  "  ;  eval  (  'echo "$foo";'  );  ?> 

Przykład zwracania wartości:


    
 
 <?php  $foo  =  "Żegnaj, świecie!  \n  "  ;  //nie działa w PHP5  echo  eval  (  'return $foo;'  );  ?> 

Lua

W Lua 5.1 loadstring kompiluje kod Lua w anonimową funkcję.

Przykład jako ewaluator wyrażenia:

 loadstring  (  "print('Witaj świecie!')"  )() 

Przykład wykonania oceny w dwóch krokach:

  
   
  a  =  1  f  =  loadstring  (  "return a + 1"  )  -- skompiluj wyrażenie do funkcji anonimowej  print  (  f  ())  -- wykonaj (i wypisz wynik „2”) 

Lua 5.2 rezygnuje z funkcji loadstring na rzecz istniejącej funkcji load , która została rozszerzona o akceptację stringów. Ponadto umożliwia bezpośrednie udostępnianie środowiska funkcji, ponieważ środowiska są teraz upvalues ​​.

           load  (  "print('Witaj' .. a)"  ,  ""  ,  "t"  ,  {  a  =  "Świat!"  ,  print  =  print  })() 

Postscriptum

exec języka PostScript bierze operand — jeśli jest to prosty literał, odkłada go z powrotem na stos. Jeśli jednak weźmie się ciąg zawierający wyrażenie PostScript, można go przekonwertować na plik wykonywalny, który następnie może zostać wykonany przez interpreter, na przykład:

    ((Hello World) =)  cvx  exec 

konwertuje wyrażenie PostScript

   (Witaj świecie)  = 

który usuwa ciąg „Hello World” ze stosu i wyświetla go na ekranie, aby mieć typ wykonywalny, a następnie jest wykonywany.

run PostScript ma podobną funkcjonalność, ale zamiast tego interpreter sam interpretuje wyrażenia PostScript w pliku.

  (plik.ps)  uruchom 

Pyton

W Pythonie funkcja eval w najprostszej postaci ocenia pojedyncze wyrażenie.

eval przykład (powłoka interaktywna):

  



 >>>  x  =  1  >>>  ewaluacja  (  'x + 1'  )  2  >>>  ewaluacja  (  'x'  )  1 

Funkcja eval przyjmuje dwa opcjonalne argumenty, global i locals , które pozwalają programiście skonfigurować ograniczone środowisko do oceny wyrażenia.

Instrukcja exec (lub funkcja exec w Pythonie 3.x) wykonuje instrukcje:

exec (powłoka interaktywna):

  
  
 


 >>>  x  =  1  >>>  y  =  1  >>>  wykonaj  "x += 1; y -= 1"  >>>  x  2  >>>  y 
0

Najbardziej ogólną formą oceny instrukcji/wyrażeń jest użycie obiektów kodu. Można je utworzyć, wywołując kompilacji () i informując ją, jakie dane wejściowe ma skompilować: instrukcję „ exec ”, instrukcję „ eval ” lub instrukcję „ single ”:

kompilacji (powłoka interaktywna):

  
  
    
 >>>  x  =  1  >>>  y  =  2  >>>  eval  (  kompilacja  (  "print 'x + y = ', x + y"  ,  "compile-sample.py"  ,  "single"  ))  x + y = 3 

D

D jest językiem kompilowanym statycznie i dlatego nie zawiera instrukcji „ eval ” w tradycyjnym sensie, ale zawiera powiązaną instrukcję „ mixin ”. Różnica polega na tym, że tam, gdzie „ eval ” interpretuje łańcuch jako kod w czasie wykonywania, z „ mixin ” ciąg jest kompilowany statycznie jak zwykły kod i musi być znany w czasie kompilacji. Na przykład:

 

  
       0
    
      
 import  standard  .  stdio  ;  nieważne  główne  ()  {  int  liczba  =  ;  mixin  (  "liczba++;"  );  writeln  (  liczba  );  // Drukuje 1.  } 

Powyższy przykład skompiluje dokładnie takie same instrukcje języka asemblera, jak gdyby „ num++; ” zostało napisane bezpośrednio, a nie wmieszane. Argument do mixin nie musi być literałem łańcuchowym, ale dowolne wyrażenia dające wartość łańcuchową, w tym wywołania funkcji, które można ocenić w czasie kompilacji.

Zimna fuzja

oceny programu ColdFusion umożliwia ocenę wyrażenia łańcuchowego w czasie wykonywania.

   
    <cfset  x  =  "int(1+1)"  >  <cfset  y  =  Oceń  (  x  )  > 

Jest to szczególnie przydatne, gdy musisz programowo wybrać zmienną, z której chcesz czytać.

    <cfset  x  =  Evaluate  (  "nazwazapytania.  #nazwakolumny#  [numer_wiersza]"  )  > 

Rubin

Interpreter języka programowania Ruby oferuje funkcję eval podobną do Pythona lub Perla, a także umożliwia określenie zakresu lub powiązania .

Oprócz określania powiązania funkcji, eval może być również używany do oceny wyrażenia w ramach określonego powiązania definicji klasy lub powiązania instancji obiektu, umożliwiając rozszerzenie klas o nowe metody określone w łańcuchach.

  
 


 
  

  a  =  1  eval  (  'a + 1'  )  # (wylicza 2)  # ocenia w kontekście  def  get_binding  (  a  )  binding  end  eval  (  'a+1'  ,  get_binding  (  3  ))  # (wylicza 4, ponieważ ' a” w kontekście get_binding to 3) 
  
 
                     test  klasy  ;  koniec  testu  .  class_eval  (  "def hello; return 'hello';end"  )  # dodaj metodę 'hello' do tej klasy  Test  .  nowy  .  cześć  # daje wynik „cześć” 

Naprzód

Większość standardowych implementacji Forth ma dwa warianty eval : EVALUATE i INTERPRET .

Przykład kodu Win32FORTH:

      S"  2 2 + .  "  OCENA  \ Wyjścia "4" 

FRED

Framework FRED to interaktywny język, w którym cały kod jest automatycznie oceniany przez Eval. Parametry ciągu w poniższych przykładach będą działać tak samo, jak gdyby zostały wpisane i wykonane w formule lub po wybraniu i wykonaniu. Ampersand & jest operatorem łączenia ciągów znaków. Eval rekurencyjnie łączy, rozwiązuje i ocenia swój parametr. FRED ma również wewnętrzną funkcję o nazwie @wartość , która ocenia ciąg parametrów. Opcjonalny drugi parametr liczbowy @value wskazuje typ danych wejściowych i formaty dla typów specjalnych, takich jak daty, czas . itp. i określa format zwracanej wartości.

Ze względów bezpieczeństwa zakres odniesienia @value jest globalny, więc zmienne lokalne utworzone za pomocą @local są niewidoczne dla @value. Można je „zobaczyć” tylko za pomocą kodu w tym samym obszarze formuły. (patrz przykład poniżej), Z tego samego powodu zmienne lokalne utworzone w zakresie @value mogą być widoczne tylko dla @value i są niewidoczne dla kodu w tej samej formule lub jakimkolwiek innym kodzie. (patrz komentarz (1*) poniżej)

Przykłady kodu FRED:

@value("5 + 4 + 1") # Zwróć wartość liczbową 10 @value("2" & "3") # Zwróć wartość liczbową 23 @value("2" & " + 3") # Zwróć wartość liczbową wartość 5 @value("2" & "+" & "3") # Zwraca wartość liczbową 5 @value("2 + 3") # Zwraca wartość liczbową 5 my_var := 3, @value("2 + my_var ") # Zwróć wartość liczbową 5 moja_zmienna := -3, @value("2 + @abs(moja_zmienna)") # Zwróć wartość liczbową 5 Ze względów bezpieczeństwa zwróci to błąd, ponieważ zakres @wartości jest globalny, a @lokalny jest niewidoczny dla globalnych odniesień i może być „widoczny” tylko przez kod w jego własnej formule. @local(a,b), a := 1, b := 2, @value("a + b") # zwraca wartość błędu (1*), ale jeśli aib są ramkami @wartość, która może odnosić się do globalnej jako podobnie jak ramki zmiennych względnych, @wartość może je „zobaczyć” a := 1, b := 2, @value("a + b") # Zwraca wartość liczbową 3 Ta linia kodu zwróci 3, ponieważ lokalne zmienne są utworzone i widoczne w zakresie @value @value("@local(a,b),a:=1,b:=2,a+b") # Zwraca wartość liczbową 3 Ale następne dwie linie kodu zwrócą niezdefiniowany błąd odniesienia, ponieważ a i b są tworzone w lokalnym zakresie @value i są niewidoczne dla reszty kodu w formule, w rzeczywistości dla dowolnego kodu w dowolnym miejscu poza tym zakresem @value. @value("@local(a,b),a:=1,b:=2), a+b # Zwraca niezdefiniowany błąd odwołania @value("{12/12/2012}",16) # Zwraca string "12 grudnia 2012" @value("@fileload(@inputline(""Wprowadź literę dysku"",""" & @item1 & """) & "& "":\myfile.txt"") ") # gdzie @item1 otrzymuje parametr "c",

wykona części łańcucha, zbuduje poniższy ciąg i wykona go jako program zaczynający się od @inputline żądający wprowadzenia danych przez użytkownika, sugerujący „C”. Jeśli użytkownik wprowadzi C, @fileload uruchomi się z ciągiem „c:\myfile.txt” jako jego parametr:

@fileload(@inputline("Wprowadź literę dysku", "c") & ":\myfile.txt") # ładuje mójplik.txt na pulpit

PODSTAWOWY

REALpodstawowy

W REALbasic istnieje klasa o nazwie RBScript , która może wykonywać kod REALbasic w czasie wykonywania. RBScript jest bardzo piaskownicą — dostępne są tylko najbardziej podstawowe funkcje języka i musisz zezwolić mu na dostęp do rzeczy, które chcesz mieć. Opcjonalnie można przypisać obiekt do właściwości context. Dzięki temu kod w RBScript może wywoływać funkcje i używać właściwości obiektu kontekstu. Jednak nadal jest to ograniczone do zrozumienia tylko najbardziej podstawowych typów, więc jeśli masz funkcję, która zwraca Dictionary lub MySpiffyObject, RBScript nie będzie mógł jej użyć. Możesz także komunikować się ze swoim RBScript poprzez zdarzenia Print i Input.

VBScript

VBScript firmy Microsoft, który jest językiem interpretowanym, ma dwie konstrukcje. Eval to ewaluator funkcji, który może zawierać wywołania funkcji zdefiniowanych przez użytkownika. (Funkcje te mogą mieć skutki uboczne, takie jak zmiana wartości zmiennych globalnych). Execute wykonuje jedną lub więcej instrukcji oddzielonych dwukropkami, które mogą zmienić stan globalny.

Zarówno VBScript, jak i JScript eval są dostępne dla programistów skompilowanych aplikacji Windows (napisanych w językach, które nie obsługują Eval) za pośrednictwem formantu ActiveX o nazwie Microsoft Script Control, którego metodę Eval można wywołać za pomocą kodu aplikacji. Aby obsługiwać wywoływanie funkcji zdefiniowanych przez użytkownika, należy najpierw zainicjować kontrolkę metodą AddCode, która ładuje ciąg znaków (lub zasób łańcuchowy) zawierający bibliotekę funkcji zdefiniowanych przez użytkownika, zdefiniowanych w wybranym przez siebie języku, przed wywołaniem Eval .

Visual Basic dla aplikacji

Visual Basic for Applications (VBA), język programowania pakietu Microsoft Office, to język maszyny wirtualnej, w którym środowisko wykonawcze kompiluje i uruchamia p-code . Jego odmiana Eval obsługuje tylko ocenę wyrażeń, gdzie wyrażenie może zawierać funkcje i obiekty zdefiniowane przez użytkownika (ale nie zdefiniowane przez użytkownika nazwy zmiennych). Warto zauważyć, że ewaluator różni się od VBS, a wywołanie pewnych funkcji zdefiniowanych przez użytkownika może działać inaczej w VBA niż identyczny kod w VBScript.

Pogawędka

Ponieważ klasy kompilatora Smalltalk są częścią standardowej biblioteki klas i zwykle są obecne w czasie wykonywania, można ich użyć do oceny ciągu kodu.

  kompilatora  :  „1 + 2” 

Ponieważ definicje klas i metod są również implementowane przez wysyłanie komunikatów (do obiektów klas), możliwe są nawet zmiany kodu:

  kompilatora  :  „Podklasa obiektu: #Foo” 

Tcl

Język programowania Tcl ma polecenie o nazwie eval , które wykonuje kod źródłowy podany jako argument. Tcl reprezentuje cały kod źródłowy jako ciągi, z nawiasami klamrowymi działającymi jako cudzysłowy, dzięki czemu argument eval może mieć takie samo formatowanie jak każdy inny kod źródłowy.

  
	   
		 
	

  set  foo  {  while  {[  incr  i  ]  <  10  }  {  stawia  "$i do kwadratu to [wyrażenie $i*$i]"  }  }  eval  $foo 

bs

bs ma funkcję eval , która przyjmuje jeden argument łańcuchowy. Funkcja jest zarówno ewaluatorem wyrażeń, jak i wykonawcą instrukcji. W tej ostatniej roli może być również używany do obsługi błędów. Poniższe przykłady i tekst pochodzą ze strony podręcznika bs , która pojawia się w Podręczniku programisty UNIX System V Release 3.2.

Argument łańcuchowy jest oceniany jako wyrażenie bs . Funkcja jest przydatna do konwertowania ciągów liczbowych na numeryczną postać wewnętrzną. eval może być również użyty jako prymitywna forma pośredniości, jak w poniższym (Zauważ, że w bs _ ( podkreślenie) jest operatorem konkatenacji.) :

   nazwa  =  "xyz"  ewaluacja  (  "++"  _ nazwa  ) 

co zwiększa zmienną xyz .

Ponadto eval poprzedzone operatorem zapytania, ? , pozwala użytkownikowi kontrolować stany błędów bs . Na przykład:

 ?eval  (  "open(\"X\", \"XXX\", \"r\")"  ) 

zwraca wartość zero, jeśli nie ma pliku o nazwie „XXX” (zamiast zatrzymywania programu użytkownika).

Poniższe polecenie wykonuje goto do etykiety L (jeśli istnieje):

  
    etykieta  =  "L"  jeśli  !  (  ?eval  (  "goto "  _ label  ))  puterr  =  "brak etykiety" 

Tłumacze wiersza poleceń

Powłoki uniksowe

Polecenie eval jest obecne we wszystkich powłokach systemu Unix , w tym w oryginalnym „sh” ( powłoka Bourne'a ). Łączy wszystkie argumenty ze spacjami, następnie ponownie analizuje i wykonuje wynik jako polecenie. sh(1) Podręcznik poleceń ogólnych FreeBSD

Windows PowerShell

W środowisku Windows PowerShell polecenie cmdlet Invoke-Expression służy temu samemu celowi, co funkcja eval w językach programowania, takich jak JavaScript, PHP i Python. Polecenie cmdlet uruchamia dowolne wyrażenie programu Windows PowerShell, które jest podane jako parametr polecenia w postaci ciągu znaków i wyświetla wynik określonego wyrażenia. Zwykle dane wyjściowe polecenia cmdlet są tego samego typu, co wynik wykonania wyrażenia. Jeśli jednak wynikiem jest pusta tablica, zwraca $null . W przypadku, gdy wynikiem jest tablica jednoelementowa, wyprowadza ten pojedynczy element. Podobnie jak JavaScript, Windows PowerShell umożliwia pominięcie ostatniego średnika.

Przykład jako ewaluator wyrażenia:

  
  PS >  $foo  =  2  PS >  wywołanie-wyrażenia  '$foo + 2' 

Przykład jako wykonawca instrukcji:

  
  PS >  $foo  =  2  PS >  wywołanie-wyrażenia  '$foo += 2; $foo'  

Mikrokod

W 1966 r. IBM Conversational Programming System (CPS) wprowadził mikroprogramowaną funkcję EVAL do wykonywania „interpretacyjnej oceny wyrażeń zapisanych w zmodyfikowanej polskiej notacji łańcuchowej ” w systemie IBM System/360 Model 50 . Mikrokodowanie tej funkcji było „znacznie więcej” niż pięć razy szybsze w porównaniu z programem, który interpretował przypisania .

Teoria

W informatyce teoretycznej często dokonuje się starannego rozróżnienia między eval i apply . Eval jest rozumiany jako krok konwersji cytowanego łańcucha na wywoływalną funkcję i jej argumenty, podczas gdy zastosowanie to rzeczywiste wywołanie funkcji z danym zestawem argumentów. Rozróżnienie to jest szczególnie widoczne w językach funkcjonalnych oraz językach opartych na rachunku lambda , takich jak LISP i Scheme . Tak więc, na przykład, w schemacie rozróżnienie jest pomiędzy

    (  ocena  '  (  f  x  )  ) 

gdzie forma (fx) ma być oceniana, oraz

    (  zastosuj  f  (  lista  x  )) 

gdzie funkcja f ma być wywołana z argumentem x .

Eval i Apply to dwa współzależne komponenty cyklu ewaluacja-stosowanie , który jest istotą ewaluacji Lispa, opisanej w SICP .

W teorii kategorii morfizm ewaluacyjny jest używany do zdefiniowania zamkniętej kategorii monoidalnej . Tak więc, na przykład, kategoria zbiorów , z funkcjami wziętymi za morfizmy i iloczynem kartezjańskim wziętym za iloczyn , tworzy zamkniętą kategorię kartezjańską . Tutaj eval (lub, właściwie mówiąc, apply ) wraz z prawym sprzężeniem , currying , tworzą prosty typ rachunku lambda , który można interpretować jako morfizm kartezjańskich kategorii zamkniętych.

Linki zewnętrzne