Здравствуйте, Курилка, Вы писали:
К>Дак как оно выглядеть будет не столько интересно, интересно скорее, как оно будет работать. Do нотация требует монаду, которая определяется в компайл-тайме (да и существует тоже по ходу тамже), а что в случае динамической типизации будешь делать?.
Хоть и вряд ли кто-то захочет в горе кода без комментариев разбираться, но тем не менее, вот он, чисто-функциональный динамически-типизированный язык с do-нотацией.
Тадам :
import Text.ParserCombinators.Parsec
-- interpreter coredata Value = VInt Integer | VFun (Value -> Value) | VAction (IO Value)
type Ident = String
data Expr = Const Integer
| Var Ident
| Add Expr Expr
| Fun Ident Expr
| App Expr Expr
| Bind Expr Expr
| Return Expr
deriving Show
type Env = [(Ident, Value)]
eval :: Expr -> Env -> Value
eval (Const x) env = VInt x
eval (Var name) env =
case lookup name env of
Just v -> v
_ -> error ("Unbound variable: " ++ name)
eval (Add e1 e2) env =
case (eval e1 env, eval e2 env) of
(VInt x, VInt y) -> VInt (x+y)
_ -> error"addition: Type error"
eval (Fun name body) env = VFun $ \val -> eval body ((name, val):env)
eval (App f x) env = case (eval f env) of
VFun fv -> fv(eval x env)
_ -> error"function application: Type error"
eval (Bind action fnext) env =
case (eval action env, eval fnext env) of
(VAction m, VFun f) -> VAction $ do x <- m
run (f x)
_ -> error"do block: Type error"
eval (Return e) env = VAction (return (eval e env))
run :: Value -> IO Value
run v@(VInt _) = return v
run v@(VFun _) = return v
run (VAction a) = a >>= run
initEnv = [("print", vprint), ("read", vread)]
where vprint = VFun $ \v -> case v of
VInt x -> VAction (print x >> return (VInt 0))
_ -> error"print: Type error"
vread = VAction (fmap VInt (putStr "Enter an integer: " >> readLn))
runProgram p = run (eval p initEnv)
-- parser
parsePureExpr = parseConst <|> parseAdd <|> try parseApp <|> parseVar
parseExpr = try parseDoBlock <|> parsePureExpr
skipSpaces = many space
parseConst = do
s <- many1 digit
skipSpaces
return (Const (read s))
parseIdent = do
s <- many1 letter
skipSpaces
return s
parseVar = fmap Var parseIdent
parseApp = do
func <- parseVar
char_ '('
arg <- parsePureExpr
char_ ')'
return (App func arg)
char_ c = char c >> skipSpaces
string_ s = string s >> skipSpaces
parseAdd = do
char_ '('
x <- parsePureExpr
char_ '+'
y <- parsePureExpr
char_ ')'
return (Add x y)
parseDefun = do
string_ "fun"
fname <- parseIdent
argname <- parseIdent
char_ '='
body <- parseExpr
char_ ';'
return (fname, Fun argname body)
parseDoBlock = do
string_ "do"
char_ '{'
stmts <- many1 parseStatement
char '}'let ("_", lastStmt) = last stmts
return (foldr bind lastStmt (init stmts))
where bind (v, e1) e2 = Bind e1 (Fun v e2)
parseStatement = try parseBinding <|> parseSimpleStatement
parseBinding = do
var <- parseIdent
string_ "<-"
rhs <- parsePureExpr
char_ ';'
return (var, rhs)
parseSimpleStatement =
try (do string_ "return"
e <- parsePureExpr
return ("_", (Return e))) <|>
(do e <- parsePureExpr
char_ ';'
return ("_", e))
parseProgram = do
funs <- many parseDefun
main_ <- parseDoBlock
return (foldr addDefun main_ funs)
where addDefun (name, fun) prog = App (Fun name prog) fun
runProgramParser = runParser parseProgram () ""
parseAndRun ptext = case runProgramParser ptext of
Right p -> runProgram p
Left e -> error (show e)
-- tests
testOk1 =
parseAndRun $ unlines $ ["fun foo x = (x + 1); ",
"fun bar x = (x + 42); ",
"fun bzzt x = do { print(x); print(777); };",
"do { x <- read; ",
" print(foo(x)); ",
" bzzt(x); ",
" print(bar(x));} " ]
testOk2 =
parseAndRun $ unlines $ ["fun action x = do { return (x + 1) };",
"do { z <- action(42); print(z); } "]
testError =
parseAndRun $ unlines $ ["fun action x = do { return (x + 1) };",
"do { print( (action(10) + 5) ); } "]
Re[9]: proof of concept (очередной игрушечный интерпретатор)
К>>Хотя прикрутить, конечно можно PM>Ну если к текущему варианту прикрутить контроль, это получится некая вырожденная система типов, и язык будет уже не совсем динамическим. Но, как я говорил, осталось сделать полшага, чтобы грязные программы обнаруживались парсером как синтаксические ошибки.
Проверку типов можно реализовать в виде двухуровневых грамматик (они же грамматики ван Вийнгаардена). И встроить в разборщик.
Вроде, всего лишь разбор по синтаксису, а типы тоже проверяются.
Товарищи из динамического сообщества не скоро поймут, в чём их обманули.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
К>> Do нотация требует монаду PM>Это в Хаскеле она требует монаду, т.к. рассахаривается в вызовы перегруженных функций (>>=) и return. Вполне можно представить себе язык, поддерживающий только одну монаду — IO — и транслирующий do-нотацию соответствующим образом.
В Helium — такой хаскеллоподобный язык — именно так и есть.
T>>Отложи проверку типов в Хаскеле до выполнения программы, получишь то, что нужно. "Ввод-вывод может производиться только в аргументах функции >>=, или в рамках do-выражения." BZ>в хаскеле не проверка, а вывод типов. и тип результата, к примеру, может определять тип аргументов функции
Это то, что происходит в compile time.
Скажи, неужели ты не можешь вообразить алгоритм, что работает в run-time и производит проверку типов?
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
PM>>>>Теоретически можно, если для операций с побочными эффектами ввести специальные синтаксические конструкции. К>>>Т.е. есть какие-то примеры подобного? T>>Haskell, do notation. К>Это ответ на "как-то контролировать чистоту для языка с динамической типизацией"?
Да.
К>Или я что-то не понял или одно из двух...
Да.
Отложи проверку типов в Хаскеле до выполнения программы, получишь то, что нужно. "Ввод-вывод может производиться только в аргументах функции >>=, или в рамках do-выражения."
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
К>>Ну скажи как твоя только одна монада будет (цитирую изначальную проблему, которую я высказал) "контролировать чистоту для языка"? BZ>самое простое — запрет на вызов процедур (имеющих побочные эффекты) из функций. и всё. даже никаких спец. синт. конструкций не понадобится
Да! Д-да! Р-рок! (С) B&B
Запретить! Вызов! Процедур!
Синтаксиса! Не НАДО!!!
Если серьёзно, то твоё запрещение и реализуется через синтаксическое ограничение.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Часто (например, в статье Влада про Linq) одним из требований, которому
должна удовлетворять функция, чтобы быть pure function является следующее
требование:
Функция не должна создавать никаких побочных эффектов. Под побочными
эффектами понимается:
....
* Посылать или принимать некие сообщения.
А как же Pid ! {} и receive в Erlang? Правильно ли я понимаю, что это как
раз и есть тот побочный эффект, про который пишет Влад?
Здравствуйте, DemAS, Вы писали:
DAS>Часто (например, в статье Влада про Linq) одним из требований, которому DAS>должна удовлетворять функция, чтобы быть pure function является следующее DAS>требование:
чистая функция — это функция в математическом смысле этого слова
[cut]
DAS>А как же Pid ! {} и receive в Erlang? Правильно ли я понимаю, что это как DAS>раз и есть тот побочный эффект, про который пишет Влад?
Ну не только ! есть же ещё ввод-вывод, например
Эрланг вроде никогда не стремился быть именно "чистым" ФЯ, да и как-то не очень представляю можно ли как-то контролировать чистоту для языка с динамической типизацией...
"Курилка" <1546@users.rsdn.ru> writes:
> Ну не только ! есть же ещё ввод-вывод, например
Да, и это тоже. С вводом/выводом понятно, а вот про сообщения хотел уточнить.
> Эрланг вроде никогда не стремился быть именно "чистым" ФЯ, да и как-то не очень представляю можно ли как-то контролировать чистоту для языка с динамической типизацией...
Что есть динамическая типизация? Это когда до моменти исполнения нельзя
сказать какого типа значение будет присвоено данной переменной ?
Здравствуйте, DemAS, Вы писали:
DAS>"Курилка" <1546@users.rsdn.ru> writes:
>> Ну не только ! есть же ещё ввод-вывод, например
DAS>Да, и это тоже. С вводом/выводом понятно, а вот про сообщения хотел уточнить.
Дак а чем сообщения от ввода-вывода отличаются принципиально?
Если передача на другую ноду, то в любом случае ввод-вывод будет
>> Эрланг вроде никогда не стремился быть именно "чистым" ФЯ, да и как-то не очень представляю можно ли как-то контролировать чистоту для языка с динамической типизацией...
DAS>Что есть динамическая типизация? Это когда до моменти исполнения нельзя DAS>сказать какого типа значение будет присвоено данной переменной ?
Ну хотяб вики посмотри чтоль.
Строго говоря в Эрланге и переменных нет
Да и тип гарантировать вполне можно, ставишь гард на функцию (например is_integer/1)
Здравствуйте, Курилка, Вы писали:
К>... да и как-то не очень представляю можно ли как-то контролировать чистоту для языка с динамической типизацией...
Теоретически можно, если для операций с побочными эффектами ввести специальные синтаксические конструкции.
Здравствуйте, palm mute, Вы писали:
PM>Здравствуйте, Курилка, Вы писали:
К>>... да и как-то не очень представляю можно ли как-то контролировать чистоту для языка с динамической типизацией... PM>Теоретически можно, если для операций с побочными эффектами ввести специальные синтаксические конструкции.
Ну в теории теория не отличается от практики
Т.е. есть какие-то примеры подобного?
Ну и вопрос будет ли стоить овчинка выделки, в смысле получим ли мы реальные бенефиты и будут ли они больше чем дополнительный гемморой от специальных "извратов".
> DAS>Что есть динамическая типизация? Это когда до моменти исполнения нельзя > DAS>сказать какого типа значение будет присвоено данной переменной ? > > Ну хотяб вики посмотри чтоль.
Извини, а это не то же самое что я сказал? Оно же, если я не ошибаюсь,
называется late/early binding.
Здравствуйте, DemAS, Вы писали:
DAS>"Курилка" <1546@users.rsdn.ru> writes:
>> DAS>Что есть динамическая типизация? Это когда до моменти исполнения нельзя >> DAS>сказать какого типа значение будет присвоено данной переменной ? >> >> Ну хотяб вики посмотри чтоль.
DAS>Извини, а это не то же самое что я сказал? Оно же, если я не ошибаюсь, DAS>называется late/early binding.
Ты задал вопрос, что это есть такое, вот и дал самую элементарную ссылку, которую можно было посмотреть, чтобы узнать.
Раннее/позднее связывание это лишь подробности разрешния имён, но к топику как-то это совсем отношения не имеет.
Здравствуйте, DemAS, Вы писали:
>> чистая функция — это функция в математическом смысле этого слова
DAS>Хороший пример ответа, когда вроде ответил, а топикстартеру понятнее не стало.
Имеются в виду 2 вещи: результат функции зависит только от ее параметров, функция занимается исключительно вычислением своего результата.
Вопрос с побочными эффектами не так прост. Например, в ленивом чистом языке функция может использовать значение переданного ей ленивого аргумента, а может не использовать. В первом случае произойдет его вычисление и обновится его внутренее представление (была некоторая функция, стал резльтат ее вычисления), в каком-то смысле это тоже побочный эффект.
PM>>Теоретически можно, если для операций с побочными эффектами ввести специальные синтаксические конструкции. К>Т.е. есть какие-то примеры подобного?
Haskell, do notation.
К>Ну и вопрос будет ли стоить овчинка выделки, в смысле получим ли мы реальные бенефиты и будут ли они больше чем дополнительный гемморой от специальных "извратов".
На этот счёт есть разные мнения.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Здравствуйте, thesz, Вы писали:
PM>>>Теоретически можно, если для операций с побочными эффектами ввести специальные синтаксические конструкции. К>>Т.е. есть какие-то примеры подобного?
T>Haskell, do notation.
Это ответ на "как-то контролировать чистоту для языка с динамической типизацией"?
Или я что-то не понял или одно из двух...
Здравствуйте, Курилка, Вы писали:
К>>>... да и как-то не очень представляю можно ли как-то контролировать чистоту для языка с динамической типизацией... PM>>Теоретически можно, если для операций с побочными эффектами ввести специальные синтаксические конструкции.
К>Ну в теории теория не отличается от практики
А кто говорил о практике? Ты сказал дословно "не очень представляю можно ли как-то.." — очевидно, как-то можно. thesz ниже совершенно правильно предложил do-нотацию как вариант _синтаксиса_.
На практике, конечно, смысла мало — приверженцы динамики не оценят.
Здравствуйте, palm mute, Вы писали:
PM>Здравствуйте, Курилка, Вы писали:
К>>>>... да и как-то не очень представляю можно ли как-то контролировать чистоту для языка с динамической типизацией... PM>>>Теоретически можно, если для операций с побочными эффектами ввести специальные синтаксические конструкции.
К>>Ну в теории теория не отличается от практики PM>А кто говорил о практике? Ты сказал дословно "не очень представляю можно ли как-то.." — очевидно, как-то можно. thesz ниже совершенно правильно предложил do-нотацию как вариант _синтаксиса_.
Дак как оно выглядеть будет не столько интересно, интересно скорее, как оно будет работать. Do нотация требует монаду, которая определяется в компайл-тайме (да и существует тоже по ходу тамже), а что в случае динамической типизации будешь делать?.
Здравствуйте, Курилка, Вы писали:
К> Do нотация требует монаду
Это в Хаскеле она требует монаду, т.к. рассахаривается в вызовы перегруженных функций (>>=) и return. Вполне можно представить себе язык, поддерживающий только одну монаду — IO — и транслирующий do-нотацию соответствующим образом.
Здравствуйте, palm mute, Вы писали:
PM>Здравствуйте, Курилка, Вы писали:
К>> Do нотация требует монаду PM>Это в Хаскеле она требует монаду, т.к. рассахаривается в вызовы перегруженных функций (>>=) и return. Вполне можно представить себе язык, поддерживающий только одну монаду — IO — и транслирующий do-нотацию соответствующим образом.
Чувствую полноценного ответа ожидать не приходится...
Ну скажи как твоя только одна монада будет (цитирую изначальную проблему, которую я высказал) "контролировать чистоту для языка"?
Здравствуйте, Курилка, Вы писали:
К>Ну скажи как твоя только одна монада будет (цитирую изначальную проблему, которую я высказал) "контролировать чистоту для языка"?
я гнева вашего никак не растолкую...
самое простое — запрет на вызов процедур (имеющих побочные эффекты) из функций. и всё. даже никаких спец. синт. конструкций не понадобится
Люди, я люблю вас! Будьте бдительны!!!
Re[7]: proof of concept (очередной игрушечный интерпретатор)
Здравствуйте, palm mute, Вы писали:
PM>Здравствуйте, Курилка, Вы писали:
К>>Дак как оно выглядеть будет не столько интересно, интересно скорее, как оно будет работать. Do нотация требует монаду, которая определяется в компайл-тайме (да и существует тоже по ходу тамже), а что в случае динамической типизации будешь делать?.
PM>Хоть и вряд ли кто-то захочет в горе кода без комментариев разбираться, но тем не менее, вот он, чисто-функциональный динамически-типизированный язык с do-нотацией.
[cut]
Клёва, только контроля нету
Хотя прикрутить, конечно можно
Здравствуйте, BulatZiganshin, Вы писали:
BZ>Здравствуйте, Курилка, Вы писали:
К>>Ну скажи как твоя только одна монада будет (цитирую изначальную проблему, которую я высказал) "контролировать чистоту для языка"?
BZ>я гнева вашего никак не растолкую...
BZ>самое простое — запрет на вызов процедур (имеющих побочные эффекты) из функций. и всё. даже никаких спец. синт. конструкций не понадобится
Дак собственно к этому я и вёл, задавал-то я вопрос по поводу контроля, а не по поводу синтаксиса.
Ну логично, что если поделить функции на чистые/грязные, то проконтролировать несложно.
Здравствуйте, Курилка, Вы писали:
К>Чувствую полноценного ответа ожидать не приходится... К>Ну скажи как твоя только одна монада будет (цитирую изначальную проблему, которую я высказал) "контролировать чистоту для языка"?
Можно ввести новый тип значений — действия.
При выполнении блока "do { x <- expr1; expr2(x) }" интерпретатор проверяет (в рантайме) что expr1 и expr2(x) возвращают действия, точно так же как при вычислении выражения "e1 + e2" он проверяет, что e1 и e2 возвращают числа, вполне в духе динамических языков. Этот вариант реализован в интерпретаторе в сообщении выше.
Можно было пойти чуть дальше и сделать так, что грязная программа будет просто синтаксически некорректной, в моем интерпретаторе для этого нужно ввести понятие процедуры с аргументами.
Re[8]: proof of concept (очередной игрушечный интерпретатор)
Здравствуйте, Курилка, Вы писали:
К>Клёва, только контроля нету
Ну почему же нету — есть, но он в рантайме. Есть важное различие между отсутствием контроля и контролем в рантайме — в первом случае ты можешь написать программу, которая будет использовать функции с побочными эффектами и делать что-то полезное, во втором случае программа будет падать, и программист буде вынужден ее переписать в чистом стиле.
К>Хотя прикрутить, конечно можно
Ну если к текущему варианту прикрутить контроль, это получится некая вырожденная система типов, и язык будет уже не совсем динамическим. Но, как я говорил, осталось сделать полшага, чтобы грязные программы обнаруживались парсером как синтаксические ошибки.
Здравствуйте, palm mute, Вы писали:
PM>Здравствуйте, Курилка, Вы писали:
К>>Чувствую полноценного ответа ожидать не приходится... К>>Ну скажи как твоя только одна монада будет (цитирую изначальную проблему, которую я высказал) "контролировать чистоту для языка"?
PM>Можно ввести новый тип значений — действия. PM>При выполнении блока "do { x <- expr1; expr2(x) }" интерпретатор проверяет (в рантайме) что expr1 и expr2(x) возвращают действия, точно так же как при вычислении выражения "e1 + e2" он проверяет, что e1 и e2 возвращают числа, вполне в духе динамических языков. Этот вариант реализован в интерпретаторе в сообщении выше.
PM>Можно было пойти чуть дальше и сделать так, что грязная программа будет просто синтаксически некорректной, в моем интерпретаторе для этого нужно ввести понятие процедуры с аргументами.
А в реальности не знаешь, кто-нибудь таким извратом занимался?
Я вот только недоделанный (вроде) fun вспомнил.
Re[9]: proof of concept (очередной игрушечный интерпретатор)
Здравствуйте, palm mute, Вы писали:
PM>Здравствуйте, Курилка, Вы писали:
К>>Клёва, только контроля нету PM>Ну почему же нету — есть, но он в рантайме. Есть важное различие между отсутствием контроля и контролем в рантайме — в первом случае ты можешь написать программу, которая будет использовать функции с побочными эффектами и делать что-то полезное, во втором случае программа будет падать, и программист буде вынужден ее переписать в чистом стиле.
Наверное я слепой, покажи где именно твой контроль?
Плюс процедуры (они же грязные функции) определять разве можно?
К>>Хотя прикрутить, конечно можно PM>Ну если к текущему варианту прикрутить контроль, это получится некая вырожденная система типов, и язык будет уже не совсем динамическим. Но, как я говорил, осталось сделать полшага, чтобы грязные программы обнаруживались парсером как синтаксические ошибки.
Я про контроль в рантайме имел в виду, конечно же.
Re[9]: proof of concept (очередной игрушечный интерпретатор)
Здравствуйте, palm mute, Вы писали:
PM>Здравствуйте, Курилка, Вы писали:
К>>Клёва, только контроля нету PM>Ну почему же нету — есть, но он в рантайме. Есть важное различие между отсутствием контроля и контролем в рантайме — в первом случае ты можешь написать программу, которая будет использовать функции с побочными эффектами и делать что-то полезное, во втором случае программа будет падать, и программист буде вынужден ее переписать в чистом стиле.
посылаю седеющую голову пеплом — просмотрел
Re[10]: proof of concept (очередной игрушечный интерпретатор
Здравствуйте, Курилка, Вы писали:
К>Наверное я слепой, покажи где именно твой контроль? К>Плюс процедуры (они же грязные функции) определять разве можно?
Ты "тесты" в конце видел? Там выражение print(action(42) + 5) падает с ошибкой.
Re[11]: proof of concept (очередной игрушечный интерпретатор
Здравствуйте, palm mute, Вы писали:
PM>Здравствуйте, Курилка, Вы писали:
К>>Наверное я слепой, покажи где именно твой контроль? К>>Плюс процедуры (они же грязные функции) определять разве можно? PM>Ты "тесты" в конце видел? Там выражение print(action(42) + 5) падает с ошибкой.
Здравствуйте, Курилка, Вы писали:
К>А в реальности не знаешь, кто-нибудь таким извратом занимался?
Не знаю, не думаю, что это кому-нибудь нужно. Как я понимаю, "динамики" не признают статического контроля вообще (не считая проверки синтаксиса), потому зачем им такая вырожденная форма контроля — ума не приложу. С другой стороны, есть же динамически типизированные DSL вообще без ввода/вывода, там и контролировать ничего не надо.
Здравствуйте, thesz, Вы писали:
К>>А в реальности не знаешь, кто-нибудь таким извратом занимался? К>>Я вот только недоделанный (вроде) fun вспомнил.
T>Этот?
Т. е. изобрели какой-то ключик, отключающий проверку типов в хаскеле до рантайма?
Если нет, то к чему твоя реплика, ибо речь шла о динамической типизации?
Re[10]: proof of concept (очередной игрушечный интерпретатор
Здравствуйте, thesz, Вы писали:
T>Проверку типов можно реализовать в виде двухуровневых грамматик (они же грамматики ван Вийнгаардена). И встроить в разборщик.
вывод типов примерно так и выглядит. тот же q-lang — скриптовый язык, но основанный на inference вместо динамики. да и сам haskell хорош в качестве скриптового языка
Здравствуйте, thesz, Вы писали:
BZ>>самое простое — запрет на вызов процедур (имеющих побочные эффекты) из функций. и всё. даже никаких спец. синт. конструкций не понадобится
T>Если серьёзно, то твоё запрещение и реализуется через синтаксическое ограничение.
в конечном счёте ты прав, но как бы никакого нового синтаксиса не нужно
Здравствуйте, thesz, Вы писали:
T>Отложи проверку типов в Хаскеле до выполнения программы, получишь то, что нужно. "Ввод-вывод может производиться только в аргументах функции >>=, или в рамках do-выражения."
в хаскеле не проверка, а вывод типов. и тип результата, к примеру, может определять тип аргументов функции
Здравствуйте, BulatZiganshin, Вы писали:
BZ>в хаскеле не проверка
<буквоед mode>
не всегда, расширения GHC сплошь и рядом требуют аннотаций
</буквоед mode>
T>>Если серьёзно, то твоё запрещение и реализуется через синтаксическое ограничение. BZ>в конечном счёте ты прав, но как бы никакого нового синтаксиса не нужно
Да ты что!
Ещё скажи, что синтаксические правила не поменялись.
Было
function ::= proc_func_header '::' type_expr 'begin' statement 'end' ';'
стало
function ::= proc_func_header '::' type_expr 'begin' func_statement 'end' ';'
где func_statement, в отличии от обычного statement, не содержит вызова процедуры.
Это ли не новый синтаксис?
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
T>>Этот? К>Т. е. изобрели какой-то ключик, отключающий проверку типов в хаскеле до рантайма? К>Если нет, то к чему твоя реплика, ибо речь шла о динамической типизации?
Вообще, я дурачусь.
Если же быть чуть более серьёзным, то Хаскель — это единственный широко распространённый язык, где есть синтаксис для ввода-вывода.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[11]: proof of concept (очередной игрушечный интерпретатор
BZ>вывод типов примерно так и выглядит. тот же q-lang — скриптовый язык, но основанный на inference вместо динамики. да и сам haskell хорош в качестве скриптового языка
ТЫ кого-то с кем-то путаешь.
q-lang не содержит никакого inference. Или поделись ссылкой, о которой я не знаю.
Вывод типов так выглядит в Хелиуме, это достаточно накладно, выводить типы синтаксически.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[12]: proof of concept (очередной игрушечный интерпретатор
Здравствуйте, thesz, Вы писали:
BZ>>вывод типов примерно так и выглядит. тот же q-lang — скриптовый язык, но основанный на inference вместо динамики. да и сам haskell хорош в качестве скриптового языка
T>ТЫ кого-то с кем-то путаешь.
DAS>А как же Pid ! {} и receive в Erlang? Правильно ли я понимаю, что это как DAS>раз и есть тот побочный эффект, про который пишет Влад?
Да, так и есть — функция, отправляющая или принимающая сообщение, является "грязной". Об этом пишет Joe Armstrong в Armstrong thesis 2003 (pdf), глава 8.3:
To simplify matters I say that a function is dirty if it sends or receives a message or if it calls one of the following Erlang BIFs: apply, cancel_timer, check_process_code, delete_module, demonitor, disconnect_node, erase, group_leader, halt, link, load_module, monitor_node, open_port, port_close, port_command, port_control, process_flag, processes, purge_module, put, register, registered, resume_process, send_nosuspend, spawn, spawn_link, spawn_opt, suspend_process, system_flag, trace, trace_info, trace_pattern, unlink, unregister, yield.