На самом деле это шутка конечно, но действительно есть. Мы экспериментировали с русскими ключевыми словами, и один из вариантов был именно такой. Нам тоже было лень переключать
А ещё вы можете попробывать использовать $include
, но это извращенство)))
Эхх мечты, мечты. был бы я разрабом языка, выкинул бы чуть чуть кучу ненужных телодвижений из него. и синтаксис поменял в некоторых моментах на сишный
- цены бы этому паскалю не было бы.
Так-то программирую, многое нравится, (особенно если учитывать, что считай вообще новичек и сходу начал писать).
Участвовать в разработке может каждый желающий. Но на сишный синтаксис вам никто нечего не даст переделать)) Большая часть того что вы называете неудобствами сейчас - помогает в долгосрочной перспективе. На сколько я понял - вы слишком мало программировали на этом паскале, чтоб понимать что где и зачем.
Паскаль еще и тем хорош для обучения, что у него операторы осмысленный вид имеют, а не С-образную арабскую вязь.
Напишу свои пожелания, мало ли.
Вот что бы хотел:
бегин энд точно бы поменял на { }
:= на = а в условиях ==
+= -= оставил бы, это полезно.
Переменные. так было бы лучше . int: a, c=8, v; по умолчанию чтоб были в 0, но если нужно прямо в объявлении переменных можно было бы задавать начальное значение.
для работы с большой программой сделал бы с боку что-то типа сворачеваемого в ± кода или как писал выше чтоб были оператор например (Блок). и без пыли и шуму
вызываем Блок1
а в файле Блок1 тупо программа которая должна быть вместо Блок1 (без всяких доп переменных, а кому нужно более расширенная версия, пусть юзают блоки по старинке, как есть сейчас)
Но это не реально наверно. Т.к. многие привыкли уже как есть.
Ребят, тут еще мне не понятно, почему когда добавил звуки, паскаль стал виснуть частовато?
begin
var sss: Sound;
sss:=Sound.Create('data\b.mp3');
sss.Play;
// Sleep(sss.Length); //эти строки выдают ошибку поэтому залочил их
// sss.Destroy;
end;
Это ваша непривычка. Это уже десятки лет практикуется в разных паскалях, а разработчики данного паскаля высоко ценят совместимость с другими паскалями
Вот я же и говорю, вы ещё не достаточно программировали чтоб что то говорить. Все переменные по умолчанию 0, но можно ещё задать своё значение:
var i1;//будет 0
var i2 := 5;
А что касается порядка - опять же к пункту 1.
Разберитесь для начала во всех возможностях IDE, перед тем как предлагать свои. К примеру то что вы говорите вроде называется “Панель навигации по исходникам
”. А чтоб создавать точки сворачивания используйте регионы.
В паскале нету имени Sound
в основном пространстве имён. Библиотек которые вы могли использовать, чтоб получить его, бесчисленное количество. Поэтому пока вы не предоставите точную информацию, что нужно чтоб воспроизвести подвисания - никто не сможет помочь.
uses Sounds;
begin
var sss: Sound;
sss:=Sound.Create('data\b.mp3');
sss.Play;
// Sleep(sss.Length);
// sss.Destroy;
end;
ну я так звуки вызываю, где-то примеры нашел, работает вроде, но виснуть иногда стало
Хах, я даже не знал что такой модуль существует. Похоже, недавно добавили.
А подвисает и эта программа или какая то другая? И в чём это подвисание выражается?
При запуске проги, тупо виснет среда разработки . Пока не снимешь с задач. Убрал временно звуки - нормально стало.
При этом, потом, когда снова ту же прогу заново запускаешь - все работает. Т.е. случайным образом, раз 10 если запускать то на какой-то раз зависает.
То, что подвисает при запуске из IDE, я тоже заметил.
Только лечится это немного по другому:
Нужно добавить закладку в панель окон (добавить новый файл или открыть существующий) и когда возникает „ситуация“, тупо мышкой или Ctrl+Tab переключиться между ними. Тогда кнопка запуска вновь станет активной!
После старого Паскаля и Оберона немного непривычно тривиальное решение классической задачи на удаление дубликатов строк в текстовом файле более 3ГБ.
Для ReadAllLines и ReadAllText перепробовал array of string и squence of string, но пока не понял, как оптимально решить задачу используя Distinct. Обычно либо построчно разбивают (сортируют) вхождения по заглавным буквам, либо через хэш нескольких первых букв, а здесь такие возможности, что глаза разбегаются. Может кто подскажет как лучше?
Также интересует как PascalABC. NET различает типы Unicode вроде UTF-8 и 16. Спасибо.
Для начала, на что вы ориентируетесь? К примеру, максимально производительное решение или то которое займёт меньше всего строк? Возможно что то другое, или комбинация нескольких вариантов в определённых рамках?
Сергей, именно это и хотелось бы понять: в чём конкретно разница (преимущества) определённого подхода и возможностей. Разумеется, основное требование - работоспособность даже при 512МБ ОЗУ.
Хорошо, тогда для начала: вы понимаете принцип ленивого запроса по которому работает sequence
?
К сожалению, кроме аналогии с RegEx, вариантов пока нет и в справке вроде не указано. Я знаю, что последовательности реализованы как динамические массивы-перечислители с методами расширения, но в чём выражается ленивость запроса, в упрощении - ленивой загрузке?
Тогда давайте по порядку:
1. Есть тип System.Collections.IEnumerable
(у него в стандартном модуле есть синонимы IEnumerable
и sequence
), это базовый тип для всего перечисляемого. Когда вы пишете
begin
var s:sequence of byte;
end.
вы указываете что переменной s
можно будет присвоить любое перечисление, то есть то у чего есть функция позволяющая получить перечислитель:
public function GetEnumerator(): System.Collections.IEnumerator; virtual;
А с перечислителем можно работать так:
begin
var s:sequence of integer := Seq(1,3,5);
var e := s.GetEnumerator;
while e.MoveNext do
writeln(e.Current);
end.
Именно по этому принципу работает foreach
, поэтому следующая запись компилируется в такую же программу:
begin
var s:sequence of integer := Seq(1,3,5);
foreach var i in s do
writeln(i);
end.
2. Самое простое перечисление которое знаю все - это массив. Он реализует ту самую GetEnumerator
, но имеет кучу надстроек. Кроме всего прочего он хранит C++ -образный массив (то есть бесформенный кусок выделенной памяти, а точнее указатель но его начало).
Когда вы пишете так:
begin
var s:sequence of byte := new byte[3](1,3,5);
foreach var b in s do
writeln(b);
end.
Уже при инициализации переменной s
в ней сохраняет все элементы массива, в виде того C++ -образного массива. А перечислитель который возвращает GetEnumerator
у массивов просто проходит по всем индексам массива, от 0 и до “Длинна-1”.
3. А теперь к последовательностям которые обычно имеют в виду, когда на этом форуме говорят “последовательность”. Вот простенький пример:
function GetMyEnumerable: sequence of byte;
begin
var current := 1;
yield current;
loop 2 do
begin
current += 2;
yield current;
end;
end;
begin
var s: sequence of byte := GetMyEnumerable;
foreach var b in s do
writeln(b);
end.
Здесь уже при инициализации переменной s
в неё не сохраняет значения которые она должна принять. В неё сохраняет только алгоритм который записан в GetMyEnumerable
. Значения элементов тут вычислятся только во время работы foreach
, при чём их вычисление будет останавливаться на каждом yield
, а возобновляться когда вызывается MoveNext
(у перечислителя который использует foreach
).
Это и называется ленивыми вычислениями, потому что последовательность не вычислит элементы до самого последнего момента, пока её не заставят сказать значение этого элемента.
Из преимуществ - все элементы этой последовательности не хранятся в памяти, а вычисляются и сразу же стираются. Из недостатков - если вы 2 раза вызовете foreach
, то вся последовательность вычислится с нуля 2 раза.
Вот такой мини-тест.
begin
var s:int64;
var t1,t2,t3,t4,k:integer;
k:=50;
Milliseconds;
loop k do
s:=Range(1,1000000).Select(t->int64(t)).Sum;
t1:=MillisecondsDelta;
loop k do
s:=SeqGen(1000000,i->int64(i+1)).Sum;
t2:=MillisecondsDelta;
loop k do begin
s:=0;
for var i:=1 to 1000000 do s+=i
end;
t3:=MillisecondsDelta;
Println(t1/k,t2/k,t3/k)
end.
Результат (процессор Intel Core 2 Duo, 3 GHz)
26.84 26.52 2.18
А может ли Sum работать более эффективно за пределами типа integer ? Т.е. с типом int64, поскольку с BigInteger он вообще не работает.