Помощь новичкам


#821

Что тут надо исправить чтобы изменить исходную последовательность? почему так не меняется?

begin
  var s := Seq(1, 2, 3); s.Println;
  s.ForEach(x -> begin if x = 2 then x := 5; Print(x) end);
  Println;
  s.Println;//1,2,3
end.

#822
begin
  var s := Seq(1, 2, 3); s.Println;
  s := s.Select(x -> x = 2 ? 5 : x); s.Println;
end.

А не меняется “так” потому, что у Вас нет операции присваивания для s.


#823

.ForEach передаёт в вашу лямбду только копию x, потому что integer это value-тип. @RAlex правильно написал, можно через Select. А ещё будет работать если элементы последовательности будут иметь ссылочный тип:

type
  c1=class
    b:byte;
    constructor(b:byte) :=
    self.b := b;
  end;
  r1=record
    b:byte;
    constructor(b:byte) :=
    self.b := b;
  end;

begin
  var sc := Seq(new c1(2));
  var sr := Seq(new r1(2));
  
  sc.ForEach(procedure(o)->o.b := 3);       //Сработает, потому что c1, как любой класс - ссылочный тип
  sc.ForEach(procedure(o)->o := new c1(4)); //Не сработает потому что тут мы заменяем ссылку, а не меняем то что находится по этой ссылке
  sr.ForEach(procedure(o)->o.b := 3);       //Не сработает, потому что r1, как любая запись - value тип
  
  sc.Select(o->o.b).Println;
  sr.Select(o->o.b).Println;
end.

#824

Что делает ключевое слово match?


#825

Это оператор сопоставления:

begin
  var o: object := 5;
  
  match o with
    real(var r): writeln($'real({r})');
    integer(var i): writeln($'integer({i})');
    object(var o2): writeln($'object({o2})');
  end;
end.

#826

по селекту это понятно, что можно, я то думал что ForEach это же процедура, а последовательность это ссылочный тип, значит должно сработать, а оно видимо еще и в лямбды нужно по ссылке передавать


#827

Ну так в лямбде действие выполняется не над всей последовательностью, а над элементом. Поэтому и зависит от того - по ссылке ли передан элемент.


#828

А как насчет этого?

begin
  var s := Seq(1, 2, 3);
  var (sum, sum2) := (0, 0);
  var p: integer->() := x -> begin x := x*x; sum += x; Print(x) end;
  foreach var x in s do
  begin
    p(x);
    sum2 += x
  end;
  Println; s.Println; //1,2,3
  Print(sum, sum2)//14 6
end.

Здесь внешняя переменная sum изменяется лямбдой. Т.е. лямбда захватывает sum по ссылке. Но при этом элементы последовательности внутри ForEach не меняются, изменяются только в лямбде. Т.е. может быть это не столько в лямбде дело, сколько в foreach? В справке написано “Изменение переменной цикла (foreach) внутри тела цикла не меняет элементы контейнера”.


#829

Цикл foreach это другое:

var s:sequence of byte;

foreach var b in s do

Но экстеншн метод foreach работает примерно так же. Что касается захвата внешней переменной - это не так работает. Тут sum объявляет как глобальную, и когда лямбда разворачивается в обычную процедуру - она может без проблем захватить sum. Никаких ссылок для этого не создаётся.


#830

100 сообщений перенесены в тему Болталка PascalABC.NET


#831

Ещё одна странность, но на этот раз с указателями. На Паскале в режиме Debug работа с массивом по указателям быстрее, чем по стандартному индексатору, а в Release - наоборот. На C# этот же код работает правильно(в Release и со включённой оптимизацией). Как это вообще понять?


#832

Наверное потому, что вы производите дополнительные преобразования к integer и назад, чтоб работать с указателями. А в Debug вообще всё работает как хочет, по скорости. Просто больше дебага сделали для for чем для работы с указателями))


#833

Тогда предложение к разработчикам. @Admin , @ibond , почему бы не оптимизировать указатели? Сейчас для изменения адреса приходится преобразовывать указатель к int32, затем прибавлять или вычитать требуемое значение, а затем сначала в Pointer и уж только потом в типизированный указатель. Можно ли сделать работу более эффективной? Представлять их как число int32?


#834

Так уже писали про указатели, что это не основная тема, которой стоит заниматься, может, когда руки дойдут и нечем больше будет заняться. В целом правильно, ведь работают они? Да, работают.

Приходит сын к папе, программисту:
- Папа, почему Солнце всходит на востоке, а заходит на Западе?
Папа - ноль эмоций...
- Папа, ну почему Солнце каждый день всходит на востоке, а заходит на Западе?
Папа - опять ноль эмоций...
Сын, нетерпеливо дергая папу за рукав - Папа, папа, ну почему Солнце
каждый день всходит на востоке, а заходит на Западе?
- Солнце ?
- Да
- Всходит на востоке ?
- Да
- Заходит на западе ?
- Да, папа
- Каждый день?
- Да...
- И давно так?
- Ну, я не знаю... Всегда...
- Знаешь что, сынок? Работает - не трогай!!!

#835

Это не наша основная цель. Указатели работают для совместимости. Мы развиваем .NET-составляющую языка, и там много идей и еще больше проблем.

Если бы разработчиков было ну хотя бы 10 человек - ну тогда можно было бы.


#836

Согласен, но разве нет интереса к оптимизации? 2.5 РАЗА, КАРЛ! Тем более, не думаю, что исправление указателей такая уж сложная задача. Есть проблемы и сложнее, корень которых не известен(почему программа на Паскале работает в 2 раза медленнее, чем на C#?). Я конечно извиняюсь, но какой смысл в синтаксическом сахаре, который постоянно вводится в язык, если это всё работает долго? Приведу в пример Питон, на который очень часто ссылаются в новых фичах. В Питоне нереально много специфических фичей, но тем не менее его используют только как обёртку для кода на C++, причём используют его возможности при этом крайне редко. Почему? Да потому что весь сахар(и не только он) работает чрезвычайно долго. Тут даже не вижу смысла докапываться до причин, важен результат. А почему все выбирают C(даже не C++) для реализации объёмных по вычислениям программ, несмотря на его громоздкость? Только лишь потому, что его код получается крайне эффективным. Почему сейчас поливают грязью FreePascal и Lazarus, хотя они гораздо моложе того же C++, но более красивы? А потому что программы получаются неэффективными. Будет обидно, если PascalABC.NET постигнет та же участь что и TurboPascal. Разумеется, всё сказанное выше - ИМХО. Если кого обидел - прошу прощения.


#837

Потому, что они с Фортраном не умеют работать. Либо, просто снобы от программирования, когда шашечки важнее того, чтобы ехать. Для объемных вычислений - только Фортран. “С” там и рядом не стоял по оптимизации и результирующей производительности. Весь ученый и инженерный мир серьезные расчеты делает в Фортране, не доверяя никаким С. И не надо, если что, общеизвестную эту истину пытаться опровергнуть. Конечно, право на собственное мнение Вы имеете. Но и только.


#838

Какой весь? Там скорее только в физике, математике и химии. Там принято использовать этот язык. Если посмотреть, например, на что-то более земное, то вот Вам, например, драйвера устройств и всевозможные низкоуровневые части ОС. Там требуется максимальная производительность. Даже сейчас некоторые части пишутся на Ассемблере. Фортран - устаревший язык, пора бы это признать, несмотря на все его заслуги. Если бы он был перспективным, то его явно развивали бы, а там…


#839

Вы себе же противоречите. Какое отношение перечисленное Вами имеет к “объемным по вычислениям расчетам” ? Не нужно скакать с темы на тему, желая что-то свое доказать - я уже писал об этом Вам.

Драйвера и иные компоненты писали на С - он для этого и создавался - пишут сейчас и будут писать еще достаточно долго. Поскольку С - почти полноценная замена Ассемблеру. И что дальше?


#840

Дело не в объёмах вычислений, а в их эффективности. Для объёмных задач эффективность крайне важна, как и для драйверов.