netch: (Default)
[personal profile] netch
(UPDATE log: с аргументом делегата - меня научили военным хитростям)

Нормальные люди, как известно, начинать считают с единицы, программисты - с нуля. BSD'шники переплюнули программистов: у них счёт начинается с минус единицы.


Первый пример: чтобы во FreeBSD в /etc/rc.conf задать адрес на сетевом интерфейсе, надо определить переменную ifconfig_ZZZ, где ZZZ - имя интерфейса. Если одного адреса не хватает... заводится ifconfig_ZZZ_alias0. Нормальный человек назвал бы её примерно как ifconfig_ZZZ_address2, программист - помня, что основной адрес вроде как нулевой - ifconfig_ZZZ_alias1. Видимо, радикализма программистов оказалось недостаточно.

Второй пример: логфайлы. Если /var/log/messages "проротейчен" (сдвинут в сторону и на его месте открыт новый) - он становится... да, уже многие догадались (если не знали уже) - /var/log/messages.0. (Ну или /var/log/messages.0.gz, если он ещё и сжимается.) Почему 0, почему не 1? Видно, великая тайна есть в развитии BSD систем, которую не понять даже такому привыкшему уже к FreeBSD старому извращенцу, как я.

К чему это я вспомнил? Ну да, читая книгу по C# обнаружил, что старый добрый printf авторов оного не устроил (ну ещё бы, великий принцип NIH - "not invented here" - руководит чуть ли не всей деятельностью конструкторской и программной разработки). Вместо старых добрых %<n>.<m><f> (например, %d - целое число со знаком, или %12.3f - вещественное число в формате фиксированной точки с 12 позициями всего и 3 после точки) - введено нечто принципиально новое: {номер_аргумента,ширина:формат}. Сразу вспомнился gettext: его выгибоны для перестановки параметров получили естественное подкрепление, теперь локализовать выводимые сообщения в System.String.Format() значительно легче. Но первый аргумент после форматной строки... имеет номер 0! Видимо, Microsoft вместе с сетевым стеком FreeBSD подхватило вирус "минус единицы", пронумеровав ею саму форматную строку.

То что совместимость с семейством printf потеряли - об этом можно и не вспоминать. Вперёд, заре навстречу, товарищи в борьбе... Да, аналогов подходов funopen() и fopencookie() в System.IO нету, не по чину такое реализовывать. Хорошо, что хоть не мешают это делать построением своих классов, в отличие от проприетарных stdio.

С тредами мы наблюдаем другой вид чудес. Для запуска нового треда в C# надо, кроме прочих шаманских действий, занести свой метод в делегат следующего вида:

public delegate void ThreadStart();

Сравнивая с другими реализациями (например, pthreads) видим отсутствие аргумента на входе:

typedef void *(*pthread_startroutine_t)(void *);

"Гады! Редиски! Куда аргумент дели?" Не надо думать, что этот плач бессмысленный; если бы передавался параметр типа object, можно было бы через него передать любую информацию, точно так же как через void* в plain C. А что остаётся - глобальные переменные? А если у нас два или больше, например, идентичных по схеме построения worker pool'а, но с разными множествами рабочих нитей (абсолютно нормальный дизайн, однако)? Сериализовать старт новых нитей? А ведь иного и не остаётся. Тут уже подсказали, что есть типа секретный метод (Шилдт про него молчал как партизан, надо было тщательно проштудировать примеры кода чтобы понять трюк), так что исправляюсь - не всё так безнадёжно. Но - 1) почему это не описывают явно и открыто? 2) почему так через одно место? На дворе всё-таки даже для первой версии был 2000-й год, а не 1970-й.

Это напомнило мне метод старта новых процессоров в Intel SMP (подробности на developer.intel.com в мануалах к Pentium, для более поздних процессоров эта документация не дублировалось). Передать что-то процессору в том IPI (inter-process interrupt), который его запускает, например, адрес точки старта и значение хотя бы одного регистра? Да боже упаси, от этого корона свалится! Поэтому:
- старт процессоров, ясен пень, сериализуется - пока один не отрапортовал что тангаж, крен и рысканье в норме, следующие на взлёт не отправляются.
- пишется системная процедурка, которая вылавливает из памяти из глобальной переменной, кого же стартуем, и начинает соответствующую отработку.
- в область данных BIOS пишется специальное указание "после проверки процессора переходить на заданный адрес" (через него в 80286, в частности, делался переход в real mode). Что будет, если в этот момент придёт reset - можно только догадываться, скорее всего, машину придётся дёргать только по питанию.
- наконец, толкаем IPI. Процессор выйдя из спячки уходит выполнять код по стандартным FFFF:0000 в real mode. Прочитав заветный приказ по 0x0470-0x0473, уходит на процедуру ОС. Стартовав, та снимает все эти навороты чтобы reset сработал:)

Стра-ашно? Вот-вот, теперь берём передачу в делегат вместе с методом объекта - объект и уходим от этого ужаса. Довольные тем, что перехитрили всех:)

Впрочем, first-class functions с возможностью конструирования их на ходу от этого всё равно не появятся. Какое-то подобие замыканий (и опять через двуединую сущность с вертикальной улыбкой!) обещают во второй версии, да когда же она будет достаточно распространена...

Впрочем, мне это всё пока что теория - ни одной живой строчки на нём я не написал и, видимо, не скоро напишу. Может, у реальных писателей на оном, стаж которых к данному моменту достиг уже 10 лет непрерывного применения в сложных условиях борьбы с тараканами оконного интерфейса и оптимизациями языка 1С, мои плачи вызовут только ироническую ухмылку - не тем, мол, занимаешься. Ладно, посмотрим.

А вообще, впечатление от оной продукции, мягко говоря, грустное. Что стоило, например, убрать вечную проблему "к какому if относится данный else?" и сделать нормальный else-if? Неужели сохранение совместимости с дизайном 35-летней давности (старше конструкции моего пердящего драндулета) стоит того, чтобы распространять грабельное поле ещё на ближайшие 10-20 лет?

Date: 2005-09-03 12:03 am (UTC)
From: [identity profile] vadim-i-z.livejournal.com
В швейцарском, кажется, футбольном чемпионате счет однажды начался с -6. Некую команду за финансовые провинности до чемпионата оштрафовали на 6 очков.
BSDшники посрамлены?

Date: 2005-09-03 07:59 am (UTC)
From: [identity profile] vadim-i-z.livejournal.com
А я систематически, систематизированно и, не побоюсь сказать, системно вычитаю из будущих экзаменационных оценок студентов баллы за несданные домашние работы. Вот!

Date: 2005-09-03 08:42 am (UTC)
From: [identity profile] dinozavrik.livejournal.com
Хм... а ежели студент не сдал десять работ - ему только вешаться?

Date: 2005-09-03 10:18 am (UTC)
From: [identity profile] vadim-i-z.livejournal.com
Я не такой страшный:
а) их (работ) всего четыре;
б) максимально возможный вычет составляет 2 балла по десятибалльной шкале.

Date: 2005-09-03 12:46 am (UTC)
From: [identity profile] egorfine.livejournal.com
VB нас всех вылечит. :-\

Date: 2005-09-03 12:57 am (UTC)
From: [identity profile] dottedmag.livejournal.com
>public delegate void ThreadStart();

>Сравнивая с другими реализациями (например, pthreads) видим отсутствие аргумента на входе:

Марш читать, что такое делегаты.

Date: 2005-09-03 07:27 am (UTC)
From: [identity profile] dottedmag.livejournal.com
Сорри, не хотел так резко выразиться.

Секретная возможность очень простая - экземпляр делегата может хранить ссылку на объект + функцию-член класса. Работало в ещё в .NET 1.0 (который я последний видел под Windows), работает и под современным Mono:

using System;

class StatefulHandler
{
    public StatefulHandler(int value) { this.value = value; }
    public void handler() { Console.WriteLine(value); }
    private int value;
}

class App
{
    delegate void D();

    static void Main()
    {
        StatefulHandler h1 = new StatefulHandler(1);
        StatefulHandler h2 = new StatefulHandler(2);

        D d1 = new D(h1.handler);
        D d2 = new D(h2.handler);

        d1();
        d2();
    }
}


>P.S. В ru.unix.prog - это Вы?

Да. Можно было определить по крайней мере сличением JID из профиля и подписи :)

Date: 2005-09-03 07:14 pm (UTC)
From: [identity profile] ysae.livejournal.com
class App {
    delegate void D();
    ...

Очень дико извиняюсь за свою лень (книжку не хочется штудировать, и на с#-пример гляжу осмысленно впервый раз). Всего один маленький вопрос.

Для ссылки на сам экземпляр чужого класса/метакласса, или его метод/аттрибут - в этом языке используется специальный тип "делегат"?
То есть, чтобы сослаться на чужой объект, выделили специальный тип?!

Only just for my info. Никакого стеба.

Date: 2005-09-03 10:04 pm (UTC)
From: [identity profile] ysae.livejournal.com
Благодарю. :)

Date: 2005-09-03 08:04 pm (UTC)
From: [identity profile] dottedmag.livejournal.com
Делегат - это callable type. Его экземпляры - это сущности, которые имеют вид функции с определенной сигнатурой. Создание делегата осуществляется подстановкой статической функции определенной сигнатуры, либо функции экзепляра вкупе с объектом того же типа. Надеюсь, ответил на вопрос?

Date: 2005-09-03 09:55 pm (UTC)
From: [identity profile] ysae.livejournal.com
Спасибо. Вполне. :)

Date: 2005-09-03 07:28 am (UTC)
From: [identity profile] lvader.livejournal.com
Нетч, а что тебе с if-else не нравится ? поподробнее можно с вариантами как бы ты хотел видеть ? Да, про C# я даже не читал еще. просто хочу понят по сравнению с теми N языками которые я помню.

Date: 2005-09-03 07:54 am (UTC)
From: [identity profile] dottedmag.livejournal.com
>но ошибки неизбежны даже при колоссальном опыте

У нас запрещается такое "законодательно", в Code Conventions. Хотя тоже - костыль, а не решение проблемы.

Date: 2005-09-03 07:55 am (UTC)
From: [identity profile] dottedmag.livejournal.com
Имелось в виду - запрещаются блоки кода длинее одной строки без скобок.

Date: 2005-09-03 08:04 am (UTC)
From: [identity profile] lvader.livejournal.com
Мда. Может быть у меня в голове не укладывается, потому как привык действительно избыточные скобки писать, и не полагатся на пробелы...
Опять же, если дело только за endif... вспоминается один человек у которого было не очень хорошее зрение, и в его коде практически первыми строками стояли:
#define Begin {
#define End }

:)

Date: 2005-09-03 08:10 am (UTC)
From: [identity profile] lvader.livejournal.com
Кто его знает. Очки человек носил действительно очень толстые.
Но идея в другом - хочешь четко для себя определить - есть методы ;)
Тому человеку захотелось для себя более наглядного кода - он выкрутился.

Date: 2005-09-03 08:47 am (UTC)
From: [identity profile] dinozavrik.livejournal.com
> старый добрый printf авторов оного не устроил (ну ещё бы, великий принцип NIH - "not invented here" - руководит чуть ли не всей деятельностью конструкторской и программной разработки)

Да не такой уж он и "старый добрый" - небезопасен, вынужденная мера для плюсов. А уж за sprintf и тому подобным провокациям-к-переполнению-буфера, например, так и вообще следовало бы расстреливать на месте.

Date: 2005-09-03 09:03 am (UTC)
From: [identity profile] dinozavrik.livejournal.com
> Речь шла про сам язык форматирований.

Так ведь и он создан с учётом того, что "неведома зверушка" интерпретируется как то, что мы укажем. В то время как в шарпе всё-таки неведомых зверушек нет. То есть если ты передаёшь число, а в строке форматирования указываешь %s - как должен вести себя шарп?

> sprintf - был диверсией, понятно. Но snprintf уже в C99.

Да-да, только это поздновато IMHO. Уже, видишь, и NX-биты в процессорах вводить начали :)

Date: 2005-09-03 09:28 pm (UTC)
From: [identity profile] dinozavrik.livejournal.com
> И что тебе дадут те NX-биты?

Дело не в том, что дадут, а в том, что вообще докатились до такого - проблемы библиотек языка решать процессорными средствами :)

Date: 2005-09-03 08:47 pm (UTC)
From: [identity profile] sha90w.livejournal.com
Нетч, а зачем тебе вообще этот C# - для расширения кругозора ? :)

Date: 2005-09-03 09:30 pm (UTC)
From: [identity profile] dinozavrik.livejournal.com
Нуууу.... можно сказать, что это такая джава улучшенная :) Я вот тоже начал шарп и CLR изучать, так после этого на джаву что-то смотреть не хочется. Хотя оно и де-факто более кроссплатформенное.

Date: 2005-09-04 07:31 am (UTC)
singalen: (Default)
From: [personal profile] singalen
Сам купил Шилдта по старой памяти. Оказался он крайне "так себе".
Рекомендуют читать Рихтера и Петцольда.

и Троелсона

Date: 2005-09-10 08:01 pm (UTC)
From: [identity profile] http://users.livejournal.com/_mxm_/
кажется не ошибся с фамилией...

такая черная обложка с желтыми большими буквами названия

Да!

Date: 2005-09-11 01:24 am (UTC)
From: [identity profile] http://users.livejournal.com/_mxm_/
Она. Рекомендую её читать и поглядывать в Рихтера.
Петцольд... Ну... Как сказать... Лучше внимательней
всмотреться в 2.0, а Петцольд никуда не денется.

Profile

netch: (Default)
netch

December 2023

S M T W T F S
     12
3456789
10111213141516
171819 20212223
24252627282930
31      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 3rd, 2026 04:49 am
Powered by Dreamwidth Studios