1936
Общий раздел / Re:Оберон в образовании.
« : Февраль 25, 2011, 06:24:41 am »А что Вы подразумеваете под функциями высшего порядка? Полиномы N-ой степени?Функции, оперирующие другими функциями.
Онлайн компилятор Oberon-07/11
Путеводитель по Оберон-проектам.
Логи jabber-конференции.
Онлайн исходники BlackBox: тут:WeBB и на github
Исходники Project Oberon V4 на github.
Сборник решений задач книги "Современное программирование с нуля!" тут. А обсуждение здесь.
В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.
А что Вы подразумеваете под функциями высшего порядка? Полиномы N-ой степени?Функции, оперирующие другими функциями.
Хех, так ведь один из авторов Хаскелла (Simon Peyton Jones) утверждает, что:Это же Хаскелл!К сожалению (или к счастью), я - убеждённый императивщик. :-) Во всяком случае, пока.
Проблему, на мой взгляд, можно решить введя в язык следующие правила:Это же Хаскелл!
1. Внутри функции глобальные (по отношению к ней) переменные доступны только для чтения.
2. Параметры, передаваемые в функцию по ссылке, доступны внутри функции только для чтения.
3. Внутри функции запрещено использовать вызов процедур.
И хватит благостной говорильни о вреде побочного эффекта
Не проще ли просто стремится к тому, чтобы процедуры/функции не изменяли что-то глобальное?Если процедура не меняет ничего глобального (в том числе -- и ввод/вывод), то толку от неё нет, только процессорное время зря тратит. Зачем она нужна?
Согласен с Ильёй. OUT-параметры вполне органично могут применяться и безболезненно применяются. Неприязнь к ним - просто особенность восприятия или привычка конкретных людей.OUT-параметры -- лишняя и бессмысленная сущность. Если процедура возвращает какие-то результаты в OUT-параметрах, то пусть она будет оформлена как функция, возвращающая кортеж из нескольких значений.
Кроме того, сама природа функций подразумевает в большинстве случаев возможность не возвратить корректный результат, так что математическая нотация в случае корректной работы с подпрограммами не может использоваться часто.такие функции должны возвращать результат типа Есть_корректный_результат/Нет_корректного_результата или Есть_корректный_результат/Код_ошибки_такой-то.
Ну вот мой пример:Однако иногда жалею, что в том же C# нет даже простых сишных макросов -- иногда они позволили бы не делать тупой копи-паст.Ну так и приведите пример. Мне, например, не приходилось жалеть.
И, кстати, где эти примеры на Лиспе с уменьшением размера кода в 20 раз?
if (obj1[i].abracadabra1 != obj2[i].other_abracadabra1)
{
какие-то действия с obj1[i].abracadabra1:
obj1[i].abracadabra1 = obj2[i].other_abracadabra1;
какие-то другие действия с obj1[i].abracadabra1:
}
if (obj1[i].abracadabra2 != obj2[i].other_abracadabra2)
{
какие-то действия с obj1[i].abracadabra2:
obj1[i].abracadabra2 = obj2[i].other_abracadabra2;
какие-то другие действия с obj1[i].abracadabra2:
}
if (obj1[i].abracadabra3 != obj2[i].other_abracadabra3)
{
какие-то действия с obj1[i].abracadabra3:
obj1[i].abracadabra3 = obj2[i].other_abracadabra3;
какие-то другие действия с obj1[i].abracadabra3:
}
if (obj1[i].abracadabra4 != obj2[i].other_abracadabra4)
{
какие-то действия с obj1[i].abracadabra4:
obj1[i].abracadabra4 = obj2[i].other_abracadabra4;
какие-то другие действия с obj1[i].abracadabra4:
}
if (obj1[i].abracadabra5 != obj2[i].other_abracadabra5)
{
какие-то действия с obj1[i].abracadabra5:
obj1[i].abracadabra5 = obj2[i].other_abracadabra5;
какие-то другие действия с obj1[i].abracadabra5:
}
Типы у этих abracadabra1..abracadabra5 -- разные, не совместимые (в смысле нет там наследований всяких).#define do_what_we_need(obj1,obj2) \\
if (obj1 != obj2) \\
{ \\
какие-то действия с obj1: \\
\\
obj1 = obj2; \\
\\
какие-то другие действия с obj1; \\
}
do_what_we_need(obj1[i].abracadabra1, obj2[i].other_abracadabra1);
do_what_we_need(obj1[i].abracadabra2, obj2[i].other_abracadabra2);
do_what_we_need(obj1[i].abracadabra3, obj2[i].other_abracadabra3);
do_what_we_need(obj1[i].abracadabra4, obj2[i].other_abracadabra4);
do_what_we_need(obj1[i].abracadabra5, obj2[i].other_abracadabra5);
То, что в списке все элементы одного типа -- скорее достоинство, чем недостаток -- проверка типов во время компиляции чаще полезна, чем неудобна.А Грейхем про него вообще что-то знает? :-)Почему-то у меня отложилось в памяти, что он считает недостатком требование, чтобы в списке все элементы были одного типа. Но сейчас не смог этого найти.
Может я все переврал и возвел напраслину?...
Да, я наверное неточно выразился. Хотел поправиться, что дело в функциональности языка, но потом вспомнил, что в том же смоллтоке будет выглядеть примерно так же, как и в хаскелле.Но Хаскелл -- ленивый язык, в нём такие фокусы проходят.А кстати, как тут помогает ленивость? Я не вижу проблем сделать то же самое на энергичном языке с замыканиями.
Во-вторых, можете привести пример гениального использования макросов? Типа, а вот здесь языки без макросов сосут.В C# есть оператор using, который, в частности, позволяет автоматически закрывать файл после того, как с ним будет проведена какая-то работа:
// точно на память работу с файлами в .NET не помню,
// просто пример как это может выглядеть
using (File file = File.Open("filename.txt"))
{
// что-то делаем с файлом file
} // тут он автоматически закрывается
Когда в С# не было этого оператора (вроде когда-то его не было, может ошибаюсь), приходилось (да и теперь в том же С или Обероне приходится) закрывать файл вручную. Естественно, можно было по запарке забыть это дело сделать.; условный синтаксис:
(defmacro with-open-file (file filename body)
(let (,file (open-file filename)
,@body
(close-file ,file))))
; пример использования:
(with-open-file file "filename.txt"
( ; что-то делаем с файлом file
)) ; тут он автоматически закрывается
Ну, в некоторых языках некоторые возможности макросов можно реализовать и без макросов. Например, в Хаскелле:with_open_file :: FilePath -> IOMode -> (Handle -> IO a) -> IO a
with_open_file filename mode action = do
fhnd <- openFile filename mode
result <- action fhnd
hClose fhnd
return result
-- Пример использования
do ...
with_open_file "filename.txt" ReadMode $ \\file -> do
... -- что-то делаем с файлом file
-- тут он автоматически закрывается
Но Хаскелл -- ленивый язык, в нём такие фокусы проходят.Здесь уже обсуждали http://forum.oberoncore.ru/viewtopic.php?f=61&t=1914&hilit=%D0%BC%D0%B0%D0%BA%D1%80%D0%BE%D1%81Скажите, в чём принципиальное отличие макросов от подпрограмм, кроме того, что макросы работают во время компиляции, а подпрограммы -- во время выполнения программы?
Отрицательное отношение к макросам я с тех пор не изменил.
module Main where
type GS = (Integer, Integer)
instance Num GS where
(a, b) * (c, d) = (a*(c+d) + b*c, a*c + b*d)
fib n = fst $ ((1, 0)::GS) ^ n
main = do
putStrLn $ take 10 $ show $ fib 1000000
А чем, собственно, зацикливание отличается от просто очень долгого алгоритма? С точки зрения конечного результата в виде "зависания".Ну, очень долгий алгоритм в конце концов всё же завершится с каким-то результатом, а зацикливание типа "10 GOTO 10" не завершится никогда.