LINUX.ORG.RU

Опубликован почти окончательный драфт генериков в Go

 


0

10

За подробностями в Go-блог (blog.golang.org/why-generics), там есть ссылка на собственно драфт.

Генерики семантически будут наподобие шаблонов C++, т.е. не boxed (как в Java), а value: компилятор будет генерировать копии с конкретными типами.

Синтаксически удалось обойтись введением всего одного нового ключевого слова contract для описания ограничений типа-значения (то есть для создания чего-то вроде метатипов).

В релизе появится всё это не скоро, в Go 2, срок выхода которого неизвестен. Go 1.13 появится на днях, 1.14 — в ноябре, к десятилетию первого публичного бета-релиза.

★★★

Что тут можно сказать
И 7 лет назад они кричали что дженерики ненужны, и в итоге родили какое-то недоразумение вместо них.

ritsufag ★★★★★ ()
Ответ на: комментарий от ritsufag

Они и сейчас не нужны. А недоразумение, чтобы грамотно слить тему.

anonymous ()
Ответ на: комментарий от anonymous

Не приписывай злому умыслу то, что можно объяснить глупостью.

anonymous ()
Ответ на: комментарий от anonymous

Это не злой умысел. Это как посылать нах хорошего знакомого, но слишком навязчивого. Исследования по генерикам и шаблонам (шаболдам) были проведены ещё до вылупления Го на свет. Результаты и мысли на этот счёт опубликованы.

anonymous ()
Ответ на: комментарий от hbee

Хех, в Rust как то сумели эти две вещи одной сущностью закрыть.

Gorthauer ★★★★★ ()
Ответ на: комментарий от beaver

Те же дженерики сейчас есть в мейнстриме, например, в шарпе и джаве, и отлично там работают. Не знаю, насчёт джавы, но в шарпе всё практически идеально в этом плане.

уже выловили и выпилили в другом яп.

Хотя уже 2 года не пишу на шарпе, прекрасно помню как минимум пару больших граблей там:

  • нельзя сделать constraint на то что класс имеет конструктор с определёнными параметрами. В результате если код активно применяет dependency injection на уровне конструкторов - приходится или перекладывать проверку на runtime, или заводить ещё factory-класс, который передавать в generic.

  • Если хрчется сделать аналог какой-то готового класса - нельзя сказать что «готовый класс реализует мой (новый) интерфейс». Приходится делать обёртку. Если бы можно было указать что существующий класс реализует новй интерфейс (т.к. все методы реализованы) - проблемы бы не было?

И вообще, почему в теме нет упоминания языка, который наиболее сильно продвинулся в этой теме? Вот он: С++/CLI! Шаблоны от C++ и generic из .Net в одном файле с похожим синтаксисом! С такими фичами можно столько всего сделать! что потом 10 килобайт кода месяцами разбирать, по опыту)

GPFault ()
Ответ на: комментарий от GPFault

С такими фичами можно столько всего сделать! что потом 10 килобайт кода месяцами разбирать, по опыту)

Да ну эти машины! Вон Иваныч давече копейку ржавую на свалке нашёл, так не вылазит из гаража, не вылазит месяцами, по опыту).

anonymous ()
Ответ на: комментарий от eao197

Вы так говорите, как будто в C++ пускаются в шаблонные навороты просто из-за любви к извращениям, а не потому, что это реально нужно.

Именно так. А реально для всего хватает C или C++98.

anonymous ()
Ответ на: комментарий от anonymous

Бу-га-га. Поржал.

ЗЫ. Метапрограммирование на шаблонах (и, как следствие, жуткие простыни шаблонного кода) как раз на C++98 в полной мере и развернулось. Новые стандарты просто сделали это более человеческим. Так что уровень вашей ыкспертизы вы сами и продемонстрировали.

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

Бу-га-га. Поржал.

Ваша позиция давно известна и Ваше ржание - не новость.

Метапрограммирование на шаблонах (и, как следствие, жуткие простыни шаблонного кода) как раз на C++98 в полной мере и развернулось.

Так я же и говорю, что C++98 хватает. Хотя метапрограммирование - это излишество, которое не нужно.

Так что уровень вашей ыкспертизы вы сами и продемонстрировали.

Ну и что из этого следует? Напишите скорее об этом в Вашем блоге, мы почитаем и, быть может, посмеёмся :-)

anonymous ()
Ответ на: комментарий от urxvt

Я пока не понял зачем ввели контракты а не использовали уже существующий механизм интерфейсов.

Потому что в интерфейсах нельзя указать операторы (< > и т.д.).

hbee ★★★ ()
Ответ на: комментарий от anonymous

Так я же и говорю, что C++98 хватает

Вы говорите что и C хватает, и C++98. Хотя это уже взаимоисключающие вещи.

А так мне еще ни разу не попадался вменяемый действующий C++ник, которому хватало бы C++98. Аномалии вроде тутошней Iron_Bug только подтверждают это наблюдение.

Вот, кстати говоря, человек на очень простом примере показал эволюцию C++ за последнее время. Код для С++11 можно было бы чутка упростить, но все равно контраст с C++98 заметен.

И мне не понятно, кто в здравом уме согласен отказываться от плюшек современных плюсов в пользу того, что было в C++98. Хотя анонимные LOR-овские надмозги на словах способны на все.

Хотя метапрограммирование - это излишество, которое не нужно.

Поржал еще раз.

Напишите скорее об этом в Вашем блоге

А вы не завидуйте, заведите свой.

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

Вы говорите что и C хватает, и C++98. Хотя это уже взаимоисключающие вещи.

Я имею в виду тот факт, что сишный код полезно пропускать через компилятор C++98. Это во-первых. А второе это то, что C++98 добавляет в C некоторые возможности, вроде виртуальных функций, необходимость которых не оспоришь. Впрочем, умеренное использование шаблонов тоже может быть на пользу, но только умеренное. Поэтому то, что есть в C++98, вполне достаточно.

Вот, кстати говоря, человек на очень простом примере показал эволюцию C++ за последнее время. Код для С++11 можно было бы чутка упростить, но все равно контраст с C++98 заметен.

Ну вот он и показал, что на C++98 получилось лучше, чем на C++11. На C++20 получилось красивее, ясное дело. Но я не о красоте, а о достаточности. Версия C++98 вполне читаемая и сопровождаемая.

Поржал еще раз.

Ну так а что Вы ещё можете? Что Вам ещё остаётся? Ржать, писать шаблоны, смотреть конференции. (И так в цикле).

Понимаете, C++98 не провоцирует ломать свой мозг на почве метапрограммирования, как это делают некоторые дарования в своих выступлениях на конференциях. Там всё относительно просто и понятно (если не упарываться шаблонами ради упарывания шаблонами ради упарывания шаблонами и т.д. в цикле), и это очень хорошо.

А вы не завидуйте, заведите свой.

Зачем? Я не страдаю NIH синдромом. Бреда в Интернете и так предостаточно :-)

anonymous ()
Ответ на: комментарий от anonymous

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

А кто решает «умеренное» употребление или нет? Анонимный LOR-овкий надмозг?

Поэтому то, что есть в C++98, вполне достаточно.

Для вас вполне. Это очевидно.

Ну вот он и показал, что на C++98 получилось лучше, чем на C++11.

Бу-га-га еще раз. Вы разве что с Iron_Bug найдете общий язык.

Зачем?

Чтобы не завидовать.

eao197 ★★★★★ ()
Ответ на: комментарий от anonymous

C++98 добавляет в C некоторые возможности, вроде виртуальных функций, необходимость которых не оспоришь.

Если бы. Есть знакомый высококлассный C++-разработчик, любитель шаблонной магии. Он на дух не переносит виртуальные функции. А когда нужно что-то вроде позднего связывания, строит таблицы указателей на функции :). Такой изврат мозга.

hbee ★★★ ()
Ответ на: комментарий от eao197

А кто решает «умеренное» употребление или нет? Анонимный LOR-овкий надмозг?

Не мудрено, что чрезмерное наблюдение за участниками разных конференций с их модными причёсками отвлекло Ваше внимание от самого Страуструпа. LOR-овский аноним без модной причёски Вам пояснит. Смотрите о чём речь. Давай обратимся за мнением создателя C++ о метапрограммировании на шаблонах C++. Итак:

Template metaprogramming is a set of powerful programming techniques, which when used with care and taste can help solve quite tricky problems

Видите, «with care and taste». Ну знаете же, что это.

Смотрите далее

Like all powerful techniques they are easily overused.

Автор языка говорит открыто, что вся эта кухня с шаблонными метарограммированиям может быть «easily overused».

Ну и на закуску

Be careful about the complexity of the templates you write or use; it is easy to get overenthusiastic and write template code that is too clever to be useful as maintainable production code.

Теперь Вы можете написать письмо Страуструпу и получить консультацию о том, что такое чрезмерное использование шаблонов у него. Это Вам не выступление какого-нибудь «молодо-зелено» с модной причёской послушать. Это же сам создатель языка Вам пояснил :-)

anonymous ()
Ответ на: комментарий от hbee

Есть знакомый высококлассный C++-разработчик
любитель шаблонной магии
Он на дух не переносит виртуальные функции
строит таблицы указателей на функции

Увы, но он не ведает, что творит. Но это его право быть самим с собой и только с самим собой и со своими ручными vtable.

anonymous ()
Ответ на: комментарий от hbee

Настоящий «любитель шаблонной магии» не будет городить «таблицы указателей на функции». Скорее он нагородит CRTP и подобные шаблоны погоняющие шаблонами.

anonymous ()
Ответ на: комментарий от anonymous

И где в словах Страуструпа то, что метапрограммирование не нужно? И что C++98 хватит?

А этого там нет, просто анонимный надмозг в очередной раз продемонстрировал особенности своего мировосприятия.

Ну а так, как ваши слова заставляют усомниться в вашем умении мыслить логически, то вот вам простое объяснение:

Если в языке есть фичи X, Y и Z, из которых вам нужно только X и Y, а мне Y и Z, то это гораздо лучше, чем если бы в языке были только X и Y. Поскольку в этом случае язык на полную катушку можете использовать и вы, и я.

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

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

И где в словах Страуструпа то, что метапрограммирование не нужно?

Он этого не говорит, конечно. Зато он говорит о личных предпочтениях:

Personally, I tend to use templates primarily for generic programming (e.g., defining containers and algorithms over containers) and for templates that generate fairly obvious code based on template arguments (e.g., generating buffers and register access code); that's sometimes called generative programming.

Здесь не усматриваются намёки на метапрограммиование вообще.

А этого там нет, просто анонимный надмозг в очередной раз продемонстрировал особенности своего мировосприятия.

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

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

Просто непонятно зачем же пудрить мозг другим про «современные подходы», когда они прекрасно обходятся чистым C и C++98?

anonymous ()
Ответ на: комментарий от anonymous

Зато он говорит о личных предпочтениях:

И отсюда мы снова приходим к вопросу на который вы ожидаемо не смогли ответить:

А кто решает «умеренное» употребление или нет? Анонимный LOR-овкий надмозг?

Ведь даже в процитированных вами словах Страуструпа нет никаких критериев, которые могли бы провести черту «умеренности». Тогда как «generative programming» вполне может быть весьма запутанным.

это удел участников конференций

У вас прямо какой-то пунктик по этому поводу. Комплексы, видимо.

Просто непонятно зачем же пудрить мозг другим про «современные подходы», когда они прекрасно обходятся чистым C и C++98?

Вот это «прекрасно», как минимум, нуждается в некотором подтверждении. Ибо почему-то когда заглядываешь даже в хорошо (по уверениям многих) написанный код nginx-а, то видишь там сплошное закатывание Солнца вручную. Например:

        ngx_http_upstream_rr_peer_lock(hp->rrp.peers, peer);

        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
                       "get hash peer, value:%uD, peer:%ui", hp->hash, p);

        if (peer->down) {
            ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer);
            goto next;
        }

        if (peer->max_fails
            && peer->fails >= peer->max_fails
            && now - peer->checked <= peer->fail_timeout)
        {
            ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer);
            goto next;
        }

        if (peer->max_conns && peer->conns >= peer->max_conns) {
            ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer);
            goto next;
        }

        break;

    next:

        if (++hp->tries > 20) {
            ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
            return hp->get_rr_peer(pc, &hp->rrp);
        }

Сколько здесь обращений к ngx_http_upstream_rr_peers_unlock?

Что уж говорить про кодовые базы, которые написаны с меньшим тщанием.

И в дополнение к том, вам никто мозг не парит. Вам достаточно C++98 и радибоха, убогим убогое. Только не нужно заявлять:

А реально для всего хватает C или C++98.

eao197 ★★★★★ ()
Ответ на: комментарий от anonymous

Так он и есть примитивный. Привет из прошлого века.

Привет из прошлого века — C. А Go создавался с уже имеющимся знанием, что в C получилось хорошо (и надо позаимствовать) и что плохо (сделать лучше).

Сам я проникся Go почти случайно, просматривая для общего развития один из его обзоров. Глаз зацепился за устройство switch, не требующее break в каждой ветке. «Во! кто-то наконец исправил эту хрень», — подумал я и начал изучать дальше, и нашёл ещё много всего интересного :).

hbee ★★★ ()
Ответ на: комментарий от eao197

Вам достаточно C++98 и радибоха, убогим убогое.

Кстати если исповедовать простоту и умеренность, но при этом не чураться С++17 или лучше С++20, то писать в стиле примитивизма будет намного проще чем в C++98.

anonymous ()
Ответ на: комментарий от eao197

написанный код nginx-а, то видишь там сплошное закатывание Солнца вручную

«Критикуешь - предлагай» (C). Вы можете похвастаться таким продуктом, как NGINX? Уверен, нет. А это, на секундочку, самый широкоиспользуемый в мире HTTP сервер, который приносит реальную пользу миллионам людей, а не восхищения пуристов в узком кругу. И этот продукт написан без единой строчки на шаблонах, без метапрограммирования. Можно ещё вспомнить PostgreSQL. СУБД на чистом C. И снова ни строчки на шаблонах и никакого метапрограммирования и опять же, широкоиспользуемый во всём мире продукт. Причём, весьма и весьма качественный. И это вполне доказывает, что C вполне достаточно для решения любой задачи :-)

anonymous ()
Ответ на: комментарий от hbee

Привет из прошлого века — C. А Go создавался с уже

Одно другому не мешает. Они оба из прошлого века. C - по факту, Go - по идеологии.

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

anonymous ()
Ответ на: комментарий от anonymous

И это вполне доказывает, что C вполне достаточно для решения любой задачи :-)

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

А без стёба - ну явное же преувеличение, но ты же за лулзами пришёл, и говна на пропеллер накинуть, газировки там надуть... ))

yyk ★★★★★ ()
Ответ на: комментарий от yyk

А без стёба - ну явное же преувеличение

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

Ну а то, что контраргументов нет, так это понятно. Их и не будет. Разве что кроме обвинений в троллинге. Ну а чего ещё ждать то? Не конструктивных доказательств же.

anonymous ()
Ответ на: комментарий от anonymous

самодостаточность и достаточноть чистого C для создания программного обеспечения любого уровня сложности

Просто дорого, долго и с кучей багов.

Так и на асме можно.

anonymous ()
Ответ на: комментарий от anonymous

Вы можете похвастаться таким продуктом, как NGINX? Уверен, нет.

Опять... Тебе ссылку на лурк кинуть или сам найдешь?

А это, на секундочку, самый широкоиспользуемый в мире HTTP сервер

И что? Оффтопик не менее используемый в мире...

который приносит реальную пользу миллионам людей

Миллионы леммингов не могут ошибаться, да?

Можно ещё вспомнить PostgreSQL
Причём, весьма и весьма качественный

Я бы не сказал. Как минимум допотопная архитектура, просто еще одно легаси, которое тут же меняют, когда выходят за рамки «локалхоста».

foror ★★★★ ()
Ответ на: комментарий от anonymous

Если бы не ООП, то и Плюсы были бы норм. Но там излишняя концентрация на типах, а не выполняемых задачах, что иногда мешает, а не помогает. Графика, и физика обычно делается на плюсах, где идёт работа с объектами со свойствами. Там это заходит и весьма неплохо.

Ну собственно в Го как раз концентрация на выполняемых задачах, что и делает его таким крутым. Ноль абстракций. Если нужно сделать что-то, то именно это и нужно сделать. Чисто синтаксически желание изобретать какую-то универсалию на все случаи жизни отпадает сразу. Есть что сделать – берёшь и делаешь. Как итог вся концентрация – концентрация на выполнении поставленной задачи. И, судя по всему закономерно, Го практически отсутствует в сфере графики и физики.

kostyarin_ ()
Ответ на: комментарий от kostyarin_

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

foror ★★★★ ()
Последнее исправление: foror (всего исправлений: 1)
Ответ на: комментарий от foror

Тут выше сказали, что он идеален для говнокодеров, вы лишь дополнили эту мысль.

Но так говорят только гонцы за «совершенным кодом», которые ускоряют пару тактов в приложении, которое стоит 90% времени с IOPS. Разве нет? По моему, это разрушение мозга.

kostyarin_ ()
Ответ на: комментарий от kostyarin_

Ну не позорьтесь пожалуйста. Идеальный код это не про пару тактов — это про расширяемость и поддерживаемость, в чем го, с решениями ровно одной задачи и максимально в лоб, размазанными из-за отсутствия абстракций в огромные простыни — очень сильно сосет.

mersinvald ★★★★ ()
Ответ на: комментарий от kostyarin_

Самое важное в коде это удобство его чтения и рефакторинга. Код написанный без напряга мозга зачастую очень плохо читаем. А если еще рефакторинг делается через грепы, а не умной IDE, то это просто write-only код. Написал и можно выкидывать в мусор, когда в будущем потребуется его доработка.

foror ★★★★ ()
Ответ на: комментарий от mersinvald

с решениями ровно одной задачи и максимально в лоб

Но это и есть его by design известный с давних пор. Он для этого и сделан. Даже пустые интерфейсы там сделаны так, чтобы применять их хотелось как можно меньше. И если Го будет отклоняться от этого пути, то именно тогда стоит начинать переживать. Всему должно быть своё место и нечего пытаться быть всеобъемлющим – это просто никому не нужно, кроме теоретиков.

kostyarin_ ()
Ответ на: комментарий от foror

Опять... Тебе ссылку на лурк кинуть или сам найдешь?

Давно нашёл - https://nginx.org Или про https://postgresql.org ?

И что? Оффтопик не менее используемый в мире...

И что?

Миллионы леммингов не могут ошибаться, да?

А ты для кого свои программульки пишешь? Для себя? Никому не нужны что-ли, кроме гениев? :-)

Я бы не сказал. Как минимум допотопная архитектура

Хахаха. Ну предложи послепотопную архитектуру, гений.

anonymous ()
Ответ на: комментарий от foror

Самое важное в коде это удобство его чтения и рефакторинга.

Ну так это про Го.

kostyarin_ ()
Ответ на: комментарий от kostyarin_

Ну собственно в Го как раз концентрация на выполняемых задачах, что и делает его таким крутым. Ноль абстракций.

Подожди, а типы, интерфейсы? Без абстракций это пхп4, попиши-ка на нем, потом расскажешь как оно так жить.

bread ()
Ответ на: комментарий от bread

а типы, интерфейсы?

Ага, когда нормально в интерфейсы может далеко не каждый, а годные примеры можно найти разве в стандартной библиотеке. Интерфейсы к месту там, когда они уже перестают быть абстракцией, а становятся стандартом, типа io.Reader.

А чего в типах абстрактного? Типы – это как раз и есть конкретика.

kostyarin_ ()
Ответ на: комментарий от anonymous

Давно нашёл - https://nginx.org Или про https://postgresql.org ?

Вот же болезный анонимус попался, держи http://lurkmore.to/Сперва_добейся

А ты для кого свои программульки пишешь? Для себя? Никому не нужны что-ли, кроме гениев? :-)

Я не вижу смысла выкладывать свой треш, в отличии от некоторых, т.к. понимаю, что это треш.

Хахаха. Ну предложи послепотопную архитектуру, гений.

Предложу, но не сегодня. А вообще, в open-source и сейчас можно что-нибудь найти на замену PostgreSQL, но в основном треш, узкоколейные поделки - будешь выбирать меньшее из зол.

foror ★★★★ ()
Последнее исправление: foror (всего исправлений: 1)
Ответ на: комментарий от anonymous

Во-первых, вы опять уныло съехали с вопроса о том, кто будет определять «умеренность» употребления шаблонов.

Во-вторых, вам был показал фрагмент кода, который бы на языке с RAII или defer/scope(exit) занял бы меньше места, был бы проще в понимании и сопровождении, дешевле в разработке.

Так что да, C вполне достаточно. Если вам платят за строчки кода. Или вы не в курсе того, что может упростить вам работу. Тогда и С вполне достаточно.

eao197 ★★★★★ ()
Ответ на: комментарий от kostyarin_

А чего в типах абстрактного? Типы – это как раз и есть конкретика.

Здрасьти, на низком уровне никаких типов нет, это все измышления людишек. В букварях прям так и пишут: абстрактные мол типы данных, алгебры там какие-то. Функция это тоже абстракция из математики. Так что непонятно, почему одни абстракции вам угодны, а другие нет.

bread ()
Ответ на: комментарий от foror

Я не вижу смысла выкладывать свой треш
Предложу, но не сегодня.

Ну вот когда предложите что-то, кроме «треша», тогда и можно будет Ваши слова воспринимать.

anonymous ()
Ответ на: комментарий от kostyarin_

Самое важное в коде это удобство его чтения и рефакторинга.
Ну так это про Го.

Нет, не про Го. Простыни кода для умственно отсталых еще не означает, что оно будет легко читаться и рефакториться.

Если бы это было так, я бы давно пилил проекты на Го. Но туда до сих пор дженерики не завезли. И это в 21 веке, что как бы намекает на уровень этого ЯП, его авторов и его последователей.

foror ★★★★ ()
Ответ на: комментарий от eao197

Во-первых, вы опять уныло съехали с вопроса о том, кто будет определять «умеренность» употребления шаблонов.

Никто и никогда. Всем, кто занят написанием реального софта заниматься всякими глупостями просто некогда. (Кстати, изучать язык, стандарт котого занимает несколько тысяч страниц, тоже мало кто будет. Нормальным людям достаточно просто C.)

Во-вторых, вам был показал фрагмент кода, который бы на языке с RAII или defer/scope(exit) занял бы меньше места, был бы проще в понимании и сопровождении, дешевле в разработке.

Никому это не интересно. Пользователи NGINX довольны и без RAII или defer/scope(exit).

Так что да, C вполне достаточно.

Ч.т.д.

anonymous ()
Ответ на: комментарий от foror

Нет, не про Го. Простыни кода для умственно отсталых еще не означает, что оно будет легко читаться и рефакториться.

В Го есть стандарт де-факто форматирования кода. Есть инструменты для рефакторинга. Куча инструментов для code style. Го как раз и есть социальный язык. Чего очень не хватает остальным, по крайней мере компилируемым, языкам.

kostyarin_ ()
Ответ на: комментарий от foror

Тебе ссылку на лурк кинуть или сам найдешь?

Там есть что-то про nginx?

anonymous ()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)