На реализацию Лиспа


Фон:
Это началось с Джеймс Коганс Лисп-Додзе для Ruby. Моя реализация может быть найден здесь. Я потом перешел на напишите себе схему в 48 часов. Этот вопрос связан с одним из решений.

Код:

Моя реализация функции eval

--# The eval function takes a scope and paresed Lisp value and
--# returns the resulting Lisp Value.
--# String, Number and Bool return themselves.
--# An Atom trys to find its self in the scope and retrun that value
--# A List is evaluated using the normal Lisp rules.
eval :: LispScope-> LispVal -> IOThrowsError LispVal
eval s val@(String _) = return val
eval s (Atom val) =  do
  (liftIO $ getValue s val) >>= maybe (throwError $ "Value not in scope: " ++ val) (return)
eval s val@(Number _) = return val
eval s val@(Bool _) = return val
eval scope (List (fn:lvs)) = do
    fun <- eval scope fn
    case fun of 
      Syntax f _-> f scope lvs
      Function f _-> evalMap scope lvs >>= f
      val -> throwError $ (show val) ++ " is not a function"
eval scope (List []) = return $ List []
eval _ badForm = throwError $ "Unrecognized form: " ++ show badForm

Обратите внимание на две вещи: 1) я не ссылаюсь на какие-то особые формы, 2) Использование синтаксиса для гигиенической формы.

Это кусок кода из напишите себе схему в течение 48 часов:

--# evaluate the "if" form
eval (List [Atom "if", pred, conseq, alt]) = 
    do result <- eval pred
       case result of
         Bool False -> eval alt
         otherwise -> eval conseq

Обратите внимание, что в учебник форме пишется непосредственно в функции eval. Этот шаблон используется для других синтаксисов, как определить и лямда.

Вопрос: Когда я реализовал свою версию я следовал тому, что я думал, был мудрым выбором показали в Джеймс Колган решение на Лиспе-додзе, чтобы сохранить ивала максимально просто и вместо того, чтобы толкать синтаксических реализаций в корневую область. например:

ifSyntax :: LispScope -> [LispVal] -> IOThrowsError LispVal
ifSyntax s [pred, consequent, alternate] = do
  pred' <- eval s pred
  case pred' of 
    Bool False -> eval s alternate
    otherwise -> eval s consequent
ifSyntax _ _ = throwError "if: Bad Syntax"

ifVal = (Syntax ifSyntax $ Left "syntax (if)")
--# this is then added to the initial scope

Я хотел бы знать, почему один выбор мог бы быть лучше, чем другие, и что характерно в реальном мире реализаций.

Ссылка:

Мое определение LispVal тип данных:

type LispScope = Scope LispVal

data Lambda = Lambda {params :: [String], body :: [LispVal]}

data LispVal = Atom String
             | List [LispVal]
             | Number Integer
             | Real Double
             | String String
             | Function ([LispVal] -> IOThrowsError LispVal) (Either String Lambda)
             | Syntax (LispScope -> [LispVal] -> IOThrowsError LispVal) (Either String Lambda)
             | Bool Bool
             | Port Handle


581
11
задан 20 апреля 2011 в 03:04 Источник Поделиться
Комментарии