Oberon space
General Category => Общий раздел => Тема начата: vlad от Март 09, 2011, 02:41:10 pm
-
Про идеальный ЯП поговорили. Давайте про реальный: чего нужно допилить в КП (как наиболее "реальном" обероне) лично для вас, чтобы можно было его использовать вместо вашего текущего ЯП для текущих задач (если бы все пришлось писать заново). Оставим за скобками инфраструктуру (библиотеки, IDE и т.д.) - только сам язык. Вот мой список (в порядке уменьшения значимости):
1.Параллельные вычисления. Не знаю в каком виде, но нечто более высокоуровневое, нежели "вот вам стандартный мьютекс - а дальше вы сами разбирайтесь". ActiveOberon - тоже слишком низкоуровнево. Как минимум, на уровне языка должны быть полностью решены проблемы конкурентной модификации данных.
2. Обработка ошибок. Что-нибудь более продвинутое, чем явное таскание кода ошибки.
3. Обобщенное программирование. Хотя бы на уровне контейнеров и алгоритмов. Чтобы не изобретать в 10 раз за день список и не писать WHILE там, где на самом деле foreach.
4. Замыкания. Принципиально упрощают код, по сравнению с закатами солнца вручную.
5. Что-то для работы с ресурсами в scope (хотя бы аналог шарпового using).
6. Объявление переменных по месту. Писать с допотопным VAR'ом я уже не смогу :)
7. Синтаксис. Ну да, можно скрипеть зубами, писать КАПСОМ и расставлять все эти точки с запятой. Но после питона от нового языка хочется чего-нибудь человеческого.
P.S. Кстати, питон удовлетворяет этому списку, за исключением пункта 1. Ну и динамической типизации :) Есть еще хаскель... :) Но хотелось бы пойти от базового, понятного и простого.
-
Мой список (в предположении что популярности КП быстро не достигнуть, а реальные ресурсы на проработку ограничены):
1. Возможность возвращение функцией записи (а не указателя). не фиг плодить сущности где это не требуется...
2. Массивы индексируемые с 1...(untagged с 0) - язык должен быть дружественным к начинающим...
3. Либо убрать repeat until, либо заменить его на do while (без инверсии условия продолжения).
-
Мой список (в предположении что популярности КП быстро не достигнуть, а реальные ресурсы на проработку ограничены):
1. Возможность возвращение функцией записи (а не указателя). не фиг плодить сущности где это не требуется...
2. Массивы индексируемые с 1...(untagged с 0) - язык должен быть дружественным к начинающим...
3. Либо убрать repeat until, либо заменить его на do while (без инверсии условия продолжения).
ИМХО массивы не с 0 - однозначное зло :) Или это уже не массив, а что-то более конкретное с конкретным индексом. Сколько с таким сталкивался... даже в С++ где можно обложить все это типами, чтобы не выстрелить в ногу - только головная боль. Или массив и 0 или не массив и итератор/ключ.
-
ИМХО массивы не с 0 - однозначное зло :) Или это уже не массив, а что-то более конкретное с конкретным индексом. Сколько с таким сталкивался... даже в С++ где можно обложить все это типами, чтобы не выстрелить в ногу - только головная боль. Или массив и 0 или не массив и итератор/ключ.
Интересно.... Пояснить свою точку зрения сможете ? Я свою - могу...
-
1. Возможность возвращение функцией записи (а не указателя). не фиг плодить сущности где это не требуется...
Сейчас, вроде, сделано так, что все функции всегда возвращают результат в регистрах проца. Если разрешить функциям возвращать записи, то этой эффективной реализации придёт кирдык. :)
2. Массивы индексируемые с 1...(untagged с 0) - язык должен быть дружественным к начинающим...
Не по-программерски это как-то :) Начинающие пусть привыкают.
-
Господа, у меня есть предложение... в эту ветку кидать только предложения , о каламбур, однако, - для обсуждения их заведем отдельную(ые) ветки. Пусть те кто предлагает и отвечают за свой "базар" ;) так будет веселе да и полезнее...
-
ИМХО массивы не с 0 - однозначное зло :) Или это уже не массив, а что-то более конкретное с конкретным индексом. Сколько с таким сталкивался... даже в С++ где можно обложить все это типами, чтобы не выстрелить в ногу - только головная боль. Или массив и 0 или не массив и итератор/ключ.
Интересно.... Пояснить свою точку зрения сможете ? Я свою - могу...
Эти единицы будут везде лезть - где-то с плюсом, где-то с минусом.
offset = index2 - index1;
array[offset]; // вот здесь будет артефактная 1
-
Господа, у меня есть предложение... в эту ветку кидать только предложения , о каламбур, однако, - для обсуждения их заведем отдельную(ые) ветки. Пусть те кто предлагает и отвечают за свой "базар" ;) так будет веселе да и полезнее...
Принимается.
-
Фичи… Хм… Ну попробую перечислить просто фичи:
1. обобщенное программирование (хотя бы на уровне дженериков).
2. человеческий bit syntax для разбора бинарей (правильный bit syntax можно посмотреть в erlang'e).
3. возможность анотирования метаинформацией как минимум всего того, что может экспортировать модуль.
4. явное наличие в языке интерфейсов (спецификаций) модулей. чтобы можно было явно сказать, что вот этот модуль удовлетворяет вот такой-то спецификации. Сейчас по сути типизация модулей утиная.
5. максимум дополнительных сложностей для создания глобальных переменных в модулях (инструмент должен провоцировать не ошибки, а правильные решения).
6. многопоточность
7. явно прописанное поведение при возникновение таких например ситуаций как деление на ноль, выход за границу массива, целочисленное переполнение.
8. foreach
9. вообще синтаксис причесать. капс убрать, многие точкизапятые тоже явно лишние.
Пункты 1 и 2 (а также горстка других, здесь не упомянутых, например возможность проверки на корректность построения того же конечного автомата на этапе компиляции) легко решаются, если сделать возможность написания модулей расширения для компилятора с явным синтаксисом. Я пока не готов сформулировать как конкретно это должно смотреться синтаксически.
-
А кстати, что допиливаем – Оберон, Оберон-2, КП, Оберон-07, Active Oberon, Zonnon, MiniComponent Pascal? :-)
-
А кстати, что допиливаем – Оберон, Оберон-2, КП, Оберон-07, Active Oberon, Zonnon, MiniComponent Pascal? :-)
Давайте КП. Потому что в нем лишнего вроде как нет. Остальные менее популярны.
-
Я ещё предложил бы совместить внешние границы областей видимости с границами соответствующих блоков. И заодно уж убрать опережающие объявления процедур.
-
Мой список (в предположении что популярности КП быстро не достигнуть, а реальные ресурсы на проработку ограничены):
1. Возможность возвращение функцией записи (а не указателя). не фиг плодить сущности где это не требуется...
2. Массивы индексируемые с 1...(untagged с 0) - язык должен быть дружественным к начинающим...
3. Либо убрать repeat until, либо заменить его на do while (без инверсии условия продолжения).
1 - возможно, да.
3 - убрать.
2 - vlad пояснил, почему нельзя. Совершенно невменяемой арифметика смещений становится, все нормальные "взрослые" рефлексы летят нафиг. Мягкость для начинающих - это одно, но нельзя вырабатывать неправильные рефлексы.
Пример невменяемости арифметики смещений: представьте себе кольцевой буфер и "закольцовку" смещения операцией MOD. MOD ведёт себя как раз по схеме "нумерации с нуля".
-
Мой список (в предположении что популярности КП быстро не достигнуть, а реальные ресурсы на проработку ограничены):
1. Возможность возвращение функцией записи (а не указателя). не фиг плодить сущности где это не требуется...
2. Массивы индексируемые с 1...(untagged с 0) - язык должен быть дружественным к начинающим...
3. Либо убрать repeat until, либо заменить его на do while (без инверсии условия продолжения).
1. IMHO - нормально. Получаем запись по значению, и возвращаем запись по значению.
Правда надо думать про передачу и возврат по ссылке или по указателю.
Ибо если передаем var, то var нужно уметь и возвращать.
Если же передаем указатель, то и возвращаем указатель (привет Си... :) )
2. Не... Я - против. Это дело привычки. В конце-концов, программирование - это специфическая деятельность. Запоминают же водители, что вперед нажимать: газ или сцепление. Так и тут. Тем более, что сейчас практически повсеместно уже массивы индексируются с нуля. Это - смещение, а не номер. Так и объяснять с самого начала.
3. А вот это - очень правильно. Вычисление условий во всех циклах должно быть единообразным.
-
Фичи… Хм… Ну попробую перечислить просто фичи:
1. обобщенное программирование (хотя бы на уровне дженериков).
2. человеческий bit syntax для разбора бинарей (правильный bit syntax можно посмотреть в erlang'e).
3. возможность анотирования метаинформацией как минимум всего того, что может экспортировать модуль.
4. явное наличие в языке интерфейсов (спецификаций) модулей. чтобы можно было явно сказать, что вот этот модуль удовлетворяет вот такой-то спецификации. Сейчас по сути типизация модулей утиная.
5. максимум дополнительных сложностей для создания глобальных переменных в модулях (инструмент должен провоцировать не ошибки, а правильные решения).
6. многопоточность
7. явно прописанное поведение при возникновение таких например ситуаций как деление на ноль, выход за границу массива, целочисленное переполнение.
8. foreach
9. вообще синтаксис причесать. капс убрать, многие точкизапятые тоже явно лишние.
Пункты 1 и 2 (а также горстка других, здесь не упомянутых, например возможность проверки на корректность построения того же конечного автомата на этапе компиляции) легко решаются, если сделать возможность написания модулей расширения для компилятора с явным синтаксисом. Я пока не готов сформулировать как конкретно это должно смотреться синтаксически.
1. Шаблон модуля с параметром типов - минимально необходимая конструкция.
2. Короче, нормальный битовый тип со всеми битовыми операциями. И возможностью преобразования целые и обратно. Да?
3-4. Пока не знаю.
5. Видимость на уровне модуля. Или отдельный модуль с глобальными переменными. То есть объявление модуля типа специальным только для глобальных объектов
6. Модуль = процесс, процедура модуля - тред.
7. То есть обработка исключительных ситуаций.
8. Шаблон функции?
-
По поводу нумерации элементов массивов. Попрограммировав чуток на Fortran я пришёл к выводу, что в Fortran всё правильно сделано. И в старом-добром Pascal тоже. То есть как захотель - так и пронумеровал. Хочу с 0, хочу с 1, хочу с -100.
Тут вот какое дело. С нуля да, нужно бывает. Когда нужны массивы. Это чёрти знает что, на самом деле, эти массивы. Тут таки всплывает это ваше смещение. Вот когда нужно это смещение - это массивы. И нужно нумеровать с 0.
Но! Часто (и неимоверно часто в Fortran) массивы = матрицы. И в любом учебнике математики все формулки предполагают нумерацию с 1. Для матриц это естественно и удобно. Это математическая абстракция, машинное представление тут идёт лесом. По-умолчанию, в Fortran с 1. В Pascal, вроде, тоже.
А ещё бывает удобно и с -100500 нумеровать.
Так что эти ваши машинные штучки со смещениями... Есть многое на свете, друг Горацио...
-
6. Модуль = процесс, процедура модуля - тред.
Это как?
-
4. явное наличие в языке интерфейсов (спецификаций) модулей. чтобы можно было явно сказать, что вот этот модуль удовлетворяет вот такой-то спецификации. Сейчас по сути типизация модулей утиная.
А зачем?
-
6. Модуль = процесс, процедура модуля - тред.
Это как?
Ну, типа специальное слово parallel j,ъявляет модуль процессом. Тогда запускаемая из него процедура - это тред. В смысле Windows. Только механизмы синхронизации должны быть спрятаны за кулисами - по одному только слову parallel все должно корректно работать.
-
Я слабо представляю как кусок кода может быть процессом.
Для процесса можно указать точку входа в коде, но модуль процессом быть не может, равно как и процедура.
-
Я слабо представляю как кусок кода может быть процессом.
Может быть имелось в виду не "процессом", а "потоком"? ::)
Но и в этом случае вопрос реализации остаётся открытым.
-
Процесс, поток… Какая разница?
-
Вроде как у процесса может быть несколько потоков.
С запущенной программой связан один процесс. Программа может быть многопоточной.
По умолчанию для процесса создаётся один поток. Если нужно больше, то ручками.
Типа, ликбез? :D
Можно ещё нити (волокна) упомянуть.
Вообще, я в этой теме плотно не сижу. Можно у Рихтера посмотреть. Или здесь более опытные товарисчи подскажут :)
-
Я к тому, что для обсуждаемого вопроса разница между процессом и потоком не играет значения. А процесс от потока отличается прежде всего изолированностью памяти.
-
Как я уже писал выше, дополнительные потоки создаются вручную, путём вызова соответсвующих функций WinAPI (если речь о винде). Суть предложения Валерия Лаптева я понял так, что эти вызовы будут встаиваться самим компилятором. Нужен новый поток в приложении?, - пометил модуль ключевым словом PARALLEL, и всё! Если я не так понял, пусть Валерий меня поправит.
Вот и связь с обсуждаемым вопросом ;) С процессами этот фокус точно не пройдёт.
-
Почему же? Вполне пройдет. Запустится просто отдельный процесс с которым взаимодействие будет автоматически организовано через какое-нибудь IPC. Разницы тут как раз особой нет.
-
4. явное наличие в языке интерфейсов (спецификаций) модулей. чтобы можно было явно сказать, что вот этот модуль удовлетворяет вот такой-то спецификации. Сейчас по сути типизация модулей утиная.
А зачем?
В экосистеме КП/ББ не принято иметь несколько версий одного модуля. Т.е. традиционная для модульных языков вариантивность на уровне "1 спецификация модуля - несколько реализаций" (вполне неплохая по-своему) ушла в прошлое, уступив место объектно-ориентированным разъёмам, когда функцию интерфейса выполняет один модуль, и в нём же объявлен тип разъёма, а функцию реализации выполняют другие модули, с различными именами, динамически загружаемые и втыкающие свои разъёмы. Это более сильный и общий подход - динамическое подключение реализаций, много реализаций одновременно, не нужна перекомпиляция и т.п. Т.е. как бы мета-подход, который снимает с уровня самих модулей некоторую старую смысловую нагрузку. Отсюда же утрата прежнего значения отдельной спецификации модуля.
-
[quote author=vlad link=topic=26
В экосистеме КП/ББ не принято иметь несколько версий одного модуля. Т.е. традиционная для модульных языков вариантивность на уровне "1 спецификация модуля - несколько реализаций" (вполне неплохая по-своему) ушла в прошлое, уступив место объектно-ориентированным разъёмам, когда функцию интерфейса выполняет один модуль, и в нём же объявлен тип разъёма, а функцию реализации выполняют другие модули, с различными именами, динамически загружаемые и втыкающие свои разъёмы. Это более сильный и общий подход - динамическое подключение реализаций, много реализаций одновременно, не нужна перекомпиляция и т.п. Т.е. как бы мета-подход, который снимает с уровня самих модулей некоторую старую смысловую нагрузку. Отсюда же утрата прежнего значения отдельной спецификации модуля.
Не, не улавливаю. Чем это принципиально отличается от классических ООП интерфейсов? Сколько угодно модулей могут реализовать заданный интерфейс и т.д. по списку.
-
Интерфейс явно специфицирован, объявлением типа.
Это к замечанию Алексея о том, что нет типизации для модулей.
-
Все привет!
Когда работал над AGG, мне сильно не хватало битовой арифметики с возможностью простого приведения численных типов.
В принципе, при манипуляции с битами часто численное значение не интересно, поэтому охрана численного типа не особо важна. Важна размерность данных: 1, 2, 4, ... 64 бита. Ну и возможность группами битов/отдельными битами манипулировать.
-
Ну я и говорю. битсинтаксис аля erlang. Ибо кошерно уж дюже. И ошибок позволяет избежать.
-
Как я уже писал выше, дополнительные потоки создаются вручную, путём вызова соответсвующих функций WinAPI (если речь о винде). Суть предложения Валерия Лаптева я понял так, что эти вызовы будут встаиваться самим компилятором. Нужен новый поток в приложении?, - пометил модуль ключевым словом PARALLEL, и всё! Если я не так понял, пусть Валерий меня поправит.
Вот и связь с обсуждаемым вопросом ;) С процессами этот фокус точно не пройдёт.
Как раз с процессами и пройдет. Только нужно этот механизм встроить непосредственно в среду ББ, которая сейчас фактически является однозадачной осью. Загружает и исполняет один модуль-процесс, в котором запускается одна процедура-поток (тред). Слово parallel для многопоточного ББ и будет означать, чтобы запускал параллельно. А процедуры в модуле - это точный аналог треда, как они описаны в винде. Параллельный поток с общей памятью.
Конечно, для параллельных модулей надо додумать инкапсуляцию. Пока получается, что по умолчанию все внутри модуля является приватным. Кроме процедур-потоков.
-
Загружает и исполняет один модуль-процесс, в котором запускается одна процедура-поток (тред).
(Выделение моё). Как же будет осуществляться обмен данными между модулями-процессами? (Механизм экспорта-импорта модулей.) Ведь память процессов вроде изолирована друг от друга. Хотите использовать файлы, отображаемые в память? А в Линуксе их вроде нет, как там быть?
Хотя, ладно.
Я считаю, что любая идея, даже самая казалось бы сумасшедшая, имеет право на жизнь. Если дело дойдёт до реализации, то все вопросы, которые я тут поднимаю, так или иначе будут решены. Либо возникнет другая идея. :)
-
Загружает и исполняет один модуль-процесс, в котором запускается одна процедура-поток (тред).
(Выделение моё). Как же будет осуществляться обмен данными между модулями-процессами? (Механизм экспорта-импорта модулей.) Ведь память процессов вроде изолирована друг от друга. Хотите использовать файлы, отображаемые в память? А в Линуксе их вроде нет, как там быть?
Есть. mmap никто не отменял. Она есть везде где поддерживается posix.
Вообще, IPC механизмов множество. Те же пайпы например. Unix domain sockets и так далее.
PS. Это просто техническое замечание.
-
Хотите использовать файлы, отображаемые в память? А в Линуксе их вроде нет, как там быть?
Есть. mmap никто не отменял. Она есть везде где поддерживается posix.
Спасибо. Буду знать теперь.