OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 15:32

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 28 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Срезы как в голанге?
СообщениеДобавлено: Воскресенье, 28 Апрель, 2019 12:27 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
В голанге можно использовать срезы (slices). Они представляют собой виртуальный массив, построенный на базе "настоящего" массива и содержат три величины: ссылку на оригинальный массив, индекс начального элемента и индекс конечного элемента. С точки зрения использования срез - это просто массив. Срезы - единственный способ иметь в голанге массив переменного размера. Настоящий массив всегда имеет фиксированный размер.

В Си этот функционал можно реализовать через арифметику указателей, в лиспе есть displaced arrays и fill pointer. Вероятно, уши растут из Фортрана... В отличие от Си, в голанге невозможно попасть за границы массива с помощью среза - имеет место динамический контроль.

По впечатлениям, что-то подобное нужно. Мне нравится, что это решение простое. В лиспе наворочено гораздо больше, а содержания не больше. Т.е. в плане наличия минимального набора примитивов решение в голанге выглядит интересным.

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

Есть ли что-то подобное в A2?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Воскресенье, 28 Апрель, 2019 13:03 
Аватара пользователя

Зарегистрирован: Пятница, 11 Май, 2007 21:57
Сообщения: 1488
Откуда: Украина, Киев
Код:
PROCEDURE Slice*(context: Commands.Context);
VAR
   a, b: ARRAY [*] OF LONGINT;
   i: LONGINT;
BEGIN
   a := [1, 2, 3, 4, 5, 6];
   b := a[2..4];
   FOR i := 0 TO LEN(b, 0) - 1 DO
      context.out.Int(b[i], 0); context.out.Ln;
   END;
END Slice;
Felix Friedrich, Jürg Gutknecht. Array-structured object types for mathematical programming
Felix Friedrich, Jürg Gutknecht, Oleksii Morozov, Patrick Hunziker. A Mathematical Programming Language Extension for Multilinear Algebra


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Воскресенье, 28 Апрель, 2019 15:26 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
Слайсов в АО нет. Но есть тип RANGE, который можно передавать вместе с массивом. К значениям типа RANGE можно применять операторы FIRST, LAST, STEP; STEP - это шаг с которым будут обрабатываться элементы массива. RANGE можно использовать везде, где допустимо использовать индекс.
Код:
MODULE Test;
IMPORT Commands;
VAR range: RANGE;
VAR a, b: ARRAY [ * ] OF LONGINT;

PROCEDURE Print( CONST array: ARRAY [ * ] OF LONGINT );
VAR i: SIZE;
VAR context: Commands.Context;
BEGIN
   context := Commands.GetContext( );
   FOR i := 0 TO LEN( array, 0 ) - 1 DO
      context.out.Int( array[ i ],0 ); context.out.Char( " " );
   END;
   context.out.Ln;
END Print;

PROCEDURE Do*;
BEGIN
   a := [ 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2 ];
   range := 0 .. LEN( a, 0 ) - 1 BY 1;
   b := a[ range ];
   Print( b );
   range := 0 .. LEN( a, 0 ) - 1 BY 2;
   b := a[ range ];
   Print( b );
   b := a[ 0.. BY 2 ];
   Print( b );
   b := a[ .. BY 2 ];
   Print( b );   
   b := a[ .. BY 2 ] * 10;
   Print( b );
   b := a[ .. ] * 10;
  Print( b );
END Do;

END Test.Do~

System.Free Test~

Вывод:
1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
10 10 10 10 10 10 10 10 10 10
10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Вторник, 30 Апрель, 2019 10:55 
Аватара пользователя

Зарегистрирован: Пятница, 11 Май, 2007 21:57
Сообщения: 1488
Откуда: Украина, Киев
Что-то у меня пока аналогичные алгоритмы на старичке Object Pascal быстрее работают чем на Go. Скорость где? :D


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Вторник, 30 Апрель, 2019 12:35 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
Ярослав Романченко писал(а):
Что-то у меня пока аналогичные алгоритмы на старичке Object Pascal быстрее работают чем на Go. Скорость где? :D
А какие там будут аналогичные алгоритмы?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Вторник, 30 Апрель, 2019 23:58 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Не нужны ни слайсы, ни рейнджы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 01:14 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
Без срезов требуется использовать лишние параметры, так как данные могут находится не с 0-го смещения. Это уменьшает ошибкоуствойчивость. Но такие срезы как в Go и AO не нужны.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 08:06 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Comdiv писал(а):
Без срезов требуется использовать лишние параметры
Это вопрос проектирования.

Срезы и проч. стимулируют рукосуйство, сложность и, по законам природы, уязвимость.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 10:17 
Аватара пользователя

Зарегистрирован: Пятница, 11 Май, 2007 21:57
Сообщения: 1488
Откуда: Украина, Киев
Comdiv писал(а):
Без срезов требуется использовать лишние параметры, так как данные могут находится не с 0-го смещения. Это уменьшает ошибкоуствойчивость. Но такие срезы как в Go и AO не нужны.
Если-бы эти срезы ещё нормально работали... Выглядит как поделие студента первого курса. Я имею в виду голанг


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 11:36 
Аватара пользователя

Зарегистрирован: Пятница, 11 Май, 2007 21:57
Сообщения: 1488
Откуда: Украина, Киев
Вот, как заставить работать такой код (Playground)? Слайс IpRanges внутри структуры не увеличивается, хоть ты тресни... с каким capacity его ни создавай. Добавляется один элемент и всё. Может всю структуру пересоздавать каждый раз? :roll:
Код:
package main

import (
   "fmt"
)

type (
   IP2LocRec struct {
      IpLo, IpHi   string
      CCode, CName string
   }

   IpDbRange struct {
      IpLo, IpHi string
   }
   IpDbRanges  []IpDbRange
   IpDbCountry struct {
      IpRanges IpDbRanges
      CName    string
   }
   IpDbCountries map[string]IpDbCountry
)

func process_line(row IP2LocRec) {
   var (
      cInfo IpDbCountry
      ok    bool
   )
   if cInfo, ok = countries[row.CCode]; !ok {
      fmt.Printf("Adding country\n")
      countries[row.CCode] = IpDbCountry{CName: row.CName, IpRanges: make([]IpDbRange, 1, 1)}
      cInfo, ok = countries[row.CCode]
      cInfo.IpRanges[len(cInfo.IpRanges)-1] = IpDbRange{IpLo:row.IpLo, IpHi:row.IpHi}
   } else {
      var newRanges IpDbRanges
      lenRanges := len(cInfo.IpRanges)
      capRanges := cap(cInfo.IpRanges)
      fmt.Printf("cInfo.IpRanges before changes: len: %v, cap: %v -> ", len(cInfo.IpRanges), cap(cInfo.IpRanges))
      if lenRanges == capRanges {
         newRanges = make([]IpDbRange, lenRanges+1, lenRanges*2)
         copy(newRanges, cInfo.IpRanges)
         cInfo.IpRanges = newRanges
         fmt.Printf("after increasing len & cap: len: %v, cap: %v\n", len(cInfo.IpRanges), cap(cInfo.IpRanges))
      } else {
         newRanges = make([]IpDbRange, lenRanges+1, capRanges)
         copy(newRanges, cInfo.IpRanges)
         cInfo.IpRanges = newRanges
         fmt.Printf("after increasing len: len: %v, cap: %v\n", len(cInfo.IpRanges), cap(cInfo.IpRanges))
      }
      //_ = append(cInfo.IpRanges, IpDbRange{IpLo:row.IpLo, IpHi:row.IpHi})
   }
   cInfo.IpRanges[len(cInfo.IpRanges)-1] = IpDbRange{IpLo:row.IpLo, IpHi:row.IpHi}
}

var countries IpDbCountries

func main() {
   countries = make(IpDbCountries)

   process_line(IP2LocRec{IpLo: "0", IpHi: "10", CCode: "US", CName: "Unated States"})
   //process_line(IP2LocRec{IpLo: "11", IpHi: "20", CCode: "SU", CName: "Soviet Union"})
   //process_line(IP2LocRec{IpLo: "41", IpHi: "50", CCode: "IL", CName: "Israel"})
   process_line(IP2LocRec{IpLo: "21", IpHi: "30", CCode: "US", CName: "Unated States"})
   //process_line(IP2LocRec{IpLo: "31", IpHi: "40", CCode: "SU", CName: "Soviet Union"})
   //process_line(IP2LocRec{IpLo: "51", IpHi: "60", CCode: "IL", CName: "Israel"})
   process_line(IP2LocRec{IpLo: "61", IpHi: "70", CCode: "US", CName: "Unated States"})
   //process_line(IP2LocRec{IpLo: "71", IpHi: "80", CCode: "SU", CName: "Soviet Union"})
   //process_line(IP2LocRec{IpLo: "81", IpHi: "90", CCode: "IL", CName: "Israel"})
   process_line(IP2LocRec{IpLo: "91", IpHi: "100", CCode: "US", CName: "Unated States"})
   //process_line(IP2LocRec{IpLo: "101", IpHi: "110", CCode: "SU", CName: "Soviet Union"})
   //process_line(IP2LocRec{IpLo: "111", IpHi: "120", CCode: "IL", CName: "Israel"})

   for cCode, cInfo := range countries {
      fmt.Printf("Country code: %v, name: %v\n", cCode, cInfo.CName)
      for iRange := 0; iRange < len(cInfo.IpRanges); iRange++ {
         ipRange := cInfo.IpRanges[iRange]
         fmt.Printf("\tRange lo: %v, range hi: %v", ipRange.IpLo, ipRange.IpHi)
      }
      fmt.Printf("\n")
   }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 13:45 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
Info21 писал(а):
Не нужны ни слайсы, ни рейнджы.

Когда собственное мнение, с большой вероятностью ошибочное, высказывается с такой категоричностью, вероятно, стоить дописывать "по моему скромному мнению". Причем, КАПСОМ, чтобы сразу была видна вся ничтожность такого мнения.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 14:20 
Аватара пользователя

Зарегистрирован: Пятница, 11 Май, 2007 21:57
Сообщения: 1488
Откуда: Украина, Киев
Вобщем, таки да, только полным пересозданием структуры IpDbCountry удаётся победить эти слайсы. Ни один из рецептов на стековерфлоу и т.д. не сработал


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 14:26 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
Посмотрел программу. Вы просто изменяли срез в локальной структуре, которая совсем не указатель. Срез тоже не указатель, но содержит указатель на массив, но не на длину. Нужно было вернуть локальное значение обратно в словарь. Например, добавлением в конец else ветки кода:
Код:
countries[row.CCode] = cInfo

В любом языке, где существуют структуры вне динамической памяти было бы так же, и срезы тут ни при чём.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 15:17 
Аватара пользователя

Зарегистрирован: Пятница, 11 Май, 2007 21:57
Сообщения: 1488
Откуда: Украина, Киев
Comdiv писал(а):
Нужно было вернуть локальное значение обратно в словарь.
Именно так и сделал.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 16:21 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Kemet писал(а):
Info21 писал(а):
Не нужны ни слайсы, ни рейнджы.

Когда собственное мнение, с большой вероятностью ошибочное, высказывается с такой категоричностью, вероятно, стоить дописывать "по моему скромному мнению". Причем, КАПСОМ, чтобы сразу была видна вся ничтожность такого мнения.
1) Всё, что я сообщаю без явных ссылок на законы и проч., и что не является очевидным (для аудитории) цитированием оных, -- это всё моё мнение.

2) Это концепты следующего уровня. Реализовывать их надо соответственно, то есть если и в языке, то в domain-specific.

3) Мне довелось участвовать в тестировании чего-то такого в ETH до публикации -- на приличном куске реального научного софта. Нашлось четыре строчки, где что-то удалось сэкономить.

4) Кемет, вы пытаетесь поднять свою доминантность за мой счёт. Почему бы это. Впрочем, keep trying.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 17:20 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
Info21 писал(а):
3) Мне довелось участвовать в тестировании чего-то такого в ETH до публикации -- на приличном куске реального научного софта. Нашлось четыре строчки, где что-то удалось сэкономить.
Мне доводилось работать с обратной ситуацией, где имелось бы значительное повышение ошибкоустойчивости во многих строках. Но человек я простой, таким великолепным проектированием, чтобы это не имело существенного значения, заниматься не умею. Есть готовые материалы, в которых можно ознакомится с примерами?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Среда, 01 Май, 2019 17:38 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
Info21 писал(а):
4) Кемет, вы пытаетесь поднять свою доминантность за мой счёт. Почему бы это. Впрочем, keep trying.

Всего лишь пытаюсь донести до разума простую мысль - нужно критичнее относится к своим измышлениям.
Цитата:
3) Мне довелось участвовать в тестировании чего-то такого в ETH до публикации -- на приличном куске реального научного софта. Нашлось четыре строчки, где что-то удалось сэкономить.
Вот об этом я и говорю - критичней к собственным представлениям нужно быть. Ибо у других-то результат совсем отличный от Вашего. Потому что это повышение ошибкоустойчивости и производительности труда ( и вычислений ) и единообразная алгебра и много чего ещё


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Четверг, 02 Май, 2019 00:39 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Кемет, довожу до Вашего разума: гоняйте мух на своей голове (с).

2)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Суббота, 04 Май, 2019 23:06 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1549
Код:
_ = append(cInfo.IpRanges, IpDbRange{IpLo:row.IpLo, IpHi:row.IpHi})


Не понял что именно не работает. Этот код?
Если да, то не работает по той причине, что это кривой код.
append нужно присваивать тому же слайсу.
т.е. так:
Код:
cInfo.IpRanges = append(cInfo.IpRanges, IpDbRange{IpLo:row.IpLo, IpHi:row.IpHi})


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Срезы как в голанге?
СообщениеДобавлено: Воскресенье, 05 Май, 2019 11:11 
Аватара пользователя

Зарегистрирован: Пятница, 11 Май, 2007 21:57
Сообщения: 1488
Откуда: Украина, Киев
ilovb писал(а):
Если да, то не работает по той причине, что это кривой код.
append нужно присваивать тому же слайсу.
т.е. так:
Код:
cInfo.IpRanges = append(cInfo.IpRanges, IpDbRange{IpLo:row.IpLo, IpHi:row.IpHi})
Криво. Тем не менее в некоторых советах на stackoverflow призывают именно ничего не присваивать слайсу, а делать всякий раз его пересоздание через make. Тиражируют повсюду заветную чудо-функцию, которая всё это делает :D Но прикол в том, что оно не работает и так как вы предлагаете тоже! :lol:
Нужно переприсваивать всю структуру в словаре, как заметил Comdiv, так как у нас тут всё статическое.
Окончательный вариант вообще вот, такой. И без каких-либо пересозданий.
Код:
   if cInfo, ok := countries[row.CCode]; !ok {
      countries[row.CCode] = IpDbCountry{CName: row.CName,
         IpRanges: []IpDbRange{IpDbRange{IpLo: row.IpLo, IpHi: row.IpHi}}}
   } else {
      countries[row.CCode] = IpDbCountry{CName: row.CName,
         IpRanges: append(
            cInfo.IpRanges, IpDbRange{IpLo: row.IpLo, IpHi: row.IpHi})}
   }
Если в конце каждого такого вызова вывести len и cap слайса видно, что при каждой необходимости его увеличения capacity удваивается, всё как в аптеке.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 28 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB