Конференция "Прочее" » Лисп
 
  • oxffff © (06.05.08 09:49) [100]

    > Григорьев Антон ©   (06.05.08 09:34) [97]
    >
    > > oxffff ©   (05.05.08 22:34) [91]
    > > А может изучить мат. часть?
    >
    > Учите. Вам знаний матчасти как раз очень не хватает.


    Ну. ну. Может вы все же удостоверитесь и откроете отладчик. И посмотрите на код который генерирует компилятор?

    И прежде чем мне приводить примеры все же изучите мат. часть.
  • oxffff © (06.05.08 10:04) [101]

    > Григорьев Антон ©   (06.05.08 09:34) [97]
    >
    > > oxffff ©   (05.05.08 22:34) [91]
    > > А может изучить мат. часть?
    >
    > Учите. Вам знаний матчасти как раз очень не хватает.
    >
    > Берём ваш код и слегка дополняем, чтобы можно было получить
    > какой-то результат.
    >
    > type
    >  TXFUNC=function (const a:TvarRec):TvarRec;
    >  VarRecArray=array of TVarRec;
    >
    > function abc(var List:array of const;func:TXFUNC):integer;
    >
    > var
    >  i:integer;
    > begin
    >  for i:=0 to length(List)-1 do
    >    LIST[i]:=func(LIST[i]);
    >  Result:=0;
    > end;
    >
    > function XSample(const a:TvarRec):TvarRec;
    > begin
    >  Result:=a;
    > end;
    >
    > function TrickInit(const List:array of const):VarRecArray;
    >
    > begin
    >  Setlength(result,length(list));
    >  copyMemory(result,@list,sizeof(TvarRec)*length(List));
    > end;
    >
    > procedure TForm1.Button1Click(Sender: TObject);
    > var A:VarRecArray;
    >    S:string;
    > begin
    >  S:='abc';
    >  UniqueString(S);
    >  A:=TrickInit([S]);
    >  S:='123';  {*}
    >  abc(A,XSample);
    >  ASSERT(A[0].VType = vtAnsiString);
    >  Label1.Caption:=string(A[0].VAnsiString)
    > end;
    >
    > Функция XSample оставляет переданное ей значение без изменения,
    >  поэтому следует ожидать появления в Label1 текста 'abc',
    >  который был присвоен переменной S, переданной затем в качестве
    > элемента массива. Тем не менее, на экране появляется непонятно
    > что (проверено в Delphi 7). А вот если убрать строку, отмеченную
    > звёздочкой, будет, как и ожидалось, строка "abc".

    А что вы хотите, если вы не знаете работу с типом TvarRec.
    И даже не удосужились не только открыть отладчик, но и внимательно посмотреть [92].

    И copyMemory(result,@list,sizeof(TvarRec)*length(List)) не имеет к этому никакого отношения.

    Тип TvarRec не имеет и иметь не может финализируемых типов.
    Поэтому семантика копирования простая без использования TypeInfo.

    >
    > Поясню, что здесь происходит. С помощью UniqueString мы
    > добиваемся того, что значение S хранится в динамической
    > памяти со счётчиком ссылок, равным 1. Когда мы передаём
    > это значение в конструктор открытого вариантного массива,
    >  указатель на эту строку тупо копируется как простой указатель,

    Это говорит о вашем не знании.
    Код создания массива создает компилятор.
    А то что вы не знаете некоторых нюансов налицо.

    Вы наверно думаете, что если вы напишите то будет использован механиазм копирования typeinfo.

    var a,b:Tvarrec;

    a:=b;    

    Ничего подобного.

    Финализируемые типы в вариантных записях запрещены. :)
    Поэтому будет простое копирование. :)

    >  который и сохраняется в нулевом элементе массива A. Механизм
    > подсчёта ссылок при этом не включается. И когда переменной
    > S присваивается другое значение, память, занимаемая строкой,
    >  считается свободной, и что там будет располагаться - это
    > как повезёт. А в A[0] при этом сохраняется этот битый указатель,
    >  в результате чего мы и имеем проблемы. Кстати, рекомендую
    > попробовать после строки со звёздочкой вставить UniqueString(S)
    > - увидите ещё один интересный эффект :))

    Проблемы в том, что вы не понимаете что вы делаете. И что делает компилятор. :)

    >
    > Кстати, я вчера задал вам несколько вопросов по поводу ваших
    > предложений, но для ответа вы почему-то выбрали только один
    > из них, скромно умолчав про остальные.
    >

    Я все ваши вопросы ответил. См. внимательно. :)

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

    Ну и кто теперь опять не прав? :)

    >
    >
    > Конечно, можно в вашу функцию TrickInit добавить контроль
    > за счётчиком ссылок или вообще преобразование, сводящее
    > всё к PChar и ручному управлению памятью.

    Это требуется от вас поскольку приведение делает компилятор и вы должны это знать.  :)

    Потребуется ещё
    > куча функций, которые будут в разных ситуациях отвечать
    > за правильное освобождение памяти в нужный момент. Но удобно
    > ли будет пользоваться такой библиотекой с такими наворотами?
    >  Да ещё и с учётом того, что для работы с ней подходит не
    > любой тип данных, а специально организованный, и не любая
    > функция, а только специально написанная? Предлагаю вам остановится
    > на таком завершении спора: "В Delphi, сильно извратившись,
    >  можно написать библиотеку, которая, при добровольном соблюдении
    > её пользователем кучи ограничений, позволит ему программировать
    > в стиле, похожем на Лисп. Но для решения любой практической
    > задачи будет удобнее писать в стиле Delphi, чем использовать
    > такую библиотеку".


    C уважением Антонов Сергей. :)
  • Григорьев Антон © (06.05.08 10:05) [102]

    > oxffff ©   (06.05.08 09:49) [100]
    > Ну. ну. Может вы все же удостоверитесь и откроете отладчик.
    >  И посмотрите на код который генерирует компилятор?

    Дык, смотрел ведь :) Копирование указателя увидел, изменения счётчика ссылок - нет. Да и результат работы этого кода говорит сам за себя. Или неизвестно какое значение - это то, что вы хотели получить с самого начала?

    А примеры кода приводите вы. Я привожу примеры того, когда ваше решение работает неправильно.
  • oxffff © (06.05.08 10:10) [103]

    > euru ©   (06.05.08 09:34) [98]
    >
    > > Alkid ©   (05.05.08 17:22) [76]
    > > А на ABAP как mapcar написать? :)))
    >
    >
    > Например, можно так:
    >
    > form mapcar
    >     using    in_table  type index table
    >              func_name type string
    >     changing out_table type index table
    > .
    > field-symbols: <in>, <out>.
    >
    >   clear out_table.
    >   loop at in_table assigning <in>.
    >     append initial line to out_table assigning <out>.
    >     perform (func_name) in program (sy-cprog)
    >         using    <in>
    >         changing <out>
    >     .
    >   endloop.
    > endform.


    Спасибо за пример.
    Мне тоже нравится понятие field-symbols
    (которые по сути являются typed ref) на ABAP.
  • oxffff © (06.05.08 10:18) [104]

    > А примеры кода приводите вы. Я привожу примеры того, когда
    > ваше решение работает неправильно.


    Решение правильное. Нужно знать работу компилятора с TvarRec.

    Проблема не в коде TrickInit (и кокретно не в CopyMemory).
    а в том, что TVarrec являясь вариантной записью не может содержать финализируемые типы.
    И разработчики Delphi не написали Compiler magic функций которые обрабатывают семантику этого типа.
    В отличии от variant.

    Проблема в том что компилятор при приведении делает это грубо, а именно в строке
    A:=TrickInit([S]);

    Посмотрите внимательно. Что будет при передаче по значению
    function abc(List:array of const);
    Будет простое копирование на стек. Никакой обработки Vtype в отличии от variant
  • oxffff © (06.05.08 10:20) [105]

    > Дык, смотрел ведь :) Копирование указателя увидел, изменения
    > счётчика ссылок - нет.

    Так устроен Delphi. И на это вы натыкатесь еще до входа в функцию TrickInit. :)
  • Григорьев Антон © (06.05.08 10:21) [106]

    > oxffff ©   (06.05.08 10:04) [101]
    > Тип TvarRec не имеет и иметь не может финализируемых типов.

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

    > Это говорит о вашем не знании.
    > Код создания массива создает компилятор.
    > А то что вы не знаете некоторых нюансов налицо.
    >
    > Вы наверно думаете, что если вы напишите то будет использован
    > механиазм копирования typeinfo.
    >
    > var a,b:Tvarrec;
    >
    > a:=b;    
    >
    > Ничего подобного.

    Как раз этого я не думаю. Как копируются записи, я знаю. Откуда вы взяли, что я так думаю - это ваши проблемы.

    > Проблемы в том, что вы не понимаете что вы делаете. И что
    > делает компилятор. :)

    Голословное утверждение. Я подробно описал, что, на мой взгляд, делает компилятор. Если я где-то допустил ошибку, укажите, где именно.

    > Ну и кто теперь опять не прав? :)

    Вы. Потому что вы привели код, позиционируя его как эквивалент Лиспа и не указав дополнительных ограничений. А он эквивалентом не является, так как не умеет работать со строками.
  • oxffff © (06.05.08 10:25) [107]
    to Григорьев Антон ©  

    Вот пример.

    function abc2(list:array of const):integer;
    begin
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    abc2([1,2,'asd','asdasd']);
    end;

    cм. копирование в теле abc2 при создании копии.
    Анализа на Vtype нет, а отличие от variant (у которых есть compiler magic).
    Такова семантика TvarRec.
  • Григорьев Антон © (06.05.08 10:26) [108]

    > oxffff ©   (06.05.08 10:18) [104]
    > Решение правильное. Нужно знать работу компилятора с TvarRec.

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

    > Посмотрите внимательно. Что будет при передаче по значению
    >
    > function abc(List:array of const);
    > Будет простое копирование на стек. Никакой обработки Vtype
    > в отличии от variant

    А я как сказал? o_O

    Я так и писал, что будет простое копирование (точнее, я назвал его не простым, а тупым, но сути это не меняет). Более того, я это знал заранее, ещё до написания этого кода, и специально писал его таким образом, чтобы наиболее наглядно это продемонстрировать.

    Теперь выдохните, подумайте и напишите, в чём именно вы хотите меня убедить.
  • oxffff © (06.05.08 10:45) [109]

    > Григорьев Антон ©   (06.05.08 10:26) [108]
    >
    > > oxffff ©   (06.05.08 10:18) [104]
    > > Решение правильное. Нужно знать работу компилятора с TvarRec.
    >
    >
    > Правильное решение - это то, для которого чётко указаны
    > границы применимости. Вы ничего не написали про ограничения
    > на работу со строками - откуда я мог знать, понимаете ли
    > вы, что ваш пример с ними работать не будет, или нет. Вот
    > и написал, что не будет.

    Мой пример будет работать, если вы знаете как устроен Delphi.

    Почему вы пытаетесь обвинить меня в том, как устроен TvarRec.
    И более того пытались мне вменить ошибку с CopyMemory (см )

    Напоминаю вам ваш пост

    Григорьев Антон ©   (05.05.08 22:12) [90]
    Будете использовать CopyMemory с автоматически финализируемым типом?


    TvarRec - имеет простую семантику копирования.

    Поэтому ситуацию которые вы смоделировали относится к TvarRec, а не к моей реализации.

    >
    > > Посмотрите внимательно. Что будет при передаче по значению
    >
    > >
    > > function abc(List:array of const);
    > > Будет простое копирование на стек. Никакой обработки Vtype
    >
    > > в отличии от variant
    >
    > А я как сказал? o_O
    >
    > Я так и писал, что будет простое копирование (точнее, я
    > назвал его не простым, а тупым, но сути это не меняет).

    А зачем был ваш вопрос про CopyMemory?  :)

    > Более того, я это знал заранее, ещё до написания этого кода,
    >  и специально писал его таким образом, чтобы наиболее наглядно
    > это продемонстрировать.

    Вы сначала пытались прицепится к CopyMemory. А потом когда я вам популярно объяснил, что TvarRec не автоматически финализируемый пытались мне вменить свое незнание.  :)

    >
    > Теперь выдохните, подумайте и напишите, в чём именно вы
    > хотите меня убедить.


    Я вам написал три варианта решения.

    Кстати как там ваше домашнее задание? см. выше
  • Alkid © (06.05.08 10:48) [110]

    > oxffff ©   (06.05.08 09:05) [95]

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

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

    Я всё это к чему веду - есть такие вещи, которые должны быть либо поддержаны на уровне самого языка, либо должны быть выброшены и стоит программировать без них. Функции высшего порядка в общем виде, например.
    Не потому, что из невозможно промоделировать, а потому что полученное решение не будет иметь production quality.

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

    Так же и тут. Реализовывать функции высшего порядка или хотя бы mapcar в общем виде на Delphi смысла нет, овчинка не стоит выделки. Будет как с тем сборщиком мусора - да, они это сделали, но потом требовалось такое количество магических пассов и приседаний, что бы с ним правильно работать, что лучше было бы ограничиться гораздо более простым и специализированным решением.
  • oxffff © (06.05.08 10:57) [111]

    > Alkid ©   (06.05.08 10:48) [110]


    Никто не спорит.

    Было утверждение, что нельзя. Я показываю как можно.
    То что это костыли никто не спорит. Да это костыли.
    Но ходить худо бедно можно.  :)
  • 31512 (06.05.08 11:00) [112]

    > oxffff ©   (06.05.08 10:57) [111]

    - Доктор! У меня заворот кишок!
    - Ничего страшного! Проглотите вот эту палочку.
  • Игорь Шевченко © (06.05.08 11:01) [113]
    Вот в паскале есть тип string, в C (и в С++) его нету. Много лет разные умы с разной степенью успеха измышляли различные способы работы со строками, подобные работе с ними же в паскале.

    И все равно, на обложке издания написано "Британская энциклопудия", то есть, работать так, как в паскале, не получается.

    Это я к тому, что работа со строками прекрасно переводится на язык команд процессора.
  • Alkid © (06.05.08 11:08) [114]

    > Было утверждение, что нельзя. Я показываю как можно.

    Не совсем. Цитирую:

    > вы хотите сказать, что на дельфи этого сделать невозможно?
    >  не понимаю.

    В рамках такой общности, как в Лисп - нет.


    То, что ты предложил по общности не дотягивает. Это всё же более специальный случай, ибо не на все функции применим, а только на те, которые TVarRec принимают :)
  • Alkid © (06.05.08 11:15) [115]

    > Вот в паскале есть тип string, в C (и в С++) его нету. Много
    > лет разные умы с разной степенью успеха измышляли различные
    > способы работы со строками, подобные работе с ними же в
    > паскале.
    >
    > И все равно, на обложке издания написано "Британская энциклопудия",
    >  то есть, работать так, как в паскале, не получается.
    >
    > Это я к тому, что работа со строками прекрасно переводится
    > на язык команд процессора.

    Кстати да. Те же яйца, но меньше. Как ты ни бейся, а сделать так, что бы выражение "bla-bla-bla" + "bu-bu-bu" на С++ занималось конкатенацией строк, а не сложением указателей, не выйдет.
  • oxffff © (06.05.08 11:23) [116]

    > Alkid ©   (06.05.08 11:08) [114]
    >
    > > Было утверждение, что нельзя. Я показываю как можно.
    >
    > Не совсем. Цитирую:
    >
    > > вы хотите сказать, что на дельфи этого сделать невозможно?
    >
    > >  не понимаю.
    >
    > В рамках такой общности, как в Лисп - нет.
    >
    > То, что ты предложил по общности не дотягивает. Это всё
    > же более специальный случай, ибо не на все функции применим,
    >  а только на те, которые  принимают :)


    Вариант на TVarRec самый простой и менее гибкий.
    Я кстати еще написал 2 варианта решения.
    Например на variant, работу с которым можно расширить посредством новых типов используя TcustomVariant.
  • Игорь Шевченко © (06.05.08 11:25) [117]

    > Я кстати еще написал 2 варианта решения.
    > Например на variant, работу с которым можно расширить посредством
    > новых типов используя TcustomVariant.


    а свой вариант с иерархией я увижу ?
  • crux (06.05.08 11:26) [118]
    Игорь Шевченко ©   (06.05.08 11:01) [113]

    Вы немного искажаете действительность. Как вам должно быть прекрасно известно, в стандартной (sic!) библиотеке С++ есть тип string, предоставляющий все необходимые абстракции, которые позволяют обращаться со строками как со встроенным типом. Кроме того, интерфейс строк включает в себя интерфейс вектора из той же стандартной библиотеки.
    А вот интересно, есть ли в паскале стандартная возможность конкатенации строк, посредством добавления в конец (append), позволяющая добиться линейной сложности в этом деле?
  • Игорь Шевченко © (06.05.08 11:33) [119]
    crux   (06.05.08 11:26) [118]


    > Вы немного искажаете действительность. Как вам должно быть
    > прекрасно известно, в стандартной (sic!) библиотеке С++
    > есть тип string, предоставляющий все необходимые абстракции,
    >  которые позволяют обращаться со строками как со встроенным
    > типом


    то есть, я могу написать
    string foo;

    foo = "foo" + "bar";

    ?
Есть новые Нет новых   [134435   +12][b:0.001][p:0.001]